From 96769486e20fd5f1142cae0db2cbacef31dc75e9 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 17 Jun 2023 21:02:37 +0200 Subject: 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 --- shell/ash.c | 24 ------------------------ shell/hush.c | 42 ++++++++++++++++-------------------------- shell/shell_common.c | 19 +++++++++++++++++++ shell/shell_common.h | 2 ++ 4 files changed, 37 insertions(+), 50 deletions(-) diff --git a/shell/ash.c b/shell/ash.c index dde36dd..96d2433 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -2260,30 +2260,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. */ static struct var ** diff --git a/shell/hush.c b/shell/hush.c index dbc4aec..4261829 100644 --- a/shell/hush.c +++ b/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) { diff --git a/shell/shell_common.c b/shell/shell_common.c index 1eca101..e5c2cef 100644 --- a/shell/shell_common.c +++ b/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 diff --git a/shell/shell_common.h b/shell/shell_common.h index 7b478f1..fab676e 100644 --- a/shell/shell_common.h +++ b/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 { -- cgit v1.1