msvcrt: Use a separate stack for back references to names

Use a separate array/stack for the back references to names as
sym->stack is used to push temporary strings to it which breaks back
referencing in some occasions (26 symbols in the mfc42 dll).  During
this cleanup get_class() a little bit.
This commit is contained in:
Michael Stefaniuc 2006-02-20 11:18:04 +01:00 committed by Alexandre Julliard
parent e367ebbf19
commit 262a5eec78
1 changed files with 27 additions and 20 deletions

View File

@ -91,6 +91,7 @@ struct parsed_symbol
const char* current; /* pointer in input (mangled) string */ const char* current; /* pointer in input (mangled) string */
char* result; /* demangled string */ char* result; /* demangled string */
struct array names; /* array of names for back reference */
struct array stack; /* stack of parsed strings */ struct array stack; /* stack of parsed strings */
void* alloc_list; /* linked list of allocated blocks */ void* alloc_list; /* linked list of allocated blocks */
@ -420,9 +421,9 @@ static char* get_literal_string(struct parsed_symbol* sym)
} }
} while (*++sym->current != '@'); } while (*++sym->current != '@');
sym->current++; sym->current++;
str_array_push(sym, ptr, sym->current - 1 - ptr, &sym->stack); str_array_push(sym, ptr, sym->current - 1 - ptr, &sym->names);
return str_array_get_ref(&sym->stack, sym->stack.num - sym->stack.start - 1); return str_array_get_ref(&sym->names, sym->names.num - sym->names.start - 1);
} }
/****************************************************************** /******************************************************************
@ -440,7 +441,7 @@ static char* get_literal_string(struct parsed_symbol* sym)
*/ */
static BOOL get_class(struct parsed_symbol* sym) static BOOL get_class(struct parsed_symbol* sym)
{ {
const char* ptr; const char* name = NULL;
while (*sym->current != '@') while (*sym->current != '@')
{ {
@ -451,39 +452,44 @@ static BOOL get_class(struct parsed_symbol* sym)
case '0': case '1': case '2': case '3': case '0': case '1': case '2': case '3':
case '4': case '5': case '6': case '7': case '4': case '5': case '6': case '7':
case '8': case '9': case '8': case '9':
ptr = str_array_get_ref(&sym->stack, *sym->current++ - '0'); name = str_array_get_ref(&sym->names, *sym->current++ - '0');
if (!ptr) return FALSE;
str_array_push(sym, ptr, -1, &sym->stack);
break; break;
case '?': case '?':
if (*++sym->current == '$') if (*++sym->current == '$')
{ {
const char* name; /* In a template argument list the back reference to names
char* full = NULL; table is separately created. '0' points to the class
component name with the template arguments. We use the same
stack array to hold the names but save/restore the stack
state before/after parsing the template argument list. */
char* args = NULL; char* args = NULL;
unsigned num_mark = sym->stack.num; unsigned num_mark = sym->names.num;
unsigned start_mark = sym->stack.start; unsigned start_mark = sym->names.start;
unsigned stack_mark = sym->stack.num;
sym->names.start = sym->names.num;
sym->current++; sym->current++;
sym->stack.start = sym->stack.num;
if (!(name = get_literal_string(sym))) if (!(name = get_literal_string(sym)))
return FALSE; return FALSE;
args = get_args(sym, NULL, FALSE, '<', '>'); args = get_args(sym, NULL, FALSE, '<', '>');
if (args != NULL) if (args != NULL)
{ name = str_printf(sym, "%s%s", name, args);
full = str_printf(sym, "%s%s", name, args); sym->names.num = num_mark;
} sym->names.start = start_mark;
if (!full) return FALSE; sym->stack.num = stack_mark;
sym->stack.elts[num_mark] = full; /* Now that we are back to the standard name scope push
sym->stack.num = num_mark + 1; the class component with all its template arguments
sym->stack.start = start_mark; to the names array for back reference. */
str_array_push(sym, name, -1, &sym->names);
} }
break; break;
default: default:
if (!get_literal_string(sym)) name = get_literal_string(sym);
return FALSE;
break; break;
} }
if (!name)
return FALSE;
str_array_push(sym, name, -1, &sym->stack);
} }
sym->current++; sym->current++;
return TRUE; return TRUE;
@ -1027,6 +1033,7 @@ static BOOL symbol_demangle(struct parsed_symbol* sym)
/* MS mangled names always begin with '?' */ /* MS mangled names always begin with '?' */
if (*sym->current != '?') return FALSE; if (*sym->current != '?') return FALSE;
str_array_init(&sym->names);
str_array_init(&sym->stack); str_array_init(&sym->stack);
sym->current++; sym->current++;