00001
00002
00003
00004
00005
00006
00007 #include "cmt_model.h"
00008 #include "cmt_fragment.h"
00009 #include "cmt_symbol.h"
00010
00014 void CmtModel::filter (cmt_string& text)
00015 {
00016 text.replace_all ("<cmt:tab/>", "\t");
00017 text.replace_all ("<cmt:cr/>", "\r");
00018 text.replace_all ("<cmt:lf/>", "\n");
00019 }
00020
00021 void CmtModel::display (cmt_string& text)
00022 {
00023 text.replace_all ("<", "<");
00024 text.replace_all (">", ">");
00025 text.replace_all ("\\\"", "\"");
00026 text.replace_all ("\\\'", "\'");
00027 text.replace_all ("<cmt:null/>", "");
00028 Symbol::expand (text);
00029 cout << text;
00030 }
00031
00032 void CmtModel::expand (const cmt_string& input_text)
00033 {
00034 int openmarker;
00035 int closemarker;
00036
00037 CmtSystem::cmt_string_vector subargs;
00038
00039 cmt_string text = input_text;
00040 cmt_string remaining;
00041
00042 filter (text);
00043
00044 for (;;)
00045 {
00051 openmarker = text.find ("<");
00052 if (openmarker == cmt_string::npos) break;
00053
00054 closemarker = text.find (openmarker, "/>");
00055 if (closemarker == cmt_string::npos) break;
00056
00057 if (CmtSystem::testenv ("CMTTESTMODEL"))
00058 {
00059 cerr << "text=[" << text << "]" << endl;
00060 }
00061
00062
00066 cmt_string command;
00067 text.substr (openmarker + 1, closemarker - openmarker - 1, command);
00068
00069 if (CmtSystem::testenv ("CMTTESTMODEL"))
00070 {
00071 cerr << "command=[" << command << "]" << endl;
00072 }
00073
00077 text.substr (closemarker + 2, remaining);
00078
00082 text.erase (openmarker);
00083
00087 display (text);
00088
00092 CmtSystem::split (command, " ", subargs);
00093
00097 expand (subargs);
00098
00102 text = remaining;
00103 }
00104
00105 if (CmtSystem::testenv ("CMTTESTMODEL"))
00106 {
00107 cerr << "text=[" << text << "]" << endl;
00108 }
00109
00113 display (text);
00114 cout << endl;
00115 }
00116
00117 void CmtModel::strict_expand (const cmt_string& input_text)
00118 {
00119 CmtSystem::cmt_string_vector subargs;
00120
00121 cmt_string text = input_text;
00122 cmt_string remaining;
00123
00124
00125
00126 cmt_string open_element = "<cmts:";
00127 cmt_string open_elements = "<cmtv:";
00128 cmt_string close_element = "/>";
00129
00130 cmt_string skip_spaces = "[ \t]+";
00131 cmt_string word = "[^ \t/>]*";
00132
00133 cmt_string attribute = "[^=/>]+=((\"([^\"]|\\\\\")*\")|(\'([^\']|\\\\\')*\'))";
00134
00135
00136
00137 cmt_regexp exp_open_element (open_element);
00138 cmt_regexp exp_open_elements (open_elements);
00139 cmt_regexp exp_close_element (close_element);
00140
00141 cmt_regexp exp_skip_spaces (skip_spaces);
00142 cmt_regexp exp_word (word);
00143
00144 cmt_regexp exp_attribute (attribute);
00145
00146 cmt_regexp::iterator it;
00147 cmt_regexp::iterator its;
00148
00149 static int expand_level = 0;
00150
00151
00152
00153 filter (text);
00154
00155
00156
00157 int pos = 0;
00158
00159 for (;;)
00160 {
00161 bool multiple = false;
00162
00163 it = exp_open_element.begin (text, pos);
00164 its = exp_open_elements.begin (text, pos);
00165
00166 if ((it == exp_open_element.end ()) && ((its == exp_open_elements.end ())))
00167 {
00168
00169
00170
00171
00172 remaining = text.substr (pos);
00173 display (remaining);
00174
00175 break;
00176 }
00177
00178 if (it == exp_open_element.end ())
00179 {
00180
00181 it = its;
00182 multiple = true;
00183 }
00184 else if (its == exp_open_elements.end ())
00185 {
00186
00187 }
00188 else if (it < its)
00189 {
00190
00191 }
00192 else
00193 {
00194
00195 it = its;
00196 multiple = true;
00197 }
00198
00199 remaining = text.substr (pos, it._pos - pos);
00200 display (remaining);
00201
00202
00203 pos = it._pos + it._length;
00204
00205 it = exp_word.begin (text, pos);
00206 if (it._pos != pos)
00207 {
00208 cerr << "Syntax error: no element name" << endl;
00209 break;
00210 }
00211
00212
00213 pos += it._length;
00214
00215 cmt_string element = it (text);
00216
00217
00218 subargs.clear ();
00219
00220 {
00221 cmt_string& s = subargs.add ();
00222 s = element;
00223 }
00224
00225 for (;;)
00226 {
00227 it = exp_skip_spaces.begin (text, pos);
00228 if (it._pos == pos)
00229 {
00230
00231 pos += it._length;
00232 }
00233
00234
00235
00236 it = exp_close_element.begin (text, pos);
00237 if (it._pos == pos)
00238 {
00239
00240
00241 int i;
00242
00243 Variable::VariableVector variables;
00244
00250 int multiple_count = 0;
00251 CmtSystem::cmt_string_vector values;
00252 cmt_string name;
00253 cmt_string value;
00254
00255 for (i = 1; i < subargs.size (); i++)
00256 {
00257 const cmt_string& arg = subargs[i];
00258
00259 int p = arg.find ("=");
00260
00261 arg.substr (0, p, name);
00262 arg.substr (p + 1, value);
00263 if (value[0] == '"')
00264 {
00265 value.erase (0, 1);
00266 if (value[value.size()-1] == '"') value.erase (value.size ()-1);
00267 }
00268 else if (value[0] == '\'')
00269 {
00270 value.erase (0, 1);
00271 if (value[value.size()-1] == '\'') value.erase (value.size ()-1);
00272 }
00273
00274
00275
00276 if (multiple)
00277 {
00278 values.clear ();
00279 CmtSystem::split (value, " \t", values);
00280 int n = values.size ();
00281 if (n > multiple_count) multiple_count = n;
00282 }
00283
00284 Variable* v = Variable::find (variables, name);
00285 if (v == 0)
00286 {
00287 v = &(variables.add ());
00288 v->set (name);
00289 }
00290
00291 (*v) = value;
00292 }
00293
00294 cmt_string sub_text;
00295
00296 FragmentHandle fragment (element);
00297
00298 if (multiple)
00299 {
00300
00301 for (int n = 0; n < multiple_count; n++)
00302 {
00303 for (i = 1; i < subargs.size (); i++)
00304 {
00305 const cmt_string& arg = subargs[i];
00306
00307 int p = arg.find ("=");
00308
00309 arg.substr (p + 1, value);
00310 if (value[0] == '"')
00311 {
00312 value.erase (0, 1);
00313 if (value[value.size()-1] == '"') value.erase (value.size ()-1);
00314 }
00315 else if (value[0] == '\'')
00316 {
00317 value.erase (0, 1);
00318 if (value[value.size()-1] == '\'') value.erase (value.size ()-1);
00319 }
00320
00321
00322
00323 values.clear ();
00324 CmtSystem::split (value, " \t", values);
00325 if (n < values.size ())
00326 {
00327 value = values[n];
00328 }
00329 else
00330 {
00331 value = "";
00332 }
00333
00334 Variable& v = variables[i-1];
00335
00336
00337
00338 v = value;
00339 }
00340
00341 fragment.copy (sub_text, variables, 0);
00342
00343 expand_level++;
00344 strict_expand (sub_text);
00345 expand_level--;
00346 }
00347 }
00348 else
00349 {
00350 fragment.copy (sub_text, variables, 0);
00351
00352 expand_level++;
00353 strict_expand (sub_text);
00354 expand_level--;
00355 }
00356
00357 pos += it._length;
00358 break;
00359 }
00360
00361
00362
00363 it = exp_attribute.begin (text, pos);
00364 if (it._pos != pos)
00365 {
00366 cerr << "Syntax error : no attribute before closing the element [" << text.substr (pos) << "]" << endl;
00367 break;
00368 }
00369
00370
00371
00372
00373 {
00374 cmt_string& s = subargs.add ();
00375 s = it (text);
00376 }
00377
00378 pos += it._length;
00379 }
00380 }
00381
00382 if (expand_level == 0) cout << endl;
00383 }
00384
00385 void CmtModel::test_regexp (const cmt_string& pattern, const cmt_string& input_text)
00386 {
00387 cout << "Testing pattern [" << pattern << "] against [" << input_text << "]" << endl;
00388
00389 cmt_regexp exp (pattern);
00390
00391 cmt_regexp::iterator it;
00392
00393 for (int pos = 0; pos < 10; pos++)
00394 {
00395 it = exp.begin (input_text, pos);
00396
00397 if (it == exp.end ())
00398 {
00399 cout << "No match" << endl;
00400 }
00401 else
00402 {
00403 cout << "p=" << it._pos << " l=" << it._length << " -> [" << it (input_text) << "]" << endl;
00404 }
00405 }
00406 }
00407
00408
00416 void CmtModel::expand (const CmtSystem::cmt_string_vector& arguments)
00417 {
00418 int i;
00419
00420 Variable::VariableVector variables;
00421
00426 for (i = 0; i < arguments.size (); i++)
00427 {
00428 const cmt_string& arg = arguments[i];
00429
00430 if (arg.find ("=") != cmt_string::npos)
00431 {
00432 cmt_string name;
00433 cmt_string value;
00434 int pos = arg.find ("=");
00435
00436 arg.substr (0, pos, name);
00437 arg.substr (pos + 1, value);
00438
00439 Variable* v = Variable::find (variables, name);
00440 if (v == 0)
00441 {
00442 v = &(variables.add ());
00443 v->set (name);
00444 }
00445
00446 (*v) = value;
00447 }
00448 }
00449
00461 cmt_string text;
00462
00463 for (i = 0; i < arguments.size (); i++)
00464 {
00465 const cmt_string& arg = arguments[i];
00466
00467 if (arg.find ("=") == cmt_string::npos)
00468 {
00469 FragmentHandle fragment (arg);
00470 fragment.copy (text, variables, 0);
00471
00472 filter (text);
00473
00474 int openmarker;
00475 int closemarker;
00476
00477 CmtSystem::cmt_string_vector subargs;
00478
00479 cmt_string remaining;
00480
00481 for (;;)
00482 {
00488 openmarker = text.find ("<");
00489 if (openmarker == cmt_string::npos) break;
00490
00491 closemarker = text.find (openmarker, "/>");
00492 if (closemarker == cmt_string::npos)
00493 {
00501 text.substr (openmarker + 1, remaining);
00502 text.erase (openmarker + 1);
00503
00507 display (text);
00508 }
00509 else
00510 {
00514 cmt_string command;
00515 text.substr (openmarker + 1, closemarker - openmarker - 1, command);
00516
00520 text.substr (closemarker + 2, remaining);
00521 text.erase (openmarker);
00522
00526 display (text);
00527
00531 CmtSystem::split (command, " ", subargs);
00532
00536 expand (subargs);
00537 }
00538
00542 text = remaining;
00543 }
00544
00548 display (text);
00549 }
00550 }
00551 }
00552