Skip to content
⌘ NSIS Forum Archive

Macro params using a variable or stack

1 posts

Zinthose#

Macro params using a variable or stack

Playing around with the macros I found that I can make some pretty powerful stuff before the code is even compiled.

I'm sharing here in hopes someone will find it useful or thought provoking.

Typically when you call a defined macro you are confined to the following convention:
${MyMacro} $0 'Some Value' 
What if we could add stack manipulations to it to avoid excessive pops and pushes by dynamically altering the calls. Say, something like this:
${MyMacro} s s 
Now the macro will use the stack for those values. We can even mix and match.
${MyMacro} $0 s
${MyMacro} s 'Some Value' 
Lets say I have want to add an item to a comma separated list multiple times. Using some fancy macro / stack manipulations I came up with this:
!ifmacrondef _CSV
    !macro _CSV _ReturnValue _Source _Value
        !if `${_Source}` != s
            Push `${_Source}`
            !if `${_Value}` == s
                Exch
            !else
                Push `${_Value}`
            !endif
        !else if `${_Value}` != s
            Push `${_Value}`
        !endif
        Call CSV
        !if ${_ReturnValue} != s
            Pop ${_ReturnValue}
        !endif
    !macroend
    !define CSV `!insertmacro _CSV`
    Function CSV
        ;Stack : _Value _Source
        Exch $0 ; $0 _Source
        Exch    ; _Source $0
        Exch $1 ; $1 $0
        
        StrCmp '' $1 StrCmpEnd
            StrCpy $0 `$1,$0`
        StrCmpEnd:
        
        Pop $1
        Exch $0
    FunctionEnd
!endif
Section CSV
    ${CSV} s "" "Hello"
    ${CSV} s s "World"
    ${CSV} s s "This"
    ${CSV} s s "is"
    ${CSV} s s "a"
    ${CSV} $0 s "test"
    DetailPrint $0
    
    ${CSV} $0 $0 "Oh and one more thing!"
    DetailPrint $0
SectionEnd 
Pretty cool eh?

Here is an example that is a bit simpler:
!ifmacrondef _Msg
    !macro _Msg _ReturnValue _Message
        !if `${_Message}` != s
            Push `${_Message}`
        !endif
        Call Msg
        !if ${_ReturnValue} != s
            Pop ${_ReturnValue}
        !endif
    !macroend
    !define Msg `!insertmacro _Msg`
    Function Msg
        Exch $0
        StrCpy $0 'The Message is "$0"'
        Exch $0
    FunctionEnd
!endif
Section Msg
    ${Msg} $R0 "Hello!"
    DetailPrint $R0
    
    ${Msg} s "Hello There!"
    Pop $R1
    DetailPrint $R1
    
    Push "Hello World!"
    ${Msg} s s
    Pop $R3
    DetailPrint $R3
SectionEnd