3 This file is part of libmspfs
4 Copyright © 2006-2008 Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
10 #include <msp/core/except.h>
14 #include <msp/strings/glob.h>
16 #include <msp/strings/utils.h>
27 string basename(const Path &p)
32 Path dirname(const Path &p)
40 return p.subpath(0, p.size()-1);
43 string basepart(const string &fn)
45 unsigned dot=fn.rfind('.');
46 return fn.substr(0, dot);
49 string extpart(const string &fn)
51 string::size_type dot=fn.rfind('.');
54 return fn.substr(dot);
57 Path fix_case(const Path &path)
61 for(Path::Iterator i=path.begin(); i!=path.end(); ++i)
69 files=list_files(result);
71 files=list_files(".");
74 for(list<string>::iterator j=files.begin(); (j!=files.end() && !found); ++j)
75 if(!strcasecmp(*j,*i))
89 Path readlink(const Path &link)
93 throw Exception("No symbolic links on win32");
96 int len=::readlink(link.str().c_str(), buf, sizeof(buf));
98 throw SystemError("readlink failed", errno);
99 return string(buf, len);
103 Path realpath(const Path &path)
106 if(path.is_absolute())
109 return getcwd()/path;
111 list<string> queue(path.begin(), path.end());
112 if(!path.is_absolute())
115 queue.insert(queue.begin(), cwd.begin(), cwd.end());
120 while(!queue.empty())
122 Path next=real/queue.front();
125 struct stat st=lstat(next);
126 if(S_ISLNK(st.st_mode))
129 throw Exception("Ludicrous amount of symlinks detected in realpath, giving up");
130 Path link=readlink(next);
131 queue.insert(queue.begin(), link.begin(), link.end());
141 void rename(const Path &from, const Path &to)
143 if(::rename(from.str().c_str(), to.str().c_str())==-1)
144 throw SystemError("rename failed", errno);
147 void unlink(const Path &path)
149 if(::unlink(path.str().c_str())==-1)
150 throw SystemError("unlink failed", errno);
153 Path relative(const Path &path, const Path &base)
155 Path::Iterator i=path.begin();
156 Path::Iterator j=base.begin();
157 for(; (i!=path.end() && j!=base.end() && *i==*j); ++i, ++j) ;
160 for(; j!=base.end(); ++j)
162 for(; i!=path.end(); ++i)
168 int descendant_depth(const Path &path, const Path &parent)
170 Path::Iterator i=path.begin();
171 Path::Iterator j=parent.begin();
172 for(; (i!=path.end() && j!=parent.end() && *i==*j); ++i, ++j) ;
178 for(; i!=path.end(); ++i)