string replacement fun
Hi,
I am a new user and have tried a few ways to multiple text replaces in a file. I have checked the macro lib and many Instructor posts. This example is an attempt to use a suggestion in the post http://forums.winamp.com/showthread.php?threadid=205146&highlight=replace
The result of running the following installer is a messagebox with "Error" in it.
; The name of the installer
Name "try"
; The default installation directory
InstallDir $PROGRAMFILES\try
; The file to write
OutFile "try.exe"
;--------------------------------
; Pages
Page directory
Page instfiles
;--------------------------------
!include "TextFunc.nsh"
!insertmacro LineFind
!include "WordFunc.nsh"
!insertmacro WordReplace
; The stuff to install
Section "" ;No components page, name is not important
File /nonfatal web.config
SetOutPath $INSTDIR
${LineFind} "web.conf" "web.conf" "1:-1" "LineFindCallback"
IfErrors 0 +2
MessageBox MB_OK "Error"
;Push "<!--<identity impersonate='true' />-->"
;Push "<identity impersonate='true' />"
WriteUninstaller uninstall.exe
IfErrors 0 +2
MessageBox MB_OK "Error"
SectionEnd ; end the section
Function LineFindCallback
${WordReplace} '$R9' '~/images/' '/images/' '+*' $R9
; ${WordReplace} '$R9' '123' '321' '+' $R9
Push $0
FunctionEnd
Section "Uninstall"
; Remove files and uninstaller
Delete $INSTDIR\try.nsi
Delete $INSTDIR\uninstall.exe
; Remove directories used
RMDir /r "$INSTDIR"
SectionEnd
Another attempt was to use the replace in file function in the macro library. What happened was that the first replace would work, but the second one would not. Even if I flip flopped them. Here is the script for that attempt.
;!include "$PROGRAMFILES\NSIS\Include\StrReplace.nsh"
; The name of the installer
Name "try"
; The default installation directory
InstallDir $PROGRAMFILES\try
; The file to write
OutFile "try.exe"
;--------------------------------
; Pages
Page directory
Page instfiles
;--------------------------------
!include "${NSISDIR}\Include\LogicLib.nsh"
!define StrRep "!insertmacro StrRep"
!macro StrRep ResultVar String SubString RepString
Push "${String}"
Push "${SubString}"
Push "${RepString}"
Call StrRep
Pop "${ResultVar}"
!macroend
Function RIF
ClearErrors ; want to be a newborn
Exch $0 ; REPLACEMENT
Exch
Exch $1 ; SEARCH_TEXT
Exch 2
Exch $2 ; SOURCE_FILE
Push $R0 ; SOURCE_FILE file handle
Push $R1 ; temporary file handle
Push $R2 ; unique temporary file name
Push $R3 ; a line to sar/save
Push $R4 ; shift puffer
IfFileExists $2 +1 RIF_error ; knock-knock
FileOpen $R0 $2 "r" ; open the door
GetTempFileName $R2 ; who's new?
FileOpen $R1 $R2 "w" ; the escape, please!
RIF_loop: ; round'n'round we go
FileRead $R0 $R3 ; read one line
IfErrors RIF_leaveloop ; enough is enough
RIF_sar: ; sar - search and replace
Push "$R3" ; (hair)stack
Push "$1" ; needle
Push "$0" ; blood
Call StrRep ; do the bartwalk
StrCpy $R4 "$R3" ; remember previous state
Pop $R3 ; gimme s.th. back in return!
StrCmp "$R3" "$R4" +1 RIF_sar ; loop, might change again!
FileWrite $R1 "$R3" ; save the newbie
Goto RIF_loop ; gimme more
RIF_leaveloop: ; over'n'out, Sir!
FileClose $R1 ; S'rry, Ma'am - clos'n now
FileClose $R0 ; me 2
Delete "$2.old" ; go away, Sire
Rename "$2" "$2.old" ; step aside, Ma'am
Rename "$R2" "$2" ; hi, baby!
ClearErrors ; now i AM a newborn
Goto RIF_out ; out'n'away
RIF_error: ; ups - s.th. went wrong...
SetErrors ; ...so cry, boy!
RIF_out: ; your wardrobe?
Pop $R4
Pop $R3
Pop $R2
Pop $R1
Pop $R0
Pop $2
Pop $0
Pop $1
FunctionEnd
!macro ReplaceInFile SOURCE_FILE SEARCH_TEXT REPLACEMENT
Push "${SOURCE_FILE}"
Push "${SEARCH_TEXT}"
Push "${REPLACEMENT}"
Call RIF
!macroend
Function StrRep
/*After this point:
------------------------------------------
$R0 = RepString (input)
$R1 = SubString (input)
$R2 = String (input)
$R3 = RepStrLen (temp)
$R4 = SubStrLen (temp)
$R5 = StrLen (temp)
$R6 = StartCharPos (temp)
$R7 = TempStrL (temp)
$R8 = TempStrR (temp)*/
;Get input from user
Exch $R0
Exch
Exch $R1
Exch
Exch 2
Exch $R2
Push $R3
Push $R4
Push $R5
Push $R6
Push $R7
Push $R8
; Return "String" if "SubString" is ""
${IfThen} $R1 == "" ${|} Goto Done ${|}
;Get "RepString", "String" and "SubString" length
StrLen $R3 $R0
StrLen $R4 $R1
StrLen $R5 $R2
;Start "StartCharPos" counter
StrCpy $R6 0
;Loop until "SubString" is found or "String" reaches its end
${Do}
;Remove everything before and after the searched part ("TempStrL")
StrCpy $R7 $R2 $R4 $R6
;Compare "TempStrL" with "SubString"
${If} $R7 == $R1
;Split "String" to replace the string wanted
StrCpy $R7 $R2 $R6 ;TempStrL
;Calc: "StartCharPos" + "SubStrLen" = EndCharPos
IntOp $R8 $R6 + $R4
StrCpy $R8 $R2 "" $R8 ;TempStrR
;Insert the new string between the two separated parts of "String"
StrCpy $R2 $R7$R0$R8
;Now calculate the new "StrLen" and "StartCharPos"
StrLen $R5 $R2
IntOp $R6 $R6 + $R3
${Continue}
${EndIf}
;If not "SubString", this could be "String" end
${IfThen} $R6 >= $R5 ${|} ${ExitDo} ${|}
;If not, continue the loop
IntOp $R6 $R6 + 1
${Loop}
Done:
;Return output to user
StrCpy $R0 $R2
/*After this point:
------------------------------------------
$R0 = ResultVar (output)*/
Pop $R8
Pop $R7
Pop $R6
Pop $R5
Pop $R4
Pop $R3
Pop $R2
Pop $R1
Exch $R0
FunctionEnd
; The stuff to install
Section "" ;No components page, name is not important
; Set output path to the installation directory.
SetOutPath $INSTDIR
File /nonfatal web.config
;!insertmacro ReplaceInFile web.config "<!--<identity impersonate='true' />-->" "<identity impersonate='true' />"
;!insertmacro ReplaceInFile web.config "~/images/" "/images/"
Push "web.config"
Push "~/images/"
Push "/images/"
Call RIF
Push "web.config"
Push "<!--<identity impersonate='true' />-->"
Push "<identity impersonate='true' />"
Call RIF
WriteUninstaller uninstall.exe
SectionEnd ; end the section
Section "Uninstall"
; Remove files and uninstaller
Delete $INSTDIR\try.nsi
Delete $INSTDIR\uninstall.exe
; Remove directories used
RMDir /r "$INSTDIR"
SectionEnd
In this script I just pasted in the text functions. Again the result was no error, but just the first string replacement would work. Any help would be appreciated.
Cheers,
JF