00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "pathReplace.h"
00020 #include "config_util.h"
00021 #include "indent.h"
00022
00023
00024
00025
00026
00027
00028 PathReplace::
00029 PathReplace() {
00030 _path_store = PS_keep;
00031 }
00032
00033
00034
00035
00036
00037
00038 PathReplace::
00039 ~PathReplace() {
00040 }
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 Filename PathReplace::
00052 match_path(const Filename &orig_filename,
00053 const DSearchPath &additional_path) {
00054 Filename match;
00055 bool got_match = false;
00056
00057 Entries::const_iterator ei;
00058 for (ei = _entries.begin(); ei != _entries.end(); ++ei) {
00059 const Entry &entry = (*ei);
00060 Filename new_filename;
00061 if (entry.try_match(orig_filename, new_filename)) {
00062
00063
00064 got_match = true;
00065 match = new_filename;
00066
00067 if (new_filename.is_fully_qualified()) {
00068
00069
00070 if (new_filename.exists()) {
00071 return new_filename;
00072 }
00073
00074 } else {
00075
00076
00077 if (new_filename.resolve_filename(_path) ||
00078 new_filename.resolve_filename(additional_path) ||
00079 new_filename.resolve_filename(get_model_path())) {
00080
00081 if (_path_store == PS_keep) {
00082
00083
00084 return match;
00085 } else {
00086
00087 return new_filename;
00088 }
00089 }
00090 }
00091
00092
00093 }
00094 }
00095
00096
00097
00098 if (got_match) {
00099 return match;
00100 }
00101
00102
00103
00104 if (_path_store != PS_keep) {
00105 Filename new_filename = orig_filename;
00106 if (new_filename.resolve_filename(_path) ||
00107 new_filename.resolve_filename(additional_path) ||
00108 new_filename.resolve_filename(get_model_path())) {
00109
00110 return new_filename;
00111 }
00112 }
00113
00114
00115 return orig_filename;
00116 }
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126 Filename PathReplace::
00127 store_path(const Filename &orig_filename) {
00128 if (_path_directory.is_local()) {
00129 _path_directory.make_absolute();
00130 }
00131 Filename filename = orig_filename;
00132
00133 switch (_path_store) {
00134 case PS_relative:
00135 filename.make_absolute();
00136 filename.make_relative_to(_path_directory);
00137 break;
00138
00139 case PS_absolute:
00140 filename.make_absolute();
00141 break;
00142
00143 case PS_rel_abs:
00144 filename.make_absolute();
00145 filename.make_relative_to(_path_directory, false);
00146 break;
00147
00148 case PS_strip:
00149 filename = filename.get_basename();
00150 break;
00151
00152 case PS_keep:
00153 break;
00154
00155 case PS_invalid:
00156 break;
00157 }
00158
00159 return filename;
00160 }
00161
00162
00163
00164
00165
00166
00167 void PathReplace::
00168 write(ostream &out, int indent_level) const {
00169 Entries::const_iterator ei;
00170 for (ei = _entries.begin(); ei != _entries.end(); ++ei) {
00171 indent(out, indent_level)
00172 << "-pr " << (*ei)._orig_prefix << "="
00173 << (*ei)._replacement_prefix << "\n";
00174 }
00175 int num_directories = _path.get_num_directories();
00176 for (int i = 0; i < num_directories; i++) {
00177 indent(out, indent_level)
00178 << "-pp " << _path.get_directory(i) << "\n";
00179 }
00180 indent(out, indent_level)
00181 << "-ps " << _path_store << "\n";
00182
00183
00184 switch (_path_store) {
00185 case PS_relative:
00186 case PS_rel_abs:
00187 indent(out, indent_level)
00188 << "-pd " << _path_directory << "\n";
00189
00190 default:
00191 break;
00192 }
00193 }
00194
00195
00196
00197
00198
00199
00200 PathReplace::Entry::
00201 Entry(const string &orig_prefix, const string &replacement_prefix) :
00202 _orig_prefix(orig_prefix),
00203 _replacement_prefix(replacement_prefix)
00204 {
00205
00206 if (_orig_prefix.length() > 1 &&
00207 _orig_prefix[_orig_prefix.length() - 1] == '/') {
00208 _orig_prefix = _orig_prefix.substr(0, _orig_prefix.length() - 1);
00209 }
00210 if (_replacement_prefix.length() > 1 &&
00211 _replacement_prefix[_replacement_prefix.length() - 1] == '/') {
00212 _replacement_prefix = _replacement_prefix.substr(0, _replacement_prefix.length() - 1);
00213 }
00214
00215 Filename filename(_orig_prefix);
00216 _is_local = filename.is_local();
00217
00218 vector_string components;
00219 filename.extract_components(components);
00220 vector_string::const_iterator ci;
00221 for (ci = components.begin(); ci != components.end(); ++ci) {
00222 _orig_components.push_back(Component(*ci));
00223 }
00224 }
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234 bool PathReplace::Entry::
00235 try_match(const Filename &filename, Filename &new_filename) const {
00236 if (_is_local != filename.is_local()) {
00237 return false;
00238 }
00239 vector_string components;
00240 filename.extract_components(components);
00241 size_t mi = r_try_match(components, 0, 0);
00242 if (mi == 0) {
00243
00244 return false;
00245 }
00246
00247
00248 string result = _replacement_prefix;
00249 while (mi < components.size()) {
00250 if (!result.empty()) {
00251 result += '/';
00252 }
00253 result += components[mi];
00254 ++mi;
00255 }
00256 new_filename = result;
00257 return true;
00258 }
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272 size_t PathReplace::Entry::
00273 r_try_match(const vector_string &components, size_t oi, size_t ci) const {
00274 if (oi >= _orig_components.size()) {
00275
00276 return ci;
00277 }
00278 if (ci >= components.size()) {
00279
00280
00281
00282
00283
00284 return 0;
00285 }
00286
00287 const Component &orig_component = _orig_components[oi];
00288 if (orig_component._double_star) {
00289
00290
00291 size_t mi = r_try_match(components, oi, ci + 1);
00292 if (mi != 0) {
00293 return mi;
00294 }
00295
00296
00297 return r_try_match(components, oi + 1, ci);
00298 }
00299
00300
00301
00302 if (orig_component._orig_prefix.matches(components[ci])) {
00303
00304 return r_try_match(components, oi + 1, ci + 1);
00305 }
00306
00307
00308 return 0;
00309 }