Old 3rd October 2003, 14:34   #1
dselkirk
Senior Member
 
Join Date: Aug 2002
Posts: 118
Exclamation NSIS Logic Library

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
Attached Files
File Type: zip logiclib.zip (3.6 KB, 1320 views)
dselkirk is offline   Reply With Quote
Old 3rd October 2003, 18:37   #2
eccles
NSIS Dev
 
eccles's Avatar
 
Join Date: Sep 2001
Location: Leicester, UK
Posts: 193
Hey Don, check your private messages...!

Dave.
eccles is offline   Reply With Quote
Old 5th October 2003, 22:06   #3
dselkirk
Senior Member
 
Join Date: Aug 2002
Posts: 118
Version 2.1 adds break and continue labels to repeat type statements. Useful for functions like MessageBox, here is an example:

code:

${do}
MessageBox MB_YESNO "Stop loop?" IDYES ${_break} ID_NO ${_continue}
${loop}



Thanks to eccles for the idea.
Attached Files
File Type: zip logiclib.zip (3.7 KB, 751 views)
dselkirk is offline   Reply With Quote
Old 7th October 2003, 00:02   #4
kichik
M.I.A.
[NSIS Dev, Mod]
 
kichik's Avatar
 
Join Date: Oct 2001
Location: Israel
Posts: 11,343
Damn, that's so cool!

NSIS FAQ | NSIS Home Page | Donate $
"I hear and I forget. I see and I remember. I do and I understand." -- Confucius
kichik is offline   Reply With Quote
Old 7th October 2003, 12:56   #5
eccles
NSIS Dev
 
eccles's Avatar
 
Join Date: Sep 2001
Location: Leicester, UK
Posts: 193
Don, I've made a couple of changes for your perusal.
  • 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.
Attached Files
File Type: nsh logiclib.nsh (16.2 KB, 804 views)
eccles is offline   Reply With Quote
Old 7th October 2003, 13:55   #6
dselkirk
Senior Member
 
Join Date: Aug 2002
Posts: 118
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:
code:

${if} 1 = 5
MessageBox MB_OK "test1"
${else}
MessageBox MB_OK "test2"
${endif}


Both messages would appear. It wasn't moving to the end. Here it is again with the updated file header.
Attached Files
File Type: zip logiclib.zip (3.8 KB, 789 views)
dselkirk is offline   Reply With Quote
Old 7th October 2003, 15:04   #7
eccles
NSIS Dev
 
eccles's Avatar
 
Join Date: Sep 2001
Location: Leicester, UK
Posts: 193
Quote:
Originally posted by dselkirk
I especially love your solution for the operation comparison in the foreach statement.
Heh, you have to jump through some hoops sometimes to get NSIS to do what you want, but it's not often impossible.
Quote:
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...).
Quote:
code:

${if} 1 = 5
MessageBox MB_OK "test1"
${else}
MessageBox MB_OK "test2"
${endif}


Both messages would appear.
Ah, OK fair enough.

--
Dave.
eccles is offline   Reply With Quote
Old 7th October 2003, 20:15   #8
fraefel
Junior Member
 
Join Date: Mar 2003
Posts: 9
Thumbs up

Hi eccles & dselkirk!

You are amazing - very nice job done !
This is going to save quite some lines of script...
fraefel is offline   Reply With Quote
Old 10th December 2003, 23:18   #9
eccles
NSIS Dev
 
eccles's Avatar
 
Join Date: Sep 2001
Location: Leicester, UK
Posts: 193
NSIS LogicLib Version 2.3
  • 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).
More changes are in the pipeline and LogicLib should be included in the standard NSIS distribution by the next NSIS release.

Enjoy!

--
Dave.
Attached Files
File Type: zip logiclib2.3.zip (5.5 KB, 839 views)
eccles is offline   Reply With Quote
Old 13th December 2003, 15:53   #10
eccles
NSIS Dev
 
eccles's Avatar
 
Join Date: Sep 2001
Location: Leicester, UK
Posts: 193
NSIS LogicLib Version 2.4
  • 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).
All of the new features can be seen in action in the example script.

--
Dave.
Attached Files
File Type: zip logiclib2.4.zip (7.6 KB, 1051 views)
eccles is offline   Reply With Quote
Old 13th December 2003, 16:04   #11
kichik
M.I.A.
[NSIS Dev, Mod]
 
kichik's Avatar
 
Join Date: Oct 2001
Location: Israel
Posts: 11,343
I love it!

NSIS FAQ | NSIS Home Page | Donate $
"I hear and I forget. I see and I remember. I do and I understand." -- Confucius
kichik is offline   Reply With Quote
Old 14th December 2003, 10:28   #12
CodeSquid
Member
 
Join Date: Dec 2001
Posts: 89
Thumbs up

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!
CodeSquid is offline   Reply With Quote
Old 14th December 2003, 12:14   #13
Joost Verburg
NSIS MUI Dev
 
Join Date: Nov 2001
Posts: 3,717
These things will become possible when NSIS supports compiler plug-ins.
Joost Verburg is offline   Reply With Quote
Old 14th December 2003, 12:54   #14
CodeSquid
Member
 
Join Date: Dec 2001
Posts: 89
Compiler plugins? Whoah, any ETA?
CodeSquid is offline   Reply With Quote
Old 14th December 2003, 14:33   #15
Joost Verburg
NSIS MUI Dev
 
Join Date: Nov 2001
Posts: 3,717
NSIS 2.1

NSIS 2.0 has to be finished first.
Joost Verburg is offline   Reply With Quote
Old 14th December 2003, 15:10   #16
eccles
NSIS Dev
 
eccles's Avatar
 
Join Date: Sep 2001
Location: Leicester, UK
Posts: 193
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).
Quote:
And last but not least: Implicit inclusion of LogicLib.nsh to every script
nsisconf.nsh

--
Dave.
eccles is offline   Reply With Quote
Old 23rd August 2004, 13:49   #17
eccles
NSIS Dev
 
eccles's Avatar
 
Join Date: Sep 2001
Location: Leicester, UK
Posts: 193
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 is offline   Reply With Quote
Old 24th August 2004, 02:54   #18
rsegal
Senior Member
 
rsegal's Avatar
 
Join Date: Feb 2003
Location: Toronto, Canada
Posts: 227
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!
rsegal is offline   Reply With Quote
Old 24th November 2005, 00:33   #19
Animaether
Major Dude
 
Join Date: Jun 2001
Posts: 1,173
small question... can you not use LogicLib inside of macros with passed variables ?
e.g.

PHP Code:
!macro someMacro someVar
  
${If} ${someVar} == 0
    
# do something
  
${EndIf}
!
macroend 
Tells me: !insertmacro: macro "_If" requires 4 parameter(s), passed 3!
Animaether is offline   Reply With Quote
Old 24th November 2005, 03:19   #20
Animaether
Major Dude
 
Join Date: Jun 2001
Posts: 1,173
nevermind... it's fine..

The problem is that I'm passing the macro an empty string:
PHP Code:
!insertmacro someMacro "" 
And that throws the error. Apparently because once inside the macro, "" becomes <null>. Weird.

Work-arounds?
PHP Code:
!macro someMacro someVar
${If} "${someVar}== "0"
  
# do something
${ElseIf} "${someVar}== ""
  
# do something else
${EndIf}
!
macroend 
That would kill any integer checks, though.

PHP Code:
!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?
Animaether is offline   Reply With Quote
Old 24th November 2005, 12:24   #21
kichik
M.I.A.
[NSIS Dev, Mod]
 
kichik's Avatar
 
Join Date: Oct 2001
Location: Israel
Posts: 11,343
Quoting in the ${If} line is the correct way to get around this. Why would it kill any integer checks?

NSIS FAQ | NSIS Home Page | Donate $
"I hear and I forget. I see and I remember. I do and I understand." -- Confucius
kichik is offline   Reply With Quote
Old 24th November 2005, 14:55   #22
Animaether
Major Dude
 
Join Date: Jun 2001
Posts: 1,173
because I'm making the gross assumption that you can't compare a string to an int :x

Thanks for the pointer
Animaether is offline   Reply With Quote
Old 24th November 2005, 15:00   #23
kichik
M.I.A.
[NSIS Dev, Mod]
 
kichik's Avatar
 
Join Date: Oct 2001
Location: Israel
Posts: 11,343
But an integer is a string in NSIS. Commands that require integers automatically convert the string to an integer.

NSIS FAQ | NSIS Home Page | Donate $
"I hear and I forget. I see and I remember. I do and I understand." -- Confucius
kichik is offline   Reply With Quote
Old 29th November 2006, 10:59   #24
mamilo
Junior Member
 
Join Date: Nov 2006
Posts: 43
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
mamilo is offline   Reply With Quote
Old 29th November 2006, 20:00   #25
bholliger
Senior Member
 
Join Date: Jul 2004
Location: Switzerland
Posts: 223
Hi mamilo!

Did you write this code below the
Section Sec01 CSEC
declaration?

Cheers

Bruno
bholliger is offline   Reply With Quote
Old 1st December 2006, 14:28   #26
Comperio
Major Dude
 
Comperio's Avatar
 
Join Date: Jan 2005
Location: Oregon Coast
Posts: 737
Shouldn't it be this?
code:

${If} ${CSEC} = ${SectionIsSelected}
!insertmacro UnSelectSection ${ESEC}
${EndIf}

Comperio is offline   Reply With Quote
Old 1st December 2006, 21:31   #27
bholliger
Senior Member
 
Join Date: Jul 2004
Location: Switzerland
Posts: 223
I think the code is correct.

http://nsis.sourceforge.net/LogicLib#Expressions

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.
bholliger is offline   Reply With Quote
Old 20th November 2008, 13:40   #28
phunkydizco
Junior Member
 
Join Date: Jul 2005
Posts: 19
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:
code:
SectionGetFlags ${SEC02} $R0
Intop $R1 $R0 | 1
SectionGetFlags ${SEC03} $R2
Intop $R3 $R2 | 1
${Unless} $R0 <> $R1 ${OrUnless} $R2 <> $R3
Do Something
${EndUnless}

phunkydizco is offline   Reply With Quote
Old 20th November 2008, 13:46   #29
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 4,888
only one "if" statement per line

IntOp $PostCount $PostCount + 1
Anders is offline   Reply With Quote
Old 20th November 2008, 13:50   #30
phunkydizco
Junior Member
 
Join Date: Jul 2005
Posts: 19
Is this correct?
code:
SectionGetFlags ${SEC02} $R0
Intop $R1 $R0 | 1
SectionGetFlags ${SEC03} $R2
Intop $R3 $R2 | 1
${Unless} $R0 <> $R1
${OrUnless} $R2 <> $R3
Do Something
${EndUnless}

phunkydizco is offline   Reply With Quote
Old 20th November 2008, 16:40   #31
Afrow UK
Moderator
 
Afrow UK's Avatar
 
Join Date: Nov 2002
Location: Surrey, England
Posts: 8,434
You can just use the ${If} ${SectionIsSelected} ... ${OrIf} ${SectionIsSelected} ...

Stu
Afrow UK is offline   Reply With Quote
Old 20th November 2008, 17:31   #32
Animaether
Major Dude
 
Join Date: Jun 2001
Posts: 1,173
besides what Afrow said - yes, that'd be correct
'd still go with what Afrow said, though
Animaether is offline   Reply With Quote
Old 20th November 2008, 17:49   #33
phunkydizco
Junior Member
 
Join Date: Jul 2005
Posts: 19
Quote:
Originally posted by Afrow UK
You can just use the ${If} ${SectionIsSelected} ... ${OrIf} ${SectionIsSelected} ...

Stu
That is not a good idea. Because with your code I have to copy my "Do Something" code twice.

${Unless} $R0 <> $R1
${OrUnless} $R2 <> $R3
Do Something
${EndUnless}

This seems to work and is very short.
phunkydizco is offline   Reply With Quote
Old 20th November 2008, 18:01   #34
Afrow UK
Moderator
 
Afrow UK's Avatar
 
Join Date: Nov 2002
Location: Surrey, England
Posts: 8,434
Why?

${If} ${SectionIsSelected} ${SEC02}
${OrIf} ${SectionIsSelected} ${SEC03}
...
${EndIf}

Stu
Afrow UK is offline   Reply With Quote
Old 20th November 2008, 18:47   #35
phunkydizco
Junior Member
 
Join Date: Jul 2005
Posts: 19
That's right I didn't see that. But my code is also ok?
phunkydizco is offline   Reply With Quote
Old 20th November 2008, 22:42   #36
Afrow UK
Moderator
 
Afrow UK's Avatar
 
Join Date: Nov 2002
Location: Surrey, England
Posts: 8,434
It may work but the proper logic is to check if ${SF_SELECTED} (1) is set:

SectionGetFlags ${SEC02} $R0
IntOp $R0 $R0 & ${SF_SELECTED}
${If} $R0 != 0
...

This is what ${If} ${SectionIsSelected} ${SEC02} would be doing internally.

Stu
Afrow UK is offline   Reply With Quote
Old 21st November 2008, 06:49   #37
phunkydizco
Junior Member
 
Join Date: Jul 2005
Posts: 19
What does this line?

IntOp $R0 $R0 & ${SF_SELECTED}
phunkydizco is offline   Reply With Quote
Old 8th March 2011, 07:06   #38
o___O
Junior Member
 
Join Date: Mar 2002
Posts: 27
There's a replacement macro for ${FileExists} in the Wiki, but it doesn't work with ${IfNot} or ${Unless}.

http://nsis.sourceforge.net/LogicLib

Quote:
FileExists

The ${FileExists} condition included in LogicLib will evaluate to true if what exists is actually a directory. I suggest you add the following macros to your script (right after including LogicLib.nsh):
!macro _FileExists2 _a _b _t _f
StrCmp `${_b}` `` `${_f}` 0
IfFileExists `${_b}` `0` `${_f}` ;returns true if this is a directory
IfFileExists `${_b}\*.*` `${_f}` `${_t}` ;so if it is a directory, jump to false
!macroend
!undef FileExists
!define FileExists `"" FileExists2`
!macro _DirExists _a _b _t _f
StrCmp `${_b}` `` `${_f}` 0
IfFileExists `${_b}\*.*` `${_t}` `${_f}`
!macroend
!define DirExists `"" DirExists`

Then you can use ${If} ${FileExists} and ${If} ${DirExists}.
In my script if I use:

${If} ${FileExists} <path> and it exists, it will perform.

However, if I use:

${IfNot} ${FileExists} <path> and the file doesn't exist, it won't perform.

I deleted the FileExists2 macro code from my script and returned to the one included in LogicLib.nsh and it works correctly again.
o___O is offline   Reply With Quote
Old 8th March 2011, 07:10   #39
MSG
Major Dude
 
Join Date: Oct 2006
Posts: 1,892
There's no need for a new macro. You can simply use ${If} ${FileExists} $YourFile ${AndIfNot} ${FileExists} "$YourFile\*.*" .
MSG is offline   Reply With Quote
Old 8th March 2011, 10:16   #40
o___O
Junior Member
 
Join Date: Mar 2002
Posts: 27
I know that but the code in the LogicLib Wiki (which is the official entry for LogicLib and makes the recommendation, actually - and links to this thread) doesn't work. It's weird that it doesn't work actually, FileExists2 is nearly identical to the old one, it looks like it should work the same except for returning false on directories.

Original:
PHP Code:
!macro _FileExists _a _b _t _f
        IfFileExists 
`${_b}` `${_t}` `${_f}`
!
macroend
!define FileExists `"" FileExists
FileExists2 (slightly edited version)
PHP Code:
!macro _FileExists2 _a _b _t _f
    IfFileExists 
`${_b}` `0` `${_f}` ;continues if something existsreturns false if not
    IfFileExists 
`${_b}\*.*` `${_f}` `${_t}` ;so if it is a directoryjump to false - else return true
!macroend
!define FileExists2 `"" FileExists2

Wonder why it doesn't work?
o___O is offline   Reply With Quote
Reply
Go Back   Winamp & SHOUTcast Forums > Developer Center > NSIS Discussion

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump