aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/rc/pcmd.c
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2003-11-23 18:04:08 +0000
committerrsc <devnull@localhost>2003-11-23 18:04:08 +0000
commitf08fdedcee12c06e3ce9ac9bec363915978e8289 (patch)
treed67a27473be1e8f98d3694028104d9ddf915345b /src/cmd/rc/pcmd.c
parent5993a8f2756bc455101a8c9ce95347d5050e7883 (diff)
downloadplan9port-f08fdedcee12c06e3ce9ac9bec363915978e8289.tar.gz
plan9port-f08fdedcee12c06e3ce9ac9bec363915978e8289.tar.bz2
plan9port-f08fdedcee12c06e3ce9ac9bec363915978e8289.zip
Plan 9's rc.
not a clear win over byron's, but at least it has the right syntax.
Diffstat (limited to 'src/cmd/rc/pcmd.c')
-rw-r--r--src/cmd/rc/pcmd.c108
1 files changed, 108 insertions, 0 deletions
diff --git a/src/cmd/rc/pcmd.c b/src/cmd/rc/pcmd.c
new file mode 100644
index 00000000..0f84298a
--- /dev/null
+++ b/src/cmd/rc/pcmd.c
@@ -0,0 +1,108 @@
+#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:
+ 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;
+ }
+}