2 This file is part of libmsppath
3 Copyright © 2006 Mikko Rasa, Mikkosoft Productions
4 Distributed under the LGPL
12 #include <msp/strings/glob.h>
14 #include <msp/strings/utils.h>
24 Fixes the case of the given path to match files / directories on the
25 filesystem. Intended to be used in programs that need to interact with
26 emulated Windows programs.
28 Path fix_case(const Path &path)
32 for(Path::iterator i=path.begin(); i!=path.end(); ++i)
40 files=list_files(result);
42 files=list_files(".");
45 for(list<string>::iterator j=files.begin(); (j!=files.end() && !found); ++j)
46 if(!strcasecmp(*j,*i))
61 Creates the given directory and any parent directories if needed.
63 @param path The path to create
64 @param mode Access mode for new directories
66 @return 0 on success, -1 on error
68 int mkpath(const Path &path, int mode)
71 for(Path::iterator i=path.begin(); i!=path.end(); ++i)
75 if(p.size()==1 && is_windows_drive(*i)) continue;
78 int err=stat(p.str().c_str(),&st);
81 if(!S_ISDIR(st.st_mode))
88 else if(errno!=ENOENT)
93 // The win32 version of this function doesn't take the mode argument. Go figure.
95 err=mkdir(p.str().c_str());
97 err=mkdir(p.str().c_str(),mode);
99 if(err==-1) return -1;
106 int rmdir(const Path &path, bool recursive)
110 list<string> files=list_files(path);
111 for(list<string>::iterator i=files.begin(); i!=files.end(); ++i)
115 stat(p.str().c_str(),&st);
117 if(S_ISDIR(st.st_mode))
120 err=unlink(p.str().c_str());
124 return rmdir(path.str().c_str());
128 Lists all files in a directory except the implied . and .. entries.
130 list<string> list_files(const Path &path)
133 DIR *dir=opendir(path.str().c_str());
136 while(dirent *de=readdir(dir))
138 const char *fn=de->d_name;
139 if(fn[0]=='.' && (fn[1]==0 || (fn[1]=='.' && fn[2]==0)))
141 result.push_back(fn);
148 bool exists(const Path &path)
151 return !stat(path.str().c_str(), &st);
154 Filename splitext(const string &fn)
157 unsigned dot=fn.rfind('.');
158 result.base=fn.substr(0, dot);
159 if(dot!=string::npos)
160 result.ext=fn.substr(dot);
164 int fnmatch(const string &pat, const Path &fn)
167 return globcasematch(pat, fn.str());
169 return ::fnmatch(pat.c_str(), fn.str().c_str(), FNM_PATHNAME);
173 Path relative(const Path &path, const Path &base)
175 Path::iterator i=path.begin();
176 Path::iterator j=base.begin();
177 for(; (i!=path.end() && j!=base.end() && *i==*j); ++i,++j);
180 for(; j!=base.end(); ++j)
182 for(; i!=path.end(); ++i)
189 Extracts the basename from the given path. Same thing as Path::Path(p)[-1],
192 string basename(const std::string &p)
194 unsigned slash=p.rfind(DIRCHAR);
195 if(slash==string::npos)
198 return p.substr(slash+1);