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