Explode

From NSIS Wiki
Jump to navigationJump to search
Author: cryonyx (talk, contrib)


Description

Version: 1.0 The function splits passed string on the basis of the separator and pushes results to stack. The last value pushed is the length of the array.

How to use

Overview

Explode accepts two parameters: separator and string to split. After processing the data it pushes to the stack values in the direct order and then pushes the count of array items stored there. This means that if you have string "Col 1,Col 2,Col 3" and a separator ",", then your stack will look like this:

[0]    3
[1]    Col 1
[2]    Col 2
[3]    Col 3
[4]    ...

Syntax

${Explode} "Length" "Separator" "String"

or

Push "Separator"
Push "String"
Call Explode
Pop  "Length"

Parameters

Length
Variable in which the length of the returned array is stored.
Separator
String, which delimiters parts of the array in the string
String
String to be splitted

Example

    ${Explode}  $0  "," "Col 0,Col 1,Col 2"
    MessageBox  MB_OK "$0 elements in array"
    ${For} $1 1 $0
        Pop $2
        MessageBox MB_OK "Element #$1: $2"
    ${Next}

Function code (requires LogicLib header file)

!define Explode "!insertmacro Explode"
 
!macro  Explode Length  Separator   String
    Push    `${Separator}`
    Push    `${String}`
    Call    Explode
    Pop     `${Length}`
!macroend
 
Function Explode
  ; Initialize variables
  Var /GLOBAL explString
  Var /GLOBAL explSeparator
  Var /GLOBAL explStrLen
  Var /GLOBAL explSepLen
  Var /GLOBAL explOffset
  Var /GLOBAL explTmp
  Var /GLOBAL explTmp2
  Var /GLOBAL explTmp3
  Var /GLOBAL explArrCount
 
  ; Get input from user
  Pop $explString
  Pop $explSeparator
 
  ; Calculates initial values
  StrLen $explStrLen $explString
  StrLen $explSepLen $explSeparator
  StrCpy $explArrCount 1
 
  ${If}   $explStrLen <= 1          ;   If we got a single character
  ${OrIf} $explSepLen > $explStrLen ;   or separator is larger than the string,
    Push    $explString             ;   then we return initial string with no change
    Push    1                       ;   and set array's length to 1
    Return
  ${EndIf}
 
  ; Set offset to the last symbol of the string
  StrCpy $explOffset $explStrLen
  IntOp  $explOffset $explOffset - 1
 
  ; Clear temp string to exclude the possibility of appearance of occasional data
  StrCpy $explTmp   ""
  StrCpy $explTmp2  ""
  StrCpy $explTmp3  ""
 
  ; Loop until the offset becomes negative
  ${Do}
    ;   If offset becomes negative, it is time to leave the function
    ${IfThen} $explOffset == -1 ${|} ${ExitDo} ${|}
 
    ;   Remove everything before and after the searched part ("TempStr")
    StrCpy $explTmp $explString $explSepLen $explOffset
 
    ${If} $explTmp == $explSeparator
        ;   Calculating offset to start copy from
        IntOp   $explTmp2 $explOffset + $explSepLen ;   Offset equals to the current offset plus length of separator
        StrCpy  $explTmp3 $explString "" $explTmp2
 
        Push    $explTmp3                           ;   Throwing array item to the stack
        IntOp   $explArrCount $explArrCount + 1     ;   Increasing array's counter
 
        StrCpy  $explString $explString $explOffset 0   ;   Cutting all characters beginning with the separator entry
        StrLen  $explStrLen $explString
    ${EndIf}
 
    ${If} $explOffset = 0                       ;   If the beginning of the line met and there is no separator,
                                                ;   copying the rest of the string
        ${If} $explSeparator == ""              ;   Fix for the empty separator
            IntOp   $explArrCount   $explArrCount - 1
        ${Else}
            Push    $explString
        ${EndIf}
    ${EndIf}
 
    IntOp   $explOffset $explOffset - 1
  ${Loop}
 
  Push $explArrCount
FunctionEnd

Versions History

1.0
Creates array in stack, splitting passed string. No support for limitation of items to output

Credits

Version 1.0 - cryonyx