StrSort

From NSIS Wiki

Author: deguix (talk, contrib)


Description

Requires: LogicLib header file.

Version: 2.0.

This function searches for a substring in a string, and returns itself plus the remaining part of the string between the left and right marker substrings. The substring, along with the marker substrings can also be hidden from the resulting value.

How To Use

Syntax

${StrSort} "ResultVar" "String" "LeftMarkerSubString" "SubString" \
"RightMarkerSubString" "IncludeLeftMarkerSubString" "IncludeSubString" \
"IncludeRightMarkerSubString"

or

Push "String"
Push "LeftMarkerSubString"
Push "SubString"
Push "RightMarkerSubString"
Push "IncludeLeftMarkerSubString"
Push "IncludeSubString"
Push "IncludeRightMarkerSubString"
Call StrSort
Pop "ResultVar"

Parameters

ResultVar
Variable where the string between LeftMarkerSubString and RightMarkerSubString containing the SubString found in String is returned.
String
String where to search for SubString.
LeftMarkerSubString
String to search with the "right-to-left" direction on the left of SubString after the SubString's search is done. If this is an empty string, everything on the left of SubString gets included in ResultVar.
SubString
String to search in String.
RightMarkerSubString
String to search with the "left-to-right" direction on the right of SubString after the SubString's search is done. If this is an empty string, everything on the right of SubString gets included in ResultVar.
IncludeLeftMarkerSubString
Allows the inclusion or not of the LeftMarkerSubString value in ResultVar. 1 = True, 0 = False. Default is 1 (True).
IncludeSubString
Allows the inclusion or not of the SubString value in ResultVar. 1 = True, 0 = False. Default is 1 (True).
IncludeRightMarkerSubString
Allows the inclusion or not of the RightMarkerSubString value in ResultVar. 1 = True, 0 = False. Default is 1 (True).

Example

${StrSort} $0 "This is just an example" "" " just" "" "0" "0" "0"
$0 = "This is an example"

Function Code

!define StrSort "!insertmacro StrSort"
 
!macro StrSort ResultVar String LeftMarkerSubString SubString \
RightMarkerSubString IncludeLeftMarkerSubString IncludeSubString \
IncludeRightMarkerSubString
  Push "${String}"
  Push "${LeftMarkerSubString}"
  Push "${SubString}"
  Push "${RightMarkerSubString}"
  Push "${IncludeLeftMarkerSubString}"
  Push "${IncludeSubString}"
  Push "${IncludeRightMarkerSubString}"
  Call StrSort
  Pop "${ResultVar}"
!macroend
 
Function StrSort
  /*After this point:
  ------------------------------------------
  $R0 = String (input)
  $R1 = LeftMarkerSubString (input)
  $R2 = SubString (input)
  $R3 = RightMarkerSubString (input)
  $R4 = IncludeLeftMarkerSubString (input)
  $R5 = IncludeSubString (input)
  $R6 = IncludeRightMarkerSubString (input)
 
  $0 = StrLen (temp)
  $1 = LeftMarkerSubStrLen (temp)
  $2 = SubStrLen (temp)
  $3 = RightMarkerSubStrLen (temp)
  $4 = StartPos (temp)
  $5 = EndPos (temp)
  $6 = StartCharPos (temp)
  $7 = EndCharPos (temp)
  $8 = TempStr (temp)*/
 
  ;Get input from user
  Exch $R6
  Exch
  Exch $R5
  Exch
  Exch 2
  Exch $R4
  Exch 2
  Exch 3
  Exch $R3
  Exch 3
  Exch 4
  Exch $R2
  Exch 4
  Exch 5
  Exch $R1
  Exch 5
  Exch 6
  Exch $R0
  Exch 6
  Push $0
  Push $1
  Push $2
  Push $3
  Push $4
  Push $5
  Push $6
  Push $7
  Push $8
 
  ;Parameter defaults
  ${IfThen} $R4 == `` ${|} StrCpy $R4 `1` ${|}
  ${IfThen} $R5 == `` ${|} StrCpy $R5 `1` ${|}
  ${IfThen} $R6 == `` ${|} StrCpy $R6 `1` ${|}
 
  ;Get "String", "SubString", "LeftMarkerSubString" and "RightMarkerSubString" length
  StrLen $0 $R0
  StrLen $1 $R1
  StrLen $2 $R2
  StrLen $3 $R3
  ;Start "StartCharPos" counter
  StrCpy $6 0
  ;Start "EndCharPos" counter based on "SubString" length
  IntOp $7 $6 + $2
 
  ;Loop until "SubString" is found or "String" reaches its end
  ${Do}
    ;Remove everything before and after the searched part ("TempStr")
    StrCpy $8 $R0 $2 $6
 
    ;Compare "TempStr" with "SubString"
    ${IfThen} $8 == $R2 ${|} ${ExitDo} ${|}
    ;If not, this could be "String" end
    ${IfThen} $7 >= $0 ${|} Goto Done ${|}
    ;If not, continue the loop
    IntOp $6 $6 + 1
    IntOp $7 $7 + 1
  ${Loop}
 
  # "SubString" was found
 
  ;Remove "SubString" from "String" if the user wants
  ${If} $R5 = 0 ;FALSE
    StrCpy $8 $R0 $6
    StrCpy $R0 $R0 `` $7
    StrCpy $R0 $8$R0
  ${EndIf}
 
  ;"StartPos" and "EndPos" will record "SubString" coordinates for now
  StrCpy $4 $6
  StrCpy $5 $7
  ;"StartCharPos" and "EndCharPos" should be before "SubString"
  IntOp $6 $6 - $1
  IntOp $7 $6 + $1
 
  ;Loop until "LeftMarkerSubString" is found or "String" reaches its start
  ${Do}
    ;Remove everything before and after the searched part ("TempStr")
    StrCpy $8 $R0 $1 $6
 
    ;If "LeftMarkerSubString" is empty
    ${If} $R1 == ``
      StrCpy $6 0
      StrCpy $7 0
      ${ExitDo}
    ${EndIf}
 
    ;Compare "TempStr" with "LeftMarkerSubString"
    ${IfThen} $8 == $R1 ${|} ${ExitDo} ${|}
    ;If not, this could be "String" start
    ${IfThen} $6 <= 0 ${|} ${ExitDo} ${|}
    ;If not, continue the loop
    IntOp $6 $6 - 1
    IntOp $7 $7 - 1
  ${Loop}
 
  # "LeftMarkerSubString" is found or "String" start was reached
 
  ;Remove "LeftMarkerSubString" from "String" if the user wants
  ${If} $R4 = 0 ;FALSE
    IntOp $6 $6 + $1
  ${EndIf}
 
  ;Record "LeftMarkerSubString" first character position on "TempStr" (temporarily)
  StrCpy $8 $6
 
  ;"StartCharPos" and "EndCharPos" should be after "SubString"
  ${If} $R5 = 0 ;FALSE
    StrCpy $6 $4
  ${Else}
    IntOp $6 $4 + $2
  ${EndIf}
  IntOp $7 $6 + $3
 
  ;Record "LeftMarkerSubString" first character position on "StartPos"
  StrCpy $4 $8
 
  ;Loop until "RightMarkerSubString" is found or "String" reaches its end
  ${Do}
    ;Remove everything before and after the searched part ("TempStr")
    StrCpy $8 $R0 $3 $6
 
    ;If "RightMarkerSubString" is empty
    ${If} $R3 == ``
      StrCpy $6 $0
      StrCpy $7 $0
      ${ExitDo}
    ${EndIf}
 
    ;Compare "TempStr" with "RightMarkerSubString"
    ${IfThen} $8 == $R3 ${|} ${ExitDo} ${|}
    ;If not, this could be "String" end
    ${IfThen} $7 >= $0 ${|} ${ExitDo} ${|}
    ;If not, continue the loop
    IntOp $6 $6 + 1
    IntOp $7 $7 + 1
  ${Loop}
 
  ;Remove "RightMarkerSubString" from "String" if the user wants
  ${If} $R6 = 0 ;FALSE
    IntOp $7 $7 - $3
  ${EndIf}
 
  ;Record "RightMarkerSubString" last character position on "StartPos"
  StrCpy $5 $7
 
  ;As the positionment is relative...
  IntOp $5 $5 - $4
 
  ;Write the string and finish the job
  StrCpy $R0 $R0 $5 $4
  Goto +2
 
  Done:
  StrCpy $R0 ``
 
/*After this point:
  ------------------------------------------
  $R0 = ResultVar (output)*/
 
  ;Return output to user
  Pop $8
  Pop $7
  Pop $6
  Pop $5
  Pop $4
  Pop $3
  Pop $2
  Pop $1
  Pop $0
  Pop $R6
  Pop $R5
  Pop $R4
  Pop $R3
  Pop $R2
  Pop $R1
  Exch $R0
FunctionEnd

Credits

Author: Diego Pedroso (deguix)
Based on Sort String 3 function.

Personal tools
donate
ads