]> git.saurik.com Git - wxWidgets.git/blame - contrib/src/deprecated/wxexpr.cpp
Applied patch [ 795491 ] Multimon sample compatibility with various conditions
[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
c74caa09
MB
35static inline wxChar* copystring(const wxChar* s)
36 { return wxStrcpy(new wxChar[wxStrlen(s) + 1], s); }
37
4a3bdee6
JS
38extern "C" void add_expr(char *);
39extern "C" void LexFromFile(FILE *fd);
40extern "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
15e8daec
VS
110extern "C" WXDLLIMPEXP_DATA_DEPRECATED(FILE*) yyin;
111extern "C" WXDLLIMPEXP_DEPRECATED int yyparse(void);
4a3bdee6
JS
112
113
114wxExprDatabase *thewxExprDatabase = NULL;
115wxExprErrorHandler currentwxExprErrorHandler;
116
117wxExpr::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
129wxExpr::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
154wxExpr::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
179wxExpr::wxExpr(long the_integer)
180{
181 type = wxExprInteger;
182 value.integer = the_integer;
183 client_data = NULL;
184 next = NULL;
185}
186
187wxExpr::wxExpr(double the_real)
188{
189 type = wxExprReal;
190 value.real = the_real;
191 client_data = NULL;
192 next = NULL;
193}
194
195wxExpr::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
216wxExpr::~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
251void 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
261void wxExpr::Insert(wxExpr *expr)
262{
263 expr->next = value.first;
264 value.first = expr;
265
266 if (!last)
267 last = expr;
268}
269
270wxExpr *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, ...
314wxExpr *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, ...
342wxExpr *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
353wxString 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
364bool 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)
374wxExpr *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)
389wxExpr *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
408int 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
423void 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
459void 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
482void 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
506void 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
528void 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
551void 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
574void 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
599void 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
635bool 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
648bool 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
661bool 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
673bool 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
685bool 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
702bool 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
714bool 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
734void 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
745void 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
771void 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
881IMPLEMENT_DYNAMIC_CLASS(wxExprDatabase, wxList)
882
883wxExprDatabase::wxExprDatabase(wxExprErrorHandler handler)
884{
885 position = NULL;
886 hash_table = NULL;
887 currentwxExprErrorHandler = handler;
888 noErrors = 0;
889}
890
891wxExprDatabase::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
906wxExprDatabase::~wxExprDatabase(void)
907{
908 ClearDatabase();
909 if (hash_table)
910 delete hash_table;
911}
912
913void wxExprDatabase::BeginFind(void) // Initialise a search
914{
915 position = GetFirst();
916}
917
918wxExpr *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
938wxExpr *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
957wxExpr *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
975wxExpr *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
993wxExpr *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
1011void 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
1037wxExpr *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
1047wxExpr *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
1053void 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
1069bool 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
1091bool 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
1103bool 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
1115bool 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
1128void add_expr(wxExpr * expr)
1129{
1130 thewxExprDatabase->Append(expr);
1131}
1132
1133// Checks functor
1134bool 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
1155char *wxmake_integer(char *str)
1156{
1157 wxExpr *x = new wxExpr(atol(str));
1158
1159 return (char *)x;
1160}
1161
1162char *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
1175char *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
1187char *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
1202char *wxmake_word(char *str)
1203{
1204 wxExpr *x = new wxExpr(wxExprWord, wxString(str, wxConvLibc).c_str());
1205 return (char *)x;
1206}
1207
1208char *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
1242char *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
1256void process_command(char * cexpr)
1257{
1258 wxExpr *expr = (wxExpr *)cexpr;
1259 add_expr(expr);
1260}
1261
1262void 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)
1272WXDLLEXPORT 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