home *** CD-ROM | disk | FTP | other *** search
/ Chip 2004 March / CMCD0304.ISO / Software / Freeware / Programare / nullsoft / nsis20.exe / Include / LogicLib.nsh next >
Text File  |  2003-12-21  |  26KB  |  691 lines

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