shell/math: return string error indicator, not integer
function old new delta expand_and_evaluate_arith 87 106 +19 expand_one_var 1563 1570 +7 arith 12 18 +6 evaluate_string 678 680 +2 arith_apply 1269 1271 +2 builtin_umask 133 132 -1 ash_arith 118 75 -43 expand_vars_to_list 1094 1038 -56 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 5/3 up/down: 36/-100) Total: -64 bytes Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
This commit is contained in:
40
shell/hush.c
40
shell/hush.c
@ -4461,7 +4461,7 @@ static char *encode_then_expand_string(const char *str, int process_bkslash, int
|
||||
}
|
||||
|
||||
#if ENABLE_SH_MATH_SUPPORT
|
||||
static arith_t expand_and_evaluate_arith(const char *arg, int *errcode_p)
|
||||
static arith_t expand_and_evaluate_arith(const char *arg, const char **errmsg_p)
|
||||
{
|
||||
arith_state_t math_state;
|
||||
arith_t res;
|
||||
@ -4472,8 +4472,11 @@ static arith_t expand_and_evaluate_arith(const char *arg, int *errcode_p)
|
||||
//math_state.endofname = endofname;
|
||||
exp_str = encode_then_expand_string(arg, /*process_bkslash:*/ 1, /*unbackslash:*/ 1);
|
||||
res = arith(&math_state, exp_str ? exp_str : arg);
|
||||
*errcode_p = math_state.errcode;
|
||||
free(exp_str);
|
||||
if (errmsg_p)
|
||||
*errmsg_p = math_state.errmsg;
|
||||
if (math_state.errmsg)
|
||||
die_if_script(math_state.errmsg);
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
@ -4714,22 +4717,26 @@ static NOINLINE const char *expand_one_var(char **to_be_freed_pp, char *arg, cha
|
||||
* var:N<SPECIAL_VAR_SYMBOL>M<SPECIAL_VAR_SYMBOL>
|
||||
*/
|
||||
arith_t beg, len;
|
||||
int errcode = 0;
|
||||
const char *errmsg;
|
||||
|
||||
beg = expand_and_evaluate_arith(exp_word, &errcode);
|
||||
beg = expand_and_evaluate_arith(exp_word, &errmsg);
|
||||
if (errmsg)
|
||||
goto arith_err;
|
||||
debug_printf_varexp("beg:'%s'=%lld\n", exp_word, (long long)beg);
|
||||
*p++ = SPECIAL_VAR_SYMBOL;
|
||||
exp_word = p;
|
||||
p = strchr(p, SPECIAL_VAR_SYMBOL);
|
||||
*p = '\0';
|
||||
len = expand_and_evaluate_arith(exp_word, &errcode);
|
||||
len = expand_and_evaluate_arith(exp_word, &errmsg);
|
||||
if (errmsg)
|
||||
goto arith_err;
|
||||
debug_printf_varexp("len:'%s'=%lld\n", exp_word, (long long)len);
|
||||
|
||||
if (errcode >= 0 && len >= 0) { /* bash compat: len < 0 is illegal */
|
||||
if (len >= 0) { /* bash compat: len < 0 is illegal */
|
||||
if (beg < 0) /* bash compat */
|
||||
beg = 0;
|
||||
debug_printf_varexp("from val:'%s'\n", val);
|
||||
if (len == 0 || !val || beg >= strlen(val)) {
|
||||
arith_err:
|
||||
val = NULL;
|
||||
} else {
|
||||
/* Paranoia. What if user entered 9999999999999
|
||||
@ -4926,28 +4933,11 @@ static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg)
|
||||
#if ENABLE_SH_MATH_SUPPORT
|
||||
case '+': { /* <SPECIAL_VAR_SYMBOL>+cmd<SPECIAL_VAR_SYMBOL> */
|
||||
arith_t res;
|
||||
int errcode;
|
||||
|
||||
arg++; /* skip '+' */
|
||||
*p = '\0'; /* replace trailing <SPECIAL_VAR_SYMBOL> */
|
||||
debug_printf_subst("ARITH '%s' first_ch %x\n", arg, first_ch);
|
||||
res = expand_and_evaluate_arith(arg, &errcode);
|
||||
|
||||
if (errcode < 0) {
|
||||
const char *msg = "error in arithmetic";
|
||||
switch (errcode) {
|
||||
case -3:
|
||||
msg = "exponent less than 0";
|
||||
break;
|
||||
case -2:
|
||||
msg = "divide by 0";
|
||||
break;
|
||||
case -5:
|
||||
msg = "expression recursion loop detected";
|
||||
break;
|
||||
}
|
||||
die_if_script(msg);
|
||||
}
|
||||
res = expand_and_evaluate_arith(arg, NULL);
|
||||
debug_printf_subst("ARITH RES '"arith_t_fmt"'\n", res);
|
||||
sprintf(arith_buf, arith_t_fmt, res);
|
||||
val = arith_buf;
|
||||
|
Reference in New Issue
Block a user