Make Path behave more consistently by always starting relative paths with a dot
authorMikko Rasa <tdb@tdb.fi>
Fri, 11 Sep 2009 15:58:51 +0000 (15:58 +0000)
committerMikko Rasa <tdb@tdb.fi>
Fri, 11 Sep 2009 15:58:51 +0000 (15:58 +0000)
Treat out-of-range index to Path::operator[] as an error
Change argv0 parameter of get_sys_*_dir to std::string

source/dir.cpp
source/dir.h
source/path.cpp
source/path.h

index 09a89f1f1f29def46e0de231deb6a309a0669140..29c24c188fa96b7d76763b9b1ab5ad4a8aa3de53 100644 (file)
@@ -32,15 +32,15 @@ namespace
 Helper function to determine the location of the program's executable.  Caches
 the last result to cut down filesystem access with repeated calls.
 */
-const Path &get_bin_dir(const Path &argv0)
+const Path &get_bin_dir(const string &argv0)
 {
-       static Path last_argv0;
+       static string last_argv0;
        static Path bin_dir;
 
        if(!(argv0==last_argv0))
        {
                Path exe;
-               if(argv0.size()==1)
+               if(argv0.find('/')==string::npos)
                {
                        const char *path=getenv("PATH");
                        vector<string> dirs=split(path, ':');
@@ -184,7 +184,7 @@ Path get_user_data_dir(const string &appname)
 #endif
 }
 
-Path get_sys_conf_dir(const Path &argv0)
+Path get_sys_conf_dir(const string &argv0)
 {
        Path dir=get_bin_dir(argv0);
 
@@ -199,7 +199,7 @@ Path get_sys_conf_dir(const Path &argv0)
                return dir;
 }
 
-Path get_sys_data_dir(const Path &argv0, const string &appname)
+Path get_sys_data_dir(const string &argv0, const string &appname)
 {
        Path dir=get_bin_dir(argv0);
 
index 30ef33dbeed4120747759f23cc71882e47bf5459..ebbe56c553a5e8cd207f18240e3a0bf474e4e684 100644 (file)
@@ -43,10 +43,10 @@ Path get_home_dir();
 Path get_user_data_dir(const std::string &appname);
 
 /// Returns a directory containing system-wide configuration
-Path get_sys_conf_dir(const Path &argv0);
+Path get_sys_conf_dir(const std::string &argv0);
 
 /// Returns a directory containing immutable system-wide data
-Path get_sys_data_dir(const Path &argv0, const std::string &appname);
+Path get_sys_data_dir(const std::string &argv0, const std::string &appname);
 
 /// Changes the current working directory
 void chdir(const Path &);
index c0b91d6c82f8321df9c31acd1e045bd026a08304..5424cb1c79e31936a7628cef52a85f1eb74306d0 100644 (file)
@@ -5,6 +5,7 @@ Copyright © 2006-2008  Mikko Rasa, Mikkosoft Productions
 Distributed under the LGPL
 */
 
+#include <msp/core/except.h>
 #include <msp/strings/utils.h>
 #include "path.h"
 #include "utils.h"
@@ -106,16 +107,15 @@ string Path::operator[](int n) const
        }
        else
        {
-               for(Iterator i=--end();; --i)
+               for(Iterator i=end(); i!=begin();)
                {
+                       --i;
                        if(!++n)
                                return *i;
-                       if(i==begin())
-                               break;
                }
        }
 
-       return string();
+       throw InvalidParameterValue("Path component index out of range");
 }
 
 bool Path::operator==(const Path &p) const
@@ -180,7 +180,7 @@ void Path::add_component(const string &comp)
 #endif
        else if(comp=="..")
        {
-               if(path.empty())
+               if(path.empty() || path==".")
                        path=comp;
                // .. in root directory is a no-op
                else if(path.size()==1 && path[0]==DIRSEP)
@@ -199,15 +199,21 @@ void Path::add_component(const string &comp)
                                path+=DIRSEP;
                                path+=comp;
                        }
+                       else if(slash==string::npos)
+                               path=".";
                        else
+                       {
+                               if(slash==0)
+                                       slash=1;
                                // Otherwise, erase the last component
                                path.erase(slash, string::npos);
+                       }
                }
        }
        else if(comp!="." || path.empty())
        {
-               if(path==".")
-                       path="";
+               if(comp!="." && path.empty())
+                       path=".";
                if(path.size()>1 || (path.size()==1 && path[0]!=DIRSEP))
                        path+=DIRSEP;
                path+=comp;
index 8c24f191394e5198d14fd7222f54f3c7bf1a6df6..751c0e3d2f66a3580e590402322d4a6aa1fb6af6 100644 (file)
@@ -23,6 +23,11 @@ enum
 #endif
 };
 
+/**
+Stores a filesystem path.  Paths are always stored in a normalized form; there
+are never any "." or ".." components in the middle of the path, and relative
+paths always begin with a single "." component or a sequence ".." components.
+*/
 class Path
 {
 public: