diff options
author | Andrew J. Schorr <aschorr@telemetry-investments.com> | 2017-03-21 13:22:18 -0400 |
---|---|---|
committer | Andrew J. Schorr <aschorr@telemetry-investments.com> | 2017-03-21 13:22:18 -0400 |
commit | d1bebd3cbf60fa25883271512cf63e0c3275e3ef (patch) | |
tree | 517a5e996e033120e73afbb4c265528909271fbc | |
parent | 489349d84fa92f69b2066240bc202a4f2777c465 (diff) | |
download | egawk-d1bebd3cbf60fa25883271512cf63e0c3275e3ef.tar.gz egawk-d1bebd3cbf60fa25883271512cf63e0c3275e3ef.tar.bz2 egawk-d1bebd3cbf60fa25883271512cf63e0c3275e3ef.zip |
Enhance FIELDWIDTHS syntax to support a skip prefix, and unify logic with API field parsing.
-rw-r--r-- | ChangeLog | 40 | ||||
-rw-r--r-- | awk.h | 2 | ||||
-rw-r--r-- | extension/ChangeLog | 11 | ||||
-rw-r--r-- | extension/readdir_test.c | 27 | ||||
-rw-r--r-- | field.c | 196 | ||||
-rw-r--r-- | gawkapi.h | 29 | ||||
-rw-r--r-- | io.c | 12 | ||||
-rw-r--r-- | test/ChangeLog | 5 | ||||
-rw-r--r-- | test/Makefile.am | 9 | ||||
-rw-r--r-- | test/Makefile.in | 11 | ||||
-rw-r--r-- | test/fwtest2b.awk | 6 | ||||
-rw-r--r-- | test/fwtest2b.ok | 12 |
12 files changed, 226 insertions, 134 deletions
@@ -1,3 +1,43 @@ +2017-03-21 Andrew J. Schorr <aschorr@telemetry-investments.com> + + * 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 <arnold@skeeve.com> Improve handling of EPIPE. Problems reported by @@ -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 bb99f9d8..7aeb8aaa 100644 --- a/extension/ChangeLog +++ b/extension/ChangeLog @@ -1,3 +1,14 @@ +2017-03-21 Andrew J. Schorr <aschorr@telemetry-investments.com> + + * 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 <aschorr@telemetry-investments.com> * 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 e023b67c..d21b4e97 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"); @@ -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"; } @@ -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 @@ -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 ad1b35b1..46c52626 100644 --- a/test/ChangeLog +++ b/test/ChangeLog @@ -1,3 +1,8 @@ +2017-03-21 Andrew J. Schorr <aschorr@telemetry-investments.com> + + * Makefile.am (fwtest2b): Add new test of enhanced FIELDWIDTHS syntax. + * fwtest2b.awk, fwtest2b.ok: New files. + 2017-03-19 Andrew J. Schorr <aschorr@telemetry-investments.com> * Makefile.am (argarray): Always copy argarray.in to the local diff --git a/test/Makefile.am b/test/Makefile.am index 855958f1..b46f36e3 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)"/$@.ok _$@ && rm -f _$@ "$(srcdir)"/$@.ok # @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ "$(srcdir)"/$@.ok || exit 0 +fwtest2b: + @echo $@ + @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/fwtest2.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ + # Targets generated for other tests: include Maketests diff --git a/test/Makefile.in b/test/Makefile.in index c23156df..fe449734 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)/$@.ok" -f "$(srcdir)"/$@.awk | grep array_f >_$@ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ "$(srcdir)"/$@.ok +# @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ "$(srcdir)"/$@.ok || exit 0 + +fwtest2b: + @echo $@ + @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/fwtest2.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ Gt-dummy: # file Maketests, generated from Makefile.am by the Gentests program addcomma: @@ -4463,7 +4471,6 @@ time: @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ # end of file Maketests -# @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ "$(srcdir)"/$@.ok || exit 0 # Targets generated for other tests: diff --git a/test/fwtest2b.awk b/test/fwtest2b.awk new file mode 100644 index 00000000..5e96c1aa --- /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 00000000..f4d28232 --- /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 |