home *** CD-ROM | disk | FTP | other *** search
/ Hackers Magazine 57 / CdHackersMagazineNr57.iso / Software / Programming / nsis-2.46-setup.exe / Include / LogicLib.nsh < prev    next >
Encoding:
Text File  |  2009-12-05  |  29.4 KB  |  793 lines

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