diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2023-06-17 21:02:37 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2023-06-17 21:13:13 +0200 |
commit | 96769486e20fd5f1142cae0db2cbacef31dc75e9 (patch) | |
tree | f40b504f812eda9787084aaaf377fe1a144466d0 | |
parent | d0441222db80c6fc0c47fa014106d38e25bfada7 (diff) | |
download | busybox-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.c | 24 | ||||
-rw-r--r-- | shell/hush.c | 42 | ||||
-rw-r--r-- | shell/shell_common.c | 19 | ||||
-rw-r--r-- | shell/shell_common.h | 2 |
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 | */ | ||
2267 | static int | ||
2268 | varcmp(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 | */ |
2289 | static struct var ** | 2265 | static 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 | */ |
2258 | static struct variable **get_ptr_to_local_var(const char *name, unsigned len) | 2258 | static 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) | |||
2272 | static const char* FAST_FUNC get_local_var_value(const char *name) | 2272 | static 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 |
2322 | static void handle_changed_special_names(const char *name, unsigned name_len) | 2321 | static 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 |
2502 | static int unset_local_var_len(const char *name, int name_len) | 2499 | static 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 | |||
2535 | static 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 @@ | |||
22 | const char defifsvar[] ALIGN1 = "IFS= \t\n"; | 22 | const char defifsvar[] ALIGN1 = "IFS= \t\n"; |
23 | const char defoptindvar[] ALIGN1 = "OPTIND=1"; | 23 | const char defoptindvar[] ALIGN1 = "OPTIND=1"; |
24 | 24 | ||
25 | /* Compare two strings up to the first '=' or '\0'. */ | ||
26 | int 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 | ||
27 | extern const char defoptindvar[] ALIGN1; /* "OPTIND=1" */ | 27 | extern const char defoptindvar[] ALIGN1; /* "OPTIND=1" */ |
28 | 28 | ||
29 | int FAST_FUNC varcmp(const char *p, const char *q); | ||
30 | |||
29 | /* Builtins */ | 31 | /* Builtins */ |
30 | 32 | ||
31 | struct builtin_read_params { | 33 | struct builtin_read_params { |