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(T(""));
280 if (value
.first
->type
== wxExprWord
)
281 return wxString(value
.first
->value
.word
);
283 return wxString(T(""));
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
, T("="));
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
, T("="));
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
, T("="));
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
, T("="));
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
, T("="));
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
, T("="));
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
, T("="));
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(), T("=")) == 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 #if !USE_SHARED_LIBRARIES
804 IMPLEMENT_DYNAMIC_CLASS(wxExprDatabase
, wxList
)
807 wxExprDatabase::wxExprDatabase(wxExprErrorHandler handler
)
811 currentwxExprErrorHandler
= handler
;
815 wxExprDatabase::wxExprDatabase(wxExprType type
, const wxString
& attribute
, int size
,
816 wxExprErrorHandler handler
)
819 attribute_to_hash
= attribute
;
820 if (type
== wxExprString
)
821 hash_table
= new wxHashTable(wxKEY_STRING
, size
);
822 else if (type
== wxExprInteger
)
823 hash_table
= new wxHashTable(wxKEY_INTEGER
, size
);
824 else hash_table
= NULL
;
826 currentwxExprErrorHandler
= handler
;
830 wxExprDatabase::~wxExprDatabase(void)
837 void wxExprDatabase::BeginFind(void) // Initialise a search
842 wxExpr
*wxExprDatabase::FindClause(long id
) // Find a term based on an integer id attribute
843 // e.g. node(id=23, type=rectangle, ....).
845 wxExpr
*found
= NULL
;
846 while (position
&& !found
)
848 wxExpr
*term
= (wxExpr
*)position
->Data();
850 if (term
->Type() == wxExprList
)
852 wxExpr
*value
= term
->AttributeValue("id");
853 if (value
->Type() == wxExprInteger
&& value
->IntegerValue() == id
)
856 position
= position
->Next();
861 // Find on basis of attribute/value pairs, e.g. type=rectangle
862 wxExpr
*wxExprDatabase::FindClause(const wxString
& word
, const wxString
& val
)
864 wxExpr
*found
= NULL
;
865 while (position
&& !found
)
867 wxExpr
*term
= (wxExpr
*)position
->Data();
869 if (term
->Type() == wxExprList
)
871 wxExpr
*value
= term
->AttributeValue(word
);
872 if ((value
->Type() == wxExprWord
&& value
->WordValue() == val
) ||
873 (value
->Type() == wxExprString
&& value
->StringValue() == val
))
876 position
= position
->Next();
881 wxExpr
*wxExprDatabase::FindClause(const wxString
& word
, long val
)
883 wxExpr
*found
= NULL
;
884 while (position
&& !found
)
886 wxExpr
*term
= (wxExpr
*)position
->Data();
888 if (term
->Type() == wxExprList
)
890 wxExpr
*value
= term
->AttributeValue(word
);
891 if ((value
->Type() == wxExprInteger
) && (value
->IntegerValue() == val
))
894 position
= position
->Next();
899 wxExpr
*wxExprDatabase::FindClause(const wxString
& word
, double val
)
901 wxExpr
*found
= NULL
;
902 while (position
&& !found
)
904 wxExpr
*term
= (wxExpr
*)position
->Data();
906 if (term
->Type() == wxExprList
)
908 wxExpr
*value
= term
->AttributeValue(word
);
909 if ((value
->Type() == wxExprReal
) && (value
->RealValue() == val
))
912 position
= position
->Next();
917 wxExpr
*wxExprDatabase::FindClauseByFunctor(const wxString
& functor
)
919 wxExpr
*found
= NULL
;
920 while (position
&& !found
)
922 wxExpr
*term
= (wxExpr
*)position
->Data();
924 if (term
->Type() == wxExprList
)
926 if (term
->Functor() == functor
)
929 position
= position
->Next();
934 // If hashing is on, must store in hash table too
935 void wxExprDatabase::Append(wxExpr
*clause
)
937 wxList::Append((wxObject
*)clause
);
940 wxString
functor(clause
->Functor());
941 wxExpr
*expr
= clause
->AttributeValue(attribute_to_hash
);
944 long functor_key
= hash_table
->MakeKey(WXSTRINGCAST functor
);
946 if (expr
&& expr
->Type() == wxExprString
)
948 value_key
= hash_table
->MakeKey(WXSTRINGCAST expr
->StringValue());
949 hash_table
->Put(functor_key
+ value_key
, WXSTRINGCAST expr
->StringValue(), (wxObject
*)clause
);
951 else if (expr
&& expr
->Type() == wxExprInteger
)
953 value_key
= expr
->IntegerValue();
954 hash_table
->Put(functor_key
+ value_key
, expr
->IntegerValue(), (wxObject
*)clause
);
961 wxExpr
*wxExprDatabase::HashFind(const wxString
& functor
, long value
) const
963 long key
= hash_table
->MakeKey(WXSTRINGCAST functor
) + value
;
965 // The key alone isn't guaranteed to be unique:
966 // must supply value too. Let's assume the value of the
967 // id is going to be reasonably unique.
968 return (wxExpr
*)hash_table
->Get(key
, value
);
971 wxExpr
*wxExprDatabase::HashFind(const wxString
& functor
, const wxString
& value
) const
973 long key
= hash_table
->MakeKey(WXSTRINGCAST functor
) + hash_table
->MakeKey(WXSTRINGCAST value
);
974 return (wxExpr
*)hash_table
->Get(key
, WXSTRINGCAST value
);
977 void wxExprDatabase::ClearDatabase(void)
980 wxNode
*node
= First();
983 wxExpr
*expr
= (wxExpr
*)node
->Data();
993 bool wxExprDatabase::Read(const wxString
& filename
)
997 FILE *f
= fopen(filename
.fn_str(), "r");
1000 thewxExprDatabase
= this;
1007 return (noErrors
== 0);
1015 bool wxExprDatabase::ReadFromString(const wxString
& buffer
)
1018 thewxExprDatabase
= this;
1020 const wxWX2MBbuf buf
= buffer
.mb_str();
1021 LexFromString(wxMBSTRINGCAST buf
);
1024 return (noErrors
== 0);
1027 bool wxExprDatabase::Write(const wxString
& fileName
)
1029 FILE *stream
= fopen( fileName
.fn_str(), "w+" );
1034 bool success
= Write(stream
);
1039 bool wxExprDatabase::Write(FILE *stream
)
1042 wxNode
*node
= First();
1045 wxExpr
*expr
= (wxExpr
*)node
->Data();
1046 expr
->WriteClause(stream
);
1047 node
= node
->Next();
1049 return (noErrors
== 0);
1052 void add_expr(wxExpr
* expr
)
1054 thewxExprDatabase
->Append(expr
);
1058 bool wxExprIsFunctor(wxExpr
*expr
, const wxString
& functor
)
1060 if (expr
&& (expr
->Type() == wxExprList
))
1062 wxExpr
*first_expr
= expr
->value
.first
;
1064 if (first_expr
&& (first_expr
->Type() == wxExprWord
) &&
1065 (first_expr
->WordValue() == functor
))
1075 * Called from parser
1079 char *wxmake_integer(char *str
)
1081 wxExpr
*x
= new wxExpr(atol(str
));
1086 char *wxmake_real(char *str1
, char *str2
)
1090 sprintf(buf
, "%s.%s", str1
, str2
);
1091 double f
= (double)atof(buf
);
1092 wxExpr
*x
= new wxExpr(f
);
1097 // extern "C" double exp10(double);
1099 char *wxmake_exp(char *str1
, char *str2
)
1101 double mantissa
= (double)atoi(str1
);
1102 double exponent
= (double)atoi(str2
);
1104 double d
= mantissa
* pow(10.0, exponent
);
1106 wxExpr
*x
= new wxExpr(d
);
1111 char *wxmake_exp2(char *str1
, char *str2
, char *str3
)
1115 sprintf(buf
, "%s.%s", str1
, str2
);
1116 double mantissa
= (double)atof(buf
);
1117 double exponent
= (double)atoi(str3
);
1119 double d
= mantissa
* pow(10.0, exponent
);
1121 wxExpr
*x
= new wxExpr(d
);
1126 char *wxmake_word(char *str
)
1128 wxExpr
*x
= new wxExpr(wxExprWord
, str
);
1132 char *wxmake_string(char *str
)
1136 const wxMB2WXbuf sbuf
= wxConvLibc
.cMB2WX(str
);
1138 // str++; /* skip leading quote */
1139 len
= wxStrlen(sbuf
) - 1; /* ignore trailing quote */
1141 s
= new wxChar
[len
+ 1];
1144 for(i
=1; i
<len
; i
++) // 1 since we want to skip leading quote
1146 if (sbuf
[i
] == T('\\') && sbuf
[i
+1] == T('"'))
1151 else if (sbuf
[i
] == T('\\') && sbuf
[i
+1] == T('\\'))
1162 wxExpr
*x
= new wxExpr(wxExprString
, s
, FALSE
);
1166 char *proio_cons(char * ccar
, char * ccdr
)
1168 wxExpr
*car
= (wxExpr
*)ccar
;
1169 wxExpr
*cdr
= (wxExpr
*)ccdr
;
1173 cdr
= new wxExpr(wxExprList
);
1180 void process_command(char * cexpr
)
1182 wxExpr
*expr
= (wxExpr
*)cexpr
;
1186 void syntax_error(char *WXUNUSED(s
))
1188 if (currentwxExprErrorHandler
)
1189 (void)(*(currentwxExprErrorHandler
))(WXEXPR_ERROR_SYNTAX
, "syntax error");
1190 if (thewxExprDatabase
) thewxExprDatabase
->noErrors
+= 1;
1195 // char *__cdecl strdup(const char *s)
1196 WXDLLEXPORT
char *strdup(const char *s
)
1198 int len
= strlen(s
);
1199 char *new_s
= (char *)malloc(sizeof(char)*(len
+1));