Sign in to follow this  
Followers 0

Ini+Ex Functions - exceed 32kb limit

76 posts in this topic

Posted (edited)

Sometimes I see posts where people are complaining about the 32kb limit on IniReadSetion. I never did understand why you would have a section that was 32kb's...

One of my string parsing functions reads and writes to an ini, well for the first time ever, the section was 34.x kbs and I couldn't understand for the longest time (about 10 trials of re-writing different things) why I wasn't getting all the values... Just bits and pieces it seemed. I never check for anything other than if IniReadSection is an array... But then I thought to look at the size... and their lay the problem.

I wrote a really slow IniReadSection for someone else 2 or so months ago that had this problem, and to be honest, it was 2000 times slower than the current released one that Valik wrote...

This didn't suite my needs either, as every second counts :P ... So I wrote another one, This one isn't near as fast as Valiks for obvious reasons, but it did the trick 20x's faster than the last one I wrote.

Hope it helps someone...

Update: - 2011/05/18 - SmOke_N

Changed: _IniReadSectionEx() - Changed all existing functions; hopefully more proficient; thanks llewxam

Old Code:

Func _IniDeleteEx($hFile, $vSection, $vKey = '')
    Local $iSize = FileGetSize($hFile) / 1024
    If $iSize <= 31 Then Return IniDelete($hFile, $vSection, $vKey)
    Local $sString = FileRead($hFile)
    Local $sFRead = @CRLF & $sString & @CRLF & '['
    $vSection = StringStripWS($vSection, 7)
    Local $aData = StringRegExp($sFRead, '(?s)(?i)\n\s*\[\s*' & $vSection & '\s*\]\s*\r\n(.*?)\[', 3)
    If IsArray($aData) = 0 Then Return SetError(1, 0, 0)
    $aData[0] = StringRegExpReplace($aData[0], '(\r\n)+$', '')
    If $vKey = '' Then
        $sString = StringRegExpReplace($sString, '(?s)(?i)(^|\n)\s*\[\s*' & $vSection & '\s*\]\s*(\r\n)+' & StringReplace($aData[0], '\', '\\'), @LF & @CRLF)
    Else
        $sString = StringRegExpReplace($aData[0], '(?s)(?i)\n\s*' & $vKey & '\s*=.*?(?m:\r\n|$)', @LF)
    EndIf
    $sString = StringRegExpReplace($sString, '(^(\r\n)+)+|^\r+|^\n+|(\r\n)+$|\[$', '')
    $sString = StringRegExpReplace($sString, '(\r\n){3}', @CRLF)
    $sString = StringRegExpReplace($sString, '(^(\r\n)+)+', '')
    FileClose(FileOpen($hFile, 2))
    Return FileWrite($hFile, $sString)
EndFunc

Func _IniWriteEx($hFile, $vSection, $vKey, $vValue)
    If FileExists($hFile) = 0 Then FileClose(FileOpen($hFile, 2))
    Local $iSize = FileGetSize($hFile) / 1024
    If $iSize <= 31 Then Return IniWrite($hFile, $vSection, $vKey, $vValue)
    Local $sString = FileRead($hFile)
    Local $sFRead = @CRLF & $sString & @CRLF & '['
    $vSection = StringStripWS($vSection, 7)
    Local $aData = StringRegExp($sFRead, '(?s)(?i)\n\s*\[\s*' & $vSection & '\s*\]\s*\r\n(.*?)\[', 3)
    If IsArray($aData) = 0 Then
        If StringRegExp($sString, '(?s)\r\n$') = 0 Then
            $sString &= @CRLF & '[' & $vSection & ']' & @CRLF & $vKey & '=' & $vValue
        Else
            $sString &= '[' & $vSection & ']' & @CRLF & $vKey & '=' & $vValue
        EndIf
        FileClose(FileOpen($hFile, 2))
        Return FileWrite($hFile, $sString)
    EndIf
    $aData[0] = StringRegExpReplace($aData[0], '(\r\n)+$', '')
    If StringRegExp(@LF & $aData[0] & @CRLF, '(?s)(?i)\n\s*' & $vKey & '\s*=') Then
        Local $sTempReplace = StringRegExpReplace(@LF & $aData[0] & @CR, _
            '(?s)(?i)\n\s*' & $vKey & '=.*?\r', @LF & $vKey & '=' & StringReplace($vValue, '\', '\\') & @CR)
        $aData[0] = StringRegExpReplace($sTempReplace, '^\r\n|^\s*\n|^\s*\r|\r$', '')
    Else
        $aData[0] = StringReplace($aData[0] & @CRLF & $vKey & '=' & $vValue, '\', '\\')
    EndIf
    $sString = StringRegExpReplace(@LF & $sString & _
        '[', '(?s)(?i)(^|\n)\s*\[\s*' & $vSection & '\s*\]\s*\r\n.*?\s*\[', @LF & @CRLF & '\[' & $vSection & '\]' & @CRLF & $aData[0] & @CRLF & @CRLF & '\[')
    $sString = StringRegExpReplace($sString, '(^(\r\n)+)+|^\r+|^\n+|\[$|(\r\n)+$', '')
    FileClose(FileOpen($hFile, 2))
    Return FileWrite($hFile, $sString)
EndFunc

Func _IniReadSectionNamesEx($hFile)
    Local $iSize = FileGetSize($hFile) / 1024
    If $iSize <= 31 Then
        Local $aNameRead = IniReadSectionNames($hFile)
        If @error Then Return SetError(@error, 0, '')
        Return $aNameRead
    EndIf
    Local $aSectionNames = StringRegExp(@CRLF & FileRead($hFile) & @CRLF, '(?s)\n\s*\[(.*?)\]s*\r', 3)
    If IsArray($aSectionNames) = 0 Then Return SetError(1, 0, 0)
    Local $nUbound = UBound($aSectionNames)
    Local $aNameReturn[$nUbound + 1]
    $aNameReturn[0] = $nUbound
    For $iCC = 0 To $nUBound - 1
        $aNameReturn[$iCC + 1] = $aSectionNames[$iCC]
    Next
    Return $aNameReturn
EndFunc

Func _IniReadSectionEx($hFile, $vSection)
    Local $iSize = FileGetSize($hFile) / 1024
    If $iSize <= 31 Then 
        Local $aSecRead = IniReadSection($hFile, $vSection)
        If @error Then Return SetError(@error, 0, '')
        Return $aSecRead
    EndIf
    Local $sFRead = @CRLF & FileRead($hFile) & @CRLF & '['
    $vSection = StringStripWS($vSection, 7)
    Local $aData = StringRegExp($sFRead, '(?s)(?i)\n\s*\[\s*' & $vSection & '\s*\]\s*\r\n(.*?)\[', 3)
    If IsArray($aData) = 0 Then Return SetError(1, 0, 0)
    Local $aKey = StringRegExp(@LF & $aData[0], '\n\s*(.*?)\s*=', 3)
    Local $aValue = StringRegExp(@LF & $aData[0], '\n\s*.*?\s*=(.*?)\r', 3)
    Local $nUbound = UBound($aKey)
    Local $aSection[$nUBound +1][2]
    $aSection[0][0] = $nUBound
    For $iCC = 0 To $nUBound - 1
        $aSection[$iCC + 1][0] = $aKey[$iCC]
        $aSection[$iCC + 1][1] = $aValue[$iCC]
    Next
    Return $aSection
EndFunc

Func _IniReadEx($hFile, $vSection, $vKey, $vDefault = -1)
    If $vDefault = -1 Or $vDefault = Default Then $vDefault = ''
    Local $iSize = FileGetSize($hFile) / 1024
    If $iSize <= 31 Then Return IniRead($hFile, $vSection, $vKey, $vDefault)
    Local $sFRead = @CRLF & FileRead($hFile) & @CRLF & '['
    $vSection = StringStripWS($vSection, 7)
    Local $aData = StringRegExp($sFRead, '(?s)(?i)\n\s*\[\s*' & $vSection & '\s*\]\s*\r\n(.*?)\[', 3)
    If IsArray($aData) = 0 Then Return SetError(1, 0, 0)
    Local $aRead = StringRegExp(@LF & $aData[0], '(?s)(?i)\n\s*' & $vKey & '\s*=(.*?)\r', 1)
    If IsArray($aRead) = 0 Then Return SetError(2, 0, 0)
    Return $aRead[0]
EndFunc

; New code with changes, be sure to test if you have doubts. I only moderately tested.

; The IniRead* functions now accept a passed string ( like from a FileRead() or ClipPut() etc... )

; change added - SmOke_N - 2011/05/18
Func _IniDeleteEx($s_file, $s_section, $s_key = "")

    If Not FileExists($s_file) Then Return SetError(-1, 0, 0)

	Local $i_size = FileGetSize($s_file)

	Local $i_delete = 0
	If $i_size < 31 Then
		$i_delete = IniDelete($s_file, $s_section, $s_key)
		Return SetError(@error, 0, $i_delete)
	EndIf

	; is file read only
	If StringInStr(FileGetAttrib($s_file), "R") Then
		Return SetError(-2, 0, 0)
	EndIf

	Local $s_fread = FileRead($s_file)

	; find out if section exist, if so get data
	Local $s_secpatt = "(?si)(?:^|\v)(\h*\[\h*\Q"
	$s_secpatt &= $s_section
	$s_secpatt &= "\E\h*\].*?)(?:\z|\v\v?\[)"
	Local $a_data = StringRegExp($s_fread, $s_secpatt, 1)
	Local $f_dataexists = Not @error

	If Not $f_dataexists Then Return 1

	Local $h_open, $i_write = 0
	If $s_key = "" Then
		If $s_fread = $a_data[0] Then
			$h_open = FileOpen($s_file, 2)
			If $h_open = -1 Then Return SetError(-3, 0, 0)
			FileClose($h_open)
			Return 1
		EndIf
		$s_fread = StringReplace($s_fread, $a_data[0], "", 1, 1)
		$h_open = FileOpen($s_file, 2)
		If $h_open = -1 Then Return SetError(-3, 0, 0)
		$i_write = FileWrite($h_open, $s_fread)
		FileClose($h_open)
		If Not $i_write Then Return SetError(-4, 0, 0)
		Return 1
	EndIf

    ; since we stop at cr/lf then lets just split
    Local $a_lines
    If StringInStr($a_data[0], @CRLF, 1, 1) Then
        $a_lines = StringSplit(StringStripCR($a_data[0]), @LF)
    ElseIf StringInStr($a_data[0], @LF, 1, 1) Then
        $a_lines = StringSplit($a_data[0], @LF)
    Else
        $a_lines = StringSplit($a_data[0], @CR)
    EndIf

    Local $a_key, $f_found = False, $s_write
    Local $s_keypatt = "\h*(?!;|#)(.*?)\h*="

	For $iline = 1 To $a_lines[0]

		If $a_lines[$iline] = "" Then ContinueLoop

        $a_key = StringRegExp($a_lines[$iline], $s_keypatt, 1)
        If @error Or $s_key <> $a_key[0] Then
			$s_write &= $a_lines[$iline] & @CRLF
			ContinueLoop
		EndIf

		$f_found = True
	Next

	If Not $f_found Then Return 1

	$s_fread = StringReplace($s_fread, $a_data[0], $s_write)

	Local $h_open = FileOpen($s_file, 2)
	$i_write = FileWrite($h_open, $s_fread)
	FileClose($h_open)

	Return $i_write
EndFunc

; change added - SmOke_N - 2011/05/18
Func _IniWriteEx($s_file, $s_section, $s_key, $s_value)

    If Not $s_file Then Return SetError(-1, 0, 0)

	Local $f_exists = FileExists($s_file)
	If Not $f_exists Then
		FileClose(FileOpen($s_file, 2))
	EndIf

	Local $i_write = 0
	Local $i_size = FileGetSize($s_file) / 1024

	; if the file is smaller than 32kb, no need for regex
	If $i_size <= 31 Then
		$i_write = IniWrite($s_file, $s_section, $s_key, $s_value)
		Return SetError(@error, 0, $i_write)
	EndIf

	; is file read only
	If $f_exists Then
		If StringInStr(FileGetAttrib($s_file), "R") Then
			Return SetError(-2, 0, 0)
		EndIf
	EndIf

    Local $s_fread = FileRead($s_file)
	Local $s_write = ""

	; find out if section exist, if so get data
	Local $s_secpatt = "(?si)(?:^|\v)(\h*\[\h*\Q"
	$s_secpatt &= $s_section
	$s_secpatt &= "\E\h*\].*?)(?:\z|\v\v?\[)"
	Local $a_data = StringRegExp($s_fread, $s_secpatt, 1)
	Local $f_dataexists = Not @error

	Local $s_write = ""

	; if section doesn't exist; append
	If Not $f_dataexists Then
		If $s_fread Then
			If StringRight($s_fread, 2) <> @CRLF Then
				$s_write &= @CRLF
			EndIf
		EndIf

		$s_write &= "[" & $s_section & "]" & @CRLF
		$s_write &= $s_key & "=" & $s_value & @CRLF

		Return FileWrite($s_file, $s_write)
	EndIf

    ; since we stop at cr/lf then lets just split
    Local $a_lines
    If StringInStr($a_data[0], @CRLF, 1, 1) Then
        $a_lines = StringSplit(StringStripCR($a_data[0]), @LF)
    ElseIf StringInStr($a_data[0], @LF, 1, 1) Then
        $a_lines = StringSplit($a_data[0], @LF)
    Else
        $a_lines = StringSplit($a_data[0], @CR)
    EndIf

    Local $a_key, $f_changed = False
    Local $s_keypatt = "\h*(?!;|#)(.*?)\h*="

	For $iline = 1 To $a_lines[0]

		If $a_lines[$iline] = "" Then ContinueLoop

        $a_key = StringRegExp($a_lines[$iline], $s_keypatt, 1)
        If @error Or $s_key <> $a_key[0] Then
			$s_write &= $a_lines[$iline] & @CRLF
			ContinueLoop
		EndIf

		$f_changed = True
		$s_write &= $s_key & "=" & $s_value & @CRLF

	Next

	If Not $f_changed Then
		If StringRight($s_fread, 2) <> @CRLF Then
			$s_write &= @CRLF
		EndIf
		$s_write &= $s_key & "=" & $s_value & @CRLF
	EndIf

	$s_fread = StringReplace($s_fread, $a_data[0], $s_write)

	Local $h_open = FileOpen($s_file, 2)
	$i_write = FileWrite($h_open, $s_fread)
	FileClose($h_open)

	Return $i_write
EndFunc

; change added - SmOke_N - 2011/05/18
Func _IniReadSectionNamesEx($v_file)

    If Not $v_file Then Return SetError(-1, 0, 0)

    Local $f_exists = FileExists($v_file)

    Local $i_size, $a_secs

    If $f_exists Then
        $i_size = FileGetSize($v_file) / 1024

        ; if the file is smaller than 32kb, no need for regex
        If $i_size <= 31 Then
            $a_secs = IniReadSectionNames($v_file)
            If @error Then Return SetError(@error, 0, 0)
            If Not IsArray($a_secs) Then Return SetError(-2, 0, 0)
            Return $a_secs
        EndIf
    EndIf

    Local $s_fread
    If Not $f_exists Then
        ; string of data was passed
        $s_fread = $v_file
    Else
        $s_fread = FileRead($v_file)
    EndIf

	Local $s_secpatt = "(?m)(?:^|\v)\h*\[\h*(.*?)\h*\]"
	Local $a_secsre = StringRegExp($s_fread, $s_secpatt, 3)
	If @error Then Return SetError(-3, 0, 0)

	Local $i_ub = UBound($a_secsre)
	Local $a_secret[$i_ub + 1] = [$i_ub]

	For $isec = 0 To $i_ub - 1
		$a_secret[$isec + 1] = $a_secsre[$isec]
	Next

	Return $a_secret
EndFunc

; change added - SmOke_N - 2011/05/17
Func _IniReadSectionEx($v_file, $s_section)

    If Not $v_file Then Return SetError(-1, 0, 0)

    Local $f_exists = FileExists($v_file)

    Local $i_size, $a_secread

    If $f_exists Then
        $i_size = FileGetSize($v_file) / 1024

        ; if the file is smaller than 32kb, no need for regex
        If $i_size <= 31 Then
            $a_secread = IniReadSection($v_file, $s_section)
            If @error Then Return SetError(@error, 0, 0)
            If Not IsArray($a_secread) Then Return SetError(-2, 0, 0)
            Return $a_secread
        EndIf
    EndIf

    Local $s_fread
    If Not $f_exists Then
        ; string of data was passed
        $s_fread = $v_file
    Else
        $s_fread = FileRead($v_file)
    EndIf

    ; data between sections or till end of file
    Local $s_datapatt = "(?is)(?:^|\v)(?!;|#)\h*\[\h*\Q"
	$s_datapatt &= $s_section
	$s_datapatt &= "\E\h*\]\h*\v+(.*?)(?:\z|\v\h*\[)"
    Local $a_data = StringRegExp($s_fread, $s_datapatt, 1)
    If @error Then Return SetError(-3, 0, 0)

    ; sanity check for inf people
    If Not StringInStr($a_data[0], "=", 1, 1) Then
        Return SetError(-4, 0, 0)
    EndIf

    ; since we stop at cr/lf then lets just split
    Local $a_lines
    If StringInStr($a_data[0], @CRLF, 1, 1) Then
        $a_lines = StringSplit(StringStripCR($a_data[0]), @LF)
    ElseIf StringInStr($a_data[0], @LF, 1, 1) Then
        $a_lines = StringSplit($a_data[0], @LF)
    Else
        $a_lines = StringSplit($a_data[0], @CR)
    EndIf

    ; prevent capturing commented keys
    Local $a_key, $a_value
    Local $s_keypatt = "\h*(?!;|#)(.*?)\h*="
    Local $s_valpatt = "\h*=\h*(.*)"
    Local $a_secs[$a_lines[0] + 1][2], $i_add = 0

    For $iline = 1 To $a_lines[0]

        $a_key = StringRegExp($a_lines[$iline], $s_keypatt, 1)
        If @error Then ContinueLoop

        $s_valpatt = "\h*=\h*(.*)"

        $a_value = StringRegExp($a_lines[$iline], $s_valpatt, 1)
        If @error Then ContinueLoop

        If StringLeft($a_key[0], 1) = '"' And StringRight($a_key[0], 1) = '"' Then
            $a_key[0] = StringTrimLeft(StringTrimRight($a_key[0], 1), 1)
        EndIf
        If StringLeft($a_value[0], 1) = '"' And StringRight($a_value[0], 1) = '"' Then
            $a_value[0] = StringTrimLeft(StringTrimRight($a_value[0], 1), 1)
        EndIf

        $i_add += 1
        $a_secs[$i_add][0] = $a_key[0]
        $a_secs[$i_add][1] = $a_value[0]
    Next

    If Not $i_add Then Return SetError(-5, 0, 0)

    ; cleanup return array
    ReDim $a_secs[$i_add + 1][2]
    $a_secs[0][0] = $i_add

    Return $a_secs
EndFunc

; change added - SmOke_N - 2011/05/18
Func _IniReadEx($v_file, $s_section, $s_key, $v_default = -1)

    If Not $v_file Then Return SetError(-1, 0, 0)

	If $v_default = -1 Or $v_default = Default Then
		$v_default = ""
	EndIf

	Local $f_exists = FileExists($v_file)

    Local $i_size, $s_read

    If $f_exists Then
        $i_size = FileGetSize($v_file) / 1024

        ; if the file is smaller than 32kb, no need for regex
        If $i_size <= 31 Then
            $s_read = IniRead($v_file, $s_section, $s_key, $v_default)
            Return $s_read
        EndIf
    EndIf

    Local $s_fread
    If Not $f_exists Then
        ; string of data was passed
        $s_fread = $v_file
    Else
        $s_fread = FileRead($v_file)
    EndIf

    ; data between sections or till end of file
    Local $s_datapatt = "(?is)(?:^|\v)(?!;|#)\h*\[\h*\Q"
	$s_datapatt &= $s_section
	$s_datapatt &= "\E\h*\]\h*\v+(.*?)(?:\z|\v\h*\[)"
    Local $a_data = StringRegExp($s_fread, $s_datapatt, 1)
    If @error Then Return SetError(-2, 0, 0)

    ; sanity check for inf people
    If Not StringInStr($a_data[0], "=", 1, 1) Then
        Return SetError(-3, 0, 0)
    EndIf

    ; since we stop at cr/lf then lets just split
    Local $a_lines
    If StringInStr($a_data[0], @CRLF, 1, 1) Then
        $a_lines = StringSplit(StringStripCR($a_data[0]), @LF)
    ElseIf StringInStr($a_data[0], @LF, 1, 1) Then
        $a_lines = StringSplit($a_data[0], @LF)
    Else
        $a_lines = StringSplit($a_data[0], @CR)
    EndIf

    ; prevent capturing commented keys
    Local $a_key, $a_value, $s_ret
    Local $s_keypatt = "\h*(?!;|#)(.*?)\h*="
    Local $s_valpatt = "\h*=\h*(.*)"

    For $iline = 1 To $a_lines[0]

        $a_key = StringRegExp($a_lines[$iline], $s_keypatt, 1)
        If @error Then ContinueLoop

        If StringLeft($a_key[0], 1) = '"' And StringRight($a_key[0], 1) = '"' Then
            $a_key[0] = StringTrimLeft(StringTrimRight($a_key[0], 1), 1)
        EndIf

		If $a_key[0] <> $s_key Then ContinueLoop

        $s_valpatt = "\h*=\h*(.*)"

        $a_value = StringRegExp($a_lines[$iline], $s_valpatt, 1)
        If @error Then ContinueLoop

        If StringLeft($a_value[0], 1) = '"' And StringRight($a_value[0], 1) = '"' Then
            $a_value[0] = StringTrimLeft(StringTrimRight($a_value[0], 1), 1)
        EndIf

		$s_ret = $a_value[0]
		ExitLoop
    Next

	If Not $s_ret Then Return $v_default

	Return $s_ret
EndFunc

If you're interested in Ini encryption, you might take a look at this thread:

I might integrate these with the IniCrypt.au3 at some future time if I don't get bug feedback from the above.

Edited by SmOke_N

Share this post


Link to post
Share on other sites



Posted

Good work, it works very well :P

I made my own version of the ini functions as well some time ago, for the exact same reason.

Share this post


Link to post
Share on other sites

Posted (edited)

While you were playing in Chat, btw I saw that post :P

I was playing around with my version of the _Ini functions

Might need some fine tuning, but here ya go (formats the same as the built in for params)

Edit: Fixed the _IniWrite so that if the ini file doesn't exist then it is created

Edit: Fixed _IniReadSection value may contain "="

Edit: Fixed _IniWrite, if adding new key and last line in section is CRLF the CRLF line is remove

Edit: Fixed _IniReadSection return error when no "=" found

Func _IniWrite($FileName, $Section, $KeyName, $Value)
	Local $INIContents, $PosSection, $PosEndSection
	If FileExists($FileName) Then
		$INIContents = FileRead($FileName)
		If @error Then Return SetError(@error, @error, @error)

		;Find section
		$PosSection = StringInStr($INIContents, "[" & $Section & "]")
		If $PosSection > 0 Then
			;Section exists. Find end of section
			$PosEndSection = StringInStr(StringMid($INIContents, $PosSection + 1), "[") + ($PosSection - 2)
			;?Is this last section?
			If $PosEndSection = 0 Then $PosEndSection = StringLen($INIContents) + 1

			;Separate section contents
			Local $OldsContents, $NewsContents, $Line
			Local $sKeyName, $Found = False
			$OldsContents = StringMid($INIContents, $PosSection, $PosEndSection - $PosSection)
			$OldsContents = StringSplit($OldsContents, @CRLF, 1)
			;Temp variable To find a Key
			$sKeyName = StringLower($KeyName & "=")

			;Enumerate section lines
			For $x = 1 To $OldsContents[0]
				If StringLower(StringMid($OldsContents[$x], 1, StringLen($sKeyName))) = $sKeyName Then
					$OldsContents[$x] = $KeyName & "=" & $Value
					$Found = True
				EndIf
				If StringLen($OldsContents[$x]) Then $NewsContents = $NewsContents & $OldsContents[$x] & @CRLF
			Next
			If $Found Then
				;remove last CRLF - the CRLF is at PosEndSection
				If StringRight($NewsContents, 2) = @CRLF Then $NewsContents = StringMid($NewsContents, 1, StringLen($NewsContents) - 2)
			Else
				;key Not found - add it at the end of section
				$NewsContents = $NewsContents & $KeyName & "=" & $Value
			EndIf

			;Combine pre-section, new section And post-section data.
			$INIContents = StringMid($INIContents, 1, $PosSection - 1) & $NewsContents & StringMid($INIContents, $PosEndSection)
		Else
			;Section Not found. Add section data at the end of file contents.
			If StringRight($INIContents, 2) <> @CRLF And StringLen($INIContents) > 0 Then $INIContents = $INIContents & @CRLF
			$INIContents = $INIContents & "[" & $Section & "]" & @LF & $KeyName & "=" & $Value
		EndIf	;if PosSection>0 Then
	Else
		$INIContents = "[" & $Section & "]" & @CRLF & $KeyName & "=" & $Value & @CRLF
	EndIf
	$file = FileOpen($FileName, 2)
	FileWrite($FileName, $INIContents)
	FileClose($file)
EndFunc   ;==>_IniWrite

Func _IniRead($FileName, $Section, $KeyName, $Default)
	Local $INIContents, $PosSection, $PosEndSection, $sContents, $Value, $Found

	$INIContents = FileRead($FileName)
	If @error Then Return SetError(@error, @error, @error)

	;Find section
	$PosSection = StringInStr($INIContents, "[" & $Section & "]")
	If $PosSection > 0 Then
		;Section exists. Find end of section
		$PosEndSection = StringInStr(StringMid($INIContents, $PosSection + 1), "[") + ($PosSection - 2)
		;?Is this last section?
		If $PosEndSection = 0 Then $PosEndSection = StringLen($INIContents) + 1

		;Separate section contents
		$sContents = StringMid($INIContents, $PosSection, $PosEndSection - $PosSection)
		Local $Found = False
		If StringInStr($sContents, $KeyName & "=") > 0 Then
			$Found = True
			;Separate value of a key.
			$Value = _SeparateField($sContents, $KeyName & "=", @CRLF)
		EndIf
	EndIf
	If Not $Found Then $Value = $Default
	Return $Value
EndFunc   ;==>_IniRead

Func _IniReadSection($FileName, $Section)
	Local $INIContents, $PosSection, $PosEndSection, $sContents, $Value, $Found

	$INIContents = FileRead($FileName)
	If @error Then Return SetError(@error, @error, @error)

	;Find section
	$PosSection = StringInStr($INIContents, "[" & $Section & "]")
	If $PosSection > 0 Then
		;Section exists. Find end of section
		$PosEndSection = StringInStr(StringMid($INIContents, $PosSection + 1), "[") + ($PosSection - 2)
		;?Is this last section?
		If $PosEndSection = 0 Then $PosEndSection = StringLen($INIContents) + 1
		Local $INISection = StringSplit(StringMid($INIContents, $PosSection, $PosEndSection), @CRLF)
		Local $a_Section[1][2]
		For $x = 2 To UBound($INISection) - 1
			$INISection[$x] = StringReplace($INISection[$x], @CRLF, "")
			If StringLen($INISection[$x]) Then
				ReDim $a_Section[UBound($a_Section) + 1][2]
				$a_Section[0][0] += 1
				Local $PosSep = StringInStr($INISection[$x], "=")
				If Not $PosSep Then Return SetError(-1,-1,-1)
				$a_Section[UBound($a_Section) - 1][0] = StringMid($INISection[$x], 1, $PosSep - 1)
				$a_Section[UBound($a_Section) - 1][1] = StringMid($INISection[$x], $PosSep + 1)
			EndIf
		Next
		Return $a_Section
	EndIf
	Return SetError(-1, -1, "")
EndFunc   ;==>_IniReadSection

Func _IniReadSectionNames($FileName)
	Local $INIContents, $PosSection, $PosEndSection, $sContents, $Value, $Found

	$INIContents = FileRead($FileName)
	If @error Then Return SetError(@error, @error, @error)
	$INIContents = StringSplit($INIContents, @CRLF)
	Local $a_SectionNames[1]
	For $x = 1 To $INIContents[0]
		If StringLeft($INIContents[$x], 1) = "[" And StringRight($INIContents[$x], 1) = "]" Then
			ReDim $a_SectionNames[UBound($a_SectionNames) + 1]
			$a_SectionNames[0] += 1
			$a_SectionNames[UBound($a_SectionNames) - 1] = StringMid($INIContents[$x], 2, StringLen($INIContents[$x]) - 2)
		EndIf
	Next
	Return $a_SectionNames
EndFunc   ;==>_IniReadSectionNames

Func _IniDelete($FileName, $Section, $KeyName = "")
	Local $INIContents, $PosSection, $PosEndSection
	
	$INIContents = FileRead($FileName)
	If @error Then Return SetError(@error, @error, @error)

	;Find section
	$PosSection = StringInStr($INIContents, "[" & $Section & "]")
	If $PosSection > 0 Then
		;Section exists. Find end of section
		$PosEndSection = StringInStr(StringMid($INIContents, $PosSection + 1), "[") + ($PosSection - 2)
		;?Is this last section?
		If $PosEndSection = 0 Then $PosEndSection = StringLen($INIContents) + 1

		;Separate section contents
		Local $OldsContents, $NewsContents, $Line
		Local $sKeyName, $Found = False
		$OldsContents = StringMid($INIContents, $PosSection, $PosEndSection - $PosSection)
		If Not StringLen($KeyName) Then
			$INIContents = StringReplace($INIContents, $OldsContents, "")
			_WriteStringAsIni($FileName, $INIContents)
			Return 1
		EndIf

		;Temp variable To find a Key
		$sKeyName = StringLower($KeyName & "=")
		$OldsContents = StringSplit($OldsContents, @CRLF, 1)
		Local $Found = False
		;Enumerate section lines
		For $x = 1 To $OldsContents[0]
			If StringLower(StringMid($OldsContents[$x], 1, StringLen($sKeyName))) = $sKeyName Then
				$Found = True
				ContinueLoop
			EndIf
			$NewsContents = $NewsContents & $OldsContents[$x] & @CRLF
		Next
		If $Found Then
			;remove last CRLF - the CRLF is at PosEndSection
			If StringRight($NewsContents, 2) = @CRLF Then $NewsContents = StringMid($NewsContents, 1, StringLen($NewsContents) - 2)
		EndIf

		;Combine pre-section, new section And post-section data.
		$INIContents = StringMid($INIContents, 1, $PosSection - 1) & $NewsContents & StringMid($INIContents, $PosEndSection)
		_WriteStringAsIni($FileName, $INIContents)
		Return 1
	EndIf
	Return 0
EndFunc   ;==>_IniDelete

;Separates one field between sStart And sEnd
Func _SeparateField($sFrom, $sStart, $sEnd)
	Local $PosB = StringInStr($sFrom, $sStart)
	If $PosB > 0 Then
		$PosB = $PosB + StringLen($sStart)
		Local $PosE = (StringInStr(StringMid($sFrom, $PosB), $sEnd))
		If $PosE Then $PosE += $PosB
		If $PosE = 0 Then $PosE = StringInStr($sFrom, @CRLF)
		If $PosE = 0 Then $PosE = StringLen($sFrom) + 1
		Return StringMid($sFrom, $PosB, $PosE - $PosB)
	EndIf

EndFunc   ;==>_SeparateField

Func _WriteStringAsIni($FileName, $INIContents)
	$file = FileOpen($FileName, 2)
	FileWrite($FileName, $INIContents)
	FileClose($file)
EndFunc   ;==>_WriteStringAsIni
Edited by gafrost

Share this post


Link to post
Share on other sites

Posted

Nice work... Quick question on your IniReadSection... what happens when the value on your section has an "=" in it, my original one I did right before this one (not the one that was 2000 x's slower) was real similar to what you did, but when I tested it, I had some value strings that had "=" in it?

Also... IniWrite Creates the file now if the file doesn't exist, on the newer releases for me...(noticed this the other day) (XP-Pro SP2)...

Share this post


Link to post
Share on other sites

Posted

Nice work... Quick question on your IniReadSection... what happens when the value on your section has an "=" in it, my original one I did right before this one (not the one that was 2000 x's slower) was real similar to what you did, but when I tested it, I had some value strings that had "=" in it?

Also... IniWrite Creates the file now if the file doesn't exist, on the newer releases for me...(noticed this the other day) (XP-Pro SP2)...

Fixed

Was alread Fixed before you replied.

Gary

Share this post


Link to post
Share on other sites

Posted

Also... IniWrite Creates the file now if the file doesn't exist, on the newer releases for me...(noticed this the other day) (XP-Pro SP2)...

The file creation has always existed, AFAIK.

Share this post


Link to post
Share on other sites

Posted

The file creation has always existed, AFAIK.

I haven't used the functions much... Just recently.

Fixed

Was alread Fixed before you replied.

Gary

:P

Share this post


Link to post
Share on other sites

Posted

While you were playing in Chat, btw I saw that post ;)

I was playing around with my version of the _Ini functions

Might need some fine tuning, but here ya go (formats the same as the built in for params)

Edit: Fixed the _IniWrite so that if the ini file doesn't exist then it is created

Edit: Fixed _IniReadSection value may contain "="

Edit: Fixed _IniWrite, if adding new key and last line in section is CRLF the CRLF line is remove

Edit: Fixed _IniReadSection return error when no "=" found

I'm trying to make a _IniWriteLine($FileName, $Section, $TextLine, $Append_Or_Prepend)

Can you help me ?

Share this post


Link to post
Share on other sites

Posted

I'm trying to make a _IniWriteLine($FileName, $Section, $TextLine, $Append_Or_Prepend)

Can you help me ?

Who are you asking for help?

What are you trying to do (in detail)?

Share this post


Link to post
Share on other sites

Posted

Who are you asking for help?

What are you trying to do (in detail)?

I'm working in project WinBuilder (www.boot-land.net/)

I use AutoIt for making script for WinBuilder (MakeScript.script)

There is allready a command IniWriteTextLine in winBuilder but i need to to use it in AutoIt

The script in Winbuilder is like a Ini file with section

So i need a command for writing line of code in section like IniWrite

Share this post


Link to post
Share on other sites

Posted (edited)

I'm working in project WinBuilder (www.boot-land.net/)

I use AutoIt for making script for WinBuilder (MakeScript.script)

There is allready a command IniWriteTextLine in winBuilder but i need to to use it in AutoIt

The script in Winbuilder is like a Ini file with section

So i need a command for writing line of code in section like IniWrite

turtle

Edit...

That explains nothing... if it's help you want, I would suggest post what you have been working on, in the support forum. If it's someone writing it for you, I'd suggest you start working on something, and if you get stuck post for help in the search forum. If it's something different you want, I suggest you explain yourself better, and post for help in the support forum. This is the scripts and scraps forum, not a can you make me forum.

Thanks for hijacking my thread ;)

Edited by SmOke_N

Share this post


Link to post
Share on other sites

Posted

Return of the turtle(s), I see.

Share this post


Link to post
Share on other sites

Posted

I tried your script, but when I pasted in notepad I can see character (1) between ab and cd. Run the script below and look at the help file appendix ASCII characters.

MsgBox(0, 'ASCII', 'ASCII Character Code: ' & Asc(_IniRead("testIni.ini","sectionName","DaKey","")))

Share this post


Link to post
Share on other sites

Posted (edited)

I tried your script, but when I pasted in notepad I can see character (1) between ab and cd. Run the script below and look at the help file appendix ASCII characters.

and it now correctly returns "" when it's blank, and it still returns the entire string if there's actually data associated with the key in the .ini file. Is this what this line should actually have been coded as? I don't want to break anything else, though _IniRead seems to be working with the line change, and I'm certainly loathe to assume that Gary made a mistake like that...others have tested these functions and not had problems with them. I also don't know if I can test with certainty that this change in code didn't break another _ini function somewhere else in his UDF... :)

Can someone else confirm if this line was/wasn't coded incorrectly or if I'm still being dense?

Thanks

Edited by Jon

Share this post


Link to post
Share on other sites

Posted (edited)

This one may seems to be much faster:

Func _IniReadSectionEx($hFile, $vSection)
	Local $iSize = FileGetSize($hFile) / 1024
	If $iSize <= 31 Then Return IniReadSection($hFile, $vSection)
	Local $sFRead = @CRLF & FileRead($hFile) & @CRLF & '['
	$vSection = StringStripWS($vSection, 7)
	Local $aData = StringRegExp($sFRead, '(?s)(?i)\n\s*\[\s*' & $vSection & '\s*\]\s*\r\n(.*?)\[', 3)
	If IsArray($aData) = 0 Then Return SetError(1, 0, 0)
	FileWrite(@TempDir & '\IniReadSectionTemp.ini', '[' & $vSection & ']' & @CRLF & $aData[0])
	Local $aSection = IniReadSection(@TempDir & '\IniReadSectionTemp.ini', $vSection)
	FileDelete(@TempDir & '\IniReadSectionTemp.ini')
	Return $aSection
EndFunc

Leaving the first post up in case someone finds something wrong with this one.

Edited by SmOke_N

Share this post


Link to post
Share on other sites

Posted (edited)

Damn...

Had to update it again, just noticed I didn't test to see if the new files were smaller than 32kb :whistle:

This one doesn't use anything but StringRegExp() unless the file is less than 31 kbs.

Func _IniReadSectionEx($hFile, $vSection)
	Local $iSize = FileGetSize($hFile) / 1024
	If $iSize <= 31 Then Return IniReadSection($hFile, $vSection)
	Local $sFRead = @CRLF & FileRead($hFile) & @CRLF & '['
	$vSection = StringStripWS($vSection, 7)
	Local $aData = StringRegExp($sFRead, '(?s)(?i)\n\s*\[\s*' & $vSection & '\s*\]\s*\r\n(.*?)\[', 1)
	If IsArray($aData) = 0 Then Return SetError(1, 0, 0)
	Local $aKey = StringRegExp(@LF & $aData[0], '\n\s*(.*?)\s*=', 3)
	Local $aValue = StringRegExp(@LF & $aData[0], '\n\s*.*?\s*=(.*?)\r', 3)
    Local $nUbound = UBound($aKey)
	Local $aSection[$nUBound +1][$nUBound +1]
	$aSection[0][0] = $nUBound
	For $iCC = 0 To $nUBound - 1
		$aSection[$iCC + 1][0] = $aKey[$iCC]
		$aSection[$iCC + 1][1] = $aValue[$iCC]
	Next
	Return $aSection
EndFunc

My test showed almost 3 times faster than the one in post #1.

Edited by SmOke_N

Share this post


Link to post
Share on other sites

Posted (edited)

_IniReadEx... Same params as IniRead(), but the default param is optional

Func _IniReadEx($hFile, $vSection, $vKey, $vDefault = -1)
	If $vDefault = -1 Or $vDefault = Default Then $vDefault = ''
	Local $iSize = FileGetSize($hFile) / 1024
	If $iSize <= 31 Then Return IniRead($hFile, $vSection, $vKey, $vDefault)
	Local $sFRead = @CRLF & FileRead($hFile) & @CRLF & '['
	$vSection = StringStripWS($vSection, 7)
	Local $aData = StringRegExp($sFRead, '(?s)(?i)\n\s*\[\s*' & $vSection & '\s*\]\s*\r\n(.*?)\[', 1)
	If IsArray($aData) = 0 Then Return SetError(1, 0, 0)
	Local $aRead = StringRegExp(@LF & $aData[0], '(?s)(?i)\n\s*' & $vKey & '\s*=(.*?)\r', 1)
	If IsArray($aRead) = 0 Then Return SetError(2, 0, 0)
	Return $aRead[0]
EndFunc

If anyone is wondering, I obviously ran into a need for them :whistle: ...

Edited by SmOke_N

Share this post


Link to post
Share on other sites

Posted (edited)

I re-wrote all the others that Gary had up there as well... these don't require making a temp folder, and "should" be faster than the others...

I'm still not deleting the original post code in case someone finds bugs with these, I spent most of the time writing them not testing them...

Func _IniDeleteEx($hFile, $vSection, $vKey = '')
	Local $iSize = FileGetSize($hFile) / 1024
	If $iSize <= 31 Then Return IniDelete($hFile, $vSection, $vKey)
	Local $sString = FileRead($hFile)
	Local $sFRead = @CRLF & $sString & @CRLF & '['
	$vSection = StringStripWS($vSection, 7)
	Local $aData = StringRegExp($sFRead, '(?s)(?i)\n\s*\[\s*' & $vSection & '\s*\]\s*\r\n(.*?)\[', 3)
	If IsArray($aData) = 0 Then Return SetError(1, 0, 0)
	$aData[0] = StringRegExpReplace($aData[0], '(\r\n)+$', '')
	If $vKey = '' Then
		$sString = StringRegExpReplace($sString, '(?s)(?i)(^|\n)\s*\[\s*' & $vSection & '\s*\]\s*(\r\n)+' & StringReplace($aData[0], '\', '\\'), @LF & @CRLF)
	Else
		$sString = StringRegExpReplace($aData[0], '(?s)(?i)\n\s*' & $vKey & '\s*=.*?(?m:\r\n|$)', @LF)
	EndIf
	$sString = StringRegExpReplace($sString, '(^(\r\n)+)+|^\r+|^\n+|(\r\n)+$|\[$', '')
	$sString = StringRegExpReplace($sString, '(\r\n){3}', @CRLF)
	$sString = StringRegExpReplace($sString, '(^(\r\n)+)+', '')
	FileClose(FileOpen($hFile, 2))
	Return FileWrite($hFile, $sString)
EndFuncoÝ÷ Û÷b½Êyº1jëh×6Func _IniWriteEx($hFile, $vSection, $vKey, $vValue)
	If FileExists($hFile) = 0 Then FileClose(FileOpen($hFile, 2))
	Local $iSize = FileGetSize($hFile) / 1024
	If $iSize <= 31 Then Return IniWrite($hFile, $vSection, $vKey, $vValue)
	Local $sString = FileRead($hFile)
	Local $sFRead = @CRLF & $sString & @CRLF & '['
	$vSection = StringStripWS($vSection, 7)
	Local $aData = StringRegExp($sFRead, '(?s)(?i)\n\s*\[\s*' & $vSection & '\s*\]\s*\r\n(.*?)\[', 3)
	If IsArray($aData) = 0 Then Return SetError(1, 0, 0)
	$aData[0] = StringRegExpReplace($aData[0], '(\r\n)+$', '')
	If StringRegExp(@LF & $aData[0] & @CRLF, '(?s)(?i)\n\s*' & $vKey & '\s*=') Then
		Local $sTempReplace = StringRegExpReplace(@LF & $aData[0] & @CR, _
			'(?s)(?i)\n\s*' & $vKey & '=.*?\r', @LF & $vKey & '=' & StringReplace($vValue, '\', '\\') & @CR)
		$aData[0] = StringRegExpReplace($sTempReplace, '^\r\n|^\s*\n|^\s*\r|\r$', '')
	Else
		$aData[0] = StringReplace($aData[0] & @CRLF & $vKey & '=' & $vValue, '\', '\\')
	EndIf
	$sString = StringRegExpReplace(@LF & $sString & _
		'[', '(?s)(?i)(^|\n)\s*\[\s*' & $vSection & '\s*\]\s*\r\n.*?\s*\[', @LF & @CRLF & '\[' & $vSection & '\]' & @CRLF & $aData[0] & @CRLF & @CRLF & '\[')
	$sString = StringRegExpReplace($sString, '(^(\r\n)+)+|^\r+|^\n+|\[$|(\r\n)+$', '')
	FileClose(FileOpen($hFile, 2))
	Return FileWrite($hFile, $sString)
EndFuncoÝ÷ Û÷b½Êyº1jëh×6Func _IniReadSectionNamesEx($hFile)
	Local $iSize = FileGetSize($hFile) / 1024
	If $iSize <= 31 Then Return IniReadSectionNames($hFile)
    Local $aSectionNames = StringRegExp(@CRLF & FileRead($hFile) & @CRLF, '(?s)\n\s*\[(.*?)\]s*\r', 3)
    If IsArray($aSectionNames) = 0 Then Return SetError(1, 0, 0)
	Local $nUbound = UBound($aSectionNames)
	Local $aNameReturn[$nUbound + 1]
	$aNameReturn[0] = $nUbound
	For $iCC = 0 To $nUBound - 1
		$aNameReturn[$iCC + 1] = $aSectionNames[$iCC]
	Next
	Return $aNameReturn
EndFuncoÝ÷ Û÷b½Êyº1jëh×6Func _IniReadEx($hFile, $vSection, $vKey, $vDefault = -1)
	If $vDefault = -1 Or $vDefault = Default Then $vDefault = ''
	Local $iSize = FileGetSize($hFile) / 1024
	If $iSize <= 31 Then Return IniRead($hFile, $vSection, $vKey, $vDefault)
	Local $sFRead = @CRLF & FileRead($hFile) & @CRLF & '['
	$vSection = StringStripWS($vSection, 7)
	Local $aData = StringRegExp($sFRead, '(?s)(?i)\n\s*\[\s*' & $vSection & '\s*\]\s*\r\n(.*?)\[', 3)
	If IsArray($aData) = 0 Then Return SetError(1, 0, 0)
	Local $aRead = StringRegExp(@LF & $aData[0], '(?s)(?i)\n\s*' & $vKey & '\s*=(.*?)\r', 1)
	If IsArray($aRead) = 0 Then Return SetError(2, 0, 0)
	Return $aRead[0]
EndFuncoÝ÷ Û÷b½Êyº1jëh×6Func _IniReadSectionEx($hFile, $vSection)
	Local $iSize = FileGetSize($hFile) / 1024
	If $iSize <= 31 Then Return IniReadSection($hFile, $vSection)
	Local $sFRead = @CRLF & FileRead($hFile) & @CRLF & '['
	$vSection = StringStripWS($vSection, 7)
	Local $aData = StringRegExp($sFRead, '(?s)(?i)\n\s*\[\s*' & $vSection & '\s*\]\s*\r\n(.*?)\[', 3)
	If IsArray($aData) = 0 Then Return SetError(1, 0, 0)
	Local $aKey = StringRegExp(@LF & $aData[0], '\n\s*(.*?)\s*=', 3)
	Local $aValue = StringRegExp(@LF & $aData[0], '\n\s*.*?\s*=(.*?)\r', 3)
    Local $nUbound = UBound($aKey)
	Local $aSection[$nUBound +1][$nUBound +1]
	$aSection[0][0] = $nUBound
	For $iCC = 0 To $nUBound - 1
		$aSection[$iCC + 1][0] = $aKey[$iCC]
		$aSection[$iCC + 1][1] = $aValue[$iCC]
	Next
	Return $aSection
EndFunc
Edited by SmOke_N

Share this post


Link to post
Share on other sites

Posted

I re-wrote all the others that Gary had up there as well... these don't require making a temp folder, and "should" be faster than the others...

Excellent SmOke_N.

I have copied all these and I now have IniEx.au3 in my includes folder. Thanks.

Share this post


Link to post
Share on other sites

Posted (edited)

Had to fix _IniWriteEx()

Func _IniWriteEx($hFile, $vSection, $vKey, $vValue)
	If FileExists($hFile) = 0 Then FileClose(FileOpen($hFile, 2))
	Local $iSize = FileGetSize($hFile) / 1024
	If $iSize <= 31 Then Return IniWrite($hFile, $vSection, $vKey, $vValue)
	Local $sString = FileRead($hFile)
	Local $sFRead = @CRLF & $sString & @CRLF & '['
	$vSection = StringStripWS($vSection, 7)
	Local $aData = StringRegExp($sFRead, '(?s)(?i)\n\s*\[\s*' & $vSection & '\s*\]\s*\r\n(.*?)\[', 3)
	If IsArray($aData) = 0 Then
		If StringRegExp($sString, '(?s)\r\n$') = 0 Then
			$sString &= @CRLF & '[' & $vSection & ']' & @CRLF & $vKey & '=' & $vValue
		Else
			$sString &= '[' & $vSection & ']' & @CRLF & $vKey & '=' & $vValue
		EndIf
		FileClose(FileOpen($hFile, 2))
		Return FileWrite($hFile, $sString)
	EndIf
	$aData[0] = StringRegExpReplace($aData[0], '(\r\n)+$', '')
	If StringRegExp(@LF & $aData[0] & @CRLF, '(?s)(?i)\n\s*' & $vKey & '\s*=') Then
		Local $sTempReplace = StringRegExpReplace(@LF & $aData[0] & @CR, _
			'(?s)(?i)\n\s*' & $vKey & '=.*?\r', @LF & $vKey & '=' & StringReplace($vValue, '\', '\\') & @CR)
		$aData[0] = StringRegExpReplace($sTempReplace, '^\r\n|^\s*\n|^\s*\r|\r$', '')
	Else
		$aData[0] = StringReplace($aData[0] & @CRLF & $vKey & '=' & $vValue, '\', '\\')
	EndIf
	$sString = StringRegExpReplace(@LF & $sString & _
		'[', '(?s)(?i)(^|\n)\s*\[\s*' & $vSection & '\s*\]\s*\r\n.*?\s*\[', @LF & @CRLF & '\[' & $vSection & '\]' & @CRLF & $aData[0] & @CRLF & @CRLF & '\[')
	$sString = StringRegExpReplace($sString, '(^(\r\n)+)+|^\r+|^\n+|\[$|(\r\n)+$', '')
	FileClose(FileOpen($hFile, 2))
	Return FileWrite($hFile, $sString)
EndFunc
It wasn't adding the section if the section didn't exist.

Edited by SmOke_N

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0