1 /* $NetBSD: main.c,v 1.7 2018/02/04 09:15:45 mrg Exp $ */ 2 3 /* flex - tool to generate fast lexical analyzers */ 4 5 /* Copyright (c) 1990 The Regents of the University of California. */ 6 /* All rights reserved. */ 7 8 /* This code is derived from software contributed to Berkeley by */ 9 /* Vern Paxson. */ 10 11 /* The United States Government has rights in this work pursuant */ 12 /* to contract no. DE-AC03-76SF00098 between the United States */ 13 /* Department of Energy and the University of California. */ 14 15 /* This file is part of flex. */ 16 17 /* Redistribution and use in source and binary forms, with or without */ 18 /* modification, are permitted provided that the following conditions */ 19 /* are met: */ 20 21 /* 1. Redistributions of source code must retain the above copyright */ 22 /* notice, this list of conditions and the following disclaimer. */ 23 /* 2. Redistributions in binary form must reproduce the above copyright */ 24 /* notice, this list of conditions and the following disclaimer in the */ 25 /* documentation and/or other materials provided with the distribution. */ 26 27 /* Neither the name of the University nor the names of its contributors */ 28 /* may be used to endorse or promote products derived from this software */ 29 /* without specific prior written permission. */ 30 31 /* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR */ 32 /* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */ 33 /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */ 34 /* PURPOSE. */ 35 #include "flexdef.h" 36 __RCSID("$NetBSD: main.c,v 1.7 2018/02/04 09:15:45 mrg Exp $"); 37 38 40 #include "version.h" 41 #include "options.h" 42 #include "tables.h" 43 #include "parse.h" 44 45 static char flex_version[] = FLEX_VERSION; 46 47 /* declare functions that have forward references */ 48 49 void flexinit(int, char **); 50 void readin(void); 51 void set_up_initial_allocations(void); 52 53 54 /* these globals are all defined and commented in flexdef.h */ 55 int printstats, syntaxerror, eofseen, ddebug, trace, nowarn, spprdflt; 56 int interactive, lex_compat, posix_compat, do_yylineno, 57 useecs, fulltbl, usemecs; 58 int fullspd, gen_line_dirs, performance_report, backing_up_report; 59 int C_plus_plus, long_align, use_read, yytext_is_array, do_yywrap, 60 csize; 61 int reentrant, bison_bridge_lval, bison_bridge_lloc; 62 int yymore_used, reject, real_reject, continued_action, in_rule; 63 int yymore_really_used, reject_really_used; 64 int trace_hex = 0; 65 int datapos, dataline, linenum; 66 FILE *skelfile = NULL; 67 int skel_ind = 0; 68 char *action_array; 69 int action_size, defs1_offset, prolog_offset, action_offset, 70 action_index; 71 char *infilename = NULL, *outfilename = NULL, *headerfilename = NULL; 72 int did_outfilename; 73 char *prefix, *yyclass, *extra_type = NULL; 74 int do_stdinit, use_stdout; 75 int onestate[ONE_STACK_SIZE], onesym[ONE_STACK_SIZE]; 76 int onenext[ONE_STACK_SIZE], onedef[ONE_STACK_SIZE], onesp; 77 int maximum_mns, current_mns, current_max_rules; 78 int num_rules, num_eof_rules, default_rule, lastnfa; 79 int *firstst, *lastst, *finalst, *transchar, *trans1, *trans2; 80 int *accptnum, *assoc_rule, *state_type; 81 int *rule_type, *rule_linenum, *rule_useful; 82 int current_state_type; 83 int variable_trailing_context_rules; 84 int numtemps, numprots, protprev[MSP], protnext[MSP], prottbl[MSP]; 85 int protcomst[MSP], firstprot, lastprot, protsave[PROT_SAVE_SIZE]; 86 int numecs, nextecm[CSIZE + 1], ecgroup[CSIZE + 1], nummecs, 87 tecfwd[CSIZE + 1]; 88 int tecbck[CSIZE + 1]; 89 int lastsc, *scset, *scbol, *scxclu, *sceof; 90 int current_max_scs; 91 char **scname; 92 int current_max_dfa_size, current_max_xpairs; 93 int current_max_template_xpairs, current_max_dfas; 94 int lastdfa, *nxt, *chk, *tnxt; 95 int *base, *def, *nultrans, NUL_ec, tblend, firstfree, **dss, *dfasiz; 96 union dfaacc_union *dfaacc; 97 int *accsiz, *dhash, numas; 98 int numsnpairs, jambase, jamstate; 99 int lastccl, *cclmap, *ccllen, *cclng, cclreuse; 100 int current_maxccls, current_max_ccl_tbl_size; 101 unsigned char *ccltbl; 102 char nmstr[MAXLINE]; 103 int sectnum, nummt, hshcol, dfaeql, numeps, eps2, num_reallocs; 104 int tmpuses, totnst, peakpairs, numuniq, numdup, hshsave; 105 int num_backing_up, bol_needed; 106 FILE *backing_up_file; 107 int end_of_buffer_state; 108 char **input_files; 109 int num_input_files; 110 jmp_buf flex_main_jmp_buf; 111 bool *rule_has_nl, *ccl_has_nl; 112 int nlch = '\n'; 113 114 bool tablesext, tablesverify, gentables; 115 char *tablesfilename=0,*tablesname=0; 116 struct yytbl_writer tableswr; 117 118 /* Make sure program_name is initialized so we don't crash if writing 119 * out an error message before getting the program name from argv[0]. 120 */ 121 char *program_name = "flex"; 122 123 static const char outfile_template[] = "lex.%s.%s"; 124 static const char backing_name[] = "lex.backup"; 125 static const char tablesfile_template[] = "lex.%s.tables"; 126 127 /* From scan.l */ 128 extern FILE* yyout; 129 130 static char outfile_path[MAXLINE]; 131 static int outfile_created = 0; 132 static char *skelname = NULL; 133 static int _stdout_closed = 0; /* flag to prevent double-fclose() on stdout. */ 134 const char *escaped_qstart = "]]M4_YY_NOOP[M4_YY_NOOP[M4_YY_NOOP[["; 135 const char *escaped_qend = "]]M4_YY_NOOP]M4_YY_NOOP]M4_YY_NOOP[["; 136 137 /* For debugging. The max number of filters to apply to skeleton. */ 138 static int preproc_level = 1000; 139 140 int flex_main (int argc, char *argv[]); 141 142 int flex_main (int argc, char *argv[]) 143 { 144 int i, exit_status, child_status; 145 146 /* Set a longjmp target. Yes, I know it's a hack, but it gets worse: The 147 * return value of setjmp, if non-zero, is the desired exit code PLUS ONE. 148 * For example, if you want 'main' to return with code '2', then call 149 * longjmp() with an argument of 3. This is because it is invalid to 150 * specify a value of 0 to longjmp. FLEX_EXIT(n) should be used instead of 151 * exit(n); 152 */ 153 exit_status = setjmp (flex_main_jmp_buf); 154 if (exit_status){ 155 if (stdout && !_stdout_closed && !ferror(stdout)){ 156 fflush(stdout); 157 fclose(stdout); 158 } 159 while (wait(&child_status) > 0){ 160 if (!WIFEXITED (child_status) 161 || WEXITSTATUS (child_status) != 0){ 162 /* report an error of a child 163 */ 164 if( exit_status <= 1 ) 165 exit_status = 2; 166 167 } 168 } 169 return exit_status - 1; 170 } 171 172 flexinit (argc, argv); 173 174 readin (); 175 176 skelout (); 177 /* %% [1.5] DFA */ 178 ntod (); 179 180 for (i = 1; i <= num_rules; ++i) 181 if (!rule_useful[i] && i != default_rule) 182 line_warning (_("rule cannot be matched"), 183 rule_linenum[i]); 184 185 if (spprdflt && !reject && rule_useful[default_rule]) 186 line_warning (_ 187 ("-s option given but default rule can be matched"), 188 rule_linenum[default_rule]); 189 190 /* Generate the C state transition tables from the DFA. */ 191 make_tables (); 192 193 /* Note, flexend does not return. It exits with its argument 194 * as status. 195 */ 196 flexend (0); 197 198 return 0; /* keep compilers/lint happy */ 199 } 200 201 /* Wrapper around flex_main, so flex_main can be built as a library. */ 202 int main (int argc, char *argv[]) 203 { 204 #if ENABLE_NLS 205 #if HAVE_LOCALE_H 206 setlocale (LC_MESSAGES, ""); 207 setlocale (LC_CTYPE, ""); 208 textdomain (PACKAGE); 209 bindtextdomain (PACKAGE, LOCALEDIR); 210 #endif 211 #endif 212 213 return flex_main (argc, argv); 214 } 215 216 /* check_options - check user-specified options */ 217 218 void check_options (void) 219 { 220 int i; 221 const char * m4 = NULL; 222 223 if (lex_compat) { 224 if (C_plus_plus) 225 flexerror (_("Can't use -+ with -l option")); 226 227 if (fulltbl || fullspd) 228 flexerror (_("Can't use -f or -F with -l option")); 229 230 if (reentrant || bison_bridge_lval) 231 flexerror (_ 232 ("Can't use --reentrant or --bison-bridge with -l option")); 233 234 yytext_is_array = true; 235 do_yylineno = true; 236 use_read = false; 237 } 238 239 240 #if 0 241 /* This makes no sense whatsoever. I'm removing it. */ 242 if (do_yylineno) 243 /* This should really be "maintain_backup_tables = true" */ 244 reject_really_used = true; 245 #endif 246 247 if (csize == unspecified) { 248 if ((fulltbl || fullspd) && !useecs) 249 csize = DEFAULT_CSIZE; 250 else 251 csize = CSIZE; 252 } 253 254 if (interactive == unspecified) { 255 if (fulltbl || fullspd) 256 interactive = false; 257 else 258 interactive = true; 259 } 260 261 if (fulltbl || fullspd) { 262 if (usemecs) 263 flexerror (_ 264 ("-Cf/-CF and -Cm don't make sense together")); 265 266 if (interactive) 267 flexerror (_("-Cf/-CF and -I are incompatible")); 268 269 if (lex_compat) 270 flexerror (_ 271 ("-Cf/-CF are incompatible with lex-compatibility mode")); 272 273 274 if (fulltbl && fullspd) 275 flexerror (_ 276 ("-Cf and -CF are mutually exclusive")); 277 } 278 279 if (C_plus_plus && fullspd) 280 flexerror (_("Can't use -+ with -CF option")); 281 282 if (C_plus_plus && yytext_is_array) { 283 lwarn (_("%array incompatible with -+ option")); 284 yytext_is_array = false; 285 } 286 287 if (C_plus_plus && (reentrant)) 288 flexerror (_("Options -+ and --reentrant are mutually exclusive.")); 289 290 if (C_plus_plus && bison_bridge_lval) 291 flexerror (_("bison bridge not supported for the C++ scanner.")); 292 293 294 if (useecs) { /* Set up doubly-linked equivalence classes. */ 295 296 /* We loop all the way up to csize, since ecgroup[csize] is 297 * the position used for NUL characters. 298 */ 299 ecgroup[1] = NIL; 300 301 for (i = 2; i <= csize; ++i) { 302 ecgroup[i] = i - 1; 303 nextecm[i - 1] = i; 304 } 305 306 nextecm[csize] = NIL; 307 } 308 309 else { 310 /* Put everything in its own equivalence class. */ 311 for (i = 1; i <= csize; ++i) { 312 ecgroup[i] = i; 313 nextecm[i] = BAD_SUBSCRIPT; /* to catch errors */ 314 } 315 } 316 317 if (extra_type) 318 buf_m4_define( &m4defs_buf, "M4_EXTRA_TYPE_DEFS", extra_type); 319 320 if (!use_stdout) { 321 FILE *prev_stdout; 322 323 if (!did_outfilename) { 324 char *suffix; 325 326 if (C_plus_plus) 327 suffix = "cc"; 328 else 329 suffix = "c"; 330 331 snprintf (outfile_path, sizeof(outfile_path), outfile_template, 332 prefix, suffix); 333 334 outfilename = outfile_path; 335 } 336 337 prev_stdout = freopen (outfilename, "w+", stdout); 338 339 if (prev_stdout == NULL) 340 lerr (_("could not create %s"), outfilename); 341 342 outfile_created = 1; 343 } 344 345 346 /* Setup the filter chain. */ 347 output_chain = filter_create_int(NULL, filter_tee_header, headerfilename); 348 if ( !(m4 = getenv("M4"))) { 349 char *slash; 350 m4 = M4; 351 if ((slash = strrchr(M4, '/')) != NULL) { 352 m4 = slash+1; 353 /* break up $PATH */ 354 const char *path = getenv("PATH"); 355 if (!path) { 356 m4 = M4; 357 } else { 358 int m4_length = strlen(m4); 359 do { 360 size_t length = strlen(path); 361 struct stat sbuf; 362 363 const char *endOfDir = strchr(path, ':'); 364 if (!endOfDir) 365 endOfDir = path+length; 366 367 { 368 char *m4_path = calloc(endOfDir-path + 1 + m4_length + 1, 1); 369 370 memcpy(m4_path, path, endOfDir-path); 371 m4_path[endOfDir-path] = '/'; 372 memcpy(m4_path + (endOfDir-path) + 1, m4, m4_length + 1); 373 if (stat(m4_path, &sbuf) == 0 && 374 (S_ISREG(sbuf.st_mode)) && sbuf.st_mode & S_IXUSR) { 375 m4 = m4_path; 376 break; 377 } 378 free(m4_path); 379 } 380 path = endOfDir+1; 381 } while (path[0]); 382 if (!path[0]) 383 m4 = M4; 384 } 385 } 386 } 387 filter_create_ext(output_chain, m4, "-P", 0); 388 filter_create_int(output_chain, filter_fix_linedirs, NULL); 389 390 /* For debugging, only run the requested number of filters. */ 391 if (preproc_level > 0) { 392 filter_truncate(output_chain, preproc_level); 393 filter_apply_chain(output_chain); 394 } 395 yyout = stdout; 396 397 398 /* always generate the tablesverify flag. */ 399 buf_m4_define (&m4defs_buf, "M4_YY_TABLES_VERIFY", tablesverify ? "1" : "0"); 400 if (tablesext) 401 gentables = false; 402 403 if (tablesverify) 404 /* force generation of C tables. */ 405 gentables = true; 406 407 408 if (tablesext) { 409 FILE *tablesout; 410 struct yytbl_hdr hdr; 411 char *pname = 0; 412 size_t nbytes = 0; 413 414 buf_m4_define (&m4defs_buf, "M4_YY_TABLES_EXTERNAL", NULL); 415 416 if (!tablesfilename) { 417 nbytes = strlen (prefix) + strlen (tablesfile_template) + 2; 418 tablesfilename = pname = calloc(nbytes, 1); 419 snprintf (pname, nbytes, tablesfile_template, prefix); 420 } 421 422 if ((tablesout = fopen (tablesfilename, "w")) == NULL) 423 lerr (_("could not create %s"), tablesfilename); 424 free(pname); 425 tablesfilename = 0; 426 427 yytbl_writer_init (&tableswr, tablesout); 428 429 nbytes = strlen (prefix) + strlen ("tables") + 2; 430 tablesname = calloc(nbytes, 1); 431 snprintf (tablesname, nbytes, "%stables", prefix); 432 yytbl_hdr_init (&hdr, flex_version, tablesname); 433 434 if (yytbl_hdr_fwrite (&tableswr, &hdr) <= 0) 435 flexerror (_("could not write tables header")); 436 } 437 438 if (skelname && (skelfile = fopen (skelname, "r")) == NULL) 439 lerr (_("can't open skeleton file %s"), skelname); 440 441 if (reentrant) { 442 buf_m4_define (&m4defs_buf, "M4_YY_REENTRANT", NULL); 443 if (yytext_is_array) 444 buf_m4_define (&m4defs_buf, "M4_YY_TEXT_IS_ARRAY", NULL); 445 } 446 447 if ( bison_bridge_lval) 448 buf_m4_define (&m4defs_buf, "M4_YY_BISON_LVAL", NULL); 449 450 if ( bison_bridge_lloc) 451 buf_m4_define (&m4defs_buf, "<M4_YY_BISON_LLOC>", NULL); 452 453 if (strchr(prefix, '[') || strchr(prefix, ']')) 454 flexerror(_("Prefix cannot include '[' or ']'")); 455 buf_m4_define(&m4defs_buf, "M4_YY_PREFIX", prefix); 456 457 if (did_outfilename) 458 line_directive_out (stdout, 0); 459 460 if (do_yylineno) 461 buf_m4_define (&m4defs_buf, "M4_YY_USE_LINENO", NULL); 462 463 /* Create the alignment type. */ 464 buf_strdefine (&userdef_buf, "YY_INT_ALIGNED", 465 long_align ? "long int" : "short int"); 466 467 /* Define the start condition macros. */ 468 { 469 struct Buf tmpbuf; 470 buf_init(&tmpbuf, sizeof(char)); 471 for (i = 1; i <= lastsc; i++) { 472 char *str, *fmt = "#define %s %d\n"; 473 size_t strsz; 474 475 strsz = strlen(fmt) + strlen(scname[i]) + (size_t)(1 + ceil (log10(i))) + 2; 476 str = malloc(strsz); 477 if (!str) 478 flexfatal(_("allocation of macro definition failed")); 479 snprintf(str, strsz, fmt, scname[i], i - 1); 480 buf_strappend(&tmpbuf, str); 481 free(str); 482 } 483 buf_m4_define(&m4defs_buf, "M4_YY_SC_DEFS", tmpbuf.elts); 484 buf_destroy(&tmpbuf); 485 } 486 487 /* This is where we begin writing to the file. */ 488 489 /* Dump the %top code. */ 490 if( top_buf.elts) 491 outn((char*) top_buf.elts); 492 493 /* Dump the m4 definitions. */ 494 buf_print_strings(&m4defs_buf, stdout); 495 m4defs_buf.nelts = 0; /* memory leak here. */ 496 497 /* Place a bogus line directive, it will be fixed in the filter. */ 498 if (gen_line_dirs) 499 outn("#line 0 \"M4_YY_OUTFILE_NAME\"\n"); 500 501 /* Dump the user defined preproc directives. */ 502 if (userdef_buf.elts) 503 outn ((char *) (userdef_buf.elts)); 504 505 skelout (); 506 /* %% [1.0] */ 507 } 508 509 /* flexend - terminate flex 510 * 511 * note 512 * This routine does not return. 513 */ 514 515 void flexend (int exit_status) 516 { 517 static int called_before = -1; /* prevent infinite recursion. */ 518 int tblsiz; 519 520 if (++called_before) 521 FLEX_EXIT (exit_status); 522 523 if (skelfile != NULL) { 524 if (ferror (skelfile)) 525 lerr (_("input error reading skeleton file %s"), 526 skelname); 527 528 else if (fclose (skelfile)) 529 lerr (_("error closing skeleton file %s"), 530 skelname); 531 } 532 533 #if 0 534 fprintf (header_out, 535 "#ifdef YY_HEADER_EXPORT_START_CONDITIONS\n"); 536 fprintf (header_out, 537 "/* Beware! Start conditions are not prefixed. */\n"); 538 539 /* Special case for "INITIAL" */ 540 fprintf (header_out, 541 "#undef INITIAL\n#define INITIAL 0\n"); 542 for (i = 2; i <= lastsc; i++) 543 fprintf (header_out, "#define %s %d\n", scname[i], i - 1); 544 fprintf (header_out, 545 "#endif /* YY_HEADER_EXPORT_START_CONDITIONS */\n\n"); 546 547 /* Kill ALL flex-related macros. This is so the user 548 * can #include more than one generated header file. */ 549 fprintf (header_out, "#ifndef YY_HEADER_NO_UNDEFS\n"); 550 fprintf (header_out, 551 "/* Undefine all internal macros, etc., that do no belong in the header. */\n\n"); 552 553 { 554 const char * undef_list[] = { 555 556 "BEGIN", 557 "ECHO", 558 "EOB_ACT_CONTINUE_SCAN", 559 "EOB_ACT_END_OF_FILE", 560 "EOB_ACT_LAST_MATCH", 561 "FLEX_SCANNER", 562 "REJECT", 563 "YYFARGS0", 564 "YYFARGS1", 565 "YYFARGS2", 566 "YYFARGS3", 567 "YYLMAX", 568 "YYSTATE", 569 "YY_AT_BOL", 570 "YY_BREAK", 571 "YY_BUFFER_EOF_PENDING", 572 "YY_BUFFER_NEW", 573 "YY_BUFFER_NORMAL", 574 "YY_BUF_SIZE", 575 "M4_YY_CALL_LAST_ARG", 576 "M4_YY_CALL_ONLY_ARG", 577 "YY_CURRENT_BUFFER", 578 "YY_DECL", 579 "M4_YY_DECL_LAST_ARG", 580 "M4_YY_DEF_LAST_ARG", 581 "M4_YY_DEF_ONLY_ARG", 582 "YY_DO_BEFORE_ACTION", 583 "YY_END_OF_BUFFER", 584 "YY_END_OF_BUFFER_CHAR", 585 "YY_EXIT_FAILURE", 586 "YY_EXTRA_TYPE", 587 "YY_FATAL_ERROR", 588 "YY_FLEX_DEFINED_ECHO", 589 "YY_FLEX_LEX_COMPAT", 590 "YY_FLEX_MAJOR_VERSION", 591 "YY_FLEX_MINOR_VERSION", 592 "YY_FLEX_SUBMINOR_VERSION", 593 "YY_FLUSH_BUFFER", 594 "YY_G", 595 "YY_INPUT", 596 "YY_INTERACTIVE", 597 "YY_INT_ALIGNED", 598 "YY_LAST_ARG", 599 "YY_LESS_LINENO", 600 "YY_LEX_ARGS", 601 "YY_LEX_DECLARATION", 602 "YY_LEX_PROTO", 603 "YY_MAIN", 604 "YY_MORE_ADJ", 605 "YY_NEED_STRLEN", 606 "YY_NEW_FILE", 607 "YY_NULL", 608 "YY_NUM_RULES", 609 "YY_ONLY_ARG", 610 "YY_PARAMS", 611 "YY_PROTO", 612 "M4_YY_PROTO_LAST_ARG", 613 "M4_YY_PROTO_ONLY_ARG void", 614 "YY_READ_BUF_SIZE", 615 "YY_REENTRANT", 616 "YY_RESTORE_YY_MORE_OFFSET", 617 "YY_RULE_SETUP", 618 "YY_SC_TO_UI", 619 "YY_SKIP_YYWRAP", 620 "YY_START", 621 "YY_START_STACK_INCR", 622 "YY_STATE_EOF", 623 "YY_STDINIT", 624 "YY_TRAILING_HEAD_MASK", 625 "YY_TRAILING_MASK", 626 "YY_USER_ACTION", 627 "YY_USE_CONST", 628 "YY_USE_PROTOS", 629 "unput", 630 "yyTABLES_NAME", 631 "yy_create_buffer", 632 "yy_delete_buffer", 633 "yy_flex_debug", 634 "yy_flush_buffer", 635 "yy_init_buffer", 636 "yy_load_buffer_state", 637 "yy_new_buffer", 638 "yy_scan_buffer", 639 "yy_scan_bytes", 640 "yy_scan_string", 641 "yy_set_bol", 642 "yy_set_interactive", 643 "yy_switch_to_buffer", 644 "yypush_buffer_state", 645 "yypop_buffer_state", 646 "yyensure_buffer_stack", 647 "yyalloc", 648 "const", 649 "yyextra", 650 "yyfree", 651 "yyget_debug", 652 "yyget_extra", 653 "yyget_in", 654 "yyget_leng", 655 "yyget_lineno", 656 "yyget_lloc", 657 "yyget_lval", 658 "yyget_out", 659 "yyget_text", 660 "yyin", 661 "yyleng", 662 "yyless", 663 "yylex", 664 "yylex_destroy", 665 "yylex_init", 666 "yylex_init_extra", 667 "yylineno", 668 "yylloc", 669 "yylval", 670 "yymore", 671 "yyout", 672 "yyrealloc", 673 "yyrestart", 674 "yyset_debug", 675 "yyset_extra", 676 "yyset_in", 677 "yyset_lineno", 678 "yyset_lloc", 679 "yyset_lval", 680 "yyset_out", 681 "yytables_destroy", 682 "yytables_fload", 683 "yyterminate", 684 "yytext", 685 "yytext_ptr", 686 "yywrap", 687 688 /* must be null-terminated */ 689 NULL}; 690 691 692 for (i=0; undef_list[i] != NULL; i++) 693 fprintf (header_out, "#undef %s\n", undef_list[i]); 694 } 695 696 /* undef any of the auto-generated symbols. */ 697 for (i = 0; i < defs_buf.nelts; i++) { 698 699 /* don't undef start conditions */ 700 if (sclookup (((char **) defs_buf.elts)[i]) > 0) 701 continue; 702 fprintf (header_out, "#undef %s\n", 703 ((char **) defs_buf.elts)[i]); 704 } 705 706 fprintf (header_out, 707 "#endif /* !YY_HEADER_NO_UNDEFS */\n"); 708 fprintf (header_out, "\n"); 709 fprintf (header_out, "#undef %sIN_HEADER\n", prefix); 710 fprintf (header_out, "#endif /* %sHEADER_H */\n", prefix); 711 712 if (ferror (header_out)) 713 lerr (_("error creating header file %s"), 714 headerfilename); 715 fflush (header_out); 716 fclose (header_out); 717 #endif 718 719 if (exit_status != 0 && outfile_created) { 720 if (ferror (stdout)) 721 lerr (_("error writing output file %s"), 722 outfilename); 723 724 else if ((_stdout_closed = 1) && fclose (stdout)) 725 lerr (_("error closing output file %s"), 726 outfilename); 727 728 else if (unlink (outfilename)) 729 lerr (_("error deleting output file %s"), 730 outfilename); 731 } 732 733 734 if (backing_up_report && backing_up_file) { 735 if (num_backing_up == 0) 736 fprintf (backing_up_file, _("No backing up.\n")); 737 else if (fullspd || fulltbl) 738 fprintf (backing_up_file, 739 _ 740 ("%d backing up (non-accepting) states.\n"), 741 num_backing_up); 742 else 743 fprintf (backing_up_file, 744 _("Compressed tables always back up.\n")); 745 746 if (ferror (backing_up_file)) 747 lerr (_("error writing backup file %s"), 748 backing_name); 749 750 else if (fclose (backing_up_file)) 751 lerr (_("error closing backup file %s"), 752 backing_name); 753 } 754 755 if (printstats) { 756 fprintf (stderr, _("%s version %s usage statistics:\n"), 757 program_name, flex_version); 758 759 fprintf (stderr, _(" scanner options: -")); 760 761 if (C_plus_plus) 762 putc ('+', stderr); 763 if (backing_up_report) 764 putc ('b', stderr); 765 if (ddebug) 766 putc ('d', stderr); 767 if (sf_case_ins()) 768 putc ('i', stderr); 769 if (lex_compat) 770 putc ('l', stderr); 771 if (posix_compat) 772 putc ('X', stderr); 773 if (performance_report > 0) 774 putc ('p', stderr); 775 if (performance_report > 1) 776 putc ('p', stderr); 777 if (spprdflt) 778 putc ('s', stderr); 779 if (reentrant) 780 fputs ("--reentrant", stderr); 781 if (bison_bridge_lval) 782 fputs ("--bison-bridge", stderr); 783 if (bison_bridge_lloc) 784 fputs ("--bison-locations", stderr); 785 if (use_stdout) 786 putc ('t', stderr); 787 if (printstats) 788 putc ('v', stderr); /* always true! */ 789 if (nowarn) 790 putc ('w', stderr); 791 if (interactive == false) 792 putc ('B', stderr); 793 if (interactive == true) 794 putc ('I', stderr); 795 if (!gen_line_dirs) 796 putc ('L', stderr); 797 if (trace) 798 putc ('T', stderr); 799 800 if (csize == unspecified) 801 /* We encountered an error fairly early on, so csize 802 * never got specified. Define it now, to prevent 803 * bogus table sizes being written out below. 804 */ 805 csize = 256; 806 807 if (csize == 128) 808 putc ('7', stderr); 809 else 810 putc ('8', stderr); 811 812 fprintf (stderr, " -C"); 813 814 if (long_align) 815 putc ('a', stderr); 816 if (fulltbl) 817 putc ('f', stderr); 818 if (fullspd) 819 putc ('F', stderr); 820 if (useecs) 821 putc ('e', stderr); 822 if (usemecs) 823 putc ('m', stderr); 824 if (use_read) 825 putc ('r', stderr); 826 827 if (did_outfilename) 828 fprintf (stderr, " -o%s", outfilename); 829 830 if (skelname) 831 fprintf (stderr, " -S%s", skelname); 832 833 if (strcmp (prefix, "yy")) 834 fprintf (stderr, " -P%s", prefix); 835 836 putc ('\n', stderr); 837 838 fprintf (stderr, _(" %d/%d NFA states\n"), 839 lastnfa, current_mns); 840 fprintf (stderr, _(" %d/%d DFA states (%d words)\n"), 841 lastdfa, current_max_dfas, totnst); 842 fprintf (stderr, _(" %d rules\n"), 843 num_rules + num_eof_rules - 844 1 /* - 1 for def. rule */ ); 845 846 if (num_backing_up == 0) 847 fprintf (stderr, _(" No backing up\n")); 848 else if (fullspd || fulltbl) 849 fprintf (stderr, 850 _ 851 (" %d backing-up (non-accepting) states\n"), 852 num_backing_up); 853 else 854 fprintf (stderr, 855 _ 856 (" Compressed tables always back-up\n")); 857 858 if (bol_needed) 859 fprintf (stderr, 860 _(" Beginning-of-line patterns used\n")); 861 862 fprintf (stderr, _(" %d/%d start conditions\n"), lastsc, 863 current_max_scs); 864 fprintf (stderr, 865 _ 866 (" %d epsilon states, %d double epsilon states\n"), 867 numeps, eps2); 868 869 if (lastccl == 0) 870 fprintf (stderr, _(" no character classes\n")); 871 else 872 fprintf (stderr, 873 _ 874 (" %d/%d character classes needed %d/%d words of storage, %d reused\n"), 875 lastccl, current_maxccls, 876 cclmap[lastccl] + ccllen[lastccl], 877 current_max_ccl_tbl_size, cclreuse); 878 879 fprintf (stderr, _(" %d state/nextstate pairs created\n"), 880 numsnpairs); 881 fprintf (stderr, 882 _(" %d/%d unique/duplicate transitions\n"), 883 numuniq, numdup); 884 885 if (fulltbl) { 886 tblsiz = lastdfa * numecs; 887 fprintf (stderr, _(" %d table entries\n"), 888 tblsiz); 889 } 890 891 else { 892 tblsiz = 2 * (lastdfa + numtemps) + 2 * tblend; 893 894 fprintf (stderr, 895 _(" %d/%d base-def entries created\n"), 896 lastdfa + numtemps, current_max_dfas); 897 fprintf (stderr, 898 _ 899 (" %d/%d (peak %d) nxt-chk entries created\n"), 900 tblend, current_max_xpairs, peakpairs); 901 fprintf (stderr, 902 _ 903 (" %d/%d (peak %d) template nxt-chk entries created\n"), 904 numtemps * nummecs, 905 current_max_template_xpairs, 906 numtemps * numecs); 907 fprintf (stderr, _(" %d empty table entries\n"), 908 nummt); 909 fprintf (stderr, _(" %d protos created\n"), 910 numprots); 911 fprintf (stderr, 912 _(" %d templates created, %d uses\n"), 913 numtemps, tmpuses); 914 } 915 916 if (useecs) { 917 tblsiz = tblsiz + csize; 918 fprintf (stderr, 919 _ 920 (" %d/%d equivalence classes created\n"), 921 numecs, csize); 922 } 923 924 if (usemecs) { 925 tblsiz = tblsiz + numecs; 926 fprintf (stderr, 927 _ 928 (" %d/%d meta-equivalence classes created\n"), 929 nummecs, csize); 930 } 931 932 fprintf (stderr, 933 _ 934 (" %d (%d saved) hash collisions, %d DFAs equal\n"), 935 hshcol, hshsave, dfaeql); 936 fprintf (stderr, _(" %d sets of reallocations needed\n"), 937 num_reallocs); 938 fprintf (stderr, _(" %d total table entries needed\n"), 939 tblsiz); 940 } 941 942 FLEX_EXIT (exit_status); 943 } 944 945 946 /* flexinit - initialize flex */ 947 948 void flexinit (int argc, char **argv) 949 { 950 int i, sawcmpflag, rv, optind; 951 char *arg; 952 scanopt_t sopt; 953 954 printstats = syntaxerror = trace = spprdflt = false; 955 lex_compat = posix_compat = C_plus_plus = backing_up_report = 956 ddebug = fulltbl = false; 957 fullspd = long_align = nowarn = yymore_used = continued_action = 958 false; 959 do_yylineno = yytext_is_array = in_rule = reject = do_stdinit = 960 false; 961 yymore_really_used = reject_really_used = unspecified; 962 interactive = csize = unspecified; 963 do_yywrap = gen_line_dirs = usemecs = useecs = true; 964 reentrant = bison_bridge_lval = bison_bridge_lloc = false; 965 performance_report = 0; 966 did_outfilename = 0; 967 prefix = "yy"; 968 yyclass = 0; 969 use_read = use_stdout = false; 970 tablesext = tablesverify = false; 971 gentables = true; 972 tablesfilename = tablesname = NULL; 973 974 sawcmpflag = false; 975 976 /* Initialize dynamic array for holding the rule actions. */ 977 action_size = 2048; /* default size of action array in bytes */ 978 action_array = allocate_character_array (action_size); 979 defs1_offset = prolog_offset = action_offset = action_index = 0; 980 action_array[0] = '\0'; 981 982 /* Initialize any buffers. */ 983 buf_init (&userdef_buf, sizeof (char)); /* one long string */ 984 buf_init (&defs_buf, sizeof (char *)); /* list of strings */ 985 buf_init (&yydmap_buf, sizeof (char)); /* one long string */ 986 buf_init (&top_buf, sizeof (char)); /* one long string */ 987 988 { 989 const char * m4defs_init_str[] = {"m4_changequote\n", 990 "m4_changequote([[, ]])\n"}; 991 buf_init (&m4defs_buf, sizeof (char *)); 992 buf_append (&m4defs_buf, &m4defs_init_str, 2); 993 } 994 995 sf_init (); 996 997 /* initialize regex lib */ 998 flex_init_regex(); 999 1000 /* Enable C++ if program name ends with '+'. */ 1001 program_name = basename (argv[0]); 1002 1003 if (program_name != NULL && 1004 program_name[strlen (program_name) - 1] == '+') 1005 C_plus_plus = true; 1006 1007 /* read flags */ 1008 sopt = scanopt_init (flexopts, argc, argv, 0); 1009 if (!sopt) { 1010 /* This will only happen when flexopts array is altered. */ 1011 fprintf (stderr, 1012 _("Internal error. flexopts are malformed.\n")); 1013 FLEX_EXIT (1); 1014 } 1015 1016 while ((rv = scanopt (sopt, &arg, &optind)) != 0) { 1017 1018 if (rv < 0) { 1019 /* Scanopt has already printed an option-specific error message. */ 1020 fprintf (stderr, 1021 _ 1022 ("Try `%s --help' for more information.\n"), 1023 program_name); 1024 FLEX_EXIT (1); 1025 } 1026 1027 switch ((enum flexopt_flag_t) rv) { 1028 case OPT_CPLUSPLUS: 1029 C_plus_plus = true; 1030 break; 1031 1032 case OPT_BATCH: 1033 interactive = false; 1034 break; 1035 1036 case OPT_BACKUP: 1037 backing_up_report = true; 1038 break; 1039 1040 case OPT_DONOTHING: 1041 break; 1042 1043 case OPT_COMPRESSION: 1044 if (!sawcmpflag) { 1045 useecs = false; 1046 usemecs = false; 1047 fulltbl = false; 1048 sawcmpflag = true; 1049 } 1050 1051 for (i = 0; arg && arg[i] != '\0'; i++) 1052 switch (arg[i]) { 1053 case 'a': 1054 long_align = true; 1055 break; 1056 1057 case 'e': 1058 useecs = true; 1059 break; 1060 1061 case 'F': 1062 fullspd = true; 1063 break; 1064 1065 case 'f': 1066 fulltbl = true; 1067 break; 1068 1069 case 'm': 1070 usemecs = true; 1071 break; 1072 1073 case 'r': 1074 use_read = true; 1075 break; 1076 1077 default: 1078 lerr (_ 1079 ("unknown -C option '%c'"), 1080 arg[i]); 1081 break; 1082 } 1083 break; 1084 1085 case OPT_DEBUG: 1086 ddebug = true; 1087 break; 1088 1089 case OPT_NO_DEBUG: 1090 ddebug = false; 1091 break; 1092 1093 case OPT_FULL: 1094 useecs = usemecs = false; 1095 use_read = fulltbl = true; 1096 break; 1097 1098 case OPT_FAST: 1099 useecs = usemecs = false; 1100 use_read = fullspd = true; 1101 break; 1102 1103 case OPT_HELP: 1104 usage (); 1105 FLEX_EXIT (0); 1106 1107 case OPT_INTERACTIVE: 1108 interactive = true; 1109 break; 1110 1111 case OPT_CASE_INSENSITIVE: 1112 sf_set_case_ins(true); 1113 break; 1114 1115 case OPT_LEX_COMPAT: 1116 lex_compat = true; 1117 break; 1118 1119 case OPT_POSIX_COMPAT: 1120 posix_compat = true; 1121 break; 1122 1123 case OPT_PREPROC_LEVEL: 1124 preproc_level = (int) strtol(arg,NULL,0); 1125 break; 1126 1127 case OPT_MAIN: 1128 buf_strdefine (&userdef_buf, "YY_MAIN", "1"); 1129 do_yywrap = false; 1130 break; 1131 1132 case OPT_NO_MAIN: 1133 buf_strdefine (&userdef_buf, "YY_MAIN", "0"); 1134 break; 1135 1136 case OPT_NO_LINE: 1137 gen_line_dirs = false; 1138 break; 1139 1140 case OPT_OUTFILE: 1141 outfilename = arg; 1142 did_outfilename = 1; 1143 break; 1144 1145 case OPT_PREFIX: 1146 prefix = arg; 1147 break; 1148 1149 case OPT_PERF_REPORT: 1150 ++performance_report; 1151 break; 1152 1153 case OPT_BISON_BRIDGE: 1154 bison_bridge_lval = true; 1155 break; 1156 1157 case OPT_BISON_BRIDGE_LOCATIONS: 1158 bison_bridge_lval = bison_bridge_lloc = true; 1159 break; 1160 1161 case OPT_REENTRANT: 1162 reentrant = true; 1163 break; 1164 1165 case OPT_NO_REENTRANT: 1166 reentrant = false; 1167 break; 1168 1169 case OPT_SKEL: 1170 skelname = arg; 1171 break; 1172 1173 case OPT_DEFAULT: 1174 spprdflt = false; 1175 break; 1176 1177 case OPT_NO_DEFAULT: 1178 spprdflt = true; 1179 break; 1180 1181 case OPT_STDOUT: 1182 use_stdout = true; 1183 break; 1184 1185 case OPT_NO_UNISTD_H: 1186 //buf_strdefine (&userdef_buf, "YY_NO_UNISTD_H", "1"); 1187 buf_m4_define( &m4defs_buf, "M4_YY_NO_UNISTD_H",0); 1188 break; 1189 1190 case OPT_TABLES_FILE: 1191 tablesext = true; 1192 tablesfilename = arg; 1193 break; 1194 1195 case OPT_TABLES_VERIFY: 1196 tablesverify = true; 1197 break; 1198 1199 case OPT_TRACE: 1200 trace = true; 1201 break; 1202 1203 case OPT_VERBOSE: 1204 printstats = true; 1205 break; 1206 1207 case OPT_VERSION: 1208 printf (_("%s %s\n"), program_name, flex_version); 1209 FLEX_EXIT (0); 1210 1211 case OPT_WARN: 1212 nowarn = false; 1213 break; 1214 1215 case OPT_NO_WARN: 1216 nowarn = true; 1217 break; 1218 1219 case OPT_7BIT: 1220 csize = 128; 1221 break; 1222 1223 case OPT_8BIT: 1224 csize = CSIZE; 1225 break; 1226 1227 case OPT_ALIGN: 1228 long_align = true; 1229 break; 1230 1231 case OPT_NO_ALIGN: 1232 long_align = false; 1233 break; 1234 1235 case OPT_ALWAYS_INTERACTIVE: 1236 buf_m4_define (&m4defs_buf, "M4_YY_ALWAYS_INTERACTIVE", 0); 1237 break; 1238 1239 case OPT_NEVER_INTERACTIVE: 1240 buf_m4_define( &m4defs_buf, "M4_YY_NEVER_INTERACTIVE", 0); 1241 break; 1242 1243 case OPT_ARRAY: 1244 yytext_is_array = true; 1245 break; 1246 1247 case OPT_POINTER: 1248 yytext_is_array = false; 1249 break; 1250 1251 case OPT_ECS: 1252 useecs = true; 1253 break; 1254 1255 case OPT_NO_ECS: 1256 useecs = false; 1257 break; 1258 1259 case OPT_HEADER_FILE: 1260 headerfilename = arg; 1261 break; 1262 1263 case OPT_META_ECS: 1264 usemecs = true; 1265 break; 1266 1267 case OPT_NO_META_ECS: 1268 usemecs = false; 1269 break; 1270 1271 case OPT_PREPROCDEFINE: 1272 { 1273 /* arg is "symbol" or "symbol=definition". */ 1274 char *def; 1275 1276 for (def = arg; 1277 *def != '\0' && *def != '='; ++def) ; 1278 1279 buf_strappend (&userdef_buf, "#define "); 1280 if (*def == '\0') { 1281 buf_strappend (&userdef_buf, arg); 1282 buf_strappend (&userdef_buf, 1283 " 1\n"); 1284 } 1285 else { 1286 buf_strnappend (&userdef_buf, arg, 1287 (int) (def - arg)); 1288 buf_strappend (&userdef_buf, " "); 1289 buf_strappend (&userdef_buf, 1290 def + 1); 1291 buf_strappend (&userdef_buf, "\n"); 1292 } 1293 } 1294 break; 1295 1296 case OPT_READ: 1297 use_read = true; 1298 break; 1299 1300 case OPT_STACK: 1301 //buf_strdefine (&userdef_buf, "YY_STACK_USED", "1"); 1302 buf_m4_define( &m4defs_buf, "M4_YY_STACK_USED",0); 1303 break; 1304 1305 case OPT_STDINIT: 1306 do_stdinit = true; 1307 break; 1308 1309 case OPT_NO_STDINIT: 1310 do_stdinit = false; 1311 break; 1312 1313 case OPT_YYCLASS: 1314 yyclass = arg; 1315 break; 1316 1317 case OPT_YYLINENO: 1318 do_yylineno = true; 1319 break; 1320 1321 case OPT_NO_YYLINENO: 1322 do_yylineno = false; 1323 break; 1324 1325 case OPT_YYWRAP: 1326 do_yywrap = true; 1327 break; 1328 1329 case OPT_NO_YYWRAP: 1330 do_yywrap = false; 1331 break; 1332 1333 case OPT_YYMORE: 1334 yymore_really_used = true; 1335 break; 1336 1337 case OPT_NO_YYMORE: 1338 yymore_really_used = false; 1339 break; 1340 1341 case OPT_REJECT: 1342 reject_really_used = true; 1343 break; 1344 1345 case OPT_NO_REJECT: 1346 reject_really_used = false; 1347 break; 1348 1349 case OPT_NO_YY_PUSH_STATE: 1350 //buf_strdefine (&userdef_buf, "YY_NO_PUSH_STATE", "1"); 1351 buf_m4_define( &m4defs_buf, "M4_YY_NO_PUSH_STATE",0); 1352 break; 1353 case OPT_NO_YY_POP_STATE: 1354 //buf_strdefine (&userdef_buf, "YY_NO_POP_STATE", "1"); 1355 buf_m4_define( &m4defs_buf, "M4_YY_NO_POP_STATE",0); 1356 break; 1357 case OPT_NO_YY_TOP_STATE: 1358 //buf_strdefine (&userdef_buf, "YY_NO_TOP_STATE", "1"); 1359 buf_m4_define( &m4defs_buf, "M4_YY_NO_TOP_STATE",0); 1360 break; 1361 case OPT_NO_UNPUT: 1362 //buf_strdefine (&userdef_buf, "YY_NO_UNPUT", "1"); 1363 buf_m4_define( &m4defs_buf, "M4_YY_NO_UNPUT",0); 1364 break; 1365 case OPT_NO_YY_SCAN_BUFFER: 1366 //buf_strdefine (&userdef_buf, "YY_NO_SCAN_BUFFER", "1"); 1367 buf_m4_define( &m4defs_buf, "M4_YY_NO_SCAN_BUFFER",0); 1368 break; 1369 case OPT_NO_YY_SCAN_BYTES: 1370 //buf_strdefine (&userdef_buf, "YY_NO_SCAN_BYTES", "1"); 1371 buf_m4_define( &m4defs_buf, "M4_YY_NO_SCAN_BYTES",0); 1372 break; 1373 case OPT_NO_YY_SCAN_STRING: 1374 //buf_strdefine (&userdef_buf, "YY_NO_SCAN_STRING", "1"); 1375 buf_m4_define( &m4defs_buf, "M4_YY_NO_SCAN_STRING",0); 1376 break; 1377 case OPT_NO_YYGET_EXTRA: 1378 //buf_strdefine (&userdef_buf, "YY_NO_GET_EXTRA", "1"); 1379 buf_m4_define( &m4defs_buf, "M4_YY_NO_GET_EXTRA",0); 1380 break; 1381 case OPT_NO_YYSET_EXTRA: 1382 //buf_strdefine (&userdef_buf, "YY_NO_SET_EXTRA", "1"); 1383 buf_m4_define( &m4defs_buf, "M4_YY_NO_SET_EXTRA",0); 1384 break; 1385 case OPT_NO_YYGET_LENG: 1386 //buf_strdefine (&userdef_buf, "YY_NO_GET_LENG", "1"); 1387 buf_m4_define( &m4defs_buf, "M4_YY_NO_GET_LENG",0); 1388 break; 1389 case OPT_NO_YYGET_TEXT: 1390 //buf_strdefine (&userdef_buf, "YY_NO_GET_TEXT", "1"); 1391 buf_m4_define( &m4defs_buf, "M4_YY_NO_GET_TEXT",0); 1392 break; 1393 case OPT_NO_YYGET_LINENO: 1394 //buf_strdefine (&userdef_buf, "YY_NO_GET_LINENO", "1"); 1395 buf_m4_define( &m4defs_buf, "M4_YY_NO_GET_LINENO",0); 1396 break; 1397 case OPT_NO_YYSET_LINENO: 1398 //buf_strdefine (&userdef_buf, "YY_NO_SET_LINENO", "1"); 1399 buf_m4_define( &m4defs_buf, "M4_YY_NO_SET_LINENO",0); 1400 break; 1401 case OPT_NO_YYGET_IN: 1402 //buf_strdefine (&userdef_buf, "YY_NO_GET_IN", "1"); 1403 buf_m4_define( &m4defs_buf, "M4_YY_NO_GET_IN",0); 1404 break; 1405 case OPT_NO_YYSET_IN: 1406 //buf_strdefine (&userdef_buf, "YY_NO_SET_IN", "1"); 1407 buf_m4_define( &m4defs_buf, "M4_YY_NO_SET_IN",0); 1408 break; 1409 case OPT_NO_YYGET_OUT: 1410 //buf_strdefine (&userdef_buf, "YY_NO_GET_OUT", "1"); 1411 buf_m4_define( &m4defs_buf, "M4_YY_NO_GET_OUT",0); 1412 break; 1413 case OPT_NO_YYSET_OUT: 1414 //buf_strdefine (&userdef_buf, "YY_NO_SET_OUT", "1"); 1415 buf_m4_define( &m4defs_buf, "M4_YY_NO_SET_OUT",0); 1416 break; 1417 case OPT_NO_YYGET_LVAL: 1418 //buf_strdefine (&userdef_buf, "YY_NO_GET_LVAL", "1"); 1419 buf_m4_define( &m4defs_buf, "M4_YY_NO_GET_LVAL",0); 1420 break; 1421 case OPT_NO_YYSET_LVAL: 1422 //buf_strdefine (&userdef_buf, "YY_NO_SET_LVAL", "1"); 1423 buf_m4_define( &m4defs_buf, "M4_YY_NO_SET_LVAL",0); 1424 break; 1425 case OPT_NO_YYGET_LLOC: 1426 //buf_strdefine (&userdef_buf, "YY_NO_GET_LLOC", "1"); 1427 buf_m4_define( &m4defs_buf, "M4_YY_NO_GET_LLOC",0); 1428 break; 1429 case OPT_NO_YYSET_LLOC: 1430 //buf_strdefine (&userdef_buf, "YY_NO_SET_LLOC", "1"); 1431 buf_m4_define( &m4defs_buf, "M4_YY_NO_SET_LLOC",0); 1432 break; 1433 case OPT_HEX: 1434 trace_hex = 1; 1435 break; 1436 case OPT_NO_SECT3_ESCAPE: 1437 no_section3_escape = true; 1438 break; 1439 } /* switch */ 1440 } /* while scanopt() */ 1441 1442 scanopt_destroy (sopt); 1443 1444 num_input_files = argc - optind; 1445 input_files = argv + optind; 1446 set_input_file (num_input_files > 0 ? input_files[0] : NULL); 1447 1448 lastccl = lastsc = lastdfa = lastnfa = 0; 1449 num_rules = num_eof_rules = default_rule = 0; 1450 numas = numsnpairs = tmpuses = 0; 1451 numecs = numeps = eps2 = num_reallocs = hshcol = dfaeql = totnst = 1452 0; 1453 numuniq = numdup = hshsave = eofseen = datapos = dataline = 0; 1454 num_backing_up = onesp = numprots = 0; 1455 variable_trailing_context_rules = bol_needed = false; 1456 1457 linenum = sectnum = 1; 1458 firstprot = NIL; 1459 1460 /* Used in mkprot() so that the first proto goes in slot 1 1461 * of the proto queue. 1462 */ 1463 lastprot = 1; 1464 1465 set_up_initial_allocations (); 1466 } 1467 1468 1469 /* readin - read in the rules section of the input file(s) */ 1470 1471 void readin (void) 1472 { 1473 static char yy_stdinit[] = "FILE *yyin = stdin, *yyout = stdout;"; 1474 static char yy_nostdinit[] = 1475 "FILE *yyin = NULL, *yyout = NULL;"; 1476 1477 line_directive_out(NULL, 1); 1478 1479 if (yyparse ()) { 1480 pinpoint_message (_("fatal parse error")); 1481 flexend (1); 1482 } 1483 1484 if (syntaxerror) 1485 flexend (1); 1486 1487 /* If the user explicitly requested posix compatibility by specifing the 1488 * posix-compat option, then we check for conflicting options. However, if 1489 * the POSIXLY_CORRECT variable is set, then we quietly make flex as 1490 * posix-compatible as possible. This is the recommended behavior 1491 * according to the GNU Coding Standards. 1492 * 1493 * Note: The posix option was added to flex to provide the posix behavior 1494 * of the repeat operator in regular expressions, e.g., `ab{3}' 1495 */ 1496 if (posix_compat) { 1497 /* TODO: This is where we try to make flex behave according to 1498 * posiz, AND check for conflicting options. How far should we go 1499 * with this? Should we disable all the neat-o flex features? 1500 */ 1501 /* Update: Estes says no, since other flex features don't violate posix. */ 1502 } 1503 1504 if (getenv ("POSIXLY_CORRECT")) { 1505 posix_compat = true; 1506 } 1507 1508 if (backing_up_report) { 1509 backing_up_file = fopen (backing_name, "w"); 1510 if (backing_up_file == NULL) 1511 lerr (_ 1512 ("could not create backing-up info file %s"), 1513 backing_name); 1514 } 1515 1516 else 1517 backing_up_file = NULL; 1518 1519 if (yymore_really_used == true) 1520 yymore_used = true; 1521 else if (yymore_really_used == false) 1522 yymore_used = false; 1523 1524 if (reject_really_used == true) 1525 reject = true; 1526 else if (reject_really_used == false) 1527 reject = false; 1528 1529 if (performance_report > 0) { 1530 if (lex_compat) { 1531 fprintf (stderr, 1532 _ 1533 ("-l AT&T lex compatibility option entails a large performance penalty\n")); 1534 fprintf (stderr, 1535 _ 1536 (" and may be the actual source of other reported performance penalties\n")); 1537 } 1538 1539 else if (do_yylineno) { 1540 fprintf (stderr, 1541 _ 1542 ("%%option yylineno entails a performance penalty ONLY on rules that can match newline characters\n")); 1543 } 1544 1545 if (performance_report > 1) { 1546 if (interactive) 1547 fprintf (stderr, 1548 _ 1549 ("-I (interactive) entails a minor performance penalty\n")); 1550 1551 if (yymore_used) 1552 fprintf (stderr, 1553 _ 1554 ("yymore() entails a minor performance penalty\n")); 1555 } 1556 1557 if (reject) 1558 fprintf (stderr, 1559 _ 1560 ("REJECT entails a large performance penalty\n")); 1561 1562 if (variable_trailing_context_rules) 1563 fprintf (stderr, 1564 _ 1565 ("Variable trailing context rules entail a large performance penalty\n")); 1566 } 1567 1568 if (reject) 1569 real_reject = true; 1570 1571 if (variable_trailing_context_rules) 1572 reject = true; 1573 1574 if ((fulltbl || fullspd) && reject) { 1575 if (real_reject) 1576 flexerror (_ 1577 ("REJECT cannot be used with -f or -F")); 1578 else if (do_yylineno) 1579 flexerror (_ 1580 ("%option yylineno cannot be used with REJECT")); 1581 else 1582 flexerror (_ 1583 ("variable trailing context rules cannot be used with -f or -F")); 1584 } 1585 1586 if (reject){ 1587 out_m4_define( "M4_YY_USES_REJECT", NULL); 1588 //outn ("\n#define YY_USES_REJECT"); 1589 } 1590 1591 if (!do_yywrap) { 1592 if (!C_plus_plus) { 1593 if (reentrant) 1594 out_str ("\n#define %swrap(yyscanner) (/*CONSTCOND*/1)\n", prefix); 1595 else 1596 out_str ("\n#define %swrap() (/*CONSTCOND*/1)\n", prefix); 1597 } 1598 outn ("#define YY_SKIP_YYWRAP"); 1599 } 1600 1601 if (ddebug) 1602 outn ("\n#define FLEX_DEBUG"); 1603 1604 OUT_BEGIN_CODE (); 1605 outn ("typedef flex_uint8_t YY_CHAR;"); 1606 OUT_END_CODE (); 1607 1608 if (C_plus_plus) { 1609 outn ("#define yytext_ptr yytext"); 1610 1611 if (interactive) 1612 outn ("#define YY_INTERACTIVE"); 1613 } 1614 1615 else { 1616 OUT_BEGIN_CODE (); 1617 /* In reentrant scanner, stdinit is handled in flex.skl. */ 1618 if (do_stdinit) { 1619 if (reentrant){ 1620 outn ("#ifdef VMS"); 1621 outn ("#ifdef __VMS_POSIX"); 1622 outn ("#define YY_STDINIT"); 1623 outn ("#endif"); 1624 outn ("#else"); 1625 outn ("#define YY_STDINIT"); 1626 outn ("#endif"); 1627 } 1628 1629 outn ("#ifdef VMS"); 1630 outn ("#ifndef __VMS_POSIX"); 1631 outn (yy_nostdinit); 1632 outn ("#else"); 1633 outn (yy_stdinit); 1634 outn ("#endif"); 1635 outn ("#else"); 1636 outn (yy_stdinit); 1637 outn ("#endif"); 1638 } 1639 1640 else { 1641 if(!reentrant) 1642 outn (yy_nostdinit); 1643 } 1644 OUT_END_CODE (); 1645 } 1646 1647 OUT_BEGIN_CODE (); 1648 if (fullspd) 1649 outn ("typedef const struct yy_trans_info *yy_state_type;"); 1650 else if (!C_plus_plus) 1651 outn ("typedef int yy_state_type;"); 1652 OUT_END_CODE (); 1653 1654 if (lex_compat) 1655 outn ("#define YY_FLEX_LEX_COMPAT"); 1656 1657 if (!C_plus_plus && !reentrant) { 1658 outn ("extern int yylineno;"); 1659 OUT_BEGIN_CODE (); 1660 outn ("int yylineno = 1;"); 1661 OUT_END_CODE (); 1662 } 1663 1664 if (C_plus_plus) { 1665 outn ("\n#include <FlexLexer.h>"); 1666 1667 if (!do_yywrap) { 1668 outn("\nint yyFlexLexer::yywrap() { return 1; }"); 1669 } 1670 1671 if (yyclass) { 1672 outn ("int yyFlexLexer::yylex()"); 1673 outn ("\t{"); 1674 outn ("\tLexerError( \"yyFlexLexer::yylex invoked but %option yyclass used\" );"); 1675 outn ("\treturn 0;"); 1676 outn ("\t}"); 1677 1678 out_str ("\n#define YY_DECL int %s::yylex()\n", 1679 yyclass); 1680 } 1681 } 1682 1683 else { 1684 1685 /* Watch out: yytext_ptr is a variable when yytext is an array, 1686 * but it's a macro when yytext is a pointer. 1687 */ 1688 if (yytext_is_array) { 1689 if (!reentrant) 1690 outn ("extern char yytext[];\n"); 1691 } 1692 else { 1693 if (reentrant) { 1694 outn ("#define yytext_ptr yytext_r"); 1695 } 1696 else { 1697 outn ("extern char *yytext;"); 1698 1699 outn("#ifdef yytext_ptr"); 1700 outn("#undef yytext_ptr"); 1701 outn("#endif"); 1702 outn ("#define yytext_ptr yytext"); 1703 } 1704 } 1705 1706 if (yyclass) 1707 flexerror (_ 1708 ("%option yyclass only meaningful for C++ scanners")); 1709 } 1710 1711 if (useecs) 1712 numecs = cre8ecs (nextecm, ecgroup, csize); 1713 else 1714 numecs = csize; 1715 1716 /* Now map the equivalence class for NUL to its expected place. */ 1717 ecgroup[0] = ecgroup[csize]; 1718 NUL_ec = ABS (ecgroup[0]); 1719 1720 if (useecs) 1721 ccl2ecl (); 1722 } 1723 1724 1725 /* set_up_initial_allocations - allocate memory for internal tables */ 1726 1727 void set_up_initial_allocations (void) 1728 { 1729 maximum_mns = (long_align ? MAXIMUM_MNS_LONG : MAXIMUM_MNS); 1730 current_mns = INITIAL_MNS; 1731 firstst = allocate_integer_array (current_mns); 1732 lastst = allocate_integer_array (current_mns); 1733 finalst = allocate_integer_array (current_mns); 1734 transchar = allocate_integer_array (current_mns); 1735 trans1 = allocate_integer_array (current_mns); 1736 trans2 = allocate_integer_array (current_mns); 1737 accptnum = allocate_integer_array (current_mns); 1738 assoc_rule = allocate_integer_array (current_mns); 1739 state_type = allocate_integer_array (current_mns); 1740 1741 current_max_rules = INITIAL_MAX_RULES; 1742 rule_type = allocate_integer_array (current_max_rules); 1743 rule_linenum = allocate_integer_array (current_max_rules); 1744 rule_useful = allocate_integer_array (current_max_rules); 1745 rule_has_nl = allocate_bool_array (current_max_rules); 1746 1747 current_max_scs = INITIAL_MAX_SCS; 1748 scset = allocate_integer_array (current_max_scs); 1749 scbol = allocate_integer_array (current_max_scs); 1750 scxclu = allocate_integer_array (current_max_scs); 1751 sceof = allocate_integer_array (current_max_scs); 1752 scname = allocate_char_ptr_array (current_max_scs); 1753 1754 current_maxccls = INITIAL_MAX_CCLS; 1755 cclmap = allocate_integer_array (current_maxccls); 1756 ccllen = allocate_integer_array (current_maxccls); 1757 cclng = allocate_integer_array (current_maxccls); 1758 ccl_has_nl = allocate_bool_array (current_maxccls); 1759 1760 current_max_ccl_tbl_size = INITIAL_MAX_CCL_TBL_SIZE; 1761 ccltbl = allocate_Character_array (current_max_ccl_tbl_size); 1762 1763 current_max_dfa_size = INITIAL_MAX_DFA_SIZE; 1764 1765 current_max_xpairs = INITIAL_MAX_XPAIRS; 1766 nxt = allocate_integer_array (current_max_xpairs); 1767 chk = allocate_integer_array (current_max_xpairs); 1768 1769 current_max_template_xpairs = INITIAL_MAX_TEMPLATE_XPAIRS; 1770 tnxt = allocate_integer_array (current_max_template_xpairs); 1771 1772 current_max_dfas = INITIAL_MAX_DFAS; 1773 base = allocate_integer_array (current_max_dfas); 1774 def = allocate_integer_array (current_max_dfas); 1775 dfasiz = allocate_integer_array (current_max_dfas); 1776 accsiz = allocate_integer_array (current_max_dfas); 1777 dhash = allocate_integer_array (current_max_dfas); 1778 dss = allocate_int_ptr_array (current_max_dfas); 1779 dfaacc = allocate_dfaacc_union (current_max_dfas); 1780 1781 nultrans = NULL; 1782 } 1783 1784 1785 void usage (void) 1786 { 1787 FILE *f = stdout; 1788 1789 if (!did_outfilename) { 1790 snprintf (outfile_path, sizeof(outfile_path), outfile_template, 1791 prefix, C_plus_plus ? "cc" : "c"); 1792 outfilename = outfile_path; 1793 } 1794 1795 fprintf (f, _("Usage: %s [OPTIONS] [FILE]...\n"), program_name); 1796 fprintf (f, 1797 _ 1798 ("Generates programs that perform pattern-matching on text.\n" 1799 "\n" "Table Compression:\n" 1800 " -Ca, --align trade off larger tables for better memory alignment\n" 1801 " -Ce, --ecs construct equivalence classes\n" 1802 " -Cf do not compress tables; use -f representation\n" 1803 " -CF do not compress tables; use -F representation\n" 1804 " -Cm, --meta-ecs construct meta-equivalence classes\n" 1805 " -Cr, --read use read() instead of stdio for scanner input\n" 1806 " -f, --full generate fast, large scanner. Same as -Cfr\n" 1807 " -F, --fast use alternate table representation. Same as -CFr\n" 1808 " -Cem default compression (same as --ecs --meta-ecs)\n" 1809 "\n" "Debugging:\n" 1810 " -d, --debug enable debug mode in scanner\n" 1811 " -b, --backup write backing-up information to %s\n" 1812 " -p, --perf-report write performance report to stderr\n" 1813 " -s, --nodefault suppress default rule to ECHO unmatched text\n" 1814 " -T, --trace %s should run in trace mode\n" 1815 " -w, --nowarn do not generate warnings\n" 1816 " -v, --verbose write summary of scanner statistics to stdout\n" 1817 " --hex use hexadecimal numbers instead of octal in debug outputs\n" 1818 "\n" "Files:\n" 1819 " -o, --outfile=FILE specify output filename\n" 1820 " -S, --skel=FILE specify skeleton file\n" 1821 " -t, --stdout write scanner on stdout instead of %s\n" 1822 " --yyclass=NAME name of C++ class\n" 1823 " --header-file=FILE create a C header file in addition to the scanner\n" 1824 " --tables-file[=FILE] write tables to FILE\n" "\n" 1825 "Scanner behavior:\n" 1826 " -7, --7bit generate 7-bit scanner\n" 1827 " -8, --8bit generate 8-bit scanner\n" 1828 " -B, --batch generate batch scanner (opposite of -I)\n" 1829 " -i, --case-insensitive ignore case in patterns\n" 1830 " -l, --lex-compat maximal compatibility with original lex\n" 1831 " -X, --posix-compat maximal compatibility with POSIX lex\n" 1832 " -I, --interactive generate interactive scanner (opposite of -B)\n" 1833 " --yylineno track line count in yylineno\n" 1834 "\n" "Generated code:\n" 1835 " -+, --c++ generate C++ scanner class\n" 1836 " -Dmacro[=defn] #define macro defn (default defn is '1')\n" 1837 " -L, --noline suppress #line directives in scanner\n" 1838 " -P, --prefix=STRING use STRING as prefix instead of \"yy\"\n" 1839 " -R, --reentrant generate a reentrant C scanner\n" 1840 " --bison-bridge scanner for bison pure parser.\n" 1841 " --bison-locations include yylloc support.\n" 1842 " --stdinit initialize yyin/yyout to stdin/stdout\n" 1843 " --nounistd do not include <unistd.h>\n" 1844 " --noFUNCTION do not generate a particular FUNCTION\n" 1845 "\n" "Miscellaneous:\n" 1846 " -c do-nothing POSIX option\n" 1847 " -n do-nothing POSIX option\n" 1848 " -?\n" 1849 " -h, --help produce this help message\n" 1850 " -V, --version report %s version\n"), 1851 backing_name, program_name, outfile_path, program_name); 1852 1853 } 1854