1/* Demangler test program, 2 Copyright (C) 2002, 2003, 2004 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#ifdef HAVE_STRING_H 30#include <string.h> 31#endif 32#if HAVE_STDLIB_H 33# include <stdlib.h> 34#endif 35 36struct line 37{ 38 size_t alloced; 39 char *data; 40}; 41 42static unsigned int lineno; 43 44/* Safely read a single line of arbitrary length from standard input. */ 45 46#define LINELEN 80 47 48static void 49getline(buf) 50 struct line *buf; 51{ 52 char *data = buf->data; 53 size_t alloc = buf->alloced; 54 size_t count = 0; 55 int c; 56 57 if (data == 0) 58 { 59 data = xmalloc (LINELEN); 60 alloc = LINELEN; 61 } 62 63 /* Skip comment lines. */ 64 while ((c = getchar()) == '#') 65 { 66 while ((c = getchar()) != EOF && c != '\n'); 67 lineno++; 68 } 69 70 /* c is the first character on the line, and it's not a comment 71 line: copy this line into the buffer and return. */ 72 while (c != EOF && c != '\n') 73 { 74 if (count + 1 >= alloc) 75 { 76 alloc *= 2; 77 data = xrealloc (data, alloc); 78 } 79 data[count++] = c; 80 c = getchar(); 81 } 82 lineno++; 83 data[count] = '\0'; 84 85 buf->data = data; 86 buf->alloced = alloc; 87} 88 89static void 90fail (lineno, opts, in, out, exp) 91 int lineno; 92 const char *opts; 93 const char *in; 94 const char *out; 95 const char *exp; 96{ 97 printf ("\ 98FAIL at line %d, options %s:\n\ 99in: %s\n\ 100out: %s\n\ 101exp: %s\n", 102 lineno, opts, in, out != NULL ? out : "(null)", exp); 103} 104 105/* The tester operates on a data file consisting of groups of lines: 106 options 107 input to be demangled 108 expected output 109 110 Supported options: 111 --format=<name> Sets the demangling style. 112 --no-params There are two lines of expected output; the first 113 is with DMGL_PARAMS, the second is without it. 114 --is-v3-ctor Calls is_gnu_v3_mangled_ctor on input; expected 115 output is an integer representing ctor_kind. 116 --is-v3-dtor Likewise, but for dtors. 117 118 For compatibility, just in case it matters, the options line may be 119 empty, to mean --format=auto. If it doesn't start with --, then it 120 may contain only a format name. 121*/ 122 123int 124main(argc, argv) 125 int argc; 126 char **argv; 127{ 128 enum demangling_styles style = auto_demangling; 129 int no_params; 130 int is_v3_ctor; 131 int is_v3_dtor; 132 struct line format; 133 struct line input; 134 struct line expect; 135 char *result; 136 int failures = 0; 137 int tests = 0; 138 139 if (argc > 1) 140 { 141 fprintf (stderr, "usage: %s < test-set\n", argv[0]); 142 return 2; 143 } 144 145 format.data = 0; 146 input.data = 0; 147 expect.data = 0; 148 149 for (;;) 150 { 151 getline (&format); 152 if (feof (stdin)) 153 break; 154 155 getline (&input); 156 getline (&expect); 157 158 tests++; 159 160 no_params = 0; 161 is_v3_ctor = 0; 162 is_v3_dtor = 0; 163 if (format.data[0] == '\0') 164 style = auto_demangling; 165 else if (format.data[0] != '-') 166 { 167 style = cplus_demangle_name_to_style (format.data); 168 if (style == unknown_demangling) 169 { 170 printf ("FAIL at line %d: unknown demangling style %s\n", 171 lineno, format.data); 172 failures++; 173 continue; 174 } 175 } 176 else 177 { 178 char *p; 179 char *opt; 180 181 p = format.data; 182 while (*p != '\0') 183 { 184 char c; 185 186 opt = p; 187 p += strcspn (p, " \t="); 188 c = *p; 189 *p = '\0'; 190 if (strcmp (opt, "--format") == 0 && c == '=') 191 { 192 char *fstyle; 193 194 *p = c; 195 ++p; 196 fstyle = p; 197 p += strcspn (p, " \t"); 198 c = *p; 199 *p = '\0'; 200 style = cplus_demangle_name_to_style (fstyle); 201 if (style == unknown_demangling) 202 { 203 printf ("FAIL at line %d: unknown demangling style %s\n", 204 lineno, fstyle); 205 failures++; 206 continue; 207 } 208 } 209 else if (strcmp (opt, "--no-params") == 0) 210 no_params = 1; 211 else if (strcmp (opt, "--is-v3-ctor") == 0) 212 is_v3_ctor = 1; 213 else if (strcmp (opt, "--is-v3-dtor") == 0) 214 is_v3_dtor = 1; 215 else 216 { 217 printf ("FAIL at line %d: unrecognized option %s\n", 218 lineno, opt); 219 failures++; 220 continue; 221 } 222 *p = c; 223 p += strspn (p, " \t"); 224 } 225 } 226 227 if (is_v3_ctor || is_v3_dtor) 228 { 229 char buf[20]; 230 231 if (is_v3_ctor) 232 { 233 enum gnu_v3_ctor_kinds kc; 234 235 kc = is_gnu_v3_mangled_ctor (input.data); 236 sprintf (buf, "%d", (int) kc); 237 } 238 else 239 { 240 enum gnu_v3_dtor_kinds kd; 241 242 kd = is_gnu_v3_mangled_dtor (input.data); 243 sprintf (buf, "%d", (int) kd); 244 } 245 246 if (strcmp (buf, expect.data) != 0) 247 { 248 fail (lineno, format.data, input.data, buf, expect.data); 249 failures++; 250 } 251 252 continue; 253 } 254 255 cplus_demangle_set_style (style); 256 257 result = cplus_demangle (input.data, 258 DMGL_PARAMS|DMGL_ANSI|DMGL_TYPES); 259 260 if (result 261 ? strcmp (result, expect.data) 262 : strcmp (input.data, expect.data)) 263 { 264 fail (lineno, format.data, input.data, result, expect.data); 265 failures++; 266 } 267 free (result); 268 269 if (no_params) 270 { 271 getline (&expect); 272 result = cplus_demangle (input.data, DMGL_ANSI|DMGL_TYPES); 273 274 if (result 275 ? strcmp (result, expect.data) 276 : strcmp (input.data, expect.data)) 277 { 278 fail (lineno, format.data, input.data, result, expect.data); 279 failures++; 280 } 281 free (result); 282 } 283 } 284 285 free (format.data); 286 free (input.data); 287 free (expect.data); 288 289 printf ("%s: %d tests, %d failures\n", argv[0], tests, failures); 290 return failures ? 1 : 0; 291} 292