[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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [gawk-diffs] [SCM] gawk branch, feature/api-min-max, created. gawk-4.1.0-2357-gf2b6d10,
Arnold Robbins <=