diff --git a/harbour/ChangeLog b/harbour/ChangeLog index bef86aa993..f3878ad845 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -1,3 +1,41 @@ +19990819-18:42 GMT+1 Victor Szel + * tests/working/rtl_test.prg + + STUFF() and RAT() tests added, some more tests added to PAD*() family. + * include/extend.h + source/rtl/strings.c + source/rtl/descend.c + source/vm/hvm.c + ! hb_strUpper(), hb_strLower(), hb_strAt() uses ULONG instead of long + for string positions and lengths. + ! hb_pad_prep() uses ULONG instead of WORD + + REPLICATE() now checks for string overflow. + * REPLICATE() uses only standard Extend API calls now. + * STUFF() made completely Clipper compatible, it now uses only standard + Extend API calls. + * hb_stricmp() USHORT changed to ULONG. + * return type of hb_strgreater changed to int from WORD + ! Some types changed to BOOL, many "long"s changed to ULONG. + * long -> LONG, _retni() -> retnl() in one place. + * Some zeros changed to \0 and NULL. + * Small name changes: + hb_pad_prep() -> hb_itemPadConv() + hb_strempty -> hb_strEmpty + hb_strdescend -> hb_strDescend + * source/rtl/copyfile.c + ! Fixed a bug when HB_STRICT_CLIPPER_COMPATBILITY was set. + * contrib/odbc/odbc.c + source/rtl/copyfile.c + source/rtl/descend.c + source/hbpp/hbpplib.c + ! Fixed #pragma startup directives. (missing "startup", missing + __GNUC__ guard.) + * source/hbpp/hbpplib.c + tests/working/testpre.prg + * HB_PREPROCESS -> HB___PREPROCESS, since this is an extension. + PREPROCESS -> __PREPROCESS + * source/vm/dynsym.c + * One small change. + 19990819-12:30 GMT+1 Victor Szel * source/rtl/strings.c ! hb_itemStr() possible error fixed when item.asDouble was @@ -60,7 +98,7 @@ source/vm/hvm.c source/rtl/transfrm.c - Removed HB_ITEM/asLogical.length variable, since it was never - used, and has no sense anyway. + used, and has no sense anyway. - Removed HB_ITEM/asDate.length variable, since it was never used, and has no sense anyway. - Removed HB_ITEM/asInteger.decimal variable, since it was never @@ -78,7 +116,7 @@ * source/tools/dates2.c * Some optimalizations, simplifications. * source/rtl/transfrm.c - ! Fixed handling of the case, when the second parameter was not a + ! Fixed handling of the case, when the second parameter was not a string. * Some optimalizations, simplifications. ! Reenabled symbol registration, to avoid an empty initialization list. diff --git a/harbour/contrib/odbc/odbc.c b/harbour/contrib/odbc/odbc.c index ebf08b9dd9..7c61fa611e 100644 --- a/harbour/contrib/odbc/odbc.c +++ b/harbour/contrib/odbc/odbc.c @@ -71,7 +71,9 @@ HB_INIT_SYMBOLS_BEGIN( odbc__InitSymbols ) { "SQLFETCH", FS_PUBLIC, HB_SQLFETCH , 0 }, { "SQLGETDATA", FS_PUBLIC, HB_SQLGETDATA , 0 } HB_INIT_SYMBOLS_END( odbc__InitSymbols ) -#pragma odbc__InitSymbols +#if ! defined(__GNUC__) +#pragma startup odbc__InitSymbols +#endif HARBOUR HB_SQLALLOCEN( void ) /* HB_SQLALLOCENV( @hEnv ) --> nRetCode */ { diff --git a/harbour/include/extend.h b/harbour/include/extend.h index 884d97ab85..0c504a65c3 100644 --- a/harbour/include/extend.h +++ b/harbour/include/extend.h @@ -277,14 +277,14 @@ extern void hb_arrayAdd( PHB_ITEM pArray, PHB_ITEM pItemValue ); #define HB_STRGREATER_RIGHT 2 extern int hb_stricmp( const char *s1, const char *s2 ); -extern BOOL hb_strempty( char * szText, ULONG ulLen ); -extern char * hb_strdescend( char * szText, ULONG ulLen ); -extern WORD hb_strgreater( char * sz1, char * sz2 ); +extern int hb_strgreater( char * sz1, char * sz2 ); extern void hb_strupr( char * szText ); extern BOOL hb_strMatchRegExp( char * szString, char * szMask ); -extern ULONG hb_strAt( char *, long, char *, long ); -extern char * hb_strUpper( char * szText, long lLen ); -extern char * hb_strLower( char * szText, long lLen ); +extern BOOL hb_strEmpty( char * szText, ULONG ulLen ); +extern char * hb_strDescend( char * szText, ULONG ulLen ); +extern ULONG hb_strAt(char *szSub, ULONG ulSubLen, char *szText, ULONG ulLen); +extern char * hb_strUpper( char * szText, ULONG ulLen ); +extern char * hb_strLower( char * szText, ULONG ulLen ); /* class management */ extern void hb_clsReleaseAll( void ); /* releases all defined classes */ diff --git a/harbour/source/hbpp/hbpplib.c b/harbour/source/hbpp/hbpplib.c index 145b21842e..ad395cd957 100644 --- a/harbour/source/hbpp/hbpplib.c +++ b/harbour/source/hbpp/hbpplib.c @@ -34,8 +34,6 @@ */ -/* TODO: Move this to source/tools */ - #include #include "hbpp.h" #include "extend.h" @@ -47,18 +45,18 @@ PATHNAMES *_pIncludePath = NULL; FILENAME *_pFileName = NULL; BOOL _bWarnings = FALSE; -HARBOUR HB_PREPROCESS(void); +HARBOUR HB___PREPROCESS(void); HB_INIT_SYMBOLS_BEGIN( Preprocess__InitSymbols ) -{ "PREPROCESS", FS_PUBLIC, HB_PREPROCESS , 0 } +{ "__PREPROCESS", FS_PUBLIC, HB___PREPROCESS , 0 } HB_INIT_SYMBOLS_END( Preprocess__InitSymbols ) #if ! defined(__GNUC__) -#pragma Preprocess__InitSymbols +#pragma startup Preprocess__InitSymbols #endif /* TODO: Extend the function to allow directives and external include files */ -HARBOUR HB_PREPROCESS(void) +HARBOUR HB___PREPROCESS(void) { if (ISCHAR(1)) { diff --git a/harbour/source/rtl/copyfile.c b/harbour/source/rtl/copyfile.c index 5f63297d76..1b38115a7f 100644 --- a/harbour/source/rtl/copyfile.c +++ b/harbour/source/rtl/copyfile.c @@ -41,47 +41,22 @@ HB_INIT_SYMBOLS_BEGIN( CopyFile__InitSymbols ) { "__COPYFILE", FS_PUBLIC, HB___COPYFILE, 0 } HB_INIT_SYMBOLS_END( CopyFile__InitSymbols ) #if ! defined(__GNUC__) - #pragma CopyFile__InitSymbols +#pragma startup CopyFile__InitSymbols #endif -static BOOL hb_fsCopy(char* szSource, char* szDest, ULONG* ulWrittenTotal); - -/* INCOMPATIBILITY: Clipper returns .F. on failure and NIL on success */ - -HARBOUR HB___COPYFILE( void ) -{ - if ( ISCHAR(1) && ISCHAR(2) ) - { -#ifdef HARBOUR_STRICT_CLIPPER_COMPATIBILITY - if (!hb_fsCopy(hb_parc(1), hb_parc(2))) - { - hb_retl(FALSE); - } -#else - ULONG ulWrittenTotal; - hb_fsCopy(hb_parc(1), hb_parc(2), &ulWrittenTotal); - hb_retnl(ulWrittenTotal); -#endif - } - else - { - hb_errRT_BASE(EG_ARG, 2010, NULL, "__COPYFILE"); - } -} - -static BOOL hb_fsCopy(char* szSource, char* szDest, ULONG* ulWrittenTotal) +static BOOL hb_fsCopy(char* szSource, char* szDest, ULONG* pulWrittenTotal) { BOOL bRetVal = FALSE; + ULONG ulWrittenTotal = 0L; + FHANDLE fhndSource; FHANDLE fhndDest; - *ulWrittenTotal = 0L; - while ((fhndSource = hb_fsOpen(( BYTE * ) szSource, FO_READ)) == FS_ERROR) { if (hb_errRT_BASE_Ext1(EG_OPEN, 2012, NULL, szSource, hb_fsError(), EF_CANDEFAULT | EF_CANRETRY ) == E_DEFAULT) { - *ulWrittenTotal = (ULONG)-1L; + ulWrittenTotal = (ULONG)-1L; break; } } @@ -92,7 +67,7 @@ static BOOL hb_fsCopy(char* szSource, char* szDest, ULONG* ulWrittenTotal) { if (hb_errRT_BASE_Ext1(EG_CREATE, 2012, NULL, szDest, hb_fsError(), EF_CANDEFAULT | EF_CANRETRY ) == E_DEFAULT) { - *ulWrittenTotal = (ULONG)-2L; + ulWrittenTotal = (ULONG)-2L; break; } } @@ -125,7 +100,7 @@ static BOOL hb_fsCopy(char* szSource, char* szDest, ULONG* ulWrittenTotal) } } - *ulWrittenTotal += (ULONG)usWritten; + ulWrittenTotal += (ULONG)usWritten; } hb_xfree(buffer); @@ -141,6 +116,31 @@ static BOOL hb_fsCopy(char* szSource, char* szDest, ULONG* ulWrittenTotal) hb_fsClose(fhndSource); } + if ( pulWrittenTotal != NULL ) + *pulWrittenTotal = ulWrittenTotal; + return bRetVal; } +/* Clipper returns .F. on failure and NIL on success */ + +HARBOUR HB___COPYFILE( void ) +{ + if ( ISCHAR(1) && ISCHAR(2) ) + { +#ifdef HARBOUR_STRICT_CLIPPER_COMPATIBILITY + if (!hb_fsCopy( hb_parc(1), hb_parc(2), NULL )) + { + hb_retl( FALSE ); + } +#else + ULONG ulWrittenTotal; + hb_fsCopy( hb_parc(1), hb_parc(2), &ulWrittenTotal ); + hb_retnl( ulWrittenTotal ); +#endif + } + else + { + hb_errRT_BASE( EG_ARG, 2010, NULL, "__COPYFILE" ); + } +} diff --git a/harbour/source/rtl/descend.c b/harbour/source/rtl/descend.c index 1d10357f19..3a7f531bf9 100644 --- a/harbour/source/rtl/descend.c +++ b/harbour/source/rtl/descend.c @@ -72,12 +72,12 @@ HB_INIT_SYMBOLS_BEGIN( Descend__InitSymbols ) { "DESCEND", FS_PUBLIC, HB_DESCEND, 0 } HB_INIT_SYMBOLS_END( Descend__InitSymbols ) #if ! defined(__GNUC__) -#pragma Descend__InitSymbols +#pragma startup Descend__InitSymbols #endif -char * hb_strdescend( char * szText, ULONG ulLen ) +char * hb_strDescend( char * szText, ULONG ulLen ) { - if (!(ulLen == 1 && szText[0] == 0)) + if (!(ulLen == 1 && szText[0] == '\0')) { char *s; @@ -97,7 +97,7 @@ HARBOUR HB_DESCEND( void ) if( pItem ) { if( IS_STRING( pItem ) ) - hb_retclen( hb_strdescend( pItem->item.asString.value, pItem->item.asString.length ), pItem->item.asString.length ); + hb_retclen( hb_strDescend( pItem->item.asString.value, pItem->item.asString.length ), pItem->item.asString.length ); else if( IS_DATE( pItem ) ) hb_retnl( 5231808 - pItem->item.asDate.value ); else if( IS_NUMERIC( pItem ) ) @@ -116,7 +116,7 @@ HARBOUR HB_DESCEND( void ) hb_itemReturn( pReturn ); hb_itemRelease( pReturn ); -/* It is dengerous to operate on the stack directly +/* It is dangerous to operate on the stack directly stack.Return.wDec = pItem->wDec; */ } diff --git a/harbour/source/rtl/strings.c b/harbour/source/rtl/strings.c index 99d60b9fb4..bd7fb6dd26 100644 --- a/harbour/source/rtl/strings.c +++ b/harbour/source/rtl/strings.c @@ -115,7 +115,7 @@ HB_CALL_ON_STARTUP_END( Strings_InitInfinity ) #endif #endif -BOOL hb_strempty( char * szText, ULONG ulLen ) +BOOL hb_strEmpty( char * szText, ULONG ulLen ) { BOOL bRetVal = TRUE; @@ -143,7 +143,8 @@ BOOL hb_strempty( char * szText, ULONG ulLen ) int hb_stricmp( const char *s1, const char *s2 ) { int rc = 0, c1, c2; - USHORT l1, l2, count; + ULONG l1, l2, count; + l1 = strlen( s1 ); l2 = strlen( s2 ); if( l1 < l2 ) count = l1; @@ -318,7 +319,7 @@ HARBOUR HB_RTRIM( void ) PHB_ITEM pText = hb_param(1, IT_STRING); if( pText ) { - BOOL bAnySpace = (hb_pcount() > 1? hb_parl(2): 0); + BOOL bAnySpace = (hb_pcount() > 1 ? hb_parl(2) : FALSE); hb_retclen(pText->item.asString.value, hb_strRTrimLen(pText->item.asString.value, pText->item.asString.length, bAnySpace)); } else @@ -346,7 +347,7 @@ HARBOUR HB_TRIM( void ) PHB_ITEM pText = hb_param(1, IT_STRING); if( pText ) { - BOOL bAnySpace = (hb_pcount() > 1? hb_parl(2): 0); + BOOL bAnySpace = (hb_pcount() > 1 ? hb_parl(2) : FALSE); hb_retclen(pText->item.asString.value, hb_strRTrimLen(pText->item.asString.value, pText->item.asString.length, bAnySpace)); } else @@ -368,7 +369,7 @@ HARBOUR HB_ALLTRIM( void ) if( hb_pcount() > 0 ) { char *szText = hb_parc(1); - BOOL bAnySpace = (hb_pcount() > 1? hb_parl(2): 0); + BOOL bAnySpace = (hb_pcount() > 1 ? hb_parl(2) : FALSE); ULONG lLen; lLen = hb_strRTrimLen(szText, hb_parclen(1), bAnySpace); @@ -385,25 +386,25 @@ HARBOUR HB_ALLTRIM( void ) /* This function is used by all of the PAD functions to prepare the argument being padded. If date, convert to string using hb_dtoc(). If numeric, convert to unpadded string. Return pointer to string and set string length */ -static char * hb_pad_prep( PHB_ITEM pItem, char * buffer, WORD * pwSize ) +static char * hb_itemPadConv( PHB_ITEM pItem, char * buffer, ULONG * pulSize ) { - char * szText = 0; + char * szText = NULL; if( pItem ) switch( pItem->type ) { case IT_DATE: szText = hb_dtoc( hb_pards( 1 ), buffer, hb_set.HB_SET_DATEFORMAT ); - *pwSize = strlen( szText ); + *pulSize = strlen( szText ); break; case IT_INTEGER: sprintf( buffer, "%d", hb_parni( 1 ) ); szText = buffer; - *pwSize = strlen( szText ); + *pulSize = strlen( szText ); break; case IT_LONG: sprintf( buffer, "%ld", hb_parnl( 1 ) ); szText = buffer; - *pwSize = strlen( szText ); + *pulSize = strlen( szText ); break; case IT_DOUBLE: if( pItem->item.asDouble.decimal ) @@ -411,11 +412,11 @@ static char * hb_pad_prep( PHB_ITEM pItem, char * buffer, WORD * pwSize ) else sprintf( buffer, "%ld", hb_parnl( 1 ) ); szText = buffer; - *pwSize = strlen( szText ); + *pulSize = strlen( szText ); break; case IT_STRING: szText = hb_parc( 1 ); - *pwSize = hb_parclen( 1 ); + *pulSize = hb_parclen( 1 ); break; } return szText; @@ -425,26 +426,25 @@ static char * hb_pad_prep( PHB_ITEM pItem, char * buffer, WORD * pwSize ) /* TEST: QOUT( "padr( 'hello', 10 ) = '" + padr( 'hello', 10 ) + "'" ) */ HARBOUR HB_PADR( void ) { - WORD wSize; + ULONG ulSize; char buffer[ 128 ]; - PHB_ITEM pItem = hb_param( 1, IT_ANY ); - char *szText = hb_pad_prep( pItem, buffer, &wSize ); + char *szText = hb_itemPadConv( hb_param( 1, IT_ANY ), buffer, &ulSize ); if( szText && hb_pcount() > 1 ) { - long lLen = hb_parnl(2); + LONG lLen = hb_parnl(2); - if( lLen > wSize ) + if( lLen > (LONG)ulSize ) { char *szResult = (char *)hb_xgrab(lLen + 1); - long lPos; + LONG lPos; char cPad; - memcpy(szResult, szText, wSize); + memcpy(szResult, szText, (LONG)ulSize); cPad = ( hb_pcount() > 2? *(hb_parc(3)): ' ' ); - for( lPos = wSize; lPos < lLen; lPos++ ) + for( lPos = (LONG)ulSize; lPos < lLen; lPos++ ) szResult[lPos] = cPad; hb_retclen(szResult, lLen); @@ -472,22 +472,21 @@ HARBOUR HB_PAD( void ) /* TEST: QOUT( "padl( 'hello', 10 ) = '" + padl( 'hello', 10 ) + "'" ) */ HARBOUR HB_PADL( void ) { - WORD wSize; + ULONG ulSize; char buffer[ 128 ]; - PHB_ITEM pItem = hb_param( 1, IT_ANY ); - char *szText = hb_pad_prep( pItem, buffer, &wSize ); + char *szText = hb_itemPadConv( hb_param( 1, IT_ANY ), buffer, &ulSize ); if( szText && hb_pcount() > 1 ) { - long lLen = hb_parnl(2); + LONG lLen = hb_parnl(2); - if( lLen > wSize ) + if( lLen > (LONG)ulSize ) { char *szResult = (char *)hb_xgrab(lLen + 1); - long lPos = lLen - wSize; + LONG lPos = lLen - (LONG)ulSize; char cPad; - memcpy(szResult + lPos, szText, wSize); + memcpy(szResult + lPos, szText, (LONG)ulSize); cPad = (hb_pcount() > 2? *(hb_parc(3)): ' '); @@ -515,32 +514,31 @@ HARBOUR HB_PADL( void ) /* TEST: QOUT( "padc( 'hello', 10 ) = '" + padc( 'hello', 10 ) + "'" ) */ HARBOUR HB_PADC( void ) { - WORD wSize; + ULONG ulSize; char buffer[ 128 ]; - PHB_ITEM pItem = hb_param( 1, IT_ANY ); - char *szText = hb_pad_prep( pItem, buffer, &wSize ); + char *szText = hb_itemPadConv( hb_param( 1, IT_ANY ), buffer, &ulSize ); if( szText && hb_pcount() > 1 ) { - long lLen = hb_parnl(2); + LONG lLen = hb_parnl(2); - if( lLen > wSize ) + if( lLen > (LONG)ulSize ) { char *szResult = (char *)hb_xgrab(lLen + 1); char cPad; - long w, lPos = (lLen - wSize) / 2; + LONG w, lPos = (lLen - (LONG)ulSize) / 2; - memcpy(szResult + lPos, szText, wSize + 1); + memcpy(szResult + lPos, szText, (LONG)ulSize + 1); cPad = ( hb_pcount() > 2? *hb_parc(3): ' ' ); for( w = 0; w < lPos; w++ ) szResult[w] = cPad; - for( w = wSize + lPos; w < lLen; w++ ) + for( w = (LONG)ulSize + lPos; w < lLen; w++ ) szResult[w] = cPad; - szResult[lLen] = 0; + szResult[lLen] = '\0'; hb_retclen(szResult, lLen); hb_xfree(szResult); @@ -557,27 +555,27 @@ HARBOUR HB_PADC( void ) hb_retc(""); } -ULONG hb_strAt(char *szSub, long lSubLen, char *szText, long lLen) +ULONG hb_strAt(char *szSub, ULONG ulSubLen, char *szText, ULONG ulLen) { - if( lSubLen ) + if( ulSubLen ) { - if( lLen >= lSubLen ) + if( ulLen >= ulSubLen ) { - long lPos = 0, lSubPos = 0; + ULONG ulPos = 0, ulSubPos = 0; - while( lPos < lLen && lSubPos < lSubLen ) + while( ulPos < ulLen && ulSubPos < ulSubLen ) { - if( *(szText + lPos) == *(szSub + lSubPos) ) + if( *(szText + ulPos) == *(szSub + ulSubPos) ) { - lSubPos++; - lPos++; + ulSubPos++; + ulPos++; } - else if( lSubPos ) - lSubPos = 0; + else if( ulSubPos ) + ulSubPos = 0; else - lPos++; + ulPos++; } - return (lSubPos < lSubLen? 0: lPos - lSubLen + 1); + return (ulSubPos < ulSubLen ? 0: ulPos - ulSubLen + 1); } else return 0; @@ -615,26 +613,26 @@ HARBOUR HB_AT( void ) /* TEST: QOUT( "rat( 'cde', 'abcdefgfedcba' ) = '" + rat( 'cde', 'abcdefgfedcba' ) + "'" ) */ HARBOUR HB_RAT( void ) { - long lSubLen = hb_parclen(1); + ULONG ulSubLen = hb_parclen(1); - if( lSubLen ) + if( ulSubLen ) { - long lPos = hb_parclen(2) - lSubLen; + long lPos = hb_parclen(2) - ulSubLen; if( lPos < 0 ) hb_retni(0); else { char *szSub = hb_parc(1); char *szText = hb_parc(2); - int bFound = 0; + BOOL bFound = FALSE; while( lPos >= 0 && !bFound ) { if( *(szText + lPos) == *szSub ) - bFound = !memcmp(szSub, szText + lPos, lSubLen); + bFound = ( memcmp(szSub, szText + lPos, ulSubLen) == 0 ); lPos--; } - hb_retnl( bFound? lPos + 2: 0 ); + hb_retnl( bFound ? lPos + 2: 0 ); } } else @@ -655,7 +653,7 @@ HARBOUR HB_CHR( void ) /* Believe it or not, clipper does this! */ chr[0] = hb_parnl(1) % 256; - chr[1] = 0; + chr[1] = '\0'; hb_retclen(chr, 1); } else @@ -838,10 +836,10 @@ HARBOUR HB_SUBSTR( void ) } /* converts szText to lower case. Does not create a new string! */ -char *hb_strLower(char *szText, long lLen) +char *hb_strLower(char *szText, ULONG ulLen) { - long i; - for( i = 0; i < lLen; i++ ) + ULONG i; + for( i = 0; i < ulLen; i++ ) szText[i] = tolower(szText[i]); return szText; } @@ -871,11 +869,19 @@ HARBOUR HB_LOWER( void ) } } -/* converts szText to upper case. Does not create a new string! */ -char *hb_strUpper(char *szText, long lLen) +void hb_strupr( char * szText ) { - long i; - for( i = 0; i < lLen; i++ ) + char *p; + + for( p = szText; *p; p++ ) + *p = toupper( *p ); +} + +/* converts szText to upper case. Does not create a new string! */ +char *hb_strUpper(char *szText, ULONG ulLen) +{ + ULONG i; + for( i = 0; i < ulLen; i++ ) szText[i] = toupper(szText[i]); return szText; } @@ -911,32 +917,32 @@ HARBOUR HB_REPLICATE( void ) { if( hb_pcount() == 2 ) { - PHB_ITEM pText = hb_param(1, IT_STRING); - PHB_ITEM pTimes = hb_param(2, IT_NUMERIC); - - if( pText && pTimes ) + if( ISCHAR(1) && ISNUM(2) ) { - long lTimes = hb_parnl(2); + LONG lTimes = hb_parnl(2); if( lTimes > 0 ) { - char *szText = pText->item.asString.value; - long lLen = pText->item.asString.length; - char *szResult = (char *)hb_xgrab((lLen * lTimes) + 1); - char *szPtr = szResult; - long i; + ULONG ulLen = hb_parclen(1); - for( i = 0; i < lTimes; i++ ) + if ( (double)((double)ulLen * (double)lTimes) < (double)ULONG_MAX ) { - memcpy(szPtr, szText, lLen); - szPtr += lLen; + char *szText = hb_parc(1); + char *szResult = (char *)hb_xgrab((ulLen * lTimes) + 1); + char *szPtr = szResult; + LONG i; + + for( i = 0; i < lTimes; i++ ) + { + memcpy(szPtr, szText, ulLen); + szPtr += ulLen; + } + + hb_retclen(szResult, ulLen * lTimes); + hb_xfree(szResult); } - - /* TODO: Check for string overflow */ - /* hb_errRT_BASE(EG_STROVERFLOW, 1234, NULL, "REPLICATE"); */ - - hb_retclen(szResult, lLen * lTimes); - hb_xfree(szResult); + else + hb_errRT_BASE(EG_STROVERFLOW, 1234, NULL, "REPLICATE"); } else hb_retc(""); @@ -963,13 +969,15 @@ HARBOUR HB_SPACE( void ) if( pLen ) { - long lLen = hb_parnl(1); + LONG lLen = hb_parnl(1); if( lLen > 0 ) { char *szResult = (char *)hb_xgrab(lLen + 1); - /* TODO: Check for string overflow */ + /* NOTE: String overflow could never occure since a string can */ + /* be as large as ULONG_MAX, and the maximum length that */ + /* can be specified is LONG_MAX here. */ /* hb_errRT_BASE(EG_STROVERFLOW, 1233, NULL, "SPACE"); */ memset(szResult, ' ', lLen); @@ -994,54 +1002,35 @@ HARBOUR HB_SPACE( void ) /* replaces characters in a string */ HARBOUR HB_STUFF( void ) { - PHB_ITEM pText; - - pText = hb_param(1, IT_STRING); - if( pText ) + if ( ISCHAR(1) && ISNUM(2) && ISNUM(3) && ISCHAR(4) ) { - char *szText = pText->item.asString.value; - PHB_ITEM pPos, pDel, pInsert; - ULONG lPos, lDel, lInsert, lTotalLen; - char *szInsert; + char *szText = hb_parc(1); + ULONG ulText = hb_parclen(1); + ULONG ulPos = hb_parnl(2); + ULONG ulDel = hb_parnl(3); + ULONG ulInsert = hb_parclen(4); - pPos = hb_param(2, IT_NUMERIC); - lPos = (pPos? hb_itemGetNL( pPos ) - 1: 0); - if( lPos > pText->item.asString.length ) - lPos = pText->item.asString.length; + ULONG ulTotalLen; - pDel = hb_param(3, IT_NUMERIC); - if( pDel ) + if( ulPos > 0) + ulPos--; + + if( ulPos > ulText ) + ulPos = ulText; + + if( ulDel > ulText - ulPos ) + ulDel = ulText - ulPos; + + if( (ulTotalLen = ulText + ulInsert - ulDel) > 0 ) { - lDel = hb_itemGetNL( pDel ); - if( lDel > pText->item.asString.length - lPos ) - lDel = pText->item.asString.length - lPos; - } - else - lDel = 0; + char *szResult = (char *)hb_xgrab(ulTotalLen + 1); - pInsert = hb_param(4, IT_STRING); - if( pInsert ) - { - szInsert = pInsert->item.asString.value; - lInsert = pInsert->item.asString.length; - } - else - { - szInsert = ""; /* shouldn't matter that we don't allocate */ - lInsert = 0; - } + memcpy(szResult, szText, ulPos); + memcpy(szResult + ulPos, hb_parc(4), ulInsert); + memcpy(szResult + ulPos + ulInsert, szText + ulPos + ulDel, ulText - (ulPos + ulDel)); - if( (lTotalLen = pText->item.asString.length + lInsert - lDel) > 0 ) - { - char *szResult = (char *)hb_xgrab(lTotalLen + 1); - - memcpy(szResult, szText, lPos); - memcpy(szResult + lPos, szInsert, lInsert); - memcpy(szResult + lPos + lInsert, szText + lPos + lDel, - pText->item.asString.length - (lPos + lDel)); - - szResult[lTotalLen] = 0; - hb_retclen(szResult, lTotalLen); + szResult[ulTotalLen] = '\0'; + hb_retclen(szResult, ulTotalLen); hb_xfree(szResult); } else @@ -1067,60 +1056,60 @@ HARBOUR HB_STRTRAN( void ) char *szSeek = pSeek->item.asString.value; PHB_ITEM pStart = hb_param(4, IT_NUMERIC); char *szReplace; - ULONG iStart; + ULONG ulStart; - iStart = (pStart? hb_parnl(4): 1); - if( !iStart ) + ulStart = (pStart? hb_parnl(4): 1); + if( !ulStart ) { /* Clipper seems to work this way */ hb_retc(""); } - else if( iStart > 0 ) + else if( ulStart > 0 ) { PHB_ITEM pReplace = hb_param(3, IT_STRING); PHB_ITEM pCount = hb_param(5, IT_NUMERIC); - ULONG iReplace; - ULONG iCount; - long bAll; + ULONG ulReplace; + ULONG ulCount; + BOOL bAll; if( pReplace ) { szReplace = pReplace->item.asString.value; - iReplace = pReplace->item.asString.length; + ulReplace = pReplace->item.asString.length; } else { szReplace = ""; /* shouldn't matter that we don't allocate */ - iReplace = 0; + ulReplace = 0; } if( pCount ) { - iCount = hb_itemGetNL( pCount ); - bAll = 0; + ulCount = hb_itemGetNL( pCount ); + bAll = FALSE; } else { - iCount = 0; - bAll = 1; + ulCount = 0; + bAll = TRUE; } - if( bAll || iCount > 0 ) + if( bAll || ulCount > 0 ) { - long iFound = 0; - long iReplaced = 0; + LONG lFound = 0; + LONG lReplaced = 0; ULONG i = 0; - ULONG iLength = pText->item.asString.length; + ULONG ulLength = pText->item.asString.length; while( i < pText->item.asString.length ) { - if( (bAll || iReplaced < iCount) && !memcmp(szText + i, szSeek, pSeek->item.asString.length) ) + if( (bAll || lReplaced < ulCount) && !memcmp(szText + i, szSeek, pSeek->item.asString.length) ) { - iFound++; - if( iFound >= iStart ) + lFound++; + if( lFound >= ulStart ) { - iReplaced++; - iLength = iLength - pSeek->item.asString.length + iReplace; + lReplaced++; + ulLength = ulLength - pSeek->item.asString.length + ulReplace; i += pSeek->item.asString.length; } else @@ -1130,23 +1119,23 @@ HARBOUR HB_STRTRAN( void ) i++; } - if( iFound ) + if( lFound ) { - char *szResult = (char *)hb_xgrab(iLength + 1); + char *szResult = (char *)hb_xgrab(ulLength + 1); char *szPtr = szResult; - iFound = 0; + lFound = 0; i = 0; while( i < pText->item.asString.length ) { - if( iReplaced && !memcmp(szText + i, szSeek, pSeek->item.asString.length) ) + if( lReplaced && !memcmp(szText + i, szSeek, pSeek->item.asString.length) ) { - iFound++; - if( iFound >= iStart ) + lFound++; + if( lFound >= ulStart ) { - iReplaced--; - memcpy(szPtr, szReplace, iReplace); - szPtr += iReplace; + lReplaced--; + memcpy(szPtr, szReplace, ulReplace); + szPtr += ulReplace; i += pSeek->item.asString.length; } else @@ -1163,7 +1152,7 @@ HARBOUR HB_STRTRAN( void ) i++; } } - hb_retclen(szResult, iLength); + hb_retclen(szResult, ulLength); hb_xfree(szResult); } else @@ -1318,7 +1307,7 @@ char * hb_itemStr( PHB_ITEM pNumber, PHB_ITEM pWidth, PHB_ITEM pDec ) if( iDec > 0 ) iBytes = sprintf( szResult, "%*.*f", iSize, iDec, dNumber ); else - iBytes = sprintf( szResult, "%*ld", iWidth, (long)dNumber ); + iBytes = sprintf( szResult, "%*ld", iWidth, (LONG)dNumber ); } } else switch( pNumber->type & ~IT_BYREF ) @@ -1333,7 +1322,7 @@ char * hb_itemStr( PHB_ITEM pNumber, PHB_ITEM pWidth, PHB_ITEM pDec ) default: iBytes = 0; - *szResult = 0; + *szResult = NULL; break; } /* Set to asterisks in case of overflow */ @@ -1356,8 +1345,8 @@ HARBOUR HB_STR( void ) { BOOL bValid = TRUE; PHB_ITEM pNumber = hb_param( 1, IT_NUMERIC ); - PHB_ITEM pWidth = 0; - PHB_ITEM pDec = 0; + PHB_ITEM pWidth = NULL; + PHB_ITEM pDec = NULL; if( !pNumber ) bValid = FALSE; @@ -1401,7 +1390,7 @@ HARBOUR HB_STR( void ) /* Values returned : HB_STRGREATER_EQUAL, HB_STRGREATER_LEFT, HB_STRGREATER_RIGHT */ -WORD hb_strgreater( char * sz1, char * sz2 ) +int hb_strgreater( char * sz1, char * sz2 ) { while( *( sz1 ) && *( sz2 ) && *( sz1 ) == *( sz2 ) ) @@ -1419,11 +1408,3 @@ WORD hb_strgreater( char * sz1, char * sz2 ) return HB_STRGREATER_EQUAL; } - -void hb_strupr( char * szText ) -{ - char *p; - - for( p = szText; *p; p++ ) - *p = toupper( *p ); -} diff --git a/harbour/source/vm/dynsym.c b/harbour/source/vm/dynsym.c index f42dc5ed40..d225febfc9 100644 --- a/harbour/source/vm/dynsym.c +++ b/harbour/source/vm/dynsym.c @@ -78,7 +78,7 @@ PHB_DYNS hb_dynsymNew( PHB_SYMB pSymbol ) /* creates a new dynamic symbol */ return pDynSym; /* Return pointer to DynSym */ } - if( ! wDynSymbols ) /* Do we have any symbols ? */ + if( wDynSymbols == 0 ) /* Do we have any symbols ? */ pDynSym = pDynItems[ 0 ].pDynSym; /* Point to first symbol */ /* *<1>* Remember we already got this one */ else diff --git a/harbour/source/vm/hvm.c b/harbour/source/vm/hvm.c index 9b35c881e3..2e6ce65c44 100644 --- a/harbour/source/vm/hvm.c +++ b/harbour/source/vm/hvm.c @@ -109,7 +109,7 @@ HB_ITEM aStatics; /* Harbour array to hold all application statics vari HB_ITEM errorBlock; /* errorblock */ PSYMBOLS pSymbols = 0; /* to hold a linked list of all different modules symbol tables */ BOOL bQuit = FALSE; /* inmediately exit the application */ -BYTE bErrorLevel = 0; /* application exit errorlevel */ +BYTE byErrorLevel = 0; /* application exit errorlevel */ #define HB_DEBUG( x ) if( bHB_DEBUG ) printf( x ) #define HB_DEBUG2( x, y ) if( bHB_DEBUG ) printf( x, y ) @@ -212,7 +212,7 @@ int main( int argc, char * argv[] ) printf( "memory size not released: %ld\n", ulMemoryConsumed ); } - return bErrorLevel; + return byErrorLevel; } void hb_vmExecute( BYTE * pCode, PHB_SYMB pSymbols ) @@ -2334,7 +2334,7 @@ HARBOUR HB_EMPTY(void) break; case IT_STRING: - hb_retl( hb_strempty( hb_parc( 1 ), hb_parclen( 1 ) ) ); + hb_retl( hb_strEmpty( hb_parc( 1 ), hb_parclen( 1 ) ) ); break; case IT_INTEGER: @@ -2503,12 +2503,13 @@ HARBOUR HB___QUIT(void) HARBOUR HB_ERRORLEVEL(void) { - BYTE bPrevValue = bErrorLevel; + BYTE byPrevValue = byErrorLevel; if( hb_pcount() > 0 ) /* Only replace the error level if a parameter was passed */ - bErrorLevel = hb_parni( 1 ); - hb_retni( bPrevValue ); + byErrorLevel = hb_parni( 1 ); + + hb_retni( byPrevValue ); } HARBOUR HB_PCOUNT(void) diff --git a/harbour/tests/working/rtl_test.prg b/harbour/tests/working/rtl_test.prg index 045de05243..7180914352 100644 --- a/harbour/tests/working/rtl_test.prg +++ b/harbour/tests/working/rtl_test.prg @@ -64,6 +64,29 @@ FUNCTION Main() TEST_LINE( At("ABCDEFG", "ABCDEF") , 0 ) TEST_LINE( At("FI", "ABCDEF") , 0 ) + /* RAT() */ + + TEST_LINE( RAt("", "") , 0 ) + TEST_LINE( RAt("", "ABCDEF") , 0 ) + TEST_LINE( RAt("ABCDEF", "") , 0 ) + TEST_LINE( RAt("AB", "AB") , 1 ) + TEST_LINE( RAt("AB", "AAB") , 2 ) + TEST_LINE( RAt("AB", "ABAB") , 3 ) + TEST_LINE( RAt("A", "ABCADEF") , 4 ) + TEST_LINE( RAt("A", "ABCADEFA") , 8 ) + TEST_LINE( RAt("A", "ABCDEFA") , 7 ) + TEST_LINE( RAt("A", "ABCDEF") , 1 ) + TEST_LINE( RAt("F", "ABCDEF") , 6 ) + TEST_LINE( RAt("D", "ABCDEF") , 4 ) + TEST_LINE( RAt("X", "ABCDEF") , 0 ) + TEST_LINE( RAt("AB", "ABCDEF") , 1 ) + TEST_LINE( RAt("AA", "ABCDEF") , 0 ) + TEST_LINE( RAt("ABCDEF", "ABCDEF") , 1 ) + TEST_LINE( RAt("BCDEF", "ABCDEF") , 2 ) + TEST_LINE( RAt("BCDEFG", "ABCDEF") , 0 ) + TEST_LINE( RAt("ABCDEFG", "ABCDEF") , 0 ) + TEST_LINE( RAt("FI", "ABCDEF") , 0 ) + /* SUBSTR() */ TEST_LINE( SubStr("abcdef", 0, -1) , "" ) @@ -114,6 +137,9 @@ FUNCTION Main() /* PADR() */ + TEST_LINE( PadR(NIL, 5) , "" ) + TEST_LINE( PadR(.T., 5) , "" ) + TEST_LINE( PadR(10, 5) , "10 " ) TEST_LINE( PadR("abcdef", -5) , "" ) TEST_LINE( PadR("abcdef", 0) , "" ) TEST_LINE( PadR("abcdef", 5) , "abcde" ) @@ -123,6 +149,9 @@ FUNCTION Main() /* PADL() */ + TEST_LINE( PadL(NIL, 5) , "" ) + TEST_LINE( PadL(.T., 5) , "" ) + TEST_LINE( PadL(10, 5) , " 10" ) TEST_LINE( PadL("abcdef", -5) , "" ) TEST_LINE( PadL("abcdef", 0) , "" ) TEST_LINE( PadL("abcdef", 5) , "abcde" ) /* QUESTION: CA-Cl*pper "bug", should return: "bcdef" ? */ @@ -132,6 +161,9 @@ FUNCTION Main() /* PADC() */ + TEST_LINE( PadC(NIL, 5) , "" ) + TEST_LINE( PadC(.T., 5) , "" ) + TEST_LINE( PadC(10, 5) , " 10 " ) TEST_LINE( PadC("abcdef", -5) , "" ) TEST_LINE( PadC("abcdef", 0) , "" ) TEST_LINE( PadC("abcdef", 2) , "ab" ) /* QUESTION: CA-Cl*pper "bug", should return: "cd" ? */ @@ -140,6 +172,18 @@ FUNCTION Main() TEST_LINE( PadC("abcdef", 10, "1") , "11abcdef11" ) TEST_LINE( PadC("abcdef", 10, "12") , "11abcdef11" ) + TEST_LINE( Stuff("ABCDEF", 0, 0, NIL) , "" ) + TEST_LINE( Stuff("ABCDEF", 0, 0, "xyz") , "xyzABCDEF" ) + TEST_LINE( Stuff("ABCDEF", 1, 0, "xyz") , "xyzABCDEF" ) + TEST_LINE( Stuff("ABCDEF", 2, 0, "xyz") , "AxyzBCDEF" ) + TEST_LINE( Stuff("ABCDEF", 2, 3, "xyz") , "AxyzEF" ) + TEST_LINE( Stuff("ABCDEF", 2, 2, "") , "ADEF" ) + TEST_LINE( Stuff("ABCDEF", 2, 1, "xyz") , "AxyzCDEF" ) + TEST_LINE( Stuff("ABCDEF", 2, 4, "xyz") , "AxyzF" ) + TEST_LINE( Stuff("ABCDEF", 2, 10, "xyz") , "Axyz" ) + +#ifdef __HARBOUR__ + /* __COLORINDEX() */ TEST_LINE( __ColorIndex() , "" ) @@ -179,6 +223,8 @@ FUNCTION Main() TEST_LINE( __ColorIndex(",,", 2) , "" ) TEST_LINE( __ColorIndex(", ,", 2) , "" ) +#endif + /* Show results, return ERRORLEVEL and exit */ TEST_STAT() diff --git a/harbour/tests/working/testpre.prg b/harbour/tests/working/testpre.prg index a8498db22e..efca44096f 100644 --- a/harbour/tests/working/testpre.prg +++ b/harbour/tests/working/testpre.prg @@ -15,27 +15,27 @@ FUNCTION Main() cString := "@ 10, 10 SAY 'Hello!'" qOut( cString ) - qOut( Preprocess( cString ) ) + qOut( __Preprocess( cString ) ) qOut( "" ) cString := "? 'Hello mom'" qOut( cString ) - qOut( Preprocess( cString ) ) + qOut( __Preprocess( cString ) ) qOut( "" ) cString := 'SET RELATION TO Something INTO MySelf' qOut( cString ) - qOut( Preprocess( cString ) ) + qOut( __Preprocess( cString ) ) qOut( "" ) cString := 'SET RELATION ADDITIVE TO Something INTO YourSelf' qOut( cString ) - qOut( Preprocess( cString ) ) + qOut( __Preprocess( cString ) ) qOut( "" ) cString := 'CLOSE ALL' qOut( cString ) - qOut( Preprocess( cString ) ) + qOut( __Preprocess( cString ) ) qOut( "" ) qOut( chr(13)+chr(10)+"Press ..." ) @@ -54,12 +54,12 @@ FUNCTION Main() 'CLOSE ALL' } FOR j := 1 TO 2 - qOut( if( j = 1, "Before", "After" ) + " Preprocess()" ) + qOut( if( j = 1, "Before", "After" ) + " __Preprocess()" ) qOut( "===================" ) qOut( "" ) FOR i := 1 TO len( aScript ) - ? if( j = 1, aScript[i], Preprocess( aScript[i] ) ) + ? if( j = 1, aScript[i], __Preprocess( aScript[i] ) ) NEXT qOut( "" )