157 lines
3.0 KiB
C
157 lines
3.0 KiB
C
/*
|
|
* This file is part of the UCB release of Plan 9. It is subject to the license
|
|
* terms in the LICENSE file found in the top-level directory of this
|
|
* distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
|
|
* part of the UCB release of Plan 9, including this file, may be copied,
|
|
* modified, propagated, or distributed except according to the terms contained
|
|
* in the LICENSE file.
|
|
*/
|
|
|
|
#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 cmd %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%t", c0, c1);
|
|
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;
|
|
}
|
|
}
|