1 /* $MirOS: src/gnu/usr.bin/binutils/libiberty/testsuite/test-demangle.c,v 1.2 2005/03/13 16:07:11 tg Exp $ */
2 
3 /* Demangler test program,
4    Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
5    Written by Zack Weinberg <zack@codesourcery.com
6 
7    This file is part of GNU libiberty.
8 
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 2 of the License, or
12    (at your option) any later version.
13 
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 */
23 
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27 #include "ansidecl.h"
28 #include <stdio.h>
29 #include "libiberty.h"
30 #include "demangle.h"
31 #ifdef HAVE_STRING_H
32 #include <string.h>
33 #endif
34 #if HAVE_STDLIB_H
35 # include <stdlib.h>
36 #endif
37 
38 __RCSID("$MirOS: src/gnu/usr.bin/binutils/libiberty/testsuite/test-demangle.c,v 1.2 2005/03/13 16:07:11 tg Exp $");
39 
40 struct line
41 {
42   size_t alloced;
43   char *data;
44 };
45 
46 static unsigned int lineno;
47 
48 /* Safely read a single line of arbitrary length from standard input.  */
49 
50 #define LINELEN 80
51 
52 static void
getline(buf)53 getline(buf)
54      struct line *buf;
55 {
56   char *data = buf->data;
57   size_t alloc = buf->alloced;
58   size_t count = 0;
59   int c;
60 
61   if (data == 0)
62     {
63       data = xmalloc (LINELEN);
64       alloc = LINELEN;
65     }
66 
67   /* Skip comment lines.  */
68   while ((c = getchar()) == '#')
69     {
70       while ((c = getchar()) != EOF && c != '\n');
71       lineno++;
72     }
73 
74   /* c is the first character on the line, and it's not a comment
75      line: copy this line into the buffer and return.  */
76   while (c != EOF && c != '\n')
77     {
78       if (count + 1 >= alloc)
79 	{
80 	  alloc *= 2;
81 	  data = xrealloc (data, alloc);
82 	}
83       data[count++] = c;
84       c = getchar();
85     }
86   lineno++;
87   data[count] = '\0';
88 
89   buf->data = data;
90   buf->alloced = alloc;
91 }
92 
93 static void
fail(lineno,opts,in,out,exp)94 fail (lineno, opts, in, out, exp)
95      int lineno;
96      const char *opts;
97      const char *in;
98      const char *out;
99      const char *exp;
100 {
101   printf ("\
102 FAIL at line %d, options %s:\n\
103 in:  %s\n\
104 out: %s\n\
105 exp: %s\n",
106 	  lineno, opts, in, out != NULL ? out : "(null)", exp);
107 }
108 
109 /* The tester operates on a data file consisting of groups of lines:
110    options
111    input to be demangled
112    expected output
113 
114    Supported options:
115      --format=<name>     Sets the demangling style.
116      --no-params         There are two lines of expected output; the first
117                          is with DMGL_PARAMS, the second is without it.
118      --is-v3-ctor        Calls is_gnu_v3_mangled_ctor on input; expected
119                          output is an integer representing ctor_kind.
120      --is-v3-dtor        Likewise, but for dtors.
121 
122    For compatibility, just in case it matters, the options line may be
123    empty, to mean --format=auto.  If it doesn't start with --, then it
124    may contain only a format name.
125 */
126 
127 int
main(argc,argv)128 main(argc, argv)
129      int argc;
130      char **argv;
131 {
132   enum demangling_styles style = auto_demangling;
133   int no_params;
134   int is_v3_ctor;
135   int is_v3_dtor;
136   struct line format;
137   struct line input;
138   struct line expect;
139   char *result;
140   int failures = 0;
141   int tests = 0;
142 
143   if (argc > 1)
144     {
145       fprintf (stderr, "usage: %s < test-set\n", argv[0]);
146       return 2;
147     }
148 
149   format.data = 0;
150   input.data = 0;
151   expect.data = 0;
152 
153   for (;;)
154     {
155       getline (&format);
156       if (feof (stdin))
157 	break;
158 
159       getline (&input);
160       getline (&expect);
161 
162       tests++;
163 
164       no_params = 0;
165       is_v3_ctor = 0;
166       is_v3_dtor = 0;
167       if (format.data[0] == '\0')
168 	style = auto_demangling;
169       else if (format.data[0] != '-')
170 	{
171 	  style = cplus_demangle_name_to_style (format.data);
172 	  if (style == unknown_demangling)
173 	    {
174 	      printf ("FAIL at line %d: unknown demangling style %s\n",
175 		      lineno, format.data);
176 	      failures++;
177 	      continue;
178 	    }
179 	}
180       else
181 	{
182 	  char *p;
183 	  char *opt;
184 
185 	  p = format.data;
186 	  while (*p != '\0')
187 	    {
188 	      char c;
189 
190 	      opt = p;
191 	      p += strcspn (p, " \t=");
192 	      c = *p;
193 	      *p = '\0';
194 	      if (strcmp (opt, "--format") == 0 && c == '=')
195 		{
196 		  char *fstyle;
197 
198 		  *p = c;
199 		  ++p;
200 		  fstyle = p;
201 		  p += strcspn (p, " \t");
202 		  c = *p;
203 		  *p = '\0';
204 		  style = cplus_demangle_name_to_style (fstyle);
205 		  if (style == unknown_demangling)
206 		    {
207 		      printf ("FAIL at line %d: unknown demangling style %s\n",
208 			      lineno, fstyle);
209 		      failures++;
210 		      continue;
211 		    }
212 		}
213 	      else if (strcmp (opt, "--no-params") == 0)
214 		no_params = 1;
215 	      else if (strcmp (opt, "--is-v3-ctor") == 0)
216 		is_v3_ctor = 1;
217 	      else if (strcmp (opt, "--is-v3-dtor") == 0)
218 		is_v3_dtor = 1;
219 	      else
220 		{
221 		  printf ("FAIL at line %d: unrecognized option %s\n",
222 			  lineno, opt);
223 		  failures++;
224 		  continue;
225 		}
226 	      *p = c;
227 	      p += strspn (p, " \t");
228 	    }
229 	}
230 
231       if (is_v3_ctor || is_v3_dtor)
232 	{
233 	  char buf[20];
234 
235 	  if (is_v3_ctor)
236 	    {
237 	      enum gnu_v3_ctor_kinds kc;
238 
239 	      kc = is_gnu_v3_mangled_ctor (input.data);
240 	      snprintf (buf, 20, "%d", (int) kc);
241 	    }
242 	  else
243 	    {
244 	      enum gnu_v3_dtor_kinds kd;
245 
246 	      kd = is_gnu_v3_mangled_dtor (input.data);
247 	      snprintf (buf, 20, "%d", (int) kd);
248 	    }
249 
250 	  if (strcmp (buf, expect.data) != 0)
251 	    {
252 	      fail (lineno, format.data, input.data, buf, expect.data);
253 	      failures++;
254 	    }
255 
256 	  continue;
257 	}
258 
259       cplus_demangle_set_style (style);
260 
261       result = cplus_demangle (input.data,
262 			       DMGL_PARAMS|DMGL_ANSI|DMGL_TYPES);
263 
264       if (result
265 	  ? strcmp (result, expect.data)
266 	  : strcmp (input.data, expect.data))
267 	{
268 	  fail (lineno, format.data, input.data, result, expect.data);
269 	  failures++;
270 	}
271       free (result);
272 
273       if (no_params)
274 	{
275 	  getline (&expect);
276 	  result = cplus_demangle (input.data, DMGL_ANSI|DMGL_TYPES);
277 
278 	  if (result
279 	      ? strcmp (result, expect.data)
280 	      : strcmp (input.data, expect.data))
281 	    {
282 	      fail (lineno, format.data, input.data, result, expect.data);
283 	      failures++;
284 	    }
285 	  free (result);
286 	}
287     }
288 
289   free (format.data);
290   free (input.data);
291   free (expect.data);
292 
293   printf ("%s: %d tests, %d failures\n", argv[0], tests, failures);
294   return failures ? 1 : 0;
295 }
296