No announcement yet.

String arrays, sort of

  • Filter
  • Time
  • Show
Clear All
new posts

  • String arrays, sort of

    Several times, I've wanted to do the same body of script code, just changing one string. Without some sort of string array, I've just made the body a function and called it several times.

    It finally occurred to me, looking at StrStr, that if I just had a special delimiter character, I could get the same effect by separating the string elements with that delimiter. So here's an implementation using "$\n" as the delimiter. I hope someone finds it useful:

    -------- PerLine.nsh


    !include LogicLib.nsh

    ; global vars for loop
    var /global PerLineArray
    var /global PerLineCount
    var /global PerLineChars

    !macro _PerLine lineArray loopVar
    StrCpy $PerLineArray ${lineArray}
    StrLen $PerLineChars $PerLineArray
    StrCpy $PerLineCount 1
    ${DoWhile} $PerLineChars > 1
    Push $PerLineArray
    Call leadingLine
    Pop ${loopVar}
    Push $r0
    StrLen $r0 ${loopVar}
    IntOp $r0 $r0 + 1
    StrCpy $PerLineArray $PerLineArray "" $r0
    Pop $r0
    StrLen $PerLineChars $PerLineArray
    !define PerLine `!insertmacro _PerLine`

    ; usage, for example:
    ; StrCpy $1 1 ; line number
    ; StrCpy $2 "" ; accumulating message
    ; ${PerLine} "line1$\nline2$\n$line3" $line
    ; ; body does something with $line 3 times
    ; StrCpy $2 "$2$\n$1 - $line"
    ; IntOp $1 $1 + 1
    ; ${Loop}
    ; MessageBox MB_OK $2

    ; helper function to strip off leading line
    Function LeadingLine
    ; input - top of stack contains string, possibly containing "$\n"
    ; output - top of stack contains string up to 1st "$\n"
    ; r0 - working copy of input & result
    ; r1 - char index
    ; r2 - length of input
    ; r3 - nth char of input
    Exch $r0
    Push $r1
    Push $r2
    Push $r3
    StrCpy $r1 0
    StrLen $r2 $r0
    IntCmp $r1 $r2 _leadDone
    StrCpy $r3 $r0 1 $r1
    StrCmp $r3 "$\n" _leadDone
    IntOp $r1 $r1 + 1
    Goto _leadLoop

    StrCpy $r0 $r0 $r1
    Pop $r3
    Pop $r2
    Pop $r1
    Exch $r0


  • #2
    This is one way but it is much easier (and cleaner) to use a plug-in (such as NSISArray) or use INI files/registry to store multiple values (i.e. by index or value name). You do not need to worry about the delimiter being in your array elements then.