From f0fb6aeab118255266370121db79ab2a2fed88ad Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Sun, 13 Sep 2009 18:41:38 +0200 Subject: Add the fs::basic_path class --- cutl/fs/path.cxx | 18 +++++++++++ cutl/fs/path.hxx | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ cutl/fs/path.txx | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ cutl/makefile | 2 ++ 4 files changed, 213 insertions(+) create mode 100644 cutl/fs/path.cxx create mode 100644 cutl/fs/path.hxx create mode 100644 cutl/fs/path.txx (limited to 'cutl') 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 +// copyright : Copyright (c) 2009 Code Synthesis Tools CC +// license : MIT; see accompanying LICENSE file + +#include + +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 +// 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 +#include + +namespace cutl +{ + namespace fs + { + struct invalid_path: std::exception + { + virtual char const* + what () const throw (); + }; + + template + class basic_path; + + typedef basic_path path; + typedef basic_path wpath; + + template + class basic_path + { + public: + typedef std::basic_string 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 + inline std::basic_ostream& + operator<< (std::basic_ostream& os, basic_path const& p) + { + return os << p.string (); + } + } +} + +#include + +#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 +// copyright : Copyright (c) 2009 Code Synthesis Tools CC +// license : MIT; see accompanying LICENSE file + +namespace cutl +{ + namespace fs + { + template + basic_path basic_path:: + 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 + basic_path basic_path:: + 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 + basic_path basic_path:: + 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 + basic_path basic_path:: + operator/ (basic_path const& r) + { + if (r.path_.empty ()) + throw invalid_path (); + + basic_path x (*this); + x.path_ += '/'; + x.path_ += r.path_; + return x; + } + + template + void basic_path:: + 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 \ -- cgit v1.1