kernel32: Separate format string parsing in FormatMessageA into a new function.

This commit is contained in:
Andrew Nguyen 2010-04-18 09:09:45 -05:00 committed by Alexandre Julliard
parent df83469258
commit f199a83d47
1 changed files with 111 additions and 97 deletions

View File

@ -404,6 +404,115 @@ static LPCWSTR format_insertW( int insert, LPCWSTR format, DWORD flags,
return format;
}
/**********************************************************************
* format_messageA (internal)
*/
static LPSTR format_messageA( DWORD dwFlags, LPCSTR fmtstr, struct format_args *format_args )
{
LPSTR target,t;
DWORD talloced;
LPCSTR f;
DWORD width = dwFlags & FORMAT_MESSAGE_MAX_WIDTH_MASK;
BOOL eos = FALSE;
CHAR ch;
target = t = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 100);
talloced = 100;
#define ADD_TO_T(c) do { \
*t++=c;\
if ((DWORD)(t-target) == talloced) {\
target = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,target,talloced*2);\
t = target+talloced;\
talloced*=2;\
}\
} while (0)
f = fmtstr;
if (dwFlags & FORMAT_MESSAGE_IGNORE_INSERTS) {
while (*f && !eos)
ADD_TO_T(*f++);
}
else {
while (*f && !eos) {
if (*f=='%') {
int insertnr;
char *str,*x;
f++;
if (!*f) {
ADD_TO_T('%');
continue;
}
switch (*f) {
case '1':case '2':case '3':case '4':case '5':
case '6':case '7':case '8':case '9':
insertnr = *f-'0';
switch (f[1]) {
case '0':case '1':case '2':case '3':
case '4':case '5':case '6':case '7':
case '8':case '9':
f++;
insertnr = insertnr*10 + *f-'0';
f++;
break;
default:
f++;
break;
}
f = format_insertA( insertnr, f, dwFlags, format_args, &str );
for (x = str; *x; x++) ADD_TO_T(*x);
HeapFree( GetProcessHeap(), 0, str );
break;
case 'n':
ADD_TO_T('\r');
ADD_TO_T('\n');
f++;
break;
case '0':
eos = TRUE;
f++;
break;
default:
ADD_TO_T(*f++);
break;
}
} else {
ch = *f;
f++;
if (ch == '\r') {
if (*f == '\n')
f++;
if(width)
ADD_TO_T(' ');
else
{
ADD_TO_T('\r');
ADD_TO_T('\n');
}
} else {
if (ch == '\n')
{
if(width)
ADD_TO_T(' ');
else
{
ADD_TO_T('\r');
ADD_TO_T('\n');
}
}
else
ADD_TO_T(ch);
}
}
}
}
*t = '\0';
return target;
}
#undef ADD_TO_T
/**********************************************************************
* format_messageW (internal)
*/
@ -529,13 +638,10 @@ DWORD WINAPI FormatMessageA(
{
struct format_args format_args;
DWORD ret = 0;
LPSTR target,t;
LPSTR target;
DWORD talloced;
LPSTR from;
LPCSTR f;
DWORD width = dwFlags & FORMAT_MESSAGE_MAX_WIDTH_MASK;
BOOL eos = FALSE;
CHAR ch;
TRACE("(0x%x,%p,%d,0x%x,%p,%d,%p)\n",
dwFlags,lpSource,dwMessageId,dwLanguageId,lpBuffer,nSize,args);
@ -578,101 +684,9 @@ DWORD WINAPI FormatMessageA(
from = load_messageA( kernel32_handle, dwMessageId, dwLanguageId );
if (!from) return 0;
}
target = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 100);
t = target;
talloced= 100;
#define ADD_TO_T(c) do { \
*t++=c;\
if ((DWORD)(t-target) == talloced) {\
target = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,target,talloced*2);\
t = target+talloced;\
talloced*=2;\
}\
} while (0)
target = format_messageA( dwFlags, from, &format_args );
if (from) {
f=from;
if (dwFlags & FORMAT_MESSAGE_IGNORE_INSERTS) {
while (*f && !eos)
ADD_TO_T(*f++);
}
else {
while (*f && !eos) {
if (*f=='%') {
int insertnr;
char *str,*x;
f++;
if (!*f) {
ADD_TO_T('%');
continue;
}
switch (*f) {
case '1':case '2':case '3':case '4':case '5':
case '6':case '7':case '8':case '9':
insertnr=*f-'0';
switch (f[1]) {
case '0':case '1':case '2':case '3':
case '4':case '5':case '6':case '7':
case '8':case '9':
f++;
insertnr=insertnr*10+*f-'0';
f++;
break;
default:
f++;
break;
}
f = format_insertA( insertnr, f, dwFlags, &format_args, &str );
for (x = str; *x; x++) ADD_TO_T(*x);
HeapFree( GetProcessHeap(), 0, str );
break;
case 'n':
ADD_TO_T('\r');
ADD_TO_T('\n');
f++;
break;
case '0':
eos = TRUE;
f++;
break;
default:
ADD_TO_T(*f++);
break;
}
} else {
ch = *f;
f++;
if (ch == '\r') {
if (*f == '\n')
f++;
if(width)
ADD_TO_T(' ');
else
{
ADD_TO_T('\r');
ADD_TO_T('\n');
}
} else {
if (ch == '\n')
{
if(width)
ADD_TO_T(' ');
else
{
ADD_TO_T('\r');
ADD_TO_T('\n');
}
}
else
ADD_TO_T(ch);
}
}
}
}
*t='\0';
}
talloced = strlen(target)+1;
TRACE("-- %s\n",debugstr_a(target));
if (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) {