From 2ade60747db41771498ab2b85ce6e3c3389f2c26 Mon Sep 17 00:00:00 2001 From: Nicholas Noll Date: Wed, 13 Oct 2021 09:08:59 -0700 Subject: feat(rc): added unix port of rc with linenoise --- sys/cmd/rc/pcmd.c | 147 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 sys/cmd/rc/pcmd.c (limited to 'sys/cmd/rc/pcmd.c') diff --git a/sys/cmd/rc/pcmd.c b/sys/cmd/rc/pcmd.c new file mode 100644 index 0000000..8caf60a --- /dev/null +++ b/sys/cmd/rc/pcmd.c @@ -0,0 +1,147 @@ +#include "rc.h" +#include "io.h" +#include "fns.h" +char nl='\n'; /* change to semicolon for bourne-proofing */ +#define c0 t->child[0] +#define c1 t->child[1] +#define c2 t->child[2] + +void +pdeglob(io *f, char *s) +{ + while(*s){ + if(*s==GLOB) + s++; + pchr(f, *s++); + } +} + +void +pcmd(io *f, tree *t) +{ + if(t==0) + return; + switch(t->type){ + default: pfmt(f, "bad %d %p %p %p", t->type, c0, c1, c2); + break; + case '$': pfmt(f, "$%t", c0); + break; + case '"': pfmt(f, "$\"%t", c0); + break; + case '&': pfmt(f, "%t&", c0); + break; + case '^': pfmt(f, "%t^%t", c0, c1); + break; + case '`': pfmt(f, "`%t", c0); + break; + case ANDAND: pfmt(f, "%t && %t", c0, c1); + break; + case BANG: pfmt(f, "! %t", c0); + break; + case BRACE: pfmt(f, "{%t}", c0); + break; + case COUNT: pfmt(f, "$#%t", c0); + break; + case FN: pfmt(f, "fn %t %t", c0, c1); + break; + case IF: pfmt(f, "if%t%t", c0, c1); + break; + case NOT: pfmt(f, "if not %t", c0); + break; + case OROR: pfmt(f, "%t || %t", c0, c1); + break; + case PCMD: + case PAREN: pfmt(f, "(%t)", c0); + break; + case SUB: pfmt(f, "$%t(%t)", c0, c1); + break; + case SIMPLE: pfmt(f, "%t", c0); + break; + case SUBSHELL: pfmt(f, "@ %t", c0); + break; + case SWITCH: pfmt(f, "switch %t %t", c0, c1); + break; + case TWIDDLE: pfmt(f, "~ %t %t", c0, c1); + break; + case WHILE: pfmt(f, "while %t%t", c0, c1); + break; + case ARGLIST: + if(c0==0) + pfmt(f, "%t", c1); + else if(c1==0) + pfmt(f, "%t", c0); + else + pfmt(f, "%t %t", c0, c1); + break; + case ';': + if(c0){ + if(c1) + pfmt(f, "%t%c%t", c0, nl, c1); + else pfmt(f, "%t", c0); + } + else pfmt(f, "%t", c1); + break; + case WORDS: + if(c0) + pfmt(f, "%t ", c0); + pfmt(f, "%t", c1); + break; + case FOR: + pfmt(f, "for(%t", c0); + if(c1) + pfmt(f, " in %t", c1); + pfmt(f, ")%t", c2); + break; + case WORD: + if(t->quoted) + pfmt(f, "%Q", t->str); + else pdeglob(f, t->str); + break; + case DUP: + if(t->rtype==DUPFD) + pfmt(f, ">[%d=%d]", t->fd1, t->fd0); /* yes, fd1, then fd0; read lex.c */ + else + pfmt(f, ">[%d=]", t->fd0); + pfmt(f, "%t", c1); + break; + case PIPEFD: + case REDIR: + switch(t->rtype){ + case HERE: + pchr(f, '<'); + case READ: + case RDWR: + pchr(f, '<'); + if(t->rtype==RDWR) + pchr(f, '>'); + if(t->fd0!=0) + pfmt(f, "[%d]", t->fd0); + break; + case APPEND: + pchr(f, '>'); + case WRITE: + pchr(f, '>'); + if(t->fd0!=1) + pfmt(f, "[%d]", t->fd0); + break; + } + pfmt(f, "%t", c0); + if(c1) + pfmt(f, " %t", c1); + break; + case '=': + pfmt(f, "%t=%t", c0, c1); + if(c2) + pfmt(f, " %t", c2); + break; + case PIPE: + pfmt(f, "%t|", c0); + if(t->fd1==0){ + if(t->fd0!=1) + pfmt(f, "[%d]", t->fd0); + } + else pfmt(f, "[%d=%d]", t->fd0, t->fd1); + pfmt(f, "%t", c1); + break; + } +} -- cgit v1.2.1