GetBetween: Get text in between two markers in a file
From NSIS Wiki
Jump to navigationJump to search
Author: Afrow UK (talk, contrib) |
Description
This function for vbgunz gets text from between two markers in a file. It returns the text from between the first occurrences of the markers and then stops searching. It works even if the markers are or are not on the same line.
Usage
${GetBetween} "This" "And This" "$INSTDIR\In_This.txt" "$R0" ; $R0 = output (text between "This", "And This").
The Macro and Function
!macro GetBetween This AndThis In Return Push "${This}" Push "${AndThis}" Push "${In}" Call GetBetween Pop "${Return}" !macroend !define GetBetween "!insertmacro GetBetween" Function GetBetween Exch $R0 ; file Exch Exch $R1 ; before this (marker 2) Exch 2 Exch $R2 ; after this (marker 1) Exch 2 Push $R3 ; marker 1 len Push $R4 ; marker 2 len Push $R5 ; marker pos Push $R6 ; file handle Push $R7 ; current line string Push $R8 ; current chop FileOpen $R6 $R0 r StrLen $R4 $R2 StrLen $R3 $R1 StrCpy $R0 "" Read1: ClearErrors FileRead $R6 $R7 IfErrors Done StrCpy $R5 0 FindMarker1: IntOp $R5 $R5 - 1 StrCpy $R8 $R7 $R4 $R5 StrCmp $R8 "" Read1 StrCmp $R8 $R2 0 FindMarker1 IntOp $R5 $R5 + $R4 StrCpy $R7 $R7 "" $R5 StrCpy $R5 -1 Goto FindMarker2 Read2: ClearErrors FileRead $R6 $R7 IfErrors Done StrCpy $R5 -1 FindMarker2: IntOp $R5 $R5 + 1 StrCpy $R8 $R7 $R3 $R5 StrCmp $R8 "" 0 +3 StrCpy $R0 $R0$R7 Goto Read2 StrCmp $R8 $R1 0 FindMarker2 StrCpy $R7 $R7 $R5 StrCpy $R0 $R0$R7 Done: FileClose $R6 Pop $R8 Pop $R7 Pop $R6 Pop $R5 Pop $R4 Pop $R3 Pop $R2 Pop $R1 Exch $R0 FunctionEnd
-Stu
Patch for the above Function
Please note and track the stack action for the above function. Calling it repeatedly will mung your registers, as shown by the step through below.
!macro GetBetween This AndThis In Return Push "${This}" ; This + Stack Push "${AndThis}" ; AndThis + This + Stack Push "${In}" ; In + AndThis + This + Stack Call GetBetween Pop "${Return}" !macroend !define GetBetween "!insertmacro GetBetween" Function GetBetween Exch $R0 ; $R0_Old + AndThis + This + Stack Exch ; AndThis + $R0_Old + This + Stack Exch $R1 ; $R1_Old + $R0_Old + This + Stack Exch 2 ; This + $R0_Old + $R1_Old + Stack Exch $R2 ; $R2_Old + $R0_OLD + $R1_Old + Stack ## ERROR IS HERE. Exch 2 ; R1 R0 R2 + stack Push $R3 ; R3 R1 R0 R2 + stack ## Careful inspection of the rest of the function, ## shows zero stack maniplation to somehow fix ## the linear re-pop of the register list 8-0
The correction at the noted error is to add two lines before pushing $R3:
Exch $R2 ;$R2_Old + $R0_OLD + $R1_Old + Stack Exch 2 ; $R1_Old + $R0_OLD + $R2_Old + Stack Exch ; $R0_Old + $R1_OLD + $R2_Old + Stack Exch 2 ; $R2_Old + $R1_OLD + $R0_Old + Stack ; Now push $R3
Pending user-group agreement; I suggest patching the original code before removing my comments. - Andrew Wallo