1+ /*
2+ @FILENAME = EnumIni.nsh
3+ @AUTHORS = Zinthose, Iceman_K
4+ @REVISIONS = zenpoy[http://forums.winamp.com/member.php?u=401997]
5+ @URL = http://nsis.sourceforge.net/mediawiki/index.php?title=Enumerate_INI
6+ */
7+ !ifndef __EnumIni__
8+ !define __EnumIni__
9+
10+ # # Includes
11+ !include " TextFunc.nsh"
12+ !ifndef StrLoc
13+ !include " StrFunc.nsh"
14+ ${StrLoc}
15+ !endif
16+
17+ # # Macro to remove leading and trailing whitespaces from a string.
18+ # # Derived from the function originaly posted by Iceman_K at:
19+ # # http://nsis.sourceforge.net/Remove_leading_and_trailing_whitespaces_from_a_string
20+ !ifmacrondef _Trim
21+ !macro _Trim _UserVar _OriginalString
22+ !define Trim_UID ${__LINE__}
23+
24+ Push $R1
25+ Push $R2
26+ Push ` ${_OriginalString}`
27+ Pop $R1
28+
29+ Loop_${Trim_UID} :
30+ StrCpy $R2 " $R1" 1
31+ StrCmp " $R2" " " TrimLeft_${Trim_UID}
32+ StrCmp " $R2" " $\r " TrimLeft_${Trim_UID}
33+ StrCmp " $R2" " $\n " TrimLeft_${Trim_UID}
34+ StrCmp " $R2" " $\t " TrimLeft_${Trim_UID}
35+ GoTo Loop2_${Trim_UID}
36+ TrimLeft_${Trim_UID} :
37+ StrCpy $R1 " $R1" " " 1
38+ Goto Loop_${Trim_UID}
39+
40+ Loop2_${Trim_UID} :
41+ StrCpy $R2 " $R1" 1 -1
42+ StrCmp " $R2" " " TrimRight_${Trim_UID}
43+ StrCmp " $R2" " $\r " TrimRight_${Trim_UID}
44+ StrCmp " $R2" " $\n " TrimRight_${Trim_UID}
45+ StrCmp " $R2" " $\t " TrimRight_${Trim_UID}
46+ GoTo Done_${Trim_UID}
47+ TrimRight_${Trim_UID} :
48+ StrCpy $R1 " $R1" -1
49+ Goto Loop2_${Trim_UID}
50+
51+ Done_${Trim_UID} :
52+ Pop $R2
53+ Exch $R1
54+ Pop ${_UserVar}
55+ !undef Trim_UID
56+ !macroend
57+ !ifdef Trim
58+ !warning ` Trim Macro Previously Defined! Beware of bugs!`
59+ !else
60+ !define Trim ` !insertmacro _Trim`
61+ !endif
62+ !endif
63+
64+ # # Global variable needed for indexing the enumerations
65+ !ifmacrondef EnumIni_IDX_VAR
66+ !macro EnumIni_IDX_VAR
67+ !ifndef EnumIni_IDX_VAR
68+ VAR /GLOBAL EnumIni_IDX_VAR
69+ !define EnumIni_IDX_VAR $EnumIni_IDX_VAR
70+ !endif
71+ !macroend
72+ !endif
73+
74+ /* ## EnumIniKey ##
75+ Nearly identical in use to the builtin EnumRegKey function, the EnumIniKey macro
76+ allows for enumeration of an existing ini file's sections.
77+
78+ ## Example ##
79+ StrCpy $0 0
80+ loop:
81+ ${EnumIniKey} $1 `c:\boot.ini` $0
82+ StrCmp $1 "" done
83+ IntOp $0 $0 + 1
84+ MessageBox MB_YESNO|MB_ICONQUESTION "Key=$1$\n$\n$\nMore?" IDYES loop
85+ done:
86+ */
87+ !ifmacrondef _EnumIniKey
88+ !insertmacro EnumIni_IDX_VAR
89+ !macro _EnumIniKey _UserVar _IniFilePath _Index
90+ !define EnumIniKey_UID ${__LINE__}
91+ ClearErrors
92+
93+ Push $R0
94+ Push $R1
95+
96+ Push ` ${_IniFilePath}`
97+ Push ` ${_Index}`
98+
99+ Pop $R1 ; ${_Index}
100+ Pop $R0 ; ${_IniFilePath}
101+
102+ IfFileExists $R0 0 Else_IfFileExists_${EnumIniKey_UID}
103+ StrCpy $EnumIni_IDX_VAR -1
104+ # # PATCH Added to Correct 0 length file infinite loop issue discovered by zenpoy
105+ # # [http://forums.winamp.com/member.php?u=401997] on January 9th 2012
106+ ${LineSum} $R0 $R1
107+ IfErrors Else_IfFileExists_${EnumINIKey_UID}
108+ IntCmp $R1 0 Else_IfFileExists_${EnumINIKey_UID} Else_IfFileExists_${EnumINIKey_UID} 0
109+ # # End Revision
110+ ${LineFind} $R0 " /NUL" " 1:-1" " EnumIniKey_CALLBACK"
111+ IfErrors Else_IfFileExists_${EnumIniKey_UID}
112+ Goto EndIf_FileExists_${EnumIniKey_UID}
113+ Else_IfFileExists_${EnumIniKey_UID} :
114+ StrCpy $R0 ' '
115+ SetErrors
116+ EndIf_FileExists_${EnumIniKey_UID} :
117+
118+ Pop $R1
119+ Exch $R0
120+ Pop ${_UserVar}
121+
122+ !undef EnumIniKey_UID
123+ !macroend
124+ !ifndef EnumIniKey
125+ !define EnumIniKey ` !insertmacro _EnumIniKey`
126+ !endif
127+ !ifdef __GLOBAL__
128+ !verbose push
129+ !verbose 0
130+ Function EnumIniKey_CALLBACK
131+ !insertmacro _Trim $R9 $R9
132+
133+ StrCmp $R9 ' ' End
134+ StrCpy $R0 $R9 1
135+ StrCmp $R0 ' [' 0 End
136+ IntOp $EnumIni_IDX_VAR $EnumIni_IDX_VAR + 1
137+ IntCmp $R1 $EnumIni_IDX_VAR 0 End End
138+ ${StrLoc} $R0 $R9 " ]" " >"
139+ IntCmp $R0 0 End
140+ IntOp $R0 $R0 - 1
141+ StrCpy $R0 $R9 $R0 1
142+ Push ' StopLineFind'
143+ Return
144+ End:
145+ StrCpy $R0 ' '
146+ Push ' '
147+ FunctionEnd
148+ !verbose pop
149+ !else
150+ !Error ` An illegal attempt was made to insert the EnumIniValue_CALLBACK function outside the Global namespace!`
151+ !endif
152+ !endif
153+
154+ /* ## EnumIniValue ##
155+ Nearly identical in use to the builtin EnumRegValue function, the EnumIniValue macro
156+ allows for enumeration of an existing ini file section.
157+
158+ ## Example ##
159+ StrCpy $0 0
160+ loop:
161+ ${EnumIniValue} $1 `c:\boot.ini` `boot loader` $0
162+ StrCmp $1 "" done
163+ IntOp $0 $0 + 1
164+ ReadIniStr $2 `c:\boot.ini` `boot loader` $1
165+ MessageBox MB_YESNO|MB_ICONQUESTION "Value=$1$\n$\t$2$\n$\n$\nMore?" IDYES loop
166+ done:
167+ */
168+ !ifmacrondef _EnumIniValue
169+ !insertmacro EnumIni_IDX_VAR
170+ !macro _EnumIniValue _UserVar _IniFilePath _Section _Index
171+ !define EnumIniValue_UID ${__LINE__}
172+ ClearErrors
173+
174+ Push $R0
175+ Push $R1
176+ Push $R2
177+ Push $R3
178+
179+ Push ` ${_IniFilePath}`
180+ Push ` ${_Section}`
181+ Push ` ${_Index}`
182+
183+ Pop $R2 ; ${_Index}
184+ Pop $R1 ; ${_Section}
185+ Pop $R0 ; ${_IniFilePath}
186+
187+ IfFileExists $R0 0 Else_IfFileExists_${EnumIniValue_UID}
188+ StrCpy $EnumIni_IDX_VAR -1
189+ ${LineFind} $R0 " /NUL" " 1:-1" " EnumIniValue_CALLBACK"
190+ IfErrors Else_IfFileExists_${EnumIniValue_UID}
191+ Goto EndIf_FileExists_${EnumIniValue_UID}
192+ Else_IfFileExists_${EnumIniValue_UID} :
193+ StrCpy $R0 ' '
194+ SetErrors
195+ EndIf_FileExists_${EnumIniValue_UID} :
196+
197+ Pop $R3
198+ Pop $R2
199+ Pop $R1
200+ Exch $R0
201+ Pop ${_UserVar}
202+ !undef EnumIniValue_UID
203+ !macroend
204+ !ifndef EnumIniValue
205+ !define EnumIniValue ` !insertmacro _EnumIniValue`
206+ !endif
207+ !ifdef __GLOBAL__
208+ !verbose push
209+ !verbose 0
210+ Function EnumIniValue_CALLBACK
211+ !insertmacro _Trim $R9 $R9
212+
213+ StrCmp $R9 ' ' End
214+ StrCpy $R0 $R9 1
215+ StrCmp $R0 ' ;' End
216+ StrCmp $R0 ' #' End
217+ StrCmp $R0 ' [' Key
218+ StrCmp $R3 [$R1 ] 0 End
219+ IntOp $EnumIni_IDX_VAR $EnumIni_IDX_VAR + 1
220+ IntCmp $R2 $EnumIni_IDX_VAR 0 End End
221+ ${StrLoc} $R0 $R9 " =" " >"
222+ IntCmp $R0 0 0 0 ValueSet
223+ StrCpy $R0 $R9
224+ ValueSet:
225+ StrCpy $R0 $R9 $R0
226+ Push ' StopLineFind'
227+ Return
228+ Key:
229+ StrCpy $R3 $R9
230+ End:
231+ StrCpy $R0 ' '
232+ Push ' '
233+ FunctionEnd
234+ !verbose pop
235+ !else
236+ !Error ` An illegal attempt was made to insert the EnumIniValue_CALLBACK function outside the Global namespace!`
237+ !endif
238+ !endif
239+ !endif
0 commit comments