Find file in a list of paths
Hi,
I had the problem that I had to find a file in a list of paths. My solution requires the "IndexOf" implementation from the Wiki.
Here's the source. Any suggestions?
Function IndexOfAny
Exch $R0
Exch
Exch $R1
Push $R2
Push $R3
Push $R4
Push $R5
Push $R6
StrCpy $R5 -1
StrCpy $R6 0
StrLen $R3 $R1
NextChar:
IntCmp $R3 0 NotFound
IntOp $R3 $R3 - 1
StrCpy $R4 $R1 1 $R3
${IndexOf} $R2 $R0 $R4
IntCmp $R2 -1 NextChar
IntCmp $R6 0 ForceSet
IntCmp $R5 $R2 NextChar NextChar 0
ForceSet:
StrCpy $R5 $R2
StrCpy $R6 1
GoTo NextChar
NotFound:
StrCpy $R0 $R5
Pop $R6
Pop $R5
Pop $R4
Pop $R3
Pop $R2
Pop $R1
Exch $R0
FunctionEnd
!macro IndexOfAny Var Str Chars
Push "${Chars}"
Push "${Str}"
Call IndexOfAny
Pop "${Var}"
!macroend
!define IndexOfAny "!insertmacro IndexOfAny"
; IN: Path list
; OUT: Remaining path list
; Path entry
Function ExtractPathFromList
Exch $R0
Push $R1 ; Index of found delimiter
Push $R2 ; Found path entry
Push $R3 ; Remaining path entries
Push $R4 ; Found character
Push $R5
Push $R6
Push $R7
Push $R8
StrCpy $R7 '" '
StrCpy $R8 '"'
StrCpy $R2 ""
StrCpy $R3 $R0
CheckAgain:
${IndexOfAny} $R1 $R3 $R7
IntCmp $R1 -1 ReturnRemaining
StrCpy $R4 $R3 1 $R1 ; Get found delimiter
StrCpy $R5 $R3 $R1 ; Get text until delimiter (excl.)
IntOp $R1 $R1 + 1
StrCpy $R3 $R3 "" $R1 ; Get remaining text
StrCpy $R2 "$R2$R5" ; Combine with ...
StrCmp $R4 $R8 FoundQuote
GoTo Finished
FoundQuote:
${IndexOf} $R1 $R3 $R8
IntCmp $R1 -1 ReturnRemaining
StrCpy $R4 $R3 1 $R1 ; Get found delimiter
StrCpy $R5 $R3 $R1 ; Get text until delimiter (excl.)
IntOp $R1 $R1 + 1
StrCpy $R3 $R3 "" $R1 ; Get remaining text
StrCpy $R2 "$R2$R5"
GoTo CheckAgain
ReturnRemaining:
StrCpy $R2 $R0
StrCpy $R3 ""
Finished:
StrCpy $R1 $R2
StrCpy $R0 $R3
Pop $R8
Pop $R7
Pop $R6
Pop $R5
Pop $R4
Pop $R3
Pop $R2
Exch $R1
Exch
Exch $R0
FunctionEnd
!macro ExtractPathFromList VarEntry VarRemaining Paths
Push '${Paths}'
Call ExtractPathFromList
Pop "${VarRemaining}"
Pop "${VarEntry}"
!macroend
!define ExtractPathFromList "!insertmacro ExtractPathFromList"
; IN: Paths
; File name
; OUT: Path+FileName
Function FindFileInPaths
Exch $R0
Exch
Exch $R1
Push $R2
Push $R3
check_next:
${ExtractPathFromList} $R2 $R1 $R1
StrCmp $R2 "" not_found
StrCpy $R2 "$R2\$R0"
IfFileExists "$R2" 0 check_next
StrCpy $R0 $R2
GoTo finished
not_found:
StrCpy $R0 ""
finished:
Pop $R3
Pop $R2
Pop $R1
Exch $R0
FunctionEnd
!macro FindFileInPaths Var FileName Paths
Push '${Paths}'
Push "${FileName}"
Call FindFileInPaths
Pop "${Var}"
!macroend
!define FindFileInPaths "!insertmacro FindFileInPaths"
The main idea is to implement an "IndexOfAny" which searches for the first occurrence of one of the given characters. The next step is to extract the first path from a "list" of paths that are divided by a SPC (ASCII 32) character. It also takes care of all quotation marks ('"').
Example usage:
${FindFileInPaths} $R0 "hh.exe" 'C:\WINDOWS C:\ "C:\Program Files"'
MessageBox MB_OK $R0
This is my first NSIS script *g*.
Regards,
Mark