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

CmtModel Class Reference

#include <cmt_model.h>

List of all members.

Static Public Member Functions

void expand (const cmt_string &input_text)
void strict_expand (const cmt_string &input_text)
void test_regexp (const cmt_string &pattern, const cmt_string &input_text)

Static Private Member Functions

void filter (cmt_string &text)
 Filters out all predefined XML constructs.

void display (cmt_string &text)
void expand (const CmtSystem::cmt_string_vector &arguments)
 Expands a model file Arguments are : model-name : name of a model file var=value : variable value to be expanded (will take the form ${var} ).


Member Function Documentation

void CmtModel::display cmt_string text  )  [static, private]
 

Definition at line 21 of file cmt_model.cxx.

References Symbol::expand(), and cmt_string::replace_all().

Referenced by expand(), and strict_expand().

00022 {
00023   text.replace_all ("&lt;", "<");
00024   text.replace_all ("&gt;", ">");
00025   text.replace_all ("\\\"", "\"");
00026   text.replace_all ("\\\'", "\'");
00027   text.replace_all ("<cmt:null/>", "");
00028   Symbol::expand (text);
00029   cout << text;
00030 }

void CmtModel::expand const CmtSystem::cmt_string_vector arguments  )  [static, private]
 

Expands a model file Arguments are : model-name : name of a model file var=value : variable value to be expanded (will take the form ${var} ).

We start by decoding all [variable=value] pairs from the arguments A vector of Variables is filled from them.

Then model names are extracted. Each model may contain a set of <...> patterns. The expected syntax for each of them is : <model-name variable-name=value ...>

Therefore the current expand function is recursively restarted.

Text around patterns is displayed after replacements of all variable values detected by ${variable-name} patterns

Look for the next <...> pattern If not found, then simply dump the text as it is.

The opening < was in the text

Get what is left from the original text beyond the pattern

Now display it

Extract the command from the pattern

Get what is left from the original text beyond the pattern

Now display it

Convert the extracted command into words

Recursively expand it

The next iteration will operate on the remaining text

Display what is left after extracting the last pattern

Definition at line 416 of file cmt_model.cxx.

References cmt_vector< T >::add(), CmtSystem::cmt_string_vector, FragmentHandle::copy(), display(), cmt_string::erase(), expand(), filter(), Variable::find(), cmt_string::find(), Variable::set(), cmt_vector< T >::size(), CmtSystem::split(), cmt_string::substr(), and Variable::VariableVector.

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 }

void CmtModel::expand const cmt_string input_text  )  [static]
 

Definition at line 32 of file cmt_model.cxx.

References CmtSystem::cmt_string_vector, display(), cmt_string::erase(), filter(), cmt_string::find(), CmtSystem::split(), cmt_string::substr(), and CmtSystem::testenv().

Referenced by Cmt::do_expand_model(), and expand().

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 }

void CmtModel::filter cmt_string text  )  [static, private]
 

Filters out all predefined XML constructs.

Definition at line 14 of file cmt_model.cxx.

References cmt_string::replace_all().

Referenced by expand(), and strict_expand().

00015 {
00016   text.replace_all ("<cmt:tab/>",  "\t");
00017   text.replace_all ("<cmt:cr/>",   "\r");
00018   text.replace_all ("<cmt:lf/>",   "\n");
00019 }

void CmtModel::strict_expand const cmt_string input_text  )  [static]
 

Definition at line 117 of file cmt_model.cxx.

References cmt_regexp::iterator::_length, cmt_regexp::iterator::_pos, cmt_vector< T >::add(), cmt_regexp::begin(), cmt_vector< T >::clear(), CmtSystem::cmt_string_vector, FragmentHandle::copy(), display(), cmt_regexp::end(), cmt_string::erase(), filter(), Variable::find(), cmt_string::find(), Variable::set(), cmt_string::size(), cmt_vector< T >::size(), CmtSystem::split(), cmt_string::substr(), and Variable::VariableVector.

Referenced by Cmt::do_expand_model().

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 = "<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   //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 }

void CmtModel::test_regexp const cmt_string pattern,
const cmt_string input_text
[static]
 

Definition at line 385 of file cmt_model.cxx.

References cmt_regexp::iterator::_length, cmt_regexp::iterator::_pos, cmt_regexp::begin(), and cmt_regexp::end().

Referenced by Cmt::do_expand_model().

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 }


The documentation for this class was generated from the following files:
Generated on Mon May 2 10:25:33 2005 for CMT by doxygen 1.3.5