1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart and Markus Holzem
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "wxexpr.h"
16 // For compilers that support precompilation, includes "wx/wx.h".
17 #include "wx/wxprec.h"
39 #include "wx/wxexpr.h"
41 extern "C" void add_expr(char *);
42 extern "C" void LexFromFile(FILE *fd
);
43 extern "C" void LexFromString(char *buf
);
45 wxExprDatabase
*thewxExprDatabase
= NULL
;
46 wxExprErrorHandler currentwxExprErrorHandler
;
48 IMPLEMENT_DYNAMIC_CLASS(wxExprDatabase
, wxList
)
50 wxExpr::wxExpr(const wxString
& functor
)
57 wxExpr
*pfunctor
= new wxExpr(wxExprWord
, functor
);
62 wxExpr::wxExpr(wxExprType the_type
, const wxString
& word_or_string
)
69 value
.word
= copystring((const char *)word_or_string
);
72 value
.string
= copystring((const char *)word_or_string
);
87 wxExpr::wxExpr(wxExprType the_type
, char *word_or_string
, bool allocate
)
94 value
.word
= allocate
? copystring(word_or_string
) : word_or_string
;
97 value
.string
= allocate
? copystring(word_or_string
) : word_or_string
;
112 wxExpr::wxExpr(long the_integer
)
114 type
= wxExprInteger
;
115 value
.integer
= the_integer
;
120 wxExpr::wxExpr(double the_real
)
123 value
.real
= the_real
;
128 wxExpr::wxExpr(wxList
*the_list
)
135 wxExpr
*listExpr
= new wxExpr(wxExprList
);
137 wxNode
*node
= the_list
->First();
140 wxExpr
*expr
= (wxExpr
*)node
->Data();
141 listExpr
->Append(expr
);
149 wxExpr::~wxExpr(void)
160 delete[] value
.string
;
170 wxExpr
*expr
= value
.first
;
173 wxExpr
*expr1
= expr
->next
;
180 case wxExprNull
: break;
184 void wxExpr::Append(wxExpr
*expr
)
194 void wxExpr::Insert(wxExpr
*expr
)
196 expr
->next
= value
.first
;
203 wxExpr
*wxExpr::Copy(void) const
205 // This seems to get round an optimizer bug when
206 // using Watcom C++ 10a in WIN32 compilation mode.
207 // If these lines not present, the type seems to be
208 // interpreted wrongly as an integer.
209 // I don't want to turn optimization off since it's needed
210 // for reading in files quickly.
211 #if defined(__WATCOMC__)
219 return new wxExpr(value
.integer
);
221 return new wxExpr(value
.real
);
223 return new wxExpr(wxExprString
, wxString(value
.string
));
225 return new wxExpr(wxExprWord
, wxString(value
.word
));
228 wxExpr
*expr
= value
.first
;
229 wxExpr
*new_list
= new wxExpr(wxExprList
);
232 wxExpr
*expr2
= expr
->Copy();
233 new_list
->Append(expr2
);
245 // Get the wxExpr (containing (= wxExpr Value) form) for the given word
246 // or string, assuming that we have Attribute=Value, ...
247 wxExpr
*wxExpr::GetAttributeValueNode(const wxString
& word
) const // Use only for a clause or list
249 if (type
!= wxExprList
)
252 wxExpr
*expr
= value
.first
;
255 if (expr
->type
== wxExprList
)
257 wxExpr
*firstNode
= expr
->value
.first
;
258 if ((firstNode
->type
== wxExprWord
) && (firstNode
->value
.word
[0] == '='))
260 wxExpr
*secondNode
= firstNode
->next
;
261 if ((secondNode
->type
== wxExprWord
) &&
262 (strcmp((const char *)word
, secondNode
->value
.word
) == 0))
273 // Get the value (in wxExpr form) for the given word or string, assuming
274 // that we have Attribute=Value, ...
275 wxExpr
*wxExpr::AttributeValue(const wxString
& word
) const // Use only for a clause or list
277 if (type
!= wxExprList
)
280 wxExpr
*attExpr
= GetAttributeValueNode(word
);
281 if (attExpr
&& attExpr
->value
.first
&& attExpr
->value
.first
->next
)
282 return attExpr
->value
.first
->next
->next
;
286 wxString
wxExpr::Functor(void) const // Use only for a clause
288 if ((type
!= wxExprList
) || !value
.first
)
291 if (value
.first
->type
== wxExprWord
)
292 return wxString(value
.first
->value
.word
);
297 bool wxExpr::IsFunctor(const wxString
& f
) const // Use only for a clause
299 if ((type
!= wxExprList
) || !value
.first
)
302 return (value
.first
->type
== wxExprWord
&&
303 (strcmp((const char *)f
, value
.first
->value
.word
) == 0));
306 // Return nth argument of a clause (starting from 1)
307 wxExpr
*wxExpr::Arg(wxExprType theType
, int arg
) const
309 wxExpr
*expr
= value
.first
;
311 for (i
= 1; i
< arg
; i
++)
315 if (expr
&& (expr
->type
== theType
))
321 // Return nth argument of a list expression (starting from zero)
322 wxExpr
*wxExpr::Nth(int arg
) const
324 if (type
!= wxExprList
)
327 wxExpr
*expr
= value
.first
;
329 for (i
= 0; i
< arg
; i
++)
340 // Returns the number of elements in a list expression
341 int wxExpr::Number(void) const
343 if (type
!= wxExprList
)
347 wxExpr
*expr
= value
.first
;
356 void wxExpr::DeleteAttributeValue(const wxString
& attribute
)
358 if (type
!= wxExprList
)
361 wxExpr
*expr
= value
.first
;
362 wxExpr
*lastExpr
= this;
365 if (expr
->type
== wxExprList
)
367 wxExpr
*firstNode
= expr
->value
.first
;
368 if ((firstNode
->type
== wxExprWord
) && (firstNode
->value
.word
[0] == '='))
370 wxExpr
*secondNode
= firstNode
->next
;
371 if ((secondNode
->type
== wxExprWord
) &&
372 (strcmp((const char *)attribute
, secondNode
->value
.word
) == 0))
374 wxExpr
*nextExpr
= expr
->next
;
377 lastExpr
->next
= nextExpr
;
392 void wxExpr::AddAttributeValue(const wxString
& attribute
, wxExpr
*val
)
394 if (type
!= wxExprList
)
396 // cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
399 // Warning - existing code may assume that any existing value
400 // is deleted first. For efficiency, we leave this to the application.
401 // DeleteAttributeValue(attribute);
403 wxExpr
*patt
= new wxExpr(wxExprWord
, attribute
);
404 wxExpr
*pequals
= new wxExpr(wxExprWord
, "=");
406 wxExpr
*listExpr
= new wxExpr(wxExprList
);
408 listExpr
->Append(pequals
);
409 listExpr
->Append(patt
);
410 listExpr
->Append(val
);
415 void wxExpr::AddAttributeValue(const wxString
& attribute
, long val
)
417 if (type
!= wxExprList
)
419 // cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
422 // Warning - existing code may assume that any existing value
423 // is deleted first. For efficiency, we leave this to the application.
424 // DeleteAttributeValue(attribute);
426 wxExpr
*patt
= new wxExpr(wxExprWord
, attribute
);
427 wxExpr
*pval
= new wxExpr(val
);
428 wxExpr
*pequals
= new wxExpr(wxExprWord
, "=");
430 wxExpr
*listExpr
= new wxExpr(wxExprList
);
432 listExpr
->Append(pequals
);
433 listExpr
->Append(patt
);
434 listExpr
->Append(pval
);
439 void wxExpr::AddAttributeValue(const wxString
& attribute
, double val
)
441 if (type
!= wxExprList
)
443 // cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
447 // DeleteAttributeValue(attribute);
448 wxExpr
*patt
= new wxExpr(wxExprWord
, attribute
);
449 wxExpr
*pval
= new wxExpr(val
);
450 wxExpr
*pequals
= new wxExpr(wxExprWord
, "=");
452 wxExpr
*listExpr
= new wxExpr(wxExprList
);
454 listExpr
->Append(pequals
);
455 listExpr
->Append(patt
);
456 listExpr
->Append(pval
);
461 void wxExpr::AddAttributeValueString(const wxString
& attribute
, const wxString
& val
)
463 if (type
!= wxExprList
)
465 // cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
469 // DeleteAttributeValue(attribute);
471 wxExpr
*patt
= new wxExpr(wxExprWord
, attribute
);
472 wxExpr
*pval
= new wxExpr(wxExprString
, val
);
473 wxExpr
*pequals
= new wxExpr(wxExprWord
, "=");
475 wxExpr
*listExpr
= new wxExpr(wxExprList
);
477 listExpr
->Append(pequals
);
478 listExpr
->Append(patt
);
479 listExpr
->Append(pval
);
484 void wxExpr::AddAttributeValueWord(const wxString
& attribute
, const wxString
& val
)
486 if (type
!= wxExprList
)
488 // cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
492 // DeleteAttributeValue(attribute);
494 wxExpr
*patt
= new wxExpr(wxExprWord
, attribute
);
495 wxExpr
*pval
= new wxExpr(wxExprWord
, val
);
496 wxExpr
*pequals
= new wxExpr(wxExprWord
, "=");
498 wxExpr
*listExpr
= new wxExpr(wxExprList
);
500 listExpr
->Append(pequals
);
501 listExpr
->Append(patt
);
502 listExpr
->Append(pval
);
507 void wxExpr::AddAttributeValue(const wxString
& attribute
, wxList
*val
)
509 if (type
!= wxExprList
)
511 // cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
517 // DeleteAttributeValue(attribute);
519 wxExpr
*patt
= new wxExpr(wxExprWord
, attribute
);
520 wxExpr
*pval
= new wxExpr(val
);
521 wxExpr
*pequals
= new wxExpr(wxExprWord
, "=");
523 wxExpr
*listExpr
= new wxExpr(wxExprList
);
525 listExpr
->Append(pequals
);
526 listExpr
->Append(patt
);
527 listExpr
->Append(pval
);
532 void wxExpr::AddAttributeValueStringList(const wxString
& attribute
, wxList
*string_list
)
534 if (type
!= wxExprList
)
536 // cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
542 // DeleteAttributeValue(attribute);
544 // First make a list of wxExpr strings
545 wxExpr
*listExpr
= new wxExpr(wxExprList
);
546 wxNode
*node
= string_list
->First();
549 char *string
= (char *)node
->Data();
550 wxExpr
*expr
= new wxExpr(wxExprString
, wxString(string
));
551 listExpr
->Append(expr
);
555 // Now make an (=, Att, Value) triple
556 wxExpr
*patt
= new wxExpr(wxExprWord
, attribute
);
557 wxExpr
*pequals
= new wxExpr(wxExprWord
, "=");
559 wxExpr
*listExpr2
= new wxExpr(wxExprList
);
561 listExpr2
->Append(pequals
);
562 listExpr2
->Append(patt
);
563 listExpr2
->Append(listExpr
);
568 bool wxExpr::GetAttributeValue(const wxString
& att
, int& var
) const
570 wxExpr
*expr
= AttributeValue(att
);
572 if (expr
&& (expr
->Type() == wxExprInteger
|| expr
->Type() == wxExprReal
))
574 var
= (int)(expr
->IntegerValue());
581 bool wxExpr::GetAttributeValue(const wxString
& att
, long& var
) const
583 wxExpr
*expr
= AttributeValue(att
);
585 if (expr
&& (expr
->Type() == wxExprInteger
|| expr
->Type() == wxExprReal
))
587 var
= expr
->IntegerValue();
594 bool wxExpr::GetAttributeValue(const wxString
& att
, float& var
) const
596 wxExpr
*expr
= AttributeValue(att
);
597 if (expr
&& (expr
->Type() == wxExprInteger
|| expr
->Type() == wxExprReal
))
599 var
= (float) expr
->RealValue();
606 bool wxExpr::GetAttributeValue(const wxString
& att
, double& var
) const
608 wxExpr
*expr
= AttributeValue(att
);
609 if (expr
&& (expr
->Type() == wxExprInteger
|| expr
->Type() == wxExprReal
))
611 var
= expr
->RealValue();
618 bool wxExpr::GetAttributeValue(const wxString
& att
, wxString
& var
) const // Word OR string -> string
620 wxExpr
*expr
= AttributeValue(att
);
621 if (expr
&& expr
->Type() == wxExprWord
)
623 var
= expr
->WordValue();
626 else if (expr
&& expr
->Type() == wxExprString
)
628 var
= expr
->StringValue();
635 bool wxExpr::GetAttributeValue(const wxString
& att
, wxExpr
**var
) const
637 wxExpr
*expr
= AttributeValue(att
);
647 bool wxExpr::GetAttributeValueStringList(const wxString
& att
, wxList
*var
) const
649 wxExpr
*expr
= AttributeValue(att
);
650 if (expr
&& expr
->Type() == wxExprList
)
652 wxExpr
*string_expr
= expr
->value
.first
;
655 if (string_expr
->Type() == wxExprString
)
656 var
->Append((wxObject
*)copystring(string_expr
->StringValue()));
658 string_expr
= string_expr
->next
;
667 void wxExpr::AssignAttributeValue(char *att
, char **var
) const
670 if (GetAttributeValue(att
, str
))
674 *var
= copystring((const char *) str
);
678 void wxExpr::WriteClause(ostream
& stream
) // Write this expression as a top-level clause
680 if (type
!= wxExprList
)
683 wxExpr
*node
= value
.first
;
686 node
->WriteExpr(stream
);
694 node
->WriteExpr(stream
);
696 if (node
) stream
<< ",\n";
703 void wxExpr::WriteExpr(ostream
& stream
) // Write as any other subexpression
705 // This seems to get round an optimizer bug when
706 // using Watcom C++ 10a in WIN32 compilation mode.
707 // If these lines not present, the type seems to be
708 // interpreted wrongly as an integer.
709 // I don't want to turn optimization off since it's needed
710 // for reading in files quickly.
711 #if defined(__WATCOMC__)
720 stream
<< value
.integer
;
725 double f
= value
.real
;
726 /* Now the parser can cope with this.
727 // Prevent printing in 'e' notation. Any better way?
728 if (fabs(f) < 0.00001)
732 sprintf(buf
, "%.6g", f
);
740 int len
= strlen(value
.string
);
741 for (i
= 0; i
< len
; i
++)
743 char ch
= value
.string
[i
];
744 if (ch
== '"' || ch
== '\\')
754 bool quote_it
= FALSE
;
755 int len
= strlen(value
.word
);
756 if ((len
== 0) || (len
> 0 && (value
.word
[0] > 64 && value
.word
[0] < 91)))
761 for (i
= 0; i
< len
; i
++)
762 if ((!isalpha(value
.word
[i
])) && (!isdigit(value
.word
[i
])) &&
763 (value
.word
[i
] != '_'))
764 { quote_it
= TRUE
; i
= len
; }
770 stream
<< value
.word
;
783 wxExpr
*expr
= value
.first
;
785 if ((expr
->Type() == wxExprWord
) && (strcmp(expr
->WordValue(), "=") == 0))
787 wxExpr
*arg1
= expr
->next
;
788 wxExpr
*arg2
= arg1
->next
;
789 arg1
->WriteExpr(stream
);
791 arg2
->WriteExpr(stream
);
798 expr
->WriteExpr(stream
);
800 if (expr
) stream
<< ", ";
807 case wxExprNull
: break;
811 void wxExpr::WriteLispExpr(ostream
& stream
)
817 stream
<< value
.integer
;
822 stream
<< value
.real
;
827 stream
<< "\"" << value
.string
<< "\"";
832 stream
<< value
.word
;
837 wxExpr
*expr
= value
.first
;
842 expr
->WriteLispExpr(stream
);
844 if (expr
) stream
<< " ";
850 case wxExprNull
: break;
854 // wxExpr 'database' (list of expressions)
855 wxExprDatabase::wxExprDatabase(wxExprErrorHandler handler
)
859 currentwxExprErrorHandler
= handler
;
863 wxExprDatabase::wxExprDatabase(wxExprType type
, const wxString
& attribute
, int size
,
864 wxExprErrorHandler handler
)
867 attribute_to_hash
= attribute
;
868 if (type
== wxExprString
)
869 hash_table
= new wxHashTable(wxKEY_STRING
, size
);
870 else if (type
== wxExprInteger
)
871 hash_table
= new wxHashTable(wxKEY_INTEGER
, size
);
872 else hash_table
= NULL
;
874 currentwxExprErrorHandler
= handler
;
878 wxExprDatabase::~wxExprDatabase(void)
885 void wxExprDatabase::BeginFind(void) // Initialise a search
890 wxExpr
*wxExprDatabase::FindClause(long id
) // Find a term based on an integer id attribute
891 // e.g. node(id=23, type=rectangle, ....).
893 wxExpr
*found
= NULL
;
894 while (position
&& !found
)
896 wxExpr
*term
= (wxExpr
*)position
->Data();
898 if (term
->Type() == wxExprList
)
900 wxExpr
*value
= term
->AttributeValue("id");
901 if (value
->Type() == wxExprInteger
&& value
->IntegerValue() == id
)
904 position
= position
->Next();
909 // Find on basis of attribute/value pairs, e.g. type=rectangle
910 wxExpr
*wxExprDatabase::FindClause(const wxString
& word
, const wxString
& val
)
912 wxExpr
*found
= NULL
;
913 while (position
&& !found
)
915 wxExpr
*term
= (wxExpr
*)position
->Data();
917 if (term
->Type() == wxExprList
)
919 wxExpr
*value
= term
->AttributeValue(word
);
920 if ((value
->Type() == wxExprWord
&& value
->WordValue() == val
) ||
921 (value
->Type() == wxExprString
&& value
->StringValue() == val
))
924 position
= position
->Next();
929 wxExpr
*wxExprDatabase::FindClause(const wxString
& word
, long val
)
931 wxExpr
*found
= NULL
;
932 while (position
&& !found
)
934 wxExpr
*term
= (wxExpr
*)position
->Data();
936 if (term
->Type() == wxExprList
)
938 wxExpr
*value
= term
->AttributeValue(word
);
939 if ((value
->Type() == wxExprInteger
) && (value
->IntegerValue() == val
))
942 position
= position
->Next();
947 wxExpr
*wxExprDatabase::FindClause(const wxString
& word
, double val
)
949 wxExpr
*found
= NULL
;
950 while (position
&& !found
)
952 wxExpr
*term
= (wxExpr
*)position
->Data();
954 if (term
->Type() == wxExprList
)
956 wxExpr
*value
= term
->AttributeValue(word
);
957 if ((value
->Type() == wxExprReal
) && (value
->RealValue() == val
))
960 position
= position
->Next();
965 wxExpr
*wxExprDatabase::FindClauseByFunctor(const wxString
& functor
)
967 wxExpr
*found
= NULL
;
968 while (position
&& !found
)
970 wxExpr
*term
= (wxExpr
*)position
->Data();
972 if (term
->Type() == wxExprList
)
974 if (term
->Functor() == functor
)
977 position
= position
->Next();
982 // If hashing is on, must store in hash table too
983 void wxExprDatabase::Append(wxExpr
*clause
)
985 wxList::Append((wxObject
*)clause
);
988 wxString
functor(clause
->Functor());
989 wxExpr
*expr
= clause
->AttributeValue(attribute_to_hash
);
992 long functor_key
= hash_table
->MakeKey((char *)(const char *)functor
);
994 if (expr
&& expr
->Type() == wxExprString
)
996 value_key
= hash_table
->MakeKey((char *)(const char *)expr
->StringValue());
997 hash_table
->Put(functor_key
+ value_key
, (char *)(const char *)expr
->StringValue(), (wxObject
*)clause
);
999 else if (expr
&& expr
->Type() == wxExprInteger
)
1001 value_key
= expr
->IntegerValue();
1002 hash_table
->Put(functor_key
+ value_key
, expr
->IntegerValue(), (wxObject
*)clause
);
1009 wxExpr
*wxExprDatabase::HashFind(const wxString
& functor
, long value
) const
1011 long key
= hash_table
->MakeKey((char *)(const char *)functor
) + value
;
1013 // The key alone isn't guaranteed to be unique:
1014 // must supply value too. Let's assume the value of the
1015 // id is going to be reasonably unique.
1016 return (wxExpr
*)hash_table
->Get(key
, value
);
1019 wxExpr
*wxExprDatabase::HashFind(const wxString
& functor
, const wxString
& value
) const
1021 long key
= hash_table
->MakeKey((char *)(const char *)functor
) + hash_table
->MakeKey((char *)(const char *)value
);
1022 return (wxExpr
*)hash_table
->Get(key
, (char *)(const char *)value
);
1025 void wxExprDatabase::ClearDatabase(void)
1028 wxNode
*node
= First();
1031 wxExpr
*expr
= (wxExpr
*)node
->Data();
1038 hash_table
->Clear();
1041 bool wxExprDatabase::Read(const wxString
& filename
)
1045 FILE *f
= fopen((const char *)filename
, "r");
1048 thewxExprDatabase
= this;
1055 return (noErrors
== 0);
1063 bool wxExprDatabase::ReadFromString(const wxString
& buffer
)
1066 thewxExprDatabase
= this;
1068 LexFromString((char *)(const char *)buffer
);
1071 return (noErrors
== 0);
1074 bool wxExprDatabase::Write(const wxString
& fileName
)
1076 ofstream
str((char *)(const char *)fileName
);
1082 bool wxExprDatabase::Write(ostream
& stream
)
1085 wxNode
*node
= First();
1088 wxExpr
*expr
= (wxExpr
*)node
->Data();
1089 expr
->WriteClause(stream
);
1090 node
= node
->Next();
1092 return (noErrors
== 0);
1095 void wxExprDatabase::WriteLisp(ostream
& stream
)
1098 wxNode
*node
= First();
1101 wxExpr
*expr
= (wxExpr
*)node
->Data();
1102 expr
->WriteLispExpr(stream
);
1104 node
= node
->Next();
1108 void add_expr(wxExpr
* expr
)
1110 thewxExprDatabase
->Append(expr
);
1114 bool wxExprIsFunctor(wxExpr
*expr
, const wxString
& functor
)
1116 if (expr
&& (expr
->Type() == wxExprList
))
1118 wxExpr
*first_expr
= expr
->value
.first
;
1120 if (first_expr
&& (first_expr
->Type() == wxExprWord
) &&
1121 (first_expr
->WordValue() == functor
))
1131 * Called from parser
1135 char *make_integer(char *str
)
1137 wxExpr
*x
= new wxExpr(atol(str
));
1142 char *make_real(char *str1
, char *str2
)
1146 sprintf(buf
, "%s.%s", str1
, str2
);
1147 double f
= (double)atof(buf
);
1148 wxExpr
*x
= new wxExpr(f
);
1153 // extern "C" double exp10(double);
1155 char *make_exp(char *str1
, char *str2
)
1157 double mantissa
= (double)atoi(str1
);
1158 double exponent
= (double)atoi(str2
);
1160 double d
= mantissa
* pow(10.0, exponent
);
1162 wxExpr
*x
= new wxExpr(d
);
1167 char *make_exp2(char *str1
, char *str2
, char *str3
)
1171 sprintf(buf
, "%s.%s", str1
, str2
);
1172 double mantissa
= (double)atof(buf
);
1173 double exponent
= (double)atoi(str3
);
1175 double d
= mantissa
* pow(10.0, exponent
);
1177 wxExpr
*x
= new wxExpr(d
);
1182 char *make_word(char *str
)
1184 wxExpr
*x
= new wxExpr(wxExprWord
, str
);
1188 char *make_string(char *str
)
1193 str
++; /* skip leading quote */
1194 len
= strlen(str
) - 1; /* ignore trailing quote */
1196 s
= new char[len
+ 1];
1199 for(i
=0; i
<len
; i
++)
1201 if (str
[i
] == '\\' && str
[i
+1] == '"')
1206 else if (str
[i
] == '\\' && str
[i
+1] == '\\')
1217 wxExpr
*x
= new wxExpr(wxExprString
, s
, FALSE
);
1221 char *proio_cons(char * ccar
, char * ccdr
)
1223 wxExpr
*car
= (wxExpr
*)ccar
;
1224 wxExpr
*cdr
= (wxExpr
*)ccdr
;
1228 cdr
= new wxExpr(wxExprList
);
1235 void process_command(char * cexpr
)
1237 wxExpr
*expr
= (wxExpr
*)cexpr
;
1241 void syntax_error(char *WXUNUSED(s
))
1243 if (currentwxExprErrorHandler
)
1244 (void)(*(currentwxExprErrorHandler
))(WXEXPR_ERROR_SYNTAX
, "syntax error");
1245 if (thewxExprDatabase
) thewxExprDatabase
->noErrors
+= 1;
1250 // char *__cdecl strdup(const char *s)
1251 WXDLLEXPORT
char *strdup(const char *s
)
1253 int len
= strlen(s
);
1254 char *new_s
= (char *)malloc(sizeof(char)*(len
+1));