gawk-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gawk-diffs] [SCM] gawk branch, feature/api-parser, updated. gawk-4.1.0-


From: Andrew J. Schorr
Subject: [gawk-diffs] [SCM] gawk branch, feature/api-parser, updated. gawk-4.1.0-2460-gd1bebd3
Date: Tue, 21 Mar 2017 13:22:47 -0400 (EDT)

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "gawk".

The branch, feature/api-parser has been updated
       via  d1bebd3cbf60fa25883271512cf63e0c3275e3ef (commit)
      from  489349d84fa92f69b2066240bc202a4f2777c465 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://git.sv.gnu.org/cgit/gawk.git/commit/?id=d1bebd3cbf60fa25883271512cf63e0c3275e3ef

commit d1bebd3cbf60fa25883271512cf63e0c3275e3ef
Author: Andrew J. Schorr <address@hidden>
Date:   Tue Mar 21 13:22:18 2017 -0400

    Enhance FIELDWIDTHS syntax to support a skip prefix, and unify logic with 
API field parsing.

diff --git a/ChangeLog b/ChangeLog
index 176142c..feea67a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,43 @@
+2017-03-21         Andrew J. Schorr     <address@hidden>
+
+       * gawkapi.h (awk_fieldwidth_info_t): Define new structure to contain
+       API field parsing info, replacing the previous awk_input_field_info_t
+       array.
+       (awk_fieldwidth_info_size): Define macro to calculate size of the
+       variable-length awk_fieldwidth_info_t structure.
+       (awk_input_buf_t): Update get_record prototype to update the type
+       of the final field_width argument from 'const awk_input_field_info_t **'
+       to 'const awk_fieldwidth_info_t **'.
+       * awk.h (set_record): Change 3rd argument from
+       'const awk_input_field_info_t *' to 'const awk_fieldwidth_info_t *'.
+       * io.c (inrec, do_getline_redir, do_getline): Change field_width type
+       from 'const awk_input_field_info_t *' to
+       'const awk_fieldwidth_info_t *'.
+       (get_a_record): Change field_width argument type from
+       'const awk_input_field_info_t **' to 'const awk_fieldwidth_info_t **'.
+       * field.c (api_parser_override): Define new boolean to track whether
+       API parsing is currently overriding default parsing behavior.
+       (api_fw): Change type from 'const awk_input_field_info_t *'
+       to 'const awk_fieldwidth_info_t *'.
+       (FIELDWIDTHS): Change type from 'int *' to 'awk_fieldwidth_info_t *'.
+       (set_record): Use new boolean api_parser_override to track whether
+       API parsing override is in effect, since we can no longer discern
+       this from the value of parse_field -- FIELDWIDTHS parsing uses the
+       same function.
+       (calc_mbslen): New function to calculate the length of a multi-byte 
+       string.
+       (fw_parse_field): Enhance to support the awk_fieldwidth_info_t 
+       structure instead of simply using an array of integer field widths.
+       (api_parse_field): Remove function no longer needed since fw_parse_field
+       now supports both FIELDWIDTHS and API parsing.
+       (set_parser): Use api_parser_override instead of comparing parse_field
+       to api_parse_field.
+       (set_FIELDWIDTHS): Enhance to use new awk_fieldwidth_info_t structure
+       and parse new skip prefix for each field.
+       (current_field_sep): Use api_parser_override flag instead of comparing
+       to api_parse_field.
+       (current_field_sep_str): Ditto.
+
 2017-03-20         Arnold D. Robbins     <address@hidden>
 
        Improve handling of EPIPE. Problems reported by
diff --git a/awk.h b/awk.h
index 1935534..43d2713 100644
--- a/awk.h
+++ b/awk.h
@@ -1510,7 +1510,7 @@ extern NODE *get_actual_argument(NODE *, int, bool);
 #endif
 /* field.c */
 extern void init_fields(void);
-extern void set_record(const char *buf, int cnt, const awk_input_field_info_t 
*);
+extern void set_record(const char *buf, int cnt, const awk_fieldwidth_info_t 
*);
 extern void reset_record(void);
 extern void rebuild_record(void);
 extern void set_NF(void);
diff --git a/extension/ChangeLog b/extension/ChangeLog
index bb99f9d..7aeb8aa 100644
--- a/extension/ChangeLog
+++ b/extension/ChangeLog
@@ -1,3 +1,14 @@
+2017-03-21         Andrew J. Schorr     <address@hidden>
+
+       * readdir_test.c (open_directory_t): Replace field_width array
+       with new awk_fieldwidth_info_t structure. Wrap it in a union so
+       we can allocate the proper size.
+       (dir_get_record): Update field_width type from
+       'const awk_input_field_info_t **' to 'const awk_fieldwidth_info_t **'.
+       Update new fieldwidth parsing info appropriately.
+       (dir_take_control_of): Populate new fieldwidth parsing structure
+       with initial values.
+
 2017-03-09         Andrew J. Schorr     <address@hidden>
 
        * readdir_test.c (open_directory_t): Update field_width type from an
diff --git a/extension/readdir_test.c b/extension/readdir_test.c
index e023b67..d21b4e9 100644
--- a/extension/readdir_test.c
+++ b/extension/readdir_test.c
@@ -85,8 +85,12 @@ int plugin_is_GPL_compatible;
 typedef struct open_directory {
        DIR *dp;
        char *buf;
-       awk_input_field_info_t field_width[4];
+       union {
+               awk_fieldwidth_info_t fw;
+               char buf[awk_fieldwidth_info_size(3)];
+       } u;
 } open_directory_t;
+#define fw u.fw
 
 /* ftype --- return type of file as a single character string */
 
@@ -170,7 +174,7 @@ get_inode(struct dirent *entry, const char *dirname)
 static int
 dir_get_record(char **out, awk_input_buf_t *iobuf, int *errcode,
                char **rt_start, size_t *rt_len,
-               const awk_input_field_info_t **field_width)
+               const awk_fieldwidth_info_t **field_width)
 {
        DIR *dp;
        struct dirent *dirent;
@@ -207,20 +211,20 @@ dir_get_record(char **out, awk_input_buf_t *iobuf, int 
*errcode,
 #else
        len = sprintf(the_dir->buf, "%llu", ino);
 #endif
-       the_dir->field_width[0].len = len;
+       the_dir->fw.fields[0].len = len;
        len += (flen = sprintf(the_dir->buf + len, "/%s", dirent->d_name));
-       the_dir->field_width[1].len = flen-1;
+       the_dir->fw.fields[1].len = flen-1;
 
        ftstr = ftype(dirent, iobuf->name);
        len += (flen = sprintf(the_dir->buf + len, "/%s", ftstr));
-       the_dir->field_width[2].len = flen-1;
+       the_dir->fw.fields[2].len = flen-1;
 
        *out = the_dir->buf;
 
        *rt_start = NULL;
        *rt_len = 0;    /* set RT to "" */
        if (field_width)
-               *field_width = the_dir->field_width;
+               *field_width = & the_dir->fw;
        return len;
 }
 
@@ -284,11 +288,12 @@ dir_take_control_of(awk_input_buf_t *iobuf)
 
        emalloc(the_dir, open_directory_t *, sizeof(open_directory_t), 
"dir_take_control_of");
        the_dir->dp = dp;
-       /* pre-populate the field_width array with constant values: */
-       the_dir->field_width[0].skip = 0;       /* no leading space */
-       the_dir->field_width[1].skip = 1;       /* single '/' separator */
-       the_dir->field_width[2].skip = 1;       /* single '/' separator */
-       the_dir->field_width[3].skip = -1;      /* terminate after 3 fields */
+       /* pre-populate the field_width struct with constant values: */
+       the_dir->fw.use_chars = awk_false;
+       the_dir->fw.nf = 3;
+       the_dir->fw.fields[0].skip = 0; /* no leading space */
+       the_dir->fw.fields[1].skip = 1; /* single '/' separator */
+       the_dir->fw.fields[2].skip = 1; /* single '/' separator */
        size = sizeof(struct dirent) + 21 /* max digits in inode */ + 2 /* 
slashes */;
        emalloc(the_dir->buf, char *, size, "dir_take_control_of");
 
diff --git a/field.c b/field.c
index 5ef4d74..bd333c9 100644
--- a/field.c
+++ b/field.c
@@ -38,6 +38,8 @@ is_blank(int c)
 
 typedef void (* Setfunc)(long, char *, long, NODE *);
 
+/* is the API currently overriding the default parsing mechanism? */
+static bool api_parser_override = false;
 static long (*parse_field)(long, char **, int, NODE *,
                             Regexp *, Setfunc, NODE *, NODE *, bool);
 /*
@@ -57,9 +59,7 @@ static long sc_parse_field(long, char **, int, NODE *,
                             Regexp *, Setfunc, NODE *, NODE *, bool);
 static long fw_parse_field(long, char **, int, NODE *,
                             Regexp *, Setfunc, NODE *, NODE *, bool);
-static long api_parse_field(long, char **, int, NODE *,
-                            Regexp *, Setfunc, NODE *, NODE *, bool);
-static const awk_input_field_info_t *api_fw = NULL;
+static const awk_fieldwidth_info_t *api_fw = NULL;
 static long fpat_parse_field(long, char **, int, NODE *,
                             Regexp *, Setfunc, NODE *, NODE *, bool);
 static void set_element(long num, char * str, long len, NODE *arr);
@@ -74,7 +74,7 @@ static bool resave_fs;
 static NODE *save_FS;          /* save current value of FS when line is read,
                                 * to be used in deferred parsing
                                 */
-static int *FIELDWIDTHS = NULL;
+static awk_fieldwidth_info_t *FIELDWIDTHS = NULL;
 
 NODE **fields_arr;             /* array of pointers to the field nodes */
 bool field0_valid;             /* $(>0) has not been changed yet */
@@ -262,7 +262,7 @@ rebuild_record()
  * but better correct than fast.
  */
 void
-set_record(const char *buf, int cnt, const awk_input_field_info_t *fw)
+set_record(const char *buf, int cnt, const awk_fieldwidth_info_t *fw)
 {
        NODE *n;
        static char *databuf;
@@ -318,11 +318,13 @@ set_record(const char *buf, int cnt, const 
awk_input_field_info_t *fw)
        fields_arr[0] = n;
        if (fw != api_fw) {
                if ((api_fw = fw) != NULL) {
-                       if (parse_field != api_parse_field) {
-                               parse_field = api_parse_field;
+                       if (! api_parser_override) {
+                               api_parser_override = true;
+                               parse_field = fw_parse_field;
                                update_PROCINFO_str("FS", "API");
                        }
-               } else if (parse_field != normal_parse_field) {
+               } else if (api_parser_override) {
+                       api_parser_override = false;
                        parse_field = normal_parse_field;
                        update_PROCINFO_str("FS", current_field_sep_str());
                }
@@ -712,83 +714,38 @@ sc_parse_field(long up_to,        /* parse only up to 
this field number */
 }
 
 /*
- * fw_parse_field --- field parsing using FIELDWIDTHS spec
- *
- * This is called from get_field() via (*parse_field)().
- * This variation is for fields are fixed widths.
+ * calc_mbslen --- calculate the length in bytes of a multi-byte string
+ * containing len characters.
  */
-static long
-fw_parse_field(long up_to,     /* parse only up to this field number */
-       char **buf,     /* on input: string to parse; on output: point to start 
next */
-       int len,
-       NODE *fs ATTRIBUTE_UNUSED,
-       Regexp *rp ATTRIBUTE_UNUSED,
-       Setfunc set,    /* routine to set the value of the parsed field */
-       NODE *n,
-       NODE *dummy ATTRIBUTE_UNUSED, /* sep_arr not needed here: hence dummy */
-       bool in_middle ATTRIBUTE_UNUSED)
+
+static size_t
+calc_mbslen(char *scan, char *end, size_t len, mbstate_t *mbs)
 {
-       char *scan = *buf;
-       long nf = parse_high_water;
-       char *end = scan + len;
-       int nmbc;
-       size_t mbclen;
-       size_t mbslen;
-       size_t lenrest;
-       char *mbscan;
-       mbstate_t mbs;
 
-       memset(&mbs, 0, sizeof(mbstate_t));
+       size_t mbclen;
+       char *mbscan = scan;
 
-       if (up_to == UNLIMITED)
-               nf = 0;
-       if (len == 0)
-               return nf;
-       for (; nf < up_to && (len = FIELDWIDTHS[nf+1]) != -1; ) {
-               if (gawk_mb_cur_max > 1) {
-                       nmbc = 0;
-                       mbslen = 0;
-                       mbscan = scan;
-                       lenrest = end - scan;
-                       while (nmbc < len && mbslen < lenrest) {
-                               mbclen = mbrlen(mbscan, end - mbscan, &mbs);
-                               if (   mbclen == 1
-                                   || mbclen == (size_t) -1
-                                   || mbclen == (size_t) -2
-                                   || mbclen == 0) {
-                                       /* We treat it as a singlebyte 
character.  */
-                                       mbclen = 1;
-                               }
-                               if (mbclen <= end - mbscan) {
-                                       mbscan += mbclen;
-                                       mbslen += mbclen;
-                                       ++nmbc;
-                               }
-                       }
-                       (*set)(++nf, scan, (long) mbslen, n);
-                       scan += mbslen;
-               } else {
-                       if (len > end - scan)
-                               len = end - scan;
-                       (*set)(++nf, scan, (long) len, n);
-                       scan += len;
-               }
+       while (len-- > 0 && mbscan < end) {
+               mbclen = mbrlen(mbscan, end - mbscan, mbs);
+               if (!(mbclen > 0 && mbclen <= (size_t)(end - mbscan)))
+                       /*
+                        * We treat it as a singlebyte character. This should
+                        * catch error codes 0, (size_t) -1, and (size_t) -2.
+                        */
+                       mbclen = 1;
+               mbscan += mbclen;
        }
-       if (len == -1)
-               *buf = end;
-       else
-               *buf = scan;
-       return nf;
+       return mbscan - scan;
 }
 
 /*
- * api_parse_field --- field parsing using field widths returned by API parser.
+ * fw_parse_field --- field parsing using FIELDWIDTHS spec
  *
  * This is called from get_field() via (*parse_field)().
+ * This variation is for fields are fixed widths.
  */
-
 static long
-api_parse_field(long up_to,    /* parse only up to this field number */
+fw_parse_field(long up_to,     /* parse only up to this field number */
        char **buf,     /* on input: string to parse; on output: point to start 
next */
        int len,
        NODE *fs ATTRIBUTE_UNUSED,
@@ -801,26 +758,50 @@ api_parse_field(long up_to,       /* parse only up to 
this field number */
        char *scan = *buf;
        long nf = parse_high_water;
        char *end = scan + len;
-       int skiplen;
+       const awk_fieldwidth_info_t *fw;
+       mbstate_t mbs;
+       size_t skiplen;
        size_t flen;
 
+       fw = (api_parser_override ? api_fw : FIELDWIDTHS);
+
        if (up_to == UNLIMITED)
                nf = 0;
        if (len == 0)
                return nf;
-       while (nf < up_to) {
-               if ((skiplen = api_fw[nf].skip) < 0) {
-                       *buf = end;
-                       return nf;
+       if (gawk_mb_cur_max > 1 && fw->use_chars) {
+               /*
+                * XXX This may be a bug. Most likely, shift state should
+                * persist across all fields in a record, if not across record
+                * boundaries as well.
+                */
+               memset(&mbs, 0, sizeof(mbstate_t));
+               while (nf < up_to) {
+                       if (nf >= fw->nf) {
+                               *buf = end;
+                               return nf;
+                       }
+                       scan += calc_mbslen(scan, end, fw->fields[nf].skip, 
&mbs);
+                       flen = calc_mbslen(scan, end, fw->fields[nf].len, &mbs);
+                       (*set)(++nf, scan, (long) flen, n);
+                       scan += flen;
+               }
+       } else {
+               while (nf < up_to) {
+                       if (nf >= fw->nf) {
+                               *buf = end;
+                               return nf;
+                       }
+                       skiplen = fw->fields[nf].skip;
+                       if (skiplen > end - scan)
+                               skiplen = end - scan;
+                       scan += skiplen;
+                       flen = fw->fields[nf].len;
+                       if (flen > end - scan)
+                               flen = end - scan;
+                       (*set)(++nf, scan, (long) flen, n);
+                       scan += flen;
                }
-               if (skiplen > end - scan)
-                       skiplen = end - scan;
-               scan += skiplen;
-               flen = api_fw[nf].len;
-               if (flen > end - scan)
-                       flen = end - scan;
-               (*set)(++nf, scan, (long) flen, n);
-               scan += flen;
        }
        *buf = scan;
        return nf;
@@ -1129,7 +1110,7 @@ static void
 set_parser(long (*func)(long, char **, int, NODE *, Regexp *, Setfunc, NODE *, 
NODE *, bool))
 {
        normal_parse_field = func;
-       if (parse_field != api_parse_field && parse_field != func) {
+       if (! api_parser_override && parse_field != func) {
                parse_field = func;
                update_PROCINFO_str("FS", current_field_sep_str());
        }
@@ -1156,7 +1137,7 @@ set_FIELDWIDTHS()
                return;
 
        /*
-        * If changing the way fields are split, obey least-suprise
+        * If changing the way fields are split, obey least-surprise
         * semantics, and force $0 to be split totally.
         */
        if (fields_arr != NULL)
@@ -1166,17 +1147,17 @@ set_FIELDWIDTHS()
        tmp = force_string(FIELDWIDTHS_node->var_value);
        scan = tmp->stptr;
 
-       if (FIELDWIDTHS == NULL)
-               emalloc(FIELDWIDTHS, int *, fw_alloc * sizeof(int), 
"set_FIELDWIDTHS");
-       FIELDWIDTHS[0] = 0;
-       for (i = 1; ; i++) {
+       if (FIELDWIDTHS == NULL) {
+               emalloc(FIELDWIDTHS, awk_fieldwidth_info_t *, 
awk_fieldwidth_info_size(fw_alloc), "set_FIELDWIDTHS");
+               FIELDWIDTHS->use_chars = awk_true;
+       }
+       FIELDWIDTHS->nf = 0;
+       for (i = 0; ; i++) {
                unsigned long int tmp;
-               if (i + 1 >= fw_alloc) {
+               if (i >= fw_alloc) {
                        fw_alloc *= 2;
-                       erealloc(FIELDWIDTHS, int *, fw_alloc * sizeof(int), 
"set_FIELDWIDTHS");
+                       erealloc(FIELDWIDTHS, awk_fieldwidth_info_t *, 
awk_fieldwidth_info_size(fw_alloc), "set_FIELDWIDTHS");
                }
-               /* Initialize value to be end of list */
-               FIELDWIDTHS[i] = -1;
                /* Ensure that there is no leading `-' sign.  Otherwise,
                   strtoul would accept it and return a bogus result.  */
                while (is_blank(*scan)) {
@@ -1194,6 +1175,13 @@ set_FIELDWIDTHS()
                   or a value that is not in the range [1..INT_MAX].  */
                errno = 0;
                tmp = strtoul(scan, &end, 10);
+               if (errno == 0 && *end == ':' && (0 < tmp && tmp <= INT_MAX)) {
+                       FIELDWIDTHS->fields[i].skip = tmp;
+                       scan = end + 1;
+                       tmp = strtoul(scan, &end, 10);
+               }
+               else
+                       FIELDWIDTHS->fields[i].skip = 0;
                if (errno != 0
                        || (*end != '\0' && ! is_blank(*end))
                                || !(0 < tmp && tmp <= INT_MAX)
@@ -1201,7 +1189,8 @@ set_FIELDWIDTHS()
                        fatal_error = true;
                        break;
                }
-               FIELDWIDTHS[i] = tmp;
+               FIELDWIDTHS->fields[i].len = tmp;
+               FIELDWIDTHS->nf = i+1;
                scan = end;
                /* Skip past any trailing blanks.  */
                while (is_blank(*scan)) {
@@ -1210,7 +1199,6 @@ set_FIELDWIDTHS()
                if (*scan == '\0')
                        break;
        }
-       FIELDWIDTHS[i+1] = -1;
 
        if (fatal_error)
                fatal(_("invalid FIELDWIDTHS value, near `%s'"),
@@ -1354,12 +1342,12 @@ choose_fs_function:
 field_sep_type
 current_field_sep()
 {
-       if (parse_field == fw_parse_field)
+       if (api_parser_override)
+               return Using_API;
+       else if (parse_field == fw_parse_field)
                return Using_FIELDWIDTHS;
        else if (parse_field == fpat_parse_field)
                return Using_FPAT;
-       else if (parse_field == api_parse_field)
-               return Using_API;
        else
                return Using_FS;
 }
@@ -1369,12 +1357,12 @@ current_field_sep()
 const char *
 current_field_sep_str()
 {
-       if (parse_field == fw_parse_field)
+       if (api_parser_override)
+               return "API";
+       else if (parse_field == fw_parse_field)
                return "FIELDWIDTHS";
        else if (parse_field == fpat_parse_field)
                return "FPAT";
-       else if (parse_field == api_parse_field)
-               return "API";
        else
                return "FS";
 }
diff --git a/gawkapi.h b/gawkapi.h
index e744a0f..1ea067f 100644
--- a/gawkapi.h
+++ b/gawkapi.h
@@ -119,16 +119,27 @@ typedef enum awk_bool {
 
 /*
  * If the input parser would like to specify the field positions in the input
- * record, it may populate an array of awk_input_field_info_t structures
- * to indicate the location of each field. The 0th array element contains
- * the information about field $1, and the NFth element should set skip
- * to a negative value. For both skip and len, the value should be in
- * bytes, not (potentially multi-byte) characters.
+ * record, it may populate an awk_fieldwidth_info_t structure to indicate
+ * the location of each field. The use_chars boolean controls whether the
+ * field lengths are specified in terms of bytes or potentially multi-byte
+ * characters. Performance will be better if the values are supplied in
+ * terms of bytes. The fields[0].skip value indicates how many bytes (or
+ * characters to skip) before $1, and fields[0].len is the length of $1, etc.
  */
 typedef struct {
-       int skip;       /* # of bytes to skip before field starts */
-       size_t len;     /* # of bytes in field */
-} awk_input_field_info_t;
+       awk_bool_t      use_chars;      /* false ==> use bytes */
+       size_t          nf;
+       struct awk_field_info {
+               size_t  skip;   /* # to skip before field starts */
+               size_t len;     /* length of field */
+       } fields[1];    /* actual dimension should be nf */
+} awk_fieldwidth_info_t;
+/*
+ * This macro calculates the total struct size needed. This is useful when
+ * calling malloc or realloc.
+ */
+#define awk_fieldwidth_info_size(NF) (sizeof(awk_fieldwidth_info_t) + \
+                       (((NF)-1) * sizeof(struct awk_field_info)))
 
 /* The information about input files that input parsers need to know: */
 typedef struct awk_input {
@@ -174,7 +185,7 @@ typedef struct awk_input {
         */
        int (*get_record)(char **out, struct awk_input *iobuf, int *errcode,
                        char **rt_start, size_t *rt_len,
-                       const awk_input_field_info_t **field_width);
+                       const awk_fieldwidth_info_t **field_width);
 
        /*
         * No argument prototype on read_func to allow for older systems
diff --git a/io.c b/io.c
index d1033fc..25b6bc9 100644
--- a/io.c
+++ b/io.c
@@ -287,7 +287,7 @@ static RECVALUE rsrescan(IOBUF *iop, struct recmatch *recm, 
SCANSTATE *state);
 
 static RECVALUE (*matchrec)(IOBUF *iop, struct recmatch *recm, SCANSTATE 
*state) = rs1scan;
 
-static int get_a_record(char **out, IOBUF *iop, int *errcode, const 
awk_input_field_info_t **field_width);
+static int get_a_record(char **out, IOBUF *iop, int *errcode, const 
awk_fieldwidth_info_t **field_width);
 
 static void free_rp(struct redirect *rp);
 
@@ -590,7 +590,7 @@ inrec(IOBUF *iop, int *errcode)
        char *begin;
        int cnt;
        bool retval = true;
-       const awk_input_field_info_t *field_width = NULL;
+       const awk_fieldwidth_info_t *field_width = NULL;
 
        if (at_eof(iop) && no_data_left(iop))
                cnt = EOF;
@@ -2638,7 +2638,7 @@ do_getline_redir(int into_variable, enum redirval 
redirtype)
        NODE *redir_exp = NULL;
        NODE **lhs = NULL;
        int redir_error = 0;
-       const awk_input_field_info_t *field_width = NULL;
+       const awk_fieldwidth_info_t *field_width = NULL;
 
        if (into_variable)
                lhs = POP_ADDRESS();
@@ -2707,7 +2707,7 @@ do_getline(int into_variable, IOBUF *iop)
        int cnt = EOF;
        char *s = NULL;
        int errcode;
-       const awk_input_field_info_t *field_width = NULL;
+       const awk_fieldwidth_info_t *field_width = NULL;
 
        if (iop == NULL) {      /* end of input */
                if (into_variable)
@@ -3676,8 +3676,8 @@ static int
 get_a_record(char **out,        /* pointer to pointer to data */
         IOBUF *iop,             /* input IOP */
         int *errcode,           /* pointer to error variable */
-        const awk_input_field_info_t **field_width)
-                               /* pointer to pointer to field_width array */
+        const awk_fieldwidth_info_t **field_width)
+                               /* pointer to pointer to field_width info */
 {
        struct recmatch recm;
        SCANSTATE state;
diff --git a/test/ChangeLog b/test/ChangeLog
index ad1b35b..46c5262 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -1,3 +1,8 @@
+2017-03-21         Andrew J. Schorr     <address@hidden>
+
+       * Makefile.am (fwtest2b): Add new test of enhanced FIELDWIDTHS syntax.
+       * fwtest2b.awk, fwtest2b.ok: New files.
+
 2017-03-19         Andrew J. Schorr     <address@hidden>
 
        * Makefile.am (argarray): Always copy argarray.in to the local
diff --git a/test/Makefile.am b/test/Makefile.am
index 855958f..b46f36e 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -385,6 +385,8 @@ EXTRA_DIST = \
        fwtest2.awk \
        fwtest2.in \
        fwtest2.ok \
+       fwtest2b.awk \
+       fwtest2b.ok \
        fwtest3.awk \
        fwtest3.in \
        fwtest3.ok \
@@ -1221,7 +1223,7 @@ GAWK_EXT_TESTS = \
        crlf dbugeval dbugeval2 dbugtypedre1 dbugtypedre2 delsub \
        devfd devfd1 devfd2 dumpvars errno exit \
        fieldwdth forcenum fpat1 fpat2 fpat3 fpat4 fpat5 fpatnull fsfwfs funlen 
\
-       functab1 functab2 functab3 fwtest fwtest2 fwtest3 \
+       functab1 functab2 functab3 fwtest fwtest2 fwtest2b fwtest3 \
        genpot gensub gensub2 gensub3 getlndir gnuops2 gnuops3 gnureops gsubind 
\
        icasefs icasers id igncdym igncfs ignrcas2 ignrcas4 ignrcase \
        incdupe incdupe2 incdupe3 incdupe4 incdupe5 incdupe6 incdupe7 \
@@ -2373,6 +2375,11 @@ arrdbg:
        @-$(CMP) "$(srcdir)"/address@hidden _$@ && rm -f _$@ 
"$(srcdir)"/address@hidden
 #      @-$(CMP) "$(srcdir)"/address@hidden _$@ && rm -f _$@ 
"$(srcdir)"/address@hidden || exit 0
 
+fwtest2b:
+       @echo $@
+       @AWKPATH="$(srcdir)" $(AWK) -f address@hidden  < "$(srcdir)"/fwtest2.in 
>_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+       @-$(CMP) "$(srcdir)"/address@hidden _$@ && rm -f _$@
+
 # Targets generated for other tests:
 include Maketests
 
diff --git a/test/Makefile.in b/test/Makefile.in
index c23156d..fe44973 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -643,6 +643,8 @@ EXTRA_DIST = \
        fwtest2.awk \
        fwtest2.in \
        fwtest2.ok \
+       fwtest2b.awk \
+       fwtest2b.ok \
        fwtest3.awk \
        fwtest3.in \
        fwtest3.ok \
@@ -1478,7 +1480,7 @@ GAWK_EXT_TESTS = \
        crlf dbugeval dbugeval2 dbugtypedre1 dbugtypedre2 delsub \
        devfd devfd1 devfd2 dumpvars errno exit \
        fieldwdth forcenum fpat1 fpat2 fpat3 fpat4 fpat5 fpatnull fsfwfs funlen 
\
-       functab1 functab2 functab3 fwtest fwtest2 fwtest3 \
+       functab1 functab2 functab3 fwtest fwtest2 fwtest2b fwtest3 \
        genpot gensub gensub2 gensub3 getlndir gnuops2 gnuops3 gnureops gsubind 
\
        icasefs icasers id igncdym igncfs ignrcas2 ignrcas4 ignrcase \
        incdupe incdupe2 incdupe3 incdupe4 incdupe5 incdupe6 incdupe7 \
@@ -2809,6 +2811,12 @@ arrdbg:
        @echo $@
        @$(AWK) -v "okfile=$(srcdir)/address@hidden" -f 
"$(srcdir)"/address@hidden | grep array_f >_$@
        @-$(CMP) "$(srcdir)"/address@hidden _$@ && rm -f _$@ 
"$(srcdir)"/address@hidden
+#      @-$(CMP) "$(srcdir)"/address@hidden _$@ && rm -f _$@ 
"$(srcdir)"/address@hidden || exit 0
+
+fwtest2b:
+       @echo $@
+       @AWKPATH="$(srcdir)" $(AWK) -f address@hidden  < "$(srcdir)"/fwtest2.in 
>_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+       @-$(CMP) "$(srcdir)"/address@hidden _$@ && rm -f _$@
 Gt-dummy:
 # file Maketests, generated from Makefile.am by the Gentests program
 addcomma:
@@ -4463,7 +4471,6 @@ time:
        @-$(CMP) "$(srcdir)"/address@hidden _$@ && rm -f _$@
 
 # end of file Maketests
-#      @-$(CMP) "$(srcdir)"/address@hidden _$@ && rm -f _$@ 
"$(srcdir)"/address@hidden || exit 0
 
 # Targets generated for other tests:
 
diff --git a/test/fwtest2b.awk b/test/fwtest2b.awk
new file mode 100644
index 0000000..5e96c1a
--- /dev/null
+++ b/test/fwtest2b.awk
@@ -0,0 +1,6 @@
+BEGIN {
+   FIELDWIDTHS = "2:13 2:13 2:13";
+}
+{
+   printf "%s|%s|%s\n", $1, $2, $3
+}
diff --git a/test/fwtest2b.ok b/test/fwtest2b.ok
new file mode 100644
index 0000000..f4d2823
--- /dev/null
+++ b/test/fwtest2b.ok
@@ -0,0 +1,12 @@
+ 0.4867373206| 1.3206333033|-0.2333178127
+ 0.5668176165| 1.3711756314|-0.2193558040
+ 0.4325251781| 1.3399488722|-0.1568307497
+ 0.4900487563| 1.3295759570|-0.2217392402
+-0.6790064191| 1.2536623801|-0.2955415433
+-0.6311440220| 1.2966579993|-0.2246692210
+-0.7209390351| 1.1783407099|-0.2539408209
+-0.6782473356| 1.2495242556|-0.2811436366
+-0.7062054082| 1.1223820964|-1.1619805834
+-0.6491590119| 1.1248946162|-1.0851579675
+-0.7948856821| 1.1208852325|-1.1259821556
+-0.7102549262| 1.1225121126|-1.1475381286

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog                |  40 ++++++++++
 awk.h                    |   2 +-
 extension/ChangeLog      |  11 +++
 extension/readdir_test.c |  27 ++++---
 field.c                  | 196 ++++++++++++++++++++++-------------------------
 gawkapi.h                |  29 ++++---
 io.c                     |  12 +--
 test/ChangeLog           |   5 ++
 test/Makefile.am         |   9 ++-
 test/Makefile.in         |  11 ++-
 test/fwtest2b.awk        |   6 ++
 test/fwtest2b.ok         |  12 +++
 12 files changed, 226 insertions(+), 134 deletions(-)
 create mode 100644 test/fwtest2b.awk
 create mode 100644 test/fwtest2b.ok


hooks/post-receive
-- 
gawk



reply via email to

[Prev in Thread] Current Thread [Next in Thread]