gawk-diffs
[Top][All Lists]
Advanced

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

[gawk-diffs] [SCM] gawk branch, select, created. gawk-4.1.0-54-g6959e2a


From: Andrew J. Schorr
Subject: [gawk-diffs] [SCM] gawk branch, select, created. gawk-4.1.0-54-g6959e2a
Date: Mon, 01 Jul 2013 00:58:37 +0000

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, select has been created
        at  6959e2ab216aeb1d5d8f07ce73cd8b9894b83006 (commit)

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

commit 6959e2ab216aeb1d5d8f07ce73cd8b9894b83006
Author: Andrew J. Schorr <address@hidden>
Date:   Sun Jun 30 20:57:03 2013 -0400

    Added first version of select extension and new API hooks needed by it.

diff --git a/ChangeLog b/ChangeLog
index 9cdaf0b..aed9b6f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2013-06-30         Andrew J. Schorr     <address@hidden>
+       * awk.h (redirect_string): Declare new function that provides API access
+       to the redirection mechanism.
+       * gawkapi.h (GAWK_API_MINOR_VERSION): Bump from 0 to 1 since 2 new
+       hooks were added to the api.
+       (gawk_api_t): Add 2 new functions api_lookup_file and api_get_file.
+       (lookup_file, get_file): New macros to wrap the new API functions.
+       * gawkapi.c (curfile): Declare this extern, since it is needed
+       by lookup_file and get_flie.
+       (api_lookup_file): Find an open file using curfile or getredirect().
+       (api_get_file): Find or open a file using curfile or redirect_string().
+       (api_impl): Add api_lookup_file and api_get_file.
+       * io.c (redirect_string): Renamed from redirect and changed arguments
+       to take a string instead of a 'NODE *'.  This allows it to be called
+       through the API's new get_file hook.
+       (redirect): Now implemented by calling redirect_string backend function.
+
 2013-06-27         Arnold D. Robbins     <address@hidden>
 
        * awkgram.y: Minor whitespace cleanup, remove redundant ifdef.
diff --git a/awk.h b/awk.h
index b9d3a1b..7ca401a 100644
--- a/awk.h
+++ b/awk.h
@@ -1517,6 +1517,7 @@ extern void set_FNR(void);
 extern void set_NR(void);
 
 extern struct redirect *redirect(NODE *redir_exp, int redirtype, int *errflg);
+extern struct redirect *redirect_string(char *redir_exp_str, size_t 
redir_exp_len, int not_string_flag, int redirtype, int *errflg);
 extern NODE *do_close(int nargs);
 extern int flush_io(void);
 extern int close_io(bool *stdio_problem);
diff --git a/extension/ChangeLog b/extension/ChangeLog
index 04159df..37cfccf 100644
--- a/extension/ChangeLog
+++ b/extension/ChangeLog
@@ -1,3 +1,12 @@
+2013-06-30         Andrew J. Schorr     <address@hidden>
+
+       * Makefile.am (pkgextension_LTLIBRARIES): Add select.la.
+       (select_la_SOURCES, select_la_LDFLAGS, select_la_LIBADD): Build new
+       select extension.
+       * configure.ac (AC_CHECK_HEADERS): Add signal.h.
+       (AC_CHECK_FUNCS): Add sigaction.
+       * select.c: Implement the new select extension.
+
 2013-06-10         Arnold D. Robbins     <address@hidden>
 
        * configure.ac (AC_HEADER_MAJOR): New macro added.
diff --git a/extension/Makefile.am b/extension/Makefile.am
index 7b52b14..58fc3df 100644
--- a/extension/Makefile.am
+++ b/extension/Makefile.am
@@ -42,6 +42,7 @@ pkgextension_LTLIBRARIES =    \
        revoutput.la    \
        revtwoway.la    \
        rwarray.la      \
+       select.la       \
        testext.la      \
        time.la
 
@@ -70,6 +71,10 @@ ordchr_la_SOURCES     = ordchr.c
 ordchr_la_LDFLAGS     = $(MY_MODULE_FLAGS)
 ordchr_la_LIBADD      = $(MY_LIBS)
 
+select_la_SOURCES     = select.c
+select_la_LDFLAGS     = $(MY_MODULE_FLAGS)
+select_la_LIBADD      = $(MY_LIBS)
+
 readdir_la_SOURCES    = readdir.c gawkdirfd.h
 readdir_la_LDFLAGS    = $(MY_MODULE_FLAGS)
 readdir_la_LIBADD     = $(MY_LIBS)
diff --git a/extension/Makefile.in b/extension/Makefile.in
index 8d0a286..97ee41f 100644
--- a/extension/Makefile.in
+++ b/extension/Makefile.in
@@ -203,6 +203,12 @@ rwarray_la_OBJECTS = $(am_rwarray_la_OBJECTS)
 rwarray_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
        $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
        $(rwarray_la_LDFLAGS) $(LDFLAGS) -o $@
+select_la_DEPENDENCIES = $(am__DEPENDENCIES_2)
+am_select_la_OBJECTS = select.lo
+select_la_OBJECTS = $(am_select_la_OBJECTS)
+select_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+       $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+       $(select_la_LDFLAGS) $(LDFLAGS) -o $@
 testext_la_DEPENDENCIES = $(am__DEPENDENCIES_2)
 am_testext_la_OBJECTS = testext.lo
 testext_la_OBJECTS = $(am_testext_la_OBJECTS)
@@ -253,12 +259,14 @@ SOURCES = $(filefuncs_la_SOURCES) $(fnmatch_la_SOURCES) \
        $(fork_la_SOURCES) $(inplace_la_SOURCES) $(ordchr_la_SOURCES) \
        $(readdir_la_SOURCES) $(readfile_la_SOURCES) \
        $(revoutput_la_SOURCES) $(revtwoway_la_SOURCES) \
-       $(rwarray_la_SOURCES) $(testext_la_SOURCES) $(time_la_SOURCES)
+       $(rwarray_la_SOURCES) $(select_la_SOURCES) \
+       $(testext_la_SOURCES) $(time_la_SOURCES)
 DIST_SOURCES = $(filefuncs_la_SOURCES) $(fnmatch_la_SOURCES) \
        $(fork_la_SOURCES) $(inplace_la_SOURCES) $(ordchr_la_SOURCES) \
        $(readdir_la_SOURCES) $(readfile_la_SOURCES) \
        $(revoutput_la_SOURCES) $(revtwoway_la_SOURCES) \
-       $(rwarray_la_SOURCES) $(testext_la_SOURCES) $(time_la_SOURCES)
+       $(rwarray_la_SOURCES) $(select_la_SOURCES) \
+       $(testext_la_SOURCES) $(time_la_SOURCES)
 RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
        ctags-recursive dvi-recursive html-recursive info-recursive \
        install-data-recursive install-dvi-recursive \
@@ -497,6 +505,7 @@ pkgextension_LTLIBRARIES = \
        revoutput.la    \
        revtwoway.la    \
        rwarray.la      \
+       select.la       \
        testext.la      \
        time.la
 
@@ -520,6 +529,9 @@ inplace_la_LIBADD = $(MY_LIBS)
 ordchr_la_SOURCES = ordchr.c
 ordchr_la_LDFLAGS = $(MY_MODULE_FLAGS)
 ordchr_la_LIBADD = $(MY_LIBS)
+select_la_SOURCES = select.c
+select_la_LDFLAGS = $(MY_MODULE_FLAGS)
+select_la_LIBADD = $(MY_LIBS)
 readdir_la_SOURCES = readdir.c gawkdirfd.h
 readdir_la_LDFLAGS = $(MY_MODULE_FLAGS)
 readdir_la_LIBADD = $(MY_LIBS)
@@ -664,6 +676,8 @@ revtwoway.la: $(revtwoway_la_OBJECTS) 
$(revtwoway_la_DEPENDENCIES) $(EXTRA_revtw
        $(AM_V_CCLD)$(revtwoway_la_LINK) -rpath $(pkgextensiondir) 
$(revtwoway_la_OBJECTS) $(revtwoway_la_LIBADD) $(LIBS)
 rwarray.la: $(rwarray_la_OBJECTS) $(rwarray_la_DEPENDENCIES) 
$(EXTRA_rwarray_la_DEPENDENCIES) 
        $(AM_V_CCLD)$(rwarray_la_LINK) -rpath $(pkgextensiondir) 
$(rwarray_la_OBJECTS) $(rwarray_la_LIBADD) $(LIBS)
+select.la: $(select_la_OBJECTS) $(select_la_DEPENDENCIES) 
$(EXTRA_select_la_DEPENDENCIES) 
+       $(AM_V_CCLD)$(select_la_LINK) -rpath $(pkgextensiondir) 
$(select_la_OBJECTS) $(select_la_LIBADD) $(LIBS)
 testext.la: $(testext_la_OBJECTS) $(testext_la_DEPENDENCIES) 
$(EXTRA_testext_la_DEPENDENCIES) 
        $(AM_V_CCLD)$(testext_la_LINK) -rpath $(pkgextensiondir) 
$(testext_la_OBJECTS) $(testext_la_LIBADD) $(LIBS)
 time.la: $(time_la_OBJECTS) $(time_la_DEPENDENCIES) 
$(EXTRA_time_la_DEPENDENCIES) 
@@ -686,6 +700,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
 @AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
 @AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
address@hidden@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
 @AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
 @AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
 @AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
diff --git a/extension/configh.in b/extension/configh.in
index 8571844..a7212dc 100644
--- a/extension/configh.in
+++ b/extension/configh.in
@@ -78,6 +78,12 @@
 /* Define to 1 if you have the `select' function. */
 #undef HAVE_SELECT
 
+/* Define to 1 if you have the `sigaction' function. */
+#undef HAVE_SIGACTION
+
+/* Define to 1 if you have the <signal.h> header file. */
+#undef HAVE_SIGNAL_H
+
 /* Define to 1 if you have the <stdint.h> header file. */
 #undef HAVE_STDINT_H
 
diff --git a/extension/configure b/extension/configure
index f59548c..02ff3dc 100755
--- a/extension/configure
+++ b/extension/configure
@@ -14002,7 +14002,8 @@ fi
   fi
 fi
 
-for ac_header in dirent.h fnmatch.h limits.h time.h sys/time.h sys/select.h 
sys/param.h
+for ac_header in dirent.h fnmatch.h limits.h time.h sys/time.h sys/select.h \
+               sys/param.h signal.h
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" 
"$ac_includes_default"
@@ -14017,7 +14018,8 @@ done
 
 
 for ac_func in fdopendir fnmatch gettimeofday \
-               getdtablesize nanosleep select GetSystemTimeAsFileTime
+               getdtablesize nanosleep select sigaction \
+               GetSystemTimeAsFileTime
 do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
diff --git a/extension/configure.ac b/extension/configure.ac
index d819ebf..5b95f96 100644
--- a/extension/configure.ac
+++ b/extension/configure.ac
@@ -67,10 +67,12 @@ else
 fi
 
 AC_HEADER_MAJOR
-AC_CHECK_HEADERS(dirent.h fnmatch.h limits.h time.h sys/time.h sys/select.h 
sys/param.h)
+AC_CHECK_HEADERS(dirent.h fnmatch.h limits.h time.h sys/time.h sys/select.h \
+               sys/param.h signal.h)
 
 AC_CHECK_FUNCS(fdopendir fnmatch gettimeofday \
-               getdtablesize nanosleep select GetSystemTimeAsFileTime)
+               getdtablesize nanosleep select sigaction \
+               GetSystemTimeAsFileTime)
 
 GAWK_FUNC_DIRFD
 GAWK_PREREQ_DIRFD
diff --git a/extension/select.c b/extension/select.c
new file mode 100644
index 0000000..f74ae25
--- /dev/null
+++ b/extension/select.c
@@ -0,0 +1,183 @@
+/*
+ * select.c - Builtin functions to provide select I/O multiplexing.
+ */
+
+/*
+ * Copyright (C) 2013 the Free Software Foundation, Inc.
+ * 
+ * This file is part of GAWK, the GNU implementation of the
+ * AWK Programming Language.
+ * 
+ * GAWK is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * GAWK is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "gawkapi.h"
+
+#include "gettext.h"
+#define _(msgid)  gettext(msgid)
+#define N_(msgid) msgid
+
+static const gawk_api_t *api;  /* for convenience macros to work */
+static awk_ext_id_t *ext_id;
+static const char *ext_version = "ordchr extension: version 1.0";
+static awk_bool_t (*init_func)(void) = NULL;
+
+int plugin_is_GPL_compatible;
+
+#if defined(HAVE_SELECT) && defined(HAVE_SYS_SELECT_H)
+#include <sys/select.h>
+#endif
+
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+
+/*  do_ord --- return numeric value of first char of string */
+
+static awk_value_t *
+do_select(int nargs, awk_value_t *result)
+{
+       static const char *argname[] = { "read", "write", "except" };
+       struct {
+               awk_value_t array;
+               awk_flat_array_t *flat;
+               fd_set bits;
+               int *array2fd;
+       } fds[3];
+       awk_value_t timeout_arg;
+       int i;
+       struct timeval maxwait;
+       struct timeval *timeout;
+       int nfds = 0;
+       int rc;
+
+       if (do_lint && nargs > 5)
+               lintwarn(ext_id, _("select: called with too many arguments"));
+
+#define EL     fds[i].flat->elements[j]
+       for (i = 0; i < sizeof(fds)/sizeof(fds[0]); i++) {
+               size_t j;
+
+               if (! get_argument(i, AWK_ARRAY, & fds[i].array)) {
+                       warning(ext_id, _("select: bad array parameter `%s'"), 
argname[i]);
+                       update_ERRNO_string(_("select: bad array parameter"));
+                       return make_number(-1, result);
+               }
+               /* N.B. flatten_array fails for empty arrays, so that's OK */
+               FD_ZERO(&fds[i].bits);
+               if (flatten_array(fds[i].array.array_cookie, &fds[i].flat)) {
+                       emalloc(fds[i].array2fd, int *, 
fds[i].flat->count*sizeof(int), "select");
+                       for (j = 0; j < fds[i].flat->count; j++) {
+                               fds[i].array2fd[j] = -1;
+                               switch (EL.index.val_type) {
+                               case AWK_NUMBER:
+                                       if (EL.index.num_value >= 0)
+                                               fds[i].array2fd[j] = 
EL.index.num_value;
+                                       if (fds[i].array2fd[j] != 
EL.index.num_value)
+                                               fds[i].array2fd[j] = -1;
+                                       break;
+                               case AWK_STRING:
+                                       if (EL.value.val_type == AWK_STRING) {
+                                               const awk_input_buf_t *buf;
+                                               if ((buf = 
get_file(EL.index.str_value.str, EL.index.str_value.len, 
EL.value.str_value.str, EL.value.str_value.len)) != NULL)
+                                                       fds[i].array2fd[j] = 
buf->fd;
+                                       }
+                                       break;
+                               }
+                               if (fds[i].array2fd[j] < 0) {
+                                       warning(ext_id, _("select: get_file 
failed"));
+                                       update_ERRNO_string(_("select: get_file 
failed"));
+                                       if (! 
release_flattened_array(fds[i].array.array_cookie, fds[i].flat))
+                                               warning(ext_id, _("select: 
release_flattened_array failed"));
+                                       free(fds[i].array2fd);
+                                       return make_number(-1, result);
+                               }
+                               FD_SET(fds[i].array2fd[j], &fds[i].bits);
+                               if (nfds <= fds[i].array2fd[j])
+                                       nfds = fds[i].array2fd[j]+1;
+                       }
+               }
+               else
+                       fds[i].flat = NULL;
+       }
+        if (get_argument(3, AWK_NUMBER, &timeout_arg)) {
+               double secs = timeout_arg.num_value;
+               if (secs < 0) {
+                       warning(ext_id, _("select: treating negative timeout as 
zero"));
+                       secs = 0;
+               }
+               maxwait.tv_sec = secs;
+               maxwait.tv_usec = (secs-(double)maxwait.tv_sec)*1000000.0;
+               timeout = &maxwait;
+       } else
+               timeout = NULL;
+       rc = select(nfds, &fds[0].bits, &fds[1].bits, &fds[2].bits, timeout);
+
+       if (rc < 0) {
+               update_ERRNO_int(errno);
+               /* bit masks are undefined, so delete all array entries */
+               for (i = 0; i < sizeof(fds)/sizeof(fds[0]); i++) {
+                       if (fds[i].flat) {
+                               size_t j;
+                               for (j = 0; j < fds[i].flat->count; j++)
+                                       EL.flags |= AWK_ELEMENT_DELETE;
+                               if (! 
release_flattened_array(fds[i].array.array_cookie, fds[i].flat))
+                                       warning(ext_id, _("select: 
release_flattened_array failed"));
+                               free(fds[i].array2fd);
+                       }
+               }
+               return make_number(rc, result);
+       }
+
+       for (i = 0; i < sizeof(fds)/sizeof(fds[0]); i++) {
+               if (fds[i].flat) {
+                       size_t j;
+                       /* remove array elements not set in the bit mask */
+                       for (j = 0; j < fds[i].flat->count; j++) {
+                               if (! FD_ISSET(fds[i].array2fd[j], 
&fds[i].bits))
+                                       EL.flags |= AWK_ELEMENT_DELETE;
+                       }
+                       if (! 
release_flattened_array(fds[i].array.array_cookie, fds[i].flat))
+                               warning(ext_id, _("select: 
release_flattened_array failed"));
+                       free(fds[i].array2fd);
+               }
+       }
+#undef EL
+
+       /* Set the return value */
+       return make_number(rc, result);
+}
+
+static awk_ext_func_t func_table[] = {
+       { "select", do_select, 5 },
+};
+
+/* define the dl_load function using the boilerplate macro */
+
+dl_load_func(func_table, select, "")
diff --git a/gawkapi.c b/gawkapi.c
index 61f91e8..78d6dbe 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 */
diff --git a/gawkapi.h b/gawkapi.h
index cc50bba..7bb9303 100644
--- a/gawkapi.h
+++ b/gawkapi.h
@@ -264,7 +264,7 @@ typedef struct awk_two_way_processor {
 /* Current version of the API. */
 enum {
        GAWK_API_MAJOR_VERSION = 1,
-       GAWK_API_MINOR_VERSION = 0
+       GAWK_API_MINOR_VERSION = 1
 };
 
 /* A number of typedefs related to different types of values. */
@@ -665,6 +665,27 @@ typedef struct gawk_api {
        awk_bool_t (*api_release_flattened_array)(awk_ext_id_t id,
                        awk_array_t a_cookie,
                        awk_flat_array_t *data);
+
+       /*
+        * Look up a currently open file.  If the name is NULL, it returns
+        * data for the currently open input file corresponding to FILENAME.
+        * If the file is not found, it returns NULL.
+        */
+       const awk_input_buf_t *(*api_lookup_file)(awk_ext_id_t id,
+                                                       const char *name,
+                                                       size_t name_len);
+       /*
+        * Look up a file.  If the name is NULL, it returns
+        * data for the currently open input file corresponding to FILENAME.
+        * If the file is not already open, it tries to open it.
+        * The "filetype" argument should be one of:
+        *    ">", ">>", "<", "|>", "|<", and "|&"
+        */
+       const awk_input_buf_t *(*api_get_file)(awk_ext_id_t id,
+                                               const char *name,
+                                               size_t name_len,
+                                               const char *filetype,
+                                               size_t typelen);
 } gawk_api_t;
 
 #ifndef GAWK   /* these are not for the gawk code itself! */
@@ -742,6 +763,12 @@ typedef struct gawk_api {
 #define release_value(value) \
        (api->api_release_value(ext_id, value))
 
+#define lookup_file(name, namelen) \
+       (api->api_lookup_file(ext_id, name, namelen))
+
+#define get_file(name, namelen, filetype, typelen) \
+       (api->api_get_file(ext_id, name, namelen, filetype, typelen))
+
 #define register_ext_version(version) \
        (api->api_register_ext_version(ext_id, version))
 
diff --git a/io.c b/io.c
index dc41aea..14b8df9 100644
--- a/io.c
+++ b/io.c
@@ -686,10 +686,9 @@ redflags2str(int flags)
 /* redirect --- Redirection for printf and print commands */
 
 struct redirect *
-redirect(NODE *redir_exp, int redirtype, int *errflg)
+redirect_string(char *str, size_t explen, int not_string, int redirtype, int 
*errflg)
 {
        struct redirect *rp;
-       char *str;
        int tflag = 0;
        int outflag = 0;
        const char *direction = "to";
@@ -736,18 +735,16 @@ redirect(NODE *redir_exp, int redirtype, int *errflg)
        default:
                cant_happen();
        }
-       if (do_lint && (redir_exp->flags & STRCUR) == 0)
+       if (do_lint && not_string)
                lintwarn(_("expression in `%s' redirection only has numeric 
value"),
                        what);
-       redir_exp = force_string(redir_exp);
-       str = redir_exp->stptr;
 
        if (str == NULL || *str == '\0')
                fatal(_("expression for `%s' redirection has null string 
value"),
                        what);
 
-       if (do_lint && (strncmp(str, "0", redir_exp->stlen) == 0
-                       || strncmp(str, "1", redir_exp->stlen) == 0))
+       if (do_lint && (strncmp(str, "0", explen) == 0
+                       || strncmp(str, "1", explen) == 0))
                lintwarn(_("filename `%s' for `%s' redirection may be result of 
logical expression"),
                                str, what);
 
@@ -785,8 +782,8 @@ redirect(NODE *redir_exp, int redirtype, int *errflg)
 #endif /* PIPES_SIMULATED */
 
                /* now check for a match */
-               if (strlen(rp->value) == redir_exp->stlen
-                   && memcmp(rp->value, str, redir_exp->stlen) == 0
+               if (strlen(rp->value) == explen
+                   && memcmp(rp->value, str, explen) == 0
                    && ((rp->flag & ~(RED_NOBUF|RED_EOF|RED_PTY)) == tflag
                        || (outflag != 0
                            && (rp->flag & (RED_FILE|RED_WRITE)) == outflag))) {
@@ -797,22 +794,24 @@ redirect(NODE *redir_exp, int redirtype, int *errflg)
                        if (do_lint && rpflag != newflag)
                                lintwarn(
                _("unnecessary mixing of `>' and `>>' for file `%.*s'"),
-                                       (int) redir_exp->stlen, rp->value);
+                                       (int) explen, rp->value);
 
                        break;
                }
        }
 
        if (rp == NULL) {
+               char *newstr;
                new_rp = true;
                if (save_rp != NULL) {
                        rp = save_rp;
                        efree(rp->value);
                } else
                        emalloc(rp, struct redirect *, sizeof(struct redirect), 
"redirect");
-               emalloc(str, char *, redir_exp->stlen + 1, "redirect");
-               memcpy(str, redir_exp->stptr, redir_exp->stlen);
-               str[redir_exp->stlen] = '\0';
+               emalloc(newstr, char *, explen + 1, "redirect");
+               memcpy(newstr, str, explen);
+               newstr[explen] = '\0';
+               str = newstr;
                rp->value = str;
                rp->flag = tflag;
                init_output_wrapper(& rp->output);
@@ -998,6 +997,15 @@ redirect(NODE *redir_exp, int redirtype, int *errflg)
        return rp;
 }
 
+struct redirect *
+redirect(NODE *redir_exp, int redirtype, int *errflg)
+{
+       int not_string = ((redir_exp->flags & STRCUR) == 0);
+       redir_exp = force_string(redir_exp);
+       return redirect_string(redir_exp->stptr, redir_exp->stlen, not_string,
+                               redirtype, errflg);
+}
+
 /* getredirect --- find the struct redirect for this file or pipe */
 
 struct redirect *

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


hooks/post-receive
-- 
gawk



reply via email to

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