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 #include <lestes/common.hh>
00035 #include <lestes/std/list.hh>
00036 #include <lestes/std/istream_wrapper.hh>
00037 #include <lestes/lang/cplus/lex/file_system.hh>
00038 #include <lestes/lang/cplus/lex/named_istream.hh>
00039
00040 #include <fstream>
00041 #include <iostream>
00042
00043 package(lestes);
00044 package(lang);
00045 package(cplus);
00046 package(lex);
00047
00048 using namespace ::std;
00049
00050
00051
00052
00053 file_system::file_system(void):
00054 search_paths(lstrings_type::create())
00055 {
00056
00057 search_paths->push_back(lstring(""));
00058 }
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 ptr< file_system::lstrings_type > file_system::split(const lstring &str, hchar delimiter)
00071 {
00072 ptr< lstrings_type > v = lstrings_type::create();
00073
00074 lstring::size_type len = str.length();
00075
00076
00077 if (!len) return v;
00078
00079 lstring::size_type i, j;
00080
00081 i = 0;
00082
00083
00084
00085 while (i <= len) {
00086 j = str.find(delimiter,i);
00087 if (j == lstring::npos)
00088
00089 j = len;
00090
00091
00092 v->push_back(str.substr(i,j-i));
00093
00094 i = j + 1;
00095 }
00096
00097 return v;
00098 }
00099
00100
00101
00102
00103
00104
00105
00106 file_system::name_type file_system::classify_name(const lstring &name)
00107 {
00108 ptr<lstrings_type> parts = split(name,'/');
00109 ulint len = parts->size();
00110
00111 if (!len) return NM_PATH_REL;
00112
00113 bool absolute = parts->at(0).length() == 0;
00114 bool pathname = parts->at(len - 1).length() == 0;
00115
00116
00117 for (ulint i = 1; i < len - 1; i++) {
00118 if (parts->at(i).length() == 0)
00119 return NM_INVALID;
00120 }
00121
00122 if (absolute) {
00123 return pathname ? NM_PATH_ABS : NM_FILE_ABS;
00124 }
00125
00126 return pathname ? NM_PATH_REL : NM_FILE_REL;
00127 }
00128
00129
00130
00131
00132
00133
00134
00135 ptr<named_istream> file_system::open_file(const lstring &name)
00136 {
00137 if (name.length() == 0) {
00138 ptr<istream_wrapper> iw = istream_wrapper::create(&::std::cin,false);
00139 return named_istream::create(iw,"","<stdin>");
00140 }
00141
00142 name_type nt = classify_name(name);
00143
00144 if (nt != NM_FILE_REL && nt != NM_FILE_ABS)
00145 return NULL;
00146
00147 fstream *f = new fstream();
00148 bool error = false;
00149 try {
00150 f->open(name.c_str(),ios_base::in);
00151 error = f->fail();
00152 } catch (...) {
00153 error = true;
00154 }
00155
00156 if (error) {
00157 delete f;
00158 return NULL;
00159 }
00160
00161 ptr<istream_wrapper> iw = istream_wrapper::create(f,true);
00162
00163 return named_istream::create(iw,name,name);
00164 }
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197 ptr<named_istream> file_system::find_file(const lstring &base_path, const lstring &name, bool system)
00198 {
00199 name_type nt = classify_name(base_path);
00200 lassert(nt == NM_PATH_REL || nt == NM_PATH_ABS);
00201
00202 nt = classify_name(name);
00203
00204 if (nt == NM_FILE_ABS)
00205 return open_file(name);
00206
00207 if (nt != NM_FILE_REL)
00208 return NULL;
00209
00210 lstrings_type::iterator it = search_paths->begin(), end = search_paths->end();
00211
00212 if (system) {
00213
00214 ++it;
00215 } else {
00216
00217 (*search_paths)[0] = base_path;
00218 }
00219
00220 fstream *f = new fstream();
00221
00222 for ( ; it != end; ++it) {
00223
00224 lstring full_name(*it);
00225 full_name.append(name);
00226
00227 bool error = false;
00228
00229 try {
00230 f->open(full_name.c_str(),ios_base::in);
00231 error = f->fail();
00232 } catch (...) {
00233 error = true;
00234 }
00235
00236 if (!error) {
00237 ptr<istream_wrapper> iw = istream_wrapper::create(f,true);
00238 return named_istream::create(iw,full_name,full_name);
00239 }
00240 }
00241
00242
00243 delete f;
00244
00245
00246 return NULL;
00247 }
00248
00249
00250
00251
00252
00253
00254 bool file_system::add_search_path(const lstring &a_path)
00255 {
00256 name_type nt = classify_name(a_path);
00257 lstring path(a_path);
00258
00259 switch (nt) {
00260 case NM_INVALID:
00261 return false;
00262 case NM_FILE_REL:
00263 case NM_FILE_ABS:
00264 path.append("/");
00265
00266 case NM_PATH_REL:
00267 case NM_PATH_ABS:
00268 search_paths->push_back(path);
00269 break;
00270 default:
00271 lassert2(false,"You should never get here");
00272 }
00273 return true;
00274 }
00275
00276
00277
00278
00279 void file_system::gc_mark(void)
00280 {
00281 search_paths.gc_mark();
00282 ::lestes::std::object::gc_mark();
00283 }
00284
00285
00286
00287
00288
00289 ptr<file_system> file_system::create(void)
00290 {
00291 return new file_system();
00292 }
00293
00294 end_package(lex);
00295 end_package(cplus);
00296 end_package(lang);
00297 end_package(lestes);
00298
00299