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