This is a test to see if the file is still locked.
[deliverable/binutils-gdb.git] / ld / cplus-dem.c
CommitLineData
d2861901
SC
1/* Demangler for GNU C++
2 Copyright 1989, 1991 Free Software Foundation, Inc.
9aa97a39 3 written by James Clark (jjc@jclark.uucp)
d2861901
SC
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2, or (at your option)
8 any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
18
19/* This is for g++ 1.95.03 (November 13 verison). */
20
21/* This file exports one function
22
23 char *cplus_demangle (const char *name, int mode)
24
25 If NAME is a mangled function name produced by GNU C++, then
26 a pointer to a malloced string giving a C++ representation
27 of the name will be returned; otherwise NULL will be returned.
28 It is the caller's responsibility to free the string which
29 is returned.
30
31 If MODE > 0, then ANSI qualifiers such as `const' and `void' are output.
32 Otherwise they are not.
33 If MODE >= 0, parameters are emitted; otherwise not.
34
35 For example,
36
37 cplus_demangle ("foo__1Ai", 0) => "A::foo(int)"
38 cplus_demangle ("foo__1Ai", 1) => "A::foo(int)"
39 cplus_demangle ("foo__1Ai", -1) => "A::foo"
40
41 cplus_demangle ("foo__1Afe", 0) => "A::foo(float,...)"
42 cplus_demangle ("foo__1Afe", 1) => "A::foo(float,...)"
43 cplus_demangle ("foo__1Afe", -1) => "A::foo"
44
45 This file imports xmalloc and xrealloc, which are like malloc and
46 realloc except that they generate a fatal error if there is no
47 available memory. */
48
49/* define this if names don't start with _ */
9aa97a39
SC
50/* #define nounderscore 1 */
51#include <ansidecl.h>
d2861901 52#include <sysdep.h>
9aa97a39 53
d2861901 54#define xmalloc ldmalloc
9aa97a39
SC
55#define xrealloc ldrealloc
56
57#if 0
58/* GDB-specific, FIXME. */
59#include "defs.h"
60#endif
61
62
63
64#define PARAMS(x) EXFUN(,x)
d2861901
SC
65
66/* This is '$' on systems where the assembler can deal with that.
67 Where the assembler can't, it's '.' (but on many systems '.' is
68 used for other things). */
69#if !defined (CPLUS_MARKER)
70#define CPLUS_MARKER '$'
71#endif
72
73#ifndef __STDC__
74#define const
75#endif
76
77#ifdef __STDC__
78extern char *cplus_demangle (const char *type, int mode);
79#else
80extern char *cplus_demangle ();
81#endif
82
83
84static char **typevec = 0;
85static int ntypes = 0;
86static int typevec_size = 0;
87
88const static struct optable {
89 const char *in;
90 const char *out;
91 int ansi;
92} optable[] = {
93 "nw", " new", 1, /* new (1.92, ansi) */
94 "dl", " delete", 1, /* new (1.92, ansi) */
95 "new", " new", 0, /* old (1.91, and 1.x) */
96 "delete", " delete", 0, /* old (1.91, and 1.x) */
97 "as", "=", 1, /* ansi */
98 "ne", "!=", 1, /* old, ansi */
99 "eq", "==", 1, /* old, ansi */
100 "ge", ">=", 1, /* old, ansi */
101 "gt", ">", 1, /* old, ansi */
102 "le", "<=", 1, /* old, ansi */
103 "lt", "<", 1, /* old, ansi */
104 "plus", "+", 0, /* old */
105 "pl", "+", 1, /* ansi */
106 "apl", "+=", 1, /* ansi */
107 "minus", "-", 0, /* old */
108 "mi", "-", 1, /* ansi */
109 "ami", "-=", 1, /* ansi */
110 "mult", "*", 0, /* old */
111 "ml", "*", 1, /* ansi */
112 "aml", "*=", 1, /* ansi */
113 "convert", "+", 0, /* old (unary +) */
114 "negate", "-", 0, /* old (unary -) */
115 "trunc_mod", "%", 0, /* old */
116 "md", "%", 1, /* ansi */
117 "amd", "%=", 1, /* ansi */
118 "trunc_div", "/", 0, /* old */
119 "dv", "/", 1, /* ansi */
120 "adv", "/=", 1, /* ansi */
121 "truth_andif", "&&", 0, /* old */
122 "aa", "&&", 1, /* ansi */
123 "truth_orif", "||", 0, /* old */
124 "oo", "||", 1, /* ansi */
125 "truth_not", "!", 0, /* old */
126 "nt", "!", 1, /* ansi */
127 "postincrement", "++", 0, /* old */
128 "pp", "++", 1, /* ansi */
129 "postdecrement", "--", 0, /* old */
130 "mm", "--", 1, /* ansi */
131 "bit_ior", "|", 0, /* old */
132 "or", "|", 1, /* ansi */
133 "aor", "|=", 1, /* ansi */
134 "bit_xor", "^", 0, /* old */
135 "er", "^", 1, /* ansi */
136 "aer", "^=", 1, /* ansi */
137 "bit_and", "&", 0, /* old */
138 "ad", "&", 1, /* ansi */
139 "aad", "&=", 1, /* ansi */
140 "bit_not", "~", 0, /* old */
141 "co", "~", 1, /* ansi */
142 "call", "()", 0, /* old */
143 "cl", "()", 1, /* ansi */
144 "alshift", "<<", 0, /* old */
145 "ls", "<<", 1, /* ansi */
146 "als", "<<=", 1, /* ansi */
147 "arshift", ">>", 0, /* old */
148 "rs", ">>", 1, /* ansi */
149 "ars", ">>=", 1, /* ansi */
150 "component", "->", 0, /* old */
151 "rf", "->", 1, /* ansi */
152 "indirect", "*", 0, /* old */
153 "method_call", "->()", 0, /* old */
154 "addr", "&", 0, /* old (unary &) */
155 "array", "[]", 0, /* old */
156 "vc", "[]", 1, /* ansi */
157 "compound", ",", 0, /* old */
158 "cm", ",", 1, /* ansi */
159 "cond", "?:", 0, /* old */
160 "cn", "?:", 1, /* psuedo-ansi */
161 "max", ">?", 0, /* old */
162 "mx", ">?", 1, /* psuedo-ansi */
163 "min", "<?", 0, /* old */
164 "mn", "<?", 1, /* psuedo-ansi */
165 "nop", "", 0, /* old (for operator=) */
166};
167
168/* Beware: these aren't '\0' terminated. */
169
170typedef struct string {
171 char *b; /* pointer to start of string */
172 char *p; /* pointer after last character */
173 char *e; /* pointer after end of allocated space */
174} string;
175
d2861901
SC
176static void
177string_need PARAMS ((string *, int));
178
179static void
180string_delete PARAMS ((string *));
181
182static void
183string_init PARAMS ((string *));
184
185static void
186string_clear PARAMS ((string *));
187
188static int
189string_empty PARAMS ((string *));
190
191static void
192string_append PARAMS ((string *, const char *));
193
194static void
195string_appends PARAMS ((string *, string *));
196
197static void
198string_appendn PARAMS ((string *, const char *, int));
199
200static void
201string_prepend PARAMS ((string *, const char *));
202
203static void
204string_prependn PARAMS ((string *, const char *, int));
205
206static int
207get_count PARAMS ((const char **, int *));
208
209static int
210do_args PARAMS ((const char **, string *, int));
211
212static int
213do_type PARAMS ((const char **, string *, int));
214
215static int
216do_arg PARAMS ((const char **, string *, int));
217
218static void
219munge_function_name PARAMS ((string *, int));
220
221static void
222remember_type PARAMS ((const char *, int));
223
224#if 0
225static void
226string_prepends PARAMS ((string *, string *));
227#endif
228
229
230/* Takes operator name as e.g. "++" and returns mangled
231 operator name (e.g. "postincrement_expr"), or NULL if not found.
232
233 If ARG_MODE == 1, return the ANSI name;
234 if ARG_MODE == 0 return the old GNU name. */
235char *
236cplus_mangle_opname (opname, arg_mode)
237 char *opname;
238 int arg_mode;
239{
240 int i, len = strlen (opname);
241
9aa97a39
SC
242 if (arg_mode != 0 && arg_mode != 1)
243 einfo ("%P%F: invalid arg_mode");
d2861901
SC
244
245 for (i = 0; i < sizeof (optable)/sizeof (optable[0]); i++)
246 {
247 if (strlen (optable[i].out) == len
248 && arg_mode == optable[i].ansi
249 && memcmp (optable[i].out, opname, len) == 0)
250 return (char *)optable[i].in;
251 }
252 return 0;
253}
254
255char *
256cplus_demangle (type, arg_mode)
257 const char *type;
258 int arg_mode;
259{
260 string decl;
261 int n;
262 int success = 0;
263 int constructor = 0;
264 int destructor = 0;
265 int static_type = 0;
266 int const_flag = 0;
267 int i;
268 const char *p;
269#ifndef LONGERNAMES
270 const char *premangle;
271#endif
272
273# define print_ansi_qualifiers (arg_mode > 0)
274# define print_arg_types (arg_mode >= 0)
275
276 if (type == NULL || *type == '\0')
277 return NULL;
278#ifndef nounderscore
279 if (*type++ != '_')
280 return NULL;
281#endif
282 p = type;
283 while (*p != '\0' && !(*p == '_' && p[1] == '_'))
284 p++;
285 if (*p == '\0')
286 {
287 /* destructor */
288 if (type[0] == '_' && type[1] == CPLUS_MARKER && type[2] == '_')
289 {
290 int n;
291 char *tem;
292
293 type += 3; /* Get past _$_ at front. */
294 while (isdigit (*type))
295 /* If there are digits at the front, it's because
296 of new 2.0 name mangling. Just skip them. */
297 type++;
298
299 n = strlen (type)*2 + 3 + 2 + 1;
300 tem = (char *) xmalloc (n);
301 strcpy (tem, type);
302 strcat (tem, "::~");
303 strcat (tem, type);
304 if (print_arg_types)
305 strcat (tem, "()");
306 return tem;
307 }
308 /* static data member */
309 if (*type != '_' && (p = strchr (type, CPLUS_MARKER)) != NULL)
310 {
311 int n = strlen (type) + 2;
312 char *tem = (char *) xmalloc (n);
313 memcpy (tem, type, p - type);
314 strcpy (tem + (p - type), "::");
315 strcpy (tem + (p - type) + 2, p + 1);
316 return tem;
317 }
318 /* virtual table "_vt$" */
319 if (type[0] == '_' && type[1] == 'v' && type[2] == 't' && type[3] == CPLUS_MARKER)
320 {
321 int n = strlen (type + 4) + 14 + 1;
322 char *tem = (char *) xmalloc (n);
323 strcpy (tem, type + 4);
324 strcat (tem, " virtual table");
325 return tem;
326 }
327 return NULL;
328 }
329
330 string_init (&decl);
331
332 if (static_type)
333 {
334 if (!isdigit (p[0]) && ('t' != p[0]))
335 {
336 string_delete (&decl);
337 return NULL;
338 }
339 }
340 else if (p == type)
341 {
342 if (!isdigit (p[2]) && ('t' != p[2]))
343 {
344 p += 1;
345 while (*p != '\0' && !(*p == '_' && p[1] == '_'))
346 p++;
347 string_appendn (&decl, type, p - type);
348 string_need (&decl, 1);
349 *(decl.p) = '\0';
350 munge_function_name (&decl, 1);
351 if (decl.b[0] == '_')
352 {
353 string_delete (&decl);
354 return NULL;
355 }
356 else
357 p += 2;
358 }
359 else
360 {
361 constructor = 1;
362 p += 2;
363 }
364 }
365 else
366 {
367 string_appendn (&decl, type, p - type);
368 string_need (&decl, 1);
369 *(decl.p) = '\0';
370 munge_function_name (&decl, arg_mode);
371 p += 2;
372 }
373
374#ifndef LONGERNAMES
375 premangle = p;
376#endif
377 switch (*p)
378 {
379 case 'C':
380 /* a const member function */
381 if (!isdigit (p[1]))
382 {
383 string_delete (&decl);
384 return NULL;
385 }
386 p += 1;
387 const_flag = 1;
388 /* fall through */
389 case '0':
390 case '1':
391 case '2':
392 case '3':
393 case '4':
394 case '5':
395 case '6':
396 case '7':
397 case '8':
398 case '9':
399 n = 0;
400 do
401 {
402 n *= 10;
403 n += *p - '0';
404 p += 1;
405 }
406 while (isdigit (*p));
407 if (strlen (p) < n)
408 {
409 string_delete (&decl);
410 return NULL;
411 }
412 if (constructor || destructor)
413 {
414 string_appendn (&decl, p, n);
415 string_append (&decl, "::");
416 if (destructor)
417 string_append(&decl, "~");
418 string_appendn (&decl, p, n);
419 }
420 else
421 {
422 string_prepend (&decl, "::");
423 string_prependn (&decl, p, n);
424 }
425 p += n;
426#ifndef LONGERNAMES
427 remember_type (premangle, p - premangle);
428#endif
429 if (static_type)
430 {
431 string_append(&decl, p+1);
432 p += strlen(p);
433 success = 1;
434 }
435 else
436 success = do_args (&p, &decl, arg_mode);
437 if (const_flag && print_arg_types)
438 string_append (&decl, " const");
439 break;
440 case 'F':
441 p += 1;
442 success = do_args (&p, &decl, arg_mode);
443 break;
444 /* template additions */
445 case 't':
446 p += 1;
447 {
448 int r, i;
449 int non_empty = 0;
450 string tname;
451 string trawname;
452
453 string temp;
454 int need_comma = 0;
455
456 string_init(&tname);
457 string_init(&trawname);
458
459 /* get template name */
460 if (!get_count (&p, &r))
461 return 0;
462 string_appendn (&tname, p, r);
463 string_appendn (&trawname, p, r);
464 string_appendn (&trawname, "", 1);
465 p += r;
466 string_append (&tname, "<");
467 /* get size of template parameter list */
468 if (!get_count (&p, &r))
469 return 0;
470 for (i = 0; i < r; i++)
471 {
472 if (need_comma)
473 string_append (&tname, ", ");
474 /* Z for type parameters */
475 if (*p == 'Z')
476 {
477 p += 1;
478
479 success = do_type (&p, &temp, arg_mode);
480 string_appendn (&temp, "", 1);
481 if (success)
482 string_append (&tname, temp.b);
483 string_delete(&temp);
484 if (!success)
485 break;
486 }
487 /* otherwise, value parameter */
488 else
489 {
490 const char *old_p = p;
491 int is_pointer = 0;
492 int is_real = 0;
493 int is_integral = 0;
494 int done = 0;
495
496 success = do_type (&p, &temp, arg_mode);
497 string_appendn (&temp, "", 1);
498 if (success)
499 string_append (&tname, temp.b);
500 string_delete(&temp);
501 if (!success)
502 break;
503 string_append (&tname, "=");
504 while (*old_p && !done)
505 {
506 switch (*old_p)
507 {
508 case 'P':
509 case 'R':
510 done = is_pointer = 1;
511 break;
512 case 'C': /* const */
513 case 'U': /* unsigned */
514 case 'V': /* volatile */
515 case 'F': /* function */
516 case 'M': /* member function */
517 case 'O': /* ??? */
518 old_p++;
519 continue;
520 case 'Q': /* repetition of following */
521 case 'T': /* remembered type */
522 abort();
523 break;
524 case 'v': /* void */
525 abort();
526 break;
527 case 'x': /* long long */
528 case 'l': /* long */
529 case 'i': /* int */
530 case 's': /* short */
531 case 'c': /* char */
532 done = is_integral = 1;
533 break;
534 case 'r': /* long double */
535 case 'd': /* double */
536 case 'f': /* float */
537 done = is_real = 1;
538 break;
539 default:
540 abort();
541 }
542 }
543 if (is_integral)
544 {
545 if (*p == 'm')
546 {
547 string_appendn (&tname, "-", 1);
548 p++;
549 }
550 while (isdigit (*p))
551 {
552 string_appendn (&tname, p, 1);
553 p++;
554 }
555 }
556 else if (is_real)
557 {
558 if (*p == 'm')
559 {
560 string_appendn (&tname, "-", 1);
561 p++;
562 }
563 while (isdigit (*p))
564 {
565 string_appendn (&tname, p, 1);
566 p++;
567 }
568 if (*p == '.') /* fraction */
569 {
570 string_appendn (&tname, ".", 1);
571 p++;
572 while (isdigit (*p))
573 {
574 string_appendn (&tname, p, 1);
575 p++;
576 }
577 }
578 if (*p == 'e') /* exponent */
579 {
580 string_appendn (&tname, "e", 1);
581 p++;
582 while (isdigit (*p))
583 {
584 string_appendn (&tname, p, 1);
585 p++;
586 }
587 }
588 }
589 else if (is_pointer)
590 {
591 int symbol_len;
592
593 if (!get_count (&p, &symbol_len))
594 {
595 success = 0;
596 break;
597 }
598 string_appendn (&tname, p, symbol_len);
599 p += symbol_len;
600 }
601 }
602 need_comma = 1;
603 }
604 string_append (&tname, ">::");
605 if (destructor)
606 string_append(&tname, "~");
607 if (constructor || destructor) {
608 string_append (&tname, trawname.b);
609 }
610 string_delete(&trawname);
611
612 if (!success) {
613 string_delete(&tname);
614 return 0;
615 }
616 string_prepend (&decl, tname.b);
617 string_delete(&tname);
618
619 if (static_type)
620 {
621 string_append(&decl, p+1);
622 p += strlen(p);
623 success = 1;
624 }
625 else
626 success = do_args (&p, &decl, arg_mode);
627 break;
628 }
629 }
630
631 for (i = 0; i < ntypes; i++)
632 if (typevec[i] != NULL)
633 free (typevec[i]);
634 ntypes = 0;
635 if (typevec != NULL)
636 {
637 free ((char *)typevec);
638 typevec = NULL;
639 typevec_size = 0;
640 }
641
642 if (success)
643 {
644 string_appendn (&decl, "", 1);
645 return decl.b;
646 }
647 else
648 {
649 string_delete (&decl);
650 return NULL;
651 }
652}
653
654static int
655get_count (type, count)
656 const char **type;
657 int *count;
658{
659 if (!isdigit (**type))
660 return 0;
661 *count = **type - '0';
662 *type += 1;
663 /* see flush_repeats in cplus-method.c */
664 if (isdigit (**type))
665 {
666 const char *p = *type;
667 int n = *count;
668 do
669 {
670 n *= 10;
671 n += *p - '0';
672 p += 1;
673 }
674 while (isdigit (*p));
675 if (*p == '_')
676 {
677 *type = p + 1;
678 *count = n;
679 }
680 }
681 return 1;
682}
683
684/* result will be initialised here; it will be freed on failure */
685
686static int
687do_type (type, result, arg_mode)
688 const char **type;
689 string *result;
690 int arg_mode;
691{
692 int n;
693 int done;
694 int non_empty = 0;
695 int success;
696 string decl;
697 const char *remembered_type;
698
699 string_init (&decl);
700 string_init (result);
701
702 done = 0;
703 success = 1;
704 while (success && !done)
705 {
706 int member;
707 switch (**type)
708 {
709 case 'Q':
710 n = (*type)[1] - '0';
711 if (n < 0 || n > 9)
712 success = 0;
713 *type += 2;
714 while (n-- > 0)
715 do_type (type, result, arg_mode);
716 break;
717
718 case 'P':
719 *type += 1;
720 string_prepend (&decl, "*");
721 break;
722
723 case 'R':
724 *type += 1;
725 string_prepend (&decl, "&");
726 break;
727
728 case 'T':
729 *type += 1;
730 if (!get_count (type, &n) || n >= ntypes)
731 success = 0;
732 else
733 {
734 remembered_type = typevec[n];
735 type = &remembered_type;
736 }
737 break;
738
739 case 'F':
740 *type += 1;
741 if (!string_empty (&decl) && decl.b[0] == '*')
742 {
743 string_prepend (&decl, "(");
744 string_append (&decl, ")");
745 }
746 if (!do_args (type, &decl, arg_mode) || **type != '_')
747 success = 0;
748 else
749 *type += 1;
750 break;
751
752 case 'M':
753 case 'O':
754 {
755 int constp = 0;
756 int volatilep = 0;
757
758 member = **type == 'M';
759 *type += 1;
760 if (!isdigit (**type))
761 {
762 success = 0;
763 break;
764 }
765 n = 0;
766 do
767 {
768 n *= 10;
769 n += **type - '0';
770 *type += 1;
771 }
772 while (isdigit (**type));
773 if (strlen (*type) < n)
774 {
775 success = 0;
776 break;
777 }
778 string_append (&decl, ")");
779 string_prepend (&decl, "::");
780 string_prependn (&decl, *type, n);
781 string_prepend (&decl, "(");
782 *type += n;
783 if (member)
784 {
785 if (**type == 'C')
786 {
787 *type += 1;
788 constp = 1;
789 }
790 if (**type == 'V')
791 {
792 *type += 1;
793 volatilep = 1;
794 }
795 if (*(*type)++ != 'F')
796 {
797 success = 0;
798 break;
799 }
800 }
801 if ((member && !do_args (type, &decl, arg_mode)) || **type != '_')
802 {
803 success = 0;
804 break;
805 }
806 *type += 1;
807 if (! print_ansi_qualifiers)
808 break;
809 if (constp)
810 {
811 if (non_empty)
812 string_append (&decl, " ");
813 else
814 non_empty = 1;
815 string_append (&decl, "const");
816 }
817 if (volatilep)
818 {
819 if (non_empty)
820 string_append (&decl, " ");
821 else
822 non_empty = 1;
823 string_append (&decl, "volatile");
824 }
825 break;
826 }
827
828 case 'C':
829 if ((*type)[1] == 'P')
830 {
831 *type += 1;
832 if (print_ansi_qualifiers)
833 {
834 if (!string_empty (&decl))
835 string_prepend (&decl, " ");
836 string_prepend (&decl, "const");
837 }
838 break;
839 }
840
841 /* fall through */
842 default:
843 done = 1;
844 break;
845 }
846 }
847
848 done = 0;
849 non_empty = 0;
850 while (success && !done)
851 {
852 switch (**type)
853 {
854 case 'C':
855 *type += 1;
856 if (print_ansi_qualifiers)
857 {
858 if (non_empty)
859 string_append (result, " ");
860 else
861 non_empty = 1;
862 string_append (result, "const");
863 }
864 break;
865 case 'U':
866 *type += 1;
867 if (non_empty)
868 string_append (result, " ");
869 else
870 non_empty = 1;
871 string_append (result, "unsigned");
872 break;
873 case 'V':
874 *type += 1;
875 if (print_ansi_qualifiers)
876 {
877 if (non_empty)
878 string_append (result, " ");
879 else
880 non_empty = 1;
881 string_append (result, "volatile");
882 }
883 break;
884 default:
885 done = 1;
886 break;
887 }
888 }
889
890 if (success)
891 switch (**type)
892 {
893 case '\0':
894 case '_':
895 break;
896 case 'v':
897 *type += 1;
898 if (non_empty)
899 string_append (result, " ");
900 string_append (result, "void");
901 break;
902 case 'x':
903 *type += 1;
904 if (non_empty)
905 string_append (result, " ");
906 string_append (result, "long long");
907 break;
908 case 'l':
909 *type += 1;
910 if (non_empty)
911 string_append (result, " ");
912 string_append (result, "long");
913 break;
914 case 'i':
915 *type += 1;
916 if (non_empty)
917 string_append (result, " ");
918 string_append (result, "int");
919 break;
920 case 's':
921 *type += 1;
922 if (non_empty)
923 string_append (result, " ");
924 string_append (result, "short");
925 break;
926 case 'c':
927 *type += 1;
928 if (non_empty)
929 string_append (result, " ");
930 string_append (result, "char");
931 break;
932 case 'r':
933 *type += 1;
934 if (non_empty)
935 string_append (result, " ");
936 string_append (result, "long double");
937 break;
938 case 'd':
939 *type += 1;
940 if (non_empty)
941 string_append (result, " ");
942 string_append (result, "double");
943 break;
944 case 'f':
945 *type += 1;
946 if (non_empty)
947 string_append (result, " ");
948 string_append (result, "float");
949 break;
950 case 'G':
951 *type += 1;
952 if (!isdigit (**type))
953 {
954 success = 0;
955 break;
956 }
957 /* fall through */
958 case '0':
959 case '1':
960 case '2':
961 case '3':
962 case '4':
963 case '5':
964 case '6':
965 case '7':
966 case '8':
967 case '9':
968 n = 0;
969 do
970 {
971 n *= 10;
972 n += **type - '0';
973 *type += 1;
974 }
975 while (isdigit (**type));
976 if (strlen (*type) < n)
977 {
978 success = 0;
979 break;
980 }
981 if (non_empty)
982 string_append (result, " ");
983 string_appendn (result, *type, n);
984 *type += n;
985 break;
986 default:
987 success = 0;
988 break;
989 }
990
991 if (success)
992 {
993 if (!string_empty (&decl))
994 {
995 string_append (result, " ");
996 string_appends (result, &decl);
997 }
998 string_delete (&decl);
999 return 1;
1000 }
1001 else
1002 {
1003 string_delete (&decl);
1004 string_delete (result);
1005 return 0;
1006 }
1007}
1008
1009/* `result' will be initialised in do_type; it will be freed on failure */
1010
1011static int
1012do_arg (type, result, arg_mode)
1013 const char **type;
1014 string *result;
1015 int arg_mode;
1016{
1017 const char *start = *type;
1018
1019 if (!do_type (type, result, arg_mode))
1020 return 0;
1021 remember_type (start, *type - start);
1022 return 1;
1023}
1024
1025static void
1026remember_type (start, len)
1027 const char *start;
1028 int len;
1029{
1030 char *tem;
1031
1032 if (ntypes >= typevec_size)
1033 {
1034 if (typevec_size == 0)
1035 {
1036 typevec_size = 3;
1037 typevec = (char **) xmalloc (sizeof (char*)*typevec_size);
1038 }
1039 else
1040 {
1041 typevec_size *= 2;
1042 typevec = (char **) xrealloc ((char *)typevec, sizeof (char*)*typevec_size);
1043 }
1044 }
1045 tem = (char *) xmalloc (len + 1);
1046 memcpy (tem, start, len);
1047 tem[len] = '\0';
1048 typevec[ntypes++] = tem;
1049}
1050
1051/* `decl' must be already initialised, usually non-empty;
1052 it won't be freed on failure */
1053
1054static int
1055do_args (type, decl, arg_mode)
1056 const char **type;
1057 string *decl;
1058 int arg_mode;
1059{
1060 string arg;
1061 int need_comma = 0;
1062
1063 if (print_arg_types)
1064 string_append (decl, "(");
1065
1066 while (**type != '_' && **type != '\0' && **type != 'e' && **type != 'v')
1067 {
1068 if (**type == 'N')
1069 {
1070 int r;
1071 int t;
1072 *type += 1;
1073 if (!get_count (type, &r) || !get_count (type, &t) || t >= ntypes)
1074 return 0;
1075 while (--r >= 0)
1076 {
1077 const char *tem = typevec[t];
1078 if (need_comma && print_arg_types)
1079 string_append (decl, ", ");
1080 if (!do_arg (&tem, &arg, arg_mode))
1081 return 0;
1082 if (print_arg_types)
1083 string_appends (decl, &arg);
1084 string_delete (&arg);
1085 need_comma = 1;
1086 }
1087 }
1088 else
1089 {
1090 if (need_comma & print_arg_types)
1091 string_append (decl, ", ");
1092 if (!do_arg (type, &arg, arg_mode))
1093 return 0;
1094 if (print_arg_types)
1095 string_appends (decl, &arg);
1096 string_delete (&arg);
1097 need_comma = 1;
1098 }
1099 }
1100
1101 if (**type == 'v')
1102 *type += 1;
1103 else if (**type == 'e')
1104 {
1105 *type += 1;
1106 if (print_arg_types)
1107 {
1108 if (need_comma)
1109 string_append (decl, ",");
1110 string_append (decl, "...");
1111 }
1112 }
1113
1114 if (print_arg_types)
1115 string_append (decl, ")");
1116 return 1;
1117}
1118
1119static void
1120munge_function_name (name, arg_mode)
1121 string *name;
1122 int arg_mode;
1123{
1124 if (string_empty (name))
1125 return;
1126
1127 if (name->p - name->b >= 3
1128 && name->b[0] == 'o' && name->b[1] == 'p' && name->b[2] == CPLUS_MARKER)
1129 {
1130 int i;
1131 /* see if it's an assignment expression */
1132 if (name->p - name->b >= 10 /* op$assign_ */
1133 && memcmp (name->b + 3, "assign_", 7) == 0)
1134 {
1135 for (i = 0; i < sizeof (optable)/sizeof (optable[0]); i++)
1136 {
1137 int len = name->p - name->b - 10;
1138 if (strlen (optable[i].in) == len
1139 && memcmp (optable[i].in, name->b + 10, len) == 0)
1140 {
1141 string_clear (name);
1142 string_append (name, "operator");
1143 string_append (name, optable[i].out);
1144 string_append (name, "=");
1145 return;
1146 }
1147 }
1148 }
1149 else
1150 {
1151 for (i = 0; i < sizeof (optable)/sizeof (optable[0]); i++)
1152 {
1153 int len = name->p - name->b - 3;
1154 if (strlen (optable[i].in) == len
1155 && memcmp (optable[i].in, name->b + 3, len) == 0)
1156 {
1157 string_clear (name);
1158 string_append (name, "operator");
1159 string_append (name, optable[i].out);
1160 return;
1161 }
1162 }
1163 }
1164 return;
1165 }
1166 else if (name->p - name->b >= 5 && memcmp (name->b, "type$", 5) == 0)
1167 {
1168 /* type conversion operator */
1169 string type;
1170 const char *tem = name->b + 5;
1171 if (do_type (&tem, &type, arg_mode))
1172 {
1173 string_clear (name);
1174 string_append (name, "operator ");
1175 string_appends (name, &type);
1176 string_delete (&type);
1177 return;
1178 }
1179 }
1180 /* ANSI. */
1181 else if (name->b[2] == 'o' && name->b[3] == 'p')
1182 {
1183 /* type conversion operator. */
1184 string type;
1185 const char *tem = name->b + 4;
1186 if (do_type (&tem, &type, arg_mode))
1187 {
1188 string_clear (name);
1189 string_append (name, "operator ");
1190 string_appends (name, &type);
1191 string_delete (&type);
1192 return;
1193 }
1194 }
1195 else if (name->b[0] == '_' && name->b[1] == '_'
1196 && name->b[2] >= 'a' && name->b[2] <= 'z'
1197 && name->b[3] >= 'a' && name->b[3] <= 'z')
1198 {
1199 int i;
1200
1201 if (name->b[4] == '\0')
1202 {
1203 /* Operator. */
1204 for (i = 0; i < sizeof (optable)/sizeof (optable[0]); i++)
1205 {
1206 if (strlen (optable[i].in) == 2
1207 && memcmp (optable[i].in, name->b + 2, 2) == 0)
1208 {
1209 string_clear (name);
1210 string_append (name, "operator");
1211 string_append (name, optable[i].out);
1212 return;
1213 }
1214 }
1215 }
1216 else
1217 {
1218 if (name->b[2] != 'a' || name->b[5] != '\0')
1219 return;
1220 /* Assignment. */
1221 for (i = 0; i < sizeof (optable)/sizeof (optable[0]); i++)
1222 {
1223 if (strlen (optable[i].in) == 3
1224 && memcmp (optable[i].in, name->b + 2, 3) == 0)
1225 {
1226 string_clear (name);
1227 string_append (name, "operator");
1228 string_append (name, optable[i].out);
1229 return;
1230 }
1231 }
1232 }
1233 }
1234}
1235
1236/* a mini string-handling package */
1237
1238static void
1239string_need (s, n)
1240 string *s;
1241 int n;
1242{
1243 if (s->b == NULL)
1244 {
1245 if (n < 32)
1246 n = 32;
1247 s->p = s->b = (char *) xmalloc (n);
1248 s->e = s->b + n;
1249 }
1250 else if (s->e - s->p < n)
1251 {
1252 int tem = s->p - s->b;
1253 n += tem;
1254 n *= 2;
1255 s->b = (char *) xrealloc (s->b, n);
1256 s->p = s->b + tem;
1257 s->e = s->b + n;
1258 }
1259}
1260
1261static void
1262string_delete (s)
1263 string *s;
1264{
1265 if (s->b != NULL)
1266 {
1267 free (s->b);
1268 s->b = s->e = s->p = NULL;
1269 }
1270}
1271
1272static void
1273string_init (s)
1274 string *s;
1275{
1276 s->b = s->p = s->e = NULL;
1277}
1278
1279static void
1280string_clear (s)
1281 string *s;
1282{
1283 s->p = s->b;
1284}
1285
1286static int
1287string_empty (s)
1288 string *s;
1289{
1290 return s->b == s->p;
1291}
1292
1293static void
1294string_append (p, s)
1295 string *p;
1296 const char *s;
1297{
1298 int n;
1299 if (s == NULL || *s == '\0')
1300 return;
1301 n = strlen (s);
1302 string_need (p, n);
1303 memcpy (p->p, s, n);
1304 p->p += n;
1305}
1306
1307static void
1308string_appends (p, s)
1309 string *p, *s;
1310{
1311 int n;
1312 if (s->b == s->p)
1313 return;
1314 n = s->p - s->b;
1315 string_need (p, n);
1316 memcpy (p->p, s->b, n);
1317 p->p += n;
1318}
1319
1320static void
1321string_appendn (p, s, n)
1322 string *p;
1323 const char *s;
1324 int n;
1325{
1326 if (n == 0)
1327 return;
1328 string_need (p, n);
1329 memcpy (p->p, s, n);
1330 p->p += n;
1331}
1332
1333static void
1334string_prepend (p, s)
1335 string *p;
1336 const char *s;
1337{
1338 if (s == NULL || *s == '\0')
1339 return;
1340 string_prependn (p, s, strlen (s));
1341}
1342
1343#if 0
1344static void
1345string_prepends (p, s)
1346 string *p, *s;
1347{
1348 if (s->b == s->p)
1349 return;
1350 string_prependn (p, s->b, s->p - s->b);
1351}
1352#endif
1353
1354static void
1355string_prependn (p, s, n)
1356 string *p;
1357 const char *s;
1358 int n;
1359{
1360 char *q;
1361
1362 if (n == 0)
1363 return;
1364 string_need (p, n);
1365 for (q = p->p - 1; q >= p->b; q--)
1366 q[n] = q[0];
1367 memcpy (p->b, s, n);
1368 p->p += n;
1369}
This page took 0.077472 seconds and 4 git commands to generate.