summaryrefslogtreecommitdiff
path: root/src/core/xbexp.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/xbexp.cpp')
-rwxr-xr-xsrc/core/xbexp.cpp102
1 files changed, 81 insertions, 21 deletions
diff --git a/src/core/xbexp.cpp b/src/core/xbexp.cpp
index deea53d..b2d4db9 100755
--- a/src/core/xbexp.cpp
+++ b/src/core/xbexp.cpp
@@ -2,7 +2,7 @@
XBase64 Software Library
-Copyright (c) 1997,2003,2014,2017,2021,2022 Gary A Kunkel
+Copyright (c) 1997,2003,2014,2017,2021,2022,2023 Gary A Kunkel
The xb64 software library is covered under
the terms of the GPL Version 3, 2007 license.
@@ -1097,12 +1097,12 @@ xbBool xbExp::IsOperator( const xbString & sExpression ){
}
/*************************************************************************/
-//! Is Token seperator
-/*! This method determines if the next token is a seperator.
+//! Is Token separator
+/*! This method determines if the next token is a separator.
\param sExpression - String expression to be evaluated.
- \returns xbTrue - Is a token seperator.<br>
- xbFalse - Is not a token seperator.
+ \returns xbTrue - Is a token separator.<br>
+ xbFalse - Is not a token separator.
*/
char xbExp::IsTokenSeparator( char c ){
if( c == '-' || c == '+' || c == '*' || c == '/' || c == '$' || c == '#' ||
@@ -1205,12 +1205,13 @@ xbInt16 xbExp::ParseExpression( xbDbf *dbf, const xbString &sExpression ){
*/
xbInt16 xbExp::ParseExpression( const xbString &sExpression, xbInt16 iWeight ){
- xbExpNode *n;
+ xbExpNode *n = NULL;
xbExpNode *nLastNode = NULL; // pointer to the last node processed
xbExpToken t;
xbInt16 iRc = XB_NO_ERROR;
xbInt16 iErrorStop = 0;
xbString s;
+ xbBool bNewNode = xbFalse;
try {
@@ -1249,6 +1250,7 @@ xbInt16 xbExp::ParseExpression( const xbString &sExpression, xbInt16 iWeight ){
case XB_EXP_CONSTANT:
n = new xbExpNode( t.sToken, t.cNodeType );
+ bNewNode = xbTrue;
if(( iRc = ParseExpressionConstant( t, n )) != XB_NO_ERROR ){
iErrorStop = 120;
throw iRc;
@@ -1257,6 +1259,7 @@ xbInt16 xbExp::ParseExpression( const xbString &sExpression, xbInt16 iWeight ){
case XB_EXP_FUNCTION:
n = new xbExpNode( t.cNodeType );
+ bNewNode = xbTrue;
if(( iRc = ParseExpressionFunction( t, n, iWeight )) != XB_NO_ERROR ){
iErrorStop = 130;
throw iRc;
@@ -1265,6 +1268,7 @@ xbInt16 xbExp::ParseExpression( const xbString &sExpression, xbInt16 iWeight ){
case XB_EXP_FIELD:
n = new xbExpNode( t.cNodeType );
+ bNewNode = xbTrue;
if(( iRc = ParseExpressionField( t, n )) != XB_NO_ERROR ){
iErrorStop = 140;
throw iRc;
@@ -1275,6 +1279,7 @@ xbInt16 xbExp::ParseExpression( const xbString &sExpression, xbInt16 iWeight ){
case XB_EXP_PRE_OPERATOR:
case XB_EXP_POST_OPERATOR:
n = new xbExpNode( t.sToken, t.cNodeType );
+ bNewNode = xbTrue;
if(( iRc = ParseExpressionOperator( t, n, iWeight )) != XB_NO_ERROR ){
iErrorStop = 150;
throw iRc;
@@ -1429,6 +1434,8 @@ xbInt16 xbExp::ParseExpression( const xbString &sExpression, xbInt16 iWeight ){
}
}
catch (xbInt16 iRc ){
+ if( bNewNode && n )
+ delete n;
xbString sMsg;
sMsg.Sprintf( "xbexp::ParseExpression() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
xbase->WriteLogMessage( sMsg.Str() );
@@ -1933,7 +1940,9 @@ xbInt16 xbExp::ProcessExpression( xbInt16 iRecBufSw ){
throw iRc;
}
if( sWork1 == " " ){
- nWork->SetResult( (xbDouble) 21474835648 ); // dbase sets a date value in ndx to this if spaces on dbf record
+ // std::cout << "xbExp::ProcessExpression() line 1938 sWork is spaces\n";
+ //nWork->SetResult( (xbDouble) 21474835648 ); // dbase sets a date value in both ndx and mdx index files to this if spaces on dbf record
+ nWork->SetResult( (xbDouble) XB_NULL_DATE );
} else {
dtWork1.Set( sWork1 );
nWork->SetResult( (xbDouble) dtWork1.JulianDays() );
@@ -2423,7 +2432,6 @@ xbInt16 xbExp::ProcessExpressionOperator( xbExpNode * n ){
xbString sMsg;
try{
-
n->GetNodeText( sOperator );
nChild1 = n->GetChild( 0 );
if( !n->IsUnaryOperator())
@@ -2532,10 +2540,19 @@ xbInt16 xbExp::ProcessExpressionOperator( xbExpNode * n ){
if( nChild1->GetReturnType() == XB_EXP_CHAR )
n->SetResult((xbBool)(nChild1->GetStringResult() > nChild2->GetStringResult()));
- else if( nChild1->GetReturnType() == XB_EXP_NUMERIC || nChild1->GetReturnType() == XB_EXP_DATE )
+
+ else if( nChild1->GetReturnType() == XB_EXP_NUMERIC )
n->SetResult((xbBool)(nChild1->GetNumericResult() > nChild2->GetNumericResult()));
- else {
+ else if( nChild1->GetReturnType() == XB_EXP_DATE ){
+ xbDouble d1 = nChild1->GetNumericResult();
+ xbDouble d2 = nChild2->GetNumericResult();
+ if( d1 == XB_NULL_DATE ) d1 = 0;
+ if( d2 == XB_NULL_DATE ) d2 = 0;
+ n->SetResult((xbBool)( d1 > d2));
+ // n->SetResult((xbBool)(nChild1->GetNumericResult() > nChild2->GetNumericResult()));
+
+ } else {
iErrorStop = 410;
iRc = XB_PARSE_ERROR;
throw iRc;
@@ -2546,10 +2563,18 @@ xbInt16 xbExp::ProcessExpressionOperator( xbExpNode * n ){
if( nChild1->GetReturnType() == XB_EXP_CHAR )
n->SetResult((xbBool)(nChild1->GetStringResult() >= nChild2->GetStringResult()));
- else if( nChild1->GetReturnType() == XB_EXP_NUMERIC || nChild1->GetReturnType() == XB_EXP_DATE )
+ else if( nChild1->GetReturnType() == XB_EXP_NUMERIC )
n->SetResult((xbBool)(nChild1->GetNumericResult() >= nChild2->GetNumericResult()));
- else {
+ else if( nChild1->GetReturnType() == XB_EXP_DATE ){
+ xbDouble d1 = nChild1->GetNumericResult();
+ xbDouble d2 = nChild2->GetNumericResult();
+ if( d1 == XB_NULL_DATE ) d1 = 0;
+ if( d2 == XB_NULL_DATE ) d2 = 0;
+ n->SetResult((xbBool)( d1 >= d2));
+ //n->SetResult((xbBool)(nChild1->GetNumericResult() >= nChild2->GetNumericResult()));
+
+ } else {
iErrorStop = 420;
iRc = XB_PARSE_ERROR;
throw iRc;
@@ -2558,13 +2583,23 @@ xbInt16 xbExp::ProcessExpressionOperator( xbExpNode * n ){
else if( sOperator == "<" ){
- if( nChild1->GetReturnType() == XB_EXP_CHAR )
+ if( nChild1->GetReturnType() == XB_EXP_CHAR ){
n->SetResult((xbBool)( nChild1->GetStringResult() < nChild2->GetStringResult()));
- else if( nChild1->GetReturnType() == XB_EXP_NUMERIC || nChild1->GetReturnType() == XB_EXP_DATE )
+ } else if( nChild1->GetReturnType() == XB_EXP_NUMERIC ){
n->SetResult((xbBool)( nChild1->GetNumericResult() < nChild2->GetNumericResult()));
- else {
+ } else if( nChild1->GetReturnType() == XB_EXP_DATE ){
+ xbDouble d1 = nChild1->GetNumericResult();
+ xbDouble d2 = nChild2->GetNumericResult();
+ if( d1 == XB_NULL_DATE ) d1 = 0;
+ if( d2 == XB_NULL_DATE ) d2 = 0;
+
+ n->SetResult((xbBool)( d1 < d2));
+
+ // std::cout << "xbexp() line 2567 [" << nChild1->GetNumericResult() << "][" << nChild2->GetNumericResult() << "]\n";
+
+ } else {
iErrorStop = 430;
iRc = XB_PARSE_ERROR;
throw iRc;
@@ -2576,10 +2611,18 @@ xbInt16 xbExp::ProcessExpressionOperator( xbExpNode * n ){
if( nChild1->GetReturnType() == XB_EXP_CHAR )
n->SetResult((xbBool)( nChild1->GetStringResult() <= nChild2->GetStringResult()));
- else if( nChild1->GetReturnType() == XB_EXP_NUMERIC || nChild1->GetReturnType() == XB_EXP_DATE )
+ else if( nChild1->GetReturnType() == XB_EXP_NUMERIC )
n->SetResult((xbBool)( nChild1->GetNumericResult() <= nChild2->GetNumericResult()));
- else {
+ else if( nChild1->GetReturnType() == XB_EXP_DATE ){
+ xbDouble d1 = nChild1->GetNumericResult();
+ xbDouble d2 = nChild2->GetNumericResult();
+ if( d1 == XB_NULL_DATE ) d1 = 0;
+ if( d2 == XB_NULL_DATE ) d2 = 0;
+ n->SetResult((xbBool)( d1 <= d2));
+ // n->SetResult((xbBool)( nChild1->GetNumericResult() <= nChild2->GetNumericResult()));
+
+ } else {
iErrorStop = 440;
iRc = XB_PARSE_ERROR;
throw iRc;
@@ -2591,10 +2634,18 @@ xbInt16 xbExp::ProcessExpressionOperator( xbExpNode * n ){
if( nChild1->GetReturnType() == XB_EXP_CHAR )
n->SetResult((xbBool)( nChild1->GetStringResult() != nChild2->GetStringResult()));
- else if( nChild1->GetReturnType() == XB_EXP_NUMERIC || nChild1->GetReturnType() == XB_EXP_DATE )
+ else if( nChild1->GetReturnType() == XB_EXP_NUMERIC )
n->SetResult((xbBool)( nChild1->GetNumericResult() != nChild2->GetNumericResult()));
- else {
+ else if( nChild1->GetReturnType() == XB_EXP_DATE ){
+ xbDouble d1 = nChild1->GetNumericResult();
+ xbDouble d2 = nChild2->GetNumericResult();
+ if( d1 == XB_NULL_DATE ) d1 = 0;
+ if( d2 == XB_NULL_DATE ) d2 = 0;
+ n->SetResult((xbBool)( d1 != d2));
+ // n->SetResult((xbBool)( nChild1->GetNumericResult() != nChild2->GetNumericResult()));
+
+ } else {
iErrorStop = 450;
iRc = XB_PARSE_ERROR;
throw iRc;
@@ -2623,15 +2674,24 @@ xbInt16 xbExp::ProcessExpressionOperator( xbExpNode * n ){
sChld2.Rtrim();
n->SetResult((xbBool)( sChld1 == sChld2 ));
- } else if( nChild1->GetReturnType() == XB_EXP_NUMERIC || nChild1->GetReturnType() == XB_EXP_DATE )
+ } else if( nChild1->GetReturnType() == XB_EXP_NUMERIC ){
n->SetResult((xbBool)( nChild1->GetNumericResult() == nChild2->GetNumericResult()));
- else {
+ } else if( nChild1->GetReturnType() == XB_EXP_DATE ){
+ xbDouble d1 = nChild1->GetNumericResult();
+ xbDouble d2 = nChild2->GetNumericResult();
+ if( d1 == XB_NULL_DATE ) d1 = 0;
+ if( d2 == XB_NULL_DATE ) d2 = 0;
+ n->SetResult((xbBool)( d1 == d2));
+ // n->SetResult((xbBool)( nChild1->GetNumericResult() == nChild2->GetNumericResult()));
+
+ } else {
iErrorStop = 470;
iRc = XB_PARSE_ERROR;
throw iRc;
}
+
} else {
iErrorStop = 500;
iRc = XB_PARSE_ERROR;