2009-12-29 14:34 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl)

* harbour/include/hbapi.h
  * harbour/src/common/hbprintf.c
    + added new function 'int hb_printf_params( const char * format )' which
      returns number of parameters necessary for format string

  * harbour/src/common/hbtrace.c
    * added protection against recursive calls when number of parameters
      used by HB_TRACE message us bigger then 16 and fm.c module was compiled
      with HB_TR_DEBUG macro
    % use the same number of characters for unicode and byte string buffers
    % use common memory area (union) for unicode and byte messages to reduce
      C stack usage
    Please test these modifications in real MS-Windows systems.
This commit is contained in:
Przemyslaw Czerpak
2009-12-29 13:34:19 +00:00
parent e1bbbb990e
commit 1b181e9773
4 changed files with 220 additions and 26 deletions

View File

@@ -17,6 +17,21 @@
past entries belonging to author(s): Viktor Szakats.
*/
2009-12-29 14:34 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl)
* harbour/include/hbapi.h
* harbour/src/common/hbprintf.c
+ added new function 'int hb_printf_params( const char * format )' which
returns number of parameters necessary for format string
* harbour/src/common/hbtrace.c
* added protection against recursive calls when number of parameters
used by HB_TRACE message us bigger then 16 and fm.c module was compiled
with HB_TR_DEBUG macro
% use the same number of characters for unicode and byte string buffers
% use common memory area (union) for unicode and byte messages to reduce
C stack usage
Please test these modifications in real MS-Windows systems.
2009-12-29 00:41 UTC-0800 Pritpal Bedi (pritpal@vouchcac.com)
* contrib/hbqt/qtgui/QTextCursor.cpp
* contrib/hbqt/qtgui/TQTextCursor.prg

View File

@@ -935,6 +935,7 @@ extern HB_EXPORT BOOL hb_strToNum( const char * szNum, HB_LONG * plVal, dou
extern HB_EXPORT BOOL hb_strnToNum( const char * szNum, ULONG ulLen, HB_LONG * plVal, double * pdVal ); /* converts string to number, returns HB_TRUE if results is double */
extern HB_EXPORT int hb_snprintf( char * buffer, size_t bufsize, const char * format, ... ) HB_PRINTF_FORMAT( 3, 4 ); /* snprintf() equivalent */
extern HB_EXPORT int hb_vsnprintf( char * buffer, size_t bufsize, const char * format, va_list ap ); /* vsnprintf() equivalent */
extern HB_EXPORT int hb_printf_params( const char * format );
extern HB_EXPORT BOOL hb_strMatchFile( const char * pszString, const char * szPattern ); /* compare two strings using platform dependent rules for file matching */
extern HB_EXPORT BOOL hb_strMatchRegExp( const char * szString, const char * szPattern ); /* compare two strings using a regular expression pattern */

View File

@@ -728,6 +728,187 @@ static size_t put_str( char *buffer, size_t bufsize, size_t size,
return size;
}
int hb_printf_params( const char * format )
{
int iParam = 0, iMax = 0;
char c;
do
{
c = *format++;
if( c == '%' )
{
const char * pattern = format;
int value, param = 0;
c = *format++;
if( c != 0 && c != '%' )
{
/* parameter position */
if( c >= '0' && c <= '9' )
{
c = get_decimal( c, &format, &param );
if( c != '$' )
format = pattern;
c = *format++;
}
/* flags */
value = 0;
while( !value ) switch( c )
{
case '#':
case '0':
case '-':
case ' ':
case '+':
#ifdef _SUSV2_COMPAT_
case '\'': /* group with locale thousands' grouping characters */
#endif
c = *format++;
break;
default:
value = 1;
break;
}
/* field width */
if( c == '*' )
{
c = *format++;
if( c >= '0' && c <= '9' )
{
c = get_decimal( c, &format, &value );
if( c == '$' )
{
if( value > iMax )
iMax = value;
c = *format++;
}
/* else error, wrong format */
}
else
++iParam;
}
else if( c >= '0' && c <= '9' )
c = get_decimal( c, &format, &value );
/* precision */
if( c == '.' )
{
c = *format++;
if( c == '*' )
{
c = *format++;
if( c >= '0' && c <= '9' )
{
c = get_decimal( c, &format, &value );
if( c == '$' )
{
if( value > iMax )
iMax = value;
c = *format++;
}
/* else error, wrong format */
}
else
++iParam;
}
else if( c >= '0' && c <= '9' )
c = get_decimal( c, &format, &value );
}
/* length modifier */
switch( c )
{
case 'h':
c = *format++;
if( c == 'h' )
c = *format++;
break;
case 'l':
c = *format++;
if( c == 'l' )
c = *format++;
break;
case 'L':
c = *format++;
break;
case 'j':
c = *format++;
break;
case 'z':
c = *format++;
break;
case 't':
c = *format++;
break;
case 'I': /* MS-Windows extension */
if( format[ 0 ] == '6' && format[ 1 ] == '4' )
{
format += 2;
c = *format++;
break;
}
else if( format[ 0 ] == '1' && format[ 1 ] == '6' )
{
format += 2;
c = *format++;
break;
}
else if( format[ 0 ] == '3' && format[ 1 ] == '2' )
{
format += 2;
c = *format++;
}
/* no break; */
default:
break;
}
/* conversion specifier */
switch( c )
{
#ifndef __NO_DOUBLE__
case 'a':
case 'A':
case 'e':
case 'E':
case 'g':
case 'G':
case 'f': /* double decimal notation */
case 'F': /* double decimal notation */
#endif
case 'd':
case 'i': /* signed int decimal conversion */
case 'o': /* unsigned int octal conversion */
case 'u': /* unsigned int decimal conversion */
case 'x': /* unsigned int hexadecimal conversion */
case 'X': /* unsigned int hexadecimal conversion */
case 'p': /* void * pointer */
case 'c': /* signed int casted to unsigned char */
case 's': /* const char * */
case 'n': /* store current result size in int * arg */
if( param == 0 )
++iParam;
else if( param > iMax )
iMax = param;
break;
case '%': /* store % consuming arguments % */
break;
default: /* error, wrong format, store pattern */
format = pattern;
c = '%';
break;
}
}
}
}
while( c );
return iParam > iMax ? iParam : iMax;
}
int hb_vsnprintf( char * buffer, size_t bufsize, const char * format, va_list ap )
{
va_list args;
@@ -779,15 +960,10 @@ int hb_vsnprintf( char * buffer, size_t bufsize, const char * format, va_list ap
{
c = get_decimal( c, &format, &value );
if( c == '$' )
{
param = value;
c = *format++;
}
else
{
format = pattern;
c = *format++;
}
c = *format++;
}
/* flags */
@@ -934,7 +1110,6 @@ int hb_vsnprintf( char * buffer, size_t bufsize, const char * format, va_list ap
}
/* conversion specifier */
switch( c )
{
#ifndef __NO_DOUBLE__

View File

@@ -223,30 +223,33 @@ static void hb_tracelog_( int level, const char * file, int line, const char * p
if( s_winout )
{
char buffer1[ 1024 ];
char buffer2[ 1024 ];
char message[ 1024 ];
union
{
char psz[ 1024 ];
TCHAR lp[ 1024 ];
} buf;
/* TOFIX: This might invoke recursive call to tracee engine when
there is more than 16 format strings. */
hb_vsnprintf( buffer1, sizeof( buffer1 ), fmt, ap );
/* We add \r\n at the end of the buffer to make WinDbg display look readable. */
if( proc )
hb_snprintf( buffer2, sizeof( buffer2 ), "%s:%d:%s() %s %s\n",
file, line, proc, pszLevel, buffer1 );
/* NOTE: This is protection against recursive call to trace engine when
there is more than 16 parameters in format string */
if( hb_xtraced() && hb_printf_params( fmt ) > 16 )
hb_snprintf( message, sizeof( message ), "more then 16 parameters in message '%s'", fmt );
else
hb_snprintf( buffer2, sizeof( buffer2 ), "%s:%d: %s %s\n",
file, line, pszLevel, buffer1 );
hb_vsnprintf( message, sizeof( message ), fmt, ap );
/* We add \n at the end of the buffer to make WinDbg display look readable. */
if( proc )
hb_snprintf( buf.psz, sizeof( buf.psz ), "%s:%d:%s() %s %s\n",
file, line, proc, pszLevel, message );
else
hb_snprintf( buf.psz, sizeof( buf.psz ), "%s:%d: %s %s\n",
file, line, pszLevel, message );
#if defined( UNICODE )
{
TCHAR lpOutputString[ 2048 ];
MultiByteToWideChar( CP_ACP, 0, buffer2, -1, lpOutputString, HB_SIZEOFARRAY( lpOutputString ) );
OutputDebugString( lpOutputString );
}
#else
OutputDebugString( buffer2 );
memcpy( message, buf.psz, sizeof( message ) );
MultiByteToWideChar( CP_ACP, 0, message, -1, buf.lp, HB_SIZEOFARRAY( buf.lp ) );
#endif
OutputDebugString( buf.lp );
}
#endif