~ubuntu-branches/ubuntu/hardy/klibc/hardy-updates

« back to all changes in this revision

Viewing changes to ash/show.c

  • Committer: Bazaar Package Importer
  • Author(s): Jeff Bailey
  • Date: 2006-01-04 20:24:52 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20060104202452-ec4v3n829rymukuv
Tags: 1.1.15-0ubuntu1
* New upstream version.

* Patch to fix compilation on parisc64 kernels.

Show diffs side-by-side

added added

removed removed

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