#include <errno.h>
#ifndef WIN32
#include <fnmatch.h>
+#else
+#include <msp/strings/glob.h>
#endif
-#include <msp/strutils.h>
+#include <msp/strings/utils.h>
#include "path.h"
#include "utils.h"
return result;
}
+/**
+Creates the given 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)
{
Path p;
{
#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);
while(dirent *de=readdir(dir))
{
const char *fn=de->d_name;
- if(fn[0]=='.' && (fn[1]==0 || (fn[1]=='.' && fn[2]==0))) continue;
+ if(fn[0]=='.' && (fn[1]==0 || (fn[1]=='.' && fn[2]==0)))
+ continue;
result.push_back(fn);
}
closedir(dir);
bool exists(const Path &path)
{
struct stat st;
- return !stat(path.str().c_str(),&st);
+ return !stat(path.str().c_str(), &st);
}
Filename splitext(const string &fn)
{
Filename result;
unsigned dot=fn.rfind('.');
- result.base=fn.substr(0,dot);
+ result.base=fn.substr(0, dot);
if(dot!=string::npos)
result.ext=fn.substr(dot);
return result;
}
-#ifndef WIN32
int fnmatch(const string &pat, const Path &fn)
{
+#ifdef WIN32
+ return globcasematch(pat, fn.str());
+#else
return ::fnmatch(pat.c_str(), fn.str().c_str(), FNM_PATHNAME);
-}
#endif
+}
+
+Path relative(const Path &path, const Path &base)
+{
+ Path::iterator i=path.begin();
+ Path::iterator j=base.begin();
+ for(; (i!=path.end() && j!=base.end() && *i==*j); ++i,++j);
+
+ Path result;
+ for(; j!=base.end(); ++j)
+ result/="..";
+ for(; i!=path.end(); ++i)
+ result/=*i;
+
+ return result;
+}
+
+/**
+Extracts the basename from the given path. Same thing as Path::Path(p)[-1],
+but faster.
+*/
+string basename(const std::string &p)
+{
+ unsigned slash=p.rfind(DIRCHAR);
+ if(slash==string::npos)
+ return p;
+ else
+ return p.substr(slash+1);
+}
} // namespace Path
} // namespace Msp