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

Sean Anderson seanga2 at gmail.com
Thu Jul 1 08:16:07 CEST 2021


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 at 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



More information about the U-Boot mailing list