Re: [boost] boost::filesystem file restrictions

2003-08-18 Thread John Torjo
 The current approach is clearly too restrictive and isn't satisfactory.
 Beyond the problems you mention, there really isn't a single standard for
 portability. Even 8.3 names aren't portable to systems which don't allow
 periods in names. A whole family of checkers is needed, giving various
 degrees of portability. Some should be supplied with the library, but
users
 also need to be able to provide their own.
 [...]

 boost/filesystem/path.hpp added this:

 typedef bool (*is_portable_test)( string  candidate );

 class scoped_portability_policy : noncopyable
 {
 public:
   explicit scoped_portabiity_policy( is_portable_test f );
   ~scoped_portabiity_policy();
  };


I'm not sure 'portability' is the right word here.

Since it can be overridden by the user, maybe a better name would be:
is_legal_name_test - and the user can override it to suit its needs.

I don't quite like is_portable_test, since I assume there is only
one 'portability', not more (at least, this is what I think, when
discussing portability). For instance, when talking about a portable name,
I assume there is a clear definition of what that means to everybody
(and I don't assume users could/should override that ;).


That said, instead of a scoped portability policy, which will go rather
bad with thread-safety, maybe, just a simple
set_legal_name_policy( is_legal_name_test f); would look better.

Users would (should) set this in main(), while there are no more threads,
and it could play nicely with thread-safety as well.


Best,
John


___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] boost::filesystem file restrictions

2003-08-18 Thread Beman Dawes
At 05:43 AM 8/18/2003, John Torjo wrote:
 The current approach is clearly too restrictive and isn't satisfactory.
 Beyond the problems you mention, there really isn't a single standard 
for
 portability. Even 8.3 names aren't portable to systems which don't 
allow
 periods in names. A whole family of checkers is needed, giving various
 degrees of portability. Some should be supplied with the library, but
users
 also need to be able to provide their own.
 [...]

 boost/filesystem/path.hpp added this:

 typedef bool (*is_portable_test)( string  candidate );

 class scoped_portability_policy : noncopyable
 {
 public:
   explicit scoped_portabiity_policy( is_portable_test f );
   ~scoped_portabiity_policy();
  };


I'm not sure 'portability' is the right word here.

Since it can be overridden by the user, maybe a better name would be:
is_legal_name_test - and the user can override it to suit its needs.

I don't quite like is_portable_test, since I assume there is only
one 'portability', not more (at least, this is what I think, when
discussing portability). For instance, when talking about a portable 
name,
I assume there is a clear definition of what that means to everybody
(and I don't assume users could/should override that ;).


That said, instead of a scoped portability policy, which will go rather
bad with thread-safety, maybe, just a simple
set_legal_name_policy( is_legal_name_test f); would look better.

Users would (should) set this in main(), while there are no more threads,
and it could play nicely with thread-safety as well.

Yes. Plus there are some other issues.

The actual interface would include boost::filesystem::path constructors 
which take an additional argument to explicitly specify a name checker 
function. In working out use cases, it seems that temporary overrides of 
the default function are best handled via these constructors. That leaves 
only the case of wishing to permanently replace the default function, and 
the simpler approach you are talking about would be better for that.

For safety, such a set_legal_name_policy() would use the 
write-once-before-read idiom to avoid a dangerous global variable. (I'm 
actually thinking of name_check for the type, and set_name_check for 
the function name.)

I'm about to post a message asking for opinions on the details of the 
policy function pointer or object.

--Beman 

___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] boost::filesystem file restrictions

2003-08-16 Thread Beman Dawes
At 08:46 PM 8/14/2003, Walter Landry wrote:

Peter Dimov [EMAIL PROTECTED] wrote:
 I am not sure that it should be the responsibility of the path class to
 enforce some notion of portability. Wouldn't it be more appropriate to
 defer the portability check, if any, to the point where the path is
 actually used in a filesystem operation?

I agree, if only because I could imagine manipulating a bunch of
non-legal paths before actually using a legal one.
I gave that some thought during the initial design. Let's say you want to 
do some manipulation of an element (that is, a name representing a node in 
the tree). Perhaps you have a home grown runtime macro expansion scheme. 
You are probably better off holding the data in a std::string until your 
manipulations (say macro expansion) have progressed to the point it is a 
valid native or portable name or path. At that point, assign the string to 
a boost::filesystem::path.

  We still have to
solve the problem, but at a different place.
Yes, exactly.

  Beman's singleton stack
seems like a reasonable solution.  We can argue over what the default
portability policy should be, but it almost becomes irrelevant because
it is easy to change and forget about it.
I've been turning that solution over and over in my mind, and while it has 
some mild blemishes, it seems clearly a big improvement over the current 
design.

Among side advantages, it doesn't break any current code. So unless someone 
comes up with a killer argument against the stack approach, I'll implement 
it within a day or two.

Part of the difficulty with the current approach is documentation; I'll try 
to rectify that in the process.

--Beman

___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] boost::filesystem file restrictions

2003-08-16 Thread Beman Dawes
At 04:23 PM 8/15/2003, Peter Dimov wrote:
Beman Dawes wrote:
 At 01:40 PM 8/14/2003, Peter Dimov wrote:
  
  I am not sure that it should be the responsibility of the path
  class to enforce some notion of portability. Wouldn't it be more
  appropriate to defer the portability check, if any, to the point
  where the path is actually used in a filesystem operation?

 That's too late. A real path is often made up of some native elements
 (which the portability check doesn't apply to) and some portable
 elements (which the portability check should be applied to).

 The earlier the error can be detected, the better. Also, a path is
 only constructed once, but may be use multiple times.

[...]

 That would be easy if we accepted the native platform as the default,
 and portable cases had to be specially coded. But my interest is in
 portable semantics as the default.

I must be missing something. What is a portable path useful for? A
portable path _grammar_ (element sequence separated by '/') is certainly
useful, it allows me to write portable _code_ that deals with paths.
Yes, to the extent the elements (the names) are portable.

Portable path _data_ is a different story.

For sure. But we have been talking only about names which are elements of 
paths and how to string them together via a portable grammar. We haven't 
been talking about file data content at all.

--Beman

___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] boost::filesystem file restrictions

2003-08-15 Thread Dick . Bridges

history comments='below'


   
 
  Edward Diener  
 
  [EMAIL PROTECTED] To:  [EMAIL PROTECTED]
 
  ft.comcc:   
 
  Sent by:   Subject: [boost] Re: 
boost::filesystem file restrictions   
  [EMAIL PROTECTED]

  s.boost.org  
 
   
 
   
 
  08/15/2003 08:35 
 
  AM   
 
  Please respond to
 
  Boost mailing list   
 
   
 
   
 




David Abrahams wrote:
 Glen Knowles [EMAIL PROTECTED] writes:

 From: David Abrahams [mailto:[EMAIL PROTECTED]
 portable_path(/foo/bar) - throws on Windows

 Not sure why this would throw, what is the purpose of
 portable_path? /foo/bar is perfectly reasonable on Windows.

 It's perfectly reasonable but it doesn't have a portable meaning.
 It
 is a relative path w.r.t. the drive of the current directory.

 Almost all paths are relative w.r.t. something, the current users
 filesystem mapping, the computer, the network.

 I find that somewhat compelling... but in the end it doesn't hold up.

 I don't see how
 leaving out the drive makes it less portable then leaving out the
 computer name.

 It's less portable because how it is to be interpreted *with respect
 to the filesystem* can change dynamically.  Remember the name of this
 library, filesystem? ;-

 Filesystems belong to computers.  A computer's filesystem is accessed
 via an infinite tree of names (**).  How those names which correspond
 actual storage are mapped can be modified dynamically in any number of
 ways: you can have symbolic and hard links, mount drives, remote
 computers can come online or go away, non-storage devices can be
 mounted at locations in the tree etc.  The one constant is the
 structure of the tree of names which allows us to access a virtual
 location in the filesystem (as opposed to physical).

 A path is a set of instructions for traversing the name tree.  By any
 reasonable definition, an absolute path identifies a single virtual
 location in a filesystem's name tree, not one that can change based on
 the process state.  A path on windows that starts with '/' is a set
 of instructions which begins: go to the root of the current
 directory path.

Correction. It does not mean that. It means go to the root directory of the
current drive. It is still not an absolute path since the current drive
changes. If one specified 'a:/', then that is an absolute path as defined
under Windows. Even if 'a:' were a removable disk, and thus could be
physically changed, it would be considered an absolute path.

/history

I'm just a confused lurker seeking some clarification.  I thought most OSs
allowed a process filesystem to be dynamically re-rooted and that '/'
refers to the current root - whatever the OS (assuming hierarchical
filesystem[s]).  If you introduce the extra-filesystem a:/ wrt Windows,
then why not chroot for *NIXs or the 9P messages that re-root the Plan 9
filesystem to a different date or file server?

I was under the impression that /foo/bar is a relative path wrt the
current root of any given process state.  For any given process, the
physical location of /foo/bar may change between points in time and, for
any two processes, the physical location of /foo/bar may be different at
the same point in time.

I've clearly lost the bubble here.  Can someone get me started in 

Re: [boost] boost::filesystem file restrictions

2003-08-15 Thread Beman Dawes
At 01:40 PM 8/14/2003, Peter Dimov wrote:
Beman Dawes wrote:

 The current approach is clearly too restrictive and isn't
 satisfactory. Beyond the problems you mention, there really isn't a
 single standard for portability. Even 8.3 names aren't portable to
 systems which don't allow periods in names. A whole family of
 checkers is needed, giving various degrees of portability. Some
 should be supplied with the library, but users also need to be able
 to provide their own.

 OTOH, a function that has to be explicitly called isn't going to be
 effective. Manual checking is too laborious in code that does a lot
 of path manipulation. A one time I took several pages of code and
 tried to add explicit checks. The code turned into a mess. Manual
 checking is also
 likely to be ignored by the very programmers who need it the most;
 those
 who have firm but erroneous ideas about what is or isn't portable.

I am not sure that it should be the responsibility of the path class to
enforce some notion of portability. Wouldn't it be more appropriate to
defer the portability check, if any, to the point where the path is
actually used in a filesystem operation?
That's too late. A real path is often made up of some native elements 
(which the portability check doesn't apply to) and some portable elements 
(which the portability check should be applied to).

The earlier the error can be detected, the better. Also, a path is only 
constructed once, but may be use multiple times.

Because it is an invariant that any fully constructed path has already been 
error checked (and operations like appends in effect construct their 
argument first if necessary to guarantee the invariant), lots of other code 
doesn't have to worry about error detection.

I'm very comfortable with applying the error check a construction time (or 
equivalent for rhs arguments), and not applying it at all for native paths. 
What I'm having trouble which is the mechanism for selecting the particular 
error function to apply.

That would be easy if we accepted the native platform as the default, and 
portable cases had to be specially coded. But my interest is in portable 
semantics as the default.

--Beman

--Beman

--Beman

___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] boost::filesystem file restrictions

2003-08-15 Thread Peter Dimov
Beman Dawes wrote:
 At 01:40 PM 8/14/2003, Peter Dimov wrote:
  
  I am not sure that it should be the responsibility of the path
  class to enforce some notion of portability. Wouldn't it be more
  appropriate to defer the portability check, if any, to the point
  where the path is actually used in a filesystem operation?

 That's too late. A real path is often made up of some native elements
 (which the portability check doesn't apply to) and some portable
 elements (which the portability check should be applied to).

 The earlier the error can be detected, the better. Also, a path is
 only constructed once, but may be use multiple times.

[...]

 That would be easy if we accepted the native platform as the default,
 and portable cases had to be specially coded. But my interest is in
 portable semantics as the default.

I must be missing something. What is a portable path useful for? A
portable path _grammar_ (element sequence separated by '/') is certainly
useful, it allows me to write portable _code_ that deals with paths.
Portable path _data_ is a different story.

___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] boost::filesystem file restrictions

2003-08-14 Thread Peter Dimov
Beman Dawes wrote:

 The current approach is clearly too restrictive and isn't
 satisfactory. Beyond the problems you mention, there really isn't a
 single standard for portability. Even 8.3 names aren't portable to
 systems which don't allow periods in names. A whole family of
 checkers is needed, giving various degrees of portability. Some
 should be supplied with the library, but users also need to be able
 to provide their own.

 OTOH, a function that has to be explicitly called isn't going to be
 effective. Manual checking is too laborious in code that does a lot
 of path manipulation. A one time I took several pages of code and
 tried to add explicit checks. The code turned into a mess. Manual
 checking is also
 likely to be ignored by the very programmers who need it the most;
 those
 who have firm but erroneous ideas about what is or isn't portable.

I am not sure that it should be the responsibility of the path class to
enforce some notion of portability. Wouldn't it be more appropriate to defer
the portability check, if any, to the point where the path is actually used
in a filesystem operation?

___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


RE: [boost] boost::filesystem file restrictions

2003-08-14 Thread Michael van der Westhuizen

-Original Message-
From: Beman Dawes [mailto:[EMAIL PROTECTED]
Sent: 14 August 2003 04:56
To: Boost mailing list; [EMAIL PROTECTED]
Subject: Re: [boost] boost::filesystem file restrictions


At 06:03 AM 8/14/2003, Walter Landry wrote:

 I've started using boost::filesystem recently, and I'm mostly very
 happy.

 Wow! A very happy user. Or at least mostly very happy. That's good news:-)

 Seriously, it is a powerful motivator to get that kind of feedback.

Well, here's another happy user :-)

-- snip --

 I'm curious to hear what others would think of the above scheme.

Oddly enough I had a similar thought halfway through reading your 
mail - by the time I got to your proposal all I could think was yes.

As for the stack/heap question... I don't believe there is a way to
portably and reliably tell how memory was allocated (please correct me
if I'm wrong - code would be most welcome!).

Michael
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] boost::filesystem file restrictions

2003-08-14 Thread Beman Dawes
At 06:03 AM 8/14/2003, Walter Landry wrote:

Greetings,

I've started using boost::filesystem recently, and I'm mostly very
happy.
Wow! A very happy user. Or at least mostly very happy. That's good news:-) 
Seriously, it is a powerful motivator to get that kind of feedback.

  One thing bothers me, though.  Why does it implement any
restrictions, by default, on what kind of files it allows?
See below.

...
I also noticed that you can't open a directory named . or ..,
though I think ./ and ../ both work.
Hum... I'm not sure that is currently intended.

  Files starting or ending with spaces also don't work.

That is intended, although it may change if the portability checking scheme 
changes.


I understand that I can (painfully) work around it by using a
different context, but I don't understand why boost::filesystem wants
to restrict me to a set of filenames that are portable.  Isn't that a
bit too much handholding?  I don't mind having an is_portable()
command or something similar, but it is incredibly annoying to have to
abide by someone else's filename restrictions.
The current approach is clearly too restrictive and isn't satisfactory. 
Beyond the problems you mention, there really isn't a single standard for 
portability. Even 8.3 names aren't portable to systems which don't allow 
periods in names. A whole family of checkers is needed, giving various 
degrees of portability. Some should be supplied with the library, but users 
also need to be able to provide their own.

OTOH, a function that has to be explicitly called isn't going to be 
effective. Manual checking is too laborious in code that does a lot of path 
manipulation. A one time I took several pages of code and tried to add 
explicit checks. The code turned into a mess. Manual checking is also 
likely to be ignored by the very programmers who need it the most; those 
who have firm but erroneous ideas about what is or isn't portable.

So it comes down to an interface problem. What is the best way for the user 
specify a portability checking function to override the default checking 
function?

It would be trivial to add an additional path constructor that takes a 
checking function or function object.

But that would kill ease-of-use. It is one thing to require an additional 
constructor argument in the fairly limited use native case, but the 
portability checking is applied to each and every path object constructed, 
including the many path temporaries created by the automatic conversions 
from char * and string.

(That kill ease-of-use point might be hard to understand if you haven't 
actually written code using the library. The automatic conversions really 
do allow script-like programming ease, and are reasonably safe given the 
conversion result is class path.)

Also, the portability checking policy often needs to propagate to called 
functions such as third party liberties. Adding overloads of functions to 
take an additional argument is also too messy, and doesn't provide for 
automatic pass-through to lower level functions. In most (but not all) 
programs it really would be convenient if portability checking policy was a 
global. But of course we all know that global variables are consider 
harmful. There are also several valid use cases where a program needs to 
switch back and forth between portability policies.

Another approach is to provide a way to tell class path that within a file 
scope use a policy other than the default. It would have to be carefully 
worked out to avoid ODR violations, and to ensure propagation to called 
library functions. I have not been able to come up with a workable version 
of this approach.

That was about as far as my thinking had gotten in the past. While 
composing this reply, I came up with another possible solution. Let's say 
boost/filesystem/path.hpp added this:

   typedef bool (*is_portable_test)( string  candidate );

   class scoped_portability_policy : noncopyable
   {
   public:
 explicit scoped_portabiity_policy( is_portable_test f );
 ~scoped_portabiity_policy();
};
The effect of constructing a scoped_portability_policy is to push p onto a 
stack. The destructor pops the stack. Class path uses the top stack entry 
as the current portability checker. The stack is initialized with a default 
portability checker.

Most programs which wanted a policy other than the default would just being 
something like this:

  int main()
  {
 scoped_portability_policy( posix_portability_check );
 ...
Although the stack is global, when coupled with scoped_portability_policy, 
it is safer than a single global variable (because library functions which 
push are guaranteed to pop.)

Of course it can be subverted by static or heap allocation. (Aside: Is 
there a reliable way to prevent static or heap allocation?)

I'm curious to hear what others would think of the above scheme.

--Beman

___
Unsubscribe  other changes: