• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/ap/gpl/amule/wxWidgets-2.8.12/contrib/src/deprecated/
1/////////////////////////////////////////////////////////////////////////////
2// Name:        wxexpr.cpp
3// Purpose:     wxExpr
4// Author:      Julian Smart
5// Modified by:
6// Created:     04/01/98
7// RCS-ID:      $Id: wxexpr.cpp 35650 2005-09-23 12:56:45Z MR $
8// Copyright:   (c) Julian Smart
9// Licence:     wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12// For compilers that support precompilation, includes "wx/wx.h".
13#include "wx/wxprec.h"
14
15#ifdef __BORLANDC__
16#pragma hdrstop
17#endif
18
19#include "wx/deprecated/setup.h"
20
21#if wxUSE_PROLOGIO
22
23#include <stdarg.h>
24#include <ctype.h>
25#include <string.h>
26
27#include "wx/utils.h"
28#include "wx/deprecated/expr.h"
29#include "wx/deprecated/wxexpr.h"
30
31#if !WXWIN_COMPATIBILITY_2_4
32static inline wxChar* copystring(const wxChar* s)
33    { return wxStrcpy(new wxChar[wxStrlen(s) + 1], s); }
34#endif
35
36extern "C" void add_expr(char *);
37extern "C" void LexFromFile(FILE *fd);
38extern "C" void LexFromString(char *buf);
39
40
41
42/* Rename all YACC/LEX stuff or we'll conflict with other
43 * applications
44 */
45
46#define yyback PROIO_yyback
47#define yylook PROIO_yylook
48#define yywrap PROIO_yywrap
49#define yyoutput PROIO_yyoutput
50#define yylex PROIO_yylex
51#define yyerror PROIO_yyerror
52#define yyleng PROIO_yyleng
53#define yytext PROIO_yytext
54#define yymorfg PROIO_yymorfg
55#define yylineno PROIO_yylineno
56#define yytchar PROIO_yytchar
57#define yyin PROIO_yyin
58#define yyout PROIO_yyout
59#define yysvf PROIO_yysvf
60#define yyestate PROIO_yyestate
61#define yysvec PROIO_yysvec
62#define yybgin PROIO_yybgin
63#define yyprevious PROIO_yyprevious
64#define yylhs PROIO_yylhs
65#define yylen PROIO_yylen
66#define yydefred PROIO_yydefred
67#define yydgoto PROIO_yydgoto
68#define yysindex PROIO_yysindex
69#define yyrindex PROIO_yyrindex
70#define yygindex PROIO_yygindex
71#define yytable PROIO_yytable
72#define yycheck PROIO_yycheck
73#define yyname PROIO_yyname
74#define yyrule PROIO_yyrule
75#define yydebug PROIO_yydebug
76#define yynerrs PROIO_yynerrs
77#define yyerrflag PROIO_yyerrflag
78#define yychar PROIO_yychar
79#define yyvsp PROIO_yyvsp
80#define yyssp PROIO_yyssp
81#define yyval PROIO_yyval
82#define yylval PROIO_yylval
83#define yyss PROIO_yyss
84#define yyvs PROIO_yyvs
85#define yyparse PROIO_yyparse
86
87/* +++steve162e: more defines necessary */
88#define yy_init_buffer PROIO_yy_init_buffer
89#define yy_create_buffer PROIO_yy_create_buffer
90#define yy_load_buffer_state PROIO_yy_load_buffer_state
91#define yyrestart PROIO_yyrestart
92#define yy_switch_to_buffer PROIO_yy_switch_to_buffer
93#define yy_delete_buffer PROIO_yy_delete_buffer
94/* ---steve162e */
95
96/* WG 1/96: still more for flex 2.5 */
97#define yy_scan_buffer PROIO_scan_buffer
98#define yy_scan_string PROIO_scan_string
99#define yy_scan_bytes PROIO_scan_bytes
100#define yy_flex_debug PROIO_flex_debug
101#define yy_flush_buffer PROIO_flush_buffer
102#if !defined(__VISAGECPP__)
103/* multiply defined??? */
104#define yyleng PROIO_yyleng
105#define yytext PROIO_yytext
106#endif
107
108extern "C" WXDLLIMPEXP_DATA_DEPRECATED(FILE*) yyin;
109extern "C" WXDLLIMPEXP_DEPRECATED int yyparse(void);
110
111
112wxExprDatabase *thewxExprDatabase = NULL;
113wxExprErrorHandler currentwxExprErrorHandler;
114
115wxExpr::wxExpr(const wxString& functor)
116{
117  type = wxExprList;
118  next = NULL;
119  last = NULL;
120  value.first = NULL;
121
122  wxExpr *pfunctor = new wxExpr(wxExprWord, functor);
123  Append(pfunctor);
124  client_data = NULL;
125}
126
127wxExpr::wxExpr(wxExprType the_type, const wxString& word_or_string)
128{
129  type = the_type;
130
131  switch (the_type)
132  {
133   case wxExprWord:
134    value.word = copystring((const wxChar *)word_or_string);
135    break;
136   case wxExprString:
137    value.string = copystring((const wxChar *)word_or_string);
138    break;
139   case wxExprList:
140    last = NULL;
141    value.first = NULL;
142    break;
143   case wxExprReal:
144   case wxExprInteger:
145   case wxExprNull:
146    break;
147  }
148  client_data = NULL;
149  next = NULL;
150}
151
152wxExpr::wxExpr(wxExprType the_type, wxChar *word_or_string, bool allocate)
153{
154  type = the_type;
155
156  switch (the_type)
157  {
158   case wxExprWord:
159    value.word = allocate ? copystring(word_or_string) : word_or_string;
160    break;
161   case wxExprString:
162    value.string = allocate ? copystring(word_or_string) : word_or_string;
163    break;
164   case wxExprList:
165    last = NULL;
166    value.first = NULL;
167    break;
168   case wxExprReal:
169   case wxExprInteger:
170   case wxExprNull:
171    break;
172  }
173  client_data = NULL;
174  next = NULL;
175}
176
177wxExpr::wxExpr(long the_integer)
178{
179  type = wxExprInteger;
180  value.integer = the_integer;
181  client_data = NULL;
182  next = NULL;
183}
184
185wxExpr::wxExpr(double the_real)
186{
187  type = wxExprReal;
188  value.real = the_real;
189  client_data = NULL;
190  next = NULL;
191}
192
193wxExpr::wxExpr(wxList *the_list)
194{
195  type = wxExprList;
196  client_data = NULL;
197  last = NULL;
198  value.first = NULL;
199
200  wxExpr *listExpr = new wxExpr(wxExprList);
201
202  wxNode *node = the_list->GetFirst();
203  while (node)
204  {
205    wxExpr *expr = (wxExpr *)node->GetData();
206    listExpr->Append(expr);
207    node = node->GetNext();
208  }
209  Append(listExpr);
210
211  delete the_list;
212}
213
214wxExpr::~wxExpr(void)
215{
216  switch (type)
217  {
218    case wxExprInteger:
219    case wxExprReal:
220    {
221     break;
222    }
223   case wxExprString:
224   {
225     delete[] value.string;
226     break;
227   }
228   case wxExprWord:
229   {
230     delete[] value.word;
231     break;
232   }
233   case wxExprList:
234   {
235     wxExpr *expr = value.first;
236     while (expr)
237     {
238       wxExpr *expr1 = expr->next;
239
240       delete expr;
241       expr = expr1;
242     }
243     break;
244   }
245   case wxExprNull: break;
246  }
247}
248
249void wxExpr::Append(wxExpr *expr)
250{
251  if (!value.first)
252    value.first = expr;
253
254  if (last)
255    last->next = expr;
256  last = expr;
257}
258
259void wxExpr::Insert(wxExpr *expr)
260{
261  expr->next = value.first;
262  value.first = expr;
263
264  if (!last)
265    last = expr;
266}
267
268wxExpr *wxExpr::Copy(void) const
269{
270  // This seems to get round an optimizer bug when
271  // using Watcom C++ 10a in WIN32 compilation mode.
272  // If these lines not present, the type seems to be
273  // interpreted wrongly as an integer.
274  // I don't want to turn optimization off since it's needed
275  // for reading in files quickly.
276#if defined(__WATCOMC__)
277  char buf[2];
278  sprintf(buf, "");
279#endif
280
281  switch (type)
282  {
283    case wxExprInteger:
284      return new wxExpr(value.integer);
285    case wxExprReal:
286      return new wxExpr(value.real);
287    case wxExprString:
288      return new wxExpr(wxExprString, wxString(value.string));
289    case wxExprWord:
290      return new wxExpr(wxExprWord, wxString(value.word));
291    case wxExprList:
292    {
293      wxExpr *expr = value.first;
294      wxExpr *new_list = new wxExpr(wxExprList);
295      while (expr)
296      {
297        wxExpr *expr2 = expr->Copy();
298        new_list->Append(expr2);
299        expr = expr->next;
300      }
301      return new_list;
302    }
303   case wxExprNull:
304    break;
305  }
306  return NULL;
307}
308
309
310// Get the wxExpr (containing (= wxExpr Value) form) for the given word
311//  or string, assuming that we have Attribute=Value, ...
312wxExpr *wxExpr::GetAttributeValueNode(const wxString& word) const // Use only for a clause or list
313{
314  if (type != wxExprList)
315    return NULL;
316
317  wxExpr *expr = value.first;
318  while (expr)
319  {
320    if (expr->type == wxExprList)
321    {
322      wxExpr *firstNode = expr->value.first;
323      if ((firstNode->type == wxExprWord) && (firstNode->value.word[0] == '='))
324      {
325        wxExpr *secondNode = firstNode->next;
326        if ((secondNode->type == wxExprWord) &&
327            (wxStrcmp((const wxChar *)word, secondNode->value.word) == 0))
328        {
329          return expr;
330        }
331      }
332    }
333    expr = expr->next;
334  }
335  return NULL;
336}
337
338// Get the value (in wxExpr form) for the given word or string, assuming
339// that we have Attribute=Value, ...
340wxExpr *wxExpr::AttributeValue(const wxString& word) const // Use only for a clause or list
341{
342  if (type != wxExprList)
343    return NULL;
344
345  wxExpr *attExpr = GetAttributeValueNode(word);
346  if (attExpr && attExpr->value.first && attExpr->value.first->next)
347    return attExpr->value.first->next->next;
348  else return NULL;
349}
350
351wxString wxExpr::Functor(void) const // Use only for a clause
352{
353  if ((type != wxExprList) || !value.first)
354    return wxString(wxT(""));
355
356  if (value.first->type == wxExprWord)
357    return wxString(value.first->value.word);
358  else
359    return wxString(wxT(""));
360}
361
362bool wxExpr::IsFunctor(const wxString& f) const  // Use only for a clause
363{
364  if ((type != wxExprList) || !value.first)
365    return false;
366
367  return (value.first->type == wxExprWord &&
368          (wxStrcmp((const wxChar *)f, value.first->value.word) == 0));
369}
370
371// Return nth argument of a clause (starting from 1)
372wxExpr *wxExpr::Arg(wxExprType theType, int arg) const
373{
374  wxExpr *expr = value.first;
375  int i;
376  for (i = 1; i < arg; i++)
377    if (expr)
378      expr = expr->next;
379
380  if (expr && (expr->type == theType))
381    return expr;
382  else
383    return NULL;
384}
385
386// Return nth argument of a list expression (starting from zero)
387wxExpr *wxExpr::Nth(int arg) const
388{
389  if (type != wxExprList)
390    return NULL;
391
392  wxExpr *expr = value.first;
393  int i;
394  for (i = 0; i < arg; i++)
395    if (expr)
396      expr = expr->next;
397    else return NULL;
398
399  if (expr)
400    return expr;
401  else
402    return NULL;
403}
404
405  // Returns the number of elements in a list expression
406int wxExpr::Number(void) const
407{
408  if (type != wxExprList)
409    return 0;
410
411  int i = 0;
412  wxExpr *expr = value.first;
413  while (expr)
414  {
415    expr = expr->next;
416    i ++;
417  }
418  return i;
419}
420
421void wxExpr::DeleteAttributeValue(const wxString& attribute)
422{
423  if (type != wxExprList)
424    return;
425
426  wxExpr *expr = value.first;
427  wxExpr *lastExpr = this;
428  while (expr)
429  {
430    if (expr->type == wxExprList)
431    {
432      wxExpr *firstNode = expr->value.first;
433      if ((firstNode->type == wxExprWord) && (firstNode->value.word[0] == '='))
434      {
435        wxExpr *secondNode = firstNode->next;
436        if ((secondNode->type == wxExprWord) &&
437            (wxStrcmp((const wxChar *)attribute, secondNode->value.word) == 0))
438        {
439          wxExpr *nextExpr = expr->next;
440          delete expr;
441
442          lastExpr->next = nextExpr;
443
444          if (last == expr)
445            last = lastExpr;
446
447          return;
448        }
449      }
450    }
451    lastExpr = expr;
452    expr = expr->next;
453  }
454  return;
455}
456
457void wxExpr::AddAttributeValue(const wxString& attribute, wxExpr *val)
458{
459  if (type != wxExprList)
460  {
461//    cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
462    return;
463  }
464  // Warning - existing code may assume that any existing value
465  // is deleted first. For efficiency, we leave this to the application.
466//  DeleteAttributeValue(attribute);
467
468  wxExpr *patt = new wxExpr(wxExprWord, attribute);
469  wxExpr *pequals = new wxExpr(wxExprWord, wxT("="));
470
471  wxExpr *listExpr = new wxExpr(wxExprList);
472
473  listExpr->Append(pequals);
474  listExpr->Append(patt);
475  listExpr->Append(val);
476
477  Append(listExpr);
478}
479
480void wxExpr::AddAttributeValue(const wxString& attribute, long val)
481{
482  if (type != wxExprList)
483  {
484//    cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
485    return;
486  }
487  // Warning - existing code may assume that any existing value
488  // is deleted first. For efficiency, we leave this to the application.
489//  DeleteAttributeValue(attribute);
490
491  wxExpr *patt = new wxExpr(wxExprWord, attribute);
492  wxExpr *pval = new wxExpr(val);
493  wxExpr *pequals = new wxExpr(wxExprWord, wxT("="));
494
495  wxExpr *listExpr = new wxExpr(wxExprList);
496
497  listExpr->Append(pequals);
498  listExpr->Append(patt);
499  listExpr->Append(pval);
500
501  Append(listExpr);
502}
503
504void wxExpr::AddAttributeValue(const wxString& attribute, double val)
505{
506  if (type != wxExprList)
507  {
508//    cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
509    return;
510  }
511
512//  DeleteAttributeValue(attribute);
513  wxExpr *patt = new wxExpr(wxExprWord, attribute);
514  wxExpr *pval = new wxExpr(val);
515  wxExpr *pequals = new wxExpr(wxExprWord, wxT("="));
516
517  wxExpr *listExpr = new wxExpr(wxExprList);
518
519  listExpr->Append(pequals);
520  listExpr->Append(patt);
521  listExpr->Append(pval);
522
523  Append(listExpr);
524}
525
526void wxExpr::AddAttributeValueString(const wxString& attribute, const wxString& val)
527{
528  if (type != wxExprList)
529  {
530//    cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
531    return;
532  }
533
534//  DeleteAttributeValue(attribute);
535
536  wxExpr *patt = new wxExpr(wxExprWord, attribute);
537  wxExpr *pval = new wxExpr(wxExprString, val);
538  wxExpr *pequals = new wxExpr(wxExprWord, wxT("="));
539
540  wxExpr *listExpr = new wxExpr(wxExprList);
541
542  listExpr->Append(pequals);
543  listExpr->Append(patt);
544  listExpr->Append(pval);
545
546  Append(listExpr);
547}
548
549void wxExpr::AddAttributeValueWord(const wxString& attribute, const wxString& val)
550{
551  if (type != wxExprList)
552  {
553//    cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
554    return;
555  }
556
557//  DeleteAttributeValue(attribute);
558
559  wxExpr *patt = new wxExpr(wxExprWord, attribute);
560  wxExpr *pval = new wxExpr(wxExprWord, val);
561  wxExpr *pequals = new wxExpr(wxExprWord, wxT("="));
562
563  wxExpr *listExpr = new wxExpr(wxExprList);
564
565  listExpr->Append(pequals);
566  listExpr->Append(patt);
567  listExpr->Append(pval);
568
569  Append(listExpr);
570}
571
572void wxExpr::AddAttributeValue(const wxString& attribute, wxList *val)
573{
574  if (type != wxExprList)
575  {
576//    cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
577    return;
578  }
579  if (!val)
580    return;
581
582//  DeleteAttributeValue(attribute);
583
584  wxExpr *patt = new wxExpr(wxExprWord, attribute);
585  wxExpr *pval = new wxExpr(val);
586  wxExpr *pequals = new wxExpr(wxExprWord, wxT("="));
587
588  wxExpr *listExpr = new wxExpr(wxExprList);
589
590  listExpr->Append(pequals);
591  listExpr->Append(patt);
592  listExpr->Append(pval);
593
594  Append(listExpr);
595}
596
597void wxExpr::AddAttributeValueStringList(const wxString& attribute, wxList *string_list)
598{
599  if (type != wxExprList)
600  {
601//    cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
602    return;
603  }
604  if (!string_list)
605    return;
606
607//  DeleteAttributeValue(attribute);
608
609  // First make a list of wxExpr strings
610  wxExpr *listExpr = new wxExpr(wxExprList);
611  wxNode *node = string_list->GetFirst();
612  while (node)
613  {
614    wxChar *string = (wxChar*)node->GetData();
615    wxExpr *expr = new wxExpr(wxExprString, wxString(string));
616    listExpr->Append(expr);
617    node = node->GetNext();
618  }
619
620  // Now make an (=, Att, Value) triple
621  wxExpr *patt = new wxExpr(wxExprWord, attribute);
622  wxExpr *pequals = new wxExpr(wxExprWord, wxT("="));
623
624  wxExpr *listExpr2 = new wxExpr(wxExprList);
625
626  listExpr2->Append(pequals);
627  listExpr2->Append(patt);
628  listExpr2->Append(listExpr);
629
630  Append(listExpr2);
631}
632
633bool wxExpr::GetAttributeValue(const wxString& att, int& var) const
634{
635  wxExpr *expr = AttributeValue(att);
636
637  if (expr && (expr->Type() == wxExprInteger || expr->Type() == wxExprReal))
638  {
639    var = (int)(expr->IntegerValue());
640    return true;
641  }
642  else
643    return false;
644}
645
646bool wxExpr::GetAttributeValue(const wxString& att, long& var) const
647{
648  wxExpr *expr = AttributeValue(att);
649
650  if (expr && (expr->Type() == wxExprInteger || expr->Type() == wxExprReal))
651  {
652    var = expr->IntegerValue();
653    return true;
654  }
655  else
656    return false;
657}
658
659bool wxExpr::GetAttributeValue(const wxString& att, float& var) const
660{
661  wxExpr *expr = AttributeValue(att);
662  if (expr && (expr->Type() == wxExprInteger || expr->Type() == wxExprReal))
663  {
664    var = (float) expr->RealValue();
665    return true;
666  }
667  else
668    return false;
669}
670
671bool wxExpr::GetAttributeValue(const wxString& att, double& var) const
672{
673  wxExpr *expr = AttributeValue(att);
674  if (expr && (expr->Type() == wxExprInteger || expr->Type() == wxExprReal))
675  {
676    var = expr->RealValue();
677    return true;
678  }
679  else
680    return false;
681}
682
683bool wxExpr::GetAttributeValue(const wxString& att, wxString& var)  const // Word OR string -> string
684{
685  wxExpr *expr = AttributeValue(att);
686  if (expr && expr->Type() == wxExprWord)
687  {
688    var = expr->WordValue();
689    return true;
690  }
691  else if (expr && expr->Type() == wxExprString)
692  {
693    var = expr->StringValue();
694    return true;
695  }
696  else
697    return false;
698}
699
700bool wxExpr::GetAttributeValue(const wxString& att, wxExpr **var) const
701{
702  wxExpr *expr = AttributeValue(att);
703  if (expr)
704  {
705    *var = expr;
706    return true;
707  }
708  else
709    return false;
710}
711
712bool wxExpr::GetAttributeValueStringList(const wxString& att, wxList *var) const
713{
714  wxExpr *expr = AttributeValue(att);
715  if (expr && expr->Type() == wxExprList)
716  {
717    wxExpr *string_expr = expr->value.first;
718    while (string_expr)
719    {
720      if (string_expr->Type() == wxExprString)
721        var->Append((wxObject *)copystring(string_expr->StringValue()));
722
723      string_expr = string_expr->next;
724    }
725    return true;
726  }
727  else
728    return false;
729}
730
731// Compatibility
732void wxExpr::AssignAttributeValue(wxChar *att, wxChar **var) const
733{
734  wxString str;
735  if (GetAttributeValue(att, str))
736  {
737    if (*var)
738      delete[] *var;
739    *var = copystring((const wxChar *) str);
740  }
741}
742
743void wxExpr::WriteClause(FILE* stream)  // Write this expression as a top-level clause
744{
745  if (type != wxExprList)
746    return;
747
748  wxExpr *node = value.first;
749  if (node)
750  {
751    node->WriteExpr(stream);
752    fprintf( stream, "(" );
753    node = node->next;
754    bool first = true;
755    while (node)
756    {
757      if (!first)
758        fprintf( stream, "  " );
759      node->WriteExpr(stream);
760      node = node->next;
761      if (node)
762        fprintf( stream, ",\n" );
763      first = false;
764    }
765    fprintf( stream, ").\n\n" );
766  }
767}
768
769void wxExpr::WriteExpr(FILE* stream)    // Write as any other subexpression
770{
771  // This seems to get round an optimizer bug when
772  // using Watcom C++ 10a in WIN32 compilation mode.
773  // If these lines not present, the type seems to be
774  // interpreted wrongly as an integer.
775  // I don't want to turn optimization off since it's needed
776  // for reading in files quickly.
777#if defined(__WATCOMC__)
778  char buf[2];
779  sprintf(buf, "");
780#endif
781
782  switch (type)
783  {
784    case wxExprInteger:
785    {
786      fprintf( stream, "%ld", value.integer );
787      break;
788    }
789    case wxExprReal:
790    {
791      double f = value.real;
792      fprintf( stream, "%.6g", f);
793      break;
794    }
795    case wxExprString:
796    {
797      fprintf( stream, "\"" );
798      size_t i;
799      const wxWX2MBbuf val = wxConvLibc.cWX2MB(value.string);
800      size_t len = strlen(val);
801      for (i = 0; i < len; i++)
802      {
803        char ch = val[i];
804        if (ch == '"' || ch == '\\')
805        fprintf( stream, "\\" );
806        char tmp[2];
807        tmp[0] = ch;
808        tmp[1] = 0;
809        fprintf( stream, tmp );
810      }
811      fprintf( stream, "\"" );
812      break;
813    }
814    case wxExprWord:
815    {
816      bool quote_it = false;
817      const wxWX2MBbuf val = wxConvLibc.cWX2MB(value.word);
818      size_t len = strlen(val);
819      if ((len == 0) || (len > 0 && (val[(size_t) 0] > 64 && val[(size_t) 0] < 91)))
820        quote_it = true;
821      else
822      {
823        size_t i;
824        for (i = 0; i < len; i++)
825          if ((!isalpha(val[i])) && (!isdigit(val[i])) &&
826              (val[i] != '_'))
827            { quote_it = true; i = len; }
828      }
829
830      if (quote_it)
831        fprintf( stream ,"'" );
832
833      fprintf( stream, val );
834
835      if (quote_it)
836        fprintf( stream, "'" );
837
838      break;
839    }
840    case wxExprList:
841    {
842      if (!value.first)
843        fprintf( stream, "[]" );
844      else
845      {
846        wxExpr *expr = value.first;
847
848        if ((expr->Type() == wxExprWord) && (wxStrcmp(expr->WordValue(), wxT("=")) == 0))
849        {
850          wxExpr *arg1 = expr->next;
851          wxExpr *arg2 = arg1->next;
852          arg1->WriteExpr(stream);
853          fprintf( stream, " = " );
854          arg2->WriteExpr(stream);
855        }
856        else
857        {
858          fprintf( stream, "[" );
859          while (expr)
860          {
861            expr->WriteExpr(stream);
862            expr = expr->next;
863            if (expr)
864              fprintf( stream, ", " );
865          }
866          fprintf( stream, "]" );
867        }
868      }
869      break;
870    }
871   case wxExprNull: break;
872  }
873}
874
875/*
876 * wxExpr 'database' (list of expressions)
877 */
878
879IMPLEMENT_DYNAMIC_CLASS(wxExprDatabase, wxList)
880
881wxExprDatabase::wxExprDatabase(wxExprErrorHandler handler)
882{
883  position = NULL;
884  hash_table = NULL;
885  currentwxExprErrorHandler = handler;
886  noErrors = 0;
887}
888
889wxExprDatabase::wxExprDatabase(wxExprType type, const wxString& attribute, int size,
890                               wxExprErrorHandler handler)
891{
892  position = NULL;
893  attribute_to_hash = attribute;
894  if (type == wxExprString)
895    hash_table = new wxHashTable(wxKEY_STRING, size);
896  else if (type == wxExprInteger)
897    hash_table = new wxHashTable(wxKEY_INTEGER, size);
898  else hash_table = NULL;
899
900  currentwxExprErrorHandler = handler;
901  noErrors = 0;
902}
903
904wxExprDatabase::~wxExprDatabase(void)
905{
906  ClearDatabase();
907  if (hash_table)
908    delete hash_table;
909}
910
911void wxExprDatabase::BeginFind(void)          // Initialise a search
912{
913  position = GetFirst();
914}
915
916wxExpr *wxExprDatabase::FindClause(long id)  // Find a term based on an integer id attribute
917                                 // e.g. node(id=23, type=rectangle, ....).
918{
919  wxExpr *found = NULL;
920  while (position && !found)
921  {
922    wxExpr *term = (wxExpr *)position->GetData();
923
924    if (term->Type() == wxExprList)
925    {
926      wxExpr *value = term->AttributeValue(wxT("id"));
927      if (value->Type() == wxExprInteger && value->IntegerValue() == id)
928        found = term;
929    }
930    position = position->GetNext();
931  }
932  return found;
933}
934
935// Find on basis of attribute/value pairs, e.g. type=rectangle
936wxExpr *wxExprDatabase::FindClause(const wxString& word, const wxString& val)
937{
938  wxExpr *found = NULL;
939  while (position && !found)
940  {
941    wxExpr *term = (wxExpr *)position->GetData();
942
943    if (term->Type() == wxExprList)
944    {
945      wxExpr *value = term->AttributeValue(word);
946      if ((value->Type() == wxExprWord && value->WordValue() == val) ||
947          (value->Type() == wxExprString && value->StringValue() == val))
948        found = term;
949    }
950    position = position->GetNext();
951  }
952  return found;
953}
954
955wxExpr *wxExprDatabase::FindClause(const wxString& word, long val)
956{
957  wxExpr *found = NULL;
958  while (position && !found)
959  {
960    wxExpr *term = (wxExpr *)position->GetData();
961
962    if (term->Type() == wxExprList)
963    {
964      wxExpr *value = term->AttributeValue(word);
965      if ((value->Type() == wxExprInteger) && (value->IntegerValue() == val))
966        found = term;
967    }
968    position = position->GetNext();
969  }
970  return found;
971}
972
973wxExpr *wxExprDatabase::FindClause(const wxString& word, double val)
974{
975  wxExpr *found = NULL;
976  while (position && !found)
977  {
978    wxExpr *term = (wxExpr *)position->GetData();
979
980    if (term->Type() == wxExprList)
981    {
982      wxExpr *value = term->AttributeValue(word);
983      if ((value->Type() == wxExprReal) && (value->RealValue() == val))
984        found = term;
985    }
986    position = position->GetNext();
987  }
988  return found;
989}
990
991wxExpr *wxExprDatabase::FindClauseByFunctor(const wxString& functor)
992{
993  wxExpr *found = NULL;
994  while (position && !found)
995  {
996    wxExpr *term = (wxExpr *)position->GetData();
997
998    if (term->Type() == wxExprList)
999    {
1000      if (term->Functor() == functor)
1001        found = term;
1002    }
1003    position = position->GetNext();
1004  }
1005  return found;
1006}
1007
1008// If hashing is on, must store in hash table too
1009void wxExprDatabase::Append(wxExpr *clause)
1010{
1011  wxList::Append((wxObject *)clause);
1012  if (hash_table)
1013  {
1014    wxString functor(clause->Functor());
1015    wxExpr *expr = clause->AttributeValue(attribute_to_hash);
1016    if (expr)
1017    {
1018      long functor_key = hash_table->MakeKey(WXSTRINGCAST functor);
1019      long value_key;
1020      if (expr && expr->Type() == wxExprString)
1021      {
1022        value_key = hash_table->MakeKey(WXSTRINGCAST expr->StringValue());
1023        hash_table->Put(functor_key + value_key, WXSTRINGCAST expr->StringValue(), (wxObject *)clause);
1024      }
1025      else if (expr && expr->Type() == wxExprInteger)
1026      {
1027        value_key = expr->IntegerValue();
1028        hash_table->Put(functor_key + value_key, expr->IntegerValue(), (wxObject *)clause);
1029      }
1030
1031    }
1032  }
1033}
1034
1035wxExpr *wxExprDatabase::HashFind(const wxString& functor, long value) const
1036{
1037  long key = hash_table->MakeKey(WXSTRINGCAST functor) + value;
1038
1039  // The key alone isn't guaranteed to be unique:
1040  // must supply value too. Let's assume the value of the
1041  // id is going to be reasonably unique.
1042  return (wxExpr *)hash_table->Get(key, value);
1043}
1044
1045wxExpr *wxExprDatabase::HashFind(const wxString& functor, const wxString& value) const
1046{
1047  long key = hash_table->MakeKey(WXSTRINGCAST functor) + hash_table->MakeKey(WXSTRINGCAST value);
1048  return (wxExpr *)hash_table->Get(key, WXSTRINGCAST value);
1049}
1050
1051void wxExprDatabase::ClearDatabase(void)
1052{
1053  noErrors = 0;
1054  wxNode *node = GetFirst();
1055  while (node)
1056  {
1057    wxExpr *expr = (wxExpr *)node->GetData();
1058    delete expr;
1059    delete node;
1060    node = GetFirst();
1061  }
1062
1063  if (hash_table)
1064    hash_table->Clear();
1065}
1066
1067bool wxExprDatabase::Read(const wxString& filename)
1068{
1069  noErrors = 0;
1070
1071  FILE *f = wxFopen(filename, _T("r"));
1072  if (f)
1073  {
1074    thewxExprDatabase = this;
1075
1076    LexFromFile(f);
1077    yyparse();
1078    fclose(f);
1079
1080    wxExprCleanUp();
1081    return (noErrors == 0);
1082  }
1083  else
1084  {
1085    return false;
1086  }
1087}
1088
1089bool wxExprDatabase::ReadFromString(const wxString& buffer)
1090{
1091  noErrors = 0;
1092  thewxExprDatabase = this;
1093
1094  const wxWX2MBbuf buf = buffer.mb_str();
1095  LexFromString(wxMBSTRINGCAST buf);
1096  yyparse();
1097  wxExprCleanUp();
1098  return (noErrors == 0);
1099}
1100
1101bool wxExprDatabase::Write(const wxString& fileName)
1102{
1103  FILE *stream = wxFopen( fileName, _T("w+"));
1104
1105  if (!stream)
1106    return false;
1107
1108  bool success = Write(stream);
1109  fclose(stream);
1110  return success;
1111}
1112
1113bool wxExprDatabase::Write(FILE *stream)
1114{
1115  noErrors = 0;
1116  wxNode *node = GetFirst();
1117  while (node)
1118  {
1119    wxExpr *expr = (wxExpr *)node->GetData();
1120    expr->WriteClause(stream);
1121    node = node->GetNext();
1122  }
1123  return (noErrors == 0);
1124}
1125
1126void add_expr(wxExpr * expr)
1127{
1128  thewxExprDatabase->Append(expr);
1129}
1130
1131// Checks functor
1132bool wxExprIsFunctor(wxExpr *expr, const wxString& functor)
1133{
1134  if (expr && (expr->Type() == wxExprList))
1135  {
1136    wxExpr *first_expr = expr->value.first;
1137
1138    if (first_expr && (first_expr->Type() == wxExprWord) &&
1139       (first_expr->WordValue() == functor))
1140      return true;
1141    else
1142      return false;
1143  }
1144  else
1145    return false;
1146}
1147
1148/*
1149 * Called from parser
1150 *
1151 */
1152
1153char *wxmake_integer(char *str)
1154{
1155  wxExpr *x = new wxExpr(atol(str));
1156
1157  return (char *)x;
1158}
1159
1160char *wxmake_real(char *str1, char *str2)
1161{
1162  char buf[50];
1163
1164  sprintf(buf, "%s.%s", str1, str2);
1165  double f = (double)atof(buf);
1166  wxExpr *x = new wxExpr(f);
1167
1168  return (char *)x;
1169}
1170
1171// extern "C" double exp10(double);
1172
1173char *wxmake_exp(char *str1, char *str2)
1174{
1175  double mantissa = (double)atoi(str1);
1176  double exponent = (double)atoi(str2);
1177
1178  double d = mantissa * pow(10.0, exponent);
1179
1180  wxExpr *x = new wxExpr(d);
1181
1182  return (char *)x;
1183}
1184
1185char *wxmake_exp2(char *str1, char *str2, char *str3)
1186{
1187  char buf[50];
1188
1189  sprintf(buf, "%s.%s", str1, str2);
1190  double mantissa = (double)atof(buf);
1191  double exponent = (double)atoi(str3);
1192
1193  double d = mantissa * pow(10.0, exponent);
1194
1195  wxExpr *x = new wxExpr(d);
1196
1197  return (char *)x;
1198}
1199
1200char *wxmake_word(char *str)
1201{
1202  wxExpr *x = new wxExpr(wxExprWord, wxString(str, wxConvLibc).c_str());
1203  return (char *)x;
1204}
1205
1206char *wxmake_string(char *str)
1207{
1208  wxChar *s, *t;
1209  size_t len, i;
1210  const wxMB2WXbuf sbuf = wxConvLibc.cMB2WX(str);
1211
1212//  str++;                    /* skip leading quote */
1213  len = wxStrlen(sbuf) - 1;   /* ignore trailing quote */
1214
1215  s = new wxChar[len + 1];
1216
1217  t = s;
1218  for(i=1; i<len; i++) // 1 since we want to skip leading quote
1219  {
1220    if (sbuf[i] == wxT('\\') && sbuf[i+1] == wxT('"'))
1221    {
1222      *t++ = wxT('"');
1223      i ++;
1224    }
1225    else if (sbuf[i] == wxT('\\') && sbuf[i+1] == wxT('\\'))
1226    {
1227      *t++ = wxT('\\');
1228      i ++;
1229    }
1230    else
1231      *t++ = sbuf[i];
1232  }
1233
1234  *t = wxT('\0');
1235
1236  wxExpr *x = new wxExpr(wxExprString, s, false);
1237  return (char *)x;
1238}
1239
1240char *proio_cons(char * ccar, char * ccdr)
1241{
1242  wxExpr *car = (wxExpr *)ccar;
1243  wxExpr *cdr = (wxExpr *)ccdr;
1244
1245  if (cdr == NULL)
1246  {
1247    cdr = new wxExpr(wxExprList);
1248  }
1249  if (car)
1250    cdr->Insert(car);
1251  return (char *)cdr;
1252}
1253
1254void process_command(char * cexpr)
1255{
1256  wxExpr *expr = (wxExpr *)cexpr;
1257  add_expr(expr);
1258}
1259
1260void syntax_error(char *WXUNUSED(s))
1261{
1262  if (currentwxExprErrorHandler)
1263    (void)(*(currentwxExprErrorHandler))(WXEXPR_ERROR_SYNTAX, (char *)"syntax error");
1264  if (thewxExprDatabase) thewxExprDatabase->noErrors += 1;
1265}
1266
1267#if 0
1268#ifdef _WINDLL
1269// char *__cdecl strdup(const char *s)
1270WXDLLEXPORT char *strdup(const char *s)
1271{
1272  int len = strlen(s);
1273  char *new_s = (char *)malloc(sizeof(char)*(len+1));
1274  strcpy(new_s, s);
1275  return new_s;
1276}
1277#endif
1278#endif
1279
1280#endif
1281  // wxUSE_PROLOGIO
1282