Statistiques
| Révision :

root / tmp / org.txm.setups / nsis / Include / LogicLib.nsh @ 3144

Historique | Voir | Annoter | Télécharger (32,55 ko)

1
; NSIS LOGIC LIBRARY - LogicLib.nsh
2
; Version 2.6 - 08/12/2007
3
; By dselkirk@hotmail.com
4
; and eccles@users.sf.net
5
; with IfNot support added by Message
6
;
7
; Questions/Comments -
8
; See http://forums.winamp.com/showthread.php?s=&postid=1116241
9
;
10
; Description:
11
;   Provides the use of various logic statements within NSIS.
12
;
13
; Usage:
14
;   The following "statements" are available:
15
;       If|IfNot|Unless..{ElseIf|ElseIfNot|ElseUnless}..[Else]..EndIf|EndUnless
16
;         - Conditionally executes a block of statements, depending on the value
17
;           of an expression. IfNot and Unless are equivalent and
18
;           interchangeable, as are ElseIfNot and ElseUnless.
19
;       AndIf|AndIfNot|AndUnless|OrIf|OrIfNot|OrUnless
20
;         - Adds any number of extra conditions to If, IfNot, Unless, ElseIf,
21
;           ElseIfNot and ElseUnless statements.
22
;       IfThen|IfNotThen..|..|
23
;         - Conditionally executes an inline statement, depending on the value
24
;           of an expression.
25
;       IfCmd..||..|
26
;         - Conditionally executes an inline statement, depending on a true
27
;           value of the provided NSIS function.
28
;       Select..{Case[2|3|4|5]}..[CaseElse|Default]..EndSelect
29
;         - Executes one of several blocks of statements, depending on the value
30
;           of an expression.
31
;       Switch..{Case|CaseElse|Default}..EndSwitch
32
;         - Jumps to one of several labels, depending on the value of an
33
;           expression.
34
;       Do[While|Until]..{ExitDo|Continue|Break}..Loop[While|Until]
35
;         - Repeats a block of statements until stopped, or depending on the
36
;           value of an expression.
37
;       While..{ExitWhile|Continue|Break}..EndWhile
38
;         - An alias for DoWhile..Loop (for backwards-compatibility)
39
;       For[Each]..{ExitFor|Continue|Break}..Next
40
;         - Repeats a block of statements varying the value of a variable.
41
;
42
;   The following "expressions" are available:
43
;       Standard (built-in) string tests (which are case-insensitive):
44
;         a == b; a != b
45
;       Additional case-insensitive string tests (using System.dll):
46
;         a S< b; a S>= b; a S> b; a S<= b
47
;       Case-sensitive string tests:
48
;         a S== b; a S!= b
49
;       Standard (built-in) signed integer tests:
50
;         a = b; a <> b; a < b; a >= b; a > b; a <= b; a & b
51
;       Standard (built-in) unsigned integer tests:
52
;         a U< b; a U>= b; a U> b; a U<= b
53
;       64-bit integer tests (using System.dll):
54
;         a L= b; a L<> b; a L< b; a L>= b; a L> b; a L<= b
55
;       ptrdiff_t integer tests
56
;         a P= b; a P<> b; a P< b; a P>= b; a P> b; a P<= b
57
;       size_t integer tests
58
;         a Z= b; a Z<> b; a Z< b; a Z>= b; a Z> b; a Z<= b
59
;       Built-in NSIS flag tests:
60
;         ${Abort}; ${Errors}; ${RebootFlag}; ${Silent}; ${RtlLanguage};
61
;         ${ShellVarContextAll}
62
;       Built-in NSIS other tests:
63
;         ${FileExists} a
64
;       Any conditional NSIS instruction test:
65
;         ${Cmd} a
66
;       Section flag tests:
67
;         ${SectionIsSelected} a; ${SectionIsSectionGroup} a;
68
;         ${SectionIsSectionGroupEnd} a; ${SectionIsBold} a;
69
;         ${SectionIsReadOnly} a; ${SectionIsExpanded} a;
70
;         ${SectionIsPartiallySelected} a
71
;       Additional tests:
72
;         HK RegKeyIsEmpty SubKey
73
;
74
; Examples:
75
;   See LogicLib.nsi in the Examples folder for lots of example usage.
76

    
77
!verbose push
78
!verbose 3
79
!ifndef LOGICLIB_VERBOSITY
80
  !define LOGICLIB_VERBOSITY 3
81
!endif
82
!define _LOGICLIB_VERBOSITY ${LOGICLIB_VERBOSITY}
83
!undef LOGICLIB_VERBOSITY
84
!verbose ${_LOGICLIB_VERBOSITY}
85

    
86
!ifndef LOGICLIB
87
  !define LOGICLIB
88
  !define | "'"
89
  !define || "' '"
90
  !define LOGICLIB_COUNTER 0
91

    
92
  !include Sections.nsh
93

    
94
  !macro _LOGICLIB_TEMP
95
    !ifndef _LOGICLIB_TEMP
96
      !define _LOGICLIB_TEMP
97
      Var /GLOBAL _LOGICLIB_TEMP  ; Temporary variable to aid the more elaborate logic tests
98
    !endif
99
  !macroend
100

    
101
  !macro LogicLib_JumpToBranch _Jump _Skip
102
    !if `${_Jump}` != ``
103
      StrCmp "" "" `${_Jump}` ${_Skip}
104
    !endif
105
  !macroend
106

    
107
  !macro _IncreaseCounter
108
    !define /redef /math LOGICLIB_COUNTER `${LOGICLIB_COUNTER}` + 1
109
  !macroend
110

    
111
  !macro _PushLogic
112
    !insertmacro _PushScope Logic _LogicLib_Label_${LOGICLIB_COUNTER}
113
    !insertmacro _IncreaseCounter
114
  !macroend
115

    
116
  !macro _PopLogic
117
    !insertmacro _PopScope Logic
118
  !macroend
119

    
120
  !macro _PushScope Type label
121
    !ifdef _${Type}                                       ; If we already have a statement
122
      !define _Cur${Type} ${_${Type}}
123
      !undef _${Type}
124
      !define _${Type} ${label}
125
      !define ${_${Type}}Prev${Type} ${_Cur${Type}}       ; Save the current logic
126
      !undef _Cur${Type}
127
    !else
128
      !define _${Type} ${label}                           ; Initialise for first statement
129
    !endif
130
  !macroend
131

    
132
  !macro _PopScope Type
133
    !ifndef _${Type}
134
      !error "Cannot use _Pop${Type} without a preceding _Push${Type}"
135
    !endif
136
    !ifdef ${_${Type}}Prev${Type}                         ; If a previous statment was active then restore it
137
      !define _Cur${Type} ${_${Type}}
138
      !undef _${Type}
139
      !define _${Type} ${${_Cur${Type}}Prev${Type}}
140
      !undef ${_Cur${Type}}Prev${Type}
141
      !undef _Cur${Type}
142
    !else
143
      !undef _${Type}
144
    !endif
145
  !macroend
146

    
147
  ; String tests
148
  !macro _== _a _b _t _f
149
    StrCmp `${_a}` `${_b}` `${_t}` `${_f}`
150
  !macroend
151

    
152
  !macro _!= _a _b _t _f
153
    !insertmacro _== `${_a}` `${_b}` `${_f}` `${_t}`
154
  !macroend
155

    
156
  ; Case-sensitive string tests
157
  !macro _S== _a _b _t _f
158
    StrCmpS `${_a}` `${_b}` `${_t}` `${_f}`
159
  !macroend
160

    
161
  !macro _S!= _a _b _t _f
162
    !insertmacro _S== `${_a}` `${_b}` `${_f}` `${_t}`
163
  !macroend
164

    
165
  ; Extra string tests (cannot do these case-sensitively - I tried and lstrcmp still ignored the case)
166
  !macro _StrCmpI _a _b _e _l _m
167
    !insertmacro _LOGICLIB_TEMP
168
    System::Call `kernel32::lstrcmpi(ts, ts) i.s` `${_a}` `${_b}`
169
    Pop $_LOGICLIB_TEMP
170
    IntCmp $_LOGICLIB_TEMP 0 `${_e}` `${_l}` `${_m}`
171
  !macroend
172

    
173
  !macro _S< _a _b _t _f
174
    !insertmacro _StrCmpI `${_a}` `${_b}` `${_f}` `${_t}` `${_f}`
175
  !macroend
176

    
177
  !macro _S>= _a _b _t _f
178
    !insertmacro _S< `${_a}` `${_b}` `${_f}` `${_t}`
179
  !macroend
180

    
181
  !macro _S> _a _b _t _f
182
    !insertmacro _StrCmpI `${_a}` `${_b}` `${_f}` `${_f}` `${_t}`
183
  !macroend
184

    
185
  !macro _S<= _a _b _t _f
186
    !insertmacro _S> `${_a}` `${_b}` `${_f}` `${_t}`
187
  !macroend
188

    
189
  ; Integer tests
190
  !macro _= _a _b _t _f
191
    IntCmp `${_a}` `${_b}` `${_t}` `${_f}` `${_f}`
192
  !macroend
193

    
194
  !macro _<> _a _b _t _f
195
    !insertmacro _= `${_a}` `${_b}` `${_f}` `${_t}`
196
  !macroend
197

    
198
  !macro _< _a _b _t _f
199
    IntCmp `${_a}` `${_b}` `${_f}` `${_t}` `${_f}`
200
  !macroend
201

    
202
  !macro _>= _a _b _t _f
203
    !insertmacro _< `${_a}` `${_b}` `${_f}` `${_t}`
204
  !macroend
205

    
206
  !macro _> _a _b _t _f
207
    IntCmp `${_a}` `${_b}` `${_f}` `${_f}` `${_t}`
208
  !macroend
209

    
210
  !macro _<= _a _b _t _f
211
    !insertmacro _> `${_a}` `${_b}` `${_f}` `${_t}`
212
  !macroend
213

    
214
  !macro _& _a _b _t _f
215
    !insertmacro _LOGICLIB_TEMP
216
    IntOp $_LOGICLIB_TEMP `${_a}` & `${_b}`
217
    !insertmacro _<> $_LOGICLIB_TEMP 0 `${_t}` `${_f}`
218
  !macroend
219

    
220
  ; Unsigned integer tests (NB: no need for extra equality tests)
221
  !macro _U< _a _b _t _f
222
    IntCmpU `${_a}` `${_b}` `${_f}` `${_t}` `${_f}`
223
  !macroend
224

    
225
  !macro _U>= _a _b _t _f
226
    !insertmacro _U< `${_a}` `${_b}` `${_f}` `${_t}`
227
  !macroend
228

    
229
  !macro _U> _a _b _t _f
230
    IntCmpU `${_a}` `${_b}` `${_f}` `${_f}` `${_t}`
231
  !macroend
232

    
233
  !macro _U<= _a _b _t _f
234
    !insertmacro _U> `${_a}` `${_b}` `${_f}` `${_t}`
235
  !macroend
236

    
237
  ; Int64 tests
238
  !macro _Int64Cmp _a _o _b _t _f
239
    !insertmacro _LOGICLIB_TEMP
240
    System::Int64Op `${_a}` `${_o}` `${_b}`
241
    Pop $_LOGICLIB_TEMP
242
    !insertmacro _= $_LOGICLIB_TEMP 0 `${_f}` `${_t}`
243
  !macroend
244

    
245
  !macro _L= _a _b _t _f
246
    !insertmacro _Int64Cmp `${_a}` = `${_b}` `${_t}` `${_f}`
247
  !macroend
248

    
249
  !macro _L<> _a _b _t _f
250
    !insertmacro _L= `${_a}` `${_b}` `${_f}` `${_t}`
251
  !macroend
252

    
253
  !macro _L< _a _b _t _f
254
    !insertmacro _Int64Cmp `${_a}` < `${_b}` `${_t}` `${_f}`
255
  !macroend
256

    
257
  !macro _L>= _a _b _t _f
258
    !insertmacro _L< `${_a}` `${_b}` `${_f}` `${_t}`
259
  !macroend
260

    
261
  !macro _L> _a _b _t _f
262
    !insertmacro _Int64Cmp `${_a}` > `${_b}` `${_t}` `${_f}`
263
  !macroend
264

    
265
  !macro _L<= _a _b _t _f
266
    !insertmacro _L> `${_a}` `${_b}` `${_f}` `${_t}`
267
  !macroend
268

    
269
  ; ptrdiff_t & size_t tests
270
  !macro LogicLib_PtrDiffTest _o _a _b _t _f
271
    !if "${NSIS_PTR_SIZE}" <= 4
272
      !insertmacro _${_o} `${_a}` `${_b}` `${_t}` `${_f}`
273
    !else
274
      !insertmacro _L${_o} `${_a}` `${_b}` `${_t}` `${_f}`
275
    !endif
276
  !macroend
277
  !macro _P= _a _b _t _f
278
    !insertmacro LogicLib_PtrDiffTest = `${_a}` `${_b}` `${_t}` `${_f}`
279
  !macroend
280
  !macro _P<> _a _b _t _f
281
    !insertmacro LogicLib_PtrDiffTest <> `${_a}` `${_b}` `${_t}` `${_f}`
282
  !macroend
283
  !macro _P< _a _b _t _f
284
    !insertmacro LogicLib_PtrDiffTest < `${_a}` `${_b}` `${_t}` `${_f}`
285
  !macroend
286
  !macro _P>= _a _b _t _f
287
    !insertmacro LogicLib_PtrDiffTest >= `${_a}` `${_b}` `${_t}` `${_f}`
288
  !macroend
289
  !macro _P> _a _b _t _f
290
    !insertmacro LogicLib_PtrDiffTest > `${_a}` `${_b}` `${_t}` `${_f}`
291
  !macroend
292
  !macro _P<= _a _b _t _f
293
    !insertmacro LogicLib_PtrDiffTest <= `${_a}` `${_b}` `${_t}` `${_f}`
294
  !macroend
295
  !include Util.nsh
296
  !macro _Z= _a _b _t _f
297
    !insertmacro LogicLib_PtrDiffTest = `${_a}` `${_b}` `${_t}` `${_f}`
298
  !macroend
299
  !macro _Z<> _a _b _t _f
300
    !insertmacro LogicLib_PtrDiffTest <> `${_a}` `${_b}` `${_t}` `${_f}`
301
  !macroend
302
  !macro _Z< _a _b _t _f
303
    !insertmacro IntPtrCmpU `${_a}` `${_b}` `${_f}` `${_t}` `${_f}`
304
  !macroend
305
  !macro _Z>= _a _b _t _f
306
    !insertmacro IntPtrCmpU `${_a}` `${_b}` `${_t}` `${_f}` `${_t}`
307
  !macroend
308
  !macro _Z> _a _b _t _f
309
    !insertmacro IntPtrCmpU `${_a}` `${_b}` `${_f}` `${_f}` `${_t}`
310
  !macroend
311
  !macro _Z<= _a _b _t _f
312
    !insertmacro IntPtrCmpU `${_a}` `${_b}` `${_t}` `${_t}` `${_f}`
313
  !macroend
314

    
315
  ; Flag tests
316
  !macro _Abort _a _b _t _f
317
    IfAbort `${_t}` `${_f}`
318
  !macroend
319
  !define Abort `"" Abort ""`
320

    
321
  !macro _Errors _a _b _t _f
322
    IfErrors `${_t}` `${_f}`
323
  !macroend
324
  !define Errors `"" Errors ""`
325

    
326
  !macro _FileExists _a _b _t _f
327
    IfFileExists `${_b}` `${_t}` `${_f}`
328
  !macroend
329
  !define FileExists `"" FileExists`
330

    
331
  !macro _RebootFlag _a _b _t _f
332
    IfRebootFlag `${_t}` `${_f}`
333
  !macroend
334
  !define RebootFlag `"" RebootFlag ""`
335

    
336
  !macro _Silent _a _b _t _f
337
    IfSilent `${_t}` `${_f}`
338
  !macroend
339
  !define Silent `"" Silent ""`
340

    
341
  !macro _ShellVarContextAll _a _b _t _f
342
    IfShellVarContextAll `${_t}` `${_f}`
343
  !macroend
344
  !define ShellVarContextAll `"" ShellVarContextAll ""`
345

    
346
  !macro _RtlLanguage _a _b _t _f
347
    IfRtlLanguage `${_t}` `${_f}`
348
  !macroend
349
  !define RtlLanguage `"" RtlLanguage ""`
350

    
351
  !macro _AltRegView _a _b _t _f
352
    IfAltRegView `${_t}` `${_f}`
353
  !macroend
354
  !define AltRegView `"" AltRegView ""`
355

    
356
  !macro _RegKeyIsEmpty _a _b _t _f
357
    !insertmacro _LOGICLIB_TEMP
358
    ClearErrors
359
    EnumRegValue $_LOGICLIB_TEMP ${_a} `${_b}` ""
360
    !if `${_f}` != ``
361
    IfErrors "" `${_f}` ; Skip calls to EnumRegKey and _== if possible
362
    !else
363
    IfErrors +3
364
    StrCpy $_LOGICLIB_TEMP "1" ; The default value is also named "", make sure we don't mistake it as empty
365
    Goto +2
366
    !endif
367
    EnumRegKey $_LOGICLIB_TEMP ${_a} `${_b}` ""
368
    !insertmacro _== $_LOGICLIB_TEMP "" `${_t}` `${_f}`
369
  !macroend
370
  !define RegKeyIsEmpty `RegKeyIsEmpty`
371

    
372
  ; "Any instruction" test
373
  !macro _Cmd _a _b _t _f
374
    !define _t=${_t}
375
    !ifdef _t=                                            ; If no true label then make one
376
      !define __t _LogicLib_Label_${LOGICLIB_COUNTER}
377
      !insertmacro _IncreaseCounter
378
    !else
379
      !define __t ${_t}
380
    !endif
381
    ${_b} ${__t}
382
    !define _f=${_f}
383
    !ifndef _f=                                           ; If a false label then go there
384
      Goto ${_f}
385
    !endif
386
    !undef _f=${_f}
387
    !ifdef _t=                                            ; If we made our own true label then place it
388
      ${__t}:
389
    !endif
390
    !undef __t
391
    !undef _t=${_t}
392
  !macroend
393
  !define Cmd `"" Cmd`
394

    
395
  ; Section flag test
396
  !macro _SectionFlagIsSet _a _b _t _f
397
    !insertmacro _LOGICLIB_TEMP
398
    SectionGetFlags `${_b}` $_LOGICLIB_TEMP
399
    IntOp $_LOGICLIB_TEMP $_LOGICLIB_TEMP & `${_a}`
400
    !insertmacro _= $_LOGICLIB_TEMP `${_a}` `${_t}` `${_f}`
401
  !macroend
402
  !define SectionIsSelected `${SF_SELECTED} SectionFlagIsSet`
403
  !define SectionIsSubSection `${SF_SUBSEC} SectionFlagIsSet`
404
  !define SectionIsSubSectionEnd `${SF_SUBSECEND} SectionFlagIsSet`
405
  !define SectionIsSectionGroup `${SF_SECGRP} SectionFlagIsSet`
406
  !define SectionIsSectionGroupEnd `${SF_SECGRPEND} SectionFlagIsSet`
407
  !define SectionIsBold `${SF_BOLD} SectionFlagIsSet`
408
  !define SectionIsReadOnly `${SF_RO} SectionFlagIsSet`
409
  !define SectionIsExpanded `${SF_EXPAND} SectionFlagIsSet`
410
  !define SectionIsPartiallySelected `${SF_PSELECTED} SectionFlagIsSet`
411

    
412
  !define IfCmd `!insertmacro _IfThen "" Cmd ${|}`
413

    
414
  !macro _If _c _a _o _b
415
    !verbose push
416
    !verbose ${LOGICLIB_VERBOSITY}
417
    !insertmacro _PushLogic
418
    !define ${_Logic}If
419
    !define ${_Logic}Else _LogicLib_ElseLabel_${LOGICLIB_COUNTER} ; Get a label for the Else
420
    !insertmacro _IncreaseCounter
421
    !define _c=${_c}
422
    !ifdef _c=true                                        ; If is true
423
      !insertmacro _${_o} `${_a}` `${_b}` "" ${${_Logic}Else}
424
    !else                                                 ; If condition is false
425
      !insertmacro _${_o} `${_a}` `${_b}` ${${_Logic}Else} ""
426
    !endif
427
    !undef _c=${_c}
428
    !verbose pop
429
  !macroend
430
  !define If     `!insertmacro _If true`
431
  !define Unless `!insertmacro _If false`
432
  !define IfNot  `!insertmacro _If false`
433

    
434
  !macro _And _c _a _o _b
435
    !verbose push
436
    !verbose ${LOGICLIB_VERBOSITY}
437
    !ifndef _Logic | ${_Logic}If
438
      !error "Cannot use And without a preceding If or IfNot/Unless"
439
    !endif
440
    !ifndef ${_Logic}Else
441
      !error "Cannot use And following an Else"
442
    !endif
443
    !define _c=${_c}
444
    !ifdef _c=true                                        ; If is true
445
      !insertmacro _${_o} `${_a}` `${_b}` "" ${${_Logic}Else}
446
    !else                                                 ; If condition is false
447
      !insertmacro _${_o} `${_a}` `${_b}` ${${_Logic}Else} ""
448
    !endif
449
    !undef _c=${_c}
450
    !verbose pop
451
  !macroend
452
  !define AndIf     `!insertmacro _And true`
453
  !define AndUnless `!insertmacro _And false`
454
  !define AndIfNot  `!insertmacro _And false`
455

    
456
  !macro _Or _c _a _o _b
457
    !verbose push
458
    !verbose ${LOGICLIB_VERBOSITY}
459
    !ifndef _Logic | ${_Logic}If
460
      !error "Cannot use Or without a preceding If or IfNot/Unless"
461
    !endif
462
    !ifndef ${_Logic}Else
463
      !error "Cannot use Or following an Else"
464
    !endif
465
    !define _label _LogicLib_Label_${LOGICLIB_COUNTER}    ; Skip this test as we already
466
    !insertmacro _IncreaseCounter
467
    Goto ${_label}                                        ; have a successful result
468
    ${${_Logic}Else}:                                     ; Place the Else label
469
    !undef ${_Logic}Else                                  ; and remove it
470
    !define ${_Logic}Else _LogicLib_ElseLabel_${LOGICLIB_COUNTER} ; Get a label for the next Else and perform the new If
471
    !insertmacro _IncreaseCounter
472
    !define _c=${_c}
473
    !ifdef _c=true                                        ; If is true
474
      !insertmacro _${_o} `${_a}` `${_b}` "" ${${_Logic}Else}
475
    !else                                                 ; If condition is false
476
      !insertmacro _${_o} `${_a}` `${_b}` ${${_Logic}Else} ""
477
    !endif
478
    !undef _c=${_c}
479
    ${_label}:
480
    !undef _label
481
    !verbose pop
482
  !macroend
483
  !define OrIf     `!insertmacro _Or true`
484
  !define OrUnless `!insertmacro _Or false`
485
  !define OrIfNot  `!insertmacro _Or false`
486

    
487
  !macro _Else
488
    !verbose push
489
    !verbose ${LOGICLIB_VERBOSITY}
490
    !ifndef _Logic | ${_Logic}If
491
      !error "Cannot use Else without a preceding If or IfNot/Unless"
492
    !endif
493
    !ifndef ${_Logic}Else
494
      !error "Cannot use Else following an Else"
495
    !endif
496
    !ifndef ${_Logic}EndIf                                ; First Else for this If?
497
      !define ${_Logic}EndIf _LogicLib_EndIfLabel_${LOGICLIB_COUNTER} ; Get a label for the EndIf
498
      !insertmacro _IncreaseCounter
499
    !endif
500
    Goto ${${_Logic}EndIf}                                ; Go to the EndIf
501
    ${${_Logic}Else}:                                     ; Place the Else label
502
    !undef ${_Logic}Else                                  ; and remove it
503
    !verbose pop
504
  !macroend
505
  !define Else `!insertmacro _Else`
506

    
507
  !macro _ElseIf _c _a _o _b
508
    !verbose push
509
    !verbose ${LOGICLIB_VERBOSITY}
510
    ${Else}                                               ; Perform the Else
511
    !define ${_Logic}Else _LogicLib_ElseLabel_${LOGICLIB_COUNTER} ; Get a label for the next Else and perform the new If
512
    !insertmacro _IncreaseCounter
513
    !define _c=${_c}
514
    !ifdef _c=true                                        ; If is true
515
      !insertmacro _${_o} `${_a}` `${_b}` "" ${${_Logic}Else}
516
    !else                                                 ; If condition is false
517
      !insertmacro _${_o} `${_a}` `${_b}` ${${_Logic}Else} ""
518
    !endif
519
    !undef _c=${_c}
520
    !verbose pop
521
  !macroend
522
  !define ElseIf     `!insertmacro _ElseIf true`
523
  !define ElseUnless `!insertmacro _ElseIf false`
524
  !define ElseIfNot  `!insertmacro _ElseIf false`
525

    
526
  !macro _EndIf _n
527
    !verbose push
528
    !verbose ${LOGICLIB_VERBOSITY}
529
    !ifndef _Logic | ${_Logic}If
530
      !error "Cannot use End${_n} without a preceding If or IfNot/Unless"
531
    !endif
532
    !ifdef ${_Logic}Else
533
      ${${_Logic}Else}:                                   ; Place the Else label
534
      !undef ${_Logic}Else                                ; and remove it
535
    !endif
536
    !ifdef ${_Logic}EndIf
537
      ${${_Logic}EndIf}:                                  ; Place the EndIf
538
      !undef ${_Logic}EndIf                               ; and remove it
539
    !endif
540
    !undef ${_Logic}If
541
    !insertmacro _PopLogic
542
    !verbose pop
543
  !macroend
544
  !define EndIf     `!insertmacro _EndIf If`
545
  !define EndUnless `!insertmacro _EndIf Unless`
546

    
547
  !macro _IfThen _a _o _b _t
548
    !verbose push
549
    !verbose ${LOGICLIB_VERBOSITY}
550
    ${If} `${_a}` `${_o}` `${_b}`
551
      ${_t}
552
    ${EndIf}
553
    !verbose pop
554
  !macroend
555
  !define IfThen `!insertmacro _IfThen`
556

    
557
  !macro _IfNotThen _a _o _b _t
558
    !verbose push
559
    !verbose ${LOGICLIB_VERBOSITY}
560
    ${IfNot} `${_a}` `${_o}` `${_b}`
561
      ${_t}
562
    ${EndIf}
563
    !verbose pop
564
  !macroend
565
  !define IfNotThen `!insertmacro _IfNotThen`
566

    
567
  !macro _ForEach _v _f _t _o _s
568
    !verbose push
569
    !verbose ${LOGICLIB_VERBOSITY}
570
    StrCpy "${_v}" "${_f}"                                ; Assign the initial value
571
    Goto +2                                               ; Skip the loop expression for the first iteration
572
    !define _DoLoopExpression `IntOp "${_v}" "${_v}" "${_o}" "${_s}"` ; Define the loop expression
573
    !define _o=${_o}
574
    !ifdef _o=+                                           ; Check the loop expression operator
575
      !define __o >                                       ; to determine the correct loop condition
576
    !else ifdef _o=-
577
      !define __o <
578
    !else
579
      !error "Unsupported ForEach step operator (must be + or -)"
580
    !endif
581
    !undef _o=${_o}
582
    !insertmacro _Do For false `${_v}` `${__o}` `${_t}`   ; Let Do do the rest
583
    !undef __o
584
    !verbose pop
585
  !macroend
586
  !define ForEach `!insertmacro _ForEach`
587

    
588
  !macro _For _v _f _t
589
    !verbose push
590
    !verbose ${LOGICLIB_VERBOSITY}
591
    ${ForEach} `${_v}` `${_f}` `${_t}` + 1                ; Pass on to ForEach
592
    !verbose pop
593
  !macroend
594
  !define For `!insertmacro _For`
595

    
596
  !define ExitFor `!insertmacro _Goto ExitFor For`
597

    
598
  !define Next      `!insertmacro _Loop For Next "" "" "" ""`
599

    
600
  !define While     `!insertmacro _Do While true`
601

    
602
  !define ExitWhile `!insertmacro _Goto ExitWhile While`
603

    
604
  !define EndWhile  `!insertmacro _Loop While EndWhile "" "" "" ""`
605

    
606
  !macro _Do _n _c _a _o _b
607
    !verbose push
608
    !verbose ${LOGICLIB_VERBOSITY}
609
    !insertmacro _PushLogic
610
    !define ${_Logic}${_n} _LogicLib_Label_${LOGICLIB_COUNTER} ; Get a label for the start of the loop
611
    !insertmacro _IncreaseCounter
612
    ${${_Logic}${_n}}:
613
    !insertmacro _PushScope Exit${_n} _LogicLib_Label_${LOGICLIB_COUNTER} ; Get a label for the end of the loop
614
    !insertmacro _IncreaseCounter
615
    !insertmacro _PushScope Break ${_Exit${_n}}           ; Break goes to the end of the loop
616
    !ifdef _DoLoopExpression
617
      ${_DoLoopExpression}                                ; Special extra parameter for inserting code
618
      !undef _DoLoopExpression                            ; between the Continue label and the loop condition
619
    !endif
620
    !define _c=${_c}
621
    !ifdef _c=                                            ; No starting condition
622
      !insertmacro _PushScope Continue _LogicLib_Label_${LOGICLIB_COUNTER} ; Get a label for Continue at the end of the loop
623
      !insertmacro _IncreaseCounter
624
    !else
625
      !insertmacro _PushScope Continue ${${_Logic}${_n}}  ; Continue goes to the start of the loop
626
      !ifdef _c=true                                      ; If is true
627
        !insertmacro _${_o} `${_a}` `${_b}` "" ${_Exit${_n}}
628
      !else                                               ; If condition is false
629
        !insertmacro _${_o} `${_a}` `${_b}` ${_Exit${_n}} ""
630
      !endif
631
    !endif
632
    !undef _c=${_c}
633
    !define ${_Logic}Condition ${_c}                      ; Remember the condition used
634
    !verbose pop
635
  !macroend
636
  !define Do      `!insertmacro _Do Do "" "" "" ""`
637
  !define DoWhile `!insertmacro _Do Do true`
638
  !define DoUntil `!insertmacro _Do Do false`
639

    
640
  !macro _Goto _n _s
641
    !verbose push
642
    !verbose ${LOGICLIB_VERBOSITY}
643
    !ifndef _${_n}
644
      !error "Cannot use ${_n} without a preceding ${_s}"
645
    !endif
646
    Goto ${_${_n}}
647
    !verbose pop
648
  !macroend
649
  !define ExitDo   `!insertmacro _Goto ExitDo Do`
650

    
651
  !macro _Loop _n _e _c _a _o _b
652
    !verbose push
653
    !verbose ${LOGICLIB_VERBOSITY}
654
    !ifndef _Logic | ${_Logic}${_n}
655
      !error "Cannot use ${_e} without a preceding ${_n}"
656
    !endif
657
    !define _c=${${_Logic}Condition}
658
    !ifdef _c=                                            ; If Do had no condition place the Continue label
659
      ${_Continue}:
660
    !endif
661
    !undef _c=${${_Logic}Condition}
662
    !define _c=${_c}
663
    !ifdef _c=                                            ; No ending condition
664
      Goto ${${_Logic}${_n}}
665
    !else ifdef _c=true                                   ; If condition is true
666
      !insertmacro _${_o} `${_a}` `${_b}` ${${_Logic}${_n}} ${_Exit${_n}}
667
    !else                                                 ; If condition is false
668
      !insertmacro _${_o} `${_a}` `${_b}` ${_Exit${_n}} ${${_Logic}${_n}}
669
    !endif
670
    !undef _c=${_c}
671
    Goto ${_Continue}                                     ; Just to ensure it is referenced at least once
672
    Goto ${_Exit${_n}}                                    ; Just to ensure it is referenced at least once
673
    ${_Exit${_n}}:                                        ; Place the loop exit point
674
    !undef ${_Logic}Condition
675
    !insertmacro _PopScope Continue
676
    !insertmacro _PopScope Break
677
    !insertmacro _PopScope Exit${_n}
678
    !undef ${_Logic}${_n}
679
    !insertmacro _PopLogic
680
    !verbose pop
681
  !macroend
682
  !define Loop      `!insertmacro _Loop Do Loop "" "" "" ""`
683
  !define LoopWhile `!insertmacro _Loop Do LoopWhile true`
684
  !define LoopUntil `!insertmacro _Loop Do LoopUntil false`
685

    
686
  !define Continue `!insertmacro _Goto Continue "For or Do or While"`
687
  !define Break    `!insertmacro _Goto Break "For or Do or While"`
688

    
689
  !macro _Select _a
690
    !verbose push
691
    !verbose ${LOGICLIB_VERBOSITY}
692
    !insertmacro _PushLogic
693
    !define ${_Logic}Select `${_a}`                       ; Remember the left hand side of the comparison
694
    !verbose pop
695
  !macroend
696
  !define Select `!insertmacro _Select`
697

    
698
  !macro _Select_CaseElse
699
    !verbose push
700
    !verbose ${LOGICLIB_VERBOSITY}
701
    !ifndef _Logic | ${_Logic}Select
702
      !error "Cannot use Case without a preceding Select"
703
    !endif
704
    !ifdef ${_Logic}EndSelect                             ; This is set only after the first case
705
      !ifndef ${_Logic}Else
706
        !error "Cannot use Case following a CaseElse"
707
      !endif
708
      Goto ${${_Logic}EndSelect}                          ; Go to EndSelect (Ends the previous Case)
709
      !define /IfNDef _LogicLib_EndSelectLabelUsed_${_Logic}
710
      ${${_Logic}Else}:                                   ; Place the Else label
711
      !undef ${_Logic}Else                                ; and remove it
712
    !else
713
      !define ${_Logic}EndSelect _LogicLib_EndSelectLabel_${LOGICLIB_COUNTER} ; Get a label for the EndSelect
714
      !insertmacro _IncreaseCounter
715
    !endif
716
    !verbose pop
717
  !macroend
718
  !define CaseElse `!insertmacro _CaseElse`
719
  !define Case_Else `!insertmacro _CaseElse`              ; Compatibility with 2.2 and earlier
720
  !define Default `!insertmacro _CaseElse`                ; For the C-minded
721

    
722
  !macro _Select_Case _a
723
    !verbose push
724
    !verbose ${LOGICLIB_VERBOSITY}
725
    ${CaseElse}                                           ; Perform the CaseElse
726
    !define ${_Logic}Else _LogicLib_NextSelectCaseLabel_${LOGICLIB_COUNTER} ; Get a label for the next Else and perform the new Case
727
    !insertmacro _IncreaseCounter
728
    !insertmacro _== `${${_Logic}Select}` `${_a}` "" ${${_Logic}Else}
729
    !verbose pop
730
  !macroend
731
  !define Case `!insertmacro _Case`
732

    
733
  !macro _Case2 _a _b
734
    !verbose push
735
    !verbose ${LOGICLIB_VERBOSITY}
736
    ${CaseElse}                                           ; Perform the CaseElse
737
    !define ${_Logic}Else _LogicLib_NextSelectCaseLabel_${LOGICLIB_COUNTER} ; Get a label for the next Else and perform the new Case
738
    !insertmacro _IncreaseCounter
739
    !insertmacro _== `${${_Logic}Select}` `${_a}` +2 ""
740
    !insertmacro _== `${${_Logic}Select}` `${_b}` "" ${${_Logic}Else}
741
    !verbose pop
742
  !macroend
743
  !define Case2 `!insertmacro _Case2`
744

    
745
  !macro _Case3 _a _b _c
746
    !verbose push
747
    !verbose ${LOGICLIB_VERBOSITY}
748
    ${CaseElse}                                           ; Perform the CaseElse
749
    !define ${_Logic}Else _LogicLib_NextSelectCaseLabel_${LOGICLIB_COUNTER} ; Get a label for the next Else and perform the new Case
750
    !insertmacro _IncreaseCounter
751
    !insertmacro _== `${${_Logic}Select}` `${_a}` +3 ""
752
    !insertmacro _== `${${_Logic}Select}` `${_b}` +2 ""
753
    !insertmacro _== `${${_Logic}Select}` `${_c}` "" ${${_Logic}Else}
754
    !verbose pop
755
  !macroend
756
  !define Case3 `!insertmacro _Case3`
757

    
758
  !macro _Case4 _a _b _c _d
759
    !verbose push
760
    !verbose ${LOGICLIB_VERBOSITY}
761
    ${CaseElse}                                           ; Perform the CaseElse
762
    !define ${_Logic}Else _LogicLib_NextSelectCaseLabel_${LOGICLIB_COUNTER} ; Get a label for the next Else and perform the new Case
763
    !insertmacro _IncreaseCounter
764
    !insertmacro _== `${${_Logic}Select}` `${_a}` +4 ""
765
    !insertmacro _== `${${_Logic}Select}` `${_b}` +3 ""
766
    !insertmacro _== `${${_Logic}Select}` `${_c}` +2 ""
767
    !insertmacro _== `${${_Logic}Select}` `${_d}` "" ${${_Logic}Else}
768
    !verbose pop
769
  !macroend
770
  !define Case4 `!insertmacro _Case4`
771

    
772
  !macro _Case5 _a _b _c _d _e
773
    !verbose push
774
    !verbose ${LOGICLIB_VERBOSITY}
775
    ${CaseElse}                                           ; Perform the CaseElse
776
    !define ${_Logic}Else _LogicLib_NextSelectCaseLabel_${LOGICLIB_COUNTER} ; Get a label for the next Else and perform the new Case
777
    !insertmacro _IncreaseCounter
778
    !insertmacro _== `${${_Logic}Select}` `${_a}` +5 ""
779
    !insertmacro _== `${${_Logic}Select}` `${_b}` +4 ""
780
    !insertmacro _== `${${_Logic}Select}` `${_c}` +3 ""
781
    !insertmacro _== `${${_Logic}Select}` `${_d}` +2 ""
782
    !insertmacro _== `${${_Logic}Select}` `${_e}` "" ${${_Logic}Else}
783
    !verbose pop
784
  !macroend
785
  !define Case5 `!insertmacro _Case5`
786

    
787
  !macro _EndSelect
788
    !verbose push
789
    !verbose ${LOGICLIB_VERBOSITY}
790
    !ifndef _Logic | ${_Logic}Select
791
      !error "Cannot use EndSelect without a preceding Select"
792
    !endif
793
    !ifdef ${_Logic}Else
794
      ${${_Logic}Else}:                                   ; Place the Else label
795
      !undef ${_Logic}Else                                ; and remove it
796
    !endif
797
    !ifdef ${_Logic}EndSelect                             ; This won't be set if there weren't any cases
798
      !ifdef _LogicLib_EndSelectLabelUsed_${_Logic}                 ; There is no jump to ${${_Logic}EndSelect}: if there is only one Case
799
        ${${_Logic}EndSelect}:                            ; Place the EndSelect
800
        !undef _LogicLib_EndSelectLabelUsed_${_Logic}
801
      !endif
802
      !undef ${_Logic}EndSelect                           ; and remove it
803
    !endif
804
    !undef ${_Logic}Select
805
    !insertmacro _PopLogic
806
    !verbose pop
807
  !macroend
808
  !define EndSelect `!insertmacro _EndSelect`
809

    
810
  !macro _Switch _a
811
    !verbose push
812
    !verbose ${LOGICLIB_VERBOSITY}
813
    !insertmacro _PushLogic
814
    !insertmacro _PushScope Switch ${_Logic}              ; Keep a separate stack for switch data
815
    !insertmacro _PushScope Break _LogicLib_Label_${LOGICLIB_COUNTER} ; Get a lable for beyond the end of the switch
816
    !insertmacro _IncreaseCounter
817
    !define ${_Switch}Var `${_a}`                         ; Remember the left hand side of the comparison
818
    !tempfile ${_Switch}Tmp                               ; Create a temporary file
819
    !define ${_Logic}Switch _LogicLib_Label_${LOGICLIB_COUNTER} ; Get a label for the end of the switch
820
    !insertmacro _IncreaseCounter
821
    Goto ${${_Logic}Switch}                               ; and go there
822
    !verbose pop
823
  !macroend
824
  !define Switch `!insertmacro _Switch`
825

    
826
  !macro _Case _a
827
    !verbose push
828
    !verbose ${LOGICLIB_VERBOSITY}
829
    !ifdef _Logic & ${_Logic}Select                       ; Check for an active Select
830
      !insertmacro _Select_Case `${_a}`
831
    !else ifndef _Switch                                  ; If not then check for an active Switch
832
      !error "Cannot use Case without a preceding Select or Switch"
833
    !else
834
      !define _label _LogicLib_Label_${LOGICLIB_COUNTER}  ; Get a label for this case,
835
      !insertmacro _IncreaseCounter
836
      ${_label}:                                          ; place it and add it's check to the temp file
837
      !appendfile "${${_Switch}Tmp}" `!insertmacro _== $\`${${_Switch}Var}$\` $\`${_a}$\` ${_label} ""$\n`
838
      !undef _label
839
    !endif
840
    !verbose pop
841
  !macroend
842

    
843
  !macro _CaseElse
844
    !verbose push
845
    !verbose ${LOGICLIB_VERBOSITY}
846
    !ifdef _Logic & ${_Logic}Select                       ; Check for an active Select
847
      !insertmacro _Select_CaseElse
848
    !else ifndef _Switch                                  ; If not then check for an active Switch
849
      !error "Cannot use Case without a preceding Select or Switch"
850
    !else ifdef ${_Switch}Else                            ; Already had a default case?
851
      !error "Cannot use CaseElse following a CaseElse"
852
    !else
853
      !define ${_Switch}Else _LogicLib_Label_${LOGICLIB_COUNTER} ; Get a label for the default case,
854
      !insertmacro _IncreaseCounter
855
      ${${_Switch}Else}:                                  ; and place it
856
    !endif
857
    !verbose pop
858
  !macroend
859

    
860
  !macro _EndSwitch
861
    !verbose push
862
    !verbose ${LOGICLIB_VERBOSITY}
863
    !ifndef _Logic | ${_Logic}Switch
864
      !error "Cannot use EndSwitch without a preceding Switch"
865
    !endif
866
    Goto ${_Break}                                        ; Skip the jump table
867
    ${${_Logic}Switch}:                                   ; Place the end of the switch
868
    !undef ${_Logic}Switch
869
    !include "${${_Switch}Tmp}"                           ; Include the jump table
870
    !delfile "${${_Switch}Tmp}"                           ; and clear it up
871
    !ifdef ${_Switch}Else                                 ; Was there a default case?
872
      Goto ${${_Switch}Else}                              ; then go there if all else fails
873
      !undef ${_Switch}Else
874
    !endif
875
    !undef ${_Switch}Tmp
876
    !undef ${_Switch}Var
877
    ${_Break}:                                            ; Place the break label
878
    !insertmacro _PopScope Break
879
    !insertmacro _PopScope Switch
880
    !insertmacro _PopLogic
881
    !verbose pop
882
  !macroend
883
  !define EndSwitch `!insertmacro _EndSwitch`
884

    
885
!endif ; LOGICLIB
886
!verbose 3
887
!define LOGICLIB_VERBOSITY ${_LOGICLIB_VERBOSITY}
888
!undef _LOGICLIB_VERBOSITY
889
!verbose pop