gawk-diffs
[Top][All Lists]
Advanced

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

[gawk-diffs] [SCM] gawk branch, extgawk, updated. 40eefdd931066129d0bb2f


From: Arnold Robbins
Subject: [gawk-diffs] [SCM] gawk branch, extgawk, updated. 40eefdd931066129d0bb2f6144a0ec7741c6cc2b
Date: Wed, 25 Jul 2012 19:56:57 +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, extgawk has been updated
       via  40eefdd931066129d0bb2f6144a0ec7741c6cc2b (commit)
       via  4bb85f0f0e221c158b1a81af286acb422834c0fd (commit)
       via  3d2d6b46bf3325c0273b35a202184ab09d38e0cd (commit)
      from  0fff60287fb9cc41288b3373f47031ab3dd597ac (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

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

commit 40eefdd931066129d0bb2f6144a0ec7741c6cc2b
Author: Arnold D. Robbins <address@hidden>
Date:   Wed Jul 25 22:56:37 2012 +0300

    Remove translation of errno strings from API.

diff --git a/ChangeLog b/ChangeLog
index 6d09764..a80439a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1399,6 +1399,19 @@
        * pprint (profile.c): Add case for the new opcode.
        * print_instruction (debug.c): Ditto.
 
+       Take out translation for errno strings; extensions will
+       need to use their own domain.
+
+       * awk.h (enum errno_translate): Removed.
+       (update_ERRNO_string): Remove second translate paramater.
+       * eval.c (update_ERRNO_string): Remove second translate paramater
+       and code that used it.
+       * gawkapi.h (api_update_ERRNO_string): Remove third translate
+       parameter.
+       * gawkapi.c (api_update_ERRNO_string): Remove third translate
+       paramater and change call to update_ERRNO_string.
+       * io.c (do_close): Fix call to update_ERRNO_string.
+
 2011-07-15         Arnold D. Robbins     <address@hidden>
 
        * awk.h: Typo fix: "loner" --> longer. Thanks to Nelson Beebe.
diff --git a/awk.h b/awk.h
index fbb57b0..ddde04b 100644
--- a/awk.h
+++ b/awk.h
@@ -1477,8 +1477,7 @@ extern void set_BINMODE(void);
 extern void set_LINT(void);
 extern void set_TEXTDOMAIN(void);
 extern void update_ERRNO_int(int);
-enum errno_translate { TRANSLATE, DONT_TRANSLATE };
-extern void update_ERRNO_string(const char *string, enum errno_translate);
+extern void update_ERRNO_string(const char *string);
 extern void unset_ERRNO(void);
 extern void update_NR(void);
 extern void update_NF(void);
diff --git a/eval.c b/eval.c
index 9b3e8e0..f703787 100644
--- a/eval.c
+++ b/eval.c
@@ -1007,13 +1007,11 @@ update_ERRNO_int(int errcode)
        ERRNO_node->var_value = make_string(cp, strlen(cp));
 }
 
-/* update_ERRNO_string --- update ERRNO with optionally translated string */
+/* update_ERRNO_string --- update ERRNO */
 
 void
-update_ERRNO_string(const char *string, enum errno_translate translate)
+update_ERRNO_string(const char *string)
 {
-       if (translate == TRANSLATE)
-               string = gettext(string);
        unref(ERRNO_node->var_value);
        ERRNO_node->var_value = make_string(string, strlen(string));
 }
diff --git a/extension/ChangeLog b/extension/ChangeLog
index 939a6ae..9f60bd0 100644
--- a/extension/ChangeLog
+++ b/extension/ChangeLog
@@ -3,6 +3,8 @@
        * readdir.c: New file.
        * Makefile.am (readdir): New extension.
 
+       * time.c: Fix all calls to update_ERRNO_string.
+
 2012-07-20         Arnold D. Robbins     <address@hidden>
 
        * filefuncs.3am, fnmatch.3am, ordchr.3am, readfile.3am:
diff --git a/extension/time.c b/extension/time.c
index eb42eee..60e569a 100644
--- a/extension/time.c
+++ b/extension/time.c
@@ -97,7 +97,7 @@ do_gettimeofday(int nargs, awk_value_t *result)
 #else
        /* no way to retrieve system time on this platform */
        curtime = -1;
-       update_ERRNO_string("gettimeofday: not supported on this platform", 1);
+       update_ERRNO_string("gettimeofday: not supported on this platform");
 #endif
 
        return make_number(curtime, result);
@@ -121,13 +121,13 @@ do_sleep(int nargs, awk_value_t *result)
                lintwarn(ext_id, "sleep: called with too many arguments");
 
        if (! get_argument(0, AWK_NUMBER, &num)) {
-               update_ERRNO_string("sleep: missing required numeric argument", 
1);
+               update_ERRNO_string("sleep: missing required numeric argument");
                return make_number(-1, result);
        }
        secs = num.num_value;
 
        if (secs < 0) {
-               update_ERRNO_string("sleep: argument is negative", 1);
+               update_ERRNO_string("sleep: argument is negative");
                return make_number(-1, result);
        }
 
@@ -154,7 +154,7 @@ do_sleep(int nargs, awk_value_t *result)
 #else
        /* no way to sleep on this platform */
        rc = -1;
-       update_ERRNO_str("sleep: not supported on this platform", 1);
+       update_ERRNO_str("sleep: not supported on this platform");
 #endif
 
        return make_number(rc, result);
diff --git a/gawkapi.c b/gawkapi.c
index 09c9f39..b72a62a 100644
--- a/gawkapi.c
+++ b/gawkapi.c
@@ -241,12 +241,11 @@ api_update_ERRNO_int(awk_ext_id_t id, int errno_val)
 
 static void
 api_update_ERRNO_string(awk_ext_id_t id,
-                       const char *string,
-                       awk_bool_t translate)
+                       const char *string)
 {
        (void) id;
 
-       update_ERRNO_string(string, (translate ? TRANSLATE : DONT_TRANSLATE));
+       update_ERRNO_string(string);
 }
 
 /* api_unset_ERRNO --- unset ERRNO */
diff --git a/gawkapi.h b/gawkapi.h
index 5816200..b8422db 100644
--- a/gawkapi.h
+++ b/gawkapi.h
@@ -294,8 +294,7 @@ typedef struct gawk_api {
 
        /* Functions to update ERRNO */
        void (*api_update_ERRNO_int)(awk_ext_id_t id, int errno_val);
-       void (*api_update_ERRNO_string)(awk_ext_id_t id, const char *string,
-                       awk_bool_t translate);
+       void (*api_update_ERRNO_string)(awk_ext_id_t id, const char *string);
        void (*api_unset_ERRNO)(awk_ext_id_t id);
 
        /* Add a function to the interpreter, returns true upon success */
@@ -475,8 +474,8 @@ typedef struct gawk_api {
 #define register_input_parser(parser)  (api->api_register_input_parser(ext_id, 
parser))
 
 #define update_ERRNO_int(e)    (api->api_update_ERRNO_int(ext_id, e))
-#define update_ERRNO_string(str, translate) \
-       (api->api_update_ERRNO_string(ext_id, str, translate))
+#define update_ERRNO_string(str) \
+       (api->api_update_ERRNO_string(ext_id, str))
 #define unset_ERRNO()  (api->api_unset_ERRNO(ext_id))
 
 #define add_ext_func(func, ns) (api->api_add_ext_func(ext_id, func, ns))
diff --git a/io.c b/io.c
index 584e434..6cfc3ef 100644
--- a/io.c
+++ b/io.c
@@ -1018,7 +1018,7 @@ do_close(int nargs)
                if (! do_traditional) {
                        /* update ERRNO manually, using errno = ENOENT is a 
stretch. */
                        cp = _("close of redirection that was never opened");
-                       update_ERRNO_string(cp, DONT_TRANSLATE);
+                       update_ERRNO_string(cp);
                }
 
                DEREF(tmp);

http://git.sv.gnu.org/cgit/gawk.git/commit/?id=4bb85f0f0e221c158b1a81af286acb422834c0fd

commit 4bb85f0f0e221c158b1a81af286acb422834c0fd
Author: Arnold D. Robbins <address@hidden>
Date:   Wed Jul 25 22:38:28 2012 +0300

    Upate po/POTFILES.in.

diff --git a/po/ChangeLog b/po/ChangeLog
index d17674d..91cbd99 100644
--- a/po/ChangeLog
+++ b/po/ChangeLog
@@ -1,3 +1,7 @@
+2012-07-25         Arnold D. Robbins     <address@hidden>
+
+       * POTFILES.in: Brought up to date.
+
 2012-03-28         Arnold D. Robbins     <address@hidden>
 
        * 4.0.1: Release tar ball made.
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 807df33..3934d7f 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -1,17 +1,25 @@
 # List of source files containing translatable strings.
-# Copyright (C) 1999, 2002 Free Software Foundation, Inc.
+# Copyright (C) 1999, 2002, 2012 Free Software Foundation, Inc.
 
 array.c
 awkgram.c
 builtin.c
+cint_array.c
+command.c
+debug.c
+dfa.c
 eval.c
 ext.c
 field.c
+floatcomp.c
+gawkapi.c
 gawkmisc.c
 getopt.c
 getopt1.c
+int_array.c
 io.c
 main.c
+mpfr.c
 msg.c
 node.c
 posix/gawkmisc.c
@@ -19,6 +27,10 @@ profile.c
 random.c
 re.c
 regcomp.c
+regex.c
 regex_internal.c
 regexec.c
 replace.c
+str_array.c
+symbol.c
+version.c

http://git.sv.gnu.org/cgit/gawk.git/commit/?id=3d2d6b46bf3325c0273b35a202184ab09d38e0cd

commit 3d2d6b46bf3325c0273b35a202184ab09d38e0cd
Author: Arnold D. Robbins <address@hidden>
Date:   Wed Jul 25 22:34:19 2012 +0300

    Start refactoring iop handling. Add readdir extension.

diff --git a/ChangeLog b/ChangeLog
index 5ad8cef..6d09764 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,26 @@
+2012-07-25         Arnold D. Robbins     <address@hidden>
+
+       Start refactoring of IOBUF handling and turn "open hooks"
+       into "input parsers".
+
+       * awk.h (IOP_NOFREE_OBJ): Flag removed.
+       (register_input_parser): Renamed from register_open_hook.
+       * ext.c (load_ext): Make sure lib_name is not NULL.
+       * gawk_api.c (api_register_input_parser): Renamed from
+       api_register_open_hook.
+       * gawk_api.h (api_register_input_parser): Renamed from
+       api_register_open_hook.  Rework structure to have "do you want it"
+       and "take control of it" functions.
+       * io.c (iop_alloc): Remove third argument which is IOBUF pointer.
+       Always malloc it. Remove use of IOP_NOFREE_OBJ everywhere.
+       (find_input_parser): Renamed from find_open_hook.
+       (nextfile): Don't use static IOBUF.
+       (iop_close): Call close_func first. Then close fd or remap it
+       if it's still not INVALID_HANDLE.
+       (register_input_parser): Renamed from register_open_hook.
+       Use a FIFO list and check if more than one parser will accept the
+       file. If so, fatal error.
+
 2012-07-25         Andrew J. Schorr     <address@hidden>
 
        * configure.ac: Instead of using acl_shlibext for the shared library
diff --git a/awk.h b/awk.h
index a85fef8..fbb57b0 100644
--- a/awk.h
+++ b/awk.h
@@ -910,10 +910,9 @@ typedef struct iobuf {
 
        int flag;
 #              define  IOP_IS_TTY      1
-#              define  IOP_NOFREE_OBJ  2
-#              define  IOP_AT_EOF      4
-#              define  IOP_CLOSED      8
-#              define  IOP_AT_START    16
+#              define  IOP_AT_EOF      2
+#              define  IOP_CLOSED      4
+#              define  IOP_AT_START    8
 } IOBUF;
 
 typedef void (*Func_ptr)(void);
@@ -1543,7 +1542,7 @@ extern int isdirpunct(int c);
 
 /* io.c */
 extern void init_io(void);
-extern void register_open_hook(void *(*open_func)(IOBUF_PUBLIC *));
+extern void register_input_parser(awk_input_parser_t *input_parser);
 extern void set_FNR(void);
 extern void set_NR(void);
 
diff --git a/ext.c b/ext.c
index af6542d..17ade95 100644
--- a/ext.c
+++ b/ext.c
@@ -51,6 +51,9 @@ load_ext(const char *lib_name)
        if (do_traditional || do_posix)
                fatal(_("-l / @load are gawk extensions"));
 
+       if (lib_name == NULL)
+               fatal(_("load_ext: received NULL lib_name"));
+
        if ((dl = dlopen(lib_name, flags)) == NULL)
                fatal(_("load_ext: cannot open library `%s' (%s)\n"), lib_name,
                      dlerror());
@@ -60,6 +63,7 @@ load_ext(const char *lib_name)
        if (gpl_compat == NULL)
                fatal(_("load_ext: library `%s': does not define 
`plugin_is_GPL_compatible' (%s)\n"),
                                lib_name, dlerror());
+
        install_func = (int (*)(const gawk_api_t *const, awk_ext_id_t))
                                dlsym(dl, INIT_FUNC);
        if (install_func == NULL)
diff --git a/extension/ChangeLog b/extension/ChangeLog
index 80cb44d..939a6ae 100644
--- a/extension/ChangeLog
+++ b/extension/ChangeLog
@@ -1,3 +1,8 @@
+2012-07-25         Arnold D. Robbins     <address@hidden>
+
+       * readdir.c: New file.
+       * Makefile.am (readdir): New extension.
+
 2012-07-20         Arnold D. Robbins     <address@hidden>
 
        * filefuncs.3am, fnmatch.3am, ordchr.3am, readfile.3am:
diff --git a/extension/Makefile.am b/extension/Makefile.am
index abe778e..3296909 100644
--- a/extension/Makefile.am
+++ b/extension/Makefile.am
@@ -36,6 +36,7 @@ pkgextension_LTLIBRARIES =    \
        fnmatch.la      \
        fork.la         \
        ordchr.la       \
+       readdir.la      \
        readfile.la     \
        rwarray.la      \
        testext.la      \
@@ -51,6 +52,8 @@ fork_la_SOURCES       = fork.c
 fork_la_LDFLAGS       = $(MY_MODULE_FLAGS)
 ordchr_la_SOURCES     = ordchr.c
 ordchr_la_LDFLAGS     = $(MY_MODULE_FLAGS)
+readdir_la_SOURCES    = readdir.c
+readdir_la_LDFLAGS    = $(MY_MODULE_FLAGS)
 readfile_la_SOURCES   = readfile.c
 readfile_la_LDFLAGS   = $(MY_MODULE_FLAGS)
 rwarray_la_SOURCES    = rwarray.c
diff --git a/extension/Makefile.in b/extension/Makefile.in
index 71920fe..14c9e14 100644
--- a/extension/Makefile.in
+++ b/extension/Makefile.in
@@ -154,6 +154,12 @@ ordchr_la_OBJECTS = $(am_ordchr_la_OBJECTS)
 ordchr_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
        $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
        $(ordchr_la_LDFLAGS) $(LDFLAGS) -o $@
+readdir_la_LIBADD =
+am_readdir_la_OBJECTS = readdir.lo
+readdir_la_OBJECTS = $(am_readdir_la_OBJECTS)
+readdir_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+       $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+       $(readdir_la_LDFLAGS) $(LDFLAGS) -o $@
 readfile_la_LIBADD =
 am_readfile_la_OBJECTS = readfile.lo
 readfile_la_OBJECTS = $(am_readfile_la_OBJECTS)
@@ -192,11 +198,13 @@ LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) 
$(LIBTOOLFLAGS) \
        --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
        $(LDFLAGS) -o $@
 SOURCES = $(filefuncs_la_SOURCES) $(fnmatch_la_SOURCES) \
-       $(fork_la_SOURCES) $(ordchr_la_SOURCES) $(readfile_la_SOURCES) \
-       $(rwarray_la_SOURCES) $(testext_la_SOURCES) $(time_la_SOURCES)
+       $(fork_la_SOURCES) $(ordchr_la_SOURCES) $(readdir_la_SOURCES) \
+       $(readfile_la_SOURCES) $(rwarray_la_SOURCES) \
+       $(testext_la_SOURCES) $(time_la_SOURCES)
 DIST_SOURCES = $(filefuncs_la_SOURCES) $(fnmatch_la_SOURCES) \
-       $(fork_la_SOURCES) $(ordchr_la_SOURCES) $(readfile_la_SOURCES) \
-       $(rwarray_la_SOURCES) $(testext_la_SOURCES) $(time_la_SOURCES)
+       $(fork_la_SOURCES) $(ordchr_la_SOURCES) $(readdir_la_SOURCES) \
+       $(readfile_la_SOURCES) $(rwarray_la_SOURCES) \
+       $(testext_la_SOURCES) $(time_la_SOURCES)
 am__can_run_installinfo = \
   case $$AM_UPDATE_INFO_DIR in \
     n|no|NO) false;; \
@@ -349,6 +357,7 @@ pkgextension_LTLIBRARIES = \
        fnmatch.la      \
        fork.la         \
        ordchr.la       \
+       readdir.la      \
        readfile.la     \
        rwarray.la      \
        testext.la      \
@@ -363,6 +372,8 @@ fork_la_SOURCES = fork.c
 fork_la_LDFLAGS = $(MY_MODULE_FLAGS)
 ordchr_la_SOURCES = ordchr.c
 ordchr_la_LDFLAGS = $(MY_MODULE_FLAGS)
+readdir_la_SOURCES = readdir.c
+readdir_la_LDFLAGS = $(MY_MODULE_FLAGS)
 readfile_la_SOURCES = readfile.c
 readfile_la_LDFLAGS = $(MY_MODULE_FLAGS)
 rwarray_la_SOURCES = rwarray.c
@@ -471,6 +482,8 @@ fork.la: $(fork_la_OBJECTS) $(fork_la_DEPENDENCIES) 
$(EXTRA_fork_la_DEPENDENCIES
        $(fork_la_LINK) -rpath $(pkgextensiondir) $(fork_la_OBJECTS) 
$(fork_la_LIBADD) $(LIBS)
 ordchr.la: $(ordchr_la_OBJECTS) $(ordchr_la_DEPENDENCIES) 
$(EXTRA_ordchr_la_DEPENDENCIES) 
        $(ordchr_la_LINK) -rpath $(pkgextensiondir) $(ordchr_la_OBJECTS) 
$(ordchr_la_LIBADD) $(LIBS)
+readdir.la: $(readdir_la_OBJECTS) $(readdir_la_DEPENDENCIES) 
$(EXTRA_readdir_la_DEPENDENCIES) 
+       $(readdir_la_LINK) -rpath $(pkgextensiondir) $(readdir_la_OBJECTS) 
$(readdir_la_LIBADD) $(LIBS)
 readfile.la: $(readfile_la_OBJECTS) $(readfile_la_DEPENDENCIES) 
$(EXTRA_readfile_la_DEPENDENCIES) 
        $(readfile_la_LINK) -rpath $(pkgextensiondir) $(readfile_la_OBJECTS) 
$(readfile_la_LIBADD) $(LIBS)
 rwarray.la: $(rwarray_la_OBJECTS) $(rwarray_la_DEPENDENCIES) 
$(EXTRA_rwarray_la_DEPENDENCIES) 
@@ -490,6 +503,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/readdir.c b/extension/readdir.c
new file mode 100644
index 0000000..a39e0c3
--- /dev/null
+++ b/extension/readdir.c
@@ -0,0 +1,220 @@
+/*
+ * readdir.c --- Provide an open hook to read directories
+ *
+ * Arnold Robbins
+ * address@hidden
+ * Written 7/2012
+ */
+
+/*
+ * Copyright (C) 2012 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
+ */
+
+#define _BSD_SOURCE
+#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 <dirent.h>
+
+#include "config.h"
+#include "gawkapi.h"
+
+static const gawk_api_t *api;  /* for convenience macros to work */
+static awk_ext_id_t *ext_id;
+
+int plugin_is_GPL_compatible;
+
+/* ftype --- return type of file as a single character string */
+
+static const char *
+ftype(struct dirent *entry)
+{
+#ifdef DT_BLK
+       switch (entry->d_type) {
+       case DT_BLK:    return "b";
+       case DT_CHR:    return "c";
+       case DT_DIR:    return "d";
+       case DT_FIFO:   return "p";
+       case DT_LNK:    return "l";
+       case DT_REG:    return "f";
+       case DT_SOCK:   return "s";
+       default:
+       case DT_UNKNOWN:        return "u";
+       }
+#else
+       struct stat sbuf;
+
+       if (lstat(entry->d_name, & sbuf) < 0)
+               return "u";
+
+       switch (sbuf.st_mode & S_IFMT) {
+       case S_IFREG: return "f";
+       case S_IFBLK: return "b";
+       case S_IFCHR: return "c";
+       case S_IFDIR: return "d";
+#ifdef S_IFSOCK
+       case S_IFSOCK: return "s";
+#endif
+#ifdef S_IFIFO
+       case S_IFIFO: return "p";
+#endif
+#ifdef S_IFLNK
+       case S_IFLNK: return "l";
+#endif
+#ifdef S_IFDOOR        /* Solaris weirdness */
+       case S_IFDOOR: return "D";
+#endif /* S_IFDOOR */
+       }
+       return "u";
+#endif
+}
+
+
+/* dir_get_record --- get one record at a time out of a directory */
+
+static int
+dir_get_record(char **out, struct iobuf_public *iobuf, int *errcode)
+{
+       DIR *dp;
+       struct dirent *dirent;
+       char buf[1000];
+       size_t len;
+
+       if (out == NULL || iobuf == NULL || iobuf->opaque == NULL)
+               return EOF;
+
+       if (errcode != NULL)
+               *errcode = 0;
+
+       /* FIXME: Need stuff for setting RT */
+       dp = (DIR *) iobuf->opaque;
+       dirent = readdir(dp);
+       if (dirent == NULL)
+               return EOF;
+
+       sprintf(buf, "%ld/%s/%s", dirent->d_ino, dirent->d_name, ftype(dirent));
+       len = strlen(buf);
+       emalloc(*out, char *, len + 1, "dir_get_record");
+       strcpy(*out, buf);
+       return len;
+}
+
+/* dir_close --- close up when done */
+
+static void
+dir_close(struct iobuf_public *iobuf)
+{
+       DIR *dp;
+
+       if (iobuf == NULL || iobuf->opaque == NULL)
+               return;
+
+       dp = (DIR *) iobuf->opaque;
+       closedir(dp);
+       iobuf->fd = -1;
+}
+
+/* dir_can_take_file --- return true if we want the file */
+
+static int
+dir_can_take_file(IOBUF_PUBLIC *iobuf)
+{
+       struct stat sbuf;
+       int fd;
+
+       if (iobuf == NULL)
+               return 0;
+
+       fd = iobuf->fd;
+       return (fd >= 0 && fstat(fd, & sbuf) >= 0 && S_ISDIR(sbuf.st_mode));
+}
+
+/* dir_take_control_of --- set up input parser */
+
+static int
+dir_take_control_of(IOBUF_PUBLIC *iobuf)
+{
+       struct stat sbuf;
+       int fd;
+       DIR *dp = NULL;
+
+       if (iobuf == NULL)
+               return 0;
+
+       fd = iobuf->fd;
+       if (dir_can_take_file(iobuf)) {
+               dp = fdopendir(fd);
+               if (dp == NULL)
+                       return 0;
+
+               iobuf->opaque = dp;
+               iobuf->get_record = dir_get_record;
+               iobuf->close_func = dir_close;
+
+               return 1;
+       }
+
+       return 0;
+}
+
+static awk_input_parser_t readdir_parser = {
+       "readdir",
+       dir_can_take_file,
+       dir_take_control_of,
+       NULL
+};
+
+#ifdef TEST_DUPLICATE
+static awk_input_parser_t readdir_parser2 = {
+       "readdir2",
+       dir_can_take_file,
+       dir_take_control_of,
+       NULL
+};
+#endif
+
+int dl_load(const gawk_api_t *const api_p, awk_ext_id_t id) 
+{
+       api = api_p;
+       ext_id = id;
+
+       if (api->major_version != GAWK_API_MAJOR_VERSION
+           || api->minor_version < GAWK_API_MINOR_VERSION) {
+               fprintf(stderr, "readdir: version mismatch with gawk!\n");
+               fprintf(stderr, "\tmy version (%d, %d), gawk version (%d, 
%d)\n",
+                       GAWK_API_MAJOR_VERSION, GAWK_API_MINOR_VERSION,
+                       api->major_version, api->minor_version);
+               exit(1);
+       }
+
+
+       register_input_parser(& readdir_parser);
+#ifdef TEST_DUPLICATE
+       register_input_parser(& readdir_parser2);
+#endif
+
+       return 1;
+}
diff --git a/gawkapi.c b/gawkapi.c
index 9e1c109..09c9f39 100644
--- a/gawkapi.c
+++ b/gawkapi.c
@@ -215,14 +215,14 @@ api_lintwarn(awk_ext_id_t id, const char *format, ...)
        }
 }
 
-/* api_register_open_hook --- register an open hook; for opening files 
read-only */
+/* api_register_input_parser --- register an input_parser; for opening files 
read-only */
 
 static void
-api_register_open_hook(awk_ext_id_t id, void* (*open_func)(IOBUF_PUBLIC *))
+api_register_input_parser(awk_ext_id_t id, awk_input_parser_t *input_parser)
 {
        (void) id;
 
-       register_open_hook(open_func);
+       register_input_parser(input_parser);
 }
 
 /* Functions to update ERRNO */
@@ -942,7 +942,7 @@ gawk_api_t api_impl = {
        api_warning,
        api_lintwarn,
 
-       api_register_open_hook,
+       api_register_input_parser,
 
        api_update_ERRNO_int,
        api_update_ERRNO_string,
diff --git a/gawkapi.h b/gawkapi.h
index 90df629..5816200 100644
--- a/gawkapi.h
+++ b/gawkapi.h
@@ -69,6 +69,13 @@
 extern "C" {
 #endif
 
+/* This is used to keep the extension from modifying certain fields in some 
structs. */
+#ifdef GAWK
+#define awk_const
+#else
+#define awk_const const
+#endif
+
 /* portions of IOBUF that should be accessible to extension functions: */
 typedef struct iobuf_public {
        const char *name;       /* filename */
@@ -78,6 +85,14 @@ typedef struct iobuf_public {
        void (*close_func)(struct iobuf_public *);
 } IOBUF_PUBLIC;
 
+typedef struct input_parser {
+       const char *name;       /* name of parser */
+       int (*can_take_file)(IOBUF_PUBLIC *iobuf);
+       int (*take_control_of)(IOBUF_PUBLIC *iobuf);
+       struct input_parser *awk_const next;    /* for use by gawk */
+} awk_input_parser_t;
+
+
 #define GAWK_API_MAJOR_VERSION 0
 #define GAWK_API_MINOR_VERSION 0
 
@@ -156,13 +171,6 @@ typedef struct awk_element {
        awk_value_t     value;
 } awk_element_t;
 
-/* This is used to keep the extension from modifying certain fields. */
-#ifdef GAWK
-#define awk_const
-#else
-#define awk_const const
-#endif
-
 /*
  * A "flattened" array. See the description above for how
  * to use the elements contained herein.
@@ -281,8 +289,8 @@ typedef struct gawk_api {
        void (*api_warning)(awk_ext_id_t id, const char *format, ...);
        void (*api_lintwarn)(awk_ext_id_t id, const char *format, ...);
 
-       /* Register an open hook; for opening files read-only */
-       void (*api_register_open_hook)(awk_ext_id_t id, void* 
(*open_func)(IOBUF_PUBLIC *));
+       /* Register an input parser; for opening files read-only */
+       void (*api_register_input_parser)(awk_ext_id_t id, awk_input_parser_t 
*input_parser);
 
        /* Functions to update ERRNO */
        void (*api_update_ERRNO_int)(awk_ext_id_t id, int errno_val);
@@ -464,7 +472,7 @@ typedef struct gawk_api {
 #define warning                api->api_warning
 #define lintwarn       api->api_lintwarn
 
-#define register_open_hook(func)       (api->api_register_open_hook(ext_id, 
func))
+#define register_input_parser(parser)  (api->api_register_input_parser(ext_id, 
parser))
 
 #define update_ERRNO_int(e)    (api->api_update_ERRNO_int(ext_id, e))
 #define update_ERRNO_string(str, translate) \
diff --git a/io.c b/io.c
index ab204e0..584e434 100644
--- a/io.c
+++ b/io.c
@@ -203,12 +203,12 @@ static int close_redir(struct redirect *rp, bool 
exitwarn, two_way_close_type ho
 static int wait_any(int interesting);
 #endif
 static IOBUF *gawk_popen(const char *cmd, struct redirect *rp);
-static IOBUF *iop_alloc(int fd, const char *name, IOBUF *buf, bool 
do_openhooks);
+static IOBUF *iop_alloc(int fd, const char *name, bool do_input_parsers);
 static int gawk_pclose(struct redirect *rp);
 static int str2mode(const char *mode);
 static int two_way_open(const char *str, struct redirect *rp);
 static int pty_vs_pipe(const char *command);
-static void find_open_hook(IOBUF *iop);
+static void find_input_parser(IOBUF *iop);
 
 static RECVALUE rs1scan(IOBUF *iop, struct recmatch *recm, SCANSTATE *state);
 static RECVALUE rsnullscan(IOBUF *iop, struct recmatch *recm, SCANSTATE 
*state);
@@ -336,10 +336,14 @@ after_beginfile(IOBUF **curfile)
         * so delay check until now.
         */
 
-       find_open_hook(iop);
+       find_input_parser(iop);
 }
 
 /* nextfile --- move to the next input data file */
+/*
+ * Return value > 0 ----> run BEGINFILE block
+ * *curfile = NULL  ----> hit EOF, run ENDFILE block
+ */
 
 int
 nextfile(IOBUF **curfile, bool skipping)
@@ -347,7 +351,6 @@ nextfile(IOBUF **curfile, bool skipping)
        static long i = 1;
        static bool files = false;
        NODE *arg, *tmp;
-       static IOBUF mybuf;
        const char *fname;
        int fd = INVALID_HANDLE;
        int errcode = 0;
@@ -406,12 +409,11 @@ nextfile(IOBUF **curfile, bool skipping)
                                mpz_set_ui(MFNR, 0);
 #endif
                        FNR = 0;
-                       iop = *curfile = iop_alloc(fd, fname, & mybuf, false);
+                       iop = *curfile = iop_alloc(fd, fname, false);
                        if (fd == INVALID_HANDLE)
                                iop->errcode = errcode;
                        else
                                iop->errcode = 0;
-                       iop->flag |= IOP_NOFREE_OBJ;
                        return ++i;     /* run beginfile block */
                }
        }
@@ -427,8 +429,7 @@ nextfile(IOBUF **curfile, bool skipping)
                FILENAME_node->var_value = make_string("-", 1);
                FILENAME_node->var_value->flags |= MAYBE_NUM; /* be pedantic */
                fname = "-";
-               iop = *curfile = iop_alloc(fileno(stdin), fname, & mybuf, 
false);
-               iop->flag |= IOP_NOFREE_OBJ;
+               iop = *curfile = iop_alloc(fileno(stdin), fname, false);
 
                if (iop->public.fd == INVALID_HANDLE) {
                        errcode = errno;
@@ -539,11 +540,6 @@ iop_close(IOBUF *iop)
 
        if (iop == NULL)
                return 0;
-       if (iop->public.fd == INVALID_HANDLE) { /* from nextfile(...) above */
-               assert(iop->buf == NULL);
-               assert((iop->flag & IOP_NOFREE_OBJ) != 0);
-               return 0;
-       }       
 
        errno = 0;
 
@@ -555,16 +551,18 @@ iop_close(IOBUF *iop)
         * So we remap the standard file to /dev/null.
         * Thanks to Jim Meyering for the suggestion.
         */
-       if (iop->public.fd == fileno(stdin)
-           || iop->public.fd == fileno(stdout)
-           || iop->public.fd == fileno(stderr))
-               ret = remap_std_file(iop->public.fd);
-       else
-               ret = close(iop->public.fd);
-
        if (iop->public.close_func != NULL)
                iop->public.close_func(&iop->public);
 
+       if (iop->public.fd != INVALID_HANDLE) {
+               if (iop->public.fd == fileno(stdin)
+                   || iop->public.fd == fileno(stdout)
+                   || iop->public.fd == fileno(stderr))
+                       ret = remap_std_file(iop->public.fd);
+               else
+                       ret = close(iop->public.fd);
+       }
+
        if (ret == -1)
                warning(_("close of fd %d (`%s') failed (%s)"), iop->public.fd,
                                iop->public.name, strerror(errno));
@@ -595,8 +593,7 @@ iop_close(IOBUF *iop)
                efree(iop->buf);
                iop->buf = NULL;
        }
-       if ((iop->flag & IOP_NOFREE_OBJ) == 0)
-               efree(iop);
+       efree(iop);
        return ret == -1 ? 1 : 0;
 }
 
@@ -805,7 +802,7 @@ redirect(NODE *redir_exp, int redirtype, int *errflg)
                                /* do not free rp, saving it for reuse (save_rp 
= rp) */
                                return NULL;
                        }
-                       rp->iop = iop_alloc(fd, str, NULL, true);
+                       rp->iop = iop_alloc(fd, str, true);
                        break;
                case redirect_twoway:
                        direction = "to/from";
@@ -1618,10 +1615,7 @@ strictopen:
                if (openfd > fileno(stderr))
                        os_close_on_exec(openfd, name, "file", "");
        }
-       /*
-        * XXX: FIXME: if fd is INVALID_HANDLE, see if an open hook
-        * can do something.
-        */
+
        return openfd;
 }
 
@@ -1652,7 +1646,7 @@ two_way_open(const char *str, struct redirect *rp)
                }
                os_close_on_exec(fd, str, "socket", "to/from");
                os_close_on_exec(newfd, str, "socket", "to/from");
-               rp->iop = iop_alloc(newfd, str, NULL, true);
+               rp->iop = iop_alloc(newfd, str, true);
                if (rp->iop == NULL) {
                        close(newfd);
                        fclose(rp->fp);
@@ -1848,7 +1842,7 @@ two_way_open(const char *str, struct redirect *rp)
                }
 
                rp->pid = pid;
-               rp->iop = iop_alloc(master, str, NULL, true);
+               rp->iop = iop_alloc(master, str, true);
                if (rp->iop == NULL) {
                        (void) close(master);
                        (void) kill(pid, SIGKILL);
@@ -2001,7 +1995,7 @@ use_pipes:
 
        /* parent */
        rp->pid = pid;
-       rp->iop = iop_alloc(ctop[0], str, NULL, true);
+       rp->iop = iop_alloc(ctop[0], str, true);
        if (rp->iop == NULL) {
                (void) close(ctop[0]);
                (void) close(ctop[1]);
@@ -2165,7 +2159,7 @@ gawk_popen(const char *cmd, struct redirect *rp)
        }
 #endif
        os_close_on_exec(p[0], cmd, "pipe", "from");
-       rp->iop = iop_alloc(p[0], cmd, NULL, true);
+       rp->iop = iop_alloc(p[0], cmd, true);
        if (rp->iop == NULL)
                (void) close(p[0]);
 
@@ -2210,7 +2204,7 @@ gawk_popen(const char *cmd, struct redirect *rp)
        if (current == NULL)
                return NULL;
        os_close_on_exec(fileno(current), cmd, "pipe", "from");
-       rp->iop = iop_alloc(fileno(current), cmd, NULL, true);
+       rp->iop = iop_alloc(fileno(current), cmd, true);
        if (rp->iop == NULL) {
                (void) pclose(current);
                current = NULL;
@@ -2585,63 +2579,73 @@ srcopen(SRCFILE *s)
        return INVALID_HANDLE;
 }
 
-/* open hooks, mainly for use by extension functions */
+/* input parsers, mainly for use by extension functions */
 
-static struct open_hook {
-       struct open_hook *next;
-       void *(*open_func)(IOBUF_PUBLIC *);
-} *open_hooks;
+static awk_input_parser_t *ip_head, *ip_tail;
 
-/* register_open_hook --- add an open hook to the list */
+/* register_input_parser --- add an input parser to the list, FIFO */
 
 void
-register_open_hook(void *(*open_func)(IOBUF_PUBLIC *))
+register_input_parser(awk_input_parser_t *input_parser)
 {
-       struct open_hook *oh;
+       if (input_parser == NULL)
+               fatal(_("register_input_parser: received NULL pointer"));
 
-       emalloc(oh, struct open_hook *, sizeof(*oh), "register_open_hook");
-       oh->open_func = open_func;
-       oh->next = open_hooks;
-       open_hooks = oh;
+       input_parser->next = NULL;      /* force it */
+       if (ip_head == NULL) {
+               ip_head = ip_tail = input_parser;
+       } else {
+               ip_tail->next = input_parser;
+               ip_tail = ip_tail->next;
+       }
 }
 
-/* find_open_hook --- search the list of open hooks */
+/* find_input_parser --- search the list of input parsers */
 
 static void
-find_open_hook(IOBUF *iop)
+find_input_parser(IOBUF *iop)
 {
-       struct open_hook *oh;
+       awk_input_parser_t *ip, *ip2;
 
-       /* walk through open hooks, stop at first one that responds */
-       for (oh = open_hooks; oh != NULL; oh = oh->next) {
-               if ((iop->public.opaque = (*oh->open_func)(&iop->public)) != 
NULL)
-                       break;
+       /* if already associated with an input parser, bail out early */
+       if (iop->public.get_record != NULL)
+               return;
+
+       ip = ip2 = NULL;
+       for (ip2 = ip_head; ip2 != NULL; ip2 = ip2->next) {
+               if (ip2->can_take_file(& iop->public)) {
+                       if (ip == NULL)
+                               ip = ip2;       /* found first one */
+                       else
+                               fatal(_("input parser `%s' conflicts with 
previously installed input parser `%s'"),
+                                               ip2->name, ip->name);
+               }
        }
+
+       if (ip != NULL)
+               ip->take_control_of(& iop->public);
 }
 
 /* iop_alloc --- allocate an IOBUF structure for an open fd */
 
 static IOBUF *
-iop_alloc(int fd, const char *name, IOBUF *iop, bool do_openhooks)
+iop_alloc(int fd, const char *name, bool do_input_parsers)
 {
        struct stat sbuf;
-       bool iop_malloced = false;
+       IOBUF *iop;
+
+       emalloc(iop, IOBUF *, sizeof(IOBUF), "iop_alloc");
 
-       if (iop == NULL) {
-               emalloc(iop, IOBUF *, sizeof(IOBUF), "iop_alloc");
-               iop_malloced = true;
-       }
        memset(iop, '\0', sizeof(IOBUF));
        iop->public.fd = fd;
        iop->public.name = name;
        iop->read_func = ( ssize_t(*)() ) read;
 
-       if (do_openhooks) {
-               find_open_hook(iop);
-               /* tried to find open hook and could not */
+       if (do_input_parsers) {
+               find_input_parser(iop);
+               /* tried to find open parser and could not */
                if (iop->public.fd == INVALID_HANDLE) {
-                       if (iop_malloced)
-                               efree(iop);
+                       efree(iop);
                        return NULL;
                }
        } else if (iop->public.fd == INVALID_HANDLE)
@@ -3300,7 +3304,6 @@ iopflags2str(int flag)
 {
        static const struct flagtab values[] = {
                { IOP_IS_TTY, "IOP_IS_TTY" },
-               { IOP_NOFREE_OBJ, "IOP_NOFREE_OBJ" },
                { IOP_AT_EOF,  "IOP_AT_EOF" },
                { IOP_CLOSED, "IOP_CLOSED" },
                { IOP_AT_START,  "IOP_AT_START" },

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

Summary of changes:
 ChangeLog             |   36 ++++++++
 awk.h                 |   12 +--
 eval.c                |    6 +-
 ext.c                 |    4 +
 extension/ChangeLog   |    7 ++
 extension/Makefile.am |    3 +
 extension/Makefile.in |   22 ++++-
 extension/readdir.c   |  220 +++++++++++++++++++++++++++++++++++++++++++++++++
 extension/time.c      |    8 +-
 gawkapi.c             |   13 ++--
 gawkapi.h             |   35 +++++---
 io.c                  |  131 +++++++++++++++--------------
 po/ChangeLog          |    4 +
 po/POTFILES.in        |   14 +++-
 14 files changed, 410 insertions(+), 105 deletions(-)
 create mode 100644 extension/readdir.c


hooks/post-receive
-- 
gawk



reply via email to

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