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