summaryrefslogtreecommitdiff
path: root/xbase64/xbexpfnc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'xbase64/xbexpfnc.cpp')
-rwxr-xr-xxbase64/xbexpfnc.cpp1092
1 files changed, 1092 insertions, 0 deletions
diff --git a/xbase64/xbexpfnc.cpp b/xbase64/xbexpfnc.cpp
new file mode 100755
index 0000000..91b6074
--- /dev/null
+++ b/xbase64/xbexpfnc.cpp
@@ -0,0 +1,1092 @@
+/* xbexpfnc.cpp
+
+ Xbase64 project source code
+
+ This file contains logic for handling Xbase expressions.
+
+ Copyright (C) 1997,2003 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 __WIN32__
+#include <xbase64/xbwincfg.h>
+#else
+#include <xbase64/xbconfig.h>
+#endif
+
+#include <xbase64/xbase64.h>
+#ifdef XB_EXPRESSIONS
+
+#include <ctype.h>
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <xbase64/xbexp.h>
+//#include <xbase64/xbexcept.h>
+
+
+/*! \file xbexpfnc.cpp
+*/
+
+/*************************************************************************/
+//! Short description.
+/*!
+ \param Func
+*/
+xbShort xbExpn::ProcessFunction( char * Func )
+{
+/* 1 - pop function from stack
+ 2 - verify function name and get no of parms needed
+ 3 - verify no of parms >= remainder of stack
+ 4 - pop parms off stack
+ 5 - execute function
+ 6 - push result back on stack
+*/
+
+
+ char *buf = 0;
+ xbExpNode *p1, *p2, *p3, *WorkNode, *FuncNode;
+ xbShort ParmsNeeded,len;
+ char ptype = 0; /* process type s=string, l=logical, d=double */
+ xbDouble DoubResult = 0;
+ xbLong IntResult = 0;
+ FuncNode = (xbExpNode *) Pop();
+
+ ParmsNeeded = GetFuncInfo( Func, 1 );
+
+ if( ParmsNeeded == -1 ) {
+ return XB_INVALID_FUNCTION;
+ }
+ else {
+ ParmsNeeded = 0;
+ if( FuncNode->Sibling1 ) ParmsNeeded++;
+ if( FuncNode->Sibling2 ) ParmsNeeded++;
+ if( FuncNode->Sibling3 ) ParmsNeeded++;
+ }
+
+ if( ParmsNeeded > GetStackDepth())
+ return XB_INSUFFICIENT_PARMS;
+
+ p1 = p2 = p3 = NULL;
+ if( ParmsNeeded > 2 ) p3 = (xbExpNode *) Pop();
+ if( ParmsNeeded > 1 ) p2 = (xbExpNode *) Pop();
+ if( ParmsNeeded > 0 ) p1 = (xbExpNode *) Pop();
+ memset( WorkBuf, 0x00, WorkBufMaxLen+1);
+
+ if( strncmp( Func, "ABS", 3 ) == 0 ) {
+ ptype = 'd';
+ DoubResult = ABS( GetDoub( p1 ));
+ }
+ else if( strncmp( Func, "ASC", 3 ) == 0 ) {
+ ptype = 'd';
+ DoubResult = ASC( p1->StringResult );
+ }
+ else if( strncmp( Func, "AT", 2 ) == 0 ) {
+ ptype = 'd';
+ DoubResult = AT( p1->StringResult, p2->StringResult );
+ }
+ else if( strncmp( Func, "CDOW", 4 ) == 0 ) {
+ ptype = 's';
+ buf = CDOW( p1->StringResult );
+ }
+ else if( strncmp( Func, "CHR", 3 ) == 0 ) {
+ ptype = 's';
+ buf = CHR( GetInt( p1 ));
+ }
+ else if( strncmp( Func, "CMONTH", 6 ) == 0 ) {
+ ptype = 's';
+ buf = CMONTH( p1->StringResult );
+ }
+ else if( strncmp( Func, "CTOD", 4 ) == 0 ) {
+ ptype = 's';
+ buf = CTOD( p1->StringResult );
+ }
+ else if( strncmp( Func, "DATE", 4 ) == 0 ) {
+ ptype = 's';
+ buf = DATE();
+ }
+ else if( strncmp( Func, "DAY", 3 ) == 0 ) {
+ ptype = 'd';
+ DoubResult = DAY( p1->StringResult );
+ }
+ else if( strncmp( Func, "DESCEND", 7 ) == 0 && p1->ExpressionType == 'C' ) {
+ ptype = 's';
+ buf = DESCEND( p1->StringResult.c_str() );
+ }
+ else if( strncmp( Func, "DESCEND", 7 ) == 0 && p1->ExpressionType == 'N' ) {
+ ptype = 'd';
+ DoubResult = DESCEND( GetDoub( p1 ));
+ }
+ else if( strncmp( Func, "DESCEND", 7 ) == 0 && p1->ExpressionType == 'D' ) {
+ xbDate d( p1->StringResult );
+ ptype = 'd';
+ DoubResult = DESCEND( d );
+ }
+ else if( strncmp( Func, "DOW", 3 ) == 0 ) {
+ ptype = 'd';
+ DoubResult = DOW( p1->StringResult );
+ }
+ else if( strncmp( Func, "DTOC", 4 ) == 0 ) {
+ ptype = 's';
+ buf = DTOC( p1->StringResult );
+ }
+ else if( strncmp( Func, "DTOS", 4 ) == 0 ) {
+ ptype = 's';
+ buf = DTOS( p1->StringResult );
+ }
+ else if( strncmp( Func, "EXP", 3 ) == 0 ) {
+ ptype = 'd';
+ DoubResult = EXP( GetDoub( p1 ));
+ }
+ else if( strncmp( Func, "IIF", 3 ) == 0 ){
+ ptype = 's';
+ buf = IIF( p1->IntResult, p2->StringResult, p3->StringResult );
+ }
+ else if( strncmp( Func, "INT", 3 ) == 0 ) {
+ ptype = 'd';
+ DoubResult = INT( GetDoub( p1 ));
+ }
+ else if( strncmp( Func, "ISALPHA", 7 ) == 0 ) {
+ ptype = 'l';
+ IntResult = ISALPHA( p1->StringResult );
+ }
+ else if( strncmp( Func, "ISLOWER", 7 ) == 0 ) {
+ ptype = 'l';
+ IntResult = ISLOWER( p1->StringResult );
+ }
+ else if( strncmp( Func, "ISUPPER", 7 ) == 0 ) {
+ ptype = 'l';
+ IntResult = ISUPPER( p1->StringResult );
+ }
+ else if( strncmp( Func, "LEN", 3 ) == 0 ) {
+ ptype = 'd';
+ DoubResult = LEN( p1->StringResult );
+ }
+ else if( strncmp( Func, "LEFT", 4 ) == 0 ) {
+ ptype = 's';
+ buf = LEFT( p1->StringResult, INT( p2->DoubResult ));
+ }
+ else if( strncmp( Func, "LTRIM", 5 ) == 0 ) {
+ ptype = 's';
+ buf = LTRIM( p1->StringResult );
+ }
+ else if( strncmp( Func, "LOG", 3 ) == 0 ) {
+ ptype = 'd';
+ DoubResult = LOG( GetDoub( p1 ));
+ }
+ else if( strncmp( Func, "LOWER", 5 ) == 0 ) {
+ ptype = 's';
+ buf = LOWER( p1->StringResult );
+ }
+ else if( strncmp( Func, "MAX", 3 ) == 0 ) {
+ ptype = 'd';
+ DoubResult = MAX( GetDoub( p1 ), GetDoub( p2 ));
+ }
+ else if( strncmp( Func, "MIN", 3 ) == 0 ) {
+ ptype = 'd';
+ DoubResult = MIN( GetDoub( p1 ), GetDoub( p2 ));
+ }
+ else if( strncmp( Func, "MONTH", 5 ) == 0 ) {
+ ptype = 'd';
+ DoubResult = MONTH( p1->StringResult );
+ }
+
+ else if( strncmp( Func, "RECNO", 5 ) == 0 )
+ {
+ ptype = 'd';
+ DoubResult = RECNO( FuncNode->dbf );
+ }
+
+ else if( strncmp( Func, "REPLICATE", 9 ) == 0 ) {
+ ptype = 's';
+ buf = REPLICATE( p1->StringResult, GetInt( p2 ));
+ }
+ else if( strncmp( Func, "RIGHT", 5 ) == 0 ) {
+ ptype = 's';
+ buf = RIGHT( p1->StringResult, GetInt( p2 ));
+ }
+ else if( strncmp( Func, "RTRIM", 5 ) == 0 ) {
+ ptype = 's';
+ buf = RTRIM( p1->StringResult );
+ }
+ else if( strncmp( Func, "SPACE", 5 ) == 0 ) {
+ ptype = 's';
+ buf = SPACE( INT( GetDoub( p1 )));
+ }
+ else if( strncmp( Func, "SQRT", 4 ) == 0 ) {
+ ptype = 'd';
+ DoubResult = SQRT( GetDoub( p1 ));
+ }
+ else if( strncmp( Func, "STRZERO", 7 ) == 0 && ParmsNeeded == 1 ) {
+ ptype = 's';
+ buf = STRZERO( p1->StringResult );
+ }
+ else if( strncmp( Func, "STRZERO", 7 ) == 0 && ParmsNeeded == 2 ) {
+ ptype = 's';
+ buf = STRZERO( p1->StringResult, GetInt( p2 ));
+ }
+ else if( strncmp( Func, "STRZERO", 7 ) == 0 && ParmsNeeded == 3 ) {
+ ptype = 's';
+ buf = STRZERO( p1->StringResult, GetInt( p2 ), GetInt( p3 ));
+ }
+
+ else if( strncmp( Func, "STR", 3 ) == 0 && p3 ) {
+ ptype = 's';
+ if(p1->ExpressionType == 'N')
+ buf = STR( p1->DoubResult, GetInt( p2 ), GetInt( p3 ));
+ else
+ buf = STR( p1->StringResult, GetInt( p2 ), GetInt( p3 ));
+ }
+
+ else if( strncmp( Func, "STR", 3 ) == 0 && p2 ) {
+ ptype = 's';
+ buf = STR( p1->StringResult, GetInt( p2 ));
+ }
+
+ else if( strncmp( Func, "STR", 3 ) == 0 && p1 ) {
+ ptype = 's';
+ buf = STR( p1->StringResult );
+ }
+
+ else if( strncmp( Func, "SUBSTR", 6 ) == 0 ) {
+ ptype = 's';
+ buf = SUBSTR( p1->StringResult, GetInt( p2 ), GetInt( p3 ));
+ }
+ else if( strncmp( Func, "TRIM", 4 ) == 0 ) {
+ ptype = 's';
+ buf = TRIM( p1->StringResult );
+ }
+ else if( strncmp( Func, "UPPER", 5 ) == 0 ) {
+ ptype = 's';
+ buf = UPPER( p1->StringResult );
+ }
+ else if( strncmp( Func, "VAL", 3 ) == 0 ) {
+ ptype = 'd';
+ DoubResult = VAL( p1->StringResult );
+ }
+ else if( strncmp( Func, "YEAR", 4 ) == 0 ) {
+ ptype = 'd';
+ DoubResult = YEAR( p1->StringResult );
+ }
+ if( p1 && !p1->InTree ) delete p1;
+ if( p2 && !p2->InTree ) delete p2;
+ if( p3 && !p3->InTree ) delete p3;
+ if( !FuncNode->InTree ) delete FuncNode;
+ if( buf ){
+ len = strlen( buf );
+ WorkNode = new xbExpNode;
+ if( !WorkNode )
+ return XB_NO_MEMORY;
+ WorkNode->ResultLen = len + 1;
+
+ } else {
+ len = 0;
+ WorkNode = new xbExpNode;
+ if( !WorkNode )
+ return XB_NO_MEMORY;
+ WorkNode->ResultLen = 0;
+ }
+
+ switch( ptype ){
+ case 's': /* string or char result */
+ WorkNode->DataLen = len;
+ WorkNode->ExpressionType = 'C';
+ WorkNode->Type = 's';
+ WorkNode->StringResult = buf;
+ break;
+ case 'd': /* numeric result */
+ WorkNode->DataLen = 0;
+ WorkNode->ExpressionType = 'N';
+ WorkNode->Type = 'd';
+ WorkNode->DoubResult = DoubResult;
+ break;
+ case 'l': /* logical result */
+ WorkNode->DataLen = 0;
+ WorkNode->ExpressionType = 'L';
+ WorkNode->Type = 'l';
+ WorkNode->IntResult = IntResult;
+ break;
+ default:
+ std::cout << "\nInternal error. " << ptype;
+ break;
+ }
+ Push(WorkNode);
+ return XB_NO_ERROR;
+}
+/*************************************************************************/
+//! Short description.
+/*!
+*/
+xbString & xbExpn::GetStringResult()
+{
+ xbString *s = 0;
+ xbExpNode *e;
+ if( GetStackDepth() < 1 ) return *s;
+ e = (xbExpNode *) Pop();
+ s = &e->StringResult;
+ Push(e);
+ return *s;
+}
+/*************************************************************************/
+//! Short description.
+/*!
+*/
+xbLong xbExpn::GetIntResult()
+{
+ xbLong l;
+ xbExpNode * e;
+ if( GetStackDepth() < 1 ) return 0L;
+ e = (xbExpNode *) Pop();
+ l = e->IntResult;
+ Push(e);
+ return l;
+}
+/*************************************************************************/
+//! Short description.
+/*!
+*/
+xbDouble xbExpn::GetDoubleResult()
+{
+ xbDouble d;
+ xbExpNode * e;
+ if( GetStackDepth() < 1 ) return (xbDouble) 0;
+ e = (xbExpNode *) Pop();
+ d = e->DoubResult;
+ Push(e);
+ return d;
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param p
+*/
+xbDouble xbExpn::GetDoub( xbExpNode * p )
+{
+ if( p->Type == 'd' )
+ return p->DoubResult;
+ else if( p->Type == 'N' || p->Type == 's' )
+ return( strtod( p->StringResult, NULL ));
+ else if( p->Type == 'D' )
+ return( p->dbf->GetDoubleField( p->FieldNo ));
+ else
+ return 0;
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param p
+*/
+xbLong xbExpn::GetInt( xbExpNode *p )
+{
+ if( p->Type == 'l' || p->Type == 'i' )
+ return p->IntResult;
+ else if( p->Type == 'N' || p->Type == 's' )
+ return atoi( p->StringResult );
+ else if( p->Type == 'D' )
+ return p->dbf->GetLongField( p->FieldNo );
+ else
+ return 0L;
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param d
+*/
+xbDouble xbExpn::ABS( xbDouble d )
+{
+ if( d < (xbDouble) 0 )
+ return d * -1;
+ else
+ return d;
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param String
+*/
+xbLong xbExpn::ASC( const char * String )
+{
+ return *String;
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param s1
+ \param s2
+*/
+xbLong xbExpn::AT( const char * s1, const char *s2 )
+{
+ /* looks for s1 in s2 */
+ xbLong cnt;
+ const char *p;
+ if( strlen( s1 ) > strlen( s2 )) return 0;
+ if(( p = strstr( s2, s1 )) == NULL )
+ return 0;
+ cnt = 1;
+ while( s2++ != p ) cnt++;
+ return cnt;
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param Date8
+*/
+char * xbExpn::CDOW( const char * Date8 )
+{
+ static char buf[10];
+ xbDate d;
+ xbShort len,i;
+ strcpy( buf, d.FormatDate( "DDDD", Date8 ));
+ len = strlen( buf );
+ for( i = len; i < 9; i++ ) buf[i] = 0x20;
+ buf[9] = 0x00;
+ return buf;
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param l
+*/
+char * xbExpn::CHR( xbLong l )
+{
+ static char buf[2];
+ xbShort i;
+ i = (xbShort) l;
+ buf[0] = i;
+ buf[1] = 0x00;
+ return buf;
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param Date8
+*/
+char * xbExpn::CMONTH( const char * Date8 )
+{
+ static char buf[10];
+ xbShort len,i;
+ xbDate d;
+ strcpy( buf, d.FormatDate( "MMMM", Date8 ));
+ len = strlen( buf );
+ for( i = len; i < 9; i++ ) buf[i] = 0x20;
+ buf[9] = 0x00;
+ return buf;
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param indate
+*/
+char * xbExpn::CTOD( const char * indate )
+{
+ xbDate d;
+ strcpy( WorkBuf, d.FormatCTODdate( indate ));
+ return WorkBuf;
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param Date8
+*/
+xbLong xbExpn::DAY( const char * Date8 )
+{
+ xbDate d;
+ return d.DayOf( XB_FMT_MONTH, Date8 );
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param date
+*/
+xbLong xbExpn::DESCEND( const xbDate & date )
+{
+ return 2415021 + date.JulianDays( "29991231" ) - date.JulianDays();
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param num
+*/
+xbDouble xbExpn::DESCEND( xbDouble d )
+{
+ return d * -1;
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param str
+*/
+char * xbExpn::DESCEND( const char * str )
+{
+ xbShort i;
+ xbShort len = strlen( str );
+
+ for( i = 0; i < len; i++ )
+ WorkBuf[i] = 255 - str[i];
+ WorkBuf[i] = 0x00;
+
+ return WorkBuf;
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param Date8
+*/
+xbLong xbExpn::DOW( const char * Date8 )
+{
+ xbDate d;
+ return d.DayOf( XB_FMT_WEEK, Date8 );
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param Date8
+*/
+char * xbExpn::DTOC( const char * Date8 )
+{
+ xbDate d;
+ strcpy( WorkBuf, d.FormatDate( xbase->GetDefaultDateFormat(), Date8 ));
+ return WorkBuf;
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param Date8
+*/
+char * xbExpn::DTOS( const char * Date8 )
+{
+ xbDate d;
+ strcpy( WorkBuf, d.FormatDate( "YYYYMMDD", Date8 ));
+ return WorkBuf;
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param d
+*/
+xbDouble xbExpn::EXP( xbDouble d )
+{
+ return exp( d );
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param ifCondition
+ \param trueRslt
+ \param falseRslt
+*/
+char * xbExpn::IIF( xbShort ifCondition,
+ const char * trueRslt, const char * falseRslt )
+{
+ if( ifCondition )
+ strcpy( WorkBuf, trueRslt );
+ else
+ strcpy( WorkBuf, falseRslt );
+
+ return WorkBuf;
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param d
+*/
+xbLong xbExpn::INT( xbDouble d )
+{
+ return (xbLong) d;
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param String
+*/
+xbLong xbExpn::ISALPHA( const char * String )
+{
+ if( isalpha(*String) ) return 1;
+ else return 0;
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param String
+*/
+xbLong xbExpn::ISLOWER( const char * String )
+{
+ if( islower(*String) ) return 1;
+ else return 0;
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param String
+*/
+xbLong xbExpn::ISUPPER( const char * String )
+{
+ if( isupper(*String) ) return 1;
+ else return 0;
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param String
+*/
+xbLong xbExpn::LEN( const char * String )
+{
+ xbLong len;
+ len = strlen( String );
+ len--;
+ while( len >= 0 && String[len] == 0x20 ) len--;
+ return ++len;
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param String
+ \param Len
+*/
+char * xbExpn::LEFT( const char * String, xbShort Len )
+{
+ xbShort i;
+ for( i = 0; i < Len && i < 100; i++ )
+ WorkBuf[i] = String[i];
+ WorkBuf[i] = 0x00;
+ return WorkBuf;
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param String
+*/
+/* This method removes any leading spaces from String */
+char * xbExpn::LTRIM( const char *String) {
+ WorkBuf[0] = 0x00;
+ if (!String)
+ return WorkBuf;
+
+ xbShort i;
+ i = 0;
+ while( *String && *String == 0x20 ) String++;
+ while( *String && i < WorkBufMaxLen ){
+ WorkBuf[i++] = *String;
+ String++;
+ }
+ WorkBuf[i] = 0x00;
+ return WorkBuf;
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param d
+*/
+xbDouble xbExpn::LOG( xbDouble d )
+{
+ return log( d );
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param String
+*/
+char *xbExpn::LOWER( const char *String )
+{
+ WorkBuf[0] = 0x00;
+ if (!String)
+ return WorkBuf;
+ xbShort i = 0;
+ while( *String && i < WorkBufMaxLen) {
+ WorkBuf[i++] = tolower( *String );
+ String++;
+ }
+ WorkBuf[i] = 0x00;
+ return WorkBuf;
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param d1
+ \param d2
+*/
+xbDouble xbExpn::MAX( xbDouble d1, xbDouble d2 )
+{
+ if( d1 > d2 )
+ return d1;
+ else
+ return d2;
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param d1
+ \param d2
+*/
+xbDouble xbExpn::MIN( xbDouble d1, xbDouble d2 )
+{
+ if( d1 < d2 )
+ return d1;
+ else
+ return d2;
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param Date8
+*/
+xbLong xbExpn::MONTH( const char * Date8 )
+{
+ xbDate d;
+ return d.MonthOf( Date8 );
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param d
+*/
+xbLong xbExpn::RECNO( xbDbf * d ) {
+ return d->GetCurRecNo();
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param String
+ \param Cnt
+*/
+char * xbExpn::REPLICATE( const char * String, xbShort Cnt )
+{
+ xbShort len, i;
+ len = strlen( String );
+ if(( len * Cnt ) > 100 ) return NULL;
+ memset( WorkBuf, 0x00, len+1 );
+ for( i = 0; i < Cnt; i++ )
+ strcat( WorkBuf, String );
+ return WorkBuf;
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param String
+ \paran cnt
+*/
+char * xbExpn::RIGHT( const char * String, xbShort cnt )
+{
+ xbShort len;
+ strcpy( WorkBuf, String );
+ len = strlen( String );
+ if( len < cnt ) return WorkBuf;
+ len = LEN( String );
+ if( len < cnt ) return WorkBuf;
+ strcpy( WorkBuf, String + len - cnt );
+ return WorkBuf;
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param String
+*/
+char * xbExpn::RTRIM( const char * String )
+{
+ return TRIM( String );
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param Cnt
+*/
+char * xbExpn::SPACE( xbShort Cnt )
+{
+ if( Cnt > 100 ) return NULL;
+ memset( WorkBuf, 0x20, Cnt );
+ WorkBuf[Cnt] = 0x00;
+ return WorkBuf;
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param d
+*/
+xbDouble xbExpn::SQRT( xbDouble d )
+{
+ return sqrt( d );
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param d
+ \param length
+ \param numDecimals
+*/
+char * xbExpn::STR(xbDouble d, xbUShort length, xbShort numDecimals) {
+ // sanity check for length arg
+ if (length > WorkBufMaxLen)
+ {
+ // maybe should generate an error here instead ?
+ length = WorkBufMaxLen;
+ }
+
+ // check the length required
+ sprintf(WorkBuf, "%.*f", numDecimals, d);
+
+ if ((xbUShort) strlen(WorkBuf) > length) {
+ memset(WorkBuf, '*', length);
+ WorkBuf[length] = 0x00;
+ } else
+ sprintf( WorkBuf, "%*.*f", length, numDecimals, d );
+
+ return WorkBuf;
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param d
+ \param length
+*/
+char * xbExpn::STR( xbDouble d, xbShort length )
+{
+ return STR( d, length, 0 );
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param d
+*/
+char * xbExpn::STR( xbDouble d )
+{
+ return STR( d, 10, 0 );
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param String
+ \param length
+ \param
+*/
+char * xbExpn::STR( const char * String, xbShort length, xbShort dec )
+{
+ xbShort len, i;
+ double d;
+ d = strtod( String, NULL );
+ return STR( d, length, dec );
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param String
+ \param length
+*/
+char * xbExpn::STR( const char *String, xbShort length )
+{
+ return STR( String, length, 0 );
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param String
+*/
+char * xbExpn::STR( const char * String )
+{
+ return STR( String, 10, 0 );
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param d
+ \param length
+ \param
+*/
+char * xbExpn::STRZERO( xbDouble d, xbShort length, xbShort )
+{
+ xbShort len,i;
+ sprintf(WorkBuf, "%*.*g", length, length, d);
+// gcvt( d, length, WorkBuf );
+ len = strlen( WorkBuf );
+ if( len > length )
+ strcpy( WorkBuf, "**********" );
+ else if( len < length )
+ {
+ for( i = len; i < length; i++ )
+ WorkBuf[i] = 0x30;
+ WorkBuf[i] = 0x00;
+ }
+ return WorkBuf;
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param d
+ \param length
+*/
+char * xbExpn::STRZERO( xbDouble d, xbShort length )
+{
+ return STRZERO( d, length, 0 );
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param d
+*/
+char * xbExpn::STRZERO( xbDouble d )
+{
+ return STRZERO( d, 10, 0 );
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param String
+ \param length
+ \param
+*/
+char * xbExpn::STRZERO( const char * String, xbShort length, xbShort )
+{
+ xbShort i, len ;
+ while( *String == ' ' ) String++;
+ len = strlen(String);
+ for( i = 0; i < abs( length-len); i++ )
+ WorkBuf[i] = 0x30;
+ WorkBuf[i] = 0x00;
+ strcat( WorkBuf, String );
+ return WorkBuf;
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param String
+ \param length
+*/
+char * xbExpn::STRZERO( const char * String, xbShort length )
+{
+ return STRZERO( String, length, 0 );
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param String
+*/
+char * xbExpn::STRZERO( const char * String )
+{
+ return STRZERO( String, 10, 0 );
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param String
+ \param StartPos
+ \param Len
+*/
+char * xbExpn::SUBSTR( const char * String, xbShort StartPos, xbShort Len )
+{
+ xbShort i;
+ if( StartPos < 1 ) return NULL;
+ String += (StartPos - 1);
+ for( i = 0; i < Len; i++ )
+ WorkBuf[i] = *String++;
+ WorkBuf[i] = 0x00;
+ return WorkBuf;
+}
+/*************************************************************************/
+//! Short description.
+/*!
+*/
+char * xbExpn::DATE()
+{
+ xbDate d;
+ strcpy( WorkBuf, d.Sysdate());
+ return WorkBuf;
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param String
+*/
+char * xbExpn::TRIM( const char * String )
+{
+ WorkBuf[0] = 0x00;
+ if( !String )
+ return WorkBuf;
+ char *sp;
+ xbShort len;
+ len = strlen( String );
+ if( len < WorkBufMaxLen ) {
+ strcpy( WorkBuf, String );
+ }
+ else {
+ strncpy( WorkBuf, String, WorkBufMaxLen );
+ WorkBuf[ WorkBufMaxLen ] = 0x00;
+ len = WorkBufMaxLen;
+ }
+ sp = WorkBuf + len - 1;
+ while( *sp == 0x20 && sp >= WorkBuf ) {
+ *sp = 0x00;
+ sp--;
+ }
+ return WorkBuf;
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param String
+*/
+char *xbExpn::UPPER( const char *String )
+{
+ WorkBuf[0] = 0x00;
+ if (!String)
+ return WorkBuf;
+ xbShort i;
+ i = 0;
+ while(*String && i < WorkBufMaxLen) {
+ WorkBuf[i++] = toupper(*String);
+ String++;
+ }
+ WorkBuf[i] = 0x00;
+ return WorkBuf;
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param String
+*/
+xbLong xbExpn::VAL( const char * String )
+{
+ if( String )
+ return (xbLong) *String;
+ else
+ return 0;
+}
+/*************************************************************************/
+//! Short description.
+/*!
+ \param Date8
+*/
+xbLong xbExpn::YEAR( const char * Date8 ){
+ xbDate d;
+ return d.YearOf( Date8 );
+}
+/*************************************************************************/
+#endif // XB_EXPRESSIONS