From ec676fce008138b222d072de28fb05e1dfd945fb Mon Sep 17 00:00:00 2001 From: Will Estes Date: Tue, 7 Aug 2012 12:18:08 -0400 Subject: reorganize flex skeleton and m4 processing --- Makefile.am | 25 +- buf.c | 82 +- ccl.c | 11 +- configure.ac | 11 +- dfa.c | 74 +- ecs.c | 11 +- filter.c | 102 +- flex_code_macros.m4 | 417 ++++++ flex_functions.m4 | 1740 ++++++++++++++++++++++++ flex_globals.m4 | 191 +++ flex_header.m4 | 564 ++++++++ flex_print_m4_params.m4 | 71 + flex_private_header.m4 | 354 +++++ flex_private_protos.m4 | 65 + flex_private_typedefs.m4 | 55 + flex_public_header.m4 | 210 +++ flex_public_protos.m4 | 152 +++ flex_public_typedefs.m4 | 76 ++ flex_skel.m4 | 725 ++++++++++ flexdef.h | 322 ++--- gen.c | 1266 +++-------------- libmain.c | 4 +- main.c | 876 ++++-------- misc.c | 367 +---- nfa.c | 58 +- options.c | 23 +- options.h | 13 +- parse.y | 51 +- prefix.m4 | 64 + regex.c | 2 +- scan.l | 315 +++-- scanflags.c | 2 +- scanopt.c | 120 +- scanopt.h | 21 +- sym.c | 93 +- tables.c | 15 +- tables.h | 2 + tables_shared.c | 81 +- tables_shared.h | 89 +- tblcmp.c | 50 +- tests/Makefile.am | 14 +- tests/test-alloc-extra/scanner.l | 3 + tests/test-basic-nr/scan.h | 210 +++ tests/test-basic-nr/scanner.l | 2 +- tests/test-basic-r/scanner.l | 2 +- tests/test-bison-nr/parser.y | 14 +- tests/test-bison-yylloc/parser.y | 11 + tests/test-bison-yylval/parser.y | 12 +- tests/test-c++-table-opts/.gitignore | 2 + tests/test-c++-table-opts/Makefile.am | 119 ++ tests/test-c++-table-opts/scanner.l | 83 ++ tests/test-c++-table-opts/test.input | 2 + tests/test-extended/scanner.l | 1 - tests/test-include-by-buffer/scanner.h | 0 tests/test-include-by-buffer/scanner.l | 4 +- tests/test-include-by-reentrant/scanner.l | 4 +- tests/test-lineno-nr/scanner.l | 4 +- tests/test-lineno-r/scanner.l | 4 +- tests/test-mem-nr/scanner.l | 1 + tests/test-mem-r/scanner.l | 1 + tests/test-namespace-nr/.gitignore | 2 + tests/test-namespace-nr/Makefile.am | 50 + tests/test-namespace-nr/parser.y | 61 + tests/test-namespace-nr/scanner.l | 54 + tests/test-namespace-nr/test.input | 2 + tests/test-no-m4/.gitignore | 2 + tests/test-no-m4/Makefile.am | 50 + tests/test-no-m4/parser.y | 61 + tests/test-no-m4/scanner.l | 70 + tests/test-no-m4/test.input | 2 + tests/test-prefix-nr/scanner.l | 6 +- tests/test-prefix-r/scanner.l | 4 +- tests/test-pthread/scanner.l | 3 +- tests/test-quotes/scanner.l | 2 +- tests/test-reject/scanner.l | 31 +- tests/test-rescan-r/scanner.l | 2 +- tests/test-table-opts/Makefile.am | 4 +- tests/test-table-opts/scanner.l | 28 +- tests/test-top-header/Makefile.am | 54 + tests/test-top-header/main.c | 63 + tests/test-top-header/scanner.c | 2109 +++++++++++++++++++++++++++++ tests/test-top-header/scanner.h | 390 ++++++ tests/test-top-header/scanner.l | 54 + tests/test-top-header/test.input | 3 + tests/test-yyextra/scanner.l | 3 +- yylex.c | 4 +- 86 files changed, 9591 insertions(+), 2786 deletions(-) create mode 100644 flex_code_macros.m4 create mode 100644 flex_functions.m4 create mode 100644 flex_globals.m4 create mode 100644 flex_header.m4 create mode 100644 flex_print_m4_params.m4 create mode 100644 flex_private_header.m4 create mode 100644 flex_private_protos.m4 create mode 100644 flex_private_typedefs.m4 create mode 100644 flex_public_header.m4 create mode 100644 flex_public_protos.m4 create mode 100644 flex_public_typedefs.m4 create mode 100644 flex_skel.m4 create mode 100644 prefix.m4 create mode 100644 tests/test-basic-nr/scan.h create mode 100644 tests/test-c++-table-opts/.gitignore create mode 100644 tests/test-c++-table-opts/Makefile.am create mode 100644 tests/test-c++-table-opts/scanner.l create mode 100644 tests/test-c++-table-opts/test.input create mode 100644 tests/test-include-by-buffer/scanner.h create mode 100644 tests/test-namespace-nr/.gitignore create mode 100644 tests/test-namespace-nr/Makefile.am create mode 100644 tests/test-namespace-nr/parser.y create mode 100644 tests/test-namespace-nr/scanner.l create mode 100644 tests/test-namespace-nr/test.input create mode 100644 tests/test-no-m4/.gitignore create mode 100644 tests/test-no-m4/Makefile.am create mode 100644 tests/test-no-m4/parser.y create mode 100644 tests/test-no-m4/scanner.l create mode 100644 tests/test-no-m4/test.input create mode 100644 tests/test-top-header/Makefile.am create mode 100644 tests/test-top-header/main.c create mode 100644 tests/test-top-header/scanner.c create mode 100644 tests/test-top-header/scanner.h create mode 100644 tests/test-top-header/scanner.l create mode 100644 tests/test-top-header/test.input diff --git a/Makefile.am b/Makefile.am index 63e5e65..bcf77b8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -54,7 +54,6 @@ flex_SOURCES = \ nfa.c \ parse.y \ scan.l \ - skel.c \ sym.c \ tblcmp.c \ yylex.c \ @@ -107,13 +106,21 @@ EXTRA_DIST = \ ABOUT-NLS \ INSTALL \ autogen.sh \ - flex.skl \ - mkskel.sh \ config.rpath \ - gettext.h + gettext.h \ + flex_skel.m4 \ + flex_code_macros.m4 \ + flex_functions.m4 \ + flex_globals.m4 \ + flex_header.m4 \ + flex_print_m4_params.m4 \ + flex_private_header.m4 \ + flex_private_protos.m4 \ + flex_private_typedefs.m4 \ + flex_public_header.m4 \ + flex_public_protos.m4 \ + flex_public_typedefs.m4 -BUILT_SOURCES = \ - skel.c SUBDIRS = \ lib \ @@ -125,12 +132,9 @@ SUBDIRS = \ tests localedir = $(datadir)/locale -AM_CPPFLAGS = -DLOCALEDIR=\"$(localedir)\" -I$(top_srcdir)/intl +AM_CPPFLAGS = -DDATAROOTDIR=\"$(datarootdir)\" -DLOCALEDIR=\"$(localedir)\" -I$(top_srcdir)/intl LIBS = @LIBINTL@ @LIBS@ -skel.c: flex.skl mkskel.sh flexint.h tables_shared.h - sed 's/m4_/m4postproc_/g; s/m4preproc_/m4_/g' $(srcdir)/flex.skl | $(m4) -P -DFLEX_MAJOR_VERSION=`echo $(VERSION)|cut -f 1 -d .` -DFLEX_MINOR_VERSION=`echo $(VERSION)|cut -f 2 -d .` -DFLEX_SUBMINOR_VERSION=`echo $(VERSION)|cut -f 3 -d .` | sed 's/m4postproc_/m4_/g' | $(SHELL) $(srcdir)/mkskel.sh >skel.c - # Explicitly describe dependencies. # You can recreate this with `gcc -I. -MM *.c' buf.o: buf.c flexdef.h flexint.h @@ -149,7 +153,6 @@ options.o: options.c options.h scanopt.h flexdef.h flexint.h parse.o: parse.c flexdef.h flexint.h tables.h tables_shared.h scan.o: scan.c flexdef.h flexint.h parse.h scanopt.o: scanopt.c flexdef.h flexint.h scanopt.h -skel.o: skel.c flexdef.h flexint.h sym.o: sym.c flexdef.h flexint.h tables.o: tables.c flexdef.h flexint.h tables.h tables_shared.h tables_shared.o: tables_shared.c flexdef.h flexint.h tables.h \ diff --git a/buf.c b/buf.c index e5deb4e..3580d53 100644 --- a/buf.c +++ b/buf.c @@ -51,6 +51,7 @@ struct Buf defs_buf; /**< for #define's autogenerated. List of strings. */ struct Buf yydmap_buf; /**< string buffer to hold yydmap elements */ struct Buf m4defs_buf; /**< m4 definitions. List of strings. */ struct Buf top_buf; /**< contains %top code. String buffer. */ +struct Buf bottom_buf; /**< contains %bottom code. String buffer. */ struct Buf *buf_print_strings(struct Buf * buf, FILE* out) { @@ -73,7 +74,7 @@ struct Buf *buf_prints (struct Buf *buf, const char *fmt, const char *s) char *t; size_t tsz; - t = flex_alloc (tsz = strlen (fmt) + strlen (s) + 1); +t = (char*)flex_alloc (tsz = strlen (fmt) + strlen (s) + 1); if (!t) flexfatal (_("Allocation of buffer to print string failed")); snprintf (t, tsz, fmt, s); @@ -90,22 +91,15 @@ struct Buf *buf_prints (struct Buf *buf, const char *fmt, const char *s) */ struct Buf *buf_linedir (struct Buf *buf, const char* filename, int lineno) { - char *dst, *src, *t; - - t = flex_alloc (strlen ("#line \"\"\n") + /* constant parts */ - 2 * strlen (filename) + /* filename with possibly all backslashes escaped */ - (int) (1 + log10 (abs (lineno))) + /* line number */ - 1); /* NUL */ - if (!t) - flexfatal (_("Allocation of buffer for line directive failed")); - for (dst = t + sprintf (t, "#line %d \"", lineno), src = filename; *src; *dst++ = *src++) - if (*src == '\\') /* escape backslashes */ - *dst++ = '\\'; - *dst++ = '"'; - *dst++ = '\n'; - *dst = '\0'; - buf = buf_strappend (buf, t); - flex_free (t); + char *t, *fmt = "#line %d \"%s\"\n"; + size_t tsz; + + if (gen_line_dirs) { + t = (char*)flex_alloc (tsz = strlen (fmt) + strlen (filename) + (int)(1 + log10(lineno>=0?lineno:-lineno)) + 1); + snprintf (t, tsz, fmt, lineno, filename); + buf = buf_strappend (buf, t); + flex_free (t); + } return buf; } @@ -123,10 +117,10 @@ struct Buf *buf_concat(struct Buf* dest, const struct Buf* src) /* Appends n characters in str to buf. */ -struct Buf *buf_strnappend (buf, str, n) - struct Buf *buf; - const char *str; - int n; +struct Buf *buf_strnappend ( + struct Buf *buf, + const char *str, + int n) { buf_append (buf, str, n + 1); @@ -137,18 +131,18 @@ struct Buf *buf_strnappend (buf, str, n) } /* Appends characters in str to buf. */ -struct Buf *buf_strappend (buf, str) - struct Buf *buf; - const char *str; +struct Buf *buf_strappend ( + struct Buf *buf, + const char *str) { return buf_strnappend (buf, str, strlen (str)); } /* appends "#define str def\n" */ -struct Buf *buf_strdefine (buf, str, def) - struct Buf *buf; - const char *str; - const char *def; +struct Buf *buf_strdefine ( + struct Buf *buf, + const char *str, + const char *def) { buf_strappend (buf, "#define "); buf_strappend (buf, " "); @@ -162,7 +156,7 @@ struct Buf *buf_strdefine (buf, str, def) /** Pushes "m4_define( [[def]], [[val]])m4_dnl" to end of buffer. * @param buf A buffer as a list of strings. * @param def The m4 symbol to define. - * @param val The definition; may be NULL. + * @param val The definition; may be NULL. If so, val="1". * @return buf */ struct Buf *buf_m4_define (struct Buf *buf, const char* def, const char* val) @@ -171,7 +165,7 @@ struct Buf *buf_m4_define (struct Buf *buf, const char* def, const char* val) char * str; size_t strsz; - val = val?val:""; + val = val?val:"1"; str = (char*)flex_alloc(strsz = strlen(fmt) + strlen(def) + strlen(val) + 2); if (!str) flexfatal (_("Allocation of buffer for m4 def failed")); @@ -202,9 +196,9 @@ struct Buf *buf_m4_undefine (struct Buf *buf, const char* def) } /* create buf with 0 elements, each of size elem_size. */ -void buf_init (buf, elem_size) - struct Buf *buf; - size_t elem_size; +void buf_init ( + struct Buf *buf, + size_t elem_size) { buf->elts = (void *) 0; buf->nelts = 0; @@ -213,14 +207,24 @@ void buf_init (buf, elem_size) } /* frees memory */ -void buf_destroy (buf) - struct Buf *buf; +void buf_destroy ( + struct Buf *buf) { if (buf && buf->elts) flex_free (buf->elts); buf->elts = (void *) 0; } +/* frees buffer memory for a list of (char*) strings. */ +void buf_free (struct Buf *buf) +{ + int i; + char **strings = (char**)buf->elts; + for (i=0; inelts; i++) { + if (strings[i]) flex_free(strings[i]); + } + buf->nelts = 0; +} /* appends ptr[] to buf, grow if necessary. * n_elem is number of elements in ptr[], NOT bytes. @@ -228,10 +232,10 @@ void buf_destroy (buf) * We grow by mod(512) boundaries. */ -struct Buf *buf_append (buf, ptr, n_elem) - struct Buf *buf; - const void *ptr; - int n_elem; +struct Buf *buf_append ( + struct Buf *buf, + const void *ptr, + int n_elem) { int n_alloc = 0; diff --git a/ccl.c b/ccl.c index 8d66bb6..e15da47 100644 --- a/ccl.c +++ b/ccl.c @@ -52,9 +52,7 @@ ccl_contains (const int cclp, const int ch) /* ccladd - add a single character to a ccl */ -void ccladd (cclp, ch) - int cclp; - int ch; +void ccladd (int cclp, int ch) { int ind, len, newpos, i; @@ -225,8 +223,7 @@ int cclinit () /* cclnegate - negate the given ccl */ -void cclnegate (cclp) - int cclp; +void cclnegate (int cclp) { cclng[cclp] = 1; ccl_has_nl[cclp] = !ccl_has_nl[cclp]; @@ -240,9 +237,7 @@ void cclnegate (cclp) * has a non-zero value in the cset array. */ -void list_character_set (file, cset) - FILE *file; - int cset[]; +void list_character_set (FILE *file, int cset[]) { register int i; diff --git a/configure.ac b/configure.ac index 61f5412..5972a45 100644 --- a/configure.ac +++ b/configure.ac @@ -34,12 +34,13 @@ AC_CONFIG_LIBOBJ_DIR([lib]) # checks for programs AM_GNU_GETTEXT([external]) -AM_GNU_GETTEXT_VERSION(0.12) +AM_GNU_GETTEXT_VERSION([0.17]) + AC_PROG_YACC AM_PROG_LEX AC_PROG_CC -AC_PROG_CXX AM_PROG_CC_C_O +AC_PROG_CXX AC_PROG_LN_S AC_PROG_RANLIB AC_PROG_AWK @@ -114,6 +115,7 @@ examples/Makefile examples/fastwc/Makefile examples/manual/Makefile lib/Makefile +m4/Makefile po/Makefile.in tools/Makefile tests/Makefile @@ -133,8 +135,6 @@ tests/test-include-by-push/Makefile tests/test-include-by-reentrant/Makefile tests/test-multiple-scanners-nr/Makefile tests/test-multiple-scanners-r/Makefile -tests/test-noansi-nr/Makefile -tests/test-noansi-r/Makefile tests/test-prefix-nr/Makefile tests/test-prefix-r/Makefile tests/test-pthread/Makefile @@ -164,6 +164,9 @@ tests/test-ccl/Makefile tests/test-extended/Makefile tests/test-c++-yywrap/Makefile tests/test-concatenated-options/Makefile +tests/test-c++-table-opts/Makefile +tests/test-namespace-nr/Makefile +tests/test-no-m4/Makefile dnl --new-test-here-- This line is processed by tests/create-test. ) diff --git a/dfa.c b/dfa.c index b8b68eb..5961713 100644 --- a/dfa.c +++ b/dfa.c @@ -34,10 +34,10 @@ /* declare functions that have forward references */ -void dump_associated_rules PROTO ((FILE *, int)); -void dump_transitions PROTO ((FILE *, int[])); -void sympartition PROTO ((int[], int, int[], int[])); -int symfollowset PROTO ((int[], int, int, int[])); +void dump_associated_rules (FILE *, int); +void dump_transitions (FILE *, int[]); +void sympartition (int[], int, int[], int[]); +int symfollowset (int[], int, int, int[]); /* check_for_backing_up - check a DFA state for backing up @@ -49,9 +49,7 @@ int symfollowset PROTO ((int[], int, int, int[])); * indexed by equivalence class. */ -void check_for_backing_up (ds, state) - int ds; - int state[]; +void check_for_backing_up (int ds, int state[]) { if ((reject && !dfaacc[ds].dfaacc_set) || (!reject && !dfaacc[ds].dfaacc_state)) { /* state is non-accepting */ ++num_backing_up; @@ -96,10 +94,8 @@ void check_for_backing_up (ds, state) * accset[1 .. nacc] is the list of accepting numbers for the DFA state. */ -void check_trailing_context (nfa_states, num_states, accset, nacc) - int *nfa_states, num_states; - int *accset; - int nacc; +void check_trailing_context (int *nfa_states, int num_states, + int *accset, int nacc) { register int i, j; @@ -137,9 +133,7 @@ void check_trailing_context (nfa_states, num_states, accset, nacc) * and writes a report to the given file. */ -void dump_associated_rules (file, ds) - FILE *file; - int ds; +void dump_associated_rules (FILE *file, int ds) { register int i, j; register int num_associated_rules = 0; @@ -187,9 +181,7 @@ void dump_associated_rules (file, ds) * is done to the given file. */ -void dump_transitions (file, state) - FILE *file; - int state[]; +void dump_transitions (FILE *file, int state[]) { register int i, ec; int out_char_set[CSIZE]; @@ -235,8 +227,8 @@ void dump_transitions (file, state) * hashval is the hash value for the dfa corresponding to the state set. */ -int *epsclosure (t, ns_addr, accset, nacc_addr, hv_addr) - int *t, *ns_addr, accset[], *nacc_addr, *hv_addr; +int *epsclosure (int *t, int *ns_addr, int accset[], + int *nacc_addr, int *hv_addr) { register int stkpos, ns, tsp; int numstates = *ns_addr, nacc, hashval, transsym, nfaccnum; @@ -351,7 +343,7 @@ ADD_STATE(state); \ /* increase_max_dfas - increase the maximum number of DFAs */ -void increase_max_dfas () +void increase_max_dfas (void) { current_max_dfas += MAX_DFAS_INCREMENT; @@ -378,7 +370,7 @@ void increase_max_dfas () * dfa starts out in state #1. */ -void ntod () +void ntod (void) { int *accset, ds, nacc, newds; int sym, hashval, numstates, dsize; @@ -541,20 +533,13 @@ void ntod () /* Unless -Ca, declare it "short" because it's a real * long-shot that that won't be large enough. */ - if (gentables) - out_str_dec - ("static yyconst %s yy_nxt[][%d] =\n {\n", - long_align ? "flex_int32_t" : "flex_int16_t", - num_full_table_rows); - else { - out_dec ("#undef YY_NXT_LOLEN\n#define YY_NXT_LOLEN (%d)\n", num_full_table_rows); - out_str ("static yyconst %s *yy_nxt =0;\n", - long_align ? "flex_int32_t" : "flex_int16_t"); - } - + if (long_align) + out ("m4_define([[M4_YY_NXT_TABLE_32BIT]],1)\n"); + out_dec ("m4_define([[M4_YY_NXT_TABLE_LOLEN]],[[%d]])\n", + num_full_table_rows); if (gentables) - outn (" {"); + out ("m4_define([[M4_YY_NXT_TABLE_DATA]],[[\n/*{*/"); /* Generate 0 entries for state #0. */ for (i = 0; i < num_full_table_rows; ++i) { @@ -563,8 +548,9 @@ void ntod () } dataflush (); + if (gentables) - outn (" },\n"); + outn ("/* }*/,"); } /* Create the first states. */ @@ -720,7 +706,7 @@ void ntod () if (gentables) - outn (" {"); + outn ("/* {*/"); /* Supply array's 0-element. */ if (ds == end_of_buffer_state) { @@ -745,7 +731,7 @@ void ntod () dataflush (); if (gentables) - outn (" },\n"); + outn ("/* }*/,\n"); } else if (fullspd) @@ -778,11 +764,14 @@ void ntod () if (fulltbl) { dataend (); + out_dec ("m4_define([[M4_YY_NXT_TABLE_SIZE]],[[/*%d*/]])\n", + yynxt_tbl->td_hilen * num_full_table_rows); + if (tablesext) { yytbl_data_compress (yynxt_tbl); if (yytbl_data_fwrite (&tableswr, yynxt_tbl) < 0) flexerror (_ - ("Could not write yynxt_tbl[][]")); + ("Could not write yynxt_tbl")); } if (yynxt_tbl) { yytbl_data_destroy (yynxt_tbl); @@ -820,8 +809,8 @@ void ntod () * On return, the dfa state number is in newds. */ -int snstods (sns, numstates, accset, nacc, hashval, newds_addr) - int sns[], numstates, accset[], nacc, hashval, *newds_addr; +int snstods (int sns[], int numstates, int accset[], int nacc, + int hashval, int *newds_addr) { int didsort = 0; register int i, j; @@ -942,8 +931,7 @@ int snstods (sns, numstates, accset, nacc, hashval, newds_addr) * int transsym, int nset[current_max_dfa_size] ); */ -int symfollowset (ds, dsize, transsym, nset) - int ds[], dsize, transsym, nset[]; +int symfollowset (int ds[], int dsize, int transsym, int nset[]) { int ns, tsp, sym, i, j, lenccl, ch, numstates, ccllist; @@ -1020,9 +1008,7 @@ int symfollowset (ds, dsize, transsym, nset) * int symlist[numecs], int duplist[numecs] ); */ -void sympartition (ds, numstates, symlist, duplist) - int ds[], numstates; - int symlist[], duplist[]; +void sympartition (int ds[], int numstates, int symlist[], int duplist[]) { int tch, i, j, k, ns, dupfwd[CSIZE + 1], lenccl, cclp, ich; diff --git a/ecs.c b/ecs.c index e2abbe4..1c94b66 100644 --- a/ecs.c +++ b/ecs.c @@ -74,8 +74,7 @@ void ccl2ecl () * Returned is the number of classes. */ -int cre8ecs (fwd, bck, num) - int fwd[], bck[], num; +int cre8ecs (int fwd[], int bck[], int num) { int i, j, numcl; @@ -112,9 +111,8 @@ int cre8ecs (fwd, bck, num) * NUL_mapping is the value which NUL (0) should be mapped to. */ -void mkeccl (ccls, lenccl, fwd, bck, llsiz, NUL_mapping) - Char ccls[]; - int lenccl, fwd[], bck[], llsiz, NUL_mapping; +void mkeccl (Char ccls[], int lenccl, int fwd[], int bck[], + int llsiz, int NUL_mapping) { int cclp, oldec, newec; int cclm, i, j; @@ -201,8 +199,7 @@ void mkeccl (ccls, lenccl, fwd, bck, llsiz, NUL_mapping) /* mkechar - create equivalence class for single character */ -void mkechar (tch, fwd, bck) - int tch, fwd[], bck[]; +void mkechar (int tch, int fwd[], int bck[]) { /* If until now the character has been a proper subset of * an equivalence class, break it away to create a new ec diff --git a/filter.c b/filter.c index c82f7f8..d9234fd 100644 --- a/filter.c +++ b/filter.c @@ -22,11 +22,12 @@ /* PURPOSE. */ #include "flexdef.h" +#if 0 static const char * check_4_gnu_m4 = "m4_dnl ifdef(`__gnu__', ," "`errprint(Flex requires GNU M4. Set the PATH or set the M4 environment variable to its path name.)" " m4exit(2)')\n"; - +#endif /** global chain. */ struct filter *output_chain = NULL; @@ -184,7 +185,7 @@ clearerr(stdin); if ((r = chain->filter_func (chain)) == -1) flexfatal (_("filter_func failed")); - exit (0); + exit (EXIT_SUCCESS); } else { execvp (chain->argv[0], @@ -193,7 +194,7 @@ clearerr(stdin); chain->argv[0]); } - exit (1); + exit (EXIT_FAILURE); } /* Parent */ @@ -230,6 +231,7 @@ int filter_truncate (struct filter *chain, int max_len) /** Splits the chain in order to write to a header file. * Similar in spirit to the 'tee' program. * The header file name is in extra. + * FIXME: actually never returns. * @return 0 (zero) on success, and -1 on failure. */ int filter_tee_header (struct filter *chain) @@ -267,29 +269,24 @@ int filter_tee_header (struct filter *chain) */ if (write_header) { - fputs (check_4_gnu_m4, to_h); - fputs ("m4_changecom`'m4_dnl\n", to_h); - fputs ("m4_changequote`'m4_dnl\n", to_h); - fputs ("m4_changequote([[,]])[[]]m4_dnl\n", to_h); - fputs ("m4_define([[M4_YY_NOOP]])[[]]m4_dnl\n", to_h); - fputs ("m4_define( [[M4_YY_IN_HEADER]],[[]])m4_dnl\n", - to_h); - fprintf (to_h, "#ifndef %sHEADER_H\n", prefix); - fprintf (to_h, "#define %sHEADER_H 1\n", prefix); - fprintf (to_h, "#define %sIN_HEADER 1\n\n", prefix); - fprintf (to_h, - "m4_define( [[M4_YY_OUTFILE_NAME]],[[%s]])m4_dnl\n", - headerfilename ? headerfilename : ""); - + fprintf(to_h, + "m4_divert(-1)\n" + "m4_define(`M4_YY_IN_HEADER',`')\n" + "m4_define(`M4_FLEX_INCLUDE',`%s')\n" + "m4_define(`M4_YY_INFILE_NAME',`%s')\n" + "m4_define(`M4_YY_OUTFILE_NAME',`%s')\n", + flex_include_path, + infilename ? infilename : "", + headerfilename ? headerfilename : ""); } - - fputs (check_4_gnu_m4, to_c); - fputs ("m4_changecom`'m4_dnl\n", to_c); - fputs ("m4_changequote`'m4_dnl\n", to_c); - fputs ("m4_changequote([[,]])[[]]m4_dnl\n", to_c); - fputs ("m4_define([[M4_YY_NOOP]])[[]]m4_dnl\n", to_c); - fprintf (to_c, "m4_define( [[M4_YY_OUTFILE_NAME]],[[%s]])m4_dnl\n", - outfilename ? outfilename : ""); + fprintf(to_c, + "m4_divert(-1)\n" + "m4_define(`M4_FLEX_INCLUDE',`%s')\n" + "m4_define(`M4_YY_INFILE_NAME',`%s')\n" + "m4_define(`M4_YY_OUTFILE_NAME',`%s')\n", + flex_include_path, + infilename ? infilename : "", + outfilename ? outfilename : ""); buf = (char *) flex_alloc (readsz); if (!buf) @@ -301,15 +298,6 @@ int filter_tee_header (struct filter *chain) } if (write_header) { - fprintf (to_h, "\n"); - - /* write a fake line number. It will get fixed by the linedir filter. */ - fprintf (to_h, "#line 4000 \"M4_YY_OUTFILE_NAME\"\n"); - - fprintf (to_h, "#undef %sIN_HEADER\n", prefix); - fprintf (to_h, "#endif /* %sHEADER_H */\n", prefix); - fputs ("m4_undefine( [[M4_YY_IN_HEADER]])m4_dnl\n", to_h); - fflush (to_h); if (ferror (to_h)) lerrsf (_("error writing output file %s"), @@ -359,7 +347,15 @@ int filter_fix_linedirs (struct filter *chain) while (fgets (buf, readsz, stdin)) { regmatch_t m[10]; - +#if 0 + /* Delete all #line directives when they are disabled, to + * handle any line directives inserted before "%option noline" + */ + if (!gen_line_dirs && !strncmp(buf,"#line ",6)) { + buf[0] = '\n'; + buf[1] = 0; + } else +#endif /* Check for #line directive. */ if (buf[0] == '#' && regexec (®ex_linedir, buf, 3, m, 0) == 0) { @@ -441,4 +437,38 @@ int filter_fix_linedirs (struct filter *chain) return 0; } -/* vim:set expandtab cindent tabstop=4 softtabstop=4 shiftwidth=4 textwidth=0: */ +int filter_check_errors (struct filter *chain) +{ + char *buf; + const int readsz = 512; + + if (!chain) + return 0; + + buf = (char *) flex_alloc (readsz); + + while (fgets (buf, readsz, stdin)) { + if (strncmp(buf,"#error ",7)==0) { + flexerror (_(&buf[7])); + } + fputs (buf, stdout); + if (strspn(buf," \t\r\n")"); + + else if (fclose (stdout)) + lerrsf (_("error closing output file %s"), + outfilename ? outfilename : ""); + + return 0; +} + +/* vim:set noexpandtab cindent tabstop=4 softtabstop=4 shiftwidth=4 textwidth=0: */ diff --git a/flex_code_macros.m4 b/flex_code_macros.m4 new file mode 100644 index 0000000..a27a19e --- /dev/null +++ b/flex_code_macros.m4 @@ -0,0 +1,417 @@ +#=================================================================== +m4_dnl /* Generate the code to find the next compressed-table state. */ +m4_define([[M4_GEN_NEXT_COMPRESSED_STATE]], +[[ + register YY_CHAR yy_c = $1; + +m4_dnl /* Save the backing-up info \before/ computing the next state +m4_dnl * because we always compute one more state than needed - we +m4_dnl * always proceed until we reach a jam state +m4_dnl */ +M4_GEN_BACKING_UP() + + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + m4_ifdef([[M4_YY_META_ECS]], + [[ +m4_dnl /* Templates are arranged so that they never chain +m4_dnl * to one another. This means we can afford to make a +m4_dnl * very simple test to see if we need to convert to +m4_dnl * yy_c's meta-equivalence class without worrying +m4_dnl * about erroneously looking up the meta-equivalence +m4_dnl * class twice +m4_dnl */ +m4_dnl /* lastdfa + 2 is the beginning of the templates */ + if ( yy_current_state >= (YY_LASTDFA+2) ) + yy_c = yy_meta[(unsigned int) yy_c]; + ]]) + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; +]]) +#=================================================================== +m4_dnl /* Generate the code to find the start state. */ +m4_define([[M4_GEN_START_STATE]], +[[ + m4_ifdef( [[M4_YY_FULLSPD]], + [[ + m4_ifdef( [[M4_YY_BOL_NEEDED]], + [[ + yy_current_state = yy_start_state_list[yy_start + YY_AT_BOL()]; + ]], + [[ + yy_current_state = yy_start_state_list[yy_start]; + ]]) + ]], + [[ + yy_current_state = yy_start; + m4_ifdef( [[M4_YY_BOL_NEEDED]], + [[ + yy_current_state += YY_AT_BOL(); + ]]) + m4_ifdef( [[M4_YY_USES_REJECT]],[[m4_dnl /* Set up for storing up states. */ + yy_state_ptr = yy_state_buf; + *yy_state_ptr++ = yy_current_state; + ]]) + ]]) +]]) +#=================================================================== +m4_ifdef([[M4_YY_NEED_BACKING_UP]], +[[ + m4_define([[M4_GEN_BACKING_UP]], + [[ + m4_ifdef( [[M4_YY_FULLSPD]], + [[ + if ( yy_current_state[-1].yy_nxt ) + ]], + [[ + if ( yy_accept[yy_current_state] ) + ]]) + { + yy_last_accepting_state = yy_current_state; + yy_last_accepting_cpos = yy_cp; + } + ]]) +]], +[[ + m4_define([[M4_GEN_BACKING_UP]],[[]]) +]]) +#=================================================================== +# Generate the code to find the next match. +# NOTE - changes in here should be reflected in gen_next_state() and +# gen_NUL_trans(). +m4_ifdef([[M4_YY_ECS]], +[[ + m4_define([[M4_CHARMAP1]],[[yy_ec[YY_SC_TO_UI(*yy_cp)] ]]) + m4_define([[M4_CHARMAP2]],[[yy_ec[YY_SC_TO_UI(*(++yy_cp))] ]]) +]], +[[ + m4_define([[M4_CHARMAP1]],[[YY_SC_TO_UI(*yy_cp)]]) + m4_define([[M4_CHARMAP2]],[[YY_SC_TO_UI(*(++yy_cp))]]) +]]) +#=================================================================== +m4_define([[M4_GEN_NEXT_MATCH]], +[[ + m4_ifdef( [[M4_YY_FULLTBL]], +[[ + while ( (yy_current_state = yy_nxt[yy_current_state*YY_NXT_LOLEN + ]]M4_CHARMAP1[[ ]) > 0 ) + { +M4_GEN_BACKING_UP() + ++yy_cp; + } + yy_current_state = -yy_current_state; + ]], + [[ + m4_ifdef([[M4_YY_FULLSPD]], + [[ + { + register const struct yy_trans_info *yy_trans_info; + register YY_CHAR yy_c; + for ( yy_c = M4_CHARMAP1; + (yy_trans_info = &yy_current_state[(unsigned int) yy_c])->yy_verify == yy_c; + yy_c = M4_CHARMAP2) + { +M4_GEN_BACKING_UP() + yy_current_state += yy_trans_info->yy_nxt; + } + } + ]],[[ m4_dnl else COMPRESSED + do { +M4_GEN_NEXT_STATE(0) + ++yy_cp; + } + m4_ifdef([[M4_YY_INTERACTIVE]], + [[ + while ( yy_base[yy_current_state] != YY_JAMBASE ); + ]], + [[ + while ( yy_current_state != YY_JAMSTATE ); + m4_ifdef([[M4_YY_USES_REJECT]],, + [[ +/* Do the guaranteed-needed backing up to figure out the match. */ + yy_cp = yy_last_accepting_cpos; + yy_current_state = yy_last_accepting_state; + ]]) + ]]) + ]]) + ]]) +]]) +#=================================================================== +m4_dnl /* Generate the code to find the action number. */ +m4_define([[M4_GEN_FIND_ACTION_NUMBER]], +[[ + m4_if_elseif([[M4_YY_FULLSPD]], + [[ + yy_act = yy_current_state[-1].yy_nxt; + ]], + [[M4_YY_FULLTBL]], + [[ + yy_act = yy_accept[yy_current_state]; + ]], + [[M4_YY_USES_REJECT]], + [[ + yy_current_state = *--yy_state_ptr; + yy_lp = yy_accept[yy_current_state]; + +find_rule: /* we branch to this label when backing up */ + + for ( ; ; ) /* until we find what rule we matched */ + { + + if ( yy_lp && yy_lp < yy_accept[yy_current_state + 1] ) + { + yy_act = yy_acclist[yy_lp]; + + m4_ifdef( [[M4_YY_VARIABLE_TRAILING_CONTEXT_RULES]], + [[ + if ( yy_act & YY_TRAILING_HEAD_MASK || + yy_looking_for_trail_begin ) + { + if ( yy_act == yy_looking_for_trail_begin ) + { + yy_looking_for_trail_begin = 0; + yy_act &= ~YY_TRAILING_HEAD_MASK; + break; + } + } + else if ( yy_act & YY_TRAILING_MASK ) + { + yy_looking_for_trail_begin = yy_act & ~YY_TRAILING_MASK; + yy_looking_for_trail_begin |= YY_TRAILING_HEAD_MASK; + + m4_ifdef([[M4_YY_REAL_REJECT]], + [[ + /* Remember matched text in case we back up + * due to REJECT. + */ + yy_full_match = yy_cp; + yy_full_state = yy_state_ptr; + yy_full_lp = yy_lp; + ]]) + } + else + { + yy_full_match = yy_cp; + yy_full_state = yy_state_ptr; + yy_full_lp = yy_lp; + break; + } + + ++yy_lp; + goto find_rule; + + } + ]], + [[ + /* Remember matched text in case we back up due to + * trailing context plus REJECT. + */ + { + yy_full_match = yy_cp; + break; + } + ]]) + + } + --yy_cp; + + /* We could consolidate the following two lines with those at + * the beginning, but at the cost of complaints that we're + * branching inside a loop. + */ + yy_current_state = *--yy_state_ptr; + yy_lp = yy_accept[yy_current_state]; + } + ]], + [[m4_dnl else compressed, no reject + yy_act = yy_accept[yy_current_state]; + m4_ifdef([[M4_YY_INTERACTIVE]], + [[ +m4_dnl /* Do the guaranteed-needed backing up to figure out +m4_dnl * the match. +m4_dnl */ + if ( yy_act == 0 ) + { /* have to back up */ + yy_cp = yy_last_accepting_cpos; + yy_current_state = yy_last_accepting_state; + yy_act = yy_accept[yy_current_state]; + } + ]]) + ]]) +]]) + +#=================================================================== +m4_dnl /* Generate the code to find the next state. */ +m4_dnl /* NOTE - changes in here should be reflected in gen_next_match() */ +# M4_GEN_NEXT_STATE(bool worry_about_NULs) +# ---------------------------------------- +m4_define([[M4_GEN_NEXT_STATE]], +[[ + m4_if(($1 && !m4_defined([[M4_YY_NULTRANS]])), + [[ + m4_ifdef([[M4_YY_ECS]], + [[ + m4_define([[M4_CHARMAP]],[[(*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : YY_NUL_EC)]]) + ]], + [[ + m4_define([[M4_CHARMAP]],[[(*yy_cp ? YY_SC_TO_UI(*yy_cp) : YY_NUL_EC)]]) + ]]) + ]], + [[ + m4_ifdef([[M4_YY_ECS]], + [[ + m4_define([[M4_CHARMAP]],[[yy_ec[YY_SC_TO_UI(*yy_cp)] ]]) + ]], + [[ + m4_define([[M4_CHARMAP]],[[YY_SC_TO_UI(*yy_cp)]]) + ]]) + ]]) + m4_if(($1 && m4_defined([[M4_YY_NULTRANS]])), + [[ + m4_ifdef([[M4_YY_COMPRESSED]], + [[ +m4_dnl /* Compressed tables back up *before* they match. */ +M4_GEN_BACKING_UP() + ]]) + if ( *yy_cp ) + { + ]]) + m4_ifdef([[M4_YY_FULLTBL]], + [[ + yy_current_state = yy_nxt[yy_current_state*YY_NXT_LOLEN + M4_CHARMAP]; + ]], + [[ + m4_ifdef([[M4_YY_FULLSPD]], + [[ + yy_current_state += yy_current_state[M4_CHARMAP].yy_nxt; + ]], + [[ +M4_GEN_NEXT_COMPRESSED_STATE(M4_CHARMAP) + ]]) + ]]) + m4_if(($1 && m4_defined([[M4_YY_NULTRANS]])), + [[ + } + else + yy_current_state = yy_nul_trans[yy_current_state]; + ]]) + m4_ifdef([[M4_YY_COMPRESSED]],, + [[ +M4_GEN_BACKING_UP() + ]]) + m4_ifdef([[M4_YY_USES_REJECT]], +[[ + *yy_state_ptr++ = yy_current_state; + ]]) +]]) + +#=================================================================== +m4_dnl /* Generate the code to make a NUL transition. */ +m4_dnl /* NOTE - changes in here should be reflected in gen_next_match() +m4_dnl * Only generate a definition for "yy_cp" if we'll generate code +m4_dnl * that uses it. Otherwise lint and the like complain. +m4_dnl */ +m4_define([[M4_GEN_NUL_TRANSITION]], +[[ + m4_if((m4_defined([[M4_YY_NEED_BACKING_UP]]) && (!m4_defined([[M4_YY_NULTRANS]]) || + m4_defined([[M4_YY_FULLSPD]]) || m4_defined([[M4_YY_FULLTBL]]))), + [[ +m4_dnl /* We're going to need yy_cp lying around for the call +m4_dnl * below to gen_backing_up(). +m4_dnl */ + register char *yy_cp = yy_c_buf_p; + ]]) + + m4_if_elseif([[M4_YY_NULTRANS]], + [[ + yy_current_state = yy_nul_trans[yy_current_state]; + yy_is_jam = (yy_current_state == 0); + ]],[[M4_YY_FULLTBL]], + [[ + yy_current_state = yy_nxt[yy_current_state*YY_NXT_LOLEN + YY_NUL_EC]; + yy_is_jam = (yy_current_state <= 0); + ]],[[M4_YY_FULLSPD]], + [[ + register int yy_c = YY_NUL_EC; + register const struct yy_trans_info *yy_trans_info; + yy_trans_info = &yy_current_state[(unsigned int) yy_c]; + yy_current_state += yy_trans_info->yy_nxt; + yy_is_jam = (yy_trans_info->yy_verify != yy_c); + ]], + [[ +M4_GEN_NEXT_COMPRESSED_STATE([[YY_NUL_EC]]) + yy_is_jam = (yy_current_state == YY_JAMSTATE); + m4_ifdef([[M4_YY_REJECT]], + [[ +m4_dnl /* Only stack this state if it's a transition we +m4_dnl * actually make. If we stack it on a jam, then +m4_dnl * the state stack and yy_c_buf_p get out of sync. +m4_dnl */ + if ( ! yy_is_jam ) + *yy_state_ptr++ = yy_current_state; + ]]) + ]]) +m4_dnl /* If we've entered an accepting state, back up; note that +m4_dnl * compressed tables have *already* done such backing up, so +m4_dnl * we needn't bother with it again. +m4_dnl */ + m4_if((m4_defined([[M4_YY_NEED_BACKING_UP]]) && !m4_defined([[M4_YY_COMPRESSED]])), + [[ + if ( ! yy_is_jam ) + { +M4_GEN_BACKING_UP() + } + ]]) +]]) + +m4_dnl Define the default C code for YY_INPUT: +m4_ifdef( [[M4_YY_USE_READ]], +[[ + m4_define([[M4_YY_INPUT]], + [[ + errno=0; + while ( (result = read( fileno(yyin), (char *) buf, max_size )) < 0 ) + { + if ( errno != EINTR) + { + YY_FATAL_ERROR("input in flex scanner failed"); + break; + } + errno=0; + clearerr(yyin); + } + ]]) +]], +[[ + m4_define([[M4_YY_INPUT]], + [[ + if ( YY_CURRENT_BUFFER->is_interactive ) + { + int c = '*'; + int n; + for( n = 0; n < (int)max_size && + (c = getc( yyin )) != EOF && c != '\n'; ++n ) + buf[n] = (char) c; + if ( c == '\n' ) + buf[n++] = (char) c; + if ( c == EOF && ferror( yyin ) ) + YY_FATAL_ERROR("input in flex scanner failed"); + result = n; + } + else + { + errno=0; + while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) + { + if ( errno != EINTR) + { + YY_FATAL_ERROR("input in flex scanner failed"); + break; + } + errno=0; + clearerr(yyin); + } + } + ]]) +]]) +#=================================================================== diff --git a/flex_functions.m4 b/flex_functions.m4 new file mode 100644 index 0000000..36dfaf2 --- /dev/null +++ b/flex_functions.m4 @@ -0,0 +1,1740 @@ +m4_dnl -*-C-*- vim:set ft=cxxm4:set noexpandtab cindent: + +m4_if_cxx_only([[ +/***************************************************************************/ + +/** M4_YY_LEX_CLASS constructor. + * @param arg_yyin The initial input buffer. + * @param arg_yyout The initial output buffer. + * @result new M4_YY_LEX_CLASS object. + */ +M4_FUNC_DEF(,M4_YY_LEX_CLASS, M4_INSTREAM* in, M4_OUTSTREAM* out) +{ + init_globals(); + this->yyin = in; + this->yyout = out; +} + +/** M4_YY_LEX_CLASS destructor. + */ +M4_FUNC_DEF(,~M4_YY_LEX_CLASS) +{ + (void) yylex_destroy(); +} + +/* Definitions for additional C++-only functions. */ +M4_FUNC_DEF(void, switch_streams, M4_INSTREAM* new_in, M4_OUTSTREAM* new_out) +{ + if ( new_in ) { + yy_delete_buffer(YY_CURRENT_BUFFER); + yy_switch_to_buffer(yy_create_buffer(new_in, YY_BUF_SIZE)); + } + if ( new_out ) yyout = new_out; +} + + m4_if_cxx_streamio([[ +M4_FUNC_DEF(int, LexerInput, char* buf, int max_size) +{ + if ( yyin->eof() || yyin->fail() ) return 0; + if ( YY_CURRENT_BUFFER->is_interactive ) + { + int n; + for( n = 0; n < max_size; n++ ) + { + buf[n] = yyin->get(); + if (buf[n] == '\n') return n+1; + if ( yyin->eof() ) return n; + if ( yyin->bad() ) + { + YY_NONFATAL_ERROR("input in flex scanner failed"); + return -1; + } + } + return n; + } + else + { + (void) yyin->read( buf, max_size ); + if ( yyin->bad() ) return -1; + else return yyin->gcount(); + } +} + ]], + [[ +M4_FUNC_DEF(int, LexerInput, char* buf, int max_size) +{ + int result; +M4_YY_INPUT() + return result; +} + ]]) +]])m4_dnl endif C++ only + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +M4_FUNC_DEF(static int, yy_get_next_buffer) +{ + register char *dest = YY_CURRENT_BUFFER->ch_buf; + register char *source = yytext_ptr; + register int number_to_move, i; + int ret_val; + + if ( yy_c_buf_p > &YY_CURRENT_BUFFER->ch_buf[yy_n_chars + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed"); + + if ( YY_CURRENT_BUFFER->fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1; + + for( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( YY_CURRENT_BUFFER->buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER->n_chars = yy_n_chars = 0; + + else + { + int num_to_read = + YY_CURRENT_BUFFER->buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + m4_ifdef( [[M4_YY_USES_REJECT]], + [[ + YY_FATAL_ERROR( +"input buffer overflow, can't enlarge buffer because scanner uses REJECT"); + ]], + [[ + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = YY_CURRENT_BUFFER; + + int yy_c_buf_p_offset = + (int) (yy_c_buf_p - b->ch_buf); + + if ( b->is_our_buffer ) + { + int new_size = b->buf_size * 2; + + if ( new_size <= 0 ) + b->buf_size += b->buf_size / 8; + else + b->buf_size *= 2; + + b->ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + yyrealloc( (void *) b->ch_buf, + b->buf_size + 2 ); + } + else + /* Can't grow it, we don't own it. */ + b->ch_buf = 0; + + if ( ! b->ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow"); + + yy_c_buf_p = &b->ch_buf[yy_c_buf_p_offset]; + + num_to_read = YY_CURRENT_BUFFER->buf_size - + number_to_move - 1; + ]]) + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER->ch_buf[number_to_move]), + yy_n_chars, (size_t) num_to_read ); + + YY_CURRENT_BUFFER->n_chars = yy_n_chars; + } + + if ( yy_n_chars == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart( yyin); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER->buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + if ((yy_size_t) (yy_n_chars + number_to_move) > YY_CURRENT_BUFFER->buf_size) { + /* Extend the array by 50%, plus the number we really need. */ + yy_size_t new_size = yy_n_chars + number_to_move + (yy_n_chars >> 1); + YY_CURRENT_BUFFER->ch_buf = (char *) yyrealloc( + (void *) YY_CURRENT_BUFFER->ch_buf, new_size ); + if ( ! YY_CURRENT_BUFFER->ch_buf ) + YY_FATAL_ERROR("out of dynamic memory in yy_get_next_buffer()"); + } + + yy_n_chars += number_to_move; + YY_CURRENT_BUFFER->ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER->ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; + + yytext_ptr = &YY_CURRENT_BUFFER->ch_buf[0]; + + return ret_val; +} + +/* yy_get_previous_state - get the state just before the EOB char was reached */ +M4_FUNC_DEF(static yy_state_type, yy_get_previous_state) +{ + register yy_state_type yy_current_state; + register char *yy_cp; + +M4_GEN_START_STATE() + + for( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp ) + { +M4_GEN_NEXT_STATE(1) + } + + return yy_current_state; +} + + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + /* NOTE: the reentrant object may be unreferenced, depending upon build options. */ +M4_FUNC_DEF(static yy_state_type, yy_try_NUL_trans, yy_state_type yy_current_state) +{ + register int yy_is_jam; + +M4_GEN_NUL_TRANSITION() + + return yy_is_jam ? 0 : yy_current_state; +} + +m4_ifdef( [[M4_YY_NO_UNPUT]],, +[[ +M4_FUNC_DEF(static void, yyunput, int c, register char *yy_bp) +{ + register char *yy_cp; + + if (!yy_init) + yylex_init_state(); + + yy_cp = yy_c_buf_p; + + /* undo effects of setting up yytext */ + *yy_cp = yy_hold_char; + + if ( yy_cp < YY_CURRENT_BUFFER->ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + register int number_to_move = yy_n_chars + 2; + register char *dest = &YY_CURRENT_BUFFER->ch_buf[ + YY_CURRENT_BUFFER->buf_size + 2]; + register char *source = + &YY_CURRENT_BUFFER->ch_buf[number_to_move]; + + while ( source > YY_CURRENT_BUFFER->ch_buf ) + *--dest = *--source; + + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + YY_CURRENT_BUFFER->n_chars = + yy_n_chars = YY_CURRENT_BUFFER->buf_size; + + if ( yy_cp < YY_CURRENT_BUFFER->ch_buf + 2 ) + YY_FATAL_ERROR("flex scanner push-back overflow"); + } + + *--yy_cp = (char) c; +m4_ifdef( [[M4_YY_USE_LINENO]], +[[ + if ( c == '\n' ) + M4_YY_DECR_LINENO(); +]]) + yytext_ptr = yy_bp; + yy_hold_char = *yy_cp; + yy_c_buf_p = yy_cp; +} +]]) + +#ifndef YY_NO_INPUT +/* Function to read one character from the input stream */ +M4_FUNC_DEF(static int, yyinput) +{ + int c; + + if (!yy_init) + yylex_init_state(); + + *yy_c_buf_p = yy_hold_char; + + if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( yy_c_buf_p < &YY_CURRENT_BUFFER->ch_buf[yy_n_chars] ) + /* This was really a NUL. */ + *yy_c_buf_p = '\0'; + + else + { /* need more input */ + int offset = yy_c_buf_p - yytext_ptr; + ++yy_c_buf_p; + + switch( yy_get_next_buffer( ) ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart( yyin); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap( ) ) + return EOF; + + if ( ! yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; + return input(); + } + + case EOB_ACT_CONTINUE_SCAN: + yy_c_buf_p = yytext_ptr + offset; + break; + } + } + } + + c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */ + *yy_c_buf_p = '\0'; /* preserve yytext */ + yy_hold_char = *++yy_c_buf_p; +m4_ifdef( [[M4_YY_BOL_NEEDED]], +[[ + /* Update BOL inside of input(). */ + YY_CURRENT_BUFFER->at_bol = ( c == '\n' ); +]]) +m4_ifdef( [[M4_YY_USE_LINENO]], +[[ + /* Update yylineno inside of input(). */ + if ( c == '\n' ) + M4_YY_INCR_LINENO(); +]]) + return c; +} +#endif /* ifndef YY_NO_INPUT */ + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * M4_YY_OBJECT_PARAM_DOC + * @note This function does not reset the start condition to @c INITIAL . + */ +M4_FUNC_DEF(void, yyrestart, M4_INSTREAM *input_file) +{ + + if ( ! YY_CURRENT_BUFFER ) + { + yyensure_buffer_stack(); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer( yyin, YY_BUF_SIZE); + } + + yy_init_buffer( YY_CURRENT_BUFFER, input_file); + yy_load_buffer_state( ); +} + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * M4_YY_OBJECT_PARAM_DOC + */ +M4_FUNC_DEF(void, yy_switch_to_buffer, YY_BUFFER_STATE new_buffer) +{ + + /* TODO. We should be able to replace this entire function body + * with + * yypop_buffer_state(); + * yypush_buffer_state(new_buffer); + */ + yyensure_buffer_stack(); + if ( YY_CURRENT_BUFFER_LVALUE == new_buffer ) + return; + + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *yy_c_buf_p = yy_hold_char; + YY_CURRENT_BUFFER->buf_pos = yy_c_buf_p; + YY_CURRENT_BUFFER->n_chars = yy_n_chars; + } + + YY_CURRENT_BUFFER_LVALUE = new_buffer; + yy_load_buffer_state( ); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + yy_did_buffer_switch_on_eof = 1; +} + +M4_FUNC_DEF(static void, yy_load_buffer_state) +{ + yy_n_chars = YY_CURRENT_BUFFER->n_chars; + yytext_ptr = yy_c_buf_p = YY_CURRENT_BUFFER->buf_pos; + yyin = YY_CURRENT_BUFFER->input_file; + yy_hold_char = *yy_c_buf_p; +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * M4_YY_OBJECT_PARAM_DOC + * @return the allocated buffer state. + */ +M4_FUNC_DEF(YY_BUFFER_STATE, yy_create_buffer, M4_INSTREAM *file, int size) +{ + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR("out of dynamic memory in yy_create_buffer()"); + + b->buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->ch_buf = (char *) yyalloc( b->buf_size + 2 ); + if ( ! b->ch_buf ) + YY_FATAL_ERROR("out of dynamic memory in yy_create_buffer()"); + + b->is_our_buffer = 1; + + yy_init_buffer( b, file); + + return b; +} + +/** Destroy the buffer. + * @param b a buffer created with yy_create_buffer() + * M4_YY_OBJECT_PARAM_DOC + */ +M4_FUNC_DEF(void, yy_delete_buffer, YY_BUFFER_STATE b) +{ + + if ( ! b ) + return; + + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; + + if ( b->is_our_buffer ) + yyfree( (void *) b->ch_buf ); + + yyfree( (void *) b ); +} + + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a yyrestart() or at EOF. + */ +M4_FUNC_DEF(static void, yy_init_buffer, YY_BUFFER_STATE b, M4_INSTREAM * file) +{ + int oerrno = errno; + + yy_flush_buffer( b); + + b->input_file = file; + b->fill_buffer = 1; + + /* If b is the current buffer, then yy_init_buffer was _probably_ + * called from yyrestart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->bs_lineno = 1; + b->bs_column = 0; + } + +m4_ifdef( [[M4_YY_ALWAYS_INTERACTIVE]], +[[ + b->is_interactive = 1; +]], +[[ + m4_ifdef( [[M4_YY_NEVER_INTERACTIVE]], + [[ + b->is_interactive = 0; + ]], + [[ + b->is_interactive = YY_ISATTY(file); + ]]) +]]) + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * M4_YY_OBJECT_PARAM_DOC + */ +M4_FUNC_DEF(void, yy_flush_buffer, YY_BUFFER_STATE b) +{ + if ( ! b ) + return; + + b->n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->buf_pos = &b->ch_buf[0]; + + b->at_bol = 1; + b->buffer_status = YY_BUFFER_NEW; + + if ( b == YY_CURRENT_BUFFER ) + yy_load_buffer_state( ); +} + +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * M4_YY_OBJECT_PARAM_DOC + */ +M4_FUNC_DEF(void, yypush_buffer_state, YY_BUFFER_STATE new_buffer) +{ + if (new_buffer == NULL) + return; + + yyensure_buffer_stack(); + + /* This block is copied from yy_switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *yy_c_buf_p = yy_hold_char; + YY_CURRENT_BUFFER->buf_pos = yy_c_buf_p; + YY_CURRENT_BUFFER->n_chars = yy_n_chars; + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + yy_buffer_stack_top++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from yy_switch_to_buffer. */ + yy_load_buffer_state( ); + yy_did_buffer_switch_on_eof = 1; +} + +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * M4_YY_OBJECT_PARAM_DOC + */ +M4_FUNC_DEF(void, yypop_buffer_state) +{ + if (!YY_CURRENT_BUFFER) + return; + + yy_delete_buffer(YY_CURRENT_BUFFER); + YY_CURRENT_BUFFER_LVALUE = NULL; + if (yy_buffer_stack_top > 0) + --yy_buffer_stack_top; + + if (YY_CURRENT_BUFFER) { + yy_load_buffer_state( ); + yy_did_buffer_switch_on_eof = 1; + } +} + +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +M4_FUNC_DEF(static void, yyensure_buffer_stack) +{ + int num_to_alloc; + + if (!yy_buffer_stack) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; + yy_buffer_stack = (struct yy_buffer_state**) + yyalloc(num_to_alloc * sizeof(struct yy_buffer_state*)); + + if ( ! yy_buffer_stack ) + YY_FATAL_ERROR("out of dynamic memory in yyensure_buffer_stack()"); + + + memset(yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + yy_buffer_stack_max = num_to_alloc; + yy_buffer_stack_top = 0; + return; + } + + if (yy_buffer_stack_top >= (yy_buffer_stack_max) - 1){ + + /* Increase the buffer to prepare for a possible push. */ + int grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = yy_buffer_stack_max + grow_size; + yy_buffer_stack = (struct yy_buffer_state**) + yyrealloc(yy_buffer_stack, + num_to_alloc * sizeof(struct yy_buffer_state*)); + + if ( ! yy_buffer_stack ) + YY_FATAL_ERROR("out of dynamic memory in yyensure_buffer_stack()"); + + /* zero only the new slots.*/ + memset(yy_buffer_stack + yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*)); + yy_buffer_stack_max = num_to_alloc; + } +} + + +m4_if_c_only([[ +m4_ifdef( [[M4_YY_NO_SCAN_BUFFER]],, +[[ +/** Setup the input buffer state to scan directly from a user-specified character buffer. + * @param base the character buffer + * @param size the size in bytes of the character buffer + * M4_YY_OBJECT_PARAM_DOC + * @return the newly allocated buffer state object. + */ +M4_FUNC_DEF(YY_BUFFER_STATE, yy_scan_buffer, char * base, yy_size_t size) +{ + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; + + b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR("out of dynamic memory in yy_scan_buffer()"); + + b->buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->buf_pos = b->ch_buf = base; + b->is_our_buffer = 0; + b->input_file = 0; + b->n_chars = b->buf_size; + b->is_interactive = 0; + b->at_bol = 1; + b->fill_buffer = 0; + b->buffer_status = YY_BUFFER_NEW; + + yy_switch_to_buffer( b ); + + return b; +} +]]) + + +m4_ifdef( [[M4_YY_NO_SCAN_STRING]],, +[[ +/** Setup the input buffer state to scan a string. The next call to yylex() will + * scan from a @e copy of @a str. + * @param yystr a NUL-terminated string to scan + * M4_YY_OBJECT_PARAM_DOC + * @return the newly allocated buffer state object. + * @note If you want to scan bytes that may contain NUL values, then use + * yy_scan_bytes() instead. + */ +M4_FUNC_DEF(YY_BUFFER_STATE, yy_scan_string, const char * yystr) +{ + + return yy_scan_bytes( yystr, strlen(yystr)); +} +]]) + + +m4_ifdef( [[M4_YY_NO_SCAN_BYTES]],, +[[ +/** Setup the input buffer state to scan the given bytes. The next call to yylex() will + * scan from a @e copy of @a bytes. + * @param bytes the byte buffer to scan + * @param len the number of bytes in the buffer pointed to by @a bytes. + * M4_YY_OBJECT_PARAM_DOC + * @return the newly allocated buffer state object. + */ +M4_FUNC_DEF(YY_BUFFER_STATE, yy_scan_bytes, const char * yybytes, int _yybytes_len) +{ + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = _yybytes_len + 2; + buf = (char *) yyalloc( n ); + if ( ! buf ) + YY_FATAL_ERROR("out of dynamic memory in yy_scan_bytes()"); + + for( i = 0; i < _yybytes_len; ++i ) + buf[i] = yybytes[i]; + + buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; + + b = yy_scan_buffer( buf, n); + if ( ! b ) + YY_FATAL_ERROR("bad buffer in yy_scan_bytes()"); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->is_our_buffer = 1; + + return b; +} +]]) +]]) + + +m4_ifdef( [[M4_YY_NO_PUSH_STATE]],, +[[ +M4_FUNC_DEF(static void, yy_push_state, int new_state) +{ + if ( yy_start_stack_ptr >= yy_start_stack_depth ) + { + yy_size_t new_size; + + yy_start_stack_depth += YY_START_STACK_INCR; + new_size = yy_start_stack_depth * sizeof( int ); + + if ( ! yy_start_stack ) + yy_start_stack = (int *) yyalloc( new_size ); + + else + yy_start_stack = (int *) yyrealloc( + (void *) yy_start_stack, new_size ); + + if ( ! yy_start_stack ) + YY_FATAL_ERROR("out of memory expanding start-condition stack"); + } + + yy_start_stack[yy_start_stack_ptr++] = YY_START; + + BEGIN(new_state); +} +]]) + + +m4_ifdef( [[M4_YY_NO_POP_STATE]],, +[[ +M4_FUNC_DEF(static void, yy_pop_state) +{ + if ( --yy_start_stack_ptr < 0 ) + YY_FATAL_ERROR("start-condition stack underflow"); + + BEGIN(yy_start_stack[yy_start_stack_ptr]); +} +]]) + + +m4_ifdef( [[M4_YY_NO_TOP_STATE]],, +[[ +M4_FUNC_DEF(static int, yy_top_state) +{ + return yy_start_stack[yy_start_stack_ptr - 1]; +} +]]) + +m4_if_cxx_only([[ +M4_FUNC_DEF_NG(static void, LexerClassError, const char* msg) +{ +m4_if_cxx_streamio([[ + std::cerr << msg << std::endl; +]], +[[ + (void) fprintf( stderr, "%s\n", msg ); +]]) + exit( YY_EXIT_FAILURE ); +} +]]) + +M4_FUNC_DEF(static void, yy_fatal_error, const char* msg) +{ +m4_if_cxx_streamio([[ + std::cerr << msg << std::endl; +]], +[[ + (void) fprintf( stderr, "%s\n", msg ); +]]) + exit( YY_EXIT_FAILURE ); +} + +/* Accessor methods(get/set functions) to struct members. */ + +m4_ifdef( [[M4_YY_NO_GET_EXTRA]],, +[[ +/** Get the user-defined data for this scanner. + * M4_YY_OBJECT_PARAM_DOC + */ +M4_FUNC_DEF(YY_EXTRA_TYPE, yyget_extra) +{ + return yyextra; +} +]]) + +m4_ifdef( [[M4_YY_NO_GET_LINENO]],, +[[ +/** Get the current line number. + * M4_YY_OBJECT_PARAM_DOC + */ +M4_FUNC_DEF(int, yyget_lineno) +{ + + m4_if_reentrant([[ + if (! YY_CURRENT_BUFFER) + return 0; + ]]) + return yylineno; +} +]]) + +m4_ifdef( [[M4_YY_NO_GET_COLUMN]],, +[[ +/** Get the current column number. + * M4_YY_OBJECT_PARAM_DOC + */ +M4_FUNC_DEF(int, yyget_column) +{ + + m4_if_reentrant([[ + if (! YY_CURRENT_BUFFER) + return 0; + ]]) + return yycolumn; +} +]]) + +m4_ifdef( [[M4_YY_NO_GET_IN]],, +[[ +/** Get the input stream. + * M4_YY_OBJECT_PARAM_DOC + */ +M4_FUNC_DEF(M4_INSTREAM *, yyget_in) +{ + return yyin; +} +]]) + +m4_ifdef( [[M4_YY_NO_GET_OUT]],, +[[ +/** Get the output stream. + * M4_YY_OBJECT_PARAM_DOC + */ +M4_FUNC_DEF(M4_OUTSTREAM *, yyget_out) +{ + return yyout; +} +]]) + +m4_ifdef( [[M4_YY_NO_GET_LENG]],, +[[ +/** Get the length of the current token. + * M4_YY_OBJECT_PARAM_DOC + */ +M4_FUNC_DEF(int, yyget_leng) +{ + return yyleng; +} +]]) + +/** Get the current token. + * M4_YY_OBJECT_PARAM_DOC + */ +m4_ifdef( [[M4_YY_NO_GET_TEXT]],, +[[ +M4_FUNC_DEF(char *, yyget_text) +{ + return yytext; +} +]]) + +m4_ifdef( [[M4_YY_NO_SET_EXTRA]],, +[[ +/** Set the user-defined data. This data is never touched by the scanner. + * @param user_defined The data to be associated with this scanner. + * M4_YY_OBJECT_PARAM_DOC + */ +M4_FUNC_DEF(void, yyset_extra, YY_EXTRA_TYPE user_defined) +{ + yyextra = user_defined ; +} +]]) + +m4_ifdef( [[M4_YY_NO_SET_LINENO]],, +[[ +/** Set the current line number. + * @param line_number + * M4_YY_OBJECT_PARAM_DOC + */ +M4_FUNC_DEF(void, yyset_lineno, int line_number) +{ + + m4_if_reentrant([[ + /* lineno is only valid if an input buffer exists. */ + if (! YY_CURRENT_BUFFER ) + YY_FATAL_ERROR("yyset_lineno called with no buffer"); + ]]) + yylineno = line_number; +} +]]) + +m4_ifdef( [[M4_YY_NO_SET_COLUMN]],, +[[ +/** Set the current column. + * @param line_number + * M4_YY_OBJECT_PARAM_DOC + */ +M4_FUNC_DEF(void, yyset_column, int column_no) +{ + + m4_if_reentrant([[ + /* column is only valid if an input buffer exists. */ + if (! YY_CURRENT_BUFFER ) + YY_FATAL_ERROR("yyset_column called with no buffer"); + ]]) + yycolumn = column_no; +} +]]) + + +m4_ifdef( [[M4_YY_NO_SET_IN]],, +[[ +/** Set the input stream. This does not discard the current + * input buffer. + * @param in_str A readable stream. + * M4_YY_OBJECT_PARAM_DOC + * @see yy_switch_to_buffer + */ +M4_FUNC_DEF(void, yyset_in, M4_INSTREAM * in_str) +{ + yyin = in_str ; +} +]]) + +m4_ifdef( [[M4_YY_NO_SET_OUT]],, +[[ +M4_FUNC_DEF(void, yyset_out, M4_OUTSTREAM * out_str) +{ + yyout = out_str ; +} +]]) + + +m4_ifdef( [[M4_YY_NO_GET_DEBUG]],, +[[ +M4_FUNC_DEF(int, yyget_debug) +{ + return yy_flex_debug; +} +]]) + +m4_ifdef( [[M4_YY_NO_SET_DEBUG]],, +[[ +M4_FUNC_DEF(void, yyset_debug, int bdebug) +{ + yy_flex_debug = bdebug ; +} +]]) + +m4_ifdef( [[M4_YY_NO_GET_LVAL]],, +[[ +M4_FUNC_DEF(YYSTYPE *, yyget_lval) +{ + return yylval; +} +]]) + +m4_ifdef( [[M4_YY_NO_SET_LVAL]],, +[[ +M4_FUNC_DEF(void, yyset_lval, YYSTYPE * yylval_param) +{ + yylval = yylval_param; +} +]]) + +m4_ifdef( [[M4_YY_NO_GET_LLOC]],, +[[ +M4_FUNC_DEF(YYLTYPE *, yyget_lloc) +{ + return yylloc; +} +]]) + +m4_ifdef( [[M4_YY_NO_SET_LLOC]],, +[[ +M4_FUNC_DEF(void, yyset_lloc, YYLTYPE * yylloc_param) +{ + yylloc = yylloc_param; +} +]]) + + +/* User-visible API */ +m4_if_reentrant([[ +/* yylex_init creates the scanner object itself (a constructor). + * It follows the convention of taking the scanner as the last argument, but + * it is a *pointer* to a scanner, and will be allocated by this call. + */ +M4_FUNC_DEF_NG(int, yylex_init, yyscan_t *yyscanner_return) +{ + yyscan_t yyscanner; + + if (yyscanner_return == 0){ + errno = EINVAL; + return 1; + } +/* yyscanner may be invalid here, unless called from yylex_init_extra. + * If yyalloc() is user-defined, and references the yyscanner object, + * you must use yylex_init_extra(). + */ + yyscanner = *yyscanner_return; + + *yyscanner_return = (yyscan_t) yyalloc( sizeof( struct yyobject_t )); + + if (*yyscanner_return == 0){ + errno = ENOMEM; + return 1; + } + +/* Assign yyscanner to the actual yyscanner object, for use by yy_init_globals */ + yyscanner = *yyscanner_return; + + /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ +m4_ifdef( [[M4_DEBUG_BUILD]], +[[ + memset(yyscanner,0xAA,sizeof(struct yyobject_t)); +]], +[[ + memset(yyscanner,0x00,sizeof(struct yyobject_t)); +]]) + + return yy_init_globals(); +} + + +/* yylex_init_extra has the same functionality as yylex_init, but includes + * an argument to initialize the yyextra pointer. This version is required + * if you supply a yyalloc() function that references the yyextra pointer. + */ +M4_FUNC_DEF_NG(int, yylex_init_extra, YY_EXTRA_TYPE user_defined, yyscan_t *yyscanner_return) +{ + struct yyobject_t dummy_object; + int status; + + yyscan_t yyscanner = (yyscan_t)&dummy_object; + yyset_extra(user_defined); + status = yylex_init(&yyscanner); + + if (!status) { + yyset_extra(user_defined); + *yyscanner_return = yyscanner; + } + + return status; +} +]])m4_dnl end if reentrant + +M4_FUNC_DEF(static int, yy_init_globals) +{ + /* Initialization is the same as for the non-reentrant scanner. + * This function is called from yylex_destroy(), so don't allocate here. + * (Which means that is essentially impossible to get an error here.) + */ +M4_GLOBALS_INIT() + /* For future reference: Set errno on error, since we are called by + * yylex_init(). Currently, no errors are possible. It would be good + * to allocate buffers, but those functions use YY_FATAL_ERROR() instead + * of returning error codes, so it will take a bit of re-writing. + */ + return 0; +} + +M4_FUNC_DEF(void, yylex_init_state) { + if (! (yy_init & YYLEX_INIT_STATE)) { +m4_ifdef( [[M4_YY_USES_REJECT]], +[[ + /* Create the reject buffer large enough to save one state per allowed character. */ + if ( ! yy_state_buf ) + yy_state_buf = (yy_state_type *)yyalloc(YY_STATE_BUF_SIZE); + if ( ! yy_state_buf ) + YY_FATAL_ERROR("out of dynamic memory in yylex()"); +]]) + if ( ! yy_start ) + BEGIN(INITIAL); /* first start state */ + + if ( ! yyin ) + yyin = M4_STDIN; + + if ( ! yyout ) + yyout = M4_STDOUT; + + if ( ! YY_CURRENT_BUFFER ) { + yyensure_buffer_stack(); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer( yyin, YY_BUF_SIZE); + } + + yy_load_buffer_state( ); + + yy_init |= YYLEX_INIT_STATE; + } +} + +/* yylex_destroy is for both reentrant and non-reentrant scanners. */ +M4_FUNC_DEF(int, yylex_destroy) +{ + + /* Pop the buffer stack, destroying each element. */ + while (YY_CURRENT_BUFFER){ + yy_delete_buffer( YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + yypop_buffer_state(); + } + + /* Destroy the stack itself. */ + yyfree(yy_buffer_stack); + yy_buffer_stack = NULL; +m4_ifdef( [[M4_YY_STACK_USED]], +[[ + /* Destroy the start condition stack. */ + yyfree( yy_start_stack ); + yy_start_stack = NULL; +]]) +m4_ifdef( [[M4_YY_USES_REJECT]], +[[ + yyfree( yy_state_buf); + yy_state_buf = NULL; +]]) +m4_if_c_only([[ + m4_if_reentrant([[ + /* Destroy the main struct(reentrant only). */ + yyfree( yyscanner ); + ]], + [[ + /* Reset the globals. This is important in a non-reentrant scanner so the next time + * yylex() is called, initialization will occur. */ + yy_init_globals(); + ]]) +]]) + return 0; +} + + +/* + * Internal utility routines. + */ +m4_dnl This assumes that C++ always has these functions. +m4_if_c_only([[ +m4_ifdef( [[M4_YY_TEXT_IS_ARRAY]], +[[ +M4_FUNC_DEF_NG(static void, yy_flex_strncpy, char* s1, const char *s2, unsigned int nmax) +{ + register unsigned int i; + for( i = 0; i < nmax; ++i ) + s1[i] = s2[i]; +} +]]) + +#ifdef YY_NEED_STRLEN +M4_FUNC_DEF_NG(static int, yy_flex_strlen, const char *s) +{ + register int n; + for( n = 0; s[n]; ++n ) + ; + + return n; +} +#endif +]]) + +m4_ifdef( [[M4_YY_NO_FLEX_ALLOC]],, +[[ +M4_FUNC_DEF(void *, yyalloc, yy_size_t size) +{ + return(void *) malloc( size ); +} +]]) + +m4_ifdef( [[M4_YY_NO_FLEX_REALLOC]],, +[[ +M4_FUNC_DEF(void *, yyrealloc, void *ptr, yy_size_t size) +{ + /* The cast to(char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return(void *) realloc( (char *) ptr, size ); +} +]]) + +m4_ifdef( [[M4_YY_NO_FLEX_FREE]],, +[[ +M4_FUNC_DEF(void, yyfree, void *ptr) +{ + free( (char *) ptr ); /* see yyrealloc() for(char *) cast */ +} +]]) + +m4_if_tables_serialization([[ +m4_dnl File contains code for yytbl_calc_total_len(const struct yytbl_data *tbl) +/* From tables_shared.c */ + +/** Get the number of integers in this table. This is NOT the + * same thing as the number of elements. + * @param td the table + * @return the number of integers in the table + */ +M4_FUNC_DEF_NG(static flex_int32_t, yytbl_calc_total_len, const struct yytbl_data *tbl) +{ + flex_int32_t n; + + /* total number of ints */ + n = tbl->td_lolen; + if (tbl->td_hilen > 0) + n *= tbl->td_hilen; + + if (tbl->td_id == YYTD_ID_TRANSITION) + n *= 2; + return n; +} + +M4_FUNC_DEF_NG(static int, yytbl_read8, void *v, struct yytbl_reader * rd) +{ + errno = 0; +m4_if_cxx_streamio([[ + rd->fp->read((char*)v, sizeof(flex_uint8_t)); + if (rd->fp->bad()) +]], +[[ + if (fread(v, sizeof(flex_uint8_t), 1, rd->fp) != 1) +]]) + { + errno = EIO; + return -1; + } + rd->bread += sizeof(flex_uint8_t); + return 0; +} + +M4_FUNC_DEF_NG(static int, yytbl_read16, void *v, struct yytbl_reader * rd) +{ + errno = 0; +m4_if_cxx_streamio([[ + rd->fp->read((char*)v, sizeof(flex_uint16_t)); + if (rd->fp->bad()) +]], +[[ + if (fread(v, sizeof(flex_uint16_t), 1, rd->fp) != 1) +]]) + { + errno = EIO; + return -1; + } + *((flex_uint16_t *) v) = ntohs(*((flex_uint16_t *) v)); + rd->bread += sizeof(flex_uint16_t); + return 0; +} + +M4_FUNC_DEF_NG(static int, yytbl_read32, void *v, struct yytbl_reader * rd) +{ + errno = 0; +m4_if_cxx_streamio([[ + rd->fp->read((char*)v, sizeof(flex_uint32_t)); + if (rd->fp->bad()) +]], +[[ + if (fread(v, sizeof(flex_uint32_t), 1, rd->fp) != 1) +]]) + { + errno = EIO; + return -1; + } + *((flex_uint32_t *) v) = ntohl(*((flex_uint32_t *) v)); + rd->bread += sizeof(flex_uint32_t); + return 0; +} + +/** Read the header */ +M4_FUNC_DEF(static int, yytbl_hdr_read, struct yytbl_hdr * th, struct yytbl_reader * rd) +{ + int bytes; + memset(th, 0, sizeof(struct yytbl_hdr)); + + if (yytbl_read32 (&(th->th_magic), rd) != 0) + return -1; + + if (th->th_magic != YYTBL_MAGIC){ + M4_YY_GLOBAL_NONFATAL_ERROR("bad magic number"); + return -1; + } + + if (yytbl_read32 (&(th->th_hsize), rd) != 0 + || yytbl_read32 (&(th->th_ssize), rd) != 0 + || yytbl_read16 (&(th->th_flags), rd) != 0) + return -1; + + /* Sanity check on header size. Greater than 1k suggests some funny business. */ + if (th->th_hsize < 16 || th->th_hsize > 1024){ + M4_YY_GLOBAL_NONFATAL_ERROR("insane header size detected"); + return -1; + } + + /* Allocate enough space for the version and name fields */ + bytes = th->th_hsize - 14; + th->th_version = (char *) yyalloc(bytes); + if ( ! th->th_version ) + M4_YY_GLOBAL_FATAL_ERROR("out of dynamic memory in yytbl_hdr_read()"); + + /* we read it all into th_version, and point th_name into that data */ +m4_if_cxx_streamio([[ + rd->fp->read(th->th_version,bytes); + if (rd->fp->gcount() != bytes) { +]], +[[ + if (fread(th->th_version, 1, bytes, rd->fp) != bytes){ +]]) + errno = EIO; + yyfree(th->th_version); + th->th_version = NULL; + return -1; + } + else + rd->bread += bytes; + + th->th_name = th->th_version + strlen(th->th_version) + 1; + return 0; +} + +/** lookup id in the dmap list. + * @param dmap pointer to first element in list + * @return NULL if not found. + */ +M4_FUNC_DEF(static struct yytbl_dmap *, yytbl_dmap_lookup, struct yytbl_dmap *dmap, int id) +{ + while (dmap->dm_id) + if (dmap->dm_id == id) + return dmap; + else + dmap++; + return NULL; +} + +/** Read a table while mapping its contents to the local array. + * @param dmap used to performing mapping + * @return 0 on success + */ +M4_FUNC_DEF(static int, yytbl_data_load, struct yytbl_dmap * dmap, struct yytbl_reader* rd) +{ + struct yytbl_data td; + struct yytbl_dmap *transdmap=0; + int len, i, rv, inner_loop_count; + void *p=0; + + memset((void*)&td, 0, sizeof(struct yytbl_data)); + + if (yytbl_read16 (&td.td_id, rd) != 0 + || yytbl_read16 (&td.td_flags, rd) != 0 + || yytbl_read32 (&td.td_hilen, rd) != 0 + || yytbl_read32 (&td.td_lolen, rd) != 0) + return -1; + + /* Lookup the map for the transition table so we have it in case we need it + * inside the loop below. This scanner might not even have a transition + * table, which is ok. + */ + transdmap = yytbl_dmap_lookup(dmap, YYTD_ID_TRANSITION); + + if ((dmap = yytbl_dmap_lookup(dmap, td.td_id)) == NULL){ + M4_YY_GLOBAL_NONFATAL_ERROR("table id not found in map."); + return -1; + } + + /* Allocate space for table. + * The --full yy_transition table is a special case, since we + * need the dmap.dm_sz entry to tell us the sizeof the individual + * struct members. + */ + { + size_t bytes; + + bytes = td.td_lolen * (td.td_hilen ? td.td_hilen : 1) * dmap->dm_sz; + + if (M4_YY_TABLES_VERIFY) + /* We point to the array itself */ + p = dmap->dm_arr; + else + /* We point to the address of a pointer. */ + *dmap->dm_arr = p = (void *) yyalloc(bytes); + if ( ! p ) + M4_YY_GLOBAL_FATAL_ERROR("out of dynamic memory in yytbl_data_load()"); + } + + /* If it's a struct, we read 2 integers to get one element */ + if ((td.td_flags & YYTD_STRUCT) != 0) + inner_loop_count = 2; + else + inner_loop_count = 1; + + /* read and map each element. + * This loop iterates once for each element of the td_data array. + * Notice that we increment 'i' in the inner loop. + */ + len = yytbl_calc_total_len(&td); + for(i = 0; i < len; ){ + int j; + + + /* This loop really executes exactly 1 or 2 times. + * The second time is to handle the second member of the + * YYTD_STRUCT for the yy_transition array. + */ + for(j = 0; j < inner_loop_count; j++, i++) { + flex_int32_t t32; + + /* read into t32 no matter what the real size is. */ + { + flex_int16_t t16; + flex_int8_t t8; + + switch(YYTDFLAGS2BYTES (td.td_flags)) { + case sizeof(flex_int32_t): + rv = yytbl_read32 (&t32, rd); + break; + case sizeof(flex_int16_t): + rv = yytbl_read16 (&t16, rd); + t32 = t16; + break; + case sizeof(flex_int8_t): + rv = yytbl_read8 (&t8, rd); + t32 = t8; + break; + default: + M4_YY_GLOBAL_NONFATAL_ERROR("invalid td_flags"); + return -1; + } + } + if (rv != 0) + return -1; + + /* copy into the deserialized array... */ + + if ((td.td_flags & YYTD_STRUCT)) { + /* t32 is the j'th member of a two-element struct. */ + void *v; + + v = j == 0 ? &(((struct yy_trans_info *) p)->yy_verify) + : &(((struct yy_trans_info *) p)->yy_nxt); + + switch(dmap->dm_sz) { +m4_if([[M4_YY_TABLES_VERIFY]],[[m4_dnl + case (2*sizeof(flex_int32_t)): + if ( ((flex_int32_t *) v)[0] != (flex_int32_t) t32) + M4_YY_GLOBAL_FATAL_ERROR("tables verification failed at YYTD_STRUCT flex_int32_t"); + break; + case (2*sizeof(flex_int16_t)): + if (((flex_int16_t *) v)[0] != (flex_int16_t) t32) + M4_YY_GLOBAL_FATAL_ERROR("tables verification failed at YYTD_STRUCT flex_int16_t"); + break; + case (2*sizeof(flex_int8_t)): + if ( ((flex_int8_t *) v)[0] != (flex_int8_t) t32) + M4_YY_GLOBAL_FATAL_ERROR("tables verification failed at YYTD_STRUCT flex_int8_t"); + break; +]],[[m4_dnl + case (2*sizeof(flex_int32_t)): + ((flex_int32_t *) v)[0] = (flex_int32_t) t32; + break; + case (2*sizeof(flex_int16_t)): + ((flex_int16_t *) v)[0] = (flex_int16_t) t32; + break; + case (2*sizeof(flex_int8_t)): + ((flex_int8_t *) v)[0] = (flex_int8_t) t32; + break; +]])m4_dnl + default: + M4_YY_GLOBAL_FATAL_ERROR("invalid dmap->dm_sz for struct"); + return -1; + } + + /* if we're done with j, increment p */ + if (j == 1) + p = (struct yy_trans_info *) p + 1; + } + else if ((td.td_flags & YYTD_PTRANS)) { + /* t32 is an index into the transition array. */ + struct yy_trans_info *v; + + + if (!transdmap){ + M4_YY_GLOBAL_NONFATAL_ERROR("transition table not found"); + return -1; + } + + if ( M4_YY_TABLES_VERIFY) + v = &(((struct yy_trans_info *) (transdmap->dm_arr))[t32]); + else + v = &((*((struct yy_trans_info **) (transdmap->dm_arr)))[t32]); + + if (M4_YY_TABLES_VERIFY ){ + if ( ((struct yy_trans_info **) p)[0] != v) + M4_YY_GLOBAL_FATAL_ERROR("tables verification failed at YYTD_PTRANS"); + }else + ((struct yy_trans_info **) p)[0] = v; + + /* increment p */ + p = (struct yy_trans_info **) p + 1; + } + else { + /* t32 is a plain int. copy data, then incrememnt p. */ + switch(dmap->dm_sz) { + case sizeof(flex_int32_t): + if (M4_YY_TABLES_VERIFY ){ + if ( ((flex_int32_t *) p)[0] != (flex_int32_t) t32) + M4_YY_GLOBAL_FATAL_ERROR("tables verification failed at flex_int32_t"); + }else + ((flex_int32_t *) p)[0] = (flex_int32_t) t32; + p = ((flex_int32_t *) p) + 1; + break; + case sizeof(flex_int16_t): + if (M4_YY_TABLES_VERIFY ){ + if ( ((flex_int16_t *) p)[0] != (flex_int16_t) t32) + M4_YY_GLOBAL_FATAL_ERROR("tables verification failed at flex_int16_t"); + }else + ((flex_int16_t *) p)[0] = (flex_int16_t) t32; + p = ((flex_int16_t *) p) + 1; + break; + case sizeof(flex_int8_t): + if (M4_YY_TABLES_VERIFY ){ + if ( ((flex_int8_t *) p)[0] != (flex_int8_t) t32) + M4_YY_GLOBAL_FATAL_ERROR("tables verification failed at flex_int8_t"); + }else + ((flex_int8_t *) p)[0] = (flex_int8_t) t32; + p = ((flex_int8_t *) p) + 1; + break; + default: + M4_YY_GLOBAL_NONFATAL_ERROR("invalid dmap->dm_sz for plain int"); + return -1; + } + } + } + + } + + /* Now eat padding. */ + { + int pad; + pad = yypad64(rd->bread); + while (--pad >= 0){ + flex_int8_t t8; + if (yytbl_read8(&t8,rd) != 0) + return -1; + } + } + + return 0; +} + +/* Find the key and load the DFA tables from the given stream. */ +M4_FUNC_DEF(static int, yytbl_fload, M4_INSTREAM * fp, const char * key) +{ + int rv=0; + struct yytbl_hdr th; + struct yytbl_reader rd; + + rd.fp = fp; + th.th_version = NULL; + + /* Keep trying until we find the right set of tables or end of file. */ +m4_if_cxx_streamio([[ + while (!rd.fp->eof()) { +]],[[ + while (!feof(rd.fp)) { +]]) + rd.bread = 0; + if (yytbl_hdr_read(&th, &rd) != 0){ + rv = -1; + goto return_rv; + } + + /* A NULL key means choose the first set of tables. */ + if (key == NULL) + break; + + if (strcmp(th.th_name,key) != 0){ + /* Skip ahead to next set */ +m4_if_cxx_streamio([[ + rd.fp->seekg(th.th_ssize - th.th_hsize, std::ios_base::cur); +]],[[ + fseek(rd.fp, th.th_ssize - th.th_hsize, SEEK_CUR); +]]) + yyfree(th.th_version); + th.th_version = NULL; + } + else + break; + } + + while (rd.bread < th.th_ssize){ + /* Load the data tables */ + if (yytbl_data_load(yydmap,&rd) != 0){ + rv = -1; + goto return_rv; + } + } + +return_rv: + if (th.th_version){ + yyfree(th.th_version); + th.th_version = NULL; + } + + return rv; +} + +/** Load the DFA tables for this scanner from the given stream. */ +M4_FUNC_DEF(int, yytables_fload, M4_INSTREAM * fp) +{ + if ( yytbl_fload(fp, YYTABLES_NAME) != 0) + return -1; + return 0; +} + +/** Destroy the loaded tables, freeing memory, etc.. */ +M4_FUNC_DEF(int, yytables_destroy) +{ + struct yytbl_dmap *dmap=0; + + if (!M4_YY_TABLES_VERIFY){ + /* Walk the dmap, freeing the pointers */ + for(dmap=yydmap; dmap->dm_id; dmap++) { + void * v; + v = dmap->dm_arr; + if (v && *(char**)v){ + yyfree(*(char**)v); + *(char**)v = NULL; + } + } + } + + return 0; +} +/* end table serialization code definitions */ +]])m4_dnl endif tables_serialization + +m4_dnl JMK: added table-loading and C++ iostream support to main. +m4_ifdef( [[M4_YY_MAIN]], [[ +M4_FUNC_PROTO_NG(extern int, main); + +M4_FUNC_DEF_NG(int, main) +{ + m4_if_reentrant([[ + yyscan_t yyscanner; + ]]) + m4_if_cxx_only([[ + M4_YY_LEX_CLASS * lexer; + ]]) + m4_if_tables_serialization([[ + m4_if_cxx_streamio([[ + std::ifstream *fp; + fp = new std::ifstream("M4_YY_TABLES_FILENAME",ios::binary); + if (!fp->is_open()) + ]], + [[ + FILE *fp; + if (!(fp = fopen("M4_YY_TABLES_FILENAME","rb")))m4_dnl JMK: added binary flag. + ]]) + M4_YY_GLOBAL_FATAL_ERROR("could not open tables file \"M4_YY_TABLES_FILENAME\" for reading"); + + if (yytables_fload(fp) < 0) + M4_YY_GLOBAL_FATAL_ERROR("yytables_fload returned < 0"); + ]]) +m4_dnl ######## NOTE: POSIX LEX MAIN() ONLY CALLS YYLEX() ONCE ############ + m4_if_cxx_only([[ + lexer = new m4_yy_class()(); + while(lexer->lex()); + delete lexer; + ]], + [[ + m4_if_reentrant([[ + yylex_init(&lexer); + while (yylex(lexer)); + yylex_destroy( lexer); + ]], + [[ + while(yylex()); + ]]) + ]]) + m4_if_tables_serialization([[ + yytables_destroy(); + ]]) + return 0; +} +]]) + diff --git a/flex_globals.m4 b/flex_globals.m4 new file mode 100644 index 0000000..b3cc024 --- /dev/null +++ b/flex_globals.m4 @@ -0,0 +1,191 @@ +# This file creates two lists of globals as M4 macros: +# M4_PUBLIC_GLOBALS: These are part of the API and are user-accessible. +# M4_PRIVATE_GLOBALS: These are for internal use, and static in the non-reentran C scanner. + +# M4_GLOBAL(LINKAGE TYPE, NAME, INIT_VAL) +# --------------------------------------- + +m4_if_reentrant([[ + m4_define([[M4_GLOBAL]],[[ + + m4_appendl([[M4_CPP_RENAME_MACROS]], + [[[[#define [[$2]] (((struct yyobject_t*)yyscanner)->m4_yystrip([[$2]]))]]]]) + + m4_appendl([[M4_M4_RENAME_MACROS]], + [[[[m4_define([[$2]],m4_dquote([[(((struct yyobject_t*)yyscanner)->]]m4_yystrip([[$2]])[[)]]))]]]]) + + m4_ifelse([[$#]],3,[[ + m4_appendl([[M4_GLOBALS_INIT]], + [[ ((struct yyobject_t*)yyscanner)->m4_patsubst([[$2]],[[^yy_?]]) = $3;]]) + ]]) + + m4_patsubst([[$1]],[[^\(static\|extern\) *]]) m4_patsubst([[$2]],[[^yy_?]]);]]) +]], +[[ + m4_if_c_only([[ + m4_define([[M4_GLOBAL]],[[ + + m4_ifelse([[M4_YY_PREFIX]],[[yy]],,[[ + m4_appendl([[M4_CPP_RENAME_MACROS]],[[[[#define [[$2]] m4_yyprefix([[$2]])]]]]) + m4_appendl([[M4_M4_RENAME_MACROS]],[[[[m4_define([[$2]],m4_dquote(m4_yyprefix([[$2]])))]]]]) + ]]) + + m4_ifelse([[$#]],3,[[ + m4_appendl([[M4_GLOBALS_INIT]], + [[ m4_yyprefix([[$2]],[[$1]]) = $3;]]) + m4_appendl([[M4_GLOBALS_DEF]], + [[m4_patsubst([[$1]],[[^extern *]]) m4_yyprefix([[$2]],[[$1]]) = $3;]]) + ]], + [[ + m4_appendl([[M4_GLOBALS_DEF]], + [[m4_patsubst([[$1]],[[^extern *]]) m4_yyprefix([[$2]],[[$1]]);]]) + ]]) + +$1 m4_yyprefix([[$2]],[[$1]]);]]) + ]], + [[ + m4_define([[M4_GLOBAL]],[[ + + m4_appendl([[M4_CPP_RENAME_MACROS]], + [[#define [[$2]] m4_patsubst([[$2]],[[^yy_?]])]]) + + m4_appendl([[M4_M4_RENAME_MACROS]], + [[[[m4_define([[$2]],[[m4_patsubst([[$2]],[[^yy_?]])]])]]]]) + + m4_ifelse([[$#]],3,[[ + m4_appendl([[M4_GLOBALS_INIT]], + [[ m4_patsubst([[$2]],[[^yy_?]]) = $3;]]) + ]]) + + m4_patsubst([[$1]],[[^\(static\|extern\) *]]) m4_patsubst([[$2]],[[^yy_?]]);]]) + ]]) +]]) + +m4_dnl :: M4_GLOBAL(linkage+type, name, initval) +m4_dnl These are unquoted, because we want the rename macros evaluated now. + +m4_define([[M4_PUBLIC_GLOBALS]], + m4_if_reentrant([[ + m4_ifdef( [[M4_YY_NO_EXTRA]],, + [[ + /* User-defined. Not touched by flex. */ + /* Defined first so that (yyobject_t*) can be cast to (YY_EXTRA_TYPE*) */ +M4_GLOBAL(extern YY_EXTRA_TYPE, yyextra) + ]]) + ]]) +M4_GLOBAL(extern M4_INSTREAM *, yyin, YYIN_INIT) +M4_GLOBAL(extern M4_OUTSTREAM *, yyout, YYOUT_INIT) + m4_ifdef( [[M4_YY_TEXT_IS_ARRAY]],[[ +M4_GLOBAL(extern char, yytext[YYLMAX]) + ]],[[ +M4_GLOBAL(extern char *, yytext, NULL) + ]]) + m4_if_not_reentrant([[ +m4_dnl /* NOTE: The reentrant scanner uses (YY_CURRENT_BUFFER->bs_lineno) */ +m4_dnl /* We do not touch yylineno unless the option is enabled. */ +m4_dnl If not enabled, it is still supplied for user's line tracking. + m4_ifdef( [[M4_YY_USE_LINENO]],[[ +M4_GLOBAL(extern int, yylineno, 1) + ]],[[ +M4_GLOBAL(extern int, yylineno) + ]]) + ]]) +M4_GLOBAL(extern int, yy_flex_debug, m4_ifdef([[M4_FLEX_DEBUG]],1,0)) +M4_GLOBAL(extern int, yyleng, 0) +)m4_dnl + +m4_define([[M4_PRIVATE_GLOBALS]], + /* Private globals */ + +/* Stack of input buffers. */ +M4_GLOBAL(static size_t, yy_buffer_stack_top, 0) /**< index of top of stack. */ +M4_GLOBAL(static size_t, yy_buffer_stack_max, 0) /**< capacity of stack. */ +M4_GLOBAL(static YY_BUFFER_STATE *, yy_buffer_stack, 0) /**< Stack as an array. */ + +/* yy_hold_char holds the character lost when yytext is formed. */ +M4_GLOBAL(static char, yy_hold_char) +M4_GLOBAL(static int, yy_n_chars) + +/* Points to current character in buffer. */ +M4_GLOBAL(static char *, yy_c_buf_p, 0) + +/* Flag indicating whether the yylex state is intialized; called from yylex */ +M4_GLOBAL(static int, yy_init, 0) + +/* Defines the initial start state for current start-condition */ +M4_GLOBAL(static int, yy_start, 0) + +/* Flag which is used to allow yywrap()'s to do buffer switches + * instead of setting up a fresh yyin. A bit of a hack ... + */ +M4_GLOBAL(static int, yy_did_buffer_switch_on_eof, 0) + + m4_ifdef( [[M4_YY_STACK_USED]], + [[ +/* Stack state */ +M4_GLOBAL(static int, yy_start_stack_ptr, 0) +M4_GLOBAL(static int, yy_start_stack_depth, 0) +M4_GLOBAL(static int *, yy_start_stack, 0) + ]]) + + m4_ifdef( [[M4_YY_NEED_BACKING_UP]], + [[ +/* Definitions for backing up. We don't need them if REJECT + * is being used because then we use an alternative backing-up + * technique instead. + */ +M4_GLOBAL(static yy_state_type, yy_last_accepting_state) +M4_GLOBAL(static char *, yy_last_accepting_cpos) + ]]) + + m4_ifdef( [[M4_YY_USES_REJECT]], + [[ +/* Reject state buffer variables */ +M4_GLOBAL(static yy_state_type *, yy_state_buf, 0) +M4_GLOBAL(static yy_state_type *, yy_state_ptr, 0) +M4_GLOBAL(static char *, yy_full_match) +M4_GLOBAL(static int, yy_lp) + ]]) + + m4_ifdef( [[M4_YY_VARIABLE_TRAILING_CONTEXT_RULES]], + [[ + /* trailing-context state information */ +M4_GLOBAL(static int, yy_looking_for_trail_begin, 0) +M4_GLOBAL(static int, yy_full_lp) +M4_GLOBAL(static int *, yy_full_state) + ]]) + + /* yytext state information */ + m4_ifdef( [[M4_YY_TEXT_IS_ARRAY]], + [[ +M4_GLOBAL(static char *, yytext_ptr, NULL) + ]]) + m4_ifdef( [[M4_YY_USES_YYMORE]], + [[ + m4_ifdef( [[M4_YY_TEXT_IS_ARRAY]], + [[ +M4_GLOBAL(static int, yy_more_offset, 0) +M4_GLOBAL(static int, yy_prev_more_offset, 0) + ]], + [[ +M4_GLOBAL(static int, yy_more_flag, 0) +M4_GLOBAL(static int, yy_more_len, 0) + ]]) + ]]) + + m4_if_cxx_or_reentrant([[ + m4_ifdef( [[M4_YY_BISON_LVAL]], + [[ +M4_GLOBAL(static YYSTYPE *, yylval) + ]]) + + m4_ifdef( [[M4_YY_BISON_LLOC]], + [[ +M4_GLOBAL(static YYLTYPE *, yylloc) + ]]) + ]]) +)m4_dnl end M4_PRIVATE_GLOBALS + +m4_clean_def([[M4_PUBLIC_GLOBALS]]) +m4_clean_def([[M4_PRIVATE_GLOBALS]]) + diff --git a/flex_header.m4 b/flex_header.m4 new file mode 100644 index 0000000..8d4570d --- /dev/null +++ b/flex_header.m4 @@ -0,0 +1,564 @@ +m4_divert(-1) +m4_changecom() +m4_changequote() +m4_changequote([[,]]) +########################################################################## +# General-purpose m4 macros are defined here. Some are derived from m4sugar.m4 + +# m4_car(LIST) +# m4_cdr(LIST) +# ------------ +# Manipulate m4 lists. +m4_define([[m4_car]], [[[[$1]]]]) +m4_define([[m4_cdr]], +[[m4_ifelse([[$#]], 0, [[m4_fatal([[$0: cannot be called without arguments]])]], + [[$#]], 1, [[]], + [[m4_dquote(m4_shift($@))]])]]) + +# m4_foreach(VARIABLE, LIST, EXPRESSION) +# -------------------------------------- +# Expand EXPRESSION assigning each value of the LIST to VARIABLE. +# LIST should have the form `item_1, item_2, ..., item_n', i.e. the +# whole list must *quoted*. Quote members too if you don't want them +# to be expanded. +m4_define([[m4_foreach]], +[[m4_pushdef([[$1]])_m4_foreach($@)m4_popdef([[$1]])]]) + +m4_define([[_m4_foreach]], +[[m4_ifelse([[$2]],[[]],[[]],[[m4_define([[$1]], m4_car($2))$3[[]]m4_dnl +_m4_foreach([[$1]], m4_cdr($2), [[$3]])]])]]) + +# m4_echo(STRING) +# ------------------------- +# Useful for unquoting a string. +m4_define([[m4_echo]],[[$*]]) + +# m4_quote(STRING) +# ------------------------- +m4_define([[m4_quote]],[[[[$*]]]]) + +# m4_dquote(STRING) +# ------------------------- +m4_define([[m4_dquote]],[[[[$@]]]]) + +# m4_shiftn(N, ...) +# ----------------- +# Returns ... shifted N times. Useful for recursive "varargs" constructs. +m4_define([[m4_shiftn]],m4_dnl +[[m4_ifelse([[$1]],0,[[m4_shift($@)]],[[m4_shiftn(m4_eval([[$1]]-1), m4_shift(m4_shift($@)))]])]]) + +# m4_bpatsubsts(STRING, RE1, SUBST1, RE2, SUBST2, ...) +# ---------------------------------------------------- +# m4 equivalent of: +# $_ = STRING; +# s/RE1/SUBST1/g; +# s/RE1/SUBST1/g; +# s/RE2/SUBST2/g; +# ... +m4_define([[m4_bpatsubsts]], +[[m4_ifelse([[$#]], 0, [[]], + [[$#]], 1, [[$1]], + [[$#]], 2, [[m4_builtin([[patsubst]], $@)]], + [[$0(m4_builtin([[patsubst]], [[[[$1]]]], [[$2]], [[$3]]), + m4_shiftn(3, $@))]])]]) + +# m4_append(MACRO-NAME, STRING, [SEPARATOR]) +# ------------------------------------------ +# Append SEPARATORE and STRING to the end of the named macro. +# If the macro is undefined, SEPARATOR is not appended. +m4_define([[m4_append]], +[[m4_define([[$1]], + m4_ifdef([[$1]], [[m4_defn([[$1]])$3]])[[$2]])]]) + +# m4_appendl(MACRO-NAME, STRING) +# ----------------------------- +# Append STRING and a newline char to the named macro. +m4_define([[m4_appendl]], +[[m4_define([[$1]], + m4_ifdef([[$1]], [[m4_defn([[$1]])]])[[$2[[ +]]]])]]) + +# m4_bool(VALUE) +# -------------- +# Try to convert VALUE to a boolean 0 or 1. +# If it looks like a macro, undefined is false, or defined with value 0. +# This assumes that macro names all start with M4_. +m4_define([[m4_bool]], +[[m4_ifelse( + m4_regexp([[$1]],[[^M4_]]),0,m4_ifdef([[$1]],m4_ifelse([[$1]],0,0,1),0), + [[$1]],0,0, + [[$1]],[[false]],0, + [[$1]],[[FALSE]],0,1)]]) + +# m4_if_elseif(BOOL1, IF-BOOL1, BOOL2, IF-BOOL2, ..., DEFAULT) +# ----------------------------------------------------------- +# Make an if/then/elseif/.../endif construct with boolean conditions. +# Words starting with "M4_" are checked with ifdef. +m4_define([[m4_if_elseif]], +[[m4_ifelse( + [[$#]], 0, [[]], + [[$#]], 1, [[$1]], + m4_bool([[$1]]), 1, [[$2]], + [[$0(m4_shiftn(2,$@))]]) +]]) + +# m4_if(BOOLEAN, IF-TRUE [, IF-FALSE]) +# ------------------------------------ +# A simple conditional with an evaluated condition expression. +m4_define([[m4_if]],[[m4_ifelse(m4_eval($1),1,[[$2]],[[$3]])]]) + +# m4_defined(MACRO-NAME) +# ---------------------- +# return boolean 1 if the macro is defined, else 0. +m4_define([[m4_defined]],[[m4_ifdef([[$1]],[[1]],[[0]])]]) + +# m4_escape_backslash(STRING) +# --------------------------- +# Replace occurances of `\' with `\\' +m4_define([[m4_escape_backslash]],m4_dnl +[[m4_patsubst([[$*]],[[\\]],[[\\\\]])]]) + +# m4_escape_newline(MULTILINE-STRING) +# ----------------------------------- +# Append backslashes to all newlines (i.e. to generate C macros). +# It also removes blank lines, and avoids a backslash on the last line. +m4_define([[m4_escape_newline]],[[m4_patsubst($*,[[[ + ]* +\(.\)]],[[ [[\\]] +\1]])]]) + +# m4_flex_include(FILENAME) +# ------------------------- +# m4 include() a file from the FLEX M4-INCLUDE directory. +m4_define([[m4_flex_include]],[[m4_include(M4_FLEX_INCLUDE()/$1)]]) + +# m4_print_string(MACRO_NAME) +# ----------------------------- +# For debugging, print the quoted value of a macro, or `undefined'. +m4_define([[m4_print_string]],m4_dnl +[[/* [[$1]] = m4_ifdef([[$1]],"$1", undefined) */]]) + +# m4_print_value(MACRO_NAME) +# ----------------------------- +# For debugging, print the un-quoted value of a macro, or `'. +m4_define([[m4_print_string]],m4_dnl +[[/* [[$1]] = m4_ifdef([[$1]],$1, [[]]) */]]) + +# m4_print_bool(MACRO_NAME) +# ------------------------- +# For debugging, print a boolean m4 macro, where defined means TRUE. +m4_define([[m4_print_bool]],m4_dnl +[[/* [[$1]] = m4_ifdef([[$1]],true,false) */]]) + +#################################################################### +# This section defines functional M4 macros that replace the +# original simple conditionals processed in skelout(). Some of them are +# just syntactic sugar for ifdefs, but many are set by the choice of +# modes C, reentrant, or C++ class. + +m4_ifdef( [[M4_YY_REENTRANT]],[[ + m4_define(m4_if_reentrant,$1) + m4_define(m4_if_not_reentrant,$2) +]],[[ + m4_define(m4_if_reentrant,$2) + m4_define(m4_if_not_reentrant,$1) +]]) + +m4_ifdef([[M4_YY_CPLUSPLUS]],[[ + m4_ifdef( [[M4_YY_CLASS]],, + [[ + m4_ifdef( [[M4_YY_PREFIX]], + [[ + m4_define([[M4_YY_CLASS]],M4_YY_PREFIX()[[FlexLexer]]) + ]], + [[ + m4_define([[M4_YY_CLASS]],[[yyFlexLexer]]) + ]]) + ]]) + m4_define([[M4_YY_USE_MALLOC]],[[]]) + m4_define([[M4_YY_PREFIX]],[[]]) + m4_define([[M4_YY_LEX_BASE_CLASS]],[[FlexLexer[[$1]]]]) + m4_define([[M4_YY_LEX_CLASS]],[[M4_YY_CLASS[[$1]]]]) + m4_ifdef([[M4_YY_CXX_IOSTREAM]],,[[m4_define([[M4_YY_CXX_IOSTREAM]],1)]]) + m4_define([[m4_if_cxx_only]],[[$1]]) + m4_define([[m4_if_c_only]],[[$2]]) + m4_define([[m4_if_cxx_or_reentrant]],[[$1]]) + m4_define([[m4_if_cxx_or_not_reentrant]],[[$1]]) +]], +[[ + m4_define([[M4_YY_LEX_CLASS]],[[]]) + m4_ifdef([[M4_YY_CXX_IOSTREAM]],,[[m4_define([[M4_YY_CXX_IOSTREAM]],0)]]) + m4_define([[m4_if_cxx_only]],[[$2]]) + m4_define([[m4_if_c_only]],[[$1]]) + m4_if_reentrant([[ + m4_define([[m4_if_cxx_or_reentrant]],[[$1]]) + m4_define([[m4_if_cxx_or_not_reentrant]],[[$2]]) + ]],[[ + m4_define([[m4_if_cxx_or_reentrant]],[[$2]]) + m4_define([[m4_if_cxx_or_not_reentrant]],[[$1]]) + ]]) +]]) + +m4_ifelse(M4_YY_CXX_IOSTREAM,1, +[[ + m4_define([[m4_if_cxx_streamio]],[[$1]]) + m4_define([[M4_INSTREAM]],[[std::istream]]) + m4_define([[M4_OUTSTREAM]],[[std::ostream]]) + m4_define([[M4_STDIN]],[[&std::cin]]) + m4_define([[M4_STDOUT]],[[&std::cout]]) +]],[[ + m4_define([[m4_if_cxx_streamio]],[[$2]]) + m4_define([[M4_INSTREAM]],[[FILE]]) + m4_define([[M4_OUTSTREAM]],[[FILE]]) + m4_define([[M4_STDIN]],[[stdin]]) + m4_define([[M4_STDOUT]],[[stdout]]) +]]) + +m4_ifdef([[M4_YY_TABLES_EXTERNAL]],[[ + m4_define([[m4_if_tables_serialization]],[[$1]]) +]],[[ + m4_define([[m4_if_tables_serialization]],[[$2]]) +]]) + +#################################################################### +# FIXME: should these be asserted in check_options()? +m4_if_not_reentrant([[ + m4_define([[M4_YY_NO_GET_EXTRA]],) + m4_define([[M4_YY_NO_SET_EXTRA]],) + m4_define([[M4_YY_NO_GET_LVAL]],) + m4_define([[M4_YY_NO_SET_LVAL]],) + m4_define([[M4_YY_NO_GET_LLOC]],) + m4_define([[M4_YY_NO_SET_LLOC]],) + m4_define([[M4_YY_NO_GET_COLUMN]]) + m4_define([[M4_YY_NO_SET_COLUMN]]) +]],[[ + m4_ifdef([[M4_YY_BISON_LVAL]],,[[ + m4_ifdef([[M4_YY_NO_GET_LVAL]],,m4_define(M4_YY_NO_GET_LVAL,)) + m4_ifdef([[M4_YY_NO_SET_LVAL]],,m4_define(M4_YY_NO_SET_LVAL,)) + ]]) + m4_ifdef([[M4_YY_BISON_LLOC]],,[[ + m4_ifdef([[M4_YY_NO_GET_LLOC]],,m4_define(M4_YY_NO_GET_LLOC,)) + m4_ifdef([[M4_YY_NO_SET_LLOC]],,m4_define(M4_YY_NO_SET_LLOC,)) + ]]) +]]) + +m4_if_c_only([[ + m4_ifdef([[M4_YY_STACK_USED]],, + [[ + m4_define( [[M4_YY_NO_PUSH_STATE]]) + m4_define( [[M4_YY_NO_POP_STATE]]) + m4_define( [[M4_YY_NO_TOP_STATE]]) + ]]) +]]) +m4_if_cxx_or_reentrant([[ + m4_define([[M4_YY_STACK_USED]],1) +]]) + +m4_dnl C++ directly uses C-lib malloc. +m4_ifdef([[M4_YY_USE_MALLOC]], +[[ + m4_define([[M4_YY_NO_FLEX_ALLOC]]) + m4_define([[M4_YY_NO_FLEX_REALLOC]]) + m4_define([[M4_YY_NO_FLEX_FREE]]) + m4_define([[yyalloc]],[[malloc[[]]m4_ifelse($]][[#,0,,($]][[*))]]) + m4_define([[yyrealloc]],[[realloc[[]]m4_ifelse($]][[#,0,,($]][[*))]]) + m4_define([[yyfree]],[[free[[]]m4_ifelse($]][[#,0,,($]][[*))]]) +]]) + +m4_ifdef([[M4_YY_ALWAYS_INTERACTIVE]], +[[ + m4_define([[M4_YY_NO_ISATTY]]) + m4_define([[M4_YY_NO_UNISTD_H]]) +]]) + +m4_ifdef([[M4_YY_NEVER_INTERACTIVE]], +[[ + m4_define([[M4_YY_NO_ISATTY]]) + m4_define([[M4_YY_NO_UNISTD_H]]) +]]) + +m4_ifdef([[M4_YY_TABLES_NAME]],, +[[ + m4_define([[M4_YY_TABLES_NAME]],[[yytables]]) +]]) + +m4_if_cxx_only([[ + m4_undefine([[M4_YY_NO_UNPUT]]) +]]) + +############################################################################ +# Prefixes: +# These m4 macros rename functions and non-static variables. +# (Reentrant globals are renamed in a different place below.) +# The complexity here is necessary so that m4 preserves +# the argument lists to each C function, and still allow for +# references not followed by parenthesis. + +m4_ifdef([[M4_YY_PREFIX]],,[[ + m4_define([[M4_YY_PREFIX]],[[yy]]) +]]) + +m4_ifelse(M4_YY_PREFIX,[[]],[[ +m4_define([[M4_YY_PREFIX_]],[[]]) +]],[[ +m4_define([[M4_YY_PREFIX_]],M4_YY_PREFIX()_) +]]) + +#-------------------------------------------------------------------- +# For use in function documentation to adjust for additional argument. +m4_if_reentrant( +[[ +m4_define( [[M4_YY_OBJECT_PARAM_DOC]], [[@param yyscanner The scanner object.]]) +]], +[[ +m4_define( [[M4_YY_OBJECT_PARAM_DOC]], [[]]) +]]) + +############################################################################ +# NOTE: These must be single-line definitions. +m4_if_reentrant([[ + m4_ifdef([[M4_YY_USE_LINENO]],[[ + m4_define([[M4_YY_USE_COLUMN]]) + ]]) +]]) + +# XXX: These yycolumn macros assume that they are always preceded +# XXX: by a check for a '\n' character. +m4_ifdef([[M4_YY_USE_COLUMN]], +[[ + m4_define( [[M4_YY_INCR_LINENO]], + [[{ yycolumn=0; ++yylineno; } else { ++yycolumn; }]]) + m4_define( [[M4_YY_DECR_LINENO]], + [[{ yycolumn=0; --yylineno; } else { --yycolumn; }]]) +]], +[[ + m4_define( [[M4_YY_INCR_LINENO]], + [[[[yylineno]]=++yylineno]]) + m4_define( [[M4_YY_DECR_LINENO]], + [[[[yylineno]]=--yylineno]]) +]]) + +m4_dnl This NAMESPACE macro is only prtially implemented. +m4_ifdef([[M4_YY_NAMESPACE]], +[[ + m4_define([[m4_yynamespace]],[[M4_YY_NAMESPACE[[$1]]]]) +]],[[ + m4_define([[m4_yynamespace]],[[]]) +]]) + +# Same as m4_shift, but return 'void' if the result is empty. +m4_define([[m4_vshift]],[[m4_dnl +m4_ifelse([[$#]],0,[[void]], + [[$#]],1,[[void]], + [[m4_shift($@)]])]]) + +# m4_yy_prefix(NAME [, LINKAGE...] ) +# ------------------------------ +# Return a prefix-modified NAME, depending on whether LINKAGE... +# starts with 'static' +m4_define([[m4_yyprefix]],[[m4_dnl +m4_ifelse(m4_regexp([[$2]],[[^static]]),0,[[$1]], +m4_regexp([[$1]],[[^yy_]]),0,[[m4_patsubst([[$1]],[[^yy_]],M4_YY_PREFIX_())]], +m4_regexp([[$1]],[[^yy]]),0,[[m4_patsubst([[$1]],[[^yy]],M4_YY_PREFIX())]], +[[$1]])]]) + +# Functions names that match this pattern are marked as const in the +# C++ class scanner. +m4_define([[M4_CONST_REGEXP]],[[get_[a-z]* *$]]) + +########################################################################### +# M4_FUNC_PROTO(RETURN-TYPE, NAME, TYPE1 ARG1, TYPE2 ARG2, ...) +# ----------------------------------------------------------- +# Declare the function NAME, create m4 conversion macros to add the extra +# argument for reentrant C scanners, and create a CPP #define to rename +# functions in user code. NOTE: the CPP macros do not add the reentrant +# yyscanner argument. +# +# These are rather dense to avoid adding extra space in the output, +# while trying to accomplish multiple tasks. + +m4_define([[m4_rename_func]],[[m4_dnl +m4_ifelse(M4_YY_PREFIX(),[[yy]],[[]],m4_dnl +[[m4_appendl([[M4_CPP_RENAME_MACROS]],[[#define [[[[$1]]]] m4_yyprefix([[$1]])]])]])[[]]m4_dnl +]])m4_dnl + +m4_dnl ========================================================================== +m4_if_c_only([[ + +m4_define([[M4_FUNC_DEF_NG]],[[m4_dnl +$1 +m4_ifelse(m4_regexp([[$1]],[[^static]]),0,[[$2]],[[m4_yyprefix([[$2]])]])[[]]m4_dnl +(m4_vshift(m4_shift($@)))]])m4_dnl + +m4_define([[M4_FUNC_PROTO_NG]],[[m4_dnl +m4_ifelse(m4_regexp([[$1]],[[^static]]),0,[[m4_dnl +$1 [[$2]](m4_vshift(m4_shift($@)))m4_dnl +]],[[m4_dnl +m4_rename_func($2)m4_dnl +$1 m4_yyprefix($2)(m4_vshift(m4_shift($@)))m4_dnl +m4_indir([[m4_define]],$2,m4_dquote(m4_yyprefix($2))[[m4_ifelse($]][[#,0,,($]][[*))]])[[]]m4_dnl +]])m4_dnl +]])m4_dnl + +m4_dnl ========================================================================== +m4_if_reentrant([[ + +m4_define([[m4_yyscanner_arg]],[[m4_dnl +($@[[]]m4_ifelse(m4_regexp([[$1]],[[^ *$]]),[[-1]],[[, yyscanner]],[[yyscanner]]))]]) + +m4_define([[M4_FUNC_DEF]],[[m4_dnl +$1 +m4_ifelse(m4_regexp([[$2]],M4_CONST_REGEXP),[[-1]],[[m4_dnl +[[$2]](m4_shiftn(2,$@,[[yyscan_t yyscanner]]))]],[[m4_dnl +[[$2]](m4_shiftn(2,$@,[[const yyscan_t yyscanner]]))]])m4_dnl +]]) + +m4_define([[M4_FUNC_PROTO]],[[m4_dnl +m4_ifelse(m4_regexp([[$1]],[[^static]]),0,[[m4_dnl +$1 $2]],[[m4_dnl +m4_rename_func($2)m4_dnl +$1 m4_yyprefix($2)]])[[]]m4_dnl +m4_dnl +m4_ifelse(m4_regexp([[$2]],M4_CONST_REGEXP),[[-1]],[[m4_dnl +(m4_shiftn(2,$@,[[yyscan_t yyscanner]]))]],[[m4_dnl +(m4_shiftn(2,$@,[[const yyscan_t yyscanner]]))]])m4_dnl +m4_dnl +m4_indir([[m4_define]],$2,m4_dquote(m4_yyprefix($2,$1))[[]]m4_dnl + [[m4_ifelse($]][[#,0,,m4_yyscanner_arg($]][[*))]])]])m4_dnl + +]],[[m4_dnl else non-reentrant +m4_dnl In the non-reentrant scanner, these are the same as for No-Globals versions +m4_define([[M4_FUNC_DEF]],[[m4_dnl +$1 +[[$2]](m4_vshift(m4_shift($@)))]])[[]]m4_dnl +m4_define([[M4_FUNC_PROTO]],[[m4_dnl +m4_ifelse(m4_regexp([[$1]],[[^static]]),0,[[m4_dnl +$1 $2(m4_vshift(m4_shift($@)))m4_dnl +]],[[m4_dnl +m4_rename_func($2)m4_dnl +$1 m4_yyprefix($2)(m4_vshift(m4_shift($@)))m4_dnl +m4_indir([[m4_define]],$2,m4_dquote(m4_yyprefix($2))[[m4_ifelse($]][[#,0,,($]][[*))]])m4_dnl +]])m4_dnl +]])m4_dnl + +]]) endif reentrant + +m4_dnl ========================================================================== +]],[[m4_dnl else C++ + +m4_define([[M4_FUNC_DEF_NG]],[[m4_dnl +m4_bpatsubsts([[$1]],[[\bstatic *]],[[]],[[\b\(YY\|yy\)]],[[M4_YY_CLASS::\1]]) +M4_YY_CLASS::m4_yystrip([[$2]])(m4_vshift(m4_shift($@)))]]) + +m4_define([[M4_FUNC_DEF]],[[m4_dnl +m4_bpatsubsts([[$1]],[[\bstatic *]],[[]],[[\b\(YY\|yy\)]],[[M4_YY_CLASS::\1]]) +M4_YY_CLASS::m4_yystrip([[$2]])(m4_vshift(m4_shift($@)))m4_dnl +m4_ifelse(m4_regexp([[$2]],M4_CONST_REGEXP),[[-1]],[[]],[[ const]])]]) + +m4_define([[M4_FUNC_PROTO_NG]],[[m4_dnl +m4_ifelse(m4_regexp([[$2]],[[^yy\(in\|un\|out\)put *$]]),0,,[[m4_rename_func($2)]])m4_dnl +m4_ifelse(m4_regexp([[$1]],[[^static]]),0,[[protected: ]],[[public: ]])m4_dnl +static m4_patsubst([[$1]],[[^\(static\|extern\) ]]) m4_yystrip($2)(m4_vshift(m4_shift($@)))m4_dnl +]])m4_dnl + +m4_define([[M4_FUNC_PROTO]],[[m4_dnl +m4_ifelse(m4_regexp([[$2]],[[^yy\(in\|un\|out\)put *$]]),0,,[[m4_rename_func($2)]])m4_dnl +m4_ifelse(m4_regexp([[$1]],[[^static]]),0,[[protected: ]],[[public: ]])m4_dnl +m4_patsubst([[$1]],[[^\(static\|extern\) ]]) m4_yystrip($2)(m4_vshift(m4_shift($@)))m4_dnl +m4_ifelse(m4_regexp([[$2]],M4_CONST_REGEXP),[[-1]],[[]],[[ const]])]])m4_dnl + +]]) +m4_dnl ========================================================================== + +m4_define([[m4_yystrip]],[[m4_ifelse( + m4_regexp([[$1]],[[^yy\(in\|un\|out\)put *$]]),0,[[$1]], + m4_patsubst([[$1]],[[^yy_?]]))]]) + +# Return a "clean" value from the named macro. +# Cleaning means to remove blank lines and trailing spaces. +m4_define([[m4_clean]],[[m4_patsubst(m4_defn([[$1]]),[[ * +\([ ]* +\)*]],[[ +]])]]) + +# Re-define the named macro to contain cleaned text, as defined above. +m4_define([[m4_clean_def]],[[ +m4_indir([[m4_define]],[[$1]],m4_clean([[$1]])) +]]) + +########################################################################### +## The line number will be replaced by the output filter. The m4 source +## line is inserted for now as a possible aid to debugging this m4 script. +m4_ifdef([[M4_YY_NO_LINE]],[[ +m4_define([[M4_LINE_DIRECTIVE]],[[]]) +]], +[[ +m4_define([[M4_LINE_DIRECTIVE]],[[#line m4___line__ "M4_YY_OUTFILE_NAME"]]) +]]) + +########################################################################### +# Build table definitions, and also declarations if C++. + +# NOTE: yy_start_state_list[] is a list of indices into yy_transition[], +# stored as pointers to yy_transition[] elements. +m4_ifdef([[M4_YY_START_STATE_LIST_TABLE_DATA]],[[ +m4_define([[M4_YY_START_STATE_LIST_TABLE_DATA_REF]],[[m4_dnl +m4_foreach([[INDEX]],m4_dquote(M4_YY_START_STATE_LIST_TABLE_DATA),[[ + &yy_transition[INDEX],]]) +]]) +m4_define([[M4_YY_START_STATE_LIST_TABLE_DATA]], +m4_quote(M4_YY_START_STATE_LIST_TABLE_DATA_REF)) +]]) + +m4_if_tables_serialization([[ +m4_define([[m4_data_table]],[[m4_ifdef([[M4_$1_TABLE_SIZE]],[[ +m4_appendl([[M4_YY_DMAP_TABLE]], +[[ {m4_patsubst([[$1]],[[^YY_]],[[YYTD_ID_]]), (void**)m4_dnl + &m4_translit([[$1]],[[A-Z]],[[a-z]]),m4_dnl + sizeof(*(m4_translit([[$1]],[[A-Z]],[[a-z]])))},]]) +static const $2 m4_if(M4_YY_TABLES_VERIFY, +[[m4_translit([[$1]],[[A-Z]],[[a-z]])[M4_$1_TABLE_SIZE] = { M4_$1_TABLE_DATA };]], +[[* m4_translit([[$1]],[[A-Z]],[[a-z]]) = 0;]])m4_dnl +]])]]) + +m4_define([[m4_int_table]], +[[m4_data_table($1,m4_ifdef(M4_$1_TABLE_32BIT,[[flex_int32_t]],[[flex_int16_t]]))]]) + +]],[[ + +m4_define([[m4_data_table]],[[m4_ifdef([[M4_$1_TABLE_DATA]],[[ +static const $2 m4_translit([[$1]],[[A-Z]],[[a-z]])[M4_$1_TABLE_SIZE] = [[{ M4_$1_TABLE_DATA }]]; +]])]]) + +m4_define([[m4_int_table]], +[[m4_data_table($1,m4_ifdef(M4_$1_TABLE_32BIT,[[flex_int32_t]],[[flex_int16_t]]))]]) +]]) +m4_define([[M4_GEN_DATA_TABLES]],[[ +m4_int_table(YY_ACCLIST) +m4_int_table(YY_ACCEPT) +m4_int_table(YY_BASE) +m4_int_table(YY_CHK) +m4_int_table(YY_DEF) +m4_int_table(YY_EC) +m4_int_table(YY_META) +m4_int_table(YY_NUL_TRANS) +m4_int_table(YY_NXT) +m4_int_table(YY_RULE_CAN_MATCH_EOL) +m4_data_table(YY_TRANSITION,[[struct yy_trans_info]]) +m4_data_table(YY_START_STATE_LIST,[[struct yy_trans_info*]]) + +m4_ifdef([[M4_YY_DMAP_TABLE]],[[ +/** A {0,0,0}-terminated list of structs, forming the map */ +static struct yytbl_dmap yydmap[] = { +M4_YY_DMAP_TABLE()m4_dnl + {YYTD_ID_END,0,0} +};]]) + +m4_dnl The rule_linenum table is never serialized. +m4_dnl It is mainly for debugging, and also normally small. +m4_ifdef([[M4_YY_RULE_LINENUM_TABLE_DATA]],[[ +static const m4_ifdef(M4_YY_RULE_LINENUM_TABLE_32BIT,[[flex_int32_t]],[[flex_int16_t]]) m4_dnl +yy_rule_linenum[M4_YY_RULE_LINENUM_TABLE_SIZE] = {M4_YY_RULE_LINENUM_TABLE_DATA}; +]]) +]]) +###################################################################### diff --git a/flex_print_m4_params.m4 b/flex_print_m4_params.m4 new file mode 100644 index 0000000..58ccddd --- /dev/null +++ b/flex_print_m4_params.m4 @@ -0,0 +1,71 @@ +/*******************************************************/ +/* M4 definitions passed to the skeleton: */ +#if 0 +/* strings */ +m4_print_string([[M4_FLEX_VERSION]]) +m4_print_string([[M4_YY_LANGUAGE]]) +m4_print_string([[M4_YY_HEADER_FILENAME]]) +m4_print_string([[M4_YY_OUTFILE_NAME]]) +m4_print_string([[M4_YY_TABLES_NAME]]) +m4_print_string([[M4_YY_TABLES_FILENAME]]) +/* non-strings */ +m4_print_value([[M4_EXTRA_TYPE_DEF]]) +m4_print_value([[M4_YY_CLASS]]) +m4_print_value([[M4_YY_PREFIX]]) +m4_print_value([[M4_YY_CHAR_TYPE]]) +m4_print_value([[M4_YY_TRAILING_HEAD_MASK]]) +m4_print_value([[M4_YY_TRAILING_MASK]]) +m4_print_value([[M4_YY_TABLES_VERIFY]]) +/* boolean (defined==TRUE) */ +m4_print_bool([[M4_FLEX_DEBUG]]) +m4_print_bool([[M4_YY_FULLSPD]]) +m4_print_bool([[M4_YY_FULLTBL]]) +m4_print_bool([[M4_YY_ALWAYS_INTERACTIVE]]) +m4_print_bool([[M4_YY_BISON_LLOC]]) +m4_print_bool([[M4_YY_BISON_LVAL]]) +m4_print_bool([[M4_YY_DO_STDINIT]]) +m4_print_bool([[M4_YY_FLEX_LEX_COMPAT]]) +m4_print_bool([[M4_YY_IN_HEADER]]) +m4_print_bool([[M4_YY_INTERACTIVE]]) +m4_print_bool([[M4_YY_MAIN]]) +m4_print_bool([[M4_YY_NEVER_INTERACTIVE]]) +m4_print_bool([[M4_YY_NO_ANSI_FUNC_DEFS]]) +m4_print_bool([[M4_YY_NO_ANSI_FUNC_PROTOS]]) +m4_print_bool([[M4_YY_NO_FLEX_ALLOC]]) +m4_print_bool([[M4_YY_NO_FLEX_FREE]]) +m4_print_bool([[M4_YY_NO_FLEX_REALLOC]]) +m4_print_bool([[M4_YY_NO_GET_DEBUG]]) +m4_print_bool([[M4_YY_NO_GET_EXTRA]]) +m4_print_bool([[M4_YY_NO_GET_IN]]) +m4_print_bool([[M4_YY_NO_GET_LENG]]) +m4_print_bool([[M4_YY_NO_GET_LINENO]]) +m4_print_bool([[M4_YY_NO_GET_LLOC]]) +m4_print_bool([[M4_YY_NO_GET_LVAL]]) +m4_print_bool([[M4_YY_NO_GET_OUT]]) +m4_print_bool([[M4_YY_NO_GET_TEXT]]) +m4_print_bool([[M4_YY_NO_POP_STATE]]) +m4_print_bool([[M4_YY_NO_PUSH_STATE]]) +m4_print_bool([[M4_YY_NO_SCAN_BUFFER]]) +m4_print_bool([[M4_YY_NO_SCAN_BYTES]]) +m4_print_bool([[M4_YY_NO_SCAN_STRING]]) +m4_print_bool([[M4_YY_NO_SET_DEBUG]]) +m4_print_bool([[M4_YY_NO_SET_EXTRA]]) +m4_print_bool([[M4_YY_NO_SET_IN]]) +m4_print_bool([[M4_YY_NO_SET_LINENO]]) +m4_print_bool([[M4_YY_NO_SET_LLOC]]) +m4_print_bool([[M4_YY_NO_SET_LVAL]]) +m4_print_bool([[M4_YY_NO_SET_OUT]]) +m4_print_bool([[M4_YY_NO_TOP_STATE]]) +m4_print_bool([[M4_YY_NO_UNISTD_H]]) +m4_print_bool([[M4_YY_NO_UNPUT]]) +m4_print_bool([[M4_YY_REENTRANT]]) +m4_print_bool([[M4_YY_SKIP_YYWRAP]]) +m4_print_bool([[M4_YY_STACK_USED]]) +m4_print_bool([[M4_YY_TABLES_EXTERNAL]]) +m4_print_bool([[M4_YY_TEXT_IS_ARRAY]]) +m4_print_bool([[M4_YY_USE_LINENO]]) +m4_print_bool([[M4_YY_USES_REJECT]]) +m4_print_bool([[M4_YY_USES_YYMORE]]) +m4_print_bool([[M4_YY_VARIABLE_TRAILING_CONTEXT_RULES]]) +#endif /*0*/ +/*******************************************************/ diff --git a/flex_private_header.m4 b/flex_private_header.m4 new file mode 100644 index 0000000..a4af64f --- /dev/null +++ b/flex_private_header.m4 @@ -0,0 +1,354 @@ +m4_dnl Private typedefs and function declarations, +m4_dnl where "private" means file-scope; i.e. static C functions. + +m4_ifdef( [[M4_YY_NO_UNISTD_H]],, +[[ +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. */ +# include +#else +# ifdef __cplusplus +extern "C" { + extern int isatty(int, fd); +} +# else +extern int isatty(int, fd); +# endif +#endif +]]) + +#ifndef YY_ +# ifdef YYENABLE_NLS +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_(msgid) dgettext ("flex-runtime", msgid) +# else +# define YY_(msgid) msgid +# endif +#endif + +/************************************************************/ +/* Private (file scope) CPP definitions */ + +m4_if_tables_serialization([[ +/* The name for this specific scanner's tables. */ +#define YYTABLES_NAME "M4_YY_TABLES_NAME" +]]) + +m4_ifdef( [[M4_YY_VARIABLE_TRAILING_CONTEXT_RULES]], +[[ +#define YY_TRAILING_MASK M4_YY_TRAILING_MASK; +#define YY_TRAILING_HEAD_MASK M4_YY_TRAILING_HEAD_MASK; +]]) + +m4_ifdef( [[M4_YY_SKIP_YYWRAP]], + [[ +#define YY_SKIP_YYWRAP +m4_dnl C++ uses an inline yywrap constant function instead of a macro + m4_if_c_only([[ +#define yywrap() 1 + ]]) +]]) + +m4_ifdef( [[M4_FLEX_DEBUG]], +[[ +#define FLEX_DEBUG +]]) + +m4_if_reentrant([[ +#define YY_REENTRANT 1 +]]) + +m4_ifdef( [[M4_YY_TEXT_IS_ARRAY]],, +[[ +#define yytext_ptr yytext +]]) + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +#define YY_JAMBASE M4_YY_JAMBASE +#define YY_JAMSTATE M4_YY_JAMSTATE +#define YY_LASTDFA M4_YY_LASTDFA +#define YY_NUL_EC M4_YY_NUL_EC + +/* These are bit-flags for yy_init */ +#define YYLEX_INIT_STATE 1 +#define YYLEX_INIT_USER 2 + +#define YY_NUM_RULES M4_YY_NUM_RULES +#define YY_END_OF_BUFFER m4_eval(M4_YY_NUM_RULES+1) + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the()-less + * definition of BEGIN. + */ +#define BEGIN yy_start = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START ((yy_start - 1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart( yyin ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* The state buf must be large enough to hold one state per character in the main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + +m4_ifdef( [[M4_YY_USE_LINENO]], +[[ +/* Note: We specifically omit the test for yy_rule_can_match_eol because it requires + * access to the local variable yy_act. Since yyless() is a macro, it would break + * existing scanners that call yyless() from OUTSIDE yylex. + * One obvious solution it to make yy_act a global. I tried that, and saw + * a 5% performance hit in a non-yylineno scanner, because yy_act is + * normally declared as a register variable-- so it is not worth it. + */ +#define YY_LESS_LINENO(n) \ + do { \ + int yyl; \ + for( yyl = n; yyl < yyleng; ++yyl ) \ + if ( yytext[[yyl]] == '\n' ) \ + M4_YY_DECR_LINENO; \ + } while (0) +]], +[[ +#define YY_LESS_LINENO(n) +]]) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg); \ + *yy_cp = yy_hold_char; \ + YY_RESTORE_YY_MORE_OFFSET \ + yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) + +m4_if_c_only([[ + m4_ifdef( [[M4_YY_NO_UNPUT]],,[[m4_dnl +m4_dnl m4 macros will insert the yyscanner arg to yyinputi here, if needed. +#define unput(c) yyunput( c, yytext_ptr ) + ]]) +]]) + +#ifndef YY_NO_INPUT +m4_if_reentrant([[m4_dnl +#define input() yyinput(yyscanner) +]],m4_dnl +[[m4_dnl +#define input() yyinput() +]])m4_dnl +#endif + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( yy_buffer_stack \ + ? yy_buffer_stack[yy_buffer_stack_top] \ + : NULL ) + +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE yy_buffer_stack[yy_buffer_stack_top] + +m4_if_c_only([[ + +#define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER) + +#define yy_new_buffer yy_create_buffer + +#define yy_set_interactive(is_interactive_) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + yyensure_buffer_stack(); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer( yyin, YY_BUF_SIZE); \ + } \ + YY_CURRENT_BUFFER->is_interactive = is_interactive_; \ + } + +#define yy_set_bol(at_bol_) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + yyensure_buffer_stack(); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer( yyin, YY_BUF_SIZE); \ + } \ + YY_CURRENT_BUFFER->at_bol = at_bol_; \ + } + +#define YY_AT_BOL() (YY_CURRENT_BUFFER->at_bol) + +]]) + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. +YY_TEXT_IS_ARRAY = m4_ifdef([[M4_YY_TEXT_IS_ARRAY]],[[true]],[[false]]) +YY_USES_YYMORE = m4_ifdef([[M4_YY_USES_YYMORE]],[[true]],[[false]]) + */ +m4_dnl Define YY_DO_BEFORE_ACTION, depending on yytext and yymore usage. +m4_dnl This is converted to macro format with backslash line continuations +m4_dnl after it is defined to avoid errors in M4 processing, and to allow +m4_dnl the same code to be as a non-macro function body in the C++ code. +m4_dnl +m4_define([[M4_YY_DO_BEFORE_ACTION]], +[[ + yytext_ptr = yy_bp; +m4_dnl %% [2.0] code to fiddle yytext and yyleng for yymore() goes here + m4_if(m4_defined([[M4_YY_USES_YYMORE]]) && !m4_defined([[M4_YY_TEXT_IS_ARRAY]]), + [[ + yytext_ptr -= yy_more_len; + yyleng = (size_t) (yy_cp - yytext_ptr); + ]], + [[ + yyleng = (size_t) (yy_cp - yy_bp); + ]]) + yy_hold_char = *yy_cp; + *yy_cp = '\0'; +m4_dnl %% [3.0] code to copy yytext_ptr to yytext[] goes here, if %array + m4_ifdef( [[M4_YY_TEXT_IS_ARRAY]], + [[ + m4_ifdef( [[M4_YY_USES_YYMORE]], + [[ + if ( yyleng + yy_more_offset >= YYLMAX ) + YY_FATAL_ERROR("token too large, exceeds YYLMAX"); + yy_flex_strncpy( &yytext[yy_more_offset], yytext_ptr, yyleng + 1); + yyleng += yy_more_offset; + yy_prev_more_offset = yy_more_offset; + yy_more_offset = 0; + + ]], + [[ + if ( yyleng >= YYLMAX ) + YY_FATAL_ERROR("token too large, exceeds YYLMAX"); + yy_flex_strncpy( yytext, yytext_ptr, yyleng + 1); + ]]) + ]]) + yy_c_buf_p = yy_cp; +]]) + +#define YY_DO_BEFORE_ACTION \ +m4_escape_newline(M4_YY_DO_BEFORE_ACTION) + +m4_ifdef( [[M4_YY_USES_REJECT]], +[[ +#define REJECT \ +{ \ + *yy_cp = yy_hold_char; /* undo effects of setting up yytext */ \ + yy_cp = yy_full_match; /* restore poss. backed-over text */ \ +m4_ifdef( [[M4_YY_variable_trailing_context_rules]],[[m4_dnl \ + yy_lp = yy_full_lp; /* restore orig. accepting pos. */ \ + yy_state_ptr = yy_full_state; /* restore orig. state */ \ + yy_current_state = *yy_state_ptr; /* restore curr. state */ \ +]])m4_dnl \ + ++yy_lp; \ + goto find_rule; \ +} +]], +[[ +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +]]) + +m4_ifdef( [[M4_YY_USES_YYMORE]], +[[ + m4_ifdef( [[M4_YY_TEXT_IS_ARRAY]], + [[ +#define yymore() (yy_more_offset = yy_flex_strlen(yytext)) +#define YY_NEED_STRLEN +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET \ + { \ + yy_more_offset = yy_prev_more_offset; \ + yyleng -= yy_more_offset; \ + } + ]], + [[ +#define yymore() (yy_more_flag = 1) +#define YY_MORE_ADJ yy_more_len +#define YY_RESTORE_YY_MORE_OFFSET + ]]) +]], +[[ +/* The intent behind this definition is that it'll catch + * any uses of yymore() which flex missed. + */ +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +]]) + +#ifndef YY_START_CONDITIONS_DEFINED +M4_YY_SC_DEFS +#endif + +/************************************************************/ +m4_if_reentrant([[m4_dnl +/* Prefix conversion and reentrant-struct access macros, for user code. */ +]],[[m4_dnl +/* Prefix conversion macros, for user code. */ +]]) +#ifndef YY_NO_RENAME_MACROS +m4_if_cxx_only([[#define yylex lex]]) +m4_dnl remove `[YYLMAX]' from `yytext[YYLMAX]' and remove #defines for yylval,yylloc +m4_patsubst(m4_dquote(m4_patsubst(M4_CPP_RENAME_MACROS,\[YYLMAX\])),[[#define yyl\(val\|loc\) .*]]) +m4_ifelse(M4_YY_PREFIX,[[yy]],,[[ +/* These have renamed prefixes in previous flex versions. All other + * static functions retain the yy prefix, so these were changed to conform. + */ +#define M4_YY_PREFIX()_init_buffer yy_init_buffer +#define M4_YY_PREFIX()_load_buffer_state yy_load_buffer_state +]]) +#endif /* YY_NO_RENAME_MACROS */ +m4_if_reentrant([[ +/* FIXME: why are these mapped to a specific buffer only for the reentrant scanner?? */ +#undef yylineno +#define yylineno (YY_CURRENT_BUFFER->bs_lineno) +#define yycolumn (YY_CURRENT_BUFFER->bs_column) +]]) + diff --git a/flex_private_protos.m4 b/flex_private_protos.m4 new file mode 100644 index 0000000..9221eb5 --- /dev/null +++ b/flex_private_protos.m4 @@ -0,0 +1,65 @@ +/****************** Private Function Prototypes **********************/ + +m4_if_tables_serialization([[ +m4_if_c_only([[ +M4_FUNC_PROTO(static int, yytbl_hdr_read, struct yytbl_hdr *th, struct yytbl_reader *rd); +M4_FUNC_PROTO(static struct yytbl_dmap *, yytbl_dmap_lookup, struct yytbl_dmap *dmap, int id); +M4_FUNC_PROTO(static int, yytbl_data_load, struct yytbl_dmap *dmap, struct yytbl_reader *rd); +M4_FUNC_PROTO(static int, yytbl_fload, M4_INSTREAM *fp, const char *key); +]], +[[ +M4_FUNC_PROTO_NG(static int, yytbl_hdr_read, struct yytbl_hdr *th, struct yytbl_reader *rd); +M4_FUNC_PROTO_NG(static struct yytbl_dmap *, yytbl_dmap_lookup, struct yytbl_dmap *dmap, int id); +M4_FUNC_PROTO_NG(static int, yytbl_data_load, struct yytbl_dmap *dmap, struct yytbl_reader *rd); +M4_FUNC_PROTO_NG(static int, yytbl_fload, M4_INSTREAM *fp, const char *key); +]]) +M4_FUNC_PROTO_NG(static flex_int32_t, yytbl_calc_total_len, const struct yytbl_data *tbl); +M4_FUNC_PROTO_NG(static int, yytbl_read8, void *v, struct yytbl_reader *rd); +M4_FUNC_PROTO_NG(static int, yytbl_read16, void *v, struct yytbl_reader *rd); +M4_FUNC_PROTO_NG(static int, yytbl_read32, void *v, struct yytbl_reader *rd); +]]) + +m4_if_cxx_or_reentrant([[ +M4_FUNC_PROTO(static int, yy_init_globals); +]]) + +M4_FUNC_PROTO(static void, yyensure_buffer_stack); +M4_FUNC_PROTO(static void, yy_load_buffer_state); +M4_FUNC_PROTO(static void, yy_init_buffer, YY_BUFFER_STATE b, M4_INSTREAM *file); +M4_FUNC_PROTO(static yy_state_type, yy_get_previous_state); +M4_FUNC_PROTO(static yy_state_type, yy_try_NUL_trans, yy_state_type current_state); +M4_FUNC_PROTO(static int, yy_get_next_buffer); +M4_FUNC_PROTO(static void, yy_fatal_error, const char *msg); + +m4_ifdef( [[M4_YY_NO_UNPUT]],,[[ +M4_FUNC_PROTO(static void, yyunput, int c, char *buf_ptr); +]]) + +m4_if_c_only([[ +m4_ifdef( [[M4_YY_TEXT_IS_ARRAY]],[[ +M4_FUNC_PROTO_NG(static void, yy_flex_strncpy, char *dest, const char *src, unsigned int nmax); +]]) + +#ifdef YY_NEED_STRLEN +M4_FUNC_PROTO_NG(static int, yy_flex_strlen, const char *str); +#else +#define yy_flex_strlen strlen +#endif +]]) + +#ifndef YY_NO_INPUT +M4_FUNC_PROTO(static int, yyinput); +#endif + +m4_ifdef( [[M4_YY_NO_PUSH_STATE]],,[[ +M4_FUNC_PROTO(static void, yy_push_state, int new_state); +]]) + +m4_ifdef( [[M4_YY_NO_POP_STATE]],,[[ +M4_FUNC_PROTO(static void, yy_pop_state); +]]) + +m4_ifdef( [[M4_YY_NO_TOP_STATE]],,[[ +M4_FUNC_PROTO(static int, yy_top_state); +]]) + diff --git a/flex_private_typedefs.m4 b/flex_private_typedefs.m4 new file mode 100644 index 0000000..a60acdc --- /dev/null +++ b/flex_private_typedefs.m4 @@ -0,0 +1,55 @@ +/**** Private typedefs ****/ +typedef M4_YY_CHAR_TYPE YY_CHAR; + +struct yy_trans_info +{ +m4_ifdef([[M4_YY_TRANS_INFO_32BIT]],[[m4_dnl + flex_int32_t yy_verify; + flex_int32_t yy_nxt; +]],m4_dnl +[[m4_dnl + flex_int16_t yy_verify; + flex_int16_t yy_nxt; +]])m4_dnl +}; + +m4_ifdef( [[M4_YY_FULLSPD]], +[[ +typedef const struct yy_trans_info *yy_state_type; +]], +[[ +typedef int yy_state_type; +]]) + +m4_if_tables_serialization([[ +m4_flex_include([[tables_shared.h]]) +/** Describes a mapping from a serialized table id to its deserialized state in + * this scanner. This is the bridge between our "generic" deserialization code + * and the specifics of this scanner. + */ +struct yytbl_dmap { + enum yytbl_id dm_id; /**< table identifier */ + void **dm_arr; /**< address of pointer to store the deserialized table. */ + size_t dm_sz; /**< local sizeof() each element in table. */ +}; + +/** A tables-reader object to maintain some state in the read. */ +struct yytbl_reader { + M4_INSTREAM * fp; /**< input stream */ + flex_uint32_t bread; /**< bytes read since beginning of current tableset */ +}; +]]) + +m4_if_reentrant([[ +/* Holds the entire state of the reentrant C scanner. */ +struct yyobject_t + { + /* User-accessible globals (via set/get) */ +M4_PUBLIC_GLOBALS() + + /* Private and other globals for use within yylex() */ +M4_PRIVATE_GLOBALS() + + }; /* end struct yyobject_t */ +]]) + diff --git a/flex_public_header.m4 b/flex_public_header.m4 new file mode 100644 index 0000000..791a5f5 --- /dev/null +++ b/flex_public_header.m4 @@ -0,0 +1,210 @@ +/************************************************************/ +/* Public CPP definitions */ +/* FIXME: Some of this file should be in the private header section. */ + +#define YY_INT_ALIGNED M4_YY_INT_ALIGNED() + +m4_ifdef( [[M4_YY_DO_STDINIT]], +[[ +/* yyin and yyout are always set to stdin and stdout if NULL during the + * first call to yylex(). Ths STDINIT feature only determines if they + * should be initialized to stdio at compile time. + */ +#ifdef VMS +# ifndef __VMS_POSIX +# undef YY_STDINIT +# endif +#endif + +#ifdef YY_STDINIT +#define YYIN_INIT M4_STDIN; +#define YYOUT_INIT M4_STDOUT; +#else +#define YYIN_INIT ((M4_INSTREAM *)0) +#define YYOUT_INIT ((M4_OUTSTREAM *)0) +#endif +]], +[[ +#define YYIN_INIT ((M4_INSTREAM *)0) +#define YYOUT_INIT ((M4_OUTSTREAM *)0) +]]) + +#define FLEX_SCANNER +m4_define(m4_define_version_,[[ +#define YY_FLEX_MAJOR_VERSION $1 +#define YY_FLEX_MINOR_VERSION $2 +#define YY_FLEX_SUBMINOR_VERSION $3 +]]) +#define YY_FLEX_VERSION M4_FLEX_VERSION() +m4_define_version_(m4_patsubst(M4_FLEX_VERSION(),[[\.]],[[,]])) +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +m4_ifdef( [[M4_YY_IN_HEADER]], +[[ +#ifdef YY_HEADER_EXPORT_START_CONDITIONS +#define YY_START_CONDITIONS_DEFINED +M4_YY_SC_DEFS +#endif]]) + +m4_ifdef( [[M4_YY_FLEX_LEX_COMPAT]], +[[ +#define YY_FLEX_LEX_COMPAT +]]) + +m4_ifdef( [[M4_EXTRA_TYPE_DEF]], +[[ +#define YY_EXTRA_TYPE M4_EXTRA_TYPE_DEF +]]) + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#define YY_BUF_SIZE 16384 +#endif + +m4_ifdef( [[M4_YY_TEXT_IS_ARRAY]], +[[ +#ifndef YYLMAX +#define YYLMAX 8192 +#endif +]]) + +m4_ifdef( [[M4_EXTRA_TYPE_DEF]],, +[[ +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif +]]) + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* FIXME: move these to the private header? */ +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +m4_if_c_only([[ +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). Checking for successful output is new. + */ +#define ECHO if ( fwrite(yytext, 1, yyleng, yyout) != yyleng) \ + { YY_FATAL_ERROR("output in flex scanner failed"); } +]], +[[ +#define ECHO if ( LexerOutput( yytext, yyleng) != yyleng) \ + { YY_FATAL_ERROR("output in flex scanner failed"); } +]]) +#endif + +m4_ifdef([[M4_YY_OUTPUT]], +[[ +/* NOTE: Flex does not use this macro. Redefining it will not + * redirect output. + */ + m4_if_cxx_streamio([[ +#define output(c) yyout->put(c) + ]], + [[ +#define output(c) fputc(c,yyout) + ]]) +]]) + +/* YY_INPUT Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +m4_if_cxx_only( +[[ +#define YY_INPUT(buf,result,max_size) \ + if ( (result = LexerInput( (char *) buf, max_size )) < 0 ) \ + YY_FATAL_ERROR("input in flex scanner failed"); +]], +[[ +m4_dnl M4_YY_INPUT is defined in flex_code_macros.m4 +#define YY_INPUT(buf,result,max_size) \ +m4_escape_newline(M4_YY_INPUT) +]]) +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +m4_ifdef( [[M4_YY_NO_ISATTY]],, +[[ +#ifndef YY_ISATTY +m4_if_cxx_streamio([[ +/* There is no portable way to get an associated file descriptor for a C++ stream. + * If isatty() is available, this seems like a reasonable best guess. If you really + * want portable code, it is bette to have an interactive option flag. + */ +#define YY_ISATTY(file) ((file==std::cin) ? (isatty(fileno(stdin)) > 0) : 0) +]],[[ +#define YY_ISATTY(file) (file ? (isatty(fileno(file)) > 0) : 0) +]]) +#endif +]]) + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +# ifdef YYENABLE_NLS +m4_if_reentrant(m4_dnl +# define YY_FATAL_ERROR(msg) yy_fatal_error(YY_(msg), yyscanner) +# else +# define YY_FATAL_ERROR(msg) yy_fatal_error(msg, yyscanner) +,[[m4_dnl +# define YY_FATAL_ERROR(msg) yy_fatal_error(YY_(msg)) +# else +# define YY_FATAL_ERROR(msg) yy_fatal_error(msg) +]])[[]]m4_dnl +# endif +#endif + +m4_dnl NOTE: if porting to a simple OS, EXIT_FAILURE may be preferred here. +/* The exit() code for fatal errors. */ +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +/* Report a non-fatal error. (experimental) */ +#ifndef YY_NONFATAL_ERROR +#define YY_NONFATAL_ERROR YY_FATAL_ERROR +#endif + +m4_if_cxx_only([[ +m4_define([[M4_YY_GLOBAL_FATAL_ERROR]],[[YY_GLOBAL_FATAL_ERROR($*)]]) +m4_define([[M4_YY_GLOBAL_NONFATAL_ERROR]],[[YY_GLOBAL_NONFATAL_ERROR($*)]]) +#ifndef YY_GLOBAL_FATAL_ERROR +#define YY_GLOBAL_FATAL_ERROR M4_YY_LEX_CLASS(::)LexerClassError +#endif +#ifndef YY_GLOBAL_NONFATAL_ERROR +#define YY_GLOBAL_NONFATAL_ERROR M4_YY_LEX_CLASS(::)LexerClassError +#endif +]],[[ +m4_define([[M4_YY_GLOBAL_FATAL_ERROR]],[[YY_FATAL_ERROR($*)]]) +m4_define([[M4_YY_GLOBAL_NONFATAL_ERROR]],[[YY_NONFATAL_ERROR($*)]]) +]]) + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + diff --git a/flex_public_protos.m4 b/flex_public_protos.m4 new file mode 100644 index 0000000..552f57e --- /dev/null +++ b/flex_public_protos.m4 @@ -0,0 +1,152 @@ +/*******************************************************************/ +/* Declaration of public functions */ +m4_if_c_only([[ +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +m4_ifdef( [[M4_YY_BISON_LLOC]],[[m4_dnl +M4_FUNC_PROTO(extern int, yylex, YYSTYPE *yylval, YYLTYPE *yylloc); +]],[[m4_dnl + m4_ifdef( [[M4_YY_BISON_LVAL]],[[ +M4_FUNC_PROTO(extern int, yylex, YYSTYPE *yylval); + ]],[[m4_dnl +M4_FUNC_PROTO(extern int, yylex); + ]])m4_dnl +]]) +#endif +]]) + +m4_ifdef( [[M4_YY_SKIP_YYWRAP]],,[[ +#ifndef YY_SKIP_YYWRAP +M4_FUNC_PROTO(extern int, yywrap); +#endif +]]) + +M4_FUNC_PROTO(extern void, yyrestart, M4_INSTREAM *input_file); +M4_FUNC_PROTO(extern void, yy_switch_to_buffer, YY_BUFFER_STATE new_buffer); +M4_FUNC_PROTO(extern YY_BUFFER_STATE, yy_create_buffer, M4_INSTREAM *file, int size ); +M4_FUNC_PROTO(extern void, yy_delete_buffer, YY_BUFFER_STATE b); +M4_FUNC_PROTO(extern void, yy_flush_buffer, YY_BUFFER_STATE b); +M4_FUNC_PROTO(extern void, yypush_buffer_state, YY_BUFFER_STATE new_buffer); +M4_FUNC_PROTO(extern void, yypop_buffer_state); + +m4_if_c_only([[ +M4_FUNC_PROTO(extern void *, yyalloc, yy_size_t size); +M4_FUNC_PROTO(extern void *, yyrealloc, void *ptr, yy_size_t size); +M4_FUNC_PROTO(extern void, yyfree, void *ptr); +]]) + +M4_FUNC_PROTO(extern YY_BUFFER_STATE, yy_scan_buffer, char *base, yy_size_t size); +M4_FUNC_PROTO(extern YY_BUFFER_STATE, yy_scan_string, const char *yy_str); +M4_FUNC_PROTO(extern YY_BUFFER_STATE, yy_scan_bytes, const char *bytes, int len); + + +m4_if_reentrant([[ +/* Constructors for the C reentrant scanner. The destructor is + * yylex_destroy(), which is also used to release the non-reentrant scanner. + */ +M4_FUNC_PROTO_NG(extern int, yylex_init, yyscan_t *yyscanner_return); + +M4_FUNC_PROTO_NG(extern int, yylex_init_extra, YY_EXTRA_TYPE user_defined, yyscan_t *yyscanner_return); +]]) +M4_FUNC_PROTO(extern void, yylex_init_state); + +/*******************************************************************/ +/* Accessor methods to globals. + * These are made visible to non-reentrant scanners for convenience. + * A nice feature would be an option to make these inline functions. + */ + +m4_ifdef( [[M4_YY_NO_DESTROY]],,[[ +M4_FUNC_PROTO(extern int, yylex_destroy); +]]) + +m4_ifdef( [[M4_YY_NO_GET_DEBUG]],,[[ +M4_FUNC_PROTO(extern int, yyget_debug); +]]) + +m4_ifdef( [[M4_YY_NO_SET_DEBUG]],,[[ +M4_FUNC_PROTO(extern void, yyset_debug, int debug_flag); +]]) + +m4_ifdef( [[M4_YY_NO_GET_EXTRA]],,[[ +M4_FUNC_PROTO(extern YY_EXTRA_TYPE, yyget_extra); +]]) + +m4_ifdef( [[M4_YY_NO_SET_EXTRA]],,[[ +M4_FUNC_PROTO(extern void, yyset_extra, YY_EXTRA_TYPE user_defined); +]]) + +m4_ifdef( [[M4_YY_NO_GET_IN]],,[[ +M4_FUNC_PROTO(extern M4_INSTREAM *, yyget_in); +]]) + +m4_ifdef( [[M4_YY_NO_SET_IN]],,[[ +M4_FUNC_PROTO(extern void, yyset_in, M4_INSTREAM *in_str); +]]) + +m4_ifdef( [[M4_YY_NO_GET_OUT]],,[[ +M4_FUNC_PROTO(extern M4_OUTSTREAM *, yyget_out); +]]) + +m4_ifdef( [[M4_YY_NO_SET_OUT]],,[[ +M4_FUNC_PROTO(extern void, yyset_out, M4_OUTSTREAM *out_str); +]]) + +m4_ifdef( [[M4_YY_NO_GET_LENG]],,[[ +M4_FUNC_PROTO(extern int, yyget_leng); +]]) + +m4_ifdef( [[M4_YY_NO_GET_TEXT]],,[[ +M4_FUNC_PROTO(extern char *, yyget_text); +]]) + +m4_ifdef( [[M4_YY_NO_GET_LINENO]],,[[ +M4_FUNC_PROTO(extern int, yyget_lineno); +]]) + +m4_ifdef( [[M4_YY_NO_SET_LINENO]],,[[ +M4_FUNC_PROTO(extern void, yyset_lineno, int line_number); +]]) + +m4_ifdef( [[M4_YY_NO_GET_COLUMN]],,[[ +M4_FUNC_PROTO(extern int, yyget_column); +]]) + +m4_ifdef( [[M4_YY_NO_SET_COLUMN]],,[[ +M4_FUNC_PROTO(extern void, yyset_column, int column_no); +]]) + +m4_ifdef( [[M4_YY_NO_GET_LVAL]],,[[ +M4_FUNC_PROTO(extern YYSTYPE *, yyget_lval); +]]) + +m4_ifdef( [[M4_YY_NO_SET_LVAL]],,[[ +M4_FUNC_PROTO(extern void, yyset_lval, YYSTYPE *yylval_param); +]]) + +m4_ifdef( [[M4_YY_NO_GET_LLOC]],,[[ +M4_FUNC_PROTO(extern YYLTYPE *, yyget_lloc); +]]) + +m4_ifdef( [[M4_YY_NO_SET_LLOC]],,[[ +M4_FUNC_PROTO(extern void, yyset_lloc, YYLTYPE *yylloc_param); +]]) + +m4_if_tables_serialization([[ + m4_if_c_only([[ +/* Load the DFA tables from the given stream. */ +M4_FUNC_PROTO(extern int, yytables_fload, M4_INSTREAM *fp); + +/* Unload the tables from memory. */ +M4_FUNC_PROTO(extern int, yytables_destroy); + ]], + [[ m4_dnl The C++ version is a static class function. +/* Load the DFA tables from the given stream. */ +M4_FUNC_PROTO_NG(extern int, yytables_fload, M4_INSTREAM *fp); + +/* Unload the tables from memory. */ +M4_FUNC_PROTO_NG(extern int, yytables_destroy); + ]]) +]]) diff --git a/flex_public_typedefs.m4 b/flex_public_typedefs.m4 new file mode 100644 index 0000000..206abc9 --- /dev/null +++ b/flex_public_typedefs.m4 @@ -0,0 +1,76 @@ +/************************************************************/ +/* Public Typedefs */ + +m4_if_reentrant([[ +/* An opaque pointer. */ +#ifndef YY_TYPEDEF_YY_SCANNER_T +#define YY_TYPEDEF_YY_SCANNER_T +typedef void* yyscan_t; +#endif + +]]) +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +m4_dnl NOTE: Declare the struct before using it in a typedef (required in C++) +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + M4_INSTREAM *input_file; + + char *ch_buf; /* input buffer */ + char *buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int at_bol; + + int bs_lineno; /**< The line count. */ + int bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int fill_buffer; + + /* Buffer status #defines are currently not written to the + * public header. + */ + int buffer_status; + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + diff --git a/flex_skel.m4 b/flex_skel.m4 new file mode 100644 index 0000000..ce3a035 --- /dev/null +++ b/flex_skel.m4 @@ -0,0 +1,725 @@ +m4_divert(-1) +# -*-C-*- vim:set ft=cxxm4:set noexpandtab cindent: +m4_dnl This skeleton requires gnu m4 for the m4_ prefix option, and the patsubst and regex commands. +m4_ifdef(`__gnu__',,`m4_errprint(Flex requires GNU M4. Set the PATH or set the M4 environment variable to its path name.) m4_m4exit(2)') +m4_changequote +m4_changequote([[,]]) +#################################################################### +# All generate macros for the m4 stage contain the text "m4" or "M4" +# in them, to distinguish them from CPP macros. +# +# m4_if_reentrant([[]]) - evaluate for reentrant scanners. +# m4_if_not_reentrant([[]]) - evaluate for non-reentrant scanners. +# m4_if_tables_serialization([[]]) - evaluate for external tables +# m4_if_cxx_only([[]]) - evaluate for C++ class scanner +# m4_if_c_only([[]]) - evaluate for C, reentrant or non-reentrant +# m4_if_cxx_or_reentrant([[]]) - eval for C++ class or reentrant C +# m4_if_cxx_or_not_reentrant([[]]) - eval for C++ class or non-reentrant C +# m4_if_cxx_streamio([[]]) - eval for C++ streamio, which man be enabled +# for any of the three scanner types. +# ... more macros are defined ... +# +# %% - A stop-point, where code is inserted by flex. +# Each stop-point is numbered here and also in the code generator. +# (See gen.c, etc. for details.) +# +########################################################################## +# Sections containing user-defined code must be quoted to prevent m4 +# processing of user code. They already contain code with quote-escapes +# inserted by the flex input scanner, and just need te outer quotes here. +########################################################################### +%% M4 DEFINES +# Include standard macros (including conditionals listed above) +m4_include(M4_FLEX_INCLUDE/flex_header.m4) + +m4_flex_include([[flex_code_macros.m4]]) + +m4_flex_include([[flex_globals.m4]]) + +m4_dnl The generated main() does not use yywrap(). +m4_ifdef( [[M4_YY_MAIN]], [[ + m4_define([[M4_YY_SKIP_YYWRAP]]) +]]) + +######################## BEGIN OUTPUT ############################# +m4_changecom +m4_divert(0) + +m4_ifdef( [[M4_YY_IN_HEADER]],[[ +#ifndef M4_YY_PREFIX()FLEX_HEADER_H +#define M4_YY_PREFIX()FLEX_HEADER_H +#define M4_YY_PREFIX()IN_HEADER 1 +]],[[ + m4_ifdef( [[M4_FLEX_DEBUG]], + [[ + m4_flex_include([[flex_print_m4_params.m4]]) + ]]) + m4_ifdef( [[M4_YY_INCLUDE_HEADER]], + [[ +#include "M4_YY_HEADER_FILENAME" + m4_divert(-1) + ]], + [[ +#ifndef M4_YY_PREFIX()FLEX_HEADER_H + ]]) +]]) +/* A lexical scanner generated by flex */ +[[ +%% USER TOP CODE -- %top{ ... } OR %header{ ... %} +]]m4_changequote(-=<{,}>=-)m4_dnl +%% USER PREDEFINES +-=<{}>=-m4_changequote([[,]]) +M4_LINE_DIRECTIVE() + +m4_ifdef( [[M4_YY_IN_HEADER]],, +[[[[ +%% USER CODE SECTION 1 +]]M4_LINE_DIRECTIVE()]]) + +/* begin standard C headers. */ +m4_if_cxx_streamio(,[[ +#include +]]) +m4_if_c_only([[ +#include +#include +]], +[[ +#include /* C memory allocation is used in the C++ class */ +]]) +#include +m4_if_tables_serialization([[ +/* These are for ntohs() and ntohl(), used for serialized tables: */ +#include +#include +]]) +/* end standard C headers. */ + +/* begin standard C++ headers. */ +m4_if_cxx_streamio([[ +#include +]], +[[ + m4_if_cxx_only([[ +#include + ]]) +]]) +m4_if_cxx_only([[ +#include +#include +]]) +/* end standard C++ headers. */ + +/* begin "flexint.h" */ +m4_flex_include([[flexint.h]])[[]] +/* end "flexint.h" */ + +m4_if_c_only([[ +m4_ifdef([[M4_YY_NAMESPACE]],[[ +namespace M4_YY_NAMESPACE() { +]]) +m4_flex_include([[flex_public_header.m4]]) +m4_ifdef([[M4_YY_NO_EXTERN_C]],,[[ +#ifdef __cplusplus +extern "C" { +#endif +]]) +m4_flex_include([[flex_public_typedefs.m4]]) +m4_if_not_reentrant([[ +/************************************************************/ +/* Declaration of public globals */ +M4_PUBLIC_GLOBALS() +]]) +m4_flex_include([[flex_public_protos.m4]]) +m4_ifdef([[M4_YY_NO_EXTERN_C]],,[[ +#ifdef __cplusplus +} /* end extern "C" */ +#endif +]]) +m4_ifdef([[M4_YY_NAMESPACE]],[[ +} /* end namespace M4_YY_NAMESPACE() */ +]]) +]], +[[ +/************************************************************/ +/* These defines prevent inclusion of the previous "FlexLexer.h" by user code. */ +#define yyFlexLexerOnce +#define __FLEX_LEXER_H + +#ifndef YYLEX_BASE_CLASS_DEFINED +#define YYLEX_BASE_CLASS_DEFINED + +m4_flex_include([[flex_public_header.m4]]) + +/* pure-virtual base class */ +class M4_YY_LEX_BASE_CLASS { +public: +m4_flex_include([[flex_public_typedefs.m4]]) + +protected: /*FIXME protected: */ +m4_flex_include([[flex_private_typedefs.m4]]) + +public: +/* Note: no destructor defined */ + virtual ~M4_YY_LEX_BASE_CLASS()(void) { }; + + virtual void switch_to_buffer(YY_BUFFER_STATE new_buffer ) = 0; + virtual YY_BUFFER_STATE create_buffer(M4_INSTREAM* stream, int size ) = 0; + virtual void delete_buffer(YY_BUFFER_STATE buffer ) = 0; + virtual void restart(M4_INSTREAM* stream ) = 0; + virtual int lex(void) = 0; + + // NOTE: In Flex, yytext is allowed to be modified in scanner actions. + // This version allows read-only access for general use with the base class. + inline const char* YYText(void) { return text; } + inline int YYLeng(void) { return leng; } + //inline int lineno() const { return yylineno; } + inline int debug() const { return flex_debug; } + inline void debug( int flag ) { flex_debug = flag; } + + // Call yylex with new input/output sources. + inline int lex(M4_INSTREAM* new_in, M4_OUTSTREAM* new_out = NULL ) + { + switch_streams( new_in, new_out ); + return lex(); + } + + // Switch to new input/output streams. If NULL, the stream is unchanged. + virtual void switch_streams( M4_INSTREAM* new_in = NULL, + M4_OUTSTREAM* new_out = NULL ) = 0; + + /************ Common state variables ************/ +// These are equivalent to the public globals in the non-reentrant C scanner. + +protected: + +M4_PUBLIC_GLOBALS() + +}; /* end M4_YY_LEX_BASE_CLASS */ +#endif // YYLEX_BASE_CLASS_DEFINED + +#define yyFlexLexer M4_YY_LEX_CLASS() + +class M4_YY_LEX_CLASS() : public M4_YY_LEX_BASE_CLASS { +public: +m4_ifdef( [[M4_YY_NO_EXTRA]],, +[[ + /* User-defined. Not touched by flex. */ + YY_EXTRA_TYPE extra; +]]) + + M4_YY_LEX_CLASS() + (M4_INSTREAM* arg_yyin = M4_STDIN, + M4_OUTSTREAM* arg_yyout = M4_STDOUT); + + ~M4_YY_LEX_CLASS()(void); + +// C++ subclasses must have the standard lex(void) function to +// support the base class. YY_DECL may still be used to alter the +// yy[[]]lex function constructed by flex, but you then must +// provide a body for the default lex() function. +// For Bison lloc and lval, use set_lval() and set_lloc(). + int lex(void); +#ifdef YY_DECL + YY_DECL; +#endif + +m4_ifdef( [[M4_YY_SKIP_YYWRAP]], +[[ + inline int yywrap(void) const { return 1; }; +]]) + +// Declarations for additional C++-only functions. + +/* Standard YY_INPUT() */ + int LexerInput( char* buf, int max_size ); + +/* Standard ECHO() */ + inline int LexerOutput( const char* buf, int size ) + { +m4_if_cxx_streamio([[ +/* With an error, iostream does not expose the number of bytes written, + * so it is estimated as all-or-nothing. (Good enough for error tests.) + */ + out->write( buf, size ); + return (out->bad() ? 0 : size); +]], +[[ + return fwrite( buf, 1, size, out ); +]]) + } + + virtual void LexerError( const char* msg ) { LexerClassError(msg); } + + void switch_streams(M4_INSTREAM* new_in, M4_OUTSTREAM* new_out=0); + +public: +m4_define([[yy_flex_strlen]],[[strlen]]) +M4_FUNC_PROTO_NG(void, LexerClassError, const char *msg); +m4_flex_include([[flex_public_protos.m4]]) + +private: +M4_PRIVATE_GLOBALS() + +private: +m4_dnl This strips the assignments, to give just declarations. +m4_patsubst(m4_quote(M4_GEN_DATA_TABLES),[[\s*=[^;]*;]],[[;]]) + +private: +m4_flex_include([[flex_private_protos.m4]]) + +/* This allows the class to be modified without an additional sub-class */ +#ifdef YY_CLASS_USER_CODE +YY_CLASS_USER_CODE +#endif +}; /* end M4_YY_LEX_CLASS */ +]]) + +m4_ifdef( [[M4_YY_IN_HEADER]],[[ +#undef M4_YY_PREFIX()IN_HEADER +#endif /* M4_YY_PREFIX()FLEX_HEADER_H */ +m4_divert(-1) +]], +[[ +m4_dnl End guard macros for inlined header code. +#endif /* M4_YY_PREFIX()FLEX_HEADER_H */ +m4_divert(0) +]]) +m4_dnl ############ END OF PUBLIC HEADER SECTION ############ + +m4_flex_include([[flex_private_header.m4]]) + +m4_if_c_only([[ +m4_ifdef([[M4_YY_NAMESPACE]],[[ +namespace M4_YY_NAMESPACE() { +]]) +m4_flex_include([[flex_private_typedefs.m4]]) +m4_flex_include([[flex_private_protos.m4]]) +]]) + +m4_if_cxx_or_reentrant(,[[ +/****************** Define globals ******************/ +M4_GLOBALS_DEF() +]]) +/****************** Define Data Tables ******************/ +m4_ifdef([[M4_YY_NXT_TABLE_LOLEN]],[[ +#define YY_NXT_LOLEN (M4_YY_NXT_TABLE_LOLEN) +]]) +m4_if_c_only([[ +m4_dnl This echo is needed to remove inner quoting of data statements, +m4_dnl which is needed to keep formatting through the C++ patsubst below. +m4_echo(M4_GEN_DATA_TABLES) +]],[[ +m4_dnl Add C++ class prefix to all yy* names, and remove 'static'. +m4_bpatsubsts(m4_quote(M4_GEN_DATA_TABLES), +[[\byy]],[[M4_YY_CLASS::yy]], +[[static ]],[[]]) +]]) + +/****************** Define functions *****************/ +#ifdef YY_INPUT_INLINE +M4_FUNC_DEF(inline int, yy_input, char* buf, int max_size) +{ + int result; +M4_YY_INPUT() + return result; +} +#endif +[[ +%% USER BOTTOM CODE -- %bottom{ ... %} +]]M4_LINE_DIRECTIVE() + +/**********************************************************************/ +m4_dnl All other functions are in "flex_functions.m4". This one needs +m4_dnl to be in the main file because it contains %% code insertion marks. +/* The main scanner function which does all the work. + * A #define so the user can easily add parameters. +m4_if_reentrant([[m4_dnl + * If YY_DECL is defined in the reentrant scanner, and includes yylval + * and/or yylloc parameters, #define YY_LVAL_PARAM and YY_LLOC_PARAM to + * the parameter names. Alternatively, leave out those parameters, and + * set them via yyset_lval() and yyset_lloc(). +]])m4_dnl + */ +/* FIXME: SHouldn't at_bol already be valid? If not, what if yyleng==0? (JMK) */ +m4_dnl yycolumn probably needs: yycolumn += yyleng +m4_ifdef( [[M4_YY_BOL_NEEDED]], +[[ +#define YY_RULE_SETUP \ + if ( yyleng > 0 ) \ + YY_CURRENT_BUFFER->at_bol = (yytext[yyleng - 1] == '\n'); \ + YY_USER_ACTION +]], +[[ +#define YY_RULE_SETUP YY_USER_ACTION +]]) + +m4_ifdef( [[M4_YY_BISON_LVAL]],[[ +#ifndef YY_LVAL_PARAM +#define YY_LVAL_PARAM yylval +#endif +]]) +m4_ifdef( [[M4_YY_BISON_LLOC]],[[ +#ifndef YY_LLOC_PARAM +#define YY_LLOC_PARAM yylloc +#endif +]]) +#ifdef YY_DECL +m4_if_cxx_only([[M4_YY_CLASS::]])m4_dnl +YY_DECL +#else +m4_ifdef( [[M4_YY_BISON_LLOC]],[[m4_dnl +M4_FUNC_DEF(int, yylex, YYSTYPE *yylval, YYLTYPE *yylloc) +]],[[m4_dnl + m4_ifdef( [[M4_YY_BISON_LVAL]],[[m4_dnl +M4_FUNC_DEF(int, yylex, YYSTYPE *yylval) + ]],[[m4_dnl +M4_FUNC_DEF(int, yylex) + ]])m4_dnl +]])m4_dnl +#endif +{ + register yy_state_type yy_current_state; + register char *yy_cp, *yy_bp; + register int yy_act; + +m4_if_reentrant([[ + m4_ifdef( [[M4_YY_BISON_LVAL]], + [[ +#ifdef YY_LVAL_PARAM + ((struct yyobject_t*)yyscanner)->lval = YY_LVAL_PARAM; +#define yylval ((struct yyobject_t*)yyscanner)->lval +#endif + ]]) + m4_ifdef( [[M4_YY_BISON_LLOC]], + [[ +#ifdef YY_LVAL_PARAM + ((struct yyobject_t*)yyscanner)->lloc = YY_LLOC_PARAM; +#define yylloc ((struct yyobject_t*)yyscanner)->lloc +#endif + ]]) +]]) +m4_ifdef([[M4_M4_RENAME_MACROS]],m4_echo(M4_M4_RENAME_MACROS()))[[]]m4_dnl +m4_if_tables_serialization([[m4_dnl JMK: added this safety check. + if (yydmap[0].dm_arr && ! *(yydmap[0].dm_arr) ) YY_FATAL_ERROR( + "fatal flex scanner error -- Serialized tables were not loaded" ); +]]) + +[[ +%% USER DECLARATIONS (input section 2) +]]M4_LINE_DIRECTIVE() + if ( ! (yy_init & YYLEX_INIT_USER) ) + { +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + /* If user-init is done, state init has to be done, so + * we avoid an extra conditional for every yylex() call. + */ + yy_init |= YYLEX_INIT_USER; + yylex_init_state(); + } + + while ( 1 ) /* loops until end-of-file is reached */ + { +m4_ifdef( [[M4_YY_USES_YYMORE]], +[[ + m4_ifdef( [[M4_YY_TEXT_IS_ARRAY]],, + [[ + yy_more_len = 0; + if ( yy_more_flag ) + { + yy_more_len = yy_c_buf_p - yytext_ptr; + yy_more_flag = 0; + } + ]]) +]]) + yy_cp = yy_c_buf_p; + + /* Support of yytext. */ + *yy_cp = yy_hold_char; + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + +M4_GEN_START_STATE() + +yy_match: +M4_GEN_NEXT_MATCH() + +yy_find_action: +M4_GEN_FIND_ACTION_NUMBER() + + YY_DO_BEFORE_ACTION; + +m4_ifdef( [[M4_YY_USE_LINENO]], +[[ + if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] ) + { + int yyl; + for ( yyl = m4_dnl + m4_ifdef( [[M4_YY_USES_YYMORE]],[[m4_dnl + m4_ifdef( [[M4_YYTEXT_IS_ARRAY]],m4_dnl + [[yy_prev_more_offset]],m4_dnl + [[yy_more_len]])m4_dnl + ]],[[m4_dnl + [[0]]m4_dnl + ]]); yyl < yyleng; ++yyl) + if ( yytext[yyl] == '\n' ) + M4_YY_INCR_LINENO(); + } +]]) + +do_action: /* This label is used only to access EOF actions. */ + +m4_dnl NOTE: This is the only place using print functions, instead of ERROR macros. +m4_ifdef( [[M4_FLEX_DEBUG]], +[[ + if ( yy_flex_debug ) + { + m4_if_cxx_streamio([[ + if ( yy_act == 0 ) + std::cerr << YY_("--scanner backing up\n"); + else if ( yy_act < YY_NUM_RULES ) + std::cerr << YY_("--accepting rule at line ") + << yy_rule_linenum[yy_act] + << "(\"" << yytext << "\")\n"; + else if ( yy_act == YY_NUM_RULES ) + std::cerr << YY_("--accepting default rule ") + << "(\"" << yytext << "\")\n"); + else if ( yy_act == (YY_NUM_RULES + 1) ) + std::cerr << YY_("--(end of buffer or a NUL)\n"); + else + std::cerr << YY_("--EOF (start condition ") + << YY_START << ")\n"; + ]], + [[ +/* Some of these C messages are split up so that they will have + * the same text strings as messages written using C++ iostream. + */ + if ( yy_act == 0 ) + fprintf( stderr, YY_("--scanner backing up\n")); + else if ( yy_act < YY_NUM_RULES ) + fprintf( stderr, "%s%ld(\"%s\")\n", + YY_("--accepting rule at line "), + (long)yy_rule_linenum[yy_act], yytext ); + else if ( yy_act == YY_NUM_RULES ) + fprintf( stderr, "%s(\"%s\")\n", + YY_("--accepting default rule "), yytext ); + else if ( yy_act == (YY_NUM_RULES + 1) ) + fprintf( stderr, YY_("--(end of buffer or a NUL)\n") ); + else + fprintf( stderr, "%s%d)\n", + YY_("--EOF (start condition "), YY_START ); + ]]) + } +]]) + + switch( yy_act ) + { /* beginning of action switch */ +m4_ifdef([[M4_YY_NEED_BACKING_UP]],[[ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = yy_hold_char; + + m4_ifdef([[M4_YY_COMPRESSED]],[[ + /* Backing-up info for compressed tables is taken *after* + * yy_cp has been incremented for the next state. + */ + yy_cp = yy_last_accepting_cpos; + ]],[[ + yy_cp = yy_last_accepting_cpos + 1; + ]]) + + yy_current_state = yy_last_accepting_state; + goto yy_find_action; +]]) + +m4_dnl This section also contains user code, and must be quoted. +m4_dnl If m4 processing is wanted for the generated parts, the +m4_dnl generated code could be made to internally quote just the +m4_dnl user action code, and leave generated code exposed to m4. +[[ +%% GEN ACTIONS +]]M4_LINE_DIRECTIVE() + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = yy_hold_char; + YY_RESTORE_YY_MORE_OFFSET + + if ( YY_CURRENT_BUFFER->buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action(other than possibly a + * back-up) that will match for the new input source. + */ + yy_n_chars = YY_CURRENT_BUFFER->n_chars; + YY_CURRENT_BUFFER->input_file = yyin; + YY_CURRENT_BUFFER->buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( yy_c_buf_p <= &YY_CURRENT_BUFFER->ch_buf[yy_n_chars] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming(and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state); + + yy_bp = yytext_ptr + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++yy_c_buf_p; + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { +m4_dnl %% [14.0] code to do back-up for compressed tables and set up yy_cp goes here +m4_dnl /* First, deal with backing up and setting up yy_cp if the scanner +m4_dnl * finds that it should JAM on the NUL. +m4_dnl */ +m4_ifdef([[M4_YY_COMPRESSED]],[[ + m4_if(!m4_defined([[M4_YY_USES_REJECT]]) && !m4_defined([[M4_YY_INTERACTIVE]]),[[ +m4_dnl /* Do the guaranteed-needed backing up to figure +m4_dnl * out the match. +m4_dnl */ + yy_cp = yy_last_accepting_cpos; + yy_current_state = yy_last_accepting_state; + ]], + [[ +m4_dnl /* Still need to initialize yy_cp, though +m4_dnl * yy_current_state was set up by +m4_dnl * yy_get_previous_state(). +m4_dnl */ + yy_cp = yy_c_buf_p; + ]]) +]], +[[ + yy_cp = yy_c_buf_p; +]]) + + goto yy_find_action; + } + } + + else switch( yy_get_next_buffer( ) ) + { + case EOB_ACT_END_OF_FILE: + { + yy_did_buffer_switch_on_eof = 0; + + if ( yywrap( ) ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser(like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + yy_c_buf_p = yytext_ptr + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + yy_c_buf_p = + yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = yy_c_buf_p; + yy_bp = yytext_ptr + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + yy_c_buf_p = + &YY_CURRENT_BUFFER->ch_buf[yy_n_chars]; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = yy_c_buf_p; + yy_bp = yytext_ptr + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + YY_("fatal flex scanner internal error--no action found")); + } /* end of action switch */ + } /* end of scanning one token */ +} /* end of yylex */ + +m4_flex_include([[flex_functions.m4]]) + +m4_ifdef([[M4_YY_NAMESPACE]],[[ +} /* end namespace M4_YY_NAMESPACE() */ +]]) +/*********************************************************/ +/* Redefine yyless() so it works in section 3 user code. */ +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + yytext[yyleng] = yy_hold_char; \ + yy_c_buf_p = yytext + yyless_macro_arg; \ + yy_hold_char = *yy_c_buf_p; \ + *yy_c_buf_p = '\0'; \ + yyleng = yyless_macro_arg; \ + } \ + while ( 0 ) + +[[ +%% USER CODE SECTION 3 +]]M4_LINE_DIRECTIVE() + diff --git a/flexdef.h b/flexdef.h index 046dd9a..e0b99f2 100644 --- a/flexdef.h +++ b/flexdef.h @@ -91,9 +91,7 @@ char *alloca (); #define true 1 #define false 0 #endif -#ifdef HAVE_REGEX_H #include -#endif #include "flexint.h" /* We use gettext. So, when we write strings which should be translated, we mark them with _() */ @@ -385,8 +383,10 @@ char *alloca (); * "no more files". * csize - size of character set for the scanner we're generating; * 128 for 7-bit chars and 256 for 8-bit - * yymore_used - if true, yymore() is used in input rules - * reject - if true, generate back-up tables for REJECT macro + * yymore_used - if true, yymore() is used in input rules; true if Flex + * detected use of yymore(), but can be overridden; see yymore_really_used) + * reject - if true, generate back-up tables for REJECT macro; true if Flex + * detected use of reject, but can be overridden; see reject_really_used) * real_reject - if true, scanner really uses REJECT (as opposed to just * having "reject" set for variable trailing context) * continued_action - true if this rule's action is to "fall through" to @@ -396,6 +396,9 @@ char *alloca (); * of what we think based on references to it in the user's actions. * reject_really_used - same for REJECT */ +#ifdef __cplusplus +extern "C" { +#endif extern int printstats, syntaxerror, eofseen, ddebug, trace, nowarn, spprdflt; @@ -403,7 +406,6 @@ extern int interactive, lex_compat, posix_compat, do_yylineno; extern int useecs, fulltbl, usemecs, fullspd; extern int gen_line_dirs, performance_report, backing_up_report; extern int reentrant, bison_bridge_lval, bison_bridge_lloc; -extern bool ansi_func_defs, ansi_func_protos; extern int C_plus_plus, long_align, use_read, yytext_is_array, do_yywrap; extern int csize; extern int yymore_used, reject, real_reject, continued_action, in_rule; @@ -416,15 +418,16 @@ extern int yymore_really_used, reject_really_used; * dataline - number of contiguous lines of data in current data * statement. Used to generate readable -f output * linenum - current input line number - * skelfile - the skeleton file - * skel - compiled-in skeleton array - * skel_ind - index into "skel" array, if skelfile is nil + * out_linenum - current output line number + * skelfile - the skeleton FILE + * skelname - Name of the skeleton source file. + * flex_include_path - path to skeleton m4 files * yyin - input file * backing_up_file - file to summarize backing-up states to * infilename - name of input file * outfilename - name of output file * headerfilename - name of the .h file to generate - * did_outfilename - whether outfilename was explicitly set + * m4outfilename - name of file for intermediate m4 file (for devel debugging) * prefix - the prefix used for externally visible names ("yy" by default) * yyclass - yyFlexLexer subclass to use for YY_DECL * do_stdinit - whether to initialize yyin/yyout to stdin/stdout @@ -443,12 +446,10 @@ extern int yymore_really_used, reject_really_used; * to "action_array" */ -extern int datapos, dataline, linenum; +extern int datapos, dataline, linenum, out_linenum; extern FILE *skelfile, *yyin, *backing_up_file; -extern const char *skel[]; -extern int skel_ind; +extern char *skelname, *flex_include_path; extern char *infilename, *outfilename, *headerfilename; -extern int did_outfilename; extern char *prefix, *yyclass, *extra_type; extern int do_stdinit, use_stdout; extern char **input_files; @@ -674,12 +675,12 @@ extern int sectnum, nummt, hshcol, dfaeql, numeps, eps2, num_reallocs; extern int tmpuses, totnst, peakpairs, numuniq, numdup, hshsave; extern int num_backing_up, bol_needed; -void *allocate_array PROTO ((int, size_t)); -void *reallocate_array PROTO ((void *, int, size_t)); +void *allocate_array (int, size_t); +void *reallocate_array (void *, int, size_t); -void *flex_alloc PROTO ((size_t)); -void *flex_realloc PROTO ((void *, size_t)); -void flex_free PROTO ((void *)); +void *flex_alloc (size_t); +void *flex_realloc (void *, size_t); +void flex_free (void *); #define allocate_integer_array(size) \ (int *) allocate_array( size, sizeof( int ) ) @@ -737,146 +738,146 @@ extern int yylval; /* from file ccl.c */ -extern void ccladd PROTO ((int, int)); /* add a single character to a ccl */ -extern int cclinit PROTO ((void)); /* make an empty ccl */ -extern void cclnegate PROTO ((int)); /* negate a ccl */ +extern void ccladd (int, int); /* add a single character to a ccl */ +extern int cclinit (void); /* make an empty ccl */ +extern void cclnegate (int); /* negate a ccl */ extern int ccl_set_diff (int a, int b); /* set difference of two ccls. */ extern int ccl_set_union (int a, int b); /* set union of two ccls. */ /* List the members of a set of characters in CCL form. */ -extern void list_character_set PROTO ((FILE *, int[])); +extern void list_character_set (FILE *, int[]); /* from file dfa.c */ /* Check a DFA state for backing up. */ -extern void check_for_backing_up PROTO ((int, int[])); +extern void check_for_backing_up (int, int[]); /* Check to see if NFA state set constitutes "dangerous" trailing context. */ -extern void check_trailing_context PROTO ((int *, int, int *, int)); +extern void check_trailing_context (int *, int, int *, int); /* Construct the epsilon closure of a set of ndfa states. */ -extern int *epsclosure PROTO ((int *, int *, int[], int *, int *)); +extern int *epsclosure (int *, int *, int[], int *, int *); /* Increase the maximum number of dfas. */ -extern void increase_max_dfas PROTO ((void)); +extern void increase_max_dfas (void); -extern void ntod PROTO ((void)); /* convert a ndfa to a dfa */ +extern void ntod (void); /* convert a ndfa to a dfa */ /* Converts a set of ndfa states into a dfa state. */ -extern int snstods PROTO ((int[], int, int[], int, int, int *)); +extern int snstods (int[], int, int[], int, int, int *); /* from file ecs.c */ /* Convert character classes to set of equivalence classes. */ -extern void ccl2ecl PROTO ((void)); +extern void ccl2ecl (void); /* Associate equivalence class numbers with class members. */ -extern int cre8ecs PROTO ((int[], int[], int)); +extern int cre8ecs (int[], int[], int); /* Update equivalence classes based on character class transitions. */ -extern void mkeccl PROTO ((Char[], int, int[], int[], int, int)); +extern void mkeccl (Char[], int, int[], int[], int, int); /* Create equivalence class for single character. */ -extern void mkechar PROTO ((int, int[], int[])); +extern void mkechar (int, int[], int[]); /* from file gen.c */ -extern void do_indent PROTO ((void)); /* indent to the current level */ +extern void do_indent (void); /* indent to the current level */ /* Generate the code to keep backing-up information. */ -extern void gen_backing_up PROTO ((void)); +extern void gen_backing_up (void); /* Generate the code to perform the backing up. */ -extern void gen_bu_action PROTO ((void)); +extern void gen_bu_action (void); /* Generate full speed compressed transition table. */ -extern void genctbl PROTO ((void)); +extern void genctbl (void); /* Generate the code to find the action number. */ -extern void gen_find_action PROTO ((void)); +extern void gen_find_action (void); -extern void genftbl PROTO ((void)); /* generate full transition table */ +extern void genftbl (void); /* generate full transition table */ /* Generate the code to find the next compressed-table state. */ -extern void gen_next_compressed_state PROTO ((char *)); +extern void gen_next_compressed_state (char *); /* Generate the code to find the next match. */ -extern void gen_next_match PROTO ((void)); +extern void gen_next_match (void); /* Generate the code to find the next state. */ -extern void gen_next_state PROTO ((int)); +extern void gen_next_state (int); /* Generate the code to make a NUL transition. */ -extern void gen_NUL_trans PROTO ((void)); +extern void gen_NUL_trans (void); /* Generate the code to find the start state. */ -extern void gen_start_state PROTO ((void)); +extern void gen_start_state (void); /* Generate data statements for the transition tables. */ -extern void gentabs PROTO ((void)); +extern void gentabs (void); /* Write out a formatted string at the current indentation level. */ -extern void indent_put2s PROTO ((const char *, const char *)); +extern void indent_put2s (const char *, const char *); /* Write out a string + newline at the current indentation level. */ -extern void indent_puts PROTO ((const char *)); +extern void indent_puts (const char *); + +extern void make_tables (void); /* generate transition tables */ -extern void make_tables PROTO ((void)); /* generate transition tables */ +extern void generate_code (void); /* main code-generation routine */ /* from file main.c */ -extern void check_options PROTO ((void)); -extern void flexend PROTO ((int)); -extern void usage PROTO ((void)); +extern void check_options (void); +extern void flexend (int); +extern void usage (void); /* from file misc.c */ /* Add a #define to the action file. */ -extern void action_define PROTO ((const char *defname, int value)); +extern void action_define (const char *defname, int value); /* Add the given text to the stored actions. */ -extern void add_action PROTO ((const char *new_text)); +extern void add_action (const char *new_text); /* True if a string is all lower case. */ -extern int all_lower PROTO ((register char *)); +extern int all_lower (register char *); /* True if a string is all upper case. */ -extern int all_upper PROTO ((register char *)); - +extern int all_upper (register char *); /* Compare two integers for use by qsort. */ extern int intcmp PROTO ((const void *, const void *)); /* Check a character to make sure it's in the expected range. */ -extern void check_char PROTO ((int c)); +extern void check_char (int c); /* Replace upper-case letter to lower-case. */ -extern Char clower PROTO ((int)); +extern Char clower (int); /* Returns a dynamically allocated copy of a string. */ -extern char *copy_string PROTO ((register const char *)); +extern char *copy_string (register const char *); /* Returns a dynamically allocated copy of a (potentially) unsigned string. */ -extern Char *copy_unsigned_string PROTO ((register Char *)); - +extern Char *copy_unsigned_string (register Char *); /* Compare two characters for use by qsort with '\0' sorting last. */ extern int cclcmp PROTO ((const void *, const void *)); /* Finish up a block of data declarations. */ -extern void dataend PROTO ((void)); +extern void dataend (void); /* Flush generated data statements. */ -extern void dataflush PROTO ((void)); +extern void dataflush (void); /* Report an error message and terminate. */ -extern void flexerror PROTO ((const char *)); +extern void flexerror (const char *); /* Report a fatal error message and terminate. */ -extern void flexfatal PROTO ((const char *)); +extern void flexfatal (const char *); /* Report a fatal error with a pinpoint, and terminate */ #if HAVE_DECL___FUNC__ @@ -900,202 +901,205 @@ extern void flexfatal PROTO ((const char *)); #endif /* ! HAVE_DECL___func__ */ /* Convert a hexadecimal digit string to an integer value. */ -extern int htoi PROTO ((Char[])); +extern int htoi (Char[]); /* Report an error message formatted with one integer argument. */ -extern void lerrif PROTO ((const char *, int)); +extern void lerrif (const char *, int); /* Report an error message formatted with one string argument. */ -extern void lerrsf PROTO ((const char *, const char *)); - -/* Like lerrsf, but also exit after displaying message. */ -extern void lerrsf_fatal PROTO ((const char *, const char *)); +extern void lerrsf (const char *, const char *); /* Spit out a "#line" statement. */ -extern void line_directive_out PROTO ((FILE *, int)); +extern void line_directive_out (FILE *, int); /* Mark the current position in the action array as the end of the section 1 * user defs. */ -extern void mark_defs1 PROTO ((void)); +extern void mark_defs1 (void); /* Mark the current position in the action array as the end of the prolog. */ -extern void mark_prolog PROTO ((void)); +extern void mark_prolog (void); /* Generate a data statment for a two-dimensional array. */ -extern void mk2data PROTO ((int)); +extern void mk2data (int); -extern void mkdata PROTO ((int)); /* generate a data statement */ +extern void mkdata (int); /* generate a data statement */ /* Return the integer represented by a string of digits. */ -extern int myctoi PROTO ((const char *)); +extern int myctoi (const char *); /* Return character corresponding to escape sequence. */ -extern Char myesc PROTO ((Char[])); +extern Char myesc (Char[]); /* Convert an octal digit string to an integer value. */ -extern int otoi PROTO ((Char[])); +extern int otoi (Char[]); /* Output a (possibly-formatted) string to the generated scanner. */ -extern void out PROTO ((const char *)); -extern void out_dec PROTO ((const char *, int)); -extern void out_dec2 PROTO ((const char *, int, int)); -extern void out_hex PROTO ((const char *, unsigned int)); -extern void out_str PROTO ((const char *, const char *)); +extern void out (const char *); +extern void out_dec (const char *, int); +extern void out_dec2 (const char *, int, int); +extern void out_hex (const char *, unsigned int); +extern void out_line_count (const char *); +extern void out_str (const char *, const char *); extern void out_str3 -PROTO ((const char *, const char *, const char *, const char *)); -extern void out_str_dec PROTO ((const char *, const char *, int)); -extern void outc PROTO ((int)); -extern void outn PROTO ((const char *)); +(const char *, const char *, const char *, const char *); +extern void out_str_dec (const char *, const char *, int); +extern void outc (int); +extern void outn (const char *); extern void out_m4_define (const char* def, const char* val); /* Return a printable version of the given character, which might be * 8-bit. */ -extern char *readable_form PROTO ((int)); +extern char *readable_form (int); /* Write out one section of the skeleton file. */ -extern void skelout PROTO ((void)); +extern void skelout (void); /* Output a yy_trans_info structure. */ -extern void transition_struct_out PROTO ((int, int)); +extern void transition_struct_out (int, int); /* Only needed when using certain broken versions of bison to build parse.c. */ -extern void *yy_flex_xmalloc PROTO ((int)); +extern void *yy_flex_xmalloc (int); /* Set a region of memory to 0. */ -extern void zero_out PROTO ((char *, size_t)); +extern void zero_out (char *, size_t); /* from file nfa.c */ /* Add an accepting state to a machine. */ -extern void add_accept PROTO ((int, int)); +extern void add_accept (int, int); /* Make a given number of copies of a singleton machine. */ -extern int copysingl PROTO ((int, int)); +extern int copysingl (int, int); /* Debugging routine to write out an nfa. */ -extern void dumpnfa PROTO ((int)); +extern void dumpnfa (int); /* Finish up the processing for a rule. */ -extern void finish_rule PROTO ((int, int, int, int, int)); +extern void finish_rule (int, int, int, int, int); /* Connect two machines together. */ -extern int link_machines PROTO ((int, int)); +extern int link_machines (int, int); /* Mark each "beginning" state in a machine as being a "normal" (i.e., * not trailing context associated) state. */ -extern void mark_beginning_as_normal PROTO ((register int)); +extern void mark_beginning_as_normal (register int); /* Make a machine that branches to two machines. */ -extern int mkbranch PROTO ((int, int)); +extern int mkbranch (int, int); -extern int mkclos PROTO ((int)); /* convert a machine into a closure */ -extern int mkopt PROTO ((int)); /* make a machine optional */ +extern int mkclos (int); /* convert a machine into a closure */ +extern int mkopt (int); /* make a machine optional */ /* Make a machine that matches either one of two machines. */ -extern int mkor PROTO ((int, int)); +extern int mkor (int, int); /* Convert a machine into a positive closure. */ -extern int mkposcl PROTO ((int)); +extern int mkposcl (int); -extern int mkrep PROTO ((int, int, int)); /* make a replicated machine */ +extern int mkrep (int, int, int); /* make a replicated machine */ /* Create a state with a transition on a given symbol. */ -extern int mkstate PROTO ((int)); +extern int mkstate (int); -extern void new_rule PROTO ((void)); /* initialize for a new rule */ +extern void new_rule (void); /* initialize for a new rule */ /* from file parse.y */ /* Build the "<>" action for the active start conditions. */ -extern void build_eof_action PROTO ((void)); +extern void build_eof_action (void); /* Write out a message formatted with one string, pinpointing its location. */ -extern void format_pinpoint_message PROTO ((const char *, const char *)); +extern void format_pinpoint_message (const char *, const char *); /* Write out a message, pinpointing its location. */ -extern void pinpoint_message PROTO ((const char *)); +extern void pinpoint_message (const char *); /* Write out a warning, pinpointing it at the given line. */ -extern void line_warning PROTO ((const char *, int)); +extern void line_warning (const char *, int); /* Write out a message, pinpointing it at the given line. */ -extern void line_pinpoint PROTO ((const char *, int)); +extern void line_pinpoint (const char *, int); /* Report a formatted syntax error. */ -extern void format_synerr PROTO ((const char *, const char *)); -extern void synerr PROTO ((const char *)); /* report a syntax error */ -extern void format_warn PROTO ((const char *, const char *)); -extern void warn PROTO ((const char *)); /* report a warning */ -extern void yyerror PROTO ((const char *)); /* report a parse error */ -extern int yyparse PROTO ((void)); /* the YACC parser */ +extern void format_synerr (const char *, const char *); +extern void synerr (const char *); /* report a syntax error */ +extern void format_warn (const char *, const char *); +extern void warn (const char *); /* report a warning */ +extern void yyerror (const char *); /* report a parse error */ +extern int yyparse (void); /* the YACC parser */ /* from file scan.l */ /* The Flex-generated scanner for flex. */ -extern int flexscan PROTO ((void)); +extern int flexscan (void); /* Open the given file (if NULL, stdin) for scanning. */ -extern void set_input_file PROTO ((char *)); +extern void set_input_file (char *); /* Wrapup a file in the lexical analyzer. */ -extern int yywrap PROTO ((void)); +extern int yywrap (void); /* from file sym.c */ /* Save the text of a character class. */ -extern void cclinstal PROTO ((Char[], int)); +extern void cclinstal (Char[], int); /* Lookup the number associated with character class. */ -extern int ccllookup PROTO ((Char[])); +extern int ccllookup (Char[]); + +extern void ndinstal (const char *, Char[]); /* install a name definition */ +extern Char *ndlookup (const char *); /* lookup a name definition */ -extern void ndinstal PROTO ((const char *, Char[])); /* install a name definition */ -extern Char *ndlookup PROTO ((const char *)); /* lookup a name definition */ +extern Char *m4_define (const char *, Char[]); /* define an M4 macro */ + /* define an M4 macro, warn if already defined */ +extern void m4_define_warn (const char *, Char[], const char *message); +extern Char *m4_lookup (const char *); /* lookup an M4 macro definition */ /* Increase maximum number of SC's. */ -extern void scextend PROTO ((void)); -extern void scinstal PROTO ((const char *, int)); /* make a start condition */ +extern void scextend (void); +extern void scinstal (const char *, int); /* make a start condition */ /* Lookup the number associated with a start condition. */ -extern int sclookup PROTO ((const char *)); +extern int sclookup (const char *); /* from file tblcmp.c */ /* Build table entries for dfa state. */ -extern void bldtbl PROTO ((int[], int, int, int, int)); +extern void bldtbl (int[], int, int, int, int); -extern void cmptmps PROTO ((void)); /* compress template table entries */ -extern void expand_nxt_chk PROTO ((void)); /* increase nxt/chk arrays */ +extern void cmptmps (void); /* compress template table entries */ +extern void expand_nxt_chk (void); /* increase nxt/chk arrays */ /* Finds a space in the table for a state to be placed. */ -extern int find_table_space PROTO ((int *, int)); -extern void inittbl PROTO ((void)); /* initialize transition tables */ +extern int find_table_space (int *, int); +extern void inittbl (void); /* initialize transition tables */ /* Make the default, "jam" table entries. */ -extern void mkdeftbl PROTO ((void)); +extern void mkdeftbl (void); /* Create table entries for a state (or state fragment) which has * only one out-transition. */ -extern void mk1tbl PROTO ((int, int, int, int)); +extern void mk1tbl (int, int, int, int); /* Place a state into full speed transition table. */ -extern void place_state PROTO ((int *, int, int)); +extern void place_state (int *, int, int); /* Save states with only one out-transition to be processed later. */ -extern void stack1 PROTO ((int, int, int, int)); +extern void stack1 (int, int, int, int); /* from file yylex.c */ -extern int yylex PROTO ((void)); +extern int yylex (void); /* A growable array. See buf.c. */ struct Buf { @@ -1105,27 +1109,29 @@ struct Buf { int nmax; /* max capacity of elements. */ }; -extern void buf_init PROTO ((struct Buf * buf, size_t elem_size)); -extern void buf_destroy PROTO ((struct Buf * buf)); +extern void buf_init (struct Buf * buf, size_t elem_size); +extern void buf_destroy (struct Buf * buf); +extern void buf_free (struct Buf * buf); extern struct Buf *buf_append -PROTO ((struct Buf * buf, const void *ptr, int n_elem)); -extern struct Buf *buf_concat PROTO((struct Buf* dest, const struct Buf* src)); -extern struct Buf *buf_strappend PROTO ((struct Buf *, const char *str)); +(struct Buf * buf, const void *ptr, int n_elem); +extern struct Buf *buf_concat (struct Buf* dest, const struct Buf* src); +extern struct Buf *buf_strappend (struct Buf *, const char *str); extern struct Buf *buf_strnappend -PROTO ((struct Buf *, const char *str, int nchars)); +(struct Buf *, const char *str, int nchars); extern struct Buf *buf_strdefine -PROTO ((struct Buf * buf, const char *str, const char *def)); -extern struct Buf *buf_prints PROTO((struct Buf *buf, const char *fmt, const char* s)); -extern struct Buf *buf_m4_define PROTO((struct Buf *buf, const char* def, const char* val)); -extern struct Buf *buf_m4_undefine PROTO((struct Buf *buf, const char* def)); -extern struct Buf *buf_print_strings PROTO((struct Buf * buf, FILE* out)); -extern struct Buf *buf_linedir PROTO((struct Buf *buf, const char* filename, int lineno)); +(struct Buf * buf, const char *str, const char *def); +extern struct Buf *buf_prints (struct Buf *buf, const char *fmt, const char* s); +extern struct Buf *buf_m4_define (struct Buf *buf, const char* def, const char* val); +extern struct Buf *buf_m4_undefine (struct Buf *buf, const char* def); +extern struct Buf *buf_print_strings (struct Buf * buf, FILE* out); +extern struct Buf *buf_linedir (struct Buf *buf, const char* filename, int lineno); extern struct Buf userdef_buf; /* a string buffer for #define's generated by user-options on cmd line. */ extern struct Buf defs_buf; /* a char* buffer to save #define'd some symbols generated by flex. */ extern struct Buf yydmap_buf; /* a string buffer to hold yydmap elements */ extern struct Buf m4defs_buf; /* Holds m4 definitions. */ extern struct Buf top_buf; /* contains %top code. String buffer. */ +extern struct Buf bottom_buf; /* contains %bottom code. String buffer. */ /* For blocking out code from the header file. */ #define OUT_BEGIN_CODE() outn("m4_ifdef( [[M4_YY_IN_HEADER]],,[[") @@ -1181,14 +1187,15 @@ struct filter { /* output filter chain */ extern struct filter * output_chain; -extern struct filter *filter_create_ext PROTO((struct filter * chain, const char *cmd, ...)); -struct filter *filter_create_int PROTO((struct filter *chain, - int (*filter_func) (struct filter *), - void *extra)); -extern bool filter_apply_chain PROTO((struct filter * chain)); +extern struct filter *filter_create_ext (struct filter * chain, const char *cmd, ...); +struct filter *filter_create_int (struct filter *chain, + int (*filter_func) (struct filter *), void *extra); +extern bool filter_apply_chain (struct filter * chain); extern int filter_truncate (struct filter * chain, int max_len); -extern int filter_tee_header PROTO((struct filter *chain)); -extern int filter_fix_linedirs PROTO((struct filter *chain)); +extern int filter_tee_header (struct filter *chain); +extern int filter_fix_linedirs (struct filter *chain); +extern int filter_check_errors (struct filter *chain); + /* @@ -1222,5 +1229,8 @@ extern void sf_init(void); extern void sf_push(void); extern void sf_pop(void); +#ifdef __cplusplus +} +#endif #endif /* not defined FLEXDEF_H */ diff --git a/gen.c b/gen.c index 8d24a86..a407b21 100644 --- a/gen.c +++ b/gen.c @@ -37,11 +37,9 @@ /* declare functions that have forward references */ -void gen_next_state PROTO ((int)); -void genecs PROTO ((void)); -void indent_put2s PROTO ((const char *, const char *)); -void indent_puts PROTO ((const char *)); - +void genecs (void); +void indent_put2s (const char *, const char *); +void indent_puts (const char *); static int indent_level = 0; /* each level is 8 spaces */ @@ -49,34 +47,6 @@ static int indent_level = 0; /* each level is 8 spaces */ #define indent_down() (--indent_level) #define set_indent(indent_val) indent_level = indent_val -/* Almost everything is done in terms of arrays starting at 1, so provide - * a null entry for the zero element of all C arrays. (The exception - * to this is that the fast table representation generally uses the - * 0 elements of its arrays, too.) - */ - -static const char *get_int16_decl (void) -{ - return (gentables) - ? "static yyconst flex_int16_t %s[%d] =\n { 0,\n" - : "static yyconst flex_int16_t * %s = 0;\n"; -} - - -static const char *get_int32_decl (void) -{ - return (gentables) - ? "static yyconst flex_int32_t %s[%d] =\n { 0,\n" - : "static yyconst flex_int32_t * %s = 0;\n"; -} - -static const char *get_state_decl (void) -{ - return (gentables) - ? "static yyconst yy_state_type %s[%d] =\n { 0,\n" - : "static yyconst yy_state_type * %s = 0;\n"; -} - /* Indent to the current level. */ void do_indent () @@ -125,73 +95,23 @@ static void geneoltbl () { int i; - outn ("m4_ifdef( [[M4_YY_USE_LINENO]],[["); - outn ("/* Table of booleans, true if rule could match eol. */"); - out_str_dec (get_int32_decl (), "yy_rule_can_match_eol", - num_rules + 1); + outn ("m4_dnl /* Table of booleans, true if rule could match eol. */"); + out ("m4_define([[M4_YY_RULE_CAN_MATCH_EOL_TABLE_32BIT]],1)\n"); + out_dec ("m4_define([[M4_YY_RULE_CAN_MATCH_EOL_TABLE_SIZE]],[[%d]])\n", num_rules + 1); if (gentables) { + outn ("m4_define([[M4_YY_RULE_CAN_MATCH_EOL_TABLE_DATA]],[[0,"); for (i = 1; i <= num_rules; i++) { out_dec ("%d, ", rule_has_nl[i] ? 1 : 0); /* format nicely, 20 numbers per line. */ if ((i % 20) == 19) out ("\n "); } - out (" };\n"); + out ("]]);\n"); } - outn ("]])"); -} - - -/* Generate the code to keep backing-up information. */ - -void gen_backing_up () -{ - if (reject || num_backing_up == 0) - return; - - if (fullspd) - indent_puts ("if ( yy_current_state[-1].yy_nxt )"); - else - indent_puts ("if ( yy_accept[yy_current_state] )"); - - indent_up (); - indent_puts ("{"); - indent_puts ("YY_G(yy_last_accepting_state) = yy_current_state;"); - indent_puts ("YY_G(yy_last_accepting_cpos) = yy_cp;"); - indent_puts ("}"); - indent_down (); } -/* Generate the code to perform the backing up. */ - -void gen_bu_action () -{ - if (reject || num_backing_up == 0) - return; - - set_indent (3); - - indent_puts ("case 0: /* must back up */"); - indent_puts ("/* undo the effects of YY_DO_BEFORE_ACTION */"); - indent_puts ("*yy_cp = YY_G(yy_hold_char);"); - - if (fullspd || fulltbl) - indent_puts ("yy_cp = YY_G(yy_last_accepting_cpos) + 1;"); - else - /* Backing-up info for compressed tables is taken \after/ - * yy_cp has been incremented for the next state. - */ - indent_puts ("yy_cp = YY_G(yy_last_accepting_cpos);"); - - indent_puts ("yy_current_state = YY_G(yy_last_accepting_state);"); - indent_puts ("goto yy_find_action;"); - outc ('\n'); - - set_indent (0); -} - /** mkctbl - make full speed compressed transition table * This is an array of structs; each struct a pair of integers. * You should call mkssltbl() immediately after this. @@ -336,10 +256,11 @@ void genctbl () int end_of_buffer_action = num_rules + 1; /* Table of verify for transition and offset to next state. */ + /* 32bit flag for struct yy_trans_info is defined in make_tables() */ + out_dec ("m4_define([[M4_YY_TRANSITION_TABLE_SIZE]],[[%d]])\n", + tblend + numecs + 1); if (gentables) - out_dec ("static yyconst struct yy_trans_info yy_transition[%d] =\n {\n", tblend + numecs + 1); - else - outn ("static yyconst struct yy_trans_info *yy_transition = 0;"); + out ("m4_define([[M4_YY_TRANSITION_TABLE_DATA]],[[\n"); /* We want the transition to be represented as the offset to the * next state, not the actual state number, which is what it currently @@ -407,21 +328,15 @@ void genctbl () transition_struct_out (chk[tblend + 2], nxt[tblend + 2]); if (gentables) - outn (" };\n"); + dataend(); /* Table of pointers to start states. */ - if (gentables) - out_dec ("static yyconst struct yy_trans_info *yy_start_state_list[%d] =\n", lastsc * 2 + 1); - else - outn ("static yyconst struct yy_trans_info **yy_start_state_list =0;"); + out_dec ("m4_define([[M4_YY_START_STATE_LIST_TABLE_SIZE]],[[%d]])\n", lastsc * 2 + 1); if (gentables) { - outn (" {"); - - for (i = 0; i <= lastsc * 2; ++i) - out_dec (" &yy_transition[%d],\n", base[i]); - - dataend (); + out ("m4_define([[M4_YY_START_STATE_LIST_TABLE_DATA]],[["); + for (i = 0; i < lastsc * 2; ++i) out_dec("%d,",base[i]); + out_dec("%d]])\n",base[lastsc*2]); } if (useecs) @@ -465,7 +380,9 @@ void genecs () register int i, j; int numrows; - out_str_dec (get_int32_decl (), "yy_ec", csize); + out ("m4_define([[M4_YY_EC_TABLE_32BIT]],1)\n"); + out_dec ("m4_define([[M4_YY_EC_TABLE_SIZE]],[[%d]])\n",csize); + if (gentables) outn ("m4_define([[M4_YY_EC_TABLE_DATA]],[[0,"); for (i = 1; i < csize; ++i) { ecgroup[i] = ABS (ecgroup[i]); @@ -493,144 +410,6 @@ void genecs () } -/* Generate the code to find the action number. */ - -void gen_find_action () -{ - if (fullspd) - indent_puts ("yy_act = yy_current_state[-1].yy_nxt;"); - - else if (fulltbl) - indent_puts ("yy_act = yy_accept[yy_current_state];"); - - else if (reject) { - indent_puts ("yy_current_state = *--YY_G(yy_state_ptr);"); - indent_puts ("YY_G(yy_lp) = yy_accept[yy_current_state];"); - - outn ("find_rule: /* we branch to this label when backing up */"); - - indent_puts - ("for ( ; ; ) /* until we find what rule we matched */"); - - indent_up (); - - indent_puts ("{"); - - indent_puts - ("if ( YY_G(yy_lp) && YY_G(yy_lp) < yy_accept[yy_current_state + 1] )"); - indent_up (); - indent_puts ("{"); - indent_puts ("yy_act = yy_acclist[YY_G(yy_lp)];"); - - if (variable_trailing_context_rules) { - indent_puts - ("if ( yy_act & YY_TRAILING_HEAD_MASK ||"); - indent_puts (" YY_G(yy_looking_for_trail_begin) )"); - indent_up (); - indent_puts ("{"); - - indent_puts - ("if ( yy_act == YY_G(yy_looking_for_trail_begin) )"); - indent_up (); - indent_puts ("{"); - indent_puts ("YY_G(yy_looking_for_trail_begin) = 0;"); - indent_puts ("yy_act &= ~YY_TRAILING_HEAD_MASK;"); - indent_puts ("break;"); - indent_puts ("}"); - indent_down (); - - indent_puts ("}"); - indent_down (); - - indent_puts - ("else if ( yy_act & YY_TRAILING_MASK )"); - indent_up (); - indent_puts ("{"); - indent_puts - ("YY_G(yy_looking_for_trail_begin) = yy_act & ~YY_TRAILING_MASK;"); - indent_puts - ("YY_G(yy_looking_for_trail_begin) |= YY_TRAILING_HEAD_MASK;"); - - if (real_reject) { - /* Remember matched text in case we back up - * due to REJECT. - */ - indent_puts - ("YY_G(yy_full_match) = yy_cp;"); - indent_puts - ("YY_G(yy_full_state) = YY_G(yy_state_ptr);"); - indent_puts ("YY_G(yy_full_lp) = YY_G(yy_lp);"); - } - - indent_puts ("}"); - indent_down (); - - indent_puts ("else"); - indent_up (); - indent_puts ("{"); - indent_puts ("YY_G(yy_full_match) = yy_cp;"); - indent_puts - ("YY_G(yy_full_state) = YY_G(yy_state_ptr);"); - indent_puts ("YY_G(yy_full_lp) = YY_G(yy_lp);"); - indent_puts ("break;"); - indent_puts ("}"); - indent_down (); - - indent_puts ("++YY_G(yy_lp);"); - indent_puts ("goto find_rule;"); - } - - else { - /* Remember matched text in case we back up due to - * trailing context plus REJECT. - */ - indent_up (); - indent_puts ("{"); - indent_puts ("YY_G(yy_full_match) = yy_cp;"); - indent_puts ("break;"); - indent_puts ("}"); - indent_down (); - } - - indent_puts ("}"); - indent_down (); - - indent_puts ("--yy_cp;"); - - /* We could consolidate the following two lines with those at - * the beginning, but at the cost of complaints that we're - * branching inside a loop. - */ - indent_puts ("yy_current_state = *--YY_G(yy_state_ptr);"); - indent_puts ("YY_G(yy_lp) = yy_accept[yy_current_state];"); - - indent_puts ("}"); - - indent_down (); - } - - else { /* compressed */ - indent_puts ("yy_act = yy_accept[yy_current_state];"); - - if (interactive && !reject) { - /* Do the guaranteed-needed backing up to figure out - * the match. - */ - indent_puts ("if ( yy_act == 0 )"); - indent_up (); - indent_puts ("{ /* have to back up */"); - indent_puts - ("yy_cp = YY_G(yy_last_accepting_cpos);"); - indent_puts - ("yy_current_state = YY_G(yy_last_accepting_state);"); - indent_puts - ("yy_act = yy_accept[yy_current_state];"); - indent_puts ("}"); - indent_down (); - } - } -} - /* mkftbl - make the full table and return the struct . * you should call mkecstbl() after this. */ @@ -677,8 +456,10 @@ void genftbl () register int i; int end_of_buffer_action = num_rules + 1; - out_str_dec (long_align ? get_int32_decl () : get_int16_decl (), - "yy_accept", lastdfa + 1); + if (long_align) + out ("m4_define([[M4_YY_ACCEPT_TABLE_32BIT]],1)\n"); + out_dec ("m4_define([[M4_YY_ACCEPT_TABLE_SIZE]],[[%d]])\n",lastdfa+1); + if (gentables) outn ("m4_define([[M4_YY_ACCEPT_TABLE_DATA]],[[0,"); dfaacc[end_of_buffer_state].dfaacc_state = end_of_buffer_action; @@ -702,350 +483,9 @@ void genftbl () */ } - -/* Generate the code to find the next compressed-table state. */ - -void gen_next_compressed_state (char_map) - char *char_map; -{ - indent_put2s ("register YY_CHAR yy_c = %s;", char_map); - - /* Save the backing-up info \before/ computing the next state - * because we always compute one more state than needed - we - * always proceed until we reach a jam state - */ - gen_backing_up (); - - indent_puts - ("while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )"); - indent_up (); - indent_puts ("{"); - indent_puts ("yy_current_state = (int) yy_def[yy_current_state];"); - - if (usemecs) { - /* We've arrange it so that templates are never chained - * to one another. This means we can afford to make a - * very simple test to see if we need to convert to - * yy_c's meta-equivalence class without worrying - * about erroneously looking up the meta-equivalence - * class twice - */ - do_indent (); - - /* lastdfa + 2 is the beginning of the templates */ - out_dec ("if ( yy_current_state >= %d )\n", lastdfa + 2); - - indent_up (); - indent_puts ("yy_c = yy_meta[(unsigned int) yy_c];"); - indent_down (); - } - - indent_puts ("}"); - indent_down (); - - indent_puts - ("yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];"); -} - - -/* Generate the code to find the next match. */ - -void gen_next_match () -{ - /* NOTE - changes in here should be reflected in gen_next_state() and - * gen_NUL_trans(). - */ - char *char_map = useecs ? - "yy_ec[YY_SC_TO_UI(*yy_cp)] " : "YY_SC_TO_UI(*yy_cp)"; - - char *char_map_2 = useecs ? - "yy_ec[YY_SC_TO_UI(*++yy_cp)] " : "YY_SC_TO_UI(*++yy_cp)"; - - if (fulltbl) { - if (gentables) - indent_put2s - ("while ( (yy_current_state = yy_nxt[yy_current_state][ %s ]) > 0 )", - char_map); - else - indent_put2s - ("while ( (yy_current_state = yy_nxt[yy_current_state*YY_NXT_LOLEN + %s ]) > 0 )", - char_map); - - indent_up (); - - if (num_backing_up > 0) { - indent_puts ("{"); - gen_backing_up (); - outc ('\n'); - } - - indent_puts ("++yy_cp;"); - - if (num_backing_up > 0) - - indent_puts ("}"); - - indent_down (); - - outc ('\n'); - indent_puts ("yy_current_state = -yy_current_state;"); - } - - else if (fullspd) { - indent_puts ("{"); - indent_puts - ("register yyconst struct yy_trans_info *yy_trans_info;\n"); - indent_puts ("register YY_CHAR yy_c;\n"); - indent_put2s ("for ( yy_c = %s;", char_map); - indent_puts - (" (yy_trans_info = &yy_current_state[(unsigned int) yy_c])->"); - indent_puts ("yy_verify == yy_c;"); - indent_put2s (" yy_c = %s )", char_map_2); - - indent_up (); - - if (num_backing_up > 0) - indent_puts ("{"); - - indent_puts ("yy_current_state += yy_trans_info->yy_nxt;"); - - if (num_backing_up > 0) { - outc ('\n'); - gen_backing_up (); - indent_puts ("}"); - } - - indent_down (); - indent_puts ("}"); - } - - else { /* compressed */ - indent_puts ("do"); - - indent_up (); - indent_puts ("{"); - - gen_next_state (false); - - indent_puts ("++yy_cp;"); - - - indent_puts ("}"); - indent_down (); - - do_indent (); - - if (interactive) - out_dec ("while ( yy_base[yy_current_state] != %d );\n", jambase); - else - out_dec ("while ( yy_current_state != %d );\n", - jamstate); - - if (!reject && !interactive) { - /* Do the guaranteed-needed backing up to figure out - * the match. - */ - indent_puts - ("yy_cp = YY_G(yy_last_accepting_cpos);"); - indent_puts - ("yy_current_state = YY_G(yy_last_accepting_state);"); - } - } -} - - -/* Generate the code to find the next state. */ - -void gen_next_state (worry_about_NULs) - int worry_about_NULs; -{ /* NOTE - changes in here should be reflected in gen_next_match() */ - char char_map[256]; - - if (worry_about_NULs && !nultrans) { - if (useecs) - snprintf (char_map, sizeof(char_map), - "(*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : %d)", - NUL_ec); - else - snprintf (char_map, sizeof(char_map), - "(*yy_cp ? YY_SC_TO_UI(*yy_cp) : %d)", - NUL_ec); - } - - else - strcpy (char_map, useecs ? - "yy_ec[YY_SC_TO_UI(*yy_cp)]" : - "YY_SC_TO_UI(*yy_cp)"); - - if (worry_about_NULs && nultrans) { - if (!fulltbl && !fullspd) - /* Compressed tables back up *before* they match. */ - gen_backing_up (); - - indent_puts ("if ( *yy_cp )"); - indent_up (); - indent_puts ("{"); - } - - if (fulltbl) { - if (gentables) - indent_put2s - ("yy_current_state = yy_nxt[yy_current_state][%s];", - char_map); - else - indent_put2s - ("yy_current_state = yy_nxt[yy_current_state*YY_NXT_LOLEN + %s];", - char_map); - } - - else if (fullspd) - indent_put2s - ("yy_current_state += yy_current_state[%s].yy_nxt;", - char_map); - - else - gen_next_compressed_state (char_map); - - if (worry_about_NULs && nultrans) { - - indent_puts ("}"); - indent_down (); - indent_puts ("else"); - indent_up (); - indent_puts - ("yy_current_state = yy_NUL_trans[yy_current_state];"); - indent_down (); - } - - if (fullspd || fulltbl) - gen_backing_up (); - - if (reject) - indent_puts ("*YY_G(yy_state_ptr)++ = yy_current_state;"); -} - - -/* Generate the code to make a NUL transition. */ - -void gen_NUL_trans () -{ /* NOTE - changes in here should be reflected in gen_next_match() */ - /* Only generate a definition for "yy_cp" if we'll generate code - * that uses it. Otherwise lint and the like complain. - */ - int need_backing_up = (num_backing_up > 0 && !reject); - - if (need_backing_up && (!nultrans || fullspd || fulltbl)) - /* We're going to need yy_cp lying around for the call - * below to gen_backing_up(). - */ - indent_puts ("register char *yy_cp = YY_G(yy_c_buf_p);"); - - outc ('\n'); - - if (nultrans) { - indent_puts - ("yy_current_state = yy_NUL_trans[yy_current_state];"); - indent_puts ("yy_is_jam = (yy_current_state == 0);"); - } - - else if (fulltbl) { - do_indent (); - if (gentables) - out_dec ("yy_current_state = yy_nxt[yy_current_state][%d];\n", NUL_ec); - else - out_dec ("yy_current_state = yy_nxt[yy_current_state*YY_NXT_LOLEN + %d];\n", NUL_ec); - indent_puts ("yy_is_jam = (yy_current_state <= 0);"); - } - - else if (fullspd) { - do_indent (); - out_dec ("register int yy_c = %d;\n", NUL_ec); - - indent_puts - ("register yyconst struct yy_trans_info *yy_trans_info;\n"); - indent_puts - ("yy_trans_info = &yy_current_state[(unsigned int) yy_c];"); - indent_puts ("yy_current_state += yy_trans_info->yy_nxt;"); - - indent_puts - ("yy_is_jam = (yy_trans_info->yy_verify != yy_c);"); - } - - else { - char NUL_ec_str[20]; - - snprintf (NUL_ec_str, sizeof(NUL_ec_str), "%d", NUL_ec); - gen_next_compressed_state (NUL_ec_str); - - do_indent (); - out_dec ("yy_is_jam = (yy_current_state == %d);\n", - jamstate); - - if (reject) { - /* Only stack this state if it's a transition we - * actually make. If we stack it on a jam, then - * the state stack and yy_c_buf_p get out of sync. - */ - indent_puts ("if ( ! yy_is_jam )"); - indent_up (); - indent_puts - ("*YY_G(yy_state_ptr)++ = yy_current_state;"); - indent_down (); - } - } - - /* If we've entered an accepting state, back up; note that - * compressed tables have *already* done such backing up, so - * we needn't bother with it again. - */ - if (need_backing_up && (fullspd || fulltbl)) { - outc ('\n'); - indent_puts ("if ( ! yy_is_jam )"); - indent_up (); - indent_puts ("{"); - gen_backing_up (); - indent_puts ("}"); - indent_down (); - } -} - - -/* Generate the code to find the start state. */ - -void gen_start_state () -{ - if (fullspd) { - if (bol_needed) { - indent_puts - ("yy_current_state = yy_start_state_list[YY_G(yy_start) + YY_AT_BOL()];"); - } - else - indent_puts - ("yy_current_state = yy_start_state_list[YY_G(yy_start)];"); - } - - else { - indent_puts ("yy_current_state = YY_G(yy_start);"); - - if (bol_needed) - indent_puts ("yy_current_state += YY_AT_BOL();"); - - if (reject) { - /* Set up for storing up states. */ - outn ("m4_ifdef( [[M4_YY_USES_REJECT]],\n[["); - indent_puts - ("YY_G(yy_state_ptr) = YY_G(yy_state_buf);"); - indent_puts - ("*YY_G(yy_state_ptr)++ = yy_current_state;"); - outn ("]])"); - } - } -} - - /* gentabs - generate data statements for the transition tables */ -void gentabs () +void gentabs (void) { int i, j, k, *accset, nacc, *acc_array, total_states; int end_of_buffer_action = num_rules + 1; @@ -1081,9 +521,10 @@ void gentabs () dfaacc[end_of_buffer_state].dfaacc_set = EOB_accepting_list; - out_str_dec (long_align ? get_int32_decl () : - get_int16_decl (), "yy_acclist", MAX (numas, - 1) + 1); + if (long_align) + out ("m4_define([[M4_YY_ACCLIST_TABLE_32BIT]],1)\n"); + out_dec ("m4_define([[M4_YY_ACCLIST_TABLE_SIZE]],[[%d]])\n",MAX(numas,1)+1); + if (gentables) outn ("m4_define([[M4_YY_ACCLIST_TABLE_DATA]],[[0,"); buf_prints (&yydmap_buf, "\t{YYTD_ID_ACCLIST, (void**)&yy_acclist, sizeof(%s)},\n", @@ -1151,6 +592,7 @@ void gentabs () acc_array[i] = j; dataend (); + outn ("]])\n"); if (tablesext) { yytbl_data_compress (yyacclist_tbl); if (yytbl_data_fwrite (&tableswr, yyacclist_tbl) < 0) @@ -1191,8 +633,10 @@ void gentabs () */ ++k; - out_str_dec (long_align ? get_int32_decl () : get_int16_decl (), - "yy_accept", k); + if (long_align) + out ("m4_define([[M4_YY_ACCEPT_TABLE_32BIT]],1)\n"); + out_dec ("m4_define([[M4_YY_ACCEPT_TABLE_SIZE]],[[%d]])\n",k); + if (gentables) outn ("m4_define([[M4_YY_ACCEPT_TABLE_DATA]],[[0,"); buf_prints (&yydmap_buf, "\t{YYTD_ID_ACCEPT, (void**)&yy_accept, sizeof(%s)},\n", @@ -1227,6 +671,7 @@ void gentabs () } dataend (); + if (tablesext) { yytbl_data_compress (yyacc_tbl); if (yytbl_data_fwrite (&tableswr, yyacc_tbl) < 0) @@ -1271,7 +716,9 @@ void gentabs () fputs (_("\n\nMeta-Equivalence Classes:\n"), stderr); - out_str_dec (get_int32_decl (), "yy_meta", numecs + 1); + out ("m4_define([[M4_YY_META_TABLE_32BIT]],1)\n"); + out_dec ("m4_define([[M4_YY_META_TABLE_SIZE]],[[%d]])\n",numecs+1); + if (gentables) outn ("m4_define([[M4_YY_META_TABLE_DATA]],[[0,"); buf_prints (&yydmap_buf, "\t{YYTD_ID_META, (void**)&yy_meta, sizeof(%s)},\n", "flex_int32_t"); @@ -1300,9 +747,10 @@ void gentabs () total_states = lastdfa + numtemps; /* Begin generating yy_base */ - out_str_dec ((tblend >= INT16_MAX || long_align) ? - get_int32_decl () : get_int16_decl (), - "yy_base", total_states + 1); + if (tblend >= INT16_MAX || long_align) + out ("m4_define([[M4_YY_BASE_TABLE_32BIT]],1)\n"); + out_dec ("m4_define([[M4_YY_BASE_TABLE_SIZE]],[[%d]])\n",total_states + 1); + if (gentables) outn ("m4_define([[M4_YY_BASE_TABLE_DATA]],[[0,"); buf_prints (&yydmap_buf, "\t{YYTD_ID_BASE, (void**)&yy_base, sizeof(%s)},\n", @@ -1359,9 +807,10 @@ void gentabs () /* Begin generating yy_def */ - out_str_dec ((total_states >= INT16_MAX || long_align) ? - get_int32_decl () : get_int16_decl (), - "yy_def", total_states + 1); + if (total_states >= INT16_MAX || long_align) + out ("m4_define([[M4_YY_DEF_TABLE_32BIT]],1)\n"); + out_dec ("m4_define([[M4_YY_DEF_TABLE_SIZE]],[[%d]])\n",total_states + 1); + if (gentables) outn ("m4_define([[M4_YY_DEF_TABLE_DATA]],[[0,"); buf_prints (&yydmap_buf, "\t{YYTD_ID_DEF, (void**)&yy_def, sizeof(%s)},\n", @@ -1393,9 +842,10 @@ void gentabs () /* Begin generating yy_nxt */ - out_str_dec ((total_states >= INT16_MAX || long_align) ? - get_int32_decl () : get_int16_decl (), "yy_nxt", - tblend + 1); + if (total_states >= INT16_MAX || long_align) + out ("m4_define([[M4_YY_NXT_TABLE_32BIT]],1)\n"); + out_dec ("m4_define([[M4_YY_NXT_TABLE_SIZE]],[[%d]])\n",tblend+1); + if (gentables) outn ("m4_define([[M4_YY_NXT_TABLE_DATA]],[[0,"); buf_prints (&yydmap_buf, "\t{YYTD_ID_NXT, (void**)&yy_nxt, sizeof(%s)},\n", @@ -1432,9 +882,10 @@ void gentabs () /* End generating yy_nxt */ /* Begin generating yy_chk */ - out_str_dec ((total_states >= INT16_MAX || long_align) ? - get_int32_decl () : get_int16_decl (), "yy_chk", - tblend + 1); + if (total_states >= INT16_MAX || long_align) + out ("m4_define([[M4_YY_CHK_TABLE_32BIT]],1)\n"); + out_dec ("m4_define([[M4_YY_CHK_TABLE_SIZE]],[[%d]])\n",tblend+1); + if (gentables) outn ("m4_define([[M4_YY_CHK_TABLE_DATA]],[[0,"); buf_prints (&yydmap_buf, "\t{YYTD_ID_CHK, (void**)&yy_chk, sizeof(%s)},\n", @@ -1475,8 +926,7 @@ void gentabs () * current indentation level, adding a final newline. */ -void indent_put2s (fmt, arg) - const char *fmt, *arg; +void indent_put2s (const char *fmt, const char *arg) { do_indent (); out_str (fmt, arg); @@ -1488,94 +938,33 @@ void indent_put2s (fmt, arg) * newline. */ -void indent_puts (str) - const char *str; +void indent_puts (const char *str) { do_indent (); outn (str); } -/* make_tables - generate transition tables and finishes generating output file +/* make_tables - generate transition tables */ -void make_tables () +void make_tables (void) { register int i; - int did_eof_rule = false; struct yytbl_data *yynultrans_tbl; + char strtmp[32]; - - skelout (); /* %% [2.0] - break point in skel */ - - /* First, take care of YY_DO_BEFORE_ACTION depending on yymore - * being used. - */ - set_indent (1); - - if (yymore_used && !yytext_is_array) { - indent_puts ("YY_G(yytext_ptr) -= YY_G(yy_more_len); \\"); - indent_puts - ("yyleng = (size_t) (yy_cp - YY_G(yytext_ptr)); \\"); - } - - else - indent_puts ("yyleng = (size_t) (yy_cp - yy_bp); \\"); - - /* Now also deal with copying yytext_ptr to yytext if needed. */ - skelout (); /* %% [3.0] - break point in skel */ - if (yytext_is_array) { - if (yymore_used) - indent_puts - ("if ( yyleng + YY_G(yy_more_offset) >= YYLMAX ) \\"); - else - indent_puts ("if ( yyleng >= YYLMAX ) \\"); - - indent_up (); - indent_puts - ("YY_FATAL_ERROR( \"token too large, exceeds YYLMAX\" ); \\"); - indent_down (); - - if (yymore_used) { - indent_puts - ("yy_flex_strncpy( &yytext[YY_G(yy_more_offset)], YY_G(yytext_ptr), yyleng + 1 M4_YY_CALL_LAST_ARG); \\"); - indent_puts ("yyleng += YY_G(yy_more_offset); \\"); - indent_puts - ("YY_G(yy_prev_more_offset) = YY_G(yy_more_offset); \\"); - indent_puts ("YY_G(yy_more_offset) = 0; \\"); - } - else { - indent_puts - ("yy_flex_strncpy( yytext, YY_G(yytext_ptr), yyleng + 1 M4_YY_CALL_LAST_ARG); \\"); - } - } - - set_indent (0); - - skelout (); /* %% [4.0] - break point in skel */ - - - /* This is where we REALLY begin generating the tables. */ - - out_dec ("#define YY_NUM_RULES %d\n", num_rules); - out_dec ("#define YY_END_OF_BUFFER %d\n", num_rules + 1); + snprintf(strtmp, sizeof(strtmp), "%d", num_rules); + buf_m4_define( &m4defs_buf, "M4_YY_NUM_RULES", strtmp); if (fullspd) { /* Need to define the transet type as a size large * enough to hold the biggest offset. */ - int total_table_size = tblend + numecs + 1; - char *trans_offset_type = - (total_table_size >= INT16_MAX || long_align) ? - "flex_int32_t" : "flex_int16_t"; - - set_indent (0); - indent_puts ("struct yy_trans_info"); - indent_up (); - indent_puts ("{"); + if ( (tblend + numecs + 1) >= INT16_MAX || long_align) + out ("m4_define([[M4_YY_TRANS_INFO_32BIT]],1)\n"); /* We require that yy_verify and yy_nxt must be of the same size int. */ - indent_put2s ("%s yy_verify;", trans_offset_type); /* In cases where its sister yy_verify *is* a "yes, there is * a transition", yy_nxt is the offset (in records) to the @@ -1584,27 +973,9 @@ void make_tables () * record of a state, though, then yy_nxt is the action number * for that state. */ - - indent_put2s ("%s yy_nxt;", trans_offset_type); - indent_puts ("};"); - indent_down (); } else { - /* We generate a bogus 'struct yy_trans_info' data type - * so we can guarantee that it is always declared in the skel. - * This is so we can compile "sizeof(struct yy_trans_info)" - * in any scanner. - */ - indent_puts - ("/* This struct is not used in this scanner,"); - indent_puts (" but its presence is necessary. */"); - indent_puts ("struct yy_trans_info"); - indent_up (); - indent_puts ("{"); - indent_puts ("flex_int32_t yy_verify;"); - indent_puts ("flex_int32_t yy_nxt;"); - indent_puts ("};"); - indent_down (); + out ("m4_define([[M4_YY_TRANS_INFO_32BIT]],1)\n"); } if (fullspd) { @@ -1659,8 +1030,9 @@ void make_tables () } } } - else + else { gentabs (); + } if (do_yylineno) { @@ -1678,25 +1050,12 @@ void make_tables () } } - /* Definitions for backing up. We don't need them if REJECT - * is being used because then we use an alternative backin-up - * technique instead. - */ - if (num_backing_up > 0 && !reject) { - if (!C_plus_plus && !reentrant) { - indent_puts - ("static yy_state_type yy_last_accepting_state;"); - indent_puts - ("static char *yy_last_accepting_cpos;\n"); - } - } - if (nultrans) { flex_int32_t *yynultrans_data = 0; /* Begin generating yy_NUL_trans */ - out_str_dec (get_state_decl (), "yy_NUL_trans", - lastdfa + 1); + out_dec ("m4_define([[M4_YY_NUL_TRANS_TABLE_SIZE]],[[%d]])\n",lastdfa+1); + if (gentables) outn ("m4_define([[M4_YY_NUL_TRANS_TABLE_DATA]],[[0,"); buf_prints (&yydmap_buf, "\t{YYTD_ID_NUL_TRANS, (void**)&yy_NUL_trans, sizeof(%s)},\n", (fullspd) ? "struct yy_trans_info*" : @@ -1739,338 +1098,194 @@ void make_tables () /* End generating yy_NUL_trans */ } - if (!C_plus_plus && !reentrant) { - indent_puts ("extern int yy_flex_debug;"); - indent_put2s ("int yy_flex_debug = %s;\n", - ddebug ? "1" : "0"); - } +} + +void generate_code(void) { + int i; + int did_eof_rule = false; + + /* This is where we begin writing to the file. */ + + skelout(); /* M4 DEFINITIONS AND DATA TABLES */ + + /* ntod() constructs the DFA states/tables */ + ntod (); + + for (i = 1; i <= num_rules; ++i) + if (!rule_useful[i] && i != default_rule) + line_warning (_("rule cannot be matched"), + rule_linenum[i]); + + if (spprdflt && !reject && rule_useful[default_rule]) + line_warning (_ + ("-s option given but default rule can be matched"), + rule_linenum[default_rule]); + + + /* Generate the C state transition tables from the DFA. */ + outn("/* C state transition tables generated from the DFA. */\n"); + make_tables (); if (ddebug) { /* Spit out table mapping rules to line numbers. */ - out_str_dec (long_align ? get_int32_decl () : - get_int16_decl (), "yy_rule_linenum", - num_rules); + if (long_align) + out ("m4_define([[M4_YY_RULE_LINENUM_TABLE_32BIT]],1)\n"); + out_dec ("m4_define([[M4_YY_RULE_LINENUM_TABLE_SIZE]],[[%d]])\n" + "m4_define([[M4_YY_RULE_LINENUM_TABLE_DATA]],[[0,\n",num_rules); for (i = 1; i < num_rules; ++i) mkdata (rule_linenum[i]); dataend (); } - if (reject) { - outn ("m4_ifdef( [[M4_YY_USES_REJECT]],\n[["); - /* Declare state buffer variables. */ - if (!C_plus_plus && !reentrant) { - outn ("static yy_state_type *yy_state_buf=0, *yy_state_ptr=0;"); - outn ("static char *yy_full_match;"); - outn ("static int yy_lp;"); - } + /* end M4_GEN_DATA_TABLES */ - if (variable_trailing_context_rules) { - if (!C_plus_plus && !reentrant) { - outn ("static int yy_looking_for_trail_begin = 0;"); - outn ("static int yy_full_lp;"); - outn ("static int *yy_full_state;"); - } + /* Dump the stored m4 definitions. */ - out_hex ("#define YY_TRAILING_MASK 0x%x\n", - (unsigned int) YY_TRAILING_MASK); - out_hex ("#define YY_TRAILING_HEAD_MASK 0x%x\n", - (unsigned int) YY_TRAILING_HEAD_MASK); - } + buf_print_strings(&m4defs_buf, stdout); + buf_free(&m4defs_buf); - outn ("#define REJECT \\"); - outn ("{ \\"); - outn ("*yy_cp = YY_G(yy_hold_char); /* undo effects of setting up yytext */ \\"); - outn ("yy_cp = YY_G(yy_full_match); /* restore poss. backed-over text */ \\"); + /* Write out remaining m4 macros directly */ - if (variable_trailing_context_rules) { - outn ("YY_G(yy_lp) = YY_G(yy_full_lp); /* restore orig. accepting pos. */ \\"); - outn ("YY_G(yy_state_ptr) = YY_G(yy_full_state); /* restore orig. state */ \\"); - outn ("yy_current_state = *YY_G(yy_state_ptr); /* restore curr. state */ \\"); - } + if (reject) + out_m4_define("M4_YY_USES_REJECT", NULL); - outn ("++YY_G(yy_lp); \\"); - outn ("goto find_rule; \\"); + if (real_reject) + out_m4_define("M4_YY_REAL_REJECT", NULL); - outn ("}"); - outn ("]])\n"); - } + if (yymore_used) + out_m4_define("M4_YY_USES_YYMORE", NULL); - else { - outn ("/* The intent behind this definition is that it'll catch"); - outn (" * any uses of REJECT which flex missed."); - outn (" */"); - outn ("#define REJECT reject_used_but_not_detected"); - } + if (!do_yywrap) + out_m4_define("M4_YY_SKIP_YYWRAP", NULL); - if (yymore_used) { - if (!C_plus_plus) { - if (yytext_is_array) { - if (!reentrant){ - indent_puts ("static int yy_more_offset = 0;"); - indent_puts ("static int yy_prev_more_offset = 0;"); - } - } - else if (!reentrant) { - indent_puts - ("static int yy_more_flag = 0;"); - indent_puts - ("static int yy_more_len = 0;"); - } - } + if (ddebug) + out_m4_define("M4_FLEX_DEBUG", NULL); - if (yytext_is_array) { - indent_puts - ("#define yymore() (YY_G(yy_more_offset) = yy_flex_strlen( yytext M4_YY_CALL_LAST_ARG))"); - indent_puts ("#define YY_NEED_STRLEN"); - indent_puts ("#define YY_MORE_ADJ 0"); - indent_puts - ("#define YY_RESTORE_YY_MORE_OFFSET \\"); - indent_up (); - indent_puts ("{ \\"); - indent_puts - ("YY_G(yy_more_offset) = YY_G(yy_prev_more_offset); \\"); - indent_puts ("yyleng -= YY_G(yy_more_offset); \\"); - indent_puts ("}"); - indent_down (); - } - else { - indent_puts - ("#define yymore() (YY_G(yy_more_flag) = 1)"); - indent_puts - ("#define YY_MORE_ADJ YY_G(yy_more_len)"); - indent_puts ("#define YY_RESTORE_YY_MORE_OFFSET"); - } - } + if (csize == 256) + out_m4_define("M4_YY_CHAR_TYPE", "unsigned char"); + else + out_m4_define("M4_YY_CHAR_TYPE", "char"); - else { - indent_puts - ("#define yymore() yymore_used_but_not_detected"); - indent_puts ("#define YY_MORE_ADJ 0"); - indent_puts ("#define YY_RESTORE_YY_MORE_OFFSET"); - } + if (interactive) + out_m4_define("M4_YY_INTERACTIVE",NULL); - if (!C_plus_plus) { - if (yytext_is_array) { - outn ("#ifndef YYLMAX"); - outn ("#define YYLMAX 8192"); - outn ("#endif\n"); - if (!reentrant){ - outn ("char yytext[YYLMAX];"); - outn ("char *yytext_ptr;"); - } - } + if (do_stdinit) + out_m4_define("M4_YY_DO_STDINIT",NULL); - else { - if(! reentrant) - outn ("char *yytext;"); - } - } + if (fullspd) + out_m4_define("M4_YY_FULLSPD",NULL); - out (&action_array[defs1_offset]); + if (fulltbl) + out_m4_define("M4_YY_FULLTBL",NULL); - line_directive_out (stdout, 0); + if (nultrans) + out_m4_define("M4_YY_NULTRANS",NULL); - skelout (); /* %% [5.0] - break point in skel */ - - if (!C_plus_plus) { - if (use_read) { - outn ("\terrno=0; \\"); - outn ("\twhile ( (result = read( fileno(yyin), (char *) buf, max_size )) < 0 ) \\"); - outn ("\t{ \\"); - outn ("\t\tif( errno != EINTR) \\"); - outn ("\t\t{ \\"); - outn ("\t\t\tYY_FATAL_ERROR( \"input in flex scanner failed\" ); \\"); - outn ("\t\t\tbreak; \\"); - outn ("\t\t} \\"); - outn ("\t\terrno=0; \\"); - outn ("\t\tclearerr(yyin); \\"); - outn ("\t}\\"); - } + if (!fullspd && !fulltbl) + out_m4_define("M4_YY_COMPRESSED",NULL); - else { - outn ("\tif ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \\"); - outn ("\t\t{ \\"); - outn ("\t\tint c = '*'; \\"); - outn ("\t\tsize_t n; \\"); - outn ("\t\tfor ( n = 0; n < max_size && \\"); - outn ("\t\t\t (c = getc( yyin )) != EOF && c != '\\n'; ++n ) \\"); - outn ("\t\t\tbuf[n] = (char) c; \\"); - outn ("\t\tif ( c == '\\n' ) \\"); - outn ("\t\t\tbuf[n++] = (char) c; \\"); - outn ("\t\tif ( c == EOF && ferror( yyin ) ) \\"); - outn ("\t\t\tYY_FATAL_ERROR( \"input in flex scanner failed\" ); \\"); - outn ("\t\tresult = n; \\"); - outn ("\t\t} \\"); - outn ("\telse \\"); - outn ("\t\t{ \\"); - outn ("\t\terrno=0; \\"); - outn ("\t\twhile ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \\"); - outn ("\t\t\t{ \\"); - outn ("\t\t\tif( errno != EINTR) \\"); - outn ("\t\t\t\t{ \\"); - outn ("\t\t\t\tYY_FATAL_ERROR( \"input in flex scanner failed\" ); \\"); - outn ("\t\t\t\tbreak; \\"); - outn ("\t\t\t\t} \\"); - outn ("\t\t\terrno=0; \\"); - outn ("\t\t\tclearerr(yyin); \\"); - outn ("\t\t\t} \\"); - outn ("\t\t}\\"); - } - } - skelout (); /* %% [6.0] - break point in skel */ + if (gentables) + out_m4_define("M4_YY_GENTABLES",NULL); - indent_puts ("#define YY_RULE_SETUP \\"); - indent_up (); - if (bol_needed) { - indent_puts ("if ( yyleng > 0 ) \\"); - indent_up (); - indent_puts ("YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \\"); - indent_puts ("\t\t(yytext[yyleng - 1] == '\\n'); \\"); - indent_down (); - } - indent_puts ("YY_USER_ACTION"); - indent_down (); + if (lex_compat) + out_m4_define("M4_YY_FLEX_LEX_COMPAT",NULL); - skelout (); /* %% [7.0] - break point in skel */ + fprintf(stdout, "m4_define( [[%s]], [[0x%08x]])m4_dnl\n", + "M4_YY_TRAILING_MASK",YY_TRAILING_MASK); - /* Copy prolog to output file. */ - out (&action_array[prolog_offset]); + fprintf(stdout, "m4_define( [[%s]], [[0x%08x]])m4_dnl\n", + "M4_YY_TRAILING_HEAD_MASK",YY_TRAILING_HEAD_MASK); - line_directive_out (stdout, 0); + if (headerfilename) + out_m4_define("M4_YY_HEADER_FILENAME",headerfilename); - skelout (); /* %% [8.0] - break point in skel */ + if (outfilename) + out_m4_define("M4_YY_SOURCE_FILENAME",outfilename); - set_indent (2); + if (posix_compat) + out_m4_define("M4_YY_POSIXLY_CORRECT",NULL); - if (yymore_used && !yytext_is_array) { - indent_puts ("YY_G(yy_more_len) = 0;"); - indent_puts ("if ( YY_G(yy_more_flag) )"); - indent_up (); - indent_puts ("{"); - indent_puts - ("YY_G(yy_more_len) = YY_G(yy_c_buf_p) - YY_G(yytext_ptr);"); - indent_puts ("YY_G(yy_more_flag) = 0;"); - indent_puts ("}"); - indent_down (); - } + if (use_read) + out_m4_define("M4_YY_USE_READ",NULL); - skelout (); /* %% [9.0] - break point in skel */ + if (!gen_line_dirs) + out_m4_define("M4_YY_NO_LINE",NULL); - gen_start_state (); + if (bol_needed) + out_m4_define("M4_YY_BOL_NEEDED",NULL); - /* Note, don't use any indentation. */ - outn ("yy_match:"); - gen_next_match (); + if (!reject && num_backing_up > 0) + out_m4_define("M4_YY_NEED_BACKING_UP",NULL); - skelout (); /* %% [10.0] - break point in skel */ - set_indent (2); - gen_find_action (); + if (variable_trailing_context_rules) + out_m4_define("M4_YY_VARIABLE_TRAILING_CONTEXT_RULES", NULL); - skelout (); /* %% [11.0] - break point in skel */ - outn ("m4_ifdef( [[M4_YY_USE_LINENO]],[["); - indent_puts - ("if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] )"); - indent_up (); - indent_puts ("{"); - indent_puts ("yy_size_t yyl;"); - do_indent (); - out_str ("for ( yyl = %s; yyl < yyleng; ++yyl )\n", - yymore_used ? (yytext_is_array ? "YY_G(yy_prev_more_offset)" : - "YY_G(yy_more_len)") : "0"); - indent_up (); - indent_puts ("if ( yytext[yyl] == '\\n' )"); - indent_up (); - indent_puts ("M4_YY_INCR_LINENO();"); - indent_down (); - indent_down (); - indent_puts ("}"); - indent_down (); - outn ("]])"); - - skelout (); /* %% [12.0] - break point in skel */ - if (ddebug) { - indent_puts ("if ( yy_flex_debug )"); - indent_up (); + if (printstats) + out_m4_define("M4_YY_VERBOSE",NULL); - indent_puts ("{"); - indent_puts ("if ( yy_act == 0 )"); - indent_up (); - indent_puts (C_plus_plus ? - "std::cerr << \"--scanner backing up\\n\";" : - "fprintf( stderr, \"--scanner backing up\\n\" );"); - indent_down (); + if (nowarn) + out_m4_define("M4_YY_NOWARN",NULL); - do_indent (); - out_dec ("else if ( yy_act < %d )\n", num_rules); - indent_up (); + if (spprdflt) + out_m4_define("M4_YY_NODEFAULT",NULL); - if (C_plus_plus) { - indent_puts - ("std::cerr << \"--accepting rule at line \" << yy_rule_linenum[yy_act] <<"); - indent_puts - (" \"(\\\"\" << yytext << \"\\\")\\n\";"); - } - else { - indent_puts - ("fprintf( stderr, \"--accepting rule at line %ld (\\\"%s\\\")\\n\","); + if (performance_report > 1) /* a buf_m4_define_int would be nice. */ + out_m4_define("M4_YY_PERFORMANCE_REPORT",NULL); - indent_puts - (" (long)yy_rule_linenum[yy_act], yytext );"); - } + if (useecs) + out_m4_define("M4_YY_ECS",NULL); - indent_down (); + if (usemecs) + out_m4_define("M4_YY_META_ECS",NULL); - do_indent (); - out_dec ("else if ( yy_act == %d )\n", num_rules); - indent_up (); + fprintf(stdout, "m4_define( [[M4_YY_LASTDFA]], [[%d]])\n",lastdfa); - if (C_plus_plus) { - indent_puts - ("std::cerr << \"--accepting default rule (\\\"\" << yytext << \"\\\")\\n\";"); - } - else { - indent_puts - ("fprintf( stderr, \"--accepting default rule (\\\"%s\\\")\\n\","); - indent_puts (" yytext );"); - } + fprintf(stdout, "m4_define( [[M4_YY_JAMSTATE]], [[%d]])\n",jamstate); - indent_down (); + fprintf(stdout, "m4_define( [[M4_YY_JAMBASE]], [[%d]])\n",jambase); - do_indent (); - out_dec ("else if ( yy_act == %d )\n", num_rules + 1); - indent_up (); + fprintf(stdout, "m4_define( [[M4_YY_NUL_EC]], [[%d]])\n",NUL_ec); - indent_puts (C_plus_plus ? - "std::cerr << \"--(end of buffer or a NUL)\\n\";" : - "fprintf( stderr, \"--(end of buffer or a NUL)\\n\" );"); + skelout(); /* USER TOP CODE */ - indent_down (); + /* Dump the user defined %top{} preproc directives. */ + /* Source #line directives are inserted while scanning. */ + if( top_buf.elts) + outn((char*) top_buf.elts); - do_indent (); - outn ("else"); - indent_up (); + skelout(); /* USER PREDEFINES */ - if (C_plus_plus) { - indent_puts - ("std::cerr << \"--EOF (start condition \" << YY_START << \")\\n\";"); - } - else { - indent_puts - ("fprintf( stderr, \"--EOF (start condition %d)\\n\", YY_START );"); - } + /* Dump the command-line -D defines. */ + if (userdef_buf.elts) { + if (gen_line_dirs) + out("#line 1 \n"); + outn ((char *) (userdef_buf.elts)); + } - indent_down (); + skelout(); /* USER SECTION 1 */ - indent_puts ("}"); - indent_down (); - } + /* Source #line directive is added while scanning. */ + out (&action_array[defs1_offset]); + + skelout(); /* USER BOTTOM CODE */ + + /* Dump the user defined %bottom{} preproc directives. */ + /* Source #line directives are inserted while scanning. */ + if( bottom_buf.elts) + outn((char*) bottom_buf.elts); + + skelout(); /* USER DECLARATIONS */ + /* User declaration section (prolog) */ + /* Copy prolog to output file. */ + out (&action_array[prolog_offset]); + + skelout(); /* GEN ACTIONS */ /* Copy actions to output file. */ - skelout (); /* %% [13.0] - break point in skel */ indent_up (); - gen_bu_action (); out (&action_array[action_offset]); + /* This line directive re-syncs after dumping the action array (FIXME?) */ line_directive_out (stdout, 0); /* generate cases for any missing EOF rules */ @@ -2087,83 +1302,12 @@ void make_tables () indent_down (); } + skelout(); /* USER SECTION 3 */ + /* User code, section 3 */ - /* Generate code for handling NUL's, if needed. */ - - /* First, deal with backing up and setting up yy_cp if the scanner - * finds that it should JAM on the NUL. - */ - skelout (); /* %% [14.0] - break point in skel */ - set_indent (4); - - if (fullspd || fulltbl) - indent_puts ("yy_cp = YY_G(yy_c_buf_p);"); - - else { /* compressed table */ - if (!reject && !interactive) { - /* Do the guaranteed-needed backing up to figure - * out the match. - */ - indent_puts - ("yy_cp = YY_G(yy_last_accepting_cpos);"); - indent_puts - ("yy_current_state = YY_G(yy_last_accepting_state);"); - } - - else - /* Still need to initialize yy_cp, though - * yy_current_state was set up by - * yy_get_previous_state(). - */ - indent_puts ("yy_cp = YY_G(yy_c_buf_p);"); - } - - - /* Generate code for yy_get_previous_state(). */ - set_indent (1); - skelout (); /* %% [15.0] - break point in skel */ - - gen_start_state (); - - set_indent (2); - skelout (); /* %% [16.0] - break point in skel */ - gen_next_state (true); - - set_indent (1); - skelout (); /* %% [17.0] - break point in skel */ - gen_NUL_trans (); - - skelout (); /* %% [18.0] - break point in skel */ - skelout (); /* %% [19.0] - break point in skel */ - /* Update BOL and yylineno inside of input(). */ - if (bol_needed) { - indent_puts - ("YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\\n');"); - if (do_yylineno) { - indent_puts - ("if ( YY_CURRENT_BUFFER_LVALUE->yy_at_bol )"); - indent_up (); - indent_puts ("M4_YY_INCR_LINENO();"); - indent_down (); - } - } - - else if (do_yylineno) { - indent_puts ("if ( c == '\\n' )"); - indent_up (); - indent_puts ("M4_YY_INCR_LINENO();"); - indent_down (); - } - - skelout (); - - /* Copy remainder of input to output. */ - + /* This line directive re-syncs to the input line number */ line_directive_out (stdout, 1); + if (sectnum == 3) (void) flexscan (); /* copy remainder of input to output */ - if (sectnum == 3) { - OUT_BEGIN_CODE (); - (void) flexscan (); /* copy remainder of input to output */ - OUT_END_CODE (); - } + skelout(); /* REMAINDER OF SKELETON */ } diff --git a/libmain.c b/libmain.c index 49262e4..6d881ab 100644 --- a/libmain.c +++ b/libmain.c @@ -23,9 +23,7 @@ extern int yylex (); -int main (argc, argv) - int argc; - char *argv[]; +int main (int argc /*@unused@*/, char *argv[] /*@unused@*/) { while (yylex () != 0) ; diff --git a/main.c b/main.c index 31833c4..4acd381 100644 --- a/main.c +++ b/main.c @@ -41,10 +41,10 @@ static char flex_version[] = FLEX_VERSION; /* declare functions that have forward references */ -void flexinit PROTO ((int, char **)); -void readin PROTO ((void)); -void set_up_initial_allocations PROTO ((void)); -static char *basename2 PROTO ((char *path, int should_strip_ext)); +void flexinit (int, char **); +void readin (void); +void set_up_initial_allocations (void); +static char *basename2 (char *path, int should_strip_ext); /* these globals are all defined and commented in flexdef.h */ @@ -57,14 +57,17 @@ int C_plus_plus, long_align, use_read, yytext_is_array, do_yywrap, int reentrant, bison_bridge_lval, bison_bridge_lloc; int yymore_used, reject, real_reject, continued_action, in_rule; int yymore_really_used, reject_really_used; -int datapos, dataline, linenum; +int datapos, dataline, linenum, out_linenum; FILE *skelfile = NULL; -int skel_ind = 0; +/* TODO: May want C skel and C++ skel, and maybe reentrant C skel */ +static char skelname_default[] = "flex_skel.m4"; +char *skelname = skelname_default; +char *flex_include_path = DATAROOTDIR; char *action_array; int action_size, defs1_offset, prolog_offset, action_offset, action_index; char *infilename = NULL, *outfilename = NULL, *headerfilename = NULL; -int did_outfilename; +char *m4outfilename = NULL; char *prefix, *yyclass, *extra_type = NULL; int do_stdinit, use_stdout; int onestate[ONE_STACK_SIZE], onesym[ONE_STACK_SIZE]; @@ -105,12 +108,16 @@ int num_input_files; jmp_buf flex_main_jmp_buf; bool *rule_has_nl, *ccl_has_nl; int nlch = '\n'; -bool ansi_func_defs, ansi_func_protos; bool tablesext, tablesverify, gentables; -char *tablesfilename=0,*tablesname=0; +char *tablesfilename=0, *tablesname=0; struct yytbl_writer tableswr; +/* This is a flag to tell the internal lexer that it is parsing + * options in the --option=LIST string. + */ +bool parsing_option_string = false; + /* Make sure program_name is initialized so we don't crash if writing * out an error message before getting the program name from argv[0]. */ @@ -132,25 +139,25 @@ extern unsigned _stklen = 16384; /* From scan.l */ extern FILE* yyout; +typedef struct yy_buffer_state *YY_BUFFER_STATE; +extern YY_BUFFER_STATE yy_scan_buffer(char *base, unsigned int size); +extern int yylex_destroy(void); static char outfile_path[MAXLINE]; static int outfile_created = 0; -static char *skelname = NULL; static int _stdout_closed = 0; /* flag to prevent double-fclose() on stdout. */ -const char *escaped_qstart = "[[]]M4_YY_NOOP[M4_YY_NOOP[M4_YY_NOOP[[]]"; -const char *escaped_qend = "[[]]M4_YY_NOOP]M4_YY_NOOP]M4_YY_NOOP[[]]"; +const char *escaped_qstart = "]]" "[[[]]" "[[[]]" "[["; +const char *escaped_qend = "]]" "[[]]]" "[[]]]" "[["; /* For debugging. The max number of filters to apply to skeleton. */ static int preproc_level = 1000; -int flex_main PROTO ((int argc, char *argv[])); -int main PROTO ((int argc, char *argv[])); +int flex_main (int argc, char *argv[]); +int main (int argc, char *argv[]); -int flex_main (argc, argv) - int argc; - char *argv[]; +int flex_main (int argc, char *argv[]) { - int i, exit_status, child_status; + int exit_status, child_status; /* Set a longjmp target. Yes, I know it's a hack, but it gets worse: The * return value of setjmp, if non-zero, is the desired exit code PLUS ONE. @@ -177,25 +184,11 @@ int flex_main (argc, argv) } return exit_status - 1; } - flexinit (argc, argv); readin (); - ntod (); - - for (i = 1; i <= num_rules; ++i) - if (!rule_useful[i] && i != default_rule) - line_warning (_("rule cannot be matched"), - rule_linenum[i]); - - if (spprdflt && !reject && rule_useful[default_rule]) - line_warning (_ - ("-s option given but default rule can be matched"), - rule_linenum[default_rule]); - - /* Generate the C state transition tables from the DFA. */ - make_tables (); + generate_code(); /* Note, flexend does not return. It exits with its argument * as status. @@ -206,9 +199,7 @@ int flex_main (argc, argv) } /* Wrapper around flex_main, so flex_main can be built as a library. */ -int main (argc, argv) - int argc; - char *argv[]; +int main (int argc, char *argv[]) { #if ENABLE_NLS #if HAVE_LOCALE_H @@ -222,9 +213,13 @@ int main (argc, argv) return flex_main (argc, argv); } -/* check_options - check user-specified options */ +/* check_options - check user-specified options + * Sets some defaults where not options were given. + * Also sets M4 macro definitions for all options not already + * defined as an m4 macro. + */ -void check_options () +void check_options (void) { int i; const char * m4 = NULL; @@ -237,8 +232,7 @@ void check_options () flexerror (_("Can't use -f or -F with -l option")); if (reentrant || bison_bridge_lval) - flexerror (_ - ("Can't use --reentrant or --bison-bridge with -l option")); + flexerror (_("Can't use --reentrant or --bison-bridge with -l option")); /* Don't rely on detecting use of yymore() and REJECT, * just assume they'll be used. @@ -250,60 +244,50 @@ void check_options () use_read = false; } + if (interactive == unspecified) + interactive = !(fulltbl || fullspd); -#if 0 - /* This makes no sense whatsoever. I'm removing it. */ - if (do_yylineno) - /* This should really be "maintain_backup_tables = true" */ - reject_really_used = true; -#endif + if (useecs == unspecified) + useecs = !(fulltbl || fullspd); - if (csize == unspecified) { - if ((fulltbl || fullspd) && !useecs) - csize = DEFAULT_CSIZE; - else - csize = CSIZE; - } + if (usemecs == unspecified) + usemecs = !(fulltbl || fullspd); - if (interactive == unspecified) { - if (fulltbl || fullspd) - interactive = false; - else - interactive = true; - } + if (use_read == unspecified) + use_read = (fulltbl || fullspd); + + if (csize == unspecified) + csize = ((fulltbl || fullspd) && !useecs) ? DEFAULT_CSIZE : CSIZE; if (fulltbl || fullspd) { if (usemecs) - flexerror (_ - ("-Cf/-CF and -Cm don't make sense together")); + flexerror (_("-Cf/-CF and -Cm don't make sense together")); if (interactive) flexerror (_("-Cf/-CF and -I are incompatible")); if (lex_compat) - flexerror (_ - ("-Cf/-CF are incompatible with lex-compatibility mode")); + flexerror (_("-Cf/-CF are incompatible with lex-compatibility mode")); if (fulltbl && fullspd) - flexerror (_ - ("-Cf and -CF are mutually exclusive")); + flexerror (_("-Cf and -CF are mutually exclusive")); } - if (C_plus_plus && fullspd) - flexerror (_("Can't use -+ with -CF option")); + if (C_plus_plus) { + if (yytext_is_array) { + warn (_("%array incompatible with -+ option")); + yytext_is_array = false; + } - if (C_plus_plus && yytext_is_array) { - warn (_("%array incompatible with -+ option")); - yytext_is_array = false; + if (reentrant) + flexerror (_("Options -+ and --reentrant are mutually exclusive.")); } - if (C_plus_plus && (reentrant)) - flexerror (_("Options -+ and --reentrant are mutually exclusive.")); - - if (C_plus_plus && bison_bridge_lval) - flexerror (_("bison bridge not supported for the C++ scanner.")); - + else { + if (yyclass) + flexerror (_("%option yyclass only meaningful for C++ scanners")); + } if (useecs) { /* Set up doubly-linked equivalence classes. */ @@ -328,19 +312,13 @@ void check_options () } } - if (!ansi_func_defs) - buf_m4_define( &m4defs_buf, "M4_YY_NO_ANSI_FUNC_DEFS", NULL); - - if (!ansi_func_protos) - buf_m4_define( &m4defs_buf, "M4_YY_NO_ANSI_FUNC_PROTOS", NULL); - - if (extra_type) - buf_m4_define( &m4defs_buf, "M4_EXTRA_TYPE_DEFS", extra_type); + if (extra_type) + buf_m4_define( &m4defs_buf, "M4_EXTRA_TYPE_DEF", extra_type); if (!use_stdout) { FILE *prev_stdout; - if (!did_outfilename) { + if (!outfilename) { char *suffix; if (C_plus_plus) @@ -363,20 +341,26 @@ void check_options () } - /* Setup the filter chain. */ - output_chain = filter_create_int(NULL, filter_tee_header, headerfilename); - if ( !(m4 = getenv("M4"))) - m4 = M4; - filter_create_ext(output_chain, m4, "-P", 0); - filter_create_int(output_chain, filter_fix_linedirs, NULL); + /* Setup the filter chain. */ + if (m4outfilename) { + output_chain = filter_create_ext(NULL, "/usr/bin/tee", m4outfilename, 0); + filter_create_int(output_chain, filter_tee_header, headerfilename); + } else { + output_chain = filter_create_int(NULL, filter_tee_header, headerfilename); + } - /* For debugging, only run the requested number of filters. */ - if (preproc_level > 0) { - filter_truncate(output_chain, preproc_level); - filter_apply_chain(output_chain); - } - yyout = stdout; + if ( !(m4 = getenv("M4"))) + m4 = M4; + filter_create_ext(output_chain, m4, "-P", 0); + filter_create_int(output_chain, filter_fix_linedirs, NULL); + filter_create_int(output_chain, filter_check_errors, NULL); + /* For debugging, only run the requested number of filters. */ + if (preproc_level > 0) { + filter_truncate(output_chain, preproc_level); + filter_apply_chain(output_chain); + } + yyout = stdout; /* always generate the tablesverify flag. */ buf_m4_define (&m4defs_buf, "M4_YY_TABLES_VERIFY", tablesverify ? "1" : "0"); @@ -402,7 +386,9 @@ void check_options () snprintf (pname, nbytes, tablesfile_template, prefix); } - if ((tablesout = fopen (tablesfilename, "w")) == NULL) + buf_m4_define (&m4defs_buf, "M4_YY_TABLES_FILENAME", tablesfilename); + + if ((tablesout = fopen (tablesfilename, "wb")) == NULL) lerrsf (_("could not create %s"), tablesfilename); if (pname) free (pname); @@ -414,37 +400,53 @@ void check_options () tablesname = (char *) calloc (nbytes, 1); snprintf (tablesname, nbytes, "%stables", prefix); yytbl_hdr_init (&hdr, flex_version, tablesname); + buf_m4_define (&m4defs_buf, "M4_YY_TABLES_NAME", tablesname); if (yytbl_hdr_fwrite (&tableswr, &hdr) <= 0) flexerror (_("could not write tables header")); } - if (skelname && (skelfile = fopen (skelname, "r")) == NULL) - lerrsf (_("can't open skeleton file %s"), skelname); - - if (reentrant) { - buf_m4_define (&m4defs_buf, "M4_YY_REENTRANT", NULL); - if (yytext_is_array) - buf_m4_define (&m4defs_buf, "M4_YY_TEXT_IS_ARRAY", NULL); + if ( (skelfile = fopen (skelname, "r")) == NULL) + { + char skelpath[1024]; + snprintf(skelpath,sizeof(skelpath),"%s/%s",flex_include_path,skelname); + if ( (skelfile = fopen (skelpath, "r")) == NULL) + { + /* No formatted flexerror(), so use snprintf() */ + snprintf(skelpath,sizeof(skelpath),_("can't open skeleton file %s"), skelname); + flexerror ( skelpath ); + } } - if ( bison_bridge_lval) - buf_m4_define (&m4defs_buf, "M4_YY_BISON_LVAL", NULL); + buf_m4_define(&m4defs_buf, "M4_FLEX_VERSION", flex_version); + + if (C_plus_plus) + buf_m4_define (&m4defs_buf, "M4_YY_CPLUSPLUS", NULL); - if ( bison_bridge_lloc) - buf_m4_define (&m4defs_buf, "", NULL); + if (yyclass) + buf_m4_define( &m4defs_buf, "M4_YY_CLASS",yyclass); - buf_m4_define(&m4defs_buf, "M4_YY_PREFIX", prefix); +/* Was BUG here? M4_YY_TEXT_IS_ARRAY was set ONLY if reentrant. */ + if (reentrant) + buf_m4_define (&m4defs_buf, "M4_YY_REENTRANT", NULL); - if (did_outfilename) - line_directive_out (stdout, 0); + if (yytext_is_array) + buf_m4_define (&m4defs_buf, "M4_YY_TEXT_IS_ARRAY", NULL); + + if (bison_bridge_lval) + buf_m4_define (&m4defs_buf, "M4_YY_BISON_LVAL", NULL); + + if (bison_bridge_lloc) + buf_m4_define (&m4defs_buf, "M4_YY_BISON_LLOC", NULL); + + buf_m4_define(&m4defs_buf, "M4_YY_PREFIX", prefix); if (do_yylineno) buf_m4_define (&m4defs_buf, "M4_YY_USE_LINENO", NULL); /* Create the alignment type. */ - buf_strdefine (&userdef_buf, "YY_INT_ALIGNED", - long_align ? "long int" : "short int"); + buf_m4_define (&m4defs_buf, "M4_YY_INT_ALIGNED", + long_align ? "flex_int32_t" : "flex_int16_t"); /* Define the start condition macros. */ { @@ -461,29 +463,10 @@ void check_options () buf_strappend(&tmpbuf, str); free(str); } - buf_m4_define(&m4defs_buf, "M4_YY_SC_DEFS", tmpbuf.elts); + buf_m4_define(&m4defs_buf, "M4_YY_SC_DEFS", (char*)tmpbuf.elts); buf_destroy(&tmpbuf); } - /* This is where we begin writing to the file. */ - - /* Dump the %top code. */ - if( top_buf.elts) - outn((char*) top_buf.elts); - - /* Dump the m4 definitions. */ - buf_print_strings(&m4defs_buf, stdout); - m4defs_buf.nelts = 0; /* memory leak here. */ - - /* Place a bogus line directive, it will be fixed in the filter. */ - outn("#line 0 \"M4_YY_OUTFILE_NAME\"\n"); - - /* Dump the user defined preproc directives. */ - if (userdef_buf.elts) - outn ((char *) (userdef_buf.elts)); - - skelout (); - /* %% [1.0] */ } /* flexend - terminate flex @@ -492,9 +475,7 @@ void check_options () * This routine does not return. */ -void flexend (exit_status) - int exit_status; - +void flexend (int exit_status) { static int called_before = -1; /* prevent infinite recursion. */ int tblsiz; @@ -512,193 +493,6 @@ void flexend (exit_status) skelname); } -#if 0 - fprintf (header_out, - "#ifdef YY_HEADER_EXPORT_START_CONDITIONS\n"); - fprintf (header_out, - "/* Beware! Start conditions are not prefixed. */\n"); - - /* Special case for "INITIAL" */ - fprintf (header_out, - "#undef INITIAL\n#define INITIAL 0\n"); - for (i = 2; i <= lastsc; i++) - fprintf (header_out, "#define %s %d\n", scname[i], i - 1); - fprintf (header_out, - "#endif /* YY_HEADER_EXPORT_START_CONDITIONS */\n\n"); - - /* Kill ALL flex-related macros. This is so the user - * can #include more than one generated header file. */ - fprintf (header_out, "#ifndef YY_HEADER_NO_UNDEFS\n"); - fprintf (header_out, - "/* Undefine all internal macros, etc., that do no belong in the header. */\n\n"); - - { - const char * undef_list[] = { - - "BEGIN", - "ECHO", - "EOB_ACT_CONTINUE_SCAN", - "EOB_ACT_END_OF_FILE", - "EOB_ACT_LAST_MATCH", - "FLEX_SCANNER", - "FLEX_STD", - "REJECT", - "YYFARGS0", - "YYFARGS1", - "YYFARGS2", - "YYFARGS3", - "YYLMAX", - "YYSTATE", - "YY_AT_BOL", - "YY_BREAK", - "YY_BUFFER_EOF_PENDING", - "YY_BUFFER_NEW", - "YY_BUFFER_NORMAL", - "YY_BUF_SIZE", - "M4_YY_CALL_LAST_ARG", - "M4_YY_CALL_ONLY_ARG", - "YY_CURRENT_BUFFER", - "YY_DECL", - "M4_YY_DECL_LAST_ARG", - "M4_YY_DEF_LAST_ARG", - "M4_YY_DEF_ONLY_ARG", - "YY_DO_BEFORE_ACTION", - "YY_END_OF_BUFFER", - "YY_END_OF_BUFFER_CHAR", - "YY_EXIT_FAILURE", - "YY_EXTRA_TYPE", - "YY_FATAL_ERROR", - "YY_FLEX_DEFINED_ECHO", - "YY_FLEX_LEX_COMPAT", - "YY_FLEX_MAJOR_VERSION", - "YY_FLEX_MINOR_VERSION", - "YY_FLEX_SUBMINOR_VERSION", - "YY_FLUSH_BUFFER", - "YY_G", - "YY_INPUT", - "YY_INTERACTIVE", - "YY_INT_ALIGNED", - "YY_LAST_ARG", - "YY_LESS_LINENO", - "YY_LEX_ARGS", - "YY_LEX_DECLARATION", - "YY_LEX_PROTO", - "YY_MAIN", - "YY_MORE_ADJ", - "YY_NEED_STRLEN", - "YY_NEW_FILE", - "YY_NULL", - "YY_NUM_RULES", - "YY_ONLY_ARG", - "YY_PARAMS", - "YY_PROTO", - "M4_YY_PROTO_LAST_ARG", - "M4_YY_PROTO_ONLY_ARG void", - "YY_READ_BUF_SIZE", - "YY_REENTRANT", - "YY_RESTORE_YY_MORE_OFFSET", - "YY_RULE_SETUP", - "YY_SC_TO_UI", - "YY_SKIP_YYWRAP", - "YY_START", - "YY_START_STACK_INCR", - "YY_STATE_EOF", - "YY_STDINIT", - "YY_TRAILING_HEAD_MASK", - "YY_TRAILING_MASK", - "YY_USER_ACTION", - "YY_USE_CONST", - "YY_USE_PROTOS", - "unput", - "yyTABLES_NAME", - "yy_create_buffer", - "yy_delete_buffer", - "yy_flex_debug", - "yy_flush_buffer", - "yy_init_buffer", - "yy_load_buffer_state", - "yy_new_buffer", - "yy_scan_buffer", - "yy_scan_bytes", - "yy_scan_string", - "yy_set_bol", - "yy_set_interactive", - "yy_switch_to_buffer", - "yypush_buffer_state", - "yypop_buffer_state", - "yyensure_buffer_stack", - "yyalloc", - "yyconst", - "yyextra", - "yyfree", - "yyget_debug", - "yyget_extra", - "yyget_in", - "yyget_leng", - "yyget_lineno", - "yyget_lloc", - "yyget_lval", - "yyget_out", - "yyget_text", - "yyin", - "yyleng", - "yyless", - "yylex", - "yylex_destroy", - "yylex_init", - "yylex_init_extra", - "yylineno", - "yylloc", - "yylval", - "yymore", - "yyout", - "yyrealloc", - "yyrestart", - "yyset_debug", - "yyset_extra", - "yyset_in", - "yyset_lineno", - "yyset_lloc", - "yyset_lval", - "yyset_out", - "yytables_destroy", - "yytables_fload", - "yyterminate", - "yytext", - "yytext_ptr", - "yywrap", - - /* must be null-terminated */ - NULL}; - - - for (i=0; undef_list[i] != NULL; i++) - fprintf (header_out, "#undef %s\n", undef_list[i]); - } - - /* undef any of the auto-generated symbols. */ - for (i = 0; i < defs_buf.nelts; i++) { - - /* don't undef start conditions */ - if (sclookup (((char **) defs_buf.elts)[i]) > 0) - continue; - fprintf (header_out, "#undef %s\n", - ((char **) defs_buf.elts)[i]); - } - - fprintf (header_out, - "#endif /* !YY_HEADER_NO_UNDEFS */\n"); - fprintf (header_out, "\n"); - fprintf (header_out, "#undef %sIN_HEADER\n", prefix); - fprintf (header_out, "#endif /* %sHEADER_H */\n", prefix); - - if (ferror (header_out)) - lerrsf (_("error creating header file %s"), - headerfilename); - fflush (header_out); - fclose (header_out); -#endif - if (exit_status != 0 && outfile_created) { if (ferror (stdout)) lerrsf (_("error writing output file %s"), @@ -719,8 +513,7 @@ void flexend (exit_status) fprintf (backing_up_file, _("No backing up.\n")); else if (fullspd || fulltbl) fprintf (backing_up_file, - _ - ("%d backing up (non-accepting) states.\n"), + _("%d backing up (non-accepting) states.\n"), num_backing_up); else fprintf (backing_up_file, @@ -807,10 +600,10 @@ void flexend (exit_status) if (use_read) putc ('r', stderr); - if (did_outfilename) + if (outfilename) fprintf (stderr, " -o%s", outfilename); - if (skelname) + if (skelname != skelname_default) fprintf (stderr, " -S%s", skelname); if (strcmp (prefix, "yy")) @@ -830,13 +623,11 @@ void flexend (exit_status) fprintf (stderr, _(" No backing up\n")); else if (fullspd || fulltbl) fprintf (stderr, - _ - (" %d backing-up (non-accepting) states\n"), + _(" %d backing-up (non-accepting) states\n"), num_backing_up); else fprintf (stderr, - _ - (" Compressed tables always back-up\n")); + _(" Compressed tables always back-up\n")); if (bol_needed) fprintf (stderr, @@ -845,16 +636,14 @@ void flexend (exit_status) fprintf (stderr, _(" %d/%d start conditions\n"), lastsc, current_max_scs); fprintf (stderr, - _ - (" %d epsilon states, %d double epsilon states\n"), + _(" %d epsilon states, %d double epsilon states\n"), numeps, eps2); if (lastccl == 0) fprintf (stderr, _(" no character classes\n")); else fprintf (stderr, - _ - (" %d/%d character classes needed %d/%d words of storage, %d reused\n"), + _(" %d/%d character classes needed %d/%d words of storage, %d reused\n"), lastccl, current_maxccls, cclmap[lastccl] + ccllen[lastccl], current_max_ccl_tbl_size, cclreuse); @@ -878,12 +667,10 @@ void flexend (exit_status) _(" %d/%d base-def entries created\n"), lastdfa + numtemps, current_max_dfas); fprintf (stderr, - _ - (" %d/%d (peak %d) nxt-chk entries created\n"), + _(" %d/%d (peak %d) nxt-chk entries created\n"), tblend, current_max_xpairs, peakpairs); fprintf (stderr, - _ - (" %d/%d (peak %d) template nxt-chk entries created\n"), + _(" %d/%d (peak %d) template nxt-chk entries created\n"), numtemps * nummecs, current_max_template_xpairs, numtemps * numecs); @@ -899,22 +686,19 @@ void flexend (exit_status) if (useecs) { tblsiz = tblsiz + csize; fprintf (stderr, - _ - (" %d/%d equivalence classes created\n"), + _(" %d/%d equivalence classes created\n"), numecs, csize); } if (usemecs) { tblsiz = tblsiz + numecs; fprintf (stderr, - _ - (" %d/%d meta-equivalence classes created\n"), + _(" %d/%d meta-equivalence classes created\n"), nummecs, csize); } fprintf (stderr, - _ - (" %d (%d saved) hash collisions, %d DFAs equal\n"), + _(" %d (%d saved) hash collisions, %d DFAs equal\n"), hshcol, hshsave, dfaeql); fprintf (stderr, _(" %d sets of reallocations needed\n"), num_reallocs); @@ -928,13 +712,11 @@ void flexend (exit_status) /* flexinit - initialize flex */ -void flexinit (argc, argv) - int argc; - char **argv; +void flexinit (int argc, char **argv) { - int i, sawcmpflag, rv, optind; + int i, rv, optind; char *arg; - scanopt_t sopt; + scanopt_t *sopt; printstats = syntaxerror = trace = spprdflt = false; lex_compat = posix_compat = C_plus_plus = backing_up_report = @@ -944,20 +726,17 @@ void flexinit (argc, argv) do_yylineno = yytext_is_array = in_rule = reject = do_stdinit = false; yymore_really_used = reject_really_used = unspecified; - interactive = csize = unspecified; - do_yywrap = gen_line_dirs = usemecs = useecs = true; + interactive = csize = usemecs = useecs = use_read = unspecified; + do_yywrap = gen_line_dirs = true; reentrant = bison_bridge_lval = bison_bridge_lloc = false; performance_report = 0; - did_outfilename = 0; prefix = "yy"; yyclass = 0; - use_read = use_stdout = false; + use_read = unspecified; + use_stdout = false; tablesext = tablesverify = false; gentables = true; tablesfilename = tablesname = NULL; - ansi_func_defs = ansi_func_protos = true; - - sawcmpflag = false; /* Initialize dynamic array for holding the rule actions. */ action_size = 2048; /* default size of action array in bytes */ @@ -969,21 +748,16 @@ void flexinit (argc, argv) buf_init (&userdef_buf, sizeof (char)); /* one long string */ buf_init (&defs_buf, sizeof (char *)); /* list of strings */ buf_init (&yydmap_buf, sizeof (char)); /* one long string */ - buf_init (&top_buf, sizeof (char)); /* one long string */ - - { - const char * m4defs_init_str[] = {"m4_changequote\n", - "m4_changequote([[, ]])\n"}; - buf_init (&m4defs_buf, sizeof (char *)); - buf_append (&m4defs_buf, &m4defs_init_str, 2); - } + buf_init (&top_buf, sizeof (char)); /* one long string */ + buf_init (&m4defs_buf, sizeof (char *));/* list of strings */ sf_init (); + if ((arg = getenv("FLEX_INCLUDE_PATH")) != NULL) flex_include_path = arg; /* FIXME? */ + /* initialize regex lib */ flex_init_regex(); - /* Enable C++ if program name ends with '+'. */ program_name = basename2 (argv[0], 0); if (program_name[0] != '\0' && @@ -1004,8 +778,7 @@ void flexinit (argc, argv) if (rv < 0) { /* Scanopt has already printed an option-specific error message. */ fprintf (stderr, - _ - ("Try `%s --help' for more information.\n"), + _("Try `%s --help' for more information.\n"), program_name); FLEX_EXIT (1); } @@ -1015,6 +788,10 @@ void flexinit (argc, argv) C_plus_plus = true; break; + case OPT_C_SCANNER: + C_plus_plus = false; + break; + case OPT_BATCH: interactive = false; break; @@ -1027,13 +804,6 @@ void flexinit (argc, argv) break; case OPT_COMPRESSION: - if (!sawcmpflag) { - useecs = false; - usemecs = false; - fulltbl = false; - sawcmpflag = true; - } - for (i = 0; arg && arg[i] != '\0'; i++) switch (arg[i]) { case 'a': @@ -1061,8 +831,7 @@ void flexinit (argc, argv) break; default: - lerrif (_ - ("unknown -C option '%c'"), + lerrif (_("unknown -C option '%c'"), (int) arg[i]); break; } @@ -1077,19 +846,21 @@ void flexinit (argc, argv) break; case OPT_FULL: - useecs = usemecs = false; - use_read = fulltbl = true; + fulltbl = true; break; case OPT_FAST: - useecs = usemecs = false; - use_read = fullspd = true; + fullspd = true; break; case OPT_HELP: usage (); FLEX_EXIT (0); + case OPT_INCLUDE_PATH: + flex_include_path = arg; + break; + case OPT_INTERACTIVE: interactive = true; break; @@ -1106,17 +877,21 @@ void flexinit (argc, argv) posix_compat = true; break; - case OPT_PREPROC_LEVEL: - preproc_level = strtol(arg,NULL,0); - break; + case OPT_PREPROC_LEVEL: + preproc_level = strtol(arg,NULL,0); + break; + + case OPT_M4OUTFILE: + m4outfilename = arg; + break; case OPT_MAIN: - buf_strdefine (&userdef_buf, "YY_MAIN", "1"); + buf_m4_define( &m4defs_buf, "M4_YY_MAIN",0); do_yywrap = false; break; case OPT_NO_MAIN: - buf_strdefine (&userdef_buf, "YY_MAIN", "0"); + buf_m4_undefine( &m4defs_buf, "M4_YY_MAIN"); break; case OPT_NO_LINE: @@ -1125,7 +900,6 @@ void flexinit (argc, argv) case OPT_OUTFILE: outfilename = arg; - did_outfilename = 1; break; case OPT_PREFIX: @@ -1169,8 +943,7 @@ void flexinit (argc, argv) break; case OPT_NO_UNISTD_H: - //buf_strdefine (&userdef_buf, "YY_NO_UNISTD_H", "1"); - buf_m4_define( &m4defs_buf, "M4_YY_NO_UNISTD_H",0); + buf_m4_define( &m4defs_buf, "M4_YY_NO_UNISTD_H",0); break; case OPT_TABLES_FILE: @@ -1198,6 +971,10 @@ void flexinit (argc, argv) nowarn = false; break; + case OPT_NO_VERBOSE: + printstats = false; + break; + case OPT_NO_WARN: nowarn = true; break; @@ -1223,7 +1000,7 @@ void flexinit (argc, argv) break; case OPT_NEVER_INTERACTIVE: - buf_m4_define( &m4defs_buf, "M4_YY_NEVER_INTERACTIVE", 0); + buf_m4_define( &m4defs_buf, "M4_YY_NEVER_INTERACTIVE", 0); break; case OPT_ARRAY: @@ -1284,8 +1061,7 @@ void flexinit (argc, argv) break; case OPT_STACK: - //buf_strdefine (&userdef_buf, "YY_STACK_USED", "1"); - buf_m4_define( &m4defs_buf, "M4_YY_STACK_USED",0); + buf_m4_define( &m4defs_buf, "M4_YY_STACK_USED",0); break; case OPT_STDINIT: @@ -1332,99 +1108,92 @@ void flexinit (argc, argv) reject_really_used = false; break; - case OPT_NO_ANSI_FUNC_DEFS: - ansi_func_defs = false; - break; + case OPT_NO_ANSI_FUNC_DEFS: + warn (_("%option noansi-definitions is obsolete")); + break; - case OPT_NO_ANSI_FUNC_PROTOS: - ansi_func_protos = false; - break; + case OPT_NO_ANSI_FUNC_PROTOS: + warn (_("%option noansi-prototypes is obsolete")); + break; case OPT_NO_YY_PUSH_STATE: - //buf_strdefine (&userdef_buf, "YY_NO_PUSH_STATE", "1"); - buf_m4_define( &m4defs_buf, "M4_YY_NO_PUSH_STATE",0); + buf_m4_define( &m4defs_buf, "M4_YY_NO_PUSH_STATE",0); break; case OPT_NO_YY_POP_STATE: - //buf_strdefine (&userdef_buf, "YY_NO_POP_STATE", "1"); - buf_m4_define( &m4defs_buf, "M4_YY_NO_POP_STATE",0); + buf_m4_define( &m4defs_buf, "M4_YY_NO_POP_STATE",0); break; case OPT_NO_YY_TOP_STATE: - //buf_strdefine (&userdef_buf, "YY_NO_TOP_STATE", "1"); - buf_m4_define( &m4defs_buf, "M4_YY_NO_TOP_STATE",0); + buf_m4_define( &m4defs_buf, "M4_YY_NO_TOP_STATE",0); break; case OPT_NO_UNPUT: - //buf_strdefine (&userdef_buf, "YY_NO_UNPUT", "1"); - buf_m4_define( &m4defs_buf, "M4_YY_NO_UNPUT",0); + buf_m4_define( &m4defs_buf, "M4_YY_NO_UNPUT",0); break; case OPT_NO_YY_SCAN_BUFFER: - //buf_strdefine (&userdef_buf, "YY_NO_SCAN_BUFFER", "1"); - buf_m4_define( &m4defs_buf, "M4_YY_NO_SCAN_BUFFER",0); + buf_m4_define( &m4defs_buf, "M4_YY_NO_SCAN_BUFFER",0); break; case OPT_NO_YY_SCAN_BYTES: - //buf_strdefine (&userdef_buf, "YY_NO_SCAN_BYTES", "1"); - buf_m4_define( &m4defs_buf, "M4_YY_NO_SCAN_BYTES",0); + buf_m4_define( &m4defs_buf, "M4_YY_NO_SCAN_BYTES",0); break; case OPT_NO_YY_SCAN_STRING: - //buf_strdefine (&userdef_buf, "YY_NO_SCAN_STRING", "1"); - buf_m4_define( &m4defs_buf, "M4_YY_NO_SCAN_STRING",0); + buf_m4_define( &m4defs_buf, "M4_YY_NO_SCAN_STRING",0); break; case OPT_NO_YYGET_EXTRA: - //buf_strdefine (&userdef_buf, "YY_NO_GET_EXTRA", "1"); - buf_m4_define( &m4defs_buf, "M4_YY_NO_GET_EXTRA",0); + buf_m4_define( &m4defs_buf, "M4_YY_NO_GET_EXTRA",0); break; case OPT_NO_YYSET_EXTRA: - //buf_strdefine (&userdef_buf, "YY_NO_SET_EXTRA", "1"); - buf_m4_define( &m4defs_buf, "M4_YY_NO_SET_EXTRA",0); + buf_m4_define( &m4defs_buf, "M4_YY_NO_SET_EXTRA",0); break; case OPT_NO_YYGET_LENG: - //buf_strdefine (&userdef_buf, "YY_NO_GET_LENG", "1"); - buf_m4_define( &m4defs_buf, "M4_YY_NO_GET_LENG",0); + buf_m4_define( &m4defs_buf, "M4_YY_NO_GET_LENG",0); break; case OPT_NO_YYGET_TEXT: - //buf_strdefine (&userdef_buf, "YY_NO_GET_TEXT", "1"); - buf_m4_define( &m4defs_buf, "M4_YY_NO_GET_TEXT",0); + buf_m4_define( &m4defs_buf, "M4_YY_NO_GET_TEXT",0); break; case OPT_NO_YYGET_LINENO: - //buf_strdefine (&userdef_buf, "YY_NO_GET_LINENO", "1"); - buf_m4_define( &m4defs_buf, "M4_YY_NO_GET_LINENO",0); + buf_m4_define( &m4defs_buf, "M4_YY_NO_GET_LINENO",0); break; case OPT_NO_YYSET_LINENO: - //buf_strdefine (&userdef_buf, "YY_NO_SET_LINENO", "1"); - buf_m4_define( &m4defs_buf, "M4_YY_NO_SET_LINENO",0); + buf_m4_define( &m4defs_buf, "M4_YY_NO_SET_LINENO",0); break; case OPT_NO_YYGET_IN: - //buf_strdefine (&userdef_buf, "YY_NO_GET_IN", "1"); - buf_m4_define( &m4defs_buf, "M4_YY_NO_GET_IN",0); + buf_m4_define( &m4defs_buf, "M4_YY_NO_GET_IN",0); break; case OPT_NO_YYSET_IN: - //buf_strdefine (&userdef_buf, "YY_NO_SET_IN", "1"); - buf_m4_define( &m4defs_buf, "M4_YY_NO_SET_IN",0); + buf_m4_define( &m4defs_buf, "M4_YY_NO_SET_IN",0); break; case OPT_NO_YYGET_OUT: - //buf_strdefine (&userdef_buf, "YY_NO_GET_OUT", "1"); - buf_m4_define( &m4defs_buf, "M4_YY_NO_GET_OUT",0); + buf_m4_define( &m4defs_buf, "M4_YY_NO_GET_OUT",0); break; case OPT_NO_YYSET_OUT: - //buf_strdefine (&userdef_buf, "YY_NO_SET_OUT", "1"); - buf_m4_define( &m4defs_buf, "M4_YY_NO_SET_OUT",0); + buf_m4_define( &m4defs_buf, "M4_YY_NO_SET_OUT",0); break; case OPT_NO_YYGET_LVAL: - //buf_strdefine (&userdef_buf, "YY_NO_GET_LVAL", "1"); - buf_m4_define( &m4defs_buf, "M4_YY_NO_GET_LVAL",0); + buf_m4_define( &m4defs_buf, "M4_YY_NO_GET_LVAL",0); break; case OPT_NO_YYSET_LVAL: - //buf_strdefine (&userdef_buf, "YY_NO_SET_LVAL", "1"); - buf_m4_define( &m4defs_buf, "M4_YY_NO_SET_LVAL",0); + buf_m4_define( &m4defs_buf, "M4_YY_NO_SET_LVAL",0); break; case OPT_NO_YYGET_LLOC: - //buf_strdefine (&userdef_buf, "YY_NO_GET_LLOC", "1"); - buf_m4_define( &m4defs_buf, "M4_YY_NO_GET_LLOC",0); + buf_m4_define( &m4defs_buf, "M4_YY_NO_GET_LLOC",0); break; case OPT_NO_YYSET_LLOC: - //buf_strdefine (&userdef_buf, "YY_NO_SET_LLOC", "1"); - buf_m4_define( &m4defs_buf, "M4_YY_NO_SET_LLOC",0); + buf_m4_define( &m4defs_buf, "M4_YY_NO_SET_LLOC",0); break; - + case OPT_OPTION_LIST: + { + struct yy_buffer_state *buf; + size_t len = strlen(arg)+12; + char *options = (char*)malloc(len); + parsing_option_string = true; + snprintf(options,len,"%%option %s\n%c%c",arg,0,0); + buf = yy_scan_buffer(options,len); + yyparse (); + if (syntaxerror) flexend(1); + free(options); + yylex_destroy(); + parsing_option_string = false; + break; + } } /* switch */ } /* while scanopt() */ @@ -1456,14 +1225,10 @@ void flexinit (argc, argv) /* readin - read in the rules section of the input file(s) */ +/* Also set most M4 flags not done in check_options(). */ -void readin () +void readin (void) { - static char yy_stdinit[] = "FILE *yyin = stdin, *yyout = stdout;"; - static char yy_nostdinit[] = - "FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;"; - - line_directive_out ((FILE *) 0, 1); if (yyparse ()) { pinpoint_message (_("fatal parse error")); @@ -1497,61 +1262,49 @@ void readin () if (backing_up_report) { backing_up_file = fopen (backing_name, "w"); if (backing_up_file == NULL) - lerrsf (_ - ("could not create backing-up info file %s"), + lerrsf (_("could not create backing-up info file %s"), backing_name); } else backing_up_file = NULL; - if (yymore_really_used == true) - yymore_used = true; - else if (yymore_really_used == false) - yymore_used = false; + if (reject_really_used != unspecified) + reject = reject_really_used; - if (reject_really_used == true) - reject = true; - else if (reject_really_used == false) - reject = false; + if (yymore_really_used != unspecified) + yymore_used = yymore_really_used; if (performance_report > 0) { if (lex_compat) { fprintf (stderr, - _ - ("-l AT&T lex compatibility option entails a large performance penalty\n")); + _("-l AT&T lex compatibility option entails a large performance penalty\n")); fprintf (stderr, - _ - (" and may be the actual source of other reported performance penalties\n")); + _(" and may be the actual source of other reported performance penalties\n")); } else if (do_yylineno) { fprintf (stderr, - _ - ("%%option yylineno entails a performance penalty ONLY on rules that can match newline characters\n")); + _("%%option yylineno entails a performance penalty ONLY on rules that can match newline characters\n")); } if (performance_report > 1) { if (interactive) fprintf (stderr, - _ - ("-I (interactive) entails a minor performance penalty\n")); + _("-I (interactive) entails a minor performance penalty\n")); if (yymore_used) fprintf (stderr, - _ - ("yymore() entails a minor performance penalty\n")); + _("yymore() entails a minor performance penalty\n")); } if (reject) fprintf (stderr, - _ - ("REJECT entails a large performance penalty\n")); + _("REJECT entails a large performance penalty\n")); if (variable_trailing_context_rules) fprintf (stderr, - _ - ("Variable trailing context rules entail a large performance penalty\n")); + _("Variable trailing context rules entail a large performance penalty\n")); } if (reject) @@ -1562,137 +1315,12 @@ void readin () if ((fulltbl || fullspd) && reject) { if (real_reject) - flexerror (_ - ("REJECT cannot be used with -f or -F")); + flexerror (_("REJECT cannot be used with -f or -F")); else if (do_yylineno) - flexerror (_ - ("%option yylineno cannot be used with REJECT")); + flexerror (_("%option yylineno cannot be used with REJECT")); else - flexerror (_ - ("variable trailing context rules cannot be used with -f or -F")); - } - - if (reject){ - out_m4_define( "M4_YY_USES_REJECT", NULL); - //outn ("\n#define YY_USES_REJECT"); - } - if (!do_yywrap) { - if (!C_plus_plus) - if (reentrant) - outn ("\n#define yywrap(yyscanner) 1"); - else - outn ("\n#define yywrap() 1"); - outn ("#define YY_SKIP_YYWRAP"); - } - - if (ddebug) - outn ("\n#define FLEX_DEBUG"); - - OUT_BEGIN_CODE (); - if (csize == 256) - outn ("typedef unsigned char YY_CHAR;"); - else - outn ("typedef char YY_CHAR;"); - OUT_END_CODE (); - - if (C_plus_plus) { - outn ("#define yytext_ptr yytext"); - - if (interactive) - outn ("#define YY_INTERACTIVE"); - } - - else { - OUT_BEGIN_CODE (); - /* In reentrant scanner, stdinit is handled in flex.skl. */ - if (do_stdinit) { - if (reentrant){ - outn ("#ifdef VMS"); - outn ("#ifdef __VMS_POSIX"); - outn ("#define YY_STDINIT"); - outn ("#endif"); - outn ("#else"); - outn ("#define YY_STDINIT"); - outn ("#endif"); - } - - outn ("#ifdef VMS"); - outn ("#ifndef __VMS_POSIX"); - outn (yy_nostdinit); - outn ("#else"); - outn (yy_stdinit); - outn ("#endif"); - outn ("#else"); - outn (yy_stdinit); - outn ("#endif"); - } - - else { - if(!reentrant) - outn (yy_nostdinit); - } - OUT_END_CODE (); - } - - OUT_BEGIN_CODE (); - if (fullspd) - outn ("typedef yyconst struct yy_trans_info *yy_state_type;"); - else if (!C_plus_plus) - outn ("typedef int yy_state_type;"); - OUT_END_CODE (); - - if (lex_compat) - outn ("#define YY_FLEX_LEX_COMPAT"); - - if (!C_plus_plus && !reentrant) { - outn ("extern int yylineno;"); - OUT_BEGIN_CODE (); - outn ("int yylineno = 1;"); - OUT_END_CODE (); - } - - if (C_plus_plus) { - outn ("\n#include "); - - if (!do_yywrap) { - outn("\nint yyFlexLexer::yywrap() { return 1; }"); - } - - if (yyclass) { - outn ("int yyFlexLexer::yylex()"); - outn ("\t{"); - outn ("\tLexerError( \"yyFlexLexer::yylex invoked but %option yyclass used\" );"); - outn ("\treturn 0;"); - outn ("\t}"); - - out_str ("\n#define YY_DECL int %s::yylex()\n", - yyclass); - } - } - - else { - - /* Watch out: yytext_ptr is a variable when yytext is an array, - * but it's a macro when yytext is a pointer. - */ - if (yytext_is_array) { - if (!reentrant) - outn ("extern char yytext[];\n"); - } - else { - if (reentrant) { - outn ("#define yytext_ptr yytext_r"); - } - else { - outn ("extern char *yytext;"); - outn ("#define yytext_ptr yytext"); - } - } - - if (yyclass) - flexerror (_ - ("%option yyclass only meaningful for C++ scanners")); + flexerror (_("variable trailing context rules cannot be used with -f or -F")); } if (useecs) @@ -1711,7 +1339,7 @@ void readin () /* set_up_initial_allocations - allocate memory for internal tables */ -void set_up_initial_allocations () +void set_up_initial_allocations (void) { maximum_mns = (long_align ? MAXIMUM_MNS_LONG : MAXIMUM_MNS); current_mns = INITIAL_MNS; @@ -1771,9 +1399,7 @@ void set_up_initial_allocations () /* extracts basename from path, optionally stripping the extension "\.*" * (same concept as /bin/sh `basename`, but different handling of extension). */ -static char *basename2 (path, strip_ext) - char *path; - int strip_ext; /* boolean */ +static char *basename2 (char *path, int strip_ext /* boolean */) { char *b, *e = 0; @@ -1789,21 +1415,22 @@ static char *basename2 (path, strip_ext) return b; } -void usage () +void usage (void) { FILE *f = stdout; - if (!did_outfilename) { + if (!outfilename) { snprintf (outfile_path, sizeof(outfile_path), outfile_template, prefix, C_plus_plus ? "cc" : "c"); outfilename = outfile_path; } - fprintf (f, _("Usage: %s [OPTIONS] [FILE]...\n"), program_name); - fprintf (f, - _ - ("Generates programs that perform pattern-matching on text.\n" - "\n" "Table Compression:\n" + fprintf (f,_("Usage: %s [OPTIONS] [FILE]...\n"), program_name); + fprintf (f,_( + "Generates programs that perform pattern-matching on text.\n" + "\n")); + fprintf (f,_( + "Table Compression:\n" " -Ca, --align trade off larger tables for better memory alignment\n" " -Ce, --ecs construct equivalence classes\n" " -Cf do not compress tables; use -f representation\n" @@ -1813,7 +1440,9 @@ void usage () " -f, --full generate fast, large scanner. Same as -Cfr\n" " -F, --fast use alternate table representation. Same as -CFr\n" " -Cem default compression (same as --ecs --meta-ecs)\n" - "\n" "Debugging:\n" + "\n")); + fprintf (f,_( + "Debugging:\n" " -d, --debug enable debug mode in scanner\n" " -b, --backup write backing-up information to %s\n" " -p, --perf-report write performance report to stderr\n" @@ -1821,13 +1450,20 @@ void usage () " -T, --trace %s should run in trace mode\n" " -w, --nowarn do not generate warnings\n" " -v, --verbose write summary of scanner statistics to stdout\n" - "\n" "Files:\n" + " -n not verbose (default; opposite of --verbose)\n" + "\n"), + backing_name, program_name); + fprintf (f,_( + "Files:\n" " -o, --outfile=FILE specify output filename\n" " -S, --skel=FILE specify skeleton file\n" " -t, --stdout write scanner on stdout instead of %s\n" " --yyclass=NAME name of C++ class\n" " --header-file=FILE create a C header file in addition to the scanner\n" - " --tables-file[=FILE] write tables to FILE\n" "\n" + " --tables-file[=FILE] write tables to FILE\n" + "\n"), + outfile_path); + fprintf (f,_( "Scanner behavior:\n" " -7, --7bit generate 7-bit scanner\n" " -8, --8bit generate 8-bit scanner\n" @@ -1837,8 +1473,11 @@ void usage () " -X, --posix-compat maximal compatibility with POSIX lex\n" " -I, --interactive generate interactive scanner (opposite of -B)\n" " --yylineno track line count in yylineno\n" - "\n" "Generated code:\n" + "\n")); + fprintf (f,_( + "Generated code:\n" " -+, --c++ generate C++ scanner class\n" + " -c generate output in C (the default)\n" " -Dmacro[=defn] #define macro defn (default defn is '1')\n" " -L, --noline suppress #line directives in scanner\n" " -P, --prefix=STRING use STRING as prefix instead of \"yy\"\n" @@ -1846,16 +1485,13 @@ void usage () " --bison-bridge scanner for bison pure parser.\n" " --bison-locations include yylloc support.\n" " --stdinit initialize yyin/yyout to stdin/stdout\n" - " --noansi-definitions old-style function definitions\n" - " --noansi-prototypes empty parameter list in prototypes\n" " --nounistd do not include \n" " --noFUNCTION do not generate a particular FUNCTION\n" - "\n" "Miscellaneous:\n" - " -c do-nothing POSIX option\n" - " -n do-nothing POSIX option\n" + "\n")); + fprintf (f,_("Miscellaneous:\n" " -?\n" " -h, --help produce this help message\n" " -V, --version report %s version\n"), - backing_name, program_name, outfile_path, program_name); + program_name); } diff --git a/misc.c b/misc.c index e3fdd50..343dd55 100644 --- a/misc.c +++ b/misc.c @@ -34,65 +34,10 @@ #include "flexdef.h" #include "tables.h" -#define CMD_IF_TABLES_SER "%if-tables-serialization" -#define CMD_TABLES_YYDMAP "%tables-yydmap" -#define CMD_DEFINE_YYTABLES "%define-yytables" -#define CMD_IF_CPP_ONLY "%if-c++-only" -#define CMD_IF_C_ONLY "%if-c-only" -#define CMD_IF_C_OR_CPP "%if-c-or-c++" -#define CMD_NOT_FOR_HEADER "%not-for-header" -#define CMD_OK_FOR_HEADER "%ok-for-header" -#define CMD_PUSH "%push" -#define CMD_POP "%pop" -#define CMD_IF_REENTRANT "%if-reentrant" -#define CMD_IF_NOT_REENTRANT "%if-not-reentrant" -#define CMD_IF_BISON_BRIDGE "%if-bison-bridge" -#define CMD_IF_NOT_BISON_BRIDGE "%if-not-bison-bridge" -#define CMD_ENDIF "%endif" - -/* we allow the skeleton to push and pop. */ -struct sko_state { - bool dc; /**< do_copy */ -}; -static struct sko_state *sko_stack=0; -static int sko_len=0,sko_sz=0; -static void sko_push(bool dc) -{ - if(!sko_stack){ - sko_sz = 1; - sko_stack = (struct sko_state*)flex_alloc(sizeof(struct sko_state)*sko_sz); - if (!sko_stack) - flexfatal(_("allocation of sko_stack failed")); - sko_len = 0; - } - if(sko_len >= sko_sz){ - sko_sz *= 2; - sko_stack = (struct sko_state*)flex_realloc(sko_stack,sizeof(struct sko_state)*sko_sz); - } - - /* initialize to zero and push */ - sko_stack[sko_len].dc = dc; - sko_len++; -} -static void sko_peek(bool *dc) -{ - if(sko_len <= 0) - flex_die("peek attempt when sko stack is empty"); - if(dc) - *dc = sko_stack[sko_len-1].dc; -} -static void sko_pop(bool* dc) -{ - sko_peek(dc); - sko_len--; - if(sko_len < 0) - flex_die("popped too many times in skeleton."); -} - /* Append "#define defname value\n" to the running buffer. */ -void action_define (defname, value) - const char *defname; - int value; +void action_define ( + const char *defname, + int value) { char buf[MAXLINE]; char *cpy; @@ -113,30 +58,8 @@ void action_define (defname, value) } -/** Append "m4_define([[defname]],[[value]])m4_dnl\n" to the running buffer. - * @param defname The macro name. - * @param value The macro value, can be NULL, which is the same as the empty string. - */ -void action_m4_define (const char *defname, const char * value) -{ - char buf[MAXLINE]; - - flexfatal ("DO NOT USE THIS FUNCTION!"); - - if ((int) strlen (defname) > MAXLINE / 2) { - format_pinpoint_message (_ - ("name \"%s\" ridiculously long"), - defname); - return; - } - - snprintf (buf, sizeof(buf), "m4_define([[%s]],[[%s]])m4_dnl\n", defname, value?value:""); - add_action (buf); -} - /* Append "new_text" to the running buffer. */ -void add_action (new_text) - const char *new_text; +void add_action (const char *new_text) { int len = strlen (new_text); @@ -164,9 +87,9 @@ void add_action (new_text) /* allocate_array - allocate memory for an integer array of the given size */ -void *allocate_array (size, element_size) - int size; - size_t element_size; +void *allocate_array ( + int size, + size_t element_size) { register void *mem; size_t num_bytes = element_size * size; @@ -182,8 +105,7 @@ void *allocate_array (size, element_size) /* all_lower - true if a string is all lower-case */ -int all_lower (str) - register char *str; +int all_lower (register char *str) { while (*str) { if (!isascii ((Char) * str) || !islower ((Char) * str)) @@ -197,8 +119,7 @@ int all_lower (str) /* all_upper - true if a string is all upper-case */ -int all_upper (str) - register char *str; +int all_upper (register char *str) { while (*str) { if (!isascii ((Char) * str) || !isupper ((Char) * str)) @@ -223,8 +144,7 @@ int intcmp (const void *a, const void *b) * and exits. */ -void check_char (c) - int c; +void check_char (int c) { if (c >= CSIZE) lerrsf (_("bad character '%s' detected in check_char()"), @@ -237,20 +157,9 @@ void check_char (c) } - -/* clower - replace upper-case letter to lower-case */ - -Char clower (c) - register int c; -{ - return (Char) ((isascii (c) && isupper (c)) ? tolower (c) : c); -} - - /* copy_string - returns a dynamically allocated copy of a string */ -char *copy_string (str) - register const char *str; +char *copy_string (register const char *str) { register const char *c1; register char *c2; @@ -277,8 +186,7 @@ char *copy_string (str) * returns a dynamically allocated copy of a (potentially) unsigned string */ -Char *copy_unsigned_string (str) - register Char *str; +Char *copy_unsigned_string (register Char *str) { register Char *c; Char *copy; @@ -310,7 +218,7 @@ int cclcmp (const void *a, const void *b) /* dataend - finish up a block of data declarations */ -void dataend () +void dataend (void) { /* short circuit any output */ if (gentables) { @@ -318,8 +226,8 @@ void dataend () if (datapos > 0) dataflush (); - /* add terminator for initialization; { for vi */ - outn (" } ;\n"); + /* add terminator for m4_define */ + outn ("]])\n"); } dataline = 0; datapos = 0; @@ -328,7 +236,7 @@ void dataend () /* dataflush - flush generated data statements */ -void dataflush () +void dataflush (void) { /* short circuit any output */ if (!gentables) @@ -351,8 +259,7 @@ void dataflush () /* flexerror - report an error message and terminate */ -void flexerror (msg) - const char *msg; +void flexerror (const char *msg) { fprintf (stderr, "%s: %s\n", program_name, msg); flexend (1); @@ -361,8 +268,7 @@ void flexerror (msg) /* flexfatal - report a fatal error message and terminate */ -void flexfatal (msg) - const char *msg; +void flexfatal (const char *msg) { fprintf (stderr, _("%s: fatal internal error, %s\n"), program_name, msg); @@ -372,8 +278,7 @@ void flexfatal (msg) /* htoi - convert a hexadecimal digit string to an integer value */ -int htoi (str) - Char str[]; +int htoi (Char str[]) { unsigned int result; @@ -385,9 +290,7 @@ int htoi (str) /* lerrif - report an error message formatted with one integer argument */ -void lerrif (msg, arg) - const char *msg; - int arg; +void lerrif (const char *msg, int arg) { char errmsg[MAXLINE]; @@ -398,8 +301,7 @@ void lerrif (msg, arg) /* lerrsf - report an error message formatted with one string argument */ -void lerrsf (msg, arg) - const char *msg, arg[]; +void lerrsf (const char *msg, const char arg[]) { char errmsg[MAXLINE]; @@ -424,18 +326,19 @@ void lerrsf_fatal (msg, arg) /* line_directive_out - spit out a "#line" statement */ -void line_directive_out (output_file, do_infile) - FILE *output_file; - int do_infile; +void line_directive_out ( + FILE *output_file, + int do_infile) { char directive[MAXLINE], filename[MAXLINE]; - char *s1, *s2, *s3; + const char *s1; + char *s2, *s3; static const char *line_fmt = "#line %d \"%s\"\n"; if (!gen_line_dirs) return; - s1 = do_infile ? infilename : "M4_YY_OUTFILE_NAME"; + s1 = do_infile ? infilename : outfilename; if (do_infile && !s1) s1 = ""; @@ -474,7 +377,7 @@ void line_directive_out (output_file, do_infile) * representing where the user's section 1 definitions end * and the prolog begins */ -void mark_defs1 () +void mark_defs1 (void) { defs1_offset = 0; action_array[action_index++] = '\0'; @@ -486,7 +389,7 @@ void mark_defs1 () /* mark_prolog - mark the current position in the action array as * representing the end of the action prolog */ -void mark_prolog () +void mark_prolog (void) { action_array[action_index++] = '\0'; action_offset = action_index; @@ -498,8 +401,7 @@ void mark_prolog () * * Generates a data statement initializing the current 2-D array to "value". */ -void mk2data (value) - int value; +void mk2data (int value) { /* short circuit any output */ if (!gentables) @@ -528,8 +430,7 @@ void mk2data (value) * Generates a data statement initializing the current array element to * "value". */ -void mkdata (value) - int value; +void mkdata (int value) { /* short circuit any output */ if (!gentables) @@ -554,8 +455,7 @@ void mkdata (value) /* myctoi - return the integer represented by a string of digits */ -int myctoi (array) - const char *array; +int myctoi (const char *array) { int val = 0; @@ -567,8 +467,7 @@ int myctoi (array) /* myesc - return character corresponding to escape sequence */ -Char myesc (array) - Char array[]; +Char myesc (Char array[]) { Char c, esc_char; @@ -655,8 +554,7 @@ Char myesc (array) /* otoi - convert an octal digit string to an integer value */ -int otoi (str) - Char str[]; +int otoi (Char str[]) { unsigned int result; @@ -669,60 +567,58 @@ int otoi (str) * generated scanner, keeping track of the line count. */ -void out (str) - const char *str; +void out (const char *str) { fputs (str, stdout); } -void out_dec (fmt, n) - const char *fmt; - int n; +void out_dec (const char *fmt, int n) { fprintf (stdout, fmt, n); } -void out_dec2 (fmt, n1, n2) - const char *fmt; - int n1, n2; +void out_dec2 (const char *fmt, int n1, int n2) { fprintf (stdout, fmt, n1, n2); } -void out_hex (fmt, x) - const char *fmt; - unsigned int x; +void out_hex (const char *fmt, unsigned int x) { fprintf (stdout, fmt, x); + out_line_count (fmt); +} + +void out_line_count (const char *str) +{ + register int i; + + for (i = 0; str[i]; ++i) + if (str[i] == '\n') + ++out_linenum; } -void out_str (fmt, str) - const char *fmt, str[]; +void out_str (const char *fmt, const char str[]) { fprintf (stdout,fmt, str); } -void out_str3 (fmt, s1, s2, s3) - const char *fmt, s1[], s2[], s3[]; +void out_str3 (const char *fmt, const char s1[], + const char s2[], const char s3[]) { fprintf (stdout,fmt, s1, s2, s3); } -void out_str_dec (fmt, str, n) - const char *fmt, str[]; - int n; +void out_str_dec (const char *fmt, const char str[], int n) { fprintf (stdout,fmt, str, n); } -void outc (c) - int c; +void outc (int c) { fputc (c, stdout); } -void outn (str) - const char *str; +void outn (const char *str) { fputs (str,stdout); fputc('\n',stdout); @@ -730,13 +626,13 @@ void outn (str) /** Print "m4_define( [[def]], [[val]])m4_dnl\n". * @param def The m4 symbol to define. - * @param val The definition; may be NULL. + * @param val The definition; may be NULL. If so, val="1". * @return buf */ void out_m4_define (const char* def, const char* val) { const char * fmt = "m4_define( [[%s]], [[%s]])m4_dnl\n"; - fprintf(stdout, fmt, def, val?val:""); + fprintf(stdout, fmt, def, val?val:"1"); } @@ -745,8 +641,7 @@ void out_m4_define (const char* def, const char* val) * The returned string is in static storage. */ -char *readable_form (c) - register int c; +char *readable_form (register int c) { static char rform[10]; @@ -790,10 +685,10 @@ char *readable_form (c) /* reallocate_array - increase the size of a dynamic array */ -void *reallocate_array (array, size, element_size) - void *array; - int size; - size_t element_size; +void *reallocate_array ( + void *array, + int size, + size_t element_size) { register void *new_array; size_t num_bytes = element_size * size; @@ -809,131 +704,20 @@ void *reallocate_array (array, size, element_size) /* skelout - write out one section of the skeleton file * * Description - * Copies skelfile or skel array to stdout until a line beginning with + * Copies skelfile to stdout until a line beginning with * "%%" or EOF is found. */ -void skelout () +void skelout (void) { char buf_storage[MAXLINE]; char *buf = buf_storage; - bool do_copy = true; - - /* "reset" the state by clearing the buffer and pushing a '1' */ - if(sko_len > 0) - sko_peek(&do_copy); - sko_len = 0; - sko_push(do_copy=true); - - /* Loop pulling lines either from the skelfile, if we're using - * one, or from the skel[] array. - */ - while (skelfile ? - (fgets (buf, MAXLINE, skelfile) != NULL) : - ((buf = (char *) skel[skel_ind++]) != 0)) { - - if (skelfile) - chomp (buf); - - /* copy from skel array */ - if (buf[0] == '%') { /* control line */ - /* print the control line as a comment. */ - if (ddebug && buf[1] != '#') { - if (buf[strlen (buf) - 1] == '\\') - out_str ("/* %s */\\\n", buf); - else - out_str ("/* %s */\n", buf); - } - - /* We've been accused of using cryptic markers in the skel. - * So we'll use emacs-style-hyphenated-commands. - * We might consider a hash if this if-else-if-else - * chain gets too large. - */ -#define cmd_match(s) (strncmp(buf,(s),strlen(s))==0) - - if (buf[1] == '%') { - /* %% is a break point for skelout() */ - return; - } - else if (cmd_match (CMD_PUSH)){ - sko_push(do_copy); - if(ddebug){ - out_str("/*(state = (%s) */",do_copy?"true":"false"); - } - out_str("%s\n", buf[strlen (buf) - 1] =='\\' ? "\\" : ""); - } - else if (cmd_match (CMD_POP)){ - sko_pop(&do_copy); - if(ddebug){ - out_str("/*(state = (%s) */",do_copy?"true":"false"); - } - out_str("%s\n", buf[strlen (buf) - 1] =='\\' ? "\\" : ""); - } - else if (cmd_match (CMD_IF_REENTRANT)){ - sko_push(do_copy); - do_copy = reentrant && do_copy; - } - else if (cmd_match (CMD_IF_NOT_REENTRANT)){ - sko_push(do_copy); - do_copy = !reentrant && do_copy; - } - else if (cmd_match(CMD_IF_BISON_BRIDGE)){ - sko_push(do_copy); - do_copy = bison_bridge_lval && do_copy; - } - else if (cmd_match(CMD_IF_NOT_BISON_BRIDGE)){ - sko_push(do_copy); - do_copy = !bison_bridge_lval && do_copy; - } - else if (cmd_match (CMD_ENDIF)){ - sko_pop(&do_copy); - } - else if (cmd_match (CMD_IF_TABLES_SER)) { - do_copy = do_copy && tablesext; - } - else if (cmd_match (CMD_TABLES_YYDMAP)) { - if (tablesext && yydmap_buf.elts) - outn ((char *) (yydmap_buf.elts)); - } - else if (cmd_match (CMD_DEFINE_YYTABLES)) { - out_str("#define YYTABLES_NAME \"%s\"\n", - tablesname?tablesname:"yytables"); - } - else if (cmd_match (CMD_IF_CPP_ONLY)) { - /* only for C++ */ - sko_push(do_copy); - do_copy = C_plus_plus; - } - else if (cmd_match (CMD_IF_C_ONLY)) { - /* %- only for C */ - sko_push(do_copy); - do_copy = !C_plus_plus; - } - else if (cmd_match (CMD_IF_C_OR_CPP)) { - /* %* for C and C++ */ - sko_push(do_copy); - do_copy = true; - } - else if (cmd_match (CMD_NOT_FOR_HEADER)) { - /* %c begin linkage-only (non-header) code. */ - OUT_BEGIN_CODE (); - } - else if (cmd_match (CMD_OK_FOR_HEADER)) { - /* %e end linkage-only code. */ - OUT_END_CODE (); - } - else if (buf[1] == '#') { - /* %# a comment in the skel. ignore. */ - } - else { - flexfatal (_("bad line in skeleton file")); - } - } - - else if (do_copy) - outn (buf); - } /* end while */ + /* Loop pulling lines from the skelfile */ + while ((fgets (buf, MAXLINE, skelfile) != NULL)) { + chomp (buf); + if (buf[0] == '%' && buf[1] == '%') break; + outn (buf); + } } @@ -943,8 +727,7 @@ void skelout () * element_n. Formats the output with spaces and carriage returns. */ -void transition_struct_out (element_v, element_n) - int element_v, element_n; +void transition_struct_out (int element_v, int element_n) { /* short circuit any output */ @@ -969,8 +752,7 @@ void transition_struct_out (element_v, element_n) /* The following is only needed when building flex's parser using certain * broken versions of bison. */ -void *yy_flex_xmalloc (size) - int size; +void *yy_flex_xmalloc (int size) { void *result = flex_alloc ((size_t) size); @@ -987,9 +769,7 @@ void *yy_flex_xmalloc (size) * Sets region_ptr[0] through region_ptr[size_in_bytes - 1] to zero. */ -void zero_out (region_ptr, size_in_bytes) - char *region_ptr; - size_t size_in_bytes; +void zero_out (char *region_ptr, size_t size_in_bytes) { register char *rp, *rp_end; @@ -1003,8 +783,7 @@ void zero_out (region_ptr, size_in_bytes) /* Remove all '\n' and '\r' characters, if any, from the end of str. * str can be any null-terminated string, or NULL. * returns str. */ -char *chomp (str) - char *str; +char *chomp (char *str) { char *p = str; diff --git a/nfa.c b/nfa.c index dbd1557..4651215 100644 --- a/nfa.c +++ b/nfa.c @@ -36,8 +36,8 @@ /* declare functions that have forward references */ -int dupmachine PROTO ((int)); -void mkxtion PROTO ((int, int)); +int dupmachine (int); +void mkxtion (int, int); /* add_accept - add an accepting state to a machine @@ -45,8 +45,7 @@ void mkxtion PROTO ((int, int)); * accepting_number becomes mach's accepting number. */ -void add_accept (mach, accepting_number) - int mach, accepting_number; +void add_accept (int mach, int accepting_number) { /* Hang the accepting number off an epsilon state. if it is associated * with a state that has a non-epsilon out-transition, then the state @@ -77,8 +76,7 @@ void add_accept (mach, accepting_number) * num - the number of copies of singl to be present in newsng */ -int copysingl (singl, num) - int singl, num; +int copysingl (int singl, int num) { int copy, i; @@ -93,9 +91,7 @@ int copysingl (singl, num) /* dumpnfa - debugging routine to write out an nfa */ -void dumpnfa (state1) - int state1; - +void dumpnfa (int state1) { int sym, tsp1, tsp2, anum, ns; @@ -148,8 +144,7 @@ void dumpnfa (state1) * states accessible by the arrays firstst and lastst */ -int dupmachine (mach) - int mach; +int dupmachine (int mach) { int i, init, state_offset; int state = 0; @@ -196,9 +191,8 @@ int dupmachine (mach) * context has variable length. */ -void finish_rule (mach, variable_trail_rule, headcnt, trailcnt, - pcont_act) - int mach, variable_trail_rule, headcnt, trailcnt, pcont_act; +void finish_rule (int mach, int variable_trail_rule, int headcnt, int trailcnt, + int pcont_act) { char action_text[MAXLINE]; @@ -250,11 +244,11 @@ void finish_rule (mach, variable_trail_rule, headcnt, trailcnt, /* Do trailing context magic to not match the trailing * characters. */ - char *scanner_cp = "YY_G(yy_c_buf_p) = yy_cp"; + char *scanner_cp = "yy_c_buf_p = yy_cp"; char *scanner_bp = "yy_bp"; add_action - ("*yy_cp = YY_G(yy_hold_char); /* undo effects of setting up yytext */\n"); + ("*yy_cp = yy_hold_char; /* undo effects of setting up yytext */\n"); if (headcnt > 0) { snprintf (action_text, sizeof(action_text), "%s = %s + %d;\n", @@ -301,8 +295,7 @@ void finish_rule (mach, variable_trail_rule, headcnt, trailcnt, * FIRST is set to new by the operation. last is unmolested. */ -int link_machines (first, last) - int first, last; +int link_machines (int first, int last) { if (first == NIL) return last; @@ -328,8 +321,7 @@ int link_machines (first, last) * The "beginning" states are the epsilon closure of the first state */ -void mark_beginning_as_normal (mach) - register int mach; +void mark_beginning_as_normal (register int mach) { switch (state_type[mach]) { case STATE_NORMAL: @@ -370,8 +362,7 @@ void mark_beginning_as_normal (mach) * more mkbranch's. Compare with mkor() */ -int mkbranch (first, second) - int first, second; +int mkbranch (int first, int second) { int eps; @@ -398,8 +389,7 @@ int mkbranch (first, second) * new - a new state which matches the closure of "state" */ -int mkclos (state) - int state; +int mkclos (int state) { return mkopt (mkposcl (state)); } @@ -419,8 +409,7 @@ int mkclos (state) * 2. mach is destroyed by the call */ -int mkopt (mach) - int mach; +int mkopt (int mach) { int eps; @@ -456,8 +445,7 @@ int mkopt (mach) * the number of epsilon states needed */ -int mkor (first, second) - int first, second; +int mkor (int first, int second) { int eps, orend; @@ -512,8 +500,7 @@ int mkor (first, second) * new - a machine matching the positive closure of "state" */ -int mkposcl (state) - int state; +int mkposcl (int state) { int eps; @@ -542,8 +529,7 @@ int mkposcl (state) * if "ub" is INFINITE_REPEAT then "new" matches "lb" or more occurrences of "mach" */ -int mkrep (mach, lb, ub) - int mach, lb, ub; +int mkrep (int mach, int lb, int ub) { int base_mach, tail, copy, i; @@ -589,8 +575,7 @@ int mkrep (mach, lb, ub) * that it admittedly is) */ -int mkstate (sym) - int sym; +int mkstate (int sym) { if (++lastnfa >= current_mns) { if ((current_mns += MNS_INCREMENT) >= maximum_mns) @@ -666,8 +651,7 @@ current_mns); * stateto - the state to which the transition is to be made */ -void mkxtion (statefrom, stateto) - int statefrom, stateto; +void mkxtion (int statefrom, int stateto) { if (trans1[statefrom] == NO_TRANSITION) trans1[statefrom] = stateto; @@ -684,7 +668,7 @@ void mkxtion (statefrom, stateto) /* new_rule - initialize for a new rule */ -void new_rule () +void new_rule (void) { if (++num_rules >= current_max_rules) { ++num_reallocs; diff --git a/options.c b/options.c index c673173..db6ddd6 100644 --- a/options.c +++ b/options.c @@ -93,10 +93,10 @@ optspec_t flexopts[] = { , /* Suppress default rule to ECHO unmatched text. */ {"--default", OPT_DEFAULT, 0} , - {"-c", OPT_DONOTHING, 0} - , /* For POSIX lex compatibility. */ - {"-n", OPT_DONOTHING, 0} - , /* For POSIX lex compatibility. */ + {"-c", OPT_C_SCANNER, 0} + , + {"-n", OPT_NO_VERBOSE, 0} + , {"--ecs", OPT_ECS, 0} , /* Construct equivalence classes. */ {"--noecs", OPT_NO_ECS, 0} @@ -117,6 +117,10 @@ optspec_t flexopts[] = { , {"--help", OPT_HELP, 0} , /* Produce this help message. */ + {"-Y PATH", OPT_INCLUDE_PATH, 0} + , /* Same as --include; Sun's lex uses -Y for this. */ + {"--include=PATH", OPT_INCLUDE_PATH, 0} + , /* Specifiy the include path for skeleton files */ {"-I", OPT_INTERACTIVE, 0} , {"--interactive", OPT_INTERACTIVE, 0} @@ -139,12 +143,16 @@ optspec_t flexopts[] = { , /* use built-in main() function. */ {"--nomain", OPT_NO_MAIN, 0} , + {"--m4outfile=FILE", OPT_M4OUTFILE, 0} + , /* Write intermediate M4 to FILE */ {"--meta-ecs", OPT_META_ECS, 0} , /* Construct meta-equivalence classes. */ {"--nometa-ecs", OPT_NO_META_ECS, 0} , {"--never-interactive", OPT_NEVER_INTERACTIVE, 0} , + {"--options=OPTIONS", OPT_OPTION_LIST, 0} + , {"-o FILE", OPT_OUTFILE, 0} , {"--outfile=FILE", OPT_OUTFILE, 0} @@ -273,7 +281,12 @@ optspec_t flexopts[] = { , {"--noyyset_lloc", OPT_NO_YYSET_LLOC, 0} , - +#if 0 + {"--include-header", OPT_INCLUDE_HEADER, 0} + , + {"--yynamespace=NAME", OPT_YYNAMESPACE, 0} + , +#endif {0, 0, 0} /* required final NULL entry. */ }; diff --git a/options.h b/options.h index 1f3925b..f2d9be1 100644 --- a/options.h +++ b/options.h @@ -52,6 +52,7 @@ enum flexopt_flag_t { OPT_CASE_INSENSITIVE, OPT_COMPRESSION, OPT_CPLUSPLUS, + OPT_C_SCANNER, OPT_DEBUG, OPT_DEFAULT, OPT_DONOTHING, @@ -60,6 +61,7 @@ enum flexopt_flag_t { OPT_FULL, OPT_HEADER_FILE, OPT_HELP, + OPT_INCLUDE_PATH, OPT_INTERACTIVE, OPT_LEX_COMPAT, OPT_POSIX_COMPAT, @@ -79,6 +81,7 @@ enum flexopt_flag_t { OPT_NO_REJECT, OPT_NO_STDINIT, OPT_NO_UNPUT, + OPT_NO_VERBOSE, OPT_NO_WARN, OPT_NO_YYGET_EXTRA, OPT_NO_YYGET_IN, @@ -126,7 +129,15 @@ enum flexopt_flag_t { OPT_YYCLASS, OPT_YYLINENO, OPT_YYMORE, - OPT_YYWRAP + OPT_YYWRAP, +/* JMK */ + OPT_OPTION_LIST, + OPT_M4OUTFILE, +#if 0 + OPT_INCLUDE_HEADER, + OPT_YYNAMESPACE +#endif +/* /JMK */ }; #endif diff --git a/parse.y b/parse.y index bbc738c..c27e783 100644 --- a/parse.y +++ b/parse.y @@ -1,8 +1,9 @@ /* parse.y - parser for flex input */ +%debug %token CHAR NUMBER SECTEND SCDECL XSCDECL NAME PREVCCL EOF_OP %token OPTION_OP OPT_OUTFILE OPT_PREFIX OPT_YYCLASS OPT_HEADER OPT_EXTRA_TYPE -%token OPT_TABLES +%token OPT_TABLES OPT_NAMESPACE OPTION_STRING OPT_SKEL %token CCE_ALNUM CCE_ALPHA CCE_BLANK CCE_CNTRL CCE_DIGIT CCE_GRAPH %token CCE_LOWER CCE_PRINT CCE_PUNCT CCE_SPACE CCE_UPPER CCE_XDIGIT @@ -115,7 +116,9 @@ int previous_continued_action; /* whether the previous rule's action was '|' */ %} %% -goal : initlex sect1 sect1end sect2 initforrule + /* OPTION_STRING is a special token for parsing --option=LIST */ +goal : OPTION_STRING optionlist + | initlex sect1 sect1end sect2 initforrule { /* add default rule */ int def_rule; @@ -181,7 +184,7 @@ namelist1 : namelist1 NAME { scinstal( nmstr, xcluflg ); } | error - { synerr( _("bad start condition list") ); } + { synerr( _("bad start condition list2") ); } ; options : OPTION_OP optionlist @@ -192,20 +195,21 @@ optionlist : optionlist option ; option : OPT_OUTFILE '=' NAME - { - outfilename = copy_string( nmstr ); - did_outfilename = 1; - } + { outfilename = copy_string( nmstr ); } | OPT_EXTRA_TYPE '=' NAME { extra_type = copy_string( nmstr ); } | OPT_PREFIX '=' NAME { prefix = copy_string( nmstr ); } + | OPT_NAMESPACE '=' NAME + { buf_m4_define( &m4defs_buf, "M4_YY_NAMESPACE", nmstr); } | OPT_YYCLASS '=' NAME { yyclass = copy_string( nmstr ); } | OPT_HEADER '=' NAME { headerfilename = copy_string( nmstr ); } - | OPT_TABLES '=' NAME - { tablesext = true; tablesfilename = copy_string( nmstr ); } + | OPT_SKEL '=' NAME + { skelname = copy_string( nmstr ); } + | OPT_TABLES '=' NAME + { tablesext = true; tablesfilename = copy_string( nmstr ); } ; sect2 : sect2 scon initforrule flexrule '\n' @@ -990,8 +994,7 @@ void build_eof_action() /* format_synerr - write out formatted syntax error */ -void format_synerr( msg, arg ) -const char *msg, arg[]; +void format_synerr(const char *msg, const char arg[]) { char errmsg[MAXLINE]; @@ -1002,8 +1005,7 @@ const char *msg, arg[]; /* synerr - report a syntax error */ -void synerr( str ) -const char *str; +void synerr(const char *str ) { syntaxerror = true; pinpoint_message( str ); @@ -1012,8 +1014,7 @@ const char *str; /* format_warn - write out formatted warning */ -void format_warn( msg, arg ) -const char *msg, arg[]; +void format_warn(const char *msg, const char arg[]) { char warn_msg[MAXLINE]; @@ -1024,8 +1025,7 @@ const char *msg, arg[]; /* warn - report a warning, unless -w was given */ -void warn( str ) -const char *str; +void warn(const char *str ) { line_warning( str, linenum ); } @@ -1034,8 +1034,7 @@ const char *str; * pinpointing its location */ -void format_pinpoint_message( msg, arg ) -const char *msg, arg[]; +void format_pinpoint_message(const char *msg, const char arg[]) { char errmsg[MAXLINE]; @@ -1046,8 +1045,7 @@ const char *msg, arg[]; /* pinpoint_message - write out a message, pinpointing its location */ -void pinpoint_message( str ) -const char *str; +void pinpoint_message(const char *str) { line_pinpoint( str, linenum ); } @@ -1055,9 +1053,7 @@ const char *str; /* line_warning - report a warning at a given line, unless -w was given */ -void line_warning( str, line ) -const char *str; -int line; +void line_warning(const char *str, int line ) { char warning[MAXLINE]; @@ -1071,9 +1067,7 @@ int line; /* line_pinpoint - write out a message, pinpointing it at the given line */ -void line_pinpoint( str, line ) -const char *str; -int line; +void line_pinpoint(const char *str, int line ) { fprintf( stderr, "%s:%d: %s\n", infilename, line, str ); } @@ -1083,7 +1077,6 @@ int line; * currently, messages are ignore */ -void yyerror( msg ) -const char *msg; +void yyerror(const char *msg ) { } diff --git a/prefix.m4 b/prefix.m4 new file mode 100644 index 0000000..e9c0561 --- /dev/null +++ b/prefix.m4 @@ -0,0 +1,64 @@ +define(`m4_changecom',defn(`changecom'))`'dnl +define(`m4_changequote',defn(`changequote'))`'dnl +define(`m4_decr',defn(`decr'))`'dnl +define(`m4_define',defn(`define'))`'dnl +define(`m4_defn',defn(`defn'))`'dnl +define(`m4_divert',defn(`divert'))`'dnl +define(`m4_divnum',defn(`divnum'))`'dnl +define(`m4_dnl',defn(`dnl'))`'dnl +define(`m4_dumpdef',defn(`dumpdef'))`'dnl +define(`m4_errprint',defn(`errprint'))`'dnl +define(`m4_eval',defn(`eval'))`'dnl +define(`m4_m4exit',defn(`m4exit'))`'dnl +define(`m4_ifelse',defn(`ifelse'))`'dnl +define(`m4_ifdef',defn(`ifdef'))`'dnl +define(`m4_include',defn(`include'))`'dnl +define(`m4_incr',defn(`incr'))`'dnl +define(`m4_index',defn(`index'))`'dnl +define(`m4_len',defn(`len'))`'dnl +define(`m4_maketemp',defn(`maketemp'))`'dnl +define(`m4_popdef',defn(`popdef'))`'dnl +define(`m4_pushdef',defn(`pushdef'))`'dnl +define(`m4_shift',defn(`shift'))`'dnl +define(`m4_sinclude',defn(`sinclude'))`'dnl +define(`m4_substr',defn(`substr'))`'dnl +define(`m4_syscmd',defn(`syscmd'))`'dnl +define(`m4_sysval',defn(`sysval'))`'dnl +define(`m4_translit',defn(`translit'))`'dnl +define(`m4_traceoff',defn(`traceoff'))`'dnl +define(`m4_traceon',defn(`traceon'))`'dnl +define(`m4_undefine',defn(`undefine'))`'dnl +define(`m4_undivert',defn(`undivert'))`'dnl +define(`m4_m4wrap',defn(`m4wrap'))`'dnl +m4_undefine(`changecom')`'m4_dnl +m4_undefine(`changequote')`'m4_dnl +m4_undefine(`decr')`'m4_dnl +m4_undefine(`define')`'m4_dnl +m4_undefine(`defn')`'m4_dnl +m4_undefine(`divert')`'m4_dnl +m4_undefine(`divnum')`'m4_dnl +m4_undefine(`dnl')`'m4_dnl +m4_undefine(`dumpdef')`'m4_dnl +m4_undefine(`errprint')`'m4_dnl +m4_undefine(`eval')`'m4_dnl +m4_undefine(`m4exit')`'m4_dnl +m4_undefine(`ifelse')`'m4_dnl +m4_undefine(`ifdef')`'m4_dnl +m4_undefine(`include')`'m4_dnl +m4_undefine(`incr')`'m4_dnl +m4_undefine(`index')`'m4_dnl +m4_undefine(`len')`'m4_dnl +m4_undefine(`maketemp')`'m4_dnl +m4_undefine(`popdef')`'m4_dnl +m4_undefine(`pushdef')`'m4_dnl +m4_undefine(`shift')`'m4_dnl +m4_undefine(`sinclude')`'m4_dnl +m4_undefine(`substr')`'m4_dnl +m4_undefine(`syscmd')`'m4_dnl +m4_undefine(`sysval')`'m4_dnl +m4_undefine(`translit')`'m4_dnl +m4_undefine(`traceoff')`'m4_dnl +m4_undefine(`traceon')`'m4_dnl +m4_undefine(`undefine')`'m4_dnl +m4_undefine(`undivert')`'m4_dnl +m4_undefine(`m4wrap')`'m4_dnl diff --git a/regex.c b/regex.c index e12cf65..cabffa8 100644 --- a/regex.c +++ b/regex.c @@ -51,7 +51,7 @@ void flex_regcomp(regex_t *preg, const char *regex, int cflags) { int err; - memset (preg, 0, sizeof (regex_t)); + memset ((void*)preg, 0, sizeof (regex_t)); if ((err = regcomp (preg, regex, cflags)) != 0) { const int errbuf_sz = 200; diff --git a/scan.l b/scan.l index 1bcb09b..6bca0d2 100644 --- a/scan.l +++ b/scan.l @@ -36,8 +36,12 @@ #include "parse.h" extern bool tablesverify, tablesext; extern int trlcontxt; /* Set in parse.y for each rule. */ +extern int parsing_option_string; /* flag for parsing --option="..." */ extern const char *escaped_qstart, *escaped_qend; +/* TODO: This macros allows for NLS support of scanner error messages. */ +/* #define YY_FATAL_ERROR(msg) yy_fatal_error(_(msg)) */ + #define ACTION_ECHO add_action( yytext ) #define ACTION_IFDEF(def, should_define) \ { \ @@ -56,6 +60,9 @@ extern const char *escaped_qstart, *escaped_qend; buf_m4_undefine( &m4defs_buf, def);\ } while(0) +#define ACTION_M4_DEFINE(def, bool) \ + buf_m4_define( &m4defs_buf, def, (bool) ? "1" : "0") + #define MARK_END_OF_PROLOG mark_prolog(); #define YY_DECL \ @@ -100,7 +107,8 @@ extern const char *escaped_qstart, *escaped_qend; %x SECT2 SECT2PROLOG SECT3 CODEBLOCK PICKUPDEF SC CARETISBOL NUM QUOTE %x FIRSTCCL CCL ACTION RECOVER COMMENT ACTION_STRING PERCENT_BRACE_ACTION -%x OPTION LINEDIR CODEBLOCK_MATCH_BRACE +%x OPTION BOOLEAN_OPTION LINEDIR CODEBLOCK_MATCH_BRACE +%x CODEBLOCK_HEADER CODEBLOCK_BOTTOM %x GROUP_WITH_PARAMS %x GROUP_MINUS_PARAMS %x EXTENDED_COMMENT @@ -139,14 +147,14 @@ M4QEND "]]" { - ^{WS} indented_code = true; BEGIN(CODEBLOCK); + ^{WS} { indented_code = true; BEGIN(CODEBLOCK); } ^"/*" ACTION_ECHO; yy_push_state( COMMENT ); ^#{OPTWS}line{WS} yy_push_state( LINEDIR ); ^"%s"{NAME}? return SCDECL; ^"%x"{NAME}? return XSCDECL; ^"%{".*{NL} { ++linenum; - line_directive_out( (FILE *) 0, 1 ); + line_directive_out( (FILE *) 0, 1 ); /* insert #line into action array */ indented_code = false; BEGIN(CODEBLOCK); } @@ -160,13 +168,26 @@ M4QEND "]]" ^"%top".* synerr( _("malformed '%top' directive") ); + ^"%header"[[:blank:]]*"{"[[:blank:]]*{NL} { + ++linenum; + buf_linedir( &top_buf, infilename?infilename:"", linenum); + yy_push_state(CODEBLOCK_HEADER); + } + + ^"%bottom"[[:blank:]]*"{"[[:blank:]]*{NL} { + ++linenum; + buf_linedir( &bottom_buf, infilename?infilename:"", linenum); + yy_push_state(CODEBLOCK_BOTTOM); + } + + {WS} /* discard */ ^"%%".* { sectnum = 2; bracelevel = 0; mark_defs1(); - line_directive_out( (FILE *) 0, 1 ); + line_directive_out( (FILE *) 0, 1 ); /* insert #line into action array */ BEGIN(SECT2PROLOG); return SECTEND; } @@ -174,7 +195,7 @@ M4QEND "]]" ^"%pointer".*{NL} yytext_is_array = false; ++linenum; ^"%array".*{NL} yytext_is_array = true; ++linenum; - ^"%option" BEGIN(OPTION); return OPTION_OP; + ^"%option" BEGIN(OPTION); return parsing_option_string ? OPTION_STRING : OPTION_OP; ^"%"{LEXOPT}{OPTWS}[[:digit:]]*{OPTWS}{NL} ++linenum; /* ignore */ ^"%"{LEXOPT}{WS}.*{NL} ++linenum; /* ignore */ @@ -253,6 +274,36 @@ M4QEND "]]" } } +{ + ^"%}".*{NL} { + ++linenum; + yy_pop_state(); + } + + {M4QSTART} buf_strnappend(&top_buf, escaped_qstart, strlen(escaped_qstart)); + {M4QEND} buf_strnappend(&top_buf, escaped_qend, strlen(escaped_qend)); + . buf_strnappend(&top_buf, yytext, yyleng); + {NL} { + ++linenum; + buf_strnappend(&top_buf, yytext, yyleng); + } +} + +{ + ^"%}".*{NL} { + ++linenum; + yy_pop_state(); + } + + {M4QSTART} buf_strnappend(&bottom_buf, escaped_qstart, strlen(escaped_qstart)); + {M4QEND} buf_strnappend(&bottom_buf, escaped_qend, strlen(escaped_qend)); + . buf_strnappend(&bottom_buf, yytext, yyleng); + {NL} { + ++linenum; + buf_strnappend(&bottom_buf, yytext, yyleng); + } +} + { "}" { if( --brace_depth == 0){ @@ -323,115 +374,20 @@ M4QEND "]]"