7 #include <msp/core/systemerror.h>
8 #include <msp/strings/utils.h>
19 string basename(const Path &p)
24 Path dirname(const Path &p)
32 return p.subpath(0, p.size()-1);
35 string basepart(const string &fn)
37 unsigned dot = fn.rfind('.');
38 return fn.substr(0, dot);
41 string extpart(const string &fn)
43 string::size_type dot = fn.rfind('.');
46 return fn.substr(dot);
49 Path fix_case(const Path &path)
53 for(Path::Iterator i=path.begin(); i!=path.end(); ++i)
61 files = list_files(result);
63 files = list_files(".");
66 for(list<string>::iterator j=files.begin(); (j!=files.end() && !found); ++j)
67 if(!strcasecmp(*j,*i))
81 Path readlink(const Path &link)
85 throw logic_error("no symbolic links on win32");
88 int len = ::readlink(link.str().c_str(), buf, sizeof(buf));
90 throw system_error("readlink");
91 return string(buf, len);
95 Path realpath(const Path &path)
98 if(path.is_absolute())
101 return getcwd()/path;
103 list<string> queue(path.begin(), path.end());
104 if(!path.is_absolute())
107 queue.insert(queue.begin(), cwd.begin(), cwd.end());
111 unsigned n_links = 0;
112 while(!queue.empty())
114 Path next = real/queue.front();
120 throw runtime_error("too many symbolic links");
121 Path link = readlink(next);
122 queue.insert(queue.begin(), link.begin(), link.end());
132 void rename(const Path &from, const Path &to)
135 if(!MoveFileEx(from.c_str(), to.c_str(), MOVEFILE_REPLACE_EXISTING))
136 throw system_error("MoveFileEx");
138 if(::rename(from.str().c_str(), to.str().c_str())==-1)
139 throw system_error("rename");
143 void unlink(const Path &path)
146 if(!DeleteFile(path.c_str()))
147 throw system_error("DeleteFile");
149 if(::unlink(path.str().c_str())==-1)
150 throw system_error("unlink");
154 Path relative(const Path &path, const Path &base)
156 Path::Iterator i = path.begin();
157 Path::Iterator j = base.begin();
158 for(; (i!=path.end() && j!=base.end() && *i==*j); ++i, ++j) ;
161 for(; j!=base.end(); ++j)
163 for(; i!=path.end(); ++i)
169 Path common_ancestor(const Path &path1, const Path &path2)
171 Path::Iterator i = path1.begin();
172 Path::Iterator j = path2.begin();
174 for(; (i!=path1.end() && j!=path2.end() && *i==*j); ++i, ++j)
179 int descendant_depth(const Path &path, const Path &parent)
181 Path::Iterator i = path.begin();
182 Path::Iterator j = parent.begin();
183 for(; (i!=path.end() && j!=parent.end() && *i==*j); ++i, ++j) ;
189 for(; i!=path.end(); ++i)