gawk-diffs
[Top][All Lists]
Advanced

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

[gawk-diffs] [SCM] gawk branch, array-iface, updated. 1a4aaf18f5ec614931


From: John Haque
Subject: [gawk-diffs] [SCM] gawk branch, array-iface, updated. 1a4aaf18f5ec6149315aabc53dbe667f1abfdb62
Date: Sat, 21 Apr 2012 11:13:51 +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, array-iface has been updated
       via  1a4aaf18f5ec6149315aabc53dbe667f1abfdb62 (commit)
      from  87dc23679566c5ad96f4869de6aec39c2a4c3aa7 (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=1a4aaf18f5ec6149315aabc53dbe667f1abfdb62

commit 1a4aaf18f5ec6149315aabc53dbe667f1abfdb62
Author: john haque <address@hidden>
Date:   Sat Apr 21 05:52:19 2012 -0500

    Add optional shutdown routine for an extension lib.

diff --git a/ChangeLog b/ChangeLog
index 5c6b811..9b46a92 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,26 @@
+2012-04-21         John Haque      <address@hidden>
+
+       Shutdown routine for a dynamic extension.
+
+       * awk.h (SRCFILE): New field fini_func.
+       * ext.c (load_ext): Takes an additional argument to look up and
+       save the clean up routine in SRCFILE struct. 
+       (INIT_FUNC, FINI_FUNC): Defines for default init and fini routine
+       names.
+       (do_ext): Use default for the name of the init or fini routine if
+       one is not supplied. Adjust call to load_ext().
+       (close_extensions): Execute fini routines.
+       * interpret.h (Op_at_exit): Call close_extensions().
+       * msg.c (gawk_exit): Ditto.
+       * debug.c (close_all): Ditto.
+       * main.c (main): Adjust call to load_ext().
+       * awkgram.y (tokentab): Specify 2nd and 3rd optional arguments
+       for the extension() built-in.
+
+       Unrelated:
+
+       * interpret.h (Op_arrayfor_init): Use assoc_length for array size. 
+       
 2012-04-19         John Haque      <address@hidden>
 
        Enhanced array interface to support transparent implementation
diff --git a/awk.h b/awk.h
index 8b9861b..c89ed97 100644
--- a/awk.h
+++ b/awk.h
@@ -953,6 +953,8 @@ typedef struct srcfile {
        int fd;
        int maxlen;     /* size of the longest line */
 
+       void (*fini_func)();    /* dynamic extension of type SRC_EXTLIB */ 
+
        char *lexptr;
        char *lexend;
        char *lexeme;
@@ -1488,12 +1490,13 @@ extern STACK_ITEM *grow_stack(void);
 extern void dump_fcall_stack(FILE *fp);
 extern int register_exec_hook(Func_pre_exec preh, Func_post_exec posth);
 /* ext.c */
-NODE *do_ext(int nargs);
-NODE *load_ext(const char *lib_name, const char *init_func, NODE *obj);
+extern NODE *do_ext(int nargs);
+extern NODE *load_ext(SRCFILE *s, const char *init_func, const char 
*fini_func, NODE *obj);
+extern void close_extensions(void);
 #ifdef DYNAMIC
-void make_builtin(const char *, NODE *(*)(int), int);
-NODE *get_argument(int);
-NODE *get_actual_argument(int, int, int);
+extern void make_builtin(const char *, NODE *(*)(int), int);
+extern NODE *get_argument(int);
+extern NODE *get_actual_argument(int, int, int);
 #define get_scalar_argument(i, opt)  get_actual_argument((i), (opt), FALSE)
 #define get_array_argument(i, opt)   get_actual_argument((i), (opt), TRUE)
 #endif
diff --git a/awkgram.c b/awkgram.c
index fd38c52..a447b23 100644
--- a/awkgram.c
+++ b/awkgram.c
@@ -4519,7 +4519,7 @@ static const struct token tokentab[] = {
 {"eval",       Op_symbol,       LEX_EVAL,      0,              0,      0},
 {"exit",       Op_K_exit,       LEX_EXIT,      0,              0,      0},
 {"exp",                Op_builtin,      LEX_BUILTIN,   A(1),           do_exp, 
MPF(exp)},
-{"extension",  Op_builtin,      LEX_BUILTIN,   GAWKX|A(2),     do_ext, 0},
+{"extension",  Op_builtin,      LEX_BUILTIN,   GAWKX|A(1)|A(2)|A(3),   do_ext, 
0},
 {"fflush",     Op_builtin,      LEX_BUILTIN,   RESX|A(0)|A(1), do_fflush,      
0},
 {"for",                Op_K_for,        LEX_FOR,       BREAK|CONTINUE, 0,      
0},
 {"func",       Op_func, LEX_FUNCTION,  NOT_POSIX|NOT_OLD,      0,      0},
diff --git a/awkgram.y b/awkgram.y
index 76b40a5..3258f00 100644
--- a/awkgram.y
+++ b/awkgram.y
@@ -1822,7 +1822,7 @@ static const struct token tokentab[] = {
 {"eval",       Op_symbol,       LEX_EVAL,      0,              0,      0},
 {"exit",       Op_K_exit,       LEX_EXIT,      0,              0,      0},
 {"exp",                Op_builtin,      LEX_BUILTIN,   A(1),           do_exp, 
MPF(exp)},
-{"extension",  Op_builtin,      LEX_BUILTIN,   GAWKX|A(2),     do_ext, 0},
+{"extension",  Op_builtin,      LEX_BUILTIN,   GAWKX|A(1)|A(2)|A(3),   do_ext, 
0},
 {"fflush",     Op_builtin,      LEX_BUILTIN,   RESX|A(0)|A(1), do_fflush,      
0},
 {"for",                Op_K_for,        LEX_FOR,       BREAK|CONTINUE, 0,      
0},
 {"func",       Op_func, LEX_FUNCTION,  NOT_POSIX|NOT_OLD,      0,      0},
diff --git a/debug.c b/debug.c
index 3645436..8bd3e84 100644
--- a/debug.c
+++ b/debug.c
@@ -5344,6 +5344,8 @@ close_all()
                }
        }
 
+       close_extensions();
+
        set_gawk_output(NULL);  /* closes output_fp if not stdout */ 
 }
 
diff --git a/ext.c b/ext.c
index f2919db..dc312cc 100644
--- a/ext.c
+++ b/ext.c
@@ -28,28 +28,44 @@
  */
 
 #include "awk.h"
+extern SRCFILE *srcfiles;
 
 #ifdef DYNAMIC
 
+#define INIT_FUNC      "dlload"
+#define FINI_FUNC      "dlunload"
+
 #include <dlfcn.h>
 
 /* do_ext --- load an extension at run-time: interface to load_ext */
-
+ 
 NODE *
 do_ext(int nargs)
 {
-       NODE *obj, *fun, *ret = NULL;
+       NODE *obj, *init = NULL, *fini = NULL, *ret = NULL;
        SRCFILE *s;
-       extern SRCFILE *srcfiles;
+       char *init_func = NULL;
+       char *fini_func = NULL;
 
-       fun = POP_STRING();
+       if (nargs == 3) {
+               fini = POP_STRING();
+               fini_func = fini->stptr;
+       }
+       if (nargs >= 2) { 
+               init = POP_STRING();
+               init_func = init->stptr;
+       }
        obj = POP_STRING();
 
        s = add_srcfile(SRC_EXTLIB, obj->stptr, srcfiles, NULL, NULL);
        if (s != NULL)
-               ret = load_ext(s->fullpath, fun->stptr, obj);
+               ret = load_ext(s, init_func, fini_func, obj);
+
        DEREF(obj);
-       DEREF(fun);
+       if (fini != NULL)
+               DEREF(fini);
+       if (init != NULL)
+               DEREF(init);
        if (ret == NULL)
                ret = dupnode(Nnull_string);
        return ret;
@@ -58,13 +74,20 @@ do_ext(int nargs)
 /* load_ext --- load an external library */
 
 NODE *
-load_ext(const char *lib_name, const char *init_func, NODE *obj)
+load_ext(SRCFILE *s, const char *init_func, const char *fini_func, NODE *obj)
 {
        NODE *tmp = NULL;
        NODE *(*func)(NODE *, void *);
        void *dl;
        int flags = RTLD_LAZY;
        int *gpl_compat;
+       const char *lib_name = s->fullpath;
+
+       if (init_func == NULL || init_func[0] == '\0')
+               init_func = INIT_FUNC;
+
+       if (fini_func == NULL || fini_func[0] == '\0')
+               fini_func = FINI_FUNC;
 
        if (do_sandbox)
                fatal(_("extensions are not allowed in sandbox mode"));
@@ -76,18 +99,18 @@ load_ext(const char *lib_name, const char *init_func, NODE 
*obj)
        flags |= RTLD_GLOBAL;
 #endif
 
-       if ((dl = dlopen(lib_name, flags)) == NULL)
-               fatal(_("extension: cannot open library `%s' (%s)\n"), lib_name,
+       if ((dl = dlopen(s->fullpath, flags)) == NULL)
+               fatal(_("extension: cannot open library `%s' (%s)"), lib_name,
                      dlerror());
 
        /* Per the GNU Coding standards */
        gpl_compat = (int *) dlsym(dl, "plugin_is_GPL_compatible");
        if (gpl_compat == NULL)
-               fatal(_("extension: library `%s': does not define 
`plugin_is_GPL_compatible' (%s)\n"),
+               fatal(_("extension: library `%s': does not define 
`plugin_is_GPL_compatible' (%s)"),
                                lib_name, dlerror());
        func = (NODE *(*)(NODE *, void *)) dlsym(dl, init_func);
        if (func == NULL)
-               fatal(_("extension: library `%s': cannot call function `%s' 
(%s)\n"),
+               fatal(_("extension: library `%s': cannot call function `%s' 
(%s)"),
                                lib_name, init_func, dlerror());
 
        if (obj == NULL) {
@@ -95,11 +118,12 @@ load_ext(const char *lib_name, const char *init_func, NODE 
*obj)
                tmp = (*func)(obj, dl);
                unref(tmp);
                unref(obj);
-               return NULL;
-       }
+               tmp = NULL;
+       } else
+               tmp = (*func)(obj, dl);
 
-       tmp = (*func)(obj, dl);
-       return tmp; 
+       s->fini_func = (void (*)(void)) dlsym(dl, fini_func);
+       return tmp;
 }
 
 
@@ -118,7 +142,7 @@ make_builtin(const char *name, NODE *(*func)(int), int 
count)
                fatal(_("extension: missing function name"));
 
        while ((c = *sp++) != '\0') {
-               if ((sp == &name[1] && c != '_' && ! isalpha((unsigned char) c))
+               if ((sp == & name[1] && c != '_' && ! isalpha((unsigned char) 
c))
                                || (sp > &name[1] && ! is_identchar((unsigned 
char) c)))
                        fatal(_("extension: illegal character `%c' in function 
name `%s'"), c, name);
        }
@@ -184,9 +208,10 @@ get_argument(int i)
 }
 
 
-/* get_actual_argument --- get the i'th scalar or array argument of a
-       dynamically linked function, allowed to be optional.
-*/
+/*
+ * get_actual_argument --- get the i'th scalar or array argument of a
+ *     dynamically linked function, allowed to be optional.
+ */
 
 NODE *
 get_actual_argument(int i, int optional, int want_array)
@@ -257,3 +282,15 @@ load_ext(const char *lib_name, const char *init_func, NODE 
*obj)
        return NULL;
 }
 #endif
+
+/* close_extensions --- execute extension cleanup routines */
+
+void
+close_extensions()
+{
+       SRCFILE *s;
+
+       for (s = srcfiles->next; s != srcfiles; s = s->next) 
+               if (s->stype == SRC_EXTLIB && s->fini_func)
+                               (*s->fini_func)();
+}
diff --git a/interpret.h b/interpret.h
index 0b83001..2fed224 100644
--- a/interpret.h
+++ b/interpret.h
@@ -106,6 +106,8 @@ top:
                         */
                        if (stdio_problem && ! exiting && exit_val == 0)
                                exit_val = 1;
+
+                       close_extensions();
                }
                        break;
 
@@ -763,12 +765,6 @@ mod:
                        /* get the array */
                        array = POP_ARRAY();
 
-                       /* sanity: check if empty */
-                       if (assoc_empty(array))
-                               goto arrayfor;
-
-                       num_elems = array->table_size;
-
                        if (sorted_in == NULL)          /* do this once */
                                sorted_in = make_string("sorted_in", 9);
 
@@ -788,7 +784,8 @@ mod:
 
                        list = assoc_list(array, how_to_sort, SORTED_IN);
 
-arrayfor:
+                       num_elems = assoc_length(array);
+
                        getnode(r);
                        r->type = Node_arrayfor;
                        r->for_list = list;
diff --git a/main.c b/main.c
index 8a38a76..570c0d5 100644
--- a/main.c
+++ b/main.c
@@ -637,7 +637,7 @@ out:
        /* load extension libs */
         for (s = srcfiles->next; s != srcfiles; s = s->next) {
                 if (s->stype == SRC_EXTLIB)
-                       (void) load_ext(s->fullpath, "dlload", NULL);
+                       (void) load_ext(s, NULL, NULL, NULL);
                else
                        have_srcfile++;
         }
diff --git a/msg.c b/msg.c
index 7881818..dabd20e 100644
--- a/msg.c
+++ b/msg.c
@@ -158,5 +158,9 @@ gawk_exit(int status)
                exit_val = status;
                longjmp(fatal_tag, 1);
        }
+
+       /* we could close_io() here */
+       close_extensions();
+
        exit(status);
 }

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

Summary of changes:
 ChangeLog   |   23 ++++++++++++++++++
 awk.h       |   13 ++++++----
 awkgram.c   |    2 +-
 awkgram.y   |    2 +-
 debug.c     |    2 +
 ext.c       |   75 ++++++++++++++++++++++++++++++++++++++++++++---------------
 interpret.h |   11 +++-----
 main.c      |    2 +-
 msg.c       |    4 +++
 9 files changed, 100 insertions(+), 34 deletions(-)


hooks/post-receive
-- 
gawk



reply via email to

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