Get all section names of INI file: Difference between revisions

From NSIS Wiki
Jump to navigationJump to search
No edit summary
 
(One intermediate revision by the same user not shown)
Line 139: Line 139:


<highlight-nsis>
<highlight-nsis>
!ifndef GetSectionNames_BufferSize
!define GetSectionNames_BufferSize 1024
!endif
!define GetSectionNames `!insertmacro GetSectionNamesCall`
!define GetSectionNames `!insertmacro GetSectionNamesCall`
   
   
Line 151: Line 155:


Function GetSectionNames
Function GetSectionNames
Exch $1
  Exch $1
Exch
  Exch
Exch $0
  Exch $0
Exch
  Exch
Push $2
  Push $2
Push $3
  Push $3
Push $4
  Push $4
Push $5
  Push $5
Push $8
  Push $9
Push $9
 
  System::Call `*(&m${GetSectionNames_BufferSize}) i .r2`
System::Call *(&m1024)i.r2
  StrCpy $3 $2
        StrCpy $3 $2
 
  System::Call `kernel32::GetPrivateProfileSectionNamesA(i r3, i ${GetSectionNames_BufferSize}, m r0) i .r4`
 
  Next:
  System::Call `kernel32::lstrlenA(i r3) i .r5`
  StrCmp $5 0 Done
 
  System::Call `*$3(&m${NSIS_MAX_STRLEN} .r9)`


        System::Call "kernel32::GetPrivateProfileSectionNamesA(i, i, m)i (r3, 1024, r0).r4"
  Push $0
     
  Push $1
enumok:
  Push $2
        System::Call 'kernel32::lstrlen(m)i (i r3).r5'
  Push $3
StrCmp $5 '0' enumex
  Push $4
  Push $5
  Call $1
  Pop $9
  Pop $5
  Pop $4
  Pop $3
  Pop $2
  Pop $1
  Pop $0
  StrCmp $9 StopGetSectionNames Done


System::Call '*$3(&m1024 .r9)'
  IntOp $5 $5 + 1
  IntOp $3 $3 + $5
  GoTo Next


Push $0
  Done:
Push $1
  System::Free $2
Push $2
Push $3
Push $4
Push $5
Push $8
Call $1
Pop $9
Pop $8
Pop $5
Pop $4
Pop $3
Pop $2
Pop $1
Pop $0
        StrCmp $9 'StopGetSectionNames' enumex


enumnext:
  Pop $9
IntOp $5 $5 + 1
  Pop $5
IntOp $3 $3 + $5
  Pop $4
goto enumok
  Pop $3
  Pop $2
enumex:
  Pop $1
System::Free $2
  Pop $0
Pop $9
Pop $8
Pop $5
Pop $4
Pop $3
Pop $2
Pop $1
Pop $0
FunctionEnd</highlight-nsis>
FunctionEnd</highlight-nsis>


[[Category:INI, CSV & Registry Functions]]
[[Category:INI, CSV & Registry Functions]]

Latest revision as of 12:15, 25 April 2013

Author: nechai (talk, contrib)


Links

If a function is used without header, put the function code in your script before calling it.

The Function Description

Based on the method to loop over a buffer of null-terminated strings in function "GetDrives"
 
Loop over all available sections in an INI file.
 
Syntax:
${GetSectionNames} "File" "Function"
 
"File"     ; name of the initialization file
"Function" ; Callback function
 
Function "Function"
         ; $9    "section name"
         ; $R0-$R9  are not used (save data in them).
 
         ; ...
 
         Push $var    ; If $var="StopGetSectionNames" Then exit from function
FunctionEnd

Example1:

Section
	${GetSectionNames} "c:\test.ini" "Example1"
SectionEnd
 
Function Example1
	MessageBox MB_OK "$9"
 
	Push $0
FunctionEnd

Example2:

Section
	${GetSectionNames} "c:\test.ini" "Example2"
SectionEnd
 
Function Example2
	StrCmp $9 $R0 0 +3
	StrCpy $R1 $9
	StrCpy $0 StopGetSectionNames
 
	Push $0
FunctionEnd

The Function Code (ANSI/Unicode)

If you are using Unicode NSIS, this code will require the input INI file to also be Unicode (with no BOM). If you wish to only use ANSI encoded INI files whether you build using NSIS or Unicode NSIS, see the alternative code further down.

!define GetSectionNames `!insertmacro GetSectionNamesCall`
 
!macro GetSectionNamesCall _FILE _FUNC
	Push $0
	Push `${_FILE}`
	GetFunctionAddress $0 `${_FUNC}`
	Push `$0`
	Call GetSectionNames
	Pop $0
!macroend
 
Function GetSectionNames
	Exch $1
	Exch
	Exch $0
	Exch
	Push $2
	Push $3
	Push $4
	Push $5
	Push $8
	Push $9
 
	System::Call *(&t1024)i.r2
        StrCpy $3 $2
 
        System::Call "kernel32::GetPrivateProfileSectionNames(i, i, t)i (r3, 1024, r0).r4"
 
	enumok:
        System::Call 'kernel32::lstrlen(t)i (i r3).r5' ; (t) is here to trigger A/W detection
	StrCmp $5 '0' enumex
 
	System::Call '*$3(&t1024 .r9)'
 
	Push $0
	Push $1
	Push $2
	Push $3
	Push $4
	Push $5
	Push $8
	Call $1
	Pop $9
	Pop $8
	Pop $5
	Pop $4
	Pop $3
	Pop $2
	Pop $1
	Pop $0
        StrCmp $9 'StopGetSectionNames' enumex
 
	enumnext:
!if "${NSIS_CHAR_SIZE}" > 1
	IntOp $5 $5 * ${NSIS_CHAR_SIZE}
	IntOp $5 $5 + ${NSIS_CHAR_SIZE}
!else
	IntOp $5 $5 + 1
!endif
	IntOp $3 $3 + $5
	goto enumok
 
	enumex:
	System::Free $2
 
	Pop $9
	Pop $8
	Pop $5
	Pop $4
	Pop $3
	Pop $2
	Pop $1
	Pop $0
FunctionEnd

The Function Code (ANSI only)

!ifndef GetSectionNames_BufferSize
!define GetSectionNames_BufferSize 1024
!endif
 
!define GetSectionNames `!insertmacro GetSectionNamesCall`
 
!macro GetSectionNamesCall _FILE _FUNC
	Push $0
	Push `${_FILE}`
	GetFunctionAddress $0 `${_FUNC}`
	Push `$0`
	Call GetSectionNames
	Pop $0
!macroend
 
Function GetSectionNames
  Exch $1
  Exch
  Exch $0
  Exch
  Push $2
  Push $3
  Push $4
  Push $5
  Push $9
 
  System::Call `*(&m${GetSectionNames_BufferSize}) i .r2`
  StrCpy $3 $2
 
  System::Call `kernel32::GetPrivateProfileSectionNamesA(i r3, i ${GetSectionNames_BufferSize}, m r0) i .r4`
 
  Next:
  System::Call `kernel32::lstrlenA(i r3) i .r5`
  StrCmp $5 0 Done
 
  System::Call `*$3(&m${NSIS_MAX_STRLEN} .r9)`
 
  Push $0
  Push $1
  Push $2
  Push $3
  Push $4
  Push $5
  Call $1
  Pop $9
  Pop $5
  Pop $4
  Pop $3
  Pop $2
  Pop $1
  Pop $0
  StrCmp $9 StopGetSectionNames Done
 
  IntOp $5 $5 + 1
  IntOp $3 $3 + $5
  GoTo Next
 
  Done:
  System::Free $2
 
  Pop $9
  Pop $5
  Pop $4
  Pop $3
  Pop $2
  Pop $1
  Pop $0
FunctionEnd