Get rid of the Path namespace
authorMikko Rasa <tdb@tdb.fi>
Sat, 22 Sep 2007 10:53:35 +0000 (10:53 +0000)
committerMikko Rasa <tdb@tdb.fi>
Sat, 22 Sep 2007 10:53:35 +0000 (10:53 +0000)
Redesign utility function so that they throw on error
Add a couple utility functions
Add Id tags

Build
source/path.cpp
source/path.h
source/utils.cpp
source/utils.h

diff --git a/Build b/Build
index 658679200591aa63b26ccfe2af058afb9fc253c4..04490594263506c819efa0430d94b7da488cda4b 100644 (file)
--- a/Build
+++ b/Build
@@ -1,3 +1,5 @@
+/* $Id$ */
+
 package "msppath"
 {
        version "0.1";
index 4f3a0b1547c3ea94018feac0c4bbd3bbbbfe77eb..25c9b170c9460b8d8bcc3bb504285a51119ec8cf 100644 (file)
@@ -1,8 +1,10 @@
-/*
+/* $Id$
+
 This file is part of libmsppath
-Copyright © 2006  Mikko Rasa, Mikkosoft Productions
+Copyright © 2006-2007  Mikko Rasa, Mikkosoft Productions
 Distributed under the LGPL
 */
+
 #include <msp/strings/utils.h>
 #include "path.h"
 #include "utils.h"
@@ -10,15 +12,17 @@ Distributed under the LGPL
 using namespace std;
 
 namespace Msp {
-namespace Path {
 
 /**
 Returns the number of components in the path.
 */
 unsigned Path::size() const
 {
-       if(!path.size()) return 0;
-       if(path.size()==1 && path[0]==DIRCHAR) return 1;
+       if(path.empty())
+               return 0;
+       if(path.size()==1 && path[0]==DIRCHAR)
+               return 1;
+
        unsigned count=1;
        for(string::const_iterator i=path.begin(); i!=path.end(); ++i)
                if(*i==DIRCHAR) ++count;
@@ -28,9 +32,11 @@ unsigned Path::size() const
 bool Path::is_absolute() const
 {
 #ifdef WIN32
-       if(is_windows_drive((*this)[0])) return true;
+       if(is_windows_drive((*this)[0]))
+               return true;
 #endif
-       if(path[0]==DIRCHAR) return true;
+       if(path[0]==DIRCHAR)
+               return true;
        return false;
 }
 
@@ -40,7 +46,7 @@ Extracts the given component range from the path.
 Path Path::subpath(unsigned start, unsigned count) const
 {
        Path result;
-       iterator i=begin();
+       Iterator i=begin();
        for(unsigned j=0; (j<start && i!=end()); ++j)
                ++i;
        for(unsigned j=0; (j<count && i!=end()); ++j)
@@ -62,7 +68,7 @@ Path &Path::operator/=(const Path &p)
                path=p.path;
        else
        {
-               for(iterator i=p.begin(); i!=p.end(); ++i)
+               for(Iterator i=p.begin(); i!=p.end(); ++i)
                        add_component(*i);
        }
        return *this;
@@ -76,12 +82,12 @@ string Path::operator[](int n) const
 {
        if(n>=0)
        {
-               for(iterator i=begin(); i!=end(); ++i,--n)
+               for(Iterator i=begin(); i!=end(); ++i, --n)
                        if(!n) return *i;
        }
        else
        {
-               for(iterator i=--end();; --i)
+               for(Iterator i=--end();; --i)
                {
                        if(!++n) return *i;
                        if(i==begin()) break;
@@ -107,11 +113,9 @@ void Path::init(const string &p)
                add_component(string(1, DIRCHAR));
        while(1)
        {
-               unsigned slash=p.find_first_of("/\\",start);
+               unsigned slash=p.find_first_of("/\\", start);
                if(slash>start)
-               {
                        add_component(p.substr(start, slash-start));
-               }
                if(slash==string::npos)
                        break;
                start=slash+1;
@@ -131,7 +135,7 @@ void Path::add_component(const string &comp)
 #ifdef WIN32
                unsigned slash=path.find(DIRCHAR);
                if(is_windows_drive(path.substr(0, slash)))
-                       path=path.substr(0,2);
+                       path=path.substr(0, 2);
                else
 #endif
                path=comp;
@@ -176,7 +180,7 @@ void Path::add_component(const string &comp)
        }
 }
 
-Path::iterator::iterator(const Path &p):
+Path::Iterator::Iterator(const Path &p):
        path(p),
        start(0)
 {
@@ -185,28 +189,28 @@ Path::iterator::iterator(const Path &p):
        else if(path.path[0]==DIRCHAR)
                end=1;
 #ifdef WIN32
-       else if(path.path.size()>2 && path.path[2]==DIRCHAR && is_windows_drive(path.path.substr(0,2)))
+       else if(path.path.size()>2 && path.path[2]==DIRCHAR && is_windows_drive(path.path.substr(0, 2)))
                end=2;
 #endif
        else
                end=path.path.find(DIRCHAR);
 }
 
-Path::iterator &Path::iterator::operator++()
+Path::Iterator &Path::Iterator::operator++()
 {
        start=end;
        if(start>=path.path.size()) return *this;
        if(path.path[start]==DIRCHAR) ++start;
-       end=path.path.find(DIRCHAR,start);
+       end=path.path.find(DIRCHAR, start);
        return *this;
 }
 
-Path::iterator &Path::iterator::operator--()
+Path::Iterator &Path::Iterator::operator--()
 {
        end=start;
        if(end==0) return *this;
        if(end>1 && end<path.path.size() && path.path[end]!=DIRCHAR) --end;
-       start=path.path.rfind(DIRCHAR,end-1);
+       start=path.path.rfind(DIRCHAR, end-1);
        if(start==string::npos)
                start=0;
        else if(start<end-1)
@@ -214,12 +218,11 @@ Path::iterator &Path::iterator::operator--()
        return *this;
 }
 
-string Path::iterator::operator*() const
+string Path::Iterator::operator*() const
 {
        if(start>=path.path.size()) return "";
        if(start==end) return "";
-       return path.path.substr(start,end-start);
+       return path.path.substr(start, end-start);
 }
 
-} // namespace Path
 } // namespace Msp
index 6662a8c20a875856c347d6488747f9c515ecdb5f..1da6a934cd800874107503ab0fea7d259061f951 100644 (file)
@@ -1,8 +1,10 @@
-/*
+/* $Id$
+
 This file is part of libmsppath
-Copyright © 2006  Mikko Rasa, Mikkosoft Productions
+Copyright © 2006-2007  Mikko Rasa, Mikkosoft Productions
 Distributed under the LGPL
 */
+
 #ifndef MSP_PATH_PATH_H_
 #define MSP_PATH_PATH_H_
 
@@ -10,7 +12,6 @@ Distributed under the LGPL
 #include <string>
 
 namespace Msp {
-namespace Path {
 
 enum
 {
@@ -24,19 +25,19 @@ enum
 class Path
 {
 public:
-       class iterator
+       class Iterator
        {
        public:
-               iterator    &operator++();
-               iterator    &operator--();
+               Iterator    &operator++();
+               Iterator    &operator--();
                std::string operator*() const;
-               bool        operator==(const iterator &i) const { return (start==i.start && end==i.end); }
-               bool        operator!=(const iterator &i) const { return !(*this==i); }
+               bool        operator==(const Iterator &i) const { return (start==i.start && end==i.end); }
+               bool        operator!=(const Iterator &i) const { return !(*this==i); }
        private:
                const Path &path;
                unsigned   start,end;
 
-               iterator(const Path &);
+               Iterator(const Path &);
 
                friend class Path;
        };
@@ -53,8 +54,8 @@ public:
        Path        &operator/=(const Path &);
        std::string operator[](int) const;
        bool        operator==(const Path &) const;
-       iterator    begin() const { return iterator(*this); }
-       iterator    end() const   { iterator i(*this); i.start=i.end=std::string::npos; return i; }
+       Iterator    begin() const { return Iterator(*this); }
+       Iterator    end() const   { Iterator i(*this); i.start=i.end=std::string::npos; return i; }
 private:
        std::string path;
 
@@ -64,7 +65,6 @@ private:
 
 inline std::ostream &operator<<(std::ostream &o, const Path &p) { o<<p.str(); return o; }
 
-} // namespace Path
 } // namespace Msp
 
 #endif
index 31ab53be7b2ed210cf66dd9f2996972f0d33b25f..acf7dcd1f66516a04ca8fdc928dc1ee0da4f513c 100644 (file)
@@ -1,11 +1,13 @@
-/*
+/* $Id$
+
 This file is part of libmsppath
-Copyright © 2006  Mikko Rasa, Mikkosoft Productions
+Copyright © 2006-2007  Mikko Rasa, Mikkosoft Productions
 Distributed under the LGPL
 */
+
 #include <dirent.h>
-#include <sys/stat.h>
 #include <errno.h>
+#include <msp/core/error.h>
 #ifndef WIN32
 #include <fnmatch.h>
 #else
@@ -18,7 +20,6 @@ Distributed under the LGPL
 using namespace std;
 
 namespace Msp {
-namespace Path {
 
 /**
 Fixes the case of the given path to match files / directories on the
@@ -29,7 +30,7 @@ Path fix_case(const Path &path)
 {
        bool found=true;
        Path result;
-       for(Path::iterator i=path.begin(); i!=path.end(); ++i)
+       for(Path::Iterator i=path.begin(); i!=path.end(); ++i)
        {
                if(!found || *i=="/")
                        result/=*i;
@@ -57,76 +58,82 @@ Path fix_case(const Path &path)
        return result;
 }
 
+void mkdir(const Path &path, int mode)
+{
+       int err;
+#ifdef WIN32
+       // The win32 version of this function doesn't take the mode argument.  Go figure.
+       (void)mode;
+       err=::mkdir(path.str().c_str());
+#else
+       err=::mkdir(path.str().c_str(), mode);
+#endif
+
+       if(err==-1)
+               throw SystemError("mkdir failed", errno);
+}
+
 /**
-Creates the given directory and any parent directories if needed.
+Creates a directory and any parent directories if needed.
 
 @param   path  The path to create
 @param   mode  Access mode for new directories
 
 @return  0 on success, -1 on error
 */
-int mkpath(const Path &path, int mode)
+void mkpath(const Path &path, int mode)
 {
        Path p;
-       for(Path::iterator i=path.begin(); i!=path.end(); ++i)
+       for(Path::Iterator i=path.begin(); i!=path.end(); ++i)
        {
                p/=*i;
 #ifdef WIN32
-               if(p.size()==1 && is_windows_drive(*i)) continue;
+               if(p.size()==1 && is_windows_drive(*i))
+                       continue;
 #endif
                struct stat st;
-               int err=stat(p.str().c_str(),&st);
+               int err=stat(pst);
                if(err==0)
                {
                        if(!S_ISDIR(st.st_mode))
-                       {
-                               errno=EEXIST;
-                               return -1;
-                       }
+                               throw Exception("A component exists and is not a directory");
                        continue;
                }
                else if(errno!=ENOENT)
-                       return -1;
+                       throw SystemError("stat failed", errno);
                else
-               {
-#ifdef WIN32
-                       // The win32 version of this function doesn't take the mode argument.  Go figure.
-                       (void)mode;
-                       err=mkdir(p.str().c_str());
-#else
-                       err=mkdir(p.str().c_str(),mode);
-#endif
-                       if(err==-1) return -1;
-               }
+                       mkdir(p, mode);
        }
+}
 
-       return 0;
+void rmdir(const Path &path)
+{
+       if(::rmdir(path.str().c_str())==-1)
+               throw SystemError("rmdir failed", errno);
 }
 
-int rmdir(const Path &path, bool recursive)
+void rmdirs(const Path &path)
 {
-       if(recursive)
+       list<string> files=list_files(path);
+       for(list<string>::iterator i=files.begin(); i!=files.end(); ++i)
        {
-               list<string> files=list_files(path);
-               for(list<string>::iterator i=files.begin(); i!=files.end(); ++i)
-               {
-                       Path p=path/ *i;
-                       struct stat st;
-                       stat(p.str().c_str(),&st);
-                       int err=0;
-                       if(S_ISDIR(st.st_mode))
-                               err=rmdir(p,true);
-                       else
-                               err=unlink(p.str().c_str());
-                       if(err) return err;
-               }
+               Path p=path / *i;
+               struct stat st=stat(p.str().c_str());
+               if(S_ISDIR(st.st_mode))
+                       rmdirs(p);
+               else
+                       unlink(p);
        }
-       return rmdir(path.str().c_str());
+
+       rmdir(path);
+}
+
+void unlink(const Path &path)
+{
+       if(::unlink(path.str().c_str())==-1)
+               throw SystemError("unlink failed", errno);
 }
 
-/**
-Lists all files in a directory except the implied . and .. entries.
-*/
 list<string> list_files(const Path &path)
 {
        list<string> result;
@@ -142,13 +149,13 @@ list<string> list_files(const Path &path)
                }
                closedir(dir);
        }
+
        return result;
 }
 
 bool exists(const Path &path)
 {
-       struct stat st;
-       return !stat(path.str().c_str(), &st);
+       return access(path.str().c_str(), F_OK)==0;
 }
 
 Filename splitext(const string &fn)
@@ -172,8 +179,8 @@ int fnmatch(const string &pat, const Path &fn)
 
 Path relative(const Path &path, const Path &base)
 {
-       Path::iterator i=path.begin();
-       Path::iterator j=base.begin();
+       Path::Iterator i=path.begin();
+       Path::Iterator j=base.begin();
        for(; (i!=path.end() && j!=base.end() && *i==*j); ++i,++j);
 
        Path result;
@@ -198,5 +205,23 @@ string basename(const std::string &p)
                return p.substr(slash+1);
 }
 
-} // namespace Path
+int stat(const Path &fn, struct stat &st)
+{
+       return ::stat(fn.str().c_str(), &st);
+}
+
+struct stat stat(const Path &fn)
+{
+       struct stat st;
+       if(stat(fn, st)==-1)
+               throw SystemError("stat failed", errno);
+       return st;
+}
+
+Path getcwd()
+{
+       char buf[1024];
+       return ::getcwd(buf, sizeof(buf));
+}
+
 } // namespace Msp
index 2b2f23cba6cc2168ccd0c61a4a4bfe92f58bf60a..47efcacd9ddb24e299411793ca745ada759ac829 100644 (file)
@@ -1,19 +1,20 @@
-/*
+/* $Id$
+
 This file is part of libmsppath
-Copyright © 2006  Mikko Rasa, Mikkosoft Productions
+Copyright © 2006-2007  Mikko Rasa, Mikkosoft Productions
 Distributed under the LGPL
 */
+
 #ifndef MSP_PATH_UTILS_H_
 #define MSP_PATH_UTILS_H_
 
 #include <sys/stat.h>
-#include <unistd.h>
 #include <list>
 #include <string>
-#include "path.h"
 
 namespace Msp {
-namespace Path {
+
+class Path;
 
 struct Filename
 {
@@ -21,26 +22,55 @@ struct Filename
        std::string ext;
 };
 
-extern Path fix_case(const Path &);
-extern int mkpath(const Path &, int);
-extern int rmdir(const Path &, bool =false);
-extern std::list<std::string> list_files(const Path &);
-extern bool exists(const Path &);
-extern Filename splitext(const std::string &);
-extern int fnmatch(const std::string &, const Path &);
-extern Path relative(const Path &, const Path &);
-extern std::string basename(const std::string &);
+Path fix_case(const Path &path);
+
+/// Creates a directory
+void mkdir(const Path &path, int mode);
+
+/// Creates a directory and any required parent directories
+void mkpath(const Path &path, int mode);
+
+/// Removes a directory
+void rmdir(const Path &path);
+
+/// Removes a directory and anything it contains
+void rmdirs(const Path &path);
+
+/// Removes a file
+void unlink(const Path &path);
 
-inline int stat(const Path &fn, struct stat &st)
-{ return ::stat(fn.str().c_str(), &st); }
+/// Lists the contents of a directory
+std::list<std::string> list_files(const Path &path);
+
+Filename splitext(const std::string &);
+int fnmatch(const std::string &, const Path &);
+
+/// Makes a path relative to some base path.  That is, base/result==path.
+Path relative(const Path &path, const Path &base);
+
+std::string basename(const std::string &);
+
+/// Tests for existence of a file
+bool exists(const Path &path);
+
+/**
+Gets information about a file.  Returns 0 on success or -1 on error.  This
+version can be used to check for file existence and get information in one
+call.
+*/
+int stat(const Path &fn, struct stat &st);
+
+/**
+Returns information about a file.  This version throws an exception if an error
+occurs.
+*/
+struct stat stat(const Path &fn);
 
-inline Path getcwd()
-{ char buf[1024]; return ::getcwd(buf, sizeof(buf)); }
+Path getcwd();
 
 inline bool is_windows_drive(const std::string &p)
 { return (p.size()==2 && ((p[0]>='A' && p[0]<='Z') || (p[0]>='a' && p[0]<='z')) && p[1]==':'); }
 
-} // namespace Path
 } // namespace Msp
 
 #endif