Converting a relative path to an absolute path
This lesson demonstrates how to convert a relative file path to its equivalent absolute path.
The absolutePath function takes two parameters
pFilePath: the relative file path, that is a file path that starts at the current folder
pFolder: an optional folder path to the folder containing the file pFilePath, if this parameter is not specified the function uses the current folder as the starting point.
The function is called with a statement such as:
put absolutePath(thisFile,myFolder) into pathToUse
set the defaultFolder to absolutePath(thisPath)
The absolutePath function works by beginning at the starting folder and moving up one level for each "../" in the relative path. Then it concatenates the changed starting folder with the relative path to produce the equivalent absolute path.
The first thing the function does is make sure that pFilePath is, in fact, a relative path. The rule for determining whether a path is a relative path is as follows:
- On Windows systems, the second character of a relative path is not a colon character.
- On all other operating systems, relative paths are those that do not begin with a slash. (On Windows, neither relative nor absolute paths begin with a slash.)
To figure out whether pFilePath meets these conditions, the function uses a complex expression with the and and or operators. If the function is running on Windows, and the second character is a colon, this isn't a relative path. If the first character is a slash, this isn't a relative path. These two conditions are each enclosed in parentheses and are joined by the or operator, so if either of them is true, the condition itself is true and LiveCode executes the contents of the if statement.
if (the platform is "Win32" and char 2 of pFilePath is ":") or (char 1 of pFilePath is "/") then return "Error: path is not a relative path" end if
If pFilePath is not actually a relative path, the handler uses the return control structure to pass an error message back to the calling handler.
Next, the handler checks pFolder. If nothing was passed in pFolder, the handler uses the current folder as the default for this parameter. (You can use this method with any handler to assign a default value to one or more of the parameters. Just check whether the parameter is empty. If it is, then no value has been passed, and you can simply put the desired default into the parameter.)
if pFolder is empty then put the defaultFolder into pFolder end if
The relative path to the current folder is ".", so if pFilePath starts with ".", the handler deletes it. This simplifies the number of different path configurations the handler must deal with, since the relative path "./Folder/File" is the same as the relative path "Folder/File".
if first item of pFilePath is "." then delete first item of pFilePath end if
Now the handler begins comparing the two paths--the pFilePath and pFolder, to remove the parts of the folder structure they have in common. Let's look at two paths to see how this comparison works.
Suppose pFolder is "/Disk/Applications/Spreadsheets/Excel/" and pFilePath is "../../Graphics/ImageEdit".
The repeat control structure checks the first item of pFilePath to see whether it's "..", which means "go up one level". If the first item is "..", the handler deletes the first item of pFilePath, and also deletes the last item of pFolder to move us up one level in the folder structure. The repeat loop continues doing this as long as the first item in pFilePath is "..".
## move up one folder for each ".." in the relative path: repeat while first item of pFilePath is ".." delete first item of pFilePath delete last item of pFolder if pFolder is empty then ## there were too many ".." in the relative path return "Error: relative path has too many components" end if end repeat
In our example, pFilePath starts with "../../", so the loop executes twice and the last two items are deleted from pFolder. The pFolder variable is now "/Disk/Applications", and pFilePath is now "Graphics/ImageEdit". We have now edited out all redundancies in the two paths, so the only thing left to do is join them together with the & operator. The expression pFolder & pFilePath is the absolute path, and this is what the function returns.
return pFolder & "/" & pFilePath
function absolutePath pFilePath, pFolder ## make sure pFilePath is a relative path: if (the platform is "Win32" and char 2 of pFilePath is ":") or (char 1 of pFilePath is "/") then return "Error: path is not a relative path" end if ## use the current folder as the starting folder by default: if pFolder is empty then put the defaultFolder into pFolder end if if last char of pFolder is "/" then delete last char of startingFolder end if set the itemDelimiter to "/" if first item of pFilePath is "." then delete first item of pFilePath end if ## move up one folder for each ".." in the relative path: repeat while first item of pFilePath is ".." delete first item of pFilePath delete last item of pFolder if pFolder is empty then ## there were too many ".." in the relative path return "Error: relative path has too many components" end if end repeat return pFolder & "/" & pFilePath end absolutePath