AutoHotkey Community

It is currently May 26th, 2012, 9:57 pm

All times are UTC [ DST ]




Post new topic Reply to topic  [ 129 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6, 7 ... 9  Next
Author Message
 Post subject:
PostPosted: September 25th, 2009, 6:22 pm 
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.


Report this post
Top
  
Reply with quote  
 Post subject: Update
PostPosted: September 26th, 2009, 8:14 am 
Offline

Joined: November 7th, 2006, 9:47 pm
Posts: 1934
Location: Germany
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.


Report this post
Top
 Profile  
Reply with quote  
 Post subject: Update
PostPosted: September 26th, 2009, 7:04 pm 
Offline

Joined: November 7th, 2006, 9:47 pm
Posts: 1934
Location: Germany
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.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 27th, 2009, 10:55 pm 
Offline

Joined: September 6th, 2009, 4:22 pm
Posts: 20
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?


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 28th, 2009, 4:17 am 
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.


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: October 22nd, 2009, 11:40 pm 
Offline

Joined: November 7th, 2006, 9:47 pm
Posts: 1934
Location: Germany
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 October 23rd, 2009, 2:04 am, edited 3 times in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 23rd, 2009, 12:25 am 
Offline

Joined: November 7th, 2006, 9:47 pm
Posts: 1934
Location: Germany
There was a fatal error, an outdated code! Have corrected that above. Sorry.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 25th, 2009, 10:18 am 
Offline

Joined: November 7th, 2006, 9:47 pm
Posts: 1934
Location: Germany
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 November 8th, 2009, 11:13 am, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 29th, 2009, 10:47 am 
Offline

Joined: November 7th, 2006, 9:47 pm
Posts: 1934
Location: Germany
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)


Report this post
Top
 Profile  
Reply with quote  
 Post subject: Update
PostPosted: November 4th, 2009, 8:08 pm 
Offline

Joined: November 7th, 2006, 9:47 pm
Posts: 1934
Location: Germany
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.


:!: 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 November 5th, 2009, 10:05 pm, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject: Re: Update
PostPosted: November 5th, 2009, 7:30 am 
Offline

Joined: October 20th, 2009, 6:36 am
Posts: 10
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


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 5th, 2009, 4:31 pm 
Offline

Joined: October 20th, 2009, 6:36 am
Posts: 10
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


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 5th, 2009, 10:00 pm 
Offline

Joined: November 7th, 2006, 9:47 pm
Posts: 1934
Location: Germany
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.


Report this post
Top
 Profile  
Reply with quote  
 Post subject: Update
PostPosted: November 7th, 2009, 2:29 pm 
Offline

Joined: November 7th, 2006, 9:47 pm
Posts: 1934
Location: Germany
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.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 28th, 2009, 12:37 am 
Offline

Joined: November 7th, 2006, 9:47 pm
Posts: 1934
Location: Germany
BUMP :P its alive

new functions are following

_________________
{1:"ahkstdlib", 2:"my libs", 3:"my apps", 4:"my license"}
--> Don't feed the troll! <--


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 129 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6, 7 ... 9  Next

All times are UTC [ DST ]


Who is online

Users browsing this forum: Apollo, bekihito, Bing [Bot], JamixZol and 6 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group