This rewrites proc to always take 3 arguments. It also adds proper error handling. TCL does not allow for anonymous functions to be created with proc. Allowing for a variable number of arguments makes the code much more complex when adding error handling.
Since fnc_proc was the last user of lil_unused_name (other than fnc_unusedname), remove it. Signed-off-by: Sean Anderson <sean...@gmail.com> --- common/cli_lil.c | 103 ++++++++++++++++------------------------------- test/cmd/lil.c | 6 ++- 2 files changed, 38 insertions(+), 71 deletions(-) diff --git a/common/cli_lil.c b/common/cli_lil.c index 7ec73675f3..1c7c340bda 100644 --- a/common/cli_lil.c +++ b/common/cli_lil.c @@ -2985,32 +2985,6 @@ struct lil_value *lil_eval_expr(struct lil *lil, struct lil_value *code) return lil_alloc_integer(ee.ival); } -struct lil_value *lil_unused_name(struct lil *lil, const char *part) -{ - char *name = malloc(strlen(part) + 64); - struct lil_value *val; - size_t i; - - for (i = 0; i < (size_t)-1; i++) { - sprintf(name, "!!un!%s!%09u!nu!!", part, (unsigned int)i); - if (lil_find_cmd(lil, name)) - continue; - - if (lil_find_var(lil, lil->env, name)) - continue; - - val = lil_alloc_string(name); - free(name); - return val; - } - return NULL; -} - -struct lil_value *lil_arg(struct lil_value **argv, size_t index) -{ - return argv ? argv[index] : NULL; -} - const char *lil_to_string(struct lil_value *val) { return (val && val->l) ? val->d : ""; @@ -3237,47 +3211,46 @@ static struct lil_value *fnc_reflect(struct lil *lil, size_t argc, static struct lil_value *fnc_proc(struct lil *lil, size_t argc, struct lil_value **argv) { - struct lil_value *name; struct lil_func *cmd; - struct lil_list *fargs; + struct lil_list *args; + struct lil_value *name, *code; - if (argc < 1) + if (argc != 3) { + lil_set_error_argc(lil, 3); return NULL; - - if (argc >= 3) { - name = lil_clone_value(argv[0]); - fargs = lil_subst_to_list(lil, argv[1]); - cmd = add_func(lil, lil_to_string(argv[0])); - if (!cmd) - return NULL; - - cmd->argnames = fargs; - cmd->code = lil_clone_value(argv[2]); - } else { - name = lil_unused_name(lil, "anonymous-function"); - if (argc < 2) { - struct lil_value *tmp = lil_alloc_string("args"); - - fargs = lil_subst_to_list(lil, tmp); - lil_free_value(tmp); - cmd = add_func(lil, lil_to_string(name)); - if (!cmd) - return NULL; - - cmd->argnames = fargs; - cmd->code = lil_clone_value(argv[0]); - } else { - fargs = lil_subst_to_list(lil, argv[0]); - cmd = add_func(lil, lil_to_string(name)); - if (!cmd) - return NULL; - - cmd->argnames = fargs; - cmd->code = lil_clone_value(argv[1]); - } } + name = lil_clone_value(argv[0]); + if (!name) { + lil_set_error_oom(lil); + return NULL; + } + + args = lil_subst_to_list(lil, argv[1]); + if (!args) + goto err_args; + + code = lil_clone_value(argv[2]); + if (!code) { + lil_set_error_oom(lil); + goto err_code; + } + + cmd = add_func(lil, lil_to_string(name)); + if (!cmd) + goto err_func; + cmd->argnames = args; + cmd->code = code; + return name; + +err_func: + lil_free_value(code); +err_code: + lil_free_list(args); +err_args: + lil_free_value(name); + return NULL; } static struct lil_value *fnc_rename(struct lil *lil, size_t argc, @@ -3312,13 +3285,6 @@ static struct lil_value *fnc_rename(struct lil *lil, size_t argc, return r; } -static struct lil_value *fnc_unusedname(struct lil *lil, size_t argc, - struct lil_value **argv) -{ - return lil_unused_name(lil, argc > 0 ? lil_to_string(argv[0]) : - "unusedname"); -} - static struct lil_value *fnc_quote(struct lil *lil, size_t argc, struct lil_value **argv) { @@ -4310,7 +4276,6 @@ static void register_stdcmds(struct lil *lil) lil_register(lil, "substr", fnc_substr); lil_register(lil, "topeval", fnc_topeval); lil_register(lil, "trim", fnc_trim); - lil_register(lil, "unusedname", fnc_unusedname); lil_register(lil, "upeval", fnc_upeval); } } diff --git a/test/cmd/lil.c b/test/cmd/lil.c index fb33fa83a6..58bc6ee842 100644 --- a/test/cmd/lil.c +++ b/test/cmd/lil.c @@ -149,9 +149,11 @@ static const struct { "[list eh??]" "];" "asserteq_list [lapply $list length] [list 9 10 4];" - "asserteq_list [lapply $list [proc {a} {" + "proc firstword {a} {" "return [index [split $a] 0]" - "}]] [list {bad's} {good's} eh??]" + "};" + "asserteq_list [lapply $list firstword] " + "[list {bad's} {good's} eh??]" }, {"lists", "set l [list foo bar baz bad];" -- 2.32.0