/[publicrep]/cgi/ezc/trunk/src/ezc.cpp
ViewVC logotype

Contents of /cgi/ezc/trunk/src/ezc.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 5 - (show annotations)
Thu Jan 25 08:25:40 2007 UTC (16 years, 1 month ago) by tomek
Content type: text/x-csrc
File size: 7925 byte(s)
added [for]
EzcInfo pushed into Ezc::
added info about a wrong directive

1 #include "ezc.h"
2
3
4 /*
5 *
6 * Ezc
7 *
8 *
9 */
10
11 bool Ezc::ReadFile(const char * name)
12 {
13 std::ifstream file(name);
14
15 if( !file )
16 {
17 std::ostringstream buffer;
18 buffer << "<!-- ezc: can't open: " << name << " -->";
19 input = buffer.str();
20
21 return false;
22 }
23
24 std::getline(file, input, '\0');
25
26 return true;
27 }
28
29
30 void Ezc::Init()
31 {
32 }
33
34 Ezc::Ezc()
35 {
36 Init();
37 }
38
39
40 void Ezc::CreateTree()
41 {
42 item_root.ClearTable();
43 item_root.type = Item::item_container;
44
45 const char * pinput = input.c_str();
46 item_root.CreateTree(pinput);
47 }
48
49
50
51 std::string Ezc::MakeText()
52 {
53 output.clear();
54
55 item_root.MakeText(output, user_info_table);
56
57 return output;
58 }
59
60
61 void Ezc::Insert(const std::string & key, UserFunction ufunction)
62 {
63 UserInfo ui;
64 ui.user_function = ufunction;
65
66 user_info_table.insert( std::make_pair(key, ui) );
67 }
68
69
70
71 /*
72 *
73 * Ezc::Item
74 *
75 *
76 */
77
78
79 Ezc::Item * Ezc::Item::AddItem(const Ezc::Item & porg)
80 {
81 Item * pitem = new Item(porg);
82
83 item_table.push_back(pitem);
84
85 return pitem;
86 }
87
88
89 void Ezc::Item::ClearTable()
90 {
91 std::vector<Item*>::iterator i = item_table.begin();
92
93 for( ; i != item_table.end() ; ++i )
94 delete *i;
95
96 item_table.clear();
97 }
98
99 Ezc::Item::Item()
100 {
101 }
102
103 Ezc::Item::~Item()
104 {
105 ClearTable();
106 }
107
108 Ezc::Item::ItemType Ezc::Item::LastItemType()
109 {
110 if( item_table.empty() )
111 return item_none;
112
113 return item_table.back()->type;
114 }
115
116
117 bool Ezc::Item::ReadChar(const char * & itext, char & result)
118 {
119 if( *itext==0 || *itext=='[' || *itext==']' )
120 return false;
121
122
123 if( *itext == '\\' )
124 {
125 if( *(itext+1)=='\\' || *(itext+1)=='[' || *(itext+1)==']' )
126 {
127 result = *(++itext);
128 ++itext;
129 return true;
130 }
131 }
132
133 result = *itext;
134 ++itext;
135
136 return true;
137 }
138
139
140 void Ezc::Item::SkipWhiteCharacters(const char * & itext)
141 {
142 while( *itext==' ' || *itext=='\t' )
143 ++itext;
144 }
145
146
147 void Ezc::Item::ReadDirective(const char * & itext, std::string & directive)
148 {
149 directive.clear();
150
151 SkipWhiteCharacters(itext);
152
153 while( (*itext>='a' && *itext<='z') ||
154 (*itext>='A' && *itext<='Z') ||
155 (*itext>='0' && *itext<='9') ||
156 *itext=='_' || *itext=='-' )
157 {
158 directive += *itext;
159
160 ++itext;
161 }
162 }
163
164 void Ezc::Item::CreateTreeReadItemDirectiveCheckEnding(const char * & itext)
165 {
166 SkipWhiteCharacters(itext);
167
168 if( *itext != ']' )
169 {
170 type = item_err;
171
172 while( *itext!=0 && *itext!=']' )
173 ++itext;
174 }
175
176 if( *itext == ']' )
177 ++itext;
178 }
179
180
181 void Ezc::Item::CreateTreeReadItemDirective(const char * & itext)
182 {
183 std::string directive;
184
185 ++itext;
186 directives.clear();
187
188 ReadDirective(itext,directive);
189
190 if( directive == "if-any" )
191 {
192 type = item_ifany;
193
194 while( true )
195 {
196 ReadDirective(itext,directive);
197
198 if( directive.empty() )
199 break;
200
201 directives.push_back(directive);
202 }
203 }
204 else
205 if( directive == "end" )
206 {
207 type = item_end;
208 }
209 else
210 if( directive == "else" )
211 {
212 type = item_else;
213 }
214 else
215 if( directive == "for" )
216 {
217 type = item_for;
218
219 ReadDirective(itext,directive);
220
221 if( !directive.empty() )
222 directives.push_back(directive);
223 }
224 else
225 {
226 directives.push_back(directive);
227 type = item_normal;
228 }
229
230 CreateTreeReadItemDirectiveCheckEnding(itext);
231 }
232
233
234 void Ezc::Item::CreateTreeReadItemText(const char * & itext)
235 {
236 char c;
237
238 text.clear();
239
240 while( ReadChar(itext, c) )
241 text += c;
242
243 type = item_text;
244 }
245
246
247 bool Ezc::Item::CreateTreeReadItem(const char * & itext)
248 {
249
250 if( *itext == '[' )
251 {
252 CreateTreeReadItemDirective(itext);
253 return true;
254 }
255 else
256 if( *itext )
257 {
258 CreateTreeReadItemText(itext);
259 return true;
260 }
261
262 // the end of the string
263 return false;
264 }
265
266
267 void Ezc::Item::CreateTreeReadAll(const char * & itext)
268 {
269 Item item;
270
271 while( item.CreateTreeReadItem(itext) )
272 {
273 AddItem(item);
274
275 if( item.type==item_end || item.type==item_else )
276 return;
277
278 if( item.type == Item::item_ifany )
279 item_table.back()->CreateTreeReadIfany(itext);
280
281 if( item.type == Item::item_for )
282 item_table.back()->CreateTreeReadFor(itext);
283 }
284 }
285
286 bool Ezc::Item::CreateTreeReadDeleteLastEndItem()
287 {
288 if( item_table.empty() )
289 return false;
290
291 if( item_table.back()->LastItemType() == item_end )
292 {
293 item_table.back()->item_table.erase(
294 item_table.back()->item_table.begin() +
295 item_table.back()->item_table.size() - 1 );
296
297 return true;
298 }
299
300 return false;
301 }
302
303 void Ezc::Item::CreateTreeReadIfany(const char * & itext)
304 {
305 Item item;
306
307 item.type = item_container;
308 AddItem(item);
309 item_table.back()->CreateTree(itext);
310
311 if( item_table.back()->LastItemType() == item_else )
312 {
313 // basically we don't have to erase it
314 CreateTreeReadDeleteLastEndItem();
315
316 item.ClearTable();
317 AddItem(item);
318 item_table.back()->CreateTree(itext);
319 }
320
321 if( !CreateTreeReadDeleteLastEndItem() )
322 {
323 // [end] is missing
324 // it's probably the end of the input string
325 }
326 }
327
328
329 void Ezc::Item::CreateTreeReadFor(const char * & itext)
330 {
331 Item item;
332
333 item.type = item_container;
334 AddItem(item);
335 item_table.back()->CreateTree(itext);
336
337 if( !CreateTreeReadDeleteLastEndItem() )
338 {
339 // [end] is missing
340 // it's probably the end of the input string
341 }
342 }
343
344
345 void Ezc::Item::CreateTree(const char * & itext)
346 {
347 if( type == item_container)
348 CreateTreeReadAll(itext);
349 }
350
351
352 //
353 void Ezc::Item::MakeTextContainer(std::string & otext, UserInfoTable & user_info_table)
354 {
355 std::vector<Item*>::iterator i = item_table.begin();
356
357 for( ; i != item_table.end() ; ++i )
358 (*i)->MakeText(otext, user_info_table);
359 }
360
361
362 void Ezc::Item::MakeTextMsgCantFind(std::string & otext, std::string & key)
363 {
364 std::ostringstream msg;
365
366 msg << "<!-- ezc: can't find: " << key << " -->";
367 otext += msg.str();
368 }
369
370
371 void Ezc::Item::MakeTextNormal(std::string & otext, UserInfoTable & user_info_table)
372 {
373 if( directives.empty() )
374 return;
375
376 UserInfoTable::iterator i = user_info_table.find( directives[0] );
377
378 if( i != user_info_table.end() )
379 {
380 Info info;
381 info.result = false;
382 info.iter = 0;
383 (i->second.user_function)(info);
384
385 otext += info.text;
386 }
387 else
388 {
389 MakeTextMsgCantFind(otext, directives[0]);
390 }
391 }
392
393 void Ezc::Item::MakeTextIfany(std::string & otext, UserInfoTable & user_info_table)
394 {
395 std::vector<std::string>::iterator d = directives.begin();
396 int how_many_true = 0;
397
398 for( ; d != directives.end() ; ++d )
399 {
400 UserInfoTable::iterator i = user_info_table.find( *d );
401
402 if( i != user_info_table.end() )
403 {
404 Info info;
405 info.result = false;
406 info.iter = 0;
407 (i->second.user_function)(info);
408
409 if( !info.text.empty() || info.result )
410 ++how_many_true;
411 }
412 else
413 {
414 MakeTextMsgCantFind(otext, *d);
415 }
416 }
417
418 if( how_many_true == directives.size() )
419 {
420 // one element should be in the table (but we're testing)
421 if( item_table.size() > 0 )
422 item_table[0]->MakeText(otext, user_info_table);
423 }
424 else
425 {
426 // second element can be (or not -- it's from [else])
427 if( item_table.size() > 1 )
428 item_table[1]->MakeText(otext, user_info_table);
429 }
430 }
431
432
433 void Ezc::Item::MakeTextFor(std::string & otext, UserInfoTable & user_info_table)
434 {
435 if( directives.empty() )
436 return;
437
438
439 UserInfoTable::iterator i = user_info_table.find( directives[0] );
440
441 if( i != user_info_table.end() )
442 {
443 Info info;
444 info.result = false;
445 info.iter = 0;
446
447 i->second.iter = info.iter;
448
449 while( true )
450 {
451 (i->second.user_function)(info);
452 ++info.iter;
453 i->second.iter = info.iter;
454
455 if( info.text.empty() && !info.result )
456 break;
457
458 if( item_table.size() > 0 )
459 item_table[0]->MakeText(otext, user_info_table);
460 }
461 }
462 else
463 {
464 MakeTextMsgCantFind(otext, directives[0]);
465 }
466 }
467
468
469 void Ezc::Item::MakeText(std::string & otext, UserInfoTable & user_info_table)
470 {
471 if( type == item_text )
472 {
473 otext += text;
474 }
475 else
476 if( type == item_container )
477 {
478 MakeTextContainer(otext, user_info_table);
479 }
480 else
481 if( type == item_normal )
482 {
483 MakeTextNormal(otext, user_info_table);
484 }
485 else
486 if( type == item_ifany )
487 {
488 MakeTextIfany(otext, user_info_table);
489 }
490 else
491 if( type == item_for )
492 {
493 MakeTextFor(otext, user_info_table);
494 }
495 else
496 if( type == item_err )
497 {
498 otext += "<!-- ezc: wrong directive -->";
499 }
500
501
502 }
503

svnadmin@ttmath.org
ViewVC Help
Powered by ViewVC 1.2.1