There are some open issues:
Example 1: GetParentDirecotry of an absolute path like "C:\" or "/".
Should the procedure really return an empty string?
Or would it more accurate to return the root "C:\" or "/", because there is no parent of the root.
Example 2:
How should relative paths be handled?
Should'nt GetParentDirectory("relativePath") return ".\"?
Should'nt GetParentDirectory(".\") return "..\"?
Should'nt GetParentDirectory("..\") return "..\..\"?
[Solved] How can I get the parent of a directory
Re: [Solved] How can I get the parent of a directory
Windows 10 / Windows 7
PB Last Final / Last Beta Testing
PB Last Final / Last Beta Testing
-
- Addict
- Posts: 4519
- Joined: Thu Jun 07, 2007 3:25 pm
- Location: Berlin, Germany
Re: [Solved] How can I get the parent of a directory
IMHO trying to get the parent of a root directory should result in an error.helpy wrote:There are some open issues:
Example 1: GetParentDirecotry of an absolute path like "C:\" or "/".
Should the procedure really return an empty string?
Or would it more accurate to return the root "C:\" or "/", because there is no parent of the root.
So for me the main question is, what is the best way to indicate an error in this context (without writing an extra GetError() function or something). I think returning an empty string is a good error indicator here, which can be checked easily by the code that calls the ParentDirectory() function.
Now the situation becomes more complex.helpy wrote:Example 2:
How should relative paths be handled?
Should'nt GetParentDirectory("relativePath") return ".\"?
Should'nt GetParentDirectory(".\") return "..\"?
Should'nt GetParentDirectory("..\") return "..\..\"?
Here is my attempt to handle absolute and relative paths:
Code: Select all
EnableExplicit
CompilerIf #PB_Compiler_OS = #PB_OS_Windows
#DirSep$ = "\"
#DirSepChars$ = #DirSep$ + "/"
Macro PathIsRelative (_path_)
(Asc(_path_) <> '\' And FindString(_path_, ":") = 0)
EndMacro
CompilerElse
#DirSep$ = "/"
#DirSepChars$ = #DirSep$
Macro PathIsRelative (_path_)
(Asc(_path_) <> '/' And Left(_path_, 2) <> "\\")
EndMacro
CompilerEndIf
Procedure.s ParentDirectory (path$)
; in : path$: absolute or relative path, with or without trailing (back)slash;
; If path$ = "", then it is set to the current directory.
; out: return value: path to parent directory, with trailing (back)slash;
; or "" if 'path$' is a root directory
Protected posn.i, ret$
If path$ = ""
path$ = GetCurrentDirectory()
EndIf
posn = Len(path$) - 1
While posn > 0 And FindString(#DirSepChars$, Mid(path$, posn, 1)) = 0
posn - 1
Wend
If Mid(path$, posn+1, 1) <> "."
ret$ = Left(path$, posn)
If (ret$ = "") And PathIsRelative(path$)
ret$ = ".\"
EndIf
ProcedureReturn ret$
Else
If FindString(#DirSepChars$, Right(path$, 1)) = 0
path$ + #DirSep$
EndIf
ProcedureReturn path$ + ".." + #DirSep$
EndIf
EndProcedure
; -- Demo (for Windows)
; absolute paths
Debug "'" + ParentDirectory("F:\Users\LJ\") + "'"
Debug "'" + ParentDirectory("C:\") + "'"
Debug "'" + ParentDirectory("\") + "'"
Debug ""
; relative paths
Debug "'" + ParentDirectory("ab\cd\") + "'"
Debug "'" + ParentDirectory("ab\") + "'"
Debug "'" + ParentDirectory(".\") + "'"
Debug "'" + ParentDirectory("..\") + "'"
Re: [Solved] How can I get the parent of a directory
Davidos code uses in its code the undocumented behavior of GetPathPart, that in case of a missing trailing slash the last directory is cut off from the path.Little John wrote:What exactly is undocumented in this context?Sicro wrote:Good trick, davido! If this is safe to use, it would save a lot of code.
But it's undocumented behavior, so currently it's not safe to use, in my opinion.
In this case, it is also an incorrect use of GetPathPart because the command parameter requires a file path and not a directory path.
Yes, you're right, of course. I didn't think enough about programming the code.Little John wrote:IMHO it never makes sense to do unnecessary work, neither for humans nor for computers.Sicro wrote:[CodeArchiv-Code]
Here, it's not necessary to re-build Path$ in each iteration of the loop. The purpose of the loop "only" is, to find the position of the regarding slash. Then the wanted path can be built afterwards outside of the loop.
At the next update of the master branch of the CodeArchive I will release an improved version of the code.
Yes, sure. While programming the code, I wanted to make it easy for everyone to understand.Little John wrote:Using pointers will probably yield even faster code.
Many thanks to everyone for their codes
Why OpenSource should have a license :: PB-CodeArchiv-Rebirth :: Pleasant-Dark (syntax color scheme) :: RegEx-Engine (compiles RegExes to NFA/DFA)
Manjaro Xfce x64 (Main system) :: Windows 10 Home (VirtualBox) :: Newest PureBasic version
-
- Addict
- Posts: 4519
- Joined: Thu Jun 07, 2007 3:25 pm
- Location: Berlin, Germany
Re: [Solved] How can I get the parent of a directory
This behaviour isn't undocumented ... doing so is the purpose of GetPathPart().Sicro wrote:Davidos code uses in its code the undocumented behavior of GetPathPart, that in case of a missing trailing slash the last directory is cut off from the path.Little John wrote:What exactly is undocumented in this context?Sicro wrote:Good trick, davido! If this is safe to use, it would save a lot of code.
But it's undocumented behavior, so currently it's not safe to use, in my opinion.
This function does not check the file system on the drive, it just parses a string. And if the path passed to it doesn't have a trailing (back)slash, then GetPathPart() cannot distinguish between a file path and a directory path -- and this distinction doesn't matter in this context at all.Sicro wrote:In this case, it is also an incorrect use of GetPathPart because the command parameter requires a file path and not a directory path.
Re: [Solved] How can I get the parent of a directory
Thank you, Little John.
I was too focused on the file system, so I didn't think that the function would only process the path as a string. Until now I have only used this function with existing paths.
Now I also think that Davido's code and the other codes here using the same technique are safe to use
I was too focused on the file system, so I didn't think that the function would only process the path as a string. Until now I have only used this function with existing paths.
Now I also think that Davido's code and the other codes here using the same technique are safe to use
Why OpenSource should have a license :: PB-CodeArchiv-Rebirth :: Pleasant-Dark (syntax color scheme) :: RegEx-Engine (compiles RegExes to NFA/DFA)
Manjaro Xfce x64 (Main system) :: Windows 10 Home (VirtualBox) :: Newest PureBasic version
Re: [Solved] How can I get the parent of a directory
Thank you all for your help with my little problem.
It is very much appreciated.
It is very much appreciated.
DE AA EB
Re: [Solved] How can I get the parent of a directory
I rewrote the code in the CodeArchive. It now uses GetPathPart() and supports relative paths.
Checking for a relative path is a simpler version than the one from Little John. I hope that this method is still enough.
Currently, the code is still in a development branch and will remain there for a while until I am sure that it is error-free and no more functions are required.
https://github.com/SicroAtGit/PureBasic ... ectory.pbi
Code snippet:
Checking for a relative path is a simpler version than the one from Little John. I hope that this method is still enough.
Currently, the code is still in a development branch and will remain there for a while until I am sure that it is error-free and no more functions are required.
https://github.com/SicroAtGit/PureBasic ... ectory.pbi
Code snippet:
Code: Select all
Procedure$ GetParentDirectory(Path$)
Select Right(Path$, 2)
Case "./" : ProcedureReturn Path$ + "../"
Case ".\" : ProcedureReturn Path$ + "..\"
EndSelect
Select Right(Path$, 3)
Case "../" : ProcedureReturn Path$ + "../"
Case "..\" : ProcedureReturn Path$ + "..\"
EndSelect
Path$ = GetPathPart(Left(Path$, Len(Path$) - 1))
ProcedureReturn Path$
EndProcedure
Why OpenSource should have a license :: PB-CodeArchiv-Rebirth :: Pleasant-Dark (syntax color scheme) :: RegEx-Engine (compiles RegExes to NFA/DFA)
Manjaro Xfce x64 (Main system) :: Windows 10 Home (VirtualBox) :: Newest PureBasic version
Re: [Solved] How can I get the parent of a directory
Mine... just one of the many
Code: Select all
Procedure.s x_chop(string.s,left.i,right.i) ; chop a bit of the left and right side of a string
Protected l.i
;
; *** chop 'n' characters from the left or right of a string
;
l = Len(string)
If left+right >= l
string = ""
Else
If right > 0
string = Left(string,l-right)
EndIf
If left > 0
string = Mid(string,left+1,l)
EndIf
EndIf
;
ProcedureReturn string
;
EndProcedure
Procedure.s x_getparentpathpart(s.s) ; returns parent folder part of a given path
Protected q.s, p.i
;
; *** get the 'parent' folder from the given string, ie. c:\windows\system32\ would return c:\windows\
;
; notes:
;
; - assume that given string is a path, regardless if it ended on a backslash or not
; - if it cannot find a parent path it returns an empty string
; - might :-/ hancle unc paths
;
If Mid(s,2,1) = ":" ; local root
q = Left(s,2)
s = Mid(s,3,#MAX_PATH)
ElseIf Left(s,2) = "\\" ; unc path
p = FindString(s,"\",3)
If p > 0 ; valid unc path
q = Left(s,p)
s = Mid(s,p+1,#MAX_PATH)
Else ; invalid unc path
q = ""
s = ""
EndIf
EndIf
;
If s > "" ; if there is something to find the parent of...
If Right(s,1) = "\" ; strip the trailing backslash to getpathpart() returns one level higher
s = x_chop(s,0,1)
EndIf
If s > "" ; there must be something left, in which case we'll put the leading drive / unc path in front of it
s = q+GetPathPart(s)
EndIf
EndIf
ProcedureReturn s
;
EndProcedure
( PB6.00 LTS Win11 x64 Asrock AB350 Pro4 Ryzen 5 3600 32GB GTX1060 6GB)
( The path to enlightenment and the PureBasic Survival Guide right here... )
( The path to enlightenment and the PureBasic Survival Guide right here... )