]> git.lyx.org Git - features.git/commitdiff
boost::filesystem added
authorLars Gullik Bjønnes <larsbj@gullik.org>
Thu, 8 Jan 2004 17:47:56 +0000 (17:47 +0000)
committerLars Gullik Bjønnes <larsbj@gullik.org>
Thu, 8 Jan 2004 17:47:56 +0000 (17:47 +0000)
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8328 a592a061-630c-0410-9148-cb99ea01b6c8

17 files changed:
ChangeLog
boost/ChangeLog
boost/boost/filesystem/convenience.hpp [new file with mode: 0644]
boost/boost/filesystem/exception.hpp [new file with mode: 0644]
boost/boost/filesystem/fstream.hpp [new file with mode: 0644]
boost/boost/filesystem/operations.hpp [new file with mode: 0644]
boost/boost/filesystem/path.hpp [new file with mode: 0644]
boost/libs/Makefile.am
boost/libs/filesystem/.cvsignore [new file with mode: 0644]
boost/libs/filesystem/Makefile.am [new file with mode: 0644]
boost/libs/filesystem/src/.cvsignore [new file with mode: 0644]
boost/libs/filesystem/src/Makefile.am [new file with mode: 0644]
boost/libs/filesystem/src/convenience.cpp [new file with mode: 0644]
boost/libs/filesystem/src/exception.cpp [new file with mode: 0644]
boost/libs/filesystem/src/operations_posix_windows.cpp [new file with mode: 0644]
boost/libs/filesystem/src/path_posix_windows.cpp [new file with mode: 0644]
configure.ac

index fcd3a91d966c0894b7adacf2b2a666bf5bb685a5..5e6731f50439a44efb1e824561a3b6bd0cf9f0a3 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,11 +1,15 @@
+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:
@@ -19,7 +23,7 @@
        * 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>
 
index 624bd12ec6b1ce37d179922ac4c100225bb7e444..14b47d234943d6c127053ea148452711aa28e12c 100644 (file)
@@ -1,3 +1,7 @@
+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
diff --git a/boost/boost/filesystem/convenience.hpp b/boost/boost/filesystem/convenience.hpp
new file mode 100644 (file)
index 0000000..5a5f428
--- /dev/null
@@ -0,0 +1,38 @@
+//  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
+
+
diff --git a/boost/boost/filesystem/exception.hpp b/boost/boost/filesystem/exception.hpp
new file mode 100644 (file)
index 0000000..8f3c9eb
--- /dev/null
@@ -0,0 +1,105 @@
+//  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
diff --git a/boost/boost/filesystem/fstream.hpp b/boost/boost/filesystem/fstream.hpp
new file mode 100644 (file)
index 0000000..3c9a4d2
--- /dev/null
@@ -0,0 +1,124 @@
+//  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
+
diff --git a/boost/boost/filesystem/operations.hpp b/boost/boost/filesystem/operations.hpp
new file mode 100644 (file)
index 0000000..b5c38b9
--- /dev/null
@@ -0,0 +1,121 @@
+//  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
diff --git a/boost/boost/filesystem/path.hpp b/boost/boost/filesystem/path.hpp
new file mode 100644 (file)
index 0000000..42e41d5
--- /dev/null
@@ -0,0 +1,213 @@
+//  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
index b8bc3cc3e5290c5599d246677ff39391d4af0472..d8654749c89fc9d53cb9ef56d3aca16ec50cdace 100644 (file)
@@ -1,3 +1,3 @@
 include $(top_srcdir)/config/common.am
 
-SUBDIRS = regex signals
+SUBDIRS = filesystem regex signals
diff --git a/boost/libs/filesystem/.cvsignore b/boost/libs/filesystem/.cvsignore
new file mode 100644 (file)
index 0000000..282522d
--- /dev/null
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/boost/libs/filesystem/Makefile.am b/boost/libs/filesystem/Makefile.am
new file mode 100644 (file)
index 0000000..c677165
--- /dev/null
@@ -0,0 +1,4 @@
+include $(top_srcdir)/config/common.am
+
+SUBDIRS = src
+
diff --git a/boost/libs/filesystem/src/.cvsignore b/boost/libs/filesystem/src/.cvsignore
new file mode 100644 (file)
index 0000000..7997408
--- /dev/null
@@ -0,0 +1,6 @@
+Makefile
+Makefile.in
+libboostfilesystem.la
+*.lo
+.libs
+.deps
diff --git a/boost/libs/filesystem/src/Makefile.am b/boost/libs/filesystem/src/Makefile.am
new file mode 100644 (file)
index 0000000..2a42b8f
--- /dev/null
@@ -0,0 +1,13 @@
+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
+
diff --git a/boost/libs/filesystem/src/convenience.cpp b/boost/libs/filesystem/src/convenience.cpp
new file mode 100644 (file)
index 0000000..8500921
--- /dev/null
@@ -0,0 +1,32 @@
+//  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
diff --git a/boost/libs/filesystem/src/exception.cpp b/boost/libs/filesystem/src/exception.cpp
new file mode 100644 (file)
index 0000000..9950418
--- /dev/null
@@ -0,0 +1,246 @@
+//  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
diff --git a/boost/libs/filesystem/src/operations_posix_windows.cpp b/boost/libs/filesystem/src/operations_posix_windows.cpp
new file mode 100644 (file)
index 0000000..33e33af
--- /dev/null
@@ -0,0 +1,484 @@
+//  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
+
diff --git a/boost/libs/filesystem/src/path_posix_windows.cpp b/boost/libs/filesystem/src/path_posix_windows.cpp
new file mode 100644 (file)
index 0000000..4e6f4e8
--- /dev/null
@@ -0,0 +1,566 @@
+//  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
index 25c22a1dd5d0a6e2d2ee0bb3d1963b03ac34be9a..9aa611350e53ea36f6b420a0f498c44f0eb81cb7 100644 (file)
@@ -389,6 +389,8 @@ AC_CONFIG_SUBDIRS(lib lib/reLyX)
 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 \