Announcement

Collapse
No announcement yet.

String arrays, sort of

Collapse
X
 
  • 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

    code:

    !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
    !macroend
    !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
    _leadLoop:
    IntCmp $r1 $r2 _leadDone
    StrCpy $r3 $r0 1 $r1
    StrCmp $r3 "$\n" _leadDone
    IntOp $r1 $r1 + 1
    Goto _leadLoop

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

    FunctionEnd


  • #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.

    Stu

    Comment

    Working...
    X
    😀
    🥰
    🤢
    😎
    😡
    👍
    👎