* cplus-dem.c (demangle_signature): Recognize misplaced '_' to
[deliverable/binutils-gdb.git] / gdb / cplus-dem.c
1 /* Demangler for GNU C++
2 Copyright 1989, 1991 Free Software Foundation, Inc.
3 Written by James Clark (jjc@jclark.uucp)
4 Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20 /* This is for g++ 1.95.03 (November 13 version). */
21
22 /* This file exports two functions; cplus_mangle_opname and cplus_demangle.
23
24 This file imports xmalloc and xrealloc, which are like malloc and
25 realloc except that they generate a fatal error if there is no
26 available memory. */
27
28 /* GDB-specific, FIXME. */
29 #include "defs.h"
30 #include "demangle.h"
31
32 #include <ctype.h>
33
34 #ifdef USG
35 #include <memory.h>
36 #include <string.h>
37 #else
38 #include <strings.h>
39 #endif
40
41 #if !defined (GNU_DEMANGLING) && !defined (ARM_DEMANGLING)
42 # define GNU_DEMANGLING 1
43 #endif
44
45 /* This is '$' on systems where the assembler can deal with that.
46 Where the assembler can't, it's '.' (but on many systems '.' is
47 used for other things). */
48
49 #if !defined (CPLUS_MARKER)
50 #define CPLUS_MARKER '$'
51 #endif
52
53 #ifndef __STDC__
54 #define const
55 #endif
56
57 /* Stuff that is shared between sub-routines.
58 * Using a shared structure allows cplus_demangle to be reentrant. */
59
60 struct work_stuff
61 {
62 int options;
63 char **typevec;
64 int ntypes;
65 int typevec_size;
66 int constructor;
67 int destructor;
68 int static_type; /* A static member function */
69 int const_type; /* A const member function */
70 };
71
72 #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
73 #define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
74
75 static const struct optable
76 {
77 const char *in;
78 const char *out;
79 int flags;
80 } optable[] = {
81 "nw", " new", DMGL_ANSI, /* new (1.92, ansi) */
82 "dl", " delete", DMGL_ANSI, /* new (1.92, ansi) */
83 "new", " new", 0, /* old (1.91, and 1.x) */
84 "delete", " delete", 0, /* old (1.91, and 1.x) */
85 "as", "=", DMGL_ANSI, /* ansi */
86 "ne", "!=", DMGL_ANSI, /* old, ansi */
87 "eq", "==", DMGL_ANSI, /* old, ansi */
88 "ge", ">=", DMGL_ANSI, /* old, ansi */
89 "gt", ">", DMGL_ANSI, /* old, ansi */
90 "le", "<=", DMGL_ANSI, /* old, ansi */
91 "lt", "<", DMGL_ANSI, /* old, ansi */
92 "plus", "+", 0, /* old */
93 "pl", "+", DMGL_ANSI, /* ansi */
94 "apl", "+=", DMGL_ANSI, /* ansi */
95 "minus", "-", 0, /* old */
96 "mi", "-", DMGL_ANSI, /* ansi */
97 "ami", "-=", DMGL_ANSI, /* ansi */
98 "mult", "*", 0, /* old */
99 "ml", "*", DMGL_ANSI, /* ansi */
100 #ifdef ARM_DEMANGLING
101 "amu", "*=", DMGL_ANSI, /* ansi */
102 #else
103 "aml", "*=", DMGL_ANSI, /* ansi */
104 #endif
105 "convert", "+", 0, /* old (unary +) */
106 "negate", "-", 0, /* old (unary -) */
107 "trunc_mod", "%", 0, /* old */
108 "md", "%", DMGL_ANSI, /* ansi */
109 "amd", "%=", DMGL_ANSI, /* ansi */
110 "trunc_div", "/", 0, /* old */
111 "dv", "/", DMGL_ANSI, /* ansi */
112 "adv", "/=", DMGL_ANSI, /* ansi */
113 "truth_andif", "&&", 0, /* old */
114 "aa", "&&", DMGL_ANSI, /* ansi */
115 "truth_orif", "||", 0, /* old */
116 "oo", "||", DMGL_ANSI, /* ansi */
117 "truth_not", "!", 0, /* old */
118 "nt", "!", DMGL_ANSI, /* ansi */
119 "postincrement","++", 0, /* old */
120 "pp", "++", DMGL_ANSI, /* ansi */
121 "postdecrement","--", 0, /* old */
122 "mm", "--", DMGL_ANSI, /* ansi */
123 "bit_ior", "|", 0, /* old */
124 "or", "|", DMGL_ANSI, /* ansi */
125 "aor", "|=", DMGL_ANSI, /* ansi */
126 "bit_xor", "^", 0, /* old */
127 "er", "^", DMGL_ANSI, /* ansi */
128 "aer", "^=", DMGL_ANSI, /* ansi */
129 "bit_and", "&", 0, /* old */
130 "ad", "&", DMGL_ANSI, /* ansi */
131 "aad", "&=", DMGL_ANSI, /* ansi */
132 "bit_not", "~", 0, /* old */
133 "co", "~", DMGL_ANSI, /* ansi */
134 "call", "()", 0, /* old */
135 "cl", "()", DMGL_ANSI, /* ansi */
136 "alshift", "<<", 0, /* old */
137 "ls", "<<", DMGL_ANSI, /* ansi */
138 "als", "<<=", DMGL_ANSI, /* ansi */
139 "arshift", ">>", 0, /* old */
140 "rs", ">>", DMGL_ANSI, /* ansi */
141 "ars", ">>=", DMGL_ANSI, /* ansi */
142 "component", "->", 0, /* old */
143 #ifdef LUCID_DEMANGLING
144 "pt", "->", DMGL_ANSI, /* ansi; Lucid C++ form */
145 #else
146 "rf", "->", DMGL_ANSI, /* ansi */
147 #endif
148 "indirect", "*", 0, /* old */
149 "method_call", "->()", 0, /* old */
150 "addr", "&", 0, /* old (unary &) */
151 "array", "[]", 0, /* old */
152 "vc", "[]", DMGL_ANSI, /* ansi */
153 "compound", ", ", 0, /* old */
154 "cm", ", ", DMGL_ANSI, /* ansi */
155 "cond", "?:", 0, /* old */
156 "cn", "?:", DMGL_ANSI, /* psuedo-ansi */
157 "max", ">?", 0, /* old */
158 "mx", ">?", DMGL_ANSI, /* psuedo-ansi */
159 "min", "<?", 0, /* old */
160 "mn", "<?", DMGL_ANSI, /* psuedo-ansi */
161 "nop", "", 0, /* old (for operator=) */
162 "rm", "->*", DMGL_ANSI, /* ansi */
163 };
164
165
166 typedef struct string /* Beware: these aren't required to be */
167 { /* '\0' terminated. */
168 char *b; /* pointer to start of string */
169 char *p; /* pointer after last character */
170 char *e; /* pointer after end of allocated space */
171 } string;
172
173 #define STRING_EMPTY(str) ((str) -> b == (str) -> p)
174 #define PREPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
175 string_prepend(str, " ");}
176 #define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
177 string_append(str, " ");}
178
179 /* Prototypes for local functions */
180
181 static char *
182 mop_up PARAMS ((string *, struct work_stuff *, int));
183
184 static int
185 demangle_method_args PARAMS ((string *, const char **, struct work_stuff *));
186
187 static int
188 demangle_template PARAMS ((string *declp, const char **, struct work_stuff *));
189
190 static int
191 demangle_qualified PARAMS ((string *, const char **, struct work_stuff *));
192
193 static int
194 demangle_class PARAMS ((string *, const char **, struct work_stuff *));
195
196 static int
197 demangle_fund_type PARAMS ((const char **, string *, struct work_stuff *));
198
199 static int
200 demangle_signature PARAMS ((string *, const char **, struct work_stuff *));
201
202 static int
203 demangle_prefix PARAMS ((string *, const char **, struct work_stuff *));
204
205 static int
206 gnu_special PARAMS ((string *, const char **, struct work_stuff *));
207
208 static void
209 string_need PARAMS ((string *, int));
210
211 static void
212 string_delete PARAMS ((string *));
213
214 static void
215 string_init PARAMS ((string *));
216
217 static void
218 string_clear PARAMS ((string *));
219
220 static int
221 string_empty PARAMS ((string *));
222
223 static void
224 string_append PARAMS ((string *, const char *));
225
226 static void
227 string_appends PARAMS ((string *, string *));
228
229 static void
230 string_appendn PARAMS ((string *, const char *, int));
231
232 static void
233 string_prepend PARAMS ((string *, const char *));
234
235 static void
236 string_prependn PARAMS ((string *, const char *, int));
237
238 static int
239 get_count PARAMS ((const char **, int *));
240
241 static int
242 demangle_args PARAMS ((string *, const char **, struct work_stuff *));
243
244 static int
245 do_type PARAMS ((const char **, string *, struct work_stuff *));
246
247 static int
248 do_arg PARAMS ((const char **, string *, struct work_stuff*));
249
250 static void
251 demangle_function_name PARAMS ((string *, const char **, struct work_stuff*,
252 const char *));
253
254 static void
255 remember_type PARAMS ((const char *, int, struct work_stuff *));
256
257 #if 0
258 static void
259 string_prepends PARAMS ((string *, string *));
260 #endif
261
262
263 /* Takes operator name as e.g. "++" and returns mangled
264 operator name (e.g. "postincrement_expr"), or NULL if not found.
265
266 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
267 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
268
269 char *
270 cplus_mangle_opname (opname, options)
271 char *opname;
272 int options;
273 {
274 int i;
275 int len;
276
277 len = strlen (opname);
278 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
279 {
280 if (strlen (optable[i].out) == len
281 && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI)
282 && memcmp (optable[i].out, opname, len) == 0)
283 return ((char *)optable[i].in);
284 }
285 return (0);
286 }
287
288 /* char *cplus_demangle (const char *name, int options)
289
290 If NAME is a mangled function name produced by GNU C++, then
291 a pointer to a malloced string giving a C++ representation
292 of the name will be returned; otherwise NULL will be returned.
293 It is the caller's responsibility to free the string which
294 is returned.
295
296 The OPTIONS arg may contain one or more of the following bits:
297
298 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
299 included.
300 DMGL_PARAMS Function parameters are included.
301
302 For example,
303
304 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
305 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
306 cplus_demangle ("foo__1Ai", 0) => "A::foo"
307
308 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
309 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
310 cplus_demangle ("foo__1Afe", 0) => "A::foo"
311
312 Note that any leading underscores, or other such characters prepended by
313 the compilation system, are presumed to have already been stripped from
314 TYPE. */
315
316 char *
317 cplus_demangle (mangled, options)
318 const char *mangled;
319 int options;
320 {
321 string decl;
322 int success = 0;
323 struct work_stuff work[1];
324 const char *p;
325 char *demangled = NULL;
326
327 if ((mangled != NULL) && (*mangled != '\0'))
328 {
329 (void) memset ((char *) work, 0, sizeof (work));
330 work -> options = options;
331
332 string_init (&decl);
333 success = demangle_prefix (&decl, &mangled, work);
334 if (success && (*mangled != '\0'))
335 {
336 success = demangle_signature (&decl, &mangled, work);
337 }
338 demangled = mop_up (&decl, work, success);
339 }
340 return (demangled);
341 }
342
343 static char *
344 mop_up (declp, work, success)
345 string *declp;
346 struct work_stuff *work;
347 int success;
348 {
349 int i;
350 char *demangled = NULL;
351
352 /* Discard the remembered types, if any. */
353
354 for (i = 0; i < work -> ntypes; i++)
355 {
356 if (work -> typevec[i] != NULL)
357 {
358 free (work -> typevec[i]);
359 }
360 }
361 if (work -> typevec != NULL)
362 {
363 free ((char *) work -> typevec);
364 }
365
366 /* If demangling was successful, ensure that the demangled string is null
367 terminated and return it. Otherwise, free the demangling decl. */
368
369 if (!success)
370 {
371 string_delete (declp);
372 }
373 else
374 {
375 string_appendn (declp, "", 1);
376 demangled = declp -> b;
377 }
378 return (demangled);
379 }
380
381 /*
382
383 LOCAL FUNCTION
384
385 demangle_signature -- demangle the signature part of a mangled name
386
387 SYNOPSIS
388
389 static int
390 demangle_signature (string *declp, const char **mangled,
391 struct work_stuff *work);
392
393 DESCRIPTION
394
395 Consume and demangle the signature portion of the mangled name.
396
397 DECLP is the string where demangled output is being built. At
398 entry it contains the demangled root name from the mangled name
399 prefix. I.E. either a demangled operator name or the root function
400 name. In some special cases, it may contain nothing.
401
402 *MANGLED points to the current unconsumed location in the mangled
403 name. As tokens are consumed and demangling is performed, the
404 pointer is updated to continuously point at the next token to
405 be consumed.
406
407 Demangling GNU style mangled names is nasty because there is no
408 explicit token that marks the start of the outermost function
409 argument list.
410 */
411
412 static int
413 demangle_signature (declp, mangled, work)
414 string *declp;
415 const char **mangled;
416 struct work_stuff *work;
417 {
418 int success = 1;
419 int func_done = 0;
420 #ifdef GNU_DEMANGLING
421 int expect_func = 0;
422 #endif
423 #ifndef LONGERNAMES
424 const char *premangle;
425 #endif
426
427 #ifndef LONGERNAMES
428 premangle = *mangled;
429 #endif
430
431 while (success && (**mangled != '\0'))
432 {
433 switch (**mangled)
434 {
435 case 'Q':
436 success = demangle_qualified (declp, mangled, work);
437 #ifdef GNU_DEMANGLING
438 expect_func = 1;
439 #endif
440 break;
441
442 case 'S':
443 /* Static member function */
444 (*mangled)++;
445 work -> static_type = 1;
446 break;
447
448 case 'C':
449 /* a const member function */
450 (*mangled)++;
451 work -> const_type = 1;
452 break;
453
454 case '0': case '1': case '2': case '3': case '4':
455 case '5': case '6': case '7': case '8': case '9':
456 success = demangle_class (declp, mangled, work);
457 #ifndef LONGERNAMES
458 if (success)
459 {
460 remember_type (premangle, *mangled - premangle, work);
461 }
462 #endif
463 #ifdef GNU_DEMANGLING
464 expect_func = 1;
465 #endif
466 break;
467
468 case 'F':
469 /* Function */
470 /* ARM style demangling includes a specific 'F' character after
471 the class name. For GNU style, it is just implied. So we can
472 safely just consume any 'F' at this point and be compatible
473 with either style. */
474 func_done = 1;
475 (*mangled)++;
476 success = demangle_args (declp, mangled, work);
477 break;
478
479 case 't':
480 /* Template */
481 success = demangle_template (declp, mangled, work);
482 break;
483
484 case '_':
485 /* At the outermost level, we cannot have a return type specified,
486 so if we run into another '_' at this point we are dealing with
487 a mangled name that is either bogus, or has been mangled by
488 some algorithm we don't know how to deal with. So just
489 reject the entire demangling. */
490 success = 0;
491 break;
492
493 default:
494 #ifdef GNU_DEMANGLING
495 /* Assume we have stumbled onto the first outermost function
496 argument token, and start processing args. */
497 func_done = 1;
498 success = demangle_args (declp, mangled, work);
499 #else
500 /* Non-GNU demanglers use a specific token to mark the start
501 of the outermost function argument tokens. Typically 'F',
502 for ARM-demangling, for example. So if we find something
503 we are not prepared for, it must be an error. */
504 success = 0;
505 #endif
506 break;
507 }
508 #ifdef GNU_DEMANGLING
509 if (success && expect_func)
510 {
511 func_done = 1;
512 success = demangle_args (declp, mangled, work);
513 }
514 #endif
515 }
516 if (success && !func_done)
517 {
518 /* Even with ARM style demangling, sometimes there is no explicit
519 function argument tokens if the function takes no arguments. */
520 success = demangle_args (declp, mangled, work);
521 }
522 if (success && work -> static_type && PRINT_ARG_TYPES)
523 {
524 string_append (declp, " static");
525 }
526 if (success && work -> const_type && PRINT_ARG_TYPES)
527 {
528 string_append (declp, " const");
529 }
530 return (success);
531 }
532
533 #if 0
534
535 static int
536 demangle_method_args (declp, mangled, work)
537 string *declp;
538 const char **mangled;
539 struct work_stuff *work;
540 {
541 int success = 0;
542
543 if (work -> static_type)
544 {
545 string_append (declp, *mangled + 1);
546 *mangled += strlen (*mangled);
547 success = 1;
548 }
549 else
550 {
551 success = demangle_args (declp, mangled, work);
552 }
553 return (success);
554 }
555
556 #endif
557
558 static int
559 demangle_template (declp, mangled, work)
560 string *declp;
561 const char **mangled;
562 struct work_stuff *work;
563 {
564 int i;
565 int n;
566 string tname;
567 string trawname;
568 int is_pointer;
569 int is_real;
570 int is_integral;
571 int r;
572 int need_comma = 0;
573 int success = 0;
574 int done;
575 const char *old_p;
576 int symbol_len;
577 string temp;
578
579 (*mangled)++;
580 string_init (&tname);
581 string_init (&trawname);
582 /* get template name */
583 if (!get_count (mangled, &r))
584 {
585 return (0);
586 }
587 string_appendn (&tname, *mangled, r);
588 string_appendn (&trawname, *mangled, r);
589 string_appendn (&trawname, "", 1);
590 *mangled += r;
591 string_append (&tname, "<");
592 /* get size of template parameter list */
593 if (!get_count (mangled, &r))
594 {
595 return (0);
596 }
597 for (i = 0; i < r; i++)
598 {
599 if (need_comma)
600 {
601 string_append (&tname, ", ");
602 }
603 /* Z for type parameters */
604 if (**mangled == 'Z')
605 {
606 (*mangled)++;
607 success = do_type (mangled, &temp, work);
608 string_appendn (&temp, "", 1);
609 if (success)
610 {
611 string_append (&tname, temp.b);
612 }
613 string_delete(&temp);
614 if (!success)
615 {
616 break;
617 }
618 }
619 else
620 {
621 /* otherwise, value parameter */
622 old_p = *mangled;
623 is_pointer = 0;
624 is_real = 0;
625 is_integral = 0;
626 done = 0;
627 success = do_type (mangled, &temp, work);
628 string_appendn (&temp, "", 1);
629 if (success)
630 {
631 string_append (&tname, temp.b);
632 }
633 string_delete(&temp);
634 if (!success)
635 {
636 break;
637 }
638 string_append (&tname, "=");
639 while (*old_p && !done)
640 {
641 switch (*old_p)
642 {
643 case 'P':
644 case 'R':
645 done = is_pointer = 1;
646 break;
647 case 'C': /* const */
648 case 'S': /* explicitly signed [char] */
649 case 'U': /* unsigned */
650 case 'V': /* volatile */
651 case 'F': /* function */
652 case 'M': /* member function */
653 case 'O': /* ??? */
654 old_p++;
655 continue;
656 case 'Q': /* repetition of following */
657 case 'T': /* remembered type */
658 abort ();
659 break;
660 case 'v': /* void */
661 abort ();
662 break;
663 case 'x': /* long long */
664 case 'l': /* long */
665 case 'i': /* int */
666 case 's': /* short */
667 case 'c': /* char */
668 done = is_integral = 1;
669 break;
670 case 'r': /* long double */
671 case 'd': /* double */
672 case 'f': /* float */
673 done = is_real = 1;
674 break;
675 default:
676 abort ();
677 }
678 }
679 if (is_integral)
680 {
681 if (**mangled == 'm')
682 {
683 string_appendn (&tname, "-", 1);
684 (*mangled)++;
685 }
686 while (isdigit (**mangled))
687 {
688 string_appendn (&tname, *mangled, 1);
689 (*mangled)++;
690 }
691 }
692 else if (is_real)
693 {
694 if (**mangled == 'm')
695 {
696 string_appendn (&tname, "-", 1);
697 (*mangled)++;
698 }
699 while (isdigit (**mangled))
700 {
701 string_appendn (&tname, *mangled, 1);
702 (*mangled)++;
703 }
704 if (**mangled == '.') /* fraction */
705 {
706 string_appendn (&tname, ".", 1);
707 (*mangled)++;
708 while (isdigit (**mangled))
709 {
710 string_appendn (&tname, *mangled, 1);
711 (*mangled)++;
712 }
713 }
714 if (**mangled == 'e') /* exponent */
715 {
716 string_appendn (&tname, "e", 1);
717 (*mangled)++;
718 while (isdigit (**mangled))
719 {
720 string_appendn (&tname, *mangled, 1);
721 (*mangled)++;
722 }
723 }
724 }
725 else if (is_pointer)
726 {
727 if (!get_count (mangled, &symbol_len))
728 {
729 success = 0;
730 break;
731 }
732 string_appendn (&tname, *mangled, symbol_len);
733 *mangled += symbol_len;
734 }
735 }
736 need_comma = 1;
737 }
738 string_append (&tname, ">::");
739 if (work -> destructor)
740 {
741 string_append (&tname, "~");
742 }
743 if (work -> constructor || work -> destructor)
744 {
745 string_append (&tname, trawname.b);
746 }
747 string_delete(&trawname);
748
749 if (!success)
750 {
751 string_delete(&tname);
752 }
753 else
754 {
755 string_prepend (declp, tname.b);
756 string_delete (&tname);
757
758 if (work -> static_type)
759 {
760 string_append (declp, *mangled + 1);
761 *mangled += strlen (*mangled);
762 success = 1;
763 }
764 else
765 {
766 success = demangle_args (declp, mangled, work);
767 }
768 }
769 }
770
771 /*
772
773 LOCAL FUNCTION
774
775 demangle_class -- demangle a mangled class sequence
776
777 SYNOPSIS
778
779 static int
780 demangle_class (string *declp, const char **mangled,
781 struct work_stuff *work)
782
783 DESCRIPTION
784
785 DECLP points to the buffer into which demangling is being done.
786
787 *MANGLED points to the current token to be demangled. On input,
788 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
789 On exit, it points to the next token after the mangled class on
790 success, or the first unconsumed token on failure.
791
792 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
793 we are demangling a constructor or destructor. In this case
794 we prepend "class::class" or "class::~class" to DECLP.
795
796 Otherwise, we prepend "class::" to the current DECLP.
797
798 Reset the constructor/destructor flags once they have been
799 "consumed". This allows demangle_class to be called later during
800 the same demangling, to do normal class demangling.
801
802 Returns 1 if demangling is successful, 0 otherwise.
803
804 */
805
806 static int
807 demangle_class (declp, mangled, work)
808 string *declp;
809 const char **mangled;
810 struct work_stuff *work;
811 {
812 int n;
813 int success = 0;
814
815 n = 0;
816 do
817 {
818 n *= 10;
819 n += **mangled - '0';
820 (*mangled)++;
821 }
822 while (isdigit (**mangled));
823 if (strlen (*mangled) >= n)
824 {
825 if (work -> constructor || work -> destructor)
826 {
827 string_prependn (declp, *mangled, n);
828 if (work -> destructor)
829 {
830 string_prepend (declp, "~");
831 }
832 work -> constructor = work -> destructor = 0;
833 }
834 string_prepend (declp, "::");
835 string_prependn (declp, *mangled, n);
836 *mangled += n;
837 success = 1;
838 }
839 return (success);
840 }
841
842 /*
843
844 LOCAL FUNCTION
845
846 demangle_prefix -- consume the mangled name prefix and find signature
847
848 SYNOPSIS
849
850 static int
851 demangle_prefix (string *declp, const char **mangled,
852 struct work_stuff *work)
853
854 DESCRIPTION
855
856 Consume and demangle the prefix of the mangled name.
857
858 DECLP points to the string buffer into which demangled output is
859 placed. On entry, the buffer is empty. On exit it contains
860 the root function name, the demangled operator name, or in some
861 special cases either nothing or the completely demangled result.
862
863 MANGLED points to the current pointer into the mangled name. As each
864 token of the mangled name is consumed, it is updated. Upon entry
865 the current mangled name pointer points to the first character of
866 the mangled name. Upon exit, it should point to the first character
867 of the signature if demangling was successful, or to the first
868 unconsumed character if demangling of the prefix was unsuccessful.
869
870 Returns 1 on success, 0 otherwise.
871 */
872
873 static int
874 demangle_prefix (declp, mangled, work)
875 string *declp;
876 const char **mangled;
877 struct work_stuff *work;
878 {
879 int success = 1;
880 const char *scan;
881
882 if ((scan = strstr (*mangled, "__")) == NULL)
883 {
884 success = gnu_special (declp, mangled, work);
885 }
886 else if (work -> static_type)
887 {
888 if (!isdigit (scan[0]) && (scan[0] != 't'))
889 {
890 success = 0;
891 }
892 }
893 else if ((scan == *mangled) && (isdigit (scan[2]) || (scan[2] == 'Q')))
894 {
895 /* A GNU style constructor starts with "__<digit>" or "__Q". */
896 work -> constructor = 1;
897 *mangled = scan + 2;
898 }
899 else if ((scan == *mangled) && !isdigit (scan[2]) && (scan[2] != 't'))
900 {
901 /* Mangled name starts with "__". Skip over any leading '_' characters,
902 then find the next "__" that separates the prefix from the signature.
903 */
904 while (*scan == '_')
905 {
906 scan++;
907 }
908 if ((scan = strstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
909 {
910 /* No separator (I.E. "__not_mangled"), or empty signature
911 (I.E. "__not_mangled_either__") */
912 success = 0;
913 }
914 else
915 {
916 demangle_function_name (declp, mangled, work, scan);
917 }
918 }
919 else if (*(scan + 2) != '\0')
920 {
921 /* Mangled name does not start with "__" but does have one somewhere
922 in there with non empty stuff after it. Looks like a global
923 function name. */
924 demangle_function_name (declp, mangled, work, scan);
925 }
926 else
927 {
928 /* Doesn't look like a mangled name */
929 success = 0;
930 }
931 return (success);
932 }
933
934 static int
935 gnu_special (declp, mangled, work)
936 string *declp;
937 const char **mangled;
938 struct work_stuff *work;
939 {
940 int n;
941 int success = 1;
942 const char *p;
943
944 if ((*mangled)[0] == '_'
945 && (*mangled)[1] == CPLUS_MARKER
946 && (*mangled)[2] == '_')
947 {
948 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
949 (*mangled) += 3;
950 work -> destructor = 1;
951 }
952 else if (**mangled != '_' && (p = strchr (*mangled, CPLUS_MARKER)) != NULL)
953 {
954 #if 0
955 /* static data member */
956 n = strlen (*mangled) + 2;
957 tem = (char *) xmalloc (n);
958 memcpy (tem, *mangled, p - *mangled);
959 strcpy (tem + (p - *mangled), "::");
960 strcpy (tem + (p - *mangled) + 2, p + 1);
961 #endif
962 }
963 else if ((*mangled)[0] == '_'
964 && (*mangled)[1] == 'v'
965 && (*mangled)[2] == 't'
966 && (*mangled)[3] == CPLUS_MARKER)
967 {
968 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
969 and create the decl. Note that we consume the entire mangled
970 input string, which means that demangle_signature has no work
971 to do. */
972 (*mangled) += 4;
973 n = strlen (*mangled);
974 string_appendn (declp, *mangled, n);
975 string_append (declp, " virtual table");
976 (*mangled) += n;
977 }
978 else
979 {
980 success = 0;
981 }
982 return (success);
983 }
984
985 /* Do a qualified name, such as "Q25Outer5Inner" for "Outer::Inner" */
986
987 static int
988 demangle_qualified (declp, mangled, work)
989 string *declp;
990 const char **mangled;
991 struct work_stuff *work;
992 {
993 int n;
994 string class;
995 string tmp;
996 int success = 0;
997
998 n = (*mangled)[1] - '0';
999 if (n >= 0 && n <= 9)
1000 {
1001 if ((*mangled)[2] == '_')
1002 {
1003 /* cfront style */
1004 (*mangled)++;
1005 }
1006 (*mangled) += 2;
1007 string_init (&class);
1008 while (n-- > 0)
1009 {
1010 success = do_type (mangled, &tmp, work);
1011 string_appends (&class, &tmp);
1012 string_append (&class, "::");
1013 if (n == 0 && (work -> constructor || work -> destructor))
1014 {
1015 if (work -> destructor)
1016 {
1017 string_append (&class, "~");
1018 }
1019 string_appends (&class, &tmp);
1020 }
1021 string_delete (&tmp);
1022 }
1023 work -> constructor = work -> destructor = 0;
1024 string_prependn (declp, class.b, class.p - class.b);
1025 string_delete (&class);
1026 }
1027 return (success);
1028 }
1029
1030 static int
1031 get_count (type, count)
1032 const char **type;
1033 int *count;
1034 {
1035 const char *p;
1036 int n;
1037
1038 if (!isdigit (**type))
1039 {
1040 return (0);
1041 }
1042 *count = **type - '0';
1043 (*type)++;
1044 /* see flush_repeats in cplus-method.c */
1045 if (isdigit (**type))
1046 {
1047 p = *type;
1048 n = *count;
1049 do
1050 {
1051 n *= 10;
1052 n += *p - '0';
1053 p++;
1054 }
1055 while (isdigit (*p));
1056 if (*p == '_')
1057 {
1058 *type = p + 1;
1059 *count = n;
1060 }
1061 }
1062 return (1);
1063 }
1064
1065 /* result will be initialised here; it will be freed on failure */
1066
1067 static int
1068 do_type (type, result, work)
1069 const char **type;
1070 string *result;
1071 struct work_stuff *work;
1072 {
1073 int n;
1074 int done;
1075 int success;
1076 string decl;
1077 const char *remembered_type;
1078 int constp;
1079 int volatilep;
1080
1081 string_init (&decl);
1082 string_init (result);
1083
1084 done = 0;
1085 success = 1;
1086 while (success && !done)
1087 {
1088 int member;
1089 switch (**type)
1090 {
1091 /* A qualified name, such as "Outer::Inner". Note qualifier count
1092 is limited to a single digit (0-9 qualifiers). */
1093 case 'Q':
1094 n = (*type)[1] - '0';
1095 if (n < 0 || n > 9)
1096 {
1097 success = 0;
1098 }
1099 if ((*type)[2] == '_') /* cfront style */
1100 {
1101 (*type)++;
1102 }
1103 *type += 2;
1104 while (n-- > 0)
1105 {
1106 do_type (type, result, work);
1107 }
1108 break;
1109
1110 /* A pointer type */
1111 case 'P':
1112 (*type)++;
1113 string_prepend (&decl, "*");
1114 break;
1115
1116 /* A reference type */
1117 case 'R':
1118 (*type)++;
1119 string_prepend (&decl, "&");
1120 break;
1121
1122 /* A back reference to a previously seen type */
1123 case 'T':
1124 (*type)++;
1125 if (!get_count (type, &n) || n >= work -> ntypes)
1126 {
1127 success = 0;
1128 }
1129 else
1130 {
1131 remembered_type = work -> typevec[n];
1132 type = &remembered_type;
1133 }
1134 break;
1135
1136 /* A function */
1137 case 'F':
1138 (*type)++;
1139 if (!STRING_EMPTY (&decl) && decl.b[0] == '*')
1140 {
1141 string_prepend (&decl, "(");
1142 string_append (&decl, ")");
1143 }
1144 /* After picking off the function args, we expect to either find the
1145 function return type (preceded by an '_') or the end of the
1146 string. */
1147 if (!demangle_args (&decl, type, work)
1148 || (**type != '_' && **type != '\0'))
1149 {
1150 success = 0;
1151 }
1152 if (success && (**type == '_'))
1153 {
1154 (*type)++;
1155 }
1156 break;
1157
1158 case 'M':
1159 case 'O':
1160 {
1161 constp = 0;
1162 volatilep = 0;
1163
1164 member = **type == 'M';
1165 (*type)++;
1166 if (!isdigit (**type))
1167 {
1168 success = 0;
1169 break;
1170 }
1171 n = 0;
1172 do
1173 {
1174 n *= 10;
1175 n += **type - '0';
1176 (*type)++;
1177 }
1178 while (isdigit (**type));
1179 if (strlen (*type) < n)
1180 {
1181 success = 0;
1182 break;
1183 }
1184 string_append (&decl, ")");
1185 string_prepend (&decl, "::");
1186 string_prependn (&decl, *type, n);
1187 string_prepend (&decl, "(");
1188 *type += n;
1189 if (member)
1190 {
1191 if (**type == 'C')
1192 {
1193 (*type)++;
1194 constp = 1;
1195 }
1196 if (**type == 'V')
1197 {
1198 (*type)++;
1199 volatilep = 1;
1200 }
1201 if (*(*type)++ != 'F')
1202 {
1203 success = 0;
1204 break;
1205 }
1206 }
1207 if ((member && !demangle_args (&decl, type, work))
1208 || **type != '_')
1209 {
1210 success = 0;
1211 break;
1212 }
1213 (*type)++;
1214 if (! PRINT_ANSI_QUALIFIERS)
1215 {
1216 break;
1217 }
1218 if (constp)
1219 {
1220 APPEND_BLANK (&decl);
1221 string_append (&decl, "const");
1222 }
1223 if (volatilep)
1224 {
1225 APPEND_BLANK (&decl);
1226 string_append (&decl, "volatile");
1227 }
1228 break;
1229 }
1230
1231 case 'C':
1232 if ((*type)[1] == 'P')
1233 {
1234 (*type)++;
1235 if (PRINT_ANSI_QUALIFIERS)
1236 {
1237 if (!STRING_EMPTY (&decl))
1238 {
1239 string_prepend (&decl, " ");
1240 }
1241 string_prepend (&decl, "const");
1242 }
1243 break;
1244 }
1245
1246 /* fall through */
1247 default:
1248 done = 1;
1249 break;
1250 }
1251 }
1252
1253 success = demangle_fund_type (type, result, work);
1254
1255 if (success)
1256 {
1257 if (!STRING_EMPTY (&decl))
1258 {
1259 string_append (result, " ");
1260 string_appends (result, &decl);
1261 }
1262 }
1263 else
1264 {
1265 string_delete (result);
1266 }
1267 string_delete (&decl);
1268 return (success);
1269 }
1270
1271 /* Given a pointer to a type string that represents a fundamental type
1272 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
1273 string in which the demangled output is being built in RESULT, and
1274 the WORK structure, decode the types and add them to the result.
1275
1276 For example:
1277
1278 "Ci" => "const int"
1279 "Sl" => "signed long"
1280 "CUs" => "const unsigned short"
1281
1282 */
1283
1284 static int
1285 demangle_fund_type (type, result, work)
1286 const char **type;
1287 string *result;
1288 struct work_stuff *work;
1289 {
1290 int done = 0;
1291 int success = 1;
1292 int n;
1293
1294 /* First pick off any type qualifiers. There can be more than one. */
1295
1296 while (!done)
1297 {
1298 switch (**type)
1299 {
1300 case 'C':
1301 (*type)++;
1302 if (PRINT_ANSI_QUALIFIERS)
1303 {
1304 APPEND_BLANK (result);
1305 string_append (result, "const");
1306 }
1307 break;
1308 case 'U':
1309 (*type)++;
1310 APPEND_BLANK (result);
1311 string_append (result, "unsigned");
1312 break;
1313 case 'S': /* signed char only */
1314 (*type)++;
1315 APPEND_BLANK (result);
1316 string_append (result, "signed");
1317 break;
1318 case 'V':
1319 (*type)++;
1320 if (PRINT_ANSI_QUALIFIERS)
1321 {
1322 APPEND_BLANK (result);
1323 string_append (result, "volatile");
1324 }
1325 break;
1326 default:
1327 done = 1;
1328 break;
1329 }
1330 }
1331
1332 /* Now pick off the fundamental type. There can be only one. */
1333
1334 switch (**type)
1335 {
1336 case '\0':
1337 case '_':
1338 break;
1339 case 'v':
1340 (*type)++;
1341 APPEND_BLANK (result);
1342 string_append (result, "void");
1343 break;
1344 case 'x':
1345 (*type)++;
1346 APPEND_BLANK (result);
1347 string_append (result, "long long");
1348 break;
1349 case 'l':
1350 (*type)++;
1351 APPEND_BLANK (result);
1352 string_append (result, "long");
1353 break;
1354 case 'i':
1355 (*type)++;
1356 APPEND_BLANK (result);
1357 string_append (result, "int");
1358 break;
1359 case 's':
1360 (*type)++;
1361 APPEND_BLANK (result);
1362 string_append (result, "short");
1363 break;
1364 case 'c':
1365 (*type)++;
1366 APPEND_BLANK (result);
1367 string_append (result, "char");
1368 break;
1369 case 'r':
1370 (*type)++;
1371 APPEND_BLANK (result);
1372 string_append (result, "long double");
1373 break;
1374 case 'd':
1375 (*type)++;
1376 APPEND_BLANK (result);
1377 string_append (result, "double");
1378 break;
1379 case 'f':
1380 (*type)++;
1381 APPEND_BLANK (result);
1382 string_append (result, "float");
1383 break;
1384 case 'G':
1385 (*type)++;
1386 if (!isdigit (**type))
1387 {
1388 success = 0;
1389 break;
1390 }
1391 /* fall through */
1392 /* An explicit type, such as "6mytype" or "7integer" */
1393 case '0':
1394 case '1':
1395 case '2':
1396 case '3':
1397 case '4':
1398 case '5':
1399 case '6':
1400 case '7':
1401 case '8':
1402 case '9':
1403 n = 0;
1404 do
1405 {
1406 n *= 10;
1407 n += **type - '0';
1408 (*type)++;
1409 }
1410 while (isdigit (**type));
1411 if (strlen (*type) < n)
1412 {
1413 success = 0;
1414 break;
1415 }
1416 APPEND_BLANK (result);
1417 string_appendn (result, *type, n);
1418 *type += n;
1419 break;
1420 default:
1421 success = 0;
1422 break;
1423 }
1424
1425 return (success);
1426 }
1427
1428 /* `result' will be initialized in do_type; it will be freed on failure */
1429
1430 static int
1431 do_arg (type, result, work)
1432 const char **type;
1433 string *result;
1434 struct work_stuff *work;
1435 {
1436 const char *start = *type;
1437
1438 if (!do_type (type, result, work))
1439 {
1440 return (0);
1441 }
1442 else
1443 {
1444 remember_type (start, *type - start, work);
1445 return (1);
1446 }
1447 }
1448
1449 static void
1450 remember_type (start, len, work)
1451 const char *start;
1452 int len;
1453 struct work_stuff *work;
1454 {
1455 char *tem;
1456
1457 if (work -> ntypes >= work -> typevec_size)
1458 {
1459 if (work -> typevec_size == 0)
1460 {
1461 work -> typevec_size = 3;
1462 work -> typevec =
1463 (char **) xmalloc (sizeof (char *) * work -> typevec_size);
1464 }
1465 else
1466 {
1467 work -> typevec_size *= 2;
1468 work -> typevec =
1469 (char **) xrealloc ((char *)work -> typevec,
1470 sizeof (char *) * work -> typevec_size);
1471 }
1472 }
1473 tem = (char *) xmalloc (len + 1);
1474 memcpy (tem, start, len);
1475 tem[len] = '\0';
1476 work -> typevec[work -> ntypes++] = tem;
1477 }
1478
1479 /* Process the argument list part of the signature, after any class spec
1480 has been consumed, as well as the first 'F' character (if any). For
1481 example:
1482
1483 "__als__3fooRT0" => process "RT0"
1484 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
1485
1486 DECLP must be already initialised, usually non-empty. It won't be freed
1487 on failure */
1488
1489 static int
1490 demangle_args (declp, type, work)
1491 string *declp;
1492 const char **type;
1493 struct work_stuff *work;
1494 {
1495 string arg;
1496 int need_comma = 0;
1497 int r;
1498 int t;
1499 const char *tem;
1500 char temptype;
1501
1502 if (PRINT_ARG_TYPES)
1503 {
1504 string_append (declp, "(");
1505 if (**type == '\0')
1506 {
1507 string_append (declp, "void");
1508 }
1509 }
1510
1511 while (**type != '_' && **type != '\0' && **type != 'e')
1512 {
1513 if ((**type == 'N') || (**type == 'T'))
1514 {
1515 temptype = *(*type)++;
1516
1517 if (temptype == 'N')
1518 {
1519 if (!get_count (type, &r))
1520 {
1521 return (0);
1522 }
1523 }
1524 else
1525 {
1526 r = 1;
1527 }
1528 if (!get_count (type, &t))
1529 {
1530 return (0);
1531 }
1532 #ifdef ARM_DEMANGLING
1533 t--;
1534 #endif
1535 if (t >= work -> ntypes)
1536 {
1537 return (0);
1538 }
1539 while (--r >= 0)
1540 {
1541 tem = work -> typevec[t];
1542 if (need_comma && PRINT_ARG_TYPES)
1543 {
1544 string_append (declp, ", ");
1545 }
1546 if (!do_arg (&tem, &arg, work))
1547 {
1548 return (0);
1549 }
1550 if (PRINT_ARG_TYPES)
1551 {
1552 string_appends (declp, &arg);
1553 }
1554 string_delete (&arg);
1555 need_comma = 1;
1556 }
1557 }
1558 else
1559 {
1560 if (need_comma & PRINT_ARG_TYPES)
1561 {
1562 string_append (declp, ", ");
1563 }
1564 if (!do_arg (type, &arg, work))
1565 {
1566 return (0);
1567 }
1568 if (PRINT_ARG_TYPES)
1569 {
1570 string_appends (declp, &arg);
1571 }
1572 string_delete (&arg);
1573 need_comma = 1;
1574 }
1575 }
1576
1577 if (**type == 'e')
1578 {
1579 (*type)++;
1580 if (PRINT_ARG_TYPES)
1581 {
1582 if (need_comma)
1583 {
1584 string_append (declp, ",");
1585 }
1586 string_append (declp, "...");
1587 }
1588 }
1589
1590 if (PRINT_ARG_TYPES)
1591 {
1592 string_append (declp, ")");
1593 }
1594 return (1);
1595 }
1596
1597 static void
1598 demangle_function_name (declp, mangled, work, scan)
1599 string *declp;
1600 const char **mangled;
1601 struct work_stuff *work;
1602 const char *scan;
1603 {
1604 int i;
1605 int len;
1606 string type;
1607 const char *tem;
1608
1609 string_appendn (declp, (*mangled), scan - (*mangled));
1610 string_need (declp, 1);
1611 *(declp -> p) = '\0';
1612
1613 /* Consume the function name, including the "__" separating the name
1614 from the signature. We are guaranteed that SCAN points to the
1615 separator. */
1616
1617 (*mangled) = scan + 2;
1618
1619 #ifdef ARM_DEMANGLING
1620
1621 /* See if we have an ARM style constructor or destructor operator.
1622 If so, then just record it, clear the decl, and return.
1623 We can't build the actual constructor/destructor decl until later,
1624 when we recover the class name from the signature. */
1625
1626 if (strcmp (declp -> b, "__ct") == 0)
1627 {
1628 work -> constructor = 1;
1629 string_clear (declp);
1630 return;
1631 }
1632 else if (strcmp (declp -> b, "__dt") == 0)
1633 {
1634 work -> destructor = 1;
1635 string_clear (declp);
1636 return;
1637 }
1638
1639 #endif
1640
1641 if (declp->p - declp->b >= 3
1642 && declp->b[0] == 'o'
1643 && declp->b[1] == 'p'
1644 && declp->b[2] == CPLUS_MARKER)
1645 {
1646 /* see if it's an assignment expression */
1647 if (declp->p - declp->b >= 10 /* op$assign_ */
1648 && memcmp (declp->b + 3, "assign_", 7) == 0)
1649 {
1650 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
1651 {
1652 len = declp->p - declp->b - 10;
1653 if (strlen (optable[i].in) == len
1654 && memcmp (optable[i].in, declp->b + 10, len) == 0)
1655 {
1656 string_clear (declp);
1657 string_append (declp, "operator");
1658 string_append (declp, optable[i].out);
1659 string_append (declp, "=");
1660 break;
1661 }
1662 }
1663 }
1664 else
1665 {
1666 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
1667 {
1668 int len = declp->p - declp->b - 3;
1669 if (strlen (optable[i].in) == len
1670 && memcmp (optable[i].in, declp->b + 3, len) == 0)
1671 {
1672 string_clear (declp);
1673 string_append (declp, "operator");
1674 string_append (declp, optable[i].out);
1675 break;
1676 }
1677 }
1678 }
1679 }
1680 else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type$", 5) == 0)
1681 {
1682 /* type conversion operator */
1683 tem = declp->b + 5;
1684 if (do_type (&tem, &type, work))
1685 {
1686 string_clear (declp);
1687 string_append (declp, "operator ");
1688 string_appends (declp, &type);
1689 string_delete (&type);
1690 }
1691 }
1692 else if (declp->b[2] == 'o' && declp->b[3] == 'p')
1693 {
1694 /* ANSI. */
1695 /* type conversion operator. */
1696 tem = declp->b + 4;
1697 if (do_type (&tem, &type, work))
1698 {
1699 string_clear (declp);
1700 string_append (declp, "operator ");
1701 string_appends (declp, &type);
1702 string_delete (&type);
1703 }
1704 }
1705 else if (declp->b[0] == '_' && declp->b[1] == '_'
1706 && declp->b[2] >= 'a' && declp->b[2] <= 'z'
1707 && declp->b[3] >= 'a' && declp->b[3] <= 'z')
1708 {
1709 if (declp->b[4] == '\0')
1710 {
1711 /* Operator. */
1712 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
1713 {
1714 if (strlen (optable[i].in) == 2
1715 && memcmp (optable[i].in, declp->b + 2, 2) == 0)
1716 {
1717 string_clear (declp);
1718 string_append (declp, "operator");
1719 string_append (declp, optable[i].out);
1720 break;
1721 }
1722 }
1723 }
1724 else
1725 {
1726 if (declp->b[2] == 'a' && declp->b[5] == '\0')
1727 {
1728 /* Assignment. */
1729 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
1730 {
1731 if (strlen (optable[i].in) == 3
1732 && memcmp (optable[i].in, declp->b + 2, 3) == 0)
1733 {
1734 string_clear (declp);
1735 string_append (declp, "operator");
1736 string_append (declp, optable[i].out);
1737 break;
1738 }
1739 }
1740 }
1741 }
1742 }
1743 }
1744
1745 /* a mini string-handling package */
1746
1747 static void
1748 string_need (s, n)
1749 string *s;
1750 int n;
1751 {
1752 int tem;
1753
1754 if (s->b == NULL)
1755 {
1756 if (n < 32)
1757 {
1758 n = 32;
1759 }
1760 s->p = s->b = (char *) xmalloc (n);
1761 s->e = s->b + n;
1762 }
1763 else if (s->e - s->p < n)
1764 {
1765 tem = s->p - s->b;
1766 n += tem;
1767 n *= 2;
1768 s->b = (char *) xrealloc (s->b, n);
1769 s->p = s->b + tem;
1770 s->e = s->b + n;
1771 }
1772 }
1773
1774 static void
1775 string_delete (s)
1776 string *s;
1777 {
1778 if (s->b != NULL)
1779 {
1780 free (s->b);
1781 s->b = s->e = s->p = NULL;
1782 }
1783 }
1784
1785 static void
1786 string_init (s)
1787 string *s;
1788 {
1789 s->b = s->p = s->e = NULL;
1790 }
1791
1792 static void
1793 string_clear (s)
1794 string *s;
1795 {
1796 s->p = s->b;
1797 }
1798
1799 static int
1800 string_empty (s)
1801 string *s;
1802 {
1803 return (s->b == s->p);
1804 }
1805
1806 static void
1807 string_append (p, s)
1808 string *p;
1809 const char *s;
1810 {
1811 int n;
1812 if (s == NULL || *s == '\0')
1813 return;
1814 n = strlen (s);
1815 string_need (p, n);
1816 memcpy (p->p, s, n);
1817 p->p += n;
1818 }
1819
1820 static void
1821 string_appends (p, s)
1822 string *p, *s;
1823 {
1824 int n;
1825
1826 if (s->b != s->p)
1827 {
1828 n = s->p - s->b;
1829 string_need (p, n);
1830 memcpy (p->p, s->b, n);
1831 p->p += n;
1832 }
1833 }
1834
1835 static void
1836 string_appendn (p, s, n)
1837 string *p;
1838 const char *s;
1839 int n;
1840 {
1841 if (n != 0)
1842 {
1843 string_need (p, n);
1844 memcpy (p->p, s, n);
1845 p->p += n;
1846 }
1847 }
1848
1849 static void
1850 string_prepend (p, s)
1851 string *p;
1852 const char *s;
1853 {
1854 if (s != NULL && *s != '\0')
1855 {
1856 string_prependn (p, s, strlen (s));
1857 }
1858 }
1859
1860 #if 0
1861 static void
1862 string_prepends (p, s)
1863 string *p, *s;
1864 {
1865 if (s->b != s->p)
1866 {
1867 string_prependn (p, s->b, s->p - s->b);
1868 }
1869 }
1870 #endif
1871
1872 static void
1873 string_prependn (p, s, n)
1874 string *p;
1875 const char *s;
1876 int n;
1877 {
1878 char *q;
1879
1880 if (n != 0)
1881 {
1882 string_need (p, n);
1883 for (q = p->p - 1; q >= p->b; q--)
1884 {
1885 q[n] = q[0];
1886 }
1887 memcpy (p->b, s, n);
1888 p->p += n;
1889 }
1890 }
1891
1892 /* To generate a standalone demangler program for testing purposes, just
1893 compile and link this file with -DMAIN. When run, it demangles each
1894 command line arg, or each stdin string, and prints the result on stdout. */
1895
1896 #ifdef MAIN
1897
1898 static void
1899 demangle_it (mangled_name)
1900 char *mangled_name;
1901 {
1902 char *result;
1903
1904 result = cplus_demangle (mangled_name, DMGL_PARAMS | DMGL_ANSI);
1905 if (result == NULL)
1906 {
1907 printf ("%s\n", mangled_name);
1908 }
1909 else
1910 {
1911 printf ("%s\n", result);
1912 free (result);
1913 }
1914 }
1915
1916 PTR
1917 xmalloc (size)
1918 long size;
1919 {
1920 PTR newmem;
1921
1922 if ((newmem = malloc ((int) size)) == NULL)
1923 {
1924 fprintf (stderr, "\nCan't allocate %u bytes\n", size);
1925 exit (1);
1926 }
1927 return (newmem);
1928 }
1929
1930 PTR
1931 xrealloc (oldmem, size)
1932 PTR oldmem;
1933 long size;
1934 {
1935 PTR newmem;
1936
1937 if ((newmem = realloc ((char *) oldmem, (int) size)) == NULL)
1938 {
1939 fprintf (stderr, "\nCan't reallocate %u bytes\n", size);
1940 exit (1);
1941 }
1942 return (newmem);
1943 }
1944
1945 main (argc, argv)
1946 int argc;
1947 char **argv;
1948 {
1949 char mangled_name[128];
1950 char *result;
1951
1952 if (argc > 1)
1953 {
1954 argc--;
1955 argv++;
1956 while (argc-- > 0)
1957 {
1958 demangle_it (*argv);
1959 }
1960 }
1961 else
1962 {
1963 while (gets (mangled_name))
1964 {
1965 demangle_it (mangled_name);
1966 }
1967 }
1968 }
1969
1970 #endif
This page took 0.084813 seconds and 5 git commands to generate.