[unDName 3/5]: Use a separate stack for back references to names

Michael Stefaniuc mstefani at redhat.de
Sat Feb 18 12:42:21 CST 2006


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(-)

637ed0ce6c10039ac1ac12dccbbbac4f130f4c0c
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++;
 
-- 
1.2.1

-- 
Michael Stefaniuc               Tel.: +49-711-96437-199
Sr. Network Engineer            Fax.: +49-711-96437-111
Red Hat GmbH                    Email: mstefani at redhat.com
Hauptstaetterstr. 58            http://www.redhat.de/
D-70178 Stuttgart
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://www.winehq.org/pipermail/wine-patches/attachments/20060218/2fe9bcfd/attachment.pgp


More information about the wine-patches mailing list