1 /* Parse command line arguments for Bison. 2 3 Copyright (C) 1984, 1986, 1989, 1992, 2000, 2001, 2002, 2003, 2004, 4 2005, 2006 Free Software Foundation, Inc. 5 6 This file is part of Bison, the GNU Compiler Compiler. 7 8 Bison is free software; you can redistribute it and/or modify it 9 under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 2, or (at your option) 11 any later version. 12 13 Bison is distributed in the hope that it will be useful, but 14 WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with Bison; see the file COPYING. If not, write to the Free 20 Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 21 02110-1301, USA. */ 22 23 #include <config.h> 24 #include "system.h" 25 26 #include <argmatch.h> 27 #include <error.h> 28 29 /* Hack to get <getopt.h> to declare getopt with a prototype. */ 30 #if lint && ! defined __GNU_LIBRARY__ 31 # define __GNU_LIBRARY__ 32 # define HACK_FOR___GNU_LIBRARY___PROTOTYPE 1 33 #endif 34 35 #include <getopt.h> 36 37 #ifdef HACK_FOR___GNU_LIBRARY___PROTOTYPE 38 # undef __GNU_LIBRARY__ 39 # undef HACK_FOR___GNU_LIBRARY___PROTOTYPE 40 #endif 41 42 #include "complain.h" 43 #include "files.h" 44 #include "getargs.h" 45 #include "uniqstr.h" 46 47 bool debug_flag; 48 bool defines_flag; 49 bool graph_flag; 50 bool locations_flag; 51 bool no_lines_flag; 52 bool no_parser_flag; 53 bool token_table_flag; 54 bool yacc_flag; /* for -y */ 55 56 bool error_verbose = false; 57 58 bool nondeterministic_parser = false; 59 bool glr_parser = false; 60 bool pure_parser = false; 61 62 int report_flag = report_none; 63 int trace_flag = trace_none; 64 65 const char *skeleton = NULL; 66 const char *include = NULL; 67 68 extern char *program_name; 69 70 71 /*---------------------. 72 | --trace's handling. | 73 `---------------------*/ 74 75 static const char * const trace_args[] = 76 { 77 /* In a series of synonyms, present the most meaningful first, so 78 that argmatch_valid be more readable. */ 79 "none - no report", 80 "scan - grammar scanner traces", 81 "parse - grammar parser traces", 82 "automaton - contruction of the automaton", 83 "bitsets - use of bitsets", 84 "grammar - reading, reducing of the grammar", 85 "resource - memory consumption (where available)", 86 "sets - grammar sets: firsts, nullable etc.", 87 "tools - m4 invocation", 88 "m4 - m4 traces", 89 "skeleton - skeleton postprocessing", 90 "time - time consumption", 91 "all - all of the above", 92 0 93 }; 94 95 static const int trace_types[] = 96 { 97 trace_none, 98 trace_scan, 99 trace_parse, 100 trace_automaton, 101 trace_bitsets, 102 trace_grammar, 103 trace_resource, 104 trace_sets, 105 trace_tools, 106 trace_m4, 107 trace_skeleton, 108 trace_time, 109 trace_all 110 }; 111 112 ARGMATCH_VERIFY (trace_args, trace_types); 113 114 static void 115 trace_argmatch (char *args) 116 { 117 if (args) 118 { 119 args = strtok (args, ","); 120 do 121 { 122 int trace = XARGMATCH ("--trace", args, 123 trace_args, trace_types); 124 if (trace == trace_none) 125 trace_flag = trace_none; 126 else 127 trace_flag |= trace; 128 } 129 while ((args = strtok (NULL, ","))); 130 } 131 else 132 trace_flag = trace_all; 133 } 134 135 136 /*----------------------. 137 | --report's handling. | 138 `----------------------*/ 139 140 static const char * const report_args[] = 141 { 142 /* In a series of synonyms, present the most meaningful first, so 143 that argmatch_valid be more readable. */ 144 "none", 145 "state", "states", 146 "itemset", "itemsets", 147 "look-ahead", "lookahead", "lookaheads", 148 "solved", 149 "all", 150 0 151 }; 152 153 static const int report_types[] = 154 { 155 report_none, 156 report_states, report_states, 157 report_states | report_itemsets, report_states | report_itemsets, 158 report_states | report_look_ahead_tokens, 159 report_states | report_look_ahead_tokens, 160 report_states | report_look_ahead_tokens, 161 report_states | report_solved_conflicts, 162 report_all 163 }; 164 165 ARGMATCH_VERIFY (report_args, report_types); 166 167 static void 168 report_argmatch (char *args) 169 { 170 args = strtok (args, ","); 171 do 172 { 173 int report = XARGMATCH ("--report", args, 174 report_args, report_types); 175 if (report == report_none) 176 report_flag = report_none; 177 else 178 report_flag |= report; 179 } 180 while ((args = strtok (NULL, ","))); 181 } 182 183 184 /*-------------------------------------------. 185 | Display the help message and exit STATUS. | 186 `-------------------------------------------*/ 187 188 static void usage (int) ATTRIBUTE_NORETURN; 189 190 static void 191 usage (int status) 192 { 193 if (status != 0) 194 fprintf (stderr, _("Try `%s --help' for more information.\n"), 195 program_name); 196 else 197 { 198 /* Some efforts were made to ease the translators' task, please 199 continue. */ 200 fputs (_("\ 201 GNU bison generates parsers for LALR(1) grammars.\n"), stdout); 202 putc ('\n', stdout); 203 204 fprintf (stdout, _("\ 205 Usage: %s [OPTION]... FILE\n"), program_name); 206 putc ('\n', stdout); 207 208 fputs (_("\ 209 If a long option shows an argument as mandatory, then it is mandatory\n\ 210 for the equivalent short option also. Similarly for optional arguments.\n"), 211 stdout); 212 putc ('\n', stdout); 213 214 fputs (_("\ 215 Operation modes:\n\ 216 -h, --help display this help and exit\n\ 217 -V, --version output version information and exit\n\ 218 --print-localedir output directory containing locale-dependent data\n\ 219 -y, --yacc emulate POSIX yacc\n"), stdout); 220 putc ('\n', stdout); 221 222 fputs (_("\ 223 Parser:\n\ 224 -S, --skeleton=FILE specify the skeleton to use\n\ 225 -t, --debug instrument the parser for debugging\n\ 226 --locations enable locations computation\n\ 227 -p, --name-prefix=PREFIX prepend PREFIX to the external symbols\n\ 228 -l, --no-lines don't generate `#line' directives\n\ 229 -n, --no-parser generate the tables only\n\ 230 -k, --token-table include a table of token names\n\ 231 "), stdout); 232 putc ('\n', stdout); 233 234 fputs (_("\ 235 Output:\n\ 236 -d, --defines also produce a header file\n\ 237 -r, --report=THINGS also produce details on the automaton\n\ 238 -v, --verbose same as `--report=state'\n\ 239 -b, --file-prefix=PREFIX specify a PREFIX for output files\n\ 240 -o, --output=FILE leave output to FILE\n\ 241 -g, --graph also produce a VCG description of the automaton\n\ 242 "), stdout); 243 putc ('\n', stdout); 244 245 fputs (_("\ 246 THINGS is a list of comma separated words that can include:\n\ 247 `state' describe the states\n\ 248 `itemset' complete the core item sets with their closure\n\ 249 `look-ahead' explicitly associate look-ahead tokens to items\n\ 250 `solved' describe shift/reduce conflicts solving\n\ 251 `all' include all the above information\n\ 252 `none' disable the report\n\ 253 "), stdout); 254 putc ('\n', stdout); 255 256 fputs (_("\ 257 Report bugs to <bug-bison (at) gnu.org>.\n"), stdout); 258 } 259 260 exit (status); 261 } 262 263 264 /*------------------------------. 265 | Display the version message. | 266 `------------------------------*/ 267 268 static void 269 version (void) 270 { 271 /* Some efforts were made to ease the translators' task, please 272 continue. */ 273 printf (_("bison (GNU Bison) %s"), VERSION); 274 putc ('\n', stdout); 275 fputs (_("Written by Robert Corbett and Richard Stallman.\n"), stdout); 276 putc ('\n', stdout); 277 278 fprintf (stdout, 279 _("Copyright (C) %d Free Software Foundation, Inc.\n"), 2006); 280 281 fputs (_("\ 282 This is free software; see the source for copying conditions. There is NO\n\ 283 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ 284 "), 285 stdout); 286 } 287 288 289 /*----------------------. 290 | Process the options. | 291 `----------------------*/ 292 293 /* Shorts options. */ 294 static char const short_options[] = "yvegdhr:ltknVo:b:p:S:T::"; 295 296 /* Values for long options that do not have single-letter equivalents. */ 297 enum 298 { 299 LOCATIONS_OPTION = CHAR_MAX + 1, 300 PRINT_LOCALEDIR_OPTION 301 }; 302 303 static struct option const long_options[] = 304 { 305 /* Operation modes. */ 306 { "help", no_argument, 0, 'h' }, 307 { "version", no_argument, 0, 'V' }, 308 { "print-localedir", no_argument, 0, PRINT_LOCALEDIR_OPTION }, 309 310 /* Parser. */ 311 { "name-prefix", required_argument, 0, 'p' }, 312 { "include", required_argument, 0, 'I' }, 313 314 /* Output. */ 315 { "file-prefix", required_argument, 0, 'b' }, 316 { "output", required_argument, 0, 'o' }, 317 { "output-file", required_argument, 0, 'o' }, 318 { "graph", optional_argument, 0, 'g' }, 319 { "report", required_argument, 0, 'r' }, 320 { "verbose", no_argument, 0, 'v' }, 321 322 /* Hidden. */ 323 { "trace", optional_argument, 0, 'T' }, 324 325 /* Output. */ 326 { "defines", optional_argument, 0, 'd' }, 327 328 /* Operation modes. */ 329 { "fixed-output-files", no_argument, 0, 'y' }, 330 { "yacc", no_argument, 0, 'y' }, 331 332 /* Parser. */ 333 { "debug", no_argument, 0, 't' }, 334 { "locations", no_argument, 0, LOCATIONS_OPTION }, 335 { "no-lines", no_argument, 0, 'l' }, 336 { "no-parser", no_argument, 0, 'n' }, 337 { "raw", no_argument, 0, 0 }, 338 { "skeleton", required_argument, 0, 'S' }, 339 { "token-table", no_argument, 0, 'k' }, 340 341 {0, 0, 0, 0} 342 }; 343 344 /* Under DOS, there is no difference on the case. This can be 345 troublesome when looking for `.tab' etc. */ 346 #ifdef MSDOS 347 # define AS_FILE_NAME(File) (strlwr (File), (File)) 348 #else 349 # define AS_FILE_NAME(File) (File) 350 #endif 351 352 void 353 getargs (int argc, char *argv[]) 354 { 355 int c; 356 357 while ((c = getopt_long (argc, argv, short_options, long_options, NULL)) 358 != -1) 359 switch (c) 360 { 361 case 0: 362 /* Certain long options cause getopt_long to return 0. */ 363 break; 364 365 case 'y': 366 yacc_flag = true; 367 break; 368 369 case 'h': 370 usage (EXIT_SUCCESS); 371 372 case 'V': 373 version (); 374 exit (EXIT_SUCCESS); 375 376 case PRINT_LOCALEDIR_OPTION: 377 printf ("%s\n", LOCALEDIR); 378 exit (EXIT_SUCCESS); 379 380 case 'g': 381 /* Here, the -g and --graph=FILE options are differentiated. */ 382 graph_flag = true; 383 if (optarg) 384 spec_graph_file = AS_FILE_NAME (optarg); 385 break; 386 387 case 'v': 388 report_flag |= report_states; 389 break; 390 391 case 'S': 392 skeleton = AS_FILE_NAME (optarg); 393 break; 394 395 case 'I': 396 include = AS_FILE_NAME (optarg); 397 break; 398 399 case 'd': 400 /* Here, the -d and --defines options are differentiated. */ 401 defines_flag = true; 402 if (optarg) 403 spec_defines_file = AS_FILE_NAME (optarg); 404 break; 405 406 case 'l': 407 no_lines_flag = true; 408 break; 409 410 case LOCATIONS_OPTION: 411 locations_flag = true; 412 break; 413 414 case 'k': 415 token_table_flag = true; 416 break; 417 418 case 'n': 419 no_parser_flag = true; 420 break; 421 422 case 't': 423 debug_flag = true; 424 break; 425 426 case 'o': 427 spec_outfile = AS_FILE_NAME (optarg); 428 break; 429 430 case 'b': 431 spec_file_prefix = AS_FILE_NAME (optarg); 432 break; 433 434 case 'p': 435 spec_name_prefix = optarg; 436 break; 437 438 case 'r': 439 report_argmatch (optarg); 440 break; 441 442 case 'T': 443 trace_argmatch (optarg); 444 break; 445 446 default: 447 usage (EXIT_FAILURE); 448 } 449 450 if (argc - optind != 1) 451 { 452 if (argc - optind < 1) 453 error (0, 0, _("missing operand after `%s'"), argv[argc - 1]); 454 else 455 error (0, 0, _("extra operand `%s'"), argv[optind + 1]); 456 usage (EXIT_FAILURE); 457 } 458 459 current_file = grammar_file = uniqstr_new (argv[optind]); 460 } 461