gawk-diffs
[Top][All Lists]
Advanced

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

[gawk-diffs] [SCM] gawk branch, feature/api-min-max, created. gawk-4.1.0


From: Arnold Robbins
Subject: [gawk-diffs] [SCM] gawk branch, feature/api-min-max, created. gawk-4.1.0-2357-gf2b6d10
Date: Tue, 6 Dec 2016 20:07:01 +0000 (UTC)

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, feature/api-min-max has been created
        at  f2b6d100d8958a9c811c950f113a0ce38a25d484 (commit)

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

commit f2b6d100d8958a9c811c950f113a0ce38a25d484
Author: Arnold D. Robbins <address@hidden>
Date:   Tue Dec 6 22:06:26 2016 +0200

    Add min_required and max_expected arg counts to API.

diff --git a/ChangeLog b/ChangeLog
index b3f3363..df8f919 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2016-12-06         Arnold D. Robbins     <address@hidden>
+
+       Add minimum required and maximum expected number of arguments
+       to the API.
+
+       * awk.h (INSTRUCTION): Add new members min_required and max_expected.
+       * ext.c (make_builtin): Store values from extension function struct
+       into the INSTRUCTION.
+       * gawkapi.h (awk_ext_func): Add min_required args. Make both it and
+       max_expected_args into unsigned short to match type in INSTRUCTION.
+       * interpret.h (Op_ext_builtin): Store min_required and max_expected
+       in instructions. Add checking code and lint checks.
+       (Op_ext_func): Copy min_required and max_expected from function info.
+
 2016-11-30         Arnold D. Robbins     <address@hidden>
 
        * dfa.c: Sync with fixes in GNULIB.
diff --git a/awk.h b/awk.h
index 5574692..4f04fc8 100644
--- a/awk.h
+++ b/awk.h
@@ -778,6 +778,10 @@ typedef struct exp_instruction {
                void (*aptr)(void);
                struct exp_instruction *xi;
                struct break_point *bpt;
+               struct {
+                       uint16_t mr;    // minimum required
+                       uint16_t me;    // maximum expected
+               } fa;   // function args
        } x;
 
        short source_line;
@@ -793,6 +797,9 @@ typedef struct exp_instruction {
 
 #define expr_count      x.xl
 
+#define min_required   x.fa.mr
+#define max_expected   x.fa.me
+
 #define target_continue d.di
 #define target_jmp      d.di
 #define target_break    x.xi
diff --git a/ext.c b/ext.c
index 10a4221..b6447c5 100644
--- a/ext.c
+++ b/ext.c
@@ -136,7 +136,8 @@ make_builtin(const awk_ext_func_t *funcinfo)
 
        b = bcalloc(Op_symbol, 1, 0);
        b->extfunc = funcinfo->function;
-       b->expr_count = count;
+       b->min_required = funcinfo->min_required_args;
+       b->max_expected = funcinfo->max_expected_args;
 
        /* NB: extension sub must return something */
 
diff --git a/extension/ChangeLog b/extension/ChangeLog
index 52d4ddb..845391f 100644
--- a/extension/ChangeLog
+++ b/extension/ChangeLog
@@ -1,3 +1,20 @@
+2016-12-06         Arnold D. Robbins     <address@hidden>
+
+       Add minimum required and maximum expected number of arguments
+       to the API.
+
+       * filefuncs.c: Update with max expected value. Remove lint
+       checks since that's now done by gawk.
+       * fnmatch.c: Ditto.
+       * fork.c: Ditto.
+       * inplace.c: Ditto.
+       * ordchr.c: Ditto.
+       * readfile.c: Ditto.
+       * rwarray.c: Ditto.
+       * rwarray0.c: Ditto.
+       * testext.c: Ditto.
+       * time.c: Ditto.
+
 2016-10-23         Arnold D. Robbins     <address@hidden>
 
        * General: Remove trailing whitespace from all relevant files.
diff --git a/extension/filefuncs.c b/extension/filefuncs.c
index a074de5..02b4053 100644
--- a/extension/filefuncs.c
+++ b/extension/filefuncs.c
@@ -160,9 +160,6 @@ do_chdir(int nargs, awk_value_t *result)
 
        assert(result != NULL);
 
-       if (do_lint && nargs != 1)
-               lintwarn(ext_id, _("chdir: called with incorrect number of 
arguments, expecting 1"));
-
        if (get_argument(0, AWK_STRING, & newdir)) {
                ret = chdir(newdir.str_value.str);
                if (ret < 0)
@@ -472,12 +469,6 @@ do_stat(int nargs, awk_value_t *result)
 
        assert(result != NULL);
 
-       if (nargs != 2 && nargs != 3) {
-               if (do_lint)
-                       lintwarn(ext_id, _("stat: called with wrong number of 
arguments"));
-               return make_number(-1, result);
-       }
-
        /* file is first arg, array to hold results is second */
        if (   ! get_argument(0, AWK_STRING, & file_param)
            || ! get_argument(1, AWK_ARRAY, & array_param)) {
@@ -522,12 +513,6 @@ do_statvfs(int nargs, awk_value_t *result)
 
        assert(result != NULL);
 
-       if (nargs != 2) {
-               if (do_lint)
-                       lintwarn(ext_id, _("statvfs: called with wrong number 
of arguments"));
-               return make_number(-1, result);
-       }
-
        /* file is first arg, array to hold results is second */
        if (   ! get_argument(0, AWK_STRING, & file_param)
            || ! get_argument(1, AWK_ARRAY, & array_param)) {
@@ -845,7 +830,7 @@ do_fts(int nargs, awk_value_t *result)
        assert(result != NULL);
        fts_errors = 0;         /* ensure a fresh start */
 
-       if (do_lint && nargs != 3)
+       if (nargs > 3)
                lintwarn(ext_id, _("fts: called with incorrect number of 
arguments, expecting 3"));
 
        if (! get_argument(0, AWK_ARRAY, & pathlist)) {
@@ -928,13 +913,13 @@ out:
 #endif /* ! __MINGW32__ */
 
 static awk_ext_func_t func_table[] = {
-       { "chdir",      do_chdir, 1 },
-       { "stat",       do_stat, 3 },
+       { "chdir",      do_chdir, 1, 1 },
+       { "stat",       do_stat, 2, 3 },
 #ifndef __MINGW32__
-       { "fts",        do_fts, 3 },
+       { "fts",        do_fts, 3, 3 },
 #endif
 #if defined(HAVE_SYS_STATVFS_H) && defined(HAVE_STATVFS)
-       { "statvfs",    do_statvfs, 2 },
+       { "statvfs",    do_statvfs, 2, 2 },
 #endif
 };
 
diff --git a/extension/fnmatch.c b/extension/fnmatch.c
index f5fb02c..caf64a7 100644
--- a/extension/fnmatch.c
+++ b/extension/fnmatch.c
@@ -107,13 +107,8 @@ do_fnmatch(int nargs, awk_value_t *result)
        int int_flags, retval;
 
        make_number(-1.0, result);      /* default return */
-#ifdef HAVE_FNMATCH
-       if (nargs < 3) {
-               warning(ext_id, _("fnmatch: called with less than three 
arguments"));
-               goto out;
-       } else if (do_lint && nargs > 3)
-               lintwarn(ext_id, _("fnmatch: called with more than three 
arguments"));
 
+#ifdef HAVE_FNMATCH
        if (! get_argument(0, AWK_STRING, & pattern)) {
                warning(ext_id, _("fnmatch: could not get first argument"));
                goto out;
@@ -199,7 +194,7 @@ init_fnmatch(void)
 }
 
 static awk_ext_func_t func_table[] = {
-       { "fnmatch", do_fnmatch, 3 },
+       { "fnmatch", do_fnmatch, 3, 3 },
 };
 
 /* define the dl_load function using the boilerplate macro */
diff --git a/extension/fork.c b/extension/fork.c
index 82593b7..064a2a8 100644
--- a/extension/fork.c
+++ b/extension/fork.c
@@ -77,9 +77,6 @@ do_fork(int nargs, awk_value_t *result)
 
        assert(result != NULL);
 
-       if (do_lint && nargs > 0)
-               lintwarn(ext_id, _("fork: called with too many arguments"));
-
        ret = fork();
 
        if (ret < 0)
@@ -114,16 +111,12 @@ do_waitpid(int nargs, awk_value_t *result)
 
        assert(result != NULL);
 
-       if (do_lint && nargs > 1)
-               lintwarn(ext_id, _("waitpid: called with too many arguments"));
-
        if (get_argument(0, AWK_NUMBER, &pid)) {
                options = WNOHANG|WUNTRACED;
                ret = waitpid(pid.num_value, NULL, options);
                if (ret < 0)
                        update_ERRNO_int(errno);
-       } else if (do_lint)
-               lintwarn(ext_id, _("wait: called with no arguments"));
+       }
 
        /* Set the return value */
        return make_number(ret, result);
@@ -139,9 +132,6 @@ do_wait(int nargs, awk_value_t *result)
 
        assert(result != NULL);
 
-       if (do_lint && nargs > 0)
-               lintwarn(ext_id, _("wait: called with too many arguments"));
-
        ret = wait(NULL);
        if (ret < 0)
                update_ERRNO_int(errno);
@@ -151,9 +141,9 @@ do_wait(int nargs, awk_value_t *result)
 }
 
 static awk_ext_func_t func_table[] = {
-       { "fork", do_fork, 0 },
-       { "waitpid", do_waitpid, 1 },
-       { "wait", do_wait, 0 },
+       { "fork", do_fork, 0, 0 },
+       { "waitpid", do_waitpid, 1, 1 },
+       { "wait", do_wait, 0, 0 },
 };
 
 /* define the dl_load function using the boilerplate macro */
diff --git a/extension/inplace.c b/extension/inplace.c
index 26c3792..19ee560 100644
--- a/extension/inplace.c
+++ b/extension/inplace.c
@@ -262,8 +262,8 @@ do_inplace_end(int nargs, awk_value_t *result)
 }
 
 static awk_ext_func_t func_table[] = {
-       { "inplace_begin", do_inplace_begin, 2 },
-       { "inplace_end", do_inplace_end, 2 },
+       { "inplace_begin", do_inplace_begin, 2, 2 },
+       { "inplace_end", do_inplace_end, 2, 2 },
 };
 
 static awk_bool_t init_inplace(void)
diff --git a/extension/ordchr.c b/extension/ordchr.c
index 4f9cd61..3722ced 100644
--- a/extension/ordchr.c
+++ b/extension/ordchr.c
@@ -65,17 +65,10 @@ do_ord(int nargs, awk_value_t *result)
 
        assert(result != NULL);
 
-       if (do_lint && nargs > 1)
-               lintwarn(ext_id, _("ord: called with too many arguments"));
-
        if (get_argument(0, AWK_STRING, & str)) {
                ret = str.str_value.str[0];
-       } else if (do_lint) {
-               if (nargs == 0)
-                       lintwarn(ext_id, _("ord: called with no arguments"));
-               else
-                       lintwarn(ext_id, _("ord: called with inappropriate 
argument(s)"));
-       }
+       } else if (do_lint)
+               lintwarn(ext_id, _("ord: called with inappropriate 
argument(s)"));
 
        /* Set the return value */
        return make_number(ret, result);
@@ -95,29 +88,22 @@ do_chr(int nargs, awk_value_t *result)
 
        assert(result != NULL);
 
-       if (do_lint && nargs > 1)
-               lintwarn(ext_id, _("chr: called with too many arguments"));
-
        if (get_argument(0, AWK_NUMBER, & num)) {
                val = num.num_value;
                ret = val;      /* convert to int */
                ret &= 0xff;
                str[0] = ret;
                str[1] = '\0';
-       } else if (do_lint) {
-               if (nargs == 0)
-                       lintwarn(ext_id, _("chr: called with no arguments"));
-               else
-                       lintwarn(ext_id, _("chr: called with inappropriate 
argument(s)"));
-       }
+       } else if (do_lint)
+               lintwarn(ext_id, _("chr: called with inappropriate 
argument(s)"));
 
        /* Set the return value */
        return make_const_string(str, 1, result);
 }
 
 static awk_ext_func_t func_table[] = {
-       { "ord", do_ord, 1 },
-       { "chr", do_chr, 1 },
+       { "ord", do_ord, 1, 1 },
+       { "chr", do_chr, 1, 1 },
 };
 
 /* define the dl_load function using the boilerplate macro */
diff --git a/extension/readfile.c b/extension/readfile.c
index fbe2574..cc9a4c1 100644
--- a/extension/readfile.c
+++ b/extension/readfile.c
@@ -109,9 +109,6 @@ do_readfile(int nargs, awk_value_t *result)
        assert(result != NULL);
        make_null_string(result);       /* default return value */
 
-       if (do_lint && nargs > 1)
-               lintwarn(ext_id, _("readfile: called with too many arguments"));
-
        unset_ERRNO();
 
        if (get_argument(0, AWK_STRING, &filename)) {
@@ -134,7 +131,7 @@ do_readfile(int nargs, awk_value_t *result)
                make_malloced_string(text, sbuf.st_size, result);
                goto done;
        } else if (do_lint)
-               lintwarn(ext_id, _("readfile: called with no arguments"));
+               lintwarn(ext_id, _("readfile: called with wrong kind of 
argument"));
 
 done:
        /* Set the return value */
@@ -241,7 +238,7 @@ init_readfile()
 }
 
 static awk_ext_func_t func_table[] = {
-       { "readfile", do_readfile, 1 },
+       { "readfile", do_readfile, 1, 1 },
 };
 
 /* define the dl_load function using the boilerplate macro */
diff --git a/extension/rwarray.c b/extension/rwarray.c
index 15e121a..8c3200e 100644
--- a/extension/rwarray.c
+++ b/extension/rwarray.c
@@ -109,9 +109,6 @@ do_writea(int nargs, awk_value_t *result)
        assert(result != NULL);
        make_number(0.0, result);
 
-       if (do_lint && nargs > 2)
-               lintwarn(ext_id, _("writea: called with too many arguments"));
-
        if (nargs < 2)
                goto out;
 
@@ -265,9 +262,6 @@ do_reada(int nargs, awk_value_t *result)
        assert(result != NULL);
        make_number(0.0, result);
 
-       if (do_lint && nargs > 2)
-               lintwarn(ext_id, _("reada: called with too many arguments"));
-
        if (nargs < 2)
                goto out;
 
@@ -470,8 +464,8 @@ read_value(FILE *fp, awk_value_t *value)
 }
 
 static awk_ext_func_t func_table[] = {
-       { "writea", do_writea, 2 },
-       { "reada", do_reada, 2 },
+       { "writea", do_writea, 2, 2 },
+       { "reada", do_reada, 2, 2 },
 };
 
 
diff --git a/extension/rwarray0.c b/extension/rwarray0.c
index 00289ca..35e0a70 100644
--- a/extension/rwarray0.c
+++ b/extension/rwarray0.c
@@ -105,9 +105,6 @@ do_writea(int nargs, awk_value_t *result)
        assert(result != NULL);
        make_number(0.0, result);
 
-       if (do_lint && nargs > 2)
-               lintwarn(ext_id, _("writea: called with too many arguments"));
-
        if (nargs < 2)
                goto out;
 
@@ -261,9 +258,6 @@ do_reada(int nargs, awk_value_t *result)
        assert(result != NULL);
        make_number(0.0, result);
 
-       if (do_lint && nargs > 2)
-               lintwarn(ext_id, _("reada: called with too many arguments"));
-
        if (nargs < 2)
                goto out;
 
@@ -465,8 +459,8 @@ read_value(int fd, awk_value_t *value)
 }
 
 static awk_ext_func_t func_table[] = {
-       { "writea", do_writea, 2 },
-       { "reada", do_reada, 2 },
+       { "writea", do_writea, 2, 2 },
+       { "reada", do_reada, 2, 2 },
 };
 
 
diff --git a/extension/testext.c b/extension/testext.c
index 9216d64..227714e 100644
--- a/extension/testext.c
+++ b/extension/testext.c
@@ -1024,20 +1024,20 @@ static void at_exit2(void *data, int exit_status)
 }
 
 static awk_ext_func_t func_table[] = {
-       { "dump_array_and_delete", dump_array_and_delete, 2 },
-       { "try_modify_environ", try_modify_environ, 0 },
-       { "var_test", var_test, 1 },
-       { "test_deferred", test_deferred, 0 },
-       { "test_errno", test_errno, 0 },
-       { "test_array_size", test_array_size, 1 },
-       { "test_array_elem", test_array_elem, 2 },
-       { "test_array_param", test_array_param, 1 },
-       { "print_do_lint", print_do_lint, 0 },
-       { "test_scalar", test_scalar, 1 },
-       { "test_scalar_reserved", test_scalar_reserved, 0 },
-       { "test_indirect_vars", test_indirect_vars, 0 },
-       { "test_get_file", test_get_file, 2 },
-       { "get_file", do_get_file, 4 },
+       { "dump_array_and_delete", dump_array_and_delete, 2, 2 },
+       { "try_modify_environ", try_modify_environ, 0, 0 },
+       { "var_test", var_test, 1, 1 },
+       { "test_deferred", test_deferred, 0, 0 },
+       { "test_errno", test_errno, 0, 0 },
+       { "test_array_size", test_array_size, 1, 1 },
+       { "test_array_elem", test_array_elem, 2, 2 },
+       { "test_array_param", test_array_param, 1, 1 },
+       { "print_do_lint", print_do_lint, 0, 0 },
+       { "test_scalar", test_scalar, 1, 1 },
+       { "test_scalar_reserved", test_scalar_reserved, 0, 0 },
+       { "test_indirect_vars", test_indirect_vars, 0, 0 },
+       { "test_get_file", test_get_file, 2, 2 },
+       { "get_file", do_get_file, 4, 4 },
 };
 
 /* init_testext --- additional initialization function */
diff --git a/extension/time.c b/extension/time.c
index e6b2b39..6700275 100644
--- a/extension/time.c
+++ b/extension/time.c
@@ -109,9 +109,6 @@ do_gettimeofday(int nargs, awk_value_t *result)
 
        assert(result != NULL);
 
-       if (do_lint && nargs > 0)
-               lintwarn(ext_id, _("gettimeofday: ignoring arguments"));
-
 #if defined(HAVE_GETTIMEOFDAY)
        {
                struct timeval tv;
@@ -161,9 +158,6 @@ do_sleep(int nargs, awk_value_t *result)
 
        assert(result != NULL);
 
-       if (do_lint && nargs > 1)
-               lintwarn(ext_id, _("sleep: called with too many arguments"));
-
        if (! get_argument(0, AWK_NUMBER, &num)) {
                update_ERRNO_string(_("sleep: missing required numeric 
argument"));
                return make_number(-1, result);
@@ -212,8 +206,8 @@ do_sleep(int nargs, awk_value_t *result)
 }
 
 static awk_ext_func_t func_table[] = {
-       { "gettimeofday", do_gettimeofday, 0 },
-       { "sleep", do_sleep, 1 },
+       { "gettimeofday", do_gettimeofday, 0, 0 },
+       { "sleep", do_sleep, 1, 1 },
 };
 
 /* define the dl_load function using the boilerplate macro */
diff --git a/gawkapi.h b/gawkapi.h
index 1c88474..af362bd 100644
--- a/gawkapi.h
+++ b/gawkapi.h
@@ -376,15 +376,22 @@ typedef struct awk_flat_array {
  * Each extension function may decide what to do if the number of
  * arguments isn't what it expected.  Following awk functions, it
  * is likely OK to ignore extra arguments.
-
- * Note that the 'max_expected_args' value should be used by the
- * extension function itself only to trigger a lint warning if more
- * arguments are passed to the function.
+ *
+ * 'min_required_args' indicates how many arguments MUST be passed.
+ * The API will throw a fatal error if not enough are passed.
+ *
+ * 'max_expected_args' is more benign; if more than that are passed,
+ * the API prints a lint message (IFF lint is enabled, of course).
+ *
+ * In any case, the extension function itself need not compare the
+ * actual number of arguments passed to those two values if it does
+ * not want to.
  */
 typedef struct awk_ext_func {
        const char *name;
        awk_value_t *(*function)(int num_actual_args, awk_value_t *result);
-       size_t max_expected_args;
+       unsigned short min_required_args;
+       unsigned short max_expected_args;
 } awk_ext_func_t;
 
 typedef void *awk_ext_id_t;    /* opaque type for extension id */
diff --git a/interpret.h b/interpret.h
index da8e060..2cefc14 100644
--- a/interpret.h
+++ b/interpret.h
@@ -956,8 +956,21 @@ arrayfor:
                case Op_ext_builtin:
                {
                        int arg_count = pc->expr_count;
+                       int min_req = pc[1].min_required;
+                       int max_expect = pc[1].max_expected;
                        awk_value_t result;
 
+                       if (min_req == 0 && max_expect == 0 && arg_count > 
min_req)
+                               fatal(_("%s: cannot be called with arguments"), 
pc[1].func_name);
+
+                       if (min_req > 0 && arg_count < min_req)
+                               fatal(_("%s: expects at least %d arguments, 
called with %d arguments"),
+                                               pc[1].func_name, min_req, 
arg_count);
+
+                       if (do_lint && arg_count > max_expect)
+                               lintwarn(_("%s: called with %d arguments, only 
expecting %d"),
+                                               pc[1].func_name, arg_count, 
max_expect);
+
                        PUSH_CODE(pc);
                        r = awk_value_to_node(pc->extfunc(arg_count, & result));
                        (void) POP_CODE();
@@ -1093,7 +1106,8 @@ match_re:
                                        npc[0].expr_count = arg_count;          
/* actual argument count */
                                        npc[1] = pc[1];
                                        npc[1].func_name = fname;       /* name 
of the builtin */
-                                       npc[1].expr_count = bc->expr_count;     
/* defined max # of arguments */
+                                       npc[1].min_required = bc->min_required;
+                                       npc[1].max_expected = bc->max_expected;
                                        ni = npc;
                                        JUMPTO(ni);
                                } else

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


hooks/post-receive
-- 
gawk



reply via email to

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