[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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [gawk-diffs] [SCM] gawk branch, select, created. gawk-4.1.0-54-g6959e2a,
Andrew J. Schorr <=