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"
29 #include "wx/wxexpr.h"
31 extern "C" void add_expr(char *);
32 extern "C" void LexFromFile(FILE *fd
);
33 extern "C" void LexFromString(char *buf
);
36 wxExprDatabase
*thewxExprDatabase
= NULL
;
37 wxExprErrorHandler currentwxExprErrorHandler
;
39 wxExpr::wxExpr(const wxString
& functor
)
46 wxExpr
*pfunctor
= new wxExpr(wxExprWord
, functor
);
51 wxExpr::wxExpr(wxExprType the_type
, const wxString
& word_or_string
)
58 value
.word
= copystring((const wxChar
*)word_or_string
);
61 value
.string
= copystring((const wxChar
*)word_or_string
);
76 wxExpr::wxExpr(wxExprType the_type
, wxChar
*word_or_string
, bool allocate
)
83 value
.word
= allocate
? copystring(word_or_string
) : word_or_string
;
86 value
.string
= allocate
? copystring(word_or_string
) : word_or_string
;
101 wxExpr::wxExpr(long the_integer
)
103 type
= wxExprInteger
;
104 value
.integer
= the_integer
;
109 wxExpr::wxExpr(double the_real
)
112 value
.real
= the_real
;
117 wxExpr::wxExpr(wxList
*the_list
)
124 wxExpr
*listExpr
= new wxExpr(wxExprList
);
126 wxNode
*node
= the_list
->First();
129 wxExpr
*expr
= (wxExpr
*)node
->Data();
130 listExpr
->Append(expr
);
138 wxExpr::~wxExpr(void)
149 delete[] value
.string
;
159 wxExpr
*expr
= value
.first
;
162 wxExpr
*expr1
= expr
->next
;
169 case wxExprNull
: break;
173 void wxExpr::Append(wxExpr
*expr
)
183 void wxExpr::Insert(wxExpr
*expr
)
185 expr
->next
= value
.first
;
192 wxExpr
*wxExpr::Copy(void) const
194 // This seems to get round an optimizer bug when
195 // using Watcom C++ 10a in WIN32 compilation mode.
196 // If these lines not present, the type seems to be
197 // interpreted wrongly as an integer.
198 // I don't want to turn optimization off since it's needed
199 // for reading in files quickly.
200 #if defined(__WATCOMC__)
208 return new wxExpr(value
.integer
);
210 return new wxExpr(value
.real
);
212 return new wxExpr(wxExprString
, wxString(value
.string
));
214 return new wxExpr(wxExprWord
, wxString(value
.word
));
217 wxExpr
*expr
= value
.first
;
218 wxExpr
*new_list
= new wxExpr(wxExprList
);
221 wxExpr
*expr2
= expr
->Copy();
222 new_list
->Append(expr2
);
234 // Get the wxExpr (containing (= wxExpr Value) form) for the given word
235 // or string, assuming that we have Attribute=Value, ...
236 wxExpr
*wxExpr::GetAttributeValueNode(const wxString
& word
) const // Use only for a clause or list
238 if (type
!= wxExprList
)
241 wxExpr
*expr
= value
.first
;
244 if (expr
->type
== wxExprList
)
246 wxExpr
*firstNode
= expr
->value
.first
;
247 if ((firstNode
->type
== wxExprWord
) && (firstNode
->value
.word
[0] == '='))
249 wxExpr
*secondNode
= firstNode
->next
;
250 if ((secondNode
->type
== wxExprWord
) &&
251 (wxStrcmp((const wxChar
*)word
, secondNode
->value
.word
) == 0))
262 // Get the value (in wxExpr form) for the given word or string, assuming
263 // that we have Attribute=Value, ...
264 wxExpr
*wxExpr::AttributeValue(const wxString
& word
) const // Use only for a clause or list
266 if (type
!= wxExprList
)
269 wxExpr
*attExpr
= GetAttributeValueNode(word
);
270 if (attExpr
&& attExpr
->value
.first
&& attExpr
->value
.first
->next
)
271 return attExpr
->value
.first
->next
->next
;
275 wxString
wxExpr::Functor(void) const // Use only for a clause
277 if ((type
!= wxExprList
) || !value
.first
)
278 return wxString(wxT(""));
280 if (value
.first
->type
== wxExprWord
)
281 return wxString(value
.first
->value
.word
);
283 return wxString(wxT(""));
286 bool wxExpr::IsFunctor(const wxString
& f
) const // Use only for a clause
288 if ((type
!= wxExprList
) || !value
.first
)
291 return (value
.first
->type
== wxExprWord
&&
292 (wxStrcmp((const wxChar
*)f
, value
.first
->value
.word
) == 0));
295 // Return nth argument of a clause (starting from 1)
296 wxExpr
*wxExpr::Arg(wxExprType theType
, int arg
) const
298 wxExpr
*expr
= value
.first
;
300 for (i
= 1; i
< arg
; i
++)
304 if (expr
&& (expr
->type
== theType
))
310 // Return nth argument of a list expression (starting from zero)
311 wxExpr
*wxExpr::Nth(int arg
) const
313 if (type
!= wxExprList
)
316 wxExpr
*expr
= value
.first
;
318 for (i
= 0; i
< arg
; i
++)
329 // Returns the number of elements in a list expression
330 int wxExpr::Number(void) const
332 if (type
!= wxExprList
)
336 wxExpr
*expr
= value
.first
;
345 void wxExpr::DeleteAttributeValue(const wxString
& attribute
)
347 if (type
!= wxExprList
)
350 wxExpr
*expr
= value
.first
;
351 wxExpr
*lastExpr
= this;
354 if (expr
->type
== wxExprList
)
356 wxExpr
*firstNode
= expr
->value
.first
;
357 if ((firstNode
->type
== wxExprWord
) && (firstNode
->value
.word
[0] == '='))
359 wxExpr
*secondNode
= firstNode
->next
;
360 if ((secondNode
->type
== wxExprWord
) &&
361 (wxStrcmp((const wxChar
*)attribute
, secondNode
->value
.word
) == 0))
363 wxExpr
*nextExpr
= expr
->next
;
366 lastExpr
->next
= nextExpr
;
381 void wxExpr::AddAttributeValue(const wxString
& attribute
, wxExpr
*val
)
383 if (type
!= wxExprList
)
385 // cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
388 // Warning - existing code may assume that any existing value
389 // is deleted first. For efficiency, we leave this to the application.
390 // DeleteAttributeValue(attribute);
392 wxExpr
*patt
= new wxExpr(wxExprWord
, attribute
);
393 wxExpr
*pequals
= new wxExpr(wxExprWord
, wxT("="));
395 wxExpr
*listExpr
= new wxExpr(wxExprList
);
397 listExpr
->Append(pequals
);
398 listExpr
->Append(patt
);
399 listExpr
->Append(val
);
404 void wxExpr::AddAttributeValue(const wxString
& attribute
, long val
)
406 if (type
!= wxExprList
)
408 // cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
411 // Warning - existing code may assume that any existing value
412 // is deleted first. For efficiency, we leave this to the application.
413 // DeleteAttributeValue(attribute);
415 wxExpr
*patt
= new wxExpr(wxExprWord
, attribute
);
416 wxExpr
*pval
= new wxExpr(val
);
417 wxExpr
*pequals
= new wxExpr(wxExprWord
, wxT("="));
419 wxExpr
*listExpr
= new wxExpr(wxExprList
);
421 listExpr
->Append(pequals
);
422 listExpr
->Append(patt
);
423 listExpr
->Append(pval
);
428 void wxExpr::AddAttributeValue(const wxString
& attribute
, double val
)
430 if (type
!= wxExprList
)
432 // cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
436 // DeleteAttributeValue(attribute);
437 wxExpr
*patt
= new wxExpr(wxExprWord
, attribute
);
438 wxExpr
*pval
= new wxExpr(val
);
439 wxExpr
*pequals
= new wxExpr(wxExprWord
, wxT("="));
441 wxExpr
*listExpr
= new wxExpr(wxExprList
);
443 listExpr
->Append(pequals
);
444 listExpr
->Append(patt
);
445 listExpr
->Append(pval
);
450 void wxExpr::AddAttributeValueString(const wxString
& attribute
, const wxString
& val
)
452 if (type
!= wxExprList
)
454 // cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
458 // DeleteAttributeValue(attribute);
460 wxExpr
*patt
= new wxExpr(wxExprWord
, attribute
);
461 wxExpr
*pval
= new wxExpr(wxExprString
, val
);
462 wxExpr
*pequals
= new wxExpr(wxExprWord
, wxT("="));
464 wxExpr
*listExpr
= new wxExpr(wxExprList
);
466 listExpr
->Append(pequals
);
467 listExpr
->Append(patt
);
468 listExpr
->Append(pval
);
473 void wxExpr::AddAttributeValueWord(const wxString
& attribute
, const wxString
& val
)
475 if (type
!= wxExprList
)
477 // cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
481 // DeleteAttributeValue(attribute);
483 wxExpr
*patt
= new wxExpr(wxExprWord
, attribute
);
484 wxExpr
*pval
= new wxExpr(wxExprWord
, val
);
485 wxExpr
*pequals
= new wxExpr(wxExprWord
, wxT("="));
487 wxExpr
*listExpr
= new wxExpr(wxExprList
);
489 listExpr
->Append(pequals
);
490 listExpr
->Append(patt
);
491 listExpr
->Append(pval
);
496 void wxExpr::AddAttributeValue(const wxString
& attribute
, wxList
*val
)
498 if (type
!= wxExprList
)
500 // cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
506 // DeleteAttributeValue(attribute);
508 wxExpr
*patt
= new wxExpr(wxExprWord
, attribute
);
509 wxExpr
*pval
= new wxExpr(val
);
510 wxExpr
*pequals
= new wxExpr(wxExprWord
, wxT("="));
512 wxExpr
*listExpr
= new wxExpr(wxExprList
);
514 listExpr
->Append(pequals
);
515 listExpr
->Append(patt
);
516 listExpr
->Append(pval
);
521 void wxExpr::AddAttributeValueStringList(const wxString
& attribute
, wxList
*string_list
)
523 if (type
!= wxExprList
)
525 // cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
531 // DeleteAttributeValue(attribute);
533 // First make a list of wxExpr strings
534 wxExpr
*listExpr
= new wxExpr(wxExprList
);
535 wxNode
*node
= string_list
->First();
538 char *string
= (char *)node
->Data();
539 wxExpr
*expr
= new wxExpr(wxExprString
, wxString(string
));
540 listExpr
->Append(expr
);
544 // Now make an (=, Att, Value) triple
545 wxExpr
*patt
= new wxExpr(wxExprWord
, attribute
);
546 wxExpr
*pequals
= new wxExpr(wxExprWord
, wxT("="));
548 wxExpr
*listExpr2
= new wxExpr(wxExprList
);
550 listExpr2
->Append(pequals
);
551 listExpr2
->Append(patt
);
552 listExpr2
->Append(listExpr
);
557 bool wxExpr::GetAttributeValue(const wxString
& att
, int& var
) const
559 wxExpr
*expr
= AttributeValue(att
);
561 if (expr
&& (expr
->Type() == wxExprInteger
|| expr
->Type() == wxExprReal
))
563 var
= (int)(expr
->IntegerValue());
570 bool wxExpr::GetAttributeValue(const wxString
& att
, long& var
) const
572 wxExpr
*expr
= AttributeValue(att
);
574 if (expr
&& (expr
->Type() == wxExprInteger
|| expr
->Type() == wxExprReal
))
576 var
= expr
->IntegerValue();
583 bool wxExpr::GetAttributeValue(const wxString
& att
, float& var
) const
585 wxExpr
*expr
= AttributeValue(att
);
586 if (expr
&& (expr
->Type() == wxExprInteger
|| expr
->Type() == wxExprReal
))
588 var
= (float) expr
->RealValue();
595 bool wxExpr::GetAttributeValue(const wxString
& att
, double& var
) const
597 wxExpr
*expr
= AttributeValue(att
);
598 if (expr
&& (expr
->Type() == wxExprInteger
|| expr
->Type() == wxExprReal
))
600 var
= expr
->RealValue();
607 bool wxExpr::GetAttributeValue(const wxString
& att
, wxString
& var
) const // Word OR string -> string
609 wxExpr
*expr
= AttributeValue(att
);
610 if (expr
&& expr
->Type() == wxExprWord
)
612 var
= expr
->WordValue();
615 else if (expr
&& expr
->Type() == wxExprString
)
617 var
= expr
->StringValue();
624 bool wxExpr::GetAttributeValue(const wxString
& att
, wxExpr
**var
) const
626 wxExpr
*expr
= AttributeValue(att
);
636 bool wxExpr::GetAttributeValueStringList(const wxString
& att
, wxList
*var
) const
638 wxExpr
*expr
= AttributeValue(att
);
639 if (expr
&& expr
->Type() == wxExprList
)
641 wxExpr
*string_expr
= expr
->value
.first
;
644 if (string_expr
->Type() == wxExprString
)
645 var
->Append((wxObject
*)copystring(string_expr
->StringValue()));
647 string_expr
= string_expr
->next
;
656 void wxExpr::AssignAttributeValue(wxChar
*att
, wxChar
**var
) const
659 if (GetAttributeValue(att
, str
))
663 *var
= copystring((const wxChar
*) str
);
667 void wxExpr::WriteClause(FILE* stream
) // Write this expression as a top-level clause
669 if (type
!= wxExprList
)
672 wxExpr
*node
= value
.first
;
675 node
->WriteExpr(stream
);
676 fprintf( stream
, "(" );
682 fprintf( stream
, " " );
683 node
->WriteExpr(stream
);
686 fprintf( stream
, ",\n" );
689 fprintf( stream
, ").\n\n" );
693 void wxExpr::WriteExpr(FILE* stream
) // Write as any other subexpression
695 // This seems to get round an optimizer bug when
696 // using Watcom C++ 10a in WIN32 compilation mode.
697 // If these lines not present, the type seems to be
698 // interpreted wrongly as an integer.
699 // I don't want to turn optimization off since it's needed
700 // for reading in files quickly.
701 #if defined(__WATCOMC__)
710 fprintf( stream
, "%ld", value
.integer
);
715 double f
= value
.real
;
716 fprintf( stream
, "%.6g", f
);
721 fprintf( stream
, "\"" );
723 const wxWX2MBbuf val
= wxConvLibc
.cWX2MB(value
.string
);
724 int len
= strlen(val
);
725 for (i
= 0; i
< len
; i
++)
728 if (ch
== '"' || ch
== '\\')
729 fprintf( stream
, "\\" );
733 fprintf( stream
, tmp
);
735 fprintf( stream
, "\"" );
740 bool quote_it
= FALSE
;
741 const wxWX2MBbuf val
= wxConvLibc
.cWX2MB(value
.word
);
742 int len
= strlen(val
);
743 if ((len
== 0) || (len
> 0 && (val
[0] > 64 && val
[0] < 91)))
748 for (i
= 0; i
< len
; i
++)
749 if ((!isalpha(val
[i
])) && (!isdigit(val
[i
])) &&
751 { quote_it
= TRUE
; i
= len
; }
755 fprintf( stream
,"'" );
757 fprintf( stream
, (const char*) val
);
760 fprintf( stream
, "'" );
767 fprintf( stream
, "[]" );
770 wxExpr
*expr
= value
.first
;
772 if ((expr
->Type() == wxExprWord
) && (wxStrcmp(expr
->WordValue(), wxT("=")) == 0))
774 wxExpr
*arg1
= expr
->next
;
775 wxExpr
*arg2
= arg1
->next
;
776 arg1
->WriteExpr(stream
);
777 fprintf( stream
, " = " );
778 arg2
->WriteExpr(stream
);
782 fprintf( stream
, "[" );
785 expr
->WriteExpr(stream
);
788 fprintf( stream
, ", " );
790 fprintf( stream
, "]" );
795 case wxExprNull
: break;
800 * wxExpr 'database' (list of expressions)
803 IMPLEMENT_DYNAMIC_CLASS(wxExprDatabase
, wxList
)
805 wxExprDatabase::wxExprDatabase(wxExprErrorHandler handler
)
809 currentwxExprErrorHandler
= handler
;
813 wxExprDatabase::wxExprDatabase(wxExprType type
, const wxString
& attribute
, int size
,
814 wxExprErrorHandler handler
)
817 attribute_to_hash
= attribute
;
818 if (type
== wxExprString
)
819 hash_table
= new wxHashTable(wxKEY_STRING
, size
);
820 else if (type
== wxExprInteger
)
821 hash_table
= new wxHashTable(wxKEY_INTEGER
, size
);
822 else hash_table
= NULL
;
824 currentwxExprErrorHandler
= handler
;
828 wxExprDatabase::~wxExprDatabase(void)
835 void wxExprDatabase::BeginFind(void) // Initialise a search
840 wxExpr
*wxExprDatabase::FindClause(long id
) // Find a term based on an integer id attribute
841 // e.g. node(id=23, type=rectangle, ....).
843 wxExpr
*found
= NULL
;
844 while (position
&& !found
)
846 wxExpr
*term
= (wxExpr
*)position
->Data();
848 if (term
->Type() == wxExprList
)
850 wxExpr
*value
= term
->AttributeValue("id");
851 if (value
->Type() == wxExprInteger
&& value
->IntegerValue() == id
)
854 position
= position
->Next();
859 // Find on basis of attribute/value pairs, e.g. type=rectangle
860 wxExpr
*wxExprDatabase::FindClause(const wxString
& word
, const wxString
& val
)
862 wxExpr
*found
= NULL
;
863 while (position
&& !found
)
865 wxExpr
*term
= (wxExpr
*)position
->Data();
867 if (term
->Type() == wxExprList
)
869 wxExpr
*value
= term
->AttributeValue(word
);
870 if ((value
->Type() == wxExprWord
&& value
->WordValue() == val
) ||
871 (value
->Type() == wxExprString
&& value
->StringValue() == val
))
874 position
= position
->Next();
879 wxExpr
*wxExprDatabase::FindClause(const wxString
& word
, long val
)
881 wxExpr
*found
= NULL
;
882 while (position
&& !found
)
884 wxExpr
*term
= (wxExpr
*)position
->Data();
886 if (term
->Type() == wxExprList
)
888 wxExpr
*value
= term
->AttributeValue(word
);
889 if ((value
->Type() == wxExprInteger
) && (value
->IntegerValue() == val
))
892 position
= position
->Next();
897 wxExpr
*wxExprDatabase::FindClause(const wxString
& word
, double val
)
899 wxExpr
*found
= NULL
;
900 while (position
&& !found
)
902 wxExpr
*term
= (wxExpr
*)position
->Data();
904 if (term
->Type() == wxExprList
)
906 wxExpr
*value
= term
->AttributeValue(word
);
907 if ((value
->Type() == wxExprReal
) && (value
->RealValue() == val
))
910 position
= position
->Next();
915 wxExpr
*wxExprDatabase::FindClauseByFunctor(const wxString
& functor
)
917 wxExpr
*found
= NULL
;
918 while (position
&& !found
)
920 wxExpr
*term
= (wxExpr
*)position
->Data();
922 if (term
->Type() == wxExprList
)
924 if (term
->Functor() == functor
)
927 position
= position
->Next();
932 // If hashing is on, must store in hash table too
933 void wxExprDatabase::Append(wxExpr
*clause
)
935 wxList::Append((wxObject
*)clause
);
938 wxString
functor(clause
->Functor());
939 wxExpr
*expr
= clause
->AttributeValue(attribute_to_hash
);
942 long functor_key
= hash_table
->MakeKey(WXSTRINGCAST functor
);
944 if (expr
&& expr
->Type() == wxExprString
)
946 value_key
= hash_table
->MakeKey(WXSTRINGCAST expr
->StringValue());
947 hash_table
->Put(functor_key
+ value_key
, WXSTRINGCAST expr
->StringValue(), (wxObject
*)clause
);
949 else if (expr
&& expr
->Type() == wxExprInteger
)
951 value_key
= expr
->IntegerValue();
952 hash_table
->Put(functor_key
+ value_key
, expr
->IntegerValue(), (wxObject
*)clause
);
959 wxExpr
*wxExprDatabase::HashFind(const wxString
& functor
, long value
) const
961 long key
= hash_table
->MakeKey(WXSTRINGCAST functor
) + value
;
963 // The key alone isn't guaranteed to be unique:
964 // must supply value too. Let's assume the value of the
965 // id is going to be reasonably unique.
966 return (wxExpr
*)hash_table
->Get(key
, value
);
969 wxExpr
*wxExprDatabase::HashFind(const wxString
& functor
, const wxString
& value
) const
971 long key
= hash_table
->MakeKey(WXSTRINGCAST functor
) + hash_table
->MakeKey(WXSTRINGCAST value
);
972 return (wxExpr
*)hash_table
->Get(key
, WXSTRINGCAST value
);
975 void wxExprDatabase::ClearDatabase(void)
978 wxNode
*node
= First();
981 wxExpr
*expr
= (wxExpr
*)node
->Data();
991 bool wxExprDatabase::Read(const wxString
& filename
)
995 FILE *f
= fopen(filename
.fn_str(), "r");
998 thewxExprDatabase
= this;
1005 return (noErrors
== 0);
1013 bool wxExprDatabase::ReadFromString(const wxString
& buffer
)
1016 thewxExprDatabase
= this;
1018 const wxWX2MBbuf buf
= buffer
.mb_str();
1019 LexFromString(wxMBSTRINGCAST buf
);
1022 return (noErrors
== 0);
1025 bool wxExprDatabase::Write(const wxString
& fileName
)
1027 FILE *stream
= fopen( fileName
.fn_str(), "w+" );
1032 bool success
= Write(stream
);
1037 bool wxExprDatabase::Write(FILE *stream
)
1040 wxNode
*node
= First();
1043 wxExpr
*expr
= (wxExpr
*)node
->Data();
1044 expr
->WriteClause(stream
);
1045 node
= node
->Next();
1047 return (noErrors
== 0);
1050 void add_expr(wxExpr
* expr
)
1052 thewxExprDatabase
->Append(expr
);
1056 bool wxExprIsFunctor(wxExpr
*expr
, const wxString
& functor
)
1058 if (expr
&& (expr
->Type() == wxExprList
))
1060 wxExpr
*first_expr
= expr
->value
.first
;
1062 if (first_expr
&& (first_expr
->Type() == wxExprWord
) &&
1063 (first_expr
->WordValue() == functor
))
1073 * Called from parser
1077 char *wxmake_integer(char *str
)
1079 wxExpr
*x
= new wxExpr(atol(str
));
1084 char *wxmake_real(char *str1
, char *str2
)
1088 sprintf(buf
, "%s.%s", str1
, str2
);
1089 double f
= (double)atof(buf
);
1090 wxExpr
*x
= new wxExpr(f
);
1095 // extern "C" double exp10(double);
1097 char *wxmake_exp(char *str1
, char *str2
)
1099 double mantissa
= (double)atoi(str1
);
1100 double exponent
= (double)atoi(str2
);
1102 double d
= mantissa
* pow(10.0, exponent
);
1104 wxExpr
*x
= new wxExpr(d
);
1109 char *wxmake_exp2(char *str1
, char *str2
, char *str3
)
1113 sprintf(buf
, "%s.%s", str1
, str2
);
1114 double mantissa
= (double)atof(buf
);
1115 double exponent
= (double)atoi(str3
);
1117 double d
= mantissa
* pow(10.0, exponent
);
1119 wxExpr
*x
= new wxExpr(d
);
1124 char *wxmake_word(char *str
)
1126 wxExpr
*x
= new wxExpr(wxExprWord
, str
);
1130 char *wxmake_string(char *str
)
1134 const wxMB2WXbuf sbuf
= wxConvLibc
.cMB2WX(str
);
1136 // str++; /* skip leading quote */
1137 len
= wxStrlen(sbuf
) - 1; /* ignore trailing quote */
1139 s
= new wxChar
[len
+ 1];
1142 for(i
=1; i
<len
; i
++) // 1 since we want to skip leading quote
1144 if (sbuf
[i
] == wxT('\\') && sbuf
[i
+1] == wxT('"'))
1149 else if (sbuf
[i
] == wxT('\\') && sbuf
[i
+1] == wxT('\\'))
1160 wxExpr
*x
= new wxExpr(wxExprString
, s
, FALSE
);
1164 char *proio_cons(char * ccar
, char * ccdr
)
1166 wxExpr
*car
= (wxExpr
*)ccar
;
1167 wxExpr
*cdr
= (wxExpr
*)ccdr
;
1171 cdr
= new wxExpr(wxExprList
);
1178 void process_command(char * cexpr
)
1180 wxExpr
*expr
= (wxExpr
*)cexpr
;
1184 void syntax_error(char *WXUNUSED(s
))
1186 if (currentwxExprErrorHandler
)
1187 (void)(*(currentwxExprErrorHandler
))(WXEXPR_ERROR_SYNTAX
, "syntax error");
1188 if (thewxExprDatabase
) thewxExprDatabase
->noErrors
+= 1;
1193 // char *__cdecl strdup(const char *s)
1194 WXDLLEXPORT
char *strdup(const char *s
)
1196 int len
= strlen(s
);
1197 char *new_s
= (char *)malloc(sizeof(char)*(len
+1));