Subversion Repositories HelenOS

Rev

Rev 2714 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2714 cejka 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
42
static 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
63
static void shtree (union node *, int, char *, FILE*);
64
static void shcmd (union node *, FILE *);
65
static void sharg (union node *, FILE *);
66
static void indent (int, char *, FILE *);
67
static void trstring (char *);
68
 
69
 
70
void
71
showtree(n)
72
    union node *n;
73
{
74
    trputs("showtree called\n");
75
    shtree(n, 1, NULL, stdout);
76
}
77
 
78
 
79
static void
80
shtree(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 = " || ";
102
binop:
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
 
134
static void
135
shcmd(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
 
178
static void
179
sharg(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
 
265
static void
266
indent(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
 
288
FILE *tracefile;
289
 
290
#if DEBUG == 2
291
int debug = 1;
292
#else
293
int debug = 0;
294
#endif
295
 
296
 
297
#ifdef DEBUG
298
void
299
trputc(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
 
310
void
311
#ifdef __STDC__
312
trace(const char *fmt, ...)
313
#else
314
trace(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
338
void
339
trputs(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
 
350
static void
351
trstring(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;
372
backslash:    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
 
392
void
393
trargs(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
412
void
413
opentrace() {
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 */