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"
36 #include "wx/wxexpr.h"
38 extern "C" void add_expr(char *);
39 extern "C" void LexFromFile(FILE *fd
);
40 extern "C" void LexFromString(char *buf
);
43 wxExprDatabase
*thewxExprDatabase
= NULL
;
44 wxExprErrorHandler currentwxExprErrorHandler
;
46 wxExpr::wxExpr(const wxString
& functor
)
53 wxExpr
*pfunctor
= new wxExpr(wxExprWord
, functor
);
58 wxExpr::wxExpr(wxExprType the_type
, const wxString
& word_or_string
)
65 value
.word
= copystring((const char *)word_or_string
);
68 value
.string
= copystring((const char *)word_or_string
);
83 wxExpr::wxExpr(wxExprType the_type
, char *word_or_string
, bool allocate
)
90 value
.word
= allocate
? copystring(word_or_string
) : word_or_string
;
93 value
.string
= allocate
? copystring(word_or_string
) : word_or_string
;
108 wxExpr::wxExpr(long the_integer
)
110 type
= wxExprInteger
;
111 value
.integer
= the_integer
;
116 wxExpr::wxExpr(double the_real
)
119 value
.real
= the_real
;
124 wxExpr::wxExpr(wxList
*the_list
)
131 wxExpr
*listExpr
= new wxExpr(wxExprList
);
133 wxNode
*node
= the_list
->First();
136 wxExpr
*expr
= (wxExpr
*)node
->Data();
137 listExpr
->Append(expr
);
145 wxExpr::~wxExpr(void)
156 delete[] value
.string
;
166 wxExpr
*expr
= value
.first
;
169 wxExpr
*expr1
= expr
->next
;
176 case wxExprNull
: break;
180 void wxExpr::Append(wxExpr
*expr
)
190 void wxExpr::Insert(wxExpr
*expr
)
192 expr
->next
= value
.first
;
199 wxExpr
*wxExpr::Copy(void) const
201 // This seems to get round an optimizer bug when
202 // using Watcom C++ 10a in WIN32 compilation mode.
203 // If these lines not present, the type seems to be
204 // interpreted wrongly as an integer.
205 // I don't want to turn optimization off since it's needed
206 // for reading in files quickly.
207 #if defined(__WATCOMC__)
215 return new wxExpr(value
.integer
);
217 return new wxExpr(value
.real
);
219 return new wxExpr(wxExprString
, wxString(value
.string
));
221 return new wxExpr(wxExprWord
, wxString(value
.word
));
224 wxExpr
*expr
= value
.first
;
225 wxExpr
*new_list
= new wxExpr(wxExprList
);
228 wxExpr
*expr2
= expr
->Copy();
229 new_list
->Append(expr2
);
241 // Get the wxExpr (containing (= wxExpr Value) form) for the given word
242 // or string, assuming that we have Attribute=Value, ...
243 wxExpr
*wxExpr::GetAttributeValueNode(const wxString
& word
) const // Use only for a clause or list
245 if (type
!= wxExprList
)
248 wxExpr
*expr
= value
.first
;
251 if (expr
->type
== wxExprList
)
253 wxExpr
*firstNode
= expr
->value
.first
;
254 if ((firstNode
->type
== wxExprWord
) && (firstNode
->value
.word
[0] == '='))
256 wxExpr
*secondNode
= firstNode
->next
;
257 if ((secondNode
->type
== wxExprWord
) &&
258 (strcmp((const char *)word
, secondNode
->value
.word
) == 0))
269 // Get the value (in wxExpr form) for the given word or string, assuming
270 // that we have Attribute=Value, ...
271 wxExpr
*wxExpr::AttributeValue(const wxString
& word
) const // Use only for a clause or list
273 if (type
!= wxExprList
)
276 wxExpr
*attExpr
= GetAttributeValueNode(word
);
277 if (attExpr
&& attExpr
->value
.first
&& attExpr
->value
.first
->next
)
278 return attExpr
->value
.first
->next
->next
;
282 wxString
wxExpr::Functor(void) const // Use only for a clause
284 if ((type
!= wxExprList
) || !value
.first
)
287 if (value
.first
->type
== wxExprWord
)
288 return wxString(value
.first
->value
.word
);
293 bool wxExpr::IsFunctor(const wxString
& f
) const // Use only for a clause
295 if ((type
!= wxExprList
) || !value
.first
)
298 return (value
.first
->type
== wxExprWord
&&
299 (strcmp((const char *)f
, value
.first
->value
.word
) == 0));
302 // Return nth argument of a clause (starting from 1)
303 wxExpr
*wxExpr::Arg(wxExprType theType
, int arg
) const
305 wxExpr
*expr
= value
.first
;
307 for (i
= 1; i
< arg
; i
++)
311 if (expr
&& (expr
->type
== theType
))
317 // Return nth argument of a list expression (starting from zero)
318 wxExpr
*wxExpr::Nth(int arg
) const
320 if (type
!= wxExprList
)
323 wxExpr
*expr
= value
.first
;
325 for (i
= 0; i
< arg
; i
++)
336 // Returns the number of elements in a list expression
337 int wxExpr::Number(void) const
339 if (type
!= wxExprList
)
343 wxExpr
*expr
= value
.first
;
352 void wxExpr::DeleteAttributeValue(const wxString
& attribute
)
354 if (type
!= wxExprList
)
357 wxExpr
*expr
= value
.first
;
358 wxExpr
*lastExpr
= this;
361 if (expr
->type
== wxExprList
)
363 wxExpr
*firstNode
= expr
->value
.first
;
364 if ((firstNode
->type
== wxExprWord
) && (firstNode
->value
.word
[0] == '='))
366 wxExpr
*secondNode
= firstNode
->next
;
367 if ((secondNode
->type
== wxExprWord
) &&
368 (strcmp((const char *)attribute
, secondNode
->value
.word
) == 0))
370 wxExpr
*nextExpr
= expr
->next
;
373 lastExpr
->next
= nextExpr
;
388 void wxExpr::AddAttributeValue(const wxString
& attribute
, wxExpr
*val
)
390 if (type
!= wxExprList
)
392 // cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
395 // Warning - existing code may assume that any existing value
396 // is deleted first. For efficiency, we leave this to the application.
397 // DeleteAttributeValue(attribute);
399 wxExpr
*patt
= new wxExpr(wxExprWord
, attribute
);
400 wxExpr
*pequals
= new wxExpr(wxExprWord
, "=");
402 wxExpr
*listExpr
= new wxExpr(wxExprList
);
404 listExpr
->Append(pequals
);
405 listExpr
->Append(patt
);
406 listExpr
->Append(val
);
411 void wxExpr::AddAttributeValue(const wxString
& attribute
, long val
)
413 if (type
!= wxExprList
)
415 // cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
418 // Warning - existing code may assume that any existing value
419 // is deleted first. For efficiency, we leave this to the application.
420 // DeleteAttributeValue(attribute);
422 wxExpr
*patt
= new wxExpr(wxExprWord
, attribute
);
423 wxExpr
*pval
= new wxExpr(val
);
424 wxExpr
*pequals
= new wxExpr(wxExprWord
, "=");
426 wxExpr
*listExpr
= new wxExpr(wxExprList
);
428 listExpr
->Append(pequals
);
429 listExpr
->Append(patt
);
430 listExpr
->Append(pval
);
435 void wxExpr::AddAttributeValue(const wxString
& attribute
, double val
)
437 if (type
!= wxExprList
)
439 // cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
443 // DeleteAttributeValue(attribute);
444 wxExpr
*patt
= new wxExpr(wxExprWord
, attribute
);
445 wxExpr
*pval
= new wxExpr(val
);
446 wxExpr
*pequals
= new wxExpr(wxExprWord
, "=");
448 wxExpr
*listExpr
= new wxExpr(wxExprList
);
450 listExpr
->Append(pequals
);
451 listExpr
->Append(patt
);
452 listExpr
->Append(pval
);
457 void wxExpr::AddAttributeValueString(const wxString
& attribute
, const wxString
& val
)
459 if (type
!= wxExprList
)
461 // cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
465 // DeleteAttributeValue(attribute);
467 wxExpr
*patt
= new wxExpr(wxExprWord
, attribute
);
468 wxExpr
*pval
= new wxExpr(wxExprString
, val
);
469 wxExpr
*pequals
= new wxExpr(wxExprWord
, "=");
471 wxExpr
*listExpr
= new wxExpr(wxExprList
);
473 listExpr
->Append(pequals
);
474 listExpr
->Append(patt
);
475 listExpr
->Append(pval
);
480 void wxExpr::AddAttributeValueWord(const wxString
& attribute
, const wxString
& val
)
482 if (type
!= wxExprList
)
484 // cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
488 // DeleteAttributeValue(attribute);
490 wxExpr
*patt
= new wxExpr(wxExprWord
, attribute
);
491 wxExpr
*pval
= new wxExpr(wxExprWord
, val
);
492 wxExpr
*pequals
= new wxExpr(wxExprWord
, "=");
494 wxExpr
*listExpr
= new wxExpr(wxExprList
);
496 listExpr
->Append(pequals
);
497 listExpr
->Append(patt
);
498 listExpr
->Append(pval
);
503 void wxExpr::AddAttributeValue(const wxString
& attribute
, wxList
*val
)
505 if (type
!= wxExprList
)
507 // cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
513 // DeleteAttributeValue(attribute);
515 wxExpr
*patt
= new wxExpr(wxExprWord
, attribute
);
516 wxExpr
*pval
= new wxExpr(val
);
517 wxExpr
*pequals
= new wxExpr(wxExprWord
, "=");
519 wxExpr
*listExpr
= new wxExpr(wxExprList
);
521 listExpr
->Append(pequals
);
522 listExpr
->Append(patt
);
523 listExpr
->Append(pval
);
528 void wxExpr::AddAttributeValueStringList(const wxString
& attribute
, wxList
*string_list
)
530 if (type
!= wxExprList
)
532 // cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
538 // DeleteAttributeValue(attribute);
540 // First make a list of wxExpr strings
541 wxExpr
*listExpr
= new wxExpr(wxExprList
);
542 wxNode
*node
= string_list
->First();
545 char *string
= (char *)node
->Data();
546 wxExpr
*expr
= new wxExpr(wxExprString
, wxString(string
));
547 listExpr
->Append(expr
);
551 // Now make an (=, Att, Value) triple
552 wxExpr
*patt
= new wxExpr(wxExprWord
, attribute
);
553 wxExpr
*pequals
= new wxExpr(wxExprWord
, "=");
555 wxExpr
*listExpr2
= new wxExpr(wxExprList
);
557 listExpr2
->Append(pequals
);
558 listExpr2
->Append(patt
);
559 listExpr2
->Append(listExpr
);
564 bool wxExpr::GetAttributeValue(const wxString
& att
, int& var
) const
566 wxExpr
*expr
= AttributeValue(att
);
568 if (expr
&& (expr
->Type() == wxExprInteger
|| expr
->Type() == wxExprReal
))
570 var
= (int)(expr
->IntegerValue());
577 bool wxExpr::GetAttributeValue(const wxString
& att
, long& var
) const
579 wxExpr
*expr
= AttributeValue(att
);
581 if (expr
&& (expr
->Type() == wxExprInteger
|| expr
->Type() == wxExprReal
))
583 var
= expr
->IntegerValue();
590 bool wxExpr::GetAttributeValue(const wxString
& att
, float& var
) const
592 wxExpr
*expr
= AttributeValue(att
);
593 if (expr
&& (expr
->Type() == wxExprInteger
|| expr
->Type() == wxExprReal
))
595 var
= (float) expr
->RealValue();
602 bool wxExpr::GetAttributeValue(const wxString
& att
, double& var
) const
604 wxExpr
*expr
= AttributeValue(att
);
605 if (expr
&& (expr
->Type() == wxExprInteger
|| expr
->Type() == wxExprReal
))
607 var
= expr
->RealValue();
614 bool wxExpr::GetAttributeValue(const wxString
& att
, wxString
& var
) const // Word OR string -> string
616 wxExpr
*expr
= AttributeValue(att
);
617 if (expr
&& expr
->Type() == wxExprWord
)
619 var
= expr
->WordValue();
622 else if (expr
&& expr
->Type() == wxExprString
)
624 var
= expr
->StringValue();
631 bool wxExpr::GetAttributeValue(const wxString
& att
, wxExpr
**var
) const
633 wxExpr
*expr
= AttributeValue(att
);
643 bool wxExpr::GetAttributeValueStringList(const wxString
& att
, wxList
*var
) const
645 wxExpr
*expr
= AttributeValue(att
);
646 if (expr
&& expr
->Type() == wxExprList
)
648 wxExpr
*string_expr
= expr
->value
.first
;
651 if (string_expr
->Type() == wxExprString
)
652 var
->Append((wxObject
*)copystring(string_expr
->StringValue()));
654 string_expr
= string_expr
->next
;
663 void wxExpr::AssignAttributeValue(char *att
, char **var
) const
666 if (GetAttributeValue(att
, str
))
670 *var
= copystring((const char *) str
);
674 void wxExpr::WriteClause(ostream
& stream
) // Write this expression as a top-level clause
676 if (type
!= wxExprList
)
679 wxExpr
*node
= value
.first
;
682 node
->WriteExpr(stream
);
690 node
->WriteExpr(stream
);
692 if (node
) stream
<< ",\n";
699 void wxExpr::WriteExpr(ostream
& stream
) // Write as any other subexpression
701 // This seems to get round an optimizer bug when
702 // using Watcom C++ 10a in WIN32 compilation mode.
703 // If these lines not present, the type seems to be
704 // interpreted wrongly as an integer.
705 // I don't want to turn optimization off since it's needed
706 // for reading in files quickly.
707 #if defined(__WATCOMC__)
716 stream
<< value
.integer
;
721 double f
= value
.real
;
722 /* Now the parser can cope with this.
723 // Prevent printing in 'e' notation. Any better way?
724 if (fabs(f) < 0.00001)
728 sprintf(buf
, "%.6g", f
);
736 int len
= strlen(value
.string
);
737 for (i
= 0; i
< len
; i
++)
739 char ch
= value
.string
[i
];
740 if (ch
== '"' || ch
== '\\')
750 bool quote_it
= FALSE
;
751 int len
= strlen(value
.word
);
752 if ((len
== 0) || (len
> 0 && (value
.word
[0] > 64 && value
.word
[0] < 91)))
757 for (i
= 0; i
< len
; i
++)
758 if ((!isalpha(value
.word
[i
])) && (!isdigit(value
.word
[i
])) &&
759 (value
.word
[i
] != '_'))
760 { quote_it
= TRUE
; i
= len
; }
766 stream
<< value
.word
;
779 wxExpr
*expr
= value
.first
;
781 if ((expr
->Type() == wxExprWord
) && (strcmp(expr
->WordValue(), "=") == 0))
783 wxExpr
*arg1
= expr
->next
;
784 wxExpr
*arg2
= arg1
->next
;
785 arg1
->WriteExpr(stream
);
787 arg2
->WriteExpr(stream
);
794 expr
->WriteExpr(stream
);
796 if (expr
) stream
<< ", ";
803 case wxExprNull
: break;
807 void wxExpr::WriteLispExpr(ostream
& stream
)
813 stream
<< value
.integer
;
818 stream
<< value
.real
;
823 stream
<< "\"" << value
.string
<< "\"";
828 stream
<< value
.word
;
833 wxExpr
*expr
= value
.first
;
838 expr
->WriteLispExpr(stream
);
840 if (expr
) stream
<< " ";
846 case wxExprNull
: break;
851 * wxExpr 'database' (list of expressions)
854 #if !USE_SHARED_LIBRARIES
855 IMPLEMENT_DYNAMIC_CLASS(wxExprDatabase
, wxList
)
858 wxExprDatabase::wxExprDatabase(wxExprErrorHandler handler
)
862 currentwxExprErrorHandler
= handler
;
866 wxExprDatabase::wxExprDatabase(wxExprType type
, const wxString
& attribute
, int size
,
867 wxExprErrorHandler handler
)
870 attribute_to_hash
= attribute
;
871 if (type
== wxExprString
)
872 hash_table
= new wxHashTable(wxKEY_STRING
, size
);
873 else if (type
== wxExprInteger
)
874 hash_table
= new wxHashTable(wxKEY_INTEGER
, size
);
875 else hash_table
= NULL
;
877 currentwxExprErrorHandler
= handler
;
881 wxExprDatabase::~wxExprDatabase(void)
888 void wxExprDatabase::BeginFind(void) // Initialise a search
893 wxExpr
*wxExprDatabase::FindClause(long id
) // Find a term based on an integer id attribute
894 // e.g. node(id=23, type=rectangle, ....).
896 wxExpr
*found
= NULL
;
897 while (position
&& !found
)
899 wxExpr
*term
= (wxExpr
*)position
->Data();
901 if (term
->Type() == wxExprList
)
903 wxExpr
*value
= term
->AttributeValue("id");
904 if (value
->Type() == wxExprInteger
&& value
->IntegerValue() == id
)
907 position
= position
->Next();
912 // Find on basis of attribute/value pairs, e.g. type=rectangle
913 wxExpr
*wxExprDatabase::FindClause(const wxString
& word
, const wxString
& val
)
915 wxExpr
*found
= NULL
;
916 while (position
&& !found
)
918 wxExpr
*term
= (wxExpr
*)position
->Data();
920 if (term
->Type() == wxExprList
)
922 wxExpr
*value
= term
->AttributeValue(word
);
923 if ((value
->Type() == wxExprWord
&& value
->WordValue() == val
) ||
924 (value
->Type() == wxExprString
&& value
->StringValue() == val
))
927 position
= position
->Next();
932 wxExpr
*wxExprDatabase::FindClause(const wxString
& word
, long val
)
934 wxExpr
*found
= NULL
;
935 while (position
&& !found
)
937 wxExpr
*term
= (wxExpr
*)position
->Data();
939 if (term
->Type() == wxExprList
)
941 wxExpr
*value
= term
->AttributeValue(word
);
942 if ((value
->Type() == wxExprInteger
) && (value
->IntegerValue() == val
))
945 position
= position
->Next();
950 wxExpr
*wxExprDatabase::FindClause(const wxString
& word
, double val
)
952 wxExpr
*found
= NULL
;
953 while (position
&& !found
)
955 wxExpr
*term
= (wxExpr
*)position
->Data();
957 if (term
->Type() == wxExprList
)
959 wxExpr
*value
= term
->AttributeValue(word
);
960 if ((value
->Type() == wxExprReal
) && (value
->RealValue() == val
))
963 position
= position
->Next();
968 wxExpr
*wxExprDatabase::FindClauseByFunctor(const wxString
& functor
)
970 wxExpr
*found
= NULL
;
971 while (position
&& !found
)
973 wxExpr
*term
= (wxExpr
*)position
->Data();
975 if (term
->Type() == wxExprList
)
977 if (term
->Functor() == functor
)
980 position
= position
->Next();
985 // If hashing is on, must store in hash table too
986 void wxExprDatabase::Append(wxExpr
*clause
)
988 wxList::Append((wxObject
*)clause
);
991 wxString
functor(clause
->Functor());
992 wxExpr
*expr
= clause
->AttributeValue(attribute_to_hash
);
995 long functor_key
= hash_table
->MakeKey((char *)(const char *)functor
);
997 if (expr
&& expr
->Type() == wxExprString
)
999 value_key
= hash_table
->MakeKey((char *)(const char *)expr
->StringValue());
1000 hash_table
->Put(functor_key
+ value_key
, (char *)(const char *)expr
->StringValue(), (wxObject
*)clause
);
1002 else if (expr
&& expr
->Type() == wxExprInteger
)
1004 value_key
= expr
->IntegerValue();
1005 hash_table
->Put(functor_key
+ value_key
, expr
->IntegerValue(), (wxObject
*)clause
);
1012 wxExpr
*wxExprDatabase::HashFind(const wxString
& functor
, long value
) const
1014 long key
= hash_table
->MakeKey((char *)(const char *)functor
) + value
;
1016 // The key alone isn't guaranteed to be unique:
1017 // must supply value too. Let's assume the value of the
1018 // id is going to be reasonably unique.
1019 return (wxExpr
*)hash_table
->Get(key
, value
);
1022 wxExpr
*wxExprDatabase::HashFind(const wxString
& functor
, const wxString
& value
) const
1024 long key
= hash_table
->MakeKey((char *)(const char *)functor
) + hash_table
->MakeKey((char *)(const char *)value
);
1025 return (wxExpr
*)hash_table
->Get(key
, (char *)(const char *)value
);
1028 void wxExprDatabase::ClearDatabase(void)
1031 wxNode
*node
= First();
1034 wxExpr
*expr
= (wxExpr
*)node
->Data();
1041 hash_table
->Clear();
1044 bool wxExprDatabase::Read(const wxString
& filename
)
1048 FILE *f
= fopen((const char *)filename
, "r");
1051 thewxExprDatabase
= this;
1058 return (noErrors
== 0);
1066 bool wxExprDatabase::ReadFromString(const wxString
& buffer
)
1069 thewxExprDatabase
= this;
1071 LexFromString((char *)(const char *)buffer
);
1074 return (noErrors
== 0);
1077 bool wxExprDatabase::Write(const wxString
& fileName
)
1079 ofstream
str((char *)(const char *)fileName
);
1085 bool wxExprDatabase::Write(ostream
& stream
)
1088 wxNode
*node
= First();
1091 wxExpr
*expr
= (wxExpr
*)node
->Data();
1092 expr
->WriteClause(stream
);
1093 node
= node
->Next();
1095 return (noErrors
== 0);
1098 void wxExprDatabase::WriteLisp(ostream
& stream
)
1101 wxNode
*node
= First();
1104 wxExpr
*expr
= (wxExpr
*)node
->Data();
1105 expr
->WriteLispExpr(stream
);
1107 node
= node
->Next();
1111 void add_expr(wxExpr
* expr
)
1113 thewxExprDatabase
->Append(expr
);
1117 bool wxExprIsFunctor(wxExpr
*expr
, const wxString
& functor
)
1119 if (expr
&& (expr
->Type() == wxExprList
))
1121 wxExpr
*first_expr
= expr
->value
.first
;
1123 if (first_expr
&& (first_expr
->Type() == wxExprWord
) &&
1124 (first_expr
->WordValue() == functor
))
1134 * Called from parser
1138 char *wxmake_integer(char *str
)
1140 wxExpr
*x
= new wxExpr(atol(str
));
1145 char *wxmake_real(char *str1
, char *str2
)
1149 sprintf(buf
, "%s.%s", str1
, str2
);
1150 double f
= (double)atof(buf
);
1151 wxExpr
*x
= new wxExpr(f
);
1156 // extern "C" double exp10(double);
1158 char *wxmake_exp(char *str1
, char *str2
)
1160 double mantissa
= (double)atoi(str1
);
1161 double exponent
= (double)atoi(str2
);
1163 double d
= mantissa
* pow(10.0, exponent
);
1165 wxExpr
*x
= new wxExpr(d
);
1170 char *wxmake_exp2(char *str1
, char *str2
, char *str3
)
1174 sprintf(buf
, "%s.%s", str1
, str2
);
1175 double mantissa
= (double)atof(buf
);
1176 double exponent
= (double)atoi(str3
);
1178 double d
= mantissa
* pow(10.0, exponent
);
1180 wxExpr
*x
= new wxExpr(d
);
1185 char *wxmake_word(char *str
)
1187 wxExpr
*x
= new wxExpr(wxExprWord
, str
);
1191 char *wxmake_string(char *str
)
1196 str
++; /* skip leading quote */
1197 len
= strlen(str
) - 1; /* ignore trailing quote */
1199 s
= new char[len
+ 1];
1202 for(i
=0; i
<len
; i
++)
1204 if (str
[i
] == '\\' && str
[i
+1] == '"')
1209 else if (str
[i
] == '\\' && str
[i
+1] == '\\')
1220 wxExpr
*x
= new wxExpr(wxExprString
, s
, FALSE
);
1224 char *proio_cons(char * ccar
, char * ccdr
)
1226 wxExpr
*car
= (wxExpr
*)ccar
;
1227 wxExpr
*cdr
= (wxExpr
*)ccdr
;
1231 cdr
= new wxExpr(wxExprList
);
1238 void process_command(char * cexpr
)
1240 wxExpr
*expr
= (wxExpr
*)cexpr
;
1244 void syntax_error(char *WXUNUSED(s
))
1246 if (currentwxExprErrorHandler
)
1247 (void)(*(currentwxExprErrorHandler
))(WXEXPR_ERROR_SYNTAX
, "syntax error");
1248 if (thewxExprDatabase
) thewxExprDatabase
->noErrors
+= 1;
1253 // char *__cdecl strdup(const char *s)
1254 WXDLLEXPORT
char *strdup(const char *s
)
1256 int len
= strlen(s
);
1257 char *new_s
= (char *)malloc(sizeof(char)*(len
+1));