From ecdecd6353ac96442d5f61e73e529189be5fac86 Mon Sep 17 00:00:00 2001
From: Beman Dawes
Why doesn't the generic path grammar include syntax for portably -specifying the root directory?
-The concept of "root directory" appears to be inherently non-portable. -For example, "/" means one thing on POSIX (an absolute path the single -filesystem root), and another on Windows (a relative path to the root of the -current drive). It goes rapidly downhill from there; on the classic Mac -OS, root names can be ambiguous!
-Why isn't there a path::is_absolute() or similar function?
-Because useful semantics are not obvious. On some operating systems a path is clearly either absolute or -relative, but on others the distinction isn't clear. For example, on Windows consider these -paths:
-Why do some path member function names have a "system_specific_" prefix?
+To alert users that the results are inherently non-portable. The names are +deliberately ugly to discourage use except where really necessary.
© Copyright Beman Dawes, 2002
Revised -12 September, 2002
\ No newline at end of file +20 November, 2002 \ No newline at end of file diff --git a/doc/path.htm b/doc/path.htm index d954ec5..4da9960 100644 --- a/doc/path.htm +++ b/doc/path.htm @@ -20,7 +20,8 @@ Header synopsisMany Filesystem Library functions traffic in objects of class path, @@ -68,19 +69,15 @@ constructor is provided which takes a system-specific format as an argument.
the operating system's format, and a file path string using the operating system's format. Additional access functions retrieve specific portions of the contained path. - - - - - -The grammar is specified in extended BNF, with terminal symbols in quotes:
-@@ -92,12 +89,17 @@ with the system_specific decorator.path ::= [system-specific-root] [relative-path]-relative-path ::= element { "/" element }-element ::= name | parent-directory+path ::= [root] [relative-path] // an empty path is valid+root ::= [system-specific-root] [root-directory]+root-directory ::= "/"+relative-path ::= path-element { "/" path-element } ["/"]+path-element ::= name | parent-directoryparent-directory ::= ".."name ::= char { char }
Although implementation-defined, it is desirable that system-specific-root have a grammar which is distinguishable from other grammar elements, and follow the conventions of the operating system.
+The optional trailing "/" in a relative-path is allowed as a +notational convenience. It has no semantic meaning and is discarded in +conversions to canonical form.
Whether or not a generic path string is actually portable to a particular operating system will depend on the names used. See the Portability Guide.
Adjacent name, parent-directory elements in m_name
-have been recursively removed.
relative-path does not have a trailing +"/".
namespace boost @@ -221,6 +223,17 @@ in the example produces a useless result. On this operating system, the programmer should only use this path as a file path. (There is a portability recommendation to not use periods in directory names.) +path string grammar relative-path syntax, and contains no embedded '\0' characters.Warning for POSIX and UNIX programmers
+POSIX and other UNIX-like file systems are single-rooted, while most other +file systems are multi-rooted. Multi-rooted file systems require a system-root +such as a drive, device, disk, volume, or share name for a path to be absolute. +Because of this, the root() and root_directory() functions return +identical results on UNIX and other single-rooted file systems, but different +results on multi-rooted file systems. Thus use of the wrong function will not be +apparent on UNIX-like systems, but will result in non-portable code which will +fail when used on multi-rooted systems. Thus UNIX programmers should use +particular care to choose between root() and root_directory().
+The same warning applies to has_root() and has_root_directory().
constructors
path();@@ -231,7 +244,7 @@ path( const char * src );
Effects: For each src element, m_name.push_back( element ).
Postcondition: m_name has been reduced to
+
Postcondition: m_name is in
canonical form.
Rationale: These constructors are not explicit because an intended use is automatic conversion of strings to paths.
@@ -239,17 +252,25 @@ path( const char * src ); path( const char * src, path_format );Precondition: src conforms to the operating system's grammar for path strings, and contains no embedded '\0' characters.
-Effects: For each src element (where an element represents a
- directory name, file name, or parent-directory indicator), m_name.push_back( element ).
Postcondition: m_name has been reduced to
+
Effects: For each src element, m_name.push_back( element ).
Postcondition: m_name is in
canonical form.
path & operator<<=( const path & rhs );-Effects: Append
+rhs.m_nametom_name.Effects: If any of the following conditions are met, then + m_name.push_back("/").
++
+- has_relative_path().
+- !is_absolute() && has_system_specific_root(), and the operating system + requires the system-specific root be absolute
+Then append
+rhs.m_nametom_name.(Footnote: Thus on Windows, (path("//share") /= "foo").string() is + "//share/foo")
Returns:
-*thisPostcondition:
m_namehas been reduced to +Postcondition:
m_nameis in canonical form.Rationale: It is not considered an error for
+rhsto include asystem-specific-rootbecause it might relative, and @@ -363,10 +384,226 @@ also supplies several non-member functions which can be used to verify that a path meets certain requirements. These subsidiary functions are undocumented pending more research and discussion, and should not be relied upon as they are likely to change.Path decomposition
+It is often useful to extract specific elements from a path object. +While any decomposition can be achieved by iterating over the elements of a +path, convenience functions are provided which are easier to use, more +efficient, and less error prone.
++
++ +generic_ +
+ string()Elements +root_ +
+ path()
+system_ +
+ specific_
+ root()root_ +
+ directory()relative_ +
+ path()root_ +
+ directory()
+ / relative_
+ path()system_ +
+ specific_
+ root() /
+ relative_
+ path()branch_ +
+ path()leaf() ++ +All systems ++ + + + + + + + + + ++ /+ /+ /+ ""+ /+ ""+ /+ ""+ ""+ /+ ++ foo+ foo+ ""+ ""+ ""+ foo+ foo+ foo+ ""+ foo+ ++ /foo+ /,foo+ /+ ""+ /+ foo+ /foo+ foo+ /+ foo+ ++ foo/bar+ foo,bar+ ""+ ""+ ""+ foo/bar+ foo/bar+ foo/bar+ foo+ bar+ ++ /foo/bar+ /,foo,bar+ /+ ""+ /+ foo/bar+ /foo/bar+ foo/bar+ /foo+ bar+ +Windows ++ + + + + + + + + + ++ c:+ c:+ c:+ c:+ ""+ ""+ ""+ c:+ ""+ c:+ ++ c:foo+ c:,foo+ c:+ c:+ ""+ foo+ foo+ c:foo+ c:+ foo+ ++ c:/+ c:,/+ c:/+ c:+ /+ ""+ /+ c:+ c:+ /+ ++ c:/foo+ c:,/,foo+ c:/+ c:+ /+ foo+ /foo+ c:foo+ c:/+ foo+ ++ //shr+ //shr+ //shr+ //shr+ ""+ ""+ ""+ //shr+ ""+ //shr+ ++ //shr/+ //shr,/+ //shr/+ //shr+ /+ ""+ /+ //shr+ //shr+ /+ ++ //shr/foo+ //shr,
+ /,foo+ //shr/+ //shr+ /+ foo+ /foo+ //shr/foo+ //shr/+ foo+ ++ prn:+ prn:+ prn:+ prn:+ ""+ ""+ ""+ prn:+ ""+ prn:
© Copyright Beman Dawes, 2002
Revised -20 September, 2002
+24 November, 2002