aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnold D. Robbins <arnold@skeeve.com>2016-12-12 21:54:57 +0200
committerArnold D. Robbins <arnold@skeeve.com>2016-12-12 21:54:57 +0200
commit539de0a854fb94fd6ba47e91cee55f22fcd851a3 (patch)
tree2c7b590ae9a91127411cf2c6d0ee0dc2caf18b9b
parent1bacda9f09bbb55c0ea3de42114c2dfe6cceec09 (diff)
downloadegawk-539de0a854fb94fd6ba47e91cee55f22fcd851a3.tar.gz
egawk-539de0a854fb94fd6ba47e91cee55f22fcd851a3.tar.bz2
egawk-539de0a854fb94fd6ba47e91cee55f22fcd851a3.zip
Improve handling of min and max args for extension functions.
-rw-r--r--ChangeLog14
-rw-r--r--awk.h8
-rw-r--r--ext.c3
-rw-r--r--extension/ChangeLog5
-rw-r--r--extension/filefuncs.c2
-rw-r--r--gawkapi.h4
-rw-r--r--interpret.h27
7 files changed, 38 insertions, 25 deletions
diff --git a/ChangeLog b/ChangeLog
index a2dbc0aa..efe20f2e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2016-12-12 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h (INSTRUCTION): Replace min_required and max_expected
+ with a pointer to the extension functions awk_ext_func_t struct.
+ * ext.c (make_builtin): Store a pointer to the extension function
+ struct into the INSTRUCTION instead of the min and max.
+ * gawkapi.h (awk_ext_func): Use size_t instead of unsigned short.
+ Put min second, which preserves source code compatibility.
+ * interpret.h (Op_ext_builtin): Use the pointer for the info
+ directly. If lint and max_expected > 0 and args > max_expected
+ print a message and set max_expected to zero so we only print once
+ per function. Remove special case of both min and max being zero.
+ (Op_ext_func): Adjust creation of the data structures.
+
2016-12-11 Arnold D. Robbins <arnold@skeeve.com>
* dfa.c: Sync with GNULIB.
diff --git a/awk.h b/awk.h
index 4f04fc83..4e365ba8 100644
--- a/awk.h
+++ b/awk.h
@@ -778,10 +778,7 @@ 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
+ awk_ext_func_t *exf;
} x;
short source_line;
@@ -797,8 +794,7 @@ typedef struct exp_instruction {
#define expr_count x.xl
-#define min_required x.fa.mr
-#define max_expected x.fa.me
+#define c_func x.exf
#define target_continue d.di
#define target_jmp d.di
diff --git a/ext.c b/ext.c
index b6447c5a..609b3b2b 100644
--- a/ext.c
+++ b/ext.c
@@ -136,8 +136,7 @@ make_builtin(const awk_ext_func_t *funcinfo)
b = bcalloc(Op_symbol, 1, 0);
b->extfunc = funcinfo->function;
- b->min_required = funcinfo->min_required_args;
- b->max_expected = funcinfo->max_expected_args;
+ b->c_func = (awk_ext_func_t *) funcinfo;
/* NB: extension sub must return something */
diff --git a/extension/ChangeLog b/extension/ChangeLog
index 845391f9..edacc2f4 100644
--- a/extension/ChangeLog
+++ b/extension/ChangeLog
@@ -1,3 +1,8 @@
+2016-12-12 Arnold D. Robbins <arnold@skeeve.com>
+
+ * filefuncs.c (func_table): Adjust ordering of min and max
+ for stat.
+
2016-12-06 Arnold D. Robbins <arnold@skeeve.com>
Add minimum required and maximum expected number of arguments
diff --git a/extension/filefuncs.c b/extension/filefuncs.c
index 02b40534..de293bee 100644
--- a/extension/filefuncs.c
+++ b/extension/filefuncs.c
@@ -914,7 +914,7 @@ out:
static awk_ext_func_t func_table[] = {
{ "chdir", do_chdir, 1, 1 },
- { "stat", do_stat, 2, 3 },
+ { "stat", do_stat, 3, 2 },
#ifndef __MINGW32__
{ "fts", do_fts, 3, 3 },
#endif
diff --git a/gawkapi.h b/gawkapi.h
index af362bd2..d1ad9a2c 100644
--- a/gawkapi.h
+++ b/gawkapi.h
@@ -390,8 +390,8 @@ typedef struct awk_flat_array {
typedef struct awk_ext_func {
const char *name;
awk_value_t *(*function)(int num_actual_args, awk_value_t *result);
- unsigned short min_required_args;
- unsigned short max_expected_args;
+ size_t max_expected_args;
+ size_t min_required_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 2cefc14c..db4bd325 100644
--- a/interpret.h
+++ b/interpret.h
@@ -956,20 +956,20 @@ 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_ext_func_t *f = pc[1].c_func;
+ int min_req = f->min_required_args;
+ int max_expect = f->max_expected_args;
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 (arg_count < min_req)
+ fatal(_("%s: called with %d arguments, expecting at least %d"),
+ pc[1].func_name, arg_count, min_req);
- 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"),
+ if (do_lint && max_expect > 0 && arg_count > max_expect) {
+ lintwarn(_("%s: called with %d arguments, expecting no more than %d; check all calls"),
pc[1].func_name, arg_count, max_expect);
+ f->max_expected_args = 0; // avoid multiple lint messages
+ }
PUSH_CODE(pc);
r = awk_value_to_node(pc->extfunc(arg_count, & result));
@@ -1106,8 +1106,7 @@ 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].min_required = bc->min_required;
- npc[1].max_expected = bc->max_expected;
+ npc[1].c_func = bc->c_func;
ni = npc;
JUMPTO(ni);
} else
@@ -1143,9 +1142,9 @@ match_re:
assert(bc->opcode == Op_symbol);
pc->opcode = Op_ext_builtin; /* self modifying code */
pc->extfunc = bc->extfunc;
- pc->expr_count = arg_count; /* actual argument count */
+ pc->expr_count = arg_count; /* actual argument count */
(pc + 1)->func_name = fname; /* name of the builtin */
- (pc + 1)->expr_count = bc->expr_count; /* defined max # of arguments */
+ (pc + 1)->c_func = bc->c_func; /* min and max args */
ni = pc;
JUMPTO(ni);
}