-/*
+/* $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
using namespace std;
namespace Msp {
-namespace Path {
/**
Fixes the case of the given path to match files / directories on the
{
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;
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(p, st);
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;
}
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)
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;
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