+2004-01-08 Lars Gullik Bjonnes <larsbj@gullik.net>
+
+ * configure.ac (AC_CONFIG_FILES): add boost::filesystem Makefiles.
+
2003-12-15 Ronald Florence <ron@18james.com>
* README.MacOSX: updated for 1.4.0cvs
-
+
2003-11-18 Angus Leeming <leeming@lyx.org>
* autogen.sh: accept autoconf 2.58 as a supported version.
-
+
2003-10-24 André Pönitz <poenitz@gmx.net>
* lyxfunc.C:
* INSTALL: remove a comment about --with-included-string
* configure.ac: remove the configure are
- --with-included-string
+ --with-included-string
2003-09-21 Lars Gullik Bjønnes <larsbj@gullik.net>
+2004-01-08 Lars Gullik Bjonnes <larsbj@gullik.net>
+
+ * add boost::filesystem.
+
2003-10-23 Lars Gullik Bjønnes <larsbj@gullik.net>
* libs/regex/src/cpp_regex_traits.cpp (seekpos): use correct
--- /dev/null
+// boost/filesystem/convenience.hpp ----------------------------------------//
+
+// (C) Copyright Beman Dawes, 2002
+// (C) Copyright Vladimir Prus, 2002
+// Permission to copy, use, modify, sell and distribute this software
+// is granted provided this copyright notice appears in all copies.
+// This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+
+
+// See http://www.boost.org/libs/filesystem for documentation.
+
+//----------------------------------------------------------------------------//
+
+#ifndef BOOST_FILESYSTEM_CONVENIENCE_HPP
+#define BOOST_FILESYSTEM_CONVENIENCE_HPP
+
+#include <boost/filesystem/path.hpp>
+#include <boost/filesystem/operations.hpp>
+
+namespace boost
+{
+ namespace filesystem
+ {
+
+// create_directories (contributed by Vladimir Prus) -----------------------//
+
+
+ /** Creates directory 'ph' and all necessary parent directories.
+ @post exists(directory_ph) && is_directory(directory_ph) && is_empty(directory_ph)
+ */
+ void create_directories(const path& ph);
+
+ } // namespace filesystem
+} // namespace boost
+#endif // BOOST_FILESYSTEM_CONVENIENCE_HPP
+
+
--- /dev/null
+// boost/filesystem/exception.hpp ------------------------------------------//
+
+// < ----------------------------------------------------------------------- >
+// < Copyright © 2002 Beman Dawes >
+// < Copyright © 2001 Dietmar Kühl, All Rights Reserved >
+// < >
+// < Permission to use, copy, modify, distribute and sell this >
+// < software for any purpose is hereby granted without fee, provided >
+// < that the above copyright notice appears in all copies and that >
+// < both that copyright notice and this permission notice appear in >
+// < supporting documentation. The authors make no representations about >
+// < the suitability of this software for any purpose. It is provided >
+// < "as is" without express or implied warranty. >
+// < ----------------------------------------------------------------------- >
+
+// See http://www.boost.org/libs/filesystem for documentation.
+
+//----------------------------------------------------------------------------//
+
+#ifndef BOOST_FILESYSTEM_EXCEPTION_HPP
+#define BOOST_FILESYSTEM_EXCEPTION_HPP
+
+#include <boost/filesystem/path.hpp>
+
+#include <string>
+#include <stdexcept>
+
+//----------------------------------------------------------------------------//
+
+namespace boost
+{
+ namespace filesystem
+ {
+ namespace detail
+ {
+ int system_error_code(); // artifact of POSIX and WINDOWS error reporting
+ }
+
+ enum error_code
+ {
+ no_error = 0,
+ system_error, // system generated error; if possible, is translated
+ // to one of the more specific errors below.
+ other_error, // library generated error
+ security_error, // includes access rights, permissions failures
+ read_only_error,
+ io_error,
+ path_error,
+ not_found_error,
+ not_directory_error,
+ busy_error, // implies trying again might succeed
+ already_exists_error,
+ not_empty_error,
+ is_directory_error,
+ out_of_space_error,
+ out_of_memory_error,
+ out_of_resource_error
+ };
+
+
+ class filesystem_error : public std::runtime_error
+ {
+ public:
+
+ filesystem_error(
+ const std::string & who,
+ const std::string & message ); // assumed to be error_code::other_error
+
+ filesystem_error(
+ const std::string & who,
+ const path & path1,
+ const std::string & message ); // assumed to be error_code::other_error
+
+ filesystem_error(
+ const std::string & who,
+ const path & path1,
+ int sys_err_code );
+
+ filesystem_error(
+ const std::string & who,
+ const path & path1,
+ const path & path2,
+ int sys_err_code );
+
+ ~filesystem_error() throw();
+
+ int native_error() const { return m_sys_err; }
+ // Note: a value of 0 implies a library (rather than system) error
+ error_code error() const { return m_err; }
+ const std::string & who() const; // name of who throwing exception
+ const path & path1() const; // argument 1 to who; may be empty()
+ const path & path2() const; // argument 2 to who; may be empty()
+
+ private:
+ int m_sys_err;
+ error_code m_err;
+ std::string m_who;
+ path m_path1;
+ path m_path2;
+ };
+
+ } // namespace filesystem
+} // namespace boost
+
+#endif // BOOST_FILESYSTEM_EXCEPTION_HPP
--- /dev/null
+// boost/filesystem/fstream.hpp --------------------------------------------//
+
+// (C) Copyright Beman Dawes 2002. Permission to copy, use, modify, sell and
+// distribute this software is granted provided this copyright notice appears
+// in all copies. This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+
+// See http://www.boost.org/libs/filesystem for documentation.
+
+//----------------------------------------------------------------------------//
+
+#ifndef BOOST_FILESYSTEM_FSTREAM_HPP
+#define BOOST_FILESYSTEM_FSTREAM_HPP
+
+#include <boost/filesystem/path.hpp>
+
+#include <iosfwd>
+#include <fstream>
+
+namespace boost
+{
+ namespace filesystem
+ {
+ template < class charT, class traits = std::char_traits<charT> >
+ class basic_filebuf : public std::basic_filebuf<charT,traits>
+ {
+ public:
+ virtual ~basic_filebuf() {}
+
+#if !defined(BOOST_MSVC) || BOOST_MSVC > 1200 // VC++ 6.0 can't handle this
+ std::basic_filebuf<charT,traits> * open( const path & file_ph,
+ std::ios_base::openmode mode )
+ {
+ return std::basic_filebuf<charT,traits>::open(
+ file_ph.native_file_string().c_str(), mode );
+ }
+#endif
+ };
+
+ typedef basic_filebuf<char> filebuf;
+# ifndef BOOST_NO_STD_WSTRING
+ typedef basic_filebuf<wchar_t> wfilebuf;
+# endif
+
+ template < class charT, class traits = std::char_traits<charT> >
+ class basic_ifstream : public std::basic_ifstream<charT,traits>
+ {
+ public:
+ basic_ifstream() {}
+ explicit basic_ifstream( const path & file_ph,
+ std::ios_base::openmode mode = std::ios_base::in )
+ : std::basic_ifstream<charT,traits>(
+ file_ph.native_file_string().c_str(), mode ) {}
+ virtual ~basic_ifstream() {}
+#if !defined(BOOST_MSVC) || BOOST_MSVC > 1200 // VC++ 6.0 can't handle this
+ void open( const path & file_ph,
+ std::ios_base::openmode mode = std::ios_base::in )
+ {
+ std::basic_ifstream<charT,traits>::open(
+ file_ph.native_file_string().c_str(), mode );
+ }
+#endif
+ };
+
+ typedef basic_ifstream<char> ifstream;
+# ifndef BOOST_NO_STD_WSTRING
+ typedef basic_ifstream<wchar_t> wifstream;
+# endif
+
+ template < class charT, class traits = std::char_traits<charT> >
+ class basic_ofstream : public std::basic_ofstream<charT,traits>
+ {
+ public:
+ basic_ofstream() {}
+ explicit basic_ofstream( const path & file_ph,
+ std::ios_base::openmode mode = std::ios_base::out )
+ : std::basic_ofstream<charT,traits>(
+ file_ph.native_file_string().c_str(), mode ) {}
+ virtual ~basic_ofstream() {}
+#if !defined(BOOST_MSVC) || BOOST_MSVC > 1200 // VC++ 6.0 can't handle this
+ void open( const path & file_ph,
+ std::ios_base::openmode mode = std::ios_base::out )
+ {
+ std::basic_ofstream<charT,traits>::open(
+ file_ph.native_file_string().c_str(), mode );
+ }
+#endif
+ };
+
+ typedef basic_ofstream<char> ofstream;
+# ifndef BOOST_NO_STD_WSTRING
+ typedef basic_ofstream<wchar_t> wofstream;
+# endif
+
+ template < class charT, class traits = std::char_traits<charT> >
+ class basic_fstream : public std::basic_fstream<charT,traits>
+ {
+ public:
+ basic_fstream() {}
+ explicit basic_fstream( const path & file_ph,
+ std::ios_base::openmode mode = std::ios_base::in|std::ios_base::out )
+ : std::basic_fstream<charT,traits>(
+ file_ph.native_file_string().c_str(), mode ) {}
+ virtual ~basic_fstream() {}
+#if !defined(BOOST_MSVC) || BOOST_MSVC > 1200 // VC++ 6.0 can't handle this
+ void open( const path & file_ph,
+ std::ios_base::openmode mode = std::ios_base::in|std::ios_base::out )
+ {
+ std::basic_fstream<charT,traits>::open(
+ file_ph.native_file_string().c_str(), mode );
+ }
+#endif
+ };
+
+ typedef basic_fstream<char> fstream;
+# ifndef BOOST_NO_STD_WSTRING
+ typedef basic_fstream<wchar_t> wfstream;
+# endif
+ } // namespace filesystem
+
+} // namespace boost
+
+#endif // BOOST_FILESYSTEM_FSTREAM_HPP
+
--- /dev/null
+// boost/filesystem/directory.hpp ------------------------------------------//
+
+// < ----------------------------------------------------------------------- >
+// < Copyright © 2002 Beman Dawes. >
+// < Copyright © 2002 Jan Langer. >
+// < Copyright © 2001 Dietmar Kühl, All Rights Reserved >
+// < >
+// < Permission to use, copy, modify, distribute and sell this >
+// < software for any purpose is hereby granted without fee, provided >
+// < that the above copyright notice appears in all copies and that >
+// < both that copyright notice and this permission notice appear in >
+// < supporting documentation. The authors make no representations about >
+// < the suitability of this software for any purpose. It is provided >
+// < "as is" without express or implied warranty. >
+// < ----------------------------------------------------------------------- >
+
+// See http://www.boost.org/libs/filesystem for documentation.
+
+//----------------------------------------------------------------------------//
+
+#ifndef BOOST_FILESYSTEM_DIRECTORY_HPP
+#define BOOST_FILESYSTEM_DIRECTORY_HPP
+
+#include <boost/config.hpp>
+#include <boost/filesystem/path.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/iterator.hpp>
+
+#include <string>
+
+//----------------------------------------------------------------------------//
+
+namespace boost
+{
+ namespace filesystem
+ {
+
+// query functions ---------------------------------------------------------//
+
+ bool exists( const path & ph );
+
+ bool is_directory( const path & ph );
+
+ // VC++ 7.0 and earlier has a serious namespace bug that causes a clash
+ // between boost::filesystem::is_empty and the unrelated type trait
+ // boost::is_empty. The workaround for those who must use broken versions
+ // of VC++ is to use the function _is_empty. All others should use the
+ // correct is_empty name.
+ bool _is_empty( const path & ph ); // deprecated
+
+# if !defined( BOOST_MSVC ) || BOOST_MSVC > 1300
+ inline bool is_empty( const path & ph ) { return _is_empty( ph ); }
+# endif
+
+// operations --------------------------------------------------------------//
+
+ void create_directory( const path & directory_ph );
+
+ bool remove( const path & ph );
+ unsigned long remove_all( const path & ph );
+
+ void rename( const path & from_path,
+ const path & to_path );
+
+ void copy_file( const path & from_file_ph,
+ const path & to_file_ph );
+
+ path current_path();
+ const path & initial_path();
+
+ path system_complete( const path & ph );
+ path complete( const path & ph, const path & base = initial_path() );
+
+// directory_iterator ------------------------------------------------------//
+
+ class directory_iterator
+ : public boost::iterator< std::input_iterator_tag,
+ path, std::ptrdiff_t, const path *, const path & >
+ {
+ private:
+ typedef directory_iterator self;
+ public:
+ directory_iterator(); // creates the "end" iterator
+ explicit directory_iterator( const path & p );
+
+ reference operator*() const { return m_deref(); }
+ pointer operator->() const { return &m_deref(); }
+ self & operator++() { m_inc(); return *this; }
+
+ friend bool operator==( const self & x, const self & y )
+ { return x.m_imp == y.m_imp; }
+ friend bool operator!=( const self & x, const self & y )
+ { return !(x.m_imp == y.m_imp); }
+
+ struct path_proxy // allows *i++ to work, as required by std
+ {
+ path pv;
+ explicit path_proxy( const path & p ) : pv(p) {}
+ path operator*() const { return pv; }
+ };
+
+ path_proxy operator++(int)
+ {
+ path_proxy pp( m_deref() );
+ ++*this;
+ return pp;
+ }
+
+ private:
+ class dir_itr_imp;
+ // shared_ptr provides shallow-copy semantics required for InputIterators
+ typedef boost::shared_ptr< dir_itr_imp > m_imp_ptr;
+ m_imp_ptr m_imp;
+ reference m_deref() const;
+ void m_inc();
+ };
+
+ } // namespace filesystem
+} // namespace boost
+
+#endif // BOOST_FILESYSTEM_DIRECTORY_HPP
--- /dev/null
+// boost/filesystem/path.hpp -----------------------------------------------//
+
+// (C) Copyright Beman Dawes 2002. Permission to copy, use, modify, sell and
+// distribute this software is granted provided this copyright notice appears
+// in all copies. This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+
+
+// See http://www.boost.org/libs/filesystem for documentation.
+
+//----------------------------------------------------------------------------//
+
+#ifndef BOOST_FILESYSTEM_PATH_HPP
+#define BOOST_FILESYSTEM_PATH_HPP
+
+#include <boost/iterator_adaptors.hpp>
+#include <string>
+#include <cassert>
+
+//----------------------------------------------------------------------------//
+
+namespace boost
+{
+ namespace filesystem
+ {
+ class path;
+
+ namespace detail
+ {
+ struct path_itr_imp
+ {
+ std::string name; // cache current element.
+ const path * path_ptr; // path being iterated over.
+ std::string::size_type pos; // position of name in
+ // path_ptr->string(). The
+ // end() iterator is indicated by
+ // pos == path_ptr->string().size()
+
+ const std::string & operator*() const { return name; }
+ void operator++();
+ void operator--();
+ bool operator==( const path_itr_imp & rhs ) const
+ { return path_ptr == rhs.path_ptr && pos == rhs.pos; }
+ };
+ } // detail
+
+ enum path_format { native }; // ugly enough to discourage use
+ // except when actually needed
+
+ // path -------------------------------------------------------------------//
+
+ class path
+ {
+ public:
+ // compiler generates copy constructor, copy assignment, and destructor
+
+ path(){}
+
+ path( const std::string & src );
+ path( const char * src );
+
+ path( const std::string & src, path_format );
+ path( const char * src, path_format );
+
+ // append operations:
+ path & operator /=( const path & rhs );
+ path operator /( const path & rhs ) const
+ { return path( *this ) /= rhs; }
+
+ // conversion functions:
+ const std::string & string() const { return m_path; }
+ std::string native_file_string() const;
+ std::string native_directory_string() const;
+
+ // decomposition functions:
+ path root_path() const;
+ std::string root_name() const;
+ std::string root_directory() const;
+ path relative_path() const;
+ std::string leaf() const;
+ path branch_path() const;
+
+ // query functions:
+ bool empty() const { return m_path.empty(); } // name consistent with std containers
+
+ bool is_complete() const;
+
+ bool has_root_path() const;
+ bool has_root_name() const;
+ bool has_root_directory() const;
+ bool has_relative_path() const;
+ bool has_leaf() const { return !m_path.empty(); }
+ bool has_branch_path() const;
+
+ // iteration over the names in the path:
+ typedef boost::iterator_adaptor<
+ detail::path_itr_imp,
+ boost::default_iterator_policies,
+ std::string,
+ const std::string &,
+ const std::string *,
+ std::bidirectional_iterator_tag,
+ std::ptrdiff_t
+ > iterator;
+
+ iterator begin() const;
+ iterator end() const
+ {
+ iterator itr;
+ itr.base().path_ptr = this;
+ itr.base().pos = m_path.size();
+ return itr;
+ }
+
+ private:
+ // Note: This is an implementation for POSIX and Windows, where there
+ // are only minor differences between generic and system-specific
+ // constructor input formats. Private members might be quite different
+ // in other implementations, particularly where there were wide
+ // differences between generic and system-specific argument formats,
+ // or between native_file_string() and native_directory_string() formats.
+
+ std::string m_path;
+
+ friend class directory_iterator;
+ friend struct boost::filesystem::detail::path_itr_imp;
+
+ enum source_context { generic, platform, nocheck };
+
+ void m_path_append( const std::string & src,
+ source_context context = generic );
+
+ public: // should be private, but friend functions don't work for me
+ void m_replace_leaf( const char * new_leaf );
+ };
+
+ // path non-member functions ---------------------------------------------//
+
+ inline path operator / ( const char * lhs, const path & rhs )
+ { return path( lhs ) /= rhs; }
+
+ inline path operator / ( const std::string & lhs, const path & rhs )
+ { return path( lhs ) /= rhs; }
+
+ // error checking --------------------------------------------------------//
+
+// TODO: write a program that probes valid file and directory names. Ask
+// Boost people to report results from many operating systems. Use results
+// to adjust generic_name().
+
+ // generic_name() is extremely permissive; its intent is not to ensure
+ // general portablity, but rather to detect names so trouble-prone that
+ // they likely represent coding errors or gross misconceptions.
+ //
+ // Any characters are allowed except:
+ //
+ // Those characters < ' ', including '\0'. These are the so-called
+ // control characters, in both ASCII (and its decendents) and EBCDIC.
+ // Hard to imagine how these could be useful in a generic path name.
+ //
+ // < > : " / \ | * ? These have special meaning to enough operating
+ // systems that use in a generic name would be a serious problem.
+ //
+ // The names "." and ".." are not allowed.
+ // An empty name (null string) is not allowed.
+ // Names beginning or ending with spaces are not allowed.
+ //
+ bool generic_name( const std::string & name );
+
+ // posix_name() is based on POSIX (IEEE Std 1003.1-2001)
+ // "Portable Filename Character Set" rules.
+ // http://www.opengroup.org/onlinepubs/007904975/basedefs/xbd_chap03.html
+ //
+ // That character set only allows 0-9, a-z, A-Z, '.', '_', and '-'.
+ // Note that such names are also portable to other popular operating
+ // systems, such as Windows.
+ //
+ bool posix_name( const std::string & name );
+
+ const path & check_posix_leaf( const path & ph );
+ // Throws: if !posix_name( ph.leaf() )
+ // Returns: ph
+ // Note: Although useful in its own right, check_posix_leaf() also serves
+ // as an example. A user might provide similar functions; behavior might
+ // be to assert or warn rather than throw. A user provided function
+ // could also check the entire path instead of just the leaf; a leaf
+ // check is often, but not always, the required behavior.
+ // Rationale: For the "const path &" rather than "void" return is to
+ // allow (and encourage portability checking) uses like:
+ // create_directory( check_posix_leaf( "foo" ) );
+ // While there is some chance of misuse (by passing through a reference
+ // to a temporary), the benefits outweigh the costs.
+
+ // For Boost, we often tighten name restrictions for maximum portability:
+ //
+ // * The portable POSIX character restrictions, plus
+ // * Maximum name length 31 characters (for Classic Mac OS).
+ // * Lowercase only (so code written on case-insensitive platforms like
+ // Windows works properly when used on case-sensitive systems like
+ // POSIX.
+ // * Directory names do not contain '.', as this is not a valid character
+ // for directory names on some systems.
+ //
+ // TODO: provide some check_boost_xxx functions once error handling
+ // approach ratified.
+
+ bool boost_file_name( const std::string & name );
+ bool boost_directory_name( const std::string & name );
+
+ } // namespace filesystem
+} // namespace boost
+
+#endif // BOOST_FILESYSTEM_PATH_HPP
include $(top_srcdir)/config/common.am
-SUBDIRS = regex signals
+SUBDIRS = filesystem regex signals
--- /dev/null
+Makefile
+Makefile.in
--- /dev/null
+include $(top_srcdir)/config/common.am
+
+SUBDIRS = src
+
--- /dev/null
+Makefile
+Makefile.in
+libboostfilesystem.la
+*.lo
+.libs
+.deps
--- /dev/null
+include $(top_srcdir)/config/common.am
+
+noinst_LTLIBRARIES = libboostfilesystem.la
+
+INCLUDES = $(BOOST_INCLUDES)
+
+libboostfilesystem_la_SOURCES = \
+ convenience.cpp \
+ exception.cpp \
+ Makefile.am \
+ operations_posix_windows.cpp \
+ path_posix_windows.cpp
+
--- /dev/null
+// libs/filesystem/src/convenience.cpp -------------------------------------//
+
+// (C) Copyright Beman Dawes, 2002
+// (C) Copyright Vladimir Prus, 2002
+// Permission to copy, use, modify, sell and distribute this software
+// is granted provided this copyright notice appears in all copies.
+// This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+
+// See http://www.boost.org/libs/filesystem for documentation.
+
+#include <boost/filesystem/convenience.hpp>
+
+namespace boost
+{
+ namespace filesystem
+ {
+
+// create_directories (contributed by Vladimir Prus) -----------------------//
+
+ void create_directories(const path& ph)
+ {
+ if (ph.empty() || exists(ph)) return;
+
+ // First create branch, by calling ourself recursively
+ create_directories(ph.branch_path());
+ // Now that parent's path exists, create the directory
+ create_directory(ph);
+ }
+
+ } // namespace filesystem
+} // namespace boost
--- /dev/null
+// Exception implementation file -------------------------------------------//
+
+// < ----------------------------------------------------------------------- >
+// < Copyright © 2002 Beman Dawes >
+// < Copyright © 2001 Dietmar Kühl, All Rights Reserved >
+// < >
+// < Permission to use, copy, modify, distribute and sell this >
+// < software for any purpose is hereby granted without fee, provided >
+// < that the above copyright notice appears in all copies and that >
+// < both that copyright notice and this permission notice appear in >
+// < supporting documentation. The authors make no representations about >
+// < the suitability of this software for any purpose. It is provided >
+// < "as is" without express or implied warranty. >
+// < ----------------------------------------------------------------------- >
+
+// See http://www.boost.org/libs/filesystem for documentation.
+
+//----------------------------------------------------------------------------//
+
+#include <boost/config.hpp>
+#include <boost/filesystem/exception.hpp>
+
+namespace fs = boost::filesystem;
+
+#include <cstring> // SGI MIPSpro compilers need this
+#include <string>
+
+# ifdef BOOST_NO_STDC_NAMESPACE
+ namespace std { using ::strerror; }
+# endif
+
+// BOOST_POSIX or BOOST_WINDOWS specify which API to use.
+# if !defined( BOOST_WINDOWS ) && !defined( BOOST_POSIX )
+# if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__)
+# define BOOST_WINDOWS
+# else
+# define BOOST_POSIX
+# endif
+# endif
+
+# if defined( BOOST_WINDOWS )
+# include "windows.h"
+# else
+# include <errno.h> // for POSIX error codes
+# endif
+
+//----------------------------------------------------------------------------//
+
+namespace
+{
+ std::string system_message( int sys_err_code )
+ {
+ std::string str;
+# ifdef BOOST_WINDOWS
+ LPVOID lpMsgBuf;
+ ::FormatMessageA(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ sys_err_code,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+ (LPSTR) &lpMsgBuf,
+ 0,
+ NULL
+ );
+ str += static_cast<LPCSTR>(lpMsgBuf);
+ ::LocalFree( lpMsgBuf ); // free the buffer
+ while ( str.size()
+ && (str[str.size()-1] == '\n' || str[str.size()-1] == '\r') )
+ str.erase( str.size()-1 );
+# else
+ str += std::strerror( errno );
+# endif
+ return str;
+ }
+
+ struct ec_xlate { int sys_ec; fs::error_code ec; };
+ const ec_xlate ec_table[] =
+ {
+# ifdef BOOST_WINDOWS
+ { ERROR_ACCESS_DENIED, fs::security_error },
+ { ERROR_INVALID_ACCESS, fs::security_error },
+ { ERROR_SHARING_VIOLATION, fs::security_error },
+ { ERROR_LOCK_VIOLATION, fs::security_error },
+ { ERROR_LOCKED, fs::security_error },
+ { ERROR_NOACCESS, fs::security_error },
+ { ERROR_WRITE_PROTECT, fs::read_only_error },
+ { ERROR_NOT_READY, fs::io_error },
+ { ERROR_SEEK, fs::io_error },
+ { ERROR_READ_FAULT, fs::io_error },
+ { ERROR_WRITE_FAULT, fs::io_error },
+ { ERROR_CANTOPEN, fs::io_error },
+ { ERROR_CANTREAD, fs::io_error },
+ { ERROR_CANTWRITE, fs::io_error },
+ { ERROR_DIRECTORY, fs::path_error },
+ { ERROR_INVALID_NAME, fs::path_error },
+ { ERROR_FILE_NOT_FOUND, fs::not_found_error },
+ { ERROR_PATH_NOT_FOUND, fs::not_found_error },
+ { ERROR_DEV_NOT_EXIST, fs::not_found_error },
+ { ERROR_DEVICE_IN_USE, fs::busy_error },
+ { ERROR_OPEN_FILES, fs::busy_error },
+ { ERROR_BUSY_DRIVE, fs::busy_error },
+ { ERROR_BUSY, fs::busy_error },
+ { ERROR_FILE_EXISTS, fs::already_exists_error },
+ { ERROR_ALREADY_EXISTS, fs::already_exists_error },
+ { ERROR_DIR_NOT_EMPTY, fs::not_empty_error },
+ { ERROR_HANDLE_DISK_FULL, fs::out_of_space_error },
+ { ERROR_DISK_FULL, fs::out_of_space_error },
+ { ERROR_OUTOFMEMORY, fs::out_of_memory_error },
+ { ERROR_NOT_ENOUGH_MEMORY, fs::out_of_memory_error },
+ { ERROR_TOO_MANY_OPEN_FILES, fs::out_of_resource_error }
+# else
+ { EACCES, fs::security_error },
+ { EROFS, fs::read_only_error },
+ { EIO, fs::io_error },
+ { ENAMETOOLONG, fs::path_error },
+ { ENOENT, fs::not_found_error },
+ { ENOTDIR, fs::not_directory_error },
+ { EAGAIN, fs::busy_error },
+ { EBUSY, fs::busy_error },
+ { ETXTBSY, fs::busy_error },
+ { EEXIST, fs::already_exists_error },
+ { ENOTEMPTY, fs::not_empty_error },
+ { EISDIR, fs::is_directory_error },
+ { ENOSPC, fs::out_of_space_error },
+ { ENOMEM, fs::out_of_memory_error },
+ { EMFILE, fs::out_of_resource_error }
+# endif
+ };
+
+ fs::error_code lookup_error( int sys_err_code )
+ {
+ for ( const ec_xlate * cur = &ec_table[0];
+ cur != ec_table
+ + sizeof(ec_table)/sizeof(ec_xlate); ++cur )
+ {
+ if ( sys_err_code == cur->sys_ec ) return cur->ec;
+ }
+ return fs::system_error; // general system error code
+ }
+
+ // These helper functions work for POSIX and Windows. For systems where
+ // path->native_file_string() != path->native_directory_string(), more
+ // care would be required to get the right form for the function involved.
+
+ std::string other_error_prep(
+ const std::string & who,
+ const std::string & message )
+ {
+ return who + ": " + message;
+ }
+
+ std::string other_error_prep(
+ const std::string & who,
+ const fs::path & path1,
+ const std::string & message )
+ {
+ return who + ": \"" + path1.native_file_string() + "\": " + message;
+ }
+
+ std::string system_error_prep(
+ const std::string & who,
+ const fs::path & path1,
+ int sys_err_code )
+ {
+ return who + ": \"" + path1.native_file_string() + "\": "
+ + system_message( sys_err_code );
+ }
+
+ std::string system_error_prep(
+ const std::string & who,
+ const fs::path & path1,
+ const fs::path & path2,
+ int sys_err_code )
+ {
+ return who + ": \"" + path1.native_file_string()
+ + "\", \"" + path2.native_file_string() + "\": "
+ + system_message( sys_err_code );
+ }
+
+} // unnamed namespace
+
+namespace boost
+{
+ namespace filesystem
+ {
+
+// filesystem_error implementation -----------------------------------------//
+
+ filesystem_error::filesystem_error(
+ const std::string & who,
+ const std::string & message )
+ : std::runtime_error(
+ other_error_prep( who, message ).c_str() ),
+ m_sys_err(0), m_err(other_error), m_who(who)
+ {}
+
+ filesystem_error::filesystem_error(
+ const std::string & who,
+ const path & path1,
+ const std::string & message )
+ : std::runtime_error(
+ other_error_prep( who, path1, message ).c_str() ),
+ m_sys_err(0), m_err(other_error), m_who(who), m_path1(path1)
+ {}
+
+ filesystem_error::filesystem_error(
+ const std::string & who,
+ const path & path1,
+ int sys_err_code )
+ : std::runtime_error(
+ system_error_prep( who, path1, sys_err_code ).c_str() ),
+ m_sys_err(sys_err_code), m_err(lookup_error(sys_err_code)),
+ m_who(who), m_path1(path1)
+ {}
+
+ filesystem_error::filesystem_error(
+ const std::string & who,
+ const path & path1,
+ const path & path2,
+ int sys_err_code )
+ : std::runtime_error(
+ system_error_prep( who, path1, path2, sys_err_code ).c_str() ),
+ m_sys_err(sys_err_code), m_err(lookup_error(sys_err_code)),
+ m_who(who), m_path1(path1), m_path2(path2)
+ {}
+
+ filesystem_error::~filesystem_error() throw()
+ {
+ }
+
+ namespace detail
+ {
+ int system_error_code() // artifact of POSIX and WINDOWS error reporting
+ {
+ # ifdef BOOST_WINDOWS
+ return ::GetLastError();
+ # else
+ return errno; // GCC 3.1 won't accept ::errno
+ # endif
+ }
+ } // namespace detail
+ } // namespace filesystem
+} // namespace boost
+
--- /dev/null
+// directory_posix_windows.cpp ---------------------------------------------//
+
+// < ----------------------------------------------------------------------- >
+// < Copyright © 2002 Beman Dawes. >
+// < Copyright © 2001 Dietmar Kühl, All Rights Reserved >
+// < >
+// < Permission to use, copy, modify, distribute and sell this >
+// < software for any purpose is hereby granted without fee, provided >
+// < that the above copyright notice appears in all copies and that >
+// < both that copyright notice and this permission notice appear in >
+// < supporting documentation. The authors make no representations about >
+// < the suitability of this software for any purpose. It is provided >
+// < "as is" without expressed or implied warranty. >
+// < ----------------------------------------------------------------------- >
+
+// See http://www.boost.org/libs/filesystem for documentation.
+
+//----------------------------------------------------------------------------//
+
+
+// The point of this implementation is to prove the interface. There is no
+// claim the implementation is efficient, follows good coding practice, etc.
+
+
+//----------------------------------------------------------------------------//
+
+#include <boost/config.hpp>
+#include <boost/filesystem/operations.hpp>
+#include <boost/filesystem/exception.hpp>
+#include <boost/scoped_array.hpp>
+#include <boost/throw_exception.hpp>
+//#include <iostream>
+
+namespace fs = boost::filesystem;
+
+// BOOST_POSIX or BOOST_WINDOWS specify which API to use.
+# if !defined( BOOST_WINDOWS ) && !defined( BOOST_POSIX )
+# if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__)
+# define BOOST_WINDOWS
+# else
+# define BOOST_POSIX
+# endif
+# endif
+
+# if defined(BOOST_WINDOWS)
+# include "windows.h"
+
+// For Windows, the xxxA form of various function names is used to avoid
+// inadvertently getting wide forms of the functions. (The undecorated
+// forms are actually macros, so can misfire if the user has various
+// other macros defined. There was a bug report of this happening.)
+
+# else
+# include "sys/stat.h"
+# include "dirent.h"
+# include "unistd.h"
+# include "fcntl.h"
+# endif
+
+#include <string>
+#include <cstdio>
+#include <cerrno>
+#include <cassert>
+
+// helpers -----------------------------------------------------------------//
+
+namespace
+{
+#ifdef BOOST_POSIX
+
+# define BOOST_HANDLE DIR *
+# define BOOST_INVALID_HANDLE_VALUE 0
+# define BOOST_SYSTEM_DIRECTORY_TYPE struct dirent *
+
+ inline const char * find_first_file( const char * dir,
+ BOOST_HANDLE & handle, BOOST_SYSTEM_DIRECTORY_TYPE & )
+ // Returns: 0 if error, otherwise name
+ {
+ const char * dummy_first_name = ".";
+ return ( (handle = ::opendir( dir ))
+ == BOOST_INVALID_HANDLE_VALUE ) ? 0 : dummy_first_name;
+ }
+
+ inline void find_close( BOOST_HANDLE handle )
+ {
+ assert( handle != BOOST_INVALID_HANDLE_VALUE );
+ ::closedir( handle );
+ }
+
+ inline const char * find_next_file(
+ BOOST_HANDLE handle, const fs::path & ph, BOOST_SYSTEM_DIRECTORY_TYPE & )
+ // Returns: if EOF 0, otherwise name
+ // Throws: if system reports error
+ {
+
+// TODO: use readdir_r() if available, so code is multi-thread safe.
+// Fly-in-ointment: not all platforms support readdir_r().
+
+ struct dirent * dp;
+ errno = 0;
+ if ( (dp = ::readdir( handle )) == 0 )
+ {
+ if ( errno != 0 )
+ {
+ boost::throw_exception(
+ fs::filesystem_error(
+ "boost::filesystem::directory_iterator::operator++",
+ ph, errno ) );
+ }
+ else { return 0; } // end reached
+ }
+ return dp->d_name;
+ }
+#else // BOOST_WINDOWS
+
+# define BOOST_HANDLE HANDLE
+# define BOOST_INVALID_HANDLE_VALUE INVALID_HANDLE_VALUE
+# define BOOST_SYSTEM_DIRECTORY_TYPE WIN32_FIND_DATAA
+
+ inline const char * find_first_file( const char * dir,
+ BOOST_HANDLE & handle, BOOST_SYSTEM_DIRECTORY_TYPE & data )
+ // Returns: 0 if error, otherwise name
+ {
+// std::cout << "find_first_file " << dir << std::endl;
+ std::string dirpath( std::string(dir) + "/*" );
+ return ( (handle = ::FindFirstFileA( dirpath.c_str(), &data ))
+ == BOOST_INVALID_HANDLE_VALUE ) ? 0 : data.cFileName;
+ }
+
+ inline void find_close( BOOST_HANDLE handle )
+ {
+// std::cout << "find_close" << std::endl;
+ assert( handle != BOOST_INVALID_HANDLE_VALUE );
+ ::FindClose( handle );
+ }
+
+ inline const char * find_next_file(
+ BOOST_HANDLE handle, const fs::path & ph,
+ BOOST_SYSTEM_DIRECTORY_TYPE & data )
+ // Returns: 0 if EOF, otherwise name
+ // Throws: if system reports error
+ {
+ if ( ::FindNextFileA( handle, &data ) == 0 )
+ {
+ if ( ::GetLastError() != ERROR_NO_MORE_FILES )
+ {
+ boost::throw_exception( fs::filesystem_error(
+ "boost::filesystem::directory_iterator::operator++",
+ ph.branch_path(), fs::detail::system_error_code() ) );
+ }
+ else { return 0; } // end reached
+ }
+ return data.cFileName;
+ }
+
+#endif
+
+ fs::directory_iterator end_itr;
+
+ bool is_empty_directory( const fs::path & dir_path )
+ {
+ return fs::directory_iterator(dir_path) == end_itr;
+ }
+
+ unsigned long remove_all_aux( const fs::path & ph )
+ {
+ unsigned long count = 1;
+ if ( fs::is_directory( ph ) )
+ {
+ for ( fs::directory_iterator itr( ph );
+ itr != end_itr; ++itr )
+ {
+ count += remove_all_aux( *itr );
+ }
+ }
+ fs::remove( ph );
+ return count;
+ }
+
+} // unnamed namespace
+
+namespace boost
+{
+ namespace filesystem
+ {
+
+// dir_itr_imp -------------------------------------------------------------//
+
+ class directory_iterator::dir_itr_imp
+ {
+ public:
+ path entry_path;
+ BOOST_HANDLE handle;
+
+ ~dir_itr_imp()
+ {
+ if ( handle != BOOST_INVALID_HANDLE_VALUE ) find_close( handle );
+ }
+ };
+
+// directory_iterator implementation ---------------------------------------//
+
+ // default ctor creates the "end" iterator (by letting base default to 0)
+ directory_iterator::directory_iterator() {}
+
+ directory_iterator::directory_iterator( const path & dir_path )
+ {
+ m_imp.reset( new dir_itr_imp );
+ BOOST_SYSTEM_DIRECTORY_TYPE scratch;
+ const char * name = 0; // initialization quiets compiler warnings
+ if ( dir_path.empty() )
+ m_imp->handle = BOOST_INVALID_HANDLE_VALUE;
+ else
+ name = find_first_file( dir_path.native_directory_string().c_str(),
+ m_imp->handle, scratch ); // sets handle
+
+ if ( m_imp->handle != BOOST_INVALID_HANDLE_VALUE )
+ {
+ m_imp->entry_path = dir_path;
+ m_imp->entry_path.m_path_append( name, path::nocheck );
+ while ( m_imp.get()
+ && ( m_imp->entry_path.leaf() == "."
+ || m_imp->entry_path.leaf() == ".." ) )
+ { operator++(); }
+ }
+ else
+ {
+ boost::throw_exception( filesystem_error(
+ "boost::filesystem::directory_iterator constructor",
+ dir_path, fs::detail::system_error_code() ) );
+ }
+ }
+
+ path const & directory_iterator::m_deref() const
+ {
+ assert( m_imp.get() ); // fails if dereference end iterator
+ return m_imp->entry_path;
+ }
+
+ void directory_iterator::m_inc()
+ {
+ assert( m_imp.get() ); // fails on increment end iterator
+ assert( m_imp->handle != BOOST_INVALID_HANDLE_VALUE ); // reality check
+
+ BOOST_SYSTEM_DIRECTORY_TYPE scratch;
+ const char * name;
+ if ( (name = find_next_file( m_imp->handle,
+ m_imp->entry_path, scratch )) != 0 )
+ {
+ m_imp->entry_path.m_replace_leaf( name );
+ }
+ else
+ {
+ m_imp.reset(); // make base() the end iterator
+ }
+ }
+
+// free functions ----------------------------------------------------------//
+
+ bool exists( const path & ph )
+ {
+# ifdef BOOST_POSIX
+ struct stat path_stat;
+ return ::stat( ph.string().c_str(), &path_stat ) == 0;
+# else
+ return ::GetFileAttributesA( ph.string().c_str() ) != 0xFFFFFFFF;
+# endif
+ }
+
+ bool is_directory( const path & ph )
+ {
+# ifdef BOOST_POSIX
+ struct stat path_stat;
+ if ( ::stat( ph.native_directory_string().c_str(), &path_stat ) != 0 )
+ boost::throw_exception( filesystem_error(
+ "boost::filesystem::is_directory",
+ ph, fs::detail::system_error_code() ) );
+ return S_ISDIR( path_stat.st_mode );
+# else
+ DWORD attributes = ::GetFileAttributesA( ph.native_directory_string().c_str() );
+ if ( attributes == 0xFFFFFFFF )
+ boost::throw_exception( filesystem_error(
+ "boost::filesystem::is_directory",
+ ph, fs::detail::system_error_code() ) );
+ return (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
+# endif
+ }
+
+ bool _is_empty( const path & ph )
+ {
+# ifdef BOOST_POSIX
+ struct stat path_stat;
+ if ( ::stat( ph.string().c_str(), &path_stat ) != 0 )
+ boost::throw_exception( filesystem_error(
+ "boost::filesystem::is_empty",
+ ph, fs::detail::system_error_code() ) );
+
+ return S_ISDIR( path_stat.st_mode )
+ ? is_empty_directory( ph )
+ : path_stat.st_size == 0;
+# else
+ WIN32_FILE_ATTRIBUTE_DATA fad;
+ if ( !::GetFileAttributesExA( ph.string().c_str(),
+ ::GetFileExInfoStandard, &fad ) )
+ boost::throw_exception( filesystem_error(
+ "boost::filesystem::is_empty",
+ ph, fs::detail::system_error_code() ) );
+
+ return ( fad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
+ ? is_empty_directory( ph )
+ :( !fad.nFileSizeHigh && !fad.nFileSizeLow );
+# endif
+ }
+
+ void create_directory( const path & dir_path )
+ {
+# ifdef BOOST_POSIX
+ if ( ::mkdir( dir_path.native_directory_string().c_str(),
+ S_IRWXU|S_IRWXG|S_IRWXO ) != 0 )
+# else
+ if ( !::CreateDirectoryA( dir_path.native_directory_string().c_str(), 0 ) )
+# endif
+ boost::throw_exception( filesystem_error(
+ "boost::filesystem::create_directory",
+ dir_path, fs::detail::system_error_code() ) );
+ }
+
+ bool remove( const path & ph )
+ {
+ if ( exists( ph ) )
+ {
+# ifdef BOOST_POSIX
+ if ( ::remove( ph.string().c_str() ) != 0 )
+ {
+# else
+ if ( is_directory( ph ) )
+ {
+ if ( !::RemoveDirectoryA( ph.string().c_str() ) )
+ boost::throw_exception( filesystem_error(
+ "boost::filesystem::remove",
+ ph, fs::detail::system_error_code() ) );
+ }
+ else
+ {
+ if ( !::DeleteFileA( ph.string().c_str() ) )
+# endif
+ boost::throw_exception( filesystem_error(
+ "boost::filesystem::remove",
+ ph, fs::detail::system_error_code() ) );
+ }
+ return true;
+ }
+ return false;
+ }
+
+ unsigned long remove_all( const path & ph )
+ {
+ return exists( ph ) ? remove_all_aux( ph ) : 0;
+ }
+
+ void rename( const path & old_path,
+ const path & new_path )
+ {
+# ifdef BOOST_POSIX
+ if ( exists( new_path ) // POSIX is too permissive so must check
+ || ::rename( old_path.string().c_str(), new_path.string().c_str() ) != 0 )
+# else
+ if ( !::MoveFileA( old_path.string().c_str(), new_path.string().c_str() ) )
+# endif
+ boost::throw_exception( filesystem_error(
+ "boost::filesystem::rename",
+ old_path, new_path, fs::detail::system_error_code() ) );
+ }
+
+ void copy_file( const path & from_file_ph,
+ const path & to_file_ph )
+ {
+# ifdef BOOST_POSIX
+ // TODO: Ask POSIX experts if this is the best way to copy a file
+
+ const std::size_t buf_sz = 32768;
+ boost::scoped_array<char> buf( new char [buf_sz] );
+ int infile, outfile=0; // init quiets compiler warning
+
+ if ( (infile = ::open( from_file_ph.string().c_str(),
+ O_RDONLY )) < 0
+ || (outfile = ::open( to_file_ph.string().c_str(),
+ O_WRONLY | O_CREAT | O_EXCL,
+ S_IRWXU|S_IRWXG|S_IRWXO )) < 0 )
+ {
+ if ( infile != 0 ) ::close( infile );
+ boost::throw_exception( filesystem_error(
+ "boost::filesystem::copy_file",
+ from_file_ph, to_file_ph, fs::detail::system_error_code() ) );
+ }
+
+ ssize_t sz;
+ while ( (sz = ::read( infile, buf.get(), buf_sz )) > 0
+ && (sz = ::write( outfile, buf.get(), sz )) > 0 ) {}
+
+ ::close( infile );
+ ::close( outfile );
+
+ if ( sz != 0 )
+# else
+ if ( !::CopyFileA( from_file_ph.string().c_str(),
+ to_file_ph.string().c_str(), /*fail_if_exists=*/true ) )
+# endif
+ boost::throw_exception( filesystem_error(
+ "boost::filesystem::copy_file",
+ from_file_ph, to_file_ph, fs::detail::system_error_code() ) );
+ }
+
+ path current_path()
+ {
+# ifdef BOOST_POSIX
+ long path_max = ::pathconf( ".", _PC_PATH_MAX );
+ if ( path_max < 1 )
+ boost::throw_exception(
+ filesystem_error( "boost::filesystem::current_path",
+ "_PC_PATH_MAX < 1" ) );
+ boost::scoped_array<char>
+ buf( new char[static_cast<std::size_t>(path_max)] );
+ if ( ::getcwd( buf.get(), static_cast<std::size_t>(path_max) ) == 0 )
+# else
+ DWORD sz;
+ if ( (sz = ::GetCurrentDirectoryA( 0, static_cast<char*>(0) )) == 0 )
+ boost::throw_exception(
+ filesystem_error( "boost::filesystem::current_path",
+ "size is 0" ) );
+ boost::scoped_array<char> buf( new char[sz] );
+ if ( ::GetCurrentDirectoryA( sz, buf.get() ) == 0 )
+# endif
+ boost::throw_exception(
+ filesystem_error( "boost::filesystem::current_path", path(),
+ fs::detail::system_error_code() ) );
+ return path( buf.get(), native );
+ }
+
+ const path & initial_path()
+ {
+ static path init_path;
+ if ( init_path.empty() ) init_path = current_path();
+ return init_path;
+ }
+
+ path system_complete( const path & ph )
+ {
+# ifdef BOOST_WINDOWS
+ if ( ph.empty() ) return ph;
+ char buf[MAX_PATH];
+ char * pfn;
+ std::size_t len = ::GetFullPathNameA( ph.string().c_str(),
+ sizeof(buf) , buf, &pfn );
+ if ( !len )
+ { boost::throw_exception(
+ filesystem_error( "boost::filesystem::system_complete",
+ ph, "size is 0" ) ); }
+ buf[len] = '\0';
+ return path( buf, native );
+# else
+ return (ph.empty() || ph.is_complete())
+ ? ph : current_path() / ph;
+# endif
+ }
+
+ path complete( const path & ph, const path & base )
+ {
+ assert( base.is_complete()
+ && (ph.is_complete() || !ph.has_root_name()) ); // precondition
+# ifdef BOOST_WINDOWS
+ if (ph.empty() || ph.is_complete()) return ph;
+ if ( !ph.has_root_name() )
+ return ph.has_root_directory()
+ ? path( base.root_name(), native ) / ph
+ : base / ph;
+ return base / ph;
+# else
+ return (ph.empty() || ph.is_complete()) ? ph : base / ph;
+# endif
+ }
+ } // namespace filesystem
+} // namespace boost
+
--- /dev/null
+// path implementation -----------------------------------------------------//
+
+// (C) Copyright Beman Dawes 2002. Permission to copy,
+// use, modify, sell and distribute this software is granted provided this
+// copyright notice appears in all copies. This software is provided "as is"
+// without express or implied warranty, and with no claim as to its
+// suitability for any purpose.
+
+// See http://www.boost.org/libs/filesystem for documentation.
+
+
+//****************************************************************************//
+
+// WARNING: This code was hacked time and time again as different library
+// designs were tried. Thus portions may be residue from the earlier
+// experiments, and be totally stupid or wrong in light of the final library
+// specifications. The code needs to be reviewed line-by-line to elmininate
+// such problems.
+
+//****************************************************************************//
+
+// BOOST_POSIX or BOOST_WINDOWS specify which API to use.
+# if !defined( BOOST_WINDOWS ) && !defined( BOOST_POSIX )
+# if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__)
+# define BOOST_WINDOWS
+# else
+# define BOOST_POSIX
+# endif
+# endif
+
+#include <boost/filesystem/path.hpp>
+#include <boost/filesystem/exception.hpp>
+
+namespace fs = boost::filesystem;
+
+#include <boost/config.hpp>
+#ifdef BOOST_NO_STDC_NAMESPACE
+ namespace std { using ::strlen; }
+#endif
+
+#include <boost/throw_exception.hpp>
+#include <cstring> // SGI MIPSpro compilers need this
+#include <vector>
+#include <cassert>
+
+// helpers -----------------------------------------------------------------//
+
+namespace
+{
+ // POSIX & Windows cases: "", "/", "/foo", "foo", "foo/bar"
+ // Windows only cases: "c:", "c:/", "c:foo", "c:/foo",
+ // "prn:", "//share", "//share/", "//share/foo"
+
+ std::string::size_type leaf_pos( const std::string & str,
+ std::string::size_type end_pos ) // end_pos is past-the-end position
+ // return 0 if str itself is leaf (or empty)
+ {
+ if ( end_pos && str[end_pos-1] == '/' ) return end_pos-1;
+
+ std::string::size_type pos( str.find_last_of( '/', end_pos-1 ) );
+# ifdef BOOST_WINDOWS
+ if ( pos == std::string::npos ) pos = str.find_last_of( ':', end_pos-2 );
+# endif
+
+ return ( pos == std::string::npos // path itself must be a leaf (or empty)
+# ifdef BOOST_WINDOWS
+ || (pos == 1 && str[0] == '/') // or share
+# endif
+ ) ? 0 // so leaf is entire string
+ : pos + 1; // or starts after delimiter
+ }
+
+ void first_name( const std::string & src, std::string & target )
+ {
+ target = ""; // VC++ 6.0 doesn't have string::clear()
+ std::string::const_iterator itr( src.begin() );
+
+# ifdef BOOST_WINDOWS
+ // deal with //share
+ if ( src.size() >= 2 && src[0] == '/' && src[1] == '/' )
+ { target = "//"; itr += 2; }
+# endif
+
+ while ( itr != src.end()
+# ifdef BOOST_WINDOWS
+ && *itr != ':'
+# endif
+ && *itr != '/' ) { target += *itr++; }
+
+ if ( itr == src.end() ) return;
+
+# ifdef BOOST_WINDOWS
+ if ( *itr == ':' )
+ {
+ target += *itr++;
+ return;
+ }
+# endif
+
+ // *itr is '/'
+ if ( itr == src.begin() ) { target += '/'; }
+ return;
+ }
+
+ const char invalid_chars[] =
+ "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
+ "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F"
+ "<>:\"/\\|*?";
+ // note that the terminating '\0' is part of the string - thus the size below
+ // is sizeof(invalid_chars) rather than sizeof(invalid_chars)-1. I
+ const std::string invalid_generic( invalid_chars, sizeof(invalid_chars) );
+
+ const std::string valid_posix(
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._-" );
+
+ const std::string valid_boost_file(
+ "abcdefghijklmnopqrstuvwxyz0123456789._-" );
+ const std::string valid_boost_directory(
+ "abcdefghijklmnopqrstuvwxyz0123456789_-" );
+
+} // unnamed namespace
+
+//----------------------------------------------------------------------------//
+
+namespace boost
+{
+ namespace filesystem
+ {
+
+ // error checking functions --------------------------------------------//
+
+ bool generic_name( const std::string & name )
+ {
+ return name.size() != 0
+ && name.find_first_of( invalid_generic ) == std::string::npos
+ && name != "."
+ && name != ".."
+ && *name.begin() != ' '
+ && *(name.end()-1) != ' ';
+ }
+
+ bool posix_name( const std::string & name )
+ {
+ return name.find_first_not_of( valid_posix ) == std::string::npos
+ && name != ".";
+ }
+
+ const path & check_posix_leaf( const path & ph )
+ {
+ if ( !posix_name( ph.leaf() ) )
+ boost::throw_exception( filesystem_error(
+ "boost::filesystem::check_posix_leaf",
+ ph, "invalid posix name: \""
+ + ph.leaf() + "\"" ) );
+ return ph;
+ }
+
+ bool boost_file_name( const std::string & name )
+ {
+ return name.size() <= 31
+ && name.find_first_not_of( valid_boost_file ) == std::string::npos
+ && name != ".";
+ }
+
+ bool boost_directory_name( const std::string & name )
+ {
+ return name.size() <= 31
+ && name.find_first_not_of( valid_boost_directory ) == std::string::npos;
+ }
+
+// path implementation -----------------------------------------------------//
+
+ path::path( const std::string & src )
+ {
+ m_path_append( src );
+ }
+
+ path::path( const char * src )
+ {
+ m_path_append( src );
+ }
+
+ path::path( const std::string & src, path_format )
+ {
+ m_path_append( src, platform );
+ }
+
+ path::path( const char * src, path_format )
+ {
+ m_path_append( src, platform );
+ }
+
+ path & path::operator /=( const path & rhs )
+ {
+ m_path_append( rhs.m_path, nocheck );
+ return *this;
+ }
+
+ void path::m_path_append( const std::string & src, source_context context )
+ {
+ // convert backslash to forward slash if context is "platform"
+ // check names if context is "generic"
+ // allow system-specific-root if context is not "generic"
+
+ assert( src.size() == std::strlen( src.c_str() ) ); // no embedded 0
+
+ if ( src.size() == 0 ) return;
+
+ std::string::const_iterator itr( src.begin() );
+
+ // [root-filesystem]
+# ifdef BOOST_WINDOWS
+ if ( context != generic && src.size() >= 2 )
+ {
+ // drive or device
+ if ( src[1] == ':' || src[src.size()-1] == ':' )
+ {
+ for ( ; *itr != ':'; ++itr ) m_path += *itr;
+ m_path += ':';
+ ++itr;
+ }
+
+ // share
+ else if ( (*itr == '/' || (*itr == '\\' && context == platform))
+ && (*(itr+1) == '/' || (*(itr+1) == '\\' && context == platform)) )
+ {
+ m_path += "//";
+ for ( itr += 2;
+ itr != src.end() && *itr != '/' && *itr != '\\';
+ ++itr ) m_path += *itr;
+ }
+ }
+# endif
+
+ // root directory [ "/" ]
+ if ( itr != src.end() && (*itr == '/'
+# ifdef BOOST_WINDOWS
+ || (*itr == '\\' && context == platform)
+# endif
+ ) )
+ {
+ ++itr;
+ if ( m_path.size() == 0
+# ifdef BOOST_WINDOWS
+ || m_path[m_path.size()-1] == ':' // drive or device
+ || ( // share
+ m_path.size() > 2
+ && m_path[0] == '/'
+ && m_path[1] == '/'
+ && m_path.find( '/', 2 ) == std::string::npos
+ )
+# endif
+ ) m_path += '/';
+ }
+
+ // element { "/" element } [ "/" ]
+ while ( itr != src.end() )
+ {
+
+ // append '/' if needed
+ if ( !empty()
+ && *(m_path.end()-1) != ':' && *(m_path.end()-1) != '/' )
+ m_path += '/';
+
+ if ( *itr == '.'&& (itr+1) != src.end() && *(itr+1) == '.' ) // ".."
+ {
+ if ( m_path.size() >= 2 // there is a named parent directory present
+ && *(m_path.end()-1) == '/'
+# ifdef BOOST_WINDOWS
+ && *(m_path.end()-2) != ':'
+# endif
+ && *(m_path.end()-2) != '.' )
+ {
+ // reference to parent so erase child
+ std::string::iterator child( m_path.end()-2 );
+
+ while ( child != m_path.begin() && *child != '/'
+# ifdef BOOST_WINDOWS
+ && *child != ':'
+# endif
+ ) --child;
+
+ // only erase '/' if it is a separator rather than part of the root
+ if ( (*child == '/'
+ && (child == m_path.begin()
+# ifdef BOOST_WINDOWS
+ || *(child-1) == ':'))
+ || *child == ':'
+# else
+ ))
+# endif
+ ) ++child;
+
+ m_path.erase( child, m_path.end() );
+ }
+ else { m_path += ".."; }
+ ++itr;
+ ++itr;
+ } // ".."
+ else // element is name
+ {
+ std::string name;
+ do
+ { name += *itr; }
+ while ( ++itr != src.end() && *itr != '/'
+# ifdef BOOST_WINDOWS
+ && (*itr != '\\' || context != platform)
+# endif
+ );
+
+ if ( context == generic && !generic_name( name ) )
+ {
+ boost::throw_exception( filesystem_error(
+ "boost::filesystem::path",
+ "invalid name \"" + name + "\" in path: \"" + src + "\"" ) );
+ }
+
+ m_path += name;
+ }
+
+ if ( itr != src.end() )
+ {
+ if ( *itr == '/'
+# ifdef BOOST_WINDOWS
+ || (*itr == '\\' && context == platform)
+# endif
+ ) ++itr;
+ else
+ boost::throw_exception( filesystem_error(
+ "boost::filesystem::path",
+ "invalid path syntax: \"" + src + "\"" ) );
+ }
+
+ } // while more elements
+ }
+
+// path conversion functions ------------------------------------------------//
+
+ std::string path::native_file_string() const
+ {
+# ifdef BOOST_WINDOWS
+ std::string s( m_path );
+ for ( std::string::iterator itr( s.begin() );
+ itr != s.end(); ++itr )
+ if ( *itr == '/' ) *itr = '\\';
+ return s;
+# else
+ return m_path;
+# endif
+ }
+
+ std::string path::native_directory_string() const
+ { return native_file_string(); }
+
+// path decomposition functions ---------------------------------------------//
+
+ path::iterator path::begin() const
+ {
+ iterator itr;
+ itr.base().path_ptr = this;
+ first_name( m_path, itr.base().name );
+ itr.base().pos = 0;
+ return itr;
+ }
+
+ void path::m_replace_leaf( const char * new_leaf )
+ {
+ m_path.erase( leaf_pos( m_path, m_path.size() ) );
+ m_path += new_leaf;
+ }
+
+ std::string path::leaf() const
+ {
+ return m_path.substr( leaf_pos( m_path, m_path.size() ) );
+ }
+
+ namespace detail
+ {
+ inline bool is_absolute_root( const std::string & s,
+ std::string::size_type len )
+ {
+ return
+ len && s[len-1] == '/'
+ &&
+ (
+ len == 1 // "/"
+# ifdef BOOST_WINDOWS
+ || ( len > 1
+ && ( s[len-2] == ':' // drive or device
+ || ( s[0] == '/' // share
+ && s[1] == '/'
+ && s.find( '/', 2 ) == len-1
+ )
+ )
+ )
+# endif
+ );
+ }
+ }
+
+ path path::branch_path() const
+ {
+ std::string::size_type end_pos( leaf_pos( m_path, m_path.size() ) );
+
+ // skip a '/' unless it is a root directory
+ if ( end_pos && m_path[end_pos-1] == '/'
+ && !detail::is_absolute_root( m_path, end_pos ) ) --end_pos;
+ return path( m_path.substr( 0, end_pos ), native );
+ }
+
+ path path::relative_path() const
+ {
+ std::string::size_type pos( 0 );
+ if ( m_path.size() && m_path[0] == '/' )
+ { pos = 1;
+# ifdef BOOST_WINDOWS
+ if ( m_path.size()>1 && m_path[1] == '/' ) // share
+ {
+ if ( (pos = m_path.find( '/', 2 )) != std::string::npos ) ++pos;
+ else return path();
+ }
+ }
+ else if ( (pos = m_path.find( ':' )) == std::string::npos ) pos = 0;
+ else // has ':'
+ {
+ if ( ++pos < m_path.size() && m_path[pos] == '/' ) ++pos;
+# endif
+ }
+ return path( m_path.substr( pos ) );
+ }
+
+ std::string path::root_name() const
+ {
+# ifdef BOOST_WINDOWS
+ std::string::size_type pos( m_path.find( ':' ) );
+ if ( pos != std::string::npos ) return m_path.substr( 0, pos+1 );
+ if ( m_path.size() > 2 && m_path[0] == '/' && m_path[1] == '/' )
+ {
+ pos = m_path.find( '/', 2 );
+ return m_path.substr( 0, pos );
+ }
+# endif
+ return std::string();
+ }
+
+ std::string path::root_directory() const
+ {
+ return std::string(
+ ( m_path.size() && m_path[0] == '/' ) // covers both "/" and "//share"
+# ifdef BOOST_WINDOWS
+ || ( m_path.size() > 2
+ && m_path[1] == ':'
+ && m_path[2] == '/' ) // "c:/"
+# endif
+ ? "/" : "" );
+ }
+
+ path path::root_path() const
+ {
+ return path(
+# ifdef BOOST_WINDOWS
+ root_name(), native ) /= root_directory();
+# else
+ root_directory() );
+# endif
+ }
+
+// path query functions -----------------------------------------------------//
+
+ bool path::is_complete() const
+ {
+# ifdef BOOST_WINDOWS
+ return m_path.size() > 2
+ && ( (m_path[1] == ':' && m_path[2] == '/') // "c:/"
+ || (m_path[0] == '/' && m_path[1] == '/') // "//share"
+ || m_path[m_path.size()-1] == ':' );
+# else
+ return m_path.size() && m_path[0] == '/';
+# endif
+ }
+
+ bool path::has_root_path() const
+ {
+ return ( m_path.size()
+ && m_path[0] == '/' ) // covers both "/" and "//share"
+# ifdef BOOST_WINDOWS
+ || ( m_path.size() > 1 && m_path[1] == ':' ) // "c:" and "c:/"
+ || ( m_path.size() > 3
+ && m_path[m_path.size()-1] == ':' ) // "device:"
+# endif
+ ;
+ }
+
+ bool path::has_root_name() const
+ {
+# ifdef BOOST_WINDOWS
+ return m_path.size() > 1
+ && ( m_path[1] == ':' // "c:"
+ || m_path[m_path.size()-1] == ':' // "prn:"
+ || (m_path[0] == '/' && m_path[1] == '/') // "//share"
+ );
+# else
+ return false;
+# endif
+ }
+
+ bool path::has_root_directory() const
+ {
+ return ( m_path.size()
+ && m_path[0] == '/' ) // covers both "/" and "//share"
+# ifdef BOOST_WINDOWS
+ || ( m_path.size() > 2
+ && m_path[1] == ':' && m_path[2] == '/' ) // "c:/"
+# endif
+ ;
+ }
+
+ bool path::has_relative_path() const { return !relative_path().empty(); }
+ bool path::has_branch_path() const { return !branch_path().empty(); }
+
+
+// path_itr_imp implementation ----------------------------------------------//
+
+ namespace detail
+ {
+ void path_itr_imp::operator++()
+ {
+ assert( pos < path_ptr->m_path.size() ); // detect increment past end
+ pos += name.size();
+ if ( pos == path_ptr->m_path.size() )
+ {
+ name = ""; // not strictly required, but might aid debugging
+ return;
+ }
+ if ( path_ptr->m_path[pos] == '/' )
+ {
+# ifdef BOOST_WINDOWS
+ if ( name[name.size()-1] == ':' // drive or device
+ || (name[0] == '/' && name[1] == '/') ) // share
+ {
+ name = "/";
+ return;
+ }
+# endif
+ ++pos;
+ }
+ std::string::size_type end_pos( path_ptr->m_path.find( '/', pos ) );
+ if ( end_pos == std::string::npos ) end_pos = path_ptr->m_path.size();
+ name = path_ptr->m_path.substr( pos, end_pos - pos );
+ }
+
+ void path_itr_imp::operator--()
+ {
+ assert( pos ); // detect decrement of begin
+ std::string::size_type end_pos( pos );
+
+ // skip a '/' unless it is a root directory
+ if ( path_ptr->m_path[end_pos-1] == '/'
+ && !detail::is_absolute_root( path_ptr->m_path, end_pos ) ) --end_pos;
+ pos = leaf_pos( path_ptr->m_path, end_pos );
+ name = path_ptr->m_path.substr( pos, end_pos - pos );
+ }
+
+ } // namespace detail
+ } // namespace filesystem
+} // namespace boost
AC_CONFIG_FILES([Makefile \
boost/Makefile \
boost/libs/Makefile \
+ boost/libs/filesystem/Makefile \
+ boost/libs/filesystem/src/Makefile \
boost/libs/regex/Makefile \
boost/libs/regex/src/Makefile \
boost/libs/signals/Makefile \