kernel32: Unify the format_insert ANSI and Unicode helpers.
This commit is contained in:
parent
053d4385c9
commit
4c657b870f
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue