[PATCH 09/10] setexpr: Convert to use a struct for values

Simon Glass sjg at chromium.org
Sun Nov 1 22:15:43 CET 2020


At present a ulong is used to hold operand values. This means that
strings cannot be used. While most operations are not useful for strings,
concatenation is. As a starting point to supporting strings, convert the
code to use a struct instead of a ulong for operands.

Signed-off-by: Simon Glass <sjg at chromium.org>
---

 cmd/setexpr.c | 111 ++++++++++++++++++++++++++++++--------------------
 1 file changed, 67 insertions(+), 44 deletions(-)

diff --git a/cmd/setexpr.c b/cmd/setexpr.c
index d364dbc2bc5..8a3654505da 100644
--- a/cmd/setexpr.c
+++ b/cmd/setexpr.c
@@ -15,8 +15,19 @@
 #include <log.h>
 #include <mapmem.h>
 
-static ulong get_arg(char *s, int w)
+/**
+ * struct expr_arg: Holds an argument to an expression
+ *
+ * @ival: Integer value (if width is not CMD_DATA_SIZE_STR)
+ */
+struct expr_arg {
+	ulong ival;
+};
+
+static int get_arg(char *s, int w, struct expr_arg *argp)
 {
+	struct expr_arg arg;
+
 	/*
 	 * If the parameter starts with a '*' then assume it is a pointer to
 	 * the value we want.
@@ -32,26 +43,33 @@ static ulong get_arg(char *s, int w)
 			p = map_sysmem(addr, sizeof(uchar));
 			val = (ulong)*(uchar *)p;
 			unmap_sysmem(p);
-			return val;
+			arg.ival = val;
+			break;
 		case 2:
 			p = map_sysmem(addr, sizeof(ushort));
 			val = (ulong)*(ushort *)p;
 			unmap_sysmem(p);
-			return val;
+			arg.ival = val;
+			break;
 		case 4:
 			p = map_sysmem(addr, sizeof(u32));
 			val = *(u32 *)p;
 			unmap_sysmem(p);
-			return val;
+			arg.ival = val;
+			break;
 		default:
 			p = map_sysmem(addr, sizeof(ulong));
 			val = *p;
 			unmap_sysmem(p);
-			return val;
+			arg.ival = val;
+			break;
 		}
 	} else {
-		return simple_strtoul(s, NULL, 16);
+		arg.ival = simple_strtoul(s, NULL, 16);
 	}
+	*argp = arg;
+
+	return 0;
 }
 
 #ifdef CONFIG_REGEX
@@ -321,7 +339,7 @@ static int regex_sub_var(const char *name, const char *r, const char *s,
 static int do_setexpr(struct cmd_tbl *cmdtp, int flag, int argc,
 		      char *const argv[])
 {
-	ulong a, b;
+	struct expr_arg aval, bval;
 	ulong value;
 	int w;
 
@@ -339,13 +357,12 @@ static int do_setexpr(struct cmd_tbl *cmdtp, int flag, int argc,
 
 	w = cmd_get_data_size(argv[0], 4);
 
-	a = get_arg(argv[2], w);
+	if (get_arg(argv[2], w, &aval))
+		return CMD_RET_FAILURE;
 
 	/* plain assignment: "setexpr name value" */
-	if (argc == 3) {
-		env_set_hex(argv[1], a);
-		return 0;
-	}
+	if (argc == 3)
+		return env_set_hex(argv[1], aval.ival);
 
 	/* 5 or 6 args (6 args only with [g]sub) */
 #ifdef CONFIG_REGEX
@@ -367,39 +384,45 @@ static int do_setexpr(struct cmd_tbl *cmdtp, int flag, int argc,
 	if (strlen(argv[3]) != 1)
 		return CMD_RET_USAGE;
 
-	b = get_arg(argv[4], w);
-
-	switch (argv[3][0]) {
-	case '|':
-		value = a | b;
-		break;
-	case '&':
-		value = a & b;
-		break;
-	case '+':
-		value = a + b;
-		break;
-	case '^':
-		value = a ^ b;
-		break;
-	case '-':
-		value = a - b;
-		break;
-	case '*':
-		value = a * b;
-		break;
-	case '/':
-		value = a / b;
-		break;
-	case '%':
-		value = a % b;
-		break;
-	default:
-		printf("invalid op\n");
-		return 1;
-	}
+	if (get_arg(argv[4], w, &bval))
+		return CMD_RET_FAILURE;
 
-	env_set_hex(argv[1], value);
+	if (w != CMD_DATA_SIZE_STR) {
+		ulong a = aval.ival;
+		ulong b = bval.ival;
+
+		switch (argv[3][0]) {
+		case '|':
+			value = a | b;
+			break;
+		case '&':
+			value = a & b;
+			break;
+		case '+':
+			value = a + b;
+			break;
+		case '^':
+			value = a ^ b;
+			break;
+		case '-':
+			value = a - b;
+			break;
+		case '*':
+			value = a * b;
+			break;
+		case '/':
+			value = a / b;
+			break;
+		case '%':
+			value = a % b;
+			break;
+		default:
+			printf("invalid op\n");
+			return 1;
+		}
+
+		env_set_hex(argv[1], value);
+	}
 
 	return 0;
 }
-- 
2.29.1.341.ge80a0c044ae-goog



More information about the U-Boot mailing list