10 #include <msp/core/systemerror.h>
11 #include <msp/strings/regex.h>
12 #include <msp/strings/utils.h>
26 /** Helper function to determine the location of the program's executable.
27 Caches the last result to cut down filesystem access with repeated calls. */
28 const Path &get_bin_dir(const string &argv0)
30 static string last_argv0;
33 if(!(argv0==last_argv0))
36 if(argv0.find('/')==string::npos)
38 const char *path = getenv("PATH");
39 vector<string> dirs = split(path, ':');
40 for(vector<string>::const_iterator i=dirs.begin(); i!=dirs.end(); ++i)
41 if(exists(Path(*i)/argv0))
43 exe = realpath(Path(*i)/argv0);
48 exe = realpath(argv0);
51 bin_dir = dirname(exe);
60 not_a_directory::not_a_directory(const Path &p):
61 runtime_error(p.str())
65 void mkdir(const Path &path, int mode)
69 if(!CreateDirectory(path.str().c_str(), NULL))
70 throw system_error("CreateDirectory");
72 if(::mkdir(path.str().c_str(), mode)==-1)
73 throw system_error("mkdir");
77 void mkpath(const Path &path, int mode)
80 for(Path::Iterator i=path.begin(); i!=path.end(); ++i)
84 if(p.size()==1 && p.is_absolute())
87 if(FS::Stat st = stat(p))
89 if(!st.is_directory())
90 throw not_a_directory(p);
98 void rmdir(const Path &path)
101 if(!RemoveDirectory(path.str().c_str()))
102 throw system_error("RemoveDirectory");
104 if(::rmdir(path.str().c_str())==-1)
105 throw system_error("rmdir");
109 void rmpath(const Path &path)
111 list<string> files = list_files(path);
112 for(list<string>::iterator i=files.begin(); i!=files.end(); ++i)
124 list<string> list_files(const Path &path)
126 return list_filtered(path, string());
129 list<string> list_filtered(const Path &path, const string &filter)
131 Regex r_filter(filter);
134 DIR *dir = opendir(path.str().c_str());
137 while(dirent *de = readdir(dir))
139 const char *fn = de->d_name;
140 if(fn[0]=='.' && (fn[1]==0 || (fn[1]=='.' && fn[2]==0)))
142 if(r_filter.match(fn))
143 result.push_back(fn);
154 return ::getcwd(buf, sizeof(buf));
161 if(SHGetFolderPath(0, CSIDL_PERSONAL, 0, 0, home)==S_OK)
164 const char *home = getenv("HOME");
171 Path get_user_data_dir(const string &appname)
174 char datadir[MAX_PATH];
175 if(SHGetFolderPath(0, CSIDL_LOCAL_APPDATA, 0, 0, datadir)==S_OK)
176 return Path(datadir)/appname;
179 return get_home_dir()/("."+appname);
183 Path get_sys_conf_dir(const string &argv0)
185 Path dir = get_bin_dir(argv0);
187 if(dir[-1]=="bin" || dir[-1]=="sbin")
198 Path get_sys_data_dir(const string &argv0, const string &appname)
200 Path dir = get_bin_dir(argv0);
202 if(dir[-1]=="bin" || dir[-1]=="sbin")
203 return dir/".."/"share"/appname;
208 Path get_sys_lib_dir(const string &argv0, const string &appname)
210 Path dir = get_bin_dir(argv0);
212 if(dir[-1]=="bin" || dir[-1]=="sbin")
213 return dir/".."/"lib"/appname;
218 void chdir(const Path &path)
220 if(::chdir(path.str().c_str())==-1)
221 throw system_error("chdir");