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 #ifndef USE_SHARED_LIBRARY
46 IMPLEMENT_DYNAMIC_CLASS(wxExprDatabase
, wxList
)
50 wxExprDatabase
*thewxExprDatabase
= NULL
;
51 wxExprErrorHandler currentwxExprErrorHandler
;
53 wxExpr::wxExpr(const wxString
& functor
)
60 wxExpr
*pfunctor
= new wxExpr(wxExprWord
, functor
);
65 wxExpr::wxExpr(wxExprType the_type
, const wxString
& word_or_string
)
72 value
.word
= copystring((const char *)word_or_string
);
75 value
.string
= copystring((const char *)word_or_string
);
90 wxExpr::wxExpr(wxExprType the_type
, char *word_or_string
, bool allocate
)
97 value
.word
= allocate
? copystring(word_or_string
) : word_or_string
;
100 value
.string
= allocate
? copystring(word_or_string
) : word_or_string
;
115 wxExpr::wxExpr(long the_integer
)
117 type
= wxExprInteger
;
118 value
.integer
= the_integer
;
123 wxExpr::wxExpr(double the_real
)
126 value
.real
= the_real
;
131 wxExpr::wxExpr(wxList
*the_list
)
138 wxExpr
*listExpr
= new wxExpr(wxExprList
);
140 wxNode
*node
= the_list
->First();
143 wxExpr
*expr
= (wxExpr
*)node
->Data();
144 listExpr
->Append(expr
);
152 wxExpr::~wxExpr(void)
163 delete[] value
.string
;
173 wxExpr
*expr
= value
.first
;
176 wxExpr
*expr1
= expr
->next
;
183 case wxExprNull
: break;
187 void wxExpr::Append(wxExpr
*expr
)
197 void wxExpr::Insert(wxExpr
*expr
)
199 expr
->next
= value
.first
;
206 wxExpr
*wxExpr::Copy(void) const
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__)
222 return new wxExpr(value
.integer
);
224 return new wxExpr(value
.real
);
226 return new wxExpr(wxExprString
, wxString(value
.string
));
228 return new wxExpr(wxExprWord
, wxString(value
.word
));
231 wxExpr
*expr
= value
.first
;
232 wxExpr
*new_list
= new wxExpr(wxExprList
);
235 wxExpr
*expr2
= expr
->Copy();
236 new_list
->Append(expr2
);
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
252 if (type
!= wxExprList
)
255 wxExpr
*expr
= value
.first
;
258 if (expr
->type
== wxExprList
)
260 wxExpr
*firstNode
= expr
->value
.first
;
261 if ((firstNode
->type
== wxExprWord
) && (firstNode
->value
.word
[0] == '='))
263 wxExpr
*secondNode
= firstNode
->next
;
264 if ((secondNode
->type
== wxExprWord
) &&
265 (strcmp((const char *)word
, secondNode
->value
.word
) == 0))
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
280 if (type
!= wxExprList
)
283 wxExpr
*attExpr
= GetAttributeValueNode(word
);
284 if (attExpr
&& attExpr
->value
.first
&& attExpr
->value
.first
->next
)
285 return attExpr
->value
.first
->next
->next
;
289 wxString
wxExpr::Functor(void) const // Use only for a clause
291 if ((type
!= wxExprList
) || !value
.first
)
294 if (value
.first
->type
== wxExprWord
)
295 return wxString(value
.first
->value
.word
);
300 bool wxExpr::IsFunctor(const wxString
& f
) const // Use only for a clause
302 if ((type
!= wxExprList
) || !value
.first
)
305 return (value
.first
->type
== wxExprWord
&&
306 (strcmp((const char *)f
, value
.first
->value
.word
) == 0));
309 // Return nth argument of a clause (starting from 1)
310 wxExpr
*wxExpr::Arg(wxExprType theType
, int arg
) const
312 wxExpr
*expr
= value
.first
;
314 for (i
= 1; i
< arg
; i
++)
318 if (expr
&& (expr
->type
== theType
))
324 // Return nth argument of a list expression (starting from zero)
325 wxExpr
*wxExpr::Nth(int arg
) const
327 if (type
!= wxExprList
)
330 wxExpr
*expr
= value
.first
;
332 for (i
= 0; i
< arg
; i
++)
343 // Returns the number of elements in a list expression
344 int wxExpr::Number(void) const
346 if (type
!= wxExprList
)
350 wxExpr
*expr
= value
.first
;
359 void wxExpr::DeleteAttributeValue(const wxString
& attribute
)
361 if (type
!= wxExprList
)
364 wxExpr
*expr
= value
.first
;
365 wxExpr
*lastExpr
= this;
368 if (expr
->type
== wxExprList
)
370 wxExpr
*firstNode
= expr
->value
.first
;
371 if ((firstNode
->type
== wxExprWord
) && (firstNode
->value
.word
[0] == '='))
373 wxExpr
*secondNode
= firstNode
->next
;
374 if ((secondNode
->type
== wxExprWord
) &&
375 (strcmp((const char *)attribute
, secondNode
->value
.word
) == 0))
377 wxExpr
*nextExpr
= expr
->next
;
380 lastExpr
->next
= nextExpr
;
395 void wxExpr::AddAttributeValue(const wxString
& attribute
, wxExpr
*val
)
397 if (type
!= wxExprList
)
399 // cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
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);
406 wxExpr
*patt
= new wxExpr(wxExprWord
, attribute
);
407 wxExpr
*pequals
= new wxExpr(wxExprWord
, "=");
409 wxExpr
*listExpr
= new wxExpr(wxExprList
);
411 listExpr
->Append(pequals
);
412 listExpr
->Append(patt
);
413 listExpr
->Append(val
);
418 void wxExpr::AddAttributeValue(const wxString
& attribute
, long val
)
420 if (type
!= wxExprList
)
422 // cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
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);
429 wxExpr
*patt
= new wxExpr(wxExprWord
, attribute
);
430 wxExpr
*pval
= new wxExpr(val
);
431 wxExpr
*pequals
= new wxExpr(wxExprWord
, "=");
433 wxExpr
*listExpr
= new wxExpr(wxExprList
);
435 listExpr
->Append(pequals
);
436 listExpr
->Append(patt
);
437 listExpr
->Append(pval
);
442 void wxExpr::AddAttributeValue(const wxString
& attribute
, double val
)
444 if (type
!= wxExprList
)
446 // cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
450 // DeleteAttributeValue(attribute);
451 wxExpr
*patt
= new wxExpr(wxExprWord
, attribute
);
452 wxExpr
*pval
= new wxExpr(val
);
453 wxExpr
*pequals
= new wxExpr(wxExprWord
, "=");
455 wxExpr
*listExpr
= new wxExpr(wxExprList
);
457 listExpr
->Append(pequals
);
458 listExpr
->Append(patt
);
459 listExpr
->Append(pval
);
464 void wxExpr::AddAttributeValueString(const wxString
& attribute
, const wxString
& val
)
466 if (type
!= wxExprList
)
468 // cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
472 // DeleteAttributeValue(attribute);
474 wxExpr
*patt
= new wxExpr(wxExprWord
, attribute
);
475 wxExpr
*pval
= new wxExpr(wxExprString
, val
);
476 wxExpr
*pequals
= new wxExpr(wxExprWord
, "=");
478 wxExpr
*listExpr
= new wxExpr(wxExprList
);
480 listExpr
->Append(pequals
);
481 listExpr
->Append(patt
);
482 listExpr
->Append(pval
);
487 void wxExpr::AddAttributeValueWord(const wxString
& attribute
, const wxString
& val
)
489 if (type
!= wxExprList
)
491 // cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
495 // DeleteAttributeValue(attribute);
497 wxExpr
*patt
= new wxExpr(wxExprWord
, attribute
);
498 wxExpr
*pval
= new wxExpr(wxExprWord
, val
);
499 wxExpr
*pequals
= new wxExpr(wxExprWord
, "=");
501 wxExpr
*listExpr
= new wxExpr(wxExprList
);
503 listExpr
->Append(pequals
);
504 listExpr
->Append(patt
);
505 listExpr
->Append(pval
);
510 void wxExpr::AddAttributeValue(const wxString
& attribute
, wxList
*val
)
512 if (type
!= wxExprList
)
514 // cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
520 // DeleteAttributeValue(attribute);
522 wxExpr
*patt
= new wxExpr(wxExprWord
, attribute
);
523 wxExpr
*pval
= new wxExpr(val
);
524 wxExpr
*pequals
= new wxExpr(wxExprWord
, "=");
526 wxExpr
*listExpr
= new wxExpr(wxExprList
);
528 listExpr
->Append(pequals
);
529 listExpr
->Append(patt
);
530 listExpr
->Append(pval
);
535 void wxExpr::AddAttributeValueStringList(const wxString
& attribute
, wxList
*string_list
)
537 if (type
!= wxExprList
)
539 // cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
545 // DeleteAttributeValue(attribute);
547 // First make a list of wxExpr strings
548 wxExpr
*listExpr
= new wxExpr(wxExprList
);
549 wxNode
*node
= string_list
->First();
552 char *string
= (char *)node
->Data();
553 wxExpr
*expr
= new wxExpr(wxExprString
, wxString(string
));
554 listExpr
->Append(expr
);
558 // Now make an (=, Att, Value) triple
559 wxExpr
*patt
= new wxExpr(wxExprWord
, attribute
);
560 wxExpr
*pequals
= new wxExpr(wxExprWord
, "=");
562 wxExpr
*listExpr2
= new wxExpr(wxExprList
);
564 listExpr2
->Append(pequals
);
565 listExpr2
->Append(patt
);
566 listExpr2
->Append(listExpr
);
571 bool wxExpr::GetAttributeValue(const wxString
& att
, int& var
) const
573 wxExpr
*expr
= AttributeValue(att
);
575 if (expr
&& (expr
->Type() == wxExprInteger
|| expr
->Type() == wxExprReal
))
577 var
= (int)(expr
->IntegerValue());
584 bool wxExpr::GetAttributeValue(const wxString
& att
, long& var
) const
586 wxExpr
*expr
= AttributeValue(att
);
588 if (expr
&& (expr
->Type() == wxExprInteger
|| expr
->Type() == wxExprReal
))
590 var
= expr
->IntegerValue();
597 bool wxExpr::GetAttributeValue(const wxString
& att
, float& var
) const
599 wxExpr
*expr
= AttributeValue(att
);
600 if (expr
&& (expr
->Type() == wxExprInteger
|| expr
->Type() == wxExprReal
))
602 var
= (float) expr
->RealValue();
609 bool wxExpr::GetAttributeValue(const wxString
& att
, double& var
) const
611 wxExpr
*expr
= AttributeValue(att
);
612 if (expr
&& (expr
->Type() == wxExprInteger
|| expr
->Type() == wxExprReal
))
614 var
= expr
->RealValue();
621 bool wxExpr::GetAttributeValue(const wxString
& att
, wxString
& var
) const // Word OR string -> string
623 wxExpr
*expr
= AttributeValue(att
);
624 if (expr
&& expr
->Type() == wxExprWord
)
626 var
= expr
->WordValue();
629 else if (expr
&& expr
->Type() == wxExprString
)
631 var
= expr
->StringValue();
638 bool wxExpr::GetAttributeValue(const wxString
& att
, wxExpr
**var
) const
640 wxExpr
*expr
= AttributeValue(att
);
650 bool wxExpr::GetAttributeValueStringList(const wxString
& att
, wxList
*var
) const
652 wxExpr
*expr
= AttributeValue(att
);
653 if (expr
&& expr
->Type() == wxExprList
)
655 wxExpr
*string_expr
= expr
->value
.first
;
658 if (string_expr
->Type() == wxExprString
)
659 var
->Append((wxObject
*)copystring(string_expr
->StringValue()));
661 string_expr
= string_expr
->next
;
670 void wxExpr::AssignAttributeValue(char *att
, char **var
) const
673 if (GetAttributeValue(att
, str
))
677 *var
= copystring((const char *) str
);
681 void wxExpr::WriteClause(ostream
& stream
) // Write this expression as a top-level clause
683 if (type
!= wxExprList
)
686 wxExpr
*node
= value
.first
;
689 node
->WriteExpr(stream
);
697 node
->WriteExpr(stream
);
699 if (node
) stream
<< ",\n";
706 void wxExpr::WriteExpr(ostream
& stream
) // Write as any other subexpression
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__)
723 stream
<< value
.integer
;
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)
735 sprintf(buf
, "%.6g", f
);
743 int len
= strlen(value
.string
);
744 for (i
= 0; i
< len
; i
++)
746 char ch
= value
.string
[i
];
747 if (ch
== '"' || ch
== '\\')
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)))
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
; }
773 stream
<< value
.word
;
786 wxExpr
*expr
= value
.first
;
788 if ((expr
->Type() == wxExprWord
) && (strcmp(expr
->WordValue(), "=") == 0))
790 wxExpr
*arg1
= expr
->next
;
791 wxExpr
*arg2
= arg1
->next
;
792 arg1
->WriteExpr(stream
);
794 arg2
->WriteExpr(stream
);
801 expr
->WriteExpr(stream
);
803 if (expr
) stream
<< ", ";
810 case wxExprNull
: break;
814 void wxExpr::WriteLispExpr(ostream
& stream
)
820 stream
<< value
.integer
;
825 stream
<< value
.real
;
830 stream
<< "\"" << value
.string
<< "\"";
835 stream
<< value
.word
;
840 wxExpr
*expr
= value
.first
;
845 expr
->WriteLispExpr(stream
);
847 if (expr
) stream
<< " ";
853 case wxExprNull
: break;
858 * wxExpr 'database' (list of expressions)
861 #if !USE_SHARED_LIBRARIES
862 IMPLEMENT_DYNAMIC_CLASS(wxExprDatabase
, wxList
)
865 wxExprDatabase::wxExprDatabase(wxExprErrorHandler handler
)
869 currentwxExprErrorHandler
= handler
;
873 wxExprDatabase::wxExprDatabase(wxExprType type
, const wxString
& attribute
, int size
,
874 wxExprErrorHandler handler
)
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
;
884 currentwxExprErrorHandler
= handler
;
888 wxExprDatabase::~wxExprDatabase(void)
895 void wxExprDatabase::BeginFind(void) // Initialise a search
900 wxExpr
*wxExprDatabase::FindClause(long id
) // Find a term based on an integer id attribute
901 // e.g. node(id=23, type=rectangle, ....).
903 wxExpr
*found
= NULL
;
904 while (position
&& !found
)
906 wxExpr
*term
= (wxExpr
*)position
->Data();
908 if (term
->Type() == wxExprList
)
910 wxExpr
*value
= term
->AttributeValue("id");
911 if (value
->Type() == wxExprInteger
&& value
->IntegerValue() == id
)
914 position
= position
->Next();
919 // Find on basis of attribute/value pairs, e.g. type=rectangle
920 wxExpr
*wxExprDatabase::FindClause(const wxString
& word
, const wxString
& val
)
922 wxExpr
*found
= NULL
;
923 while (position
&& !found
)
925 wxExpr
*term
= (wxExpr
*)position
->Data();
927 if (term
->Type() == wxExprList
)
929 wxExpr
*value
= term
->AttributeValue(word
);
930 if ((value
->Type() == wxExprWord
&& value
->WordValue() == val
) ||
931 (value
->Type() == wxExprString
&& value
->StringValue() == val
))
934 position
= position
->Next();
939 wxExpr
*wxExprDatabase::FindClause(const wxString
& word
, long 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() == wxExprInteger
) && (value
->IntegerValue() == val
))
952 position
= position
->Next();
957 wxExpr
*wxExprDatabase::FindClause(const wxString
& word
, double val
)
959 wxExpr
*found
= NULL
;
960 while (position
&& !found
)
962 wxExpr
*term
= (wxExpr
*)position
->Data();
964 if (term
->Type() == wxExprList
)
966 wxExpr
*value
= term
->AttributeValue(word
);
967 if ((value
->Type() == wxExprReal
) && (value
->RealValue() == val
))
970 position
= position
->Next();
975 wxExpr
*wxExprDatabase::FindClauseByFunctor(const wxString
& functor
)
977 wxExpr
*found
= NULL
;
978 while (position
&& !found
)
980 wxExpr
*term
= (wxExpr
*)position
->Data();
982 if (term
->Type() == wxExprList
)
984 if (term
->Functor() == functor
)
987 position
= position
->Next();
992 // If hashing is on, must store in hash table too
993 void wxExprDatabase::Append(wxExpr
*clause
)
995 wxList::Append((wxObject
*)clause
);
998 wxString
functor(clause
->Functor());
999 wxExpr
*expr
= clause
->AttributeValue(attribute_to_hash
);
1002 long functor_key
= hash_table
->MakeKey((char *)(const char *)functor
);
1004 if (expr
&& expr
->Type() == wxExprString
)
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
);
1009 else if (expr
&& expr
->Type() == wxExprInteger
)
1011 value_key
= expr
->IntegerValue();
1012 hash_table
->Put(functor_key
+ value_key
, expr
->IntegerValue(), (wxObject
*)clause
);
1019 wxExpr
*wxExprDatabase::HashFind(const wxString
& functor
, long value
) const
1021 long key
= hash_table
->MakeKey((char *)(const char *)functor
) + value
;
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
);
1029 wxExpr
*wxExprDatabase::HashFind(const wxString
& functor
, const wxString
& value
) const
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
);
1035 void wxExprDatabase::ClearDatabase(void)
1038 wxNode
*node
= First();
1041 wxExpr
*expr
= (wxExpr
*)node
->Data();
1048 hash_table
->Clear();
1051 bool wxExprDatabase::Read(const wxString
& filename
)
1055 FILE *f
= fopen((const char *)filename
, "r");
1058 thewxExprDatabase
= this;
1065 return (noErrors
== 0);
1073 bool wxExprDatabase::ReadFromString(const wxString
& buffer
)
1076 thewxExprDatabase
= this;
1078 LexFromString((char *)(const char *)buffer
);
1081 return (noErrors
== 0);
1084 bool wxExprDatabase::Write(const wxString
& fileName
)
1086 ofstream
str((char *)(const char *)fileName
);
1092 bool wxExprDatabase::Write(ostream
& stream
)
1095 wxNode
*node
= First();
1098 wxExpr
*expr
= (wxExpr
*)node
->Data();
1099 expr
->WriteClause(stream
);
1100 node
= node
->Next();
1102 return (noErrors
== 0);
1105 void wxExprDatabase::WriteLisp(ostream
& stream
)
1108 wxNode
*node
= First();
1111 wxExpr
*expr
= (wxExpr
*)node
->Data();
1112 expr
->WriteLispExpr(stream
);
1114 node
= node
->Next();
1118 void add_expr(wxExpr
* expr
)
1120 thewxExprDatabase
->Append(expr
);
1124 bool wxExprIsFunctor(wxExpr
*expr
, const wxString
& functor
)
1126 if (expr
&& (expr
->Type() == wxExprList
))
1128 wxExpr
*first_expr
= expr
->value
.first
;
1130 if (first_expr
&& (first_expr
->Type() == wxExprWord
) &&
1131 (first_expr
->WordValue() == functor
))
1141 * Called from parser
1145 char *make_integer(char *str
)
1147 wxExpr
*x
= new wxExpr(atol(str
));
1152 char *make_real(char *str1
, char *str2
)
1156 sprintf(buf
, "%s.%s", str1
, str2
);
1157 double f
= (double)atof(buf
);
1158 wxExpr
*x
= new wxExpr(f
);
1163 // extern "C" double exp10(double);
1165 char *make_exp(char *str1
, char *str2
)
1167 double mantissa
= (double)atoi(str1
);
1168 double exponent
= (double)atoi(str2
);
1170 double d
= mantissa
* pow(10.0, exponent
);
1172 wxExpr
*x
= new wxExpr(d
);
1177 char *make_exp2(char *str1
, char *str2
, char *str3
)
1181 sprintf(buf
, "%s.%s", str1
, str2
);
1182 double mantissa
= (double)atof(buf
);
1183 double exponent
= (double)atoi(str3
);
1185 double d
= mantissa
* pow(10.0, exponent
);
1187 wxExpr
*x
= new wxExpr(d
);
1192 char *make_word(char *str
)
1194 wxExpr
*x
= new wxExpr(wxExprWord
, str
);
1198 char *make_string(char *str
)
1203 str
++; /* skip leading quote */
1204 len
= strlen(str
) - 1; /* ignore trailing quote */
1206 s
= new char[len
+ 1];
1209 for(i
=0; i
<len
; i
++)
1211 if (str
[i
] == '\\' && str
[i
+1] == '"')
1216 else if (str
[i
] == '\\' && str
[i
+1] == '\\')
1227 wxExpr
*x
= new wxExpr(wxExprString
, s
, FALSE
);
1231 char *proio_cons(char * ccar
, char * ccdr
)
1233 wxExpr
*car
= (wxExpr
*)ccar
;
1234 wxExpr
*cdr
= (wxExpr
*)ccdr
;
1238 cdr
= new wxExpr(wxExprList
);
1245 void process_command(char * cexpr
)
1247 wxExpr
*expr
= (wxExpr
*)cexpr
;
1251 void syntax_error(char *WXUNUSED(s
))
1253 if (currentwxExprErrorHandler
)
1254 (void)(*(currentwxExprErrorHandler
))(WXEXPR_ERROR_SYNTAX
, "syntax error");
1255 if (thewxExprDatabase
) thewxExprDatabase
->noErrors
+= 1;
1260 // char *__cdecl strdup(const char *s)
1261 WXDLLEXPORT
char *strdup(const char *s
)
1263 int len
= strlen(s
);
1264 char *new_s
= (char *)malloc(sizeof(char)*(len
+1));