home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
wxos2240.zip
/
wxWindows-2.4.0
/
src
/
common
/
wxexpr.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
2002-11-09
|
30KB
|
1,279 lines
/////////////////////////////////////////////////////////////////////////////
// Name: wxexpr.cpp
// Purpose: wxExpr
// Author: Julian Smart
// Modified by:
// Created: 04/01/98
// RCS-ID: $Id: wxexpr.cpp,v 1.25.2.1 2002/11/04 23:11:23 VZ Exp $
// Copyright: (c) Julian Smart and Markus Holzem
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#pragma implementation "wxexpr.h"
#endif
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#if wxUSE_PROLOGIO
#include <stdarg.h>
#include <ctype.h>
#include <string.h>
#include "wx/utils.h"
#include "wx/expr.h"
#include "wx/wxexpr.h"
extern "C" void add_expr(char *);
extern "C" void LexFromFile(FILE *fd);
extern "C" void LexFromString(char *buf);
/* Rename all YACC/LEX stuff or we'll conflict with other
* applications
*/
#define yyback PROIO_yyback
#define yylook PROIO_yylook
#define yywrap PROIO_yywrap
#define yyoutput PROIO_yyoutput
#define yylex PROIO_yylex
#define yyerror PROIO_yyerror
#define yyleng PROIO_yyleng
#define yytext PROIO_yytext
#define yymorfg PROIO_yymorfg
#define yylineno PROIO_yylineno
#define yytchar PROIO_yytchar
#define yyin PROIO_yyin
#define yyout PROIO_yyout
#define yysvf PROIO_yysvf
#define yyestate PROIO_yyestate
#define yysvec PROIO_yysvec
#define yybgin PROIO_yybgin
#define yyprevious PROIO_yyprevious
#define yylhs PROIO_yylhs
#define yylen PROIO_yylen
#define yydefred PROIO_yydefred
#define yydgoto PROIO_yydgoto
#define yysindex PROIO_yysindex
#define yyrindex PROIO_yyrindex
#define yygindex PROIO_yygindex
#define yytable PROIO_yytable
#define yycheck PROIO_yycheck
#define yyname PROIO_yyname
#define yyrule PROIO_yyrule
#define yydebug PROIO_yydebug
#define yynerrs PROIO_yynerrs
#define yyerrflag PROIO_yyerrflag
#define yychar PROIO_yychar
#define yyvsp PROIO_yyvsp
#define yyssp PROIO_yyssp
#define yyval PROIO_yyval
#define yylval PROIO_yylval
#define yyss PROIO_yyss
#define yyvs PROIO_yyvs
#define yyparse PROIO_yyparse
/* +++steve162e: more defines necessary */
#define yy_init_buffer PROIO_yy_init_buffer
#define yy_create_buffer PROIO_yy_create_buffer
#define yy_load_buffer_state PROIO_yy_load_buffer_state
#define yyrestart PROIO_yyrestart
#define yy_switch_to_buffer PROIO_yy_switch_to_buffer
#define yy_delete_buffer PROIO_yy_delete_buffer
/* ---steve162e */
/* WG 1/96: still more for flex 2.5 */
#define yy_scan_buffer PROIO_scan_buffer
#define yy_scan_string PROIO_scan_string
#define yy_scan_bytes PROIO_scan_bytes
#define yy_flex_debug PROIO_flex_debug
#define yy_flush_buffer PROIO_flush_buffer
#if !defined(__VISAGECPP__)
/* multiply defined??? */
#define yyleng PROIO_yyleng
#define yytext PROIO_yytext
#endif
extern "C" WXDLLEXPORT_DATA(FILE*) yyin;
extern "C" WXDLLEXPORT int yyparse(void);
wxExprDatabase *thewxExprDatabase = NULL;
wxExprErrorHandler currentwxExprErrorHandler;
wxExpr::wxExpr(const wxString& functor)
{
type = wxExprList;
next = NULL;
last = NULL;
value.first = NULL;
wxExpr *pfunctor = new wxExpr(wxExprWord, functor);
Append(pfunctor);
client_data = NULL;
}
wxExpr::wxExpr(wxExprType the_type, const wxString& word_or_string)
{
type = the_type;
switch (the_type)
{
case wxExprWord:
value.word = copystring((const wxChar *)word_or_string);
break;
case wxExprString:
value.string = copystring((const wxChar *)word_or_string);
break;
case wxExprList:
last = NULL;
value.first = NULL;
break;
case wxExprReal:
case wxExprInteger:
case wxExprNull:
break;
}
client_data = NULL;
next = NULL;
}
wxExpr::wxExpr(wxExprType the_type, wxChar *word_or_string, bool allocate)
{
type = the_type;
switch (the_type)
{
case wxExprWord:
value.word = allocate ? copystring(word_or_string) : word_or_string;
break;
case wxExprString:
value.string = allocate ? copystring(word_or_string) : word_or_string;
break;
case wxExprList:
last = NULL;
value.first = NULL;
break;
case wxExprReal:
case wxExprInteger:
case wxExprNull:
break;
}
client_data = NULL;
next = NULL;
}
wxExpr::wxExpr(long the_integer)
{
type = wxExprInteger;
value.integer = the_integer;
client_data = NULL;
next = NULL;
}
wxExpr::wxExpr(double the_real)
{
type = wxExprReal;
value.real = the_real;
client_data = NULL;
next = NULL;
}
wxExpr::wxExpr(wxList *the_list)
{
type = wxExprList;
client_data = NULL;
last = NULL;
value.first = NULL;
wxExpr *listExpr = new wxExpr(wxExprList);
wxNode *node = the_list->First();
while (node)
{
wxExpr *expr = (wxExpr *)node->Data();
listExpr->Append(expr);
node = node->Next();
}
Append(listExpr);
delete the_list;
}
wxExpr::~wxExpr(void)
{
switch (type)
{
case wxExprInteger:
case wxExprReal:
{
break;
}
case wxExprString:
{
delete[] value.string;
break;
}
case wxExprWord:
{
delete[] value.word;
break;
}
case wxExprList:
{
wxExpr *expr = value.first;
while (expr)
{
wxExpr *expr1 = expr->next;
delete expr;
expr = expr1;
}
break;
}
case wxExprNull: break;
}
}
void wxExpr::Append(wxExpr *expr)
{
if (!value.first)
value.first = expr;
if (last)
last->next = expr;
last = expr;
}
void wxExpr::Insert(wxExpr *expr)
{
expr->next = value.first;
value.first = expr;
if (!last)
last = expr;
}
wxExpr *wxExpr::Copy(void) const
{
// This seems to get round an optimizer bug when
// using Watcom C++ 10a in WIN32 compilation mode.
// If these lines not present, the type seems to be
// interpreted wrongly as an integer.
// I don't want to turn optimization off since it's needed
// for reading in files quickly.
#if defined(__WATCOMC__)
char buf[2];
sprintf(buf, "");
#endif
switch (type)
{
case wxExprInteger:
return new wxExpr(value.integer);
case wxExprReal:
return new wxExpr(value.real);
case wxExprString:
return new wxExpr(wxExprString, wxString(value.string));
case wxExprWord:
return new wxExpr(wxExprWord, wxString(value.word));
case wxExprList:
{
wxExpr *expr = value.first;
wxExpr *new_list = new wxExpr(wxExprList);
while (expr)
{
wxExpr *expr2 = expr->Copy();
new_list->Append(expr2);
expr = expr->next;
}
return new_list;
}
case wxExprNull:
break;
}
return NULL;
}
// Get the wxExpr (containing (= wxExpr Value) form) for the given word
// or string, assuming that we have Attribute=Value, ...
wxExpr *wxExpr::GetAttributeValueNode(const wxString& word) const // Use only for a clause or list
{
if (type != wxExprList)
return NULL;
wxExpr *expr = value.first;
while (expr)
{
if (expr->type == wxExprList)
{
wxExpr *firstNode = expr->value.first;
if ((firstNode->type == wxExprWord) && (firstNode->value.word[0] == '='))
{
wxExpr *secondNode = firstNode->next;
if ((secondNode->type == wxExprWord) &&
(wxStrcmp((const wxChar *)word, secondNode->value.word) == 0))
{
return expr;
}
}
}
expr = expr->next;
}
return NULL;
}
// Get the value (in wxExpr form) for the given word or string, assuming
// that we have Attribute=Value, ...
wxExpr *wxExpr::AttributeValue(const wxString& word) const // Use only for a clause or list
{
if (type != wxExprList)
return NULL;
wxExpr *attExpr = GetAttributeValueNode(word);
if (attExpr && attExpr->value.first && attExpr->value.first->next)
return attExpr->value.first->next->next;
else return NULL;
}
wxString wxExpr::Functor(void) const // Use only for a clause
{
if ((type != wxExprList) || !value.first)
return wxString(wxT(""));
if (value.first->type == wxExprWord)
return wxString(value.first->value.word);
else
return wxString(wxT(""));
}
bool wxExpr::IsFunctor(const wxString& f) const // Use only for a clause
{
if ((type != wxExprList) || !value.first)
return FALSE;
return (value.first->type == wxExprWord &&
(wxStrcmp((const wxChar *)f, value.first->value.word) == 0));
}
// Return nth argument of a clause (starting from 1)
wxExpr *wxExpr::Arg(wxExprType theType, int arg) const
{
wxExpr *expr = value.first;
int i;
for (i = 1; i < arg; i++)
if (expr)
expr = expr->next;
if (expr && (expr->type == theType))
return expr;
else
return NULL;
}
// Return nth argument of a list expression (starting from zero)
wxExpr *wxExpr::Nth(int arg) const
{
if (type != wxExprList)
return NULL;
wxExpr *expr = value.first;
int i;
for (i = 0; i < arg; i++)
if (expr)
expr = expr->next;
else return NULL;
if (expr)
return expr;
else
return NULL;
}
// Returns the number of elements in a list expression
int wxExpr::Number(void) const
{
if (type != wxExprList)
return 0;
int i = 0;
wxExpr *expr = value.first;
while (expr)
{
expr = expr->next;
i ++;
}
return i;
}
void wxExpr::DeleteAttributeValue(const wxString& attribute)
{
if (type != wxExprList)
return;
wxExpr *expr = value.first;
wxExpr *lastExpr = this;
while (expr)
{
if (expr->type == wxExprList)
{
wxExpr *firstNode = expr->value.first;
if ((firstNode->type == wxExprWord) && (firstNode->value.word[0] == '='))
{
wxExpr *secondNode = firstNode->next;
if ((secondNode->type == wxExprWord) &&
(wxStrcmp((const wxChar *)attribute, secondNode->value.word) == 0))
{
wxExpr *nextExpr = expr->next;
delete expr;
lastExpr->next = nextExpr;
if (last == expr)
last = lastExpr;
return;
}
}
}
lastExpr = expr;
expr = expr->next;
}
return;
}
void wxExpr::AddAttributeValue(const wxString& attribute, wxExpr *val)
{
if (type != wxExprList)
{
// cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
return;
}
// Warning - existing code may assume that any existing value
// is deleted first. For efficiency, we leave this to the application.
// DeleteAttributeValue(attribute);
wxExpr *patt = new wxExpr(wxExprWord, attribute);
wxExpr *pequals = new wxExpr(wxExprWord, wxT("="));
wxExpr *listExpr = new wxExpr(wxExprList);
listExpr->Append(pequals);
listExpr->Append(patt);
listExpr->Append(val);
Append(listExpr);
}
void wxExpr::AddAttributeValue(const wxString& attribute, long val)
{
if (type != wxExprList)
{
// cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
return;
}
// Warning - existing code may assume that any existing value
// is deleted first. For efficiency, we leave this to the application.
// DeleteAttributeValue(attribute);
wxExpr *patt = new wxExpr(wxExprWord, attribute);
wxExpr *pval = new wxExpr(val);
wxExpr *pequals = new wxExpr(wxExprWord, wxT("="));
wxExpr *listExpr = new wxExpr(wxExprList);
listExpr->Append(pequals);
listExpr->Append(patt);
listExpr->Append(pval);
Append(listExpr);
}
void wxExpr::AddAttributeValue(const wxString& attribute, double val)
{
if (type != wxExprList)
{
// cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
return;
}
// DeleteAttributeValue(attribute);
wxExpr *patt = new wxExpr(wxExprWord, attribute);
wxExpr *pval = new wxExpr(val);
wxExpr *pequals = new wxExpr(wxExprWord, wxT("="));
wxExpr *listExpr = new wxExpr(wxExprList);
listExpr->Append(pequals);
listExpr->Append(patt);
listExpr->Append(pval);
Append(listExpr);
}
void wxExpr::AddAttributeValueString(const wxString& attribute, const wxString& val)
{
if (type != wxExprList)
{
// cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
return;
}
// DeleteAttributeValue(attribute);
wxExpr *patt = new wxExpr(wxExprWord, attribute);
wxExpr *pval = new wxExpr(wxExprString, val);
wxExpr *pequals = new wxExpr(wxExprWord, wxT("="));
wxExpr *listExpr = new wxExpr(wxExprList);
listExpr->Append(pequals);
listExpr->Append(patt);
listExpr->Append(pval);
Append(listExpr);
}
void wxExpr::AddAttributeValueWord(const wxString& attribute, const wxString& val)
{
if (type != wxExprList)
{
// cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
return;
}
// DeleteAttributeValue(attribute);
wxExpr *patt = new wxExpr(wxExprWord, attribute);
wxExpr *pval = new wxExpr(wxExprWord, val);
wxExpr *pequals = new wxExpr(wxExprWord, wxT("="));
wxExpr *listExpr = new wxExpr(wxExprList);
listExpr->Append(pequals);
listExpr->Append(patt);
listExpr->Append(pval);
Append(listExpr);
}
void wxExpr::AddAttributeValue(const wxString& attribute, wxList *val)
{
if (type != wxExprList)
{
// cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
return;
}
if (!val)
return;
// DeleteAttributeValue(attribute);
wxExpr *patt = new wxExpr(wxExprWord, attribute);
wxExpr *pval = new wxExpr(val);
wxExpr *pequals = new wxExpr(wxExprWord, wxT("="));
wxExpr *listExpr = new wxExpr(wxExprList);
listExpr->Append(pequals);
listExpr->Append(patt);
listExpr->Append(pval);
Append(listExpr);
}
void wxExpr::AddAttributeValueStringList(const wxString& attribute, wxList *string_list)
{
if (type != wxExprList)
{
// cout << "Error! tried to add an attribute-value pair to a nonlist wxExpr expression\n";
return;
}
if (!string_list)
return;
// DeleteAttributeValue(attribute);
// First make a list of wxExpr strings
wxExpr *listExpr = new wxExpr(wxExprList);
wxNode *node = string_list->First();
while (node)
{
char *string = (char *)node->Data();
wxExpr *expr = new wxExpr(wxExprString, wxString(string));
listExpr->Append(expr);
node = node->Next();
}
// Now make an (=, Att, Value) triple
wxExpr *patt = new wxExpr(wxExprWord, attribute);
wxExpr *pequals = new wxExpr(wxExprWord, wxT("="));
wxExpr *listExpr2 = new wxExpr(wxExprList);
listExpr2->Append(pequals);
listExpr2->Append(patt);
listExpr2->Append(listExpr);
Append(listExpr2);
}
bool wxExpr::GetAttributeValue(const wxString& att, int& var) const
{
wxExpr *expr = AttributeValue(att);
if (expr && (expr->Type() == wxExprInteger || expr->Type() == wxExprReal))
{
var = (int)(expr->IntegerValue());
return TRUE;
}
else
return FALSE;
}
bool wxExpr::GetAttributeValue(const wxString& att, long& var) const
{
wxExpr *expr = AttributeValue(att);
if (expr && (expr->Type() == wxExprInteger || expr->Type() == wxExprReal))
{
var = expr->IntegerValue();
return TRUE;
}
else
return FALSE;
}
bool wxExpr::GetAttributeValue(const wxString& att, float& var) const
{
wxExpr *expr = AttributeValue(att);
if (expr && (expr->Type() == wxExprInteger || expr->Type() == wxExprReal))
{
var = (float) expr->RealValue();
return TRUE;
}
else
return FALSE;
}
bool wxExpr::GetAttributeValue(const wxString& att, double& var) const
{
wxExpr *expr = AttributeValue(att);
if (expr && (expr->Type() == wxExprInteger || expr->Type() == wxExprReal))
{
var = expr->RealValue();
return TRUE;
}
else
return FALSE;
}
bool wxExpr::GetAttributeValue(const wxString& att, wxString& var) const // Word OR string -> string
{
wxExpr *expr = AttributeValue(att);
if (expr && expr->Type() == wxExprWord)
{
var = expr->WordValue();
return TRUE;
}
else if (expr && expr->Type() == wxExprString)
{
var = expr->StringValue();
return TRUE;
}
else
return FALSE;
}
bool wxExpr::GetAttributeValue(const wxString& att, wxExpr **var) const
{
wxExpr *expr = AttributeValue(att);
if (expr)
{
*var = expr;
return TRUE;
}
else
return FALSE;
}
bool wxExpr::GetAttributeValueStringList(const wxString& att, wxList *var) const
{
wxExpr *expr = AttributeValue(att);
if (expr && expr->Type() == wxExprList)
{
wxExpr *string_expr = expr->value.first;
while (string_expr)
{
if (string_expr->Type() == wxExprString)
var->Append((wxObject *)copystring(string_expr->StringValue()));
string_expr = string_expr->next;
}
return TRUE;
}
else
return FALSE;
}
// Compatibility
void wxExpr::AssignAttributeValue(wxChar *att, wxChar **var) const
{
wxString str;
if (GetAttributeValue(att, str))
{
if (*var)
delete[] *var;
*var = copystring((const wxChar *) str);
}
}
void wxExpr::WriteClause(FILE* stream) // Write this expression as a top-level clause
{
if (type != wxExprList)
return;
wxExpr *node = value.first;
if (node)
{
node->WriteExpr(stream);
fprintf( stream, "(" );
node = node->next;
bool first = TRUE;
while (node)
{
if (!first)
fprintf( stream, " " );
node->WriteExpr(stream);
node = node->next;
if (node)
fprintf( stream, ",\n" );
first = FALSE;
}
fprintf( stream, ").\n\n" );
}
}
void wxExpr::WriteExpr(FILE* stream) // Write as any other subexpression
{
// This seems to get round an optimizer bug when
// using Watcom C++ 10a in WIN32 compilation mode.
// If these lines not present, the type seems to be
// interpreted wrongly as an integer.
// I don't want to turn optimization off since it's needed
// for reading in files quickly.
#if defined(__WATCOMC__)
char buf[2];
sprintf(buf, "");
#endif
switch (type)
{
case wxExprInteger:
{
fprintf( stream, "%ld", value.integer );
break;
}
case wxExprReal:
{
double f = value.real;
fprintf( stream, "%.6g", f);
break;
}
case wxExprString:
{
fprintf( stream, "\"" );
size_t i;
const wxWX2MBbuf val = wxConvLibc.cWX2MB(value.string);
size_t len = strlen(val);
for (i = 0; i < len; i++)
{
char ch = val[i];
if (ch == '"' || ch == '\\')
fprintf( stream, "\\" );
char tmp[2];
tmp[0] = ch;
tmp[1] = 0;
fprintf( stream, tmp );
}
fprintf( stream, "\"" );
break;
}
case wxExprWord:
{
bool quote_it = FALSE;
const wxWX2MBbuf val = wxConvLibc.cWX2MB(value.word);
size_t len = strlen(val);
if ((len == 0) || (len > 0 && (val[(size_t) 0] > 64 && val[(size_t) 0] < 91)))
quote_it = TRUE;
else
{
size_t i;
for (i = 0; i < len; i++)
if ((!isalpha(val[i])) && (!isdigit(val[i])) &&
(val[i] != '_'))
{ quote_it = TRUE; i = len; }
}
if (quote_it)
fprintf( stream ,"'" );
fprintf( stream, val );
if (quote_it)
fprintf( stream, "'" );
break;
}
case wxExprList:
{
if (!value.first)
fprintf( stream, "[]" );
else
{
wxExpr *expr = value.first;
if ((expr->Type() == wxExprWord) && (wxStrcmp(expr->WordValue(), wxT("=")) == 0))
{
wxExpr *arg1 = expr->next;
wxExpr *arg2 = arg1->next;
arg1->WriteExpr(stream);
fprintf( stream, " = " );
arg2->WriteExpr(stream);
}
else
{
fprintf( stream, "[" );
while (expr)
{
expr->WriteExpr(stream);
expr = expr->next;
if (expr)
fprintf( stream, ", " );
}
fprintf( stream, "]" );
}
}
break;
}
case wxExprNull: break;
}
}
/*
* wxExpr 'database' (list of expressions)
*/
IMPLEMENT_DYNAMIC_CLASS(wxExprDatabase, wxList)
wxExprDatabase::wxExprDatabase(wxExprErrorHandler handler)
{
position = NULL;
hash_table = NULL;
currentwxExprErrorHandler = handler;
noErrors = 0;
}
wxExprDatabase::wxExprDatabase(wxExprType type, const wxString& attribute, int size,
wxExprErrorHandler handler)
{
position = NULL;
attribute_to_hash = attribute;
if (type == wxExprString)
hash_table = new wxHashTable(wxKEY_STRING, size);
else if (type == wxExprInteger)
hash_table = new wxHashTable(wxKEY_INTEGER, size);
else hash_table = NULL;
currentwxExprErrorHandler = handler;
noErrors = 0;
}
wxExprDatabase::~wxExprDatabase(void)
{
ClearDatabase();
if (hash_table)
delete hash_table;
}
void wxExprDatabase::BeginFind(void) // Initialise a search
{
position = First();
}
wxExpr *wxExprDatabase::FindClause(long id) // Find a term based on an integer id attribute
// e.g. node(id=23, type=rectangle, ....).
{
wxExpr *found = NULL;
while (position && !found)
{
wxExpr *term = (wxExpr *)position->Data();
if (term->Type() == wxExprList)
{
wxExpr *value = term->AttributeValue("id");
if (value->Type() == wxExprInteger && value->IntegerValue() == id)
found = term;
}
position = position->Next();
}
return found;
}
// Find on basis of attribute/value pairs, e.g. type=rectangle
wxExpr *wxExprDatabase::FindClause(const wxString& word, const wxString& val)
{
wxExpr *found = NULL;
while (position && !found)
{
wxExpr *term = (wxExpr *)position->Data();
if (term->Type() == wxExprList)
{
wxExpr *value = term->AttributeValue(word);
if ((value->Type() == wxExprWord && value->WordValue() == val) ||
(value->Type() == wxExprString && value->StringValue() == val))
found = term;
}
position = position->Next();
}
return found;
}
wxExpr *wxExprDatabase::FindClause(const wxString& word, long val)
{
wxExpr *found = NULL;
while (position && !found)
{
wxExpr *term = (wxExpr *)position->Data();
if (term->Type() == wxExprList)
{
wxExpr *value = term->AttributeValue(word);
if ((value->Type() == wxExprInteger) && (value->IntegerValue() == val))
found = term;
}
position = position->Next();
}
return found;
}
wxExpr *wxExprDatabase::FindClause(const wxString& word, double val)
{
wxExpr *found = NULL;
while (position && !found)
{
wxExpr *term = (wxExpr *)position->Data();
if (term->Type() == wxExprList)
{
wxExpr *value = term->AttributeValue(word);
if ((value->Type() == wxExprReal) && (value->RealValue() == val))
found = term;
}
position = position->Next();
}
return found;
}
wxExpr *wxExprDatabase::FindClauseByFunctor(const wxString& functor)
{
wxExpr *found = NULL;
while (position && !found)
{
wxExpr *term = (wxExpr *)position->Data();
if (term->Type() == wxExprList)
{
if (term->Functor() == functor)
found = term;
}
position = position->Next();
}
return found;
}
// If hashing is on, must store in hash table too
void wxExprDatabase::Append(wxExpr *clause)
{
wxList::Append((wxObject *)clause);
if (hash_table)
{
wxString functor(clause->Functor());
wxExpr *expr = clause->AttributeValue(attribute_to_hash);
if (expr)
{
long functor_key = hash_table->MakeKey(WXSTRINGCAST functor);
long value_key = 0;
if (expr && expr->Type() == wxExprString)
{
value_key = hash_table->MakeKey(WXSTRINGCAST expr->StringValue());
hash_table->Put(functor_key + value_key, WXSTRINGCAST expr->StringValue(), (wxObject *)clause);
}
else if (expr && expr->Type() == wxExprInteger)
{
value_key = expr->IntegerValue();
hash_table->Put(functor_key + value_key, expr->IntegerValue(), (wxObject *)clause);
}
}
}
}
wxExpr *wxExprDatabase::HashFind(const wxString& functor, long value) const
{
long key = hash_table->MakeKey(WXSTRINGCAST functor) + value;
// The key alone isn't guaranteed to be unique:
// must supply value too. Let's assume the value of the
// id is going to be reasonably unique.
return (wxExpr *)hash_table->Get(key, value);
}
wxExpr *wxExprDatabase::HashFind(const wxString& functor, const wxString& value) const
{
long key = hash_table->MakeKey(WXSTRINGCAST functor) + hash_table->MakeKey(WXSTRINGCAST value);
return (wxExpr *)hash_table->Get(key, WXSTRINGCAST value);
}
void wxExprDatabase::ClearDatabase(void)
{
noErrors = 0;
wxNode *node = First();
while (node)
{
wxExpr *expr = (wxExpr *)node->Data();
delete expr;
delete node;
node = First();
}
if (hash_table)
hash_table->Clear();
}
bool wxExprDatabase::Read(const wxString& filename)
{
noErrors = 0;
FILE *f = wxFopen(filename, _T("r"));
if (f)
{
thewxExprDatabase = this;
LexFromFile(f);
yyparse();
fclose(f);
wxExprCleanUp();
return (noErrors == 0);
}
else
{
return FALSE;
}
}
bool wxExprDatabase::ReadFromString(const wxString& buffer)
{
noErrors = 0;
thewxExprDatabase = this;
const wxWX2MBbuf buf = buffer.mb_str();
LexFromString(wxMBSTRINGCAST buf);
yyparse();
wxExprCleanUp();
return (noErrors == 0);
}
bool wxExprDatabase::Write(const wxString& fileName)
{
FILE *stream = wxFopen( fileName, _T("w+"));
if (!stream)
return FALSE;
bool success = Write(stream);
fclose(stream);
return success;
}
bool wxExprDatabase::Write(FILE *stream)
{
noErrors = 0;
wxNode *node = First();
while (node)
{
wxExpr *expr = (wxExpr *)node->Data();
expr->WriteClause(stream);
node = node->Next();
}
return (noErrors == 0);
}
void add_expr(wxExpr * expr)
{
thewxExprDatabase->Append(expr);
}
// Checks functor
bool wxExprIsFunctor(wxExpr *expr, const wxString& functor)
{
if (expr && (expr->Type() == wxExprList))
{
wxExpr *first_expr = expr->value.first;
if (first_expr && (first_expr->Type() == wxExprWord) &&
(first_expr->WordValue() == functor))
return TRUE;
else
return FALSE;
}
else
return FALSE;
}
/*
* Called from parser
*
*/
char *wxmake_integer(char *str)
{
wxExpr *x = new wxExpr(atol(str));
return (char *)x;
}
char *wxmake_real(char *str1, char *str2)
{
char buf[50];
sprintf(buf, "%s.%s", str1, str2);
double f = (double)atof(buf);
wxExpr *x = new wxExpr(f);
return (char *)x;
}
// extern "C" double exp10(double);
char *wxmake_exp(char *str1, char *str2)
{
double mantissa = (double)atoi(str1);
double exponent = (double)atoi(str2);
double d = mantissa * pow(10.0, exponent);
wxExpr *x = new wxExpr(d);
return (char *)x;
}
char *wxmake_exp2(char *str1, char *str2, char *str3)
{
char buf[50];
sprintf(buf, "%s.%s", str1, str2);
double mantissa = (double)atof(buf);
double exponent = (double)atoi(str3);
double d = mantissa * pow(10.0, exponent);
wxExpr *x = new wxExpr(d);
return (char *)x;
}
char *wxmake_word(char *str)
{
wxExpr *x = new wxExpr(wxExprWord, str);
return (char *)x;
}
char *wxmake_string(char *str)
{
wxChar *s, *t;
size_t len, i;
const wxMB2WXbuf sbuf = wxConvLibc.cMB2WX(str);
// str++; /* skip leading quote */
len = wxStrlen(sbuf) - 1; /* ignore trailing quote */
s = new wxChar[len + 1];
t = s;
for(i=1; i<len; i++) // 1 since we want to skip leading quote
{
if (sbuf[i] == wxT('\\') && sbuf[i+1] == wxT('"'))
{
*t++ = wxT('"');
i ++;
}
else if (sbuf[i] == wxT('\\') && sbuf[i+1] == wxT('\\'))
{
*t++ = wxT('\\');
i ++;
}
else
*t++ = sbuf[i];
}
*t = wxT('\0');
wxExpr *x = new wxExpr(wxExprString, s, FALSE);
return (char *)x;
}
char *proio_cons(char * ccar, char * ccdr)
{
wxExpr *car = (wxExpr *)ccar;
wxExpr *cdr = (wxExpr *)ccdr;
if (cdr == NULL)
{
cdr = new wxExpr(wxExprList);
}
if (car)
cdr->Insert(car);
return (char *)cdr;
}
void process_command(char * cexpr)
{
wxExpr *expr = (wxExpr *)cexpr;
add_expr(expr);
}
void syntax_error(char *WXUNUSED(s))
{
if (currentwxExprErrorHandler)
(void)(*(currentwxExprErrorHandler))(WXEXPR_ERROR_SYNTAX, (char *)"syntax error");
if (thewxExprDatabase) thewxExprDatabase->noErrors += 1;
}
#if 0
#ifdef _WINDLL
// char *__cdecl strdup(const char *s)
WXDLLEXPORT char *strdup(const char *s)
{
int len = strlen(s);
char *new_s = (char *)malloc(sizeof(char)*(len+1));
strcpy(new_s, s);
return new_s;
}
#endif
#endif
#endif
// wxUSE_PROLOGIO