test-demangle.c revision 169695
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 --ret-postfix Passes the DMGL_RET_POSTFIX option 118 119 For compatibility, just in case it matters, the options line may be 120 empty, to mean --format=auto. If it doesn't start with --, then it 121 may contain only a format name. 122*/ 123 124int 125main(argc, argv) 126 int argc; 127 char **argv; 128{ 129 enum demangling_styles style = auto_demangling; 130 int no_params; 131 int is_v3_ctor; 132 int is_v3_dtor; 133 int ret_postfix; 134 struct line format; 135 struct line input; 136 struct line expect; 137 char *result; 138 int failures = 0; 139 int tests = 0; 140 141 if (argc > 1) 142 { 143 fprintf (stderr, "usage: %s < test-set\n", argv[0]); 144 return 2; 145 } 146 147 format.data = 0; 148 input.data = 0; 149 expect.data = 0; 150 151 for (;;) 152 { 153 getline (&format); 154 if (feof (stdin)) 155 break; 156 157 getline (&input); 158 getline (&expect); 159 160 tests++; 161 162 no_params = 0; 163 ret_postfix = 0; 164 is_v3_ctor = 0; 165 is_v3_dtor = 0; 166 if (format.data[0] == '\0') 167 style = auto_demangling; 168 else if (format.data[0] != '-') 169 { 170 style = cplus_demangle_name_to_style (format.data); 171 if (style == unknown_demangling) 172 { 173 printf ("FAIL at line %d: unknown demangling style %s\n", 174 lineno, format.data); 175 failures++; 176 continue; 177 } 178 } 179 else 180 { 181 char *p; 182 char *opt; 183 184 p = format.data; 185 while (*p != '\0') 186 { 187 char c; 188 189 opt = p; 190 p += strcspn (p, " \t="); 191 c = *p; 192 *p = '\0'; 193 if (strcmp (opt, "--format") == 0 && c == '=') 194 { 195 char *fstyle; 196 197 *p = c; 198 ++p; 199 fstyle = p; 200 p += strcspn (p, " \t"); 201 c = *p; 202 *p = '\0'; 203 style = cplus_demangle_name_to_style (fstyle); 204 if (style == unknown_demangling) 205 { 206 printf ("FAIL at line %d: unknown demangling style %s\n", 207 lineno, fstyle); 208 failures++; 209 continue; 210 } 211 } 212 else if (strcmp (opt, "--no-params") == 0) 213 no_params = 1; 214 else if (strcmp (opt, "--is-v3-ctor") == 0) 215 is_v3_ctor = 1; 216 else if (strcmp (opt, "--is-v3-dtor") == 0) 217 is_v3_dtor = 1; 218 else if (strcmp (opt, "--ret-postfix") == 0) 219 ret_postfix = 1; 220 else 221 { 222 printf ("FAIL at line %d: unrecognized option %s\n", 223 lineno, opt); 224 failures++; 225 continue; 226 } 227 *p = c; 228 p += strspn (p, " \t"); 229 } 230 } 231 232 if (is_v3_ctor || is_v3_dtor) 233 { 234 char buf[20]; 235 236 if (is_v3_ctor) 237 { 238 enum gnu_v3_ctor_kinds kc; 239 240 kc = is_gnu_v3_mangled_ctor (input.data); 241 sprintf (buf, "%d", (int) kc); 242 } 243 else 244 { 245 enum gnu_v3_dtor_kinds kd; 246 247 kd = is_gnu_v3_mangled_dtor (input.data); 248 sprintf (buf, "%d", (int) kd); 249 } 250 251 if (strcmp (buf, expect.data) != 0) 252 { 253 fail (lineno, format.data, input.data, buf, expect.data); 254 failures++; 255 } 256 257 continue; 258 } 259 260 cplus_demangle_set_style (style); 261 262 result = cplus_demangle (input.data, 263 DMGL_PARAMS|DMGL_ANSI|DMGL_TYPES 264 |(ret_postfix ? DMGL_RET_POSTFIX : 0)); 265 266 if (result 267 ? strcmp (result, expect.data) 268 : strcmp (input.data, expect.data)) 269 { 270 fail (lineno, format.data, input.data, result, expect.data); 271 failures++; 272 } 273 free (result); 274 275 if (no_params) 276 { 277 getline (&expect); 278 result = cplus_demangle (input.data, DMGL_ANSI|DMGL_TYPES); 279 280 if (result 281 ? strcmp (result, expect.data) 282 : strcmp (input.data, expect.data)) 283 { 284 fail (lineno, format.data, input.data, result, expect.data); 285 failures++; 286 } 287 free (result); 288 } 289 } 290 291 free (format.data); 292 free (input.data); 293 free (expect.data); 294 295 printf ("%s: %d tests, %d failures\n", argv[0], tests, failures); 296 return failures ? 1 : 0; 297} 298