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