From 41dfa883e178c239bed0ec02fa38af09739d55b0 Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Wed, 8 Apr 2020 23:08:57 -0500 Subject: Implement ! and $$ and fix quoted "$(subshell)" --- toys/pending/sh.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) (limited to 'toys') diff --git a/toys/pending/sh.c b/toys/pending/sh.c index 55c30a19..183d5fd1 100644 --- a/toys/pending/sh.c +++ b/toys/pending/sh.c @@ -485,7 +485,7 @@ static int redir_prefix(char *word) } // parse next word from command line. Returns end, or 0 if need continuation -// caller eats leading spaces. If early, stop at first unquoted char. +// caller eats leading spaces. early = skip one quote block (or return start) static char *parse_word(char *start, int early) { int i, quote = 0, q, qc = 0; @@ -497,8 +497,7 @@ static char *parse_word(char *start, int early) // Redirections. 123<c?TT.arg->c-1:0); else if (cc == '*' || cc == '@') { // If not doing word split, handle here @@ -1025,7 +1025,7 @@ static void expand_arg(struct sh_arg *arg, char *old, unsigned flags, { struct brace { struct brace *next, *prev, *stack; - int active, cnt, idx, commas[]; + int active, cnt, idx, dots[2], commas[]; } *bb = 0, *blist = 0, *bstk, *bnext; int i, j; char *s, *ss; @@ -1214,6 +1214,12 @@ static struct sh_process *expand_redir(struct sh_arg *arg, int envlen, int *urd) s = arg->v[j]; + if (!strcmp(s, "!")) { + pp->not ^= 1; + + continue; + } + // Handle <() >() redirectionss if ((*s == '<' || *s == '>') && s[1] == '(') { int new = pipe_subshell(s+2, strlen(s+2)-1, *s == '>'); @@ -1884,7 +1890,7 @@ static int wait_pipeline(struct sh_process *pp) pp->pid = 0; } // TODO handle set -o pipefail here - rc = pp->exit; + rc = pp->not ? !pp->exit : pp->exit; } return rc; @@ -2640,9 +2646,9 @@ void export_main(void) void eval_main(void) { int len = 1; - char *s = merge_args("", toys.optc+1, toys.argv, " ", &len, ""); + char *s; - sh_run(s); + sh_run(s = merge_args("", toys.optc+1, toys.argv, " ", &len, "")); free(s); } -- cgit v1.2.3