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