Statistiques
| Révision :

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

Historique | Voir | Annoter | Télécharger (30,74 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
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}
61
;       Built-in NSIS other tests:
62
;         ${FileExists} a
63
;       Any conditional NSIS instruction test:
64
;         ${Cmd} a
65
;       Section flag tests:
66
;         ${SectionIsSelected} a; ${SectionIsSectionGroup} a;
67
;         ${SectionIsSectionGroupEnd} a; ${SectionIsBold} a;
68
;         ${SectionIsReadOnly} a; ${SectionIsExpanded} a;
69
;         ${SectionIsPartiallySelected} a
70
;
71
; Examples:
72
;   See LogicLib.nsi in the Examples folder for lots of example usage.
73

    
74
!verbose push
75
!verbose 3
76
!ifndef LOGICLIB_VERBOSITY
77
  !define LOGICLIB_VERBOSITY 3
78
!endif
79
!define _LOGICLIB_VERBOSITY ${LOGICLIB_VERBOSITY}
80
!undef LOGICLIB_VERBOSITY
81
!verbose ${_LOGICLIB_VERBOSITY}
82

    
83
!ifndef LOGICLIB
84
  !define LOGICLIB
85
  !define | "'"
86
  !define || "' '"
87
  !define LOGICLIB_COUNTER 0
88

    
89
  !include Sections.nsh
90

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

    
98
  !macro _IncreaseCounter
99
    !define _LOGICLIB_COUNTER ${LOGICLIB_COUNTER}
100
    !undef LOGICLIB_COUNTER
101
    !define /math LOGICLIB_COUNTER ${_LOGICLIB_COUNTER} + 1
102
    !undef _LOGICLIB_COUNTER
103
  !macroend
104

    
105
  !macro _PushLogic
106
    !insertmacro _PushScope Logic _LogicLib_Label_${LOGICLIB_COUNTER}
107
    !insertmacro _IncreaseCounter
108
  !macroend
109

    
110
  !macro _PopLogic
111
    !insertmacro _PopScope Logic
112
  !macroend
113

    
114
  !macro _PushScope Type label
115
    !ifdef _${Type}                                       ; If we already have a statement
116
      !define _Cur${Type} ${_${Type}}
117
      !undef _${Type}
118
      !define _${Type} ${label}
119
      !define ${_${Type}}Prev${Type} ${_Cur${Type}}       ; Save the current logic
120
      !undef _Cur${Type}
121
    !else
122
      !define _${Type} ${label}                           ; Initialise for first statement
123
    !endif
124
  !macroend
125

    
126
  !macro _PopScope Type
127
    !ifndef _${Type}
128
      !error "Cannot use _Pop${Type} without a preceding _Push${Type}"
129
    !endif
130
    !ifdef ${_${Type}}Prev${Type}                         ; If a previous statment was active then restore it
131
      !define _Cur${Type} ${_${Type}}
132
      !undef _${Type}
133
      !define _${Type} ${${_Cur${Type}}Prev${Type}}
134
      !undef ${_Cur${Type}}Prev${Type}
135
      !undef _Cur${Type}
136
    !else
137
      !undef _${Type}
138
    !endif
139
  !macroend
140

    
141
  ; String tests
142
  !macro _== _a _b _t _f
143
    StrCmp `${_a}` `${_b}` `${_t}` `${_f}`
144
  !macroend
145

    
146
  !macro _!= _a _b _t _f
147
    !insertmacro _== `${_a}` `${_b}` `${_f}` `${_t}`
148
  !macroend
149

    
150
  ; Case-sensitive string tests
151
  !macro _S== _a _b _t _f
152
    StrCmpS `${_a}` `${_b}` `${_t}` `${_f}`
153
  !macroend
154

    
155
  !macro _S!= _a _b _t _f
156
    !insertmacro _S== `${_a}` `${_b}` `${_f}` `${_t}`
157
  !macroend
158

    
159
  ; Extra string tests (cannot do these case-sensitively - I tried and lstrcmp still ignored the case)
160
  !macro _StrCmpI _a _b _e _l _m
161
    !insertmacro _LOGICLIB_TEMP
162
    System::Call `kernel32::lstrcmpiA(ts, ts) i.s` `${_a}` `${_b}`
163
    Pop $_LOGICLIB_TEMP
164
    IntCmp $_LOGICLIB_TEMP 0 `${_e}` `${_l}` `${_m}`
165
  !macroend
166

    
167
  !macro _S< _a _b _t _f
168
    !insertmacro _StrCmpI `${_a}` `${_b}` `${_f}` `${_t}` `${_f}`
169
  !macroend
170

    
171
  !macro _S>= _a _b _t _f
172
    !insertmacro _S< `${_a}` `${_b}` `${_f}` `${_t}`
173
  !macroend
174

    
175
  !macro _S> _a _b _t _f
176
    !insertmacro _StrCmpI `${_a}` `${_b}` `${_f}` `${_f}` `${_t}`
177
  !macroend
178

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

    
183
  ; Integer tests
184
  !macro _= _a _b _t _f
185
    IntCmp `${_a}` `${_b}` `${_t}` `${_f}` `${_f}`
186
  !macroend
187

    
188
  !macro _<> _a _b _t _f
189
    !insertmacro _= `${_a}` `${_b}` `${_f}` `${_t}`
190
  !macroend
191

    
192
  !macro _< _a _b _t _f
193
    IntCmp `${_a}` `${_b}` `${_f}` `${_t}` `${_f}`
194
  !macroend
195

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

    
200
  !macro _> _a _b _t _f
201
    IntCmp `${_a}` `${_b}` `${_f}` `${_f}` `${_t}`
202
  !macroend
203

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

    
208
  ; Unsigned integer tests (NB: no need for extra equality tests)
209
  !macro _U< _a _b _t _f
210
    IntCmpU `${_a}` `${_b}` `${_f}` `${_t}` `${_f}`
211
  !macroend
212

    
213
  !macro _U>= _a _b _t _f
214
    !insertmacro _U< `${_a}` `${_b}` `${_f}` `${_t}`
215
  !macroend
216

    
217
  !macro _U> _a _b _t _f
218
    IntCmpU `${_a}` `${_b}` `${_f}` `${_f}` `${_t}`
219
  !macroend
220

    
221
  !macro _U<= _a _b _t _f
222
    !insertmacro _U> `${_a}` `${_b}` `${_f}` `${_t}`
223
  !macroend
224

    
225
  ; Int64 tests
226
  !macro _Int64Cmp _a _o _b _t _f
227
    !insertmacro _LOGICLIB_TEMP
228
    System::Int64Op `${_a}` `${_o}` `${_b}`
229
    Pop $_LOGICLIB_TEMP
230
    !insertmacro _= $_LOGICLIB_TEMP 0 `${_f}` `${_t}`
231
  !macroend
232

    
233
  !macro _L= _a _b _t _f
234
    !insertmacro _Int64Cmp `${_a}` = `${_b}` `${_t}` `${_f}`
235
  !macroend
236

    
237
  !macro _L<> _a _b _t _f
238
    !insertmacro _L= `${_a}` `${_b}` `${_f}` `${_t}`
239
  !macroend
240

    
241
  !macro _L< _a _b _t _f
242
    !insertmacro _Int64Cmp `${_a}` < `${_b}` `${_t}` `${_f}`
243
  !macroend
244

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

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

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

    
257
  ; ptrdiff_t & size_t tests
258
  !macro _P= _a _b _t _f
259
    !insertmacro _= `${_a}` `${_b}` `${_t}` `${_f}`
260
  !macroend
261
  !macro _P<> _a _b _t _f
262
    !insertmacro _<> `${_a}` `${_b}` `${_t}` `${_f}`
263
  !macroend
264
  !macro _P< _a _b _t _f
265
    !insertmacro _< `${_a}` `${_b}` `${_t}` `${_f}`
266
  !macroend
267
  !macro _P>= _a _b _t _f
268
    !insertmacro _>= `${_a}` `${_b}` `${_t}` `${_f}`
269
  !macroend
270
  !macro _P> _a _b _t _f
271
    !insertmacro _> `${_a}` `${_b}` `${_t}` `${_f}`
272
  !macroend
273
  !macro _P<= _a _b _t _f
274
    !insertmacro _<= `${_a}` `${_b}` `${_t}` `${_f}`
275
  !macroend
276
  !macro _Z= _a _b _t _f
277
    !insertmacro _= `${_a}` `${_b}` `${_t}` `${_f}`
278
  !macroend
279
  !macro _Z<> _a _b _t _f
280
    !insertmacro _<> `${_a}` `${_b}` `${_t}` `${_f}`
281
  !macroend
282
  !macro _Z< _a _b _t _f
283
    !insertmacro _U< `${_a}` `${_b}` `${_t}` `${_f}`
284
  !macroend
285
  !macro _Z>= _a _b _t _f
286
    !insertmacro _U>= `${_a}` `${_b}` `${_t}` `${_f}`
287
  !macroend
288
  !macro _Z> _a _b _t _f
289
    !insertmacro _U> `${_a}` `${_b}` `${_t}` `${_f}`
290
  !macroend
291
  !macro _Z<= _a _b _t _f
292
    !insertmacro _U<= `${_a}` `${_b}` `${_t}` `${_f}`
293
  !macroend
294

    
295
  ; Flag tests
296
  !macro _Abort _a _b _t _f
297
    IfAbort `${_t}` `${_f}`
298
  !macroend
299
  !define Abort `"" Abort ""`
300

    
301
  !macro _Errors _a _b _t _f
302
    IfErrors `${_t}` `${_f}`
303
  !macroend
304
  !define Errors `"" Errors ""`
305

    
306
  !macro _FileExists _a _b _t _f
307
    IfFileExists `${_b}` `${_t}` `${_f}`
308
  !macroend
309
  !define FileExists `"" FileExists`
310

    
311
  !macro _RebootFlag _a _b _t _f
312
    IfRebootFlag `${_t}` `${_f}`
313
  !macroend
314
  !define RebootFlag `"" RebootFlag ""`
315

    
316
  !macro _Silent _a _b _t _f
317
    IfSilent `${_t}` `${_f}`
318
  !macroend
319
  !define Silent `"" Silent ""`
320

    
321
  ; "Any instruction" test
322
  !macro _Cmd _a _b _t _f
323
    !define _t=${_t}
324
    !ifdef _t=                                            ; If no true label then make one
325
      !define __t _LogicLib_Label_${LOGICLIB_COUNTER}
326
      !insertmacro _IncreaseCounter
327
    !else
328
      !define __t ${_t}
329
    !endif
330
    ${_b} ${__t}
331
    !define _f=${_f}
332
    !ifndef _f=                                           ; If a false label then go there
333
      Goto ${_f}
334
    !endif
335
    !undef _f=${_f}
336
    !ifdef _t=                                            ; If we made our own true label then place it
337
      ${__t}:
338
    !endif
339
    !undef __t
340
    !undef _t=${_t}
341
  !macroend
342
  !define Cmd `"" Cmd`
343

    
344
  ; Section flag test
345
  !macro _SectionFlagIsSet _a _b _t _f
346
    !insertmacro _LOGICLIB_TEMP
347
    SectionGetFlags `${_b}` $_LOGICLIB_TEMP
348
    IntOp $_LOGICLIB_TEMP $_LOGICLIB_TEMP & `${_a}`
349
    !insertmacro _= $_LOGICLIB_TEMP `${_a}` `${_t}` `${_f}`
350
  !macroend
351
  !define SectionIsSelected `${SF_SELECTED} SectionFlagIsSet`
352
  !define SectionIsSubSection `${SF_SUBSEC} SectionFlagIsSet`
353
  !define SectionIsSubSectionEnd `${SF_SUBSECEND} SectionFlagIsSet`
354
  !define SectionIsSectionGroup `${SF_SECGRP} SectionFlagIsSet`
355
  !define SectionIsSectionGroupEnd `${SF_SECGRPEND} SectionFlagIsSet`
356
  !define SectionIsBold `${SF_BOLD} SectionFlagIsSet`
357
  !define SectionIsReadOnly `${SF_RO} SectionFlagIsSet`
358
  !define SectionIsExpanded `${SF_EXPAND} SectionFlagIsSet`
359
  !define SectionIsPartiallySelected `${SF_PSELECTED} SectionFlagIsSet`
360

    
361
  !define IfCmd `!insertmacro _IfThen "" Cmd ${|}`
362

    
363
  !macro _If _c _a _o _b
364
    !verbose push
365
    !verbose ${LOGICLIB_VERBOSITY}
366
    !insertmacro _PushLogic
367
    !define ${_Logic}If
368
    !define ${_Logic}Else _LogicLib_Label_${LOGICLIB_COUNTER}                    ; Get a label for the Else
369
    !insertmacro _IncreaseCounter
370
    !define _c=${_c}
371
    !ifdef _c=true                                        ; If is true
372
      !insertmacro _${_o} `${_a}` `${_b}` "" ${${_Logic}Else}
373
    !else                                                 ; If condition is false
374
      !insertmacro _${_o} `${_a}` `${_b}` ${${_Logic}Else} ""
375
    !endif
376
    !undef _c=${_c}
377
    !verbose pop
378
  !macroend
379
  !define If     `!insertmacro _If true`
380
  !define Unless `!insertmacro _If false`
381
  !define IfNot  `!insertmacro _If false`
382

    
383
  !macro _And _c _a _o _b
384
    !verbose push
385
    !verbose ${LOGICLIB_VERBOSITY}
386
    !ifndef _Logic | ${_Logic}If
387
      !error "Cannot use And without a preceding If or IfNot/Unless"
388
    !endif
389
    !ifndef ${_Logic}Else
390
      !error "Cannot use And following an Else"
391
    !endif
392
    !define _c=${_c}
393
    !ifdef _c=true                                        ; If is true
394
      !insertmacro _${_o} `${_a}` `${_b}` "" ${${_Logic}Else}
395
    !else                                                 ; If condition is false
396
      !insertmacro _${_o} `${_a}` `${_b}` ${${_Logic}Else} ""
397
    !endif
398
    !undef _c=${_c}
399
    !verbose pop
400
  !macroend
401
  !define AndIf     `!insertmacro _And true`
402
  !define AndUnless `!insertmacro _And false`
403
  !define AndIfNot  `!insertmacro _And false`
404

    
405
  !macro _Or _c _a _o _b
406
    !verbose push
407
    !verbose ${LOGICLIB_VERBOSITY}
408
    !ifndef _Logic | ${_Logic}If
409
      !error "Cannot use Or without a preceding If or IfNot/Unless"
410
    !endif
411
    !ifndef ${_Logic}Else
412
      !error "Cannot use Or following an Else"
413
    !endif
414
    !define _label _LogicLib_Label_${LOGICLIB_COUNTER}                           ; Skip this test as we already
415
    !insertmacro _IncreaseCounter
416
    Goto ${_label}                                        ; have a successful result
417
    ${${_Logic}Else}:                                     ; Place the Else label
418
    !undef ${_Logic}Else                                  ; and remove it
419
    !define ${_Logic}Else _LogicLib_Label_${LOGICLIB_COUNTER}                    ; Get a label for the next Else and perform the new If
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
    ${_label}:
429
    !undef _label
430
    !verbose pop
431
  !macroend
432
  !define OrIf     `!insertmacro _Or true`
433
  !define OrUnless `!insertmacro _Or false`
434
  !define OrIfNot  `!insertmacro _Or false`
435

    
436
  !macro _Else
437
    !verbose push
438
    !verbose ${LOGICLIB_VERBOSITY}
439
    !ifndef _Logic | ${_Logic}If
440
      !error "Cannot use Else without a preceding If or IfNot/Unless"
441
    !endif
442
    !ifndef ${_Logic}Else
443
      !error "Cannot use Else following an Else"
444
    !endif
445
    !ifndef ${_Logic}EndIf                                ; First Else for this If?
446
      !define ${_Logic}EndIf _LogicLib_Label_${LOGICLIB_COUNTER}                 ; Get a label for the EndIf
447
      !insertmacro _IncreaseCounter
448
    !endif
449
    Goto ${${_Logic}EndIf}                                ; Go to the EndIf
450
    ${${_Logic}Else}:                                     ; Place the Else label
451
    !undef ${_Logic}Else                                  ; and remove it
452
    !verbose pop
453
  !macroend
454
  !define Else `!insertmacro _Else`
455

    
456
  !macro _ElseIf _c _a _o _b
457
    !verbose push
458
    !verbose ${LOGICLIB_VERBOSITY}
459
    ${Else}                                               ; Perform the Else
460
    !define ${_Logic}Else _LogicLib_Label_${LOGICLIB_COUNTER}                    ; Get a label for the next Else and perform the new If
461
    !insertmacro _IncreaseCounter
462
    !define _c=${_c}
463
    !ifdef _c=true                                        ; If is true
464
      !insertmacro _${_o} `${_a}` `${_b}` "" ${${_Logic}Else}
465
    !else                                                 ; If condition is false
466
      !insertmacro _${_o} `${_a}` `${_b}` ${${_Logic}Else} ""
467
    !endif
468
    !undef _c=${_c}
469
    !verbose pop
470
  !macroend
471
  !define ElseIf     `!insertmacro _ElseIf true`
472
  !define ElseUnless `!insertmacro _ElseIf false`
473
  !define ElseIfNot  `!insertmacro _ElseIf false`
474

    
475
  !macro _EndIf _n
476
    !verbose push
477
    !verbose ${LOGICLIB_VERBOSITY}
478
    !ifndef _Logic | ${_Logic}If
479
      !error "Cannot use End${_n} without a preceding If or IfNot/Unless"
480
    !endif
481
    !ifdef ${_Logic}Else
482
      ${${_Logic}Else}:                                   ; Place the Else label
483
      !undef ${_Logic}Else                                ; and remove it
484
    !endif
485
    !ifdef ${_Logic}EndIf
486
      ${${_Logic}EndIf}:                                  ; Place the EndIf
487
      !undef ${_Logic}EndIf                               ; and remove it
488
    !endif
489
    !undef ${_Logic}If
490
    !insertmacro _PopLogic
491
    !verbose pop
492
  !macroend
493
  !define EndIf     `!insertmacro _EndIf If`
494
  !define EndUnless `!insertmacro _EndIf Unless`
495

    
496
  !macro _IfThen _a _o _b _t
497
    !verbose push
498
    !verbose ${LOGICLIB_VERBOSITY}
499
    ${If} `${_a}` `${_o}` `${_b}`
500
      ${_t}
501
    ${EndIf}
502
    !verbose pop
503
  !macroend
504
  !define IfThen `!insertmacro _IfThen`
505

    
506
  !macro _IfNotThen _a _o _b _t
507
    !verbose push
508
    !verbose ${LOGICLIB_VERBOSITY}
509
    ${IfNot} `${_a}` `${_o}` `${_b}`
510
      ${_t}
511
    ${EndIf}
512
    !verbose pop
513
  !macroend
514
  !define IfNotThen `!insertmacro _IfNotThen`
515

    
516
  !macro _ForEach _v _f _t _o _s
517
    !verbose push
518
    !verbose ${LOGICLIB_VERBOSITY}
519
    StrCpy "${_v}" "${_f}"                                ; Assign the initial value
520
    Goto +2                                               ; Skip the loop expression for the first iteration
521
    !define _DoLoopExpression `IntOp "${_v}" "${_v}" "${_o}" "${_s}"` ; Define the loop expression
522
    !define _o=${_o}
523
    !ifdef _o=+                                           ; Check the loop expression operator
524
      !define __o >                                       ; to determine the correct loop condition
525
    !else ifdef _o=-
526
      !define __o <
527
    !else
528
      !error "Unsupported ForEach step operator (must be + or -)"
529
    !endif
530
    !undef _o=${_o}
531
    !insertmacro _Do For false `${_v}` `${__o}` `${_t}`   ; Let Do do the rest
532
    !undef __o
533
    !verbose pop
534
  !macroend
535
  !define ForEach `!insertmacro _ForEach`
536

    
537
  !macro _For _v _f _t
538
    !verbose push
539
    !verbose ${LOGICLIB_VERBOSITY}
540
    ${ForEach} `${_v}` `${_f}` `${_t}` + 1                ; Pass on to ForEach
541
    !verbose pop
542
  !macroend
543
  !define For `!insertmacro _For`
544

    
545
  !define ExitFor `!insertmacro _Goto ExitFor For`
546

    
547
  !define Next      `!insertmacro _Loop For Next "" "" "" ""`
548

    
549
  !define While     `!insertmacro _Do While true`
550

    
551
  !define ExitWhile `!insertmacro _Goto ExitWhile While`
552

    
553
  !define EndWhile  `!insertmacro _Loop While EndWhile "" "" "" ""`
554

    
555
  !macro _Do _n _c _a _o _b
556
    !verbose push
557
    !verbose ${LOGICLIB_VERBOSITY}
558
    !insertmacro _PushLogic
559
    !define ${_Logic}${_n} _LogicLib_Label_${LOGICLIB_COUNTER}                   ; Get a label for the start of the loop
560
    !insertmacro _IncreaseCounter
561
    ${${_Logic}${_n}}:
562
    !insertmacro _PushScope Exit${_n} _LogicLib_Label_${LOGICLIB_COUNTER}        ; Get a label for the end of the loop
563
    !insertmacro _IncreaseCounter
564
    !insertmacro _PushScope Break ${_Exit${_n}}           ; Break goes to the end of the loop
565
    !ifdef _DoLoopExpression
566
      ${_DoLoopExpression}                                ; Special extra parameter for inserting code
567
      !undef _DoLoopExpression                            ; between the Continue label and the loop condition
568
    !endif
569
    !define _c=${_c}
570
    !ifdef _c=                                            ; No starting condition
571
      !insertmacro _PushScope Continue _LogicLib_Label_${LOGICLIB_COUNTER}       ; Get a label for Continue at the end of the loop
572
      !insertmacro _IncreaseCounter
573
    !else
574
      !insertmacro _PushScope Continue ${${_Logic}${_n}}  ; Continue goes to the start of the loop
575
      !ifdef _c=true                                      ; If is true
576
        !insertmacro _${_o} `${_a}` `${_b}` "" ${_Exit${_n}}
577
      !else                                               ; If condition is false
578
        !insertmacro _${_o} `${_a}` `${_b}` ${_Exit${_n}} ""
579
      !endif
580
    !endif
581
    !undef _c=${_c}
582
    !define ${_Logic}Condition ${_c}                      ; Remember the condition used
583
    !verbose pop
584
  !macroend
585
  !define Do      `!insertmacro _Do Do "" "" "" ""`
586
  !define DoWhile `!insertmacro _Do Do true`
587
  !define DoUntil `!insertmacro _Do Do false`
588

    
589
  !macro _Goto _n _s
590
    !verbose push
591
    !verbose ${LOGICLIB_VERBOSITY}
592
    !ifndef _${_n}
593
      !error "Cannot use ${_n} without a preceding ${_s}"
594
    !endif
595
    Goto ${_${_n}}
596
    !verbose pop
597
  !macroend
598
  !define ExitDo   `!insertmacro _Goto ExitDo Do`
599

    
600
  !macro _Loop _n _e _c _a _o _b
601
    !verbose push
602
    !verbose ${LOGICLIB_VERBOSITY}
603
    !ifndef _Logic | ${_Logic}${_n}
604
      !error "Cannot use ${_e} without a preceding ${_n}"
605
    !endif
606
    !define _c=${${_Logic}Condition}
607
    !ifdef _c=                                            ; If Do had no condition place the Continue label
608
      ${_Continue}:
609
    !endif
610
    !undef _c=${${_Logic}Condition}
611
    !define _c=${_c}
612
    !ifdef _c=                                            ; No ending condition
613
      Goto ${${_Logic}${_n}}
614
    !else ifdef _c=true                                   ; If condition is true
615
      !insertmacro _${_o} `${_a}` `${_b}` ${${_Logic}${_n}} ${_Exit${_n}}
616
    !else                                                 ; If condition is false
617
      !insertmacro _${_o} `${_a}` `${_b}` ${_Exit${_n}} ${${_Logic}${_n}}
618
    !endif
619
    !undef _c=${_c}
620
    Goto ${_Continue}                                     ; Just to ensure it is referenced at least once
621
	Goto ${_Exit${_n}}                                    ; Just to ensure it is referenced at least once
622
    ${_Exit${_n}}:                                        ; Place the loop exit point
623
    !undef ${_Logic}Condition
624
    !insertmacro _PopScope Continue
625
    !insertmacro _PopScope Break
626
    !insertmacro _PopScope Exit${_n}
627
    !undef ${_Logic}${_n}
628
    !insertmacro _PopLogic
629
    !verbose pop
630
  !macroend
631
  !define Loop      `!insertmacro _Loop Do Loop "" "" "" ""`
632
  !define LoopWhile `!insertmacro _Loop Do LoopWhile true`
633
  !define LoopUntil `!insertmacro _Loop Do LoopUntil false`
634

    
635
  !define Continue `!insertmacro _Goto Continue "For or Do or While"`
636
  !define Break    `!insertmacro _Goto Break "For or Do or While"`
637

    
638
  !macro _Select _a
639
    !verbose push
640
    !verbose ${LOGICLIB_VERBOSITY}
641
    !insertmacro _PushLogic
642
    !define ${_Logic}Select `${_a}`                       ; Remember the left hand side of the comparison
643
    !verbose pop
644
  !macroend
645
  !define Select `!insertmacro _Select`
646

    
647
  !macro _Select_CaseElse
648
    !verbose push
649
    !verbose ${LOGICLIB_VERBOSITY}
650
    !ifndef _Logic | ${_Logic}Select
651
      !error "Cannot use Case without a preceding Select"
652
    !endif
653
    !ifdef ${_Logic}EndSelect                             ; This is set only after the first case
654
      !ifndef ${_Logic}Else
655
        !error "Cannot use Case following a CaseElse"
656
      !endif
657
      Goto ${${_Logic}EndSelect}                          ; Go to the EndSelect
658
      ${${_Logic}Else}:                                   ; Place the Else label
659
      !undef ${_Logic}Else                                ; and remove it
660
    !else
661
      !define ${_Logic}EndSelect _LogicLib_Label_${LOGICLIB_COUNTER}             ; Get a label for the EndSelect
662
      !insertmacro _IncreaseCounter
663
    !endif
664
    !verbose pop
665
  !macroend
666
  !define CaseElse `!insertmacro _CaseElse`
667
  !define Case_Else `!insertmacro _CaseElse`              ; Compatibility with 2.2 and earlier
668
  !define Default `!insertmacro _CaseElse`                ; For the C-minded
669

    
670
  !macro _Select_Case _a
671
    !verbose push
672
    !verbose ${LOGICLIB_VERBOSITY}
673
    ${CaseElse}                                           ; Perform the CaseElse
674
    !define ${_Logic}Else _LogicLib_Label_${LOGICLIB_COUNTER}                    ; Get a label for the next Else and perform the new Case
675
    !insertmacro _IncreaseCounter
676
    !insertmacro _== `${${_Logic}Select}` `${_a}` "" ${${_Logic}Else}
677
    !verbose pop
678
  !macroend
679
  !define Case `!insertmacro _Case`
680

    
681
  !macro _Case2 _a _b
682
    !verbose push
683
    !verbose ${LOGICLIB_VERBOSITY}
684
    ${CaseElse}                                           ; Perform the CaseElse
685
    !define ${_Logic}Else _LogicLib_Label_${LOGICLIB_COUNTER}                    ; Get a label for the next Else and perform the new Case
686
    !insertmacro _IncreaseCounter
687
    !insertmacro _== `${${_Logic}Select}` `${_a}` +2 ""
688
    !insertmacro _== `${${_Logic}Select}` `${_b}` "" ${${_Logic}Else}
689
    !verbose pop
690
  !macroend
691
  !define Case2 `!insertmacro _Case2`
692

    
693
  !macro _Case3 _a _b _c
694
    !verbose push
695
    !verbose ${LOGICLIB_VERBOSITY}
696
    ${CaseElse}                                           ; Perform the CaseElse
697
    !define ${_Logic}Else _LogicLib_Label_${LOGICLIB_COUNTER}                    ; Get a label for the next Else and perform the new Case
698
    !insertmacro _IncreaseCounter
699
    !insertmacro _== `${${_Logic}Select}` `${_a}` +3 ""
700
    !insertmacro _== `${${_Logic}Select}` `${_b}` +2 ""
701
    !insertmacro _== `${${_Logic}Select}` `${_c}` "" ${${_Logic}Else}
702
    !verbose pop
703
  !macroend
704
  !define Case3 `!insertmacro _Case3`
705

    
706
  !macro _Case4 _a _b _c _d
707
    !verbose push
708
    !verbose ${LOGICLIB_VERBOSITY}
709
    ${CaseElse}                                           ; Perform the CaseElse
710
    !define ${_Logic}Else _LogicLib_Label_${LOGICLIB_COUNTER}                    ; Get a label for the next Else and perform the new Case
711
    !insertmacro _IncreaseCounter
712
    !insertmacro _== `${${_Logic}Select}` `${_a}` +4 ""
713
    !insertmacro _== `${${_Logic}Select}` `${_b}` +3 ""
714
    !insertmacro _== `${${_Logic}Select}` `${_c}` +2 ""
715
    !insertmacro _== `${${_Logic}Select}` `${_d}` "" ${${_Logic}Else}
716
    !verbose pop
717
  !macroend
718
  !define Case4 `!insertmacro _Case4`
719

    
720
  !macro _Case5 _a _b _c _d _e
721
    !verbose push
722
    !verbose ${LOGICLIB_VERBOSITY}
723
    ${CaseElse}                                           ; Perform the CaseElse
724
    !define ${_Logic}Else _LogicLib_Label_${LOGICLIB_COUNTER}                    ; Get a label for the next Else and perform the new Case
725
    !insertmacro _IncreaseCounter
726
    !insertmacro _== `${${_Logic}Select}` `${_a}` +5 ""
727
    !insertmacro _== `${${_Logic}Select}` `${_b}` +4 ""
728
    !insertmacro _== `${${_Logic}Select}` `${_c}` +3 ""
729
    !insertmacro _== `${${_Logic}Select}` `${_d}` +2 ""
730
    !insertmacro _== `${${_Logic}Select}` `${_e}` "" ${${_Logic}Else}
731
    !verbose pop
732
  !macroend
733
  !define Case5 `!insertmacro _Case5`
734

    
735
  !macro _EndSelect
736
    !verbose push
737
    !verbose ${LOGICLIB_VERBOSITY}
738
    !ifndef _Logic | ${_Logic}Select
739
      !error "Cannot use EndSelect without a preceding Select"
740
    !endif
741
    !ifdef ${_Logic}Else
742
      ${${_Logic}Else}:                                   ; Place the Else label
743
      !undef ${_Logic}Else                                ; and remove it
744
    !endif
745
    !ifdef ${_Logic}EndSelect                             ; This won't be set if there weren't any cases
746
      ${${_Logic}EndSelect}:                              ; Place the EndSelect
747
      !undef ${_Logic}EndSelect                           ; and remove it
748
    !endif
749
    !undef ${_Logic}Select
750
    !insertmacro _PopLogic
751
    !verbose pop
752
  !macroend
753
  !define EndSelect `!insertmacro _EndSelect`
754

    
755
  !macro _Switch _a
756
    !verbose push
757
    !verbose ${LOGICLIB_VERBOSITY}
758
    !insertmacro _PushLogic
759
    !insertmacro _PushScope Switch ${_Logic}              ; Keep a separate stack for switch data
760
    !insertmacro _PushScope Break _LogicLib_Label_${LOGICLIB_COUNTER}            ; Get a lable for beyond the end of the switch
761
    !insertmacro _IncreaseCounter
762
    !define ${_Switch}Var `${_a}`                         ; Remember the left hand side of the comparison
763
    !tempfile ${_Switch}Tmp                               ; Create a temporary file
764
    !define ${_Logic}Switch _LogicLib_Label_${LOGICLIB_COUNTER}                  ; Get a label for the end of the switch
765
    !insertmacro _IncreaseCounter
766
    Goto ${${_Logic}Switch}                               ; and go there
767
    !verbose pop
768
  !macroend
769
  !define Switch `!insertmacro _Switch`
770

    
771
  !macro _Case _a
772
    !verbose push
773
    !verbose ${LOGICLIB_VERBOSITY}
774
    !ifdef _Logic & ${_Logic}Select                       ; Check for an active Select
775
      !insertmacro _Select_Case `${_a}`
776
    !else ifndef _Switch                                  ; If not then check for an active Switch
777
      !error "Cannot use Case without a preceding Select or Switch"
778
    !else
779
      !define _label _LogicLib_Label_${LOGICLIB_COUNTER}                         ; Get a label for this case,
780
      !insertmacro _IncreaseCounter
781
      ${_label}:                                          ; place it and add it's check to the temp file
782
      !appendfile "${${_Switch}Tmp}" `!insertmacro _== $\`${${_Switch}Var}$\` $\`${_a}$\` ${_label} ""$\n`
783
      !undef _label
784
    !endif
785
    !verbose pop
786
  !macroend
787

    
788
  !macro _CaseElse
789
    !verbose push
790
    !verbose ${LOGICLIB_VERBOSITY}
791
    !ifdef _Logic & ${_Logic}Select                       ; Check for an active Select
792
      !insertmacro _Select_CaseElse
793
    !else ifndef _Switch                                  ; If not then check for an active Switch
794
      !error "Cannot use Case without a preceding Select or Switch"
795
    !else ifdef ${_Switch}Else                            ; Already had a default case?
796
      !error "Cannot use CaseElse following a CaseElse"
797
    !else
798
      !define ${_Switch}Else _LogicLib_Label_${LOGICLIB_COUNTER}                 ; Get a label for the default case,
799
      !insertmacro _IncreaseCounter
800
      ${${_Switch}Else}:                                  ; and place it
801
    !endif
802
    !verbose pop
803
  !macroend
804

    
805
  !macro _EndSwitch
806
    !verbose push
807
    !verbose ${LOGICLIB_VERBOSITY}
808
    !ifndef _Logic | ${_Logic}Switch
809
      !error "Cannot use EndSwitch without a preceding Switch"
810
    !endif
811
    Goto ${_Break}                                        ; Skip the jump table
812
    ${${_Logic}Switch}:                                   ; Place the end of the switch
813
    !undef ${_Logic}Switch
814
    !include "${${_Switch}Tmp}"                           ; Include the jump table
815
    !delfile "${${_Switch}Tmp}"                           ; and clear it up
816
    !ifdef ${_Switch}Else                                 ; Was there a default case?
817
      Goto ${${_Switch}Else}                              ; then go there if all else fails
818
      !undef ${_Switch}Else
819
    !endif
820
    !undef ${_Switch}Tmp
821
    !undef ${_Switch}Var
822
    ${_Break}:                                            ; Place the break label
823
    !insertmacro _PopScope Break
824
    !insertmacro _PopScope Switch
825
    !insertmacro _PopLogic
826
    !verbose pop
827
  !macroend
828
  !define EndSwitch `!insertmacro _EndSwitch`
829

    
830
!endif ; LOGICLIB
831
!verbose 3
832
!define LOGICLIB_VERBOSITY ${_LOGICLIB_VERBOSITY}
833
!undef _LOGICLIB_VERBOSITY
834
!verbose pop