Coverage Report

Created: 2026-09-01 07:02

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