LineFind: Difference between revisions

From NSIS Wiki
Jump to navigationJump to search
No edit summary
 
(3 intermediate revisions by 3 users not shown)
Line 1: Line 1:
{|align=right
{{PageAuthor|Instructor}}
|<small>Author: [[{{ns:2}}:Instructor|Instructor]] ([[{{ns:3}}:Instructor|talk]], [[{{ns:-1}}:Contributions/Instructor|contrib]])</small>
|}
<br style="clear:both;">
== Links ==
; Latest version of headers "nsh.zip":
: http://forums.winamp.com/showthread.php?s=&threadid=203228&goto=lastpost


If function used without header then put function in script before call it
{{User:Instructor/Headers/Template}}


== The Function ==
== Function Description==
<highlight-nsis>/*
 
<highlight-nsis>
____________________________________________________________________________
____________________________________________________________________________


                             LineFind v1.5
                             LineFind v1.5
____________________________________________________________________________
____________________________________________________________________________
2005 Shengalts Aleksander (Shengalts@mail.ru)




Find specified lines in text file and edit or view this lines in callback
Find specified lines in text file and edit or view this lines in callback function.
function.




Line 58: Line 50:


Push $var      ; If $var="StopLineFind"  Then exit from function
Push $var      ; If $var="StopLineFind"  Then exit from function
              ; If $var="SkipWrite"    Then skip current line
              ; If $var="SkipWrite"    Then skip current line (ignored if "/NUL")
              ;                        (ignored if "/NUL")
FunctionEnd
FunctionEnd


Line 68: Line 59:
-Ranges must be specified on growth (2 4:5 9:-8 -5:-4 -2:-1)
-Ranges must be specified on growth (2 4:5 9:-8 -5:-4 -2:-1)
-Output file will not be updated if no changes made.
-Output file will not be updated if no changes made.
</highlight-nsis>






Example1 (delete first two symbols):
<b>Example1 (delete first two symbols):</b>
Section
<highlight-nsis>Section
${LineFind} "C:\a.log" "C:\a-edited.log" "3:-1" "Example1"
${LineFind} "C:\a.log" "C:\a-edited.log" "3:-1" "Example1"
IfErrors 0 +2
IfErrors 0 +2
Line 86: Line 78:
Push $0
Push $0
FunctionEnd
FunctionEnd
</highlight-nsis>






Example2 (show changed lines):
<b>Example2 (show changed lines):</b>
Section
<highlight-nsis>Section
${LineFind} "C:\a.log" "a.log" "{5:12 15 -6:-5 -1}" "Example2"
${LineFind} "C:\a.log" "a.log" "{5:12 15 -6:-5 -1}" "Example2"
IfErrors 0 +2
IfErrors 0 +2
Line 102: Line 95:
Push $0
Push $0
FunctionEnd
FunctionEnd
</highlight-nsis>






Example3 (delete lines):
<b>Example3 (delete lines):</b>
Section
<highlight-nsis>Section
${LineFind} "C:\a.log" "\logs\a.log" "2:3 10:-5 -3:-2" "Example3"
${LineFind} "C:\a.log" "\logs\a.log" "2:3 10:-5 -3:-2" "Example3"
IfErrors 0 +2
IfErrors 0 +2
Line 117: Line 111:
Push $0
Push $0
FunctionEnd
FunctionEnd
</highlight-nsis>






Example4 (insert lines):
<b>Example4 (insert lines):</b>
Section
<highlight-nsis>Section
${LineFind} "C:\a.log" "" "10" "Example4
${LineFind} "C:\a.log" "" "10" "Example4"
IfErrors 0 +2
IfErrors 0 +2
MessageBox MB_OK "Error"
MessageBox MB_OK "Error"
Line 133: Line 128:
Push $0
Push $0
FunctionEnd
FunctionEnd
</highlight-nsis>






Example5 (replace in file with count of changes - "WordFunc.nsh" required):
<b>Example5 (replace in file with count of changes - "WordFunc.nsh" required):</b>
!include "WordFunc.nsh"
<highlight-nsis>!include "WordFunc.nsh"
!insertmacro WordReplace
!insertmacro WordReplace


Line 159: Line 155:
Push $0
Push $0
FunctionEnd
FunctionEnd
</highlight-nsis>






Example6 (line string to cut or delete):
<b>Example6 (line string to cut or delete):</b>
Section
<highlight-nsis>Section
${LineFind} "\a.log" "C:\logs\a.log" "" "Example6"
${LineFind} "\a.log" "C:\logs\a.log" "" "Example6"
IfErrors 0 +2
IfErrors 0 +2
Line 211: Line 208:
Push $0
Push $0
FunctionEnd
FunctionEnd
</highlight-nsis>






Example7 (read lines):
<b>Example7 (read lines):</b>
Section
<highlight-nsis>Section
${LineFind} "C:\a.log" "/NUL" "1:-1" "Example7"
${LineFind} "C:\a.log" "/NUL" "1:-1" "Example7"
IfErrors 0 +2
IfErrors 0 +2
Line 227: Line 225:
Push $0
Push $0
FunctionEnd
FunctionEnd
*/
</highlight-nsis>


;---------------------------------------------------------------------------
== Function Code ==


<highlight-nsis>
Function LineFind
Function LineFind
!define LineFind `!insertmacro LineFindCall`
!define LineFind `!insertmacro LineFindCall`
Line 484: Line 483:
</highlight-nsis>
</highlight-nsis>


[[{{ns:14}}:Text Files Manipulation Functions]]
[[Category:Text Files Manipulation Functions]]

Latest revision as of 11:28, 30 November 2005

Author: Instructor (talk, contrib)


Page for NSIS 2.07 and below users

You can use the latest version of headers (recommended) or the following function code (put the function code in your script before calling it)

Function Description

____________________________________________________________________________
 
                            LineFind v1.5
____________________________________________________________________________
 
 
Find specified lines in text file and edit or view this lines in callback function.
 
 
Syntax:
${LineFind} "[File1]" "[File2|/NUL]" "[LineNumbers]" "Function"
 
"[File1]"         ; Input text file
                  ;
"[File2|/NUL]"    ; [File2]
                  ;   Output text file
                  ;   If empty then File2=File1
                  ; [/NUL]
                  ;   No output text file (only read File1)
                  ;
"[LineNumbers]"   ; [No|-No|No:No|{No}|{-No}|{No:No}]
                  ;   1:-1     all lines to change (default)
                  ;   2        second line from start
                  ;   -3       third line from end
                  ;   5:9      range of lines from 5 to 9
                  ;   {2}      only second line from start to output
                  ;   {-3}     only third line from end to output
                  ;   {5:9}    only range of lines from 5 to 9 to output
                  ;
"Function"        ; Callback function for specified lines
 
Function "Function"
	; $R9       current line
	; $R8       current line number
	; $R7       current line negative number
	; $R6       current range of lines
	; $R5       handle of a file opened to read
	; $R4       handle of a file opened to write ($R4="" if "/NUL")
 
	; you can use any string functions
	; $R0-$R3  are not used (save data in them).
	; ...
 
	Push $var      ; If $var="StopLineFind"  Then exit from function
	               ; If $var="SkipWrite"     Then skip current line (ignored if "/NUL")
FunctionEnd
 
 
Note:
-Error flag if input file isn't exists
-Error flag if output file path isn't exists
-Ranges must be specified on growth (2 4:5 9:-8 -5:-4 -2:-1)
-Output file will not be updated if no changes made.


Example1 (delete first two symbols):

Section
	${LineFind} "C:\a.log" "C:\a-edited.log" "3:-1" "Example1"
	IfErrors 0 +2
	MessageBox MB_OK "Error"
SectionEnd
 
Function Example1
	${TrimNewLines} '$R9' $R9
	StrCpy $R9 $R9 '' 2
	StrCpy $R9 '$R9$\r$\n'
	;start from 3 line and delete first two symbols
 
	Push $0
FunctionEnd


Example2 (show changed lines):

Section
	${LineFind} "C:\a.log" "a.log" "{5:12 15 -6:-5 -1}" "Example2"
	IfErrors 0 +2
	MessageBox MB_OK "Error"
SectionEnd
 
Function Example2
	${TrimNewLines} '$R9' $R9
	StrCpy $R9 "$R9   ~Changed line ($R8)~$\r$\n"
 
	Push $0
FunctionEnd


Example3 (delete lines):

Section
	${LineFind} "C:\a.log" "\logs\a.log" "2:3 10:-5 -3:-2" "Example3"
	IfErrors 0 +2
	MessageBox MB_OK "Error"
SectionEnd
 
Function Example3
	StrCpy $0 SkipWrite
 
	Push $0
FunctionEnd


Example4 (insert lines):

Section
	${LineFind} "C:\a.log" "" "10" "Example4"
	IfErrors 0 +2
	MessageBox MB_OK "Error"
SectionEnd
 
Function Example4
	FileWrite $R4 "---First Line---$\r$\n"
	FileWrite $R4 "---Second Line ...---$\r$\n"
 
	Push $0
FunctionEnd


Example5 (replace in file with count of changes - "WordFunc.nsh" required):

!include "WordFunc.nsh"
!insertmacro WordReplace
 
Section
	StrCpy $R0 0
	${LineFind} "C:\a.log" "C:\logs\a.log" "1:-1" "Example5"
	IfErrors 0 +2
	MessageBox MB_OK "Error" IDOK +2
	MessageBox MB_OK "Changed lines=$R0"
SectionEnd
 
Function Example5
	StrCpy $1 $R9
 
	${WordReplace} '$R9' ' ' '_' '+*' $R9
 
	StrCmp $1 $R9 +2
	IntOp $R0 $R0 + 1
	;$R0   count of changed lines
 
	Push $0
FunctionEnd


Example6 (line string to cut or delete):

Section
	${LineFind} "\a.log" "C:\logs\a.log" "" "Example6"
	IfErrors 0 +2
	MessageBox MB_OK "Error" IDOK +2
	MessageBox MB_OK "Processed lines=$R1:$R2"
SectionEnd
 
Function Example6
	;(Cut lines from a line to another line (also including that line))
	StrCmp $R0 finish stop
	StrCmp $R0 start finish
	StrCmp $R9 'Start Line$\r$\n' 0 skip
	StrCpy $R0 start
	StrCpy $R1 $R8
	goto code
	finish:
	StrCmp $R9 'Finish Line$\r$\n' 0 code
	StrCpy $R0 finish
	StrCpy $R2 $R8
	goto code
	skip:
	StrCpy $0 SkipWrite
	goto output
	stop:
	StrCpy $0 StopLineFind
	goto output
 
	;;(Delete lines from a line to another line (also including that line))
	; StrCmp $R0 finish code
	; StrCmp $R0 start finish
	; StrCmp $R9 'Start Line$\r$\n' 0 code
	; StrCpy $R0 start
	; StrCpy $R1 $R8
	; goto skip
	; finish:
	; StrCmp $R9 'Finish Line$\r$\n' 0 skip
	; StrCpy $R0 finish
	; StrCpy $R2 $R8
	; skip:
	; StrCpy $0 SkipWrite
	; goto output
 
	code:
	;...
 
	output:
	Push $0
FunctionEnd


Example7 (read lines):

Section
	${LineFind} "C:\a.log" "/NUL" "1:-1" "Example7"
	IfErrors 0 +2
	MessageBox MB_OK "Error"
SectionEnd
 
Function Example7
	MessageBox MB_OKCANCEL '$$R9  "Line"=[$R9]$\n$$R8     "#" =[$R8]' IDOK +2
	StrCpy $0 StopLineFind
 
	Push $0
FunctionEnd

Function Code

Function LineFind
	!define LineFind `!insertmacro LineFindCall`
 
	!macro LineFindCall _INPUT _OUTPUT _RANGE _FUNC
		Push $0
		Push `${_INPUT}`
		Push `${_OUTPUT}`
		Push `${_RANGE}`
		GetFunctionAddress $0 `${_FUNC}`
		Push `$0`
		Call LineFind
		Pop $0
	!macroend
 
	Exch $3
	Exch
	Exch $2
	Exch
	Exch 2
	Exch $1
	Exch 2
	Exch 3
	Exch $0
	Exch 3
	Push $4
	Push $5
	Push $6
	Push $7
	Push $8
	Push $9
	Push $R4
	Push $R5
	Push $R6
	Push $R7
	Push $R8
	Push $R9
	ClearErrors
 
	IfFileExists '$0' 0 error
	StrCmp $1 '/NUL' begin
	StrCpy $8 0
	IntOp $8 $8 - 1
	StrCpy $9 $1 1 $8
	StrCmp $9 \ +2
	StrCmp $9 '' +3 -3
	StrCpy $9 $1 $8
	IfFileExists '$9\*.*' 0 error
 
	begin:
	StrCpy $4 1
	StrCpy $5 -1
	StrCpy $6 0
	StrCpy $7 0
	StrCpy $R4 ''
	StrCpy $R6 ''
	StrCpy $R7 ''
	StrCpy $R8 0
 
	StrCpy $8 $2 1
	StrCmp $8 '{' 0 delspaces
	StrCpy $2 $2 '' 1
	StrCpy $8 $2 1 -1
	StrCmp $8 '}' 0 delspaces
	StrCpy $2 $2 -1
	StrCpy $R6 cut
 
	delspaces:
	StrCpy $8 $2 1
	StrCmp $8 ' ' 0 +3
	StrCpy $2 $2 '' 1
	goto -3
	StrCmp $2$7 '0' file
	StrCpy $4 ''
	StrCpy $5 ''
	StrCmp $2 '' writechk
 
	range:
	StrCpy $8 0
	StrCpy $9 $2 1 $8
	StrCmp $9 '' +5
	StrCmp $9 ' ' +4
	StrCmp $9 ':' +3
	IntOp $8 $8 + 1
	goto -5
	StrCpy $5 $2 $8
	IntOp $5 $5 + 0
	IntOp $8 $8 + 1
	StrCpy $2 $2 '' $8
	StrCmp $4 '' 0 +2
	StrCpy $4 $5
	StrCmp $9 ':' range
 
	IntCmp $4 0 0 +2
	IntCmp $5 -1 goto 0 growthcmp
	StrCmp $R7 '' 0 minus2plus
	StrCpy $R7 0
	FileOpen $8 $0 r
	FileRead $8 $9
	IfErrors +3
	IntOp $R7 $R7 + 1
	Goto -3
	FileClose $8
 
	minus2plus:
	IntCmp $4 0 +5 0 +5
	IntOp $4 $R7 + $4
	IntOp $4 $4 + 1
	IntCmp $4 0 +2 0 +2
	StrCpy $4 0
	IntCmp $5 -1 goto 0 growthcmp
	IntOp $5 $R7 + $5
	IntOp $5 $5 + 1
	growthcmp:
	IntCmp $4 $5 goto goto
	StrCpy $5 $4
	goto:
	goto $7
 
	file:
	StrCmp $1 '/NUL' +4
	GetTempFileName $R4
	Push $R4
	FileOpen $R4 $R4 w
	FileOpen $R5 $0 r
	IfErrors preerror
 
	loop:
	IntOp $R8 $R8 + 1
	FileRead $R5 $R9
	IfErrors handleclose
 
	cmp:
	StrCmp $2$4$5 '' writechk
	IntCmp $4 $R8 call 0 writechk
	StrCmp $5 -1 call
	IntCmp $5 $R8 call 0 call
 
	GetLabelAddress $7 cmp
	goto delspaces
 
	call:
	StrCpy $7 $R9
	Push $0
	Push $1
	Push $2
	Push $3
	Push $4
	Push $5
	Push $6
	Push $7
	Push $R4
	Push $R5
	Push $R6
	Push $R7
	Push $R8
	StrCpy $R6 '$4:$5'
	StrCmp $R7 '' +3
	IntOp $R7 $R8 - $R7
	IntOp $R7 $R7 - 1
	Call $3
	Pop $9
	Pop $R8
	Pop $R7
	Pop $R6
	Pop $R5
	Pop $R4
	Pop $7
	Pop $6
	Pop $5
	Pop $4
	Pop $3
	Pop $2
	Pop $1
	Pop $0
	IfErrors preerror
	StrCmp $9 'StopLineFind' 0 +3
	IntOp $6 $6 + 1
	goto handleclose
	StrCmp $1 '/NUL' loop
	StrCmp $9 'SkipWrite' 0 +3
	IntOp $6 $6 + 1
	goto loop
	StrCmp $7 $R9 write
	IntOp $6 $6 + 1
	goto write
 
	writechk:
	StrCmp $1 '/NUL' loop
	StrCmp $R6 cut 0 write
	IntOp $6 $6 + 1
	goto loop
 
	write:
	FileWrite $R4 $R9
	goto loop
 
	preerror:
	SetErrors
 
	handleclose:
	StrCmp $1 '/NUL' +3
	FileClose $R4
	Pop $R4
	FileClose $R5
	IfErrors error
 
	StrCmp $1 '/NUL' end
	StrCmp $1 '' 0 +2
	StrCpy $1 $0
	StrCmp $6 0 0 rename
	FileOpen $7 $0 r
	FileSeek $7 0 END $8
	FileClose $7
	FileOpen $7 $R4 r
	FileSeek $7 0 END $9
	FileClose $7
	IntCmp $8 $9 0 rename
	Delete $R4
	StrCmp $1 $0 end
	CopyFiles /SILENT $0 $1
	goto end
 
	rename:
	Delete '$EXEDIR\$1'
	Rename $R4 '$EXEDIR\$1'
	IfErrors 0 end
	Delete $1
	Rename $R4 $1
	IfErrors 0 end
 
	error:
	SetErrors
 
	end:
	Pop $R9
	Pop $R8
	Pop $R7
	Pop $R6
	Pop $R5
	Pop $R4
	Pop $9
	Pop $8
	Pop $7
	Pop $6
	Pop $5
	Pop $4
	Pop $3
	Pop $2
	Pop $1
	Pop $0
FunctionEnd