diff --git a/harbour/ChangeLog b/harbour/ChangeLog index aac6d2397c..1e55693cb3 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -17,6 +17,15 @@ past entries belonging to author(s): Viktor Szakats. */ +2009-11-02 12:29 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/src/rtl/cdpapi.c + * harbour/include/hbapicdp.h + + added two new functions hb_cdpU16ToStr() and hb_cdpU16LEToStr() + + * harbour/doc/xhb-diff.txt + ! fixed typo in code example reported by Guy Roussin + ! fixed some other typos - i.e. in detached local description + 2009-11-02 12:06 UTC+0100 Viktor Szakats (harbour.01 syenar.hu) * config/win/bcc.mk ! Fixed -I order after recent change to not interfere with diff --git a/harbour/doc/xhb-diff.txt b/harbour/doc/xhb-diff.txt index 5c23caa83a..56f3c39465 100644 --- a/harbour/doc/xhb-diff.txt +++ b/harbour/doc/xhb-diff.txt @@ -104,12 +104,12 @@ file system(s) and with different OS(s). ? a, b NEXT c) it has native support for hashes: - FOR EACH x IN {"ABC"=>123,"ASD"=>456,"ZXC"=>789} + FOR EACH x IN { "ABC" => 123, "ASD" => 456, "ZXC" => 789 } ? x, "@", x:__enumKey() NEXT d) it allows to assing string items, f.e.: s := "abcdefghijk" - FOR EACH c IN (@s) + FOR EACH c IN @s IF c $ "aei" c := UPPER( c ) ENDIF @@ -118,7 +118,7 @@ file system(s) and with different OS(s). e) it gives OOP interface to controll enumerator variables what is very important when more then one variable is iterated or when FOR EACH is called recursively, f.e.: - hVal := {"ABC"=>123,"ASD"=>456,"ZXC"=>789} + hVal := { "ABC" => 123, "ASD" => 456, "ZXC" => 789 } FOR EACH x IN hVal ? x:__enumIndex(), ":", x:__enumKey(), "=>", x:__enumValue(), ; "=>", x:__enumBase()[ x:__enumKey() ] @@ -300,13 +300,13 @@ In xHarbour the behavior of references stored in array is reverted in comparison to Clipper or Harbour. In Clipper and Harbour VM executing code like: aVal[ 1 ] := 100 -clears unconditional 1-st item in aVal array and assign to it value 100. -xHarbour checks if aVal[ 1 ] is an reference and in such case it resolve +clears unconditionally 1-st item in aVal array and assign to it value 100. +xHarbour checks if aVal[ 1 ] is an reference and in such case it resolves the reference and then assign 100 to the destination item. On access Clipper and Harbour VM executing code like: x := aVal[ 1 ] copy to x the exact value stored in aVal[ 1 ]. xHarbour checks is aVal[ 1 ] -is an reference and in such case it resolve the reference and then copy to x +is an reference and in such case it resolves the reference and then copy to x the value of reference destination item. It can be seen in code like: proc main @@ -426,11 +426,11 @@ the function, f.e.: return {|| ++n } We call such variables "detached locals". Here there are two important differences between Clipper and [x]Harbour. -In Clipper variables are detached when function exists and it does not -know which variables were used but simply detach whole local variable -frame from VM stack. It's very important to know that because it can -be source of serious memory problems in OS like DOS. -This simply code illustrates it: +In Clipper variables are detached when function exits (returns) and it +does not know which variables were used but simply detach whole local +variable frame from VM stack. It's very important to know that because +it can be source of serious memory problems in OS like DOS. +This simple code illustrates it: // link using RTLINK and run with //e:0 //swapk:0 // repeat test second time with additional non empty parameter @@ -461,10 +461,11 @@ is detached with codeblock which uses 'ref' variable and not released as long as codeblock is still accessible. It means that in few iterations all memory are allocated and program crashes. Clipper's programmers should know that and be careful when use detached local and if necessary clear -explicitly other local variables before exist by setting NIL to them. +explicitly other local variables before returning from the function by +setting NIL to them. In Harbour and xHarbour only variables explicitly used in codeblocks are detached and detaching is done when codeblock is created and original -local variables are replaced by references. It was possible because Harbour +local variables are replaced by references. It is possible because Harbour and xHarbour support multilevel references chains so it works correctly also for local parameters passed be reference from parent functions. In Clipper only one level references are supported what creates second diff --git a/harbour/include/hbapicdp.h b/harbour/include/hbapicdp.h index 3d4e7755a3..43faaba831 100644 --- a/harbour/include/hbapicdp.h +++ b/harbour/include/hbapicdp.h @@ -331,16 +331,22 @@ extern HB_EXPORT void hb_cdpnTranslate( char *, PHB_CODEPAGE, PHB_CODEP extern HB_EXPORT HB_WCHAR hb_cdpGetU16( PHB_CODEPAGE, BOOL, UCHAR ); extern HB_EXPORT UCHAR hb_cdpGetChar( PHB_CODEPAGE, BOOL, HB_WCHAR ); extern HB_EXPORT BOOL hb_cdpGetFromUTF8( PHB_CODEPAGE, BOOL, UCHAR, int *, HB_WCHAR * ); -extern HB_EXPORT ULONG hb_cdpStrnToUTF8( PHB_CODEPAGE, BOOL, const char *, ULONG, char * ); -extern HB_EXPORT ULONG hb_cdpStrnToUTF8n( PHB_CODEPAGE, BOOL, const char *, ULONG, char *, ULONG ); + extern HB_EXPORT ULONG hb_cdpStrnToU16( PHB_CODEPAGE, BOOL, const char *, ULONG, HB_WCHAR * ); extern HB_EXPORT ULONG hb_cdpStrnToU16n( PHB_CODEPAGE, BOOL, const char *, ULONG, HB_WCHAR *, ULONG ); extern HB_EXPORT ULONG hb_cdpStrnToU16LE( PHB_CODEPAGE, BOOL, const char *, ULONG, HB_WCHAR * ); extern HB_EXPORT ULONG hb_cdpStrnToU16LEn( PHB_CODEPAGE, BOOL, const char *, ULONG, HB_WCHAR *, ULONG ); extern HB_EXPORT ULONG hb_cdpStringInU16Length( PHB_CODEPAGE, BOOL, const char *, ULONG ); extern HB_EXPORT ULONG hb_cdpStringInU16Length2( PHB_CODEPAGE, BOOL, const char *, ULONG, ULONG ); + +extern HB_EXPORT char * hb_cdpU16ToStr( PHB_CODEPAGE, BOOL, const HB_WCHAR *, ULONG, char *, ULONG * ); +extern HB_EXPORT char * hb_cdpU16LEToStr( PHB_CODEPAGE, BOOL, const HB_WCHAR *, ULONG, char *, ULONG * ); + +extern HB_EXPORT ULONG hb_cdpStrnToUTF8( PHB_CODEPAGE, BOOL, const char *, ULONG, char * ); +extern HB_EXPORT ULONG hb_cdpStrnToUTF8n( PHB_CODEPAGE, BOOL, const char *, ULONG, char *, ULONG ); extern HB_EXPORT ULONG hb_cdpStringInUTF8Length( PHB_CODEPAGE, BOOL, const char *, ULONG ); extern HB_EXPORT ULONG hb_cdpStringInUTF8Length2( PHB_CODEPAGE, BOOL, const char *, ULONG, ULONG ); + extern HB_EXPORT ULONG hb_cdpUTF8ToStrn( PHB_CODEPAGE, BOOL, const char *, ULONG, char *, ULONG ); extern HB_EXPORT ULONG hb_cdpUTF8StringLength( const char *, ULONG ); extern HB_EXPORT char * hb_cdpUTF8StringSubstr( const char *, ULONG, ULONG, ULONG, ULONG * ); diff --git a/harbour/src/rtl/cdpapi.c b/harbour/src/rtl/cdpapi.c index dbc511d2cc..44fdfe290b 100644 --- a/harbour/src/rtl/cdpapi.c +++ b/harbour/src/rtl/cdpapi.c @@ -783,6 +783,10 @@ ULONG hb_cdpUTF8StringLength( const char * pSrc, ULONG ulLen ) HB_WCHAR uc; int n = 0; + /* + * TODO: add support for multibyte characters + */ + for( ul = ulDst = 0; ul < ulLen; ++ul ) { if( utf8tou16nextchar( ( UCHAR ) pSrc[ ul ], &n, &uc ) ) @@ -1034,6 +1038,98 @@ ULONG hb_cdpStringInU16Length2( PHB_CODEPAGE cdp, BOOL fCtrl, return ulLen; } +char * hb_cdpU16ToStr( PHB_CODEPAGE cdp, BOOL fCtrl, + const HB_WCHAR * pSrc, ULONG ulLen, + char * pDst, ULONG * pulDst ) +{ + ULONG ulDst, ul; + HB_WCHAR wc; + + /* + * TODO: add support for multibyte characters + */ + + if( pDst ) + { + ulDst = *pulDst; + } + else + { + ulDst = ulLen + 1; + pDst = hb_xgrab( ulDst ); + } + + for( ul = 0; ul < ulLen && ul < ulDst; ++ul ) + { + wc = HB_GET_BE_UINT16( &pSrc[ ul ] ); + if( fCtrl || wc >= 32 ) + { + int i; + for( i = fCtrl ? 0 : 32; i < cdp->uniTable->nChars; i++ ) + { + if( cdp->uniTable->uniCodes[ i ] == wc ) + { + wc = ( HB_WCHAR ) i; + break; + } + } + } + pDst[ ul ] = wc >= 0x100 ? '?' : ( UCHAR ) wc; + } + + if( ul < ulDst ) + pDst[ ul ] = 0; + *pulDst = ul; + + return pDst; +} + +char * hb_cdpU16LEToStr( PHB_CODEPAGE cdp, BOOL fCtrl, + const HB_WCHAR * pSrc, ULONG ulLen, + char * pDst, ULONG * pulDst ) +{ + ULONG ulDst, ul; + HB_WCHAR wc; + + /* + * TODO: add support for multibyte characters + */ + + if( pDst ) + { + ulDst = *pulDst; + } + else + { + ulDst = ulLen + 1; + pDst = hb_xgrab( ulDst ); + } + + for( ul = 0; ul < ulLen && ul < ulDst; ++ul ) + { + wc = HB_GET_LE_UINT16( &pSrc[ ul ] ); + if( fCtrl || wc >= 32 ) + { + int i; + for( i = fCtrl ? 0 : 32; i < cdp->uniTable->nChars; i++ ) + { + if( cdp->uniTable->uniCodes[ i ] == wc ) + { + wc = ( HB_WCHAR ) i; + break; + } + } + } + pDst[ ul ] = wc >= 0x100 ? '?' : ( UCHAR ) wc; + } + + if( ul < ulDst ) + pDst[ ul ] = 0; + *pulDst = ul; + + return pDst; +} + ULONG hb_cdpStrnToU16( PHB_CODEPAGE cdp, BOOL fCtrl, const char * pSrc, ULONG ulLen, HB_WCHAR * pDst ) {