OpenRTM
1.0.0
|
00001 // -*- C++ -*- 00019 #ifndef COIL_FILE_H 00020 #define COIL_FILE_H 00021 00022 #include <cstring> 00023 #include <sys/types.h> 00024 #include <dirent.h> 00025 #include <libgen.h> 00026 00027 #include <coil/config_coil.h> 00028 #include <coil/stringutil.h> 00029 00030 namespace coil 00031 { 00032 00056 inline std::string dirname(char* path) 00057 { 00058 char path_name[strlen(path)+1]; 00059 strcpy(path_name, path); 00060 std::string dir_name = ::dirname(path); 00061 return dir_name; 00062 } 00063 00087 inline std::string basename(const char* path) 00088 { 00089 char path_name[strlen(path)+1]; 00090 strcpy(path_name, path); 00091 std::string base_name = ::basename(path_name); 00092 return base_name; 00093 } 00094 00120 inline coil::vstring filelist(const char* path, const char* glob_str = "") 00121 { 00122 struct dirent* ent; 00123 coil::vstring flist; 00124 bool has_glob(false); 00125 std::string pattern; 00126 00127 if (path == 0) { return flist; } 00128 if (glob_str[0] != '\0') { has_glob = true; } 00129 00130 DIR* dir_ptr(::opendir(path)); 00131 if (dir_ptr == 0) { return flist; } 00132 00133 while ((ent = ::readdir(dir_ptr)) != 0) 00134 { 00135 bool match(true); 00136 if (has_glob) 00137 { 00138 const char* globc(glob_str); 00139 std::string fname(ent->d_name); 00140 for (size_t i(0); i < fname.size() && globc != '\0'; ++i, ++globc) 00141 { 00142 if (*globc == '*') 00143 { 00144 // the last '*' matches every thing 00145 if (globc[1] == '\0') { break; } 00146 // consecutive * or + are skiped, but fname keeps pointer 00147 if (globc[1] == '*' || globc[1] == '+') { --i; continue; } 00148 00149 // advance pointer and find normal characters 00150 ++globc; 00151 size_t pos(fname.find(*globc, i)); 00152 if (pos == std::string::npos) { match = false; break; } 00153 // matched, and advance i to pos 00154 i = pos; 00155 } 00156 else if (*globc == '+') 00157 { 00158 // the last '+' matches last one or more characters 00159 if (globc[1] == '\0' && !(i + 1 < fname.size())) { break; } 00160 // consecutive * or + are skiped, but fname keeps pointer 00161 if (globc[1] == '*' || globc[1] == '+') { --i; continue; } 00162 00163 // advance pointer and find normal characters 00164 ++globc; 00165 size_t pos(fname.find(*globc, i + 1)); 00166 if (pos == std::string::npos) { match = false; break; } 00167 // matched, and advance i to pos 00168 i = pos; 00169 } 00170 else 00171 { 00172 if (fname[i] != *globc) { match = false; } 00173 } 00174 00175 // in the last fname character, if glob is not end, 00176 // or *, fname is not matched. 00177 if (i + 1 == fname.size() && 00178 globc[1] != '\0' && globc[1] != '*') { match = false; } 00179 } 00180 } 00181 if (match) { flist.push_back(ent->d_name); } 00182 } 00183 ::closedir(dir_ptr); 00184 00185 return flist; 00186 } 00187 }; 00188 00189 #endif // COIL_FILE_H