diff options
author | Arnold D. Robbins <arnold@skeeve.com> | 2016-12-12 21:54:57 +0200 |
---|---|---|
committer | Arnold D. Robbins <arnold@skeeve.com> | 2016-12-12 21:54:57 +0200 |
commit | 539de0a854fb94fd6ba47e91cee55f22fcd851a3 (patch) | |
tree | 2c7b590ae9a91127411cf2c6d0ee0dc2caf18b9b | |
parent | 1bacda9f09bbb55c0ea3de42114c2dfe6cceec09 (diff) | |
download | egawk-539de0a854fb94fd6ba47e91cee55f22fcd851a3.tar.gz egawk-539de0a854fb94fd6ba47e91cee55f22fcd851a3.tar.bz2 egawk-539de0a854fb94fd6ba47e91cee55f22fcd851a3.zip |
Improve handling of min and max args for extension functions.
-rw-r--r-- | ChangeLog | 14 | ||||
-rw-r--r-- | awk.h | 8 | ||||
-rw-r--r-- | ext.c | 3 | ||||
-rw-r--r-- | extension/ChangeLog | 5 | ||||
-rw-r--r-- | extension/filefuncs.c | 2 | ||||
-rw-r--r-- | gawkapi.h | 4 | ||||
-rw-r--r-- | interpret.h | 27 |
7 files changed, 38 insertions, 25 deletions
@@ -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. @@ -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 @@ -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 @@ -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); } |