1 /* Demangler test program,
2    Copyright (C) 2002 Free Software Foundation, Inc.
3    Written by Zack Weinberg <zack@codesourcery.com
4 
5    This file is part of GNU libiberty.
6 
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11 
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21 
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25 #include "ansidecl.h"
26 #include <stdio.h>
27 #include "libiberty.h"
28 #include "demangle.h"
29 #include <string.h>
30 #include <stdlib.h>
31 
32 struct line
33 {
34   size_t alloced;
35   char *data;
36 };
37 
38 static unsigned int lineno;
39 
40 /* Safely read a single line of arbitrary length from standard input.  */
41 
42 #define LINELEN 80
43 
44 static void
get_line(buf)45 get_line(buf)
46      struct line *buf;
47 {
48   char *data = buf->data;
49   size_t alloc = buf->alloced;
50   size_t count = 0;
51   int c;
52 
53   if (data == 0)
54     {
55       data = xmalloc (LINELEN);
56       alloc = LINELEN;
57     }
58 
59   /* Skip comment lines.  */
60   while ((c = getchar()) == '#')
61     {
62       while ((c = getchar()) != EOF && c != '\n');
63       lineno++;
64     }
65 
66   /* c is the first character on the line, and it's not a comment
67      line: copy this line into the buffer and return.  */
68   while (c != EOF && c != '\n')
69     {
70       if (count + 1 >= alloc)
71 	{
72 	  alloc *= 2;
73 	  data = xrealloc (data, alloc);
74 	}
75       data[count++] = c;
76       c = getchar();
77     }
78   lineno++;
79   data[count] = '\0';
80 
81   buf->data = data;
82   buf->alloced = alloc;
83 }
84 
85 /* The tester operates on a data file consisting of triples of lines:
86    format switch
87    input to be demangled
88    expected output
89 
90    The format switch is expected to be either the empty string, a
91    line of the form --format=<name>, or just <name> by itself.  */
92 
93 #define FORMATS "--format="
94 #define FORMATL (sizeof FORMATS - 1)
95 
96 int
main(argc,argv)97 main(argc, argv)
98      int argc;
99      char **argv;
100 {
101   enum demangling_styles style;
102   struct line format;
103   struct line input;
104   struct line expect;
105   char *fstyle;
106   char *result;
107   int failures = 0;
108   int tests = 0;
109 
110   if (argc > 1)
111     {
112       fprintf (stderr, "usage: %s < test-set\n", argv[0]);
113       return 2;
114     }
115 
116   format.data = 0;
117   input.data = 0;
118   expect.data = 0;
119 
120   for (;;)
121     {
122       get_line (&format);
123       if (feof (stdin))
124 	break;
125 
126       get_line (&input);
127       get_line (&expect);
128 
129       tests++;
130 
131       fstyle = format.data;
132       if (!strncmp (fstyle, FORMATS, FORMATL))
133 	fstyle += FORMATL;
134 
135       if (fstyle[0] == '\0')
136 	style = auto_demangling;
137       else
138 	style = cplus_demangle_name_to_style (fstyle);
139 
140       if (style == unknown_demangling)
141 	{
142 	  printf ("FAIL at line %d: unknown demangling style %s\n",
143 		  lineno, fstyle);
144 	  failures++;
145 	  continue;
146 	}
147 
148       cplus_demangle_set_style (style);
149 
150       result = cplus_demangle (input.data,
151 			       DMGL_PARAMS|DMGL_ANSI|DMGL_VERBOSE|DMGL_TYPES);
152 
153       if (result
154 	  ? strcmp (result, expect.data)
155 	  : strcmp (input.data, expect.data))
156 	{
157 	  printf ("\
158 FAIL at line %d, style %s:\n\
159 in:  %s\n\
160 out: %s\n\
161 exp: %s\n",
162 		   lineno, fstyle,
163 		   input.data,
164 		   result,
165 		   expect.data);
166 	  failures++;
167 	}
168       free (result);
169     }
170 
171   free (format.data);
172   free (input.data);
173   free (expect.data);
174 
175   printf ("%s: %d tests, %d failures\n", argv[0], tests, failures);
176   return failures ? 1 : 0;
177 }
178