I was trying to use the RPath_Absolute() function to allow paths (optionally) relative to the script directory to be specified when loading settings from a file and came across a couple of problems.
- It stripped trailing slashes from the relative path. E.g
Code:
RPath=..\Folder\
APath=D:\Temp
Result=D:\Folder ;No trailing slash
- If an already absolute path which did not require any substitution was supplied it just joined the 2 in a bit of a mess. E.g
Code:
RPath=D:\Folder
APath=D:\Temp
Result=D:\Temp\D:\Folder ;I think it should just return D:\Folder
Now, I'm not sure if any of this behavior is by design, but it was not doing what I needed so I modified the function to work like I thought it should in these two cases. Other than no longer stripping the trailing slash I believe it will work as it did before. That being said, I'm not 100% sure on all the things it was meant to do before either.
Here's the modified version
Code:
; Modified: AbsolutePath
RPath_Absolute(AbsolutPath, RelativePath, s="\") {
len := InStr(AbsolutPath, s, "", InStr(AbsolutPath, s . s) + 2) - 1 ;get server or drive string length
pr := SubStr(AbsolutPath, 1, len) ;get server or drive name
AbsolutPath := SubStr(AbsolutPath, len + 1) ;remove server or drive from AbsolutPath
If InStr(AbsolutPath, s, "", 0) = StrLen(AbsolutPath) ;remove last \ from AbsolutPath if any
StringTrimRight, AbsolutPath, AbsolutPath, 1
If InStr(RelativePath, s) = 1 ;when first char is \ go to AbsolutPath of server or drive
AbsolutPath := "", RelativePath := SubStr(RelativePath, 2) ;set AbsolutPath to nothing and remove one char from RelativePath
Else If InStr(RelativePath,"." s) = 1 ;when first two chars are .\ add to current AbsolutPath directory
RelativePath := SubStr(RelativePath, 3) ;remove two chars from RelativePath
Else If InStr(RelativePath,".." s) = 1 { ;otherwise when first 3 char are ..\
StringReplace, RelativePath, RelativePath, ..%s%, , UseErrorLevel ;remove all ..\ from RelativePath
Loop, %ErrorLevel% ;for all ..\
AbsolutPath := SubStr(AbsolutPath, 1, InStr(AbsolutPath, s, "", 0) - 1) ;remove one folder from AbsolutPath
} Else ;relative path does not need any substitution
pr := "", AbsolutPath := "", s := "" ;clear all variables to just return RelativePath
Return, pr . AbsolutPath . s . RelativePath ;concatenate server + AbsolutPath + separator + RelativePath
}
And here's a script like the example to test the original vs modified
Code:
PathA = \\server.com\user\Files\Docs\Code\AHK\SciTEDirector\includes
PathR = .\..\SmartGui\no_commit\icons_dev\
MsgText .= "PathA=" PathA "`nPathR=" PathR "`n"
MsgText .= "> RPath_Absolute(PathA, PathR)`n"
MsgText .= "Original: " RPath_Absolute_Original(PathA, PathR) . "`n"
MsgText .= "Modified: " RPath_Absolute_Modified(PathA, PathR) . "`n"
MsgText .= "Note trailing slash got stripped from path in original version.`n`n"
PathA = \\server.com\user\Files\Docs\Code\AHK\
PathR = D:\Path\Which\Requires\No\Substitution.exe
MsgText .= "PathA=" PathA "`nPathR=" PathR "`n"
MsgText .= "> RPath_Absolute(PathA, PathR)`n"
MsgText .= "Original: " RPath_Absolute_Original(PathA, PathR) . "`n"
MsgText .= "Modified: " RPath_Absolute_Modified(PathA, PathR) . "`n"
MsgText .= "Note the original version did not handle case of path which was already absolute too well.`n`n"
PathA = \\server.com\user\Files\Docs\Code\AHK\SciTEDirector\includes
PathR = ..\..\SmartGui\no_commit\icons_dev
MsgText .= "PathA=" PathA "`nPathR=" PathR "`n"
MsgText .= "Original: " RPath_Absolute_Original(PathA, PathR) . "`n"
MsgText .= "Modified: " RPath_Absolute_Modified(PathA, PathR) . "`n`n"
PathA = \\server.com\user\Files\Docs\Code\AHK\SciTEDirector\includes
PathR = .\..\SmartGui\no_commit\icons_dev
MsgText .= "PathA=" PathA "`nPathR=" PathR "`n"
MsgText .= "Original: " RPath_Absolute_Original(PathA, PathR) . "`n"
MsgText .= "Modified: " RPath_Absolute_Modified(PathA, PathR) . "`n`n"
PathA = \\server.com\user\Files\Docs\Code\AHK\SciTEDirector\includes
PathR = \SmartGui\no_commit\icons_dev
MsgText .= "PathA=" PathA "`nPathR=" PathR "`n"
MsgText .= "Original: " RPath_Absolute_Original(PathA, PathR) . "`n"
MsgText .= "Modified: " RPath_Absolute_Modified(PathA, PathR) . "`n`n"
PathA = \\server.com\user\Files\Docs\Code\AHK\SciTEDirector\includes
PathR = ..\..\SmartGui\no_commit\icons_dev\
MsgText .= "PathA=" PathA "`nPathR=" PathR "`n"
MsgText .= "Original: " RPath_Absolute_Original(PathA, PathR) . "`n"
MsgText .= "Modified: " RPath_Absolute_Modified(PathA, PathR) . "`n`n"
PathA = \\server.com\user\Files\Docs\Code\AHK\SciTEDirector\includes
PathR = .\..\SmartGui\no_commit\icons_dev\
MsgText .= "PathA=" PathA "`nPathR=" PathR "`n"
MsgText .= "Original: " RPath_Absolute_Original(PathA, PathR) . "`n"
MsgText .= "Modified: " RPath_Absolute_Modified(PathA, PathR) . "`n`n"
PathA = \\server.com\user\Files\Docs\Code\AHK\SciTEDirector\includes
PathR = \SmartGui\no_commit\icons_dev\
MsgText .= "PathA=" PathA "`nPathR=" PathR "`n"
MsgText .= "Original: " RPath_Absolute_Original(PathA, PathR) . "`n"
MsgText .= "Modified: " RPath_Absolute_Modified(PathA, PathR)
MsgBox %MsgText%
; Modified: AbsolutePath
RPath_Absolute_Modified(AbsolutPath, RelativePath, s="\") {
len := InStr(AbsolutPath, s, "", InStr(AbsolutPath, s . s) + 2) - 1 ;get server or drive string length
pr := SubStr(AbsolutPath, 1, len) ;get server or drive name
AbsolutPath := SubStr(AbsolutPath, len + 1) ;remove server or drive from AbsolutPath
If InStr(AbsolutPath, s, "", 0) = StrLen(AbsolutPath) ;remove last \ from AbsolutPath if any
StringTrimRight, AbsolutPath, AbsolutPath, 1
If InStr(RelativePath, s) = 1 ;when first char is \ go to AbsolutPath of server or drive
AbsolutPath := "", RelativePath := SubStr(RelativePath, 2) ;set AbsolutPath to nothing and remove one char from RelativePath
Else If InStr(RelativePath,"." s) = 1 ;when first two chars are .\ add to current AbsolutPath directory
RelativePath := SubStr(RelativePath, 3) ;remove two chars from RelativePath
Else If InStr(RelativePath,".." s) = 1 { ;otherwise when first 3 char are ..\
StringReplace, RelativePath, RelativePath, ..%s%, , UseErrorLevel ;remove all ..\ from RelativePath
Loop, %ErrorLevel% ;for all ..\
AbsolutPath := SubStr(AbsolutPath, 1, InStr(AbsolutPath, s, "", 0) - 1) ;remove one folder from AbsolutPath
} Else ;relative path does not need any substitution
pr := "", AbsolutPath := "", s := "" ;clear all variables to just return RelativePath
Return, pr . AbsolutPath . s . RelativePath ;concatenate server + AbsolutPath + separator + RelativePath
}
; Original: AbsolutePath
RPath_Absolute_Original(AbsolutPath, RelativePath, s="\") {
len := InStr(AbsolutPath, s, "", InStr(AbsolutPath, s . s) + 2) - 1 ;get server or drive string length
pr := SubStr(AbsolutPath, 1, len) ;get server or drive name
AbsolutPath := SubStr(AbsolutPath, len + 1) ;remove server or drive from AbsolutPath
If InStr(AbsolutPath, s, "", 0) = StrLen(AbsolutPath) ;remove last \ from AbsolutPath if any
StringTrimRight, AbsolutPath, AbsolutPath, 1
If InStr(RelativePath, s, "", 0) = StrLen(RelativePath) ;remove last \ from RelativePath if any
StringTrimRight, RelativePath, RelativePath, 1
If InStr(RelativePath, s) = 1 ;when first char is \ go to AbsolutPath of server or drive
AbsolutPath := "", RelativePath := SubStr(RelativePath, 2) ;set AbsolutPath to nothing and remove one char from RelativePath
Else If InStr(RelativePath,"." s) = 1 ;when first two chars are .\ add to current AbsolutPath directory
RelativePath := SubStr(RelativePath, 3) ;remove two chars from RelativePath
Else { ;otherwise
StringReplace, RelativePath, RelativePath, ..%s%, , UseErrorLevel ;remove all ..\ from RelativePath
Loop, %ErrorLevel% ;for all ..\
AbsolutPath := SubStr(AbsolutPath, 1, InStr(AbsolutPath, s, "", 0) - 1) ;remove one folder from AbsolutPath
}
Return, pr . AbsolutPath . s . RelativePath ;concatenate server + AbsolutPath + separator + RelativePath
}
which gave the following (AHK_L 1.1.0.0)
Code:
PathA=\\server.com\user\Files\Docs\Code\AHK\SciTEDirector\includes
PathR=.\..\SmartGui\no_commit\icons_dev\
> RPath_Absolute(PathA, PathR)
Original: \\server.com\user\Files\Docs\Code\AHK\SciTEDirector\includes\..\SmartGui\no_commit\icons_dev
Modified: \\server.com\user\Files\Docs\Code\AHK\SciTEDirector\includes\..\SmartGui\no_commit\icons_dev\
Note trailing slash got stripped from path in original version.
PathA=\\server.com\user\Files\Docs\Code\AHK\
PathR=D:\Path\Which\Requires\No\Substitution.exe
> RPath_Absolute(PathA, PathR)
Original: \\server.com\user\Files\Docs\Code\AHK\D:\Path\Which\Requires\No\Substitution.exe
Modified: D:\Path\Which\Requires\No\Substitution.exe
Note the original version did not handle case of path which was already absolute too well.
PathA=\\server.com\user\Files\Docs\Code\AHK\SciTEDirector\includes
PathR=..\..\SmartGui\no_commit\icons_dev
Original: \\server.com\user\Files\Docs\Code\AHK\SmartGui\no_commit\icons_dev
Modified: \\server.com\user\Files\Docs\Code\AHK\SmartGui\no_commit\icons_dev
PathA=\\server.com\user\Files\Docs\Code\AHK\SciTEDirector\includes
PathR=.\..\SmartGui\no_commit\icons_dev
Original: \\server.com\user\Files\Docs\Code\AHK\SciTEDirector\includes\..\SmartGui\no_commit\icons_dev
Modified: \\server.com\user\Files\Docs\Code\AHK\SciTEDirector\includes\..\SmartGui\no_commit\icons_dev
PathA=\\server.com\user\Files\Docs\Code\AHK\SciTEDirector\includes
PathR=\SmartGui\no_commit\icons_dev
Original: \\server.com\SmartGui\no_commit\icons_dev
Modified: \\server.com\SmartGui\no_commit\icons_dev
PathA=\\server.com\user\Files\Docs\Code\AHK\SciTEDirector\includes
PathR=..\..\SmartGui\no_commit\icons_dev\
Original: \\server.com\user\Files\Docs\Code\AHK\SmartGui\no_commit\icons_dev
Modified: \\server.com\user\Files\Docs\Code\AHK\SmartGui\no_commit\icons_dev\
PathA=\\server.com\user\Files\Docs\Code\AHK\SciTEDirector\includes
PathR=.\..\SmartGui\no_commit\icons_dev\
Original: \\server.com\user\Files\Docs\Code\AHK\SciTEDirector\includes\..\SmartGui\no_commit\icons_dev
Modified: \\server.com\user\Files\Docs\Code\AHK\SciTEDirector\includes\..\SmartGui\no_commit\icons_dev\
PathA=\\server.com\user\Files\Docs\Code\AHK\SciTEDirector\includes
PathR=\SmartGui\no_commit\icons_dev\
Original: \\server.com\SmartGui\no_commit\icons_dev
Modified: \\server.com\SmartGui\no_commit\icons_dev\
BTW, the original I got from the standard library collection thing which I'd just downloaded (2010 Sep it says at the top).