From 46297fa6cd2cb85785a355a760e1026df550d2e9 Mon Sep 17 00:00:00 2001 From: eccles Date: Sun, 14 Dec 2003 00:23:56 +0000 Subject: [PATCH] NSIS Logic Library - dselkirk's logiclib 2.0: - Complete rewrite using new push/pop system. git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@3275 212acab6-be3b-0410-9dea-997c60f758d6 --- Examples/LogicLib.nsi | 107 +++++- Include/LogicLib.nsh | 762 ++++++++++++++++++++++++------------------ 2 files changed, 523 insertions(+), 346 deletions(-) diff --git a/Examples/LogicLib.nsi b/Examples/LogicLib.nsi index ced43ca3..8f34705d 100644 --- a/Examples/LogicLib.nsi +++ b/Examples/LogicLib.nsi @@ -1,22 +1,97 @@ -Name "test" -OutFile "test.exe" +Name "NSIS LogicLib Example" +OutFile "example.exe" SilentInstall silent !include "logiclib.nsh" +!define MsgBox "MessageBox MB_OK" Section - ${IF} "test" = "test2" - MessageBox MB_OK "test" - ${ELSE} - ${IF} "test" = "test" - ${SELECT} 5 - ${CASE} 4 - MessageBox MB_OK "case 4" - ${CASE} 5;6 - MessageBox MB_OK "case 5 or 6" - ${CASE_ELSE} - MessageBox MB_OK "case else" - ${ENDSELECT} - ${ENDIF} - ${ENDIF} + + ; if..elseif..else..endif + StrCpy $R1 1 ;change to test the following if statement + ${if} $R1 = 1 + MessageBox MB_OK "if: R1=1" + ${elseif} $R1 = 2 + MessageBox MB_OK "ifelse: R1=2" + ${else} + MessageBox MB_OK "else: R1=$R1" + ${endif} + + ; ifthen..|..| + StrCpy $R1 1 ; change to test ifthen statement. + ${ifthen} $R1 = 1 ${|} MessageBox MB_OK "R1=1" ${|} + + ; ifcmd..||..| + StrCpy $R1 "example.nsi" ; change to test ifcmd statement + ${ifcmd} IfFileExists "example.nsi" ${||} MessageBox MB_OK "IfFileExists: R1=$R1" ${|} + + ; select..case..case2..case3..case4..case5..case_else..endselect + StrCpy $R1 1 ;change to test the following if statement + ${select} $R1 + ${case} "1" + MessageBox MB_OK "case: R1=1" + ${case} "2" + MessageBox MB_OK "case: R1=2" + ${case2} "3" "4" + MessageBox MB_OK "case2: R1=3 or 4, R1=$R1" + ${case_else} + MessageBox MB_OK "caseelse: R1=$R1" + ${endselect} + + ; for..exitfor..next + ${for} $R1 1 5 + MessageBox MB_OK "for: R1=$R1" + ${next} + + ; foreach..exitfor..next + ${foreach} $R1 10 1 - 1 + MessageBox MB_OK "foreach: R1=$R1" + ${next} + + ; do..exitdo..loop + StrCpy $R1 0 + ${do} + IntOp $R1 $R1 + 1 + MessageBox MB_YESNO "Do..Loop statement test, iteration $R1.$\nDo you want to stop?" IDYES 0 IDNO +2 + ${exitdo} + ${loop} + + ; do..exitdo..loopuntil + StrCpy $R1 0 + ${do} + IntOp $R1 $R1 + 1 + ${loopuntil} $R1 >= 5 ; Change to test loop until + MessageBox MB_OK "do..loopuntil: R1=$R1" + + ; dountil..exitdo..loop + StrCpy $R1 0 + ${dountil} $R1 >= 5 ; Change to test loop until + IntOp $R1 $R1 + 1 + ${loop} + MessageBox MB_OK "dountil..loop: R1=$R1" + + ; exitdo statement test + StrCpy $R1 0 + StrCpy $R2 0 + ${do} + IntOp $R1 $R1 + 1 + IntCmp $R1 5 +2 +2 0 + ${exitdo} + StrCpy $R2 0 + ${do} + IntOp $R2 $R2 + 1 + MessageBox MB_OK "loop1: $R1$\nloop2: $R2" + IntCmp $R2 5 0 +2 0 + ${exitdo} + ${loop} + ${loop} + MessageBox MB_OK "loopR1: $R1$\nloop2: $R2" + + ; while..exitwhile..endwhile + StrCpy $R1 0 + ${while} $R1 < 5 ;change to test while statement. + IntOp $R1 $R1 + 1 + ${endwhile} + MessageBox MB_OK "while: R1=$R1" + SectionEnd \ No newline at end of file diff --git a/Include/LogicLib.nsh b/Include/LogicLib.nsh index e92d025d..e1a4f49f 100644 --- a/Include/LogicLib.nsh +++ b/Include/LogicLib.nsh @@ -1,372 +1,474 @@ ; NSIS LOGIC LIBRARY - logiclib.nsh -; Version 1.3 - 09/22/2003 +; Version 2.0 - 10/03/2003 ; Questions/Comments - dselkirk@hotmail.com +; Special thanks to eccles for Push/Pop Logic! ; ; Description: -; Provides the use of select and if statements within NSIS. +; Provides the use of various logic statements within NSIS. ; ; Notes: -; Only limitation is the statement depth. You can have no more than 10 statements -; within each other. -; ${IF} - 1 -; ${IF} - 2 -; ${IF} - 3 ... etc. +; Version 2 is a complete rewrite of the original. Here are some of the major differences: +; - Structure redesign based upon version by eccles. +; - No statement limitations. +; - Following statements are now available. +; if..elseif..else..endif +; - Conditionally executes a group of statements, depending on the value of an expression. +; ifthen..|..| +; - 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..case2..case3..case4..case5..case_else..endselect +; - Executes one of several groups of statements, depending on the value of an expression. +; for..exitfor..next +; - Repeats a group of statements a specified number of times. +; foreach..exitfor..next +; - Repeats a group of statements a specified number of times stepping in order specified. +; do..exitdo..loop +; - Repeats a block of statements until stopped. +; dountil..exitdo..loop +; - Repeats a block of statements until a condition is True. +; do..exitdo..loopuntil +; - Repeats a block of statements until a condition is True. +; while..exitwhile..endwhile +; - Executes a series of statements as long as a given condition is True. ; ; Usage: -; Select Statements - -; ${SELECT} "test1" -; ${CASE} "test1" -; MessageBox MB_OK "case: test1" -; ${CASE} "test 2;test3" -; MessageBox MB_OK "case: test2 or test3" -; ${CASE_ELSE} -; MessageBox MB_OK "case else" -; ${ENDSELECT} -; -; If Statements - -; ${IF} 5 > 10 -; MessageBox MB_OK "if: 5>10" -; ${ELSEIF} 5 = 10 -; MessageBox MB_OK "elseif: 5>10" -; ${ELSE} -; MessageBox MB_OK "else" -; ${ENDIF} +; See example.nsi ; ; History: ; 1.0 - 09/19/2003 - Initial release. ; 1.1 - 09/20/2003 - Added simplified macros and removed NAME requirement. -; 1.2 - 09/21/2003 - Changed library name to Lib. -; - Allow for 5 statements deep without use of name variable. -; - Added If..ElseIf..Else..Endif statements. +; 1.2 - 09/21/2003 - Changed library name to LogicLib. +; - Allow for 5 statements deep without use of name variable. +; - Added If..ElseIf..Else..Endif statements. ; 1.3 - 09/22/2003 - Fixed maximum allow statements. -; - Now allows 10 statement depth. -; - Condensed code. +; - Now allows 10 statement depth. +; - Condensed code. +; 2.0 - 10/03/2003 - Inital release 2, see notes. + +!verbose 3 !ifndef LOGICLIB !define LOGICLIB + !define | "'" + !define || "' '" - ; check if defines are already in use - !ifdef LOGIC_COUNTER \ - | LOGIC_DELIMITER \ - | LOGIC_NEXT \ - | LOGIC_STEP \ - | LOGIC_STEP_1 \ - | LOGIC_STEP_2 \ - | LOGIC_STEP_3 \ - | LOGIC_STEP_4 \ - | LOGIC_STEP_5 \ - | LOGIC_STEP_6 \ - | LOGIC_STEP_7 \ - | LOGIC_STEP_8 \ - | LOGIC_STEP_9 \ - | LOGIC_STEP_10 \ - | SELECT \ - | CASE \ - | CASE_ELSE \ - | SELECTEND \ - | IF \ - | ELSEIF \ - | ELSE \ - | ENDIF - !error "Defines required for this library are already in use." - !endif - - ; change if requried - !define LOGIC_DELIMITER ";" - - ; create quick macros - !define SELECT "!insertmacro SELECT" - !define CASE "!insertmacro CASE" - !define CASE_ELSE "!insertmacro CASE_ELSE" - !define ENDSELECT "!insertmacro ENDSELECT" - - !define IF "!insertmacro IF" - !define ELSEIF "!insertmacro ELSEIF" - !define ELSE "!insertmacro ELSE" - !define ENDIF "!insertmacro ENDIF" - - ; set local parameters based on counter and step - !macro LOGIC_DEFINES - !ifdef LOGIC_NEXT - !undef LOGIC_NEXT - !endif - !ifdef LOGIC_CURRENT - !undef LOGIC_CURRENT - !endif - !ifdef LOGIC_END - !undef LOGIC_END - !endif - !define LOGIC_END "LOGIC_${LOGIC_COUNTER}_${LOGIC_STEP}_END" - - !define LOGIC_CURRENT "${LOGIC_${LOGIC_COUNTER}_${LOGIC_STEP}_LINE}" - !define LOGIC_NEXT "LOGIC_${LOGIC_COUNTER}_${LOGIC_STEP}_${LOGIC_CURRENT}" - !macroend - - ; start new statment - !macro LOGIC_START - !ifdef LOGIC_STEP - !undef LOGIC_STEP - !ifdef LOGIC_STEP_2 - !ifdef LOGIC_STEP_3 - !ifdef LOGIC_STEP_4 - !ifdef LOGIC_STEP_5 - !ifdef LOGIC_STEP_6 - !ifdef LOGIC_STEP_7 - !ifdef LOGIC_STEP_8 - !ifdef LOGIC_STEP_9 - !ifdef LOGIC_STEP_10 - !error "Maximum statement depth reached." - !else - !define LOGIC_STEP 10 - !define LOGIC_STEP_10 - !endif - !else - !define LOGIC_STEP 9 - !define LOGIC_STEP_9 - !endif - !else - !define LOGIC_STEP 8 - !define LOGIC_STEP_8 - !endif - !else - !define LOGIC_STEP 7 - !define LOGIC_STEP_7 - !endif - !else - !define LOGIC_STEP 6 - !define LOGIC_STEP_6 - !endif - !else - !define LOGIC_STEP 5 - !define LOGIC_STEP_5 - !endif - !else - !define LOGIC_STEP 4 - !define LOGIC_STEP_4 - !endif - !else - !define LOGIC_STEP 3 - !define LOGIC_STEP_3 - !endif - !else - !define LOGIC_STEP 2 - !define LOGIC_STEP_2 - !endif + !macro _PushLogic + !ifdef _Logic ; If we already have a statement + !define _CurLogic ${_Logic} + !undef _Logic + !define _Logic _${__LINE__} + !define ${_Logic}Prev ${_CurLogic} ; Save the current logic + !undef _CurLogic !else - !define LOGIC_STEP 1 - !define LOGIC_STEP_1 - - !ifdef LOGIC_COUNTER - !undef LOGIC_COUNTER - !endif - !define LOGIC_COUNTER ${__LINE__} + !define _Logic _${__LINE__} ; Initialise for first statement !endif - !define "LOGIC_${LOGIC_COUNTER}_${LOGIC_STEP}_LINE" "${__LINE__}" - !insertmacro LOGIC_DEFINES - Goto "${LOGIC_NEXT}" !macroend - ; complete last statement and increment line number - !macro LOGIC_NEXT - !insertmacro LOGIC_DEFINES - Goto "${LOGIC_END}" - "${LOGIC_NEXT}:" - !undef "LOGIC_${LOGIC_COUNTER}_${LOGIC_STEP}_LINE" - !define "LOGIC_${LOGIC_COUNTER}_${LOGIC_STEP}_LINE" "${__LINE__}" - !insertmacro LOGIC_DEFINES - !macroend - - ; complete statement and cleanup defines - !macro LOGIC_END - !insertmacro LOGIC_DEFINES - Goto "${LOGIC_END}" - Goto "${LOGIC_NEXT}" - "${LOGIC_NEXT}:" - "${LOGIC_END}:" - - !undef LOGIC_END - !undef LOGIC_NEXT - !undef "LOGIC_${LOGIC_COUNTER}_${LOGIC_STEP}_LINE" - !undef LOGIC_CURRENT - - !undef LOGIC_STEP - !ifndef LOGIC_STEP_10 - !ifndef LOGIC_STEP_9 - !ifndef LOGIC_STEP_8 - !ifndef LOGIC_STEP_7 - !ifndef LOGIC_STEP_6 - !ifndef LOGIC_STEP_5 - !ifndef LOGIC_STEP_4 - !ifndef LOGIC_STEP_3 - !ifndef LOGIC_STEP_2 - !ifndef LOGIC_STEP_1 - !undef LOGIC_STEP_1 - !endif - !else - !undef LOGIC_STEP_2 - !define LOGIC_STEP 1 - !endif - !else - !undef LOGIC_STEP_3 - !define LOGIC_STEP 2 - !endif - !else - !undef LOGIC_STEP_4 - !define LOGIC_STEP 3 - !endif - !else - !undef LOGIC_STEP_5 - !define LOGIC_STEP 4 - !endif - !else - !undef LOGIC_STEP_5 - !define LOGIC_STEP 4 - !endif - !else - !undef LOGIC_STEP_6 - !define LOGIC_STEP 5 - !endif - !else - !undef LOGIC_STEP_8 - !define LOGIC_STEP 7 - !endif - !else - !undef LOGIC_STEP_9 - !define LOGIC_STEP 8 - !endif + !macro _PopLogic + !ifdef ${_Logic}Prev ; If a previous statment was active then restore it + !define _CurLogic ${_Logic} + !undef _Logic + !define _Logic ${${_CurLogic}Prev} + !undef ${_CurLogic}Prev + !undef _CurLogic !else - !undef LOGIC_STEP_10 - !define LOGIC_STEP 9 + !undef _Logic !endif !macroend - !macro ELSEIF VALUE1 OP VALUE2 - !insertmacro LOGIC_NEXT - - StrCmp "${OP}" "<>" "${LOGIC_NEXT}_NotEqual" - StrCmp "${OP}" "<" "${LOGIC_NEXT}_Less" - StrCmp "${OP}" ">" "${LOGIC_NEXT}_Greater" - StrCmp "${OP}" "<=" "${LOGIC_NEXT}_LessEqual" - StrCmp "${OP}" ">=" "${LOGIC_NEXT}_GreaterEqual" - StrCmp "${OP}" "=" "${LOGIC_NEXT}_Equal" 0 ;default - - "${LOGIC_NEXT}_Equal:" - StrCmp "${VALUE1}" "${VALUE2}" 0 "${LOGIC_NEXT}" - Goto "${LOGIC_NEXT}_done" - - "${LOGIC_NEXT}_NotEqual:" - StrCmp "${VALUE1}" "${VALUE2}" "${LOGIC_NEXT}" 0 - Goto "${LOGIC_NEXT}_done" - - "${LOGIC_NEXT}_Less:" - IntCmp "${VALUE1}" "${VALUE2}" "${LOGIC_NEXT}" 0 "${LOGIC_NEXT}" - Goto "${LOGIC_NEXT}_done" - - "${LOGIC_NEXT}_Greater:" - IntCmp "${VALUE1}" "${VALUE2}" "${LOGIC_NEXT}" "${LOGIC_NEXT}" 0 - Goto "${LOGIC_NEXT}_done" - - "${LOGIC_NEXT}_LessEqual:" - IntCmp "${VALUE1}" "${VALUE2}" 0 0 "${LOGIC_NEXT}" - Goto "${LOGIC_NEXT}_done" - - "${LOGIC_NEXT}_GreaterEqual:" - IntCmp "${VALUE1}" "${VALUE2}" 0 "${LOGIC_NEXT}" 0 - Goto "${LOGIC_NEXT}_done" - - "${LOGIC_NEXT}_done:" + !macro _PushCustom Type endlabel + !ifdef _${Type} ; If we already have a statement + !define _Cur${Type} ${_${Type}} + !undef _${Type} + !define _${Type} ${endlabel} + !define ${_${Type}}Prev${Type} ${_Cur${Type}} ; Save the current logic + !undef _Cur${Type} + !else + !define _${Type} ${endlabel} ; Initialise for first statement + !endif !macroend - !macro IF VALUE1 OP VALUE2 - !insertmacro LOGIC_START - !insertmacro ELSEIF "${VALUE1}" "${OP}" "${VALUE2}" + !macro _PopCustom 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 - !macro ELSE - !insertmacro LOGIC_NEXT + ; String tests + !macro _== _a _b _t _f + StrCmp "${_a}" "${_b}" "${_t}" "${_f}" !macroend - !macro ENDIF - !insertmacro LOGIC_END + !macro _!= _a _b _t _f + !insertmacro _== "${_a}" "${_b}" "${_f}" "${_t}" !macroend - !macro SELECT VALUE - !insertmacro LOGIC_START - !define "LOGIC_${LOGIC_COUNTER}_${LOGIC_STEP}_VALUE" "${VALUE}" + ; Integer tests + !macro _= _a _b _t _f + IntCmp "${_a}" "${_b}" "${_t}" "${_f}" "${_f}" !macroend - !macro CASE VALUES - !insertmacro LOGIC_NEXT - Push $R1 ;counter - Push $R2 ;value - Push $R3 ;return - StrCpy $R1 "${VALUES};" - "${LOGIC_NEXT}_loop:" - StrCmp $R1 "" "${LOGIC_NEXT}" - Push "$R1" - Push ";" - Call StrTok - Pop $R2 - Pop $R1 - StrCmp $R2 "${LOGIC_${LOGIC_COUNTER}_${LOGIC_STEP}_VALUE}" "${LOGIC_NEXT}_done" "${LOGIC_NEXT}_loop" - "${LOGIC_NEXT}_done:" - Pop $R3 - Pop $R2 - Pop $R1 + !macro _<> _a _b _t _f + !insertmacro _= "${_a}" "${_b}" "${_f}" "${_t}" !macroend - !macro CASE_ELSE - !insertmacro LOGIC_NEXT + !macro _< _a _b _t _f + IntCmp "${_a}" "${_b}" "${_f}" "${_t}" "${_f}" !macroend - !macro ENDSELECT -!undef "LOGIC_${LOGIC_COUNTER}_${LOGIC_STEP}_VALUE" - !insertmacro LOGIC_END + !macro _>= _a _b _t _f + !insertmacro _< "${_a}" "${_b}" "${_f}" "${_t}" !macroend -Function StrTok - Exch $R1 - Exch 1 - Exch $R0 - Push $R2 - Push $R3 - Push $R4 - Push $R5 - StrLen $R2 $R0 - IntOp $R2 $R2 + 1 - loop1: - IntOp $R2 $R2 - 1 - IntCmp $R2 0 exit - StrCpy $R4 $R0 1 -$R2 - StrLen $R3 $R1 - IntOp $R3 $R3 + 1 - loop2: - IntOp $R3 $R3 - 1 - IntCmp $R3 0 loop1 - StrCpy $R5 $R1 1 -$R3 - StrCmp $R4 $R5 Found - Goto loop2 - Goto loop1 - exit: - StrCpy $R1 "" - StrCpy $R0 "" - Goto Cleanup - Found: - StrLen $R3 $R0 - IntOp $R3 $R3 - $R2 - StrCpy $R1 $R0 $R3 - IntOp $R2 $R2 - 1 - IntOp $R3 $R3 + 1 - StrCpy $R0 $R0 $R2 $R3 - Cleanup: - Pop $R5 - Pop $R4 - Pop $R3 - Pop $R2 - Exch $R0 - Exch 1 - Exch $R1 - Return -FunctionEnd + !macro _> _a _b _t _f + IntCmp "${_a}" "${_b}" "${_f}" "${_f}" "${_t}" + !macroend -!endif ; LOGICLIB \ No newline at end of file + !macro _<= _a _b _t _f + !insertmacro _> "${_a}" "${_b}" "${_f}" "${_t}" + !macroend + + !macro IfThen _a _o _b _t + !verbose 3 + !insertmacro _PushLogic + !define ${_Logic}IfThen _${__LINE__} ; Get a label for the (provisional) EndIf (it might turn out to be Else) + !insertmacro _${_o} "${_a}" "${_b}" "" ${${_Logic}IfThen} + ${_t} + Goto ${${_Logic}IfThen} + ${${_Logic}IfThen}: ; Place the EndIf + !undef ${_Logic}IfThen + !insertmacro _PopLogic + !verbose 4 + !macroend + !define IfThen "!insertmacro IfThen" + + !macro IfCmd _a _t + !verbose 3 + !insertmacro _PushLogic + !define ${_Logic}IfTrue _${__LINE__} + !define ${_Logic}IfCmd _${__LINE__} + ${_a} ${${_Logic}IfTrue} + Goto ${${_Logic}IfCmd} + ${${_Logic}IfTrue}: + ${_t} + Goto ${${_Logic}IfCmd} + ${${_Logic}IfCmd}: ; Place the EndIf + !undef ${_Logic}IfTrue + !undef ${_Logic}IfCmd + !insertmacro _PopLogic + !verbose 4 + !macroend + !define IfCmd "!insertmacro IfCmd '" + + !macro If _a _o _b + !verbose 3 + !insertmacro _PushLogic + !define ${_Logic}Elseif _${__LINE__} ; Get a label for the (provisional) EndIf (it might turn out to be Else) + !define ${_Logic}EndIf _${__LINE__} ; Get a label for the (provisional) EndIf (it might turn out to be Else) + !insertmacro _${_o} "${_a}" "${_b}" "" ${${_Logic}Elseif} + !verbose 4 + !macroend + !define If "!insertmacro If" + + !macro Else + !verbose 3 + !ifndef _Logic | ${_Logic}Elseif + !error "Cannot use Else|Elseif without a preceding If" + !endif + !ifdef ${_Logic}Else + !error "Cannot use Else after Else" + !endif + Goto ${${_Logic}EndIf} + !define ${_Logic}Else ${${_Logic}Elseif} ; Save current Else label + !undef ${_Logic}Elseif + !define ${_Logic}Elseif _${__LINE__} ; Get a label for the (new) EndIf and go there + ${${_Logic}Else}: ; Place the saved Else label + !verbose 4 + !macroend + !define Else "!insertmacro Else" + + !macro ElseIf _a _o _b + !verbose 3 + !insertmacro Else ; Place in Else code as normal + !undef ${_Logic}Else ; Forget the Else and perform the new If + !insertmacro _${_o} "${_a}" "${_b}" "" ${${_Logic}Elseif} + !verbose 4 + !macroend + !define ElseIf "!insertmacro ElseIf" + + !macro EndIf + !verbose 3 + !ifndef _Logic | ${_Logic}Elseif + !error "Cannot use EndIf without a preceding If" + !endif + Goto ${${_Logic}EndIf} + Goto ${${_Logic}ElseIf} + ${${_Logic}ElseIf}: + ${${_Logic}EndIf}: ; Place the EndIf + !undef ${_Logic}Elseif + !undef ${_Logic}EndIf + !ifdef ${_Logic}Else + !undef ${_Logic}Else ; Clear the Else flag + !endif + !insertmacro _PopLogic + !verbose 4 + !macroend + !define EndIf "!insertmacro EndIf" + + !macro For _v _f _t + !verbose 3 + StrCpy ${_v} ${_f} + !insertmacro _PushLogic + !define ${_Logic}For _${__LINE__} ; Get a label for the start of the loop + !define ${_Logic}For2 _${__LINE__} ; Get a label for the start of the loop + !define ${_Logic}Next _${__LINE__} ; Get a label for the end of the loop + !insertmacro _PushCustom "ExitFor" ${${_Logic}Next} + Goto ${${_Logic}For2} + ${${_Logic}For}: ; Insert the loop condition + IntOp ${_v} ${_v} + 1 + ${${_Logic}For2}: ; Insert the loop condition + !insertmacro _> ${_v} ${_t} ${${_Logic}Next} "" + !undef ${_Logic}For2 + !verbose 4 + !macroend + !define For "!insertmacro For" + + !macro ForEach _v _f _t _o _s + !verbose 3 + StrCpy ${_v} ${_f} + !insertmacro _PushLogic + !define ${_Logic}For _${__LINE__} ; Get a label for the start of the loop + !define ${_Logic}For2 _${__LINE__} ; Get a label for the start of the loop + !define ${_Logic}Next _${__LINE__} ; Get a label for the end of the loop + !insertmacro _PushCustom "ExitFor" ${${_Logic}Next} + Goto ${${_Logic}For2} + ${${_Logic}For}: ; Insert the loop condition + IntOp ${_v} ${_v} ${_o} ${_s} + ${${_Logic}For2}: ; Insert the loop condition + IntCmp ${_v} ${_t} ${${_Logic}Next} + !undef ${_Logic}For2 + !verbose 4 + !macroend + !define ForEach "!insertmacro ForEach" + + !macro ExitFor + Goto ${_ExitFor} + !macroend + !define ExitFor "!insertmacro ExitFor" + + !macro Next + !verbose 3 + !ifndef _Logic | ${_Logic}For + !error "Cannot use Next without a preceding For" + !endif + Goto ${${_Logic}For} ; Loop back to the For condition + ${${_Logic}Next}: ; Place the Next + !undef ${_Logic}For + !undef ${_Logic}Next + !insertmacro _PopLogic + !insertmacro _PopCustom "ExitFor" + !verbose 4 + !macroend + !define Next "!insertmacro Next" + + !macro While _a _o _b + !verbose 3 + !insertmacro _PushLogic + !define ${_Logic}While _${__LINE__} ; Get a label for the start of the loop + !define ${_Logic}EndWhile _${__LINE__} ; Get a label for the end of the loop + !insertmacro _PushCustom "ExitWhile" ${${_Logic}EndWhile} + ${${_Logic}While}: ; Insert the loop condition + !insertmacro _${_o} "${_a}" "${_b}" "" ${${_Logic}EndWhile} + !verbose 4 + !macroend + !define While "!insertmacro While" + + !macro ExitWhile + Goto ${_ExitWhile} + !macroend + !define ExitWhile "!insertmacro ExitWhile" + + !macro EndWhile + !verbose 3 + !ifndef _Logic | ${_Logic}While + !error "Cannot use EndWhile without a preceding While" + !endif + Goto ${${_Logic}While} ; Loop back to the While condition + ${${_Logic}EndWhile}: ; Place the EndWhile + !undef ${_Logic}While + !undef ${_Logic}EndWhile + !insertmacro _PopLogic + !insertmacro _PopCustom "ExitWhile" + !verbose 4 + !macroend + !define EndWhile "!insertmacro EndWhile" + + !macro Do + !verbose 3 + !insertmacro _PushLogic + !define ${_Logic}Do _${__LINE__} ; Get a label for the start of the loop + !define ${_Logic}Loop _${__LINE__} ; Get a label for the end of the loop + !insertmacro _PushCustom "ExitDo" ${${_Logic}Loop} + ${${_Logic}Do}: ; Insert the loop condition + !verbose 4 + !macroend + !define Do "!insertmacro Do" + + !macro DoUntil _a _o _b + !verbose 3 + !insertmacro Do + !insertmacro _${_o} "${_a}" "${_b}" ${${_Logic}Loop} "" + !verbose 4 + !macroend + !define DoUntil "!insertmacro DoUntil" + + !macro ExitDo + Goto ${_ExitDo} + !macroend + !define ExitDo "!insertmacro ExitDo" + + !macro Loop + !verbose 3 + !ifndef _Logic | ${_Logic}Do + !error "Cannot use EndWhile without a preceding Do" + !endif + Goto ${${_Logic}Do} ; Loop back to the Do condition + ${${_Logic}Loop}: ; Place the Loop + !undef ${_Logic}Do + !undef ${_Logic}Loop + !insertmacro _PopLogic + !insertmacro _PopCustom "ExitDo" + !verbose 4 + !macroend + !define Loop "!insertmacro Loop" + + !macro LoopUntil _a _o _b + !verbose 3 + !ifndef _Logic | ${_Logic}Do + !error "Cannot use EndWhile without a preceding Do" + !endif + !insertmacro _${_o} "${_a}" "${_b}" ${${_Logic}Loop} ${${_Logic}Do} + ${${_Logic}Loop}: ; Place the Loop + !undef ${_Logic}Do + !undef ${_Logic}Loop + !insertmacro _PopLogic + !insertmacro _PopCustom "ExitDo" + !verbose 4 + !macroend + !define LoopUntil "!insertmacro LoopUntil" + + !macro Select _a + !verbose 3 + !insertmacro _PushLogic + !define ${_Logic}Case _${__LINE__} ; Get a label for the (provisional) EndSelect (it might turn out to be case_else) + !define ${_Logic}EndSelect _${__LINE__} ; Get a label for the (provisional) EndIf (it might turn out to be Else) + !define ${_Logic}Value "${_a}" + Goto ${${_Logic}Case} + !verbose 4 + !macroend + !define Select "!insertmacro Select" + + !macro Case_Else + !verbose 3 + !ifndef _Logic | ${_Logic}Case + !error "Cannot use Case|case_else without a preceding Select" + !endif + !ifdef ${_Logic}case_else + !error "Cannot use case_else after case_else" + !endif + Goto ${${_Logic}EndSelect} + !define ${_Logic}case_else ${${_Logic}Case} ; Save current case_else label + !undef ${_Logic}Case + !define ${_Logic}Case _${__LINE__} ; Get a label for the (new) EndSelect and go there + ${${_Logic}case_else}: ; Place the saved case_else label + !verbose 4 + !macroend + !define case_else "!insertmacro case_else" + + !macro Case _a + !verbose 3 + !insertmacro Case_Else ; Place in case_else code as normal + !undef ${_Logic}case_else ; Forget the case_else and perform the new Case + !insertmacro _== "${_a}" "${${_Logic}Value}" "" ${${_Logic}Case} + !verbose 4 + !macroend + !define Case "!insertmacro Case" + + !macro Case2 _a _b + !verbose 3 + !insertmacro case_else ; Place in case_else code as normal + !undef ${_Logic}case_else ; Forget the case_else and perform the new Case + !insertmacro _== "${_a}" "${${_Logic}Value}" +2 0 + !insertmacro _== "${_b}" "${${_Logic}Value}" 0 ${${_Logic}Case} + !verbose 4 + !macroend + !define Case2 "!insertmacro Case2" + + !macro Case3 _a _b _c + !verbose 3 + !insertmacro case_else ; Place in case_else code as normal + !undef ${_Logic}case_else ; Forget the case_else and perform the new Case + !insertmacro _== "${_a}" "${${_Logic}Value}" +3 0 + !insertmacro _== "${_b}" "${${_Logic}Value}" +2 0 + !insertmacro _== "${_c}" "${${_Logic}Value}" 0 ${${_Logic}Case} + !verbose 4 + !macroend + !define Case3 "!insertmacro Case3" + + !macro Case4 _a _b _c _d + !verbose 3 + !insertmacro case_else ; Place in case_else code as normal + !undef ${_Logic}case_else ; Forget the case_else and perform the new Case + !insertmacro _== "${_a}" "${${_Logic}Value}" +4 0 + !insertmacro _== "${_b}" "${${_Logic}Value}" +3 0 + !insertmacro _== "${_c}" "${${_Logic}Value}" +2 0 + !insertmacro _== "${_d}" "${${_Logic}Value}" 0 ${${_Logic}Case} + !verbose 4 + !macroend + !define Case4 "!insertmacro Case4" + + !macro Case5 _a _b _c _d _e + !verbose 3 + !insertmacro case_else ; Place in case_else code as normal + !undef ${_Logic}case_else ; Forget the case_else and perform the new Case + !insertmacro _== "${_a}" "${${_Logic}Value}" +5 0 + !insertmacro _== "${_b}" "${${_Logic}Value}" +4 0 + !insertmacro _== "${_c}" "${${_Logic}Value}" +3 0 + !insertmacro _== "${_d}" "${${_Logic}Value}" +2 0 + !insertmacro _== "${_e}" "${${_Logic}Value}" 0 ${${_Logic}Case} + !verbose 4 + !macroend + !define Case5 "!insertmacro Case5" + + !macro EndSelect + !verbose 3 + !ifndef _Logic | ${_Logic}Case + !error "Cannot use EndSelect without a preceding Select" + !endif + Goto ${${_Logic}Case} + Goto ${${_Logic}EndSelect} + ${${_Logic}Case}: + ${${_Logic}EndSelect}: ; Place the EndSelect + !undef ${_Logic}Case + !undef ${_Logic}EndSelect + !undef ${_Logic}Value + !ifdef ${_Logic}case_else + !undef ${_Logic}case_else ; Clear the case_else flag + !endif + !insertmacro _PopLogic + !verbose 4 + !macroend + !define EndSelect "!insertmacro EndSelect" + +!endif ; LOGICLIB +!verbose 4 \ No newline at end of file