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>
This commit is contained in:
parent
d0441222db
commit
96769486e2
4 changed files with 37 additions and 50 deletions
24
shell/ash.c
24
shell/ash.c
|
@ -2259,30 +2259,6 @@ getoptsreset(const char *value)
|
||||||
}
|
}
|
||||||
#endif
|
#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.
|
* Find the appropriate entry in the hash table from the name.
|
||||||
*/
|
*/
|
||||||
|
|
42
shell/hush.c
42
shell/hush.c
|
@ -2255,14 +2255,14 @@ static const char *get_cwd(int force)
|
||||||
/*
|
/*
|
||||||
* Shell and environment variable support
|
* 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 **pp;
|
||||||
struct variable *cur;
|
struct variable *cur;
|
||||||
|
|
||||||
pp = &G.top_var;
|
pp = &G.top_var;
|
||||||
while ((cur = *pp) != NULL) {
|
while ((cur = *pp) != NULL) {
|
||||||
if (strncmp(cur->varstr, name, len) == 0 && cur->varstr[len] == '=')
|
if (varcmp(cur->varstr, name) == 0)
|
||||||
return pp;
|
return pp;
|
||||||
pp = &cur->next;
|
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)
|
static const char* FAST_FUNC get_local_var_value(const char *name)
|
||||||
{
|
{
|
||||||
struct variable **vpp;
|
struct variable **vpp;
|
||||||
unsigned len = strlen(name);
|
|
||||||
|
|
||||||
if (G.expanded_assignments) {
|
if (G.expanded_assignments) {
|
||||||
char **cpp = G.expanded_assignments;
|
char **cpp = G.expanded_assignments;
|
||||||
while (*cpp) {
|
while (*cpp) {
|
||||||
char *cp = *cpp;
|
char *cp = *cpp;
|
||||||
if (strncmp(cp, name, len) == 0 && cp[len] == '=')
|
if (varcmp(cp, name) == 0)
|
||||||
return cp + len + 1;
|
return strchr(cp, '=') + 1;
|
||||||
cpp++;
|
cpp++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vpp = get_ptr_to_local_var(name, len);
|
vpp = get_ptr_to_local_var(name);
|
||||||
if (vpp)
|
if (vpp)
|
||||||
return (*vpp)->varstr + len + 1;
|
return strchr((*vpp)->varstr, '=') + 1;
|
||||||
|
|
||||||
if (strcmp(name, "PPID") == 0)
|
if (strcmp(name, "PPID") == 0)
|
||||||
return utoa(G.root_ppid);
|
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
|
#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 (varcmp(name, "OPTIND") == 0) {
|
||||||
if (strncmp(name, "OPTIND", 6) == 0) {
|
G.getopt_count = 0;
|
||||||
G.getopt_count = 0;
|
return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@ -2476,7 +2473,7 @@ static int set_local_var(char *str, unsigned flags)
|
||||||
}
|
}
|
||||||
free(free_me);
|
free(free_me);
|
||||||
|
|
||||||
handle_changed_special_names(cur->varstr, name_len - 1);
|
handle_changed_special_names(cur->varstr);
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
@ -2499,16 +2496,14 @@ static void set_pwd_var(unsigned flag)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ENABLE_HUSH_UNSET || ENABLE_HUSH_GETOPTS
|
#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;
|
||||||
struct variable **cur_pp;
|
struct variable **cur_pp;
|
||||||
|
|
||||||
cur_pp = &G.top_var;
|
cur_pp = &G.top_var;
|
||||||
while ((cur = *cur_pp) != NULL) {
|
while ((cur = *cur_pp) != NULL) {
|
||||||
if (strncmp(cur->varstr, name, name_len) == 0
|
if (varcmp(cur->varstr, name) == 0) {
|
||||||
&& cur->varstr[name_len] == '='
|
|
||||||
) {
|
|
||||||
if (cur->flg_read_only) {
|
if (cur->flg_read_only) {
|
||||||
bb_error_msg("%s: readonly variable", name);
|
bb_error_msg("%s: readonly variable", name);
|
||||||
return EXIT_FAILURE;
|
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 "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;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int unset_local_var(const char *name)
|
|
||||||
{
|
|
||||||
return unset_local_var_len(name, strlen(name));
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -2581,7 +2571,7 @@ static void set_vars_and_save_old(char **strings)
|
||||||
eq = strchr(*s, '=');
|
eq = strchr(*s, '=');
|
||||||
if (HUSH_DEBUG && !eq)
|
if (HUSH_DEBUG && !eq)
|
||||||
bb_simple_error_msg_and_die("BUG in varexp4");
|
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) {
|
if (var_pp) {
|
||||||
var_p = *var_pp;
|
var_p = *var_pp;
|
||||||
if (var_p->flg_read_only) {
|
if (var_p->flg_read_only) {
|
||||||
|
@ -11215,7 +11205,7 @@ static int helper_export_local(char **argv, unsigned flags)
|
||||||
if (*name_end == '\0') {
|
if (*name_end == '\0') {
|
||||||
struct variable *var, **vpp;
|
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;
|
var = vpp ? *vpp : NULL;
|
||||||
|
|
||||||
if (flags & SETFLAG_UNEXPORT) {
|
if (flags & SETFLAG_UNEXPORT) {
|
||||||
|
|
|
@ -22,6 +22,25 @@
|
||||||
const char defifsvar[] ALIGN1 = "IFS= \t\n";
|
const char defifsvar[] ALIGN1 = "IFS= \t\n";
|
||||||
const char defoptindvar[] ALIGN1 = "OPTIND=1";
|
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 */
|
/* read builtin */
|
||||||
|
|
||||||
/* Needs to be interruptible: shell must handle traps and shell-special signals
|
/* Needs to be interruptible: shell must handle traps and shell-special signals
|
||||||
|
|
|
@ -26,6 +26,8 @@ extern const char defifsvar[] ALIGN1; /* "IFS= \t\n" */
|
||||||
|
|
||||||
extern const char defoptindvar[] ALIGN1; /* "OPTIND=1" */
|
extern const char defoptindvar[] ALIGN1; /* "OPTIND=1" */
|
||||||
|
|
||||||
|
int FAST_FUNC varcmp(const char *p, const char *q);
|
||||||
|
|
||||||
/* Builtins */
|
/* Builtins */
|
||||||
|
|
||||||
struct builtin_read_params {
|
struct builtin_read_params {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue