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).