xref: /inferno-os/utils/rcsh/pcmd.c (revision d0e1d143ef6f03c75c008c7ec648859dd260cbab)
1 #include "rc.h"
2 #include "y.tab.h"
3 
4 char nl='\n';		/* change to semicolon for bourne-proofing */
5 
6 #define	c0	t->child[0]
7 #define	c1	t->child[1]
8 #define	c2	t->child[2]
9 
10 void
11 pdeglob(Io *f, char *s)
12 {
13 	while(*s){
14 		if(*s==GLOB) s++;
15 		pchr(f, *s++);
16 	}
17 }
18 
19 void
20 pcmd(Io *f, Tree *t)
21 {
22 	if(t==0)
23 		return;
24 
25 	switch(t->type){
26 	default:	pfmt(f, "bad %d %p %p %p", t->type, c0, c1, c2); break;
27 	case '$':	pfmt(f, "$%t", c0); break;
28 	case '"':	pfmt(f, "$\"%t", c0); break;
29 	case '&':	pfmt(f, "%t&", c0); break;
30 	case '^':	pfmt(f, "%t^%t", c0, c1); break;
31 	case '`':	pfmt(f, "`%t", c0); break;
32 	case ANDAND:	pfmt(f, "%t && %t", c0, c1); break;
33 	case ARGLIST:	pfmt(f, "%t %t", c0, c1); break;
34 	case BANG:	pfmt(f, "! %t", c0); break;
35 	case BRACE:	pfmt(f, "{%t}", c0); break;
36 	case COUNT:	pfmt(f, "$#%t", c0); break;
37 	case FN:	pfmt(f, "fn %t %t", c0, c1); break;
38 	case IF:	pfmt(f, "if%t%t", c0, c1); break;
39 	case NOT:	pfmt(f, "if not %t", c0); break;
40 	case OROR:	pfmt(f, "%t || %t", c0, c1); break;
41 	case PCMD:
42 	case PAREN:	pfmt(f, "(%t)", c0); break;
43 	case SUB:	pfmt(f, "$%t(%t)", c0, c1); break;
44 	case SIMPLE:	pfmt(f, "%t", c0); break;
45 	case SUBSHELL:	pfmt(f, "@ %t", c0); break;
46 	case SWITCH:	pfmt(f, "switch %t %t", c0, c1); break;
47 	case TWIDDLE:	pfmt(f, "~ %t %t", c0, c1); break;
48 	case WHILE:	pfmt(f, "while %t%t", c0, c1); break;
49 	case ';':
50 		if(c0){
51 			if(c1) pfmt(f, "%t%c%t", c0, nl, c1);
52 			else pfmt(f, "%t", c0);
53 		}
54 		else pfmt(f, "%t", c1);
55 		break;
56 	case WORDS:
57 		if(c0) pfmt(f, "%t ", c0);
58 		pfmt(f, "%t", c1);
59 		break;
60 	case FOR:
61 		pfmt(f, "for(%t", c0);
62 		if(c1) pfmt(f, " in %t", c1);
63 		pfmt(f, ")%t", c2);
64 		break;
65 	case WORD:
66 		if(t->quoted) pfmt(f, "%Q", t->str);
67 		else pdeglob(f, t->str);
68 		break;
69 	case DUP:
70 		pfmt(f, ">[%d=", t->fd0);
71 		if(t->rtype==DUPFD)
72 			pfmt(f, "%d", t->fd1);
73 		/* else t->rtype == CLOSE */
74 		pchr(f, ']');
75 		break;
76 	case PIPEFD:
77 	case REDIR:
78 		switch(t->rtype){
79 		case HERE:
80 			pchr(f, '<');
81 		case READ:
82 			pchr(f, '<');
83 			if(t->fd0!=0)
84 				pfmt(f, "[%d]", t->fd0);
85 			break;
86 		case APPEND:
87 			pchr(f, '>');
88 		case WRITE:
89 			pchr(f, '>');
90 			if(t->fd0!=1)
91 				pfmt(f, "[%d]", t->fd0);
92 			break;
93 		}
94 		pfmt(f, "%t", c0);
95 		if(c1) pfmt(f, " %t", c1);
96 		break;
97 	case '=':
98 		pfmt(f, "%t=%t", c0, c1);
99 		if(c2) pfmt(f, " %t", c2);
100 		break;
101 	case PIPE:
102 		pfmt(f, "%t|", c0);
103 		if(t->fd1==0){
104 			if(t->fd0!=1) pfmt(f, "[%d]", t->fd0);
105 		}
106 		else pfmt(f, "[%d=%d]", t->fd0, t->fd1);
107 		pfmt(f, "%t", c1);
108 		break;
109 	}
110 }
111