diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 39e650b4e8..85a83ff5ff 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -17,6 +17,29 @@ past entries belonging to author(s): Viktor Szakats. */ +2009-12-11 20:42 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/src/vm/strapi.c + * harbour/include/hbapistr.h + + added new functions to operate on Harbour wide character strings: + ULONG hb_wstrlen( const HB_WCHAR * szText ); + HB_WCHAR * hb_wstrdup( const HB_WCHAR * szText ); + HB_WCHAR * hb_wstrndup( const HB_WCHAR * szText, ULONG ulLen ); + int hb_wstrcmp( const HB_WCHAR * s1, const HB_WCHAR * s2 ); + int hb_wstrncmp( const HB_WCHAR * s1, + const HB_WCHAR * s2, ULONG count ); + + added new functions to convert NULL pointers to empty strings: + const char * hb_strnull( const char * str ); + const HB_WCHAR * hb_wstrnull( const HB_WCHAR * str ); + + added new functions to convert string buffer returned by Harbour + string functions to writable state: + char * hb_strunshare( void ** phStr, + const char * pStr, ULONG ulLen ); + HB_WCHAR * hb_wstrunshare( void ** phStr, + const HB_WCHAR * pStr, ULONG ulLen ); + * harbour/include/hbwinuni.h + ! fixed HB_PARSTRDEF() to return empty string instead of NULL + ! fixed HB_ARRAYSETSTR() to accept NULL as string parameter + 2009-12-11 20:25 UTC+0100 Viktor Szakats (harbour.01 syenar.hu) * contrib/hbwin/win_regc.c ! WIN_REGSETVALUEEX(): Off by one bug fixed in prev commit. diff --git a/harbour/include/hbapistr.h b/harbour/include/hbapistr.h index 5ef8a9d431..93ac914771 100644 --- a/harbour/include/hbapistr.h +++ b/harbour/include/hbapistr.h @@ -58,6 +58,18 @@ HB_EXTERN_BEGIN +extern HB_EXPORT ULONG hb_wstrlen( const HB_WCHAR * szText ); +extern HB_EXPORT int hb_wstrcmp( const HB_WCHAR * s1, const HB_WCHAR * s2 ); +extern HB_EXPORT int hb_wstrncmp( const HB_WCHAR * s1, const HB_WCHAR * s2, ULONG count ); +extern HB_EXPORT HB_WCHAR * hb_wstrdup( const HB_WCHAR * szText ); +extern HB_EXPORT HB_WCHAR * hb_wstrndup( const HB_WCHAR * szText, ULONG ulLen ); + +extern HB_EXPORT char * hb_strunshare( void ** phStr, const char * pStr, ULONG ulLen ); +extern HB_EXPORT HB_WCHAR * hb_wstrunshare( void ** phStr, const HB_WCHAR * pStr, ULONG ulLen ); +extern HB_EXPORT const char * hb_strnull( const char * str ); +extern HB_EXPORT const HB_WCHAR * hb_wstrnull( const HB_WCHAR * str ); + + extern HB_EXPORT void hb_strfree( void * hString ); extern HB_EXPORT const char * hb_itemGetStr( PHB_ITEM pItem, void * cdp, void ** phString, ULONG * pulLen ); diff --git a/harbour/include/hbwinuni.h b/harbour/include/hbwinuni.h index 0774e03d93..983b26db6a 100644 --- a/harbour/include/hbwinuni.h +++ b/harbour/include/hbwinuni.h @@ -61,27 +61,27 @@ #if defined( UNICODE ) #define HB_PARSTR( n, h, len ) hb_parstr_u16( n, HB_CDP_ENDIAN_NATIVE, h, len ) - #define HB_PARSTRDEF( n, h, len ) hb_parstr_u16( n, HB_CDP_ENDIAN_NATIVE, h, len ) + #define HB_PARSTRDEF( n, h, len ) hb_wstrnull( hb_parstr_u16( n, HB_CDP_ENDIAN_NATIVE, h, len ) ) #define HB_RETSTR( str ) hb_retstr_u16( HB_CDP_ENDIAN_NATIVE, ( const HB_WCHAR * ) ( str ) ) #define HB_RETSTRLEN( str, len ) hb_retstrlen_u16( HB_CDP_ENDIAN_NATIVE, ( const HB_WCHAR * ) ( str ), len ) #define HB_STORSTR( str, n ) hb_storstr_u16( HB_CDP_ENDIAN_NATIVE, ( const HB_WCHAR * ) ( str ), n ) #define HB_STORSTRLEN( str, len, n ) hb_storstrlen_u16( HB_CDP_ENDIAN_NATIVE, ( const HB_WCHAR * ) ( str ), len, n ) #define HB_ARRAYSETSTR( arr, n, str ) \ hb_itemPutStrLenU16( hb_arrayGetItemPtr( arr, n ), \ - HB_CDP_ENDIAN_NATIVE, str, lstrlenW( str ) ) + HB_CDP_ENDIAN_NATIVE, str, hb_wstrlen( hb_wstrnull( str ) ) ) #define HB_ARRAYSETSTRLEN( arr, n, str, len ) \ hb_itemPutStrLenU16( hb_arrayGetItemPtr( arr, n ), \ HB_CDP_ENDIAN_NATIVE, str, len ) #else #define HB_PARSTR( n, h, len ) hb_parstr( n, hb_setGetOSCP(), h, len ) - #define HB_PARSTRDEF( n, h, len ) hb_parstr( n, hb_setGetOSCP(), h, len ) + #define HB_PARSTRDEF( n, h, len ) hb_strnull( hb_parstr( n, hb_setGetOSCP(), h, len ) ) #define HB_RETSTR( str ) hb_retstr( hb_setGetOSCP(), str ) #define HB_RETSTRLEN( str, len ) hb_retstrlen( hb_setGetOSCP(), str, len ) #define HB_STORSTR( str, n ) hb_storstr( hb_setGetOSCP(), str, n ) #define HB_STORSTRLEN( str, len, n ) hb_storstrlen( hb_setGetOSCP(), str, len, n ) #define HB_ARRAYSETSTR( arr, n, str ) \ hb_itemPutStrLen( hb_arrayGetItemPtr( arr, n ), \ - hb_setGetOSCP(), str, strlen( str ) ) + hb_setGetOSCP(), str, strlen( hb_strnull( str ) ) ) #define HB_ARRAYSETSTRLEN( arr, n, str, len ) \ hb_itemPutStrLen( hb_arrayGetItemPtr( arr, n ), \ hb_setGetOSCP(), str, len ) diff --git a/harbour/src/vm/strapi.c b/harbour/src/vm/strapi.c index febe6876b0..45cf73b154 100644 --- a/harbour/src/vm/strapi.c +++ b/harbour/src/vm/strapi.c @@ -58,10 +58,12 @@ static const HB_WCHAR s_szConstStr[ 1 ] = { 0 }; -static ULONG hb_wstrlen( const HB_WCHAR * szText ) +ULONG hb_wstrlen( const HB_WCHAR * szText ) { ULONG ulLen = 0; + HB_TRACE(HB_TR_DEBUG, ("hb_wstrlen(%p)", szText)); + if( szText ) { while( szText[ ulLen ] ) @@ -71,6 +73,140 @@ static ULONG hb_wstrlen( const HB_WCHAR * szText ) return ulLen; } +int hb_wstrcmp( const HB_WCHAR * s1, const HB_WCHAR * s2 ) +{ + int rc = 0; + + HB_TRACE(HB_TR_DEBUG, ("hb_wstrcmp(%p, %p)", s1, s2)); + + for( ;; ) + { + if( *s1 != *s2 ) + { + rc = ( *s1 < *s2 ? -1 : 1 ); + break; + } + else if( *s1 == 0 ) + break; + + s1++; + s2++; + } + + return rc; +} + +int hb_wstrncmp( const HB_WCHAR * s1, const HB_WCHAR * s2, ULONG count ) +{ + int rc = 0; + + HB_TRACE(HB_TR_DEBUG, ("hb_wstrncmp(%p, %p, %lu)", s1, s2, count)); + + while( count-- ) + { + if( *s1 != *s2 ) + { + rc = ( *s1 < *s2 ? -1 : 1 ); + break; + } + else if( *s1 == 0 ) + break; + + s1++; + s2++; + } + + return rc; +} + +HB_WCHAR * hb_wstrdup( const HB_WCHAR * szText ) +{ + HB_WCHAR * pszDest; + ULONG ulSize; + + HB_TRACE(HB_TR_DEBUG, ("hb_wstrdup(%p)", szText)); + + ulSize = ( hb_wstrlen( szText ) + 1 ) * sizeof( HB_WCHAR ); + pszDest = ( HB_WCHAR * ) hb_xgrab( ulSize ); + + memcpy( pszDest, szText, ulSize ); + + return pszDest; +} + +HB_WCHAR * hb_wstrndup( const HB_WCHAR * szText, ULONG ulLen ) +{ + HB_WCHAR * pszDest; + ULONG ulSize; + + HB_TRACE(HB_TR_DEBUG, ("hb_wstrndup(%p,%lu)", szText,ulLen)); + + ulSize = hb_wstrlen( szText ); + if( ulSize < ulLen ) + ulLen = ulSize; + ulSize = ulLen * sizeof( HB_WCHAR ); + pszDest = ( HB_WCHAR * ) hb_xgrab( ulSize + sizeof( HB_WCHAR ) ); + memcpy( pszDest, szText, ulSize ); + pszDest[ ulLen ] = 0; + + return pszDest; +} + +HB_WCHAR * hb_wstrunshare( void ** phStr, const HB_WCHAR * pStr, ULONG ulLen ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_wstrunshare(%p,%p,%lu)", phStr, pStr, ulLen)); + + if( pStr == NULL || phStr == NULL || *phStr == NULL ) + return NULL; + + if( *phStr == ( void * ) s_szConstStr && ulLen > 0 ) + { + HB_WCHAR * pszDest = ( HB_WCHAR * ) hb_xgrab( ( ulLen + 1 ) * + sizeof( HB_WCHAR ) ); + memcpy( pszDest, pStr, ulLen * sizeof( HB_WCHAR ) ); + pszDest[ ulLen ] = 0; + * phStr = ( void * ) pszDest; + + return pszDest; + } + + return ( HB_WCHAR * ) pStr; +} + +char * hb_strunshare( void ** phStr, const char * pStr, ULONG ulLen ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_strunshare(%p,%p,%lu)", phStr, pStr, ulLen)); + + if( pStr == NULL || phStr == NULL || *phStr == NULL ) + return NULL; + + if( *phStr == ( void * ) s_szConstStr && ulLen > 0 ) + { + char * pszDest = ( char * ) hb_xgrab( ( ulLen + 1 ) * sizeof( char ) ); + memcpy( pszDest, pStr, ulLen * sizeof( char ) ); + pszDest[ ulLen ] = 0; + * phStr = ( void * ) pszDest; + + return pszDest; + } + + return ( char * ) pStr; +} + +const char * hb_strnull( const char * str ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_strnull(%p)", str)); + + return str ? str : ""; +} + +const HB_WCHAR * hb_wstrnull( const HB_WCHAR * str ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_wstrnull(%p)", str)); + + return str ? str : s_szConstStr; +} + void hb_strfree( void * hString ) { HB_TRACE(HB_TR_DEBUG, ("hb_strfree(%p)", hString));