diff options
author | Andrew J. Schorr <aschorr@telemetry-investments.com> | 2017-03-09 20:44:09 -0500 |
---|---|---|
committer | Andrew J. Schorr <aschorr@telemetry-investments.com> | 2017-03-09 20:44:09 -0500 |
commit | 39c46265139aa8faf87160b30710876bde4c6ba9 (patch) | |
tree | 7d55e7d483a2e35ec675223cf0b3e5755b693a61 | |
parent | feb12baf11e39f60e57b988d29aa96bda4dddcff (diff) | |
download | egawk-39c46265139aa8faf87160b30710876bde4c6ba9.tar.gz egawk-39c46265139aa8faf87160b30710876bde4c6ba9.tar.bz2 egawk-39c46265139aa8faf87160b30710876bde4c6ba9.zip |
For API input field parsing, use an array of structs instead of an array of integers.
-rw-r--r-- | ChangeLog | 19 | ||||
-rw-r--r-- | awk.h | 2 | ||||
-rw-r--r-- | extension/ChangeLog | 7 | ||||
-rw-r--r-- | extension/readdir_test.c | 19 | ||||
-rw-r--r-- | field.c | 17 | ||||
-rw-r--r-- | gawkapi.h | 23 | ||||
-rw-r--r-- | io.c | 11 |
7 files changed, 69 insertions, 29 deletions
@@ -1,3 +1,22 @@ +2017-03-09 Andrew J. Schorr <aschorr@telemetry-investments.com> + + * gawkapi.h (awk_input_field_info_t): Define new structure to contain + API field parsing info. + (awk_input_buf_t): Update get_record prototype to use an array of + awk_input_field_info_t instead of integers. + * awk.h (set_record): Change 3rd argument from 'const int *' to + 'const awk_input_field_info_t *'. + * field.c (api_fw): Now points to an array of awk_input_field_info_t + instead of integers. + (set_record): Change 3rd argument to point to an array of + awk_input_field_info_t. + (api_parse_field): Update parsing logic to use awk_input_field_info_t + structures instead of an array of integers. + * io.c (inrec, do_getline_redir, do_getline): Change field_width type + from 'const int *' to 'const awk_input_field_info_t *'. + (get_a_record): Change field_width argument type from 'const int **' + to 'const awk_input_field_info_t **'. + 2017-03-09 Arnold D. Robbins <arnold@skeeve.com> * field.c: Minor style edits. @@ -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 int *); +extern void set_record(const char *buf, int cnt, const awk_input_field_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 5d9a194e..bb99f9d8 100644 --- a/extension/ChangeLog +++ b/extension/ChangeLog @@ -1,3 +1,10 @@ +2017-03-09 Andrew J. Schorr <aschorr@telemetry-investments.com> + + * readdir_test.c (open_directory_t): Update field_width type from an + array of integers to an array of awk_input_field_info_t. + (dir_get_record): Ditto. + (dir_take_control_of): Ditto. + 2017-03-07 Andrew J. Schorr <aschorr@telemetry-investments.com> * Makefile.am (pkgextension_LTLIBRARIES): Remove testext.la, since it diff --git a/extension/readdir_test.c b/extension/readdir_test.c index cc23081e..e023b67c 100644 --- a/extension/readdir_test.c +++ b/extension/readdir_test.c @@ -85,7 +85,7 @@ int plugin_is_GPL_compatible; typedef struct open_directory { DIR *dp; char *buf; - int field_width[7]; + awk_input_field_info_t field_width[4]; } open_directory_t; /* ftype --- return type of file as a single character string */ @@ -169,7 +169,8 @@ 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 int **field_width) + char **rt_start, size_t *rt_len, + const awk_input_field_info_t **field_width) { DIR *dp; struct dirent *dirent; @@ -206,13 +207,13 @@ 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[1] = len; + the_dir->field_width[0].len = len; len += (flen = sprintf(the_dir->buf + len, "/%s", dirent->d_name)); - the_dir->field_width[3] = flen-1; + the_dir->field_width[1].len = flen-1; ftstr = ftype(dirent, iobuf->name); len += (flen = sprintf(the_dir->buf + len, "/%s", ftstr)); - the_dir->field_width[5] = flen-1; + the_dir->field_width[2].len = flen-1; *out = the_dir->buf; @@ -284,10 +285,10 @@ 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] = 0; /* no leading space */ - the_dir->field_width[2] = 1; /* single slash sign separator*/ - the_dir->field_width[4] = 1; /* single slash sign separator*/ - the_dir->field_width[6] = -1; /* terminate it after 3 fields */ + 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 */ size = sizeof(struct dirent) + 21 /* max digits in inode */ + 2 /* slashes */; emalloc(the_dir->buf, char *, size, "dir_take_control_of"); @@ -59,7 +59,7 @@ 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 int *api_fw = NULL; +static const awk_input_field_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); @@ -262,7 +262,7 @@ rebuild_record() * but better correct than fast. */ void -set_record(const char *buf, int cnt, const int *fw) +set_record(const char *buf, int cnt, const awk_input_field_info_t *fw) { NODE *n; static char *databuf; @@ -802,24 +802,25 @@ api_parse_field(long up_to, /* parse only up to this field number */ long nf = parse_high_water; char *end = scan + len; int skiplen; + size_t flen; if (up_to == UNLIMITED) nf = 0; if (len == 0) return nf; while (nf < up_to) { - if (((skiplen = api_fw[2*nf]) < 0) || - ((len = api_fw[2*nf+1]) < 0)) { + if ((skiplen = api_fw[nf].skip) < 0) { *buf = end; return nf; } if (skiplen > end - scan) skiplen = end - scan; scan += skiplen; - if (len > end - scan) - len = end - scan; - (*set)(++nf, scan, (long) len, n); - scan += len; + flen = api_fw[nf].len; + if (flen > end - scan) + flen = end - scan; + (*set)(++nf, scan, (long) flen, n); + scan += flen; } *buf = scan; return nf; @@ -117,6 +117,19 @@ typedef enum awk_bool { awk_true } awk_bool_t; /* we don't use <stdbool.h> on purpose */ +/* + * 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. + */ +typedef struct { + int skip; /* # of bytes to skip before field starts */ + size_t len; /* # of bytes in field */ +} awk_input_field_info_t; + /* The information about input files that input parsers need to know: */ typedef struct awk_input { const char *name; /* filename */ @@ -149,12 +162,10 @@ typedef struct awk_input { * * If field_width is non-NULL, then its value will be initialized * to NULL, and the function may set it to point to an array of - * integers supplying field width information to override the default + * structures supplying field width information to override the default * gawk field parsing mechanism. The field_width array should have - * at least 2*NF+1 elements, and the value of field_width[2*NF] - * must be negative. The first entry field_width[0] should contain - * the number of bytes to skip before $1; field_width[1] contains - * the number of bytes in $1. Note that these values are specified + * at least NF+1 elements, and the value of field_width[NF].skip + * must be negative. Note that these values are specified * in bytes, not (potentially multi-byte) characters! And note that this * array will not be copied by gawk; it must persist at least until the * next call to get_record or close_func. Note that field_width will @@ -163,7 +174,7 @@ typedef struct awk_input { */ int (*get_record)(char **out, struct awk_input *iobuf, int *errcode, char **rt_start, size_t *rt_len, - const int **field_width); + const awk_input_field_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 int **field_width); +static int get_a_record(char **out, IOBUF *iop, int *errcode, const awk_input_field_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 int *field_width = NULL; + const awk_input_field_info_t *field_width = NULL; if (at_eof(iop) && no_data_left(iop)) cnt = EOF; @@ -2619,7 +2619,7 @@ do_getline_redir(int into_variable, enum redirval redirtype) NODE *redir_exp = NULL; NODE **lhs = NULL; int redir_error = 0; - const int *field_width = NULL; + const awk_input_field_info_t *field_width = NULL; if (into_variable) lhs = POP_ADDRESS(); @@ -2688,7 +2688,7 @@ do_getline(int into_variable, IOBUF *iop) int cnt = EOF; char *s = NULL; int errcode; - const int *field_width = NULL; + const awk_input_field_info_t *field_width = NULL; if (iop == NULL) { /* end of input */ if (into_variable) @@ -3657,7 +3657,8 @@ static int get_a_record(char **out, /* pointer to pointer to data */ IOBUF *iop, /* input IOP */ int *errcode, /* pointer to error variable */ - const int **field_width)/* pointer to pointer to field_width array */ + const awk_input_field_info_t **field_width) + /* pointer to pointer to field_width array */ { struct recmatch recm; SCANSTATE state; |