[unDName 2/5]: Move code to parse a literal string out of get_class()

Michael Stefaniuc mstefani at redhat.de
Sat Feb 18 12:40:27 CST 2006


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

a7f99c8efd40c4d5c55031ff43b14158a9f1c91e
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 at 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;
         }
     }
-- 
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/674002d2/attachment.pgp


More information about the wine-patches mailing list