]> granicus.if.org Git - flex/commitdiff
Tons more work on tables.
authorJohn Millaway <john43@users.sourceforge.net>
Thu, 5 Sep 2002 10:48:55 +0000 (10:48 +0000)
committerJohn Millaway <john43@users.sourceforge.net>
Thu, 5 Sep 2002 10:48:55 +0000 (10:48 +0000)
flex.texi
flexdef.h
gen.c
main.c
options.c
options.h
scan.l
tables.c

index 40af567f2e71dd1d3d9496d06022529edfb11a16..e84ef407108800ac42df156677c21fa2d8d63bd9 100644 (file)
--- a/flex.texi
+++ b/flex.texi
@@ -4660,12 +4660,12 @@ indexed by name, as described below. The file format is as follows:
                 | char            th_name[];    |
                 | uint8           th_pad64[];   |
                 +-------------------------------+
-        Table 1 | uint16          t_id;         |
-                | uint16          t_flags;      |
-                | uint32          t_lolen;      |
-                | uint32          t_hilen;      |
-                | void            t_data[];     |
-                | uint8           t_pad64[];    |
+        Table 1 | uint16          td_id;         |
+                | uint16          td_flags;      |
+                | uint32          td_lolen;      |
+                | uint32          td_hilen;      |
+                | void            td_data[];     |
+                | uint8           td_pad64[];    |
                 +-------------------------------+
         Table 2 |                               |
            .    .                               .
@@ -4723,7 +4723,7 @@ Zero or more NUL bytes, padding the entire header to the next 64-bit boundary.
 Fields of a table:
 
 @table @code
-@item t_id
+@item td_id
 Specifies the table identifier. Possible values are:
 @table @code
 @item YYT_ID_ACCEPT (0x01)
@@ -4741,22 +4741,22 @@ Specifies the table identifier. Possible values are:
 @item YYT_ID_NUL_TRANS (0x07)
 @code{yy_NUL_trans}
 @item YYT_ID_NXT (0x08)
-@code{yy_nxt}. This array may be two dimensional. See the @code{t_hilen}
+@code{yy_nxt}. This array may be two dimensional. See the @code{td_hilen}
 field below.
 @item YYT_ID_RULE_CAN_MATCH_EOL (0x09)
 @code{yy_rule_can_match_eol}
 @item YYT_ID_START_STATE_LIST (0x0A)
 @code{yy_start_state_list}. This array is handled specially because it is an
-array of pointers to srtucts. See the @code{t_flags} field below.
+array of pointers to structs. See the @code{td_flags} field below.
 @item YYT_ID_TRANSITION (0x0B)
 @code{yy_transition}. This array is handled specially because it is an array of
-structs. See the @code{t_lolen} field below.
+structs. See the @code{td_lolen} field below.
 @end table
 
-@item t_flags
-Bit flags describing how to interpret the data in @code{t_data}.
+@item td_flags
+Bit flags describing how to interpret the data in @code{td_data}.
 The data arrays are one-dimensional by default, but may be
-two dimensional as specified in the @code{t_hilen} field.
+two dimensional as specified in the @code{td_hilen} field.
 
 @table @code
 @item YYT_DATA8 (0x01)
@@ -4773,30 +4773,30 @@ in the @code{yy_transition} array. It is not guaranteed that the
 the offsets.
 @end table
 
-@item t_lolen
+@item td_lolen
 Specifies the number of elements in the lowest dimension array.
 
-@item t_hilen
-If @code{t_hilen} is non-zero, then the data is a two-dimensional array.
-Otherwise, the data is a one-dimensional array. @code{t_hilen} contains the
-number of elements in the higher dimensional array, and @code{t_lolen} contains
+@item td_hilen
+If @code{td_hilen} is non-zero, then the data is a two-dimensional array.
+Otherwise, the data is a one-dimensional array. @code{td_hilen} contains the
+number of elements in the higher dimensional array, and @code{td_lolen} contains
 the number of elements in the lowest dimension.
 
-Conceptually, @code{t_data} is either @code{int t_data[t_lolen]},
-or @code{int t_data[t_hilen][t_lolen]}.  It is possible for both @code{t_lolen}
-and @code{t_hilen} to be zero, in which case @code{t_data} is a zero length
+Conceptually, @code{td_data} is either @code{int td_data[td_lolen]},
+or @code{int td_data[td_hilen][td_lolen]}.  It is possible for both @code{td_lolen}
+and @code{td_hilen} to be zero, in which case @code{td_data} is a zero length
 array, and no data is loaded, i.e., this table is simply skipped. A special
-case is made when @code{t_id} equals @code{YYT_ID_TRANSITION}, then
-@code{t_lolen} is the number of structs in the array. Each struct contains two
+case is made when @code{td_id} equals @code{YYT_ID_TRANSITION}, then
+@code{td_lolen} is the number of structs in the array. Each struct contains two
 integer fields, with the @code{yy_verify} field first, followed by the
 @code{yy_nxt} field.
 
-@item t_data[]
+@item td_data[]
 The table data. This array may be a one- or two-dimensional array, of type int8,
-int16, or int32, depending upon the values in the  @code{t_flags}, @code{t_lolen}, and
-@code{t_hilen} fields.
+int16, or int32, depending upon the values in the  @code{td_flags}, @code{td_lolen}, and
+@code{td_hilen} fields.
 
-@item t_pad64[]
+@item td_pad64[]
 Zero or more NUL bytes, padding the table to the next 64-bit boundary.
 @end table
 
index b7fdd644283394a2505ba415515420a52bdba1ac..a571fb77a38b43b275a0d4234b1f36e7ad873c28 100644 (file)
--- a/flexdef.h
+++ b/flexdef.h
@@ -445,16 +445,6 @@ 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;
 
-/*
- * tablesext - if true, create external tables
- * tablestoggle - if true, output external tables code while processing skel
- * tablesfilename - filename for external tables
- * tablesout - FILE stream for external tables
- */
-extern bool tablesext, tablestoggle;
-extern char *tablesfilename;
-extern FILE *tablesout;
-
 extern int yymore_really_used, reject_really_used;
 
 
@@ -1157,7 +1147,34 @@ extern char *chomp (char *str);
 
 /* Tables serialization API declarations. */
 #include "tables_shared.h"
+struct yytbl_writer {
+       FILE   *out;
+       uint32_t total_written;
+                           /**< bytes written so far */
+       fpos_t  th_ssize_pos;
+                           /**< position of th_ssize */
+};
+
+
+/* 
+ * tablesext - if true, create external tables
+ * tablestoggle - if true, output external tables code while processing skel
+ * tablesfilename - filename for external tables
+ * tableswr -  writer for external tables
+ */
+extern bool tablesext, tablestoggle;
+extern char *tablesfilename;
+extern struct yytbl_writer tableswr;
+
+int     yytbl_writer_init (struct yytbl_writer *, FILE *);
+int     yytbl_hdr_init (struct yytbl_hdr *th, const char *version_str,
+                       const char *name);
 int     yytbl_data_init (struct yytbl_data *tbl, enum yytbl_id id);
+int     yytbl_data_destroy (struct yytbl_data *td);
+int     yytbl_hdr_fwrite (struct yytbl_writer *wr,
+                         const struct yytbl_hdr *th);
+int     yytbl_data_fwrite (struct yytbl_writer *wr, struct yytbl_data *td);
+void    yytbl_data_compress (struct yytbl_data *tbl);
 struct yytbl_data *mkftbl (void);
 
 
diff --git a/gen.c b/gen.c
index 39b59a578ae68dffd5e03e3f3f1cdb5dcd5b9529..14bd2546c67d5f713cb85e84a11fc811710f2de7 100644 (file)
--- a/gen.c
+++ b/gen.c
@@ -54,22 +54,18 @@ static int indent_level = 0;        /* each level is 8 spaces */
  * 0 elements of its arrays, too.)
  */
 static const char *C_int_decl =
-
        "static yyconst int %s[%d] =\n    {   0,\n";
 static const char *C_short_decl =
-
        "static yyconst short int %s[%d] =\n    {   0,\n";
 static const char *C_long_decl =
-
        "static yyconst long int %s[%d] =\n    {   0,\n";
 static const char *C_state_decl =
-
        "static yyconst yy_state_type %s[%d] =\n    {   0,\n";
 
 
 /* Indent to the current level. */
 
-void    do_indent ()
+void do_indent ()
 {
        register int i = indent_level * 8;
 
@@ -84,6 +80,31 @@ void    do_indent ()
        }
 }
 
+
+/** Make the table for possible eol matches.
+ *  @return the newly allocated rule_can_match_eol table
+ */
+struct yytbl_data *mkeoltbl (void)
+{
+       int     i;
+       int8_t *tdata = 0;
+       struct yytbl_data *tbl;
+
+       tbl = (struct yytbl_data *) calloc (1, sizeof (struct yytbl_data));
+       yytbl_data_init (tbl, YYT_ID_RULE_CAN_MATCH_EOL);
+       tbl->td_flags = YYT_DATA8;
+       tbl->td_lolen = num_rules + 1;
+       tbl->td_data = tdata =
+               (int8_t *) calloc (tbl->td_lolen, sizeof (int8_t));
+
+       for (i = 0; i < num_rules; i++)
+               tdata[i] = rule_has_nl[i] ? 1 : 0;
+
+       tdata[i] = rule_has_nl[i] ? 1 : 0;
+
+       return tbl;
+}
+
 /* Generate the table for possible eol matches. */
 static void geneoltbl ()
 {
@@ -91,9 +112,7 @@ static void geneoltbl ()
 
        outn ("#ifdef YY_USE_LINENO");
        outn ("/* Table of booleans, true if rule could match eol. */");
-       out_dec
-               ("static const int yy_rule_can_match_eol[%d] =\n    {\n    ",
-                num_rules + 1);
+       out_dec ("static const int yy_rule_can_match_eol[%d] =\n    {\n    ", num_rules + 1);
 
        for (i = 0; i < num_rules; i++) {
                out_dec ("%d, ", rule_has_nl[i] ? 1 : 0);
@@ -108,7 +127,7 @@ static void geneoltbl ()
 
 /* Generate the code to keep backing-up information. */
 
-void    gen_backing_up ()
+void gen_backing_up ()
 {
        if (reject || num_backing_up == 0)
                return;
@@ -129,7 +148,7 @@ void    gen_backing_up ()
 
 /* Generate the code to perform the backing up. */
 
-void    gen_bu_action ()
+void gen_bu_action ()
 {
        if (reject || num_backing_up == 0)
                return;
@@ -155,18 +174,147 @@ void    gen_bu_action ()
        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.
+ * Then, I think, mkecstbl(). Arrrg.
+ * @return the newly allocated trans table
+ */
+
+struct yytbl_data *mkctbl (void)
+{
+       register int i;
+       struct yytbl_data *tbl = 0;
+       int32_t *tdata = 0, curr = 0;
+       int     end_of_buffer_action = num_rules + 1;
+
+       tbl = (struct yytbl_data *) calloc (1, sizeof (struct yytbl_data));
+       yytbl_data_init (tbl, YYT_ID_TRANSITION);
+       tbl->td_flags |= YYT_DATA32;
+       tbl->td_hilen = 0;
+       tbl->td_lolen = tblend + numecs + 1;    /* number of structs */
+
+       tbl->td_data = tdata =
+               (int32_t *) calloc (tbl->td_lolen * 2, sizeof (int32_t));
+
+       /* We want the transition to be represented as the offset to the
+        * next state, not the actual state number, which is what it currently
+        * is.  The offset is base[nxt[i]] - (base of current state)].  That's
+        * just the difference between the starting points of the two involved
+        * states (to - from).
+        *
+        * First, though, we need to find some way to put in our end-of-buffer
+        * flags and states.  We do this by making a state with absolutely no
+        * transitions.  We put it at the end of the table.
+        */
+
+       /* We need to have room in nxt/chk for two more slots: One for the
+        * action and one for the end-of-buffer transition.  We now *assume*
+        * that we're guaranteed the only character we'll try to index this
+        * nxt/chk pair with is EOB, i.e., 0, so we don't have to make sure
+        * there's room for jam entries for other characters.
+        */
+
+       while (tblend + 2 >= current_max_xpairs)
+               expand_nxt_chk ();
+
+       while (lastdfa + 1 >= current_max_dfas)
+               increase_max_dfas ();
+
+       base[lastdfa + 1] = tblend + 2;
+       nxt[tblend + 1] = end_of_buffer_action;
+       chk[tblend + 1] = numecs + 1;
+       chk[tblend + 2] = 1;    /* anything but EOB */
+
+       /* So that "make test" won't show arb. differences. */
+       nxt[tblend + 2] = 0;
+
+       /* Make sure every state has an end-of-buffer transition and an
+        * action #.
+        */
+       for (i = 0; i <= lastdfa; ++i) {
+               int     anum = dfaacc[i].dfaacc_state;
+               int     offset = base[i];
+
+               chk[offset] = EOB_POSITION;
+               chk[offset - 1] = ACTION_POSITION;
+               nxt[offset - 1] = anum; /* action number */
+       }
+
+       for (i = 0; i <= tblend; ++i) {
+               if (chk[i] == EOB_POSITION) {
+                       tdata[curr++] = 0;
+                       tdata[curr++] = base[lastdfa + 1] - i;
+               }
+
+               else if (chk[i] == ACTION_POSITION) {
+                       tdata[curr++] = 0;
+                       tdata[curr++] = nxt[i];
+               }
+
+               else if (chk[i] > numecs || chk[i] == 0) {
+                       tdata[curr++] = 0;
+                       tdata[curr++] = 0;
+               }
+               else {          /* verify, transition */
+
+                       tdata[curr++] = chk[i];
+                       tdata[curr++] = base[nxt[i]] - (i - chk[i]);
+               }
+       }
+
+
+       /* Here's the final, end-of-buffer state. */
+       tdata[curr++] = chk[tblend + 1];
+       tdata[curr++] = nxt[tblend + 1];
+
+       tdata[curr++] = chk[tblend + 2];
+       tdata[curr++] = nxt[tblend + 2];
+
+       /* TODO: deal with this: 
+          if (useecs)
+          genecs ();
+        */
+       return tbl;
+}
+
+
+/** Make start_state_list table.
+ *  @param trans_tbl The transition table created  by mkctbl().
+ *  @return the newly allocated start_state_list table
+ */
+struct yytbl_data *mkssltbl (struct yytbl_data *trans_tbl)
+{
+       struct yytbl_data *tbl = 0;
+       int32_t *tdata = 0;
+       int32_t i;
+
+       tbl = (struct yytbl_data *) calloc (1, sizeof (struct yytbl_data));
+       yytbl_data_init (tbl, YYT_ID_START_STATE_LIST);
+       tbl->td_flags = YYT_DATA32;
+       tbl->td_hilen = 0;
+       tbl->td_lolen = lastsc * 2 + 1;
+
+       tbl->td_data = tdata =
+               (int32_t *) calloc (tbl->td_lolen, sizeof (int32_t));
+
+       for (i = 0; i <= lastsc * 2; ++i)
+               tdata[i] = base[i];
+
+       return tbl;
+}
+
+
 
 /* genctbl - generates full speed compressed transition table */
 
-void    genctbl ()
+void genctbl ()
 {
        register int i;
        int     end_of_buffer_action = num_rules + 1;
 
        /* Table of verify for transition and offset to next state. */
-       out_dec
-               ("static yyconst struct yy_trans_info yy_transition[%d] =\n",
-                tblend + numecs + 1);
+       out_dec ("static yyconst struct yy_trans_info yy_transition[%d] =\n", tblend + numecs + 1);
        outn ("    {");
 
        /* We want the transition to be represented as the offset to the
@@ -237,9 +385,7 @@ void    genctbl ()
        outn ("    };\n");
 
        /* Table of pointers to start states. */
-       out_dec
-               ("static yyconst struct yy_trans_info *yy_start_state_list[%d] =\n",
-                lastsc * 2 + 1);
+       out_dec ("static yyconst struct yy_trans_info *yy_start_state_list[%d] =\n", lastsc * 2 + 1);
        outn ("    {");
 
        for (i = 0; i <= lastsc * 2; ++i)
@@ -261,8 +407,8 @@ struct yytbl_data *mkecstbl (void)
        struct yytbl_data *tbl = 0;
        int32_t *tdata = 0;
 
-       tbl = (struct yytbl_data*)flex_alloc(sizeof(struct yytbl_data));
-       yytbl_data_init (tbl,YYT_ID_EC);
+       tbl = (struct yytbl_data *) calloc (1, sizeof (struct yytbl_data));
+       yytbl_data_init (tbl, YYT_ID_EC);
        tbl->td_flags |= YYT_DATA32;
        tbl->td_hilen = 0;
        tbl->td_lolen = csize;
@@ -300,7 +446,7 @@ struct yytbl_data *mkecstbl (void)
 
 /* Generate equivalence-class tables. */
 
-void    genecs ()
+void genecs ()
 {
        register int i, j;
        int     numrows;
@@ -338,7 +484,7 @@ void    genecs ()
 
 /* Generate the code to find the action number. */
 
-void    gen_find_action ()
+void gen_find_action ()
 {
        if (fullspd)
                indent_puts ("yy_act = yy_current_state[-1].yy_nxt;");
@@ -350,8 +496,7 @@ void    gen_find_action ()
                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 */");
+               outn ("find_rule: /* we branch to this label when backing up */");
 
                indent_puts
                        ("for ( ; ; ) /* until we find what rule we matched */");
@@ -484,8 +629,8 @@ struct yytbl_data *mkftbl (void)
        struct yytbl_data *tbl;
        int32_t *tdata = 0;
 
-       tbl = (struct yytbl_data*)flex_alloc(sizeof(struct yytbl_data));
-       yytbl_data_init (tbl,YYT_ID_ACCEPT);
+       tbl = (struct yytbl_data *) calloc (1, sizeof (struct yytbl_data));
+       yytbl_data_init (tbl, YYT_ID_ACCEPT);
        tbl->td_flags |= YYT_DATA32;
        tbl->td_hilen = 0;      /* it's a one-dimensional array */
        tbl->td_lolen = lastdfa + 1;
@@ -511,7 +656,7 @@ struct yytbl_data *mkftbl (void)
 
 /* genftbl - generate full transition table */
 
-void    genftbl ()
+void genftbl ()
 {
        register int i;
        int     end_of_buffer_action = num_rules + 1;
@@ -544,7 +689,7 @@ void    genftbl ()
 
 /* Generate the code to find the next compressed-table state. */
 
-void    gen_next_compressed_state (char_map)
+void gen_next_compressed_state (char_map)
      char   *char_map;
 {
        indent_put2s ("register YY_CHAR yy_c = %s;", char_map);
@@ -589,17 +734,15 @@ void    gen_next_compressed_state (char_map)
 
 /* Generate the code to find the next match. */
 
-void    gen_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) {
@@ -672,9 +815,7 @@ void    gen_next_match ()
                do_indent ();
 
                if (interactive)
-                       out_dec
-                               ("while ( yy_base[yy_current_state] != %d );\n",
-                                jambase);
+                       out_dec ("while ( yy_base[yy_current_state] != %d );\n", jambase);
                else
                        out_dec ("while ( yy_current_state != %d );\n",
                                 jamstate);
@@ -694,8 +835,8 @@ void    gen_next_match ()
 
 /* Generate the code to find the next state. */
 
-void    gen_next_state (worry_about_NULs)
-     int     worry_about_NULs;
+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];
 
@@ -759,7 +900,7 @@ void    gen_next_state (worry_about_NULs)
 
 /* Generate the code to make a NUL transition. */
 
-void    gen_NUL_trans ()
+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.
@@ -782,9 +923,7 @@ void    gen_NUL_trans ()
 
        else if (fulltbl) {
                do_indent ();
-               out_dec
-                       ("yy_current_state = yy_nxt[yy_current_state][%d];\n",
-                        NUL_ec);
+               out_dec ("yy_current_state = yy_nxt[yy_current_state][%d];\n", NUL_ec);
                indent_puts ("yy_is_jam = (yy_current_state <= 0);");
        }
 
@@ -843,7 +982,7 @@ void    gen_NUL_trans ()
 
 /* Generate the code to find the start state. */
 
-void    gen_start_state ()
+void gen_start_state ()
 {
        if (fullspd) {
                if (bol_needed) {
@@ -876,10 +1015,15 @@ void    gen_start_state ()
 
 /* gentabs - generate data statements for the transition tables */
 
-void    gentabs ()
+void gentabs ()
 {
        int     i, j, k, *accset, nacc, *acc_array, total_states;
        int     end_of_buffer_action = num_rules + 1;
+       struct yytbl_data *yyacc_tbl = 0, *yymeta_tbl = 0, *yybase_tbl = 0,
+               *yydef_tbl = 0, *yynxt_tbl = 0, *yychk_tbl = 0;
+       int32_t *yyacc_data = 0, *yybase_data = 0, *yydef_data = 0,
+               *yynxt_data = 0, *yychk_data = 0;
+       int32_t yybase_curr = 0;
 
        acc_array = allocate_integer_array (current_max_dfas);
        nummt = 0;
@@ -977,6 +1121,8 @@ void    gentabs ()
                acc_array[i] = 0;
        }
 
+       /* Begin generating yy_accept */
+
        /* Spit out "yy_accept" array.  If we're doing "reject", it'll be
         * pointers into the "yy_acclist" array.  Otherwise it's actual
         * accepting numbers.  In either case, we just dump the numbers.
@@ -998,8 +1144,17 @@ void    gentabs ()
        out_str_dec (long_align ? C_long_decl : C_short_decl, "yy_accept",
                     k);
 
+       yyacc_tbl =
+               (struct yytbl_data *) calloc (1,
+                                             sizeof (struct yytbl_data));
+       yytbl_data_init (yyacc_tbl, YYT_ID_ACCEPT);
+       yyacc_tbl->td_lolen = k;
+       yyacc_tbl->td_data = yyacc_data =
+               (int32_t *) calloc (yyacc_tbl->td_lolen, sizeof (int32_t));
+
        for (i = 1; i <= lastdfa; ++i) {
                mkdata (acc_array[i]);
+               yyacc_data[i] = acc_array[i];
 
                if (!reject && trace && acc_array[i])
                        fprintf (stderr, _("state # %d accepts: [%d]\n"),
@@ -1008,20 +1163,42 @@ void    gentabs ()
 
        /* Add entry for "jam" state. */
        mkdata (acc_array[i]);
+       yyacc_data[i] = acc_array[i];
 
-       if (reject)
+       if (reject) {
                /* Add "cap" for the list. */
                mkdata (acc_array[i]);
+               yyacc_data[i] = acc_array[i];
+       }
 
        dataend ();
+       if (tablesext) {
+               yytbl_data_compress (yyacc_tbl);
+               if (yytbl_data_fwrite (&tableswr, yyacc_tbl) < 0)
+                       flexerror (_("Could not write yyacc_tbl"));
+               yytbl_data_destroy (yyacc_tbl);
+               yyacc_tbl = NULL;
+       }
+       /* End generating yy_accept */
 
        if (useecs)
                genecs ();
 
        if (usemecs) {
+               /* Begin generating yy_meta */
                /* Write out meta-equivalence classes (used to index
                 * templates with).
                 */
+               int32_t *yymecs_data = 0;
+               yymeta_tbl =
+                       (struct yytbl_data *) calloc (1,
+                                                     sizeof (struct
+                                                             yytbl_data));
+               yytbl_data_init (yymeta_tbl, YYT_ID_META);
+               yymeta_tbl->td_lolen = numecs + 1;
+               yymeta_tbl->td_data = yymecs_data =
+                       (int32_t *) calloc (yymeta_tbl->td_lolen,
+                                           sizeof (int32_t));
 
                if (trace)
                        fputs (_("\n\nMeta-Equivalence Classes:\n"),
@@ -1035,17 +1212,38 @@ void    gentabs ()
                                         i, ABS (tecbck[i]));
 
                        mkdata (ABS (tecbck[i]));
+                       yymecs_data[i] = ABS (tecbck[i]);
                }
 
                dataend ();
+               if (tablesext) {
+                       yytbl_data_compress (yymeta_tbl);
+                       if (yytbl_data_fwrite (&tableswr, yymeta_tbl) < 0)
+                               flexerror (_
+                                          ("Could not write yymeta_tbl"));
+                       yytbl_data_destroy (yymeta_tbl);
+                       yymeta_tbl = NULL;
+               }
+               /* End generating yy_meta */
        }
 
        total_states = lastdfa + numtemps;
 
+       /* Begin generating yy_base */
        out_str_dec ((tblend >= MAX_SHORT || long_align) ?
                     C_long_decl : C_short_decl,
                     "yy_base", total_states + 1);
 
+       yybase_tbl =
+               (struct yytbl_data *) calloc (1,
+                                             sizeof (struct yytbl_data));
+       yytbl_data_init (yybase_tbl, YYT_ID_BASE);
+       yybase_tbl->td_lolen = total_states + 1;
+       yybase_tbl->td_data = yybase_data =
+               (int32_t *) calloc (yybase_tbl->td_lolen,
+                                   sizeof (int32_t));
+       yybase_curr = 1;
+
        for (i = 1; i <= lastdfa; ++i) {
                register int d = def[i];
 
@@ -1062,30 +1260,72 @@ void    gentabs ()
                }
 
                mkdata (base[i]);
+               yybase_data[yybase_curr++] = base[i];
        }
 
        /* Generate jam state's base index. */
        mkdata (base[i]);
+       yybase_data[yybase_curr++] = base[i];
 
        for (++i /* skip jam state */ ; i <= total_states; ++i) {
                mkdata (base[i]);
+               yybase_data[yybase_curr++] = base[i];
                def[i] = jamstate;
        }
 
        dataend ();
+       if (tablesext) {
+               yytbl_data_compress (yybase_tbl);
+               if (yytbl_data_fwrite (&tableswr, yybase_tbl) < 0)
+                       flexerror (_("Could not write yybase_tbl"));
+               yytbl_data_destroy (yybase_tbl);
+               yybase_tbl = NULL;
+       }
+       /* End generating yy_base */
+
 
+       /* Begin generating yy_def */
        out_str_dec ((total_states >= MAX_SHORT || long_align) ?
                     C_long_decl : C_short_decl,
                     "yy_def", total_states + 1);
 
-       for (i = 1; i <= total_states; ++i)
+
+       yydef_tbl =
+               (struct yytbl_data *) calloc (1,
+                                             sizeof (struct yytbl_data));
+       yytbl_data_init (yydef_tbl, YYT_ID_DEF);
+       yydef_tbl->td_lolen = total_states + 1;
+       yydef_tbl->td_data = yydef_data =
+               (int32_t *) calloc (yydef_tbl->td_lolen, sizeof (int32_t));
+
+       for (i = 1; i <= total_states; ++i) {
                mkdata (def[i]);
+               yydef_data[i] = base[i];
+       }
 
        dataend ();
+       if (tablesext) {
+               yytbl_data_compress (yydef_tbl);
+               if (yytbl_data_fwrite (&tableswr, yydef_tbl) < 0)
+                       flexerror (_("Could not write yydef_tbl"));
+               yytbl_data_destroy (yydef_tbl);
+               yydef_tbl = NULL;
+       }
+       /* End generating yy_def */
+
 
+       /* Begin generating yy_nxt */
        out_str_dec ((total_states >= MAX_SHORT || long_align) ?
                     C_long_decl : C_short_decl, "yy_nxt", tblend + 1);
 
+       yynxt_tbl =
+               (struct yytbl_data *) calloc (1,
+                                             sizeof (struct yytbl_data));
+       yytbl_data_init (yynxt_tbl, YYT_ID_NXT);
+       yynxt_tbl->td_lolen = tblend + 1;
+       yynxt_tbl->td_data = yynxt_data =
+               (int32_t *) calloc (yynxt_tbl->td_lolen, sizeof (int32_t));
+
        for (i = 1; i <= tblend; ++i) {
                /* Note, the order of the following test is important.
                 * If chk[i] is 0, then nxt[i] is undefined.
@@ -1094,21 +1334,48 @@ void    gentabs ()
                        nxt[i] = jamstate;      /* new state is the JAM state */
 
                mkdata (nxt[i]);
+               yynxt_data[i] = nxt[i];
        }
 
        dataend ();
+       if (tablesext) {
+               yytbl_data_compress (yynxt_tbl);
+               if (yytbl_data_fwrite (&tableswr, yynxt_tbl) < 0)
+                       flexerror (_("Could not write yynxt_tbl"));
+               yytbl_data_destroy (yynxt_tbl);
+               yynxt_tbl = NULL;
+       }
+       /* End generating yy_nxt */
 
+       /* Begin generating yy_chk */
        out_str_dec ((total_states >= MAX_SHORT || long_align) ?
                     C_long_decl : C_short_decl, "yy_chk", tblend + 1);
 
+       yychk_tbl =
+               (struct yytbl_data *) calloc (1,
+                                             sizeof (struct yytbl_data));
+       yytbl_data_init (yychk_tbl, YYT_ID_CHK);
+       yychk_tbl->td_lolen = tblend + 1;
+       yychk_tbl->td_data = yychk_data =
+               (int32_t *) calloc (yychk_tbl->td_lolen, sizeof (int32_t));
+
        for (i = 1; i <= tblend; ++i) {
                if (chk[i] == 0)
                        ++nummt;
 
                mkdata (chk[i]);
+               yychk_data[i] = chk[i];
        }
 
        dataend ();
+       if (tablesext) {
+               yytbl_data_compress (yychk_tbl);
+               if (yytbl_data_fwrite (&tableswr, yychk_tbl) < 0)
+                       flexerror (_("Could not write yychk_tbl"));
+               yytbl_data_destroy (yychk_tbl);
+               yychk_tbl = NULL;
+       }
+       /* End generating yy_chk */
 
        flex_free ((void *) acc_array);
 }
@@ -1118,7 +1385,7 @@ void    gentabs ()
  * current indentation level, adding a final newline.
  */
 
-void    indent_put2s (fmt, arg)
+void indent_put2s (fmt, arg)
      const char *fmt, *arg;
 {
        do_indent ();
@@ -1131,7 +1398,7 @@ void    indent_put2s (fmt, arg)
  * newline.
  */
 
-void    indent_puts (str)
+void indent_puts (str)
      const char *str;
 {
        do_indent ();
@@ -1142,10 +1409,12 @@ void    indent_puts (str)
 /* make_tables - generate transition tables and finishes generating output file
  */
 
-void    make_tables ()
+void make_tables ()
 {
        register int i;
        int     did_eof_rule = false;
+       struct yytbl_data *yynultrans_tbl;
+
 
        skelout ();             /* %% [2.0] - break point in skel */
 
@@ -1233,8 +1502,12 @@ void    make_tables ()
                indent_down ();
        }
 
-       if (fullspd)
+       if (fullspd) {
                genctbl ();
+               if (tablesext) {
+                       /* TODO: mkctbl(); */
+               }
+       }
        else if (fulltbl)
                genftbl ();
        else
@@ -1257,17 +1530,44 @@ void    make_tables ()
        }
 
        if (nultrans) {
+               int32_t *yynultrans_data = 0;
+
+               /* Begin generating yy_NUL_trans */
                out_str_dec (C_state_decl, "yy_NUL_trans", lastdfa + 1);
 
+               yynultrans_tbl =
+                       (struct yytbl_data *) calloc (1,
+                                                     sizeof (struct
+                                                             yytbl_data));
+               yytbl_data_init (yynultrans_tbl, YYT_ID_NUL_TRANS);
+               yynultrans_tbl->td_lolen = lastdfa + 1;
+               yynultrans_tbl->td_data = yynultrans_data =
+                       (int32_t *) calloc (yynultrans_tbl->td_lolen,
+                                           sizeof (int32_t));
+
                for (i = 1; i <= lastdfa; ++i) {
-                       if (fullspd)
+                       if (fullspd) {
                                out_dec ("    &yy_transition[%d],\n",
                                         base[i]);
-                       else
+                               yynultrans_data[i] = base[i];
+                       }
+                       else {
                                mkdata (nultrans[i]);
+                               yynultrans_data[i] = nultrans[i];
+                       }
                }
 
                dataend ();
+               if (tablesext) {
+                       yytbl_data_compress (yynultrans_tbl);
+                       if (yytbl_data_fwrite (&tableswr, yynultrans_tbl) <
+                           0)
+                               flexerror (_
+                                          ("Could not write yynultrans_tbl"));
+                       yytbl_data_destroy (yynultrans_tbl);
+                       yynultrans_tbl = NULL;
+               }
+               /* End generating yy_NUL_trans */
        }
 
        if (ddebug) {           /* Spit out table mapping rules to line numbers. */
@@ -1287,16 +1587,14 @@ void    make_tables ()
                outn ("#ifdef YY_USES_REJECT");
                /* Declare state buffer variables. */
                if (!C_plus_plus && !reentrant) {
-                       outn
-                               ("static yy_state_type *yy_state_buf=0, *yy_state_ptr=0;");
+                       outn ("static yy_state_type *yy_state_buf=0, *yy_state_ptr=0;");
                        outn ("static char *yy_full_match;");
                        outn ("static int yy_lp;");
                }
 
                if (variable_trailing_context_rules) {
                        if (!C_plus_plus) {
-                               outn
-                                       ("static int yy_looking_for_trail_begin = 0;");
+                               outn ("static int yy_looking_for_trail_begin = 0;");
                                outn ("static int yy_full_lp;");
                                outn ("static int *yy_full_state;");
                        }
@@ -1309,18 +1607,13 @@ void    make_tables ()
 
                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 */ \\");
+               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 */ \\");
 
                if (variable_trailing_context_rules) {
-                       outn
-                               ("YY_G(yy_lp) = yy_full_lp; /* restore orig. accepting pos. */ \\");
-                       outn
-                               ("YY_G(yy_state_ptr) = yy_full_state; /* restore orig. state */ \\");
-                       outn
-                               ("yy_current_state = *YY_G(yy_state_ptr); /* restore curr. state */ \\");
+                       outn ("YY_G(yy_lp) = yy_full_lp; /* restore orig. accepting pos. */ \\");
+                       outn ("YY_G(yy_state_ptr) = yy_full_state; /* restore orig. state */ \\");
+                       outn ("yy_current_state = *YY_G(yy_state_ptr); /* restore curr. state */ \\");
                }
 
                outn ("++YY_G(yy_lp); \\");
@@ -1331,8 +1624,7 @@ void    make_tables ()
        }
 
        else {
-               outn
-                       ("/* The intent behind this definition is that it'll catch");
+               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");
@@ -1416,13 +1708,11 @@ void    make_tables ()
        if (!C_plus_plus) {
                if (use_read) {
                        outn ("\terrno=0; \\");
-                       outn
-                               ("\twhile ( (result = read( fileno(yyin), (char *) buf, max_size )) < 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\tYY_FATAL_ERROR( \"input in flex scanner failed\" ); \\");
                        outn ("\t\t\tbreak; \\");
                        outn ("\t\t} \\");
                        outn ("\t\terrno=0; \\");
@@ -1431,32 +1721,27 @@ void    make_tables ()
                }
 
                else {
-                       outn
-                               ("\tif ( YY_G(yy_current_buffer)->yy_is_interactive ) \\");
+                       outn ("\tif ( YY_G(yy_current_buffer)->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\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\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\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\tYY_FATAL_ERROR( \"input in flex scanner failed\" ); \\");
                        outn ("\t\t\t\tbreak; \\");
                        outn ("\t\t\t\t} \\");
                        outn ("\t\t\terrno=0; \\");
diff --git a/main.c b/main.c
index 15f98b76bd0ba063dfc04b82fe4994afe5167cc8..7ec512f9162dd32ea80be9228f7a3a9506d958b5 100644 (file)
--- a/main.c
+++ b/main.c
@@ -52,7 +52,6 @@ int     interactive, caseins, lex_compat, posix_compat, do_yylineno,
        useecs, fulltbl, usemecs;
 int     fullspd, gen_line_dirs, performance_report, backing_up_report;
 int     C_plus_plus, long_align, use_read, yytext_is_array, do_yywrap,
-
        csize;
 int     reentrant, reentrant_bison_pure;
 int     yymore_used, reject, real_reject, continued_action, in_rule;
@@ -62,7 +61,6 @@ FILE   *skelfile = NULL;
 int     skel_ind = 0;
 char   *action_array;
 int     action_size, defs1_offset, prolog_offset, action_offset,
-
        action_index;
 char   *infilename = NULL, *outfilename = NULL, *headerfilename = NULL;
 int     did_outfilename;
@@ -109,7 +107,7 @@ int     nlch = '\n';
 
 bool    tablesext, tablestoggle;
 char   *tablesfilename;
-FILE   *tablesout;
+struct yytbl_writer tableswr;
 
 /* 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].
@@ -119,9 +117,11 @@ char   *program_name = "flex";
 #ifndef SHORT_FILE_NAMES
 static char *outfile_template = "lex.%s.%s";
 static char *backing_name = "lex.backup";
+static char *tablesfile_template = "lex.%s.tables";
 #else
 static char *outfile_template = "lex%s.%s";
 static char *backing_name = "lex.bck";
+static char *tablesfile_template = "lex%s.tbl";
 #endif
 
 #ifdef MS_DOS
@@ -136,8 +136,8 @@ int flex_main PROTO ((int argc, char *argv[]));
 int main PROTO ((int argc, char *argv[]));
 void fix_line_dirs PROTO ((char *, char *, char *, int));
 
-int     flex_main (argc, argv)
-     int     argc;
+int flex_main (argc, argv)
+     int argc;
      char   *argv[];
 {
        int     i, exit_status;
@@ -167,7 +167,7 @@ int     flex_main (argc, argv)
        if (spprdflt && !reject && rule_useful[default_rule])
                line_warning (_
                              ("-s option given but default rule can be matched"),
-rule_linenum[default_rule]);
+                             rule_linenum[default_rule]);
 
        /* Generate the C state transition tables from the DFA. */
        make_tables ();
@@ -181,8 +181,8 @@ rule_linenum[default_rule]);
 }
 
 /* Wrapper around flex_main, so flex_main can be built as a library. */
-int     main (argc, argv)
-     int     argc;
+int main (argc, argv)
+     int argc;
      char   *argv[];
 {
 #if ENABLE_NLS
@@ -196,7 +196,7 @@ int     main (argc, argv)
 
 /* check_options - check user-specified options */
 
-void    check_options ()
+void check_options ()
 {
        int     i;
 
@@ -325,6 +325,38 @@ void    check_options ()
                outfile_created = 1;
        }
 
+       if (tablesext) {
+               FILE   *tablesout;
+               struct yytbl_hdr hdr;
+               char   *pname = 0;
+               int     nbytes = 0;
+
+               if (!tablesfilename) {
+                       nbytes = strlen (prefix) +
+                               strlen (tablesfile_template) + 2;
+                       tablesfilename = pname =
+                               (char *) calloc (nbytes, 1);
+                       sprintf (pname, tablesfile_template, prefix);
+               }
+
+               if ((tablesout = fopen (tablesfilename, "w")) == NULL)
+                       lerrsf (_("could not create %s"), tablesfilename);
+               if (pname)
+                       free (pname);
+               tablesfilename = 0;
+
+               yytbl_writer_init (&tableswr, tablesout);
+
+               nbytes = strlen (prefix) + strlen ("tables") + 2;
+               pname = (char *) calloc (nbytes, 1);
+               sprintf (pname, "%stables", prefix);
+               yytbl_hdr_init (&hdr, "TODO", pname);
+               free (pname);
+
+               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);
 
@@ -418,11 +450,11 @@ void    check_options ()
  * for the generated header. We chaneg the line number and filename.
  * linebuf is modified in place.
  */
-void    fix_line_dirs (linebuf, outfilename, headerfilename, nlines)
+void fix_line_dirs (linebuf, outfilename, headerfilename, nlines)
      char   *linebuf;
      char   *outfilename;
      char   *headerfilename;
-     int     nlines;
+     int nlines;
 {
        char   *pname, *p;
 
@@ -475,8 +507,8 @@ void    fix_line_dirs (linebuf, outfilename, headerfilename, nlines)
  *    This routine does not return.
  */
 
-void    flexend (exit_status)
-     int     exit_status;
+void flexend (exit_status)
+     int exit_status;
 
 {
        static int called_before = -1;  /* prevent infinite recursion. */
@@ -532,10 +564,8 @@ void    flexend (exit_status)
                while (fgets (linebuf, LINE_SZ, stdout)) {
                        if (strstr (linebuf, "YY-DISCARD-FROM-HEADER"))
                                discard++;
-                       else
-                               if (strstr
-                                   (linebuf,
-                                    "YY-END-DISCARD-FROM-HEADER")) {
+                       else if (strstr
+                                (linebuf, "YY-END-DISCARD-FROM-HEADER")) {
                                discard--;
                                continue;
                        }
@@ -971,8 +1001,8 @@ void    flexend (exit_status)
 
 /* flexinit - initialize flex */
 
-void    flexinit (argc, argv)
-     int     argc;
+void flexinit (argc, argv)
+     int argc;
      char  **argv;
 {
        int     i, sawcmpflag, rv, optind;
@@ -997,7 +1027,6 @@ void    flexinit (argc, argv)
        use_read = use_stdout = false;
        tablesext = tablestoggle = false;
        tablesfilename = NULL;
-       tablesout = NULL;
 
        sawcmpflag = false;
 
@@ -1176,7 +1205,7 @@ void    flexinit (argc, argv)
                                else
                                        lerrif (_
                                                ("unknown -R option '%c'"),
-(int) arg[0]);
+                                               (int) arg[0]);
                        }
                        break;
 
@@ -1205,8 +1234,9 @@ void    flexinit (argc, argv)
                                       "1");
                        break;
 
-               case OPT_TABLES:
+               case OPT_TABLES_FILE:
                        tablesext = true;
+                       tablesfilename = arg;
                        break;
 
                case OPT_TRACE:
@@ -1472,11 +1502,10 @@ void    flexinit (argc, argv)
 
 /* readin - read in the rules section of the input file(s) */
 
-void    readin ()
+void readin ()
 {
        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);
@@ -1515,7 +1544,7 @@ void    readin ()
                if (backing_up_file == NULL)
                        lerrsf (_
                                ("could not create backing-up info file %s"),
-backing_name);
+                               backing_name);
        }
 
        else
@@ -1648,8 +1677,7 @@ backing_name);
 
        OUT_BEGIN_CODE ();
        if (fullspd)
-               outn
-                       ("typedef yyconst struct yy_trans_info *yy_state_type;");
+               outn ("typedef yyconst struct yy_trans_info *yy_state_type;");
        else if (!C_plus_plus)
                outn ("typedef int yy_state_type;");
        OUT_END_CODE ();
@@ -1672,8 +1700,7 @@ backing_name);
                if (yyclass) {
                        outn ("int yyFlexLexer::yylex()");
                        outn ("\t{");
-                       outn
-                               ("\tLexerError( \"yyFlexLexer::yylex invoked but %option yyclass used\" );");
+                       outn ("\tLexerError( \"yyFlexLexer::yylex invoked but %option yyclass used\" );");
                        outn ("\treturn 0;");
                        outn ("\t}");
 
@@ -1722,7 +1749,7 @@ backing_name);
 
 /* set_up_initial_allocations - allocate memory for internal tables */
 
-void    set_up_initial_allocations ()
+void set_up_initial_allocations ()
 {
        maximum_mns = (long_align ? MAXIMUM_MNS_LONG : MAXIMUM_MNS);
        current_mns = INITIAL_MNS;
@@ -1784,7 +1811,7 @@ void    set_up_initial_allocations ()
  * (same concept as /bin/sh `basename`, but different handling of extension). */
 static char *basename2 (path, strip_ext)
      char   *path;
-     int     strip_ext;                /* boolean */
+     int strip_ext;            /* boolean */
 {
        char   *b, *e = 0;
 
@@ -1800,7 +1827,7 @@ static char *basename2 (path, strip_ext)
        return b;
 }
 
-void    usage ()
+void usage ()
 {
        FILE   *f = stdout;
 
@@ -1838,7 +1865,7 @@ void    usage ()
                  "  -t, --stdout            write scanner on stdout instead of %s\n"
                  "      --yyclass=NAME      name of C++ class\n"
                  "      --header=FILE       create a C header file in addition to the scanner\n"
-                 "      --tables[=FILE]     write tables to FILE\n" "\n"
+                 "      --tables-file[=FILE]  write tables to FILE\n" "\n"
                  "Scanner behavior:\n"
                  "  -7, --7bit              generate 7-bit scanner\n"
                  "  -8, --8bit              generate 8-bit scanner\n"
index a6322c14212da3e57cb1dbc5a37a554ad25244d5..f9515ea3091088d53f7c6fee4b49c2122549af0e 100644 (file)
--- a/options.c
+++ b/options.c
@@ -187,7 +187,7 @@ optspec_t flexopts[] = {
        ,
        {"--trace", OPT_TRACE, 0}
        ,                       /* Flex should run in trace mode. */
-       {"--tables[=FILE]", OPT_TABLES, 0}
+       {"--tables-file[=FILE]", OPT_TABLES_FILE, 0}
        ,                       /* Save tables to FILE */
        {"--nounistd", OPT_NO_UNISTD_H, 0}
        ,                       /* Do not include unistd.h */
index b4fe0661658265282ed1f3b03f101c1df57f642f..51b13e5dfe345b71d5a31003c6d56482f9b2681d 100644 (file)
--- a/options.h
+++ b/options.h
@@ -112,7 +112,7 @@ enum flexopt_flag_t {
        OPT_STACK,
        OPT_STDINIT,
        OPT_STDOUT,
-       OPT_TABLES,
+       OPT_TABLES_FILE,
        OPT_TRACE,
        OPT_NO_UNISTD_H,
        OPT_VERBOSE,
diff --git a/scan.l b/scan.l
index 43dd66981f5328aaa78370fc5796d064079b0a59..f297846c1e3a3c88be8f2edaf6fd16796c6822b9 100644 (file)
--- a/scan.l
+++ b/scan.l
@@ -315,8 +315,8 @@ LEXOPT              [aceknopr]
        outfile         return OPT_OUTFILE;
        prefix          return OPT_PREFIX;
        yyclass         return OPT_YYCLASS;
-       header      return OPT_HEADER;
-       tables      return OPT_TABLES;
+       header(-file)?      return OPT_HEADER;
+       tables-file         return OPT_TABLES;
 
        \"[^"\n]*\"     {
                        strcpy( nmstr, yytext + 1 );
index a19bcfece85b19b6fcd7202fe3cbd4fa09694bda..71dd02a3cb6436d69a27202397fab05bf3fa3533 100644 (file)
--- a/tables.c
+++ b/tables.c
  */
 #define TFLAGS_CLRDATA(flg) ((flg) & ~(YYT_DATA8 | YYT_DATA16 | YYT_DATA32))
 
-int     yytbl_fwrite32 (FILE * out, uint32_t v);
-int     yytbl_fwrite16 (FILE * out, uint16_t v);
-int     yytbl_fwrite8 (FILE * out, uint8_t v);
+int     yytbl_fwrite32 (struct yytbl_writer *wr, uint32_t v);
+int     yytbl_fwrite16 (struct yytbl_writer *wr, uint16_t v);
+int     yytbl_fwrite8 (struct yytbl_writer *wr, uint8_t v);
+int     yytbl_fwriten (struct yytbl_writer *wr, void *v, int32_t len);
+static int32_t tbl_get_total_len (struct yytbl_data *tbl);
+static int32_t yytbl_data_geti (const struct yytbl_data *tbl, int i);
+
+
+/** Initialize the table writer.
+ *  @param wr an uninitialized writer
+ *  @param the output file
+ *  @return 0 on success
+ */
+int yytbl_writer_init (struct yytbl_writer *wr, FILE * out)
+{
+       wr->out = out;
+       wr->total_written = 0;
+       return 0;
+}
 
 /** Initialize a table header.
  *  @param th  The uninitialized structure
  *  @param version_str the  version string
  *  @param name the name of this table set
  */
-void yytbl_hdr_init (struct yytbl_hdr *th, const char *version_str,
-                    const char *name)
+int yytbl_hdr_init (struct yytbl_hdr *th, const char *version_str,
+                   const char *name)
 {
        memset (th, 0, sizeof (struct yytbl_hdr));
 
        th->th_magic = 0xF13C57B1;
-       th->th_hsize =
-               yypad64 (20 + strlen (version_str) + 1 + strlen (name) +
-                        1);
+       th->th_hsize = 14 + strlen (version_str) + 1 + strlen (name) + 1;
+       th->th_hsize += yypad64 (th->th_hsize);
        th->th_ssize = 0;       // Not known at this point.
        th->th_flags = 0;
        th->th_version = copy_string (version_str);
        th->th_name = copy_string (name);
+       return 0;
 }
 
 /** Allocate and initialize a table data structure.
@@ -100,41 +116,64 @@ int yytbl_data_init (struct yytbl_data *td, enum yytbl_id id)
        return 0;
 }
 
+int yytbl_data_destroy (struct yytbl_data *td)
+{
+       if (td->td_data)
+               free (td->td_data);
+       td->td_data = 0;
+       free (td);
+       return 0;
+}
+static int yytbl_fwrite_pad64 (struct yytbl_writer *wr)
+{
+       int     pad, bwritten = 0;
+
+       pad = yypad64 (wr->total_written);
+       while (pad-- > 0)
+               if (yytbl_fwrite8 (wr, 0) < 0)
+                       return -1;
+               else
+                       bwritten++;
+       return bwritten;
+}
+
 /** write the header.
  *  @param out the output stream
  *  @param th table header to be written
  *  @return -1 on error, or bytes written on success.
  */
-int yytbl_hdr_fwrite (FILE * out, const struct yytbl_hdr *th)
+int yytbl_hdr_fwrite (struct yytbl_writer *wr, const struct yytbl_hdr *th)
 {
        size_t  sz, rv;
-       int     pad, bwritten = 0;
+       int     bwritten = 0;
 
-       if (yytbl_fwrite32 (out, th->th_magic) < 0
-           || yytbl_fwrite32 (out, th->th_hsize) < 0
-           || yytbl_fwrite32 (out, th->th_ssize) < 0
-           || yytbl_fwrite16 (out, th->th_flags) < 0)
+       if (yytbl_fwrite32 (wr, th->th_magic) < 0
+           || yytbl_fwrite32 (wr, th->th_hsize) < 0)
                return -1;
-       else
-               bwritten += 3 * 4 + 2;
+       bwritten += 8;
+
+       if (fgetpos (wr->out, &(wr->th_ssize_pos)) != 0)
+               return -1;
+
+       if (yytbl_fwrite32 (wr, th->th_ssize) < 0
+           || yytbl_fwrite16 (wr, th->th_flags) < 0)
+               return -1;
+       bwritten += 6;
 
        sz = strlen (th->th_version) + 1;
-       if ((rv = fwrite (th->th_version, 1, sz, out)) != sz)
+       if ((rv = yytbl_fwriten (wr, th->th_version, sz)) != sz)
                return -1;
        bwritten += rv;
 
        sz = strlen (th->th_name) + 1;
-       if ((rv = fwrite (th->th_name, 1, sz, out)) != sz)
+       if ((rv = yytbl_fwriten (wr, th->th_name, sz)) != sz)
                return 1;
        bwritten += rv;
 
        /* add padding */
-       pad = yypad64 (bwritten) - bwritten;
-       while (pad-- > 0)
-               if (yytbl_fwrite8 (out, 0) < 0)
-                       return -1;
-               else
-                       bwritten++;
+       if ((rv = yytbl_fwrite_pad64 (wr)) < 0)
+               return -1;
+       bwritten += rv;
 
        /* Sanity check */
        if (bwritten != th->th_hsize) {
@@ -145,55 +184,146 @@ int yytbl_hdr_fwrite (FILE * out, const struct yytbl_hdr *th)
        return bwritten;
 }
 
+
+/** Write this table.
+ *  @param out the file writer
+ *  @param td table data to be written
+ *  @return -1 on error, or bytes written on success.
+ */
+int yytbl_data_fwrite (struct yytbl_writer *wr, struct yytbl_data *td)
+{
+       size_t  rv;
+       int32_t bwritten = 0;
+       int32_t i, total_len;
+       fpos_t  pos;
+
+       if ((rv = yytbl_fwrite16 (wr, td->td_id)) < 0)
+               return -1;
+       bwritten += rv;
+
+       if ((rv = yytbl_fwrite16 (wr, td->td_flags)) < 0)
+               return -1;
+       bwritten += rv;
+
+       if ((rv = yytbl_fwrite32 (wr, td->td_hilen)) < 0)
+               return -1;
+       bwritten += rv;
+
+       if ((rv = yytbl_fwrite32 (wr, td->td_lolen)) < 0)
+               return -1;
+       bwritten += rv;
+
+       total_len = tbl_get_total_len (td);
+       for (i = 0; i < total_len; i++) {
+               switch (TFLAGS2BYTES (td->td_flags)) {
+               case sizeof (int8_t):
+                       rv = yytbl_fwrite8 (wr, yytbl_data_geti (td, i));
+                       break;
+               case sizeof (int16_t):
+                       rv = yytbl_fwrite16 (wr, yytbl_data_geti (td, i));
+                       break;
+               case sizeof (int32_t):
+                       rv = yytbl_fwrite32 (wr, yytbl_data_geti (td, i));
+                       break;
+               default:        /* TODO: error. Something really wrong. */
+               }
+               if (rv < 0)
+                       return -1;
+               bwritten += rv;
+       }
+
+       /* Sanity check */
+       if (bwritten != (12 + total_len * TFLAGS2BYTES (td->td_flags))) {
+               /* Oops. */
+               return -1;
+       }
+
+       /* add padding */
+       if ((rv = yytbl_fwrite_pad64 (wr)) < 0)
+               return -1;
+       bwritten += rv;
+
+       /* Now go back and update the th_hsize member */
+       if (fgetpos (wr->out, &pos) != 0
+           || fsetpos (wr->out, &(wr->th_ssize_pos)) != 0
+           || yytbl_fwrite32 (wr, wr->total_written) < 0
+           || fsetpos (wr->out, &pos))
+               return -1;
+       else
+               /* Don't count the int we just wrote. */
+               wr->total_written -= sizeof (int32_t);
+       return bwritten;
+}
+
+/** Write n bytes.
+ *  @param  wr   the table writer
+ *  @param  v    data to be written
+ *  @param  len  number of bytes
+ *  @return  -1 on error. number of bytes written on success.
+ */
+int yytbl_fwriten (struct yytbl_writer *wr, void *v, int32_t len)
+{
+       size_t  rv;
+
+       rv = fwrite (v, 1, len, wr->out);
+       if (rv != len)
+               return -1;
+       wr->total_written += len;
+       return len;
+}
+
 /** Write four bytes in network byte order
- *  @param  out  the output stream
+ *  @param  wr  the table writer
  *  @param  v    a dword in host byte order
  *  @return  -1 on error. number of bytes written on success.
  */
-int yytbl_fwrite32 (FILE * out, uint32_t v)
+int yytbl_fwrite32 (struct yytbl_writer *wr, uint32_t v)
 {
        uint32_t vnet;
        size_t  bytes, rv;
 
        vnet = htonl (v);
        bytes = sizeof (uint32_t);
-       rv = fwrite (&vnet, bytes, 1, out);
-       if (rv != bytes)
+       rv = fwrite (&vnet, bytes, 1, wr->out);
+       if (rv != 1)
                return -1;
+       wr->total_written += bytes;
        return bytes;
 }
 
 /** Write two bytes in network byte order.
- *  @param  out  the output stream
+ *  @param  wr  the table writer
  *  @param  v    a word in host byte order
  *  @return  -1 on error. number of bytes written on success.
  */
-int yytbl_fwrite16 (FILE * out, uint16_t v)
+int yytbl_fwrite16 (struct yytbl_writer *wr, uint16_t v)
 {
        uint16_t vnet;
        size_t  bytes, rv;
 
        vnet = htons (v);
        bytes = sizeof (uint16_t);
-       rv = fwrite (&vnet, bytes, 1, out);
-       if (rv != bytes)
+       rv = fwrite (&vnet, bytes, 1, wr->out);
+       if (rv != 1)
                return -1;
+       wr->total_written += bytes;
        return bytes;
 }
 
 /** Write a byte.
- *  @param  out  the output stream
+ *  @param  wr  the table writer
  *  @param  v    the value to be written
  *  @return  -1 on error. number of bytes written on success.
  */
-int yytbl_fwrite8 (FILE * out, uint8_t v)
+int yytbl_fwrite8 (struct yytbl_writer *wr, uint8_t v)
 {
        size_t  bytes, rv;
 
        bytes = sizeof (uint8_t);
-       rv = fwrite (&v, bytes, 1, out);
-       if (rv != bytes)
+       rv = fwrite (&v, bytes, 1, wr->out);
+       if (rv != 1)
                return -1;
+       wr->total_written += bytes;
        return bytes;
 }
 
@@ -283,16 +413,19 @@ static int32_t yytbl_data_geti (const struct yytbl_data *tbl, int i)
  * @param newval new value for data[i]
  */
 static void yytbl_data_seti (const struct yytbl_data *tbl, int i,
-                            int newval)
+                            int32_t newval)
 {
 
        switch (TFLAGS2BYTES (tbl->td_flags)) {
        case sizeof (int8_t):
                ((int8_t *) (tbl->td_data))[i] = (int8_t) newval;
+               break;
        case sizeof (int16_t):
                ((int16_t *) (tbl->td_data))[i] = (int16_t) newval;
+               break;
        case sizeof (int32_t):
                ((int32_t *) (tbl->td_data))[i] = (int32_t) newval;
+               break;
        default:                /* TODO: error. major foobar somewhere. */
                break;
        }
@@ -349,7 +482,6 @@ void yytbl_data_compress (struct yytbl_data *tbl)
        newsz = min_int_size (tbl);
 
 
-
        if (newsz == TFLAGS2BYTES (tbl->td_flags))
                /* No change in this table needed. */
                return;
@@ -360,12 +492,16 @@ void yytbl_data_compress (struct yytbl_data *tbl)
        }
 
        total_len = tbl_get_total_len (tbl);
-       newtbl.td_data = flex_alloc (newsz * total_len);
+       newtbl.td_data = calloc (total_len, newsz);
        newtbl.td_flags =
-               TFLAGS_CLRDATA (newtbl.td_flags) & BYTES2TFLAG (newsz);
+               TFLAGS_CLRDATA (newtbl.td_flags) | BYTES2TFLAG (newsz);
 
-       for (i = 0; i < total_len; i++)
-               yytbl_data_seti (&newtbl, i, yytbl_data_geti (tbl, i));
+       for (i = 0; i < total_len; i++) {
+               int32_t g;
+
+               g = yytbl_data_geti (tbl, i);
+               yytbl_data_seti (&newtbl, i, g);
+       }
 
 
        /* Now copy over the old table */