Archive: Select Statements


Select Statements
Another library I slapped together to make things a little easier. This one provides NSIS with the select statement functionality.


;Usage:
;
;open a new select statement
;!insertmacro SELECT <selectname> <selectvalue>
;add case statements
;!insertmacro CASE <comparevalues>
;!insertmacro CASE <comparevalues>
;if comparison not found, optional
;!insertmacro CASE_ELSE
;close select statement
;!insertmacro SELECTEND
;
;Variable descriptions:
;<selectname> is if you want multiple selects
;<selectvalue> is the value to compare too
;<comparevalues> is a ";" delimited string of the compare values

Section
!insertmacro SELECT "TESTCASE" "test1"
!insertmacro CASE "test1"
MessageBox MB_OK "case test1"
!insertmacro CASE "test 2;test3"
MessageBox MB_OK "case test2 or test3"
!insertmacro CASE_ELSE
MessageBox MB_OK "case else"
!insertmacro SELECTEND
SectionEnd

Here is version 1.1. I've added simplified macros as discussed here:
http://forums.winamp.com/showthread....hreadid=149805
I also removed the required of the name field.
Enjoy


We already got !ifdef, !else ifdef, !else etc. What is the difference?


There are 3 major differences. First, !ifdef, !endif only work during compile time while this works after compile. 2nd, !ifdef only checks if another define exists instead of check the value. And finally, This can handle multipe values, you can check if a single variable is equivalant to multiple values. You can also compare this to the C++ switch statement or the VB select case statement. Does that answer your questions?

Thanks


Yes, I understand. !insertmacro is a compile time command, so that's why it's a bit confusing.

Something that would be even more useful is run-time If, ElseIf and EndIf support. That's easier than using StrCmp etc.


Agreed, If..ElseIf..Else statements would be better than using the StrCmp function. This was meant as a work around until we get that sort of support. I've already started to modify the selectlib to act like an if statement. I'll let you know when its done.


No Archive page? :(


Please excuse the delay of my reply. Been busy polishing up this code. It is now called the NSIS Logic Lib and not only provides better Select statements but also If statements as well. Enjoy!

Archive Page:
http://nsis.sourceforge.net/archive/...10&instances=0


Funnily enough I was experimenting with a similar idea a while back but never completed it. Thanks to your posts I decided to dig it out and clean it up. :)

Mine does not have select/case but it does have do and while style loops.

Maybe some of our ideas can be combined?


Maybe you can use some unique values like ${__LINE__} to make usage unlimited.


eccles: just had a chance to go through your version. Very nice. I noticed you were using the quick macros. Now those are a time saver. I espically love your Push and Pop Logic, great way to get around the limitations of mine. It also makes the code simpler. I'll try integrating our 2 codes to gether and see what I can come up with. Can you think of any other logic statements that might be good to include?


dselkirk,

Yes, I put your defines in just before posting. 'tis a good trick!

It's a shame the select/case code has to do all that work at run-time checking for ';'. How do you feel about it being done at compile time? e.g.

${SELECT} "test1"
${CASE} "test1"
MessageBox MB_OK "case: test1"
${CASE2} "test2" "test3"
MessageBox MB_OK "case: test2 or test3"
${CASE_ELSE}
MessageBox MB_OK "case else"
${ENDSELECT}


As for logic statements, I can't think of any others at the mo.

How about more tests though? First of all, unsigned integer comparisons (IntCmpU). What symbols could be used for these?

Next, other tests that NSIS has, e.g. IfFileExists. Slightly tricky as the If template is operand_1 operator operand_2, but maybe something like
${If} "some_file_name" does exist
could be made to work?

Good idea for the select..case. We cap it off at case5, if a user needs to use more then they can simply use multipe cases.

I thought of another great statement to do. It will save us all alot of time. For..Next statements:


!macro For _v _f _t _o _s
StrCpy ${_v} ${_f}
!insertmacro _PushLogic
!define ${_Logic}For _${__LINE__}
!define ${_Logic}For2 _${__LINE__}
!define ${_Logic}Next _${__LINE__}
Goto ${${_Logic}For2}
${${_Logic}For}:
IntOp ${_v} ${_v} ${_o} ${_s}
${${_Logic}For2}:
!insertmacro _> ${_v} ${_t} ${${_Logic}Next} ""
!undef ${_Logic}For2
!macroend
!define For "!insertmacro For"

!macro ExitFor
;Goto
!macroend
!define ExitFor "!insertmacro ExitFor"

!macro Next
!ifndef _Logic | ${_Logic}For
!error "Cannot use Next without a preceding For"
!endif
Goto ${${_Logic}For} ; Loop back to the For condition
${${_Logic}Next}: ; Place the Next
!undef ${_Logic}For
!undef ${_Logic}Next
!insertmacro _PopLogic
!macroend
!define Next "!insertmacro Next"

;${for} variable from to direction steps
${for} $1 0 20 + 2
${next}


For the "if" statements, why don't we treat them basically as boolean returns:

${if} ${FileExists} "c:\test.txt"
or
${if} "5 < 10"


I was also trying to write ExitFor, ExitDo and ExitWhile statements but with no luck. I thought of using two defines which would store the current and the previous loop end labels. Any ideas.

There was something else but I can't remember it right now. I had written this entire message and hit my mouse by accident. It went back a page and I lost it, now I can't remember everything I mentioned before. huh!

Hadn't thought of For; good idea. Maybe Next should be called EndFor though, to match the others? :)

I'll have a go at ExitFor/While/Do (although I'll do just one and call it Break) and also Continue. Might be more tricky though as they need to be kept separate from Ifs.

Hope you remember what you forgot :)
btw, do you visit the NSIS IRC channel?