Commit | Line | Data |
---|---|---|
a9f0b747 KB |
1 | /*- |
2 | * Copyright (c) 1991 The Regents of the University of California. | |
3 | * All rights reserved. | |
4 | * | |
5 | * This code is derived from software contributed to Berkeley by | |
6 | * Kenneth Almquist. | |
7 | * | |
8 | * %sccs.include.redist.c% | |
9 | */ | |
10 | ||
11 | #ifndef lint | |
44c32b7a | 12 | static char sccsid[] = "@(#)show.c 5.2 (Berkeley) %G%"; |
a9f0b747 KB |
13 | #endif /* not lint */ |
14 | ||
15 | #include <stdio.h> | |
16 | #include "shell.h" | |
17 | #include "parser.h" | |
18 | #include "nodes.h" | |
19 | #include "mystring.h" | |
20 | ||
21 | ||
22 | #ifdef DEBUG | |
23 | static shtree(), shcmd(), sharg(), indent(); | |
24 | ||
25 | ||
26 | showtree(n) | |
27 | union node *n; | |
28 | { | |
29 | trputs("showtree called\n"); | |
30 | shtree(n, 1, NULL, stdout); | |
31 | } | |
32 | ||
33 | ||
34 | static | |
35 | shtree(n, ind, pfx, fp) | |
36 | union node *n; | |
37 | char *pfx; | |
38 | FILE *fp; | |
39 | { | |
40 | struct nodelist *lp; | |
41 | char *s; | |
42 | ||
43 | indent(ind, pfx, fp); | |
44 | switch(n->type) { | |
45 | case NSEMI: | |
46 | s = "; "; | |
47 | goto binop; | |
48 | case NAND: | |
49 | s = " && "; | |
50 | goto binop; | |
51 | case NOR: | |
52 | s = " || "; | |
53 | binop: | |
54 | shtree(n->nbinary.ch1, ind, NULL, fp); | |
55 | /* if (ind < 0) */ | |
56 | fputs(s, fp); | |
57 | shtree(n->nbinary.ch2, ind, NULL, fp); | |
58 | break; | |
59 | case NCMD: | |
60 | shcmd(n, fp); | |
61 | if (ind >= 0) | |
62 | putc('\n', fp); | |
63 | break; | |
64 | case NPIPE: | |
65 | for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) { | |
66 | shcmd(lp->n, fp); | |
67 | if (lp->next) | |
68 | fputs(" | ", fp); | |
69 | } | |
70 | if (n->npipe.backgnd) | |
71 | fputs(" &", fp); | |
72 | if (ind >= 0) | |
73 | putc('\n', fp); | |
74 | break; | |
75 | default: | |
76 | fprintf(fp, "<node type %d>", n->type); | |
77 | if (ind >= 0) | |
78 | putc('\n', fp); | |
79 | break; | |
80 | } | |
81 | } | |
82 | ||
83 | ||
84 | ||
85 | static | |
86 | shcmd(cmd, fp) | |
87 | union node *cmd; | |
88 | FILE *fp; | |
89 | { | |
90 | union node *np; | |
91 | int first; | |
92 | char *s; | |
93 | int dftfd; | |
94 | ||
95 | first = 1; | |
96 | for (np = cmd->ncmd.args ; np ; np = np->narg.next) { | |
97 | if (! first) | |
98 | putchar(' '); | |
99 | sharg(np, fp); | |
100 | first = 0; | |
101 | } | |
102 | for (np = cmd->ncmd.redirect ; np ; np = np->nfile.next) { | |
103 | if (! first) | |
104 | putchar(' '); | |
105 | switch (np->nfile.type) { | |
106 | case NTO: s = ">"; dftfd = 1; break; | |
107 | case NAPPEND: s = ">>"; dftfd = 1; break; | |
108 | case NTOFD: s = ">&"; dftfd = 1; break; | |
109 | case NFROM: s = "<"; dftfd = 0; break; | |
110 | case NFROMFD: s = "<&"; dftfd = 0; break; | |
111 | } | |
112 | if (np->nfile.fd != dftfd) | |
113 | fprintf(fp, "%d", np->nfile.fd); | |
114 | fputs(s, fp); | |
115 | if (np->nfile.type == NTOFD || np->nfile.type == NFROMFD) { | |
116 | fprintf(fp, "%d", np->ndup.dupfd); | |
117 | } else { | |
118 | sharg(np->nfile.fname, fp); | |
119 | } | |
120 | first = 0; | |
121 | } | |
122 | } | |
123 | ||
124 | ||
125 | ||
126 | static | |
127 | sharg(arg, fp) | |
128 | union node *arg; | |
129 | FILE *fp; | |
130 | { | |
131 | char *p; | |
132 | struct nodelist *bqlist; | |
133 | int subtype; | |
134 | ||
135 | if (arg->type != NARG) { | |
136 | printf("<node type %d>\n", arg->type); | |
137 | fflush(stdout); | |
138 | abort(); | |
139 | } | |
140 | bqlist = arg->narg.backquote; | |
141 | for (p = arg->narg.text ; *p ; p++) { | |
142 | switch (*p) { | |
143 | case CTLESC: | |
144 | putc(*++p, fp); | |
145 | break; | |
146 | case CTLVAR: | |
147 | putc('$', fp); | |
148 | putc('{', fp); | |
149 | subtype = *++p; | |
150 | while (*p != '=') | |
151 | putc(*p++, fp); | |
152 | if (subtype & VSNUL) | |
153 | putc(':', fp); | |
154 | switch (subtype & VSTYPE) { | |
155 | case VSNORMAL: | |
156 | putc('}', fp); | |
157 | break; | |
158 | case VSMINUS: | |
159 | putc('-', fp); | |
160 | break; | |
161 | case VSPLUS: | |
162 | putc('+', fp); | |
163 | break; | |
164 | case VSQUESTION: | |
165 | putc('?', fp); | |
166 | break; | |
167 | case VSASSIGN: | |
168 | putc('=', fp); | |
169 | break; | |
170 | default: | |
171 | printf("<subtype %d>", subtype); | |
172 | } | |
173 | break; | |
174 | case CTLENDVAR: | |
175 | putc('}', fp); | |
176 | break; | |
177 | case CTLBACKQ: | |
178 | case CTLBACKQ|CTLQUOTE: | |
179 | putc('$', fp); | |
180 | putc('(', fp); | |
181 | shtree(bqlist->n, -1, NULL, fp); | |
182 | putc(')', fp); | |
183 | break; | |
184 | default: | |
185 | putc(*p, fp); | |
186 | break; | |
187 | } | |
188 | } | |
189 | } | |
190 | ||
191 | ||
192 | static | |
193 | indent(amount, pfx, fp) | |
194 | char *pfx; | |
195 | FILE *fp; | |
196 | { | |
197 | int i; | |
198 | ||
199 | for (i = 0 ; i < amount ; i++) { | |
200 | if (pfx && i == amount - 1) | |
201 | fputs(pfx, fp); | |
202 | putc('\t', fp); | |
203 | } | |
204 | } | |
205 | #endif | |
206 | ||
207 | ||
208 | ||
209 | /* | |
210 | * Debugging stuff. | |
211 | */ | |
212 | ||
213 | ||
214 | FILE *tracefile; | |
215 | ||
44c32b7a MT |
216 | #if DEBUG == 2 |
217 | int debug = 1; | |
218 | #else | |
219 | int debug = 0; | |
220 | #endif | |
a9f0b747 KB |
221 | |
222 | ||
223 | trputc(c) { | |
224 | #ifdef DEBUG | |
225 | if (tracefile == NULL) | |
226 | return; | |
227 | putc(c, tracefile); | |
228 | if (c == '\n') | |
229 | fflush(tracefile); | |
230 | #endif | |
231 | } | |
232 | ||
233 | ||
234 | trace(fmt, a1, a2, a3, a4, a5, a6, a7, a8) | |
235 | char *fmt; | |
236 | { | |
237 | #ifdef DEBUG | |
238 | if (tracefile == NULL) | |
239 | return; | |
240 | fprintf(tracefile, fmt, a1, a2, a3, a4, a5, a6, a7, a8); | |
241 | if (strchr(fmt, '\n')) | |
242 | fflush(tracefile); | |
243 | #endif | |
244 | } | |
245 | ||
246 | ||
247 | trputs(s) | |
248 | char *s; | |
249 | { | |
250 | #ifdef DEBUG | |
251 | if (tracefile == NULL) | |
252 | return; | |
253 | fputs(s, tracefile); | |
254 | if (strchr(s, '\n')) | |
255 | fflush(tracefile); | |
256 | #endif | |
257 | } | |
258 | ||
259 | ||
260 | trstring(s) | |
261 | char *s; | |
262 | { | |
263 | register char *p; | |
264 | char c; | |
265 | ||
266 | #ifdef DEBUG | |
267 | if (tracefile == NULL) | |
268 | return; | |
269 | putc('"', tracefile); | |
270 | for (p = s ; *p ; p++) { | |
271 | switch (*p) { | |
272 | case '\n': c = 'n'; goto backslash; | |
273 | case '\t': c = 't'; goto backslash; | |
274 | case '\r': c = 'r'; goto backslash; | |
275 | case '"': c = '"'; goto backslash; | |
276 | case '\\': c = '\\'; goto backslash; | |
277 | case CTLESC: c = 'e'; goto backslash; | |
278 | case CTLVAR: c = 'v'; goto backslash; | |
279 | case CTLVAR+CTLQUOTE: c = 'V'; goto backslash; | |
280 | case CTLBACKQ: c = 'q'; goto backslash; | |
281 | case CTLBACKQ+CTLQUOTE: c = 'Q'; goto backslash; | |
282 | backslash: putc('\\', tracefile); | |
283 | putc(c, tracefile); | |
284 | break; | |
285 | default: | |
286 | if (*p >= ' ' && *p <= '~') | |
287 | putc(*p, tracefile); | |
288 | else { | |
289 | putc('\\', tracefile); | |
290 | putc(*p >> 6 & 03, tracefile); | |
291 | putc(*p >> 3 & 07, tracefile); | |
292 | putc(*p & 07, tracefile); | |
293 | } | |
294 | break; | |
295 | } | |
296 | } | |
297 | putc('"', tracefile); | |
298 | #endif | |
299 | } | |
300 | ||
301 | ||
302 | trargs(ap) | |
303 | char **ap; | |
304 | { | |
305 | #ifdef DEBUG | |
306 | if (tracefile == NULL) | |
307 | return; | |
308 | while (*ap) { | |
309 | trstring(*ap++); | |
310 | if (*ap) | |
311 | putc(' ', tracefile); | |
312 | else | |
313 | putc('\n', tracefile); | |
314 | } | |
315 | fflush(tracefile); | |
316 | #endif | |
317 | } | |
318 | ||
319 | ||
320 | opentrace() { | |
321 | char s[100]; | |
322 | char *p; | |
323 | char *getenv(); | |
324 | int flags; | |
325 | ||
326 | #ifdef DEBUG | |
44c32b7a MT |
327 | if (!debug) |
328 | return; | |
329 | if ((p = getenv("HOME")) == NULL) { | |
330 | if (getuid() == 0) | |
331 | p = "/"; | |
332 | else | |
333 | p = "/tmp"; | |
334 | } | |
a9f0b747 KB |
335 | scopy(p, s); |
336 | strcat(s, "/trace"); | |
337 | if ((tracefile = fopen(s, "a")) == NULL) { | |
338 | fprintf(stderr, "Can't open %s\n", s); | |
44c32b7a | 339 | return; |
a9f0b747 KB |
340 | } |
341 | #ifdef O_APPEND | |
342 | if ((flags = fcntl(fileno(tracefile), F_GETFL, 0)) >= 0) | |
343 | fcntl(fileno(tracefile), F_SETFL, flags | O_APPEND); | |
344 | #endif | |
345 | fputs("\nTracing started.\n", tracefile); | |
346 | fflush(tracefile); | |
347 | #endif | |
348 | } |