Module: wine
Branch: refs/heads/master
Commit: 262a5eec7873a3890c044650b950cb532fa368a0
URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=262a5eec7873a3890c04465…
Author: Michael Stefaniuc <mstefani(a)redhat.de>
Date: Mon Feb 20 11:18:04 2006 +0100
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.
---
dlls/msvcrt/undname.c | 47 +++++++++++++++++++++++++++--------------------
1 files changed, 27 insertions(+), 20 deletions(-)
diff --git a/dlls/msvcrt/undname.c b/dlls/msvcrt/undname.c
index f5e3ecd..f879e49 100644
--- a/dlls/msvcrt/undname.c
+++ b/dlls/msvcrt/undname.c
@@ -91,6 +91,7 @@ struct parsed_symbol
const char* current; /* pointer in input (mangled) string */
char* result; /* demangled string */
+ struct array names; /* array of names for back reference */
struct array stack; /* stack of parsed strings */
void* alloc_list; /* linked list of allocated blocks */
@@ -420,9 +421,9 @@ static char* get_literal_string(struct p
}
} while (*++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 p
*/
static BOOL get_class(struct parsed_symbol* sym)
{
- const char* ptr;
+ const char* name = NULL;
while (*sym->current != '@')
{
@@ -451,39 +452,44 @@ static BOOL get_class(struct parsed_symb
case '0': case '1': case '2': case '3':
case '4': case '5': case '6': case '7':
case '8': case '9':
- ptr = str_array_get_ref(&sym->stack, *sym->current++ - '0');
- if (!ptr) return FALSE;
- str_array_push(sym, ptr, -1, &sym->stack);
+ name = str_array_get_ref(&sym->names, *sym->current++ - '0');
break;
case '?':
if (*++sym->current == '$')
{
- const char* name;
- char* full = NULL;
+ /* In a template argument list the back reference to names
+ 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;
- unsigned num_mark = sym->stack.num;
- unsigned start_mark = sym->stack.start;
+ unsigned num_mark = sym->names.num;
+ unsigned start_mark = sym->names.start;
+ unsigned stack_mark = sym->stack.num;
+ sym->names.start = sym->names.num;
sym->current++;
- sym->stack.start = sym->stack.num;
if (!(name = get_literal_string(sym)))
return FALSE;
args = get_args(sym, NULL, FALSE, '<', '>');
if (args != NULL)
- {
- full = str_printf(sym, "%s%s", name, args);
- }
- if (!full) return FALSE;
- sym->stack.elts[num_mark] = full;
- sym->stack.num = num_mark + 1;
- sym->stack.start = start_mark;
+ name = str_printf(sym, "%s%s", name, args);
+ sym->names.num = num_mark;
+ sym->names.start = start_mark;
+ sym->stack.num = stack_mark;
+ /* Now that we are back to the standard name scope push
+ the class component with all its template arguments
+ to the names array for back reference. */
+ str_array_push(sym, name, -1, &sym->names);
}
break;
default:
- if (!get_literal_string(sym))
- return FALSE;
+ name = get_literal_string(sym);
break;
}
+ if (!name)
+ return FALSE;
+ str_array_push(sym, name, -1, &sym->stack);
}
sym->current++;
return TRUE;
@@ -1027,6 +1033,7 @@ static BOOL symbol_demangle(struct parse
/* MS mangled names always begin with '?' */
if (*sym->current != '?') return FALSE;
+ str_array_init(&sym->names);
str_array_init(&sym->stack);
sym->current++;
Module: wine
Branch: refs/heads/master
Commit: e367ebbf19d7d0531bbb28de9cf35d8aa46b5c2b
URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=e367ebbf19d7d0531bbb28d…
Author: Michael Stefaniuc <mstefani(a)redhat.de>
Date: Mon Feb 20 11:17:41 2006 +0100
msvcrt: Move code to parse a literal string out of get_class().
unDName: Move the code to parse a literal string from get_class() to a
separate function. Add some error handling to the new function.
---
dlls/msvcrt/undname.c | 55 ++++++++++++++++++++++++++++++++++++++-----------
1 files changed, 43 insertions(+), 12 deletions(-)
diff --git a/dlls/msvcrt/undname.c b/dlls/msvcrt/undname.c
index 4318ca8..f5e3ecd 100644
--- a/dlls/msvcrt/undname.c
+++ b/dlls/msvcrt/undname.c
@@ -400,11 +400,43 @@ static const char* get_modified_type(str
}
/******************************************************************
+ * get_literal_string
+ * Gets the literal name from the current position in the mangled
+ * symbol to the first '@' character. It pushes the parsed name to
+ * the symbol names stack and returns a pointer to it or NULL in
+ * case of an error.
+ */
+static char* get_literal_string(struct parsed_symbol* sym)
+{
+ const char *ptr = sym->current;
+
+ do {
+ if (!((*sym->current >= 'A' && *sym->current <= 'Z') ||
+ (*sym->current >= 'a' && *sym->current <= 'z') ||
+ (*sym->current >= '0' && *sym->current <= '9') ||
+ *sym->current == '_' || *sym->current == '$')) {
+ TRACE("Failed at '%c' in %s\n", *sym->current, ptr);
+ return NULL;
+ }
+ } while (*++sym->current != '@');
+ sym->current++;
+ str_array_push(sym, ptr, sym->current - 1 - ptr, &sym->stack);
+
+ return str_array_get_ref(&sym->stack, sym->stack.num - sym->stack.start - 1);
+}
+
+/******************************************************************
* get_class
- * Parses class as a list of parent-classes, separated by '@', terminated by '@@'
- * and stores the result in 'a' array. Each parent-classes, as well as the inner
- * element (either field/method name or class name), are stored as allocated
- * strings in the array.
+ * Parses class as a list of parent-classes, terminated by '@' and stores the
+ * result in 'a' array. Each parent-classes, as well as the inner element
+ * (either field/method name or class name), are represented in the mangled
+ * name by a literal name ([a-zA-Z0-9_]+ terminated by '@') or a back reference
+ * ([0-9]) or a name with template arguments ('?$' literal name followed by the
+ * template argument list). The class name components appear in the reverse
+ * order in the mangled name, e.g aaa@bbb@ccc@@ will be demangled to
+ * ccc::bbb::aaa
+ * For each of this class name componets a string will be allocated in the
+ * array.
*/
static BOOL get_class(struct parsed_symbol* sym)
{
@@ -426,20 +458,20 @@ static BOOL get_class(struct parsed_symb
case '?':
if (*++sym->current == '$')
{
- const char* name = ++sym->current;
+ const char* name;
char* full = NULL;
char* args = NULL;
unsigned num_mark = sym->stack.num;
unsigned start_mark = sym->stack.start;
- while (*sym->current++ != '@');
-
+ sym->current++;
sym->stack.start = sym->stack.num;
- str_array_push(sym, name, sym->current - name -1, &sym->stack);
+ if (!(name = get_literal_string(sym)))
+ return FALSE;
args = get_args(sym, NULL, FALSE, '<', '>');
if (args != NULL)
{
- full = str_printf(sym, "%s%s", sym->stack.elts[num_mark], args);
+ full = str_printf(sym, "%s%s", name, args);
}
if (!full) return FALSE;
sym->stack.elts[num_mark] = full;
@@ -448,9 +480,8 @@ static BOOL get_class(struct parsed_symb
}
break;
default:
- ptr = sym->current;
- while (*sym->current++ != '@');
- str_array_push(sym, ptr, sym->current - 1 - ptr, &sym->stack);
+ if (!get_literal_string(sym))
+ return FALSE;
break;
}
}