BSD 4_4_Lite2 release
[unix-history] / usr / src / bin / sh / show.c
CommitLineData
a9f0b747 1/*-
8276a8e2
KB
2 * Copyright (c) 1991, 1993
3 * The Regents of the University of California. All rights reserved.
a9f0b747
KB
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Kenneth Almquist.
7 *
ad787160
C
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
a9f0b747
KB
35 */
36
37#ifndef lint
fd88f5c5 38static char sccsid[] = "@(#)show.c 8.3 (Berkeley) 5/4/95";
a9f0b747
KB
39#endif /* not lint */
40
41#include <stdio.h>
13b3e634
CZ
42#if __STDC__
43#include <stdarg.h>
44#else
45#include <varargs.h>
46#endif
47
a9f0b747
KB
48#include "shell.h"
49#include "parser.h"
50#include "nodes.h"
51#include "mystring.h"
13b3e634 52#include "show.h"
a9f0b747
KB
53
54
55#ifdef DEBUG
13b3e634
CZ
56static void shtree __P((union node *, int, char *, FILE*));
57static void shcmd __P((union node *, FILE *));
58static void sharg __P((union node *, FILE *));
59static void indent __P((int, char *, FILE *));
60static void trstring __P((char *));
a9f0b747
KB
61
62
13b3e634 63void
a9f0b747
KB
64showtree(n)
65 union node *n;
13b3e634 66{
a9f0b747
KB
67 trputs("showtree called\n");
68 shtree(n, 1, NULL, stdout);
69}
70
71
13b3e634 72static void
a9f0b747
KB
73shtree(n, ind, pfx, fp)
74 union node *n;
13b3e634 75 int ind;
a9f0b747
KB
76 char *pfx;
77 FILE *fp;
13b3e634 78{
a9f0b747
KB
79 struct nodelist *lp;
80 char *s;
81
17f6a06f
KB
82 if (n == NULL)
83 return;
84
a9f0b747
KB
85 indent(ind, pfx, fp);
86 switch(n->type) {
87 case NSEMI:
88 s = "; ";
89 goto binop;
90 case NAND:
91 s = " && ";
92 goto binop;
93 case NOR:
94 s = " || ";
95binop:
96 shtree(n->nbinary.ch1, ind, NULL, fp);
97 /* if (ind < 0) */
98 fputs(s, fp);
99 shtree(n->nbinary.ch2, ind, NULL, fp);
100 break;
101 case NCMD:
102 shcmd(n, fp);
103 if (ind >= 0)
104 putc('\n', fp);
105 break;
106 case NPIPE:
107 for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) {
108 shcmd(lp->n, fp);
109 if (lp->next)
110 fputs(" | ", fp);
111 }
112 if (n->npipe.backgnd)
113 fputs(" &", fp);
114 if (ind >= 0)
115 putc('\n', fp);
116 break;
117 default:
118 fprintf(fp, "<node type %d>", n->type);
119 if (ind >= 0)
120 putc('\n', fp);
121 break;
122 }
123}
124
125
126
13b3e634 127static void
a9f0b747
KB
128shcmd(cmd, fp)
129 union node *cmd;
130 FILE *fp;
13b3e634 131{
a9f0b747
KB
132 union node *np;
133 int first;
134 char *s;
135 int dftfd;
136
137 first = 1;
138 for (np = cmd->ncmd.args ; np ; np = np->narg.next) {
139 if (! first)
140 putchar(' ');
141 sharg(np, fp);
142 first = 0;
143 }
144 for (np = cmd->ncmd.redirect ; np ; np = np->nfile.next) {
145 if (! first)
146 putchar(' ');
147 switch (np->nfile.type) {
148 case NTO: s = ">"; dftfd = 1; break;
149 case NAPPEND: s = ">>"; dftfd = 1; break;
150 case NTOFD: s = ">&"; dftfd = 1; break;
151 case NFROM: s = "<"; dftfd = 0; break;
152 case NFROMFD: s = "<&"; dftfd = 0; break;
13b3e634 153 default: s = "*error*"; dftfd = 0; break;
a9f0b747
KB
154 }
155 if (np->nfile.fd != dftfd)
156 fprintf(fp, "%d", np->nfile.fd);
157 fputs(s, fp);
158 if (np->nfile.type == NTOFD || np->nfile.type == NFROMFD) {
159 fprintf(fp, "%d", np->ndup.dupfd);
160 } else {
161 sharg(np->nfile.fname, fp);
162 }
163 first = 0;
164 }
165}
166
167
168
13b3e634 169static void
a9f0b747
KB
170sharg(arg, fp)
171 union node *arg;
172 FILE *fp;
173 {
174 char *p;
175 struct nodelist *bqlist;
176 int subtype;
177
178 if (arg->type != NARG) {
179 printf("<node type %d>\n", arg->type);
180 fflush(stdout);
181 abort();
182 }
183 bqlist = arg->narg.backquote;
184 for (p = arg->narg.text ; *p ; p++) {
185 switch (*p) {
186 case CTLESC:
187 putc(*++p, fp);
188 break;
189 case CTLVAR:
190 putc('$', fp);
191 putc('{', fp);
192 subtype = *++p;
17f6a06f
KB
193 if (subtype == VSLENGTH)
194 putc('#', fp);
195
a9f0b747
KB
196 while (*p != '=')
197 putc(*p++, fp);
17f6a06f 198
a9f0b747
KB
199 if (subtype & VSNUL)
200 putc(':', fp);
17f6a06f 201
a9f0b747
KB
202 switch (subtype & VSTYPE) {
203 case VSNORMAL:
204 putc('}', fp);
205 break;
206 case VSMINUS:
207 putc('-', fp);
208 break;
209 case VSPLUS:
210 putc('+', fp);
211 break;
212 case VSQUESTION:
213 putc('?', fp);
214 break;
215 case VSASSIGN:
216 putc('=', fp);
217 break;
17f6a06f
KB
218 case VSTRIMLEFT:
219 putc('#', fp);
220 break;
221 case VSTRIMLEFTMAX:
222 putc('#', fp);
223 putc('#', fp);
224 break;
225 case VSTRIMRIGHT:
226 putc('%', fp);
227 break;
228 case VSTRIMRIGHTMAX:
229 putc('%', fp);
230 putc('%', fp);
231 break;
232 case VSLENGTH:
233 break;
a9f0b747
KB
234 default:
235 printf("<subtype %d>", subtype);
236 }
237 break;
238 case CTLENDVAR:
239 putc('}', fp);
240 break;
241 case CTLBACKQ:
242 case CTLBACKQ|CTLQUOTE:
243 putc('$', fp);
244 putc('(', fp);
245 shtree(bqlist->n, -1, NULL, fp);
246 putc(')', fp);
247 break;
248 default:
249 putc(*p, fp);
250 break;
251 }
252 }
253}
254
255
13b3e634 256static void
a9f0b747 257indent(amount, pfx, fp)
13b3e634 258 int amount;
a9f0b747
KB
259 char *pfx;
260 FILE *fp;
13b3e634 261{
a9f0b747
KB
262 int i;
263
264 for (i = 0 ; i < amount ; i++) {
265 if (pfx && i == amount - 1)
266 fputs(pfx, fp);
267 putc('\t', fp);
268 }
269}
270#endif
271
272
273
274/*
275 * Debugging stuff.
276 */
277
278
279FILE *tracefile;
280
44c32b7a
MT
281#if DEBUG == 2
282int debug = 1;
283#else
284int debug = 0;
285#endif
a9f0b747
KB
286
287
13b3e634
CZ
288void
289trputc(c)
290 int c;
291{
a9f0b747
KB
292#ifdef DEBUG
293 if (tracefile == NULL)
294 return;
295 putc(c, tracefile);
296 if (c == '\n')
297 fflush(tracefile);
298#endif
299}
300
13b3e634
CZ
301void
302#if __STDC__
303trace(const char *fmt, ...)
304#else
305trace(va_alist)
306 va_dcl
307#endif
308{
a9f0b747 309#ifdef DEBUG
13b3e634
CZ
310 va_list va;
311#if __STDC__
312 va_start(va, fmt);
313#else
314 char *fmt;
315 va_start(va);
316 fmt = va_arg(va, char *);
317#endif
318 if (tracefile != NULL) {
319 (void) vfprintf(tracefile, fmt, va);
320 if (strchr(fmt, '\n'))
321 (void) fflush(tracefile);
322 }
323 va_end(va);
a9f0b747
KB
324#endif
325}
326
327
13b3e634 328void
a9f0b747
KB
329trputs(s)
330 char *s;
13b3e634 331{
a9f0b747
KB
332#ifdef DEBUG
333 if (tracefile == NULL)
334 return;
335 fputs(s, tracefile);
336 if (strchr(s, '\n'))
337 fflush(tracefile);
338#endif
339}
340
341
13b3e634 342static void
a9f0b747
KB
343trstring(s)
344 char *s;
13b3e634 345{
a9f0b747
KB
346 register char *p;
347 char c;
348
349#ifdef DEBUG
350 if (tracefile == NULL)
351 return;
352 putc('"', tracefile);
353 for (p = s ; *p ; p++) {
354 switch (*p) {
355 case '\n': c = 'n'; goto backslash;
356 case '\t': c = 't'; goto backslash;
357 case '\r': c = 'r'; goto backslash;
358 case '"': c = '"'; goto backslash;
359 case '\\': c = '\\'; goto backslash;
360 case CTLESC: c = 'e'; goto backslash;
361 case CTLVAR: c = 'v'; goto backslash;
362 case CTLVAR+CTLQUOTE: c = 'V'; goto backslash;
363 case CTLBACKQ: c = 'q'; goto backslash;
364 case CTLBACKQ+CTLQUOTE: c = 'Q'; goto backslash;
365backslash: putc('\\', tracefile);
366 putc(c, tracefile);
367 break;
368 default:
369 if (*p >= ' ' && *p <= '~')
370 putc(*p, tracefile);
371 else {
372 putc('\\', tracefile);
373 putc(*p >> 6 & 03, tracefile);
374 putc(*p >> 3 & 07, tracefile);
375 putc(*p & 07, tracefile);
376 }
377 break;
378 }
379 }
380 putc('"', tracefile);
381#endif
382}
383
384
13b3e634 385void
a9f0b747
KB
386trargs(ap)
387 char **ap;
13b3e634 388{
a9f0b747
KB
389#ifdef DEBUG
390 if (tracefile == NULL)
391 return;
392 while (*ap) {
393 trstring(*ap++);
394 if (*ap)
395 putc(' ', tracefile);
396 else
397 putc('\n', tracefile);
398 }
399 fflush(tracefile);
400#endif
401}
402
403
13b3e634 404void
a9f0b747
KB
405opentrace() {
406 char s[100];
a9f0b747 407 char *getenv();
13b3e634 408#ifdef O_APPEND
a9f0b747 409 int flags;
13b3e634 410#endif
a9f0b747
KB
411
412#ifdef DEBUG
44c32b7a
MT
413 if (!debug)
414 return;
e2bf5c64 415#ifdef not_this_way
13b3e634
CZ
416 {
417 char *p;
418 if ((p = getenv("HOME")) == NULL) {
419 if (geteuid() == 0)
420 p = "/";
421 else
422 p = "/tmp";
423 }
424 scopy(p, s);
425 strcat(s, "/trace");
44c32b7a 426 }
e2bf5c64
MT
427#else
428 scopy("./trace", s);
429#endif /* not_this_way */
a9f0b747
KB
430 if ((tracefile = fopen(s, "a")) == NULL) {
431 fprintf(stderr, "Can't open %s\n", s);
44c32b7a 432 return;
a9f0b747
KB
433 }
434#ifdef O_APPEND
435 if ((flags = fcntl(fileno(tracefile), F_GETFL, 0)) >= 0)
436 fcntl(fileno(tracefile), F_SETFL, flags | O_APPEND);
437#endif
438 fputs("\nTracing started.\n", tracefile);
439 fflush(tracefile);
e2bf5c64 440#endif /* DEBUG */
a9f0b747 441}