]> git.saurik.com Git - wxWidgets.git/blob - contrib/src/deprecated/wxexpr.cpp
wxEmptyString decorations.
[wxWidgets.git] / contrib / src / deprecated / wxexpr.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: wxexpr.cpp
3 // Purpose: wxExpr
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "wxexpr.h"
14 #endif
15
16 // For compilers that support precompilation, includes "wx/wx.h".
17 #include "wx/wxprec.h"
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 #include "wx/deprecated/setup.h"
24
25 #if wxUSE_PROLOGIO
26
27 #include <stdarg.h>
28 #include <ctype.h>
29 #include <string.h>
30
31 #include "wx/utils.h"
32 #include "wx/deprecated/expr.h"
33 #include "wx/deprecated/wxexpr.h"
34
35 #if !WXWIN_COMPATIBILITY_2_4
36 static inline wxChar* copystring(const wxChar* s)
37 { return wxStrcpy(new wxChar[wxStrlen(s) + 1], s); }
38 #endif
39
40 extern "C" void add_expr(char *);
41 extern "C" void LexFromFile(FILE *fd);
42 extern "C" void LexFromString(char *buf);
43
44
45
46 /* Rename all YACC/LEX stuff or we'll conflict with other
47 * applications
48 */
49
50 #define yyback PROIO_yyback
51 #define yylook PROIO_yylook
52 #define yywrap PROIO_yywrap
53 #define yyoutput PROIO_yyoutput
54 #define yylex PROIO_yylex
55 #define yyerror PROIO_yyerror
56 #define yyleng PROIO_yyleng
57 #define yytext PROIO_yytext
58 #define yymorfg PROIO_yymorfg
59 #define yylineno PROIO_yylineno
60 #define yytchar PROIO_yytchar
61 #define yyin PROIO_yyin
62 #define yyout PROIO_yyout
63 #define yysvf PROIO_yysvf
64 #define yyestate PROIO_yyestate
65 #define yysvec PROIO_yysvec
66 #define yybgin PROIO_yybgin
67 #define yyprevious PROIO_yyprevious
68 #define yylhs PROIO_yylhs
69 #define yylen PROIO_yylen
70 #define yydefred PROIO_yydefred
71 #define yydgoto PROIO_yydgoto
72 #define yysindex PROIO_yysindex
73 #define yyrindex PROIO_yyrindex
74 #define yygindex PROIO_yygindex
75 #define yytable PROIO_yytable
76 #define yycheck PROIO_yycheck
77 #define yyname PROIO_yyname
78 #define yyrule PROIO_yyrule
79 #define yydebug PROIO_yydebug
80 #define yynerrs PROIO_yynerrs
81 #define yyerrflag PROIO_yyerrflag
82 #define yychar PROIO_yychar
83 #define yyvsp PROIO_yyvsp
84 #define yyssp PROIO_yyssp
85 #define yyval PROIO_yyval
86 #define yylval PROIO_yylval
87 #define yyss PROIO_yyss
88 #define yyvs PROIO_yyvs
89 #define yyparse PROIO_yyparse
90
91 /* +++steve162e: more defines necessary */
92 #define yy_init_buffer PROIO_yy_init_buffer
93 #define yy_create_buffer PROIO_yy_create_buffer
94 #define yy_load_buffer_state PROIO_yy_load_buffer_state
95 #define yyrestart PROIO_yyrestart
96 #define yy_switch_to_buffer PROIO_yy_switch_to_buffer
97 #define yy_delete_buffer PROIO_yy_delete_buffer
98 /* ---steve162e */
99
100 /* WG 1/96: still more for flex 2.5 */
101 #define yy_scan_buffer PROIO_scan_buffer
102 #define yy_scan_string PROIO_scan_string
103 #define yy_scan_bytes PROIO_scan_bytes
104 #define yy_flex_debug PROIO_flex_debug
105 #define yy_flush_buffer PROIO_flush_buffer
106 #if !defined(__VISAGECPP__)
107 /* multiply defined??? */
108 #define yyleng PROIO_yyleng
109 #define yytext PROIO_yytext
110 #endif
111
112 extern "C" WXDLLIMPEXP_DATA_DEPRECATED(FILE*) yyin;
113 extern "C" WXDLLIMPEXP_DEPRECATED int yyparse(void);
114
115
116 wxExprDatabase *thewxExprDatabase = NULL;
117 wxExprErrorHandler currentwxExprErrorHandler;
118
119 wxExpr::wxExpr(const wxString& functor)
120 {
121 type = wxExprList;
122 next = NULL;
123 last = NULL;
124 value.first = NULL;
125
126 wxExpr *pfunctor = new wxExpr(wxExprWord, functor);
127 Append(pfunctor);
128 client_data = NULL;
129 }
130
131 wxExpr::wxExpr(wxExprType the_type, const wxString& word_or_string)
132 {
133 type = the_type;
134
135 switch (the_type)
136 {
137 case wxExprWord:
138 value.word = copystring((const wxChar *)word_or_string);
139 break;
140 case wxExprString:
141 value.string = copystring((const wxChar *)word_or_string);
142 break;
143 case wxExprList:
144 last = NULL;
145 value.first = NULL;
146 break;
147 case wxExprReal:
148 case wxExprInteger:
149 case wxExprNull:
150 break;
151 }
152 client_data = NULL;
153 next = NULL;
154 }
155
156 wxExpr::wxExpr(wxExprType the_type, wxChar *word_or_string, bool allocate)
157 {
158 type = the_type;
159
160 switch (the_type)
161 {
162 case wxExprWord:
163 value.word = allocate ? copystring(word_or_string) : word_or_string;
164 break;
165 case wxExprString:
166 value.string = allocate ? copystring(word_or_string) : word_or_string;
167 break;
168 case wxExprList:
169 last = NULL;
170 value.first = NULL;
171 break;
172 case wxExprReal:
173 case wxExprInteger:
174 case wxExprNull:
175 break;
176 }
177 client_data = NULL;
178 next = NULL;
179 }
180
181 wxExpr::wxExpr(long the_integer)
182 {
183 type = wxExprInteger;
184 value.integer = the_integer;
185 client_data = NULL;
186 next = NULL;
187 }
188
189 wxExpr::wxExpr(double the_real)
190 {
191 type = wxExprReal;
192 value.real = the_real;
193 client_data = NULL;
194 next = NULL;
195 }
196
197 wxExpr::wxExpr(wxList *the_list)
198 {
199 type = wxExprList;
200 client_data = NULL;
201 last = NULL;
202 value.first = NULL;
203
204 wxExpr *listExpr = new wxExpr(wxExprList);
205
206 wxNode *node = the_list->GetFirst();
207 while (node)
208 {
209 wxExpr *expr = (wxExpr *)node->GetData();
210 listExpr->Append(expr);
211 node = node->GetNext();
212 }
213 Append(listExpr);
214
215 delete the_list;
216 }
217
218 wxExpr::~wxExpr(void)
219 {
220 switch (type)
221 {
222 case wxExprInteger:
223 case wxExprReal:
224 {
225 break;
226 }
227 case wxExprString:
228 {
229 delete[] value.string;
230 break;
231 }
232 case wxExprWord:
233 {
234 delete[] value.word;
235 break;
236 }
237 case wxExprList:
238 {
239 wxExpr *expr = value.first;
240 while (expr)
241 {
242 wxExpr *expr1 = expr->next;
243
244 delete expr;
245 expr = expr1;
246 }
247 break;
248 }
249 case wxExprNull: break;
250 }
251 }
252
253 void wxExpr::Append(wxExpr *expr)
254 {
255 if (!value.first)
256 value.first = expr;
257
258 if (last)
259 last->next = expr;
260 last = expr;
261 }
262
263 void wxExpr::Insert(wxExpr *expr)
264 {
265 expr->next = value.first;
266 value.first = expr;
267
268 if (!last)
269 last = expr;
270 }
271
272 wxExpr *wxExpr::Copy(void) const
273 {
274 // This seems to get round an optimizer bug when
275 // using Watcom C++ 10a in WIN32 compilation mode.
276 // If these lines not present, the type seems to be
277 // interpreted wrongly as an integer.
278 // I don't want to turn optimization off since it's needed
279 // for reading in files quickly.
280 #if defined(__WATCOMC__)
281 char buf[2];
282 sprintf(buf, "");
283 #endif
284
285 switch (type)
286 {
287 case wxExprInteger:
288 return new wxExpr(value.integer);
289 case wxExprReal:
290 return new wxExpr(value.real);
291 case wxExprString:
292 return new wxExpr(wxExprString, wxString(value.string));
293 case wxExprWord:
294 return new wxExpr(wxExprWord, wxString(value.word));
295 case wxExprList:
296 {
297 wxExpr *expr = value.first;
298 wxExpr *new_list = new wxExpr(wxExprList);
299 while (expr)
300 {
301 wxExpr *expr2 = expr->Copy();
302 new_list->Append(expr2);
303 expr = expr->next;
304 }
305 return new_list;
306 }
307 case wxExprNull:
308 break;
309 }
310 return NULL;
311 }
312
313
314 // Get the wxExpr (containing (= wxExpr Value) form) for the given word
315 // or string, assuming that we have Attribute=Value, ...
316 wxExpr *wxExpr::GetAttributeValueNode(const wxString& word) const // Use only for a clause or list
317 {
318 if (type != wxExprList)
319 return NULL;
320
321 wxExpr *expr = value.first;
322 while (expr)
323 {
324 if (expr->type == wxExprList)
325 {
326 wxExpr *firstNode = expr->value.first;
327 if ((firstNode->type == wxExprWord) && (firstNode->value.word[0] == '='))
328 {
329 wxExpr *secondNode = firstNode->next;
330 if ((secondNode->type == wxExprWord) &&
331 (wxStrcmp((const wxChar *)word, secondNode->value.word) == 0))
332 {
333 return expr;
334 }
335 }
336 }
337 expr = expr->next;
338 }
339 return NULL;
340 }
341
342 // Get the value (in wxExpr form) for the given word or string, assuming
343 // that we have Attribute=Value, ...
344 wxExpr *wxExpr::AttributeValue(const wxString& word) const // Use only for a clause or list
345 {
346 if (type != wxExprList)
347 return NULL;
348
349 wxExpr *attExpr = GetAttributeValueNode(word);
350 if (attExpr && attExpr->value.first && attExpr->value.first->next)
351 return attExpr->value.first->next->next;
352 else return NULL;
353 }
354
355 wxString wxExpr::Functor(void) const // Use only for a clause
356 {
357 if ((type != wxExprList) || !value.first)
358 return wxString(wxT(""));
359
360 if (value.first->type == wxExprWord)
361 return wxString(value.first->value.word);
362 else
363 return wxString(wxT(""));
364 }
365
366 bool wxExpr::IsFunctor(const wxString& f) const // Use only for a clause
367 {
368 if ((type != wxExprList) || !value.first)
369 return false;
370
371 return (value.first->type == wxExprWord &&
372 (wxStrcmp((const wxChar *)f, value.first->value.word) == 0));
373 }
374
375 // Return nth argument of a clause (starting from 1)
376 wxExpr *wxExpr::Arg(wxExprType theType, int arg) const
377 {
378 wxExpr *expr = value.first;
379 int i;
380 for (i = 1; i < arg; i++)
381 if (expr)
382 expr = expr->next;
383
384 if (expr && (expr->type == theType))
385 return expr;
386 else
387 return NULL;
388 }
389
390 // Return nth argument of a list expression (starting from zero)
391 wxExpr *wxExpr::Nth(int arg) const
392 {
393 if (type != wxExprList)
394 return NULL;
395
396 wxExpr *expr = value.first;
397 int i;
398 for (i = 0; i < arg; i++)
399 if (expr)
400 expr = expr->next;
401 else return NULL;
402
403 if (expr)
404 return expr;
405 else
406 return NULL;
407 }
408
409 // Returns the number of elements in a list expression
410 int wxExpr::Number(void) const
411 {
412 if (type != wxExprList)
413 return 0;
414
415 int i = 0;
416 wxExpr *expr = value.first;
417 while (expr)
418 {
419 expr = expr->next;
420 i ++;
421 }
422 return i;
423 }
424
425 void wxExpr::DeleteAttributeValue(const wxString& attribute)
426 {
427 if (type != wxExprList)
428 return;
429
430 wxExpr *expr = value.first;
431 wxExpr *lastExpr = this;
432 while (expr)
433 {
434 if (expr->type == wxExprList)
435 {
436 wxExpr *firstNode = expr->value.first;
437 if ((firstNode->type == wxExprWord) && (firstNode->value.word[0] == '='))
438 {
439 wxExpr *secondNode = firstNode->next;
440 if ((secondNode->type == wxExprWord) &&
441 (wxStrcmp((const wxChar *)attribute, secondNode->value.word) == 0))
442 {
443 wxExpr *nextExpr = expr->next;
444 delete expr;
445
446 lastExpr->next = nextExpr;
447
448 if (last == expr)
449 last = lastExpr;
450
451 return;
452 }
453 }
454 }
455 lastExpr = expr;
456 expr = expr->next;
457 }
458 return;
459 }
460
461 void wxExpr::AddAttributeValue(const wxString& attribute, wxExpr *val)
462 {
463 if (type != wxExprList)
464 {
465 // cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
466 return;
467 }
468 // Warning - existing code may assume that any existing value
469 // is deleted first. For efficiency, we leave this to the application.
470 // DeleteAttributeValue(attribute);
471
472 wxExpr *patt = new wxExpr(wxExprWord, attribute);
473 wxExpr *pequals = new wxExpr(wxExprWord, wxT("="));
474
475 wxExpr *listExpr = new wxExpr(wxExprList);
476
477 listExpr->Append(pequals);
478 listExpr->Append(patt);
479 listExpr->Append(val);
480
481 Append(listExpr);
482 }
483
484 void wxExpr::AddAttributeValue(const wxString& attribute, long val)
485 {
486 if (type != wxExprList)
487 {
488 // cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
489 return;
490 }
491 // Warning - existing code may assume that any existing value
492 // is deleted first. For efficiency, we leave this to the application.
493 // DeleteAttributeValue(attribute);
494
495 wxExpr *patt = new wxExpr(wxExprWord, attribute);
496 wxExpr *pval = new wxExpr(val);
497 wxExpr *pequals = new wxExpr(wxExprWord, wxT("="));
498
499 wxExpr *listExpr = new wxExpr(wxExprList);
500
501 listExpr->Append(pequals);
502 listExpr->Append(patt);
503 listExpr->Append(pval);
504
505 Append(listExpr);
506 }
507
508 void wxExpr::AddAttributeValue(const wxString& attribute, double val)
509 {
510 if (type != wxExprList)
511 {
512 // cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
513 return;
514 }
515
516 // DeleteAttributeValue(attribute);
517 wxExpr *patt = new wxExpr(wxExprWord, attribute);
518 wxExpr *pval = new wxExpr(val);
519 wxExpr *pequals = new wxExpr(wxExprWord, wxT("="));
520
521 wxExpr *listExpr = new wxExpr(wxExprList);
522
523 listExpr->Append(pequals);
524 listExpr->Append(patt);
525 listExpr->Append(pval);
526
527 Append(listExpr);
528 }
529
530 void wxExpr::AddAttributeValueString(const wxString& attribute, const wxString& val)
531 {
532 if (type != wxExprList)
533 {
534 // cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
535 return;
536 }
537
538 // DeleteAttributeValue(attribute);
539
540 wxExpr *patt = new wxExpr(wxExprWord, attribute);
541 wxExpr *pval = new wxExpr(wxExprString, val);
542 wxExpr *pequals = new wxExpr(wxExprWord, wxT("="));
543
544 wxExpr *listExpr = new wxExpr(wxExprList);
545
546 listExpr->Append(pequals);
547 listExpr->Append(patt);
548 listExpr->Append(pval);
549
550 Append(listExpr);
551 }
552
553 void wxExpr::AddAttributeValueWord(const wxString& attribute, const wxString& val)
554 {
555 if (type != wxExprList)
556 {
557 // cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
558 return;
559 }
560
561 // DeleteAttributeValue(attribute);
562
563 wxExpr *patt = new wxExpr(wxExprWord, attribute);
564 wxExpr *pval = new wxExpr(wxExprWord, val);
565 wxExpr *pequals = new wxExpr(wxExprWord, wxT("="));
566
567 wxExpr *listExpr = new wxExpr(wxExprList);
568
569 listExpr->Append(pequals);
570 listExpr->Append(patt);
571 listExpr->Append(pval);
572
573 Append(listExpr);
574 }
575
576 void wxExpr::AddAttributeValue(const wxString& attribute, wxList *val)
577 {
578 if (type != wxExprList)
579 {
580 // cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
581 return;
582 }
583 if (!val)
584 return;
585
586 // DeleteAttributeValue(attribute);
587
588 wxExpr *patt = new wxExpr(wxExprWord, attribute);
589 wxExpr *pval = new wxExpr(val);
590 wxExpr *pequals = new wxExpr(wxExprWord, wxT("="));
591
592 wxExpr *listExpr = new wxExpr(wxExprList);
593
594 listExpr->Append(pequals);
595 listExpr->Append(patt);
596 listExpr->Append(pval);
597
598 Append(listExpr);
599 }
600
601 void wxExpr::AddAttributeValueStringList(const wxString& attribute, wxList *string_list)
602 {
603 if (type != wxExprList)
604 {
605 // cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
606 return;
607 }
608 if (!string_list)
609 return;
610
611 // DeleteAttributeValue(attribute);
612
613 // First make a list of wxExpr strings
614 wxExpr *listExpr = new wxExpr(wxExprList);
615 wxNode *node = string_list->GetFirst();
616 while (node)
617 {
618 wxChar *string = (wxChar*)node->GetData();
619 wxExpr *expr = new wxExpr(wxExprString, wxString(string));
620 listExpr->Append(expr);
621 node = node->GetNext();
622 }
623
624 // Now make an (=, Att, Value) triple
625 wxExpr *patt = new wxExpr(wxExprWord, attribute);
626 wxExpr *pequals = new wxExpr(wxExprWord, wxT("="));
627
628 wxExpr *listExpr2 = new wxExpr(wxExprList);
629
630 listExpr2->Append(pequals);
631 listExpr2->Append(patt);
632 listExpr2->Append(listExpr);
633
634 Append(listExpr2);
635 }
636
637 bool wxExpr::GetAttributeValue(const wxString& att, int& var) const
638 {
639 wxExpr *expr = AttributeValue(att);
640
641 if (expr && (expr->Type() == wxExprInteger || expr->Type() == wxExprReal))
642 {
643 var = (int)(expr->IntegerValue());
644 return true;
645 }
646 else
647 return false;
648 }
649
650 bool wxExpr::GetAttributeValue(const wxString& att, long& var) const
651 {
652 wxExpr *expr = AttributeValue(att);
653
654 if (expr && (expr->Type() == wxExprInteger || expr->Type() == wxExprReal))
655 {
656 var = expr->IntegerValue();
657 return true;
658 }
659 else
660 return false;
661 }
662
663 bool wxExpr::GetAttributeValue(const wxString& att, float& var) const
664 {
665 wxExpr *expr = AttributeValue(att);
666 if (expr && (expr->Type() == wxExprInteger || expr->Type() == wxExprReal))
667 {
668 var = (float) expr->RealValue();
669 return true;
670 }
671 else
672 return false;
673 }
674
675 bool wxExpr::GetAttributeValue(const wxString& att, double& var) const
676 {
677 wxExpr *expr = AttributeValue(att);
678 if (expr && (expr->Type() == wxExprInteger || expr->Type() == wxExprReal))
679 {
680 var = expr->RealValue();
681 return true;
682 }
683 else
684 return false;
685 }
686
687 bool wxExpr::GetAttributeValue(const wxString& att, wxString& var) const // Word OR string -> string
688 {
689 wxExpr *expr = AttributeValue(att);
690 if (expr && expr->Type() == wxExprWord)
691 {
692 var = expr->WordValue();
693 return true;
694 }
695 else if (expr && expr->Type() == wxExprString)
696 {
697 var = expr->StringValue();
698 return true;
699 }
700 else
701 return false;
702 }
703
704 bool wxExpr::GetAttributeValue(const wxString& att, wxExpr **var) const
705 {
706 wxExpr *expr = AttributeValue(att);
707 if (expr)
708 {
709 *var = expr;
710 return true;
711 }
712 else
713 return false;
714 }
715
716 bool wxExpr::GetAttributeValueStringList(const wxString& att, wxList *var) const
717 {
718 wxExpr *expr = AttributeValue(att);
719 if (expr && expr->Type() == wxExprList)
720 {
721 wxExpr *string_expr = expr->value.first;
722 while (string_expr)
723 {
724 if (string_expr->Type() == wxExprString)
725 var->Append((wxObject *)copystring(string_expr->StringValue()));
726
727 string_expr = string_expr->next;
728 }
729 return true;
730 }
731 else
732 return false;
733 }
734
735 // Compatibility
736 void wxExpr::AssignAttributeValue(wxChar *att, wxChar **var) const
737 {
738 wxString str;
739 if (GetAttributeValue(att, str))
740 {
741 if (*var)
742 delete[] *var;
743 *var = copystring((const wxChar *) str);
744 }
745 }
746
747 void wxExpr::WriteClause(FILE* stream) // Write this expression as a top-level clause
748 {
749 if (type != wxExprList)
750 return;
751
752 wxExpr *node = value.first;
753 if (node)
754 {
755 node->WriteExpr(stream);
756 fprintf( stream, "(" );
757 node = node->next;
758 bool first = true;
759 while (node)
760 {
761 if (!first)
762 fprintf( stream, " " );
763 node->WriteExpr(stream);
764 node = node->next;
765 if (node)
766 fprintf( stream, ",\n" );
767 first = false;
768 }
769 fprintf( stream, ").\n\n" );
770 }
771 }
772
773 void wxExpr::WriteExpr(FILE* stream) // Write as any other subexpression
774 {
775 // This seems to get round an optimizer bug when
776 // using Watcom C++ 10a in WIN32 compilation mode.
777 // If these lines not present, the type seems to be
778 // interpreted wrongly as an integer.
779 // I don't want to turn optimization off since it's needed
780 // for reading in files quickly.
781 #if defined(__WATCOMC__)
782 char buf[2];
783 sprintf(buf, "");
784 #endif
785
786 switch (type)
787 {
788 case wxExprInteger:
789 {
790 fprintf( stream, "%ld", value.integer );
791 break;
792 }
793 case wxExprReal:
794 {
795 double f = value.real;
796 fprintf( stream, "%.6g", f);
797 break;
798 }
799 case wxExprString:
800 {
801 fprintf( stream, "\"" );
802 size_t i;
803 const wxWX2MBbuf val = wxConvLibc.cWX2MB(value.string);
804 size_t len = strlen(val);
805 for (i = 0; i < len; i++)
806 {
807 char ch = val[i];
808 if (ch == '"' || ch == '\\')
809 fprintf( stream, "\\" );
810 char tmp[2];
811 tmp[0] = ch;
812 tmp[1] = 0;
813 fprintf( stream, tmp );
814 }
815 fprintf( stream, "\"" );
816 break;
817 }
818 case wxExprWord:
819 {
820 bool quote_it = false;
821 const wxWX2MBbuf val = wxConvLibc.cWX2MB(value.word);
822 size_t len = strlen(val);
823 if ((len == 0) || (len > 0 && (val[(size_t) 0] > 64 && val[(size_t) 0] < 91)))
824 quote_it = true;
825 else
826 {
827 size_t i;
828 for (i = 0; i < len; i++)
829 if ((!isalpha(val[i])) && (!isdigit(val[i])) &&
830 (val[i] != '_'))
831 { quote_it = true; i = len; }
832 }
833
834 if (quote_it)
835 fprintf( stream ,"'" );
836
837 fprintf( stream, val );
838
839 if (quote_it)
840 fprintf( stream, "'" );
841
842 break;
843 }
844 case wxExprList:
845 {
846 if (!value.first)
847 fprintf( stream, "[]" );
848 else
849 {
850 wxExpr *expr = value.first;
851
852 if ((expr->Type() == wxExprWord) && (wxStrcmp(expr->WordValue(), wxT("=")) == 0))
853 {
854 wxExpr *arg1 = expr->next;
855 wxExpr *arg2 = arg1->next;
856 arg1->WriteExpr(stream);
857 fprintf( stream, " = " );
858 arg2->WriteExpr(stream);
859 }
860 else
861 {
862 fprintf( stream, "[" );
863 while (expr)
864 {
865 expr->WriteExpr(stream);
866 expr = expr->next;
867 if (expr)
868 fprintf( stream, ", " );
869 }
870 fprintf( stream, "]" );
871 }
872 }
873 break;
874 }
875 case wxExprNull: break;
876 }
877 }
878
879 /*
880 * wxExpr 'database' (list of expressions)
881 */
882
883 IMPLEMENT_DYNAMIC_CLASS(wxExprDatabase, wxList)
884
885 wxExprDatabase::wxExprDatabase(wxExprErrorHandler handler)
886 {
887 position = NULL;
888 hash_table = NULL;
889 currentwxExprErrorHandler = handler;
890 noErrors = 0;
891 }
892
893 wxExprDatabase::wxExprDatabase(wxExprType type, const wxString& attribute, int size,
894 wxExprErrorHandler handler)
895 {
896 position = NULL;
897 attribute_to_hash = attribute;
898 if (type == wxExprString)
899 hash_table = new wxHashTable(wxKEY_STRING, size);
900 else if (type == wxExprInteger)
901 hash_table = new wxHashTable(wxKEY_INTEGER, size);
902 else hash_table = NULL;
903
904 currentwxExprErrorHandler = handler;
905 noErrors = 0;
906 }
907
908 wxExprDatabase::~wxExprDatabase(void)
909 {
910 ClearDatabase();
911 if (hash_table)
912 delete hash_table;
913 }
914
915 void wxExprDatabase::BeginFind(void) // Initialise a search
916 {
917 position = GetFirst();
918 }
919
920 wxExpr *wxExprDatabase::FindClause(long id) // Find a term based on an integer id attribute
921 // e.g. node(id=23, type=rectangle, ....).
922 {
923 wxExpr *found = NULL;
924 while (position && !found)
925 {
926 wxExpr *term = (wxExpr *)position->GetData();
927
928 if (term->Type() == wxExprList)
929 {
930 wxExpr *value = term->AttributeValue(wxT("id"));
931 if (value->Type() == wxExprInteger && value->IntegerValue() == id)
932 found = term;
933 }
934 position = position->GetNext();
935 }
936 return found;
937 }
938
939 // Find on basis of attribute/value pairs, e.g. type=rectangle
940 wxExpr *wxExprDatabase::FindClause(const wxString& word, const wxString& val)
941 {
942 wxExpr *found = NULL;
943 while (position && !found)
944 {
945 wxExpr *term = (wxExpr *)position->GetData();
946
947 if (term->Type() == wxExprList)
948 {
949 wxExpr *value = term->AttributeValue(word);
950 if ((value->Type() == wxExprWord && value->WordValue() == val) ||
951 (value->Type() == wxExprString && value->StringValue() == val))
952 found = term;
953 }
954 position = position->GetNext();
955 }
956 return found;
957 }
958
959 wxExpr *wxExprDatabase::FindClause(const wxString& word, long val)
960 {
961 wxExpr *found = NULL;
962 while (position && !found)
963 {
964 wxExpr *term = (wxExpr *)position->GetData();
965
966 if (term->Type() == wxExprList)
967 {
968 wxExpr *value = term->AttributeValue(word);
969 if ((value->Type() == wxExprInteger) && (value->IntegerValue() == val))
970 found = term;
971 }
972 position = position->GetNext();
973 }
974 return found;
975 }
976
977 wxExpr *wxExprDatabase::FindClause(const wxString& word, double val)
978 {
979 wxExpr *found = NULL;
980 while (position && !found)
981 {
982 wxExpr *term = (wxExpr *)position->GetData();
983
984 if (term->Type() == wxExprList)
985 {
986 wxExpr *value = term->AttributeValue(word);
987 if ((value->Type() == wxExprReal) && (value->RealValue() == val))
988 found = term;
989 }
990 position = position->GetNext();
991 }
992 return found;
993 }
994
995 wxExpr *wxExprDatabase::FindClauseByFunctor(const wxString& functor)
996 {
997 wxExpr *found = NULL;
998 while (position && !found)
999 {
1000 wxExpr *term = (wxExpr *)position->GetData();
1001
1002 if (term->Type() == wxExprList)
1003 {
1004 if (term->Functor() == functor)
1005 found = term;
1006 }
1007 position = position->GetNext();
1008 }
1009 return found;
1010 }
1011
1012 // If hashing is on, must store in hash table too
1013 void wxExprDatabase::Append(wxExpr *clause)
1014 {
1015 wxList::Append((wxObject *)clause);
1016 if (hash_table)
1017 {
1018 wxString functor(clause->Functor());
1019 wxExpr *expr = clause->AttributeValue(attribute_to_hash);
1020 if (expr)
1021 {
1022 long functor_key = hash_table->MakeKey(WXSTRINGCAST functor);
1023 long value_key;
1024 if (expr && expr->Type() == wxExprString)
1025 {
1026 value_key = hash_table->MakeKey(WXSTRINGCAST expr->StringValue());
1027 hash_table->Put(functor_key + value_key, WXSTRINGCAST expr->StringValue(), (wxObject *)clause);
1028 }
1029 else if (expr && expr->Type() == wxExprInteger)
1030 {
1031 value_key = expr->IntegerValue();
1032 hash_table->Put(functor_key + value_key, expr->IntegerValue(), (wxObject *)clause);
1033 }
1034
1035 }
1036 }
1037 }
1038
1039 wxExpr *wxExprDatabase::HashFind(const wxString& functor, long value) const
1040 {
1041 long key = hash_table->MakeKey(WXSTRINGCAST functor) + value;
1042
1043 // The key alone isn't guaranteed to be unique:
1044 // must supply value too. Let's assume the value of the
1045 // id is going to be reasonably unique.
1046 return (wxExpr *)hash_table->Get(key, value);
1047 }
1048
1049 wxExpr *wxExprDatabase::HashFind(const wxString& functor, const wxString& value) const
1050 {
1051 long key = hash_table->MakeKey(WXSTRINGCAST functor) + hash_table->MakeKey(WXSTRINGCAST value);
1052 return (wxExpr *)hash_table->Get(key, WXSTRINGCAST value);
1053 }
1054
1055 void wxExprDatabase::ClearDatabase(void)
1056 {
1057 noErrors = 0;
1058 wxNode *node = GetFirst();
1059 while (node)
1060 {
1061 wxExpr *expr = (wxExpr *)node->GetData();
1062 delete expr;
1063 delete node;
1064 node = GetFirst();
1065 }
1066
1067 if (hash_table)
1068 hash_table->Clear();
1069 }
1070
1071 bool wxExprDatabase::Read(const wxString& filename)
1072 {
1073 noErrors = 0;
1074
1075 FILE *f = wxFopen(filename.fn_str(), _T("r"));
1076 if (f)
1077 {
1078 thewxExprDatabase = this;
1079
1080 LexFromFile(f);
1081 yyparse();
1082 fclose(f);
1083
1084 wxExprCleanUp();
1085 return (noErrors == 0);
1086 }
1087 else
1088 {
1089 return false;
1090 }
1091 }
1092
1093 bool wxExprDatabase::ReadFromString(const wxString& buffer)
1094 {
1095 noErrors = 0;
1096 thewxExprDatabase = this;
1097
1098 const wxWX2MBbuf buf = buffer.mb_str();
1099 LexFromString(wxMBSTRINGCAST buf);
1100 yyparse();
1101 wxExprCleanUp();
1102 return (noErrors == 0);
1103 }
1104
1105 bool wxExprDatabase::Write(const wxString& fileName)
1106 {
1107 FILE *stream = wxFopen( fileName.fn_str(), _T("w+"));
1108
1109 if (!stream)
1110 return false;
1111
1112 bool success = Write(stream);
1113 fclose(stream);
1114 return success;
1115 }
1116
1117 bool wxExprDatabase::Write(FILE *stream)
1118 {
1119 noErrors = 0;
1120 wxNode *node = GetFirst();
1121 while (node)
1122 {
1123 wxExpr *expr = (wxExpr *)node->GetData();
1124 expr->WriteClause(stream);
1125 node = node->GetNext();
1126 }
1127 return (noErrors == 0);
1128 }
1129
1130 void add_expr(wxExpr * expr)
1131 {
1132 thewxExprDatabase->Append(expr);
1133 }
1134
1135 // Checks functor
1136 bool wxExprIsFunctor(wxExpr *expr, const wxString& functor)
1137 {
1138 if (expr && (expr->Type() == wxExprList))
1139 {
1140 wxExpr *first_expr = expr->value.first;
1141
1142 if (first_expr && (first_expr->Type() == wxExprWord) &&
1143 (first_expr->WordValue() == functor))
1144 return true;
1145 else
1146 return false;
1147 }
1148 else
1149 return false;
1150 }
1151
1152 /*
1153 * Called from parser
1154 *
1155 */
1156
1157 char *wxmake_integer(char *str)
1158 {
1159 wxExpr *x = new wxExpr(atol(str));
1160
1161 return (char *)x;
1162 }
1163
1164 char *wxmake_real(char *str1, char *str2)
1165 {
1166 char buf[50];
1167
1168 sprintf(buf, "%s.%s", str1, str2);
1169 double f = (double)atof(buf);
1170 wxExpr *x = new wxExpr(f);
1171
1172 return (char *)x;
1173 }
1174
1175 // extern "C" double exp10(double);
1176
1177 char *wxmake_exp(char *str1, char *str2)
1178 {
1179 double mantissa = (double)atoi(str1);
1180 double exponent = (double)atoi(str2);
1181
1182 double d = mantissa * pow(10.0, exponent);
1183
1184 wxExpr *x = new wxExpr(d);
1185
1186 return (char *)x;
1187 }
1188
1189 char *wxmake_exp2(char *str1, char *str2, char *str3)
1190 {
1191 char buf[50];
1192
1193 sprintf(buf, "%s.%s", str1, str2);
1194 double mantissa = (double)atof(buf);
1195 double exponent = (double)atoi(str3);
1196
1197 double d = mantissa * pow(10.0, exponent);
1198
1199 wxExpr *x = new wxExpr(d);
1200
1201 return (char *)x;
1202 }
1203
1204 char *wxmake_word(char *str)
1205 {
1206 wxExpr *x = new wxExpr(wxExprWord, wxString(str, wxConvLibc).c_str());
1207 return (char *)x;
1208 }
1209
1210 char *wxmake_string(char *str)
1211 {
1212 wxChar *s, *t;
1213 size_t len, i;
1214 const wxMB2WXbuf sbuf = wxConvLibc.cMB2WX(str);
1215
1216 // str++; /* skip leading quote */
1217 len = wxStrlen(sbuf) - 1; /* ignore trailing quote */
1218
1219 s = new wxChar[len + 1];
1220
1221 t = s;
1222 for(i=1; i<len; i++) // 1 since we want to skip leading quote
1223 {
1224 if (sbuf[i] == wxT('\\') && sbuf[i+1] == wxT('"'))
1225 {
1226 *t++ = wxT('"');
1227 i ++;
1228 }
1229 else if (sbuf[i] == wxT('\\') && sbuf[i+1] == wxT('\\'))
1230 {
1231 *t++ = wxT('\\');
1232 i ++;
1233 }
1234 else
1235 *t++ = sbuf[i];
1236 }
1237
1238 *t = wxT('\0');
1239
1240 wxExpr *x = new wxExpr(wxExprString, s, false);
1241 return (char *)x;
1242 }
1243
1244 char *proio_cons(char * ccar, char * ccdr)
1245 {
1246 wxExpr *car = (wxExpr *)ccar;
1247 wxExpr *cdr = (wxExpr *)ccdr;
1248
1249 if (cdr == NULL)
1250 {
1251 cdr = new wxExpr(wxExprList);
1252 }
1253 if (car)
1254 cdr->Insert(car);
1255 return (char *)cdr;
1256 }
1257
1258 void process_command(char * cexpr)
1259 {
1260 wxExpr *expr = (wxExpr *)cexpr;
1261 add_expr(expr);
1262 }
1263
1264 void syntax_error(char *WXUNUSED(s))
1265 {
1266 if (currentwxExprErrorHandler)
1267 (void)(*(currentwxExprErrorHandler))(WXEXPR_ERROR_SYNTAX, (char *)"syntax error");
1268 if (thewxExprDatabase) thewxExprDatabase->noErrors += 1;
1269 }
1270
1271 #if 0
1272 #ifdef _WINDLL
1273 // char *__cdecl strdup(const char *s)
1274 WXDLLEXPORT char *strdup(const char *s)
1275 {
1276 int len = strlen(s);
1277 char *new_s = (char *)malloc(sizeof(char)*(len+1));
1278 strcpy(new_s, s);
1279 return new_s;
1280 }
1281 #endif
1282 #endif
1283
1284 #endif
1285 // wxUSE_PROLOGIO