1; NSIS LOGIC LIBRARY - LogicLib.nsh 2; see mingw-file-association.nshmingw-file-association.nsh for license info 3; Version 2.6 - 08/12/2007 4; By dselkirk@hotmail.com 5; and eccles@users.sf.net 6; with IfNot support added by Message 7; 8; Questions/Comments - 9; See http://forums.winamp.com/showthread.php?s=&postid=1116241 10; 11; Description: 12; Provides the use of various logic statements within NSIS. 13; 14; Usage: 15; The following "statements" are available: 16; If|IfNot|Unless..{ElseIf|ElseIfNot|ElseUnless}..[Else]..EndIf|EndUnless 17; - Conditionally executes a block of statements, depending on the value 18; of an expression. IfNot and Unless are equivalent and 19; interchangeable, as are ElseIfNot and ElseUnless. 20; AndIf|AndIfNot|AndUnless|OrIf|OrIfNot|OrUnless 21; - Adds any number of extra conditions to If, IfNot, Unless, ElseIf, 22; ElseIfNot and ElseUnless statements. 23; IfThen|IfNotThen..|..| 24; - Conditionally executes an inline statement, depending on the value 25; of an expression. 26; IfCmd..||..| 27; - Conditionally executes an inline statement, depending on a true 28; value of the provided NSIS function. 29; Select..{Case[2|3|4|5]}..[CaseElse|Default]..EndSelect 30; - Executes one of several blocks of statements, depending on the value 31; of an expression. 32; Switch..{Case|CaseElse|Default}..EndSwitch 33; - Jumps to one of several labels, depending on the value of an 34; expression. 35; Do[While|Until]..{ExitDo|Continue|Break}..Loop[While|Until] 36; - Repeats a block of statements until stopped, or depending on the 37; value of an expression. 38; While..{ExitWhile|Continue|Break}..EndWhile 39; - An alias for DoWhile..Loop (for backwards-compatibility) 40; For[Each]..{ExitFor|Continue|Break}..Next 41; - Repeats a block of statements varying the value of a variable. 42; 43; The following "expressions" are available: 44; Standard (built-in) string tests (which are case-insensitive): 45; a == b; a != b 46; Additional case-insensitive string tests (using System.dll): 47; a S< b; a S>= b; a S> b; a S<= b 48; Case-sensitive string tests: 49; a S== b; a S!= b 50; Standard (built-in) signed integer tests: 51; a = b; a <> b; a < b; a >= b; a > b; a <= b 52; Standard (built-in) unsigned integer tests: 53; a U< b; a U>= b; a U> b; a U<= b 54; 64-bit integer tests (using System.dll): 55; a L= b; a L<> b; a L< b; a L>= b; a L> b; a L<= b 56; Built-in NSIS flag tests: 57; ${Abort}; ${Errors}; ${RebootFlag}; ${Silent} 58; Built-in NSIS other tests: 59; ${FileExists} a 60; Any conditional NSIS instruction test: 61; ${Cmd} a 62; Section flag tests: 63; ${SectionIsSelected} a; ${SectionIsSectionGroup} a; 64; ${SectionIsSectionGroupEnd} a; ${SectionIsBold} a; 65; ${SectionIsReadOnly} a; ${SectionIsExpanded} a; 66; ${SectionIsPartiallySelected} a 67; 68; Examples: 69; See LogicLib.nsi in the Examples folder for lots of example usage. 70 71!verbose push 72!verbose 3 73!ifndef LOGICLIB_VERBOSITY 74 !define LOGICLIB_VERBOSITY 3 75!endif 76!define _LOGICLIB_VERBOSITY ${LOGICLIB_VERBOSITY} 77!undef LOGICLIB_VERBOSITY 78!verbose ${_LOGICLIB_VERBOSITY} 79 80!ifndef LOGICLIB 81 !define LOGICLIB 82 !define | "'" 83 !define || "' '" 84 !define LOGICLIB_COUNTER 0 85 86 !include Sections.nsh 87 88 !macro _LOGICLIB_TEMP 89 !ifndef _LOGICLIB_TEMP 90 !define _LOGICLIB_TEMP 91 Var /GLOBAL _LOGICLIB_TEMP ; Temporary variable to aid the more elaborate logic tests 92 !endif 93 !macroend 94 95 !macro _IncreaseCounter 96 !define _LOGICLIB_COUNTER ${LOGICLIB_COUNTER} 97 !undef LOGICLIB_COUNTER 98 !define /math LOGICLIB_COUNTER ${_LOGICLIB_COUNTER} + 1 99 !undef _LOGICLIB_COUNTER 100 !macroend 101 102 !macro _PushLogic 103 !insertmacro _PushScope Logic _LogicLib_Label_${LOGICLIB_COUNTER} 104 !insertmacro _IncreaseCounter 105 !macroend 106 107 !macro _PopLogic 108 !insertmacro _PopScope Logic 109 !macroend 110 111 !macro _PushScope Type label 112 !ifdef _${Type} ; If we already have a statement 113 !define _Cur${Type} ${_${Type}} 114 !undef _${Type} 115 !define _${Type} ${label} 116 !define ${_${Type}}Prev${Type} ${_Cur${Type}} ; Save the current logic 117 !undef _Cur${Type} 118 !else 119 !define _${Type} ${label} ; Initialise for first statement 120 !endif 121 !macroend 122 123 !macro _PopScope Type 124 !ifndef _${Type} 125 !error "Cannot use _Pop${Type} without a preceding _Push${Type}" 126 !endif 127 !ifdef ${_${Type}}Prev${Type} ; If a previous statement was active then restore it 128 !define _Cur${Type} ${_${Type}} 129 !undef _${Type} 130 !define _${Type} ${${_Cur${Type}}Prev${Type}} 131 !undef ${_Cur${Type}}Prev${Type} 132 !undef _Cur${Type} 133 !else 134 !undef _${Type} 135 !endif 136 !macroend 137 138 ; String tests 139 !macro _== _a _b _t _f 140 StrCmp `${_a}` `${_b}` `${_t}` `${_f}` 141 !macroend 142 143 !macro _!= _a _b _t _f 144 !insertmacro _== `${_a}` `${_b}` `${_f}` `${_t}` 145 !macroend 146 147 ; Case-sensitive string tests 148 !macro _S== _a _b _t _f 149 StrCmpS `${_a}` `${_b}` `${_t}` `${_f}` 150 !macroend 151 152 !macro _S!= _a _b _t _f 153 !insertmacro _S== `${_a}` `${_b}` `${_f}` `${_t}` 154 !macroend 155 156 ; Extra string tests (cannot do these case-sensitively - I tried and lstrcmp still ignored the case) 157 !macro _StrCmpI _a _b _e _l _m 158 !insertmacro _LOGICLIB_TEMP 159 System::Call `kernel32::lstrcmpiA(ts, ts) i.s` `${_a}` `${_b}` 160 Pop $_LOGICLIB_TEMP 161 IntCmp $_LOGICLIB_TEMP 0 `${_e}` `${_l}` `${_m}` 162 !macroend 163 164 !macro _S< _a _b _t _f 165 !insertmacro _StrCmpI `${_a}` `${_b}` `${_f}` `${_t}` `${_f}` 166 !macroend 167 168 !macro _S>= _a _b _t _f 169 !insertmacro _S< `${_a}` `${_b}` `${_f}` `${_t}` 170 !macroend 171 172 !macro _S> _a _b _t _f 173 !insertmacro _StrCmpI `${_a}` `${_b}` `${_f}` `${_f}` `${_t}` 174 !macroend 175 176 !macro _S<= _a _b _t _f 177 !insertmacro _S> `${_a}` `${_b}` `${_f}` `${_t}` 178 !macroend 179 180 ; Integer tests 181 !macro _= _a _b _t _f 182 IntCmp `${_a}` `${_b}` `${_t}` `${_f}` `${_f}` 183 !macroend 184 185 !macro _<> _a _b _t _f 186 !insertmacro _= `${_a}` `${_b}` `${_f}` `${_t}` 187 !macroend 188 189 !macro _< _a _b _t _f 190 IntCmp `${_a}` `${_b}` `${_f}` `${_t}` `${_f}` 191 !macroend 192 193 !macro _>= _a _b _t _f 194 !insertmacro _< `${_a}` `${_b}` `${_f}` `${_t}` 195 !macroend 196 197 !macro _> _a _b _t _f 198 IntCmp `${_a}` `${_b}` `${_f}` `${_f}` `${_t}` 199 !macroend 200 201 !macro _<= _a _b _t _f 202 !insertmacro _> `${_a}` `${_b}` `${_f}` `${_t}` 203 !macroend 204 205 ; Unsigned integer tests (NB: no need for extra equality tests) 206 !macro _U< _a _b _t _f 207 IntCmpU `${_a}` `${_b}` `${_f}` `${_t}` `${_f}` 208 !macroend 209 210 !macro _U>= _a _b _t _f 211 !insertmacro _U< `${_a}` `${_b}` `${_f}` `${_t}` 212 !macroend 213 214 !macro _U> _a _b _t _f 215 IntCmpU `${_a}` `${_b}` `${_f}` `${_f}` `${_t}` 216 !macroend 217 218 !macro _U<= _a _b _t _f 219 !insertmacro _U> `${_a}` `${_b}` `${_f}` `${_t}` 220 !macroend 221 222 ; Int64 tests 223 !macro _Int64Cmp _a _o _b _t _f 224 !insertmacro _LOGICLIB_TEMP 225 System::Int64Op `${_a}` `${_o}` `${_b}` 226 Pop $_LOGICLIB_TEMP 227 !insertmacro _= $_LOGICLIB_TEMP 0 `${_f}` `${_t}` 228 !macroend 229 230 !macro _L= _a _b _t _f 231 !insertmacro _Int64Cmp `${_a}` = `${_b}` `${_t}` `${_f}` 232 !macroend 233 234 !macro _L<> _a _b _t _f 235 !insertmacro _L= `${_a}` `${_b}` `${_f}` `${_t}` 236 !macroend 237 238 !macro _L< _a _b _t _f 239 !insertmacro _Int64Cmp `${_a}` < `${_b}` `${_t}` `${_f}` 240 !macroend 241 242 !macro _L>= _a _b _t _f 243 !insertmacro _L< `${_a}` `${_b}` `${_f}` `${_t}` 244 !macroend 245 246 !macro _L> _a _b _t _f 247 !insertmacro _Int64Cmp `${_a}` > `${_b}` `${_t}` `${_f}` 248 !macroend 249 250 !macro _L<= _a _b _t _f 251 !insertmacro _L> `${_a}` `${_b}` `${_f}` `${_t}` 252 !macroend 253 254 ; Flag tests 255 !macro _Abort _a _b _t _f 256 IfAbort `${_t}` `${_f}` 257 !macroend 258 !define Abort `"" Abort ""` 259 260 !macro _Errors _a _b _t _f 261 IfErrors `${_t}` `${_f}` 262 !macroend 263 !define Errors `"" Errors ""` 264 265 !macro _FileExists _a _b _t _f 266 IfFileExists `${_b}` `${_t}` `${_f}` 267 !macroend 268 !define FileExists `"" FileExists` 269 270 !macro _RebootFlag _a _b _t _f 271 IfRebootFlag `${_t}` `${_f}` 272 !macroend 273 !define RebootFlag `"" RebootFlag ""` 274 275 !macro _Silent _a _b _t _f 276 IfSilent `${_t}` `${_f}` 277 !macroend 278 !define Silent `"" Silent ""` 279 280 ; "Any instruction" test 281 !macro _Cmd _a _b _t _f 282 !define _t=${_t} 283 !ifdef _t= ; If no true label then make one 284 !define __t _LogicLib_Label_${LOGICLIB_COUNTER} 285 !insertmacro _IncreaseCounter 286 !else 287 !define __t ${_t} 288 !endif 289 ${_b} ${__t} 290 !define _f=${_f} 291 !ifndef _f= ; If a false label then go there 292 Goto ${_f} 293 !endif 294 !undef _f=${_f} 295 !ifdef _t= ; If we made our own true label then place it 296 ${__t}: 297 !endif 298 !undef __t 299 !undef _t=${_t} 300 !macroend 301 !define Cmd `"" Cmd` 302 303 ; Section flag test 304 !macro _SectionFlagIsSet _a _b _t _f 305 !insertmacro _LOGICLIB_TEMP 306 SectionGetFlags `${_b}` $_LOGICLIB_TEMP 307 IntOp $_LOGICLIB_TEMP $_LOGICLIB_TEMP & `${_a}` 308 !insertmacro _= $_LOGICLIB_TEMP `${_a}` `${_t}` `${_f}` 309 !macroend 310 !define SectionIsSelected `${SF_SELECTED} SectionFlagIsSet` 311 !define SectionIsSubSection `${SF_SUBSEC} SectionFlagIsSet` 312 !define SectionIsSubSectionEnd `${SF_SUBSECEND} SectionFlagIsSet` 313 !define SectionIsSectionGroup `${SF_SECGRP} SectionFlagIsSet` 314 !define SectionIsSectionGroupEnd `${SF_SECGRPEND} SectionFlagIsSet` 315 !define SectionIsBold `${SF_BOLD} SectionFlagIsSet` 316 !define SectionIsReadOnly `${SF_RO} SectionFlagIsSet` 317 !define SectionIsExpanded `${SF_EXPAND} SectionFlagIsSet` 318 !define SectionIsPartiallySelected `${SF_PSELECTED} SectionFlagIsSet` 319 320 !define IfCmd `!insertmacro _IfThen "" Cmd ${|}` 321 322 !macro _If _c _a _o _b 323 !verbose push 324 !verbose ${LOGICLIB_VERBOSITY} 325 !insertmacro _PushLogic 326 !define ${_Logic}If 327 !define ${_Logic}Else _LogicLib_Label_${LOGICLIB_COUNTER} ; Get a label for the Else 328 !insertmacro _IncreaseCounter 329 !define _c=${_c} 330 !ifdef _c=true ; If is true 331 !insertmacro _${_o} `${_a}` `${_b}` "" ${${_Logic}Else} 332 !else ; If condition is false 333 !insertmacro _${_o} `${_a}` `${_b}` ${${_Logic}Else} "" 334 !endif 335 !undef _c=${_c} 336 !verbose pop 337 !macroend 338 !define If `!insertmacro _If true` 339 !define Unless `!insertmacro _If false` 340 !define IfNot `!insertmacro _If false` 341 342 !macro _And _c _a _o _b 343 !verbose push 344 !verbose ${LOGICLIB_VERBOSITY} 345 !ifndef _Logic | ${_Logic}If 346 !error "Cannot use And without a preceding If or IfNot/Unless" 347 !endif 348 !ifndef ${_Logic}Else 349 !error "Cannot use And following an Else" 350 !endif 351 !define _c=${_c} 352 !ifdef _c=true ; If is true 353 !insertmacro _${_o} `${_a}` `${_b}` "" ${${_Logic}Else} 354 !else ; If condition is false 355 !insertmacro _${_o} `${_a}` `${_b}` ${${_Logic}Else} "" 356 !endif 357 !undef _c=${_c} 358 !verbose pop 359 !macroend 360 !define AndIf `!insertmacro _And true` 361 !define AndUnless `!insertmacro _And false` 362 !define AndIfNot `!insertmacro _And false` 363 364 !macro _Or _c _a _o _b 365 !verbose push 366 !verbose ${LOGICLIB_VERBOSITY} 367 !ifndef _Logic | ${_Logic}If 368 !error "Cannot use Or without a preceding If or IfNot/Unless" 369 !endif 370 !ifndef ${_Logic}Else 371 !error "Cannot use Or following an Else" 372 !endif 373 !define _label _LogicLib_Label_${LOGICLIB_COUNTER} ; Skip this test as we already 374 !insertmacro _IncreaseCounter 375 Goto ${_label} ; have a successful result 376 ${${_Logic}Else}: ; Place the Else label 377 !undef ${_Logic}Else ; and remove it 378 !define ${_Logic}Else _LogicLib_Label_${LOGICLIB_COUNTER} ; Get a label for the next Else and perform the new If 379 !insertmacro _IncreaseCounter 380 !define _c=${_c} 381 !ifdef _c=true ; If is true 382 !insertmacro _${_o} `${_a}` `${_b}` "" ${${_Logic}Else} 383 !else ; If condition is false 384 !insertmacro _${_o} `${_a}` `${_b}` ${${_Logic}Else} "" 385 !endif 386 !undef _c=${_c} 387 ${_label}: 388 !undef _label 389 !verbose pop 390 !macroend 391 !define OrIf `!insertmacro _Or true` 392 !define OrUnless `!insertmacro _Or false` 393 !define OrIfNot `!insertmacro _Or false` 394 395 !macro _Else 396 !verbose push 397 !verbose ${LOGICLIB_VERBOSITY} 398 !ifndef _Logic | ${_Logic}If 399 !error "Cannot use Else without a preceding If or IfNot/Unless" 400 !endif 401 !ifndef ${_Logic}Else 402 !error "Cannot use Else following an Else" 403 !endif 404 !ifndef ${_Logic}EndIf ; First Else for this If? 405 !define ${_Logic}EndIf _LogicLib_Label_${LOGICLIB_COUNTER} ; Get a label for the EndIf 406 !insertmacro _IncreaseCounter 407 !endif 408 Goto ${${_Logic}EndIf} ; Go to the EndIf 409 ${${_Logic}Else}: ; Place the Else label 410 !undef ${_Logic}Else ; and remove it 411 !verbose pop 412 !macroend 413 !define Else `!insertmacro _Else` 414 415 !macro _ElseIf _c _a _o _b 416 !verbose push 417 !verbose ${LOGICLIB_VERBOSITY} 418 ${Else} ; Perform the Else 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 !verbose pop 429 !macroend 430 !define ElseIf `!insertmacro _ElseIf true` 431 !define ElseUnless `!insertmacro _ElseIf false` 432 !define ElseIfNot `!insertmacro _ElseIf false` 433 434 !macro _EndIf _n 435 !verbose push 436 !verbose ${LOGICLIB_VERBOSITY} 437 !ifndef _Logic | ${_Logic}If 438 !error "Cannot use End${_n} without a preceding If or IfNot/Unless" 439 !endif 440 !ifdef ${_Logic}Else 441 ${${_Logic}Else}: ; Place the Else label 442 !undef ${_Logic}Else ; and remove it 443 !endif 444 !ifdef ${_Logic}EndIf 445 ${${_Logic}EndIf}: ; Place the EndIf 446 !undef ${_Logic}EndIf ; and remove it 447 !endif 448 !undef ${_Logic}If 449 !insertmacro _PopLogic 450 !verbose pop 451 !macroend 452 !define EndIf `!insertmacro _EndIf If` 453 !define EndUnless `!insertmacro _EndIf Unless` 454 455 !macro _IfThen _a _o _b _t 456 !verbose push 457 !verbose ${LOGICLIB_VERBOSITY} 458 ${If} `${_a}` `${_o}` `${_b}` 459 ${_t} 460 ${EndIf} 461 !verbose pop 462 !macroend 463 !define IfThen `!insertmacro _IfThen` 464 465 !macro _IfNotThen _a _o _b _t 466 !verbose push 467 !verbose ${LOGICLIB_VERBOSITY} 468 ${IfNot} `${_a}` `${_o}` `${_b}` 469 ${_t} 470 ${EndIf} 471 !verbose pop 472 !macroend 473 !define IfNotThen `!insertmacro _IfNotThen` 474 475 !macro _ForEach _v _f _t _o _s 476 !verbose push 477 !verbose ${LOGICLIB_VERBOSITY} 478 StrCpy "${_v}" "${_f}" ; Assign the initial value 479 Goto +2 ; Skip the loop expression for the first iteration 480 !define _DoLoopExpression `IntOp "${_v}" "${_v}" "${_o}" "${_s}"` ; Define the loop expression 481 !define _o=${_o} 482 !ifdef _o=+ ; Check the loop expression operator 483 !define __o > ; to determine the correct loop condition 484 !else ifdef _o=- 485 !define __o < 486 !else 487 !error "Unsupported ForEach step operator (must be + or -)" 488 !endif 489 !undef _o=${_o} 490 !insertmacro _Do For false `${_v}` `${__o}` `${_t}` ; Let Do do the rest 491 !undef __o 492 !verbose pop 493 !macroend 494 !define ForEach `!insertmacro _ForEach` 495 496 !macro _For _v _f _t 497 !verbose push 498 !verbose ${LOGICLIB_VERBOSITY} 499 ${ForEach} `${_v}` `${_f}` `${_t}` + 1 ; Pass on to ForEach 500 !verbose pop 501 !macroend 502 !define For `!insertmacro _For` 503 504 !define ExitFor `!insertmacro _Goto ExitFor For` 505 506 !define Next `!insertmacro _Loop For Next "" "" "" ""` 507 508 !define While `!insertmacro _Do While true` 509 510 !define ExitWhile `!insertmacro _Goto ExitWhile While` 511 512 !define EndWhile `!insertmacro _Loop While EndWhile "" "" "" ""` 513 514 !macro _Do _n _c _a _o _b 515 !verbose push 516 !verbose ${LOGICLIB_VERBOSITY} 517 !insertmacro _PushLogic 518 !define ${_Logic}${_n} _LogicLib_Label_${LOGICLIB_COUNTER} ; Get a label for the start of the loop 519 !insertmacro _IncreaseCounter 520 ${${_Logic}${_n}}: 521 !insertmacro _PushScope Exit${_n} _LogicLib_Label_${LOGICLIB_COUNTER} ; Get a label for the end of the loop 522 !insertmacro _IncreaseCounter 523 !insertmacro _PushScope Break ${_Exit${_n}} ; Break goes to the end of the loop 524 !ifdef _DoLoopExpression 525 ${_DoLoopExpression} ; Special extra parameter for inserting code 526 !undef _DoLoopExpression ; between the Continue label and the loop condition 527 !endif 528 !define _c=${_c} 529 !ifdef _c= ; No starting condition 530 !insertmacro _PushScope Continue _LogicLib_Label_${LOGICLIB_COUNTER} ; Get a label for Continue at the end of the loop 531 !insertmacro _IncreaseCounter 532 !else 533 !insertmacro _PushScope Continue ${${_Logic}${_n}} ; Continue goes to the start of the loop 534 !ifdef _c=true ; If is true 535 !insertmacro _${_o} `${_a}` `${_b}` "" ${_Exit${_n}} 536 !else ; If condition is false 537 !insertmacro _${_o} `${_a}` `${_b}` ${_Exit${_n}} "" 538 !endif 539 !endif 540 !undef _c=${_c} 541 !define ${_Logic}Condition ${_c} ; Remember the condition used 542 !verbose pop 543 !macroend 544 !define Do `!insertmacro _Do Do "" "" "" ""` 545 !define DoWhile `!insertmacro _Do Do true` 546 !define DoUntil `!insertmacro _Do Do false` 547 548 !macro _Goto _n _s 549 !verbose push 550 !verbose ${LOGICLIB_VERBOSITY} 551 !ifndef _${_n} 552 !error "Cannot use ${_n} without a preceding ${_s}" 553 !endif 554 Goto ${_${_n}} 555 !verbose pop 556 !macroend 557 !define ExitDo `!insertmacro _Goto ExitDo Do` 558 559 !macro _Loop _n _e _c _a _o _b 560 !verbose push 561 !verbose ${LOGICLIB_VERBOSITY} 562 !ifndef _Logic | ${_Logic}${_n} 563 !error "Cannot use ${_e} without a preceding ${_n}" 564 !endif 565 !define _c=${${_Logic}Condition} 566 !ifdef _c= ; If Do had no condition place the Continue label 567 ${_Continue}: 568 !endif 569 !undef _c=${${_Logic}Condition} 570 !define _c=${_c} 571 !ifdef _c= ; No ending condition 572 Goto ${${_Logic}${_n}} 573 !else ifdef _c=true ; If condition is true 574 !insertmacro _${_o} `${_a}` `${_b}` ${${_Logic}${_n}} ${_Exit${_n}} 575 !else ; If condition is false 576 !insertmacro _${_o} `${_a}` `${_b}` ${_Exit${_n}} ${${_Logic}${_n}} 577 !endif 578 !undef _c=${_c} 579 Goto ${_Continue} ; Just to ensure it is referenced at least once 580 Goto ${_Exit${_n}} ; Just to ensure it is referenced at least once 581 ${_Exit${_n}}: ; Place the loop exit point 582 !undef ${_Logic}Condition 583 !insertmacro _PopScope Continue 584 !insertmacro _PopScope Break 585 !insertmacro _PopScope Exit${_n} 586 !undef ${_Logic}${_n} 587 !insertmacro _PopLogic 588 !verbose pop 589 !macroend 590 !define Loop `!insertmacro _Loop Do Loop "" "" "" ""` 591 !define LoopWhile `!insertmacro _Loop Do LoopWhile true` 592 !define LoopUntil `!insertmacro _Loop Do LoopUntil false` 593 594 !define Continue `!insertmacro _Goto Continue "For or Do or While"` 595 !define Break `!insertmacro _Goto Break "For or Do or While"` 596 597 !macro _Select _a 598 !verbose push 599 !verbose ${LOGICLIB_VERBOSITY} 600 !insertmacro _PushLogic 601 !define ${_Logic}Select `${_a}` ; Remember the left hand side of the comparison 602 !verbose pop 603 !macroend 604 !define Select `!insertmacro _Select` 605 606 !macro _Select_CaseElse 607 !verbose push 608 !verbose ${LOGICLIB_VERBOSITY} 609 !ifndef _Logic | ${_Logic}Select 610 !error "Cannot use Case without a preceding Select" 611 !endif 612 !ifdef ${_Logic}EndSelect ; This is set only after the first case 613 !ifndef ${_Logic}Else 614 !error "Cannot use Case following a CaseElse" 615 !endif 616 Goto ${${_Logic}EndSelect} ; Go to the EndSelect 617 ${${_Logic}Else}: ; Place the Else label 618 !undef ${_Logic}Else ; and remove it 619 !else 620 !define ${_Logic}EndSelect _LogicLib_Label_${LOGICLIB_COUNTER} ; Get a label for the EndSelect 621 !insertmacro _IncreaseCounter 622 !endif 623 !verbose pop 624 !macroend 625 !define CaseElse `!insertmacro _CaseElse` 626 !define Case_Else `!insertmacro _CaseElse` ; Compatibility with 2.2 and earlier 627 !define Default `!insertmacro _CaseElse` ; For the C-minded 628 629 !macro _Select_Case _a 630 !verbose push 631 !verbose ${LOGICLIB_VERBOSITY} 632 ${CaseElse} ; Perform the CaseElse 633 !define ${_Logic}Else _LogicLib_Label_${LOGICLIB_COUNTER} ; Get a label for the next Else and perform the new Case 634 !insertmacro _IncreaseCounter 635 !insertmacro _== `${${_Logic}Select}` `${_a}` "" ${${_Logic}Else} 636 !verbose pop 637 !macroend 638 !define Case `!insertmacro _Case` 639 640 !macro _Case2 _a _b 641 !verbose push 642 !verbose ${LOGICLIB_VERBOSITY} 643 ${CaseElse} ; Perform the CaseElse 644 !define ${_Logic}Else _LogicLib_Label_${LOGICLIB_COUNTER} ; Get a label for the next Else and perform the new Case 645 !insertmacro _IncreaseCounter 646 !insertmacro _== `${${_Logic}Select}` `${_a}` +2 "" 647 !insertmacro _== `${${_Logic}Select}` `${_b}` "" ${${_Logic}Else} 648 !verbose pop 649 !macroend 650 !define Case2 `!insertmacro _Case2` 651 652 !macro _Case3 _a _b _c 653 !verbose push 654 !verbose ${LOGICLIB_VERBOSITY} 655 ${CaseElse} ; Perform the CaseElse 656 !define ${_Logic}Else _LogicLib_Label_${LOGICLIB_COUNTER} ; Get a label for the next Else and perform the new Case 657 !insertmacro _IncreaseCounter 658 !insertmacro _== `${${_Logic}Select}` `${_a}` +3 "" 659 !insertmacro _== `${${_Logic}Select}` `${_b}` +2 "" 660 !insertmacro _== `${${_Logic}Select}` `${_c}` "" ${${_Logic}Else} 661 !verbose pop 662 !macroend 663 !define Case3 `!insertmacro _Case3` 664 665 !macro _Case4 _a _b _c _d 666 !verbose push 667 !verbose ${LOGICLIB_VERBOSITY} 668 ${CaseElse} ; Perform the CaseElse 669 !define ${_Logic}Else _LogicLib_Label_${LOGICLIB_COUNTER} ; Get a label for the next Else and perform the new Case 670 !insertmacro _IncreaseCounter 671 !insertmacro _== `${${_Logic}Select}` `${_a}` +4 "" 672 !insertmacro _== `${${_Logic}Select}` `${_b}` +3 "" 673 !insertmacro _== `${${_Logic}Select}` `${_c}` +2 "" 674 !insertmacro _== `${${_Logic}Select}` `${_d}` "" ${${_Logic}Else} 675 !verbose pop 676 !macroend 677 !define Case4 `!insertmacro _Case4` 678 679 !macro _Case5 _a _b _c _d _e 680 !verbose push 681 !verbose ${LOGICLIB_VERBOSITY} 682 ${CaseElse} ; Perform the CaseElse 683 !define ${_Logic}Else _LogicLib_Label_${LOGICLIB_COUNTER} ; Get a label for the next Else and perform the new Case 684 !insertmacro _IncreaseCounter 685 !insertmacro _== `${${_Logic}Select}` `${_a}` +5 "" 686 !insertmacro _== `${${_Logic}Select}` `${_b}` +4 "" 687 !insertmacro _== `${${_Logic}Select}` `${_c}` +3 "" 688 !insertmacro _== `${${_Logic}Select}` `${_d}` +2 "" 689 !insertmacro _== `${${_Logic}Select}` `${_e}` "" ${${_Logic}Else} 690 !verbose pop 691 !macroend 692 !define Case5 `!insertmacro _Case5` 693 694 !macro _EndSelect 695 !verbose push 696 !verbose ${LOGICLIB_VERBOSITY} 697 !ifndef _Logic | ${_Logic}Select 698 !error "Cannot use EndSelect without a preceding Select" 699 !endif 700 !ifdef ${_Logic}Else 701 ${${_Logic}Else}: ; Place the Else label 702 !undef ${_Logic}Else ; and remove it 703 !endif 704 !ifdef ${_Logic}EndSelect ; This won't be set if there weren't any cases 705 ${${_Logic}EndSelect}: ; Place the EndSelect 706 !undef ${_Logic}EndSelect ; and remove it 707 !endif 708 !undef ${_Logic}Select 709 !insertmacro _PopLogic 710 !verbose pop 711 !macroend 712 !define EndSelect `!insertmacro _EndSelect` 713 714 !macro _Switch _a 715 !verbose push 716 !verbose ${LOGICLIB_VERBOSITY} 717 !insertmacro _PushLogic 718 !insertmacro _PushScope Switch ${_Logic} ; Keep a separate stack for switch data 719 !insertmacro _PushScope Break _LogicLib_Label_${LOGICLIB_COUNTER} ; Get a lable for beyond the end of the switch 720 !insertmacro _IncreaseCounter 721 !define ${_Switch}Var `${_a}` ; Remember the left hand side of the comparison 722 !tempfile ${_Switch}Tmp ; Create a temporary file 723 !define ${_Logic}Switch _LogicLib_Label_${LOGICLIB_COUNTER} ; Get a label for the end of the switch 724 !insertmacro _IncreaseCounter 725 Goto ${${_Logic}Switch} ; and go there 726 !verbose pop 727 !macroend 728 !define Switch `!insertmacro _Switch` 729 730 !macro _Case _a 731 !verbose push 732 !verbose ${LOGICLIB_VERBOSITY} 733 !ifdef _Logic & ${_Logic}Select ; Check for an active Select 734 !insertmacro _Select_Case `${_a}` 735 !else ifndef _Switch ; If not then check for an active Switch 736 !error "Cannot use Case without a preceding Select or Switch" 737 !else 738 !define _label _LogicLib_Label_${LOGICLIB_COUNTER} ; Get a label for this case, 739 !insertmacro _IncreaseCounter 740 ${_label}: ; place it and add it's check to the temp file 741 !appendfile "${${_Switch}Tmp}" `!insertmacro _== $\`${${_Switch}Var}$\` $\`${_a}$\` ${_label} ""$\n` 742 !undef _label 743 !endif 744 !verbose pop 745 !macroend 746 747 !macro _CaseElse 748 !verbose push 749 !verbose ${LOGICLIB_VERBOSITY} 750 !ifdef _Logic & ${_Logic}Select ; Check for an active Select 751 !insertmacro _Select_CaseElse 752 !else ifndef _Switch ; If not then check for an active Switch 753 !error "Cannot use Case without a preceding Select or Switch" 754 !else ifdef ${_Switch}Else ; Already had a default case? 755 !error "Cannot use CaseElse following a CaseElse" 756 !else 757 !define ${_Switch}Else _LogicLib_Label_${LOGICLIB_COUNTER} ; Get a label for the default case, 758 !insertmacro _IncreaseCounter 759 ${${_Switch}Else}: ; and place it 760 !endif 761 !verbose pop 762 !macroend 763 764 !macro _EndSwitch 765 !verbose push 766 !verbose ${LOGICLIB_VERBOSITY} 767 !ifndef _Logic | ${_Logic}Switch 768 !error "Cannot use EndSwitch without a preceding Switch" 769 !endif 770 Goto ${_Break} ; Skip the jump table 771 ${${_Logic}Switch}: ; Place the end of the switch 772 !undef ${_Logic}Switch 773 !include "${${_Switch}Tmp}" ; Include the jump table 774 !delfile "${${_Switch}Tmp}" ; and clear it up 775 !ifdef ${_Switch}Else ; Was there a default case? 776 Goto ${${_Switch}Else} ; then go there if all else fails 777 !undef ${_Switch}Else 778 !endif 779 !undef ${_Switch}Tmp 780 !undef ${_Switch}Var 781 ${_Break}: ; Place the break label 782 !insertmacro _PopScope Break 783 !insertmacro _PopScope Switch 784 !insertmacro _PopLogic 785 !verbose pop 786 !macroend 787 !define EndSwitch `!insertmacro _EndSwitch` 788 789!endif ; LOGICLIB 790!verbose 3 791!define LOGICLIB_VERBOSITY ${_LOGICLIB_VERBOSITY} 792!undef _LOGICLIB_VERBOSITY 793!verbose pop 794