; NSIS LOGIC LIBRARY - LogicLib.nsh | |
; Version 2.6 - 08/12/2007 | |
; By dselkirk@hotmail.com | |
; and eccles@users.sf.net | |
; with IfNot support added by Message | |
; | |
; Questions/Comments - | |
; See http://forums.winamp.com/showthread.php?s=&postid=1116241 | |
; | |
; Description: | |
; Provides the use of various logic statements within NSIS. | |
; | |
; Usage: | |
; The following "statements" are available: | |
; If|IfNot|Unless..{ElseIf|ElseIfNot|ElseUnless}..[Else]..EndIf|EndUnless | |
; - Conditionally executes a block of statements, depending on the value | |
; of an expression. IfNot and Unless are equivalent and | |
; interchangeable, as are ElseIfNot and ElseUnless. | |
; AndIf|AndIfNot|AndUnless|OrIf|OrIfNot|OrUnless | |
; - Adds any number of extra conditions to If, IfNot, Unless, ElseIf, | |
; ElseIfNot and ElseUnless statements. | |
; IfThen|IfNotThen..|..| | |
; - Conditionally executes an inline statement, depending on the value | |
; of an expression. | |
; IfCmd..||..| | |
; - Conditionally executes an inline statement, depending on a true | |
; value of the provided NSIS function. | |
; Select..{Case[2|3|4|5]}..[CaseElse|Default]..EndSelect | |
; - Executes one of several blocks of statements, depending on the value | |
; of an expression. | |
; Switch..{Case|CaseElse|Default}..EndSwitch | |
; - Jumps to one of several labels, depending on the value of an | |
; expression. | |
; Do[While|Until]..{ExitDo|Continue|Break}..Loop[While|Until] | |
; - Repeats a block of statements until stopped, or depending on the | |
; value of an expression. | |
; While..{ExitWhile|Continue|Break}..EndWhile | |
; - An alias for DoWhile..Loop (for backwards-compatibility) | |
; For[Each]..{ExitFor|Continue|Break}..Next | |
; - Repeats a block of statements varying the value of a variable. | |
; | |
; The following "expressions" are available: | |
; Standard (built-in) string tests (which are case-insensitive): | |
; a == b; a != b | |
; Additional case-insensitive string tests (using System.dll): | |
; a S< b; a S>= b; a S> b; a S<= b | |
; Case-sensitive string tests: | |
; a S== b; a S!= b | |
; Standard (built-in) signed integer tests: | |
; a = b; a <> b; a < b; a >= b; a > b; a <= b | |
; Standard (built-in) unsigned integer tests: | |
; a U< b; a U>= b; a U> b; a U<= b | |
; 64-bit integer tests (using System.dll): | |
; a L= b; a L<> b; a L< b; a L>= b; a L> b; a L<= b | |
; ptrdiff_t integer tests | |
; a P= b; a P<> b; a P< b; a P>= b; a P> b; a P<= b | |
; Built-in NSIS flag tests: | |
; ${Abort}; ${Errors}; ${RebootFlag}; ${Silent} | |
; Built-in NSIS other tests: | |
; ${FileExists} a | |
; Any conditional NSIS instruction test: | |
; ${Cmd} a | |
; Section flag tests: | |
; ${SectionIsSelected} a; ${SectionIsSectionGroup} a; | |
; ${SectionIsSectionGroupEnd} a; ${SectionIsBold} a; | |
; ${SectionIsReadOnly} a; ${SectionIsExpanded} a; | |
; ${SectionIsPartiallySelected} a | |
; | |
; Examples: | |
; See LogicLib.nsi in the Examples folder for lots of example usage. | |
!verbose push | |
!verbose 3 | |
!ifndef LOGICLIB_VERBOSITY | |
!define LOGICLIB_VERBOSITY 3 | |
!endif | |
!define _LOGICLIB_VERBOSITY ${LOGICLIB_VERBOSITY} | |
!undef LOGICLIB_VERBOSITY | |
!verbose ${_LOGICLIB_VERBOSITY} | |
!ifndef LOGICLIB | |
!define LOGICLIB | |
!define | "'" | |
!define || "' '" | |
!define LOGICLIB_COUNTER 0 | |
!include Sections.nsh | |
!macro _LOGICLIB_TEMP | |
!ifndef _LOGICLIB_TEMP | |
!define _LOGICLIB_TEMP | |
Var /GLOBAL _LOGICLIB_TEMP ; Temporary variable to aid the more elaborate logic tests | |
!endif | |
!macroend | |
!macro LogicLib_JumpToBranch _Jump _Skip | |
StrCmp "" "" `${_Jump}` ${_Skip} | |
!macroend | |
!macro _IncreaseCounter | |
!define _LOGICLIB_COUNTER ${LOGICLIB_COUNTER} | |
!undef LOGICLIB_COUNTER | |
!define /math LOGICLIB_COUNTER ${_LOGICLIB_COUNTER} + 1 | |
!undef _LOGICLIB_COUNTER | |
!macroend | |
!macro _PushLogic | |
!insertmacro _PushScope Logic _LogicLib_Label_${LOGICLIB_COUNTER} | |
!insertmacro _IncreaseCounter | |
!macroend | |
!macro _PopLogic | |
!insertmacro _PopScope Logic | |
!macroend | |
!macro _PushScope Type label | |
!ifdef _${Type} ; If we already have a statement | |
!define _Cur${Type} ${_${Type}} | |
!undef _${Type} | |
!define _${Type} ${label} | |
!define ${_${Type}}Prev${Type} ${_Cur${Type}} ; Save the current logic | |
!undef _Cur${Type} | |
!else | |
!define _${Type} ${label} ; Initialise for first statement | |
!endif | |
!macroend | |
!macro _PopScope Type | |
!ifndef _${Type} | |
!error "Cannot use _Pop${Type} without a preceding _Push${Type}" | |
!endif | |
!ifdef ${_${Type}}Prev${Type} ; If a previous statment was active then restore it | |
!define _Cur${Type} ${_${Type}} | |
!undef _${Type} | |
!define _${Type} ${${_Cur${Type}}Prev${Type}} | |
!undef ${_Cur${Type}}Prev${Type} | |
!undef _Cur${Type} | |
!else | |
!undef _${Type} | |
!endif | |
!macroend | |
; String tests | |
!macro _== _a _b _t _f | |
StrCmp `${_a}` `${_b}` `${_t}` `${_f}` | |
!macroend | |
!macro _!= _a _b _t _f | |
!insertmacro _== `${_a}` `${_b}` `${_f}` `${_t}` | |
!macroend | |
; Case-sensitive string tests | |
!macro _S== _a _b _t _f | |
StrCmpS `${_a}` `${_b}` `${_t}` `${_f}` | |
!macroend | |
!macro _S!= _a _b _t _f | |
!insertmacro _S== `${_a}` `${_b}` `${_f}` `${_t}` | |
!macroend | |
; Extra string tests (cannot do these case-sensitively - I tried and lstrcmp still ignored the case) | |
!macro _StrCmpI _a _b _e _l _m | |
!insertmacro _LOGICLIB_TEMP | |
System::Call `kernel32::lstrcmpi(ts, ts) i.s` `${_a}` `${_b}` | |
Pop $_LOGICLIB_TEMP | |
IntCmp $_LOGICLIB_TEMP 0 `${_e}` `${_l}` `${_m}` | |
!macroend | |
!macro _S< _a _b _t _f | |
!insertmacro _StrCmpI `${_a}` `${_b}` `${_f}` `${_t}` `${_f}` | |
!macroend | |
!macro _S>= _a _b _t _f | |
!insertmacro _S< `${_a}` `${_b}` `${_f}` `${_t}` | |
!macroend | |
!macro _S> _a _b _t _f | |
!insertmacro _StrCmpI `${_a}` `${_b}` `${_f}` `${_f}` `${_t}` | |
!macroend | |
!macro _S<= _a _b _t _f | |
!insertmacro _S> `${_a}` `${_b}` `${_f}` `${_t}` | |
!macroend | |
; Integer tests | |
!macro _= _a _b _t _f | |
IntCmp `${_a}` `${_b}` `${_t}` `${_f}` `${_f}` | |
!macroend | |
!macro _<> _a _b _t _f | |
!insertmacro _= `${_a}` `${_b}` `${_f}` `${_t}` | |
!macroend | |
!macro _< _a _b _t _f | |
IntCmp `${_a}` `${_b}` `${_f}` `${_t}` `${_f}` | |
!macroend | |
!macro _>= _a _b _t _f | |
!insertmacro _< `${_a}` `${_b}` `${_f}` `${_t}` | |
!macroend | |
!macro _> _a _b _t _f | |
IntCmp `${_a}` `${_b}` `${_f}` `${_f}` `${_t}` | |
!macroend | |
!macro _<= _a _b _t _f | |
!insertmacro _> `${_a}` `${_b}` `${_f}` `${_t}` | |
!macroend | |
; Unsigned integer tests (NB: no need for extra equality tests) | |
!macro _U< _a _b _t _f | |
IntCmpU `${_a}` `${_b}` `${_f}` `${_t}` `${_f}` | |
!macroend | |
!macro _U>= _a _b _t _f | |
!insertmacro _U< `${_a}` `${_b}` `${_f}` `${_t}` | |
!macroend | |
!macro _U> _a _b _t _f | |
IntCmpU `${_a}` `${_b}` `${_f}` `${_f}` `${_t}` | |
!macroend | |
!macro _U<= _a _b _t _f | |
!insertmacro _U> `${_a}` `${_b}` `${_f}` `${_t}` | |
!macroend | |
; Int64 tests | |
!macro _Int64Cmp _a _o _b _t _f | |
!insertmacro _LOGICLIB_TEMP | |
System::Int64Op `${_a}` `${_o}` `${_b}` | |
Pop $_LOGICLIB_TEMP | |
!insertmacro _= $_LOGICLIB_TEMP 0 `${_f}` `${_t}` | |
!macroend | |
!macro _L= _a _b _t _f | |
!insertmacro _Int64Cmp `${_a}` = `${_b}` `${_t}` `${_f}` | |
!macroend | |
!macro _L<> _a _b _t _f | |
!insertmacro _L= `${_a}` `${_b}` `${_f}` `${_t}` | |
!macroend | |
!macro _L< _a _b _t _f | |
!insertmacro _Int64Cmp `${_a}` < `${_b}` `${_t}` `${_f}` | |
!macroend | |
!macro _L>= _a _b _t _f | |
!insertmacro _L< `${_a}` `${_b}` `${_f}` `${_t}` | |
!macroend | |
!macro _L> _a _b _t _f | |
!insertmacro _Int64Cmp `${_a}` > `${_b}` `${_t}` `${_f}` | |
!macroend | |
!macro _L<= _a _b _t _f | |
!insertmacro _L> `${_a}` `${_b}` `${_f}` `${_t}` | |
!macroend | |
; ptrdiff_t tests | |
!macro LogicLib_PtrDiffTest _o _a _b _t _f | |
!if ${NSIS_PTR_SIZE} <= 4 | |
!insertmacro _${_o} `${_a}` `${_b}` `${_t}` `${_f}` | |
!else | |
!insertmacro _L${_o} `${_a}` `${_b}` `${_t}` `${_f}` | |
!endif | |
!macroend | |
!macro _P= _a _b _t _f | |
!insertmacro LogicLib_PtrDiffTest = `${_a}` `${_b}` `${_t}` `${_f}` | |
!macroend | |
!macro _P<> _a _b _t _f | |
!insertmacro LogicLib_PtrDiffTest <> `${_a}` `${_b}` `${_t}` `${_f}` | |
!macroend | |
!macro _P< _a _b _t _f | |
!insertmacro LogicLib_PtrDiffTest < `${_a}` `${_b}` `${_t}` `${_f}` | |
!macroend | |
!macro _P>= _a _b _t _f | |
!insertmacro LogicLib_PtrDiffTest >= `${_a}` `${_b}` `${_t}` `${_f}` | |
!macroend | |
!macro _P> _a _b _t _f | |
!insertmacro LogicLib_PtrDiffTest > `${_a}` `${_b}` `${_t}` `${_f}` | |
!macroend | |
!macro _P<= _a _b _t _f | |
!insertmacro LogicLib_PtrDiffTest <= `${_a}` `${_b}` `${_t}` `${_f}` | |
!macroend | |
; Flag tests | |
!macro _Abort _a _b _t _f | |
IfAbort `${_t}` `${_f}` | |
!macroend | |
!define Abort `"" Abort ""` | |
!macro _Errors _a _b _t _f | |
IfErrors `${_t}` `${_f}` | |
!macroend | |
!define Errors `"" Errors ""` | |
!macro _FileExists _a _b _t _f | |
IfFileExists `${_b}` `${_t}` `${_f}` | |
!macroend | |
!define FileExists `"" FileExists` | |
!macro _RebootFlag _a _b _t _f | |
IfRebootFlag `${_t}` `${_f}` | |
!macroend | |
!define RebootFlag `"" RebootFlag ""` | |
!macro _Silent _a _b _t _f | |
IfSilent `${_t}` `${_f}` | |
!macroend | |
!define Silent `"" Silent ""` | |
; "Any instruction" test | |
!macro _Cmd _a _b _t _f | |
!define _t=${_t} | |
!ifdef _t= ; If no true label then make one | |
!define __t _LogicLib_Label_${LOGICLIB_COUNTER} | |
!insertmacro _IncreaseCounter | |
!else | |
!define __t ${_t} | |
!endif | |
${_b} ${__t} | |
!define _f=${_f} | |
!ifndef _f= ; If a false label then go there | |
Goto ${_f} | |
!endif | |
!undef _f=${_f} | |
!ifdef _t= ; If we made our own true label then place it | |
${__t}: | |
!endif | |
!undef __t | |
!undef _t=${_t} | |
!macroend | |
!define Cmd `"" Cmd` | |
; Section flag test | |
!macro _SectionFlagIsSet _a _b _t _f | |
!insertmacro _LOGICLIB_TEMP | |
SectionGetFlags `${_b}` $_LOGICLIB_TEMP | |
IntOp $_LOGICLIB_TEMP $_LOGICLIB_TEMP & `${_a}` | |
!insertmacro _= $_LOGICLIB_TEMP `${_a}` `${_t}` `${_f}` | |
!macroend | |
!define SectionIsSelected `${SF_SELECTED} SectionFlagIsSet` | |
!define SectionIsSubSection `${SF_SUBSEC} SectionFlagIsSet` | |
!define SectionIsSubSectionEnd `${SF_SUBSECEND} SectionFlagIsSet` | |
!define SectionIsSectionGroup `${SF_SECGRP} SectionFlagIsSet` | |
!define SectionIsSectionGroupEnd `${SF_SECGRPEND} SectionFlagIsSet` | |
!define SectionIsBold `${SF_BOLD} SectionFlagIsSet` | |
!define SectionIsReadOnly `${SF_RO} SectionFlagIsSet` | |
!define SectionIsExpanded `${SF_EXPAND} SectionFlagIsSet` | |
!define SectionIsPartiallySelected `${SF_PSELECTED} SectionFlagIsSet` | |
!define IfCmd `!insertmacro _IfThen "" Cmd ${|}` | |
!macro _If _c _a _o _b | |
!verbose push | |
!verbose ${LOGICLIB_VERBOSITY} | |
!insertmacro _PushLogic | |
!define ${_Logic}If | |
!define ${_Logic}Else _LogicLib_Label_${LOGICLIB_COUNTER} ; Get a label for the Else | |
!insertmacro _IncreaseCounter | |
!define _c=${_c} | |
!ifdef _c=true ; If is true | |
!insertmacro _${_o} `${_a}` `${_b}` "" ${${_Logic}Else} | |
!else ; If condition is false | |
!insertmacro _${_o} `${_a}` `${_b}` ${${_Logic}Else} "" | |
!endif | |
!undef _c=${_c} | |
!verbose pop | |
!macroend | |
!define If `!insertmacro _If true` | |
!define Unless `!insertmacro _If false` | |
!define IfNot `!insertmacro _If false` | |
!macro _And _c _a _o _b | |
!verbose push | |
!verbose ${LOGICLIB_VERBOSITY} | |
!ifndef _Logic | ${_Logic}If | |
!error "Cannot use And without a preceding If or IfNot/Unless" | |
!endif | |
!ifndef ${_Logic}Else | |
!error "Cannot use And following an Else" | |
!endif | |
!define _c=${_c} | |
!ifdef _c=true ; If is true | |
!insertmacro _${_o} `${_a}` `${_b}` "" ${${_Logic}Else} | |
!else ; If condition is false | |
!insertmacro _${_o} `${_a}` `${_b}` ${${_Logic}Else} "" | |
!endif | |
!undef _c=${_c} | |
!verbose pop | |
!macroend | |
!define AndIf `!insertmacro _And true` | |
!define AndUnless `!insertmacro _And false` | |
!define AndIfNot `!insertmacro _And false` | |
!macro _Or _c _a _o _b | |
!verbose push | |
!verbose ${LOGICLIB_VERBOSITY} | |
!ifndef _Logic | ${_Logic}If | |
!error "Cannot use Or without a preceding If or IfNot/Unless" | |
!endif | |
!ifndef ${_Logic}Else | |
!error "Cannot use Or following an Else" | |
!endif | |
!define _label _LogicLib_Label_${LOGICLIB_COUNTER} ; Skip this test as we already | |
!insertmacro _IncreaseCounter | |
Goto ${_label} ; have a successful result | |
${${_Logic}Else}: ; Place the Else label | |
!undef ${_Logic}Else ; and remove it | |
!define ${_Logic}Else _LogicLib_Label_${LOGICLIB_COUNTER} ; Get a label for the next Else and perform the new If | |
!insertmacro _IncreaseCounter | |
!define _c=${_c} | |
!ifdef _c=true ; If is true | |
!insertmacro _${_o} `${_a}` `${_b}` "" ${${_Logic}Else} | |
!else ; If condition is false | |
!insertmacro _${_o} `${_a}` `${_b}` ${${_Logic}Else} "" | |
!endif | |
!undef _c=${_c} | |
${_label}: | |
!undef _label | |
!verbose pop | |
!macroend | |
!define OrIf `!insertmacro _Or true` | |
!define OrUnless `!insertmacro _Or false` | |
!define OrIfNot `!insertmacro _Or false` | |
!macro _Else | |
!verbose push | |
!verbose ${LOGICLIB_VERBOSITY} | |
!ifndef _Logic | ${_Logic}If | |
!error "Cannot use Else without a preceding If or IfNot/Unless" | |
!endif | |
!ifndef ${_Logic}Else | |
!error "Cannot use Else following an Else" | |
!endif | |
!ifndef ${_Logic}EndIf ; First Else for this If? | |
!define ${_Logic}EndIf _LogicLib_Label_${LOGICLIB_COUNTER} ; Get a label for the EndIf | |
!insertmacro _IncreaseCounter | |
!endif | |
Goto ${${_Logic}EndIf} ; Go to the EndIf | |
${${_Logic}Else}: ; Place the Else label | |
!undef ${_Logic}Else ; and remove it | |
!verbose pop | |
!macroend | |
!define Else `!insertmacro _Else` | |
!macro _ElseIf _c _a _o _b | |
!verbose push | |
!verbose ${LOGICLIB_VERBOSITY} | |
${Else} ; Perform the Else | |
!define ${_Logic}Else _LogicLib_Label_${LOGICLIB_COUNTER} ; Get a label for the next Else and perform the new If | |
!insertmacro _IncreaseCounter | |
!define _c=${_c} | |
!ifdef _c=true ; If is true | |
!insertmacro _${_o} `${_a}` `${_b}` "" ${${_Logic}Else} | |
!else ; If condition is false | |
!insertmacro _${_o} `${_a}` `${_b}` ${${_Logic}Else} "" | |
!endif | |
!undef _c=${_c} | |
!verbose pop | |
!macroend | |
!define ElseIf `!insertmacro _ElseIf true` | |
!define ElseUnless `!insertmacro _ElseIf false` | |
!define ElseIfNot `!insertmacro _ElseIf false` | |
!macro _EndIf _n | |
!verbose push | |
!verbose ${LOGICLIB_VERBOSITY} | |
!ifndef _Logic | ${_Logic}If | |
!error "Cannot use End${_n} without a preceding If or IfNot/Unless" | |
!endif | |
!ifdef ${_Logic}Else | |
${${_Logic}Else}: ; Place the Else label | |
!undef ${_Logic}Else ; and remove it | |
!endif | |
!ifdef ${_Logic}EndIf | |
${${_Logic}EndIf}: ; Place the EndIf | |
!undef ${_Logic}EndIf ; and remove it | |
!endif | |
!undef ${_Logic}If | |
!insertmacro _PopLogic | |
!verbose pop | |
!macroend | |
!define EndIf `!insertmacro _EndIf If` | |
!define EndUnless `!insertmacro _EndIf Unless` | |
!macro _IfThen _a _o _b _t | |
!verbose push | |
!verbose ${LOGICLIB_VERBOSITY} | |
${If} `${_a}` `${_o}` `${_b}` | |
${_t} | |
${EndIf} | |
!verbose pop | |
!macroend | |
!define IfThen `!insertmacro _IfThen` | |
!macro _IfNotThen _a _o _b _t | |
!verbose push | |
!verbose ${LOGICLIB_VERBOSITY} | |
${IfNot} `${_a}` `${_o}` `${_b}` | |
${_t} | |
${EndIf} | |
!verbose pop | |
!macroend | |
!define IfNotThen `!insertmacro _IfNotThen` | |
!macro _ForEach _v _f _t _o _s | |
!verbose push | |
!verbose ${LOGICLIB_VERBOSITY} | |
StrCpy "${_v}" "${_f}" ; Assign the initial value | |
Goto +2 ; Skip the loop expression for the first iteration | |
!define _DoLoopExpression `IntOp "${_v}" "${_v}" "${_o}" "${_s}"` ; Define the loop expression | |
!define _o=${_o} | |
!ifdef _o=+ ; Check the loop expression operator | |
!define __o > ; to determine the correct loop condition | |
!else ifdef _o=- | |
!define __o < | |
!else | |
!error "Unsupported ForEach step operator (must be + or -)" | |
!endif | |
!undef _o=${_o} | |
!insertmacro _Do For false `${_v}` `${__o}` `${_t}` ; Let Do do the rest | |
!undef __o | |
!verbose pop | |
!macroend | |
!define ForEach `!insertmacro _ForEach` | |
!macro _For _v _f _t | |
!verbose push | |
!verbose ${LOGICLIB_VERBOSITY} | |
${ForEach} `${_v}` `${_f}` `${_t}` + 1 ; Pass on to ForEach | |
!verbose pop | |
!macroend | |
!define For `!insertmacro _For` | |
!define ExitFor `!insertmacro _Goto ExitFor For` | |
!define Next `!insertmacro _Loop For Next "" "" "" ""` | |
!define While `!insertmacro _Do While true` | |
!define ExitWhile `!insertmacro _Goto ExitWhile While` | |
!define EndWhile `!insertmacro _Loop While EndWhile "" "" "" ""` | |
!macro _Do _n _c _a _o _b | |
!verbose push | |
!verbose ${LOGICLIB_VERBOSITY} | |
!insertmacro _PushLogic | |
!define ${_Logic}${_n} _LogicLib_Label_${LOGICLIB_COUNTER} ; Get a label for the start of the loop | |
!insertmacro _IncreaseCounter | |
${${_Logic}${_n}}: | |
!insertmacro _PushScope Exit${_n} _LogicLib_Label_${LOGICLIB_COUNTER} ; Get a label for the end of the loop | |
!insertmacro _IncreaseCounter | |
!insertmacro _PushScope Break ${_Exit${_n}} ; Break goes to the end of the loop | |
!ifdef _DoLoopExpression | |
${_DoLoopExpression} ; Special extra parameter for inserting code | |
!undef _DoLoopExpression ; between the Continue label and the loop condition | |
!endif | |
!define _c=${_c} | |
!ifdef _c= ; No starting condition | |
!insertmacro _PushScope Continue _LogicLib_Label_${LOGICLIB_COUNTER} ; Get a label for Continue at the end of the loop | |
!insertmacro _IncreaseCounter | |
!else | |
!insertmacro _PushScope Continue ${${_Logic}${_n}} ; Continue goes to the start of the loop | |
!ifdef _c=true ; If is true | |
!insertmacro _${_o} `${_a}` `${_b}` "" ${_Exit${_n}} | |
!else ; If condition is false | |
!insertmacro _${_o} `${_a}` `${_b}` ${_Exit${_n}} "" | |
!endif | |
!endif | |
!undef _c=${_c} | |
!define ${_Logic}Condition ${_c} ; Remember the condition used | |
!verbose pop | |
!macroend | |
!define Do `!insertmacro _Do Do "" "" "" ""` | |
!define DoWhile `!insertmacro _Do Do true` | |
!define DoUntil `!insertmacro _Do Do false` | |
!macro _Goto _n _s | |
!verbose push | |
!verbose ${LOGICLIB_VERBOSITY} | |
!ifndef _${_n} | |
!error "Cannot use ${_n} without a preceding ${_s}" | |
!endif | |
Goto ${_${_n}} | |
!verbose pop | |
!macroend | |
!define ExitDo `!insertmacro _Goto ExitDo Do` | |
!macro _Loop _n _e _c _a _o _b | |
!verbose push | |
!verbose ${LOGICLIB_VERBOSITY} | |
!ifndef _Logic | ${_Logic}${_n} | |
!error "Cannot use ${_e} without a preceding ${_n}" | |
!endif | |
!define _c=${${_Logic}Condition} | |
!ifdef _c= ; If Do had no condition place the Continue label | |
${_Continue}: | |
!endif | |
!undef _c=${${_Logic}Condition} | |
!define _c=${_c} | |
!ifdef _c= ; No ending condition | |
Goto ${${_Logic}${_n}} | |
!else ifdef _c=true ; If condition is true | |
!insertmacro _${_o} `${_a}` `${_b}` ${${_Logic}${_n}} ${_Exit${_n}} | |
!else ; If condition is false | |
!insertmacro _${_o} `${_a}` `${_b}` ${_Exit${_n}} ${${_Logic}${_n}} | |
!endif | |
!undef _c=${_c} | |
Goto ${_Continue} ; Just to ensure it is referenced at least once | |
Goto ${_Exit${_n}} ; Just to ensure it is referenced at least once | |
${_Exit${_n}}: ; Place the loop exit point | |
!undef ${_Logic}Condition | |
!insertmacro _PopScope Continue | |
!insertmacro _PopScope Break | |
!insertmacro _PopScope Exit${_n} | |
!undef ${_Logic}${_n} | |
!insertmacro _PopLogic | |
!verbose pop | |
!macroend | |
!define Loop `!insertmacro _Loop Do Loop "" "" "" ""` | |
!define LoopWhile `!insertmacro _Loop Do LoopWhile true` | |
!define LoopUntil `!insertmacro _Loop Do LoopUntil false` | |
!define Continue `!insertmacro _Goto Continue "For or Do or While"` | |
!define Break `!insertmacro _Goto Break "For or Do or While"` | |
!macro _Select _a | |
!verbose push | |
!verbose ${LOGICLIB_VERBOSITY} | |
!insertmacro _PushLogic | |
!define ${_Logic}Select `${_a}` ; Remember the left hand side of the comparison | |
!verbose pop | |
!macroend | |
!define Select `!insertmacro _Select` | |
!macro _Select_CaseElse | |
!verbose push | |
!verbose ${LOGICLIB_VERBOSITY} | |
!ifndef _Logic | ${_Logic}Select | |
!error "Cannot use Case without a preceding Select" | |
!endif | |
!ifdef ${_Logic}EndSelect ; This is set only after the first case | |
!ifndef ${_Logic}Else | |
!error "Cannot use Case following a CaseElse" | |
!endif | |
Goto ${${_Logic}EndSelect} ; Go to the EndSelect | |
${${_Logic}Else}: ; Place the Else label | |
!undef ${_Logic}Else ; and remove it | |
!else | |
!define ${_Logic}EndSelect _LogicLib_Label_${LOGICLIB_COUNTER} ; Get a label for the EndSelect | |
!insertmacro _IncreaseCounter | |
!endif | |
!verbose pop | |
!macroend | |
!define CaseElse `!insertmacro _CaseElse` | |
!define Case_Else `!insertmacro _CaseElse` ; Compatibility with 2.2 and earlier | |
!define Default `!insertmacro _CaseElse` ; For the C-minded | |
!macro _Select_Case _a | |
!verbose push | |
!verbose ${LOGICLIB_VERBOSITY} | |
${CaseElse} ; Perform the CaseElse | |
!define ${_Logic}Else _LogicLib_Label_${LOGICLIB_COUNTER} ; Get a label for the next Else and perform the new Case | |
!insertmacro _IncreaseCounter | |
!insertmacro _== `${${_Logic}Select}` `${_a}` "" ${${_Logic}Else} | |
!verbose pop | |
!macroend | |
!define Case `!insertmacro _Case` | |
!macro _Case2 _a _b | |
!verbose push | |
!verbose ${LOGICLIB_VERBOSITY} | |
${CaseElse} ; Perform the CaseElse | |
!define ${_Logic}Else _LogicLib_Label_${LOGICLIB_COUNTER} ; Get a label for the next Else and perform the new Case | |
!insertmacro _IncreaseCounter | |
!insertmacro _== `${${_Logic}Select}` `${_a}` +2 "" | |
!insertmacro _== `${${_Logic}Select}` `${_b}` "" ${${_Logic}Else} | |
!verbose pop | |
!macroend | |
!define Case2 `!insertmacro _Case2` | |
!macro _Case3 _a _b _c | |
!verbose push | |
!verbose ${LOGICLIB_VERBOSITY} | |
${CaseElse} ; Perform the CaseElse | |
!define ${_Logic}Else _LogicLib_Label_${LOGICLIB_COUNTER} ; Get a label for the next Else and perform the new Case | |
!insertmacro _IncreaseCounter | |
!insertmacro _== `${${_Logic}Select}` `${_a}` +3 "" | |
!insertmacro _== `${${_Logic}Select}` `${_b}` +2 "" | |
!insertmacro _== `${${_Logic}Select}` `${_c}` "" ${${_Logic}Else} | |
!verbose pop | |
!macroend | |
!define Case3 `!insertmacro _Case3` | |
!macro _Case4 _a _b _c _d | |
!verbose push | |
!verbose ${LOGICLIB_VERBOSITY} | |
${CaseElse} ; Perform the CaseElse | |
!define ${_Logic}Else _LogicLib_Label_${LOGICLIB_COUNTER} ; Get a label for the next Else and perform the new Case | |
!insertmacro _IncreaseCounter | |
!insertmacro _== `${${_Logic}Select}` `${_a}` +4 "" | |
!insertmacro _== `${${_Logic}Select}` `${_b}` +3 "" | |
!insertmacro _== `${${_Logic}Select}` `${_c}` +2 "" | |
!insertmacro _== `${${_Logic}Select}` `${_d}` "" ${${_Logic}Else} | |
!verbose pop | |
!macroend | |
!define Case4 `!insertmacro _Case4` | |
!macro _Case5 _a _b _c _d _e | |
!verbose push | |
!verbose ${LOGICLIB_VERBOSITY} | |
${CaseElse} ; Perform the CaseElse | |
!define ${_Logic}Else _LogicLib_Label_${LOGICLIB_COUNTER} ; Get a label for the next Else and perform the new Case | |
!insertmacro _IncreaseCounter | |
!insertmacro _== `${${_Logic}Select}` `${_a}` +5 "" | |
!insertmacro _== `${${_Logic}Select}` `${_b}` +4 "" | |
!insertmacro _== `${${_Logic}Select}` `${_c}` +3 "" | |
!insertmacro _== `${${_Logic}Select}` `${_d}` +2 "" | |
!insertmacro _== `${${_Logic}Select}` `${_e}` "" ${${_Logic}Else} | |
!verbose pop | |
!macroend | |
!define Case5 `!insertmacro _Case5` | |
!macro _EndSelect | |
!verbose push | |
!verbose ${LOGICLIB_VERBOSITY} | |
!ifndef _Logic | ${_Logic}Select | |
!error "Cannot use EndSelect without a preceding Select" | |
!endif | |
!ifdef ${_Logic}Else | |
${${_Logic}Else}: ; Place the Else label | |
!undef ${_Logic}Else ; and remove it | |
!endif | |
!ifdef ${_Logic}EndSelect ; This won't be set if there weren't any cases | |
${${_Logic}EndSelect}: ; Place the EndSelect | |
!undef ${_Logic}EndSelect ; and remove it | |
!endif | |
!undef ${_Logic}Select | |
!insertmacro _PopLogic | |
!verbose pop | |
!macroend | |
!define EndSelect `!insertmacro _EndSelect` | |
!macro _Switch _a | |
!verbose push | |
!verbose ${LOGICLIB_VERBOSITY} | |
!insertmacro _PushLogic | |
!insertmacro _PushScope Switch ${_Logic} ; Keep a separate stack for switch data | |
!insertmacro _PushScope Break _LogicLib_Label_${LOGICLIB_COUNTER} ; Get a lable for beyond the end of the switch | |
!insertmacro _IncreaseCounter | |
!define ${_Switch}Var `${_a}` ; Remember the left hand side of the comparison | |
!tempfile ${_Switch}Tmp ; Create a temporary file | |
!define ${_Logic}Switch _LogicLib_Label_${LOGICLIB_COUNTER} ; Get a label for the end of the switch | |
!insertmacro _IncreaseCounter | |
Goto ${${_Logic}Switch} ; and go there | |
!verbose pop | |
!macroend | |
!define Switch `!insertmacro _Switch` | |
!macro _Case _a | |
!verbose push | |
!verbose ${LOGICLIB_VERBOSITY} | |
!ifdef _Logic & ${_Logic}Select ; Check for an active Select | |
!insertmacro _Select_Case `${_a}` | |
!else ifndef _Switch ; If not then check for an active Switch | |
!error "Cannot use Case without a preceding Select or Switch" | |
!else | |
!define _label _LogicLib_Label_${LOGICLIB_COUNTER} ; Get a label for this case, | |
!insertmacro _IncreaseCounter | |
${_label}: ; place it and add it's check to the temp file | |
!appendfile "${${_Switch}Tmp}" `!insertmacro _== $\`${${_Switch}Var}$\` $\`${_a}$\` ${_label} ""$\n` | |
!undef _label | |
!endif | |
!verbose pop | |
!macroend | |
!macro _CaseElse | |
!verbose push | |
!verbose ${LOGICLIB_VERBOSITY} | |
!ifdef _Logic & ${_Logic}Select ; Check for an active Select | |
!insertmacro _Select_CaseElse | |
!else ifndef _Switch ; If not then check for an active Switch | |
!error "Cannot use Case without a preceding Select or Switch" | |
!else ifdef ${_Switch}Else ; Already had a default case? | |
!error "Cannot use CaseElse following a CaseElse" | |
!else | |
!define ${_Switch}Else _LogicLib_Label_${LOGICLIB_COUNTER} ; Get a label for the default case, | |
!insertmacro _IncreaseCounter | |
${${_Switch}Else}: ; and place it | |
!endif | |
!verbose pop | |
!macroend | |
!macro _EndSwitch | |
!verbose push | |
!verbose ${LOGICLIB_VERBOSITY} | |
!ifndef _Logic | ${_Logic}Switch | |
!error "Cannot use EndSwitch without a preceding Switch" | |
!endif | |
Goto ${_Break} ; Skip the jump table | |
${${_Logic}Switch}: ; Place the end of the switch | |
!undef ${_Logic}Switch | |
!include "${${_Switch}Tmp}" ; Include the jump table | |
!delfile "${${_Switch}Tmp}" ; and clear it up | |
!ifdef ${_Switch}Else ; Was there a default case? | |
Goto ${${_Switch}Else} ; then go there if all else fails | |
!undef ${_Switch}Else | |
!endif | |
!undef ${_Switch}Tmp | |
!undef ${_Switch}Var | |
${_Break}: ; Place the break label | |
!insertmacro _PopScope Break | |
!insertmacro _PopScope Switch | |
!insertmacro _PopLogic | |
!verbose pop | |
!macroend | |
!define EndSwitch `!insertmacro _EndSwitch` | |
!endif ; LOGICLIB | |
!verbose 3 | |
!define LOGICLIB_VERBOSITY ${_LOGICLIB_VERBOSITY} | |
!undef _LOGICLIB_VERBOSITY | |
!verbose pop |