Main?Page | Class?Hierarchy | Class?List | File?List | Class?Members | File?Members

cmt_model.cxx

Go to the documentation of this file.
00001 //-----------------------------------------------------------
00002 // Copyright Christian Arnault LAL-Orsay CNRS
00003 // 
00004 // See the complete license in cmt_license.txt "http://www.cecill.info". 
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 ("",  "\t");
00017   text.replace_all ("",   "\r");
00018   text.replace_all ("",   "\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 ("", "");
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   // The patterns for syntax parsing
00125 
00126   cmt_string open_element = ";
00127   cmt_string open_elements = ";
00128   cmt_string close_element = "/>";
00129 
00130   cmt_string skip_spaces = "[ \t]+";
00131   cmt_string word = "[^ \t/>]*";
00132 
00133   cmt_string attribute = "[^=/>]+=((\"([^\"]|\\\\\")*\")|(\'([^\']|\\\\\')*\'))";
00134 
00135   //cout << "attribute=[" << attribute << "]" << endl;
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   //cout << "Text=[" << text << "]" << endl;
00152 
00153   filter (text);
00154 
00155   //cout << "Text=[" << text << "]" << endl;
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           // no more opening element
00169 
00170           // Display the remaining text. The parsing is now completed.
00171 
00172           remaining = text.substr (pos);
00173           display (remaining);
00174 
00175           break;
00176         }
00177 
00178       if (it == exp_open_element.end ())
00179         {
00180           // no single element -> we have a multiple one
00181           it = its;
00182           multiple = true;
00183         }
00184       else if (its == exp_open_elements.end ())
00185         {
00186           // no multiple element -> we have a single one
00187         }
00188       else if (it < its)
00189         {
00190           // the single is before the multiple
00191         }
00192       else
00193         {
00194           // the multiple is before the single
00195           it = its;
00196           multiple = true;
00197         }
00198 
00199       remaining = text.substr (pos, it._pos - pos);
00200       display (remaining);
00201 
00202       //cout << "pos=" << pos << " open_element -> p=" << it._pos << " l=" << it._length << endl;
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       //cout << "pos=" << pos << " word -> p=" << it._pos << " l=" << it._length << endl;
00213       pos += it._length;
00214 
00215       cmt_string element = it (text);
00216       //cout << "pos=" << pos << " element=" << element << endl;
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               //cout << "pos=" << pos << " skip_spaces -> p=" << it._pos << " l=" << it._length << endl;
00231               pos += it._length;
00232             }
00233 
00234           //cout << "pos=" << pos << endl;
00235 
00236           it = exp_close_element.begin (text, pos);
00237           if (it._pos == pos)
00238             {
00239               //cout << "Recursing to [" << element << "]" << endl;
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                   //cout << "+ name = [" << value << "]" << endl;
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                   //cout << "+ count = " << multiple_count << endl;
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                           //cout << "+ values = [" << value << "]" << endl;
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                           //cout << "+ value = [" << value << "]" << endl;
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           //cout << "Try attribute at pos=" << pos << " [" << text.substr (pos) << "]" << endl;
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           //cout << "pos=" << pos << " attribute -> p=" << it._pos << " l=" << it._length << endl;
00371           //cout << "pos=" << pos << " attr=[" << it (text) << "]" << endl;
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 

Generated on Mon May 2 10:25:05 2005 for CMT by 1.3.5