00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #ifdef INVT_HAVE_BOOST_FILESYSTEM
00044
00045
00046 #include "Robots/LoBot/util/LoFile.H"
00047
00048
00049 #include <boost/filesystem/operations.hpp>
00050
00051
00052 #include <algorithm>
00053 #include <deque>
00054 #include <functional>
00055 #include <iterator>
00056
00057 namespace lobot {
00058
00059
00060 std::string dirname(const std::string& path)
00061 {
00062 namespace fs = boost::filesystem ;
00063 return fs::path(path).branch_path().string() ;
00064 }
00065
00066 std::string basename(const std::string& path)
00067 {
00068 namespace fs = boost::filesystem ;
00069 return fs::path(path).leaf() ;
00070 }
00071
00072
00073 bool exists(const std::string& path)
00074 {
00075 namespace fs = boost::filesystem ;
00076 return fs::exists(fs::path(path));
00077 }
00078
00079 bool is_dir(const std::string& path)
00080 {
00081 namespace fs = boost::filesystem ;
00082 fs::path p(path) ;
00083 return fs::exists(p) && fs::is_directory(p) ;
00084 }
00085
00086 bool is_file(const std::string& path)
00087 {
00088 return !is_dir(path) ;
00089 }
00090
00091
00092 std::vector<std::string> list_dir(const std::string& path)
00093 {
00094 namespace fs = boost::filesystem ;
00095 fs::path p(path) ;
00096 std::vector<std::string> ls ;
00097 std::transform(fs::directory_iterator(p), fs::directory_iterator(),
00098 std::back_inserter(ls), std::mem_fun_ref(&fs::path::string));
00099 return ls ;
00100 }
00101
00102 }
00103
00104 #else // Boost.Filesystem not available
00105
00106
00107
00108
00109 #include "Robots/LoBot/util/LoFile.H"
00110 #include "Robots/LoBot/util/LoSysConf.H"
00111
00112
00113 #include <algorithm>
00114 #include <deque>
00115 #include <iterator>
00116
00117
00118 #include <stdlib.h>
00119 #include <stddef.h>
00120
00121
00122 #include <libgen.h>
00123 #include <dirent.h>
00124 #include <sys/stat.h>
00125 #include <sys/types.h>
00126
00127
00128
00129
00130 static char* dup_string(const std::string& s)
00131 {
00132 const int N = s.size() ;
00133 char* tmp = new char[N + 1] ;
00134 std::copy(s.begin(), s.end(), tmp) ;
00135 tmp[N] = '\0' ;
00136 return tmp ;
00137 }
00138
00139 namespace lobot {
00140
00141
00142 std::string dirname(const std::string& path)
00143 {
00144 char* tmp = dup_string(path) ;
00145 std::string dname = ::dirname(tmp) ;
00146 delete[] tmp ;
00147 return dname ;
00148 }
00149
00150 std::string basename(const std::string& path)
00151 {
00152 char* tmp = dup_string(path) ;
00153 std::string bname = ::basename(tmp) ;
00154 delete[] tmp ;
00155 return bname ;
00156 }
00157
00158
00159 bool exists(const std::string& path)
00160 {
00161 struct stat buf ;
00162 return stat(path.c_str(), &buf) == 0 ;
00163 }
00164
00165 bool is_dir(const std::string& path)
00166 {
00167 struct stat buf ;
00168 return stat(path.c_str(), &buf) == 0 && S_ISDIR(buf.st_mode) ;
00169 }
00170
00171 bool is_file(const std::string& path)
00172 {
00173 struct stat buf ;
00174 return stat(path.c_str(), &buf) == 0 && S_ISREG(buf.st_mode) ;
00175 }
00176
00177
00178
00179
00180
00181
00182 std::vector<std::string> list_dir(const std::string& path)
00183 {
00184 typedef std::vector<std::string> list ;
00185
00186 const int N = maxlen_filename(path.c_str()) ;
00187 struct dirent* input = reinterpret_cast<struct dirent*>(
00188 malloc(offsetof(struct dirent, d_name) + N + 1)) ;
00189 if (input == NULL)
00190 return list() ;
00191
00192 DIR* dir = opendir(path.c_str()) ;
00193 if (dir == NULL) {
00194 free(input) ;
00195 return list() ;
00196 }
00197
00198 list ls ;
00199 for(;;)
00200 {
00201 struct dirent* output = NULL ;
00202 readdir_r(dir, input, &output) ;
00203 if (output == NULL)
00204 break ;
00205
00206 std::string file_name = output->d_name ;
00207 if (file_name == "." || file_name == "..")
00208 continue ;
00209 ls.push_back(path + "/" + file_name) ;
00210 }
00211
00212 closedir(dir) ;
00213 free(input) ;
00214 return ls ;
00215 }
00216
00217 }
00218
00219 #endif // INVT_HAVE_BOOST_FILESYSTEM
00220
00221
00222
00223 #ifdef INVT_HAVE_BOOST_REGEX
00224
00225 #include <boost/regex.hpp>
00226
00227
00228 static bool match_exact(const std::string& name, const std::string& target)
00229 {
00230 return name == target ;
00231 }
00232
00233 namespace lobot {
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249 class match_regex {
00250 boost::regex m_regex ;
00251 public:
00252 match_regex(const std::string& pattern) ;
00253 bool operator()(const std::string& name, const std::string&) const {
00254 return boost::regex_search(name, m_regex) ;
00255 }
00256 } ;
00257
00258 match_regex::match_regex(const std::string& pattern)
00259 : m_regex(pattern)
00260 {}
00261
00262
00263
00264
00265 template<typename pred>
00266 static std::vector<std::string>
00267 find_helper(const std::string& dir, const std::string& target,
00268 pred match, bool (*is_type)(const std::string&))
00269 {
00270 typedef std::vector<std::string> list ;
00271 if (! is_dir(dir))
00272 return list() ;
00273
00274 list matches ;
00275 std::deque <std::string> fringe ;
00276 fringe.push_back(dir) ;
00277
00278 while (! fringe.empty())
00279 {
00280 std::string item = fringe.front() ;
00281 fringe.pop_front() ;
00282
00283 if (is_dir(item)) {
00284 list ls = list_dir(item) ;
00285 std::copy(ls.begin(), ls.end(), std::back_inserter(fringe)) ;
00286 }
00287
00288 if (is_type(item) && match(item, target))
00289 matches.push_back(item) ;
00290 }
00291 std::sort(matches.begin(), matches.end()) ;
00292 return matches ;
00293 }
00294
00295
00296 std::vector<std::string>
00297 find_file(const std::string& dir, const std::string& target)
00298 {
00299 try
00300 {
00301 return find_helper(dir, target, match_regex(target), is_file) ;
00302 }
00303 catch (boost::regex_error&){}
00304 return find_helper(dir, target, match_exact, is_file) ;
00305 }
00306
00307
00308 std::vector<std::string>
00309 find_dir(const std::string& dir, const std::string& target)
00310 {
00311 try
00312 {
00313 return find_helper(dir, target, match_regex(target), is_dir) ;
00314 }
00315 catch (boost::regex_error&){}
00316 return find_helper(dir, target, match_exact, is_dir) ;
00317 }
00318
00319 }
00320
00321 #else // Boost.Regex not available
00322
00323
00324
00325 #include <regex.h>
00326
00327
00328 static bool
00329 match_exact(const std::string& name, const std::string& target, const regex_t*)
00330 {
00331 return name == target ;
00332 }
00333
00334
00335 static bool
00336 match_regex(const std::string& name, const std::string&, const regex_t* regex)
00337 {
00338 return regexec(regex, name.c_str(), 0, 0, 0) == 0 ;
00339 }
00340
00341 namespace lobot {
00342
00343
00344
00345 static std::vector<std::string>
00346 find_helper(const std::string& dir, const std::string& target,
00347 bool (*is_type)(const std::string&))
00348 {
00349 typedef std::vector<std::string> list ;
00350 if (! is_dir(dir))
00351 return list() ;
00352
00353 typedef bool (*MatchFunc)(const std::string&,
00354 const std::string&, const regex_t*) ;
00355 MatchFunc match = match_exact ;
00356
00357 regex_t regex ;
00358 if (regcomp(®ex, target.c_str(),
00359 REG_EXTENDED | REG_NOSUB | REG_NEWLINE) == 0)
00360 match = match_regex ;
00361
00362 list matches ;
00363 std::deque<std::string> fringe ;
00364 fringe.push_back(dir) ;
00365
00366 while (! fringe.empty())
00367 {
00368 std::string item = fringe.front() ;
00369 fringe.pop_front() ;
00370
00371 if (is_dir(item)) {
00372 list ls = list_dir(item) ;
00373 std::copy(ls.begin(), ls.end(), std::back_inserter(fringe)) ;
00374 }
00375
00376 if (is_type(item) && match(item, target, ®ex))
00377 matches.push_back(item) ;
00378 }
00379
00380 if (match == match_regex)
00381 regfree(®ex) ;
00382
00383 std::sort(matches.begin(), matches.end()) ;
00384 return matches ;
00385 }
00386
00387
00388 std::vector<std::string>
00389 find_file(const std::string& dir, const std::string& target)
00390 {
00391 return find_helper(dir, target, is_file) ;
00392 }
00393
00394
00395 std::vector<std::string>
00396 find_dir(const std::string& dir, const std::string& target)
00397 {
00398 return find_helper(dir, target, is_dir) ;
00399 }
00400
00401 }
00402
00403 #endif // INVT_HAVE_BOOST_REGEX
00404
00405
00406
00407
00408
00409 namespace lobot {
00410
00411
00412 std::string extension(const std::string& path)
00413 {
00414 std::string base_name = basename(path) ;
00415 return base_name.substr(base_name.find('.') + 1) ;
00416 }
00417
00418 }
00419
00420
00421
00422
00423
00424
00425