mirror of
https://github.com/reactos/reactos.git
synced 2025-01-06 06:20:13 +00:00
[kernel32]
sync format_msg.c with wine 1.7.11 svn path=/trunk/; revision=62234
This commit is contained in:
parent
d76955a546
commit
9a2dc33fb5
1 changed files with 98 additions and 52 deletions
|
@ -115,7 +115,7 @@ static LPCWSTR format_insert( BOOL unicode_caller, int insert, LPCWSTR format,
|
||||||
DWORD flags, struct format_args *args,
|
DWORD flags, struct format_args *args,
|
||||||
LPWSTR *result )
|
LPWSTR *result )
|
||||||
{
|
{
|
||||||
static const WCHAR fmt_lu[] = {'%','l','u',0};
|
static const WCHAR fmt_u[] = {'%','u',0};
|
||||||
WCHAR *wstring = NULL, *p, fmt[256];
|
WCHAR *wstring = NULL, *p, fmt[256];
|
||||||
ULONG_PTR arg;
|
ULONG_PTR arg;
|
||||||
int size;
|
int size;
|
||||||
|
@ -155,7 +155,7 @@ static LPCWSTR format_insert( BOOL unicode_caller, int insert, LPCWSTR format,
|
||||||
{
|
{
|
||||||
if (*format == '*')
|
if (*format == '*')
|
||||||
{
|
{
|
||||||
p += sprintfW( p, fmt_lu, get_arg( insert, flags, args ));
|
p += sprintfW( p, fmt_u, get_arg( insert, flags, args ));
|
||||||
insert = -1;
|
insert = -1;
|
||||||
format++;
|
format++;
|
||||||
}
|
}
|
||||||
|
@ -168,7 +168,7 @@ static LPCWSTR format_insert( BOOL unicode_caller, int insert, LPCWSTR format,
|
||||||
*p++ = *format++;
|
*p++ = *format++;
|
||||||
if (*format == '*')
|
if (*format == '*')
|
||||||
{
|
{
|
||||||
p += sprintfW( p, fmt_lu, get_arg( insert, flags, args ));
|
p += sprintfW( p, fmt_u, get_arg( insert, flags, args ));
|
||||||
insert = -1;
|
insert = -1;
|
||||||
format++;
|
format++;
|
||||||
}
|
}
|
||||||
|
@ -198,7 +198,7 @@ static LPCWSTR format_insert( BOOL unicode_caller, int insert, LPCWSTR format,
|
||||||
(unicode_caller && format[0] == 'C') ||
|
(unicode_caller && format[0] == 'C') ||
|
||||||
(!unicode_caller && format[0] == 'c'))
|
(!unicode_caller && format[0] == 'c'))
|
||||||
{
|
{
|
||||||
char ch = (char)arg;
|
char ch = arg;
|
||||||
wstring = HeapAlloc( GetProcessHeap(), 0, 2 * sizeof(WCHAR) );
|
wstring = HeapAlloc( GetProcessHeap(), 0, 2 * sizeof(WCHAR) );
|
||||||
MultiByteToWideChar( CP_ACP, 0, &ch, 1, wstring, 1 );
|
MultiByteToWideChar( CP_ACP, 0, &ch, 1, wstring, 1 );
|
||||||
wstring[1] = 0;
|
wstring[1] = 0;
|
||||||
|
@ -249,31 +249,85 @@ static LPCWSTR format_insert( BOOL unicode_caller, int insert, LPCWSTR format,
|
||||||
return format;
|
return format;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct _format_message_data
|
||||||
|
{
|
||||||
|
LPWSTR formatted;
|
||||||
|
DWORD size;
|
||||||
|
LPWSTR t;
|
||||||
|
LPWSTR space;
|
||||||
|
BOOL inspace;
|
||||||
|
DWORD width, w;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void format_add_char(struct _format_message_data *fmd, WCHAR c)
|
||||||
|
{
|
||||||
|
*fmd->t++ = c;
|
||||||
|
if (fmd->width && fmd->width != FORMAT_MESSAGE_MAX_WIDTH_MASK)
|
||||||
|
{
|
||||||
|
switch (c) {
|
||||||
|
case '\r':
|
||||||
|
case '\n':
|
||||||
|
fmd->space = NULL;
|
||||||
|
fmd->inspace = FALSE;
|
||||||
|
fmd->w = 0;
|
||||||
|
break;
|
||||||
|
case ' ':
|
||||||
|
if (!fmd->inspace)
|
||||||
|
fmd->space = fmd->t - 1;
|
||||||
|
fmd->inspace = TRUE;
|
||||||
|
fmd->w++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fmd->inspace = FALSE;
|
||||||
|
fmd->w++;
|
||||||
|
}
|
||||||
|
if (fmd->w == fmd->width) {
|
||||||
|
LPWSTR notspace;
|
||||||
|
if (fmd->space) {
|
||||||
|
notspace = fmd->space;
|
||||||
|
while (*notspace == ' ' && notspace != fmd->t)
|
||||||
|
notspace++;
|
||||||
|
} else
|
||||||
|
notspace = fmd->space = fmd->t;
|
||||||
|
fmd->w = fmd->t - notspace;
|
||||||
|
memmove(fmd->space+2, notspace, fmd->w * sizeof(*fmd->t));
|
||||||
|
*fmd->space++ = '\r';
|
||||||
|
*fmd->space++ = '\n';
|
||||||
|
fmd->t = fmd->space + fmd->w;
|
||||||
|
fmd->space = NULL;
|
||||||
|
fmd->inspace = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((DWORD)(fmd->t - fmd->formatted) == fmd->size) {
|
||||||
|
DWORD_PTR ispace = fmd->space - fmd->formatted;
|
||||||
|
/* Allocate two extra characters so we can insert a '\r\n' in
|
||||||
|
* the middle of a word.
|
||||||
|
*/
|
||||||
|
fmd->formatted = HeapReAlloc(GetProcessHeap(), 0, fmd->formatted, (fmd->size * 2 + 2) * sizeof(WCHAR));
|
||||||
|
fmd->t = fmd->formatted + fmd->size;
|
||||||
|
if (fmd->space)
|
||||||
|
fmd->space = fmd->formatted + ispace;
|
||||||
|
fmd->size *= 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* format_message (internal)
|
* format_message (internal)
|
||||||
*/
|
*/
|
||||||
static LPWSTR format_message( BOOL unicode_caller, DWORD dwFlags, LPCWSTR fmtstr,
|
static LPWSTR format_message( BOOL unicode_caller, DWORD dwFlags, LPCWSTR fmtstr,
|
||||||
struct format_args *format_args )
|
struct format_args *format_args )
|
||||||
{
|
{
|
||||||
LPWSTR target,t;
|
struct _format_message_data fmd;
|
||||||
DWORD talloced;
|
|
||||||
LPCWSTR f;
|
LPCWSTR f;
|
||||||
DWORD width = dwFlags & FORMAT_MESSAGE_MAX_WIDTH_MASK;
|
|
||||||
BOOL eos = FALSE;
|
BOOL eos = FALSE;
|
||||||
WCHAR ch;
|
|
||||||
|
|
||||||
target = t = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 100 * sizeof(WCHAR) );
|
fmd.size = 100;
|
||||||
talloced = 100;
|
fmd.formatted = fmd.t = HeapAlloc( GetProcessHeap(), 0, (fmd.size + 2) * sizeof(WCHAR) );
|
||||||
|
|
||||||
#define ADD_TO_T(c) do {\
|
|
||||||
*t++=c;\
|
|
||||||
if ((DWORD)(t-target) == talloced) {\
|
|
||||||
target = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,target,talloced*2*sizeof(WCHAR));\
|
|
||||||
t = target+talloced;\
|
|
||||||
talloced*=2;\
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
|
fmd.width = dwFlags & FORMAT_MESSAGE_MAX_WIDTH_MASK;
|
||||||
|
fmd.w = 0;
|
||||||
|
fmd.inspace = FALSE;
|
||||||
|
fmd.space = NULL;
|
||||||
f = fmtstr;
|
f = fmtstr;
|
||||||
while (*f && !eos) {
|
while (*f && !eos) {
|
||||||
if (*f=='%') {
|
if (*f=='%') {
|
||||||
|
@ -290,7 +344,7 @@ static LPWSTR format_message( BOOL unicode_caller, DWORD dwFlags, LPCWSTR fmtstr
|
||||||
(!(dwFlags & FORMAT_MESSAGE_ARGUMENT_ARRAY) && !format_args->list))
|
(!(dwFlags & FORMAT_MESSAGE_ARGUMENT_ARRAY) && !format_args->list))
|
||||||
{
|
{
|
||||||
SetLastError(ERROR_INVALID_PARAMETER);
|
SetLastError(ERROR_INVALID_PARAMETER);
|
||||||
HeapFree(GetProcessHeap(), 0, target);
|
HeapFree(GetProcessHeap(), 0, fmd.formatted);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
insertnr = *f-'0';
|
insertnr = *f-'0';
|
||||||
|
@ -307,20 +361,20 @@ static LPWSTR format_message( BOOL unicode_caller, DWORD dwFlags, LPCWSTR fmtstr
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
f = format_insert( unicode_caller, insertnr, f, dwFlags, format_args, &str );
|
f = format_insert( unicode_caller, insertnr, f, dwFlags, format_args, &str );
|
||||||
for (x = str; *x; x++) ADD_TO_T(*x);
|
for (x = str; *x; x++) format_add_char(&fmd, *x);
|
||||||
HeapFree( GetProcessHeap(), 0, str );
|
HeapFree( GetProcessHeap(), 0, str );
|
||||||
break;
|
break;
|
||||||
case 'n':
|
case 'n':
|
||||||
ADD_TO_T('\r');
|
format_add_char(&fmd, '\r');
|
||||||
ADD_TO_T('\n');
|
format_add_char(&fmd, '\n');
|
||||||
f++;
|
f++;
|
||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
ADD_TO_T('\r');
|
format_add_char(&fmd, '\r');
|
||||||
f++;
|
f++;
|
||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
ADD_TO_T('\t');
|
format_add_char(&fmd, '\t');
|
||||||
f++;
|
f++;
|
||||||
break;
|
break;
|
||||||
case '0':
|
case '0':
|
||||||
|
@ -329,53 +383,51 @@ static LPWSTR format_message( BOOL unicode_caller, DWORD dwFlags, LPCWSTR fmtstr
|
||||||
break;
|
break;
|
||||||
case '\0':
|
case '\0':
|
||||||
SetLastError(ERROR_INVALID_PARAMETER);
|
SetLastError(ERROR_INVALID_PARAMETER);
|
||||||
HeapFree(GetProcessHeap(), 0, target);
|
HeapFree(GetProcessHeap(), 0, fmd.formatted);
|
||||||
return NULL;
|
return NULL;
|
||||||
ignore_inserts:
|
ignore_inserts:
|
||||||
default:
|
default:
|
||||||
if (dwFlags & FORMAT_MESSAGE_IGNORE_INSERTS)
|
if (dwFlags & FORMAT_MESSAGE_IGNORE_INSERTS)
|
||||||
ADD_TO_T('%');
|
format_add_char(&fmd, '%');
|
||||||
ADD_TO_T(*f++);
|
format_add_char(&fmd, *f++);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ch = *f;
|
WCHAR ch = *f;
|
||||||
f++;
|
f++;
|
||||||
if (ch == '\r') {
|
if (ch == '\r') {
|
||||||
if (*f == '\n')
|
if (*f == '\n')
|
||||||
f++;
|
f++;
|
||||||
if(width)
|
if(fmd.width)
|
||||||
ADD_TO_T(' ');
|
format_add_char(&fmd, ' ');
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ADD_TO_T('\r');
|
format_add_char(&fmd, '\r');
|
||||||
ADD_TO_T('\n');
|
format_add_char(&fmd, '\n');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (ch == '\n')
|
if (ch == '\n')
|
||||||
{
|
{
|
||||||
if(width)
|
if(fmd.width)
|
||||||
ADD_TO_T(' ');
|
format_add_char(&fmd, ' ');
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ADD_TO_T('\r');
|
format_add_char(&fmd, '\r');
|
||||||
ADD_TO_T('\n');
|
format_add_char(&fmd, '\n');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ADD_TO_T(ch);
|
format_add_char(&fmd, ch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*t = '\0';
|
*fmd.t = '\0';
|
||||||
|
|
||||||
return target;
|
return fmd.formatted;
|
||||||
}
|
}
|
||||||
#undef ADD_TO_T
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* FormatMessageA (KERNEL32.@)
|
* FormatMessageA (KERNEL32.@)
|
||||||
* FIXME: missing wrap,
|
|
||||||
*/
|
*/
|
||||||
DWORD WINAPI FormatMessageA(
|
DWORD WINAPI FormatMessageA(
|
||||||
DWORD dwFlags,
|
DWORD dwFlags,
|
||||||
|
@ -391,7 +443,6 @@ DWORD WINAPI FormatMessageA(
|
||||||
LPWSTR target;
|
LPWSTR target;
|
||||||
DWORD destlength;
|
DWORD destlength;
|
||||||
LPWSTR from;
|
LPWSTR from;
|
||||||
DWORD width = dwFlags & FORMAT_MESSAGE_MAX_WIDTH_MASK;
|
|
||||||
|
|
||||||
TRACE("(0x%x,%p,%d,0x%x,%p,%d,%p)\n",
|
TRACE("(0x%x,%p,%d,0x%x,%p,%d,%p)\n",
|
||||||
dwFlags,lpSource,dwMessageId,dwLanguageId,lpBuffer,nSize,args);
|
dwFlags,lpSource,dwMessageId,dwLanguageId,lpBuffer,nSize,args);
|
||||||
|
@ -420,8 +471,6 @@ DWORD WINAPI FormatMessageA(
|
||||||
format_args.last = 0;
|
format_args.last = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (width && width != FORMAT_MESSAGE_MAX_WIDTH_MASK)
|
|
||||||
FIXME("line wrapping (%u) not supported.\n", width);
|
|
||||||
from = NULL;
|
from = NULL;
|
||||||
if (dwFlags & FORMAT_MESSAGE_FROM_STRING)
|
if (dwFlags & FORMAT_MESSAGE_FROM_STRING)
|
||||||
{
|
{
|
||||||
|
@ -432,9 +481,9 @@ DWORD WINAPI FormatMessageA(
|
||||||
else if (dwFlags & (FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_FROM_SYSTEM))
|
else if (dwFlags & (FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_FROM_SYSTEM))
|
||||||
{
|
{
|
||||||
if (dwFlags & FORMAT_MESSAGE_FROM_HMODULE)
|
if (dwFlags & FORMAT_MESSAGE_FROM_HMODULE)
|
||||||
from = load_message( (HMODULE)lpSource, dwMessageId, (WORD)dwLanguageId );
|
from = load_message( (HMODULE)lpSource, dwMessageId, dwLanguageId );
|
||||||
if (!from && (dwFlags & FORMAT_MESSAGE_FROM_SYSTEM))
|
if (!from && (dwFlags & FORMAT_MESSAGE_FROM_SYSTEM))
|
||||||
from = load_message( kernel32_handle, dwMessageId, (WORD)dwLanguageId );
|
from = load_message( kernel32_handle, dwMessageId, dwLanguageId );
|
||||||
if (!from) return 0;
|
if (!from) return 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -497,7 +546,6 @@ DWORD WINAPI FormatMessageW(
|
||||||
LPWSTR target;
|
LPWSTR target;
|
||||||
DWORD talloced;
|
DWORD talloced;
|
||||||
LPWSTR from;
|
LPWSTR from;
|
||||||
DWORD width = dwFlags & FORMAT_MESSAGE_MAX_WIDTH_MASK;
|
|
||||||
|
|
||||||
TRACE("(0x%x,%p,%d,0x%x,%p,%d,%p)\n",
|
TRACE("(0x%x,%p,%d,0x%x,%p,%d,%p)\n",
|
||||||
dwFlags,lpSource,dwMessageId,dwLanguageId,lpBuffer,nSize,args);
|
dwFlags,lpSource,dwMessageId,dwLanguageId,lpBuffer,nSize,args);
|
||||||
|
@ -524,8 +572,6 @@ DWORD WINAPI FormatMessageW(
|
||||||
format_args.last = 0;
|
format_args.last = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (width && width != FORMAT_MESSAGE_MAX_WIDTH_MASK)
|
|
||||||
FIXME("line wrapping not supported.\n");
|
|
||||||
from = NULL;
|
from = NULL;
|
||||||
if (dwFlags & FORMAT_MESSAGE_FROM_STRING) {
|
if (dwFlags & FORMAT_MESSAGE_FROM_STRING) {
|
||||||
from = HeapAlloc( GetProcessHeap(), 0, (strlenW(lpSource) + 1) *
|
from = HeapAlloc( GetProcessHeap(), 0, (strlenW(lpSource) + 1) *
|
||||||
|
@ -535,9 +581,9 @@ DWORD WINAPI FormatMessageW(
|
||||||
else if (dwFlags & (FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_FROM_SYSTEM))
|
else if (dwFlags & (FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_FROM_SYSTEM))
|
||||||
{
|
{
|
||||||
if (dwFlags & FORMAT_MESSAGE_FROM_HMODULE)
|
if (dwFlags & FORMAT_MESSAGE_FROM_HMODULE)
|
||||||
from = load_message( (HMODULE)lpSource, dwMessageId, (WORD)dwLanguageId );
|
from = load_message( (HMODULE)lpSource, dwMessageId, dwLanguageId );
|
||||||
if (!from && (dwFlags & FORMAT_MESSAGE_FROM_SYSTEM))
|
if (!from && (dwFlags & FORMAT_MESSAGE_FROM_SYSTEM))
|
||||||
from = load_message( kernel32_handle, dwMessageId, (WORD)dwLanguageId );
|
from = load_message( kernel32_handle, dwMessageId, dwLanguageId );
|
||||||
if (!from) return 0;
|
if (!from) return 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in a new issue