Archive: StrCpy mixes up macro parameter


StrCpy mixes up macro parameter
Hi :)

I'm kind of ... stunned. I've got over 3000 lines of NSIS code right now, but now a strange error occurres in the middle of my program - the value of a variable gets replaced.
Right from the start I've thought, I've mixed up some Pushes and Pops. I've traced the error and limited the code where it occurres.

!macro __appendStrToFile _file _mode _string
Push $0
Push $1
Push $2


MessageBox MB_OK "${_string}"
StrCpy $0 "${_file}"
MessageBox MB_OK "${_string}"
StrCpy $1 "${_mode}"
StrCpy $2 "${_string}"
Call __appendStrToFile

Exch 3 # stack: 0, 2, 1, return
Pop $0
Pop $2
Pop $1
!macroend

I'm calling the macro from inside a function:
Function myFunc
# write comment to file
${AppendStrToFile} ${RB_REG_SCRIPTS} o "; $0 ${LineBreak}${LineBreak}"
FunctionEnd

$0 of myFunc is a file name. Lets say it's C:\file.txt. And let's say ${RB_REG_SCRIPTS} is D:\abc.de

The first message box displays: "; C:\file.txt"
The second says: "; D:\abc.de"

I've checked: Only _string changed - all other parameter stay the same ...

As you notice: the semicolon and the space remain, but the file name changed. So, how can it be, that only the value of the variable inside the string changes??
The real value of ${_string} is 82 or 84 chars long - is that a problem? (But it can be displayed without any problems...)

Thanks! :)

CJ

If $0 = "C:\file.txt" and ${RB_REG_SCRIPTS} is "D:\abc.de" then when the line

${AppendStrToFile} ${RB_REG_SCRIPTS} o "; $0 ${LineBreak}${LineBreak}"

gets expanded the following will happen:

(a) the first MessageBox MB_OK "${_string}" line will print the string "; $0 ${LineBreak}${LineBreak}" and since $0 = "C:\file.txt" the message box will display "; C:\file.txt" as you expected

(b) the StrCpy $0 "${_file}" line will copy "D:\abc.de" into $0 (so $0 is now "D:\abc.de")

(c) the second MessageBox MB_OK "${_string}" line will print the string "; $0 ${LineBreak}${LineBreak}" but since $0 now holds "D:\abc.de" the message box will actually display "; D:\abc.de"


Re: StrCpy mixes up macro parameter
Macros are not functions. Whatever is inside a macro is literally inserted in your script whenever you call the macro, and this is done before compiling, so you can't expect $0 inside the macro to be any different from $0 outside the macro. They are, in fact, exactly the same.

So the way you've coded this, your script file (as far as the compiler can see) ends up looking like this:

Function myFunc
# write comment to file
Push $0
Push $1
Push $2


MessageBox MB_OK "; $0 ${LineBreak}${LineBreak}"
StrCpy $0 "${RB_REG_SCRIPTS}"
MessageBox MB_OK "; $0 ${LineBreak}${LineBreak}"
StrCpy $1 "o"
StrCpy $2 "; $0 ${LineBreak}${LineBreak}"
Call __appendStrToFile

Exch 3 # stack: 0, 2, 1, return
Pop $0
Pop $2
Pop $1
FunctionEnd

As you can see, it's logical for your second messagebox to display a different $0 value. You just changed it, after all!

To avoid this problem, I usually make sure I only push/pop $R0 through $R9 inside my macros, and only use $0 through $9 in the 'regular' script.


Edit: Darnit, too slow. :D

Thank you! :)

I didn't know that ... -.-' ... Kind of stupid from me ... -.-'
I think I will check my whole code again. ;)

CJ