private static string get_number(ParsedSymbol sym) { char[] ptr; var sgn = false; if (sym.currentc == '?') { sgn = true; sym.current++; } if (sym.currentc >= '0' && sym.currentc <= '8') { ptr = new char[2]; // 3 with zterm if (sgn) ptr[0] = '-'; ptr[sgn ? 1 : 0] = (char)(sym.currentc + 1); //ptr[sgn ? 2 : 1] = '\0'; sym.current++; } else if (sym.currentc == '9') { ptr = new char[3]; // 4 with zterm if (sgn) ptr[0] = '-'; ptr[sgn ? 1 : 0] = '1'; ptr[sgn ? 2 : 1] = '0'; //ptr[sgn ? 3 : 2] = '\0'; sym.current++; } else if (sym.currentc >= 'A' && sym.currentc <= 'P') { var ret = 0; while (sym.currentc >= 'A' && sym.currentc <= 'P') { ret *= 16; ret += sym.current.Inc() - 'A'; } if (sym.currentc != '@') return null; //ptr = new char[17]; //sprintf(ptr, "%s%u", sgn ? "-" : "", ret); ptr = $"{(sgn ? "-" : "")}{ret}".ToCharArray(); sym.current++; } else return null; return ptr.ToString(); }
/* private static bool get_modified_type(DataType ct, ParsedSymbol sym, array? *pmt_ref, char modif, bool in_args) { string modifier; string str_modif; string ptr_modif = ""; // TODO: ptr_modif will be overrided in get_modifier??? if (sym.currentc == 'E') { if (!sym.flags.HasFlag(DemanglerFlags.UNDNAME_NO_MS_KEYWORDS)) { // TODO: Add "__" on !flag ptr_modif = sym.flags.HasFlag(DemanglerFlags.UNDNAME_NO_LEADING_UNDERSCORES) ? " ptr64" : " __ptr64"; } sym.current++; } switch (modif) { case 'A': str_modif = $" &{ptr_modif}"; break; case 'B': str_modif = $" &{ptr_modif} volatile"; break; case 'P': str_modif = $" *{ptr_modif}"; break; case 'Q': str_modif = $" *{ptr_modif} const"; break; case 'R': str_modif = $" *{ptr_modif} volatile"; break; case 'S': str_modif = $" *{ptr_modif} const volatile"; break; case '?': str_modif = ""; break; default: return false; } if (get_modifier(sym, out modifier, out ptr_modif)) { var mark = sym.stack; // TODO: CLONE! DataType sub_ct; // multidimensional arrays if (sym.currentc == 'Y') { sym.current++; var n1 = get_number(sym); if (n1 == null) return false; var num = Int32.Parse(n1); if (str_modif[0] == ' ' && modifier == null) //str_modif++; ; // TODO! if (modifier != null) { str_modif = $" ({modifier}{str_modif})"; modifier = null; } else str_modif = $" ({str_modif})"; while (num-- != 0) str_modif = $"{str_modif}[{get_number(sym)}]"; } // Recurse to get the referred-to type if (!demangle_datatype(sym, &sub_ct, pmt_ref, false)) return false; if (modifier != null) ct.left = $"{sub_ct.left} {modifier}{str_modif}"; else { // don't insert a space between duplicate '*' if (!in_args && str_modif[0] && str_modif[1] == '*' && sub_ct.left[strlen(sub_ct.left) - 1] == '*') str_modif++; ct.left = $"{sub_ct.left}{str_modif}"; } ct.right = sub_ct.right; sym.stack = mark; // TODO: RESTORE } return true; } */ private static string get_literal_string(ParsedSymbol sym) { //const char *ptr = sym->current; var literal = new StringBuilder(); do { if (!((sym.currentc >= 'A' && sym.currentc <= 'Z') || (sym.currentc >= 'a' && sym.currentc <= 'z') || (sym.currentc >= '0' && sym.currentc <= '9') || sym.currentc == '_' || sym.currentc == '$')) { //TRACE($"Failed at '{sym.currentc}' in {ptr}"); return null; } literal.Append(sym.currentc); } while (sym.current.PreInc() != '@'); sym.current++; //if (!str_array_push(sym, ptr, sym->current - 1 - ptr, &sym->names)) // return null; sym.names.Add(literal.ToString()); //return str_array_get_ref(&sym->names, sym->names.num - sym->names.start - 1); return sym.names.Last(); }
/* private static string get_args(ParsedSymbol sym, array? *pmt_ref, bool z_term, char open_char, char close_char) { struct datatype_t ct; struct array arg_collect; char* args_str = NULL; char* last; unsigned int i; str_array_init(&arg_collect); // Now come the function arguments while (*sym->current) { // Decode each data type and append it to the argument list if (*sym->current == '@') { sym->current++; break; } if (!demangle_datatype(sym, &ct, pmt_ref, TRUE)) return NULL; // 'void' terminates an argument list in a function if (z_term && !strcmp(ct.left, "void")) break; if (!str_array_push(sym, str_printf(sym, "%s%s", ct.left, ct.right), -1, &arg_collect)) return NULL; if (!strcmp(ct.left, "...")) break; } // Functions are always terminated by 'Z'. If we made it this far and // don't find it, we have incorrectly identified a data type. if (z_term && * sym->current++ != 'Z') return NULL; if (arg_collect.num == 0 || (arg_collect.num == 1 && !strcmp(arg_collect.elts[0], "void"))) return str_printf(sym, "%cvoid%c", open_char, close_char); for (i = 1; i<arg_collect.num; i++) { args_str = str_printf(sym, "%s,%s", args_str, arg_collect.elts[i]); } last = args_str? args_str : arg_collect.elts[0]; if (close_char == '>' && last[strlen(last) - 1] == '>') args_str = str_printf(sym, "%c%s%s %c", open_char, arg_collect.elts[0], args_str, close_char); else args_str = str_printf(sym, "%c%s%s%c", open_char, arg_collect.elts[0], args_str, close_char); return args_str; } */ private static bool get_modifier(ParsedSymbol sym, out string ret, out string ptr_modif) { ptr_modif = null; if (sym.currentc == 'E') { if (!sym.flags.HasFlag(DemanglerFlags.UNDNAME_NO_MS_KEYWORDS)) { // TODO: Add "__" on !flag ptr_modif = sym.flags.HasFlag(DemanglerFlags.UNDNAME_NO_LEADING_UNDERSCORES) ? " ptr64" : " __ptr64"; } sym.current++; } ret = null; switch (sym.current.Inc()) { case 'A': break; case 'B': ret = "const"; break; case 'C': ret = "volatile"; break; case 'D': ret = "const volatile"; break; default: return false; } return true; }