LogicLib.nsh 32 KB

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