StrRep: Difference between revisions

From NSIS Wiki
Jump to navigationJump to search
(→‎Syntax: Fixed strings pushed in wrong order)
(improvements/fixes)
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 "Shame on you, you broke your old needle!"
Push "old"
Push "brand new"
Call StrReplace
Pop $0
MessageBox MB_OK $0 ; will be "Shame on you, you broke your brand new needle!"
</highlight-nsis>


; Usage
${StrRep} "$result_var" "String" "SubString" "RepString"
: ${StrReplace} "$result_var" "SubString" "RepString" "String"
 
=== Parameters ===


; $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}"
    Push "${new}"
    !ifdef __UNINSTALL__
        Call un.StrRep
    !else
        Call StrRep
    !endif
    Pop ${output}
!macroend


Var STR_REPLACE_VAR_0
!macro Func_StrRep un
Var STR_REPLACE_VAR_1
    Function StrRep
Var STR_REPLACE_VAR_2
        Exch $R2 ;new
Var STR_REPLACE_VAR_3
        Exch 1
Var STR_REPLACE_VAR_4
        Exch $R1 ;old
Var STR_REPLACE_VAR_5
        Exch 2
Var STR_REPLACE_VAR_6
        Exch $R0 ;string
Var STR_REPLACE_VAR_7
        Push $R3
Var STR_REPLACE_VAR_8
        Push $R4
        Push $R5
        Push $R6
        Push $R7
        Push $R8
        Push $R9


Function StrReplace
        StrCpy $R3 0
  Exch $STR_REPLACE_VAR_2
        StrLen $R4 $R1
  Exch 1
        StrLen $R6 $R0
  Exch $STR_REPLACE_VAR_1
        StrLen $R9 $R2
  Exch 2
        loop:
  Exch $STR_REPLACE_VAR_0
            StrCpy $R5 $R0 $R4 $R3
    StrCpy $STR_REPLACE_VAR_3 -1
            StrCmp $R5 $R1 found
    StrLen $STR_REPLACE_VAR_4 $STR_REPLACE_VAR_1
            StrCmp $R3 $R6 done
    StrLen $STR_REPLACE_VAR_6 $STR_REPLACE_VAR_0
            IntOp $R3 $R3 + 1 ;move offset by 1 to check the next character
    loop:
            Goto loop
      IntOp $STR_REPLACE_VAR_3 $STR_REPLACE_VAR_3 + 1
        found:
      StrCpy $STR_REPLACE_VAR_5 $STR_REPLACE_VAR_0 $STR_REPLACE_VAR_4 $STR_REPLACE_VAR_3
            StrCpy $R5 $R0 $R3
      StrCmp $STR_REPLACE_VAR_5 $STR_REPLACE_VAR_1 found
            IntOp $R8 $R3 + $R4
      StrCmp $STR_REPLACE_VAR_3 $STR_REPLACE_VAR_6 done
            StrCpy $R7 $R0 "" $R8
      Goto loop
            StrCpy $R0 $R5$R2$R7
    found:
            StrLen $R6 $R0
      StrCpy $STR_REPLACE_VAR_5 $STR_REPLACE_VAR_0 $STR_REPLACE_VAR_3
            IntOp $R3 $R3 + $R9 ;move offset by length of the replacement string
      IntOp $STR_REPLACE_VAR_8 $STR_REPLACE_VAR_3 + $STR_REPLACE_VAR_4
            Goto loop
      StrCpy $STR_REPLACE_VAR_7 $STR_REPLACE_VAR_0 "" $STR_REPLACE_VAR_8
        done:
      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
        Pop $R9
      Goto loop
        Pop $R8
    done:
        Pop $R7
  Pop $STR_REPLACE_VAR_1 ; Prevent "invalid opcode" errors and keep the
        Pop $R6
  Pop $STR_REPLACE_VAR_1 ; stack as it was before the function was called
        Pop $R5
  Exch $STR_REPLACE_VAR_0
        Pop $R4
FunctionEnd
        Pop $R3
 
        Push $R0
!macro _strReplaceConstructor OUT NEEDLE NEEDLE2 HAYSTACK
        Push $R1
  Push "${HAYSTACK}"
        Pop $R0
  Push "${NEEDLE}"
        Pop $R1
  Push "${NEEDLE2}"
        Pop $R0
  Call StrReplace
        Pop $R2
  Pop "${OUT}"
        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.1
; 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
: Fixed bug where macro pushed strings in the wrong order


; 3.0
; 3.0 - updated by Dan Fuhry
: Updated by dandaman32 - uses less code and doesn't depend on LogicLib
: Uses less code and doesn't depend on LogicLib
: Also: changed macro syntax to work like the PHP eqivalent
: 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 4.0 - Marshall ([[User:Marshall|Marshall]]).<br>
Version 3.x - Dan Fuhry ([[User:dandaman32|dandaman32]]).<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]]

Revision as of 10:56, 16 November 2010

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 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)