All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sean Anderson <seanga2@gmail.com>
To: u-boot@lists.denx.de, Tom Rini <trini@konsulko.com>
Cc: "Marek Behún" <marek.behun@nic.cz>, "Wolfgang Denk" <wd@denx.de>,
	"Simon Glass" <sjg@chromium.org>,
	"Roland Gaudig" <roland.gaudig-oss@weidmueller.com>,
	"Heinrich Schuchardt" <xypron.glpk@gmx.de>,
	"Kostas Michalopoulos" <badsector@runtimeterror.com>,
	"Sean Anderson" <seanga2@gmail.com>
Subject: [RFC PATCH 09/28] cli: lil: Use error codes
Date: Thu,  1 Jul 2021 02:15:52 -0400	[thread overview]
Message-ID: <20210701061611.957918-10-seanga2@gmail.com> (raw)
In-Reply-To: <20210701061611.957918-1-seanga2@gmail.com>

This adds numeric error codes to be used for errors. This makes it easier
for code to differentiate between different classes of errors. Some error
codes are not used yet, and will be added in future commits. The position
argument has been removed for a few reasons:

- It doesn't make sense for some errors, such as running out of memory
- It was often not very helpful, since it pointed at the end of the command
- Determining the location of an error is more difficult when the parsing
  and evaluating steps are done separately.

In addition, lil.error is changed to lil.err for consistency.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
---

 common/cli_lil.c  | 92 ++++++++++++++++++-----------------------------
 include/cli_lil.h | 36 +++++++++++++++++--
 2 files changed, 68 insertions(+), 60 deletions(-)

diff --git a/common/cli_lil.c b/common/cli_lil.c
index dd020e8452..1bdf0e5265 100644
--- a/common/cli_lil.c
+++ b/common/cli_lil.c
@@ -92,12 +92,7 @@ struct lil {
 	struct lil_env *rootenv;
 	struct lil_env *downenv;
 	struct lil_value *empty;
-	enum {
-		ERROR_NOERROR = 0,
-		ERROR_DEFAULT,
-		ERROR_FIXHEAD,
-	} error;
-	size_t err_head;
+	enum lil_error err;
 	char *err_msg;
 	struct lil_callbacks callbacks;
 	size_t parse_depth;
@@ -117,6 +112,7 @@ struct expreval {
 
 static struct lil_value *next_word(struct lil *lil);
 static void register_stdcmds(struct lil *lil);
+static void lil_set_error(struct lil *lil, enum lil_error err, const char *msg);
 
 #ifdef LIL_ENABLE_POOLS
 static struct lil_value **pool;
@@ -974,7 +970,7 @@ static struct lil_list *substitute(struct lil *lil)
 	struct lil_list *words = lil_alloc_list();
 
 	lil_skip_spaces(lil);
-	while (lil->head < lil->clen && !ateol(lil) && !lil->error) {
+	while (lil->head < lil->clen && !ateol(lil) && !lil->err) {
 		struct lil_value *w = alloc_value(NULL);
 
 		do {
@@ -993,7 +989,7 @@ static struct lil_list *substitute(struct lil *lil)
 			lil_free_value(wp);
 		} while (lil->head < lil->clen &&
 			 !eolchar(lil->code[lil->head]) &&
-			 !isspace(lil->code[lil->head]) && !lil->error);
+			 !isspace(lil->code[lil->head]) && !lil->err);
 		lil_skip_spaces(lil);
 
 		lil_list_append(words, w);
@@ -1042,13 +1038,7 @@ static struct lil_value *run_cmd(struct lil *lil, struct lil_func *cmd,
 	struct lil_value *r;
 
 	if (cmd->proc) {
-		size_t shead = lil->head;
-
 		r = cmd->proc(lil, words->c - 1, words->v + 1);
-		if (lil->error == ERROR_FIXHEAD) {
-			lil->error = ERROR_DEFAULT;
-			lil->err_head = shead;
-		}
 	} else {
 		lil_push_env(lil);
 		lil->env->func = cmd;
@@ -1102,18 +1092,18 @@ struct lil_value *lil_parse(struct lil *lil, const char *code, size_t codelen,
 	lil->parse_depth++;
 #ifdef LIL_ENABLE_RECLIMIT
 	if (lil->parse_depth > LIL_ENABLE_RECLIMIT) {
-		lil_set_error(lil, "Too many recursive calls");
+		lil_set_error(lil, LIL_ERR_DEPTH, "Too many recursive calls");
 		goto cleanup;
 	}
 #endif
 
 	if (lil->parse_depth == 1)
-		lil->error = 0;
+		lil->err = LIL_ERR_NONE;
 
 	if (funclevel)
 		lil->env->breakrun = 0;
 
-	while (lil->head < lil->clen && !lil->error) {
+	while (lil->head < lil->clen && !lil->err) {
 		if (words)
 			lil_free_list(words);
 
@@ -1122,7 +1112,7 @@ struct lil_value *lil_parse(struct lil *lil, const char *code, size_t codelen,
 		val = NULL;
 
 		words = substitute(lil);
-		if (!words || lil->error)
+		if (!words || lil->err)
 			goto cleanup;
 
 		if (words->c) {
@@ -1136,7 +1126,7 @@ struct lil_value *lil_parse(struct lil *lil, const char *code, size_t codelen,
 					snprintf(msg, sizeof(msg),
 						 "unknown function %s",
 						 words->v[0]->d);
-					lil_set_error_at(lil, lil->head, msg);
+					lil_set_error(lil, LIL_ERR_NOCMD, msg);
 					goto cleanup;
 				}
 			} else {
@@ -1182,38 +1172,25 @@ struct lil_value *lil_parse_value(struct lil *lil, struct lil_value *val,
 	return lil_parse(lil, val->d, val->l, funclevel);
 }
 
-void lil_set_error(struct lil *lil, const char *msg)
+static void lil_set_error(struct lil *lil, enum lil_error err, const char *msg)
 {
-	if (lil->error)
-		return;
-
+	assert(!lil->err);
 	free(lil->err_msg);
-	lil->error = ERROR_FIXHEAD;
-	lil->err_head = 0;
-	lil->err_msg = strdup(msg ? msg : "");
+	lil->err = err;
+	lil->err_msg = strdup(msg);
 }
 
-void lil_set_error_at(struct lil *lil, size_t pos, const char *msg)
+enum lil_error lil_error(struct lil *lil, const char **msg)
 {
-	if (lil->error)
-		return;
+	enum lil_error err = lil->err;
 
-	free(lil->err_msg);
-	lil->error = ERROR_DEFAULT;
-	lil->err_head = pos;
-	lil->err_msg = strdup(msg ? msg : "");
-}
-
-int lil_error(struct lil *lil, const char **msg, size_t *pos)
-{
-	if (!lil->error)
-		return 0;
+	if (!err)
+		return LIL_ERR_NONE;
 
 	*msg = lil->err_msg;
-	*pos = lil->err_head;
-	lil->error = ERROR_NOERROR;
+	lil->err = LIL_ERR_NONE;
 
-	return 1;
+	return err;
 }
 
 static void ee_expr(struct expreval *ee);
@@ -1642,7 +1619,7 @@ struct lil_value *lil_eval_expr(struct lil *lil, struct lil_value *code)
 	struct expreval ee;
 
 	code = lil_subst_to_value(lil, code);
-	if (lil->error)
+	if (lil->err)
 		return NULL;
 
 	ee.code = lil_to_string(code);
@@ -1664,13 +1641,13 @@ struct lil_value *lil_eval_expr(struct lil *lil, struct lil_value *code)
 	lil_free_value(code);
 	switch (ee.error) {
 	case EERR_DIVISION_BY_ZERO:
-		lil_set_error(lil, "division by zero in expression");
+		lil_set_error(lil, LIL_ERR_DOM, "division by zero");
 		return NULL;
 	case EERR_SYNTAX_ERROR:
-		lil_set_error(lil, "expression syntax error");
+		lil_set_error(lil, LIL_ERR_SYNTAX, "expression syntax");
 		return NULL;
 	case EERR_INVALID_EXPRESSION:
-		lil_set_error(lil, "invalid expression");
+		lil_set_error(lil, LIL_ERR_SYNTAX, "invalid expression");
 		return NULL;
 	case EERR_NO_ERROR:
 		break;
@@ -1994,7 +1971,7 @@ static struct lil_value *fnc_rename(struct lil *lil, size_t argc,
 		char *msg = malloc(24 + strlen(oldname));
 
 		sprintf(msg, "unknown function '%s'", oldname);
-		lil_set_error_at(lil, lil->head, msg);
+		lil_set_error(lil, LIL_ERR_NOCMD, msg);
 		free(msg);
 		return NULL;
 	}
@@ -2397,7 +2374,7 @@ static struct lil_value *fnc_foreach(struct lil *lil, size_t argc,
 		else
 			lil_free_value(rv);
 
-		if (lil->env->breakrun || lil->error)
+		if (lil->env->breakrun || lil->err)
 			break;
 	}
 
@@ -2499,7 +2476,7 @@ static struct lil_value *fnc_if(struct lil *lil, size_t argc,
 		return NULL;
 
 	val = lil_eval_expr(lil, argv[base]);
-	if (!val || lil->error)
+	if (!val || lil->err)
 		return NULL;
 
 	v = lil_to_boolean(val);
@@ -2530,9 +2507,9 @@ static struct lil_value *fnc_while(struct lil *lil, size_t argc,
 	if (argc < (size_t)base + 2)
 		return NULL;
 
-	while (!lil->error && !lil->env->breakrun) {
+	while (!lil->err && !lil->env->breakrun) {
 		val = lil_eval_expr(lil, argv[base]);
-		if (!val || lil->error)
+		if (!val || lil->err)
 			return NULL;
 
 		v = lil_to_boolean(val);
@@ -2562,9 +2539,9 @@ static struct lil_value *fnc_for(struct lil *lil, size_t argc,
 		return NULL;
 
 	lil_free_value(lil_parse_value(lil, argv[0], 0));
-	while (!lil->error && !lil->env->breakrun) {
+	while (!lil->err && !lil->env->breakrun) {
 		val = lil_eval_expr(lil, argv[1]);
-		if (!val || lil->error)
+		if (!val || lil->err)
 			return NULL;
 
 		if (!lil_to_boolean(val)) {
@@ -2889,12 +2866,12 @@ static struct lil_value *fnc_try(struct lil *lil, size_t argc,
 	if (argc < 1)
 		return NULL;
 
-	if (lil->error)
+	if (lil->err)
 		return NULL;
 
 	r = lil_parse_value(lil, argv[0], 0);
-	if (lil->error) {
-		lil->error = ERROR_NOERROR;
+	if (lil->err) {
+		lil->err = LIL_ERR_NONE;
 		lil_free_value(r);
 
 		if (argc > 1)
@@ -2908,7 +2885,8 @@ static struct lil_value *fnc_try(struct lil *lil, size_t argc,
 static struct lil_value *fnc_error(struct lil *lil, size_t argc,
 				   struct lil_value **argv)
 {
-	lil_set_error(lil, argc > 0 ? lil_to_string(argv[0]) : NULL);
+	lil_set_error(lil, LIL_ERR_USER,
+		      argc > 0 ? lil_to_string(argv[0]) : NULL);
 	return NULL;
 }
 
diff --git a/include/cli_lil.h b/include/cli_lil.h
index b8df94a766..cdaa79fd15 100644
--- a/include/cli_lil.h
+++ b/include/cli_lil.h
@@ -39,6 +39,38 @@ struct lil_callbacks {
 		      struct lil_value **value);
 };
 
+/**
+ * enum lil_error - Error codes returned by @lil_error
+ * LIL_ERR_NONE: No error
+ * LIL_ERR_OOM: Out of memory
+ * LIL_ERR_CASE: Missing case statement; generally a bug in the program or the
+ *               result of memory corruption.
+ * LIL_ERR_DEPTH: Too much recursion while parsing or evaluating
+ * LIL_ERR_SYNTAX: Unrecoverable syntax error
+ * LIL_ERR_EOF: Unexpected end of input; may be recoverable by prompting the
+ *              user for more input.
+ * LIL_ERR_INTR: Interrupted by Ctrl-C
+ * LIL_ERR_NOCMD: No such command
+ * LIL_ERR_NOVAR: No such variable
+ * LIL_ERR_ARGC: Incorrect number of arguments
+ * LIL_ERR_DOM: Numerical argument out of range (typically division by zero)
+ * LIL_ERR_USER: Error set by user
+ */
+enum lil_error {
+	LIL_ERR_NONE = 0,
+	LIL_ERR_OOM,
+	LIL_ERR_CASE,
+	LIL_ERR_DEPTH,
+	LIL_ERR_SYNTAX,
+	LIL_ERR_EOF,
+	LIL_ERR_INTR,
+	LIL_ERR_NOCMD,
+	LIL_ERR_NOVAR,
+	LIL_ERR_ARGC,
+	LIL_ERR_DOM,
+	LIL_ERR_USER,
+};
+
 struct lil *lil_new(const struct lil_callbacks *callbacks);
 void lil_free(struct lil *lil);
 
@@ -49,9 +81,7 @@ struct lil_value *lil_parse(struct lil *lil, const char *code, size_t codelen,
 struct lil_value *lil_parse_value(struct lil *lil, struct lil_value *val,
 				  int funclevel);
 
-void lil_set_error(struct lil *lil, const char *msg);
-void lil_set_error_at(struct lil *lil, size_t pos, const char *msg);
-int lil_error(struct lil *lil, const char **msg, size_t *pos);
+enum lil_error lil_error(struct lil *lil, const char **msg);
 
 const char *lil_to_string(struct lil_value *val);
 ssize_t lil_to_integer(struct lil_value *val);
-- 
2.32.0


  parent reply	other threads:[~2021-07-01  6:18 UTC|newest]

Thread overview: 107+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-07-01  6:15 [RFC PATCH 00/28] cli: Add a new shell Sean Anderson
2021-07-01  6:15 ` [RFC PATCH 01/28] Add Zlib License Sean Anderson
2021-07-05 15:29   ` Simon Glass
2021-07-01  6:15 ` [RFC PATCH 02/28] cli: Add LIL shell Sean Anderson
2021-07-02 11:03   ` Wolfgang Denk
2021-07-02 13:33     ` Sean Anderson
2021-07-03  2:12       ` Sean Anderson
2021-07-03 19:33         ` Wolfgang Denk
2021-07-05 15:29           ` Simon Glass
2021-07-05 19:10           ` Tom Rini
2021-07-05 19:47             ` Sean Anderson
2021-07-05 19:53               ` Tom Rini
2021-07-05 19:55                 ` Sean Anderson
2021-07-06  7:46               ` Wolfgang Denk
2021-07-06  7:52                 ` Michael Nazzareno Trimarchi
2021-07-06 14:57                   ` Simon Glass
2021-07-06 15:48                     ` Tom Rini
2021-07-07  8:22                     ` Michael Nazzareno Trimarchi
2021-07-06 14:54                 ` Tom Rini
2021-07-07  8:15                   ` Wolfgang Denk
2021-07-07 13:58                     ` Tom Rini
2021-07-07 14:10                       ` Wolfgang Denk
2021-07-07 14:14                         ` Tom Rini
2021-07-07 14:23                           ` Wolfgang Denk
2021-07-06  7:44             ` Wolfgang Denk
2021-07-06 15:43               ` Tom Rini
2021-07-06 16:09                 ` Kostas Michalopoulos
2021-07-07 13:32                   ` Sean Anderson
2021-07-07  8:15                 ` Wolfgang Denk
2021-07-07 13:46                   ` Sean Anderson
2021-07-07 13:51                     ` Tom Rini
2021-07-07 13:58                   ` Tom Rini
2021-07-07 14:48                   ` Marek Behun
2021-07-08  5:19                     ` Michael Nazzareno Trimarchi
2021-07-08 15:33                       ` Tom Rini
2021-07-08  4:56               ` Sean Anderson
2021-07-08 17:00                 ` Wolfgang Denk
2021-07-03 19:23       ` Wolfgang Denk
2021-07-01  6:15 ` [RFC PATCH 03/28] cli: lil: Replace strclone with strdup Sean Anderson
2021-07-02  8:36   ` Rasmus Villemoes
2021-07-02 11:38     ` Wolfgang Denk
2021-07-02 13:38     ` Sean Anderson
2021-07-02 14:28       ` Tom Rini
2021-07-02 22:18       ` Kostas Michalopoulos
2021-07-03  2:28         ` Sean Anderson
2021-07-03 19:26       ` Wolfgang Denk
2021-07-05  5:07         ` Steve Bennett
2021-07-05 14:42           ` Sean Anderson
2021-07-05 15:29             ` Simon Glass
2021-07-05 15:42               ` Sean Anderson
2021-07-05 17:50             ` Wolfgang Denk
2021-07-08  4:37               ` Sean Anderson
2021-07-08 16:13                 ` Wolfgang Denk
2021-07-01  6:15 ` [RFC PATCH 04/28] cli: lil: Remove most functions by default Sean Anderson
2021-07-05 15:29   ` Simon Glass
2021-07-01  6:15 ` [RFC PATCH 05/28] cli: lil: Rename some functions to be more like TCL Sean Anderson
2021-07-05 15:29   ` Simon Glass
2021-07-05 15:54     ` Sean Anderson
2021-07-05 17:58       ` Wolfgang Denk
2021-07-05 18:51         ` Tom Rini
2021-07-05 21:02           ` Simon Glass
2021-07-05 21:36             ` Tom Rini
2021-07-06  7:52           ` Wolfgang Denk
2021-07-06 15:21             ` Simon Glass
2021-07-06 15:33             ` Tom Rini
2021-07-06 16:00               ` Kostas Michalopoulos
2021-07-07  8:16               ` Wolfgang Denk
2021-07-07 13:58                 ` Tom Rini
2021-07-05 19:46         ` Sean Anderson
2021-07-06  7:50           ` Wolfgang Denk
2021-07-08  4:47             ` Sean Anderson
2021-07-08 16:21               ` Wolfgang Denk
2021-07-01  6:15 ` [RFC PATCH 06/28] cli: lil: Convert some defines to enums Sean Anderson
2021-07-01  6:15 ` [RFC PATCH 07/28] cli: lil: Simplify callbacks Sean Anderson
2021-07-01  6:15 ` [RFC PATCH 08/28] cli: lil: Handle commands with dots Sean Anderson
2021-07-01  6:15 ` Sean Anderson [this message]
2021-07-01  6:15 ` [RFC PATCH 10/28] cli: lil: Add printf-style format helper for errors Sean Anderson
2021-07-01  6:15 ` [RFC PATCH 11/28] cli: lil: Add several helper functions " Sean Anderson
2021-07-01  6:15 ` [RFC PATCH 12/28] cli: lil: Check for ctrl-c Sean Anderson
2021-07-05 15:29   ` Simon Glass
2021-07-01  6:15 ` [RFC PATCH 13/28] cli: lil: Wire up LIL to the rest of U-Boot Sean Anderson
2021-07-02  8:18   ` Rasmus Villemoes
2021-07-02 13:40     ` Sean Anderson
2021-07-05 15:29   ` Simon Glass
2021-07-01  6:15 ` [RFC PATCH 14/28] cli: lil: Document structures Sean Anderson
2021-07-01  6:15 ` [RFC PATCH 15/28] cli: lil: Convert LIL_ENABLE_POOLS to Kconfig Sean Anderson
2021-07-01  6:15 ` [RFC PATCH 16/28] cli: lil: Convert LIL_ENABLE_RECLIMIT to KConfig Sean Anderson
2021-07-01  6:16 ` [RFC PATCH 17/28] test: Add tests for LIL Sean Anderson
2021-07-05 15:29   ` Simon Glass
2021-07-01  6:16 ` [RFC PATCH 18/28] cli: lil: Remove duplicate function bodies Sean Anderson
2021-07-01  6:16 ` [RFC PATCH 19/28] cli: lil: Add "symbol" structure Sean Anderson
2021-07-01  6:16 ` [RFC PATCH 20/28] cli: lil: Add config to enable debug output Sean Anderson
2021-07-01  6:16 ` [RFC PATCH 21/28] cli: lil: Add a distinct parsing step Sean Anderson
2021-07-01  6:16 ` [RFC PATCH 22/28] env: Add a priv pointer to hwalk_r Sean Anderson
2021-07-01 20:10   ` Tom Rini
2021-07-01  6:16 ` [RFC PATCH 23/28] cli: lil: Handle OOM for hm_put Sean Anderson
2021-07-01  6:16 ` [RFC PATCH 24/28] cli: lil: Make proc always take 3 arguments Sean Anderson
2021-07-01  6:16 ` [RFC PATCH 25/28] cli: lil: Always quote items in lil_list_to_value Sean Anderson
2021-07-01  6:16 ` [RFC PATCH 26/28] cli: lil: Allocate len even when str is NULL in alloc_value_len Sean Anderson
2021-07-01  6:16 ` [RFC PATCH 27/28] cli: lil: Add a function to quote values Sean Anderson
2021-07-01  6:16 ` [RFC PATCH 28/28] cli: lil: Load procs from the environment Sean Anderson
2021-07-01 20:21 ` [RFC PATCH 00/28] cli: Add a new shell Tom Rini
2021-07-02 11:30   ` Wolfgang Denk
2021-07-02 13:56     ` Sean Anderson
2021-07-02 14:07   ` Sean Anderson
2021-07-08  3:49 ` Heiko Schocher
2021-07-08  4:26   ` Sean Anderson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210701061611.957918-10-seanga2@gmail.com \
    --to=seanga2@gmail.com \
    --cc=badsector@runtimeterror.com \
    --cc=marek.behun@nic.cz \
    --cc=roland.gaudig-oss@weidmueller.com \
    --cc=sjg@chromium.org \
    --cc=trini@konsulko.com \
    --cc=u-boot@lists.denx.de \
    --cc=wd@denx.de \
    --cc=xypron.glpk@gmx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.