source: CMT/v1r12p20020606/src/cmt_model.cxx @ 1

Last change on this file since 1 was 1, checked in by arnault, 19 years ago

Import all tags

File size: 6.4 KB
Line 
1
2#include "cmt_model.h"
3#include "cmt_fragment.h"
4#include "cmt_symbol.h"
5
6/**
7 *   Filters out all predefined XML constructs.
8 */
9void CmtModel::filter (cmt_string& text)
10{
11  text.replace_all ("<cmt:tab/>", "\t");
12  text.replace_all ("<cmt:cr/>",  "\r");
13  text.replace_all ("<cmt:lf/>",  "\n");
14}
15
16void CmtModel::display (cmt_string& text)
17{
18  text.replace_all ("&lt;", "<");
19  text.replace_all ("&gt;", ">");
20  Symbol::expand (text);
21  cout << text;
22}
23
24void CmtModel::expand (const cmt_string& input_text)
25{
26  int openmarker;
27  int closemarker;
28
29  CmtSystem::cmt_string_vector subargs;
30
31  cmt_string text = input_text;
32  cmt_string remaining;
33
34  filter (text);
35
36  for (;;)
37    {
38      /**
39       *   Look for the next < ... /> pattern
40       *   If not found, then simply dump the text as it is.
41       */
42     
43      openmarker = text.find ("<");
44      if (openmarker == cmt_string::npos) break;
45     
46      closemarker = text.find (openmarker, "/>");
47      if (closemarker == cmt_string::npos) break;
48
49      if (CmtSystem::testenv ("CMTTESTMODEL"))
50        {
51          cerr << "text=[" << text << "]" << endl;
52        }
53         
54
55      /**
56       *  Extract the command from the pattern
57       */
58      cmt_string command;
59      text.substr (openmarker + 1, closemarker - openmarker - 1, command);
60
61      if (CmtSystem::testenv ("CMTTESTMODEL"))
62        {
63          cerr << "command=[" << command << "]" << endl;
64        }
65         
66      /**
67       *   Get what is left from the original text beyond the pattern
68       */
69      text.substr (closemarker + 2, remaining);
70
71      /**
72       *   Cut the original text up to the pattern start
73       */
74      text.erase (openmarker);
75     
76      /**
77       *   Now display it
78       */
79      display (text);
80         
81      /**
82       * Convert the extracted command into words
83       */
84      CmtSystem::split (command, " ", subargs);
85         
86      /**
87       *  Recursively expand it
88       */
89      expand (subargs);
90     
91      /**
92       *  The next iteration will operate on the remaining text
93       */
94      text = remaining;
95    }
96 
97  if (CmtSystem::testenv ("CMTTESTMODEL"))
98    {
99      cerr << "text=[" << text << "]" << endl;
100    }
101         
102  /**
103   *   Display what is left after extracting the last pattern
104   */
105  display (text);
106  cout << endl;
107}
108
109/**
110 *   Expands a model file
111 *   Arguments are :
112 *     model-name   : name of a model file
113 *     var=value    : variable value to be expanded
114 *                    (will take the form ${var} )
115 */
116void CmtModel::expand (const CmtSystem::cmt_string_vector& arguments)
117{
118  int i;
119
120  Variable::VariableVector variables;
121
122  /**
123   *   We start by decoding all [variable=value] pairs from the arguments
124   *   A vector of Variables is filled from them.
125   */
126  for (i = 0; i < arguments.size (); i++)
127    {
128      const cmt_string& arg = arguments[i];
129
130      if (arg.find ("=") != cmt_string::npos)
131        {
132          cmt_string name;
133          cmt_string value;
134          int pos = arg.find ("=");
135
136          arg.substr (0, pos, name);
137          arg.substr (pos + 1, value);
138
139          Variable* v = Variable::find (variables, name);
140          if (v == 0)
141            {
142              v = &(variables.add ());
143              v->set (name);
144            }
145
146          (*v) = value;
147        }
148    }
149
150  /**
151   *   Then model names are extracted.
152   *   Each model may contain a set of <...> patterns.
153   *   The expected syntax for each of them is :
154   *     <model-name variable-name=value ...>
155   *
156   *   Therefore the current expand function is recursively restarted.
157   *
158   *   Text around patterns is displayed after replacements of all
159   *   variable values detected by ${variable-name} patterns
160   */
161  cmt_string text;
162
163  for (i = 0; i < arguments.size (); i++)
164    {
165      const cmt_string& arg = arguments[i];
166
167      if (arg.find ("=") == cmt_string::npos)
168        {
169          FragmentHandle fragment (arg);
170          fragment.copy (text, variables, 0);
171
172          filter (text);
173
174          int openmarker;
175          int closemarker;
176
177          CmtSystem::cmt_string_vector subargs;
178
179          cmt_string remaining;
180
181          for (;;)
182            {
183              /**
184               *   Look for the next <...> pattern
185               *   If not found, then simply dump the text as it is.
186               */
187
188              openmarker = text.find ("<");
189              if (openmarker == cmt_string::npos) break;
190
191              closemarker = text.find (openmarker, "/>");
192              if (closemarker == cmt_string::npos)
193                {
194                  /**
195                   *  The opening < was in the text
196                   */
197
198                  /**
199                   *   Get what is left from the original text beyond the pattern
200                   */
201                  text.substr (openmarker + 1, remaining);
202                  text.erase (openmarker + 1);
203                 
204                  /**
205                   *   Now display it
206                   */
207                  display (text);
208                }
209              else
210                {
211                  /**
212                   *  Extract the command from the pattern
213                   */
214                  cmt_string command;
215                  text.substr (openmarker + 1, closemarker - openmarker - 1, command);
216
217                  /**
218                   *   Get what is left from the original text beyond the pattern
219                   */
220                  text.substr (closemarker + 2, remaining);
221                  text.erase (openmarker);
222                 
223                  /**
224                   *   Now display it
225                   */
226                  display (text);
227
228                  /**
229                   * Convert the extracted command into words
230                   */
231                  CmtSystem::split (command, " ", subargs);
232                 
233                  /**
234                   *  Recursively expand it
235                   */
236                  expand (subargs);
237                }
238
239              /**
240               *  The next iteration will operate on the remaining text
241               */
242              text = remaining;
243            }
244
245          /**
246           *   Display what is left after extracting the last pattern
247           */
248          display (text);
249        }
250    }
251}
252
Note: See TracBrowser for help on using the repository browser.