Old 17th November 2007, 17:08   #1
David B. Trout
Junior Member
 
David B. Trout's Avatar
 
Join Date: Sep 2007
Location: Bellevue, WA
Posts: 7
"!if cond || cond" conditional compilation

I'd like to be able to do:

!if ((${A} == ${B}) || (${A} == ${C}))
...(code)...
!endif

How do I do that??
David B. Trout is offline   Reply With Quote
Old 17th November 2007, 19:17   #2
kichik
M.I.A.
[NSIS Dev, Mod]
 
kichik's Avatar
 
Join Date: Oct 2001
Location: Israel
Posts: 11,343
If you really want to create such a compile-time condition, you have two hackish solutions I can think of.
  1. Double the !if, use !macro inside.
    code:
    !macro blah
    # ...(code)...
    !macroend
    !if "${A}" == "${B}"
    !insertmacro blah
    !else if "${A}" == "${B}"
    !insertmacro blah
    !endif

  2. Use !ifdef.
    code:
    !define A_test_${B}
    !define A_test_${C}
    !ifdef A_test_${A}
    # ...(code)...
    !endif

But most new users want runtime check. For that you have the LogicLib. !if is only for the preprocessor.
code:
!include LogicLib.nsh
#...
${If} $A == $B
${OrIf} $A == $C
# ...(code)...
${EndIf}


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 18th November 2007, 04:04   #3
David B. Trout
Junior Member
 
David B. Trout's Avatar
 
Join Date: Sep 2007
Location: Bellevue, WA
Posts: 7
I may be [relatively] new to NSIS kichik, but I'm definitely NOT new to programming (having been one for for over 30 years). I *do* know the difference between compile-time and run-time checking, and I'm here to tell you this is most definitely *NOT* a run-time need.

Thus your closing suggestion is unfortunately completely out of the question.

And your first "hackish" suggestion is also rejected for being too, .. well, .. (forgive me) F'ing UGLY.

(Besides, IMO simply calling a function instead (which I had already considered and rejected BTW) would be much cleaner/clearer than invoking a macro)

Your second hackish suggestion however, looks somewhat intriguing and MIGHT be a possibility -- if only I actually understood what you were suggesting that is! (which I don't!)

Could you do me a favor and explain it a bit more please?

Thanks.

Thanks for the quick reply and thanks for NSIS itself too. Much appreciated.
David B. Trout is offline   Reply With Quote
Old 18th November 2007, 13:45   #4
demiller9
Senior Member
 
Join Date: Mar 2006
Location: Dallas
Posts: 462
David,
Let me offer a suggestion:
code:
!if "${A}" == "${B}"
!define AequalBorC
!endif
!if "${A}" == "${C}"
!define AequalBorC
!endif
!ifdef ${AequalBorC}
...code...
!endif



It's a crappy temp define name, but you see the idea.

Don
demiller9 is offline   Reply With Quote
Old 18th November 2007, 13:56   #5
Afrow UK
Moderator
 
Afrow UK's Avatar
 
Join Date: Nov 2002
Location: Surrey, England
Posts: 8,434
For the 2nd example that kichik has posted, let's say A (99) is equal to B (99):

code:
!define A_test_${B} # defines A_test_99
!define A_test_${C} # defines A_test_128
!ifdef A_test_${A} # A is 99 (A_test_99 is defined) therefore A==B.
# ...(code)...
!endif

Edit: You should probably wrap the two !defines in !ifdefs in case B==C (you will get a compiler error)!

Stu
Afrow UK is offline   Reply With Quote
Old 19th November 2007, 03:34   #6
David B. Trout
Junior Member
 
David B. Trout's Avatar
 
Join Date: Sep 2007
Location: Bellevue, WA
Posts: 7
Quote:
Originally posted by demiller9

David,
Let me offer a suggestion:
code:
!if "${A}" == "${B}"
!define AequalBorC
!endif
!if "${A}" == "${C}"
!define AequalBorC
!endif
!ifdef ${AequalBorC}
...code...
!endif

It's a crappy temp define name, but you see the idea.

Don
Yes, thanks, that is what I decided to go with in the interim since luckily I don't (yet) have too many combinations to deal with. As the number of tests (comparison combinations) increases though, it could become quite cumbersome, which is what I was hoping to avoid.

'Tis a shame though that NSIS doesn't (yet?) support the format/style I originally posted. Any chance of that perhaps sometime changing in the [hopefully] near future?? <hint! hint!>
David B. Trout is offline   Reply With Quote
Old 19th November 2007, 04:21   #7
David B. Trout
Junior Member
 
David B. Trout's Avatar
 
Join Date: Sep 2007
Location: Bellevue, WA
Posts: 7
Quote:
Originally posted by Afrow UK

For the 2nd example that kichik has posted, let's say A (99) is equal to B (99):

code:
!define A_test_${B} # defines A_test_99
!define A_test_${C} # defines A_test_128
!ifdef A_test_${A} # A is 99 (A_test_99 is defined) therefore A==B.
# ...(code)...
!endif

Edit: You should probably wrap the two !defines in !ifdefs in case B==C (you will get a compiler error)!

Stu
(DOH!) Thanks Stu. Makes perfect sense now. Don't know why I didn't see it the first time. <embarassed>

Unfortunately however, this technique, while slick, doesn't exactly help uncomplicate my code any.

I mean, in order to use it the way I want to use it, I'd have to do something like:
code:
!define _STD_INSTALLER 1 /* NORMAL installer WITHOUT any developer files */
!define _DEV_INSTALLER 2 /* With FishLib DEVELOPMENT FILES also embedded */
!define _MIN_INSTALLER 3 /* ONLY FishLib, to embed into other installers */
!define _WEB_INSTALLER 4 /* NO FILES embedded at all, downloaded instead */


/* We wish to test if INSTALLER_TYPE == 2 or INSTALLER_TYPE == 4 */

!define INSTALLER_TYPE_2 /* (define what to test for) */
!define INSTALLER_TYPE_4 /* (define what to test for) */

!ifdef INSTALLER_TYPE_${_INSTALLER_TYPE} /* (perform the actual test) */

...(code)...

!endif
!undef INSTALLER_TYPE_2 /* (must always cleanup too) */
!undef INSTALLER_TYPE_4 /* (must always cleanup too) */

... (bunch of unrelated code) ...

/* NOW we need to test a completely different combination... */

!define INSTALLER_TYPE_1 /* (define what to test for) */
!define INSTALLER_TYPE_3 /* (define what to test for) */

!ifdef INSTALLER_TYPE_${_INSTALLER_TYPE} /* (perform the actual test) */

...(code)...

!endif
!undef INSTALLER_TYPE_1 /* (must always cleanup too) */
!undef INSTALLER_TYPE_3 /* (must always cleanup too) */

...(etc)...

As you can see, using this particular technique doesn't exactly make the code neat and clean, does it?

Thanks anyway Stu and kichik, but I think I'm going to stick with Don's suggestion (which I had already figured out on my own) until such time as NSIS can be fixed. At least with his technique I can hide all my needed !defines in a !included header somewhere and then just use a simple, SINGLE, !ifdef whereever I need to, thereby preserving the simplicity/readability (and thus maintainability) of my code.

Thanks for everyone's help folks. Much appreciated.
David B. Trout is offline   Reply With Quote
Old 21st November 2007, 12:40   #8
Mr Inches
Member
 
Join Date: Jan 2006
Location: Canberra, Australia
Posts: 76
Hi David

Depending on how your bitwise logical operator skills are, you could also use an approach similar to this (which is based on using bitmasks in C) by getting creative with the /math option for !define:

code:

!define Standard 0x00000001
!define Development 0x00000002
!define Web 0x00000004

!define /math InstallerType ${Standard} | ${Development}

!define /math IsStandardInstaller ${InstallerType} & ${Standard}
!define /math IsDevelopmentInstaller ${InstallerType} & ${Development}
!define /math IsStandardDevelopmentInstaller ${IsStandardInstaller} & ${Development}

!if ${IsStandardInstaller}
!echo "standard installation"
!endif

!if ${IsDevelopmentInstaller}
!echo "development installation"
!endif

!if ${IsStandardDevelopmentInstaller}
!echo "standard and development installation"
!endif



and so on.

I don't know how this would work out for you, but it could be worth trying out, particularly if work through some of the other combinations of the bitmasks to reflect your desired logic.

Duncan
Mr Inches is offline   Reply With Quote
Old 23rd November 2007, 21:31   #9
Fightin_Foo
Junior Member
 
Join Date: Nov 2007
Location: Ohio
Posts: 49
Send a message via AIM to Fightin_Foo
Maybe I am making this all too simple but have you tried the OrIf in the LogicLib?

${If} "${A}" == "${B}"
;;
${OrIf} "${A}" == "${C}"
;;
${EndIf}

It was just a thought, like I said probably making the problem too simple

From there to here,
from here to there,
funny things
are everywhere.

Dr. Seuss
"One Fish Two Fish Red Fish Blue Fish"
Fightin_Foo is offline   Reply With Quote
Old 24th November 2007, 05:12   #10
David B. Trout
Junior Member
 
David B. Trout's Avatar
 
Join Date: Sep 2007
Location: Bellevue, WA
Posts: 7
Quote:
Originally posted by Fightin_Foo
Maybe I am making this all too simple but have you tried the OrIf in the LogicLib?

${If} "${A}" == "${B}"
;;
${OrIf} "${A}" == "${C}"
;;
${EndIf}

It was just a thought, like I said probably making the problem too simple
(SIGH!)

Please read the complete thread before posting.

Thank you.
David B. Trout is offline   Reply With Quote
Old 24th November 2007, 06:14   #11
David B. Trout
Junior Member
 
David B. Trout's Avatar
 
Join Date: Sep 2007
Location: Bellevue, WA
Posts: 7
Quote:
Originally posted by Mr Inches:

Hi David

Depending on how your bitwise logical operator skills are, you could also use an approach similar to this (which is based on using bitmasks in C) by getting creative with the /math option for !define:
<code snipped>
Quote:
and so on.

I don't know how this would work out for you, but it could be worth trying out, particularly if work through some of the other combinations of the bitmasks to reflect your desired logic.

Duncan
My bitwise operator skills are just fine Duncan, but your suggestion is unfortunately no better than Don's (and in many ways worse). Thanks anyway.


-------------------------
<hint> Try changing your "InstallerType" to just "Standard" (it will NEVER be more than one value at the same time!!) and then show the code necessary to test whether the passed "InstallerType" is EITHER "Standard" -OR- "Development". Do that and I think you'll see your technique is actually worse than Don's since it takes more code to setup the combination-value tests.
David B. Trout 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