diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 7b8269ae9b..66bb497090 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -8,6 +8,26 @@ 2002-12-01 13:30 UTC+0100 Foo Bar */ +2007-07-18 21:30 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/include/hbapicdp.h + * harbour/source/rtl/cdpapi.c + + added C functions: hb_cdpUTF8StringSubstr(), hb_cdpUTF8StringPeek() + + added .prg functions: HB_UTF8SUBSTR(), HB_UTF8LEFT(), HB_UTF8RIGHT(), + HB_UTF8LEN(), HB_UTF8PEEK() + They are working like corresponding functions: SUBSTR(), LEFT(), + RIGHT(), LEN(), STRPEEK() but operates on UTF-8 strings. + TODO: HB_UTF8STUFF(), HB_UTF8TRAN(), HB_UTF8POKE() + + * harbour/include/hbcompat.ch + + added translation rule for str(,,,.t.) + + * harbour/contrib/tip/ftpcln.prg + ! changed str(,,,.t.) to ltrim(str()) + + * harbour/source/rtl/right.c + * harbour/source/rtl/left.c + % minor optimization + 2007-07-18 16:43 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) * harbour/contrib/libct/Makefile * harbour/contrib/libct/makefile.bc diff --git a/harbour/contrib/tip/ftpcln.prg b/harbour/contrib/tip/ftpcln.prg index 80e6a9dc9c..c17414c2dd 100644 --- a/harbour/contrib/tip/ftpcln.prg +++ b/harbour/contrib/tip/ftpcln.prg @@ -274,7 +274,7 @@ RETURN ::GetReply() METHOD Rest( nPos ) CLASS tIPClientFTP - ::InetSendall( ::SocketCon, "REST " + Str( If( Empty( nPos ), 0, nPos ),,, .T. ) + ::cCRLF ) + ::InetSendall( ::SocketCon, "REST " + LTrim( Str( If( Empty( nPos ), 0, nPos ) ) ) + ::cCRLF ) RETURN ::GetReply() diff --git a/harbour/include/hbapicdp.h b/harbour/include/hbapicdp.h index 9690165a31..9ad1760120 100644 --- a/harbour/include/hbapicdp.h +++ b/harbour/include/hbapicdp.h @@ -191,6 +191,8 @@ extern HB_EXPORT ULONG hb_cdpStrnToU16( PHB_CODEPAGE, BOOL, const BYTE * extern HB_EXPORT ULONG hb_cdpStringInUTF8Length( PHB_CODEPAGE, BOOL, const BYTE *, ULONG ); extern HB_EXPORT ULONG hb_cdpUTF8ToStrn( PHB_CODEPAGE, BOOL, const BYTE *, ULONG, BYTE *, ULONG ); extern HB_EXPORT ULONG hb_cdpUTF8StringLength( const BYTE *, ULONG ); +extern HB_EXPORT BYTE * hb_cdpUTF8StringSubstr( const BYTE *, ULONG, ULONG, ULONG, ULONG * ); +extern HB_EXPORT ULONG hb_cdpUTF8StringPeek( const BYTE *, ULONG, ULONG ); extern PHB_CODEPAGE hb_cdp_page; diff --git a/harbour/include/hbcompat.ch b/harbour/include/hbcompat.ch index ea3dd7a533..c93bad6927 100644 --- a/harbour/include/hbcompat.ch +++ b/harbour/include/hbcompat.ch @@ -96,9 +96,11 @@ #xtranslate libLoad([]) => hb_libLoad() #xtranslate libFree([]) => hb_libFree() - #xtranslate CStr([]) => hb_CStr() #xtranslate hb_checksum([]) => hb_adler32() + #xtranslate CStr([]) => hb_CStr() + #xtranslate str(,[],[],)=> iif(, ltrim(str()), str()) + #xtranslate HASH([]) => HB_HASH() #xtranslate HHASKEY([]) => HB_HHASKEY() #xtranslate HGETPOS([]) => HB_HPOS() diff --git a/harbour/source/rtl/cdpapi.c b/harbour/source/rtl/cdpapi.c index e374d253de..22cdf5c95c 100644 --- a/harbour/source/rtl/cdpapi.c +++ b/harbour/source/rtl/cdpapi.c @@ -56,6 +56,7 @@ #include "hbapiitm.h" #include "hbapicdp.h" +#include "hbapierr.h" #define NUMBER_OF_CHARS 256 @@ -518,6 +519,90 @@ HB_EXPORT USHORT hb_cdpGetU16( PHB_CODEPAGE cdp, BOOL fCtrl, BYTE ch ) return u; } +HB_EXPORT BYTE * hb_cdpUTF8StringSubstr( const BYTE * pSrc, ULONG ulLen, + ULONG ulFrom, ULONG ulCount, + ULONG * pulDest ) +{ + ULONG ul, ulCnt, ulDst = 0; + USHORT uc; + int n; + BYTE * pDst = NULL; + + if( ulCount && ulLen ) + { + n = 0; + for( ul = 0; ul < ulLen && ulFrom; ++ul ) + { + if( utf8tou16nextchar( pSrc[ ul ], &n, &uc ) ) + { + if( n == 0 ) + --ulFrom; + } + } + + if( ul < ulLen ) + { + ulFrom = ul; + ulCnt = ulCount; + n = 0; + do + { + if( utf8tou16nextchar( pSrc[ ul ], &n, &uc ) ) + { + if( n == 0 ) + --ulCnt; + } + } + while( ++ul < ulLen && ulCnt ); + + ulDst = ul - ulFrom; + pDst = ( BYTE * ) hb_xgrab( ulDst + 1 ); + memcpy( pDst, &pSrc[ ulFrom ], ulDst ); + } + } + + if( pulDest ) + * pulDest = ulDst; + + return pDst; +} + +HB_EXPORT ULONG hb_cdpUTF8StringPeek( const BYTE * pSrc, ULONG ulLen, + ULONG ulPos ) +{ + if( ulLen ) + { + ULONG ul; + USHORT uc = 0; + int n = 0; + + for( ul = 0; ul < ulLen && ulPos; ++ul ) + { + if( utf8tou16nextchar( pSrc[ ul ], &n, &uc ) ) + { + if( n == 0 ) + --ulPos; + } + } + + if( ul < ulLen ) + { + n = 0; + do + { + if( utf8tou16nextchar( pSrc[ ul ], &n, &uc ) ) + { + if( n == 0 ) + return uc; + } + } + while( ++ul < ulLen ); + } + } + + return 0; +} + HB_EXPORT ULONG hb_cdpUTF8StringLength( const BYTE * pSrc, ULONG ulLen ) { ULONG ul, ulDst; @@ -1085,4 +1170,126 @@ HB_FUNC( HB_UTF8TOSTR ) hb_retc( NULL ); } +HB_FUNC( HB_UTF8SUBSTR ) +{ + int iPCount = hb_pcount(); + + if( ISCHAR( 1 ) && ( iPCount < 2 || + ( ISNUM( 2 ) && ( iPCount < 3 || ISNUM( 3 ) ) ) ) ) + { + char * szString = hb_parc( 1 ), * szDest = NULL; + ULONG ulLen = hb_parclen( 1 ), ulDest = 0; + LONG lFrom = hb_parnl( 2 ); + LONG lCount = iPCount < 3 ? ( LONG ) ulLen : hb_parnl( 3 ); + + if( lFrom < 0 ) + { + lFrom += hb_cdpUTF8StringLength( ( BYTE * ) szString, ulLen ); + if( lFrom < 0 ) + lFrom = 0; + } + else if( lFrom ) + --lFrom; + + if( ulLen && lCount > 0 ) + szDest = ( char * ) hb_cdpUTF8StringSubstr( ( BYTE * ) szString, + ulLen, lFrom, lCount, + &ulDest ); + if( szDest ) + hb_retclen_buffer( szDest, ulDest ); + else + hb_retc( NULL ); + } + else + hb_errRT_BASE_SubstR( EG_ARG, 3012, NULL, &hb_errFuncName, + HB_ERR_ARGS_BASEPARAMS ); +} + +HB_FUNC( HB_UTF8LEFT ) +{ + char * szString = hb_parc( 1 ); + + if( szString && ISNUM( 2 ) ) + { + LONG lLen = hb_parnl( 2 ); + ULONG ulDest = 0; + char * szDest = NULL; + + if( lLen > 0 ) + szDest = ( char * ) hb_cdpUTF8StringSubstr( ( BYTE * ) szString, + hb_parclen( 1 ), 0, + lLen, &ulDest ); + + if( szDest ) + hb_retclen_buffer( szDest, ulDest ); + else + hb_retc( NULL ); + } + else + hb_errRT_BASE_SubstR( EG_ARG, 3012, NULL, &hb_errFuncName, + HB_ERR_ARGS_BASEPARAMS ); +} + +HB_FUNC( HB_UTF8RIGHT ) +{ + char * szString = hb_parc( 1 ); + + if( szString && ISNUM( 2 ) ) + { + LONG lLen = hb_parnl( 2 ), lFrom; + ULONG ulLen = hb_parclen( 1 ), ulDest = 0; + char * szDest = NULL; + + if( ulLen && lLen > 0 ) + { + lFrom = hb_cdpUTF8StringLength( ( BYTE * ) szString, ulLen ) - lLen; + if( lFrom < 0 ) + lFrom = 0; + szDest = ( char * ) hb_cdpUTF8StringSubstr( ( BYTE * ) szString, + ulLen, lFrom, + lLen, &ulDest ); + } + + if( szDest ) + hb_retclen_buffer( szDest, ulDest ); + else + hb_retc( NULL ); + } + else + hb_errRT_BASE_SubstR( EG_ARG, 3012, NULL, &hb_errFuncName, + HB_ERR_ARGS_BASEPARAMS ); +} + +HB_FUNC( HB_UTF8PEEK ) +{ + char * szString = hb_parc( 1 ); + + if( szString && ISNUM( 2 ) ) + { + ULONG ulPos = hb_parnl( 2 ); + ULONG ulLen = hb_parclen( 1 ); + + if( ulPos > 0 && ulPos < ulLen ) + hb_retnint( hb_cdpUTF8StringPeek( ( BYTE * ) szString, ulLen, ulPos - 1 ) ); + else + hb_retni( 0 ); + } + else + hb_errRT_BASE_SubstR( EG_ARG, 3012, NULL, &hb_errFuncName, + HB_ERR_ARGS_BASEPARAMS ); +} + +HB_FUNC( HB_UTF8LEN ) +{ + char * szString = hb_parc( 1 ); + + if( szString ) + hb_retnint( hb_cdpUTF8StringLength( ( BYTE * ) szString, hb_parclen( 1 ) ) ); + else + hb_errRT_BASE_SubstR( EG_ARG, 3012, NULL, &hb_errFuncName, + HB_ERR_ARGS_BASEPARAMS ); +} + +/* TODO: HB_UTF8TRAN, HB_UTF8STUFF, HB_UTF8POKE */ + #endif /* HB_CDP_SUPPORT_OFF */ diff --git a/harbour/source/rtl/left.c b/harbour/source/rtl/left.c index 33b4005900..388411234a 100644 --- a/harbour/source/rtl/left.c +++ b/harbour/source/rtl/left.c @@ -63,7 +63,7 @@ HB_FUNC( LEFT ) if( pText && ISNUM( 2 ) ) { long lLen = hb_parnl( 2 ); - if( lLen < 0 ) + if( lLen <= 0 ) hb_retc( NULL ); else { diff --git a/harbour/source/rtl/right.c b/harbour/source/rtl/right.c index 52f4522de8..92538f5686 100644 --- a/harbour/source/rtl/right.c +++ b/harbour/source/rtl/right.c @@ -63,7 +63,7 @@ HB_FUNC( RIGHT ) if( pText && ISNUM( 2 ) ) { long lLen = hb_parnl( 2 ); - if( lLen < 0 ) + if( lLen <= 0 ) hb_retc( NULL ); else {