diff options
Diffstat (limited to 'src/core/xbexp.cpp')
-rwxr-xr-x | src/core/xbexp.cpp | 102 |
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; |