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"
31 #include "wx/wxexpr.h"
33 extern "C" void add_expr(char *);
34 extern "C" void LexFromFile(FILE *fd
);
35 extern "C" void LexFromString(char *buf
);
37 wxExprDatabase
*thewxExprDatabase
= NULL
;
38 wxExprErrorHandler currentwxExprErrorHandler
;
40 IMPLEMENT_DYNAMIC_CLASS(wxExprDatabase
, wxList
)
42 wxExpr::wxExpr(const wxString
& functor
)
49 wxExpr
*pfunctor
= new wxExpr(wxExprWord
, functor
);
54 wxExpr::wxExpr(wxExprType the_type
, const wxString
& word_or_string
)
61 value
.word
= copystring((const char *)word_or_string
);
64 value
.string
= copystring((const char *)word_or_string
);
79 wxExpr::wxExpr(wxExprType the_type
, char *word_or_string
, bool allocate
)
86 value
.word
= allocate
? copystring(word_or_string
) : word_or_string
;
89 value
.string
= allocate
? copystring(word_or_string
) : word_or_string
;
104 wxExpr::wxExpr(long the_integer
)
106 type
= wxExprInteger
;
107 value
.integer
= the_integer
;
112 wxExpr::wxExpr(double the_real
)
115 value
.real
= the_real
;
120 wxExpr::wxExpr(wxList
*the_list
)
127 wxExpr
*listExpr
= new wxExpr(wxExprList
);
129 wxNode
*node
= the_list
->First();
132 wxExpr
*expr
= (wxExpr
*)node
->Data();
133 listExpr
->Append(expr
);
141 wxExpr::~wxExpr(void)
152 delete[] value
.string
;
162 wxExpr
*expr
= value
.first
;
165 wxExpr
*expr1
= expr
->next
;
172 case wxExprNull
: break;
176 void wxExpr::Append(wxExpr
*expr
)
186 void wxExpr::Insert(wxExpr
*expr
)
188 expr
->next
= value
.first
;
195 wxExpr
*wxExpr::Copy(void) const
197 // This seems to get round an optimizer bug when
198 // using Watcom C++ 10a in WIN32 compilation mode.
199 // If these lines not present, the type seems to be
200 // interpreted wrongly as an integer.
201 // I don't want to turn optimization off since it's needed
202 // for reading in files quickly.
203 #if defined(__WATCOMC__)
211 return new wxExpr(value
.integer
);
213 return new wxExpr(value
.real
);
215 return new wxExpr(wxExprString
, wxString(value
.string
));
217 return new wxExpr(wxExprWord
, wxString(value
.word
));
220 wxExpr
*expr
= value
.first
;
221 wxExpr
*new_list
= new wxExpr(wxExprList
);
224 wxExpr
*expr2
= expr
->Copy();
225 new_list
->Append(expr2
);
237 // Get the wxExpr (containing (= wxExpr Value) form) for the given word
238 // or string, assuming that we have Attribute=Value, ...
239 wxExpr
*wxExpr::GetAttributeValueNode(const wxString
& word
) const // Use only for a clause or list
241 if (type
!= wxExprList
)
244 wxExpr
*expr
= value
.first
;
247 if (expr
->type
== wxExprList
)
249 wxExpr
*firstNode
= expr
->value
.first
;
250 if ((firstNode
->type
== wxExprWord
) && (firstNode
->value
.word
[0] == '='))
252 wxExpr
*secondNode
= firstNode
->next
;
253 if ((secondNode
->type
== wxExprWord
) &&
254 (strcmp((const char *)word
, secondNode
->value
.word
) == 0))
265 // Get the value (in wxExpr form) for the given word or string, assuming
266 // that we have Attribute=Value, ...
267 wxExpr
*wxExpr::AttributeValue(const wxString
& word
) const // Use only for a clause or list
269 if (type
!= wxExprList
)
272 wxExpr
*attExpr
= GetAttributeValueNode(word
);
273 if (attExpr
&& attExpr
->value
.first
&& attExpr
->value
.first
->next
)
274 return attExpr
->value
.first
->next
->next
;
278 wxString
wxExpr::Functor(void) const // Use only for a clause
280 if ((type
!= wxExprList
) || !value
.first
)
283 if (value
.first
->type
== wxExprWord
)
284 return wxString(value
.first
->value
.word
);
289 bool wxExpr::IsFunctor(const wxString
& f
) const // Use only for a clause
291 if ((type
!= wxExprList
) || !value
.first
)
294 return (value
.first
->type
== wxExprWord
&&
295 (strcmp((const char *)f
, value
.first
->value
.word
) == 0));
298 // Return nth argument of a clause (starting from 1)
299 wxExpr
*wxExpr::Arg(wxExprType theType
, int arg
) const
301 wxExpr
*expr
= value
.first
;
303 for (i
= 1; i
< arg
; i
++)
307 if (expr
&& (expr
->type
== theType
))
313 // Return nth argument of a list expression (starting from zero)
314 wxExpr
*wxExpr::Nth(int arg
) const
316 if (type
!= wxExprList
)
319 wxExpr
*expr
= value
.first
;
321 for (i
= 0; i
< arg
; i
++)
332 // Returns the number of elements in a list expression
333 int wxExpr::Number(void) const
335 if (type
!= wxExprList
)
339 wxExpr
*expr
= value
.first
;
348 void wxExpr::DeleteAttributeValue(const wxString
& attribute
)
350 if (type
!= wxExprList
)
353 wxExpr
*expr
= value
.first
;
354 wxExpr
*lastExpr
= this;
357 if (expr
->type
== wxExprList
)
359 wxExpr
*firstNode
= expr
->value
.first
;
360 if ((firstNode
->type
== wxExprWord
) && (firstNode
->value
.word
[0] == '='))
362 wxExpr
*secondNode
= firstNode
->next
;
363 if ((secondNode
->type
== wxExprWord
) &&
364 (strcmp((const char *)attribute
, secondNode
->value
.word
) == 0))
366 wxExpr
*nextExpr
= expr
->next
;
369 lastExpr
->next
= nextExpr
;
384 void wxExpr::AddAttributeValue(const wxString
& attribute
, wxExpr
*val
)
386 if (type
!= wxExprList
)
388 // cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
391 // Warning - existing code may assume that any existing value
392 // is deleted first. For efficiency, we leave this to the application.
393 // DeleteAttributeValue(attribute);
395 wxExpr
*patt
= new wxExpr(wxExprWord
, attribute
);
396 wxExpr
*pequals
= new wxExpr(wxExprWord
, "=");
398 wxExpr
*listExpr
= new wxExpr(wxExprList
);
400 listExpr
->Append(pequals
);
401 listExpr
->Append(patt
);
402 listExpr
->Append(val
);
407 void wxExpr::AddAttributeValue(const wxString
& attribute
, long val
)
409 if (type
!= wxExprList
)
411 // cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
414 // Warning - existing code may assume that any existing value
415 // is deleted first. For efficiency, we leave this to the application.
416 // DeleteAttributeValue(attribute);
418 wxExpr
*patt
= new wxExpr(wxExprWord
, attribute
);
419 wxExpr
*pval
= new wxExpr(val
);
420 wxExpr
*pequals
= new wxExpr(wxExprWord
, "=");
422 wxExpr
*listExpr
= new wxExpr(wxExprList
);
424 listExpr
->Append(pequals
);
425 listExpr
->Append(patt
);
426 listExpr
->Append(pval
);
431 void wxExpr::AddAttributeValue(const wxString
& attribute
, double val
)
433 if (type
!= wxExprList
)
435 // cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
439 // DeleteAttributeValue(attribute);
440 wxExpr
*patt
= new wxExpr(wxExprWord
, attribute
);
441 wxExpr
*pval
= new wxExpr(val
);
442 wxExpr
*pequals
= new wxExpr(wxExprWord
, "=");
444 wxExpr
*listExpr
= new wxExpr(wxExprList
);
446 listExpr
->Append(pequals
);
447 listExpr
->Append(patt
);
448 listExpr
->Append(pval
);
453 void wxExpr::AddAttributeValueString(const wxString
& attribute
, const wxString
& val
)
455 if (type
!= wxExprList
)
457 // cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
461 // DeleteAttributeValue(attribute);
463 wxExpr
*patt
= new wxExpr(wxExprWord
, attribute
);
464 wxExpr
*pval
= new wxExpr(wxExprString
, val
);
465 wxExpr
*pequals
= new wxExpr(wxExprWord
, "=");
467 wxExpr
*listExpr
= new wxExpr(wxExprList
);
469 listExpr
->Append(pequals
);
470 listExpr
->Append(patt
);
471 listExpr
->Append(pval
);
476 void wxExpr::AddAttributeValueWord(const wxString
& attribute
, const wxString
& val
)
478 if (type
!= wxExprList
)
480 // cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
484 // DeleteAttributeValue(attribute);
486 wxExpr
*patt
= new wxExpr(wxExprWord
, attribute
);
487 wxExpr
*pval
= new wxExpr(wxExprWord
, val
);
488 wxExpr
*pequals
= new wxExpr(wxExprWord
, "=");
490 wxExpr
*listExpr
= new wxExpr(wxExprList
);
492 listExpr
->Append(pequals
);
493 listExpr
->Append(patt
);
494 listExpr
->Append(pval
);
499 void wxExpr::AddAttributeValue(const wxString
& attribute
, wxList
*val
)
501 if (type
!= wxExprList
)
503 // cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
509 // DeleteAttributeValue(attribute);
511 wxExpr
*patt
= new wxExpr(wxExprWord
, attribute
);
512 wxExpr
*pval
= new wxExpr(val
);
513 wxExpr
*pequals
= new wxExpr(wxExprWord
, "=");
515 wxExpr
*listExpr
= new wxExpr(wxExprList
);
517 listExpr
->Append(pequals
);
518 listExpr
->Append(patt
);
519 listExpr
->Append(pval
);
524 void wxExpr::AddAttributeValueStringList(const wxString
& attribute
, wxList
*string_list
)
526 if (type
!= wxExprList
)
528 // cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
534 // DeleteAttributeValue(attribute);
536 // First make a list of wxExpr strings
537 wxExpr
*listExpr
= new wxExpr(wxExprList
);
538 wxNode
*node
= string_list
->First();
541 char *string
= (char *)node
->Data();
542 wxExpr
*expr
= new wxExpr(wxExprString
, wxString(string
));
543 listExpr
->Append(expr
);
547 // Now make an (=, Att, Value) triple
548 wxExpr
*patt
= new wxExpr(wxExprWord
, attribute
);
549 wxExpr
*pequals
= new wxExpr(wxExprWord
, "=");
551 wxExpr
*listExpr2
= new wxExpr(wxExprList
);
553 listExpr2
->Append(pequals
);
554 listExpr2
->Append(patt
);
555 listExpr2
->Append(listExpr
);
560 bool wxExpr::GetAttributeValue(const wxString
& att
, int& var
) const
562 wxExpr
*expr
= AttributeValue(att
);
564 if (expr
&& (expr
->Type() == wxExprInteger
|| expr
->Type() == wxExprReal
))
566 var
= (int)(expr
->IntegerValue());
573 bool wxExpr::GetAttributeValue(const wxString
& att
, long& var
) const
575 wxExpr
*expr
= AttributeValue(att
);
577 if (expr
&& (expr
->Type() == wxExprInteger
|| expr
->Type() == wxExprReal
))
579 var
= expr
->IntegerValue();
586 bool wxExpr::GetAttributeValue(const wxString
& att
, float& var
) const
588 wxExpr
*expr
= AttributeValue(att
);
589 if (expr
&& (expr
->Type() == wxExprInteger
|| expr
->Type() == wxExprReal
))
591 var
= (float) expr
->RealValue();
598 bool wxExpr::GetAttributeValue(const wxString
& att
, double& var
) const
600 wxExpr
*expr
= AttributeValue(att
);
601 if (expr
&& (expr
->Type() == wxExprInteger
|| expr
->Type() == wxExprReal
))
603 var
= expr
->RealValue();
610 bool wxExpr::GetAttributeValue(const wxString
& att
, wxString
& var
) const // Word OR string -> string
612 wxExpr
*expr
= AttributeValue(att
);
613 if (expr
&& expr
->Type() == wxExprWord
)
615 var
= expr
->WordValue();
618 else if (expr
&& expr
->Type() == wxExprString
)
620 var
= expr
->StringValue();
627 bool wxExpr::GetAttributeValue(const wxString
& att
, wxExpr
**var
) const
629 wxExpr
*expr
= AttributeValue(att
);
639 bool wxExpr::GetAttributeValueStringList(const wxString
& att
, wxList
*var
) const
641 wxExpr
*expr
= AttributeValue(att
);
642 if (expr
&& expr
->Type() == wxExprList
)
644 wxExpr
*string_expr
= expr
->value
.first
;
647 if (string_expr
->Type() == wxExprString
)
648 var
->Append((wxObject
*)copystring(string_expr
->StringValue()));
650 string_expr
= string_expr
->next
;
659 void wxExpr::AssignAttributeValue(char *att
, char **var
) const
662 if (GetAttributeValue(att
, str
))
666 *var
= copystring((const char *) str
);
670 void wxExpr::WriteClause(ostream
& stream
) // Write this expression as a top-level clause
672 if (type
!= wxExprList
)
675 wxExpr
*node
= value
.first
;
678 node
->WriteExpr(stream
);
686 node
->WriteExpr(stream
);
688 if (node
) stream
<< ",\n";
695 void wxExpr::WriteExpr(ostream
& stream
) // Write as any other subexpression
697 // This seems to get round an optimizer bug when
698 // using Watcom C++ 10a in WIN32 compilation mode.
699 // If these lines not present, the type seems to be
700 // interpreted wrongly as an integer.
701 // I don't want to turn optimization off since it's needed
702 // for reading in files quickly.
703 #if defined(__WATCOMC__)
712 stream
<< value
.integer
;
717 double f
= value
.real
;
718 /* Now the parser can cope with this.
719 // Prevent printing in 'e' notation. Any better way?
720 if (fabs(f) < 0.00001)
724 sprintf(buf
, "%.6g", f
);
732 int len
= strlen(value
.string
);
733 for (i
= 0; i
< len
; i
++)
735 char ch
= value
.string
[i
];
736 if (ch
== '"' || ch
== '\\')
746 bool quote_it
= FALSE
;
747 int len
= strlen(value
.word
);
748 if ((len
== 0) || (len
> 0 && (value
.word
[0] > 64 && value
.word
[0] < 91)))
753 for (i
= 0; i
< len
; i
++)
754 if ((!isalpha(value
.word
[i
])) && (!isdigit(value
.word
[i
])) &&
755 (value
.word
[i
] != '_'))
756 { quote_it
= TRUE
; i
= len
; }
762 stream
<< value
.word
;
775 wxExpr
*expr
= value
.first
;
777 if ((expr
->Type() == wxExprWord
) && (strcmp(expr
->WordValue(), "=") == 0))
779 wxExpr
*arg1
= expr
->next
;
780 wxExpr
*arg2
= arg1
->next
;
781 arg1
->WriteExpr(stream
);
783 arg2
->WriteExpr(stream
);
790 expr
->WriteExpr(stream
);
792 if (expr
) stream
<< ", ";
799 case wxExprNull
: break;
803 void wxExpr::WriteLispExpr(ostream
& stream
)
809 stream
<< value
.integer
;
814 stream
<< value
.real
;
819 stream
<< "\"" << value
.string
<< "\"";
824 stream
<< value
.word
;
829 wxExpr
*expr
= value
.first
;
834 expr
->WriteLispExpr(stream
);
836 if (expr
) stream
<< " ";
842 case wxExprNull
: break;
846 // wxExpr 'database' (list of expressions)
847 wxExprDatabase::wxExprDatabase(wxExprErrorHandler handler
)
851 currentwxExprErrorHandler
= handler
;
855 wxExprDatabase::wxExprDatabase(wxExprType type
, const wxString
& attribute
, int size
,
856 wxExprErrorHandler handler
)
859 attribute_to_hash
= attribute
;
860 if (type
== wxExprString
)
861 hash_table
= new wxHashTable(wxKEY_STRING
, size
);
862 else if (type
== wxExprInteger
)
863 hash_table
= new wxHashTable(wxKEY_INTEGER
, size
);
864 else hash_table
= NULL
;
866 currentwxExprErrorHandler
= handler
;
870 wxExprDatabase::~wxExprDatabase(void)
877 void wxExprDatabase::BeginFind(void) // Initialise a search
882 wxExpr
*wxExprDatabase::FindClause(long id
) // Find a term based on an integer id attribute
883 // e.g. node(id=23, type=rectangle, ....).
885 wxExpr
*found
= NULL
;
886 while (position
&& !found
)
888 wxExpr
*term
= (wxExpr
*)position
->Data();
890 if (term
->Type() == wxExprList
)
892 wxExpr
*value
= term
->AttributeValue("id");
893 if (value
->Type() == wxExprInteger
&& value
->IntegerValue() == id
)
896 position
= position
->Next();
901 // Find on basis of attribute/value pairs, e.g. type=rectangle
902 wxExpr
*wxExprDatabase::FindClause(const wxString
& word
, const wxString
& val
)
904 wxExpr
*found
= NULL
;
905 while (position
&& !found
)
907 wxExpr
*term
= (wxExpr
*)position
->Data();
909 if (term
->Type() == wxExprList
)
911 wxExpr
*value
= term
->AttributeValue(word
);
912 if ((value
->Type() == wxExprWord
&& value
->WordValue() == val
) ||
913 (value
->Type() == wxExprString
&& value
->StringValue() == val
))
916 position
= position
->Next();
921 wxExpr
*wxExprDatabase::FindClause(const wxString
& word
, long val
)
923 wxExpr
*found
= NULL
;
924 while (position
&& !found
)
926 wxExpr
*term
= (wxExpr
*)position
->Data();
928 if (term
->Type() == wxExprList
)
930 wxExpr
*value
= term
->AttributeValue(word
);
931 if ((value
->Type() == wxExprInteger
) && (value
->IntegerValue() == val
))
934 position
= position
->Next();
939 wxExpr
*wxExprDatabase::FindClause(const wxString
& word
, double val
)
941 wxExpr
*found
= NULL
;
942 while (position
&& !found
)
944 wxExpr
*term
= (wxExpr
*)position
->Data();
946 if (term
->Type() == wxExprList
)
948 wxExpr
*value
= term
->AttributeValue(word
);
949 if ((value
->Type() == wxExprReal
) && (value
->RealValue() == val
))
952 position
= position
->Next();
957 wxExpr
*wxExprDatabase::FindClauseByFunctor(const wxString
& functor
)
959 wxExpr
*found
= NULL
;
960 while (position
&& !found
)
962 wxExpr
*term
= (wxExpr
*)position
->Data();
964 if (term
->Type() == wxExprList
)
966 if (term
->Functor() == functor
)
969 position
= position
->Next();
974 // If hashing is on, must store in hash table too
975 void wxExprDatabase::Append(wxExpr
*clause
)
977 wxList::Append((wxObject
*)clause
);
980 wxString
functor(clause
->Functor());
981 wxExpr
*expr
= clause
->AttributeValue(attribute_to_hash
);
984 long functor_key
= hash_table
->MakeKey((char *)(const char *)functor
);
986 if (expr
&& expr
->Type() == wxExprString
)
988 value_key
= hash_table
->MakeKey((char *)(const char *)expr
->StringValue());
989 hash_table
->Put(functor_key
+ value_key
, (char *)(const char *)expr
->StringValue(), (wxObject
*)clause
);
991 else if (expr
&& expr
->Type() == wxExprInteger
)
993 value_key
= expr
->IntegerValue();
994 hash_table
->Put(functor_key
+ value_key
, expr
->IntegerValue(), (wxObject
*)clause
);
1001 wxExpr
*wxExprDatabase::HashFind(const wxString
& functor
, long value
) const
1003 long key
= hash_table
->MakeKey((char *)(const char *)functor
) + value
;
1005 // The key alone isn't guaranteed to be unique:
1006 // must supply value too. Let's assume the value of the
1007 // id is going to be reasonably unique.
1008 return (wxExpr
*)hash_table
->Get(key
, value
);
1011 wxExpr
*wxExprDatabase::HashFind(const wxString
& functor
, const wxString
& value
) const
1013 long key
= hash_table
->MakeKey((char *)(const char *)functor
) + hash_table
->MakeKey((char *)(const char *)value
);
1014 return (wxExpr
*)hash_table
->Get(key
, (char *)(const char *)value
);
1017 void wxExprDatabase::ClearDatabase(void)
1020 wxNode
*node
= First();
1023 wxExpr
*expr
= (wxExpr
*)node
->Data();
1030 hash_table
->Clear();
1033 bool wxExprDatabase::Read(const wxString
& filename
)
1037 FILE *f
= fopen((const char *)filename
, "r");
1040 thewxExprDatabase
= this;
1047 return (noErrors
== 0);
1055 bool wxExprDatabase::ReadFromString(const wxString
& buffer
)
1058 thewxExprDatabase
= this;
1060 LexFromString((char *)(const char *)buffer
);
1063 return (noErrors
== 0);
1066 bool wxExprDatabase::Write(const wxString
& fileName
)
1068 ofstream
str((char *)(const char *)fileName
);
1074 bool wxExprDatabase::Write(ostream
& stream
)
1077 wxNode
*node
= First();
1080 wxExpr
*expr
= (wxExpr
*)node
->Data();
1081 expr
->WriteClause(stream
);
1082 node
= node
->Next();
1084 return (noErrors
== 0);
1087 void wxExprDatabase::WriteLisp(ostream
& stream
)
1090 wxNode
*node
= First();
1093 wxExpr
*expr
= (wxExpr
*)node
->Data();
1094 expr
->WriteLispExpr(stream
);
1096 node
= node
->Next();
1100 void add_expr(wxExpr
* expr
)
1102 thewxExprDatabase
->Append(expr
);
1106 bool wxExprIsFunctor(wxExpr
*expr
, const wxString
& functor
)
1108 if (expr
&& (expr
->Type() == wxExprList
))
1110 wxExpr
*first_expr
= expr
->value
.first
;
1112 if (first_expr
&& (first_expr
->Type() == wxExprWord
) &&
1113 (first_expr
->WordValue() == functor
))
1123 * Called from parser
1127 char *make_integer(char *str
)
1129 wxExpr
*x
= new wxExpr(atol(str
));
1134 char *make_real(char *str1
, char *str2
)
1138 sprintf(buf
, "%s.%s", str1
, str2
);
1139 double f
= (double)atof(buf
);
1140 wxExpr
*x
= new wxExpr(f
);
1145 // extern "C" double exp10(double);
1147 char *make_exp(char *str1
, char *str2
)
1149 double mantissa
= (double)atoi(str1
);
1150 double exponent
= (double)atoi(str2
);
1152 double d
= mantissa
* pow(10.0, exponent
);
1154 wxExpr
*x
= new wxExpr(d
);
1159 char *make_exp2(char *str1
, char *str2
, char *str3
)
1163 sprintf(buf
, "%s.%s", str1
, str2
);
1164 double mantissa
= (double)atof(buf
);
1165 double exponent
= (double)atoi(str3
);
1167 double d
= mantissa
* pow(10.0, exponent
);
1169 wxExpr
*x
= new wxExpr(d
);
1174 char *make_word(char *str
)
1176 wxExpr
*x
= new wxExpr(wxExprWord
, str
);
1180 char *make_string(char *str
)
1185 str
++; /* skip leading quote */
1186 len
= strlen(str
) - 1; /* ignore trailing quote */
1188 s
= new char[len
+ 1];
1191 for(i
=0; i
<len
; i
++)
1193 if (str
[i
] == '\\' && str
[i
+1] == '"')
1198 else if (str
[i
] == '\\' && str
[i
+1] == '\\')
1209 wxExpr
*x
= new wxExpr(wxExprString
, s
, FALSE
);
1213 char *proio_cons(char * ccar
, char * ccdr
)
1215 wxExpr
*car
= (wxExpr
*)ccar
;
1216 wxExpr
*cdr
= (wxExpr
*)ccdr
;
1220 cdr
= new wxExpr(wxExprList
);
1227 void process_command(char * cexpr
)
1229 wxExpr
*expr
= (wxExpr
*)cexpr
;
1233 void syntax_error(char *s
)
1235 if (currentwxExprErrorHandler
)
1236 (void)(*(currentwxExprErrorHandler
))(WXEXPR_ERROR_SYNTAX
, "syntax error");
1237 if (thewxExprDatabase
) thewxExprDatabase
->noErrors
+= 1;
1242 // char *__cdecl strdup(const char *s)
1243 WXDLLEXPORT
char *strdup(const char *s
)
1245 int len
= strlen(s
);
1246 char *new_s
= (char *)malloc(sizeof(char)*(len
+1));