Hey, Here is another library to simplify the creation of your installs. This is the result of the previous post entitled "Select Statements". Thanks to eccles I have been able to completely rewrite it with improved functionality and speed.
Here is a list of the available statements:
if..elseif..else..endif
ifthen..|..|
ifcmd..||..|
select..case..case2..case3..case4..case5..case_else..endselect
for..exitfor..next
foreach..exitfor..next
do..exitdo..loop
dountil..exitdo..loop
do..exitdo..loopuntil
while..exitwhile..endwhile
Have a look at the provided example.nsi for working examples of the library. Once I get some feed back on possible changes or improvements then I will post it in the archive.
Don
NSIS Logic Library
43 posts
Hey Don, check your private messages...!
Dave.
Dave.
Version 2.1 adds break and continue labels to repeat type statements. Useful for functions like MessageBox, here is an example:
Thanks to eccles for the idea.
${do}
MessageBox MB_YESNO "Stop loop?" IDYES ${_break} ID_NO ${_continue}
${loop}
Damn, that's so cool! 🙂
Don, I've made a couple of changes for your perusal.
You've added some code to the If {ElseIf} [Else] EndIf code (ElseIf labels) that I don't understand - I'm not sure that they are needed?
Anyway, looking good! Should help newcommers to NSIS no end 🙂
--
Dave.
- Simplified IfThen by utilising If and EndIf
- Maybe something similar could be done with IfCmd but I've not investigated this yet
- Simplified For by utilising ForEach
- Fixed ForEach missing the final iteration
- Fixed a couple of Break/Continue bugs
You've added some code to the If {ElseIf} [Else] EndIf code (ElseIf labels) that I don't understand - I'm not sure that they are needed?
Anyway, looking good! Should help newcommers to NSIS no end 🙂
--
Dave.
Good work on the consolidation and fixes. I especially love your solution for the operation comparison in the foreach statement. Very nice. What were the issues with the break and continue labels? For the if..then statments I had to add some extra lines to handle just an if..else..endif statements. When I had something like the foloowing:
Both messages would appear. It wasn't moving to the end. Here it is again with the updated file header.
${if} 1 = 5
MessageBox MB_OK "test1"
${else}
MessageBox MB_OK "test2"
${endif}
Originally posted by dselkirkHeh, you have to jump through some hoops sometimes to get NSIS to do what you want, but it's not often impossible.
I especially love your solution for the operation comparison in the foreach statement.
What were the issues with the break and continue labels?Either For or ForEach was not setting them (I forget which) and a couple of places were pushing them instead of popping them (IIRC...).
Ah, OK fair enough. 🙂Both messages would appear.
${if} 1 = 5
MessageBox MB_OK "test1"
${else}
MessageBox MB_OK "test2"
${endif}
--
Dave.
Hi eccles & dselkirk!
You are amazing - very nice job done !
This is going to save quite some lines of script...
You are amazing - very nice job done !
This is going to save quite some lines of script...
NSIS LogicLib Version 2.3
Enjoy!
--
Dave.
- Much reworking and refactoring of things to help reduce duplication, etc. E.g. all loop varieties now go through a common set of macros.
- Added built-in support for the rest of NSIS's built-in conditional tests (Abort, Errors, FileExists, RebootFlag, Silent).
- Added ability to use any NSIS conditional command in a normal If type statement (no longer restricted to the specialised IfCmd statement).
- Optimised the code produced by If (fewer Goto's).
- Added statement similar to If that works in reverse: "Unless" executes the code in the contained block if the condition is false. If, Unless, ElseIf, ElseUnless, EndIf and EndUnless can be used freely in any combination.
- Fixed bug where using Continue in a Do..LoopUntil loop went to the top of the loop and not the loop condition.
- Added DoWhile..Loop and Do..LoopWhile loop varieties (the existing While..EndWhile loop is still available and is identical to DoWhile..Loop).
- Optimised the code produced by Select (fewer Goto's).
- Renamed Case_Else to CaseElse (nothing else has an underscore so why should that one). The old name is still available too though (if you must).
- CaseElse can also be called Default (for the C-minded).
Enjoy!
--
Dave.
NSIS LogicLib Version 2.4
--
Dave.
- Added Switch..Case*/Default..EndSwitch: similar to Select but behaves just like the C version. I.e.:
- Each Case is more like a label than a block so execution "falls through" unless you use Break.
- CaseElse (or Default) does not have to be the final case.
- Case*/Default can appear anywhere inside the Switch (e.g. inside an If inside the Switch).
(With thanks to kichik for the idea and proof-of-concept model). - Added unsigned integer comparisons U<, U>=, U> and U<=.
- Added 64-bit integer comparisons L=, L<>, L<, L>=, L> and L<= (these use System.dll).
- Added case-sensitive string tests S== and S!= (these use System.dll).
- Added string comparisons (not case sensitive) S<, S>=, S> and S<= (these use System.dll).
- Added section flag tests (SectionIsSelected, etc.) (to use these your script must include sections.nsh).
--
Dave.
I love it! 😁 👍
Great stuff! Truly amazing! What dou you come up with next? A NSIS compiler written in NSIS? 😁
There's only one thing which should be improved:
Get rid of the ${} around the commands.
For example by adding a DeclareCommand function to NSIS or something similar. DeclareCommand ${If} If would make the If command available which then works like any of the built-in commands.
Or another way: Add support for function parameters and get rid of call.
And last but not least: Implicit inclusion of LogicLib.nsh to every script 😉
Keep up the good work!
There's only one thing which should be improved:
Get rid of the ${} around the commands.
For example by adding a DeclareCommand function to NSIS or something similar. DeclareCommand ${If} If would make the If command available which then works like any of the built-in commands.
Or another way: Add support for function parameters and get rid of call.
And last but not least: Implicit inclusion of LogicLib.nsh to every script 😉
Keep up the good work!
These things will become possible when NSIS supports compiler plug-ins.
Compiler plugins? Whoah, any ETA?
NSIS 2.1 🙂
NSIS 2.0 has to be finished first.
NSIS 2.0 has to be finished first.
Thanks all for the thanks 😁 Thanks must also go out to Don (dselkirk) for planting the seed (and the code up to version 2.1 😉).
LogicLib has now been added to CVS and is included in the nightly snapshots and forthcoming NSIS releases.
I am open to ideas for other improvements and logic tests to encapsulate (such as the section flag tests added in the latest version).
--
Dave.
LogicLib has now been added to CVS and is included in the nightly snapshots and forthcoming NSIS releases.
I am open to ideas for other improvements and logic tests to encapsulate (such as the section flag tests added in the latest version).
And last but not least: Implicit inclusion of LogicLib.nsh to every script 😉nsisconf.nsh 😛
--
Dave.
New in CVS: LogicLib v2.5
- AndIf, AndUnless, OrIf, OrUnless added. These can be placed after If, Unless, ElseIf and ElseUnless to add any number of extra conditions. Order of precedence is strictly left-to-right though (or rather, top to bottom).
- Warnings of "unused variable _LOGICLIB_TEMP" are now avoided. When using the features that make use of this variable you will need to add a !define above !include LogicLib.nsh to let LogicLib know in advance. If you forget, a compiler error message will explain what is needed.
eccles this logic library is amazing. I've converted some of my scripts to use it and have been able to eliminate huge chunks of script because of it. Thanks alot man!
small question... can you not use LogicLib inside of macros with passed variables ?
e.g.
e.g.
!macro someMacro someVar
${If} ${someVar} == 0
# do something
${EndIf}
!macroend Tells me: !insertmacro: macro "_If" requires 4 parameter(s), passed 3!nevermind... it's fine..
The problem is that I'm passing the macro an empty string:
Work-arounds?
I'm a bit confused as to why an empty string becomes null if passed to a macro, though. In the latter bit, my string consisting of two quotation marks essentially becomes an empty string? 🙂
The problem is that I'm passing the macro an empty string:
!insertmacro someMacro "" And that throws the error. Apparently because once inside the macro, "" becomes <null>. Weird.Work-arounds?
!macro someMacro someVar
${If} "${someVar}" == "0"
# do something
${ElseIf} "${someVar}" == ""
# do something else
${EndIf}
!macroend That would kill any integer checks, though.!insertmacro someMacro "''" Seems to work - is that the proper way to go about this ?I'm a bit confused as to why an empty string becomes null if passed to a macro, though. In the latter bit, my string consisting of two quotation marks essentially becomes an empty string? 🙂
Quoting in the ${If} line is the correct way to get around this. Why would it kill any integer checks?
because I'm making the gross assumption that you can't compare a string to an int :x
Thanks for the pointer 🙂
Thanks for the pointer 🙂
But an integer is a string in NSIS. Commands that require integers automatically convert the string to an integer.
Hi,
i have a question how to use If in the new Logiclib.
${If} ${SectionIsSelected} ${CSEC}
!insertmacro UnSelectSection ${ESEC}
${EndIf}
i get an error: "macro "If" requires 3 parameter(s), passed 2!"
I don't understand
i have a question how to use If in the new Logiclib.
${If} ${SectionIsSelected} ${CSEC}
!insertmacro UnSelectSection ${ESEC}
${EndIf}
i get an error: "macro "If" requires 3 parameter(s), passed 2!"
I don't understand
Hi mamilo!
Did you write this code below the
Section Sec01 CSEC
declaration?
Cheers
Bruno
Did you write this code below the
Section Sec01 CSEC
declaration?
Cheers
Bruno
Shouldn't it be this?
${If} ${CSEC} = ${SectionIsSelected}
!insertmacro UnSelectSection ${ESEC}
${EndIf}
I think the code is correct.
But I believe the define has not yet been created by the compiler and therefore the constant is empty. Put the code below the section declaration.
But I believe the define has not yet been created by the compiler and therefore the constant is empty. Put the code below the section declaration.
How do I use the OrUnless Statement correctly? I want to do something when one of two sections is selected. Here is my code that doesn't work:
SectionGetFlags ${SEC02} $R0
Intop $R1 $R0 | 1
SectionGetFlags ${SEC03} $R2
Intop $R3 $R2 | 1
${Unless} $R0 <> $R1 ${OrUnless} $R2 <> $R3
Do Something
${EndUnless}
only one "if" statement per line
Is this correct?
SectionGetFlags ${SEC02} $R0
Intop $R1 $R0 | 1
SectionGetFlags ${SEC03} $R2
Intop $R3 $R2 | 1
${Unless} $R0 <> $R1
${OrUnless} $R2 <> $R3
Do Something
${EndUnless}