[RFC PATCH 24/28] cli: lil: Make proc always take 3 arguments

Sean Anderson
2021-07-01T06:20:44Z

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 <seanga2@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