00001
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005
00006 #include "vul_file_iterator.h"
00007 #include <vcl_string.h>
00008 #include <vcl_cassert.h>
00009
00010 #include <vul/vul_file.h>
00011 #include <vul/vul_reg_exp.h>
00012
00013
00014
00015
00016
00017
00018
00019
00020 #if defined(VCL_WIN32) && !defined(__CYGWIN__)
00021
00022 #if defined(VCL_BORLAND_56)
00023 # include <stdint.h>
00024 #endif
00025
00026 #include <io.h>
00027
00028 struct vul_file_iterator_data
00029 {
00030 struct _finddata_t data_;
00031 # if defined VCL_VC_6 || defined VCL_VC_5 || defined VCL_BORLAND_55 || defined __MINGW32__
00032 typedef long handle_type;
00033 # else
00034 typedef intptr_t handle_type;
00035 #endif
00036 handle_type handle_;
00037
00038 vcl_string found_;
00039 char const* name_;
00040 vul_reg_exp reg_exp_;
00041 vcl_string original_dirname_;
00042
00043 handle_type find_first(const char* dirname, struct _finddata_t* data)
00044 {
00045 return _findfirst(const_cast<char*>(dirname), data);
00046 }
00047
00048 vul_file_iterator_data(char const* glob);
00049
00050 void mkname() {
00051
00052 found_ = original_dirname_ + "\\" + data_.name;
00053 name_ = found_.c_str();
00054
00055 }
00056
00057
00058 void next() {
00059 assert(handle_ != 0);
00060 do
00061 {
00062 if (_findnext(handle_, &data_) != 0) {
00063 _findclose(handle_);
00064 handle_ = -1L;
00065 return;
00066 }
00067 } while ( ! reg_exp_.find(data_.name) );
00068 mkname();
00069 }
00070
00071
00072
00073 char const* value() {
00074 if (handle_ == -1L) return 0;
00075 return name_;
00076 }
00077
00078
00079 char const* value_filename() {
00080 if (handle_ == -1L) return 0;
00081 return data_.name;
00082 }
00083
00084 ~vul_file_iterator_data() {
00085 if (handle_ != -1L)
00086 _findclose(handle_);
00087 }
00088 };
00089
00090 vul_file_iterator_data::vul_file_iterator_data(char const* glob)
00091 {
00092 original_dirname_ = vul_file::dirname(glob);
00093 handle_ = find_first((original_dirname_ + "\\*").c_str(), &data_);
00094
00095 vcl_string baseglob = vul_file::basename(glob);
00096 vcl_string::iterator i = baseglob.begin();
00097 bool prev_slash=false, in_sqr_brackets=false;
00098
00099 vcl_string re = "^";
00100 while (i != baseglob.end())
00101 {
00102 if (*i=='\\' && !prev_slash)
00103 prev_slash = true;
00104 else if (prev_slash)
00105 {
00106 prev_slash = false;
00107 re.append(1,('\\'));
00108 re.append(1,*i);
00109 }
00110 else if (*i=='[' && !in_sqr_brackets)
00111 {
00112 in_sqr_brackets = true;
00113 re.append(1,'[');
00114 }
00115 else if (*i==']' && in_sqr_brackets)
00116 {
00117 in_sqr_brackets = false;
00118 re.append(1,']');
00119 }
00120 else if (*i=='?' && !in_sqr_brackets)
00121 re.append(1,'.');
00122 else if (*i=='*' && !in_sqr_brackets)
00123 re.append(".*");
00124 else
00125 re.append(vul_reg_exp::protect(*i));
00126
00127 ++i;
00128 }
00129
00130 re += '$';
00131
00132 reg_exp_.compile(re.c_str());
00133
00134
00135 if (handle_ != -1L)
00136 {
00137 while ( ! reg_exp_.find(data_.name) )
00138 {
00139 if (_findnext(handle_, &data_) != 0) {
00140 _findclose(handle_);
00141 handle_ = -1L;
00142 return;
00143 }
00144 }
00145 mkname();
00146 }
00147 }
00148
00149 #else // !defined(VCL_WIN32) || defined(__CYGWIN__)
00150
00151 #include <dirent.h>
00152
00153 struct vul_file_iterator_data
00154 {
00155 vcl_string original_dirname_;
00156 DIR* dir_handle_;
00157 dirent* de_;
00158 vcl_string found_;
00159 char const* name_;
00160 vul_reg_exp reg_exp_;
00161
00162 vul_file_iterator_data(char const* glob);
00163
00164 void mkname() {
00165
00166 found_ = original_dirname_ + de_->d_name;
00167 name_ = found_.c_str();
00168
00169 }
00170
00171 void next() {
00172 assert(dir_handle_ != 0);
00173 do
00174 {
00175 de_ = readdir(dir_handle_);
00176 if (de_==0) {
00177 closedir(dir_handle_);
00178 dir_handle_ = 0;
00179 return;
00180 }
00181 } while ( ! reg_exp_.find(de_->d_name) );
00182 mkname();
00183 }
00184
00185
00186 char const* value() {
00187 if (!dir_handle_) return 0;
00188 return name_;
00189 }
00190
00191
00192 char const* value_filename() {
00193 if (!dir_handle_) return 0;
00194 return de_->d_name;
00195 }
00196
00197 ~vul_file_iterator_data() {
00198 if (dir_handle_)
00199 closedir(dir_handle_);
00200 }
00201 };
00202
00203 vul_file_iterator_data::vul_file_iterator_data(char const* glob)
00204 {
00205 original_dirname_ = vul_file::dirname(glob) + "/";
00206
00207 vcl_string baseglob = vul_file::basename(glob);
00208 vcl_string::iterator i = baseglob.begin();
00209 bool prev_slash=false, in_sqr_brackets=false;
00210
00211 vcl_string re = "^";
00212 while (i != baseglob.end())
00213 {
00214 if (*i=='\\' && !prev_slash)
00215 prev_slash = true;
00216 else if (prev_slash)
00217 {
00218 prev_slash = false;
00219 re += '\\';
00220 re += *i;
00221 }
00222 else if (*i=='[' && !in_sqr_brackets)
00223 {
00224 in_sqr_brackets = true;
00225 re += '[';
00226 }
00227 else if (*i==']' && in_sqr_brackets)
00228 {
00229 in_sqr_brackets = false;
00230 re += ']';
00231 }
00232 else if (*i=='?' && !in_sqr_brackets)
00233 re += '.';
00234 else if (*i=='*' && !in_sqr_brackets)
00235 re += ".*";
00236 else
00237 re += vul_reg_exp::protect(*i);
00238
00239 ++i;
00240 }
00241
00242 re += '$';
00243
00244 reg_exp_.compile(re.c_str());
00245
00246 dir_handle_ = opendir(original_dirname_.c_str());
00247
00248 next();
00249 }
00250
00251 #endif // !defined(VCL_WIN32) || defined(__CYGWIN__)
00252
00253
00254
00255 vul_file_iterator::vul_file_iterator(char const* glob)
00256 {
00257 p = 0;
00258 reset(glob);
00259 }
00260
00261 vul_file_iterator::vul_file_iterator(vcl_string const& glob)
00262 {
00263 p = 0;
00264 reset(glob.c_str());
00265 }
00266
00267 vul_file_iterator::~vul_file_iterator()
00268 {
00269 delete p;
00270 }
00271
00272 void vul_file_iterator::reset(char const* glob)
00273 {
00274 delete p;
00275 p = new vul_file_iterator_data(glob);
00276 }
00277
00278 char const* vul_file_iterator::operator()()
00279 {
00280 return p->value();
00281 }
00282
00283 char const* vul_file_iterator::filename()
00284 {
00285 return p->value_filename();
00286 }
00287
00288 vul_file_iterator::operator vul_file_iterator::safe_bool() const
00289 {
00290 return (p->value() != 0)? VCL_SAFE_BOOL_TRUE : 0;
00291 }
00292
00293 bool vul_file_iterator::operator!() const
00294 {
00295 return (p->value() != 0)? false : true;
00296 }
00297
00298 vul_file_iterator& vul_file_iterator::operator++()
00299 {
00300 p->next();
00301 return *this;
00302 }