 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
Tuncay n-l-i mobile Guest
|
Posted: Fri Sep 25, 2009 6:22 pm Post subject: |
|
|
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
|
Posted: Sat Sep 26, 2009 8:14 am Post subject: Update |
|
|
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 |
|
 |
Tuncay
Joined: 07 Nov 2006 Posts: 893 Location: Berlin, DE
|
Posted: Sat Sep 26, 2009 7:04 pm Post subject: Update |
|
|
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 |
|
 |
rootey
Joined: 06 Sep 2009 Posts: 19
|
Posted: Sun Sep 27, 2009 10:55 pm Post subject: |
|
|
| 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 |
|
 |
Tuncay n-l-i mobile Guest
|
Posted: Mon Sep 28, 2009 4:17 am Post subject: |
|
|
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
|
Posted: Thu Oct 22, 2009 11:40 pm Post subject: |
|
|
| 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 |
|
 |
Tuncay
Joined: 07 Nov 2006 Posts: 893 Location: Berlin, DE
|
Posted: Fri Oct 23, 2009 12:25 am Post subject: |
|
|
| There was a fatal error, an outdated code! Have corrected that above. Sorry. |
|
| Back to top |
|
 |
Tuncay
Joined: 07 Nov 2006 Posts: 893 Location: Berlin, DE
|
Posted: Sun Oct 25, 2009 10:18 am Post subject: |
|
|
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 |
|
 |
Tuncay
Joined: 07 Nov 2006 Posts: 893 Location: Berlin, DE
|
Posted: Thu Oct 29, 2009 10:47 am Post subject: |
|
|
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 |
|
 |
Tuncay
Joined: 07 Nov 2006 Posts: 893 Location: Berlin, DE
|
Posted: Wed Nov 04, 2009 8:08 pm Post subject: Update |
|
|
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 Thu Nov 05, 2009 10:05 pm; edited 1 time in total |
|
| Back to top |
|
 |
alpinestars
Joined: 20 Oct 2009 Posts: 5
|
Posted: Thu Nov 05, 2009 7:30 am Post subject: Re: Update |
|
|
| 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 |
|
 |
alpinestars
Joined: 20 Oct 2009 Posts: 5
|
Posted: Thu Nov 05, 2009 4:31 pm Post subject: |
|
|
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 |
|
 |
Tuncay
Joined: 07 Nov 2006 Posts: 893 Location: Berlin, DE
|
Posted: Thu Nov 05, 2009 10:00 pm Post subject: |
|
|
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 |
|
 |
Tuncay
Joined: 07 Nov 2006 Posts: 893 Location: Berlin, DE
|
Posted: Sat Nov 07, 2009 2:29 pm Post subject: Update |
|
|
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 |
|
 |
Tuncay
Joined: 07 Nov 2006 Posts: 893 Location: Berlin, DE
|
Posted: Sat Nov 28, 2009 12:37 am Post subject: |
|
|
BUMP its alive
new functions are following _________________ Download Ahk Standard Library Collection - An archive with stdlib compatible function libraries |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|