X-Git-Url: http://git.tdb.fi/?p=libs%2Fcore.git;a=blobdiff_plain;f=source%2Futils.cpp;h=5c8c8d4cdd08e899336b2bf8d15b3f0170a5be2b;hp=bae91cc50898ad83838749f58987a9c3a182d61a;hb=f91f1df3e0b00b3a270e571d4b2c8251da4d1226;hpb=6f4ac56492d45c04df0f205252b3c3210e319b4f diff --git a/source/utils.cpp b/source/utils.cpp index bae91cc..5c8c8d4 100644 --- a/source/utils.cpp +++ b/source/utils.cpp @@ -1,22 +1,26 @@ -/* -This file is part of libmsppath -Copyright © 2006 Mikko Rasa, Mikkosoft Productions +/* $Id$ + +This file is part of libmspfs +Copyright © 2006-2008 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ -#include -#include -#include + +#include +#include #ifndef WIN32 #include +#else +#include #endif -#include +#include +#include "dir.h" #include "path.h" #include "utils.h" using namespace std; namespace Msp { -namespace Path { +namespace FS { /** Fixes the case of the given path to match files / directories on the @@ -27,7 +31,7 @@ Path fix_case(const Path &path) { 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; @@ -55,106 +59,58 @@ Path fix_case(const Path &path) return result; } -int mkpath(const Path &path, int mode) -{ - Path p; - for(Path::iterator i=path.begin(); i!=path.end(); ++i) - { - p/=*i; -#ifdef WIN32 - if(p.size()==1 && is_windows_drive(*i)) continue; -#endif - struct stat st; - int err=stat(p.str().c_str(),&st); - if(err==0) - { - if(!S_ISDIR(st.st_mode)) - { - errno=EEXIST; - return -1; - } - continue; - } - else if(errno!=ENOENT) - return -1; - else - { -#ifdef WIN32 - // The win32 version of this function doesn't take the mode argument. Go figure. - err=mkdir(p.str().c_str()); -#else - err=mkdir(p.str().c_str(),mode); -#endif - if(err==-1) return -1; - } - } - - return 0; -} - -int rmdir(const Path &path, bool recursive) -{ - if(recursive) - { - list files=list_files(path); - for(list::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; - } - } - return rmdir(path.str().c_str()); -} - -/** -Lists all files in a directory except the implied . and .. entries. -*/ -list list_files(const Path &path) -{ - list result; - DIR *dir=opendir(path.str().c_str()); - if(dir) - { - while(dirent *de=readdir(dir)) - { - const char *fn=de->d_name; - if(fn[0]=='.' && (fn[1]==0 || (fn[1]=='.' && fn[2]==0))) continue; - result.push_back(fn); - } - closedir(dir); - } - return result; -} - -bool exists(const Path &path) +void unlink(const Path &path) { - struct stat st; - return !stat(path.str().c_str(),&st); + if(::unlink(path.str().c_str())==-1) + throw SystemError("unlink failed", errno); } 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 FS } // namespace Msp