Archive: Messing With Your Heads


Messing With Your Heads
  This is just something fun in the compiler I discovered. It will make the newbs flee :cry: and the veterans will simply whack me with a rolled up newspaper and sternly say "NO! BAD!" :mad:

Compile this:

!define `War"="What is it good for?"$\n!define: "Result` Nothing!

!error `Result = ${War"="What is it good for?"$\n!define: "Result}`
And you will see this in the compiler output:
Processing script file: "C:\NOBAD.nsi"
!define: "War"="What is it good for?"
!define: "Result"="Nothing!"
!error: Result = Nothing!


What dose this mean?
Basically you can make a define be just about ANY VALUE as long as it is is defined in one line and is wrapped in string delimiter.

Example:
!define `${__DATE__}1234567890-=~!@#$%^&*()_+qwertyuiop***91;***93;\{}|asdfghjkl:";'zxcvbnm,./<>? $\n$\t$\r` 21

>!define /math "The Meaning of Life the Universe, Everything!" ${${__DATE__}1234567890-=~!@#$%^&*()_+qwertyuiop***91;***93;\{}|asdfghjkl:";'zxcvbnm,./<>? $\n$\t$\r} * 2
>!error `Result = ${The Meaning of Life the Universe, Everything!}`
Results:
!define: "6/23/20101234567890-=~!@#$%^&*()_+qwertyuiop[]\{}|asdfghjkl:";'zxcvbnm,./<>? 

"="21"
!define: "The Meaning of Life the Universe, Everything!"="42"
!error: Result = 42


:igor: Messes with your head doesn't it? :confused:

Originally posted by Zinthose
:igor: Messes with your head doesn't it? :confused:
Err... No it doesn't? It's doing exactly what it should. Of course you can make a define be just about any value. That's the whole point. It's just the preprocessor doing a straight text-replace.

I know it's working as intended.. I'm just impressed how well it's doing it :)


Actually, according to the manual the following:

$\r $\n $\t $$

Are listed under variables, but as I found out the hardway before, they are predefines.

Like:
StrCmp $R2 $\t 0 +3
ends up being
StrCmp $R2 0 +3

It does get people confused


Originally posted by gringoloco023
$\r $\n $\t $$
..., they are predefines.
If that was 100% true, the following would work.
!echo One$r$n!echo Two 

>
However, It fails with an error when compiling...
!echo expects 1 parameters, got 2.


Odly though this will compile...

Two

>!echo ${Test}
but the second !echo is lost in Limbo somewhere.

I gave this some quick additional test and strangely enough it only seems to happen for $\t !

StrCpy $R2 $\t

Error: StrCpy expects 2-4 parameters, got 1.

While
StrCpy $R2 '$\t'
Compiles fine !


You can also do some interesting things with comment blocks...

!define Result1 /* Inline comments don't effect anything */ "I am assigned to Result1!"
!define Result2 /* That is...
...until you add a line break */ "Errors here!"
!define: "Result1"="I am assigned to Result1!"
!define: "Result2"=""
Invalid command: Errors here!

My personal favorite is:

!define a blah
DetailPrint ${a}
DetailPrint $${a}
StrCpy $0 $$
DetailPrint $0{a}

besides all the fun,

I really consider the way how NSIS handles $\t, to be a BUG.
And maybe consider relocating $\t,$\r,$\n,$$, from constant variables to pre-defines, in the NSIS manual !

regards


Originally posted by gringoloco023
I really consider the way how NSIS handles $\t, to be a BUG.
And maybe consider relocating $\t,$\r,$\n,$$, from constant variables to pre-defines, in the NSIS manual !
I agree, the $\t dose appear to be a bug. However, I do not agree that they should be converted to pre-defines as it would cause a few problems.

Predefines are part of the precompiler. Thus, the compiler would have to deal with multi-line string values / statements as the $\n and $\r meta sequences are replaced. At the moment it can't. (Although I wish it it did at times)

StrCpy$0 "Hello$\nWorld!" 

Would become...
StrCpy$0 "Hello

World!"
See the problem?

It would be awesome though to have a few new predefines to play with so I could create some more complex precompiler macros.