]> git.lyx.org Git - lyx.git/blob - boost/boost/filesystem/path.hpp
boost::filesystem added
[lyx.git] / boost / boost / filesystem / path.hpp
1 //  boost/filesystem/path.hpp  -----------------------------------------------//
2
3 //  (C) Copyright Beman Dawes 2002. Permission to copy, use, modify, sell and
4 //  distribute this software is granted provided this copyright notice appears
5 //  in all copies. This software is provided "as is" without express or implied
6 //  warranty, and with no claim as to its suitability for any purpose.
7
8
9 //  See http://www.boost.org/libs/filesystem for documentation.
10
11 //----------------------------------------------------------------------------// 
12
13 #ifndef BOOST_FILESYSTEM_PATH_HPP
14 #define BOOST_FILESYSTEM_PATH_HPP
15
16 #include <boost/iterator_adaptors.hpp>
17 #include <string>
18 #include <cassert>
19
20 //----------------------------------------------------------------------------//
21
22 namespace boost
23 {
24   namespace filesystem
25   {
26     class path;
27
28     namespace detail
29     {
30       struct path_itr_imp
31       {
32         std::string             name;     // cache current element.
33         const path *            path_ptr; // path being iterated over.
34         std::string::size_type  pos;      // position of name in
35                                           // path_ptr->string(). The
36                                           // end() iterator is indicated by 
37                                           // pos == path_ptr->string().size()
38
39         const std::string & operator*() const { return name; }
40         void operator++();
41         void operator--();
42         bool operator==( const path_itr_imp & rhs ) const
43           { return path_ptr == rhs.path_ptr && pos == rhs.pos; }
44       };
45     } // detail
46
47     enum path_format { native }; // ugly enough to discourage use
48                                  // except when actually needed
49
50   //  path -------------------------------------------------------------------//
51
52     class path
53     {
54     public:
55       // compiler generates copy constructor, copy assignment, and destructor
56
57       path(){}
58
59       path( const std::string & src );
60       path( const char * src );
61
62       path( const std::string & src, path_format );
63       path( const char * src, path_format );
64
65       // append operations:
66       path & operator /=( const path & rhs );
67       path operator /( const path & rhs ) const
68         { return path( *this ) /= rhs; }
69
70       // conversion functions:
71       const std::string & string() const { return m_path; }
72       std::string native_file_string() const;
73       std::string native_directory_string() const;
74
75       // decomposition functions:
76       path         root_path() const;
77       std::string  root_name() const;
78       std::string  root_directory() const;
79       path         relative_path() const;
80       std::string  leaf() const;
81       path         branch_path() const;
82
83       // query functions:
84       bool empty() const { return m_path.empty(); } // name consistent with std containers
85
86       bool is_complete() const;
87
88       bool has_root_path() const;
89       bool has_root_name() const;
90       bool has_root_directory() const;
91       bool has_relative_path() const;
92       bool has_leaf() const { return !m_path.empty(); }
93       bool has_branch_path() const;
94
95       // iteration over the names in the path:
96       typedef boost::iterator_adaptor<
97         detail::path_itr_imp,
98         boost::default_iterator_policies,
99         std::string,
100         const std::string &,
101         const std::string *,
102         std::bidirectional_iterator_tag,
103         std::ptrdiff_t 
104         > iterator;
105
106       iterator begin() const;
107       iterator end() const
108       {
109         iterator itr;
110         itr.base().path_ptr = this;
111         itr.base().pos = m_path.size();
112         return itr;
113       }
114
115     private:
116       // Note: This is an implementation for POSIX and Windows, where there
117       // are only minor differences between generic and system-specific
118       // constructor input formats.  Private members might be quite different
119       // in other implementations, particularly where there were wide
120       // differences between generic and system-specific argument formats,
121       // or between native_file_string() and native_directory_string() formats.
122
123       std::string  m_path;
124
125       friend class directory_iterator;
126       friend struct boost::filesystem::detail::path_itr_imp;
127
128       enum source_context { generic, platform, nocheck };
129
130       void m_path_append( const std::string & src,
131         source_context context = generic );
132
133     public: // should be private, but friend functions don't work for me
134       void m_replace_leaf( const char * new_leaf );
135     };
136
137   //  path non-member functions  ---------------------------------------------//
138
139     inline path operator / ( const char * lhs, const path & rhs )
140       { return path( lhs ) /= rhs; }
141
142     inline path operator / ( const std::string & lhs, const path & rhs )
143       { return path( lhs ) /= rhs; }
144    
145   //  error checking  --------------------------------------------------------//
146
147 // TODO: write a program that probes valid file and directory names.  Ask
148 // Boost people to report results from many operating systems.  Use results
149 // to adjust generic_name().
150
151     //  generic_name() is extremely permissive; its intent is not to ensure
152     //  general portablity, but rather to detect names so trouble-prone that
153     //  they likely represent coding errors or gross misconceptions.
154     //
155     //  Any characters are allowed except:
156     //
157     //     Those characters < ' ', including '\0'. These are the so-called
158     //     control characters, in both ASCII (and its decendents) and EBCDIC.
159     //     Hard to imagine how these could be useful in a generic path name.
160     //
161     //     < > : " / \ | * ?  These have special meaning to enough operating
162     //     systems that use in a generic name would be a serious problem.
163     //
164     //  The names "." and ".." are not allowed.
165     //  An empty name (null string) is not allowed.
166     //  Names beginning or ending with spaces are not allowed.
167     //
168     bool generic_name( const std::string & name ); 
169
170     //  posix_name() is based on POSIX (IEEE Std 1003.1-2001)
171     //  "Portable Filename Character Set" rules.
172     //  http://www.opengroup.org/onlinepubs/007904975/basedefs/xbd_chap03.html
173     //
174     //  That character set only allows 0-9, a-z, A-Z, '.', '_', and '-'.
175     //  Note that such names are also portable to other popular operating
176     //  systems, such as Windows.
177     //
178     bool posix_name( const std::string & name );
179
180     const path & check_posix_leaf( const path & ph );
181     //  Throws: if !posix_name( ph.leaf() )
182     //  Returns: ph
183     //  Note: Although useful in its own right, check_posix_leaf() also serves
184     //  as an example.  A user might provide similar functions; behavior might
185     //  be to assert or warn rather than throw. A user provided function
186     //  could also check the entire path instead of just the leaf; a leaf
187     //  check is often, but not always, the required behavior.
188     //  Rationale: For the "const path &" rather than "void" return is to
189     //  allow (and encourage portability checking) uses like:
190     //      create_directory( check_posix_leaf( "foo" ) );
191     //  While there is some chance of misuse (by passing through a reference
192     //  to a temporary), the benefits outweigh the costs.
193
194     //  For Boost, we often tighten name restrictions for maximum portability:
195     //
196     //    * The portable POSIX character restrictions, plus
197     //    * Maximum name length 31 characters (for Classic Mac OS).
198     //    * Lowercase only (so code written on case-insensitive platforms like
199     //      Windows works properly when used on case-sensitive systems like
200     //      POSIX.
201     //    * Directory names do not contain '.', as this is not a valid character
202     //      for directory names on some systems.
203     //
204     //  TODO: provide some check_boost_xxx functions once error handling
205     //  approach ratified.
206
207     bool boost_file_name( const std::string & name );
208     bool boost_directory_name( const std::string & name );
209
210   } // namespace filesystem
211 } // namespace boost
212
213 #endif // BOOST_FILESYSTEM_PATH_HPP