kernel32: Unify the format_insert ANSI and Unicode helpers.

This commit is contained in:
Andrew Nguyen 2010-04-18 09:09:59 -05:00 committed by Alexandre Julliard
parent 053d4385c9
commit 4c657b870f
1 changed files with 24 additions and 135 deletions

View File

@ -121,12 +121,12 @@ static ULONG_PTR get_arg( int nr, DWORD flags, struct format_args *args )
return args->args[nr - 1]; return args->args[nr - 1];
} }
/********************************************************************** /**********************************************************************
* format_insertA (internal) * format_insert (internal)
*/ */
static LPCWSTR format_insertA( int insert, LPCWSTR format, DWORD flags, static LPCWSTR format_insert( BOOL unicode_caller, int insert, LPCWSTR format,
struct format_args *args, LPWSTR *result ) DWORD flags, struct format_args *args,
LPWSTR *result )
{ {
static const WCHAR fmt_lu[] = {'%','l','u',0}; static const WCHAR fmt_lu[] = {'%','l','u',0};
WCHAR *wstring = NULL, *p, fmt[256]; WCHAR *wstring = NULL, *p, fmt[256];
@ -135,135 +135,20 @@ static LPCWSTR format_insertA( int insert, LPCWSTR format, DWORD flags,
if (*format != '!') /* simple string */ if (*format != '!') /* simple string */
{ {
char *str = (char *)get_arg( insert, flags, args ); arg = get_arg( insert, flags, args );
DWORD length = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0); if (unicode_caller)
*result = HeapAlloc( GetProcessHeap(), 0, length * sizeof(WCHAR) );
MultiByteToWideChar(CP_ACP, 0, str, -1, *result, length);
return format;
}
format++;
p = fmt;
*p++ = '%';
while (*format == '0' ||
*format == '+' ||
*format == '-' ||
*format == ' ' ||
*format == '*' ||
*format == '#')
{
if (*format == '*')
{ {
p += sprintfW( p, fmt_lu, get_arg( insert, flags, args )); WCHAR *str = (WCHAR *)arg;
insert = -1; *result = HeapAlloc( GetProcessHeap(), 0, (strlenW(str) + 1) * sizeof(WCHAR) );
format++; strcpyW( *result, str );
}
else *p++ = *format++;
}
while (isdigit(*format)) *p++ = *format++;
if (*format == '.')
{
*p++ = *format++;
if (*format == '*')
{
p += sprintfW( p, fmt_lu, get_arg( insert, flags, args ));
insert = -1;
format++;
}
else
while (isdigit(*format)) *p++ = *format++;
}
/* replicate MS bug: drop an argument when using va_list with width/precision */
if (insert == -1 && args->list) args->last--;
arg = get_arg( insert, flags, args );
/* check for wide string format */
if ((format[0] == 'l' && format[1] == 's') ||
(format[0] == 'l' && format[1] == 'S') ||
(format[0] == 'w' && format[1] == 's') ||
(format[0] == 'S'))
{
*p++ = 's';
}
/* check for wide character format */
else if ((format[0] == 'l' && format[1] == 'c') ||
(format[0] == 'l' && format[1] == 'C') ||
(format[0] == 'w' && format[1] == 'c') ||
(format[0] == 'C'))
{
*p++ = 'c';
}
/* check for ascii string format */
else if ((format[0] == 'h' && format[1] == 's') ||
(format[0] == 'h' && format[1] == 'S') ||
(format[0] == 's'))
{
DWORD len = MultiByteToWideChar( CP_ACP, 0, (char *)arg, -1, NULL, 0 );
wstring = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
MultiByteToWideChar( CP_ACP, 0, (char *)arg, -1, wstring, len );
arg = (ULONG_PTR)wstring;
*p++ = 's';
}
/* check for ascii character format */
else if ((format[0] == 'h' && format[1] == 'c') ||
(format[0] == 'h' && format[1] == 'C') ||
(format[0] == 'c'))
{
char ch = arg;
wstring = HeapAlloc( GetProcessHeap(), 0, 2 * sizeof(WCHAR) );
MultiByteToWideChar( CP_ACP, 0, &ch, 1, wstring, 1 );
wstring[1] = 0;
arg = (ULONG_PTR)wstring;
*p++ = 's';
}
/* FIXME: handle I64 etc. */
else while (*format && *format != '!') *p++ = *format++;
*p = 0;
size = 256;
for (;;)
{
WCHAR *ret = HeapAlloc( GetProcessHeap(), 0, size * sizeof(WCHAR));
int needed = snprintfW( ret, size, fmt, arg );
if (needed == -1 || needed >= size)
{
HeapFree( GetProcessHeap(), 0, ret );
size = max( needed + 1, size * 2 );
} }
else else
{ {
*result = ret; char *str = (char *)get_arg( insert, flags, args );
break; DWORD length = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 );
*result = HeapAlloc( GetProcessHeap(), 0, length * sizeof(WCHAR) );
MultiByteToWideChar( CP_ACP, 0, str, -1, *result, length );
} }
}
while (*format && *format != '!') format++;
if (*format == '!') format++;
HeapFree( GetProcessHeap(), 0, wstring );
return format;
}
/**********************************************************************
* format_insertW (internal)
*/
static LPCWSTR format_insertW( int insert, LPCWSTR format, DWORD flags,
struct format_args *args, LPWSTR *result )
{
static const WCHAR fmt_lu[] = {'%','l','u',0};
WCHAR *wstring = NULL, *p, fmt[256];
ULONG_PTR arg;
int size;
if (*format != '!') /* simple string */
{
WCHAR *str = (WCHAR *)get_arg( insert, flags, args );
*result = HeapAlloc( GetProcessHeap(), 0, (strlenW(str) + 1) * sizeof(WCHAR) );
strcpyW( *result, str );
return format; return format;
} }
@ -308,9 +193,10 @@ static LPCWSTR format_insertW( int insert, LPCWSTR format, DWORD flags,
/* check for ascii string format */ /* check for ascii string format */
if ((format[0] == 'h' && format[1] == 's') || if ((format[0] == 'h' && format[1] == 's') ||
(format[0] == 'h' && format[1] == 'S') || (format[0] == 'h' && format[1] == 'S') ||
(format[0] == 'S')) (unicode_caller && format[0] == 'S') ||
(!unicode_caller && format[0] == 's'))
{ {
DWORD len = MultiByteToWideChar( CP_ACP, 0, (char *)arg, -1, /*FIXME*/ NULL, 0 ); DWORD len = MultiByteToWideChar( CP_ACP, 0, (char *)arg, -1, NULL, 0 );
wstring = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ); wstring = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
MultiByteToWideChar( CP_ACP, 0, (char *)arg, -1, wstring, len ); MultiByteToWideChar( CP_ACP, 0, (char *)arg, -1, wstring, len );
arg = (ULONG_PTR)wstring; arg = (ULONG_PTR)wstring;
@ -319,7 +205,8 @@ static LPCWSTR format_insertW( int insert, LPCWSTR format, DWORD flags,
/* check for ascii character format */ /* check for ascii character format */
else if ((format[0] == 'h' && format[1] == 'c') || else if ((format[0] == 'h' && format[1] == 'c') ||
(format[0] == 'h' && format[1] == 'C') || (format[0] == 'h' && format[1] == 'C') ||
(format[0] == 'C')) (unicode_caller && format[0] == 'C') ||
(!unicode_caller && format[0] == 'c'))
{ {
char ch = arg; char ch = arg;
wstring = HeapAlloc( GetProcessHeap(), 0, 2 * sizeof(WCHAR) ); wstring = HeapAlloc( GetProcessHeap(), 0, 2 * sizeof(WCHAR) );
@ -331,14 +218,16 @@ static LPCWSTR format_insertW( int insert, LPCWSTR format, DWORD flags,
/* check for wide string format */ /* check for wide string format */
else if ((format[0] == 'l' && format[1] == 's') || else if ((format[0] == 'l' && format[1] == 's') ||
(format[0] == 'l' && format[1] == 'S') || (format[0] == 'l' && format[1] == 'S') ||
(format[0] == 'w' && format[1] == 's')) (format[0] == 'w' && format[1] == 's') ||
(!unicode_caller && format[0] == 'S'))
{ {
*p++ = 's'; *p++ = 's';
} }
/* check for wide character format */ /* check for wide character format */
else if ((format[0] == 'l' && format[1] == 'c') || else if ((format[0] == 'l' && format[1] == 'c') ||
(format[0] == 'l' && format[1] == 'C') || (format[0] == 'l' && format[1] == 'C') ||
(format[0] == 'w' && format[1] == 'c')) (format[0] == 'w' && format[1] == 'c') ||
(!unicode_caller && format[0] == 'C'))
{ {
*p++ = 'c'; *p++ = 'c';
} }
@ -426,7 +315,7 @@ static LPWSTR format_messageA( DWORD dwFlags, LPCWSTR fmtstr, struct format_args
f++; f++;
break; break;
} }
f = format_insertA( insertnr, f, dwFlags, format_args, &str ); f = format_insert( FALSE, insertnr, f, dwFlags, format_args, &str );
for (x = str; *x; x++) ADD_TO_T(*x); for (x = str; *x; x++) ADD_TO_T(*x);
HeapFree( GetProcessHeap(), 0, str ); HeapFree( GetProcessHeap(), 0, str );
break; break;
@ -536,7 +425,7 @@ static LPWSTR format_messageW( DWORD dwFlags, LPCWSTR fmtstr, struct format_args
f++; f++;
break; break;
} }
f = format_insertW( insertnr, f, dwFlags, format_args, &str ); f = format_insert( TRUE, insertnr, f, dwFlags, format_args, &str );
for (x = str; *x; x++) ADD_TO_T(*x); for (x = str; *x; x++) ADD_TO_T(*x);
HeapFree( GetProcessHeap(), 0, str ); HeapFree( GetProcessHeap(), 0, str );
break; break;