From 5c20d687c495f2cb3f3a390d04854dcceb2ef74e Mon Sep 17 00:00:00 2001 From: Nicholas Noll Date: Thu, 21 Oct 2021 11:17:15 -0700 Subject: feat(rc): expanded tree printing --- sys/cmd/rc/io.c | 120 ++++++++++++++++++++++++++++++++++++++++++++---------- sys/cmd/rc/lex.c | 75 +++++++++++++++++++++++++++++++--- sys/cmd/rc/main.c | 2 +- sys/cmd/rc/rc.h | 7 +++- sys/cmd/rc/sys.c | 4 +- 5 files changed, 177 insertions(+), 31 deletions(-) (limited to 'sys') diff --git a/sys/cmd/rc/io.c b/sys/cmd/rc/io.c index 7f2d869..f033031 100644 --- a/sys/cmd/rc/io.c +++ b/sys/cmd/rc/io.c @@ -216,6 +216,10 @@ printval(Io *io, Word *a) } } +#define C0 t->child[0] +#define C1 t->child[1] +#define C2 t->child[2] + static void printtree(Io *io, Tree *t) @@ -224,42 +228,116 @@ printtree(Io *io, Tree *t) return; switch(t->type){ - case Tword: - print(io,"{%s}",t->str); - break; - - case Tbasic: - print(io, ">%t", t->child[0]); - break; + default: print(io, "bad(%d)[%p %p %p]", t->type, C0, C1, C2); break; + case '$': print(io,"$%t",C0); break; + case '"': print(io,"\"%t",C0); break; + case '&': print(io,"%t&",C0); break; + case '^': print(io,"%t^%t",C0,C1); break; + case '`': print(io,"`%t",C0); break; + + case Tbasic: print(io, "%t", C0); break; + case Tbang: print(io, "!%t", C0); break; + case Tblock: print(io, "{%t}", C0); break; + case Tcount: print(io, "$#%t", C0); break; + case Tparen: print(io, "(%t)", C0); break; + case Tindex: print(io, "%t(%t)",C0); break; + case Tsubshell: print(io, "@ %t",C0); break; + //case Ttwiddle: print(io, "~ %t %t", C0, C1); break; + + case Toror: + case Tandand: case Targs: - if(!t->child[0]) - print(io, "%t", t->child[1]); - else if(!t->child[1]) - print(io, "%t", t->child[0]); + if(!C0) + print(io, "%t", C1); + else if(!C1) + print(io, "%t", C0); else - print(io, "[%t %t]", t->child[0], t->child[1]); + print(io, "%t %t", C0, C1); break; case ';': - if(t->child[0]){ - if(t->child[1]) - print(io, ";[%t %t]", t->child[0], t->child[1]); + if(C0){ + if(C1) + print(io, "%t;%t", C0, C1); else - print(io, "%t", t->child[0]); + print(io, "%t", C0); }else - print(io, "%t", t->child[1]); + print(io, "%t", C1); break; - case '&': - print(io, "&(%t)", t->child[0]); + case Twords: + if(C0) + print(io, "%t", C0); + print(io, "%t", C1); + + case Tword: + if(t->quoted) + print(io, "%Q", t->str); + print(io, "%q", t->str); + break; + + case '=': + print(io, "%t=%t", C0, C1); + if(C2) + print(io, " %t", C2); break; - default: - print(io, "bad(%d)[%p %p %p]", t->type, t->child[0], t->child[1], t->child[2]); + case Tdup: + if(t->redir.type == Rdupfd) + print(io, ">[%d=%d]", t->redir.fd[1], t->redir.fd[0]); + else + print(io, ">[%d=]", t->redir.fd[0]); + print(io, "%t", C1); + break; + + case Tredir: + switch(t->redir.type){ + case Rhere: + printchar(io, '<'); + case Rread: + printchar(io, '<'); + goto readfd; + case Rrdwr: + printchar(io, '<'); + printchar(io, '>'); + readfd: + if(t->redir.fd[0]!=0) + print(io, "[%d]", t->redir.fd[0]); + break; + case Rappend: + printchar(io, '>'); + goto writefd; + case Rwrite: + printchar(io, '>'); + printchar(io, '>'); + writefd: + if(t->redir.fd[0]!=1) + print(io, "[%d]", t->redir.fd[0]); + break; + } + print(io, "%t", C0); + if(C1) + print(io, " %t", C1); + break; + + case Tpipe: + print(io, "%t|", C0); + if(t->redir.fd[1]==0){ + if(t->redir.fd[0]!=1) + print(io, "[%d]", t->redir.fd[0]); + } + else + print(io, "[%d=%d]", t->redir.fd[0], t->redir.fd[1]); + print(io, "%t", C1); + break; } } +#undef C0 +#undef C1 +#undef C2 + // ----------------------------------------------------------------------- // exports diff --git a/sys/cmd/rc/lex.c b/sys/cmd/rc/lex.c index eb3a268..31c7cdc 100644 --- a/sys/cmd/rc/lex.c +++ b/sys/cmd/rc/lex.c @@ -10,6 +10,9 @@ struct Lexer { int c[2]; ushort doprompt; + ushort hadword; + ushort haddollar; + ushort inquote; char buf[BUFSIZ]; }; @@ -166,40 +169,67 @@ putrune(char *buf, int c) // ----------------------------------------------------------------------- // exported functions +// TODO: turn into static tables int iswordchar(int c) { return !strchr("\n \t#;&|^$=`'{}()<>", c) && c!=EOF; } +int +isidentchar(int c) +{ + return c>' ' && !strchr("!\"#$%&'()+,-./:;<=>?@[\\]^`{|}~", c); +} + int yylex(void) { - int c; + int c, d = peekc(); Tree *node; char *w = lexer.buf; yylval.tree = nil; + /* inject tokens */ + if(lexer.hadword){ + if(d=='('){ + advance(); + strcpy(lexer.buf, "( [Tindex]"); + return Tindex; + } + if(iswordchar(d) || d=='\'' || d=='`' || d=='$' || d=='"'){ + strcpy(lexer.buf, "^"); + return '^'; + } + } + + lexer.inquote = 0; + skipws(); switch(c=advance()){ case EOF: + lexer.haddollar = 0; put3('E','O','F'); return EOF; case '@': + lexer.haddollar = 0; put1('@'); return Tsubshell; case '!': + lexer.haddollar = 0; put1('!'); return Tbang; case '&': + lexer.haddollar = 0; put1('&'); return '&'; case '|': + lexer.haddollar = 0; if(nextis('|')){ put2('|','|'); return Toror; @@ -213,6 +243,7 @@ yylex(void) goto redir; case '>': + lexer.haddollar = 0; node = maketree(); *w++ = '>'; node->type = Tredir; @@ -226,6 +257,7 @@ yylex(void) goto redir; case '<': + lexer.haddollar = 0; node = maketree(); *w++ = '<'; node->type = Tredir; @@ -270,7 +302,7 @@ yylex(void) goto badredir; node->redir.type = Rclose; }else{ - node->redir.type = Rdup; + node->redir.type = Rdupfd; node->redir.fd[1] = node->redir.fd[0]; node->redir.fd[0] = 0; do{ @@ -289,6 +321,7 @@ yylex(void) return node->type; case '$': + lexer.haddollar = 1; if(nextis('#')){ put2('$','#'); return Tcount; @@ -300,22 +333,54 @@ yylex(void) put1('$'); return '$'; + case '\'': + lexer.hadword = 1; + lexer.inquote = 1; + lexer.haddollar = 0; + for(;;){ + c = advance(); + if(c==EOF) + break; + + if(c=='\''){ + if(peekc()!='\'') + break; + advance(); + } + w = putrune(w, c); + } + if(w) + *w = 0; + node = token(Tword, lexer.buf); + node->quoted = 1; + return node->type; + default: ; } - if(!iswordchar(c)) + if(!iswordchar(c)){ + put1(c); + lexer.haddollar = 0; return c; + } for(;;){ w = putrune(w, c); c = peekc(); - if(!iswordchar(c)) + if(lexer.haddollar ? !isidentchar(c) : !iswordchar(c)) break; advance(); } - w[0] = 0; + + lexer.hadword = 1; + lexer.haddollar = 0; + if(w) + *w = 0; node = token(Tword, lexer.buf); + // TODO: keywords + + node->quoted = 0; yylval.tree = node; return node->type; diff --git a/sys/cmd/rc/main.c b/sys/cmd/rc/main.c index 86c6792..3f2e02e 100644 --- a/sys/cmd/rc/main.c +++ b/sys/cmd/rc/main.c @@ -58,6 +58,6 @@ main(int argc, char *argv[]) initpath(); initshell(); - enablevi(); + // enablevi(); xboot(argc, argv); } diff --git a/sys/cmd/rc/rc.h b/sys/cmd/rc/rc.h index d3fc7bf..13444e6 100644 --- a/sys/cmd/rc/rc.h +++ b/sys/cmd/rc/rc.h @@ -29,7 +29,7 @@ enum Rwrite, Rread, Rhere, - Rdup, + Rdupfd, Ropen, Rclose, Rrdwr @@ -39,7 +39,10 @@ struct Tree { int type; union{ - char *str; // Tword + struct { + ushort quoted; + char *str; // Tword + }; struct { ushort type; // Tpipe, Tredir, Tdup int fd[2]; diff --git a/sys/cmd/rc/sys.c b/sys/cmd/rc/sys.c index a24545f..86c430e 100644 --- a/sys/cmd/rc/sys.c +++ b/sys/cmd/rc/sys.c @@ -103,7 +103,7 @@ redirect(Redir *r) close(r->from); } break; - case Rdup: + case Rdupfd: dup2(r->from, r->to); // TODO: error checking break; case Rclose: @@ -125,7 +125,7 @@ mapfd(int fd) if(r->from == fd) fd = -1; break; - case Rdup: + case Rdupfd: case Ropen: if(r->to == fd) fd = r->from; -- cgit v1.2.1