hush: remove code which errors out on $- and $_, it's useless;

wrap some longish lines

function                                             old     new   delta
handle_dollar                                        667     626     -41
This commit is contained in:
Denis Vlasenko 2009-04-04 15:24:40 +00:00
parent 7c9861214b
commit a24c8caeb2

View File

@ -1517,13 +1517,16 @@ static int o_save_ptr_helper(o_string *o, int n)
list = (char**)o->data; list = (char**)o->data;
memmove(list + n + 0x10, list + n, string_len); memmove(list + n + 0x10, list + n, string_len);
o->length += 0x10 * sizeof(list[0]); o->length += 0x10 * sizeof(list[0]);
} else } else {
debug_printf_list("list[%d]=%d string_start=%d\n", n, string_len, string_start); debug_printf_list("list[%d]=%d string_start=%d\n",
n, string_len, string_start);
}
} else { } else {
/* We have empty slot at list[n], reuse without growth */ /* We have empty slot at list[n], reuse without growth */
string_start = ((n+1 + 0xf) & ~0xf) * sizeof(list[0]); /* NB: n+1! */ string_start = ((n+1 + 0xf) & ~0xf) * sizeof(list[0]); /* NB: n+1! */
string_len = o->length - string_start; string_len = o->length - string_start;
debug_printf_list("list[%d]=%d string_start=%d (empty slot)\n", n, string_len, string_start); debug_printf_list("list[%d]=%d string_start=%d (empty slot)\n",
n, string_len, string_start);
o->has_empty_slot = 0; o->has_empty_slot = 0;
} }
list[n] = (char*)(ptrdiff_t)string_len; list[n] = (char*)(ptrdiff_t)string_len;
@ -1917,7 +1920,6 @@ static int expand_vars_to_list(o_string *output, int n, char *arg, char or_mask)
} }
arg[0] = first_ch; arg[0] = first_ch;
#if ENABLE_HUSH_TICK #if ENABLE_HUSH_TICK
store_val: store_val:
#endif #endif
@ -2203,8 +2205,12 @@ typedef struct nommu_save_t {
* XXX no exit() here. If you don't exec, use _exit instead. * XXX no exit() here. If you don't exec, use _exit instead.
* The at_exit handlers apparently confuse the calling process, * The at_exit handlers apparently confuse the calling process,
* in particular stdin handling. Not sure why? -- because of vfork! (vda) */ * in particular stdin handling. Not sure why? -- because of vfork! (vda) */
static void pseudo_exec_argv(nommu_save_t *nommu_save, char **argv, int assignment_cnt, char **argv_expanded) NORETURN; static void pseudo_exec_argv(nommu_save_t *nommu_save,
static void pseudo_exec_argv(nommu_save_t *nommu_save, char **argv, int assignment_cnt, char **argv_expanded) char **argv, int assignment_cnt,
char **argv_expanded) NORETURN;
static void pseudo_exec_argv(nommu_save_t *nommu_save,
char **argv, int assignment_cnt,
char **argv_expanded)
{ {
int rcode; int rcode;
char **new_env; char **new_env;
@ -2279,8 +2285,12 @@ static int run_list(struct pipe *pi);
/* Called after [v]fork() in run_pipe() /* Called after [v]fork() in run_pipe()
*/ */
static void pseudo_exec(nommu_save_t *nommu_save, struct command *command, char **argv_expanded) NORETURN; static void pseudo_exec(nommu_save_t *nommu_save,
static void pseudo_exec(nommu_save_t *nommu_save, struct command *command, char **argv_expanded) struct command *command,
char **argv_expanded) NORETURN;
static void pseudo_exec(nommu_save_t *nommu_save,
struct command *command,
char **argv_expanded)
{ {
if (command->argv) if (command->argv)
pseudo_exec_argv(nommu_save, command->argv, command->assignment_cnt, argv_expanded); pseudo_exec_argv(nommu_save, command->argv, command->assignment_cnt, argv_expanded);
@ -2655,7 +2665,8 @@ static int run_pipe(struct pipe *pi)
setup_redirects(command, squirrel); setup_redirects(command, squirrel);
new_env = expand_assignments(argv, command->assignment_cnt); new_env = expand_assignments(argv, command->assignment_cnt);
old_env = putenv_all_and_save_old(new_env); old_env = putenv_all_and_save_old(new_env);
debug_printf_exec(": builtin '%s' '%s'...\n", x->cmd, argv_expanded[1]); debug_printf_exec(": builtin '%s' '%s'...\n",
x->cmd, argv_expanded[1]);
rcode = x->function(argv_expanded) & 0xff; rcode = x->function(argv_expanded) & 0xff;
#if ENABLE_FEATURE_SH_STANDALONE #if ENABLE_FEATURE_SH_STANDALONE
clean_up_and_ret: clean_up_and_ret:
@ -2677,7 +2688,8 @@ static int run_pipe(struct pipe *pi)
save_nofork_data(&G.nofork_save); save_nofork_data(&G.nofork_save);
new_env = expand_assignments(argv, command->assignment_cnt); new_env = expand_assignments(argv, command->assignment_cnt);
old_env = putenv_all_and_save_old(new_env); old_env = putenv_all_and_save_old(new_env);
debug_printf_exec(": run_nofork_applet '%s' '%s'...\n", argv_expanded[0], argv_expanded[1]); debug_printf_exec(": run_nofork_applet '%s' '%s'...\n",
argv_expanded[0], argv_expanded[1]);
rcode = run_nofork_applet_prime(&G.nofork_save, i, argv_expanded); rcode = run_nofork_applet_prime(&G.nofork_save, i, argv_expanded);
goto clean_up_and_ret; goto clean_up_and_ret;
} }
@ -2701,7 +2713,8 @@ static int run_pipe(struct pipe *pi)
#endif #endif
command = &(pi->cmds[i]); command = &(pi->cmds[i]);
if (command->argv) { if (command->argv) {
debug_printf_exec(": pipe member '%s' '%s'...\n", command->argv[0], command->argv[1]); debug_printf_exec(": pipe member '%s' '%s'...\n",
command->argv[0], command->argv[1]);
} else } else
debug_printf_exec(": pipe member with no argv\n"); debug_printf_exec(": pipe member with no argv\n");
@ -2841,7 +2854,9 @@ static void debug_print_tree(struct pipe *pi, int lvl)
struct command *command = &pi->cmds[prn]; struct command *command = &pi->cmds[prn];
char **argv = command->argv; char **argv = command->argv;
fprintf(stderr, "%*s prog %d assignment_cnt:%d", lvl*2, "", prn, command->assignment_cnt); fprintf(stderr, "%*s prog %d assignment_cnt:%d",
lvl*2, "", prn,
command->assignment_cnt);
if (command->group) { if (command->group) {
fprintf(stderr, " group %s: (argv=%p)\n", fprintf(stderr, " group %s: (argv=%p)\n",
GRPTYPE[command->grp_type], GRPTYPE[command->grp_type],
@ -3046,8 +3061,9 @@ static int run_list(struct pipe *pi)
pi->cmds[0].argv[0] = xasprintf("%s=%s", for_varname, *for_lcur++); pi->cmds[0].argv[0] = xasprintf("%s=%s", for_varname, *for_lcur++);
pi->cmds[0].assignment_cnt = 1; pi->cmds[0].assignment_cnt = 1;
} }
if (rword == RES_IN) /* "for v IN list;..." - "in" has no cmds anyway */ if (rword == RES_IN) {
continue; continue; /* "for v IN list;..." - "in" has no cmds anyway */
}
if (rword == RES_DONE) { if (rword == RES_DONE) {
continue; /* "done" has no cmds too */ continue; /* "done" has no cmds too */
} }
@ -3603,7 +3619,8 @@ static int done_word(o_string *word, struct parse_context *ctx)
debug_printf_parse(": checking '%s' for reserved-ness\n", word->data); debug_printf_parse(": checking '%s' for reserved-ness\n", word->data);
if (reserved_word(word, ctx)) { if (reserved_word(word, ctx)) {
o_reset(word); o_reset(word);
debug_printf_parse("done_word return %d\n", (ctx->ctx_res_w == RES_SNTX)); debug_printf_parse("done_word return %d\n",
(ctx->ctx_res_w == RES_SNTX));
return (ctx->ctx_res_w == RES_SNTX); return (ctx->ctx_res_w == RES_SNTX);
} }
} }
@ -3800,7 +3817,8 @@ static int parse_group(o_string *dest, struct parse_context *ctx,
|| dest->nonnull /* ""(... */ || dest->nonnull /* ""(... */
) { ) {
syntax(NULL); syntax(NULL);
debug_printf_parse("parse_group return 1: syntax error, groups and arglists don't mix\n"); debug_printf_parse("parse_group return 1: "
"syntax error, groups and arglists don't mix\n");
return 1; return 1;
} }
endch = '}'; endch = '}';
@ -3812,7 +3830,8 @@ static int parse_group(o_string *dest, struct parse_context *ctx,
/* empty ()/{} or parse error? */ /* empty ()/{} or parse error? */
if (!pipe_list || pipe_list == ERR_PTR) { if (!pipe_list || pipe_list == ERR_PTR) {
syntax(NULL); syntax(NULL);
debug_printf_parse("parse_group return 1: parse_stream returned %p\n", pipe_list); debug_printf_parse("parse_group return 1: "
"parse_stream returned %p\n", pipe_list);
return 1; return 1;
} }
command->group = pipe_list; command->group = pipe_list;
@ -3910,7 +3929,7 @@ static void add_till_closing_paren(o_string *dest, struct in_str *input, bool db
break; break;
if (ch == '(') if (ch == '(')
count++; count++;
if (ch == ')') if (ch == ')') {
if (--count < 0) { if (--count < 0) {
if (!dbl) if (!dbl)
break; break;
@ -3919,6 +3938,7 @@ static void add_till_closing_paren(o_string *dest, struct in_str *input, bool db
break; break;
} }
} }
}
o_addchr(dest, ch); o_addchr(dest, ch);
if (ch == '\'') { if (ch == '\'') {
add_till_single_quote(dest, input); add_till_single_quote(dest, input);
@ -4002,10 +4022,11 @@ static int handle_dollar(o_string *dest, struct in_str *input)
} }
} }
if (expansion < 2 && if (expansion < 2
((all_digits && !isdigit(ch)) || && ( (all_digits && !isdigit(ch))
(!all_digits && !isalnum(ch) && ch != '_'))) || (!all_digits && !isalnum(ch) && ch != '_')
{ )
) {
/* handle parameter expansions /* handle parameter expansions
* http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_06_02 * http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_06_02
*/ */
@ -4019,7 +4040,6 @@ static int handle_dollar(o_string *dest, struct in_str *input)
break; break;
} }
goto case_default; goto case_default;
#if 0 /* not implemented yet :( */ #if 0 /* not implemented yet :( */
case '#': /* remove prefix */ case '#': /* remove prefix */
case '%': /* remove suffix */ case '%': /* remove suffix */
@ -4030,7 +4050,6 @@ static int handle_dollar(o_string *dest, struct in_str *input)
} }
goto case_default; goto case_default;
#endif #endif
case '-': /* default value */ case '-': /* default value */
case '=': /* assign default */ case '=': /* assign default */
case '+': /* alternative */ case '+': /* alternative */
@ -4038,7 +4057,6 @@ static int handle_dollar(o_string *dest, struct in_str *input)
debug_printf_parse(": parameter expansion\n"); debug_printf_parse(": parameter expansion\n");
expansion = 2; expansion = 2;
break; break;
default: default:
case_default: case_default:
syntax("unterminated ${name}"); syntax("unterminated ${name}");
@ -4046,7 +4064,6 @@ static int handle_dollar(o_string *dest, struct in_str *input)
return 1; return 1;
} }
} }
char_ok: char_ok:
debug_printf_parse(": '%c'\n", ch); debug_printf_parse(": '%c'\n", ch);
o_addchr(dest, ch | quote_mask); o_addchr(dest, ch | quote_mask);
@ -4058,7 +4075,6 @@ static int handle_dollar(o_string *dest, struct in_str *input)
} }
case '(': { case '(': {
i_getch(input); i_getch(input);
#if ENABLE_SH_MATH_SUPPORT #if ENABLE_SH_MATH_SUPPORT
if (i_peek(input) == '(') { if (i_peek(input) == '(') {
i_getch(input); i_getch(input);
@ -4069,7 +4085,6 @@ static int handle_dollar(o_string *dest, struct in_str *input)
break; break;
} }
#endif #endif
#if ENABLE_HUSH_TICK #if ENABLE_HUSH_TICK
//int pos = dest->length; //int pos = dest->length;
o_addchr(dest, SPECIAL_VAR_SYMBOL); o_addchr(dest, SPECIAL_VAR_SYMBOL);
@ -4088,11 +4103,9 @@ static int handle_dollar(o_string *dest, struct in_str *input)
goto make_var; goto make_var;
} }
/* else: it's $_ */ /* else: it's $_ */
case '-': /* TODO: */
/* still unhandled, but should be eventually */ /* $_ Shell or shell script name; or last cmd name */
bb_error_msg("unhandled syntax: $%c", ch); /* $- Option flags set by set builtin or shell options (-i etc) */
return 1;
break;
default: default:
o_addQchr(dest, '$'); o_addQchr(dest, '$');
} }
@ -4100,7 +4113,8 @@ static int handle_dollar(o_string *dest, struct in_str *input)
return 0; return 0;
} }
static int parse_stream_dquoted(o_string *dest, struct in_str *input, int dquote_end) static int parse_stream_dquoted(o_string *dest,
struct in_str *input, int dquote_end)
{ {
int ch; int ch;
int next; int next;
@ -4149,7 +4163,8 @@ static int parse_stream_dquoted(o_string *dest, struct in_str *input, int dquote
} }
if (ch == '$') { if (ch == '$') {
if (handle_dollar(dest, input) != 0) { if (handle_dollar(dest, input) != 0) {
debug_printf_parse("parse_stream_dquoted return 1: handle_dollar returned non-0\n"); debug_printf_parse("parse_stream_dquoted return 1: "
"handle_dollar returned non-0\n");
return 1; return 1;
} }
goto again; goto again;
@ -4196,8 +4211,8 @@ static struct pipe *parse_stream(struct in_str *input, int end_trigger)
/* Double-quote state is handled in the state variable is_in_dquote. /* Double-quote state is handled in the state variable is_in_dquote.
* A single-quote triggers a bypass of the main loop until its mate is * A single-quote triggers a bypass of the main loop until its mate is
* found. When recursing, quote state is passed in via dest->o_escape. */ * found. When recursing, quote state is passed in via dest->o_escape.
*/
debug_printf_parse("parse_stream entered, end_trigger='%c'\n", debug_printf_parse("parse_stream entered, end_trigger='%c'\n",
end_trigger ? : 'X'); end_trigger ? : 'X');
@ -4338,7 +4353,8 @@ static struct pipe *parse_stream(struct in_str *input, int end_trigger)
break; break;
case '$': case '$':
if (handle_dollar(&dest, input) != 0) { if (handle_dollar(&dest, input) != 0) {
debug_printf_parse("parse_stream parse error: handle_dollar returned non-0\n"); debug_printf_parse("parse_stream parse error: "
"handle_dollar returned non-0\n");
goto parse_error; goto parse_error;
} }
break; break;
@ -4532,8 +4548,9 @@ static struct pipe *parse_stream(struct in_str *input, int end_trigger)
/* Clean up allocated tree. /* Clean up allocated tree.
* Samples for finding leaks on syntax error recovery path. * Samples for finding leaks on syntax error recovery path.
* Execute them from interactive shell and watch pmap `pidof hush`. * Run them from interactive shell, watch pmap `pidof hush`.
* while if false; then false; fi do break; done (bash accepts it) * while if false; then false; fi do break; done
* (bash accepts it)
* while if false; then false; fi; do break; fi * while if false; then false; fi; do break; fi
*/ */
pctx = &ctx; pctx = &ctx;