source: mainline/uspace/app/ash/show.c@ 8ccd2ea

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 8ccd2ea was c28a023, checked in by Josef Cejka <malyzelenyhnus@…>, 17 years ago

Initial commit of ash shell.
It cannot be compiled yet.

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