diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 2b93bdf547..8858606a3d 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -16,6 +16,13 @@ The license applies to all entries newer than 2009-04-28. */ +2011-08-02 00:11 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/src/common/hbprintf.c + + added very basic support for '%ls' in hb_snprintf() + + * harbour/ChangeLog + ! typo in last description + 2011-08-01 15:28 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) * harbour/include/hbstack.h * harbour/src/vm/estack.c @@ -29,7 +36,7 @@ successful return. This extensions is critical for MT applications which need to safely reenter HVM also from code encapsulated inside unknown - number of hb_vnUnlock()/hb_vnLock() calls. + number of hb_vmUnlock()/hb_vmLock() calls. [TOMERGE 3.0] * harbour/src/compiler/cmdcheck.c diff --git a/harbour/src/common/hbprintf.c b/harbour/src/common/hbprintf.c index 266bc198a8..9e9802644e 100644 --- a/harbour/src/common/hbprintf.c +++ b/harbour/src/common/hbprintf.c @@ -95,6 +95,7 @@ optimized. /* hbfloat.h have to be included first */ #include "hbfloat.h" +#include "hbapicdp.h" #include #if defined( __FreeBSD__ ) @@ -201,6 +202,8 @@ optimized. #define _x_ptrdiff_t ptrdiff_t #define _x_ptr void * #define _x_str char * +#define _x_wchar wchar_t +#define _x_wstr _x_wchar * #define _x_intptr int * #define v_x_int 1 @@ -215,9 +218,10 @@ optimized. #define v_x_ptrdiff_t 10 #define v_x_ptr 11 #define v_x_str 12 -#define v_x_intptr 13 -#define v_x_double 14 -#define v_x_long_dbl 15 +#define v_x_wstr 13 +#define v_x_intptr 14 +#define v_x_double 15 +#define v_x_long_dbl 16 typedef union { _x_int as_x_int; @@ -232,6 +236,7 @@ typedef union { _x_ptrdiff_t as_x_ptrdiff_t; _x_ptr as_x_ptr; _x_str as_x_str; + _x_wstr as_x_wstr; _x_intptr as_x_intptr; _x_double as_x_double; _x_long_dbl as_x_long_dbl; @@ -360,6 +365,9 @@ static void va_arg_fill( v_paramlst * plst, va_list va ) case v_x_str: plst->arglst[ iArg ].value.as_x_str = va_arg( va, _x_str ); break; + case v_x_wstr: + plst->arglst[ iArg ].value.as_x_wstr = va_arg( va, _x_wstr ); + break; case v_x_intptr: plst->arglst[ iArg ].value.as_x_intptr = va_arg( va, _x_intptr ); break; @@ -712,7 +720,7 @@ static int _hb_strnlen( const char * str, int len ) } static size_t put_str( char *buffer, size_t bufsize, size_t size, - const char * str, int flags, int width, int precision ) + const _x_str str, int flags, int width, int precision ) { if( !str ) str = "(null)"; @@ -747,6 +755,56 @@ static size_t put_str( char *buffer, size_t bufsize, size_t size, return size; } +static size_t put_wstr( char *buffer, size_t bufsize, size_t size, + const _x_wstr wstr, int flags, int width, + int precision ) +{ + if( !wstr ) + { + const _x_wchar wstr_null[] = { '(', 'n', 'u', 'l', 'l', ')', 0 }; + wstr = wstr_null; + } + + if( precision < 0 ) + { + precision = 0; + while( wstr[ precision ] ) + ++precision; + } + else if( precision > 0 ) + { + int size = precision; + precision = 0; + while( precision < size && wstr[ precision ] ) + ++precision; + } + + width -= precision; + if( ( flags & _F_LEFTADJUSTED ) == 0 ) while( width > 0 ) + { + if( size < bufsize ) + buffer[ size ] = ' '; + ++size; + --width; + } + while( precision > 0 ) + { + if( size < bufsize ) + buffer[ size ] = ( char ) *wstr++; + ++size; + --precision; + } + while( width > 0 ) + { + if( size < bufsize ) + buffer[ size ] = ' '; + ++size; + --width; + } + + return size; +} + int hb_printf_params( const char * format ) { int iParam = 0, iMax = 0; @@ -1262,9 +1320,18 @@ int hb_vsnprintf( char * buffer, size_t bufsize, const char * format, va_list ap } continue; case 's': /* const char * */ - argval.value.as_x_str = va_arg_n( args, _x_str, param ); - size = put_str( buffer, bufsize, size, argval.value.as_x_str, - flags, width, precision ); + if( length == _L_LONG_ ) + { + argval.value.as_x_wstr = va_arg_n( args, _x_wstr, param ); + size = put_wstr( buffer, bufsize, size, argval.value.as_x_wstr, + flags, width, precision ); + } + else + { + argval.value.as_x_str = va_arg_n( args, _x_str, param ); + size = put_str( buffer, bufsize, size, argval.value.as_x_str, + flags, width, precision ); + } continue; case 'n': /* store current result size in int * arg */ /* This is very danger feature in *printf() functions