aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2023-06-17 21:02:37 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2023-06-17 21:13:13 +0200
commit96769486e20fd5f1142cae0db2cbacef31dc75e9 (patch)
treef40b504f812eda9787084aaaf377fe1a144466d0
parentd0441222db80c6fc0c47fa014106d38e25bfada7 (diff)
downloadbusybox-w32-96769486e20fd5f1142cae0db2cbacef31dc75e9.tar.gz
busybox-w32-96769486e20fd5f1142cae0db2cbacef31dc75e9.tar.bz2
busybox-w32-96769486e20fd5f1142cae0db2cbacef31dc75e9.zip
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>
-rw-r--r--shell/ash.c24
-rw-r--r--shell/hush.c42
-rw-r--r--shell/shell_common.c19
-rw-r--r--shell/shell_common.h2
4 files changed, 37 insertions, 50 deletions
diff --git a/shell/ash.c b/shell/ash.c
index dde36dd7c..96d2433d3 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -2260,30 +2260,6 @@ getoptsreset(const char *value)
2260#endif 2260#endif
2261 2261
2262/* 2262/*
2263 * Compares two strings up to the first = or '\0'. The first
2264 * string must be terminated by '='; the second may be terminated by
2265 * either '=' or '\0'.
2266 */
2267static int
2268varcmp(const char *p, const char *q)
2269{
2270 int c, d;
2271
2272 while ((c = *p) == (d = *q)) {
2273 if (c == '\0' || c == '=')
2274 goto out;
2275 p++;
2276 q++;
2277 }
2278 if (c == '=')
2279 c = '\0';
2280 if (d == '=')
2281 d = '\0';
2282 out:
2283 return c - d;
2284}
2285
2286/*
2287 * Find the appropriate entry in the hash table from the name. 2263 * Find the appropriate entry in the hash table from the name.
2288 */ 2264 */
2289static struct var ** 2265static struct var **
diff --git a/shell/hush.c b/shell/hush.c
index dbc4aecab..426182924 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -2255,14 +2255,14 @@ static const char *get_cwd(int force)
2255/* 2255/*
2256 * Shell and environment variable support 2256 * Shell and environment variable support
2257 */ 2257 */
2258static struct variable **get_ptr_to_local_var(const char *name, unsigned len) 2258static struct variable **get_ptr_to_local_var(const char *name)
2259{ 2259{
2260 struct variable **pp; 2260 struct variable **pp;
2261 struct variable *cur; 2261 struct variable *cur;
2262 2262
2263 pp = &G.top_var; 2263 pp = &G.top_var;
2264 while ((cur = *pp) != NULL) { 2264 while ((cur = *pp) != NULL) {
2265 if (strncmp(cur->varstr, name, len) == 0 && cur->varstr[len] == '=') 2265 if (varcmp(cur->varstr, name) == 0)
2266 return pp; 2266 return pp;
2267 pp = &cur->next; 2267 pp = &cur->next;
2268 } 2268 }
@@ -2272,21 +2272,20 @@ static struct variable **get_ptr_to_local_var(const char *name, unsigned len)
2272static const char* FAST_FUNC get_local_var_value(const char *name) 2272static const char* FAST_FUNC get_local_var_value(const char *name)
2273{ 2273{
2274 struct variable **vpp; 2274 struct variable **vpp;
2275 unsigned len = strlen(name);
2276 2275
2277 if (G.expanded_assignments) { 2276 if (G.expanded_assignments) {
2278 char **cpp = G.expanded_assignments; 2277 char **cpp = G.expanded_assignments;
2279 while (*cpp) { 2278 while (*cpp) {
2280 char *cp = *cpp; 2279 char *cp = *cpp;
2281 if (strncmp(cp, name, len) == 0 && cp[len] == '=') 2280 if (varcmp(cp, name) == 0)
2282 return cp + len + 1; 2281 return strchr(cp, '=') + 1;
2283 cpp++; 2282 cpp++;
2284 } 2283 }
2285 } 2284 }
2286 2285
2287 vpp = get_ptr_to_local_var(name, len); 2286 vpp = get_ptr_to_local_var(name);
2288 if (vpp) 2287 if (vpp)
2289 return (*vpp)->varstr + len + 1; 2288 return strchr((*vpp)->varstr, '=') + 1;
2290 2289
2291 if (strcmp(name, "PPID") == 0) 2290 if (strcmp(name, "PPID") == 0)
2292 return utoa(G.root_ppid); 2291 return utoa(G.root_ppid);
@@ -2319,13 +2318,11 @@ static const char* FAST_FUNC get_local_var_value(const char *name)
2319} 2318}
2320 2319
2321#if ENABLE_HUSH_GETOPTS 2320#if ENABLE_HUSH_GETOPTS
2322static void handle_changed_special_names(const char *name, unsigned name_len) 2321static void handle_changed_special_names(const char *name)
2323{ 2322{
2324 if (name_len == 6) { 2323 if (varcmp(name, "OPTIND") == 0) {
2325 if (strncmp(name, "OPTIND", 6) == 0) { 2324 G.getopt_count = 0;
2326 G.getopt_count = 0; 2325 return;
2327 return;
2328 }
2329 } 2326 }
2330} 2327}
2331#else 2328#else
@@ -2476,7 +2473,7 @@ static int set_local_var(char *str, unsigned flags)
2476 } 2473 }
2477 free(free_me); 2474 free(free_me);
2478 2475
2479 handle_changed_special_names(cur->varstr, name_len - 1); 2476 handle_changed_special_names(cur->varstr);
2480 2477
2481 return retval; 2478 return retval;
2482} 2479}
@@ -2499,16 +2496,14 @@ static void set_pwd_var(unsigned flag)
2499} 2496}
2500 2497
2501#if ENABLE_HUSH_UNSET || ENABLE_HUSH_GETOPTS 2498#if ENABLE_HUSH_UNSET || ENABLE_HUSH_GETOPTS
2502static int unset_local_var_len(const char *name, int name_len) 2499static int unset_local_var(const char *name)
2503{ 2500{
2504 struct variable *cur; 2501 struct variable *cur;
2505 struct variable **cur_pp; 2502 struct variable **cur_pp;
2506 2503
2507 cur_pp = &G.top_var; 2504 cur_pp = &G.top_var;
2508 while ((cur = *cur_pp) != NULL) { 2505 while ((cur = *cur_pp) != NULL) {
2509 if (strncmp(cur->varstr, name, name_len) == 0 2506 if (varcmp(cur->varstr, name) == 0) {
2510 && cur->varstr[name_len] == '='
2511 ) {
2512 if (cur->flg_read_only) { 2507 if (cur->flg_read_only) {
2513 bb_error_msg("%s: readonly variable", name); 2508 bb_error_msg("%s: readonly variable", name);
2514 return EXIT_FAILURE; 2509 return EXIT_FAILURE;
@@ -2527,15 +2522,10 @@ static int unset_local_var_len(const char *name, int name_len)
2527 } 2522 }
2528 2523
2529 /* Handle "unset LINENO" et al even if did not find the variable to unset */ 2524 /* Handle "unset LINENO" et al even if did not find the variable to unset */
2530 handle_changed_special_names(name, name_len); 2525 handle_changed_special_names(name);
2531 2526
2532 return EXIT_SUCCESS; 2527 return EXIT_SUCCESS;
2533} 2528}
2534
2535static int unset_local_var(const char *name)
2536{
2537 return unset_local_var_len(name, strlen(name));
2538}
2539#endif 2529#endif
2540 2530
2541 2531
@@ -2581,7 +2571,7 @@ static void set_vars_and_save_old(char **strings)
2581 eq = strchr(*s, '='); 2571 eq = strchr(*s, '=');
2582 if (HUSH_DEBUG && !eq) 2572 if (HUSH_DEBUG && !eq)
2583 bb_simple_error_msg_and_die("BUG in varexp4"); 2573 bb_simple_error_msg_and_die("BUG in varexp4");
2584 var_pp = get_ptr_to_local_var(*s, eq - *s); 2574 var_pp = get_ptr_to_local_var(*s);
2585 if (var_pp) { 2575 if (var_pp) {
2586 var_p = *var_pp; 2576 var_p = *var_pp;
2587 if (var_p->flg_read_only) { 2577 if (var_p->flg_read_only) {
@@ -11215,7 +11205,7 @@ static int helper_export_local(char **argv, unsigned flags)
11215 if (*name_end == '\0') { 11205 if (*name_end == '\0') {
11216 struct variable *var, **vpp; 11206 struct variable *var, **vpp;
11217 11207
11218 vpp = get_ptr_to_local_var(name, name_end - name); 11208 vpp = get_ptr_to_local_var(name);
11219 var = vpp ? *vpp : NULL; 11209 var = vpp ? *vpp : NULL;
11220 11210
11221 if (flags & SETFLAG_UNEXPORT) { 11211 if (flags & SETFLAG_UNEXPORT) {
diff --git a/shell/shell_common.c b/shell/shell_common.c
index 1eca101b9..e5c2cefb3 100644
--- a/shell/shell_common.c
+++ b/shell/shell_common.c
@@ -22,6 +22,25 @@
22const char defifsvar[] ALIGN1 = "IFS= \t\n"; 22const char defifsvar[] ALIGN1 = "IFS= \t\n";
23const char defoptindvar[] ALIGN1 = "OPTIND=1"; 23const char defoptindvar[] ALIGN1 = "OPTIND=1";
24 24
25/* Compare two strings up to the first '=' or '\0'. */
26int FAST_FUNC varcmp(const char *p, const char *q)
27{
28 int c, d;
29
30 while ((c = *p) == (d = *q)) {
31 if (c == '\0' || c == '=')
32 goto out;
33 p++;
34 q++;
35 }
36 if (c == '=')
37 c = '\0';
38 if (d == '=')
39 d = '\0';
40 out:
41 return c - d;
42}
43
25/* read builtin */ 44/* read builtin */
26 45
27/* Needs to be interruptible: shell must handle traps and shell-special signals 46/* 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 7b478f1df..fab676e4a 100644
--- a/shell/shell_common.h
+++ b/shell/shell_common.h
@@ -26,6 +26,8 @@ extern const char defifsvar[] ALIGN1; /* "IFS= \t\n" */
26 26
27extern const char defoptindvar[] ALIGN1; /* "OPTIND=1" */ 27extern const char defoptindvar[] ALIGN1; /* "OPTIND=1" */
28 28
29int FAST_FUNC varcmp(const char *p, const char *q);
30
29/* Builtins */ 31/* Builtins */
30 32
31struct builtin_read_params { 33struct builtin_read_params {