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

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:

get absolutePath("../File","/Disk/Folder")
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.

Checking the pFilePath parameter

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.

Checking the pFolder parameter

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

Building the absolute path

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

The absolutePath function code

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

0 Comments

Add your comment

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.