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