aboutsummaryrefslogtreecommitdiff
path: root/cutl
diff options
context:
space:
mode:
Diffstat (limited to 'cutl')
-rw-r--r--cutl/fs/path.cxx18
-rw-r--r--cutl/fs/path.hxx97
-rw-r--r--cutl/fs/path.txx96
-rw-r--r--cutl/makefile2
4 files changed, 213 insertions, 0 deletions
diff --git a/cutl/fs/path.cxx b/cutl/fs/path.cxx
new file mode 100644
index 0000000..6e295c6
--- /dev/null
+++ b/cutl/fs/path.cxx
@@ -0,0 +1,18 @@
+// file : cutl/fs/path.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2009 Code Synthesis Tools CC
+// license : MIT; see accompanying LICENSE file
+
+#include <cutl/fs/path.hxx>
+
+namespace cutl
+{
+ namespace fs
+ {
+ char const* invalid_path::
+ what () const throw ()
+ {
+ return "invalid filesystem path";
+ }
+ }
+}
diff --git a/cutl/fs/path.hxx b/cutl/fs/path.hxx
new file mode 100644
index 0000000..a79fc5c
--- /dev/null
+++ b/cutl/fs/path.hxx
@@ -0,0 +1,97 @@
+// file : cutl/fs/path.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2009 Code Synthesis Tools CC
+// license : MIT; see accompanying LICENSE file
+
+#ifndef CUTL_FS_PATH_HXX
+#define CUTL_FS_PATH_HXX
+
+#include <string>
+#include <iosfwd>
+
+namespace cutl
+{
+ namespace fs
+ {
+ struct invalid_path: std::exception
+ {
+ virtual char const*
+ what () const throw ();
+ };
+
+ template <typename C>
+ class basic_path;
+
+ typedef basic_path<char> path;
+ typedef basic_path<wchar_t> wpath;
+
+ template <typename C>
+ class basic_path
+ {
+ public:
+ typedef std::basic_string<C> string_type;
+ typedef typename string_type::size_type size_type;
+
+ explicit
+ basic_path (C const* s)
+ : path_ (s)
+ {
+ init (false);
+ }
+
+ explicit
+ basic_path (string_type const& s)
+ : path_ (s)
+ {
+ init (false);
+ }
+
+ public:
+ basic_path
+ leaf () const;
+
+ basic_path
+ directory () const;
+
+ basic_path
+ base () const;
+
+ public:
+ basic_path
+ operator/ (basic_path const&);
+
+ public:
+ string_type
+ string () const
+ {
+ return path_.empty () ? string_type (1, '/') : path_;
+ }
+
+ private:
+ void
+ init (bool internal);
+
+ // Assume internal format.
+ //
+ basic_path (C const* s, size_type n)
+ : path_ (s, n)
+ {
+ init (true);
+ }
+
+ private:
+ string_type path_;
+ };
+
+ template <typename C>
+ inline std::basic_ostream<C>&
+ operator<< (std::basic_ostream<C>& os, basic_path<C> const& p)
+ {
+ return os << p.string ();
+ }
+ }
+}
+
+#include <cutl/fs/path.txx>
+
+#endif // CUTL_FS_PATH_HXX
diff --git a/cutl/fs/path.txx b/cutl/fs/path.txx
new file mode 100644
index 0000000..caff259
--- /dev/null
+++ b/cutl/fs/path.txx
@@ -0,0 +1,96 @@
+// file : cutl/fs/path.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2009 Code Synthesis Tools CC
+// license : MIT; see accompanying LICENSE file
+
+namespace cutl
+{
+ namespace fs
+ {
+ template <typename C>
+ basic_path<C> basic_path<C>::
+ leaf () const
+ {
+ size_type n (path_.size ()), i (n);
+
+ for (; i > 0; --i)
+ {
+ if (path_[i - 1] == '/' || path_[i - 1] == '\\')
+ break;
+ }
+
+ return i != 0 ? basic_path (path_.c_str () + i, n - i) : *this;
+ }
+
+ template <typename C>
+ basic_path<C> basic_path<C>::
+ directory () const
+ {
+ size_type i (path_.size ());
+
+ for (; i > 0; --i)
+ {
+ if (path_[i - 1] == '/' || path_[i - 1] == '\\')
+ break;
+ }
+
+ return i != 0 ? basic_path (path_.c_str (), i - 1) : *this;
+ }
+
+ template <typename C>
+ basic_path<C> basic_path<C>::
+ base () const
+ {
+ size_type i (path_.size ());
+
+ for (; i > 0; --i)
+ {
+ if (path_[i - 1] == '.')
+ break;
+
+ if (path_[i - 1] == '/' || path_[i - 1] == '\\')
+ {
+ i = 0;
+ break;
+ }
+ }
+
+ // Weed out paths like ".txt" and "/.txt"
+ //
+ if (i > 1 && path_[i - 2] != '/' && path_[i - 2] != '\\')
+ {
+ return basic_path (path_.c_str (), i - 1);
+ }
+ else
+ return *this;
+ }
+
+ template <typename C>
+ basic_path<C> basic_path<C>::
+ operator/ (basic_path<C> const& r)
+ {
+ if (r.path_.empty ())
+ throw invalid_path ();
+
+ basic_path<C> x (*this);
+ x.path_ += '/';
+ x.path_ += r.path_;
+ return x;
+ }
+
+ template <typename C>
+ void basic_path<C>::
+ init (bool internal)
+ {
+ if (!internal && path_.empty ())
+ throw invalid_path ();
+
+ // Strip trailing slashes. This way empty string represents
+ // root directory.
+ //
+ size_type n (path_.size ());
+ for (; n > 0 && (path_[n - 1] == '/' || path_[n - 1] == '\\'); --n) ;
+ path_.resize (n);
+ }
+ }
+}
diff --git a/cutl/makefile b/cutl/makefile
index 635524e..f5adfce 100644
--- a/cutl/makefile
+++ b/cutl/makefile
@@ -7,6 +7,8 @@ include $(dir $(lastword $(MAKEFILE_LIST)))../build/bootstrap.make
cxx_tun := shared-ptr/base.cxx
+cxx_tun += fs/path.cxx
+
cxx_tun += \
compiler/context.cxx \
compiler/type-info.cxx \