| #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; | 
 | 	} | 
 | } |