diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 6bfde66f19..6485038ae8 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -1,3 +1,22 @@ +19991027-17:24 GMT+1 Victor Szel + * source/rtl/strings.c + source/rtl/descend.c + include/extend.h + % hb_strEmpty(), hb_str*cmp() a few optimalizations. + + Using const keyword for hb_str*() function parameters. + * Small formatting, some Hungarian notations adjusted. + + CHR() STRICT mode replaced with a comment, that the buggy Clipper + behaviour should (or should not) be implemented in the Harbour compiler + optimizer. + - tests/hardcr.prg + - tests/mtran.prg + tests/Makefile + + These test files has been removed, since they were moved to RTL_TEST + * tests/rtl_test.prg + * Some CHR() tests simplified, one added to show the buggy Clipper + behaviour. + + HARDCR(), MEMOTRAN() tests added. + 19991027-16:57 GMT+1 Antonio Linares * source/vm/mainwin.c * added missing #includes. diff --git a/harbour/include/extend.h b/harbour/include/extend.h index dddb56a01d..68a36f9b1c 100644 --- a/harbour/include/extend.h +++ b/harbour/include/extend.h @@ -334,17 +334,18 @@ extern PHB_ITEM hb_arrayClone( PHB_ITEM pArray ); extern int hb_stricmp( const char * s1, const char * s2 ); extern int hb_strnicmp( const char * s1, const char * s2, ULONG ulLen ); -extern int hb_strgreater( char * szText1, char * szText2 ); +extern int hb_strgreater( const char * szText1, const char * szText2 ); extern void hb_strupr( char * szText ); -extern BOOL hb_strMatchRegExp( char * szString, char * szMask ); -extern BOOL hb_strEmpty( char * szText, ULONG ulLen ); -extern void hb_strDescend( char * szStringTo, char * szStringFrom, ULONG ulLen ); -extern ULONG hb_strAt( char * szSub, ULONG ulSubLen, char * szText, ULONG ulLen ); +extern BOOL hb_strMatchRegExp( const char * szString, const char * szMask ); +extern BOOL hb_strEmpty( const char * szText, ULONG ulLen ); +extern void hb_strDescend( char * szStringTo, const char * szStringFrom, ULONG ulLen ); +extern ULONG hb_strAt( const char * szSub, ULONG ulSubLen, const char * szText, ULONG ulLen ); extern char * hb_strUpper( char * szText, ULONG ulLen ); extern char * hb_strLower( char * szText, ULONG ulLen ); -extern char * hb_strncpyUpper( char * pDest, char * pSource, ULONG ulLen ); -extern double hb_strVal( char * szText ); -extern char * hb_strLTrim( char * szText, ULONG * ulLen ); +extern char * hb_strncpyUpper( char * pDest, const char * pSource, ULONG ulLen ); +extern double hb_strVal( const char * szText ); +extern char * hb_strLTrim( const char * szText, ULONG * ulLen ); +extern ULONG hb_strRTrimLen( const char * szText, ULONG ulLen, BOOL bAnySpace ); extern double hb_numRound( double dResult, int iDec ); @@ -354,7 +355,7 @@ extern void hb_clsReleaseAll( void ); /* releases all defined classes */ /* object management */ extern char * hb_objGetClsName( PHB_ITEM pObject ); /* retrieves an object class name */ extern PHB_FUNC hb_objGetMethod( PHB_ITEM pObject, PHB_SYMB pSymMsg ); /* returns the method pointer of a object class */ -extern ULONG hb_objHasMsg( PHB_ITEM pObject, char *szString ); +extern ULONG hb_objHasMsg( PHB_ITEM pObject, char * szString ); /* dynamic symbol table management */ extern PHB_DYNS hb_dynsymGet( char * szName ); /* finds and creates a dynamic symbol if not found */ diff --git a/harbour/source/rtl/descend.c b/harbour/source/rtl/descend.c index f940e77317..9baec813e4 100644 --- a/harbour/source/rtl/descend.c +++ b/harbour/source/rtl/descend.c @@ -67,7 +67,7 @@ #include "extend.h" #include "itemapi.h" -void hb_strDescend( char * szStringTo, char * szStringFrom, ULONG ulLen ) +void hb_strDescend( char * szStringTo, const char * szStringFrom, ULONG ulLen ) { HB_TRACE(("hb_strDescend(%s, %s, %lu)", szStringTo, szStringFrom, ulLen)); diff --git a/harbour/source/rtl/strings.c b/harbour/source/rtl/strings.c index 85b2b87451..f9d734eea8 100644 --- a/harbour/source/rtl/strings.c +++ b/harbour/source/rtl/strings.c @@ -79,10 +79,8 @@ HB_CALL_ON_STARTUP_END( Strings_InitInfinity ) #endif -BOOL hb_strEmpty( char * szText, ULONG ulLen ) +BOOL hb_strEmpty( const char * szText, ULONG ulLen ) { - BOOL bRetVal = TRUE; - HB_TRACE(("hb_strEmpty(%s, %lu)", szText, ulLen)); while( ulLen-- ) @@ -90,13 +88,10 @@ BOOL hb_strEmpty( char * szText, ULONG ulLen ) char c = szText[ ulLen ]; if( !HB_ISSPACE( c ) ) - { - bRetVal = FALSE; - break; - } + return FALSE; } - return bRetVal; + return TRUE; } int hb_stricmp( const char * s1, const char * s2 ) @@ -110,10 +105,7 @@ int hb_stricmp( const char * s1, const char * s2 ) l1 = strlen( s1 ); l2 = strlen( s2 ); - if( l1 < l2 ) - count = l1; - else - count = l2; + count = ( l1 < l2 ? l1 : l2 ); while( rc == 0 && count > 0 ) { @@ -127,12 +119,7 @@ int hb_stricmp( const char * s1, const char * s2 ) } if( rc == 0 && l1 != l2 ) - { - if( l1 < l2 ) - rc = -1; - else - rc = 1; - } + rc = ( l1 < l2 ? -1 : 1 ); return rc; } @@ -149,11 +136,7 @@ int hb_strnicmp( const char * s1, const char * s2, ULONG count ) l2 = strlen( s2 ); if( l1 > count ) l1 = count; - - if( l1 < l2 ) - count = l1; - else - count = l2; + count = ( l1 < l2 ? l1 : l2 ); while( rc == 0 && count > 0 ) { @@ -167,17 +150,12 @@ int hb_strnicmp( const char * s1, const char * s2, ULONG count ) } if( rc == 0 && l1 != l2 ) - { - if( l1 < l2 ) - rc = -1; - else - rc = 1; - } + rc = ( l1 < l2 ? -1 : 1 ); return rc; } -static BOOL hb_strMatchDOS( char * pszString, char * pszMask ) +static BOOL hb_strMatchDOS( const char * pszString, const char * pszMask ) { HB_TRACE(("hb_strMatchDOS(%s, %s)", pszString, pszMask)); @@ -225,7 +203,7 @@ static BOOL hb_strMatchDOS( char * pszString, char * pszMask ) /* TODO: Replace it with a code that supports real regular expressions * */ -BOOL hb_strMatchRegExp( char * szString, char * szMask ) +BOOL hb_strMatchRegExp( const char * szString, const char * szMask ) { HB_TRACE(("hb_strMatchRegExp(%s, %s)", szString, szMask)); @@ -267,17 +245,17 @@ HARBOUR HB_ISLOWER( void ) /* trims from the left, and returns a new pointer to szText */ /* also returns the new length in lLen */ -char * hb_strLTrim( char * szText, ULONG * lLen ) +char * hb_strLTrim( const char * szText, ULONG * ulLen ) { - HB_TRACE(("hb_strLTrim(%s, %p)", szText, lLen)); + HB_TRACE(("hb_strLTrim(%s, %p)", szText, ulLen)); - while( *lLen && HB_ISSPACE( *szText ) ) + while( *ulLen && HB_ISSPACE( *szText ) ) { szText++; - ( *lLen )--; + ( *ulLen )--; } - return szText; + return ( char * ) szText; } /* trims leading spaces from a string */ @@ -290,10 +268,10 @@ HARBOUR HB_LTRIM( void ) if( pText ) { - ULONG lLen = pText->item.asString.length; - char * szText = hb_strLTrim( pText->item.asString.value, &lLen ); + ULONG ulLen = pText->item.asString.length; + char * szText = hb_strLTrim( pText->item.asString.value, &ulLen ); - hb_retclen( szText, lLen ); + hb_retclen( szText, ulLen ); } else { @@ -311,22 +289,22 @@ HARBOUR HB_LTRIM( void ) } /* returns szText and the new length in lLen */ -ULONG hb_strRTrimLen( char * szText, ULONG lLen, BOOL bAnySpace ) +ULONG hb_strRTrimLen( const char * szText, ULONG ulLen, BOOL bAnySpace ) { - HB_TRACE(("hb_strRTrimLen(%s, %lu. %d)", szText, lLen, (int) bAnySpace)); + HB_TRACE(("hb_strRTrimLen(%s, %lu. %d)", szText, ulLen, (int) bAnySpace)); if( bAnySpace ) { - while( lLen && HB_ISSPACE( szText[ lLen - 1 ] ) ) - lLen--; + while( ulLen && HB_ISSPACE( szText[ ulLen - 1 ] ) ) + ulLen--; } else { - while( lLen && szText[ lLen - 1 ] == ' ' ) - lLen--; + while( ulLen && szText[ ulLen - 1 ] == ' ' ) + ulLen--; } - return lLen; + return ulLen; } /* NOTE: The second parameter is a Harbour extension */ @@ -379,13 +357,11 @@ HARBOUR HB_ALLTRIM( void ) { char * szText = hb_parc( 1 ); BOOL bAnySpace = ( ISLOG( 2 ) ? hb_parl( 2 ) : FALSE ); - ULONG lLen; + ULONG ulLen = hb_strRTrimLen( szText, hb_parclen( 1 ), bAnySpace ); - lLen = hb_strRTrimLen( szText, hb_parclen( 1 ), bAnySpace ); + szText = hb_strLTrim( szText, &ulLen ); - szText = hb_strLTrim( szText, &lLen ); - - hb_retclen( szText, lLen ); + hb_retclen( szText, ulLen ); } else #ifdef HB_COMPAT_C53 @@ -584,7 +560,7 @@ HARBOUR HB_PADC( void ) hb_retc( "" ); } -ULONG hb_strAt( char * szSub, ULONG ulSubLen, char * szText, ULONG ulLen ) +ULONG hb_strAt( const char * szSub, ULONG ulSubLen, const char * szText, ULONG ulLen ) { HB_TRACE(("hb_strAt(%s, %lu, %s, %lu)", szSub, ulSubLen, szText, ulLen)); @@ -682,22 +658,16 @@ HARBOUR HB_CHR( void ) { char szChar[ 2 ]; - /* Believe it or not, clipper does this! */ + /* NOTE: CA-Cl*pper's compiler optimizer will be wrong for those + CHR() cases where the passed parameter is a constant which + can be divided by 256 but it's not zero, in this case it + will return an empty string instead of a Chr(0). [vszel] */ -#ifdef HARBOUR_STRICT_CLIPPER_COMPATIBILITY - long lValue = hb_parnl( 1 ); - - szChar[ 0 ] = lValue % 256; - szChar[ 1 ] = '\0'; - - hb_retclen( szChar, lValue != 0 && szChar[ 0 ] == '\0' ? 0 : 1 ); -#else /* Believe it or not, clipper does this! */ szChar[ 0 ] = hb_parnl( 1 ) % 256; szChar[ 1 ] = '\0'; hb_retclen( szChar, 1 ); -#endif } else { @@ -944,7 +914,7 @@ char * hb_strUpper( char * szText, ULONG ulLen ) /* This function copies and converts szText to upper case. */ -char * hb_strncpyUpper( char * pDest, char * pSource, ULONG ulLen ) +char * hb_strncpyUpper( char * pDest, const char * pSource, ULONG ulLen ) { char * pStart = pDest; @@ -1287,7 +1257,7 @@ HARBOUR HB_STRTRAN( void ) } /* returns the numeric value of a character string representation of a number */ -double hb_strVal( char * szText ) +double hb_strVal( const char * szText ) { HB_TRACE(("hb_strVal(%s)", szText)); @@ -1615,21 +1585,22 @@ HARBOUR HB_STRZERO( void ) /* Values returned : HB_STRGREATER_EQUAL, HB_STRGREATER_LEFT, HB_STRGREATER_RIGHT */ -int hb_strgreater( char * szText1, char * szText2 ) +int hb_strgreater( const char * szText1, const char * szText2 ) { HB_TRACE(("hb_strgreater(%s, %s)", szText1, szText2)); - while( *( szText1 ) && *( szText2 ) && *( szText1 ) == *( szText2 ) ) + while( *szText1 && *szText2 && *szText1 == *szText2 ) { - szText1++; - szText2++; + szText1++; + szText2++; } - if( ( *( szText1 ) == '\0' && *( szText2 ) != '\0' ) || - ( *( szText2 ) > *( szText1 ) ) ) + + if( ( *szText1 == '\0' && *szText2 != '\0' ) || + ( *szText1 < *szText2 ) ) return HB_STRGREATER_RIGHT; - if( ( *( szText1 ) != '\0' && *( szText2 ) == '\0' ) || - ( *( szText1 ) > *( szText2 ) ) ) + if( ( *szText1 != '\0' && *szText2 == '\0' ) || + ( *szText1 > *szText2 ) ) return HB_STRGREATER_LEFT; return HB_STRGREATER_EQUAL; diff --git a/harbour/tests/Makefile b/harbour/tests/Makefile index 07af96b5b4..2079ec6ce3 100644 --- a/harbour/tests/Makefile +++ b/harbour/tests/Makefile @@ -69,7 +69,6 @@ PRG_SOURCES=\ fornext.prg \ fortest.prg \ funcarr.prg \ - hardcr.prg \ hello.prg \ ifelse.prg \ ifinline.prg \ @@ -88,7 +87,6 @@ PRG_SOURCES=\ memory.prg \ memvar.prg \ menutest.prg \ - mtran.prg \ multiarg.prg \ nums.prg \ objarr.prg \ diff --git a/harbour/tests/hardcr.prg b/harbour/tests/hardcr.prg deleted file mode 100644 index b239fe1a57..0000000000 --- a/harbour/tests/hardcr.prg +++ /dev/null @@ -1,35 +0,0 @@ -// -// $Id$ -// - - -function main() - local cString - - cString := "[HARBOUR]" + chr(141)+chr(10) + ; - "[POWER]" + chr(141)+chr(10) + ; - "[WHATEVER]" + chr(141) + ; - "[MAGIC]" - - OutSpec( cString ) - OutSpec( HardCR( cString ) ) - - cString := "[HAR" + Chr(0) + "BOUR]" + chr(141)+chr(10) + ; - Chr(0) + "[POWER]" + chr(141)+chr(10) + ; - "[WHATEVER]" + chr(141) + ; - "[MAGIC]" + Chr(0) - - OutSpec( cString ) - OutSpec( HardCR( cString ) ) - -return nil - -STATIC FUNCTION OutSpec( cString ) - - cString := StrTran(cString, Chr(13), "!") - cString := StrTran(cString, Chr(10), "?") - - OutStd( ">" + cString + "<" + Chr(13) + Chr(10) ) - - RETURN NIL - diff --git a/harbour/tests/mtran.prg b/harbour/tests/mtran.prg deleted file mode 100644 index e445b19d00..0000000000 --- a/harbour/tests/mtran.prg +++ /dev/null @@ -1,46 +0,0 @@ -// -// $Id$ -// - - -function main() - LOCAL cString - - cString := "[HARBOUR]" + chr(141)+chr(10) + ; - "[POWER]" + chr(13)+chr(10) + ; - "[MAGIC]" - - OutSpec( cString ) - OutSpec( MemoTran( cString ) ) - - cString := "[HAR" + Chr(0) + "OUR]" + chr(141)+chr(10) + ; - "[POWER]" + chr(13)+chr(10) + ; - "[MA" + Chr(0) + "IC]" - - OutSpec( cString ) - OutSpec( MemoTran( cString ) ) - - cString := "Mr. Chandler " + Chr(13) +; - " something " + Chr(13) + Chr(10) +; - " wonderful " + Chr(141) +; - " will " + Chr(141) + Chr(10) +; - " happen" + Chr(13) - - OutSpec( cString ) - OutSpec( MemoTran( cString ) ) - OutSpec( MemoTran( cString, "111", "222" ) ) - OutSpec( MemoTran( cString, "", "" ) ) - OutSpec( MemoTran() ) - OutSpec( MemoTran( 100 ) ) - -return nil - -STATIC FUNCTION OutSpec( cString ) - - cString := StrTran(cString, Chr(13), "!") - cString := StrTran(cString, Chr(10), "?") - - OutStd( ">" + cString + "<" + Chr(13) + Chr(10) ) - - RETURN NIL - diff --git a/harbour/tests/rtl_test.prg b/harbour/tests/rtl_test.prg index 26bff92046..b165b9d22f 100644 --- a/harbour/tests/rtl_test.prg +++ b/harbour/tests/rtl_test.prg @@ -1223,7 +1223,6 @@ STATIC FUNCTION Main_MATH() RETURN NIL STATIC FUNCTION Main_STRINGS() - LOCAL xLocal /* VAL() */ @@ -1249,11 +1248,12 @@ STATIC FUNCTION Main_STRINGS() TEST_LINE( Chr( 66.5 ) , "B" ) TEST_LINE( Chr( 66.6 ) , "B" ) TEST_LINE( Chr( 255 ) , "ÿ" ) - TEST_LINE( Chr( xLocal := 256 ) , ""+Chr(0)+"" ) /* xLocal should be used here to avoid the optimizer of the CA-Cl*pper compiler */ + TEST_LINE( Chr( 256 ) , ""+Chr(0)+"" ) /* Due to a bug in CA-Cl*pper compiler optimizer, a wrong result will be calculated ar compile time: "" */ + TEST_LINE( Chr( ( 256 ) ) , ""+Chr(0)+"" ) /* Double paranthesis should be used here to avoid the optimizer of the CA-Cl*pper compiler */ TEST_LINE( Chr( 257 ) , "" ) - TEST_LINE( Chr( xLocal := 512 ) , ""+Chr(0)+"" ) /* xLocal should be used here to avoid the optimizer of the CA-Cl*pper compiler */ + TEST_LINE( Chr( ( 512 ) ) , ""+Chr(0)+"" ) /* Double paranthesis should be used here to avoid the optimizer of the CA-Cl*pper compiler */ TEST_LINE( Chr( 1023 ) , "ÿ" ) - TEST_LINE( Chr( xLocal := 1024 ) , ""+Chr(0)+"" ) /* xLocal should be used here to avoid the optimizer of the CA-Cl*pper compiler */ + TEST_LINE( Chr( ( 1024 ) ) , ""+Chr(0)+"" ) /* Double paranthesis should be used here to avoid the optimizer of the CA-Cl*pper compiler */ TEST_LINE( Chr( 1025 ) , "" ) TEST_LINE( Chr( 1000 ) , "è" ) TEST_LINE( Chr( 100000 ) , " " ) @@ -2934,6 +2934,39 @@ STATIC FUNCTION Main_MISC() TEST_LINE( MEMVARBLOCK( "mxNotHere" ) , NIL ) TEST_LINE( MEMVARBLOCK( "mcString" ) , "{||...}" ) + /* Defines for HARDCR() and MEMOTRAN() */ + + #define SO Chr( 141 ) + #define NU Chr( 0 ) + #define LF Chr( 10 ) + #define CR Chr( 13 ) + + /* HARDCR() */ + + TEST_LINE( HardCR() , "" ) + TEST_LINE( HardCR(NIL) , "" ) + TEST_LINE( HardCR(100) , "" ) +#ifdef __HARBOUR__ + TEST_LINE( HardCR(@scString) , "HELLO" ) /* Bug in CA-Cl*pper, it will return "" */ +#endif + TEST_LINE( HardCR("H"+SO+LF+"P"+SO+LF+"W"+SO+"M") , "H"+Chr(13)+""+Chr(10)+"P"+Chr(13)+""+Chr(10)+"WM" ) + TEST_LINE( HardCR("H"+NU+"B"+SO+LF+NU+"P"+SO+LF+"W"+SO+"M"+NU) , "H"+Chr(0)+"B"+Chr(13)+""+Chr(10)+""+Chr(0)+"P"+Chr(13)+""+Chr(10)+"WM"+Chr(0)+"" ) + + /* MEMOTRAN() */ + + TEST_LINE( MemoTran() , "" ) + TEST_LINE( MemoTran(NIL) , "" ) + TEST_LINE( MemoTran(100) , "" ) + TEST_LINE( MemoTran(100,"1","2") , "" ) +#ifdef __HARBOUR__ + TEST_LINE( MemoTran(@scString) , "HELLO" ) /* Bug in CA-Cl*pper, it will return "" */ +#endif + TEST_LINE( MemoTran("H"+SO+LF+"P"+CR+LF+"M") , "H P;M" ) + TEST_LINE( MemoTran("H"+NU+"O"+SO+LF+"P"+CR+LF+"M"+NU+"I") , "H"+Chr(0)+"O P;M"+Chr(0)+"I" ) + TEST_LINE( MemoTran("M"+CR+"s"+CR+LF+"w"+SO+"w"+SO+LF+"h"+CR) , "M"+Chr(13)+"s;ww h"+Chr(13)+"" ) + TEST_LINE( MemoTran("M"+CR+"s"+CR+LF+"w"+SO+"w"+SO+LF+"h"+CR,"111","222"), "M"+Chr(13)+"s1ww2h"+Chr(13)+"" ) + TEST_LINE( MemoTran("M"+CR+"s"+CR+LF+"w"+SO+"w"+SO+LF+"h"+CR,"","") , "M"+Chr(13)+"s"+Chr(0)+"ww"+Chr(0)+"h"+Chr(13)+"" ) + /* MEMOWRITE()/MEMOREAD() */ TEST_LINE( MemoWrit() , .F. )