RE: [Boost-users] New design proposal for boost::filesystem
Carlo Wood
I propose the following design. The aim of boost::filesystem should be to support the following coding idiom:
* The programmer should take care to only handle two types of paths in his application:
1) Complete paths 2) Relative paths
Are there any other types?
* The programmer will have to specifically tell the libary when a constructed path is 'native' and when not. <snip>
Sounds reasonable.
I propose two design changes:
1) 'native' is now not only a representation, but an *internal state* of fs::path. (this has no effect on the representation as returned by fs::path::string()). 2) All 'complete' paths are automatically marked as 'native'.
Examples, the following code is legal:
fs::path p1("C:\foo\a.exe", native); // Fails on linux, // success on windows.
You have that backwards. "\f" and "\a" are not valid in a filename in Win32. Now if those backslashes are changed to "\\" this will work on Win32. Either version of the name will work on Linux because all characters except "\0" are valid in a Unix filename.
fs::path p2("/usr/src/a.out, native); // Fails on windows, // success on linux.
That should work on Windows too because "/" is supported as an alternative to "\\". <snip>
But in case more than one 'working' directory seems needed then we can add support for that too by allowing to construct paths with a reference to the (complete/native) working directory. Ie,
fs::path home_base(...); // ...
fs::path runtime_rcfile(home_base); // ...
runtime_rcfile = "myapplication/config/runtime/rc";
which is then relative to `home_base' instead of a single, global 'working directory' (as now returned by fs::current_path()). <snip>
That doesn't seem right to me. Assignment should overwrite the old value rather than combining with it.
On Fri, Aug 20, 2004 at 05:19:12PM +0100, Ben Hutchings wrote:
Carlo Wood
wrote: * The programmer should take care to only handle two types of paths in his application:
1) Complete paths 2) Relative paths
Are there any other types?
Yes, on multi-root systems you can have a path with root directory, but without root name. For example "\Program Files". This is not a relative path, but also not complete. Note that there is another type, like "C:foo" which is relative but specifies the root name; however, it is not safe because it is unclear what is the 'current directory' on C: (if I understood the documentation of boost::filesystem correctly), so I don't think this type needs to get a lot of weight in the process of (re)design. [..snip..]
You have that backwards. "\f" and "\a" are not valid in a filename in Win32. Now if those backslashes are changed to "\\" this will work on Win32.
Sorry - that is what I meant :/ I forgot to escape them.
Either version of the name will work on Linux because all characters except "\0" are valid in a Unix filename.
Ok, but surely it is not what is intended. But you are right that it won't 'fail'. The result just won't make any sense.
fs::path p2("/usr/src/a.out, native); // Fails on windows, // success on linux.
That should work on Windows too because "/" is supported as an alternative to "\\".
Same answer. So, it doesn't "fail" in the sense that it throws, but it fails because it doesn't do what you want. The point is that the used string is a typical POSIX/UNIX path and therefore should be marked 'native'.
<snip>
But in case more than one 'working' directory seems needed then we can add support for that too by allowing to construct paths with a reference to the (complete/native) working directory. Ie,
fs::path home_base(...); // ...
fs::path runtime_rcfile(home_base); // ...
runtime_rcfile = "myapplication/config/runtime/rc";
which is then relative to `home_base' instead of a single, global 'working directory' (as now returned by fs::current_path()). <snip>
That doesn't seem right to me. Assignment should overwrite the old value rather than combining with it.
It does. The whole value will be the relative path "myapplication/config/runtime/rc"
But something that is relative will, in an application that makes sense,
always be relative to an definable 'root base' (or 'working directory').
What I propose is to not have just ONE such 'working directory', or - like
the current boost::filesystem is doing - one FIXED 'root base' being the
working directory at the moment of application start - but instead have
allow to use an arbitrary other fs::path object (that has to be complete
and a directory) for each relative path object.
This means that runtime_rcfile.string() will return "myapplication/config/runtime/rc"
and runtime_rcfile.native_file_string() will return "myapplication\config\runtime\rc"
on windows (or \\ if you want), but a fs::complete(runtime_rcfile) will
basically return home_base / runtime_rcfile. And, most importantly, when
calling operations that need to actually pass the path to a system call,
then this completion is performed automatically; ie, calling fs::exists(runtime_rcfile)
will act as if one did
(using the current boost::filesystem): fs::exists(fs::complete(runtime_rcfile, home_base))
The idea then that one can have multiple directory "nodes":
fs::path homedir;
fs::path tmpdir;
fs::path rcdir;
fs::path datadir;
etc.
And have fs::path objects with relative values that
automatically use one of these base points when file system
access is really needed.
--
Carlo Wood
participants (2)
-
Ben Hutchings
-
Carlo Wood