From 9c48f72f02e3112f4193cc8b3f12b135aa483de1 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Fri, 11 Sep 2009 15:58:51 +0000 Subject: [PATCH] Make Path behave more consistently by always starting relative paths with a dot Treat out-of-range index to Path::operator[] as an error Change argv0 parameter of get_sys_*_dir to std::string --- source/dir.cpp | 10 +++++----- source/dir.h | 4 ++-- source/path.cpp | 20 +++++++++++++------- source/path.h | 5 +++++ 4 files changed, 25 insertions(+), 14 deletions(-) diff --git a/source/dir.cpp b/source/dir.cpp index 09a89f1..29c24c1 100644 --- a/source/dir.cpp +++ b/source/dir.cpp @@ -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 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); diff --git a/source/dir.h b/source/dir.h index 30ef33d..ebbe56c 100644 --- a/source/dir.h +++ b/source/dir.h @@ -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 &); diff --git a/source/path.cpp b/source/path.cpp index c0b91d6..5424cb1 100644 --- a/source/path.cpp +++ b/source/path.cpp @@ -5,6 +5,7 @@ Copyright © 2006-2008 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ +#include #include #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; diff --git a/source/path.h b/source/path.h index 8c24f19..751c0e3 100644 --- a/source/path.h +++ b/source/path.h @@ -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: -- 2.43.0