StrRep: Difference between revisions

From NSIS Wiki
Jump to navigationJump to search
No edit summary
m (changed push calls to add support for usage with " sign)
 
(8 intermediate revisions by 7 users not shown)
Line 2: Line 2:


== Description ==
== Description ==
'''Version: 3.0'''
This function searches and replaces all occurrences of a substring in a string.
This function searches and replaces all occurrences of a substring in a string.


== How To Use ==
== How To Use ==


=== Syntax ===
=== Usage / Syntax ===
 
; Single command
: This is by far the easiest way to use StrReplace.
<highlight-nsis>
<highlight-nsis>
${StrReplace} '$0' '\' '_' 'C:\Documents and Settings\Dan\Desktop\PSCP Frontend.exe'
${StrRep} '$0' 'C:\Documents and Settings\Dan\Desktop\PSCP Frontend.exe' '\' '\\'
MessageBox MB_OK $0 ; will be C:_Documents and Settings_Dan_Desktop_PSCP Frontend.exe
MessageBox MB_OK $0 ; will be C:\\Documents and Settings\\Dan\\Desktop\\PSCP Frontend.exe
</highlight-nsis>
</highlight-nsis>


; Push/function call
=== Parameters ===
: For when you're used to NSIS :)
<highlight-nsis>
Push "old"
Push "brand new"
Push "Shame on you, you broke your old needle!"
Call StrReplace
Pop $0
MessageBox MB_OK $0 ; will be "Shame on you, you broke your brand new needle!"
</highlight-nsis>
 
; Usage
: ${StrReplace} "$result_var" "SubString" "RepString" "String"


=== Parameters ===
${StrRep} "$result_var" "String" "SubString" "RepString"


; $result_var
; $result_var
Line 49: Line 31:


<highlight-nsis>
<highlight-nsis>
${StrReplace} $0 "just " "" "This is just an example"
${StrRep} $0 "This is just an example" "just " ""
;$0 = "This is an example"
;$0 = "This is an example"
</highlight-nsis>
</highlight-nsis>
Line 56: Line 38:


<highlight-nsis>
<highlight-nsis>
; StrReplace
!define StrRep "!insertmacro StrRep"
; Replaces all ocurrences of a given needle within a haystack with another string
!macro StrRep output string old new
; Written by dandaman32
    Push `${string}`
 
    Push `${old}`
Var STR_REPLACE_VAR_0
    Push `${new}`
Var STR_REPLACE_VAR_1
    !ifdef __UNINSTALL__
Var STR_REPLACE_VAR_2
        Call un.StrRep
Var STR_REPLACE_VAR_3
    !else
Var STR_REPLACE_VAR_4
        Call StrRep
Var STR_REPLACE_VAR_5
    !endif
Var STR_REPLACE_VAR_6
    Pop ${output}
Var STR_REPLACE_VAR_7
!macroend
Var STR_REPLACE_VAR_8


Function StrReplace
!macro Func_StrRep un
  Exch $STR_REPLACE_VAR_2
    Function ${un}StrRep
  Exch 1
        Exch $R2 ;new
  Exch $STR_REPLACE_VAR_1
        Exch 1
  Exch 2
        Exch $R1 ;old
  Exch $STR_REPLACE_VAR_0
        Exch 2
    StrCpy $STR_REPLACE_VAR_3 -1
        Exch $R0 ;string
    StrLen $STR_REPLACE_VAR_4 $STR_REPLACE_VAR_1
        Push $R3
    StrLen $STR_REPLACE_VAR_6 $STR_REPLACE_VAR_0
        Push $R4
    loop:
        Push $R5
      IntOp $STR_REPLACE_VAR_3 $STR_REPLACE_VAR_3 + 1
        Push $R6
      StrCpy $STR_REPLACE_VAR_5 $STR_REPLACE_VAR_0 $STR_REPLACE_VAR_4 $STR_REPLACE_VAR_3
        Push $R7
      StrCmp $STR_REPLACE_VAR_5 $STR_REPLACE_VAR_1 found
        Push $R8
      StrCmp $STR_REPLACE_VAR_3 $STR_REPLACE_VAR_6 done
        Push $R9
      Goto loop
    found:
      StrCpy $STR_REPLACE_VAR_5 $STR_REPLACE_VAR_0 $STR_REPLACE_VAR_3
      IntOp $STR_REPLACE_VAR_8 $STR_REPLACE_VAR_3 + $STR_REPLACE_VAR_4
      StrCpy $STR_REPLACE_VAR_7 $STR_REPLACE_VAR_0 "" $STR_REPLACE_VAR_8
      StrCpy $STR_REPLACE_VAR_0 $STR_REPLACE_VAR_5$STR_REPLACE_VAR_2$STR_REPLACE_VAR_7
      StrLen $STR_REPLACE_VAR_6 $STR_REPLACE_VAR_0
      Goto loop
    done:
  Pop $STR_REPLACE_VAR_1 ; Prevent "invalid opcode" errors and keep the
  Pop $STR_REPLACE_VAR_1 ; stack as it was before the function was called
  Exch $STR_REPLACE_VAR_0
FunctionEnd


!macro _strReplaceConstructor OUT NEEDLE NEEDLE2 HAYSTACK
        StrCpy $R3 0
  Push "${NEEDLE}"
        StrLen $R4 $R1
  Push "${NEEDLE2}"
        StrLen $R6 $R0
  Push "${HAYSTACK}"
        StrLen $R9 $R2
  Call StrReplace
        loop:
  Pop "${OUT}"
            StrCpy $R5 $R0 $R4 $R3
            StrCmp $R5 $R1 found
            StrCmp $R3 $R6 done
            IntOp $R3 $R3 + 1 ;move offset by 1 to check the next character
            Goto loop
        found:
            StrCpy $R5 $R0 $R3
            IntOp $R8 $R3 + $R4
            StrCpy $R7 $R0 "" $R8
            StrCpy $R0 $R5$R2$R7
            StrLen $R6 $R0
            IntOp $R3 $R3 + $R9 ;move offset by length of the replacement string
            Goto loop
        done:
       
        Pop $R9
        Pop $R8
        Pop $R7
        Pop $R6
        Pop $R5
        Pop $R4
        Pop $R3
        Push $R0
        Push $R1
        Pop $R0
        Pop $R1
        Pop $R0
        Pop $R2
        Exch $R1
    FunctionEnd
!macroend
!macroend
!insertmacro Func_StrRep ""
!insertmacro Func_StrRep "un."


!define StrReplace '!insertmacro "_strReplaceConstructor"'
</highlight-nsis>
</highlight-nsis>


== Versions History ==
== Versions History ==


; 3.0
; 4.0 - updated by Marshall
: Updated by dandaman32 - uses less code and doesn't depend on LogicLib
: Replaced superfluos extra variables with standard registers
: Also: changed macro syntax to work like the PHP eqivalent
: Fixed infinite loop bug where replacement string contained the string-to-replace
: Structured for installer/uninstaller versions
: Changed macro parameter order to be more intuitive
 
; 3.0.1 - updated by Dan Fuhry
: Fixed bug where macro pushed strings in the wrong order
 
; 3.0 - updated by Dan Fuhry
: Uses less code and doesn't depend on LogicLib
: Changed macro syntax to work like the PHP eqivalent


;2.0.1
; 2.0.1 - updated by Diego Pedroso
:Fixed stack problems.
: Fixed stack problems


== Credits ==
== Credits ==
Version 3.x - Dan Fuhry ([[User:dandaman32]]).<br>
Version 4.0 - Marshall ([[User:Marshall|Marshall]]).<br>
Version 3.x - Dan Fuhry ([[User:dandaman32|dandaman32]]).<br>
Version 2.x - Diego Pedroso ([[User:deguix|deguix]]).<br>
Version 2.x - Diego Pedroso ([[User:deguix|deguix]]).<br>
Version 1.x [[User:Afrow UK|Afrow UK]] / Diego Pedroso ([[User:deguix|deguix]]).<br>
Version 1.x - [[User:Afrow UK|Afrow UK]] / Diego Pedroso ([[User:deguix|deguix]]).<br>
Version [http://forums.winamp.com/showthread.php?threadid=83283 1.0] - Hendri Adriaens ([[User:Smile2Me|Smile2Me]])
Version [http://forums.winamp.com/showthread.php?threadid=83283 1.0] - Hendri Adriaens ([[User:Smile2Me|Smile2Me]])


[[Category:String Functions]]
[[Category:String Functions]]

Latest revision as of 17:26, 29 August 2013

Author: dandaman32 (talk, contrib)


Description

This function searches and replaces all occurrences of a substring in a string.

How To Use

Usage / Syntax

${StrRep} '$0' 'C:\Documents and Settings\Dan\Desktop\PSCP Frontend.exe' '\' '\\'
MessageBox MB_OK $0 ; will be C:\\Documents and Settings\\Dan\\Desktop\\PSCP Frontend.exe

Parameters

${StrRep} "$result_var" "String" "SubString" "RepString"

$result_var
Variable where resulting operation of the replacement is returned. If SubString is not found, the value is the same as String.
String
String where to search for SubString.
SubString
String to search in String and to be replaced by RepString.
RepString
String to replace all occurrences of SubString inside String.

Example

${StrRep} $0 "This is just an example" "just " ""
;$0 = "This is an example"

Function Code

!define StrRep "!insertmacro StrRep"
!macro StrRep output string old new
    Push `${string}`
    Push `${old}`
    Push `${new}`
    !ifdef __UNINSTALL__
        Call un.StrRep
    !else
        Call StrRep
    !endif
    Pop ${output}
!macroend
 
!macro Func_StrRep un
    Function ${un}StrRep
        Exch $R2 ;new
        Exch 1
        Exch $R1 ;old
        Exch 2
        Exch $R0 ;string
        Push $R3
        Push $R4
        Push $R5
        Push $R6
        Push $R7
        Push $R8
        Push $R9
 
        StrCpy $R3 0
        StrLen $R4 $R1
        StrLen $R6 $R0
        StrLen $R9 $R2
        loop:
            StrCpy $R5 $R0 $R4 $R3
            StrCmp $R5 $R1 found
            StrCmp $R3 $R6 done
            IntOp $R3 $R3 + 1 ;move offset by 1 to check the next character
            Goto loop
        found:
            StrCpy $R5 $R0 $R3
            IntOp $R8 $R3 + $R4
            StrCpy $R7 $R0 "" $R8
            StrCpy $R0 $R5$R2$R7
            StrLen $R6 $R0
            IntOp $R3 $R3 + $R9 ;move offset by length of the replacement string
            Goto loop
        done:
 
        Pop $R9
        Pop $R8
        Pop $R7
        Pop $R6
        Pop $R5
        Pop $R4
        Pop $R3
        Push $R0
        Push $R1
        Pop $R0
        Pop $R1
        Pop $R0
        Pop $R2
        Exch $R1
    FunctionEnd
!macroend
!insertmacro Func_StrRep ""
!insertmacro Func_StrRep "un."

Versions History

4.0 - updated by Marshall
Replaced superfluos extra variables with standard registers
Fixed infinite loop bug where replacement string contained the string-to-replace
Structured for installer/uninstaller versions
Changed macro parameter order to be more intuitive
3.0.1 - updated by Dan Fuhry
Fixed bug where macro pushed strings in the wrong order
3.0 - updated by Dan Fuhry
Uses less code and doesn't depend on LogicLib
Changed macro syntax to work like the PHP eqivalent
2.0.1 - updated by Diego Pedroso
Fixed stack problems

Credits

Version 4.0 - Marshall (Marshall).
Version 3.x - Dan Fuhry (dandaman32).
Version 2.x - Diego Pedroso (deguix).
Version 1.x - Afrow UK / Diego Pedroso (deguix).
Version 1.0 - Hendri Adriaens (Smile2Me)