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, ':');
#endif
}
-Path get_sys_conf_dir(const Path &argv0)
+Path get_sys_conf_dir(const string &argv0)
{
Path dir=get_bin_dir(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);
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 &);
Distributed under the LGPL
*/
+#include <msp/core/except.h>
#include <msp/strings/utils.h>
#include "path.h"
#include "utils.h"
}
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
#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)
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;
#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: