X-Git-Url: http://git.tdb.fi/?p=libs%2Fcore.git;a=blobdiff_plain;f=source%2Ffs%2Futils.cpp;h=7ceb7adae843e149c3c05dd6d464d9b2e0bd9396;hp=a34dd4e54ca86d6baf72a877cea30d6daa959c91;hb=HEAD;hpb=9ef362fabde5092288a8f59e6dae503c83a9462c diff --git a/source/fs/utils.cpp b/source/fs/utils.cpp index a34dd4e..7ceb7ad 100644 --- a/source/fs/utils.cpp +++ b/source/fs/utils.cpp @@ -1,12 +1,5 @@ -#include -#ifndef WIN32 -#include -#endif -#include #include #include "dir.h" -#include "path.h" -#include "stat.h" #include "utils.h" using namespace std; @@ -16,11 +9,13 @@ namespace FS { string basename(const Path &p) { - return p[-1]; + return p.empty() ? string() : p[-1]; } Path dirname(const Path &p) { + if(p.empty()) + return p; if(p.size()==1) { if(p.is_absolute()) @@ -48,101 +43,41 @@ Path fix_case(const Path &path) { bool found = true; Path result; - for(Path::Iterator i=path.begin(); i!=path.end(); ++i) + for(const string &c: path) { - if(!found || *i=="/") - result /= *i; + if(!found || (result.empty() && (c=="/" || c=="."))) + result /= c; else { - list files; + vector files; if(result.size()) files = list_files(result); else files = list_files("."); found = false; - for(list::iterator j=files.begin(); (j!=files.end() && !found); ++j) - if(!strcasecmp(*j,*i)) + for(const string &f: files) + if(!strcasecmp(f, c)) { - result /= *j; + result /= f; found = true; } if(!found) - result /= *i; + result /= c; } } return result; } -Path readlink(const Path &link) -{ -#ifdef WIN32 - (void)link; - throw logic_error("no symbolic links on win32"); -#else - char buf[4096]; - int len = ::readlink(link.str().c_str(), buf, sizeof(buf)); - if(len==-1) - throw system_error("readlink"); - return string(buf, len); -#endif -} - -Path realpath(const Path &path) -{ -#ifdef WIN32 - if(path.is_absolute()) - return path; - else - return getcwd()/path; -#else - list queue(path.begin(), path.end()); - if(!path.is_absolute()) - { - Path cwd = getcwd(); - queue.insert(queue.begin(), cwd.begin(), cwd.end()); - } - - Path real; - unsigned n_links = 0; - while(!queue.empty()) - { - Path next = real/queue.front(); - queue.pop_front(); - - if(is_link(next)) - { - if(++n_links>64) - throw runtime_error("too many symbolic links"); - Path link = readlink(next); - queue.insert(queue.begin(), link.begin(), link.end()); - } - else - real = next; - } - - return real; -#endif -} - -void rename(const Path &from, const Path &to) -{ - if(::rename(from.str().c_str(), to.str().c_str())==-1) - throw system_error("rename"); -} - -void unlink(const Path &path) -{ - if(::unlink(path.str().c_str())==-1) - throw system_error("unlink"); -} - Path relative(const Path &path, const Path &base) { - Path::Iterator i = path.begin(); - Path::Iterator j = base.begin(); + if(path.is_absolute()!=base.is_absolute()) + throw invalid_argument("FS::relative"); + + auto i = path.begin(); + auto j = base.begin(); for(; (i!=path.end() && j!=base.end() && *i==*j); ++i, ++j) ; Path result; @@ -154,10 +89,23 @@ Path relative(const Path &path, const Path &base) return result; } +Path common_ancestor(const Path &path1, const Path &path2) +{ + auto i = path1.begin(); + auto j = path2.begin(); + Path result; + for(; (i!=path1.end() && j!=path2.end() && *i==*j); ++i, ++j) + result /= *i; + return result; +} + int descendant_depth(const Path &path, const Path &parent) { - Path::Iterator i = path.begin(); - Path::Iterator j = parent.begin(); + if(path.is_absolute()!=parent.is_absolute()) + throw invalid_argument("FS::descendant_depth"); + + auto i = path.begin(); + auto j = parent.begin(); for(; (i!=path.end() && j!=parent.end() && *i==*j); ++i, ++j) ; if(j!=parent.end())