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