xref: /plan9/sys/src/cmd/rc/pcmd.c (revision 4e3613ab15c331a9ada113286cc0f2a35bc0373d)
1 #include "rc.h"
2 #include "io.h"
3 #include "fns.h"
4 char nl='\n';		/* change to semicolon for bourne-proofing */
5 #define	c0	t->child[0]
6 #define	c1	t->child[1]
7 #define	c2	t->child[2]
8 
9 void
pdeglob(io * f,char * s)10 pdeglob(io *f, char *s)
11 {
12 	while(*s){
13 		if(*s==GLOB)
14 			s++;
15 		pchr(f, *s++);
16 	}
17 }
18 
19 void
pcmd(io * f,tree * t)20 pcmd(io *f, tree *t)
21 {
22 	if(t==0)
23 		return;
24 	assert(f != nil);
25 	switch(t->type){
26 	default:	pfmt(f, "bad cmd %d %p %p %p", t->type, c0, c1, c2);
27 	break;
28 	case '$':	pfmt(f, "$%t", c0);
29 	break;
30 	case '"':	pfmt(f, "$\"%t", c0);
31 	break;
32 	case '&':	pfmt(f, "%t&", c0);
33 	break;
34 	case '^':	pfmt(f, "%t^%t", c0, c1);
35 	break;
36 	case '`':	pfmt(f, "`%t", c0);
37 	break;
38 	case ANDAND:	pfmt(f, "%t && %t", c0, c1);
39 	break;
40 	case BANG:	pfmt(f, "! %t", c0);
41 	break;
42 	case BRACE:	pfmt(f, "{%t}", c0);
43 	break;
44 	case COUNT:	pfmt(f, "$#%t", c0);
45 	break;
46 	case FN:	pfmt(f, "fn %t %t", c0, c1);
47 	break;
48 	case IF:	pfmt(f, "if%t%t", c0, c1);
49 	break;
50 	case NOT:	pfmt(f, "if not %t", c0);
51 	break;
52 	case OROR:	pfmt(f, "%t || %t", c0, c1);
53 	break;
54 	case PCMD:
55 	case PAREN:	pfmt(f, "(%t)", c0);
56 	break;
57 	case SUB:	pfmt(f, "$%t(%t)", c0, c1);
58 	break;
59 	case SIMPLE:	pfmt(f, "%t", c0);
60 	break;
61 	case SUBSHELL:	pfmt(f, "@ %t", c0);
62 	break;
63 	case SWITCH:	pfmt(f, "switch %t %t", c0, c1);
64 	break;
65 	case TWIDDLE:	pfmt(f, "~ %t %t", c0, c1);
66 	break;
67 	case WHILE:	pfmt(f, "while %t%t", c0, c1);
68 	break;
69 	case ARGLIST:
70 		if(c0==0)
71 			pfmt(f, "%t", c1);
72 		else if(c1==0)
73 			pfmt(f, "%t", c0);
74 		else
75 			pfmt(f, "%t %t", c0, c1);
76 		break;
77 	case ';':
78 		if(c0){
79 			if(c1)
80 				pfmt(f, "%t%c%t", c0, nl, c1);
81 			else pfmt(f, "%t", c0);
82 		}
83 		else pfmt(f, "%t", c1);
84 		break;
85 	case WORDS:
86 		if(c0)
87 			pfmt(f, "%t ", c0);
88 		pfmt(f, "%t", c1);
89 		break;
90 	case FOR:
91 		pfmt(f, "for(%t", c0);
92 		if(c1)
93 			pfmt(f, " in %t", c1);
94 		pfmt(f, ")%t", c2);
95 		break;
96 	case WORD:
97 		if(t->quoted)
98 			pfmt(f, "%Q", t->str);
99 		else pdeglob(f, t->str);
100 		break;
101 	case DUP:
102 		if(t->rtype==DUPFD)
103 			pfmt(f, ">[%d=%d]", t->fd1, t->fd0); /* yes, fd1, then fd0; read lex.c */
104 		else
105 			pfmt(f, ">[%d=]", t->fd0);
106 		pfmt(f, "%t", c1);
107 		break;
108 	case PIPEFD:
109 	case REDIR:
110 		switch(t->rtype){
111 		case HERE:
112 			pchr(f, '<');
113 		case READ:
114 		case RDWR:
115 			pchr(f, '<');
116 			if(t->rtype==RDWR)
117 				pchr(f, '>');
118 			if(t->fd0!=0)
119 				pfmt(f, "[%d]", t->fd0);
120 			break;
121 		case APPEND:
122 			pchr(f, '>');
123 		case WRITE:
124 			pchr(f, '>');
125 			if(t->fd0!=1)
126 				pfmt(f, "[%d]", t->fd0);
127 			break;
128 		}
129 		pfmt(f, "%t", c0);
130 		if(c1)
131 			pfmt(f, " %t", c1);
132 		break;
133 	case '=':
134 		pfmt(f, "%t=%t", c0, c1);
135 		if(c2)
136 			pfmt(f, " %t", c2);
137 		break;
138 	case PIPE:
139 		pfmt(f, "%t|", c0);
140 		if(t->fd1==0){
141 			if(t->fd0!=1)
142 				pfmt(f, "[%d]", t->fd0);
143 		}
144 		else pfmt(f, "[%d=%d]", t->fd0, t->fd1);
145 		pfmt(f, "%t", c1);
146 		break;
147 	}
148 }
149