From 6959e2ab216aeb1d5d8f07ce73cd8b9894b83006 Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Sun, 30 Jun 2013 20:57:03 -0400 Subject: Added first version of select extension and new API hooks needed by it. --- gawkapi.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) (limited to 'gawkapi.c') diff --git a/gawkapi.c b/gawkapi.c index 61f91e8c..78d6dbe4 100644 --- a/gawkapi.c +++ b/gawkapi.c @@ -25,6 +25,8 @@ #include "awk.h" +extern IOBUF *curfile; /* required by api_lookup_file and api_get_file */ + static awk_bool_t node_to_awk_value(NODE *node, awk_value_t *result, awk_valtype_t wanted); /* @@ -1028,6 +1030,84 @@ api_release_value(awk_ext_id_t id, awk_value_cookie_t value) return true; } +/* api_lookup_file --- return a handle to an open file */ + +static const awk_input_buf_t * +api_lookup_file(awk_ext_id_t id, const char *name, size_t namelen) +{ + const struct redirect *f; + + if ((name == NULL) || (namelen == 0)) { + if (curfile == NULL) + return NULL; + return &curfile->public; + } + if ((f = getredirect(name, namelen)) == NULL) + return NULL; + return &f->iop->public; +} + +/* api_get_file --- return a handle to an existing or newly opened file */ + +static const awk_input_buf_t * +api_get_file(awk_ext_id_t id, const char *name, size_t namelen, const char *filetype, size_t typelen) +{ + const struct redirect *f; + int flag; /* not used, sigh */ + enum redirval redirtype; + + if ((name == NULL) || (namelen == 0)) { + if (curfile == NULL) { + if (nextfile(& curfile, false) <= 0) + return NULL; + /* XXX Fix me! */ + fputs("Bug: need to call BEGINFILE!\n", stderr); + } + return &curfile->public; + } + redirtype = redirect_none; + switch (typelen) { + case 1: + switch (*filetype) { + case '<': + redirtype = redirect_input; + break; + case '>': + redirtype = redirect_output; + break; + } + break; + case 2: + switch (*filetype) { + case '>': + if (filetype[1] == '>') + redirtype = redirect_append; + break; + case '|': + switch (filetype[1]) { + case '>': + redirtype = redirect_pipe; + break; + case '<': + redirtype = redirect_pipein; + break; + case '&': + redirtype = redirect_twoway; + break; + } + break; + } + } + if (redirtype == redirect_none) { + warning(_("cannot open unrecognized file type `%s' for `%s'"), + filetype, name); + return NULL; + } + if ((f = redirect_string(name, namelen, 0, redirtype, &flag)) == NULL) + return NULL; + return &f->iop->public; +} + /* * Register a version string for this extension with gawk. */ @@ -1107,6 +1187,10 @@ gawk_api_t api_impl = { api_clear_array, api_flatten_array, api_release_flattened_array, + + /* Find/get open files */ + api_lookup_file, + api_get_file, }; /* init_ext_api --- init the extension API */ -- cgit v1.2.3 From 6ace1b5a655517a41be7d1633ec7592ad940c0e6 Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Tue, 2 Jul 2013 15:59:15 -0400 Subject: Patch gawkapi flatten_array to pass index values as strings in all cases! --- gawkapi.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'gawkapi.c') diff --git a/gawkapi.c b/gawkapi.c index 78d6dbe4..3fc23388 100644 --- a/gawkapi.c +++ b/gawkapi.c @@ -936,12 +936,17 @@ api_flatten_array(awk_ext_id_t id, for (i = j = 0; i < 2 * array->table_size; i += 2, j++) { NODE *index, *value; - index = force_string(list[i]); + index = list[i]; value = list[i + 1]; /* number or string or subarray */ - /* convert index and value to ext types */ + /* + * Convert index and value to ext types. Force the + * index to be a string, since indices are always + * conceptually strings, regardless of internal optimizations + * to treat them as integers in some cases. + */ if (! node_to_awk_value(index, - & (*data)->elements[j].index, AWK_UNDEFINED)) { + & (*data)->elements[j].index, AWK_STRING)) { fatal(_("api_flatten_array: could not convert index %d\n"), (int) i); } -- cgit v1.2.3 From 9ee8aeb59ad3b3873d52f3c9a2ab80b28c4c2c20 Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Tue, 2 Jul 2013 20:45:46 -0400 Subject: After the gawkapi get_file function opens a file, call the BEGINFILE block. --- gawkapi.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) (limited to 'gawkapi.c') diff --git a/gawkapi.c b/gawkapi.c index 3fc23388..e12e55d5 100644 --- a/gawkapi.c +++ b/gawkapi.c @@ -1054,6 +1054,9 @@ api_lookup_file(awk_ext_id_t id, const char *name, size_t namelen) /* api_get_file --- return a handle to an existing or newly opened file */ +extern INSTRUCTION *main_beginfile; +extern int currule; + static const awk_input_buf_t * api_get_file(awk_ext_id_t id, const char *name, size_t namelen, const char *filetype, size_t typelen) { @@ -1065,8 +1068,27 @@ api_get_file(awk_ext_id_t id, const char *name, size_t namelen, const char *file if (curfile == NULL) { if (nextfile(& curfile, false) <= 0) return NULL; - /* XXX Fix me! */ - fputs("Bug: need to call BEGINFILE!\n", stderr); + { + INSTRUCTION *pc = main_beginfile; + /* save execution state */ + int save_rule = currule; + char *save_source = source; + + while (1) { + if (!pc) + fatal(_("cannot find end of BEGINFILE rule")); + if (pc->opcode == Op_after_beginfile) + break; + pc = pc->nexti; + } + pc->opcode = Op_stop; + (void) (*interpret)(main_beginfile); + pc->opcode = Op_after_beginfile; + after_beginfile(& curfile); + /* restore execution state */ + currule = save_rule; + source = save_source; + } } return &curfile->public; } -- cgit v1.2.3 From d8bd9f5261761dd4ffca331d9c6055c48a0a332b Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Tue, 2 Jul 2013 20:52:25 -0400 Subject: Remove unused api_lookup_file hook. --- gawkapi.c | 28 +++++----------------------- 1 file changed, 5 insertions(+), 23 deletions(-) (limited to 'gawkapi.c') diff --git a/gawkapi.c b/gawkapi.c index e12e55d5..ac466249 100644 --- a/gawkapi.c +++ b/gawkapi.c @@ -25,7 +25,10 @@ #include "awk.h" -extern IOBUF *curfile; /* required by api_lookup_file and api_get_file */ +/* Declare some globals used by api_get_file: */ +extern IOBUF *curfile; +extern INSTRUCTION *main_beginfile; +extern int currule; static awk_bool_t node_to_awk_value(NODE *node, awk_value_t *result, awk_valtype_t wanted); @@ -1035,28 +1038,8 @@ api_release_value(awk_ext_id_t id, awk_value_cookie_t value) return true; } -/* api_lookup_file --- return a handle to an open file */ - -static const awk_input_buf_t * -api_lookup_file(awk_ext_id_t id, const char *name, size_t namelen) -{ - const struct redirect *f; - - if ((name == NULL) || (namelen == 0)) { - if (curfile == NULL) - return NULL; - return &curfile->public; - } - if ((f = getredirect(name, namelen)) == NULL) - return NULL; - return &f->iop->public; -} - /* api_get_file --- return a handle to an existing or newly opened file */ -extern INSTRUCTION *main_beginfile; -extern int currule; - static const awk_input_buf_t * api_get_file(awk_ext_id_t id, const char *name, size_t namelen, const char *filetype, size_t typelen) { @@ -1215,8 +1198,7 @@ gawk_api_t api_impl = { api_flatten_array, api_release_flattened_array, - /* Find/get open files */ - api_lookup_file, + /* Find/open a file */ api_get_file, }; -- cgit v1.2.3 From e3f20c041c078eacf648af94d9f012e4906359bb Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Thu, 6 Nov 2014 14:18:37 -0500 Subject: Enhance get_file API to return info about input and output and to enable extensions to create already-opened files or sockets. --- gawkapi.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'gawkapi.c') diff --git a/gawkapi.c b/gawkapi.c index 46aef7b6..00a101ea 100644 --- a/gawkapi.c +++ b/gawkapi.c @@ -1039,8 +1039,8 @@ api_release_value(awk_ext_id_t id, awk_value_cookie_t value) /* api_get_file --- return a handle to an existing or newly opened file */ -static const awk_input_buf_t * -api_get_file(awk_ext_id_t id, const char *name, size_t namelen, const char *filetype, size_t typelen) +static awk_bool_t +api_get_file(awk_ext_id_t id, const char *name, size_t namelen, const char *filetype, size_t typelen, int fd, const awk_input_buf_t **ibufp, const awk_output_buf_t **obufp) { const struct redirect *f; int flag; /* not used, sigh */ @@ -1049,7 +1049,7 @@ api_get_file(awk_ext_id_t id, const char *name, size_t namelen, const char *file if ((name == NULL) || (namelen == 0)) { if (curfile == NULL) { if (nextfile(& curfile, false) <= 0) - return NULL; + return awk_false; { INSTRUCTION *pc = main_beginfile; /* save execution state */ @@ -1072,7 +1072,9 @@ api_get_file(awk_ext_id_t id, const char *name, size_t namelen, const char *file source = save_source; } } - return &curfile->public; + *ibufp = &curfile->public; + *obufp = NULL; + return awk_true; } redirtype = redirect_none; switch (typelen) { @@ -1110,11 +1112,13 @@ api_get_file(awk_ext_id_t id, const char *name, size_t namelen, const char *file if (redirtype == redirect_none) { warning(_("cannot open unrecognized file type `%s' for `%s'"), filetype, name); - return NULL; + return awk_false; } - if ((f = redirect_string(name, namelen, 0, redirtype, &flag)) == NULL) - return NULL; - return &f->iop->public; + if ((f = redirect_string(name, namelen, 0, redirtype, &flag, fd)) == NULL) + return awk_false; + *ibufp = f->iop ? & f->iop->public : NULL; + *obufp = f->output.fp ? & f->output : NULL; + return awk_true; } /* -- cgit v1.2.3 From e36300be4deb7bbdeff17c8e896ac2f727e1477e Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Fri, 2 Jan 2015 16:44:33 -0500 Subject: Remove api_get_file typelen argument. --- gawkapi.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'gawkapi.c') diff --git a/gawkapi.c b/gawkapi.c index e2c0b1a0..a693621e 100644 --- a/gawkapi.c +++ b/gawkapi.c @@ -1043,7 +1043,7 @@ api_release_value(awk_ext_id_t id, awk_value_cookie_t value) /* api_get_file --- return a handle to an existing or newly opened file */ static awk_bool_t -api_get_file(awk_ext_id_t id, const char *name, size_t namelen, const char *filetype, size_t typelen, int fd, const awk_input_buf_t **ibufp, const awk_output_buf_t **obufp) +api_get_file(awk_ext_id_t id, const char *name, size_t namelen, const char *filetype, int fd, const awk_input_buf_t **ibufp, const awk_output_buf_t **obufp) { const struct redirect *f; int flag; /* not used, sigh */ @@ -1080,24 +1080,24 @@ api_get_file(awk_ext_id_t id, const char *name, size_t namelen, const char *file return awk_true; } redirtype = redirect_none; - switch (typelen) { - case 1: - switch (*filetype) { - case '<': + switch (filetype[0]) { + case '<': + if (filetype[1] == '\0') redirtype = redirect_input; - break; - case '>': + break; + case '>': + switch (filetype[1]) { + case '\0': redirtype = redirect_output; break; - } - break; - case 2: - switch (*filetype) { case '>': - if (filetype[1] == '>') + if (filetype[2] == '\0') redirtype = redirect_append; break; - case '|': + } + break; + case '|': + if (filetype[2] == '\0') { switch (filetype[1]) { case '>': redirtype = redirect_pipe; @@ -1109,8 +1109,8 @@ api_get_file(awk_ext_id_t id, const char *name, size_t namelen, const char *file redirtype = redirect_twoway; break; } - break; } + break; } if (redirtype == redirect_none) { warning(_("cannot open unrecognized file type `%s' for `%s'"), -- cgit v1.2.3 From 9121c3059288f36e004108e02ed4d826b84604e7 Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Tue, 6 Jan 2015 14:20:19 -0500 Subject: Fix bug so that extensions can create deferred arrays PROCINFO and ENVIRON properly. --- gawkapi.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) (limited to 'gawkapi.c') diff --git a/gawkapi.c b/gawkapi.c index a693621e..5630185c 100644 --- a/gawkapi.c +++ b/gawkapi.c @@ -579,10 +579,34 @@ api_sym_update(awk_ext_id_t id, if (node == NULL) { /* new value to be installed */ if (value->val_type == AWK_ARRAY) { + unsigned long nel; + array_node = awk_value_to_node(value); - node = install_symbol(estrdup((char *) name, strlen(name)), - Node_var_array); + /* + * use variable_create instead of install_symbol in + * case this is a deferred variable such as PROCINFO + * or ENVIRON + */ + node = variable_create(estrdup((char *) name, strlen(name)), Node_var_array); array_node->vname = node->vname; + if ((nel = assoc_length(node)) > 0) { + /* merge the 2 arrays */ + NODE **list; + NODE akind; + unsigned long i; + + akind.flags = (AINDEX|AVALUE); + list = node->alist(node, & akind); + for (i = 0; i < nel; i++) { + NODE **aptr; + aptr = assoc_lookup(array_node, list[2*i]); + unref(*aptr); + unref(list[2*i]); /* alist duped it */ + *aptr = dupnode(list[2*i+1]); + } + efree(list); + assoc_clear(node); + } *node = *array_node; freenode(array_node); value->array_cookie = node; /* pass new cookie back to extension */ -- cgit v1.2.3 From f38a8f801496ea91cef7a8507e2919f6586d0694 Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Tue, 6 Jan 2015 20:17:35 -0500 Subject: Fix bug in API deferred variable creation and add a test case. --- gawkapi.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) (limited to 'gawkapi.c') diff --git a/gawkapi.c b/gawkapi.c index 5630185c..e8879022 100644 --- a/gawkapi.c +++ b/gawkapi.c @@ -579,7 +579,7 @@ api_sym_update(awk_ext_id_t id, if (node == NULL) { /* new value to be installed */ if (value->val_type == AWK_ARRAY) { - unsigned long nel; + bool is_deferred; array_node = awk_value_to_node(value); /* @@ -587,27 +587,35 @@ api_sym_update(awk_ext_id_t id, * case this is a deferred variable such as PROCINFO * or ENVIRON */ - node = variable_create(estrdup((char *) name, strlen(name)), Node_var_array); - array_node->vname = node->vname; - if ((nel = assoc_length(node)) > 0) { - /* merge the 2 arrays */ + node = variable_create(estrdup((char *) name, strlen(name)), Node_var_array, & is_deferred); + if (is_deferred) { + /* + * merge the user-supplied elements into the + * already-existing array. Since ENVIRON + * has special array_funcs, we need to retain + * the auto-created array! + */ + unsigned long nel; NODE **list; NODE akind; unsigned long i; + nel = assoc_length(array_node); akind.flags = (AINDEX|AVALUE); - list = node->alist(node, & akind); + list = array_node->alist(array_node, & akind); for (i = 0; i < nel; i++) { NODE **aptr; - aptr = assoc_lookup(array_node, list[2*i]); + aptr = assoc_lookup(node, list[2*i]); unref(*aptr); unref(list[2*i]); /* alist duped it */ *aptr = dupnode(list[2*i+1]); } efree(list); - assoc_clear(node); + assoc_clear(array_node); + } else { + array_node->vname = node->vname; + *node = *array_node; } - *node = *array_node; freenode(array_node); value->array_cookie = node; /* pass new cookie back to extension */ } else { -- cgit v1.2.3 From 444afe9e4a9c70f0833f6a0a912651dd0d0e57aa Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Tue, 6 Jan 2015 21:28:12 -0500 Subject: The API should call the astore hook after array assignment. --- gawkapi.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'gawkapi.c') diff --git a/gawkapi.c b/gawkapi.c index e8879022..371a375c 100644 --- a/gawkapi.c +++ b/gawkapi.c @@ -605,10 +605,15 @@ api_sym_update(awk_ext_id_t id, list = array_node->alist(array_node, & akind); for (i = 0; i < nel; i++) { NODE **aptr; + NODE *elem; aptr = assoc_lookup(node, list[2*i]); unref(*aptr); + elem = *aptr = dupnode(list[2*i+1]); + if (elem->type == Node_var_array) + elem->parent_array = node; + if (node->astore != NULL) + (*node->astore)(node, list[2*i]); unref(list[2*i]); /* alist duped it */ - *aptr = dupnode(list[2*i+1]); } efree(list); assoc_clear(array_node); @@ -820,7 +825,6 @@ api_set_array_element(awk_ext_id_t id, awk_array_t a_cookie, tmp = awk_value_to_node(index); aptr = assoc_lookup(array, tmp); - unref(tmp); unref(*aptr); elem = *aptr = awk_value_to_node(value); if (elem->type == Node_var_array) { @@ -829,6 +833,9 @@ api_set_array_element(awk_ext_id_t id, awk_array_t a_cookie, index->str_value.len); make_aname(elem); } + if (array->astore != NULL) + (*array->astore)(array, tmp); + unref(tmp); return awk_true; } -- cgit v1.2.3 From 55aefdc29dde7eb585b7a553876313ecceec1d68 Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Wed, 7 Jan 2015 13:08:23 -0500 Subject: Remove stray call to make_aname in api_set_array_element. --- gawkapi.c | 1 - 1 file changed, 1 deletion(-) (limited to 'gawkapi.c') diff --git a/gawkapi.c b/gawkapi.c index 371a375c..749be178 100644 --- a/gawkapi.c +++ b/gawkapi.c @@ -831,7 +831,6 @@ api_set_array_element(awk_ext_id_t id, awk_array_t a_cookie, elem->parent_array = array; elem->vname = estrdup(index->str_value.str, index->str_value.len); - make_aname(elem); } if (array->astore != NULL) (*array->astore)(array, tmp); -- cgit v1.2.3 From 41483acb1969b24e336b11aaf3bfdc1dbdfe33a8 Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Thu, 8 Jan 2015 09:20:09 -0500 Subject: Revert changes to API deferred variable creation, since this should be done at lookup time. --- gawkapi.c | 45 ++++----------------------------------------- 1 file changed, 4 insertions(+), 41 deletions(-) (limited to 'gawkapi.c') diff --git a/gawkapi.c b/gawkapi.c index 749be178..f8d04986 100644 --- a/gawkapi.c +++ b/gawkapi.c @@ -579,48 +579,11 @@ api_sym_update(awk_ext_id_t id, if (node == NULL) { /* new value to be installed */ if (value->val_type == AWK_ARRAY) { - bool is_deferred; - array_node = awk_value_to_node(value); - /* - * use variable_create instead of install_symbol in - * case this is a deferred variable such as PROCINFO - * or ENVIRON - */ - node = variable_create(estrdup((char *) name, strlen(name)), Node_var_array, & is_deferred); - if (is_deferred) { - /* - * merge the user-supplied elements into the - * already-existing array. Since ENVIRON - * has special array_funcs, we need to retain - * the auto-created array! - */ - unsigned long nel; - NODE **list; - NODE akind; - unsigned long i; - - nel = assoc_length(array_node); - akind.flags = (AINDEX|AVALUE); - list = array_node->alist(array_node, & akind); - for (i = 0; i < nel; i++) { - NODE **aptr; - NODE *elem; - aptr = assoc_lookup(node, list[2*i]); - unref(*aptr); - elem = *aptr = dupnode(list[2*i+1]); - if (elem->type == Node_var_array) - elem->parent_array = node; - if (node->astore != NULL) - (*node->astore)(node, list[2*i]); - unref(list[2*i]); /* alist duped it */ - } - efree(list); - assoc_clear(array_node); - } else { - array_node->vname = node->vname; - *node = *array_node; - } + node = install_symbol(estrdup((char *) name, strlen(name)), + Node_var_array); + array_node->vname = node->vname; + *node = *array_node; freenode(array_node); value->array_cookie = node; /* pass new cookie back to extension */ } else { -- cgit v1.2.3 From f8fecb69346cbcd774a73a49322aeb8ddea73e44 Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Thu, 8 Jan 2015 09:41:19 -0500 Subject: When an extension calls sym_lookup on a deferred variable, it should always succeed. --- gawkapi.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'gawkapi.c') diff --git a/gawkapi.c b/gawkapi.c index f8d04986..0213936a 100644 --- a/gawkapi.c +++ b/gawkapi.c @@ -486,6 +486,16 @@ node_to_awk_value(NODE *node, awk_value_t *val, awk_valtype_t wanted) return ret; } +static NODE * +lookup_deferred(const char *name) +{ + NODE *node; + + if ((node = lookup(name)) != NULL) + return node; + return deferred_create(name); +} + /* * Symbol table access: * - No access to special variables (NF, etc.) @@ -516,7 +526,7 @@ api_sym_lookup(awk_ext_id_t id, if ( name == NULL || *name == '\0' || result == NULL - || (node = lookup(name)) == NULL) + || (node = lookup_deferred(name)) == NULL) return awk_false; if (is_off_limits_var(name)) /* a built-in variable */ @@ -574,7 +584,7 @@ api_sym_update(awk_ext_id_t id, return awk_false; } - node = lookup(name); + node = lookup_deferred(name); if (node == NULL) { /* new value to be installed */ -- cgit v1.2.3 From 2d3f4ffebcb451da84ceb8a4be58bbb23946ee6e Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Mon, 19 Jan 2015 13:56:58 -0500 Subject: Revert "When an extension calls sym_lookup on a deferred variable, it should always succeed." This reverts commit f8fecb69346cbcd774a73a49322aeb8ddea73e44. --- gawkapi.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) (limited to 'gawkapi.c') diff --git a/gawkapi.c b/gawkapi.c index 0213936a..f8d04986 100644 --- a/gawkapi.c +++ b/gawkapi.c @@ -486,16 +486,6 @@ node_to_awk_value(NODE *node, awk_value_t *val, awk_valtype_t wanted) return ret; } -static NODE * -lookup_deferred(const char *name) -{ - NODE *node; - - if ((node = lookup(name)) != NULL) - return node; - return deferred_create(name); -} - /* * Symbol table access: * - No access to special variables (NF, etc.) @@ -526,7 +516,7 @@ api_sym_lookup(awk_ext_id_t id, if ( name == NULL || *name == '\0' || result == NULL - || (node = lookup_deferred(name)) == NULL) + || (node = lookup(name)) == NULL) return awk_false; if (is_off_limits_var(name)) /* a built-in variable */ @@ -584,7 +574,7 @@ api_sym_update(awk_ext_id_t id, return awk_false; } - node = lookup_deferred(name); + node = lookup(name); if (node == NULL) { /* new value to be installed */ -- cgit v1.2.3 From 6522e5b623e083565229dc742336219a0dda1344 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Tue, 24 Mar 2015 22:58:20 +0200 Subject: General cleanups prepatory to merging. --- gawkapi.c | 53 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 31 insertions(+), 22 deletions(-) (limited to 'gawkapi.c') diff --git a/gawkapi.c b/gawkapi.c index 01bfa765..01ccdf2b 100644 --- a/gawkapi.c +++ b/gawkapi.c @@ -1044,42 +1044,48 @@ api_release_value(awk_ext_id_t id, awk_value_cookie_t value) /* api_get_file --- return a handle to an existing or newly opened file */ static awk_bool_t -api_get_file(awk_ext_id_t id, const char *name, size_t namelen, const char *filetype, int fd, const awk_input_buf_t **ibufp, const awk_output_buf_t **obufp) +api_get_file(awk_ext_id_t id, const char *name, size_t namelen, const char *filetype, + int fd, const awk_input_buf_t **ibufp, const awk_output_buf_t **obufp) { const struct redirect *f; int flag; /* not used, sigh */ enum redirval redirtype; - if ((name == NULL) || (namelen == 0)) { + if (name == NULL || namelen == 0) { if (curfile == NULL) { + INSTRUCTION *pc; + int save_rule; + char *save_source; + if (nextfile(& curfile, false) <= 0) return awk_false; - { - INSTRUCTION *pc = main_beginfile; - /* save execution state */ - int save_rule = currule; - char *save_source = source; - - while (1) { - if (!pc) - fatal(_("cannot find end of BEGINFILE rule")); - if (pc->opcode == Op_after_beginfile) - break; - pc = pc->nexti; - } - pc->opcode = Op_stop; - (void) (*interpret)(main_beginfile); - pc->opcode = Op_after_beginfile; - after_beginfile(& curfile); - /* restore execution state */ - currule = save_rule; - source = save_source; + + pc = main_beginfile; + /* save execution state */ + save_rule = currule; + save_source = source; + + while (1) { + if (!pc) + fatal(_("cannot find end of BEGINFILE rule")); + if (pc->opcode == Op_after_beginfile) + break; + pc = pc->nexti; } + pc->opcode = Op_stop; + (void) (*interpret)(main_beginfile); + pc->opcode = Op_after_beginfile; + after_beginfile(& curfile); + /* restore execution state */ + currule = save_rule; + source = save_source; } *ibufp = &curfile->public; *obufp = NULL; + return awk_true; } + redirtype = redirect_none; switch (filetype[0]) { case '<': @@ -1113,13 +1119,16 @@ api_get_file(awk_ext_id_t id, const char *name, size_t namelen, const char *file } break; } + if (redirtype == redirect_none) { warning(_("cannot open unrecognized file type `%s' for `%s'"), filetype, name); return awk_false; } + if ((f = redirect_string(name, namelen, 0, redirtype, &flag, fd, false)) == NULL) return awk_false; + *ibufp = f->iop ? & f->iop->public : NULL; *obufp = f->output.fp ? & f->output : NULL; return awk_true; -- cgit v1.2.3 From 9d43b510f74f63806279ce40f65245ea7e5b0d53 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Fri, 27 Mar 2015 06:32:13 +0300 Subject: Some more cleanups. Ready to merge! --- gawkapi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'gawkapi.c') diff --git a/gawkapi.c b/gawkapi.c index 01ccdf2b..9d8c6f36 100644 --- a/gawkapi.c +++ b/gawkapi.c @@ -1065,8 +1065,8 @@ api_get_file(awk_ext_id_t id, const char *name, size_t namelen, const char *file save_rule = currule; save_source = source; - while (1) { - if (!pc) + for (;;) { + if (pc == NULL) fatal(_("cannot find end of BEGINFILE rule")); if (pc->opcode == Op_after_beginfile) break; -- cgit v1.2.3