AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

[Lib] ini v0.15.1 - Basic ini string functions
Goto page Previous  1, 2, 3, 4, 5  Next
 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
Tuncay n-l-i mobile
Guest





PostPosted: Fri Sep 25, 2009 6:22 pm    Post subject: Reply with quote

yes i know that. That bug should be eliminated. Some days ago i have started to continue on this and it does have a full documentation. Its still beta but many different test cases are showing its working good enough on most cases.

I am not at home now. Today i post the update, later.

majkinetor: currently i have no comparison done. I should not write that before any test. It is just a guess.
Back to top
Tuncay



Joined: 07 Nov 2006
Posts: 893
Location: Berlin, DE

PostPosted: Sat Sep 26, 2009 8:14 am    Post subject: Update Reply with quote

Updated to version 0.9.

Last changes
  • fixed ini_getAllKeyNames() where it catched a section
  • fixed ini_getAllSectionNames() where it did not catched all sections
  • changed in ini_replaceValue(), ini_replaceKey() the internal regex to use the good one by Mystiq. Now it works better.
  • changed ini_getAllKeyNames() and ini_getAllSectionNames() so that they return no space after comma of any list item
  • added more testcases
  • changed internal documentation to work with Natural Docs and created a full describing docu

Now it includes a full documentation describing and showing everything of the functions you need to know. And the described bug found by erinau is also eliminated.

But I have a note to your example:
erinau wrote:
Code:
ini_replaceKey(ini, "DATA", "AAAAA","hkjh")

This would change the key/value line to "hkjh". You should specify the key also or it is replaced by the characters "hkjh" only.
If you want to change the value only, without affecting the keyname, then ini_replaceValue() might be the better function to you.

Online Documentation

Download (~60 kb)
    The archive contains the ini library, a test module and full documentation generated with Natural Docs. Still on test phase and beta stage.
Back to top
View user's profile Send private message
Tuncay



Joined: 07 Nov 2006
Posts: 893
Location: Berlin, DE

PostPosted: Sat Sep 26, 2009 7:04 pm    Post subject: Update Reply with quote

Updated to version 0.10.

Last changes
  • Wrote a remark about how to switch to regex in section and key names
    (via character sequence "\E" to begin and "\Q" to end).
  • Added functions of AutoHotkey aliases: Ini_Read, Ini_Write and Ini_Delete.
    They mimic and act like the original commands, but for use with variables,
    instead of files.
  • Added another related link in documentation.
Back to top
View user's profile Send private message
rootey



Joined: 06 Sep 2009
Posts: 19

PostPosted: Sun Sep 27, 2009 10:55 pm    Post subject: Reply with quote

Tuncay, been testing these, and reading through the docs. All appears to work & is clear. But I didn't see a way to do a ini_appendKey(ini, "Section", "key") So that you could add to a recent file list, or add to a set of tags in a Section. Have I overlooked something, or is it something you might add?
Back to top
View user's profile Send private message
Tuncay n-l-i mobile
Guest





PostPosted: Mon Sep 28, 2009 4:17 am    Post subject: Reply with quote

Thanks for testing and interesting it. Yes you have overlooked something. Please look in documentation, its called ini_insertKey().
Usage:
Code:
ini_insertKey(ini, "section", "key=value")


If you have any wish or suggestion, please ask. And if all works, so please say this also. I want mark that lib as stable, if it is stable enough.

There are aliases of existing autohotkey commands also.
Back to top
Tuncay



Joined: 07 Nov 2006
Posts: 893
Location: Berlin, DE

PostPosted: Thu Oct 22, 2009 11:40 pm    Post subject: Reply with quote

rootey wrote:
Tuncay, been testing these, and reading through the docs. All appears to work & is clear. But I didn't see a way to do a ini_appendKey(ini, "Section", "key") So that you could add to a recent file list, or add to a set of tags in a Section. Have I overlooked something, or is it something you might add?

Now I have some functions which operate on a key, that is working as a list. Default list separator is the "|" character, but can be redefined in parameter list.
All functions working now and there are implementation of some simple functions and one more complex and general usable one. Here the implemented functions (name and functionality can be change):

  • ini_swapStack(ByRef _Content, _Section, _Key, _Separator = "|")
    swap the two last item entries in stack (last object)
  • ini_pushStack(ByRef _Content, _Section, _Key, _Value = "", _Separator = "|", _PreserveSpace = False)
    add item entry to stack (last object)
  • ini_popStack(ByRef _Content, _Section, _Key, _Separator = "|")
    read and delete item entry from stack (last object)
  • ini_peekStack(ByRef _Content, _Section, _Key, _Separator = "|")
    read only item entry from stack (last object)
  • ini_readStack(ByRef _Content, _Section, _Key, _BeginPos = 1, _Delete = false, _Separator = "|")
    Read a part from stack. BeginPos begins from first item. Any negative value is counted from last to first item, where 0 is the last item. If Count is 0 or less, then nothing is returned. ErrorLevel holds the number of all items. On error, ErrorLevel contains -1.

Full documentation and implementation in source will be done, if nothing is supposed to be changed. Its a working proof of concept.
The terms peek, push, pop and swap used as the functions names are generally used in other environments to indicate its function with a stack.

For the sake of speed, I would recommend to read the key once and work with the keys value only and then replace the value.

Code:
ini =
(
[s]
k1=|test1|test2|test3|test4|test5|test6|test7|test8|test9|test10
k2=
[t]
k1
)
s=s
k=k1

Error = 0

; Get last object and delete it from the list. The "|" is deleted automatically.
Expected := "test10"
Result := ini_popStack(ini, s, k), Throw(Result, Expected)
Expected := "test9"
Result := ini_popStack(ini, s, k), Throw(Result, Expected)

; Add an item to end of list. The "|" is added automatically.
Expected := "1"
Result := ini_pushStack(ini, s, k, "test10"), Throw(Result, Expected)
Expected := "1"
Result := ini_pushStack(ini, s, k, "test9"), Throw(Result, Expected)

; Swaps the last two items in list.
Expected := "1"
Result := ini_swapStack(ini, s, k), Throw(Result, Expected)

; Get last object from list without "|".
Expected := "test10"
Result := ini_peekStack(ini, s, k), Throw(Result, Expected)

Expected := "|test1|test2|test3|test4|test5|test6|test7|test8|test9|test10"
Result := ini_readStack(ini, s, k, 1, 10), Throw(Result, Expected)
Result := ini_readStack(ini, s, k, 1, 13), Throw(Result, Expected)
Result := ini_readStack(ini, s, k, -9, 10), Throw(Result, Expected)
Result := ini_readStack(ini, s, k, -9, 13), Throw(Result, Expected)
Result := ini_readStack(ini, s, k, 0, 10), Throw(Result, Expected)
   
Expected := "|test10"
Result := ini_readStack(ini, s, k, 10, 1), Throw(Result, Expected)
Result := ini_readStack(ini, s, k, 0, 1), Throw(Result, Expected)
   
Expected := "|test3|test4|test5|test6|test7"
Result := ini_readStack(ini, s, k, 3, 5), Throw(Result, Expected)
Result := ini_readStack(ini, s, k, -7, 5), Throw(Result, Expected)

If (Error = 0)
{
   MsgBox There is no error. All tests are successful terminated.
}
msgbox % ini_readStack(ini, s, k, -2, 2)
msgbox %errorlevel% items counted`n`ncontent:`n%ini%

Throw(_Result, _Expected)
{
   Global Error
   Static TestNo := 0
   TestNo++
   If (_Result != _Expected)
   {
      MsgBox, , Unexpected Result, %TestNo%`n`nResult:          "%_Result%"`nExpected:     "%_Expected%"
      Error++
   }
}

; Read a part from stack. BeginPos begins from first item. Any negative value is counted
; from last to first item, where 0 is the last item. If Count is 0 or less, then nothing
; is returned. ErrorLevel holds the number of all items. On error, ErrorLevel contains -1.
ini_readStack(ByRef _Content, _Section, _Key, _BeginPos = 1, _Count = 1, _Separator = "|")
{
    If (_Section = "")
        _Section = (?:\[.*])?
    Else
         _Section = \[\s*?\Q%_Section%\E\s*?]
   StringReplace, _Content,_Content, |, |, UseErrorLevel
   ItemCount := ErrorLevel
   If (_BeginPos > 0)
   {
      If (_Count >= ItemCount)
         _Count := ItemCount - _BeginPos + 1
      _BeginPos--
   }
    Else If (_BeginPos = 0)
   {
      If (_Count > ItemCount)
         _Count := ItemCount
      _BeginPos := ItemCount - _Count
   }
   Else
   {
      _BeginPos := -_BeginPos
      If (_BeginPos > ItemCount)
         _BeginPos = 0
      Else
         _BeginPos := ItemCount - _BeginPos - 1
      If (_Count + _BeginPos > ItemCount)
         _Count := ItemCount - _BeginPos
   }
   RegExPart = (?:\Q%_Separator%\E.*){%_BeginPos%}((?:\Q%_Separator%\E(?:.*)){%_Count%})(?:\Q%_Separator%\E.*)?
   ; Note: The regex of this function was written by Mystiq.
    RegEx = S`aiU)(?:\R|^)\s*%_Section%\s*(?:\R\s*|\R\s*[\w\s]+\s*=\s*.*?\s*(?=\R)|\R\s*[;#].*?(?=\R))*\R\s*\Q%_Key%\E\s*=%RegExPart%(?=\R|$)
   If RegExMatch(_Content, RegEx, Value)
      ErrorLevel := ItemCount
   Else
      ErrorLevel = -1
   Return Value1
}

; read only item entry from stack (last object)
; alias ini_getLastItem()
ini_peekStack(ByRef _Content, _Section, _Key, _Separator = "|")
{
    If (_Section = "")
        _Section = (?:\[.*])?
    Else
         _Section = \[\s*?\Q%_Section%\E\s*?]
    ; Note: The regex of this function was written by Mystiq.
    RegEx = S`aiU)(?:\R|^)\s*%_Section%\s*(?:\R\s*|\R\s*[\w\s]+\s*=\s*.*?\s*(?=\R)|\R\s*[;#].*?(?=\R))*\R\s*\Q%_Key%\E\s*=.*?\Q%_Separator%\E(.*)(?=\R|$)
   If RegExMatch(_Content, RegEx, Value)
        ErrorLevel = 0
    Else
        ErrorLevel = 1
    Return Value1
}

; read and delete item entry from stack (last object)
; alias ini_deleteLastItem()
ini_popStack(ByRef _Content, _Section, _Key, _Separator = "|")
{
    If (_Section = "")
        _Section = (?:\[.*])?
    Else
         _Section = \[\s*?\Q%_Section%\E\s*?]
    ; Note: The regex of this function was written by Mystiq.
    RegEx = S`aiU)((?:\R|^)\s*%_Section%\s*(?:\R\s*|\R\s*[\w\s]+\s*=\s*.*?\s*(?=\R)|\R\s*[;#].*?(?=\R))*\R\s*\Q%_Key%\E\s*=.*?)\Q%_Separator%\E(.*)((?=\R|$))
   If RegExMatch(_Content, RegEx, Value)
   {
      _Content := RegExReplace(_Content, RegEx, "$1$3")
        ErrorLevel = 0
   }
    Else
        ErrorLevel = 1
    Return Value2
}

; add item entry to stack (last object)
; alias ini_addItem() or ini_enQueue()
; Returns 1 if succsess and 0 otherwise.
ini_pushStack(ByRef _Content, _Section, _Key, _Value = "", _Separator = "|", _PreserveSpace = False)
{
    If (_Section = "")
        _Section = (?:\[.*])?
    Else
         _Section = \[\s*?\Q%_Section%\E\s*?]
    If Not _PreserveSpace
        _Value = %_Value% ; Trim spaces.
    ; Note: The regex of this function was written by Mystiq.
    RegEx = S`aiU)((?:\R|^)\s*%_Section%\s*(?:\R\s*|\R\s*[\w\s]+\s*=\s*.*?\s*(?=\R)|\R\s*[;#].*?(?=\R))*\R\s*\Q%_Key%\E\s*=.*?(?:\Q%_Separator%\E.*)?)((?=\R|$))
    _Content := RegExReplace(_Content, RegEx, "$1" . _Separator . _Value . "$2", isReplaced, 1)
    If isReplaced
        ErrorLevel = 0
    Else
        ErrorLevel = 1
    Return isReplaced
}

; swap the two last item entries in stack (last object)
; alias ini_swapLastItems()
; Returns 1 if succsess and 0 otherwise.
ini_swapStack(ByRef _Content, _Section, _Key, _Separator = "|")
{
    If (_Section = "")
        _Section = (?:\[.*])?
    Else
         _Section = \[\s*?\Q%_Section%\E\s*?]
    ; Note: The regex of this function was written by Mystiq.
    RegEx = S`aiU)((?:\R|^)\s*%_Section%\s*(?:\R\s*|\R\s*[\w\s]+\s*=\s*.*?\s*(?=\R)|\R\s*[;#].*?(?=\R))*\R\s*\Q%_Key%\E\s*=.*?)(\Q%_Separator%\E.*)(\Q%_Separator%\E.*)((?=\R|$))
   NewContent := RegExReplace(_Content, RegEx, "$1$3$2$4")
   If NewContent
   {
      _Content := NewContent
        ErrorLevel = 0
   }
    Else
        ErrorLevel = 1
    Return !ErrorLevel
}


Comments are welcome. These functions are independent from the main ini source.
edit: updated code, fatal error corrected
edit2: updated code, a simple optimization at swap (uses now 1 instead of 2 regex calls).


Last edited by Tuncay on Fri Oct 23, 2009 2:04 am; edited 3 times in total
Back to top
View user's profile Send private message
Tuncay



Joined: 07 Nov 2006
Posts: 893
Location: Berlin, DE

PostPosted: Fri Oct 23, 2009 12:25 am    Post subject: Reply with quote

There was a fatal error, an outdated code! Have corrected that above. Sorry.
Back to top
View user's profile Send private message
Tuncay



Joined: 07 Nov 2006
Posts: 893
Location: Berlin, DE

PostPosted: Sun Oct 25, 2009 10:18 am    Post subject: Reply with quote

Here is a repair function for ini files:
Code:
ini =
(
[s]
k1 =|test1|test2|test3|test4|test5|test6|test7|test8|test9|test10
k2= t    test its a string   #test   

;[s]
;k=keycomment


[   t ]

k1  =           key
)
s=s
k=k1
MsgBox before:`n%ini%
ini := ini_repair(ini)
MsgBox after:`n%ini%
exitapp
ini_repair(_Content, _CommentSymbols = ";#", _LineDelim = "`r`n")
{
    If (_CommentSymbols != "")
    {
        regex = `aiUSm)\R?\s*[%_CommentSymbols%].*?(?=\R)
        _Content := RegExReplace(_Content, regex)
    }
    Loop, Parse, _Content, `n, `r
    {
        If (RegExMatch(A_LoopField, "`aiUSm)\[\s*?(\w+)\s*?]", Match))
        {
            newIni .= _LineDelim . "[" . Match1 . "]"
        }
        Else If (RegExMatch(A_LoopField, "`aiUSm)(\w+)\s*?=(.*?)", Match))
        {
            newIni .= _LineDelim . Match1 . "=" . Match2
        }
    }
    StringReplace, newIni, newIni, %_LineDelim%
    Return newIni
}

Its still not integrated into ini library. Other than the other functions, it works with a Loop command and can be slow on big line numbers. Unneeded whitespaces and comments are stripped away and the whole ini is build consistently with defined new line character.
This function can be of help in case where the ini file is edited by different programs or persons.
Documentation will follow after it is intregrated into library.

note: this is an old version. The newer version is in main source integrated.


Last edited by Tuncay on Sun Nov 08, 2009 11:13 am; edited 1 time in total
Back to top
View user's profile Send private message
Tuncay



Joined: 07 Nov 2006
Posts: 893
Location: Berlin, DE

PostPosted: Thu Oct 29, 2009 10:47 am    Post subject: Reply with quote

Updated to version 0.11 (then later to 0.12).

Last changes
  • ini_insertValue() added. It adds value to the end of existing value of specified key.
  • changed so ini_getValue() deletes surrounding quotes also, if preserveSpaces mode is not active.

This change can break existing scripts using this function ini_getValue(). But I decided to implement it, because this is the default behavior of Windows (everyone can change back to preserve mode).

Look at request: http://www.autohotkey.com/forum/viewtopic.php?t=29853

EDIT:
Supplement: ini_getValue() changed.

EDIT AGAIN: The documentation was not included in archive. (fixed)
Back to top
View user's profile Send private message
Tuncay



Joined: 07 Nov 2006
Posts: 893
Location: Berlin, DE

PostPosted: Wed Nov 04, 2009 8:08 pm    Post subject: Update Reply with quote

Updated to version 0.12.1.

Last changes
  • Changed: Now all functions working with special characters in keyname. In example the "@" is now allowed in keyname in a ini.


Exclamation ini_insertKey() function does not work correctly, even though the test cases are success. I am not sure in which case it fails, so be careful. Try to avoid this function until it works (like the other functions).


Last edited by Tuncay on Thu Nov 05, 2009 10:05 pm; edited 1 time in total
Back to top
View user's profile Send private message
alpinestars



Joined: 20 Oct 2009
Posts: 5

PostPosted: Thu Nov 05, 2009 7:30 am    Post subject: Re: Update Reply with quote

Tuncay wrote:
Updated to version 0.12.1.

Last changes
  • Changed: Now all functions working with special characters in keyname. In example the "@" is now allowed in keyname in a ini.


Thanks a lot!

BR
Patrick
Back to top
View user's profile Send private message
alpinestars



Joined: 20 Oct 2009
Posts: 5

PostPosted: Thu Nov 05, 2009 4:31 pm    Post subject: Reply with quote

Hi,

I have a problem ...
If I use
Code:
ini_insertKey(ini, "favorites", fav)

the key/value pairs are added successfully, but there will be a blank line after the section name

Code:
[favorites]

80.80.104.174:2302
81.19.217.189:2302
64.246.3.202:2302


EDIT:
If I enter a new key to a section which contains keys, there is no problem!

How can it be done to enter a key to a section that does not exist before?

Thx,
alpinestars
Back to top
View user's profile Send private message
Tuncay



Joined: 07 Nov 2006
Posts: 893
Location: Berlin, DE

PostPosted: Thu Nov 05, 2009 10:00 pm    Post subject: Reply with quote

Yes that function did sometimes not work correctly, it is noted above post.
Until it works, I am using this technique successfully:

Code:
sectionName := "favorites"
sectionCopy := ini_getSection(ini, sectionName)
keyList := ini_getAllKeyNames(sectionCopy)
keyName := "variable1"
value := "content"
If keyName Not In %keyList%
{
    sectionCopy .= "`n" . keyName . "=" . value
}
ini_replaceSection(ini, sectionName, sectionCopy)


It is simple workaround:
1. Copy the section into a variable.
2. Add a string containing the key or keys into the variable.
3. Replace the section in the ini with the modified section variable.

If you need to check if variable exist, you can try to load all key names of that section. And then any key can be checked if it is in the list. Thats it.
Back to top
View user's profile Send private message
Tuncay



Joined: 07 Nov 2006
Posts: 893
Location: Berlin, DE

PostPosted: Sat Nov 07, 2009 2:29 pm    Post subject: Update Reply with quote

Updated to version 0.13.

Last changes
  • added: New optional parameter "count" in getAllKeyNames and getAllSectionNames added. It counts the items in the list and the count variable will be set.
  • added: New function ini_repair() for building the whole ini from scratch. All comments are lost, unneeded lines and whitespaces are lost.
  • added: New function ini_mergeKeys() for bringing two ini sources into one. There is an updateMode parameter specifieng how existing keys in both sources should be processed.
Back to top
View user's profile Send private message
Tuncay



Joined: 07 Nov 2006
Posts: 893
Location: Berlin, DE

PostPosted: Sat Nov 28, 2009 12:37 am    Post subject: Reply with quote

BUMP Razz its alive

new functions are following
_________________
Download Ahk Standard Library Collection - An archive with stdlib compatible function libraries
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Goto page Previous  1, 2, 3, 4, 5  Next
Page 4 of 5

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group