hush: search/and/replace style cleanups, no code changes

This commit is contained in:
Denis Vlasenko 2008-06-10 18:05:12 +00:00
parent 7b4f3f13d3
commit 46ccdcb96e

View File

@ -20,7 +20,7 @@
* rewrites. * rewrites.
* *
* Other credits: * Other credits:
* b_addchr() derived from similar w_addchar function in glibc-2.2 * o_addchr() derived from similar w_addchar function in glibc-2.2
* setup_redirect(), redirect_opt_num(), and big chunks of main() * setup_redirect(), redirect_opt_num(), and big chunks of main()
* and many builtins derived from contributions by Erik Andersen * and many builtins derived from contributions by Erik Andersen
* miscellaneous bugfixes from Matt Kraai * miscellaneous bugfixes from Matt Kraai
@ -293,10 +293,6 @@ struct child_prog {
smallint is_stopped; /* is the program currently running? */ smallint is_stopped; /* is the program currently running? */
struct redir_struct *redirects; /* I/O redirections */ struct redir_struct *redirects; /* I/O redirections */
struct pipe *family; /* pointer back to the child's parent pipe */ struct pipe *family; /* pointer back to the child's parent pipe */
//sp counting seems to be broken... so commented out, grep for '//sp:'
//sp: int sp; /* number of SPECIAL_VAR_SYMBOL */
//seems to be unused, grep for '//pt:'
//pt: int parse_type;
}; };
/* argv vector may contain variable references (^Cvar^C, ^C0^C etc) /* argv vector may contain variable references (^Cvar^C, ^C0^C etc)
* and on execution these are substituted with their values. * and on execution these are substituted with their values.
@ -361,8 +357,8 @@ struct in_str {
int (*get) (struct in_str *); int (*get) (struct in_str *);
int (*peek) (struct in_str *); int (*peek) (struct in_str *);
}; };
#define b_getch(input) ((input)->get(input)) #define i_getch(input) ((input)->get(input))
#define b_peek(input) ((input)->peek(input)) #define i_peek(input) ((input)->peek(input))
enum { enum {
CHAR_ORDINARY = 0, CHAR_ORDINARY = 0,
@ -533,12 +529,12 @@ static int done_pipe(struct p_context *ctx, pipe_style type);
static int redirect_dup_num(struct in_str *input); static int redirect_dup_num(struct in_str *input);
static int redirect_opt_num(o_string *o); static int redirect_opt_num(o_string *o);
#if ENABLE_HUSH_TICK #if ENABLE_HUSH_TICK
static int process_command_subs(o_string *dest, /*struct p_context *ctx,*/ static int process_command_subs(o_string *dest,
struct in_str *input, const char *subst_end); struct in_str *input, const char *subst_end);
#endif #endif
static int parse_group(o_string *dest, struct p_context *ctx, struct in_str *input, int ch); static int parse_group(o_string *dest, struct p_context *ctx, struct in_str *input, int ch);
static const char *lookup_param(const char *src); static const char *lookup_param(const char *src);
static int handle_dollar(o_string *dest, /*struct p_context *ctx,*/ static int handle_dollar(o_string *dest,
struct in_str *input); struct in_str *input);
static int parse_stream(o_string *dest, struct p_context *ctx, struct in_str *input0, const char *end_trigger); static int parse_stream(o_string *dest, struct p_context *ctx, struct in_str *input0, const char *end_trigger);
/* setup: */ /* setup: */
@ -1175,7 +1171,7 @@ static int builtin_unset(char **argv)
*/ */
#define B_CHUNK (32 * sizeof(char*)) #define B_CHUNK (32 * sizeof(char*))
static void b_reset(o_string *o) static void o_reset(o_string *o)
{ {
o->length = 0; o->length = 0;
o->nonnull = 0; o->nonnull = 0;
@ -1183,13 +1179,13 @@ static void b_reset(o_string *o)
o->data[0] = '\0'; o->data[0] = '\0';
} }
static void b_free(o_string *o) static void o_free(o_string *o)
{ {
free(o->data); free(o->data);
memset(o, 0, sizeof(*o)); memset(o, 0, sizeof(*o));
} }
static void b_grow_by(o_string *o, int len) static void o_grow_by(o_string *o, int len)
{ {
if (o->length + len > o->maxlen) { if (o->length + len > o->maxlen) {
o->maxlen += (2*len > B_CHUNK ? 2*len : B_CHUNK); o->maxlen += (2*len > B_CHUNK ? 2*len : B_CHUNK);
@ -1197,18 +1193,18 @@ static void b_grow_by(o_string *o, int len)
} }
} }
static void b_addchr(o_string *o, int ch) static void o_addchr(o_string *o, int ch)
{ {
debug_printf("b_addchr: '%c' o->length=%d o=%p\n", ch, o->length, o); debug_printf("o_addchr: '%c' o->length=%d o=%p\n", ch, o->length, o);
b_grow_by(o, 1); o_grow_by(o, 1);
o->data[o->length] = ch; o->data[o->length] = ch;
o->length++; o->length++;
o->data[o->length] = '\0'; o->data[o->length] = '\0';
} }
static void b_addstr(o_string *o, const char *str, int len) static void o_addstr(o_string *o, const char *str, int len)
{ {
b_grow_by(o, len); o_grow_by(o, len);
memcpy(&o->data[o->length], str, len); memcpy(&o->data[o->length], str, len);
o->length += len; o->length += len;
o->data[o->length] = '\0'; o->data[o->length] = '\0';
@ -1217,12 +1213,12 @@ static void b_addstr(o_string *o, const char *str, int len)
/* My analysis of quoting semantics tells me that state information /* My analysis of quoting semantics tells me that state information
* is associated with a destination, not a source. * is associated with a destination, not a source.
*/ */
static void b_addqchr(o_string *o, int ch, int quote) static void o_addqchr(o_string *o, int ch, int quote)
{ {
if (quote && strchr("*?[\\", ch)) { if (quote && strchr("*?[\\", ch)) {
b_addchr(o, '\\'); o_addchr(o, '\\');
} }
b_addchr(o, ch); o_addchr(o, ch);
} }
/* A special kind of o_string for $VAR and `cmd` expansion. /* A special kind of o_string for $VAR and `cmd` expansion.
@ -1232,10 +1228,10 @@ static void b_addqchr(o_string *o, int ch, int quote)
* It means that if list[] needs to grow, data needs to be moved higher up * It means that if list[] needs to grow, data needs to be moved higher up
* but list[i]'s need not be modified. * but list[i]'s need not be modified.
* NB: remembering how many list[i]'s you have there is crucial. * NB: remembering how many list[i]'s you have there is crucial.
* b_finalize_list() operation post-processes this structure - calculates * o_finalize_list() operation post-processes this structure - calculates
* and stores actual char* ptrs in list[]. Oh, it NULL terminates it as well. * and stores actual char* ptrs in list[]. Oh, it NULL terminates it as well.
*/ */
static int b_addptr(o_string *o, int n) static int o_save_ptr(o_string *o, int n)
{ {
char **list = (char**)o->data; char **list = (char**)o->data;
int string_start = ((n + 0xf) & ~0xf) * sizeof(list[0]); int string_start = ((n + 0xf) & ~0xf) * sizeof(list[0]);
@ -1258,7 +1254,7 @@ static int b_addptr(o_string *o, int n)
return n + 1; return n + 1;
} }
static int b_get_last_ptr(o_string *o, int n) static int o_get_last_ptr(o_string *o, int n)
{ {
char **list = (char**)o->data; char **list = (char**)o->data;
int string_start = ((n + 0xf) & ~0xf) * sizeof(list[0]); int string_start = ((n + 0xf) & ~0xf) * sizeof(list[0]);
@ -1266,12 +1262,12 @@ static int b_get_last_ptr(o_string *o, int n)
return ((int)list[n-1]) + string_start; return ((int)list[n-1]) + string_start;
} }
static char **b_finalize_list(o_string *o, int n) static char **o_finalize_list(o_string *o, int n)
{ {
char **list = (char**)o->data; char **list = (char**)o->data;
int string_start; int string_start;
b_addptr(o, n); /* force growth for list[n] if necessary */ o_save_ptr(o, n); /* force growth for list[n] if necessary */
string_start = ((n+1 + 0xf) & ~0xf) * sizeof(list[0]); string_start = ((n+1 + 0xf) & ~0xf) * sizeof(list[0]);
list[n] = NULL; list[n] = NULL;
while (n) { while (n) {
@ -1282,7 +1278,7 @@ static char **b_finalize_list(o_string *o, int n)
} }
#ifdef DEBUG_EXPAND #ifdef DEBUG_EXPAND
static void b_debug_list(const char *prefix, o_string *o, int n) static void o_debug_list(const char *prefix, o_string *o, int n)
{ {
char **list = (char**)o->data; char **list = (char**)o->data;
int string_start = ((n + 0xf) & ~0xf) * sizeof(list[0]); int string_start = ((n + 0xf) & ~0xf) * sizeof(list[0]);
@ -1300,7 +1296,7 @@ static void b_debug_list(const char *prefix, o_string *o, int n)
} }
} }
#else #else
#define b_debug_list(prefix, o, n) ((void)0) #define o_debug_list(prefix, o, n) ((void)0)
#endif #endif
@ -1931,7 +1927,6 @@ static int run_pipe(struct pipe *pi)
} }
for (i = 0; is_assignment(argv[i]); i++) { for (i = 0; is_assignment(argv[i]); i++) {
p = expand_string_to_string(argv[i]); p = expand_string_to_string(argv[i]);
//sp: child->sp--;
putenv(p); putenv(p);
} }
for (x = bltins; x->cmd; x++) { for (x = bltins; x->cmd; x++) {
@ -1948,7 +1943,6 @@ static int run_pipe(struct pipe *pi)
* things seem to work with glibc. */ * things seem to work with glibc. */
setup_redirects(child, squirrel); setup_redirects(child, squirrel);
debug_printf_exec(": builtin '%s' '%s'...\n", x->cmd, argv[i+1]); debug_printf_exec(": builtin '%s' '%s'...\n", x->cmd, argv[i+1]);
//sp: if (child->sp) /* btw we can do it unconditionally... */
argv_expanded = expand_strvec_to_strvec(argv + i); argv_expanded = expand_strvec_to_strvec(argv + i);
rcode = x->function(argv_expanded) & 0xff; rcode = x->function(argv_expanded) & 0xff;
free(argv_expanded); free(argv_expanded);
@ -1964,7 +1958,6 @@ static int run_pipe(struct pipe *pi)
setup_redirects(child, squirrel); setup_redirects(child, squirrel);
save_nofork_data(&nofork_save); save_nofork_data(&nofork_save);
argv_expanded = argv + i; argv_expanded = argv + i;
//sp: if (child->sp)
argv_expanded = expand_strvec_to_strvec(argv + i); argv_expanded = expand_strvec_to_strvec(argv + i);
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(&nofork_save, a, argv_expanded); rcode = run_nofork_applet_prime(&nofork_save, a, argv_expanded);
@ -2549,17 +2542,17 @@ static int expand_on_ifs(o_string *output, int n, const char *str)
while (1) { while (1) {
int word_len = strcspn(str, ifs); int word_len = strcspn(str, ifs);
if (word_len) { if (word_len) {
b_addstr(output, str, word_len); /* store non-ifs chars */ o_addstr(output, str, word_len); /* store non-ifs chars */
str += word_len; str += word_len;
} }
if (!*str) /* EOL - do not finalize word */ if (!*str) /* EOL - do not finalize word */
break; break;
b_addchr(output, '\0'); o_addchr(output, '\0');
b_debug_list("expand_on_ifs", output, n); o_debug_list("expand_on_ifs", output, n);
n = b_addptr(output, n); n = o_save_ptr(output, n);
str += strspn(str, ifs); /* skip ifs chars */ str += strspn(str, ifs); /* skip ifs chars */
} }
b_debug_list("expand_on_ifs[1]", output, n); o_debug_list("expand_on_ifs[1]", output, n);
return n; return n;
} }
@ -2583,15 +2576,15 @@ static int expand_vars_to_list(o_string *output, int n, char *arg, char or_mask)
ored_ch = 0; ored_ch = 0;
debug_printf_expand("expand_vars_to_list: arg '%s'\n", arg); debug_printf_expand("expand_vars_to_list: arg '%s'\n", arg);
b_debug_list("expand_vars_to_list", output, n); o_debug_list("expand_vars_to_list", output, n);
n = b_addptr(output, n); n = o_save_ptr(output, n);
b_debug_list("expand_vars_to_list[0]", output, n); o_debug_list("expand_vars_to_list[0]", output, n);
while ((p = strchr(arg, SPECIAL_VAR_SYMBOL)) != NULL) { while ((p = strchr(arg, SPECIAL_VAR_SYMBOL)) != NULL) {
o_string subst_result = NULL_O_STRING; o_string subst_result = NULL_O_STRING;
b_addstr(output, arg, p - arg); o_addstr(output, arg, p - arg);
b_debug_list("expand_vars_to_list[1]", output, n); o_debug_list("expand_vars_to_list[1]", output, n);
arg = ++p; arg = ++p;
p = strchr(p, SPECIAL_VAR_SYMBOL); p = strchr(p, SPECIAL_VAR_SYMBOL);
@ -2625,10 +2618,10 @@ static int expand_vars_to_list(o_string *output, int n, char *arg, char or_mask)
if (global_argv[i++][0] && global_argv[i]) { if (global_argv[i++][0] && global_argv[i]) {
/* this argv[] is not empty and not last: /* this argv[] is not empty and not last:
* put terminating NUL, start new word */ * put terminating NUL, start new word */
b_addchr(output, '\0'); o_addchr(output, '\0');
b_debug_list("expand_vars_to_list[2]", output, n); o_debug_list("expand_vars_to_list[2]", output, n);
n = b_addptr(output, n); n = o_save_ptr(output, n);
b_debug_list("expand_vars_to_list[3]", output, n); o_debug_list("expand_vars_to_list[3]", output, n);
} }
} }
} else } else
@ -2636,20 +2629,20 @@ static int expand_vars_to_list(o_string *output, int n, char *arg, char or_mask)
* and in this case should treat it like '$*' - see 'else...' below */ * and in this case should treat it like '$*' - see 'else...' below */
if (first_ch == ('@'|0x80) && !or_mask) { /* quoted $@ */ if (first_ch == ('@'|0x80) && !or_mask) { /* quoted $@ */
while (1) { while (1) {
b_addstr(output, global_argv[i], strlen(global_argv[i])); o_addstr(output, global_argv[i], strlen(global_argv[i]));
if (++i >= global_argc) if (++i >= global_argc)
break; break;
b_addchr(output, '\0'); o_addchr(output, '\0');
b_debug_list("expand_vars_to_list[4]", output, n); o_debug_list("expand_vars_to_list[4]", output, n);
n = b_addptr(output, n); n = o_save_ptr(output, n);
} }
} else { /* quoted $*: add as one word */ } else { /* quoted $*: add as one word */
while (1) { while (1) {
b_addstr(output, global_argv[i], strlen(global_argv[i])); o_addstr(output, global_argv[i], strlen(global_argv[i]));
if (!global_argv[++i]) if (!global_argv[++i])
break; break;
if (ifs[0]) if (ifs[0])
b_addchr(output, ifs[0]); o_addchr(output, ifs[0]);
} }
} }
break; break;
@ -2685,17 +2678,17 @@ static int expand_vars_to_list(o_string *output, int n, char *arg, char or_mask)
} /* else: quoted $VAR, val will be appended below */ } /* else: quoted $VAR, val will be appended below */
} }
if (val) if (val)
b_addstr(output, val, strlen(val)); o_addstr(output, val, strlen(val));
b_free(&subst_result); o_free(&subst_result);
arg = ++p; arg = ++p;
} /* end of "while (SPECIAL_VAR_SYMBOL is found) ..." */ } /* end of "while (SPECIAL_VAR_SYMBOL is found) ..." */
b_debug_list("expand_vars_to_list[a]", output, n); o_debug_list("expand_vars_to_list[a]", output, n);
b_addstr(output, arg, strlen(arg) + 1); o_addstr(output, arg, strlen(arg) + 1);
b_debug_list("expand_vars_to_list[b]", output, n); o_debug_list("expand_vars_to_list[b]", output, n);
//TESTME //TESTME
if (output->length - 1 == b_get_last_ptr(output, n)) { /* expansion is empty */ if (output->length - 1 == o_get_last_ptr(output, n)) { /* expansion is empty */
if (!(ored_ch & 0x80)) { /* all vars were not quoted... */ if (!(ored_ch & 0x80)) { /* all vars were not quoted... */
n--; n--;
/* allow to reuse list[n] later without re-growth */ /* allow to reuse list[n] later without re-growth */
@ -2717,10 +2710,10 @@ static char **expand_variables(char **argv, char or_mask)
v = argv; v = argv;
while (*v) while (*v)
n = expand_vars_to_list(&output, n, *v++, or_mask); n = expand_vars_to_list(&output, n, *v++, or_mask);
b_debug_list("expand_variables", &output, n); o_debug_list("expand_variables", &output, n);
/* output.data (malloced) gets returned in "list" */ /* output.data (malloced) gets returned in "list" */
list = b_finalize_list(&output, n); list = o_finalize_list(&output, n);
#ifdef DEBUG_EXPAND #ifdef DEBUG_EXPAND
{ {
@ -3021,7 +3014,7 @@ static int reserved_word(o_string *dest, struct p_context *ctx)
if (ctx->res_w == RES_IN || ctx->res_w == RES_FOR) { if (ctx->res_w == RES_IN || ctx->res_w == RES_FOR) {
syntax("malformed for"); /* example: 'for if' */ syntax("malformed for"); /* example: 'for if' */
ctx->res_w = RES_SNTX; ctx->res_w = RES_SNTX;
b_reset(dest); o_reset(dest);
return 1; return 1;
} }
#endif #endif
@ -3032,7 +3025,7 @@ static int reserved_word(o_string *dest, struct p_context *ctx)
} else if (ctx->res_w == RES_NONE || !(ctx->old_flag & (1 << r->code))) { } else if (ctx->res_w == RES_NONE || !(ctx->old_flag & (1 << r->code))) {
syntax(NULL); syntax(NULL);
ctx->res_w = RES_SNTX; ctx->res_w = RES_SNTX;
b_reset(dest); o_reset(dest);
return 1; return 1;
} }
ctx->res_w = r->code; ctx->res_w = r->code;
@ -3047,7 +3040,7 @@ static int reserved_word(o_string *dest, struct p_context *ctx)
*ctx = *old; /* physical copy */ *ctx = *old; /* physical copy */
free(old); free(old);
} }
b_reset(dest); o_reset(dest);
return 1; return 1;
} }
return 0; return 0;
@ -3092,7 +3085,7 @@ static int done_word(o_string *dest, struct p_context *ctx)
return 1; return 1;
} }
b_reset(dest); o_reset(dest);
if (ctx->pending_redirect) { if (ctx->pending_redirect) {
/* NB: don't free_strings(ctx->pending_redirect->glob_word) here */ /* NB: don't free_strings(ctx->pending_redirect->glob_word) here */
if (ctx->pending_redirect->glob_word if (ctx->pending_redirect->glob_word
@ -3151,8 +3144,6 @@ static int done_command(struct p_context *ctx)
/*child->is_stopped = 0;*/ /*child->is_stopped = 0;*/
/*child->group = NULL;*/ /*child->group = NULL;*/
child->family = pi; child->family = pi;
//sp: /*child->sp = 0;*/
//pt: child->parse_type = ctx->parse_type;
ctx->child = child; ctx->child = child;
/* but ctx->pipe and ctx->list_head remain unchanged */ /* but ctx->pipe and ctx->list_head remain unchanged */
@ -3190,20 +3181,20 @@ static int done_pipe(struct p_context *ctx, pipe_style type)
static int redirect_dup_num(struct in_str *input) static int redirect_dup_num(struct in_str *input)
{ {
int ch, d = 0, ok = 0; int ch, d = 0, ok = 0;
ch = b_peek(input); ch = i_peek(input);
if (ch != '&') return -1; if (ch != '&') return -1;
b_getch(input); /* get the & */ i_getch(input); /* get the & */
ch = b_peek(input); ch = i_peek(input);
if (ch == '-') { if (ch == '-') {
b_getch(input); i_getch(input);
return -3; /* "-" represents "close me" */ return -3; /* "-" represents "close me" */
} }
while (isdigit(ch)) { while (isdigit(ch)) {
d = d*10 + (ch-'0'); d = d*10 + (ch-'0');
ok = 1; ok = 1;
b_getch(input); i_getch(input);
ch = b_peek(input); ch = i_peek(input);
} }
if (ok) return d; if (ok) return d;
@ -3235,7 +3226,7 @@ static int redirect_opt_num(o_string *o)
} }
/* reuse num (and save an int) */ /* reuse num (and save an int) */
num = atoi(o->data); num = atoi(o->data);
b_reset(o); o_reset(o);
return num; return num;
} }
@ -3285,7 +3276,6 @@ static FILE *generate_stream_from_list(struct pipe *head)
/* Return code is exit status of the process that is run. */ /* Return code is exit status of the process that is run. */
static int process_command_subs(o_string *dest, static int process_command_subs(o_string *dest,
/*struct p_context *ctx,*/
struct in_str *input, struct in_str *input,
const char *subst_end) const char *subst_end)
{ {
@ -3303,7 +3293,7 @@ static int process_command_subs(o_string *dest,
return retcode; /* syntax error or EOF */ return retcode; /* syntax error or EOF */
done_word(&result, &inner); done_word(&result, &inner);
done_pipe(&inner, PIPE_SEQ); done_pipe(&inner, PIPE_SEQ);
b_free(&result); o_free(&result);
p = generate_stream_from_list(inner.list_head); p = generate_stream_from_list(inner.list_head);
if (p == NULL) if (p == NULL)
@ -3313,16 +3303,16 @@ static int process_command_subs(o_string *dest,
/* now send results of command back into original context */ /* now send results of command back into original context */
eol_cnt = 0; eol_cnt = 0;
while ((ch = b_getch(&pipe_str)) != EOF) { while ((ch = i_getch(&pipe_str)) != EOF) {
if (ch == '\n') { if (ch == '\n') {
eol_cnt++; eol_cnt++;
continue; continue;
} }
while (eol_cnt) { while (eol_cnt) {
b_addqchr(dest, '\n', dest->o_quote); o_addqchr(dest, '\n', dest->o_quote);
eol_cnt--; eol_cnt--;
} }
b_addqchr(dest, ch, dest->o_quote); o_addqchr(dest, ch, dest->o_quote);
} }
debug_printf("done reading from pipe, pclose()ing\n"); debug_printf("done reading from pipe, pclose()ing\n");
@ -3386,31 +3376,31 @@ static void add_till_backquote(o_string *dest, struct in_str *input);
static void add_till_single_quote(o_string *dest, struct in_str *input) static void add_till_single_quote(o_string *dest, struct in_str *input)
{ {
while (1) { while (1) {
int ch = b_getch(input); int ch = i_getch(input);
if (ch == EOF) if (ch == EOF)
break; break;
if (ch == '\'') if (ch == '\'')
break; break;
b_addchr(dest, ch); o_addchr(dest, ch);
} }
} }
/* "...\"...`..`...." - do we need to handle "...$(..)..." too? */ /* "...\"...`..`...." - do we need to handle "...$(..)..." too? */
static void add_till_double_quote(o_string *dest, struct in_str *input) static void add_till_double_quote(o_string *dest, struct in_str *input)
{ {
while (1) { while (1) {
int ch = b_getch(input); int ch = i_getch(input);
if (ch == '"') if (ch == '"')
break; break;
if (ch == '\\') { /* \x. Copy both chars. */ if (ch == '\\') { /* \x. Copy both chars. */
b_addchr(dest, ch); o_addchr(dest, ch);
ch = b_getch(input); ch = i_getch(input);
} }
if (ch == EOF) if (ch == EOF)
break; break;
b_addchr(dest, ch); o_addchr(dest, ch);
if (ch == '`') { if (ch == '`') {
add_till_backquote(dest, input); add_till_backquote(dest, input);
b_addchr(dest, ch); o_addchr(dest, ch);
continue; continue;
} }
// if (ch == '$') ... // if (ch == '$') ...
@ -3433,19 +3423,19 @@ static void add_till_double_quote(o_string *dest, struct in_str *input)
static void add_till_backquote(o_string *dest, struct in_str *input) static void add_till_backquote(o_string *dest, struct in_str *input)
{ {
while (1) { while (1) {
int ch = b_getch(input); int ch = i_getch(input);
//bb_error_msg("ADD '%c'", ch); //bb_error_msg("ADD '%c'", ch);
if (ch == '`') if (ch == '`')
break; break;
if (ch == '\\') { /* \x. Copy both chars unless it is \` */ if (ch == '\\') { /* \x. Copy both chars unless it is \` */
int ch2 = b_getch(input); int ch2 = i_getch(input);
if (ch2 != '`' && ch2 != '$' && ch2 != '\\') if (ch2 != '`' && ch2 != '$' && ch2 != '\\')
b_addchr(dest, ch); o_addchr(dest, ch);
ch = ch2; ch = ch2;
} }
if (ch == EOF) if (ch == EOF)
break; break;
b_addchr(dest, ch); o_addchr(dest, ch);
} }
} }
/* Process $(cmd) - copy contents until ")" is seen. Complicated by /* Process $(cmd) - copy contents until ")" is seen. Complicated by
@ -3464,7 +3454,7 @@ static void add_till_closing_curly_brace(o_string *dest, struct in_str *input)
{ {
int count = 0; int count = 0;
while (1) { while (1) {
int ch = b_getch(input); int ch = i_getch(input);
if (ch == EOF) if (ch == EOF)
break; break;
if (ch == '(') if (ch == '(')
@ -3472,51 +3462,47 @@ static void add_till_closing_curly_brace(o_string *dest, struct in_str *input)
if (ch == ')') if (ch == ')')
if (--count < 0) if (--count < 0)
break; break;
b_addchr(dest, ch); o_addchr(dest, ch);
if (ch == '\'') { if (ch == '\'') {
add_till_single_quote(dest, input); add_till_single_quote(dest, input);
b_addchr(dest, ch); o_addchr(dest, ch);
continue; continue;
} }
if (ch == '"') { if (ch == '"') {
add_till_double_quote(dest, input); add_till_double_quote(dest, input);
b_addchr(dest, ch); o_addchr(dest, ch);
continue; continue;
} }
} }
} }
#endif /* ENABLE_HUSH_TICK */ #endif /* ENABLE_HUSH_TICK */
//FIXME: remove ctx and sp
/* return code: 0 for OK, 1 for syntax error */ /* return code: 0 for OK, 1 for syntax error */
static int handle_dollar(o_string *dest, /*struct p_context *ctx,*/ struct in_str *input) static int handle_dollar(o_string *dest, struct in_str *input)
{ {
int ch = b_peek(input); /* first character after the $ */ int ch = i_peek(input); /* first character after the $ */
unsigned char quote_mask = dest->o_quote ? 0x80 : 0; unsigned char quote_mask = dest->o_quote ? 0x80 : 0;
debug_printf_parse("handle_dollar entered: ch='%c'\n", ch); debug_printf_parse("handle_dollar entered: ch='%c'\n", ch);
if (isalpha(ch)) { if (isalpha(ch)) {
b_addchr(dest, SPECIAL_VAR_SYMBOL); o_addchr(dest, SPECIAL_VAR_SYMBOL);
//sp: ctx->child->sp++;
while (1) { while (1) {
debug_printf_parse(": '%c'\n", ch); debug_printf_parse(": '%c'\n", ch);
b_getch(input); i_getch(input);
b_addchr(dest, ch | quote_mask); o_addchr(dest, ch | quote_mask);
quote_mask = 0; quote_mask = 0;
ch = b_peek(input); ch = i_peek(input);
if (!isalnum(ch) && ch != '_') if (!isalnum(ch) && ch != '_')
break; break;
} }
b_addchr(dest, SPECIAL_VAR_SYMBOL); o_addchr(dest, SPECIAL_VAR_SYMBOL);
} else if (isdigit(ch)) { } else if (isdigit(ch)) {
make_one_char_var: make_one_char_var:
b_addchr(dest, SPECIAL_VAR_SYMBOL); o_addchr(dest, SPECIAL_VAR_SYMBOL);
//sp: ctx->child->sp++;
debug_printf_parse(": '%c'\n", ch); debug_printf_parse(": '%c'\n", ch);
b_getch(input); i_getch(input);
b_addchr(dest, ch | quote_mask); o_addchr(dest, ch | quote_mask);
b_addchr(dest, SPECIAL_VAR_SYMBOL); o_addchr(dest, SPECIAL_VAR_SYMBOL);
} else switch (ch) { } else switch (ch) {
case '$': /* pid */ case '$': /* pid */
case '!': /* last bg pid */ case '!': /* last bg pid */
@ -3526,12 +3512,11 @@ static int handle_dollar(o_string *dest, /*struct p_context *ctx,*/ struct in_st
case '@': /* args */ case '@': /* args */
goto make_one_char_var; goto make_one_char_var;
case '{': case '{':
b_addchr(dest, SPECIAL_VAR_SYMBOL); o_addchr(dest, SPECIAL_VAR_SYMBOL);
//sp: ctx->child->sp++; i_getch(input);
b_getch(input);
/* XXX maybe someone will try to escape the '}' */ /* XXX maybe someone will try to escape the '}' */
while (1) { while (1) {
ch = b_getch(input); ch = i_getch(input);
if (ch == '}') if (ch == '}')
break; break;
if (!isalnum(ch) && ch != '_') { if (!isalnum(ch) && ch != '_') {
@ -3540,18 +3525,18 @@ static int handle_dollar(o_string *dest, /*struct p_context *ctx,*/ struct in_st
return 1; return 1;
} }
debug_printf_parse(": '%c'\n", ch); debug_printf_parse(": '%c'\n", ch);
b_addchr(dest, ch | quote_mask); o_addchr(dest, ch | quote_mask);
quote_mask = 0; quote_mask = 0;
} }
b_addchr(dest, SPECIAL_VAR_SYMBOL); o_addchr(dest, SPECIAL_VAR_SYMBOL);
break; break;
#if ENABLE_HUSH_TICK #if ENABLE_HUSH_TICK
case '(': case '(':
b_getch(input); i_getch(input);
b_addchr(dest, SPECIAL_VAR_SYMBOL); o_addchr(dest, SPECIAL_VAR_SYMBOL);
b_addchr(dest, quote_mask | '`'); o_addchr(dest, quote_mask | '`');
add_till_closing_curly_brace(dest, input); add_till_closing_curly_brace(dest, input);
b_addchr(dest, SPECIAL_VAR_SYMBOL); o_addchr(dest, SPECIAL_VAR_SYMBOL);
break; break;
#endif #endif
case '-': case '-':
@ -3561,7 +3546,7 @@ static int handle_dollar(o_string *dest, /*struct p_context *ctx,*/ struct in_st
return 1; return 1;
break; break;
default: default:
b_addqchr(dest, '$', dest->o_quote); o_addqchr(dest, '$', dest->o_quote);
} }
debug_printf_parse("handle_dollar return 0\n"); debug_printf_parse("handle_dollar return 0\n");
return 0; return 0;
@ -3585,11 +3570,11 @@ static int parse_stream(o_string *dest, struct p_context *ctx,
while (1) { while (1) {
m = CHAR_IFS; m = CHAR_IFS;
next = '\0'; next = '\0';
ch = b_getch(input); ch = i_getch(input);
if (ch != EOF) { if (ch != EOF) {
m = charmap[ch]; m = charmap[ch];
if (ch != '\n') if (ch != '\n')
next = b_peek(input); next = i_peek(input);
} }
debug_printf_parse(": ch=%c (%d) m=%d quote=%d\n", debug_printf_parse(": ch=%c (%d) m=%d quote=%d\n",
ch, ch, m, dest->o_quote); ch, ch, m, dest->o_quote);
@ -3601,7 +3586,7 @@ static int parse_stream(o_string *dest, struct p_context *ctx,
debug_printf_parse("parse_stream return 1: unterminated \"\n"); debug_printf_parse("parse_stream return 1: unterminated \"\n");
return 1; return 1;
} }
b_addqchr(dest, ch, dest->o_quote); o_addqchr(dest, ch, dest->o_quote);
continue; continue;
} }
if (m == CHAR_IFS) { if (m == CHAR_IFS) {
@ -3630,13 +3615,13 @@ static int parse_stream(o_string *dest, struct p_context *ctx,
case '#': case '#':
if (dest->length == 0 && !dest->o_quote) { if (dest->length == 0 && !dest->o_quote) {
while (1) { while (1) {
ch = b_peek(input); ch = i_peek(input);
if (ch == EOF || ch == '\n') if (ch == EOF || ch == '\n')
break; break;
b_getch(input); i_getch(input);
} }
} else { } else {
b_addqchr(dest, ch, dest->o_quote); o_addqchr(dest, ch, dest->o_quote);
} }
break; break;
case '\\': case '\\':
@ -3645,11 +3630,11 @@ static int parse_stream(o_string *dest, struct p_context *ctx,
debug_printf_parse("parse_stream return 1: \\<eof>\n"); debug_printf_parse("parse_stream return 1: \\<eof>\n");
return 1; return 1;
} }
b_addqchr(dest, '\\', dest->o_quote); o_addqchr(dest, '\\', dest->o_quote);
b_addqchr(dest, b_getch(input), dest->o_quote); o_addqchr(dest, i_getch(input), dest->o_quote);
break; break;
case '$': case '$':
if (handle_dollar(dest, /*ctx,*/ input) != 0) { if (handle_dollar(dest, input) != 0) {
debug_printf_parse("parse_stream return 1: handle_dollar returned non-0\n"); debug_printf_parse("parse_stream return 1: handle_dollar returned non-0\n");
return 1; return 1;
} }
@ -3657,10 +3642,10 @@ static int parse_stream(o_string *dest, struct p_context *ctx,
case '\'': case '\'':
dest->nonnull = 1; dest->nonnull = 1;
while (1) { while (1) {
ch = b_getch(input); ch = i_getch(input);
if (ch == EOF || ch == '\'') if (ch == EOF || ch == '\'')
break; break;
b_addchr(dest, ch); o_addchr(dest, ch);
} }
if (ch == EOF) { if (ch == EOF) {
syntax("unterminated '"); syntax("unterminated '");
@ -3675,10 +3660,10 @@ static int parse_stream(o_string *dest, struct p_context *ctx,
#if ENABLE_HUSH_TICK #if ENABLE_HUSH_TICK
case '`': { case '`': {
//int pos = dest->length; //int pos = dest->length;
b_addchr(dest, SPECIAL_VAR_SYMBOL); o_addchr(dest, SPECIAL_VAR_SYMBOL);
b_addchr(dest, dest->o_quote ? 0x80 | '`' : '`'); o_addchr(dest, dest->o_quote ? 0x80 | '`' : '`');
add_till_backquote(dest, input); add_till_backquote(dest, input);
b_addchr(dest, SPECIAL_VAR_SYMBOL); o_addchr(dest, SPECIAL_VAR_SYMBOL);
//bb_error_msg("RES '%s'", dest->data + pos); //bb_error_msg("RES '%s'", dest->data + pos);
break; break;
} }
@ -3689,7 +3674,7 @@ static int parse_stream(o_string *dest, struct p_context *ctx,
redir_style = REDIRECT_OVERWRITE; redir_style = REDIRECT_OVERWRITE;
if (next == '>') { if (next == '>') {
redir_style = REDIRECT_APPEND; redir_style = REDIRECT_APPEND;
b_getch(input); i_getch(input);
} }
#if 0 #if 0
else if (next == '(') { else if (next == '(') {
@ -3706,10 +3691,10 @@ static int parse_stream(o_string *dest, struct p_context *ctx,
redir_style = REDIRECT_INPUT; redir_style = REDIRECT_INPUT;
if (next == '<') { if (next == '<') {
redir_style = REDIRECT_HEREIS; redir_style = REDIRECT_HEREIS;
b_getch(input); i_getch(input);
} else if (next == '>') { } else if (next == '>') {
redir_style = REDIRECT_IO; redir_style = REDIRECT_IO;
b_getch(input); i_getch(input);
} }
#if 0 #if 0
else if (next == '(') { else if (next == '(') {
@ -3727,7 +3712,7 @@ static int parse_stream(o_string *dest, struct p_context *ctx,
case '&': case '&':
done_word(dest, ctx); done_word(dest, ctx);
if (next == '&') { if (next == '&') {
b_getch(input); i_getch(input);
done_pipe(ctx, PIPE_AND); done_pipe(ctx, PIPE_AND);
} else { } else {
done_pipe(ctx, PIPE_BG); done_pipe(ctx, PIPE_BG);
@ -3736,7 +3721,7 @@ static int parse_stream(o_string *dest, struct p_context *ctx,
case '|': case '|':
done_word(dest, ctx); done_word(dest, ctx);
if (next == '|') { if (next == '|') {
b_getch(input); i_getch(input);
done_pipe(ctx, PIPE_OR); done_pipe(ctx, PIPE_OR);
} else { } else {
/* we could pick up a file descriptor choice here /* we could pick up a file descriptor choice here
@ -3836,14 +3821,14 @@ static int parse_and_run_stream(struct in_str *inp, int parse_flag)
} else { } else {
if (ctx.old_flag != 0) { if (ctx.old_flag != 0) {
free(ctx.stack); free(ctx.stack);
b_reset(&temp); o_reset(&temp);
} }
temp.nonnull = 0; temp.nonnull = 0;
temp.o_quote = 0; temp.o_quote = 0;
inp->p = NULL; inp->p = NULL;
free_pipe_list(ctx.list_head, /* indent: */ 0); free_pipe_list(ctx.list_head, /* indent: */ 0);
} }
b_free(&temp); o_free(&temp);
} while (rcode != -1 && !(parse_flag & PARSEFLAG_EXIT_FROM_LOOP)); /* loop on syntax errors, return on EOF */ } while (rcode != -1 && !(parse_flag & PARSEFLAG_EXIT_FROM_LOOP)); /* loop on syntax errors, return on EOF */
return 0; return 0;
} }