From 4875a3dd9b183dcd2256e2abfc4ccf7484c233b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Wed, 7 Dec 2022 13:17:14 +0100 Subject: New upstream version 4.0.2 --- xbase64/xbexp.cpp | 1323 ----------------------------------------------------- 1 file changed, 1323 deletions(-) delete mode 100755 xbase64/xbexp.cpp (limited to 'xbase64/xbexp.cpp') diff --git a/xbase64/xbexp.cpp b/xbase64/xbexp.cpp deleted file mode 100755 index a3e1fa5..0000000 --- a/xbase64/xbexp.cpp +++ /dev/null @@ -1,1323 +0,0 @@ -/* xbexp.cpp - - Xbase64 project source code - - This file contains logic for handling Xbase expressions. - - Copyright (C) 1997,2003,2004 Gary A Kunkel - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - - Contact: - - Email: - - xdb-devel@lists.sourceforge.net - xdb-users@lists.sourceforge.net - - - Regular Mail: - - XBase Support - 149C South Main St - Keller Texas, 76248 - USA - -*/ - -#ifdef __GNU LesserG__ - #pragma implementation "xbexp.h" -#endif - -#ifdef __WIN32__ -#include -#else -#include -#endif - -#include -#ifdef XB_EXPRESSIONS -#include -#include - -//#include - - -/*! \file xbexp.cpp -*/ - -// set the default date format -//xbString xbExpn::DefaultDateFormat = "MM/DD/YY"; - -/************************************************************************/ -/* putting this part in EXP did not work */ - -/* No of parms - - value meaning - - 0 0 - 1 1 - 2 2 - 100 0 or more - 101 1 or more - 102 2 or more - - - Return Type - N Numeric - C Char or string - 1 Varies, if sibling 1 is C, set to C, otherwise N - - -*/ - - - - - - -static xbFuncDtl FuncList[] = -{ - /* Func # of Return - Name parms Type */ - { "ABS", 1, 'N' }, - { "ASC", 1, 'N' }, - { "AT", 2, 'N' }, - { "CDOW", 1, 'C' }, - { "CHR", 1, 'C' }, - { "CMONTH", 1, 'C' }, - { "CTOD", 1, 'C' }, - { "DATE", 0, 'C' }, - { "DAY", 1, 'N' }, - { "DESCEND", 1, '1' }, - { "DOW", 1, 'N' }, - { "DTOC", 1, 'C' }, - { "DTOS", 1, 'C' }, - { "EXP", 1, 'N' }, - { "IIF", 3, 'C' }, - { "INT", 1, 'N' }, - { "ISALPHA", 1, 'L' }, - { "ISLOWER", 1, 'L' }, - { "ISUPPER", 1, 'L' }, - { "LEFT", 2, 'C' }, - { "LEN", 1, 'N' }, - { "LOG", 1, 'N' }, - { "LOWER", 1, 'C' }, - { "LTRIM", 1, 'C' }, - { "MAX", 2, 'N' }, - { "MIN", 2, 'N' }, - { "MONTH", 1, 'N' }, - { "RECNO", 0, 'N' }, - { "REPLICATE", 2, 'C' }, - { "RIGHT", 2, 'C' }, - { "RTRIM", 1, 'C' }, - { "SPACE", 1, 'C' }, - { "SQRT", 1, 'N' }, - { "STR", 101, 'C' }, - { "STRZERO", 1, 'C' }, - { "SUBSTR", 3, 'C' }, - { "TRIM", 1, 'C' }, - { "UPPER", 1, 'C' }, - { "VAL", 1, 'N' }, - { "YEAR", 1, 'N' }, - { 0, 0, 0 }, -}; - -/*************************************************************************/ -//! xbExpn Constructor -/*! -*/ -xbExpn::xbExpn( xbXBase * x ) -{ - xbase = x; - TokenType = 0; - Tree = 0; - TokenLen = 0; - OpLen1 = 0; - OpLen2 = 0; - OpDataLen1 = 0; - OpDataLen2 = 0; - Op1 = 0; - Op2 = 0; - First = 0; - Last = 0; - StackDepth = 0; - XbaseFuncList = FuncList; - memset( WorkBuf, 0x00, WorkBufMaxLen+1 ); -} -/*************************************************************************/ -//! xbExpn Destructor -/*! -*/ -xbExpn::~xbExpn() -{ - InitStack(); - - delete Tree; - - if(Op1) - free(Op1); - - if(Op2) - free(Op2); - -} - -/*************************************************************************/ -//! Get information on a function. -/*! - Returns the information specifed (Option) for the specified function. - - \param Function name of function to get information about - \param Option One of the following: - \htmlonly -

- - - - -
OptionDescription
1Return minimum number of parms
2Return function result type
?Return 0 if valid function
- \endhtmlonly - \latexonly - \\ - \\ - \begin{tabular}{|l|l|} \hline - \textbf{Option} & \textbf{Description} \\ \hline \hline - 1 & Return minimum number of parms \\ \hline - 2 & Return function result type \\ \hline - ? & Return 0 if valid function \\ \hline - \end{tabular} - \endlatexonly - - \returns requested information or -1 on failure. -*/ -xbShort xbExpn::GetFuncInfo( const char * Function, xbShort Option ) -{ -/* Option = - 1 - return minimum number of needed parms - 2 - return function result type - ? - return 0 if valid function -*/ - xbFuncDtl * f; - xbShort i, len; - const char *s; - - if(( Option<1 )||( Option>2 )) - return XB_INVALID_OPTION; - - s = Function; - len = 0; - while( *s && *s != '(' ) { s++; len++; } - - f = XbaseFuncList; - i = 0; - while( f[i].FuncName ){ - if( strncmp( f[i].FuncName, Function, len ) == 0 ) - return( (Option==1) ? f[i].ParmCnt : f[i].ReturnType ); - i++; - } - return -1; -} - -/*************************************************************************/ -//! IsWhiteSpace -/*! -*/ -xbShort xbExpn::IsWhiteSpace( char c ) -{ - return(( c == 0x20 )? 1 : 0 ); -} - -/*************************************************************************/ -//! GetNextToken -/*! -*/ -xbShort xbExpn::GetNextToken( const char * s, xbShort MaxLen ) -{ - /* TreeResultType Settings - Token Action/ - Was Type Result - Unv N N - Unv C C - Unv Function Table Lookup - Unv Field Field Type - Not L Any Logical L - */ - - xbShort Wctr, Wtype, Wsw, EmptyCtr, MaxCtr, MaxCtrSave; - const char *sp, *np, *pp; /* save, next and previous pointer */ - - LogicalType = 0; - TokenType = 0; - TokenLen = 0; - EmptyCtr = 0; - MaxCtr = 0; - - if( !s || ! *s ) - return XB_NO_DATA; - - /* go past any initial white space */ - while( s && *s && IsWhiteSpace( *s )){ - s++; - MaxCtr++; - if (MaxCtr >= MaxLen) - return XB_NO_ERROR; - } - -/* 1 - check for parens */ -/* '(', if found go to corresponding ')', if no ')', return -1 */ - if( *s == '(' || *s == '{' ){ - if( *s == '{' ) Wtype = 0; else Wtype = 1; - Wctr = 1; - s++; - - MaxCtr++; - if( MaxCtr >= MaxLen ) - return XB_PARSE_ERROR; - - while( s && *s ){ - if(( *s == ')' && Wtype == 1 ) || (*s == '}' && Wtype == 0 )){ - Wctr--; - if( Wctr == 0 ){ - if( EmptyCtr != 0 ) { - TokenType = 'E'; - PreviousType = 'E'; - } else - return XB_PARSE_ERROR; - - TokenLen += 2; - return XB_NO_ERROR; - } - } - else if(( *s == '(' && Wtype == 1 ) || (*s == '{' && Wtype == 0 )){ - Wctr++; - EmptyCtr++; - } else if( *s != ' ' ) - EmptyCtr++; - - s++; - TokenLen++; - MaxCtr++; - if( MaxCtr >= MaxLen ) - return XB_PARSE_ERROR; - } - return XB_PARSE_ERROR; - } - - -/* 2 - Check for Constants */ -/* check for "'" or """, if no corresponding quote return -1 */ - if( *s == '"' || *s == '\'' ){ - if( *s == '"' ) Wtype = 0; else Wtype = 1; - TokenType = 'C'; /* set to constant */ - PreviousType = 'C'; - s++; - MaxCtr++; - if( MaxCtr >= MaxLen ) - return XB_NO_ERROR; - while( s && *s ){ - if(( *s == '"' && Wtype == 0 ) || (*s == '\'' && Wtype == 1 )) - return XB_NO_ERROR; - s++; - TokenLen++; - MaxCtr++; - if( MaxCtr >= MaxLen ) - return XB_NO_ERROR; - } - return XB_PARSE_ERROR; - } - - -/* 3 - check for .T. .F. .TRUE. or .FALSE. */ - if( s && *s && *s == '.' ){ - if(( strncmp( s, ".T.", 3 ) == 0 ) || ( strncmp( s, ".F.", 3 ) == 0 )){ - TokenLen = 3; - TokenType = 'C'; /* constant */ - PreviousType = 'C'; - LogicalType = 1; - return XB_NO_ERROR; - } else if( strncmp( s, ".TRUE.", 6 ) == 0 ){ - TokenLen = 6; - TokenType = 'C'; /* constant */ - PreviousType = 'C'; - LogicalType = 1; - return XB_NO_ERROR; - } else if( strncmp( s, ".FALSE.", 7 ) == 0 ){ - TokenLen = 7; - TokenType = 'C'; /* constant */ - PreviousType = 'C'; - LogicalType = 1; - return XB_NO_ERROR; - } - } - -/* 4 - check for positive, negative or decimal number constants */ - if(( *s == '-' && ( PreviousType == 'O' || PreviousType == 0 )) || - ( *s == '+' && ( PreviousType == 'O' || PreviousType == 0 )) || - *s == '.' || isdigit( *s )){ - sp = s; - MaxCtrSave = MaxCtr; - Wsw = Wctr = 0; - if( *s == '.' ){ - Wctr++; - s++; - MaxCtr++; - if( MaxCtr >= MaxLen ) - return XB_PARSE_ERROR; - - if( s && *s && isdigit( *s )) - TokenLen++; - else - Wsw++; - } else if( *s == '-' ){ - s++; - TokenLen++; - MaxCtr++; - if( MaxCtr >= MaxLen ) - return XB_PARSE_ERROR; - - /* go past any white space between sign and number */ - while( s && *s && IsWhiteSpace( *s )){ - s++; - TokenLen++; - MaxCtr++; - if( MaxCtr >= MaxLen ) - return XB_PARSE_ERROR; - } - } - - if( isdigit( *s ) || (*s == '.' && !Wsw )){ - while(s && *s && ((*s == '.' && Wctr < 2 ) || isdigit(*s)) && !Wsw ){ - if( *s == '.' ) { - Wctr++; - if( Wctr > 1 ) break; - s++; - - MaxCtr++; - if( MaxCtr >= MaxLen ){ - TokenType = 'N'; - PreviousType = 'N'; - return XB_NO_ERROR; - } - - if( s && *s && isdigit( *s )) - TokenLen++; - else - Wsw++; - } else { - s++; - TokenLen++; - MaxCtr++; - if( MaxCtr >= MaxLen ) { - TokenType = 'N'; - PreviousType = 'N'; - return XB_NO_ERROR; - } - } - } - TokenType = 'N'; /* constant */ - PreviousType = 'N'; - return XB_NO_ERROR; - } else { - s = sp; - MaxCtr = MaxCtrSave; - } - } - -/* 5 - Check for operators */ - if( *s == '+' || *s == '-' || *s == '/' || *s == '^'){ - TokenLen = 1; - TokenType = 'O'; - PreviousType = 'O'; - return XB_NO_ERROR; - } - if(*s == '=' || *s == '$' || *s == '#' ){ - LogicalType = 1; - TokenLen = 1; - TokenType = 'O'; - PreviousType = 'O'; - return XB_NO_ERROR; - } - if( strncmp( s, "!=", 2 ) == 0 ){ - LogicalType = 1; - TokenLen = 2; - TokenType = 'O'; - PreviousType = 'O'; - return XB_NO_ERROR; - } - if( *s == '*' ){ - s++; - MaxCtr++; - if( MaxCtr >= MaxLen ) - return XB_PARSE_ERROR; - - TokenType = 'O'; - PreviousType = 'O'; - if( *s == '*' ){ - TokenLen = 2; - return XB_NO_ERROR; - } else { - TokenLen = 1; - return XB_NO_ERROR; - } - } - if( *s == '<' || *s == '>' ) { - s++; - - MaxCtr++; - if( MaxCtr >= MaxLen ) - return XB_PARSE_ERROR; - - LogicalType = 1; // added 3/25/00 dtb - TokenType = 'O'; - PreviousType = 'O'; - if( *s == '<' || *s == '>' || *s == '=' ){ - TokenLen = 2; - return XB_NO_ERROR; - } else { - TokenLen = 1; - return XB_NO_ERROR; - } - } - -/* check for .NOT. .OR. .AND. */ - - if( s && *s && *s == '.' ){ - if( strncmp( s, ".NOT.", 5 ) == 0 ){ - TokenLen = 5; - TokenType = 'O'; /* constant */ - PreviousType = 'O'; - LogicalType = 1; - return XB_NO_ERROR; - } else if( strncmp( s, ".AND.", 5 ) == 0 ){ - TokenLen = 5; - TokenType = 'O'; /* constant */ - PreviousType = 'O'; - LogicalType = 1; - return XB_NO_ERROR; - } else if( strncmp( s, ".OR.", 4 ) == 0 ){ - TokenLen = 4; - TokenType = 'O'; /* constant */ - PreviousType = 'O'; - LogicalType = 1; - return XB_NO_ERROR; - } - } - - /* If get this far, must be function or database field */ - while( s && *s ){ - s++; - TokenLen++; - MaxCtr++; - if( MaxCtr >= MaxLen ) { - TokenType = 'D'; - PreviousType = 'D'; - return XB_NO_ERROR; - } - - if( s && *s && *s == '(' ) { - /* look for corresponding ) */ - Wctr = 1; - s++; - TokenLen++; - MaxCtr++; - if( MaxCtr >= MaxLen ) - return XB_PARSE_ERROR; - - while( s && *s ) { - if( *s == ')' ) { - Wctr--; - if( !Wctr ) { - TokenType = 'F'; /* function */ - PreviousType = 'F'; - TokenLen++; - return XB_NO_ERROR; - } - } - if( *s == '(' ) Wctr++; - s++; - TokenLen++; - MaxCtr++; - if( MaxCtr >= MaxLen ) - return XB_PARSE_ERROR; - } - return XB_PARSE_ERROR; - } else { - np = s + 1; - pp = s - 1; - if( !s || !*s || (IsSeparator( *s ) && - !(*s == '-' && *np == '>' ) && !(*s == '>' && *pp == '-' ))) { - if( TokenLen > 0 ){ - TokenType = 'D'; /* database field */ - PreviousType = 'D'; - return XB_NO_ERROR; - } - } - } - } - return XB_NO_ERROR; -} -/*************************************************************************/ -//! IsSeparator -/*! -*/ -char xbExpn::IsSeparator( char c ) -{ - if( c == '-' || c == '+' || c == '*' || c == '/' || c == '$' || - c == ' ' || c == '#' || c == '<' || c == '>' || c == '^' || - c == '=' || c == '.' || c == '!' /* || c == ')' */ ) - return c; - else - return 0; -} - -/*************************************************************************/ -//! GetExpNode -/*! -*/ -/* -xbExpNode * xbExpn::GetExpNode(xbShort Len) { - xbExpNode * Temp; - - Temp = new xbExpNode; - if( Temp && Len > 0 ) - Temp->ResultLen = Len; - return Temp; -} -*/ -/*************************************************************************/ -//! LoadExpNode -/*! -*/ -xbExpNode * xbExpn::LoadExpNode( - const char *ENodeText, /* pointer to text data */ - const char EType, /* Operand type */ - const xbShort ELen, /* length of node text data */ - const xbShort BufLen ) /* length needed in the buffer*/ -{ -// xbExpNode * CurNode; -// if(( CurNode = GetExpNode(BufLen)) == NULL ) return NULL; - - xbExpNode * CurNode = new xbExpNode; - if( !CurNode ) - return NULL; - CurNode->ResultLen = BufLen; - - CurNode->NodeText = strdup( ENodeText ); - CurNode->Type = EType; - CurNode->Len = ELen; - CurNode->InTree = 1; - CurNode->ResultLen = BufLen; - return CurNode; -} - -/*************************************************************************/ -//! BuildExpressionTree -/*! -*/ -xbShort xbExpn::BuildExpressionTree( const char * Expression, - xbShort MaxTokenLen, xbDbf * d ) -{ - /* previous node is the node to insert under */ - xbExpNode * CurNode = 0; - xbExpNode * PreviousNode; - xbShort rc, FieldNo=0, BufLen; - xbShort TokenLenCtr; - char c; - const char *p; - char TempField[11]; - char TableName[31]; - xbDbf * TempDbf=0; - int LocTokenLen; - - if( Tree ) { - delete Tree; - Tree = NULL; - } - - p = Expression; - PreviousNode = NULL; - PreviousType = TokenLenCtr = 0; - - while( IsWhiteSpace( *p )) { - p++; - TokenLenCtr++; - if(TokenLenCtr >= MaxTokenLen) - return XB_NO_ERROR; - } - - rc = GetNextToken( p, MaxTokenLen-TokenLenCtr ); - LocTokenLen = TokenLen; - if( rc != XB_NO_DATA && rc != XB_NO_ERROR ) - return rc; - - while( rc == 0 ){ - if( TokenType == 'D' && d ){ - if( TokenLen > 30 ) - strncpy( TableName, p, 30 ); - else - strncpy( TableName, p, TokenLen ); - - memset( TempField, 0x00, 11 ); - - if( strstr( p, "->" ) != NULL ) { - if(( TempDbf = d->xbase->GetDbfPtr( TableName )) == NULL ) - return XB_INVALID_FIELD; - xbShort tlen = 0; - while( TableName[tlen] != '-' && TableName[tlen+1] != '>' ) - tlen++; - tlen = TokenLen - tlen - 2; // length of field name - const char * fp = strstr( p, "->" ); - fp += 2; // ptr to beginning of field name - strncpy( TempField, fp, tlen ); - } else { - TempDbf = d; - if( TokenLen > 10 ) - return XB_INVALID_FIELD; - strncpy( TempField, p, TokenLen ); - } - if(( FieldNo = TempDbf->GetFieldNo( TempField )) == -1 ) - return XB_INVALID_FIELD; - BufLen = TempDbf->GetFieldLen( FieldNo ) + 1; - } - else if( TokenType == 'C' || TokenType == 'N' ) - BufLen = TokenLen + 1; - else - BufLen = 0; - - if( TokenType == 'C' ) p++; /* go past first ' */ - - if( TokenType != 'O' ){ - if( !Tree ) { /* create root node with this token */ - CurNode = LoadExpNode( p, TokenType, TokenLen, BufLen ); - Tree = CurNode; - } else { /* put as child 2 of previous node */ - CurNode = LoadExpNode( p, TokenType, TokenLen, BufLen ); - PreviousNode->Sibling2 = CurNode; - CurNode->Node = PreviousNode; - } - - if( TokenType == 'E' ){ - if((rc=ReduceComplexExpression(p,TokenLen,CurNode,d))!=0) - return rc; - if(PreviousNode) - CurNode = PreviousNode->Sibling2; - else - CurNode = Tree; - } else if( TokenType == 'F' ){ - if(( rc = ReduceFunction( p, CurNode, d)) != 0 ) - return rc; - - xbShort parmCnt = GetFuncInfo( p, 1 ); - if( (parmCnt == 1 || parmCnt == 101 ) && !CurNode->Sibling1 || - (parmCnt == 2 || parmCnt == 201 ) && !CurNode->Sibling2 || - (parmCnt == 3 ) && !CurNode->Sibling3 ) - return XB_INSUFFICIENT_PARMS; - else if( parmCnt == 0 && CurNode->Sibling1 ) - return XB_TOO_MANY_PARMS; - else if( parmCnt == 1 && CurNode->Sibling2 ) - return XB_TOO_MANY_PARMS; - else if( parmCnt == 2 && CurNode->Sibling3 ) - return XB_TOO_MANY_PARMS; - - CurNode->ExpressionType = GetFuncInfo( p, 2 ); - if( CurNode->ExpressionType == '1' ){ - if( CurNode->Sibling1 ) - if( CurNode->Sibling1->ExpressionType == 'C' ) - CurNode->ExpressionType = 'C'; - else - CurNode->ExpressionType = 'N'; - else - return XB_INSUFFICIENT_PARMS; - } - - CurNode->dbf = d; - } - else if( TokenType == 'D' && d ) { - CurNode->DataLen = BufLen - 1; - CurNode->FieldNo = FieldNo; - CurNode->dbf = TempDbf; - c = TempDbf->GetFieldType( FieldNo ); - if( c == 'C' || c == 'M' ) CurNode->ExpressionType = 'C'; - else if( c == 'L' ) CurNode->ExpressionType = 'L'; - else if( c == 'N' || c == 'F' ) CurNode->ExpressionType = 'N'; - else if( c == 'D' ) CurNode->ExpressionType = 'D'; - } else if( TokenType == 'C' || TokenType == 'N' ) { - CurNode->DataLen = CurNode->Len; - CurNode->StringResult = CurNode->NodeText; - CurNode->StringResult.resize( CurNode->DataLen+1 ); - if( TokenType == 'N' ) { - CurNode->DoubResult = strtod( CurNode->StringResult, 0 ); - CurNode->ExpressionType = 'N'; - } else - CurNode->ExpressionType = 'C'; - } - } - else /* it is an operator */ - { - if(!Tree){ - if(*p == '-'){ - CurNode = LoadExpNode( p, TokenType, TokenLen, 0 ); - CurNode->ExpressionType = 'C'; - } else - return XB_EXP_SYNTAX_ERROR; - } else { - if( Tree->Type != 'O' ){ - CurNode = LoadExpNode( p, TokenType, TokenLen, 0 ); - Tree->Node = CurNode; /* link the new parent to old tree */ - CurNode->Sibling1 = Tree; /* connect the sibling */ - Tree = CurNode; /* root in tree */ - } else { - PreviousNode = CurNode->Node; - CurNode = LoadExpNode( p, TokenType, TokenLen, 0 ); - while( PreviousNode && - (( OperatorWeight( PreviousNode->NodeText, TokenLen ) == 0 ) || - ( OperatorWeight( CurNode->NodeText, TokenLen ) <= - OperatorWeight( PreviousNode->NodeText, TokenLen )))) - PreviousNode = PreviousNode->Node; - - if( PreviousNode ) { - CurNode->Node = PreviousNode; - CurNode->Sibling1 = PreviousNode->Sibling2; - PreviousNode->Sibling2 = CurNode; - CurNode->Sibling1->Node = CurNode; - } else { /* insert at root */ - CurNode->Sibling1 = Tree; - Tree = CurNode; - CurNode->Sibling1->Node = CurNode; - } - } - if( LogicalType ) - CurNode->ExpressionType = 'L'; - } - } - PreviousNode = CurNode; -// p += CurNode->Len; // 2/20/04 - not sure when this was updated - gk - p += LocTokenLen; - -// if( TokenType == 'C' ) { gk - 2/20/04 func("fff") + 4 didn't work - if( TokenType == 'C' && CurNode->Type != 'F' ){ - p++; /* go past last ' */ - TokenLenCtr+=2; /* add the quotes */ - } - -// TokenLenCtr += CurNode->Len; // 2/20/04 - not sure when this was updated - gk - TokenLenCtr += LocTokenLen; - if( TokenLenCtr >= MaxTokenLen ) - return XB_NO_ERROR; - if( p && *p && TokenType == 'E' ) { - p++; - TokenLenCtr++; - } - - while( IsWhiteSpace( *p )) { - p++; - TokenLenCtr++; - if( TokenLenCtr >= MaxTokenLen ) - return XB_NO_ERROR; - } - rc = GetNextToken( p, MaxTokenLen-TokenLenCtr ); - LocTokenLen = TokenLen; - if( rc != XB_NO_DATA && rc != XB_NO_ERROR ) - return rc; - } - return XB_NO_ERROR; -} -/*************************************************************************/ -//! GetExpressionResultType -/*! -*/ -char xbExpn::GetExpressionResultType( xbExpNode * e ) { - xbExpNode * Temp = 0; - if( e ) - Temp = e; - else if( !Temp ) - Temp = Tree; - else - return 0; - - if( e->Type == 'O' && - ( *e->NodeText == '<' || *e->NodeText == '>' || *e->NodeText == '=' || - *e->NodeText == '#' || *e->NodeText == '$' || - strncmp( e->NodeText, "!=", 2 ) == 0 )) - return 'L'; - - /* go down to second lowest level */ - while( Temp && Temp->Sibling1 && Temp->Sibling1->Sibling1 ) - Temp = Temp->Sibling1; - - /* if subtracting dates, return numeric type */ - if( Temp->Type == 'O' && *Temp->NodeText == '-' && - Temp->Sibling1 && Temp->Sibling2 && - Temp->Sibling1->ExpressionType == 'D' && - Temp->Sibling2->ExpressionType == 'D' ) - return 'N'; - - /* else return the type of the lowest left node */ - while( Temp && !Temp->ExpressionType && Temp->Sibling1 ) - Temp = Temp->Sibling1; - return Temp->ExpressionType; -} -/*************************************************************************/ -//! GetExpressionHandle -/*! -*/ -xbExpNode * xbExpn::GetExpressionHandle() { - xbExpNode * e; - e = Tree; - Tree = NULL; - return e; -} -/*************************************************************************/ -//! OperatorWeight -/*! This function determines the priority of an operator -*/ -xbShort xbExpn::OperatorWeight( const char * Oper, xbShort len ) -{ - /* operator precendence - - not all are implemented yet, but the structure is here - - 10 .AND. .OR. .NOT. (not really an operator) - 9 > or < (includes <= or >=) - 6 unary plus or minus (+,-) - 5 prefix increment and/or decrement (++,--) - 4 exponentiation ** or ^ - 3 multiplication,division or modulus (*,/,%) - 2 Addition, subtraction (+,-) - 1 Postfix increment and/or decrement (++,--) - */ - - if( len < 1 || len > 5 ) return 0; - - - if( Oper[0] == '>' || Oper[0] == '<' ) - return 13; - - if( strncmp( Oper, ".AND.", 5 ) == 0 || - strncmp( Oper, ".OR.", 4 ) == 0 || - strncmp( Oper, ".NOT.", 5 )) - return 10; - - if( strncmp( Oper, "**", 2 ) == 0 || Oper[0] == '^' ) - return 4; - - if( Oper[0] == '*' || Oper[0] == '/' || Oper[0] == '%' ) - return 3; - - if( Oper[0] == '+' || Oper[0] == '-' ) - return 1; - - return 0; -} -/*************************************************************************/ -//! ReduceComplexExpression -/*! -*/ -xbShort xbExpn::ReduceComplexExpression(const char *NextToken, xbShort Len, - xbExpNode *cn, xbDbf *d) { - const char *p; - xbShort rc; - xbExpNode * SaveTree; - - SaveTree = Tree; - Tree = NULL; - - p = NextToken; - p++; - - if(( rc = BuildExpressionTree( p, Len-2, d )) != XB_NO_ERROR ) - return rc; - - if(cn->Node) { /* then this is the base tree */ - cn->Node->Sibling2 = Tree; - Tree->Node = cn->Node; - delete cn; - Tree = SaveTree; - } else - delete cn; - - return XB_NO_ERROR; -} -/*************************************************************************/ -//! GetFunctionTokenLen -/*! -*/ -xbShort xbExpn::GetFunctionTokenLen( const char * s ) -{ - xbShort cnt, LeftParenCtr; - const char *p; - - cnt = LeftParenCtr = 0; - p = s; - - while( p && ( *p != ',' || ( *p == ',' && LeftParenCtr > 0 )) && - !( LeftParenCtr == 0 && *p == ')')) { - if( *p == '(' ) - LeftParenCtr++; - else if( *p == ')' ) - LeftParenCtr--; - p++; - cnt++; - } - return cnt; -} -/*************************************************************************/ -//! ReduceFunction -/*! -*/ -xbShort xbExpn::ReduceFunction(const char *NextToken, xbExpNode *cn, xbDbf *d) -{ - const char *p; - xbShort rc; - xbShort FuncTokenLen; - xbExpNode * SaveTree; - - p = strchr( NextToken, '(' ); - if (!p) - return XB_PARSE_ERROR; - - p++; - while( IsWhiteSpace( *p )) p++; - if (*p == ')') - return XB_NO_ERROR; - - /* do function paramater 1 */ - FuncTokenLen = GetFunctionTokenLen( p ); - SaveTree = Tree; - Tree = NULL; - if(( rc = BuildExpressionTree( p, FuncTokenLen, d )) != XB_NO_ERROR ) - return rc; - cn->Sibling1 = Tree; - Tree->Node = cn; - Tree = SaveTree; - - /* do function paramater 2 */ - - p += FuncTokenLen; - while( IsWhiteSpace( *p )) p++; - if(*p == ')') - return XB_NO_ERROR; - if( *p != ',' ) - return XB_PARSE_ERROR; - - p++; - while( IsWhiteSpace( *p )) p++; - FuncTokenLen = GetFunctionTokenLen( p ); - SaveTree = Tree; - Tree = NULL; - if(( rc = BuildExpressionTree( p, FuncTokenLen, d )) != XB_NO_ERROR ) - return rc; - - cn->Sibling2 = Tree; - Tree->Node = cn; - Tree = SaveTree; - - /* do function paramater 3 */ - p += FuncTokenLen; - while( IsWhiteSpace( *p )) p++; - if (*p == ')') - return XB_NO_ERROR; - if( *p != ',' ) - return XB_PARSE_ERROR; - - p++; - while( IsWhiteSpace( *p )) p++; - FuncTokenLen = GetFunctionTokenLen( p ); - SaveTree = Tree; - Tree = NULL; - if(( rc = BuildExpressionTree( p, FuncTokenLen, d )) != XB_NO_ERROR ) - return rc; - - cn->Sibling3 = Tree; - Tree->Node = cn; - Tree = SaveTree; - - return XB_NO_ERROR; -} -/*************************************************************************/ -//! ParseExpression -/*! -*/ -xbShort xbExpn::ParseExpression(const char *exp, xbDbf *d) { - return BuildExpressionTree(exp, strlen(exp), d); -} -/*************************************************************************/ -//! ProcessExpression -/*! -*/ -xbShort xbExpn::ProcessExpression(const char *e, xbDbf *d) { - xbShort rc; - if(( rc = BuildExpressionTree( e, strlen( e ), d )) != XB_NO_ERROR ) - return rc; - if(( rc = ProcessExpression( Tree )) != XB_NO_ERROR ) - return rc; - return XB_NO_ERROR; -} -/*************************************************************************/ -#ifdef XBASE_DEBUG -//! DumpExpressionTree -/*! -*/ -void xbExpn::DumpExpressionTree( xbExpNode * E, xbShort printOption ) -{ - if( !E ) E = Tree; - if( !E ) return; - DumpExpNode( E, printOption ); - - if( E->Sibling1 ) DumpExpressionTree( E->Sibling1, printOption ); - if( E->Sibling2 ) DumpExpressionTree( E->Sibling2, printOption ); - if( E->Sibling3 ) DumpExpressionTree( E->Sibling3, printOption ); - return; -} -/*************************************************************************/ -//! DumpExpNode -/*! -*/ -void xbExpn::DumpExpNode(xbExpNode *e, xbShort printOption) -{ - xbString ntext; - - ntext = e->NodeText; - ntext.resize( e->Len + 1 ); - - if( printOption ){ - FILE * dmp; - if(( dmp = fopen( "xbase64.log", "a" )) == NULL ) - return; - - fprintf( dmp, "******* Exp Node *******\n" ); - fprintf( dmp, "Exp Node Address = %x\n", e ); - fprintf( dmp, "Node Text = %s\n", ntext.getData()); - fprintf( dmp, "Type = %c\n", e->Type ); - fprintf( dmp, "Len = %d\n", e->Len ); - fprintf( dmp, "InTree = %d\n", e->InTree ); - fprintf( dmp, "Field No = %d\n", e->FieldNo ); - fprintf( dmp, "ExpressionType = %c\n", e->ExpressionType ); - fprintf( dmp, "StringResult = %s\n", e->StringResult.getData()); - fprintf( dmp, "DoubResult = %d\n", e->DoubResult ); - fprintf( dmp, "IntResult = %d\n", e->IntResult ); - fprintf( dmp, "ResultLen = %d\n", e->ResultLen ); - fprintf( dmp, "DataLen = %x\n", e->DataLen ); - - if( e->Node ) - fprintf( dmp, "Parent = %x\n", e->Node ); - if( e->Sibling1 ) - fprintf( dmp, "Sibling 1 = %x\n", e->Sibling1 ); - if( e->Sibling2 ) - fprintf( dmp, "Sibling 2 = %x\n", e->Sibling2 ); - if( e->Sibling3 ) - fprintf( dmp, "Sibling 3 = %x\n", e->Sibling3 ); - fprintf( dmp, "\n" ); - fclose( dmp ); - } - else - { - std::cout << "****** Exp Node ******"; - std::cout << "Exp Node Address = " << e << std::endl; - std::cout << "Node Text = " << ntext << std::endl; - std::cout << "Type = " << e->Type << std::endl; - std::cout << "Len = " << e->Len << std::endl; - std::cout << "InTree = " << e->InTree << std::endl; - std::cout << "Field No = " << e->FieldNo << std::endl; - std::cout << "ExpressionType = " << e->ExpressionType << std::endl; - std::cout << "StringResult = " << e->StringResult << std::endl; - std::cout << "DoubResult = " << e->DoubResult << std::endl; - std::cout << "IntResult = " << e->IntResult << std::endl; - std::cout << "ResultLen = " << e->ResultLen << std::endl; - std::cout << "DataLen = " << e->DataLen << std::endl; - if( e->Node ) - std::cout << "Parent = " << e->Node << std::endl; - if( e->Sibling1 ) - std::cout << "Sibling 1 = " << e->Sibling1 << std::endl; - if( e->Sibling2 ) - std::cout << "Sibling 2 = " << e->Sibling2 << std::endl; - if( e->Sibling3 ) - std::cout << "Sibling3 = " << e->Sibling3 << std::endl; - } - return; -} -#endif - -/*************************************************************************/ -//! xbExpNode() -/*! -*/ -xbExpNode::xbExpNode() : - NodeText(0), - Type(0), - Len(0), - InTree(0), - Node(0), - Sibling1(0), - Sibling2(0), - Sibling3(0), - DataLen(0), - ResultLen(0), - DoubResult(0), - IntResult(0), - dbf(0), - FieldNo(-1), - ExpressionType(0) -{ -} -/*************************************************************************/ -//! ~xbExpNode() -/*! -*/ -xbExpNode::~xbExpNode() -{ - if(NodeText) - free(NodeText); - - if(Sibling1) - delete Sibling1; - - if(Sibling2) - delete Sibling2; - - if(Sibling3) - delete Sibling3; -} -/*************************************************************************/ -//! Constructor. -/*! -*/ -xbStackElement::xbStackElement() -{ - Next = 0; - Previous = 0; - NodePtr = 0; -} -/*************************************************************************/ -//! Destructor. -/*! -*/ -xbStackElement::~xbStackElement() -{ -} -/*************************************************************************/ - -//! Destructor. -/*! -*/ - -/*************************************************************************/ -//! Short description. -/*! -*/ -void xbExpn::InitStack() -{ - xbStackElement *next; - - while(First){ - next = First->Next; - - if( First->NodePtr->InTree == 0 ) - delete First->NodePtr; - - delete First; - First = next; - } - - Last = 0; - StackDepth = 0; - return; -} -/*************************************************************************/ -//! Push a value onto the stack. -/*! - \param p -*/ -xbShort xbExpn::Push( xbExpNode *p ) -{ - xbStackElement *Temp = new xbStackElement; - - if(!Temp) - return XB_NO_MEMORY; - - Temp->NodePtr = p; - - if( !First ){ - First = Temp; - Last = Temp; - StackDepth = 1; - } else { - Last->Next = Temp; - Temp->Previous = Last; - Last = Temp; - StackDepth++; - } - return XB_NO_ERROR; -} -/*************************************************************************/ -//! Pop the top value from the stack. -/*! -*/ -xbExpNode * xbExpn::Pop() -{ - xbExpNode *p; - xbStackElement *Save; - - if( StackDepth == 0 ) - return 0; - else { - p = Last->NodePtr; - if( StackDepth == 1 ){ - delete First; - First = 0; - Last = 0; - } else { /* number of items in Stack must be > 1 */ - Last->Previous->Next = 0; - Save = Last; - Last = Last->Previous; - delete Save; - } - StackDepth--; - return p; - } -} -/*************************************************************************/ -//! Short description. -/*! -*/ -#ifdef XBASE_DEBUG -void xbExpn::DumpStack() -{ - xbStackElement * e; - if( StackDepth == 0 ){ - std::cout << "\nStack is empty..."; - return; - } - - std::cout << "\nThere are " << StackDepth << " entries."; - std::cout << "\nFirst = " << First << " Last = " << Last; - - e = First; - while( e ){ - std::cout << "\n*****************************"; - std::cout << "\nThis = " << e; - std::cout << "\nNext = " << e->Next; - std::cout << "\nPrevious = " << e->Previous; - std::cout << "\nNode Ptr = " << e->NodePtr; - e = e->Next; - } - return; -} -#endif // XB_EXPRESSIONS -#endif -/*************************************************************************/ -- cgit v1.2.3