diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2022-02-16 18:07:21 +0000 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2022-02-16 18:07:21 +0000 |
commit | 755880b19f365c3f98eac5c7de1d8b25f773ace3 (patch) | |
tree | 28f1615267a197c780c3a48921f879c3b2b5529d /sys/src/cmd/rc | |
parent | c5c79d61e67f2c74a8d57eb1aeea87a23eeadd87 (diff) |
rc: fix globbing with lists (thanks qwx)
Pattern matching with lists no longer works:
; ls /tmp/*.c
/tmp/npage.c
/tmp/pagedebug.c
/tmp/pageold.c
/tmp/scheduler.c
/tmp/writeimagetest.c
; ls /tmp/^(*.c)
ls: /tmp/*.c: '/tmp/*.c' directory entry not found
; 9fs dump
; bind /n/dump/2021/1002/amd64/bin/rc /bin/rc
; rc
; ls /tmp/^(*.c)
/tmp/npage.c
/tmp/pagedebug.c
/tmp/pageold.c
/tmp/scheduler.c
/tmp/writeimagetest.c
the fix:
we have to propagate the glob attribute thru lists
as well. before it was only handled for single words
and propagated thru concatenations...
the Xglob instruction now works on list, and we
propagate the glob attribute thru PAREN and WORDS
and ARGLIST nodes.
also, avoid using negative numbers for the Tree.glob
field as char might be unsigned on some targets.
Diffstat (limited to 'sys/src/cmd/rc')
-rw-r--r-- | sys/src/cmd/rc/code.c | 10 | ||||
-rw-r--r-- | sys/src/cmd/rc/exec.c | 9 | ||||
-rw-r--r-- | sys/src/cmd/rc/rc.h | 2 | ||||
-rw-r--r-- | sys/src/cmd/rc/syn.y | 6 | ||||
-rw-r--r-- | sys/src/cmd/rc/tree.c | 22 |
5 files changed, 32 insertions, 17 deletions
diff --git a/sys/src/cmd/rc/code.c b/sys/src/cmd/rc/code.c index 958907c57..3b940ccd3 100644 --- a/sys/src/cmd/rc/code.c +++ b/sys/src/cmd/rc/code.c @@ -58,8 +58,8 @@ compile(tree *t) * called on a tree where we expect eigther * a pattern or a string instead of a glob to * remove the GLOB chars from the strings - * or set glob to -1 for pattern so not Xglob - * is inserted when compiling the tree. + * or set glob to 2 for pattern so Xglob + * is not inserted when compiling the tree. */ void noglobs(tree *t, int pattern) @@ -69,13 +69,13 @@ Again: return; if(t->type==WORD && t->glob){ if(pattern) - t->glob=-1; + t->glob=2; else{ deglob(t->str); t->glob=0; } } - if(t->type==WORDS || t->type=='^'){ + if(t->type==PAREN || t->type==WORDS || t->type=='^'){ t->glob=0; noglobs(c1, pattern); t = c0; @@ -425,7 +425,7 @@ outcode(tree *t, int eflag) emitf(Xpipewait); break; } - if(t->glob > 0) + if(t->glob==1) emitf(Xglob); if(t->type!=NOT && t->type!=';') lex->iflast = t->type==IF; diff --git a/sys/src/cmd/rc/exec.c b/sys/src/cmd/rc/exec.c index 6de94ebb7..32e7644ac 100644 --- a/sys/src/cmd/rc/exec.c +++ b/sys/src/cmd/rc/exec.c @@ -305,7 +305,7 @@ main(int argc, char *argv[]) * Xfalse{...} execute {} if false * Xfn(name){... Xreturn} define function * Xfor(var, list){... Xreturn} for loop - * Xglob(word) glob word inplace + * Xglob(list) glob a list of words inplace * Xjump[addr] goto * Xlocal(name, val) create local variable, assign value * Xmark mark stack @@ -1152,7 +1152,12 @@ Xfor(void) void Xglob(void) { - globword(runq->argv->words); + word *a, *x; + + for(a = runq->argv->words; a; a = x){ + x = a->next; + globword(a); + } } void diff --git a/sys/src/cmd/rc/rc.h b/sys/src/cmd/rc/rc.h index 2967a44b4..a688663d8 100644 --- a/sys/src/cmd/rc/rc.h +++ b/sys/src/cmd/rc/rc.h @@ -43,7 +43,7 @@ struct tree{ int type; int rtype, fd0, fd1; /* details of REDIR PIPE DUP tokens */ int line; - char glob; /* 0=string, 1=glob, -1=pattern see globprop() and noglobs() */ + char glob; /* 0=string, 1=glob, 2=pattern see globprop() and noglobs() */ char quoted; char iskw; char *str; diff --git a/sys/src/cmd/rc/syn.y b/sys/src/cmd/rc/syn.y index c29241f55..781bdf316 100644 --- a/sys/src/cmd/rc/syn.y +++ b/sys/src/cmd/rc/syn.y @@ -71,8 +71,8 @@ cmd: {$$=0;} | FN words brace {$$=tree2(FN, $2, $3);} | FN words {$$=tree1(FN, $2);} simple: first -| simple word {$$=tree2(ARGLIST, $1, $2);} -| simple redir {$$=tree2(ARGLIST, $1, $2);} +| simple word {$$=globprop(tree2(ARGLIST, $1, $2));} +| simple redir {$$=globprop(tree2(ARGLIST, $1, $2));} first: comword | first '^' word {$$=globprop(tree2('^', $1, $3));} word: keyword {lex->lastword=1; $1->type=WORD;} @@ -85,7 +85,7 @@ comword: '$' word {$$=tree1('$', $2);} | WORD | '`' brace {$$=tree2('`', (tree*)0, $2);} | '`' word brace {$$=tree2('`', $2, $3);} -| '(' words ')' {$$=tree1(PAREN, $2);} +| '(' words ')' {$$=globprop(tree1(PAREN, $2));} | REDIR brace {$$=mung1($1, $2); $$->type=PIPEFD;} keyword: FOR|IN|WHILE|IF|NOT|TWIDDLE|BANG|SUBSHELL|SWITCH|FN words: {$$=(tree*)0;} diff --git a/sys/src/cmd/rc/tree.c b/sys/src/cmd/rc/tree.c index da7157312..d3909b639 100644 --- a/sys/src/cmd/rc/tree.c +++ b/sys/src/cmd/rc/tree.c @@ -158,12 +158,22 @@ globprop(tree *t) { tree *c0 = t->child[0]; tree *c1 = t->child[1]; - if(t->glob==0){ - if(c0->glob || c1->glob){ - if(c0->glob) - c0->glob=-1; - if(c1->glob) - c1->glob=-1; + if(c1==0){ + while(c0 && c0->type==WORDS){ + c1 = c0->child[1]; + if(c1 && c1->glob){ + c1->glob=2; + t->glob=1; + } + c0 = c0->child[0]; + } + } else { + if(c0->glob){ + c0->glob=2; + t->glob=1; + } + if(c1->glob){ + c1->glob=2; t->glob=1; } } |