00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifdef HAVE_CONFIG_H
00033 #include "config.h"
00034 #endif
00035
00036 #include <ctype.h>
00037 #include <sys/types.h>
00038 #include <string.h>
00039 #include <stdio.h>
00040 #include <stdlib.h>
00041
00042 #include "demangle.h"
00043 #undef CURRENT_DEMANGLING_STYLE
00044 #define CURRENT_DEMANGLING_STYLE work->options
00045
00046
00047 #define xmalloc malloc
00048 #define xrealloc realloc
00049
00050 #define min(X,Y) (((X) < (Y)) ? (X) : (Y))
00051
00052
00053
00054 #define INTBUF_SIZE 32
00055
00056 extern void fancy_abort (void);
00057
00058 static const char *mystrstr (const char *, const char *);
00059
00060 static const char *
00061 mystrstr (s1, s2)
00062 const char *s1, *s2;
00063 {
00064 register const char *p = s1;
00065 register int len = strlen (s2);
00066
00067 for (; (p = strchr (p, *s2)) != 0; p++)
00068 {
00069 if (strncmp (p, s2, len) == 0)
00070 {
00071 return (p);
00072 }
00073 }
00074 return (0);
00075 }
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 #if !defined (CPLUS_MARKER)
00094 #define CPLUS_MARKER '$'
00095 #endif
00096
00097 enum demangling_styles current_demangling_style = gnu_demangling;
00098
00099 static char cplus_markers[] = { CPLUS_MARKER, '.', '$', '\0' };
00100
00101 static char char_str[2] = { '\000', '\000' };
00102
00103 void
00104 set_cplus_marker_for_demangling (ch)
00105 int ch;
00106 {
00107 cplus_markers[0] = ch;
00108 }
00109
00110 typedef struct string
00111 {
00112 char *b;
00113 char *p;
00114 char *e;
00115 } string;
00116
00117
00118
00119
00120 struct work_stuff
00121 {
00122 int options;
00123 char **typevec;
00124 char **ktypevec;
00125 char **btypevec;
00126 int numk;
00127 int numb;
00128 int ksize;
00129 int bsize;
00130 int ntypes;
00131 int typevec_size;
00132 int constructor;
00133 int destructor;
00134 int static_type;
00135 int temp_start;
00136 int type_quals;
00137 int dllimported;
00138 char **tmpl_argvec;
00139 int ntmpl_args;
00140 int forgetting_types;
00141
00142 string* previous_argument;
00143 int nrepeats;
00144
00145 };
00146
00147 #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
00148 #define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
00149
00150 static const struct optable
00151 {
00152 const char *in;
00153 const char *out;
00154 int flags;
00155 } optable[] = {
00156 {"nw", " new", DMGL_ANSI},
00157 {"dl", " delete", DMGL_ANSI},
00158 {"new", " new", 0},
00159 {"delete", " delete", 0},
00160 {"vn", " new []", DMGL_ANSI},
00161 {"vd", " delete []", DMGL_ANSI},
00162 {"as", "=", DMGL_ANSI},
00163 {"ne", "!=", DMGL_ANSI},
00164 {"eq", "==", DMGL_ANSI},
00165 {"ge", ">=", DMGL_ANSI},
00166 {"gt", ">", DMGL_ANSI},
00167 {"le", "<=", DMGL_ANSI},
00168 {"lt", "<", DMGL_ANSI},
00169 {"plus", "+", 0},
00170 {"pl", "+", DMGL_ANSI},
00171 {"apl", "+=", DMGL_ANSI},
00172 {"minus", "-", 0},
00173 {"mi", "-", DMGL_ANSI},
00174 {"ami", "-=", DMGL_ANSI},
00175 {"mult", "*", 0},
00176 {"ml", "*", DMGL_ANSI},
00177 {"amu", "*=", DMGL_ANSI},
00178 {"aml", "*=", DMGL_ANSI},
00179 {"convert", "+", 0},
00180 {"negate", "-", 0},
00181 {"trunc_mod", "%", 0},
00182 {"md", "%", DMGL_ANSI},
00183 {"amd", "%=", DMGL_ANSI},
00184 {"trunc_div", "/", 0},
00185 {"dv", "/", DMGL_ANSI},
00186 {"adv", "/=", DMGL_ANSI},
00187 {"truth_andif", "&&", 0},
00188 {"aa", "&&", DMGL_ANSI},
00189 {"truth_orif", "||", 0},
00190 {"oo", "||", DMGL_ANSI},
00191 {"truth_not", "!", 0},
00192 {"nt", "!", DMGL_ANSI},
00193 {"postincrement","++", 0},
00194 {"pp", "++", DMGL_ANSI},
00195 {"postdecrement","--", 0},
00196 {"mm", "--", DMGL_ANSI},
00197 {"bit_ior", "|", 0},
00198 {"or", "|", DMGL_ANSI},
00199 {"aor", "|=", DMGL_ANSI},
00200 {"bit_xor", "^", 0},
00201 {"er", "^", DMGL_ANSI},
00202 {"aer", "^=", DMGL_ANSI},
00203 {"bit_and", "&", 0},
00204 {"ad", "&", DMGL_ANSI},
00205 {"aad", "&=", DMGL_ANSI},
00206 {"bit_not", "~", 0},
00207 {"co", "~", DMGL_ANSI},
00208 {"call", "()", 0},
00209 {"cl", "()", DMGL_ANSI},
00210 {"alshift", "<<", 0},
00211 {"ls", "<<", DMGL_ANSI},
00212 {"als", "<<=", DMGL_ANSI},
00213 {"arshift", ">>", 0},
00214 {"rs", ">>", DMGL_ANSI},
00215 {"ars", ">>=", DMGL_ANSI},
00216 {"component", "->", 0},
00217 {"pt", "->", DMGL_ANSI},
00218 {"rf", "->", DMGL_ANSI},
00219 {"indirect", "*", 0},
00220 {"method_call", "->()", 0},
00221 {"addr", "&", 0},
00222 {"array", "[]", 0},
00223 {"vc", "[]", DMGL_ANSI},
00224 {"compound", ", ", 0},
00225 {"cm", ", ", DMGL_ANSI},
00226 {"cond", "?:", 0},
00227 {"cn", "?:", DMGL_ANSI},
00228 {"max", ">?", 0},
00229 {"mx", ">?", DMGL_ANSI},
00230 {"min", "<?", 0},
00231 {"mn", "<?", DMGL_ANSI},
00232 {"nop", "", 0},
00233 {"rm", "->*", DMGL_ANSI},
00234 {"sz", "sizeof ", DMGL_ANSI}
00235 };
00236
00237
00238
00239
00240 typedef enum type_kind_t
00241 {
00242 tk_none,
00243 tk_pointer,
00244 tk_reference,
00245 tk_integral,
00246 tk_bool,
00247 tk_char,
00248 tk_real
00249 } type_kind_t;
00250
00251 #define STRING_EMPTY(str) ((str) -> b == (str) -> p)
00252 #define PREPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
00253 string_prepend(str, " ");}
00254 #define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
00255 string_append(str, " ");}
00256 #define LEN_STRING(str) ( (STRING_EMPTY(str))?0:((str)->p - (str)->b))
00257
00258
00259
00260 #define SCOPE_STRING(work) ((work->options & DMGL_JAVA) ? "." : "::")
00261
00262 #define ARM_VTABLE_STRING "__vtbl__"
00263 #define ARM_VTABLE_STRLEN 8
00264
00265
00266
00267 static char *
00268 mop_up (struct work_stuff *, string *, int);
00269
00270 static void
00271 squangle_mop_up (struct work_stuff *);
00272
00273 #if 0
00274 static int
00275 demangle_method_args (struct work_stuff *, const char **, string *);
00276 #endif
00277
00278 static char *
00279 internal_cplus_demangle (struct work_stuff *, const char *);
00280
00281 static int
00282 demangle_template_template_parm (struct work_stuff *work,
00283 const char **, string *);
00284
00285 static int
00286 demangle_template (struct work_stuff *work, const char **, string *,
00287 string *, int, int);
00288
00289 static int
00290 arm_pt (struct work_stuff *, const char *, int, const char **,
00291 const char **);
00292
00293 static int
00294 demangle_class_name (struct work_stuff *, const char **, string *);
00295
00296 static int
00297 demangle_qualified (struct work_stuff *, const char **, string *,
00298 int, int);
00299
00300 static int
00301 demangle_class (struct work_stuff *, const char **, string *);
00302
00303 static int
00304 demangle_fund_type (struct work_stuff *, const char **, string *);
00305
00306 static int
00307 demangle_signature (struct work_stuff *, const char **, string *);
00308
00309 static int
00310 demangle_prefix (struct work_stuff *, const char **, string *);
00311
00312 static int
00313 gnu_special (struct work_stuff *, const char **, string *);
00314
00315 static int
00316 arm_special (const char **, string *);
00317
00318 static void
00319 string_need (string *, int);
00320
00321 static void
00322 string_delete (string *);
00323
00324 static void
00325 string_init (string *);
00326
00327 static void
00328 string_clear (string *);
00329
00330 #if 0
00331 static int
00332 string_empty (string *);
00333 #endif
00334
00335 static void
00336 string_append (string *, const char *);
00337
00338 static void
00339 string_appends (string *, string *);
00340
00341 static void
00342 string_appendn (string *, const char *, int);
00343
00344 static void
00345 string_prepend (string *, const char *);
00346
00347 static void
00348 string_prependn (string *, const char *, int);
00349
00350 static void
00351 string_append_template_idx (string *, int);
00352
00353 static int
00354 get_count (const char **, int *);
00355
00356 static int
00357 consume_count (const char **);
00358
00359 static int
00360 consume_count_with_underscores (const char**);
00361
00362 static int
00363 demangle_args (struct work_stuff *, const char **, string *);
00364
00365 static int
00366 demangle_nested_args (struct work_stuff*, const char**, string*);
00367
00368 static int
00369 do_type (struct work_stuff *, const char **, string *);
00370
00371 static int
00372 do_arg (struct work_stuff *, const char **, string *);
00373
00374 static void
00375 demangle_function_name (struct work_stuff *, const char **, string *,
00376 const char *);
00377
00378 static void
00379 remember_type (struct work_stuff *, const char *, int);
00380
00381 static void
00382 remember_Btype (struct work_stuff *, const char *, int, int);
00383
00384 static int
00385 register_Btype (struct work_stuff *);
00386
00387 static void
00388 remember_Ktype (struct work_stuff *, const char *, int);
00389
00390 static void
00391 forget_types (struct work_stuff *);
00392
00393 static void
00394 forget_B_and_K_types (struct work_stuff *);
00395
00396 static void
00397 string_prepends (string *, string *);
00398
00399 static int
00400 demangle_template_value_parm (struct work_stuff*, const char**,
00401 string*, type_kind_t);
00402
00403 static int
00404 do_hpacc_template_const_value (struct work_stuff *, const char **, string *);
00405
00406 static int
00407 do_hpacc_template_literal (struct work_stuff *, const char **, string *);
00408
00409 static int
00410 snarf_numeric_literal (const char **, string *);
00411
00412
00413
00414
00415
00416 #define TYPE_UNQUALIFIED 0x0
00417 #define TYPE_QUAL_CONST 0x1
00418 #define TYPE_QUAL_VOLATILE 0x2
00419 #define TYPE_QUAL_RESTRICT 0x4
00420
00421 static int
00422 code_for_qualifier (int);
00423
00424 static const char*
00425 qualifier_string (int);
00426
00427 static const char*
00428 demangle_qualifier (int);
00429
00430 static int
00431 demangle_expression (struct work_stuff *, const char **, string *,
00432 type_kind_t);
00433
00434 static int
00435 demangle_integral_value (struct work_stuff *, const char **,
00436 string *);
00437
00438 static int
00439 demangle_real_value (struct work_stuff *, const char **, string *);
00440
00441 static void
00442 demangle_arm_hp_template (struct work_stuff *, const char **, int,
00443 string *);
00444
00445 static void
00446 recursively_demangle (struct work_stuff *, const char **, string *,
00447 int);
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457 static int
00458 consume_count (type)
00459 const char **type;
00460 {
00461 int count = 0;
00462
00463 if (! isdigit ((unsigned char)**type))
00464 return -1;
00465
00466 while (isdigit ((unsigned char)**type))
00467 {
00468 count *= 10;
00469
00470
00471
00472
00473
00474
00475 if ((count % 10) != 0)
00476 {
00477 while (isdigit ((unsigned char) **type))
00478 (*type)++;
00479 return -1;
00480 }
00481
00482 count += **type - '0';
00483 (*type)++;
00484 }
00485
00486 return (count);
00487 }
00488
00489
00490
00491
00492
00493
00494 static int
00495 consume_count_with_underscores (mangled)
00496 const char **mangled;
00497 {
00498 int idx;
00499
00500 if (**mangled == '_')
00501 {
00502 (*mangled)++;
00503 if (!isdigit ((unsigned char)**mangled))
00504 return -1;
00505
00506 idx = consume_count (mangled);
00507 if (**mangled != '_')
00508
00509 return -1;
00510
00511 (*mangled)++;
00512 }
00513 else
00514 {
00515 if (**mangled < '0' || **mangled > '9')
00516 return -1;
00517
00518 idx = **mangled - '0';
00519 (*mangled)++;
00520 }
00521
00522 return idx;
00523 }
00524
00525
00526
00527
00528 static int
00529 code_for_qualifier (c)
00530 int c;
00531 {
00532 switch (c)
00533 {
00534 case 'C':
00535 return TYPE_QUAL_CONST;
00536
00537 case 'V':
00538 return TYPE_QUAL_VOLATILE;
00539
00540 case 'u':
00541 return TYPE_QUAL_RESTRICT;
00542
00543 default:
00544 break;
00545 }
00546
00547
00548 abort ();
00549 }
00550
00551
00552
00553
00554 static const char*
00555 qualifier_string (type_quals)
00556 int type_quals;
00557 {
00558 switch (type_quals)
00559 {
00560 case TYPE_UNQUALIFIED:
00561 return "";
00562
00563 case TYPE_QUAL_CONST:
00564 return "const";
00565
00566 case TYPE_QUAL_VOLATILE:
00567 return "volatile";
00568
00569 case TYPE_QUAL_RESTRICT:
00570 return "__restrict";
00571
00572 case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE:
00573 return "const volatile";
00574
00575 case TYPE_QUAL_CONST | TYPE_QUAL_RESTRICT:
00576 return "const __restrict";
00577
00578 case TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
00579 return "volatile __restrict";
00580
00581 case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
00582 return "const volatile __restrict";
00583
00584 default:
00585 break;
00586 }
00587
00588
00589 abort ();
00590 }
00591
00592
00593
00594
00595
00596 static const char*
00597 demangle_qualifier (c)
00598 int c;
00599 {
00600 return qualifier_string (code_for_qualifier (c));
00601 }
00602
00603 int
00604 cplus_demangle_opname (opname, result, options)
00605 const char *opname;
00606 char *result;
00607 int options;
00608 {
00609 int len, len1, ret;
00610 string type;
00611 struct work_stuff work[1];
00612 const char *tem;
00613
00614 len = strlen(opname);
00615 result[0] = '\0';
00616 ret = 0;
00617 memset ((char *) work, 0, sizeof (work));
00618 work->options = options;
00619
00620 if (opname[0] == '_' && opname[1] == '_'
00621 && opname[2] == 'o' && opname[3] == 'p')
00622 {
00623
00624
00625 tem = opname + 4;
00626 if (do_type (work, &tem, &type))
00627 {
00628 strcat (result, "operator ");
00629 strncat (result, type.b, type.p - type.b);
00630 string_delete (&type);
00631 ret = 1;
00632 }
00633 }
00634 else if (opname[0] == '_' && opname[1] == '_'
00635 && opname[2] >= 'a' && opname[2] <= 'z'
00636 && opname[3] >= 'a' && opname[3] <= 'z')
00637 {
00638 if (opname[4] == '\0')
00639 {
00640
00641 size_t i;
00642 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
00643 {
00644 if (strlen (optable[i].in) == 2
00645 && memcmp (optable[i].in, opname + 2, 2) == 0)
00646 {
00647 strcat (result, "operator");
00648 strcat (result, optable[i].out);
00649 ret = 1;
00650 break;
00651 }
00652 }
00653 }
00654 else
00655 {
00656 if (opname[2] == 'a' && opname[5] == '\0')
00657 {
00658
00659 size_t i;
00660 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
00661 {
00662 if (strlen (optable[i].in) == 3
00663 && memcmp (optable[i].in, opname + 2, 3) == 0)
00664 {
00665 strcat (result, "operator");
00666 strcat (result, optable[i].out);
00667 ret = 1;
00668 break;
00669 }
00670 }
00671 }
00672 }
00673 }
00674 else if (len >= 3
00675 && opname[0] == 'o'
00676 && opname[1] == 'p'
00677 && strchr (cplus_markers, opname[2]) != NULL)
00678 {
00679
00680 if (len >= 10
00681 && memcmp (opname + 3, "assign_", 7) == 0)
00682 {
00683 size_t i;
00684 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
00685 {
00686 len1 = len - 10;
00687 if ((int) strlen (optable[i].in) == len1
00688 && memcmp (optable[i].in, opname + 10, len1) == 0)
00689 {
00690 strcat (result, "operator");
00691 strcat (result, optable[i].out);
00692 strcat (result, "=");
00693 ret = 1;
00694 break;
00695 }
00696 }
00697 }
00698 else
00699 {
00700 size_t i;
00701 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
00702 {
00703 len1 = len - 3;
00704 if ((int) strlen (optable[i].in) == len1
00705 && memcmp (optable[i].in, opname + 3, len1) == 0)
00706 {
00707 strcat (result, "operator");
00708 strcat (result, optable[i].out);
00709 ret = 1;
00710 break;
00711 }
00712 }
00713 }
00714 }
00715 else if (len >= 5 && memcmp (opname, "type", 4) == 0
00716 && strchr (cplus_markers, opname[4]) != NULL)
00717 {
00718
00719 tem = opname + 5;
00720 if (do_type (work, &tem, &type))
00721 {
00722 strcat (result, "operator ");
00723 strncat (result, type.b, type.p - type.b);
00724 string_delete (&type);
00725 ret = 1;
00726 }
00727 }
00728 squangle_mop_up (work);
00729 return ret;
00730
00731 }
00732
00733
00734
00735
00736
00737
00738 const char *
00739 cplus_mangle_opname (opname, options)
00740 const char *opname;
00741 int options;
00742 {
00743 size_t i;
00744 int len;
00745
00746 len = strlen (opname);
00747 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
00748 {
00749 if ((int) strlen (optable[i].out) == len
00750 && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI)
00751 && memcmp (optable[i].out, opname, len) == 0)
00752 return optable[i].in;
00753 }
00754 return (0);
00755 }
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785 char *
00786 cplus_demangle (mangled, options)
00787 const char *mangled;
00788 int options;
00789 {
00790 char *ret;
00791 struct work_stuff work[1];
00792 memset ((char *) work, 0, sizeof (work));
00793 work -> options = options;
00794 if ((work -> options & DMGL_STYLE_MASK) == 0)
00795 work -> options |= (int) current_demangling_style & DMGL_STYLE_MASK;
00796
00797 ret = internal_cplus_demangle (work, mangled);
00798 squangle_mop_up (work);
00799 return (ret);
00800 }
00801
00802
00803
00804
00805
00806
00807
00808
00809 static char *
00810 internal_cplus_demangle (work, mangled)
00811 struct work_stuff *work;
00812 const char *mangled;
00813 {
00814
00815 string decl;
00816 int success = 0;
00817 char *demangled = NULL;
00818 int s1,s2,s3,s4;
00819 s1 = work->constructor;
00820 s2 = work->destructor;
00821 s3 = work->static_type;
00822 s4 = work->type_quals;
00823 work->constructor = work->destructor = 0;
00824 work->type_quals = TYPE_UNQUALIFIED;
00825 work->dllimported = 0;
00826
00827 if ((mangled != NULL) && (*mangled != '\0'))
00828 {
00829 string_init (&decl);
00830
00831
00832
00833
00834
00835
00836
00837
00838 if ((AUTO_DEMANGLING || GNU_DEMANGLING))
00839 {
00840 success = gnu_special (work, &mangled, &decl);
00841 }
00842 if (!success)
00843 {
00844 success = demangle_prefix (work, &mangled, &decl);
00845 }
00846 if (success && (*mangled != '\0'))
00847 {
00848 success = demangle_signature (work, &mangled, &decl);
00849 }
00850 if (work->constructor == 2)
00851 {
00852 string_prepend (&decl, "global constructors keyed to ");
00853 work->constructor = 0;
00854 }
00855 else if (work->destructor == 2)
00856 {
00857 string_prepend (&decl, "global destructors keyed to ");
00858 work->destructor = 0;
00859 }
00860 else if (work->dllimported == 1)
00861 {
00862 string_prepend (&decl, "import stub for ");
00863 work->dllimported = 0;
00864 }
00865 demangled = mop_up (work, &decl, success);
00866 }
00867 work->constructor = s1;
00868 work->destructor = s2;
00869 work->static_type = s3;
00870 work->type_quals = s4;
00871 return (demangled);
00872 }
00873
00874
00875
00876 static void
00877 squangle_mop_up (work)
00878 struct work_stuff *work;
00879 {
00880
00881 forget_B_and_K_types (work);
00882 if (work -> btypevec != NULL)
00883 {
00884 free ((char *) work -> btypevec);
00885 }
00886 if (work -> ktypevec != NULL)
00887 {
00888 free ((char *) work -> ktypevec);
00889 }
00890 }
00891
00892
00893
00894 static char *
00895 mop_up (work, declp, success)
00896 struct work_stuff *work;
00897 string *declp;
00898 int success;
00899 {
00900 char *demangled = NULL;
00901
00902
00903
00904 forget_types (work);
00905 if (work -> typevec != NULL)
00906 {
00907 free ((char *) work -> typevec);
00908 work -> typevec = NULL;
00909 work -> typevec_size = 0;
00910 }
00911 if (work->tmpl_argvec)
00912 {
00913 int i;
00914
00915 for (i = 0; i < work->ntmpl_args; i++)
00916 if (work->tmpl_argvec[i])
00917 free ((char*) work->tmpl_argvec[i]);
00918
00919 free ((char*) work->tmpl_argvec);
00920 work->tmpl_argvec = NULL;
00921 }
00922 if (work->previous_argument)
00923 {
00924 string_delete (work->previous_argument);
00925 free ((char*) work->previous_argument);
00926 work->previous_argument = NULL;
00927 }
00928
00929
00930
00931
00932 if (!success)
00933 {
00934 string_delete (declp);
00935 }
00936 else
00937 {
00938 string_appendn (declp, "", 1);
00939 demangled = declp -> b;
00940 }
00941 return (demangled);
00942 }
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974 static int
00975 demangle_signature (work, mangled, declp)
00976 struct work_stuff *work;
00977 const char **mangled;
00978 string *declp;
00979 {
00980 int success = 1;
00981 int func_done = 0;
00982 int expect_func = 0;
00983 int expect_return_type = 0;
00984 const char *oldmangled = NULL;
00985 string trawname;
00986 string tname;
00987
00988 while (success && (**mangled != '\0'))
00989 {
00990 switch (**mangled)
00991 {
00992 case 'Q':
00993 oldmangled = *mangled;
00994 success = demangle_qualified (work, mangled, declp, 1, 0);
00995 if (success)
00996 remember_type (work, oldmangled, *mangled - oldmangled);
00997 if (AUTO_DEMANGLING || GNU_DEMANGLING)
00998 expect_func = 1;
00999 oldmangled = NULL;
01000 break;
01001
01002 case 'K':
01003 oldmangled = *mangled;
01004 success = demangle_qualified (work, mangled, declp, 1, 0);
01005 if (AUTO_DEMANGLING || GNU_DEMANGLING)
01006 {
01007 expect_func = 1;
01008 }
01009 oldmangled = NULL;
01010 break;
01011
01012 case 'S':
01013
01014 if (oldmangled == NULL)
01015 {
01016 oldmangled = *mangled;
01017 }
01018 (*mangled)++;
01019 work -> static_type = 1;
01020 break;
01021
01022 case 'C':
01023 case 'V':
01024 case 'u':
01025 work->type_quals |= code_for_qualifier (**mangled);
01026
01027
01028 if (oldmangled == NULL)
01029 oldmangled = *mangled;
01030 (*mangled)++;
01031 break;
01032
01033 case 'L':
01034
01035 if (HP_DEMANGLING)
01036 {
01037 while (**mangled && (**mangled != '_'))
01038 (*mangled)++;
01039 if (!**mangled)
01040 success = 0;
01041 else
01042 (*mangled)++;
01043 }
01044 else
01045 success = 0;
01046 break;
01047
01048 case '0': case '1': case '2': case '3': case '4':
01049 case '5': case '6': case '7': case '8': case '9':
01050 if (oldmangled == NULL)
01051 {
01052 oldmangled = *mangled;
01053 }
01054 work->temp_start = -1;
01055 success = demangle_class (work, mangled, declp);
01056 if (success)
01057 {
01058 remember_type (work, oldmangled, *mangled - oldmangled);
01059 }
01060 if (AUTO_DEMANGLING || GNU_DEMANGLING || EDG_DEMANGLING)
01061 {
01062
01063
01064 if (**mangled != 'F')
01065 expect_func = 1;
01066 }
01067 oldmangled = NULL;
01068 break;
01069
01070 case 'B':
01071 {
01072 string s;
01073 success = do_type (work, mangled, &s);
01074 if (success)
01075 {
01076 string_append (&s, SCOPE_STRING (work));
01077 string_prepends (declp, &s);
01078 }
01079 oldmangled = NULL;
01080 expect_func = 1;
01081 }
01082 break;
01083
01084 case 'F':
01085
01086
01087
01088
01089
01090
01091 oldmangled = NULL;
01092 func_done = 1;
01093 (*mangled)++;
01094
01095
01096
01097
01098
01099
01100 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
01101 {
01102 forget_types (work);
01103 }
01104 success = demangle_args (work, mangled, declp);
01105
01106
01107
01108 if (success && (AUTO_DEMANGLING || EDG_DEMANGLING) && **mangled == '_')
01109 {
01110 ++(*mangled);
01111
01112 success = do_type (work, mangled, &tname);
01113 string_delete (&tname);
01114 }
01115
01116 break;
01117
01118 case 't':
01119
01120 string_init(&trawname);
01121 string_init(&tname);
01122 if (oldmangled == NULL)
01123 {
01124 oldmangled = *mangled;
01125 }
01126 success = demangle_template (work, mangled, &tname,
01127 &trawname, 1, 1);
01128 if (success)
01129 {
01130 remember_type (work, oldmangled, *mangled - oldmangled);
01131 }
01132 string_append (&tname, SCOPE_STRING (work));
01133
01134 string_prepends(declp, &tname);
01135 if (work -> destructor & 1)
01136 {
01137 string_prepend (&trawname, "~");
01138 string_appends (declp, &trawname);
01139 work->destructor -= 1;
01140 }
01141 if ((work->constructor & 1) || (work->destructor & 1))
01142 {
01143 string_appends (declp, &trawname);
01144 work->constructor -= 1;
01145 }
01146 string_delete(&trawname);
01147 string_delete(&tname);
01148 oldmangled = NULL;
01149 expect_func = 1;
01150 break;
01151
01152 case '_':
01153 if (GNU_DEMANGLING && expect_return_type)
01154 {
01155
01156 string return_type;
01157 string_init (&return_type);
01158
01159 (*mangled)++;
01160 success = do_type (work, mangled, &return_type);
01161 APPEND_BLANK (&return_type);
01162
01163 string_prepends (declp, &return_type);
01164 string_delete (&return_type);
01165 break;
01166 }
01167 else
01168
01169
01170
01171
01172
01173
01174
01175
01176 if (HP_DEMANGLING)
01177 {
01178 (*mangled)++;
01179 while (**mangled && isdigit ((unsigned char)**mangled))
01180 (*mangled)++;
01181 }
01182 else
01183 success = 0;
01184 break;
01185
01186 case 'H':
01187 if (GNU_DEMANGLING)
01188 {
01189
01190 success = demangle_template (work, mangled, declp, 0, 0,
01191 0);
01192 if (!(work->constructor & 1))
01193 expect_return_type = 1;
01194 (*mangled)++;
01195 break;
01196 }
01197 else
01198
01199 {;}
01200
01201 default:
01202 if (AUTO_DEMANGLING || GNU_DEMANGLING)
01203 {
01204
01205
01206 func_done = 1;
01207 success = demangle_args (work, mangled, declp);
01208 }
01209 else
01210 {
01211
01212
01213
01214
01215 success = 0;
01216 }
01217 break;
01218 }
01219
01220
01221
01222 {
01223 if (success && expect_func)
01224 {
01225 func_done = 1;
01226 if (LUCID_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING)
01227 {
01228 forget_types (work);
01229 }
01230 success = demangle_args (work, mangled, declp);
01231
01232
01233
01234 expect_func = 0;
01235 }
01236 }
01237 }
01238 if (success && !func_done)
01239 {
01240 if (AUTO_DEMANGLING || GNU_DEMANGLING)
01241 {
01242
01243
01244
01245
01246
01247
01248 success = demangle_args (work, mangled, declp);
01249 }
01250 }
01251 if (success && PRINT_ARG_TYPES)
01252 {
01253 if (work->static_type)
01254 string_append (declp, " static");
01255 if (work->type_quals != TYPE_UNQUALIFIED)
01256 {
01257 APPEND_BLANK (declp);
01258 string_append (declp, qualifier_string (work->type_quals));
01259 }
01260 }
01261
01262 return (success);
01263 }
01264
01265 #if 0
01266
01267 static int
01268 demangle_method_args (work, mangled, declp)
01269 struct work_stuff *work;
01270 const char **mangled;
01271 string *declp;
01272 {
01273 int success = 0;
01274
01275 if (work -> static_type)
01276 {
01277 string_append (declp, *mangled + 1);
01278 *mangled += strlen (*mangled);
01279 success = 1;
01280 }
01281 else
01282 {
01283 success = demangle_args (work, mangled, declp);
01284 }
01285 return (success);
01286 }
01287
01288 #endif
01289
01290 static int
01291 demangle_template_template_parm (work, mangled, tname)
01292 struct work_stuff *work;
01293 const char **mangled;
01294 string *tname;
01295 {
01296 int i;
01297 int r;
01298 int need_comma = 0;
01299 int success = 1;
01300 string temp;
01301
01302 string_append (tname, "template <");
01303
01304 if (get_count (mangled, &r))
01305 {
01306 for (i = 0; i < r; i++)
01307 {
01308 if (need_comma)
01309 {
01310 string_append (tname, ", ");
01311 }
01312
01313
01314 if (**mangled == 'Z')
01315 {
01316 (*mangled)++;
01317 string_append (tname, "class");
01318 }
01319
01320 else if (**mangled == 'z')
01321 {
01322 (*mangled)++;
01323 success =
01324 demangle_template_template_parm (work, mangled, tname);
01325 if (!success)
01326 {
01327 break;
01328 }
01329 }
01330 else
01331 {
01332
01333 success = do_type (work, mangled, &temp);
01334 if (success)
01335 {
01336 string_appends (tname, &temp);
01337 }
01338 string_delete(&temp);
01339 if (!success)
01340 {
01341 break;
01342 }
01343 }
01344 need_comma = 1;
01345 }
01346
01347 }
01348 if (tname->p[-1] == '>')
01349 string_append (tname, " ");
01350 string_append (tname, "> class");
01351 return (success);
01352 }
01353
01354 static int
01355 demangle_expression (work, mangled, s, tk)
01356 struct work_stuff *work;
01357 const char** mangled;
01358 string* s;
01359 type_kind_t tk;
01360 {
01361 int need_operator = 0;
01362 int success;
01363
01364 success = 1;
01365 string_appendn (s, "(", 1);
01366 (*mangled)++;
01367 while (success && **mangled != 'W' && **mangled != '\0')
01368 {
01369 if (need_operator)
01370 {
01371 size_t i;
01372 size_t len;
01373
01374 success = 0;
01375
01376 len = strlen (*mangled);
01377
01378 for (i = 0;
01379 i < sizeof (optable) / sizeof (optable [0]);
01380 ++i)
01381 {
01382 size_t l = strlen (optable[i].in);
01383
01384 if (l <= len
01385 && memcmp (optable[i].in, *mangled, l) == 0)
01386 {
01387 string_appendn (s, " ", 1);
01388 string_append (s, optable[i].out);
01389 string_appendn (s, " ", 1);
01390 success = 1;
01391 (*mangled) += l;
01392 break;
01393 }
01394 }
01395
01396 if (!success)
01397 break;
01398 }
01399 else
01400 need_operator = 1;
01401
01402 success = demangle_template_value_parm (work, mangled, s, tk);
01403 }
01404
01405 if (**mangled != 'W')
01406 success = 0;
01407 else
01408 {
01409 string_appendn (s, ")", 1);
01410 (*mangled)++;
01411 }
01412
01413 return success;
01414 }
01415
01416 static int
01417 demangle_integral_value (work, mangled, s)
01418 struct work_stuff *work;
01419 const char** mangled;
01420 string* s;
01421 {
01422 int success;
01423
01424 if (**mangled == 'E')
01425 success = demangle_expression (work, mangled, s, tk_integral);
01426 else if (**mangled == 'Q' || **mangled == 'K')
01427 success = demangle_qualified (work, mangled, s, 0, 1);
01428 else
01429 {
01430 int value;
01431
01432 success = 0;
01433
01434
01435 if (**mangled == 'm')
01436 {
01437 string_appendn (s, "-", 1);
01438 (*mangled)++;
01439 }
01440
01441
01442 value = consume_count_with_underscores (mangled);
01443 if (value != -1)
01444 {
01445 char buf[INTBUF_SIZE];
01446 sprintf (buf, "%d", value);
01447 string_append (s, buf);
01448
01449
01450 if (**mangled == '_')
01451 (*mangled)++;
01452
01453
01454 success = 1;
01455 }
01456 }
01457
01458 return success;
01459 }
01460
01461
01462
01463 static int
01464 demangle_real_value (work, mangled, s)
01465 struct work_stuff *work;
01466 const char **mangled;
01467 string* s;
01468 {
01469 if (**mangled == 'E')
01470 return demangle_expression (work, mangled, s, tk_real);
01471
01472 if (**mangled == 'm')
01473 {
01474 string_appendn (s, "-", 1);
01475 (*mangled)++;
01476 }
01477 while (isdigit ((unsigned char)**mangled))
01478 {
01479 string_appendn (s, *mangled, 1);
01480 (*mangled)++;
01481 }
01482 if (**mangled == '.')
01483 {
01484 string_appendn (s, ".", 1);
01485 (*mangled)++;
01486 while (isdigit ((unsigned char)**mangled))
01487 {
01488 string_appendn (s, *mangled, 1);
01489 (*mangled)++;
01490 }
01491 }
01492 if (**mangled == 'e')
01493 {
01494 string_appendn (s, "e", 1);
01495 (*mangled)++;
01496 while (isdigit ((unsigned char)**mangled))
01497 {
01498 string_appendn (s, *mangled, 1);
01499 (*mangled)++;
01500 }
01501 }
01502
01503 return 1;
01504 }
01505
01506 static int
01507 demangle_template_value_parm (work, mangled, s, tk)
01508 struct work_stuff *work;
01509 const char **mangled;
01510 string* s;
01511 type_kind_t tk;
01512 {
01513 int success = 1;
01514
01515 if (**mangled == 'Y')
01516 {
01517
01518 int idx;
01519
01520 (*mangled)++;
01521 idx = consume_count_with_underscores (mangled);
01522 if (idx == -1
01523 || (work->tmpl_argvec && idx >= work->ntmpl_args)
01524 || consume_count_with_underscores (mangled) == -1)
01525 return -1;
01526 if (work->tmpl_argvec)
01527 string_append (s, work->tmpl_argvec[idx]);
01528 else
01529 string_append_template_idx (s, idx);
01530 }
01531 else if (tk == tk_integral)
01532 success = demangle_integral_value (work, mangled, s);
01533 else if (tk == tk_char)
01534 {
01535 char tmp[2];
01536 int val;
01537 if (**mangled == 'm')
01538 {
01539 string_appendn (s, "-", 1);
01540 (*mangled)++;
01541 }
01542 string_appendn (s, "'", 1);
01543 val = consume_count(mangled);
01544 if (val <= 0)
01545 success = 0;
01546 else
01547 {
01548 tmp[0] = (char)val;
01549 tmp[1] = '\0';
01550 string_appendn (s, &tmp[0], 1);
01551 string_appendn (s, "'", 1);
01552 }
01553 }
01554 else if (tk == tk_bool)
01555 {
01556 int val = consume_count (mangled);
01557 if (val == 0)
01558 string_appendn (s, "false", 5);
01559 else if (val == 1)
01560 string_appendn (s, "true", 4);
01561 else
01562 success = 0;
01563 }
01564 else if (tk == tk_real)
01565 success = demangle_real_value (work, mangled, s);
01566 else if (tk == tk_pointer || tk == tk_reference)
01567 {
01568 if (**mangled == 'Q')
01569 success = demangle_qualified (work, mangled, s,
01570 0,
01571 1);
01572 else
01573 {
01574 int symbol_len = consume_count (mangled);
01575 if (symbol_len == -1)
01576 return -1;
01577 if (symbol_len == 0)
01578 string_appendn (s, "0", 1);
01579 else
01580 {
01581 char *p = xmalloc (symbol_len + 1), *q;
01582 strncpy (p, *mangled, symbol_len);
01583 p [symbol_len] = '\0';
01584
01585
01586
01587
01588
01589 q = cplus_demangle (p, work->options);
01590 if (tk == tk_pointer)
01591 string_appendn (s, "&", 1);
01592
01593
01594 if (q)
01595 {
01596 string_append (s, q);
01597 free (q);
01598 }
01599 else
01600 string_append (s, p);
01601 free (p);
01602 }
01603 *mangled += symbol_len;
01604 }
01605 }
01606
01607 return success;
01608 }
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618 static int
01619 demangle_template (work, mangled, tname, trawname, is_type, remember)
01620 struct work_stuff *work;
01621 const char **mangled;
01622 string *tname;
01623 string *trawname;
01624 int is_type;
01625 int remember;
01626 {
01627 int i;
01628 int r;
01629 int need_comma = 0;
01630 int success = 0;
01631 const char *start;
01632 int is_java_array = 0;
01633 string temp;
01634 int bindex = 0;
01635
01636 (*mangled)++;
01637 if (is_type)
01638 {
01639 if (remember)
01640 bindex = register_Btype (work);
01641 start = *mangled;
01642
01643 if (**mangled == 'z')
01644 {
01645 int idx;
01646 (*mangled)++;
01647 (*mangled)++;
01648
01649 idx = consume_count_with_underscores (mangled);
01650 if (idx == -1
01651 || (work->tmpl_argvec && idx >= work->ntmpl_args)
01652 || consume_count_with_underscores (mangled) == -1)
01653 return (0);
01654
01655 if (work->tmpl_argvec)
01656 {
01657 string_append (tname, work->tmpl_argvec[idx]);
01658 if (trawname)
01659 string_append (trawname, work->tmpl_argvec[idx]);
01660 }
01661 else
01662 {
01663 string_append_template_idx (tname, idx);
01664 if (trawname)
01665 string_append_template_idx (trawname, idx);
01666 }
01667 }
01668 else
01669 {
01670 if ((r = consume_count (mangled)) <= 0
01671 || (int) strlen (*mangled) < r)
01672 {
01673 return (0);
01674 }
01675 is_java_array = (work -> options & DMGL_JAVA)
01676 && strncmp (*mangled, "JArray1Z", 8) == 0;
01677 if (! is_java_array)
01678 {
01679 string_appendn (tname, *mangled, r);
01680 }
01681 if (trawname)
01682 string_appendn (trawname, *mangled, r);
01683 *mangled += r;
01684 }
01685 }
01686 if (!is_java_array)
01687 string_append (tname, "<");
01688
01689 if (!get_count (mangled, &r))
01690 {
01691 return (0);
01692 }
01693 if (!is_type)
01694 {
01695
01696 work->tmpl_argvec = (char**) xmalloc (r * sizeof (char *));
01697 work->ntmpl_args = r;
01698 for (i = 0; i < r; i++)
01699 work->tmpl_argvec[i] = 0;
01700 }
01701 for (i = 0; i < r; i++)
01702 {
01703 if (need_comma)
01704 {
01705 string_append (tname, ", ");
01706 }
01707
01708 if (**mangled == 'Z')
01709 {
01710 (*mangled)++;
01711
01712 success = do_type (work, mangled, &temp);
01713 if (success)
01714 {
01715 string_appends (tname, &temp);
01716
01717 if (!is_type)
01718 {
01719
01720 int len = temp.p - temp.b;
01721 work->tmpl_argvec[i] = xmalloc (len + 1);
01722 memcpy (work->tmpl_argvec[i], temp.b, len);
01723 work->tmpl_argvec[i][len] = '\0';
01724 }
01725 }
01726 string_delete(&temp);
01727 if (!success)
01728 {
01729 break;
01730 }
01731 }
01732
01733 else if (**mangled == 'z')
01734 {
01735 int r2;
01736 (*mangled)++;
01737 success = demangle_template_template_parm (work, mangled, tname);
01738
01739 if (success
01740 && (r2 = consume_count (mangled)) > 0
01741 && (int) strlen (*mangled) >= r2)
01742 {
01743 string_append (tname, " ");
01744 string_appendn (tname, *mangled, r2);
01745 if (!is_type)
01746 {
01747
01748 int len = r2;
01749 work->tmpl_argvec[i] = xmalloc (len + 1);
01750 memcpy (work->tmpl_argvec[i], *mangled, len);
01751 work->tmpl_argvec[i][len] = '\0';
01752 }
01753 *mangled += r2;
01754 }
01755 if (!success)
01756 {
01757 break;
01758 }
01759 }
01760 else
01761 {
01762 string param;
01763 string* s;
01764
01765
01766
01767
01768 success = do_type (work, mangled, &temp);
01769 string_delete(&temp);
01770 if (!success)
01771 break;
01772
01773 if (!is_type)
01774 {
01775 s = ¶m;
01776 string_init (s);
01777 }
01778 else
01779 s = tname;
01780
01781 success = demangle_template_value_parm (work, mangled, s,
01782 (type_kind_t) success);
01783
01784 if (!success)
01785 {
01786 if (!is_type)
01787 string_delete (s);
01788 success = 0;
01789 break;
01790 }
01791
01792 if (!is_type)
01793 {
01794 int len = s->p - s->b;
01795 work->tmpl_argvec[i] = xmalloc (len + 1);
01796 memcpy (work->tmpl_argvec[i], s->b, len);
01797 work->tmpl_argvec[i][len] = '\0';
01798
01799 string_appends (tname, s);
01800 string_delete (s);
01801 }
01802 }
01803 need_comma = 1;
01804 }
01805 if (is_java_array)
01806 {
01807 string_append (tname, "[]");
01808 }
01809 else
01810 {
01811 if (tname->p[-1] == '>')
01812 string_append (tname, " ");
01813 string_append (tname, ">");
01814 }
01815
01816 if (is_type && remember)
01817 remember_Btype (work, tname->b, LEN_STRING (tname), bindex);
01818
01819
01820
01821
01822
01823
01824
01825
01826
01827
01828
01829
01830
01831
01832 return (success);
01833 }
01834
01835 static int
01836 arm_pt (work, mangled, n, anchor, args)
01837 struct work_stuff *work;
01838 const char *mangled;
01839 int n;
01840 const char **anchor, **args;
01841 {
01842
01843
01844 if ((ARM_DEMANGLING || HP_DEMANGLING) && (*anchor = mystrstr (mangled, "__pt__")))
01845 {
01846 int len;
01847 *args = *anchor + 6;
01848 len = consume_count (args);
01849 if (len == -1)
01850 return 0;
01851 if (*args + len == mangled + n && **args == '_')
01852 {
01853 ++*args;
01854 return 1;
01855 }
01856 }
01857 if (AUTO_DEMANGLING || EDG_DEMANGLING)
01858 {
01859 if ((*anchor = mystrstr (mangled, "__tm__"))
01860 || (*anchor = mystrstr (mangled, "__ps__"))
01861 || (*anchor = mystrstr (mangled, "__pt__")))
01862 {
01863 int len;
01864 *args = *anchor + 6;
01865 len = consume_count (args);
01866 if (len == -1)
01867 return 0;
01868 if (*args + len == mangled + n && **args == '_')
01869 {
01870 ++*args;
01871 return 1;
01872 }
01873 }
01874 else if ((*anchor = mystrstr (mangled, "__S")))
01875 {
01876 int len;
01877 *args = *anchor + 3;
01878 len = consume_count (args);
01879 if (len == -1)
01880 return 0;
01881 if (*args + len == mangled + n && **args == '_')
01882 {
01883 ++*args;
01884 return 1;
01885 }
01886 }
01887 }
01888
01889 return 0;
01890 }
01891
01892 static void
01893 demangle_arm_hp_template (work, mangled, n, declp)
01894 struct work_stuff *work;
01895 const char **mangled;
01896 int n;
01897 string *declp;
01898 {
01899 const char *p;
01900 const char *args;
01901 const char *e = *mangled + n;
01902 string arg;
01903
01904
01905
01906 if (HP_DEMANGLING && ((*mangled)[n] == 'X'))
01907 {
01908 char *start_spec_args = NULL;
01909
01910
01911
01912 start_spec_args = strchr (*mangled, '<');
01913 if (start_spec_args && (start_spec_args - *mangled < n))
01914 string_appendn (declp, *mangled, start_spec_args - *mangled);
01915 else
01916 string_appendn (declp, *mangled, n);
01917 (*mangled) += n + 1;
01918 string_init (&arg);
01919 if (work->temp_start == -1)
01920 work->temp_start = declp->p - declp->b;
01921 string_append (declp, "<");
01922 while (1)
01923 {
01924 string_clear (&arg);
01925 switch (**mangled)
01926 {
01927 case 'T':
01928
01929 (*mangled)++;
01930 if (!do_type (work, mangled, &arg))
01931 goto hpacc_template_args_done;
01932 break;
01933
01934 case 'U':
01935 case 'S':
01936
01937 if (!do_hpacc_template_const_value (work, mangled, &arg))
01938 goto hpacc_template_args_done;
01939 break;
01940
01941 case 'A':
01942
01943 if (!do_hpacc_template_literal (work, mangled, &arg))
01944 goto hpacc_template_args_done;
01945 break;
01946
01947 default:
01948
01949
01950
01951 goto hpacc_template_args_done;
01952 }
01953 string_appends (declp, &arg);
01954
01955
01956
01957 if ((**mangled == '\000') || (**mangled == '_'))
01958 break;
01959 else
01960 string_append (declp, ",");
01961 }
01962 hpacc_template_args_done:
01963 string_append (declp, ">");
01964 string_delete (&arg);
01965 if (**mangled == '_')
01966 (*mangled)++;
01967 return;
01968 }
01969
01970 else if (arm_pt (work, *mangled, n, &p, &args))
01971 {
01972 string type_str;
01973
01974 string_init (&arg);
01975 string_appendn (declp, *mangled, p - *mangled);
01976 if (work->temp_start == -1)
01977 work->temp_start = declp->p - declp->b;
01978 string_append (declp, "<");
01979
01980 while (args < e) {
01981 string_clear (&arg);
01982
01983
01984 switch (*args)
01985 {
01986
01987
01988
01989 case 'X':
01990
01991 args++;
01992 if (!do_type (work, &args, &type_str))
01993 goto cfront_template_args_done;
01994 string_append (&arg, "(");
01995 string_appends (&arg, &type_str);
01996 string_append (&arg, ")");
01997 if (*args != 'L')
01998 goto cfront_template_args_done;
01999 args++;
02000
02001 if (!snarf_numeric_literal (&args, &arg))
02002 goto cfront_template_args_done;
02003 break;
02004
02005 case 'L':
02006
02007 args++;
02008 if (!snarf_numeric_literal (&args, &arg))
02009 goto cfront_template_args_done;
02010 break;
02011 default:
02012
02013 if (!do_type (work, &args, &arg))
02014 goto cfront_template_args_done;
02015 }
02016 string_appends (declp, &arg);
02017 string_append (declp, ",");
02018 }
02019 cfront_template_args_done:
02020 string_delete (&arg);
02021 if (args >= e)
02022 --declp->p;
02023 string_append (declp, ">");
02024 }
02025 else if (n>10 && strncmp (*mangled, "_GLOBAL_", 8) == 0
02026 && (*mangled)[9] == 'N'
02027 && (*mangled)[8] == (*mangled)[10]
02028 && strchr (cplus_markers, (*mangled)[8]))
02029 {
02030
02031 string_append (declp, "{anonymous}");
02032 }
02033 else
02034 {
02035 if (work->temp_start == -1)
02036 work->temp_start = 0;
02037 string_appendn (declp, *mangled, n);
02038 }
02039 *mangled += n;
02040 }
02041
02042
02043
02044
02045
02046 static int
02047 demangle_class_name (work, mangled, declp)
02048 struct work_stuff *work;
02049 const char **mangled;
02050 string *declp;
02051 {
02052 int n;
02053 int success = 0;
02054
02055 n = consume_count (mangled);
02056 if (n == -1)
02057 return 0;
02058 if ((int) strlen (*mangled) >= n)
02059 {
02060 demangle_arm_hp_template (work, mangled, n, declp);
02061 success = 1;
02062 }
02063
02064 return (success);
02065 }
02066
02067
02068
02069
02070
02071
02072
02073
02074
02075
02076
02077
02078
02079
02080
02081
02082
02083
02084
02085
02086
02087
02088
02089
02090
02091
02092
02093
02094
02095
02096
02097
02098
02099
02100
02101
02102 static int
02103 demangle_class (work, mangled, declp)
02104 struct work_stuff *work;
02105 const char **mangled;
02106 string *declp;
02107 {
02108 int success = 0;
02109 int btype;
02110 string class_name;
02111 char *save_class_name_end = 0;
02112
02113 string_init (&class_name);
02114 btype = register_Btype (work);
02115 if (demangle_class_name (work, mangled, &class_name))
02116 {
02117 save_class_name_end = class_name.p;
02118 if ((work->constructor & 1) || (work->destructor & 1))
02119 {
02120
02121 if (work->temp_start && (work->temp_start != -1))
02122 {
02123 class_name.p = class_name.b + work->temp_start;
02124 }
02125 string_prepends (declp, &class_name);
02126 if (work -> destructor & 1)
02127 {
02128 string_prepend (declp, "~");
02129 work -> destructor -= 1;
02130 }
02131 else
02132 {
02133 work -> constructor -= 1;
02134 }
02135 }
02136 class_name.p = save_class_name_end;
02137 remember_Ktype (work, class_name.b, LEN_STRING(&class_name));
02138 remember_Btype (work, class_name.b, LEN_STRING(&class_name), btype);
02139 string_prepend (declp, SCOPE_STRING (work));
02140 string_prepends (declp, &class_name);
02141 success = 1;
02142 }
02143 string_delete (&class_name);
02144 return (success);
02145 }
02146
02147
02148
02149
02150
02151
02152
02153
02154
02155
02156
02157
02158
02159
02160
02161
02162
02163
02164
02165
02166
02167
02168
02169
02170
02171
02172
02173
02174
02175
02176
02177
02178 static int
02179 demangle_prefix (work, mangled, declp)
02180 struct work_stuff *work;
02181 const char **mangled;
02182 string *declp;
02183 {
02184 int success = 1;
02185 const char *scan;
02186 int i;
02187
02188 if (strlen(*mangled) > 6
02189 && (strncmp(*mangled, "_imp__", 6) == 0
02190 || strncmp(*mangled, "__imp_", 6) == 0))
02191 {
02192
02193
02194
02195 (*mangled) += 6;
02196 work->dllimported = 1;
02197 }
02198 else if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)
02199 {
02200 char *marker = strchr (cplus_markers, (*mangled)[8]);
02201 if (marker != NULL && *marker == (*mangled)[10])
02202 {
02203 if ((*mangled)[9] == 'D')
02204 {
02205
02206 (*mangled) += 11;
02207 work->destructor = 2;
02208 if (gnu_special (work, mangled, declp))
02209 return success;
02210 }
02211 else if ((*mangled)[9] == 'I')
02212 {
02213
02214 (*mangled) += 11;
02215 work->constructor = 2;
02216 if (gnu_special (work, mangled, declp))
02217 return success;
02218 }
02219 }
02220 }
02221 else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__std__", 7) == 0)
02222 {
02223
02224 (*mangled) += 7;
02225 work->destructor = 2;
02226 }
02227 else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__sti__", 7) == 0)
02228 {
02229
02230 (*mangled) += 7;
02231 work->constructor = 2;
02232 }
02233
02234
02235
02236
02237
02238 {
02239 scan = *mangled;
02240
02241 do {
02242 scan = strchr (scan, '_');
02243 } while (scan != NULL && *++scan != '_');
02244
02245 if (scan != NULL) --scan;
02246 }
02247
02248 if (scan != NULL)
02249 {
02250
02251
02252 i = strspn (scan, "_");
02253 if (i > 2)
02254 {
02255 scan += (i - 2);
02256 }
02257 }
02258
02259 if (scan == NULL)
02260 {
02261 success = 0;
02262 }
02263 else if (work -> static_type)
02264 {
02265 if (!isdigit ((unsigned char)scan[0]) && (scan[0] != 't'))
02266 {
02267 success = 0;
02268 }
02269 }
02270 else if ((scan == *mangled)
02271 && (isdigit ((unsigned char)scan[2]) || (scan[2] == 'Q')
02272 || (scan[2] == 't') || (scan[2] == 'K') || (scan[2] == 'H')))
02273 {
02274
02275
02276
02277 if ((LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING)
02278 && isdigit ((unsigned char)scan[2]))
02279 {
02280 *mangled = scan + 2;
02281 consume_count (mangled);
02282 string_append (declp, *mangled);
02283 *mangled += strlen (*mangled);
02284 success = 1;
02285 }
02286 else
02287 {
02288
02289
02290
02291
02292 if (!(LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING))
02293 work -> constructor += 1;
02294 *mangled = scan + 2;
02295 }
02296 }
02297 else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')
02298 {
02299
02300 success = 1;
02301
02302
02303 demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
02304 }
02305 else if (EDG_DEMANGLING && ((scan[2] == 't' && scan[3] == 'm')
02306 || (scan[2] == 'p' && scan[3] == 's')
02307 || (scan[2] == 'p' && scan[3] == 't')))
02308 {
02309
02310 success = 1;
02311
02312
02313 demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
02314 }
02315 else if ((scan == *mangled) && !isdigit ((unsigned char)scan[2])
02316 && (scan[2] != 't'))
02317 {
02318
02319
02320
02321 if (!(ARM_DEMANGLING || LUCID_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
02322 || (arm_special (mangled, declp) == 0))
02323 {
02324 while (*scan == '_')
02325 {
02326 scan++;
02327 }
02328 if ((scan = mystrstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
02329 {
02330
02331
02332 success = 0;
02333 }
02334 else
02335 {
02336 const char *tmp;
02337
02338
02339
02340 if (!(ARM_DEMANGLING || HP_DEMANGLING))
02341 {
02342 while ((tmp = mystrstr (scan + 2, "__")) != NULL)
02343 scan = tmp;
02344 }
02345 if (*(scan + 2) == '\0')
02346 success = 0;
02347 else
02348 demangle_function_name (work, mangled, declp, scan);
02349 }
02350 }
02351 }
02352 else if (*(scan + 2) != '\0')
02353 {
02354
02355
02356
02357 demangle_function_name (work, mangled, declp, scan);
02358 }
02359 else
02360 {
02361
02362 success = 0;
02363 }
02364
02365 if (!success && (work->constructor == 2 || work->destructor == 2))
02366 {
02367 string_append (declp, *mangled);
02368 *mangled += strlen (*mangled);
02369 success = 1;
02370 }
02371 return (success);
02372 }
02373
02374
02375
02376
02377
02378
02379
02380
02381
02382
02383
02384
02385
02386
02387
02388
02389
02390
02391
02392
02393
02394
02395
02396
02397
02398
02399
02400
02401
02402 static int
02403 gnu_special (work, mangled, declp)
02404 struct work_stuff *work;
02405 const char **mangled;
02406 string *declp;
02407 {
02408 int n;
02409 int success = 1;
02410 const char *p;
02411
02412 if ((*mangled)[0] == '_'
02413 && strchr (cplus_markers, (*mangled)[1]) != NULL
02414 && (*mangled)[2] == '_')
02415 {
02416
02417 (*mangled) += 3;
02418 work -> destructor += 1;
02419 }
02420 else if ((*mangled)[0] == '_'
02421 && (((*mangled)[1] == '_'
02422 && (*mangled)[2] == 'v'
02423 && (*mangled)[3] == 't'
02424 && (*mangled)[4] == '_')
02425 || ((*mangled)[1] == 'v'
02426 && (*mangled)[2] == 't'
02427 && strchr (cplus_markers, (*mangled)[3]) != NULL)))
02428 {
02429
02430
02431
02432
02433 if ((*mangled)[2] == 'v')
02434 (*mangled) += 5;
02435 else
02436 (*mangled) += 4;
02437 while (**mangled != '\0')
02438 {
02439 switch (**mangled)
02440 {
02441 case 'Q':
02442 case 'K':
02443 success = demangle_qualified (work, mangled, declp, 0, 1);
02444 break;
02445 case 't':
02446 success = demangle_template (work, mangled, declp, 0, 1,
02447 1);
02448 break;
02449 default:
02450 if (isdigit((unsigned char)*mangled[0]))
02451 {
02452 n = consume_count(mangled);
02453
02454
02455
02456
02457 if (n > (int) strlen (*mangled))
02458 {
02459 success = 1;
02460 break;
02461 }
02462 }
02463 else
02464 {
02465 n = strcspn (*mangled, cplus_markers);
02466 }
02467 string_appendn (declp, *mangled, n);
02468 (*mangled) += n;
02469 }
02470
02471 p = strpbrk (*mangled, cplus_markers);
02472 if (success && ((p == NULL) || (p == *mangled)))
02473 {
02474 if (p != NULL)
02475 {
02476 string_append (declp, SCOPE_STRING (work));
02477 (*mangled)++;
02478 }
02479 }
02480 else
02481 {
02482 success = 0;
02483 break;
02484 }
02485 }
02486 if (success)
02487 string_append (declp, " virtual table");
02488 }
02489 else if ((*mangled)[0] == '_'
02490 && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
02491 && (p = strpbrk (*mangled, cplus_markers)) != NULL)
02492 {
02493
02494 (*mangled)++;
02495 switch (**mangled)
02496 {
02497 case 'Q':
02498 case 'K':
02499 success = demangle_qualified (work, mangled, declp, 0, 1);
02500 break;
02501 case 't':
02502 success = demangle_template (work, mangled, declp, 0, 1, 1);
02503 break;
02504 default:
02505 n = consume_count (mangled);
02506 if (n < 0 || n > (long) strlen (*mangled))
02507 {
02508 success = 0;
02509 break;
02510 }
02511 string_appendn (declp, *mangled, n);
02512 (*mangled) += n;
02513 }
02514 if (success && (p == *mangled))
02515 {
02516
02517
02518 (*mangled)++;
02519 string_append (declp, SCOPE_STRING (work));
02520 n = strlen (*mangled);
02521 string_appendn (declp, *mangled, n);
02522 (*mangled) += n;
02523 }
02524 else
02525 {
02526 success = 0;
02527 }
02528 }
02529 else if (strncmp (*mangled, "__thunk_", 8) == 0)
02530 {
02531 int delta;
02532
02533 (*mangled) += 8;
02534 delta = consume_count (mangled);
02535 if (delta == -1)
02536 success = 0;
02537 else
02538 {
02539 char *method = internal_cplus_demangle (work, ++*mangled);
02540
02541 if (method)
02542 {
02543 char buf[50];
02544 sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);
02545 string_append (declp, buf);
02546 string_append (declp, method);
02547 free (method);
02548 n = strlen (*mangled);
02549 (*mangled) += n;
02550 }
02551 else
02552 {
02553 success = 0;
02554 }
02555 }
02556 }
02557 else if (strncmp (*mangled, "__t", 3) == 0
02558 && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f'))
02559 {
02560 p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function";
02561 (*mangled) += 4;
02562 switch (**mangled)
02563 {
02564 case 'Q':
02565 case 'K':
02566 success = demangle_qualified (work, mangled, declp, 0, 1);
02567 break;
02568 case 't':
02569 success = demangle_template (work, mangled, declp, 0, 1, 1);
02570 break;
02571 default:
02572 success = demangle_fund_type (work, mangled, declp);
02573 break;
02574 }
02575 if (success && **mangled != '\0')
02576 success = 0;
02577 if (success)
02578 string_append (declp, p);
02579 }
02580 else
02581 {
02582 success = 0;
02583 }
02584 return (success);
02585 }
02586
02587 static void
02588 recursively_demangle(work, mangled, result, namelength)
02589 struct work_stuff *work;
02590 const char **mangled;
02591 string *result;
02592 int namelength;
02593 {
02594 char * recurse = (char *)NULL;
02595 char * recurse_dem = (char *)NULL;
02596
02597 recurse = (char *) xmalloc (namelength + 1);
02598 memcpy (recurse, *mangled, namelength);
02599 recurse[namelength] = '\000';
02600
02601 recurse_dem = cplus_demangle (recurse, work->options);
02602
02603 if (recurse_dem)
02604 {
02605 string_append (result, recurse_dem);
02606 free (recurse_dem);
02607 }
02608 else
02609 {
02610 string_appendn (result, *mangled, namelength);
02611 }
02612 free (recurse);
02613 *mangled += namelength;
02614 }
02615
02616
02617
02618
02619
02620
02621
02622
02623
02624
02625
02626
02627
02628
02629
02630
02631
02632
02633
02634
02635
02636
02637
02638
02639 static int
02640 arm_special (mangled, declp)
02641 const char **mangled;
02642 string *declp;
02643 {
02644 int n;
02645 int success = 1;
02646 const char *scan;
02647
02648 if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
02649 {
02650
02651
02652
02653
02654 scan = *mangled + ARM_VTABLE_STRLEN;
02655 while (*scan != '\0')
02656 {
02657 n = consume_count (&scan);
02658 if (n == -1)
02659 {
02660 return (0);
02661 }
02662 scan += n;
02663 if (scan[0] == '_' && scan[1] == '_')
02664 {
02665 scan += 2;
02666 }
02667 }
02668 (*mangled) += ARM_VTABLE_STRLEN;
02669 while (**mangled != '\0')
02670 {
02671 n = consume_count (mangled);
02672 if (n == -1
02673 || n > (long) strlen (*mangled))
02674 return 0;
02675 string_prependn (declp, *mangled, n);
02676 (*mangled) += n;
02677 if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
02678 {
02679 string_prepend (declp, "::");
02680 (*mangled) += 2;
02681 }
02682 }
02683 string_append (declp, " virtual table");
02684 }
02685 else
02686 {
02687 success = 0;
02688 }
02689 return (success);
02690 }
02691
02692
02693
02694
02695
02696
02697
02698
02699
02700
02701
02702
02703
02704
02705
02706
02707
02708
02709
02710
02711
02712
02713
02714
02715
02716
02717
02718
02719
02720
02721
02722
02723
02724 static int
02725 demangle_qualified (work, mangled, result, isfuncname, append)
02726 struct work_stuff *work;
02727 const char **mangled;
02728 string *result;
02729 int isfuncname;
02730 int append;
02731 {
02732 int qualifiers = 0;
02733 int success = 1;
02734 char num[2];
02735 string temp;
02736 string last_name;
02737 int bindex = register_Btype (work);
02738
02739
02740
02741 isfuncname = (isfuncname
02742 && ((work->constructor & 1) || (work->destructor & 1)));
02743
02744 string_init (&temp);
02745 string_init (&last_name);
02746
02747 if ((*mangled)[0] == 'K')
02748 {
02749
02750 int idx;
02751 (*mangled)++;
02752 idx = consume_count_with_underscores (mangled);
02753 if (idx == -1 || idx >= work -> numk)
02754 success = 0;
02755 else
02756 string_append (&temp, work -> ktypevec[idx]);
02757 }
02758 else
02759 switch ((*mangled)[1])
02760 {
02761 case '_':
02762
02763
02764
02765 (*mangled)++;
02766 qualifiers = consume_count_with_underscores (mangled);
02767 if (qualifiers == -1)
02768 success = 0;
02769 break;
02770
02771 case '1':
02772 case '2':
02773 case '3':
02774 case '4':
02775 case '5':
02776 case '6':
02777 case '7':
02778 case '8':
02779 case '9':
02780
02781 num[0] = (*mangled)[1];
02782 num[1] = '\0';
02783 qualifiers = atoi (num);
02784
02785
02786
02787
02788 if ((*mangled)[2] == '_')
02789 {
02790 (*mangled)++;
02791 }
02792 (*mangled) += 2;
02793 break;
02794
02795 case '0':
02796 default:
02797 success = 0;
02798 }
02799
02800 if (!success)
02801 return success;
02802
02803
02804
02805
02806 while (qualifiers-- > 0)
02807 {
02808 int remember_K = 1;
02809 string_clear (&last_name);
02810
02811 if (*mangled[0] == '_')
02812 (*mangled)++;
02813
02814 if (*mangled[0] == 't')
02815 {
02816
02817
02818
02819
02820
02821
02822 success = demangle_template(work, mangled, &temp,
02823 &last_name, 1, 0);
02824 if (!success)
02825 break;
02826 }
02827 else if (*mangled[0] == 'K')
02828 {
02829 int idx;
02830 (*mangled)++;
02831 idx = consume_count_with_underscores (mangled);
02832 if (idx == -1 || idx >= work->numk)
02833 success = 0;
02834 else
02835 string_append (&temp, work->ktypevec[idx]);
02836 remember_K = 0;
02837
02838 if (!success) break;
02839 }
02840 else
02841 {
02842 if (EDG_DEMANGLING)
02843 {
02844 int namelength;
02845
02846
02847
02848 namelength = consume_count (mangled);
02849 if (namelength == -1)
02850 {
02851 success = 0;
02852 break;
02853 }
02854 recursively_demangle(work, mangled, &temp, namelength);
02855 }
02856 else
02857 {
02858 success = do_type (work, mangled, &last_name);
02859 if (!success)
02860 break;
02861 string_appends (&temp, &last_name);
02862 }
02863 }
02864
02865 if (remember_K)
02866 remember_Ktype (work, temp.b, LEN_STRING (&temp));
02867
02868 if (qualifiers > 0)
02869 string_append (&temp, SCOPE_STRING (work));
02870 }
02871
02872 remember_Btype (work, temp.b, LEN_STRING (&temp), bindex);
02873
02874
02875
02876
02877
02878
02879 if (isfuncname)
02880 {
02881 string_append (&temp, SCOPE_STRING (work));
02882 if (work -> destructor & 1)
02883 string_append (&temp, "~");
02884 string_appends (&temp, &last_name);
02885 }
02886
02887
02888
02889
02890 if (append)
02891 string_appends (result, &temp);
02892 else
02893 {
02894 if (!STRING_EMPTY (result))
02895 string_append (&temp, SCOPE_STRING (work));
02896 string_prepends (result, &temp);
02897 }
02898
02899 string_delete (&last_name);
02900 string_delete (&temp);
02901 return (success);
02902 }
02903
02904
02905
02906
02907
02908
02909
02910
02911
02912
02913
02914
02915
02916
02917
02918
02919
02920
02921
02922
02923
02924
02925
02926
02927
02928
02929
02930
02931
02932
02933
02934
02935
02936
02937
02938
02939
02940
02941
02942
02943
02944
02945
02946
02947
02948
02949
02950 static int
02951 get_count (type, count)
02952 const char **type;
02953 int *count;
02954 {
02955 const char *p;
02956 int n;
02957
02958 if (!isdigit ((unsigned char)**type))
02959 return (0);
02960 else
02961 {
02962 *count = **type - '0';
02963 (*type)++;
02964 if (isdigit ((unsigned char)**type))
02965 {
02966 p = *type;
02967 n = *count;
02968 do
02969 {
02970 n *= 10;
02971 n += *p - '0';
02972 p++;
02973 }
02974 while (isdigit ((unsigned char)*p));
02975 if (*p == '_')
02976 {
02977 *type = p + 1;
02978 *count = n;
02979 }
02980 }
02981 }
02982 return (1);
02983 }
02984
02985
02986
02987
02988 static int
02989 do_type (work, mangled, result)
02990 struct work_stuff *work;
02991 const char **mangled;
02992 string *result;
02993 {
02994 int n;
02995 int done;
02996 int success;
02997 string decl;
02998 const char *remembered_type;
02999 int type_quals;
03000 string btype;
03001 type_kind_t tk = tk_none;
03002
03003 string_init (&btype);
03004 string_init (&decl);
03005 string_init (result);
03006
03007 done = 0;
03008 success = 1;
03009 while (success && !done)
03010 {
03011 int member;
03012 switch (**mangled)
03013 {
03014
03015
03016 case 'P':
03017 case 'p':
03018 (*mangled)++;
03019 if (! (work -> options & DMGL_JAVA))
03020 string_prepend (&decl, "*");
03021 if (tk == tk_none)
03022 tk = tk_pointer;
03023 break;
03024
03025
03026 case 'R':
03027 (*mangled)++;
03028 string_prepend (&decl, "&");
03029 if (tk == tk_none)
03030 tk = tk_reference;
03031 break;
03032
03033
03034 case 'A':
03035 {
03036 ++(*mangled);
03037 if (!STRING_EMPTY (&decl)
03038 && (decl.b[0] == '*' || decl.b[0] == '&'))
03039 {
03040 string_prepend (&decl, "(");
03041 string_append (&decl, ")");
03042 }
03043 string_append (&decl, "[");
03044 if (**mangled != '_')
03045 success = demangle_template_value_parm (work, mangled, &decl,
03046 tk_integral);
03047 if (**mangled == '_')
03048 ++(*mangled);
03049 string_append (&decl, "]");
03050 break;
03051 }
03052
03053
03054 case 'T':
03055 (*mangled)++;
03056 if (!get_count (mangled, &n) || n >= work -> ntypes)
03057 {
03058 success = 0;
03059 }
03060 else
03061 {
03062 remembered_type = work -> typevec[n];
03063 mangled = &remembered_type;
03064 }
03065 break;
03066
03067
03068 case 'F':
03069 (*mangled)++;
03070 if (!STRING_EMPTY (&decl)
03071 && (decl.b[0] == '*' || decl.b[0] == '&'))
03072 {
03073 string_prepend (&decl, "(");
03074 string_append (&decl, ")");
03075 }
03076
03077
03078
03079 if (!demangle_nested_args (work, mangled, &decl)
03080 || (**mangled != '_' && **mangled != '\0'))
03081 {
03082 success = 0;
03083 break;
03084 }
03085 if (success && (**mangled == '_'))
03086 (*mangled)++;
03087 break;
03088
03089 case 'M':
03090 case 'O':
03091 {
03092 type_quals = TYPE_UNQUALIFIED;
03093
03094 member = **mangled == 'M';
03095 (*mangled)++;
03096
03097 string_append (&decl, ")");
03098
03099
03100
03101 if (**mangled != 'Q')
03102 string_prepend (&decl, SCOPE_STRING (work));
03103
03104 if (isdigit ((unsigned char)**mangled))
03105 {
03106 n = consume_count (mangled);
03107 if (n == -1
03108 || (int) strlen (*mangled) < n)
03109 {
03110 success = 0;
03111 break;
03112 }
03113 string_prependn (&decl, *mangled, n);
03114 *mangled += n;
03115 }
03116 else if (**mangled == 'X' || **mangled == 'Y')
03117 {
03118 string temp;
03119 do_type (work, mangled, &temp);
03120 string_prepends (&decl, &temp);
03121 }
03122 else if (**mangled == 't')
03123 {
03124 string temp;
03125 string_init (&temp);
03126 success = demangle_template (work, mangled, &temp,
03127 NULL, 1, 1);
03128 if (success)
03129 {
03130 string_prependn (&decl, temp.b, temp.p - temp.b);
03131 string_clear (&temp);
03132 }
03133 else
03134 break;
03135 }
03136 else if (**mangled == 'Q')
03137 {
03138 success = demangle_qualified (work, mangled, &decl,
03139 0,
03140 0);
03141 if (!success)
03142 break;
03143 }
03144 else
03145 {
03146 success = 0;
03147 break;
03148 }
03149
03150 string_prepend (&decl, "(");
03151 if (member)
03152 {
03153 switch (**mangled)
03154 {
03155 case 'C':
03156 case 'V':
03157 case 'u':
03158 type_quals |= code_for_qualifier (**mangled);
03159 (*mangled)++;
03160 break;
03161
03162 default:
03163 break;
03164 }
03165
03166 if (*(*mangled)++ != 'F')
03167 {
03168 success = 0;
03169 break;
03170 }
03171 }
03172 if ((member && !demangle_nested_args (work, mangled, &decl))
03173 || **mangled != '_')
03174 {
03175 success = 0;
03176 break;
03177 }
03178 (*mangled)++;
03179 if (! PRINT_ANSI_QUALIFIERS)
03180 {
03181 break;
03182 }
03183 if (type_quals != TYPE_UNQUALIFIED)
03184 {
03185 APPEND_BLANK (&decl);
03186 string_append (&decl, qualifier_string (type_quals));
03187 }
03188 break;
03189 }
03190 case 'G':
03191 (*mangled)++;
03192 break;
03193
03194 case 'C':
03195 case 'V':
03196 case 'u':
03197 if (PRINT_ANSI_QUALIFIERS)
03198 {
03199 if (!STRING_EMPTY (&decl))
03200 string_prepend (&decl, " ");
03201
03202 string_prepend (&decl, demangle_qualifier (**mangled));
03203 }
03204 (*mangled)++;
03205 break;
03206
03207
03208
03209
03210
03211 default:
03212 done = 1;
03213 break;
03214 }
03215 }
03216
03217 if (success) switch (**mangled)
03218 {
03219
03220 case 'Q':
03221 case 'K':
03222 {
03223 success = demangle_qualified (work, mangled, result, 0, 1);
03224 break;
03225 }
03226
03227
03228 case 'B':
03229 (*mangled)++;
03230 if (!get_count (mangled, &n) || n >= work -> numb)
03231 success = 0;
03232 else
03233 string_append (result, work->btypevec[n]);
03234 break;
03235
03236 case 'X':
03237 case 'Y':
03238
03239 {
03240 int idx;
03241
03242 (*mangled)++;
03243 idx = consume_count_with_underscores (mangled);
03244
03245 if (idx == -1
03246 || (work->tmpl_argvec && idx >= work->ntmpl_args)
03247 || consume_count_with_underscores (mangled) == -1)
03248 {
03249 success = 0;
03250 break;
03251 }
03252
03253 if (work->tmpl_argvec)
03254 string_append (result, work->tmpl_argvec[idx]);
03255 else
03256 string_append_template_idx (result, idx);
03257
03258 success = 1;
03259 }
03260 break;
03261
03262 default:
03263 success = demangle_fund_type (work, mangled, result);
03264 if (tk == tk_none)
03265 tk = (type_kind_t) success;
03266 break;
03267 }
03268
03269 if (success)
03270 {
03271 if (!STRING_EMPTY (&decl))
03272 {
03273 string_append (result, " ");
03274 string_appends (result, &decl);
03275 }
03276 }
03277 else
03278 string_delete (result);
03279 string_delete (&decl);
03280
03281 if (success)
03282
03283 return (int) ((tk == tk_none) ? tk_integral : tk);
03284 else
03285 return 0;
03286 }
03287
03288
03289
03290
03291
03292
03293
03294
03295
03296
03297
03298
03299
03300
03301 static int
03302 demangle_fund_type (work, mangled, result)
03303 struct work_stuff *work;
03304 const char **mangled;
03305 string *result;
03306 {
03307 int done = 0;
03308 int success = 1;
03309 char buf[10];
03310 int dec = 0;
03311 string btype;
03312 type_kind_t tk = tk_integral;
03313
03314 string_init (&btype);
03315
03316
03317
03318 while (!done)
03319 {
03320 switch (**mangled)
03321 {
03322 case 'C':
03323 case 'V':
03324 case 'u':
03325 if (PRINT_ANSI_QUALIFIERS)
03326 {
03327 if (!STRING_EMPTY (result))
03328 string_prepend (result, " ");
03329 string_prepend (result, demangle_qualifier (**mangled));
03330 }
03331 (*mangled)++;
03332 break;
03333 case 'U':
03334 (*mangled)++;
03335 APPEND_BLANK (result);
03336 string_append (result, "unsigned");
03337 break;
03338 case 'S':
03339 (*mangled)++;
03340 APPEND_BLANK (result);
03341 string_append (result, "signed");
03342 break;
03343 case 'J':
03344 (*mangled)++;
03345 APPEND_BLANK (result);
03346 string_append (result, "__complex");
03347 break;
03348 default:
03349 done = 1;
03350 break;
03351 }
03352 }
03353
03354
03355
03356 switch (**mangled)
03357 {
03358 case '\0':
03359 case '_':
03360 break;
03361 case 'v':
03362 (*mangled)++;
03363 APPEND_BLANK (result);
03364 string_append (result, "void");
03365 break;
03366 case 'x':
03367 (*mangled)++;
03368 APPEND_BLANK (result);
03369 string_append (result, "long long");
03370 break;
03371 case 'l':
03372 (*mangled)++;
03373 APPEND_BLANK (result);
03374 string_append (result, "long");
03375 break;
03376 case 'i':
03377 (*mangled)++;
03378 APPEND_BLANK (result);
03379 string_append (result, "int");
03380 break;
03381 case 's':
03382 (*mangled)++;
03383 APPEND_BLANK (result);
03384 string_append (result, "short");
03385 break;
03386 case 'b':
03387 (*mangled)++;
03388 APPEND_BLANK (result);
03389 string_append (result, "bool");
03390 tk = tk_bool;
03391 break;
03392 case 'c':
03393 (*mangled)++;
03394 APPEND_BLANK (result);
03395 string_append (result, "char");
03396 tk = tk_char;
03397 break;
03398 case 'w':
03399 (*mangled)++;
03400 APPEND_BLANK (result);
03401 string_append (result, "wchar_t");
03402 tk = tk_char;
03403 break;
03404 case 'r':
03405 (*mangled)++;
03406 APPEND_BLANK (result);
03407 string_append (result, "long double");
03408 tk = tk_real;
03409 break;
03410 case 'd':
03411 (*mangled)++;
03412 APPEND_BLANK (result);
03413 string_append (result, "double");
03414 tk = tk_real;
03415 break;
03416 case 'f':
03417 (*mangled)++;
03418 APPEND_BLANK (result);
03419 string_append (result, "float");
03420 tk = tk_real;
03421 break;
03422 case 'G':
03423 (*mangled)++;
03424 if (!isdigit ((unsigned char)**mangled))
03425 {
03426 success = 0;
03427 break;
03428 }
03429 case 'I':
03430 (*mangled)++;
03431 if (**mangled == '_')
03432 {
03433 int i;
03434 (*mangled)++;
03435 for (i = 0;
03436 i < (long) sizeof (buf) - 1 && **mangled && **mangled != '_';
03437 (*mangled)++, i++)
03438 buf[i] = **mangled;
03439 if (**mangled != '_')
03440 {
03441 success = 0;
03442 break;
03443 }
03444 buf[i] = '\0';
03445 (*mangled)++;
03446 }
03447 else
03448 {
03449 strncpy (buf, *mangled, 2);
03450 buf[2] = '\0';
03451 *mangled += min (strlen (*mangled), 2);
03452 }
03453 sscanf (buf, "%x", &dec);
03454 sprintf (buf, "int%i_t", dec);
03455 APPEND_BLANK (result);
03456 string_append (result, buf);
03457 break;
03458
03459
03460
03461 case '0':
03462 case '1':
03463 case '2':
03464 case '3':
03465 case '4':
03466 case '5':
03467 case '6':
03468 case '7':
03469 case '8':
03470 case '9':
03471 {
03472 int bindex = register_Btype (work);
03473 string btype;
03474 string_init (&btype);
03475 if (demangle_class_name (work, mangled, &btype)) {
03476 remember_Btype (work, btype.b, LEN_STRING (&btype), bindex);
03477 APPEND_BLANK (result);
03478 string_appends (result, &btype);
03479 }
03480 else
03481 success = 0;
03482 string_delete (&btype);
03483 break;
03484 }
03485 case 't':
03486 {
03487 success = demangle_template (work, mangled, &btype, 0, 1, 1);
03488 string_appends (result, &btype);
03489 break;
03490 }
03491 default:
03492 success = 0;
03493 break;
03494 }
03495
03496 return success ? ((int) tk) : 0;
03497 }
03498
03499
03500
03501
03502
03503 static int
03504 do_hpacc_template_const_value (work, mangled, result)
03505 struct work_stuff *work;
03506 const char **mangled;
03507 string *result;
03508 {
03509 int unsigned_const;
03510
03511 if (**mangled != 'U' && **mangled != 'S')
03512 return 0;
03513
03514 unsigned_const = (**mangled == 'U');
03515
03516 (*mangled)++;
03517
03518 switch (**mangled)
03519 {
03520 case 'N':
03521 string_append (result, "-");
03522
03523 case 'P':
03524 (*mangled)++;
03525 break;
03526 case 'M':
03527
03528 string_append (result, "-2147483648");
03529 (*mangled)++;
03530 return 1;
03531 default:
03532 return 0;
03533 }
03534
03535
03536 if (!(isdigit ((unsigned char)**mangled)))
03537 return 0;
03538
03539
03540
03541 while (isdigit ((unsigned char)**mangled))
03542 {
03543 char_str[0] = **mangled;
03544 string_append (result, char_str);
03545 (*mangled)++;
03546 }
03547
03548 if (unsigned_const)
03549 string_append (result, "U");
03550
03551
03552
03553
03554 return 1;
03555 }
03556
03557
03558
03559
03560 static int
03561 do_hpacc_template_literal (work, mangled, result)
03562 struct work_stuff *work;
03563 const char **mangled;
03564 string *result;
03565 {
03566 int literal_len = 0;
03567 char * recurse;
03568 char * recurse_dem;
03569
03570 if (**mangled != 'A')
03571 return 0;
03572
03573 (*mangled)++;
03574
03575 literal_len = consume_count (mangled);
03576
03577 if (literal_len <= 0)
03578 return 0;
03579
03580
03581
03582 string_append (result, "&");
03583
03584
03585 recurse = (char *) xmalloc (literal_len + 1);
03586 memcpy (recurse, *mangled, literal_len);
03587 recurse[literal_len] = '\000';
03588
03589 recurse_dem = cplus_demangle (recurse, work->options);
03590
03591 if (recurse_dem)
03592 {
03593 string_append (result, recurse_dem);
03594 free (recurse_dem);
03595 }
03596 else
03597 {
03598 string_appendn (result, *mangled, literal_len);
03599 }
03600 (*mangled) += literal_len;
03601 free (recurse);
03602
03603 return 1;
03604 }
03605
03606 static int
03607 snarf_numeric_literal (args, arg)
03608 const char ** args;
03609 string * arg;
03610 {
03611 if (**args == '-')
03612 {
03613 char_str[0] = '-';
03614 string_append (arg, char_str);
03615 (*args)++;
03616 }
03617 else if (**args == '+')
03618 (*args)++;
03619
03620 if (!isdigit ((unsigned char)**args))
03621 return 0;
03622
03623 while (isdigit ((unsigned char)**args))
03624 {
03625 char_str[0] = **args;
03626 string_append (arg, char_str);
03627 (*args)++;
03628 }
03629
03630 return 1;
03631 }
03632
03633
03634
03635
03636
03637 static int
03638 do_arg (work, mangled, result)
03639 struct work_stuff *work;
03640 const char **mangled;
03641 string *result;
03642 {
03643
03644
03645 const char *start = *mangled;
03646
03647 string_init (result);
03648
03649 if (work->nrepeats > 0)
03650 {
03651 --work->nrepeats;
03652
03653 if (work->previous_argument == 0)
03654 return 0;
03655
03656
03657 string_appends (result, work->previous_argument);
03658 return 1;
03659 }
03660
03661 if (**mangled == 'n')
03662 {
03663
03664 (*mangled)++;
03665 work->nrepeats = consume_count(mangled);
03666
03667 if (work->nrepeats <= 0)
03668
03669 return 0;
03670
03671 if (work->nrepeats > 9)
03672 {
03673 if (**mangled != '_')
03674
03675
03676 return 0;
03677 else
03678 (*mangled)++;
03679 }
03680
03681
03682 return do_arg (work, mangled, result);
03683 }
03684
03685
03686
03687
03688
03689 if (work->previous_argument)
03690 string_clear (work->previous_argument);
03691 else
03692 {
03693 work->previous_argument = (string*) xmalloc (sizeof (string));
03694 string_init (work->previous_argument);
03695 }
03696
03697 if (!do_type (work, mangled, work->previous_argument))
03698 return 0;
03699
03700 string_appends (result, work->previous_argument);
03701
03702 remember_type (work, start, *mangled - start);
03703 return 1;
03704 }
03705
03706 static void
03707 remember_type (work, start, len)
03708 struct work_stuff *work;
03709 const char *start;
03710 int len;
03711 {
03712 char *tem;
03713
03714 if (work->forgetting_types)
03715 return;
03716
03717 if (work -> ntypes >= work -> typevec_size)
03718 {
03719 if (work -> typevec_size == 0)
03720 {
03721 work -> typevec_size = 3;
03722 work -> typevec
03723 = (char **) xmalloc (sizeof (char *) * work -> typevec_size);
03724 }
03725 else
03726 {
03727 work -> typevec_size *= 2;
03728 work -> typevec
03729 = (char **) xrealloc ((char *)work -> typevec,
03730 sizeof (char *) * work -> typevec_size);
03731 }
03732 }
03733 tem = xmalloc (len + 1);
03734 memcpy (tem, start, len);
03735 tem[len] = '\0';
03736 work -> typevec[work -> ntypes++] = tem;
03737 }
03738
03739
03740
03741 static void
03742 remember_Ktype (work, start, len)
03743 struct work_stuff *work;
03744 const char *start;
03745 int len;
03746 {
03747 char *tem;
03748
03749 if (work -> numk >= work -> ksize)
03750 {
03751 if (work -> ksize == 0)
03752 {
03753 work -> ksize = 5;
03754 work -> ktypevec
03755 = (char **) xmalloc (sizeof (char *) * work -> ksize);
03756 }
03757 else
03758 {
03759 work -> ksize *= 2;
03760 work -> ktypevec
03761 = (char **) xrealloc ((char *)work -> ktypevec,
03762 sizeof (char *) * work -> ksize);
03763 }
03764 }
03765 tem = xmalloc (len + 1);
03766 memcpy (tem, start, len);
03767 tem[len] = '\0';
03768 work -> ktypevec[work -> numk++] = tem;
03769 }
03770
03771
03772
03773
03774
03775 static int
03776 register_Btype (work)
03777 struct work_stuff *work;
03778 {
03779 int ret;
03780
03781 if (work -> numb >= work -> bsize)
03782 {
03783 if (work -> bsize == 0)
03784 {
03785 work -> bsize = 5;
03786 work -> btypevec
03787 = (char **) xmalloc (sizeof (char *) * work -> bsize);
03788 }
03789 else
03790 {
03791 work -> bsize *= 2;
03792 work -> btypevec
03793 = (char **) xrealloc ((char *)work -> btypevec,
03794 sizeof (char *) * work -> bsize);
03795 }
03796 }
03797 ret = work -> numb++;
03798 work -> btypevec[ret] = NULL;
03799 return(ret);
03800 }
03801
03802
03803
03804 static void
03805 remember_Btype (work, start, len, index)
03806 struct work_stuff *work;
03807 const char *start;
03808 int len, index;
03809 {
03810 char *tem;
03811
03812 tem = xmalloc (len + 1);
03813 memcpy (tem, start, len);
03814 tem[len] = '\0';
03815 work -> btypevec[index] = tem;
03816 }
03817
03818
03819 static void
03820 forget_B_and_K_types (work)
03821 struct work_stuff *work;
03822 {
03823 int i;
03824
03825 while (work -> numk > 0)
03826 {
03827 i = --(work -> numk);
03828 if (work -> ktypevec[i] != NULL)
03829 {
03830 free (work -> ktypevec[i]);
03831 work -> ktypevec[i] = NULL;
03832 }
03833 }
03834
03835 while (work -> numb > 0)
03836 {
03837 i = --(work -> numb);
03838 if (work -> btypevec[i] != NULL)
03839 {
03840 free (work -> btypevec[i]);
03841 work -> btypevec[i] = NULL;
03842 }
03843 }
03844 }
03845
03846
03847 static void
03848 forget_types (work)
03849 struct work_stuff *work;
03850 {
03851 int i;
03852
03853 while (work -> ntypes > 0)
03854 {
03855 i = --(work -> ntypes);
03856 if (work -> typevec[i] != NULL)
03857 {
03858 free (work -> typevec[i]);
03859 work -> typevec[i] = NULL;
03860 }
03861 }
03862 }
03863
03864
03865
03866
03867
03868
03869
03870
03871
03872
03873
03874
03875
03876
03877
03878
03879
03880
03881
03882
03883
03884
03885
03886
03887
03888
03889
03890
03891
03892
03893
03894
03895
03896
03897
03898
03899
03900
03901
03902
03903
03904
03905
03906 static int
03907 demangle_args (work, mangled, declp)
03908 struct work_stuff *work;
03909 const char **mangled;
03910 string *declp;
03911 {
03912 string arg;
03913 int need_comma = 0;
03914 int r;
03915 int t;
03916 const char *tem;
03917 char temptype;
03918
03919 if (PRINT_ARG_TYPES)
03920 {
03921 string_append (declp, "(");
03922 if (**mangled == '\0')
03923 {
03924 string_append (declp, "void");
03925 }
03926 }
03927
03928 while ((**mangled != '_' && **mangled != '\0' && **mangled != 'e')
03929 || work->nrepeats > 0)
03930 {
03931 if ((**mangled == 'N') || (**mangled == 'T'))
03932 {
03933 temptype = *(*mangled)++;
03934
03935 if (temptype == 'N')
03936 {
03937 if (!get_count (mangled, &r))
03938 {
03939 return (0);
03940 }
03941 }
03942 else
03943 {
03944 r = 1;
03945 }
03946 if ((HP_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING) && work -> ntypes >= 10)
03947 {
03948
03949
03950
03951
03952
03953
03954 if ((t = consume_count(mangled)) <= 0)
03955 {
03956 return (0);
03957 }
03958 }
03959 else
03960 {
03961 if (!get_count (mangled, &t))
03962 {
03963 return (0);
03964 }
03965 }
03966 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
03967 {
03968 t--;
03969 }
03970
03971
03972 if ((t < 0) || (t >= work -> ntypes))
03973 {
03974 return (0);
03975 }
03976 while (work->nrepeats > 0 || --r >= 0)
03977 {
03978 tem = work -> typevec[t];
03979 if (need_comma && PRINT_ARG_TYPES)
03980 {
03981 string_append (declp, ", ");
03982 }
03983 if (!do_arg (work, &tem, &arg))
03984 {
03985 return (0);
03986 }
03987 if (PRINT_ARG_TYPES)
03988 {
03989 string_appends (declp, &arg);
03990 }
03991 string_delete (&arg);
03992 need_comma = 1;
03993 }
03994 }
03995 else
03996 {
03997 if (need_comma && PRINT_ARG_TYPES)
03998 string_append (declp, ", ");
03999 if (!do_arg (work, mangled, &arg))
04000 return (0);
04001 if (PRINT_ARG_TYPES)
04002 string_appends (declp, &arg);
04003 string_delete (&arg);
04004 need_comma = 1;
04005 }
04006 }
04007
04008 if (**mangled == 'e')
04009 {
04010 (*mangled)++;
04011 if (PRINT_ARG_TYPES)
04012 {
04013 if (need_comma)
04014 {
04015 string_append (declp, ",");
04016 }
04017 string_append (declp, "...");
04018 }
04019 }
04020
04021 if (PRINT_ARG_TYPES)
04022 {
04023 string_append (declp, ")");
04024 }
04025 return (1);
04026 }
04027
04028
04029
04030
04031 static int
04032 demangle_nested_args (work, mangled, declp)
04033 struct work_stuff *work;
04034 const char **mangled;
04035 string *declp;
04036 {
04037 string* saved_previous_argument;
04038 int result;
04039 int saved_nrepeats;
04040
04041
04042
04043
04044
04045 ++work->forgetting_types;
04046
04047
04048
04049 saved_previous_argument = work->previous_argument;
04050 saved_nrepeats = work->nrepeats;
04051 work->previous_argument = 0;
04052 work->nrepeats = 0;
04053
04054
04055 result = demangle_args (work, mangled, declp);
04056
04057
04058 if (work->previous_argument)
04059 string_delete (work->previous_argument);
04060 work->previous_argument = saved_previous_argument;
04061 --work->forgetting_types;
04062 work->nrepeats = saved_nrepeats;
04063
04064 return result;
04065 }
04066
04067 static void
04068 demangle_function_name (work, mangled, declp, scan)
04069 struct work_stuff *work;
04070 const char **mangled;
04071 string *declp;
04072 const char *scan;
04073 {
04074 size_t i;
04075 string type;
04076 const char *tem;
04077
04078 string_appendn (declp, (*mangled), scan - (*mangled));
04079 string_need (declp, 1);
04080 *(declp -> p) = '\0';
04081
04082
04083
04084
04085
04086 (*mangled) = scan + 2;
04087
04088
04089
04090
04091
04092 if (HP_DEMANGLING && (**mangled == 'X'))
04093 {
04094 demangle_arm_hp_template (work, mangled, 0, declp);
04095
04096 }
04097
04098 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
04099 {
04100
04101
04102
04103
04104
04105
04106 if (strcmp (declp -> b, "__ct") == 0)
04107 {
04108 work -> constructor += 1;
04109 string_clear (declp);
04110 return;
04111 }
04112 else if (strcmp (declp -> b, "__dt") == 0)
04113 {
04114 work -> destructor += 1;
04115 string_clear (declp);
04116 return;
04117 }
04118 }
04119
04120 if (declp->p - declp->b >= 3
04121 && declp->b[0] == 'o'
04122 && declp->b[1] == 'p'
04123 && strchr (cplus_markers, declp->b[2]) != NULL)
04124 {
04125
04126 if (declp->p - declp->b >= 10
04127 && memcmp (declp->b + 3, "assign_", 7) == 0)
04128 {
04129 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
04130 {
04131 int len = declp->p - declp->b - 10;
04132 if ((int) strlen (optable[i].in) == len
04133 && memcmp (optable[i].in, declp->b + 10, len) == 0)
04134 {
04135 string_clear (declp);
04136 string_append (declp, "operator");
04137 string_append (declp, optable[i].out);
04138 string_append (declp, "=");
04139 break;
04140 }
04141 }
04142 }
04143 else
04144 {
04145 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
04146 {
04147 int len = declp->p - declp->b - 3;
04148 if ((int) strlen (optable[i].in) == len
04149 && memcmp (optable[i].in, declp->b + 3, len) == 0)
04150 {
04151 string_clear (declp);
04152 string_append (declp, "operator");
04153 string_append (declp, optable[i].out);
04154 break;
04155 }
04156 }
04157 }
04158 }
04159 else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
04160 && strchr (cplus_markers, declp->b[4]) != NULL)
04161 {
04162
04163 tem = declp->b + 5;
04164 if (do_type (work, &tem, &type))
04165 {
04166 string_clear (declp);
04167 string_append (declp, "operator ");
04168 string_appends (declp, &type);
04169 string_delete (&type);
04170 }
04171 }
04172 else if (declp->b[0] == '_' && declp->b[1] == '_'
04173 && declp->b[2] == 'o' && declp->b[3] == 'p')
04174 {
04175
04176
04177 tem = declp->b + 4;
04178 if (do_type (work, &tem, &type))
04179 {
04180 string_clear (declp);
04181 string_append (declp, "operator ");
04182 string_appends (declp, &type);
04183 string_delete (&type);
04184 }
04185 }
04186 else if (declp->b[0] == '_' && declp->b[1] == '_'
04187 && declp->b[2] >= 'a' && declp->b[2] <= 'z'
04188 && declp->b[3] >= 'a' && declp->b[3] <= 'z')
04189 {
04190 if (declp->b[4] == '\0')
04191 {
04192
04193 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
04194 {
04195 if (strlen (optable[i].in) == 2
04196 && memcmp (optable[i].in, declp->b + 2, 2) == 0)
04197 {
04198 string_clear (declp);
04199 string_append (declp, "operator");
04200 string_append (declp, optable[i].out);
04201 break;
04202 }
04203 }
04204 }
04205 else
04206 {
04207 if (declp->b[2] == 'a' && declp->b[5] == '\0')
04208 {
04209
04210 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
04211 {
04212 if (strlen (optable[i].in) == 3
04213 && memcmp (optable[i].in, declp->b + 2, 3) == 0)
04214 {
04215 string_clear (declp);
04216 string_append (declp, "operator");
04217 string_append (declp, optable[i].out);
04218 break;
04219 }
04220 }
04221 }
04222 }
04223 }
04224 }
04225
04226
04227
04228 static void
04229 string_need (s, n)
04230 string *s;
04231 int n;
04232 {
04233 int tem;
04234
04235 if (s->b == NULL)
04236 {
04237 if (n < 32)
04238 {
04239 n = 32;
04240 }
04241 s->p = s->b = xmalloc (n);
04242 s->e = s->b + n;
04243 }
04244 else if (s->e - s->p < n)
04245 {
04246 tem = s->p - s->b;
04247 n += tem;
04248 n *= 2;
04249 s->b = xrealloc (s->b, n);
04250 s->p = s->b + tem;
04251 s->e = s->b + n;
04252 }
04253 }
04254
04255 static void
04256 string_delete (s)
04257 string *s;
04258 {
04259 if (s->b != NULL)
04260 {
04261 free (s->b);
04262 s->b = s->e = s->p = NULL;
04263 }
04264 }
04265
04266 static void
04267 string_init (s)
04268 string *s;
04269 {
04270 s->b = s->p = s->e = NULL;
04271 }
04272
04273 static void
04274 string_clear (s)
04275 string *s;
04276 {
04277 s->p = s->b;
04278 }
04279
04280 #if 0
04281
04282 static int
04283 string_empty (s)
04284 string *s;
04285 {
04286 return (s->b == s->p);
04287 }
04288
04289 #endif
04290
04291 static void
04292 string_append (p, s)
04293 string *p;
04294 const char *s;
04295 {
04296 int n;
04297 if (s == NULL || *s == '\0')
04298 return;
04299 n = strlen (s);
04300 string_need (p, n);
04301 memcpy (p->p, s, n);
04302 p->p += n;
04303 }
04304
04305 static void
04306 string_appends (p, s)
04307 string *p, *s;
04308 {
04309 int n;
04310
04311 if (s->b != s->p)
04312 {
04313 n = s->p - s->b;
04314 string_need (p, n);
04315 memcpy (p->p, s->b, n);
04316 p->p += n;
04317 }
04318 }
04319
04320 static void
04321 string_appendn (p, s, n)
04322 string *p;
04323 const char *s;
04324 int n;
04325 {
04326 if (n != 0)
04327 {
04328 string_need (p, n);
04329 memcpy (p->p, s, n);
04330 p->p += n;
04331 }
04332 }
04333
04334 static void
04335 string_prepend (p, s)
04336 string *p;
04337 const char *s;
04338 {
04339 if (s != NULL && *s != '\0')
04340 {
04341 string_prependn (p, s, strlen (s));
04342 }
04343 }
04344
04345 static void
04346 string_prepends (p, s)
04347 string *p, *s;
04348 {
04349 if (s->b != s->p)
04350 {
04351 string_prependn (p, s->b, s->p - s->b);
04352 }
04353 }
04354
04355 static void
04356 string_prependn (p, s, n)
04357 string *p;
04358 const char *s;
04359 int n;
04360 {
04361 char *q;
04362
04363 if (n != 0)
04364 {
04365 string_need (p, n);
04366 for (q = p->p - 1; q >= p->b; q--)
04367 {
04368 q[n] = q[0];
04369 }
04370 memcpy (p->b, s, n);
04371 p->p += n;
04372 }
04373 }
04374
04375 static void
04376 string_append_template_idx (s, idx)
04377 string *s;
04378 int idx;
04379 {
04380 char buf[INTBUF_SIZE + 1 ];
04381 sprintf(buf, "T%d", idx);
04382 string_append (s, buf);
04383 }
04384
04385