Browse Source

shell: move varcmp() to shell_common.h and use it in hush

function                                             old     new   delta
unset_local_var                                        -     112    +112
findvar                                               31      35      +4
set_vars_and_save_old                                144     141      -3
helper_export_local                                  235     230      -5
set_local_var                                        425     416      -9
handle_changed_special_names                          38      27     -11
builtin_unset                                        154     141     -13
builtin_getopts                                      404     391     -13
get_local_var_value                                  281     260     -21
get_ptr_to_local_var                                  71      45     -26
unset_local_var_len                                  139       -    -139
------------------------------------------------------------------------------
(add/remove: 1/1 grow/shrink: 1/8 up/down: 116/-240)         Total: -124 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Denys Vlasenko 10 months ago
parent
commit
96769486e2
4 changed files with 37 additions and 50 deletions
  1. 0 24
      shell/ash.c
  2. 16 26
      shell/hush.c
  3. 19 0
      shell/shell_common.c
  4. 2 0
      shell/shell_common.h

+ 0 - 24
shell/ash.c

@@ -2259,30 +2259,6 @@ getoptsreset(const char *value)
 }
 #endif
 
-/*
- * Compares two strings up to the first = or '\0'.  The first
- * string must be terminated by '='; the second may be terminated by
- * either '=' or '\0'.
- */
-static int
-varcmp(const char *p, const char *q)
-{
-	int c, d;
-
-	while ((c = *p) == (d = *q)) {
-		if (c == '\0' || c == '=')
-			goto out;
-		p++;
-		q++;
-	}
-	if (c == '=')
-		c = '\0';
-	if (d == '=')
-		d = '\0';
- out:
-	return c - d;
-}
-
 /*
  * Find the appropriate entry in the hash table from the name.
  */

+ 16 - 26
shell/hush.c

@@ -2255,14 +2255,14 @@ static const char *get_cwd(int force)
 /*
  * Shell and environment variable support
  */
-static struct variable **get_ptr_to_local_var(const char *name, unsigned len)
+static struct variable **get_ptr_to_local_var(const char *name)
 {
 	struct variable **pp;
 	struct variable *cur;
 
 	pp = &G.top_var;
 	while ((cur = *pp) != NULL) {
-		if (strncmp(cur->varstr, name, len) == 0 && cur->varstr[len] == '=')
+		if (varcmp(cur->varstr, name) == 0)
 			return pp;
 		pp = &cur->next;
 	}
@@ -2272,21 +2272,20 @@ static struct variable **get_ptr_to_local_var(const char *name, unsigned len)
 static const char* FAST_FUNC get_local_var_value(const char *name)
 {
 	struct variable **vpp;
-	unsigned len = strlen(name);
 
 	if (G.expanded_assignments) {
 		char **cpp = G.expanded_assignments;
 		while (*cpp) {
 			char *cp = *cpp;
-			if (strncmp(cp, name, len) == 0 && cp[len] == '=')
-				return cp + len + 1;
+			if (varcmp(cp, name) == 0)
+				return strchr(cp, '=') + 1;
 			cpp++;
 		}
 	}
 
-	vpp = get_ptr_to_local_var(name, len);
+	vpp = get_ptr_to_local_var(name);
 	if (vpp)
-		return (*vpp)->varstr + len + 1;
+		return strchr((*vpp)->varstr, '=') + 1;
 
 	if (strcmp(name, "PPID") == 0)
 		return utoa(G.root_ppid);
@@ -2319,13 +2318,11 @@ static const char* FAST_FUNC get_local_var_value(const char *name)
 }
 
 #if ENABLE_HUSH_GETOPTS
-static void handle_changed_special_names(const char *name, unsigned name_len)
+static void handle_changed_special_names(const char *name)
 {
-	if (name_len == 6) {
-		if (strncmp(name, "OPTIND", 6) == 0) {
-			G.getopt_count = 0;
-			return;
-		}
+	if (varcmp(name, "OPTIND") == 0) {
+		G.getopt_count = 0;
+		return;
 	}
 }
 #else
@@ -2476,7 +2473,7 @@ static int set_local_var(char *str, unsigned flags)
 	}
 	free(free_me);
 
-	handle_changed_special_names(cur->varstr, name_len - 1);
+	handle_changed_special_names(cur->varstr);
 
 	return retval;
 }
@@ -2499,16 +2496,14 @@ static void set_pwd_var(unsigned flag)
 }
 
 #if ENABLE_HUSH_UNSET || ENABLE_HUSH_GETOPTS
-static int unset_local_var_len(const char *name, int name_len)
+static int unset_local_var(const char *name)
 {
 	struct variable *cur;
 	struct variable **cur_pp;
 
 	cur_pp = &G.top_var;
 	while ((cur = *cur_pp) != NULL) {
-		if (strncmp(cur->varstr, name, name_len) == 0
-		 && cur->varstr[name_len] == '='
-		) {
+		if (varcmp(cur->varstr, name) == 0) {
 			if (cur->flg_read_only) {
 				bb_error_msg("%s: readonly variable", name);
 				return EXIT_FAILURE;
@@ -2527,15 +2522,10 @@ static int unset_local_var_len(const char *name, int name_len)
 	}
 
 	/* Handle "unset LINENO" et al even if did not find the variable to unset */
-	handle_changed_special_names(name, name_len);
+	handle_changed_special_names(name);
 
 	return EXIT_SUCCESS;
 }
-
-static int unset_local_var(const char *name)
-{
-	return unset_local_var_len(name, strlen(name));
-}
 #endif
 
 
@@ -2581,7 +2571,7 @@ static void set_vars_and_save_old(char **strings)
 		eq = strchr(*s, '=');
 		if (HUSH_DEBUG && !eq)
 			bb_simple_error_msg_and_die("BUG in varexp4");
-		var_pp = get_ptr_to_local_var(*s, eq - *s);
+		var_pp = get_ptr_to_local_var(*s);
 		if (var_pp) {
 			var_p = *var_pp;
 			if (var_p->flg_read_only) {
@@ -11215,7 +11205,7 @@ static int helper_export_local(char **argv, unsigned flags)
 		if (*name_end == '\0') {
 			struct variable *var, **vpp;
 
-			vpp = get_ptr_to_local_var(name, name_end - name);
+			vpp = get_ptr_to_local_var(name);
 			var = vpp ? *vpp : NULL;
 
 			if (flags & SETFLAG_UNEXPORT) {

+ 19 - 0
shell/shell_common.c

@@ -22,6 +22,25 @@
 const char defifsvar[] ALIGN1 = "IFS= \t\n";
 const char defoptindvar[] ALIGN1 = "OPTIND=1";
 
+/* Compare two strings up to the first '=' or '\0'. */
+int FAST_FUNC varcmp(const char *p, const char *q)
+{
+	int c, d;
+
+	while ((c = *p) == (d = *q)) {
+		if (c == '\0' || c == '=')
+			goto out;
+		p++;
+		q++;
+	}
+	if (c == '=')
+		c = '\0';
+	if (d == '=')
+		d = '\0';
+ out:
+	return c - d;
+}
+
 /* read builtin */
 
 /* Needs to be interruptible: shell must handle traps and shell-special signals

+ 2 - 0
shell/shell_common.h

@@ -26,6 +26,8 @@ extern const char defifsvar[] ALIGN1; /* "IFS= \t\n" */
 
 extern const char defoptindvar[] ALIGN1; /* "OPTIND=1" */
 
+int FAST_FUNC varcmp(const char *p, const char *q);
+
 /* Builtins */
 
 struct builtin_read_params {