shell: unify endofname() in hush and ash

function                                             old     new   delta
builtin_umask                                        132     133      +1
changepath                                           195     194      -1
expand_and_evaluate_arith                             77      69      -8
ash_arith                                            143     135      -8
expand_one_var                                      1551    1515     -36
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/4 up/down: 1/-53)             Total: -52 bytes

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
This commit is contained in:
Denys Vlasenko 2010-09-07 12:19:33 +02:00
parent 27c56f1267
commit 8b2f13d84d
4 changed files with 42 additions and 43 deletions

View File

@ -1982,10 +1982,6 @@ extern struct globals_var *const ash_ptr_to_globals_var;
# define optindval() (voptind.var_text + 7) # define optindval() (voptind.var_text + 7)
#endif #endif
#define is_name(c) ((c) == '_' || isalpha((unsigned char)(c)))
#define is_in_name(c) ((c) == '_' || isalnum((unsigned char)(c)))
#if ENABLE_ASH_GETOPTS #if ENABLE_ASH_GETOPTS
static void FAST_FUNC static void FAST_FUNC
getoptsreset(const char *value) getoptsreset(const char *value)
@ -1995,24 +1991,26 @@ getoptsreset(const char *value)
} }
#endif #endif
/* math.h has these, otherwise define our private copies */
#if !ENABLE_SH_MATH_SUPPORT
#define is_name(c) ((c) == '_' || isalpha((unsigned char)(c)))
#define is_in_name(c) ((c) == '_' || isalnum((unsigned char)(c)))
/* /*
* Return of a legal variable name (a letter or underscore followed by zero or * Return the pointer to the first char which is not part of a legal variable name
* more letters, underscores, and digits). * (a letter or underscore followed by letters, underscores, and digits).
*/ */
static char* FAST_FUNC static const char*
endofname(const char *name) endofname(const char *name)
{ {
char *p; if (!is_name(*name))
return name;
p = (char *) name; while (*++name) {
if (!is_name(*p)) if (!is_in_name(*name))
return p;
while (*++p) {
if (!is_in_name(*p))
break; break;
} }
return p; return name;
} }
#endif
/* /*
* Compares two strings up to the first = or '\0'. The first * Compares two strings up to the first = or '\0'. The first
@ -2195,9 +2193,10 @@ setvareq(char *s, int flags)
static void static void
setvar(const char *name, const char *val, int flags) setvar(const char *name, const char *val, int flags)
{ {
char *p, *q; const char *q;
size_t namelen; char *p;
char *nameeq; char *nameeq;
size_t namelen;
size_t vallen; size_t vallen;
q = endofname(name); q = endofname(name);
@ -2211,12 +2210,13 @@ setvar(const char *name, const char *val, int flags)
} else { } else {
vallen = strlen(val); vallen = strlen(val);
} }
INT_OFF; INT_OFF;
nameeq = ckmalloc(namelen + vallen + 2); nameeq = ckmalloc(namelen + vallen + 2);
p = (char *)memcpy(nameeq, name, namelen) + namelen; p = memcpy(nameeq, name, namelen) + namelen;
if (val) { if (val) {
*p++ = '='; *p++ = '=';
p = (char *)memcpy(p, val, vallen) + vallen; p = memcpy(p, val, vallen) + vallen;
} }
*p = '\0'; *p = '\0';
setvareq(nameeq, flags | VNOSAVE); setvareq(nameeq, flags | VNOSAVE);
@ -5444,7 +5444,7 @@ ash_arith(const char *s)
math_hooks.lookupvar = lookupvar; math_hooks.lookupvar = lookupvar;
math_hooks.setvar = setvar2; math_hooks.setvar = setvar2;
math_hooks.endofname = endofname; //math_hooks.endofname = endofname;
INT_OFF; INT_OFF;
result = arith(s, &errcode, &math_hooks); result = arith(s, &errcode, &math_hooks);
@ -9405,7 +9405,7 @@ evalbltin(const struct builtincmd *cmd, int argc, char **argv)
static int static int
goodname(const char *p) goodname(const char *p)
{ {
return !*endofname(p); return endofname(p)[0] == '\0';
} }

View File

@ -1671,24 +1671,6 @@ static void unset_vars(char **strings)
free(strings); free(strings);
} }
#if ENABLE_SH_MATH_SUPPORT
# define is_name(c) ((c) == '_' || isalpha((unsigned char)(c)))
# define is_in_name(c) ((c) == '_' || isalnum((unsigned char)(c)))
static char* FAST_FUNC endofname(const char *name)
{
char *p;
p = (char *) name;
if (!is_name(*p))
return p;
while (*++p) {
if (!is_in_name(*p))
break;
}
return p;
}
#endif
static void FAST_FUNC set_local_var_from_halves(const char *name, const char *val) static void FAST_FUNC set_local_var_from_halves(const char *name, const char *val)
{ {
char *var = xasprintf("%s=%s", name, val); char *var = xasprintf("%s=%s", name, val);
@ -4446,7 +4428,7 @@ static arith_t expand_and_evaluate_arith(const char *arg, int *errcode_p)
hooks.lookupvar = get_local_var_value; hooks.lookupvar = get_local_var_value;
hooks.setvar = set_local_var_from_halves; hooks.setvar = set_local_var_from_halves;
hooks.endofname = endofname; //hooks.endofname = endofname;
exp_str = expand_pseudo_dquoted(arg); exp_str = expand_pseudo_dquoted(arg);
res = arith(exp_str ? exp_str : arg, errcode_p, &hooks); res = arith(exp_str ? exp_str : arg, errcode_p, &hooks);
free(exp_str); free(exp_str);

View File

@ -122,7 +122,7 @@
#define a_e_h_t arith_eval_hooks_t #define a_e_h_t arith_eval_hooks_t
#define lookupvar (math_hooks->lookupvar) #define lookupvar (math_hooks->lookupvar)
#define setvar (math_hooks->setvar ) #define setvar (math_hooks->setvar )
#define endofname (math_hooks->endofname) //#define endofname (math_hooks->endofname)
#define arith_isspace(arithval) \ #define arith_isspace(arithval) \
(arithval == ' ' || arithval == '\n' || arithval == '\t') (arithval == ' ' || arithval == '\n' || arithval == '\t')
@ -479,6 +479,18 @@ static const char op_tokens[] ALIGN1 = {
/* ptr to ")" */ /* ptr to ")" */
#define endexpression (&op_tokens[sizeof(op_tokens)-7]) #define endexpression (&op_tokens[sizeof(op_tokens)-7])
const char* FAST_FUNC
endofname(const char *name)
{
if (!is_name(*name))
return name;
while (*++name) {
if (!is_in_name(*name))
break;
}
return name;
}
arith_t arith_t
arith(const char *expr, int *perrcode, a_e_h_t *math_hooks) arith(const char *expr, int *perrcode, a_e_h_t *math_hooks)
{ {

View File

@ -87,14 +87,19 @@ typedef long arith_t;
#define strto_arith_t strtoul #define strto_arith_t strtoul
#endif #endif
/* ash's and hush's endofname is the same, so... */
# define is_name(c) ((c) == '_' || isalpha((unsigned char)(c)))
# define is_in_name(c) ((c) == '_' || isalnum((unsigned char)(c)))
const char* FAST_FUNC endofname(const char *name);
typedef const char* FAST_FUNC (*arith_var_lookup_t)(const char *name); typedef const char* FAST_FUNC (*arith_var_lookup_t)(const char *name);
typedef void FAST_FUNC (*arith_var_set_t)(const char *name, const char *val); typedef void FAST_FUNC (*arith_var_set_t)(const char *name, const char *val);
typedef char* FAST_FUNC (*arith_var_endofname_t)(const char *name); //typedef const char* FAST_FUNC (*arith_var_endofname_t)(const char *name);
typedef struct arith_eval_hooks { typedef struct arith_eval_hooks {
arith_var_lookup_t lookupvar; arith_var_lookup_t lookupvar;
arith_var_set_t setvar; arith_var_set_t setvar;
arith_var_endofname_t endofname; // arith_var_endofname_t endofname;
} arith_eval_hooks_t; } arith_eval_hooks_t;
arith_t arith(const char *expr, int *perrcode, arith_eval_hooks_t*); arith_t arith(const char *expr, int *perrcode, arith_eval_hooks_t*);