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

« back to all changes in this revision

Viewing changes to dash/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
/*-
 
2
 * Copyright (c) 1991, 1993
 
3
 *      The Regents of the University of California.  All rights reserved.
 
4
 * Copyright (c) 1997-2005
 
5
 *      Herbert Xu <herbert@gondor.apana.org.au>.  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
#include <stdio.h>
 
36
#include <stdarg.h>
 
37
 
 
38
#include "shell.h"
 
39
#include "parser.h"
 
40
#include "nodes.h"
 
41
#include "mystring.h"
 
42
#include "show.h"
 
43
#include "options.h"
 
44
 
 
45
 
 
46
#ifdef DEBUG
 
47
static void shtree(union node *, int, char *, FILE*);
 
48
static void shcmd(union node *, FILE *);
 
49
static void sharg(union node *, FILE *);
 
50
static void indent(int, char *, FILE *);
 
51
static void trstring(char *);
 
52
 
 
53
 
 
54
void
 
55
showtree(union node *n)
 
56
{
 
57
        trputs("showtree called\n");
 
58
        shtree(n, 1, NULL, stdout);
 
59
}
 
60
 
 
61
 
 
62
static void
 
63
shtree(union node *n, int ind, char *pfx, FILE *fp)
 
64
{
 
65
        struct nodelist *lp;
 
66
        const char *s;
 
67
 
 
68
        if (n == NULL)
 
69
                return;
 
70
 
 
71
        indent(ind, pfx, fp);
 
72
        switch(n->type) {
 
73
        case NSEMI:
 
74
                s = "; ";
 
75
                goto binop;
 
76
        case NAND:
 
77
                s = " && ";
 
78
                goto binop;
 
79
        case NOR:
 
80
                s = " || ";
 
81
binop:
 
82
                shtree(n->nbinary.ch1, ind, NULL, fp);
 
83
           /*    if (ind < 0) */
 
84
                        fputs(s, fp);
 
85
                shtree(n->nbinary.ch2, ind, NULL, fp);
 
86
                break;
 
87
        case NCMD:
 
88
                shcmd(n, fp);
 
89
                if (ind >= 0)
 
90
                        putc('\n', fp);
 
91
                break;
 
92
        case NPIPE:
 
93
                for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) {
 
94
                        shcmd(lp->n, fp);
 
95
                        if (lp->next)
 
96
                                fputs(" | ", fp);
 
97
                }
 
98
                if (n->npipe.backgnd)
 
99
                        fputs(" &", fp);
 
100
                if (ind >= 0)
 
101
                        putc('\n', fp);
 
102
                break;
 
103
        default:
 
104
                fprintf(fp, "<node type %d>", n->type);
 
105
                if (ind >= 0)
 
106
                        putc('\n', fp);
 
107
                break;
 
108
        }
 
109
}
 
110
 
 
111
 
 
112
 
 
113
static void
 
114
shcmd(union node *cmd, FILE *fp)
 
115
{
 
116
        union node *np;
 
117
        int first;
 
118
        const char *s;
 
119
        int dftfd;
 
120
 
 
121
        first = 1;
 
122
        for (np = cmd->ncmd.args ; np ; np = np->narg.next) {
 
123
                if (! first)
 
124
                        putchar(' ');
 
125
                sharg(np, fp);
 
126
                first = 0;
 
127
        }
 
128
        for (np = cmd->ncmd.redirect ; np ; np = np->nfile.next) {
 
129
                if (! first)
 
130
                        putchar(' ');
 
131
                switch (np->nfile.type) {
 
132
                        case NTO:       s = ">";  dftfd = 1; break;
 
133
                        case NCLOBBER:  s = ">|"; dftfd = 1; break;
 
134
                        case NAPPEND:   s = ">>"; dftfd = 1; break;
 
135
                        case NTOFD:     s = ">&"; dftfd = 1; break;
 
136
                        case NFROM:     s = "<";  dftfd = 0; break;
 
137
                        case NFROMFD:   s = "<&"; dftfd = 0; break;
 
138
                        case NFROMTO:   s = "<>"; dftfd = 0; break;
 
139
                        default:        s = "*error*"; dftfd = 0; break;
 
140
                }
 
141
                if (np->nfile.fd != dftfd)
 
142
                        fprintf(fp, "%d", np->nfile.fd);
 
143
                fputs(s, fp);
 
144
                if (np->nfile.type == NTOFD || np->nfile.type == NFROMFD) {
 
145
                        fprintf(fp, "%d", np->ndup.dupfd);
 
146
                } else {
 
147
                        sharg(np->nfile.fname, fp);
 
148
                }
 
149
                first = 0;
 
150
        }
 
151
}
 
152
 
 
153
 
 
154
 
 
155
static void
 
156
sharg(union node *arg, FILE *fp)
 
157
{
 
158
        char *p;
 
159
        struct nodelist *bqlist;
 
160
        int subtype;
 
161
 
 
162
        if (arg->type != NARG) {
 
163
                printf("<node type %d>\n", arg->type);
 
164
                abort();
 
165
        }
 
166
        bqlist = arg->narg.backquote;
 
167
        for (p = arg->narg.text ; *p ; p++) {
 
168
                switch (*p) {
 
169
                case CTLESC:
 
170
                        putc(*++p, fp);
 
171
                        break;
 
172
                case CTLVAR:
 
173
                        putc('$', fp);
 
174
                        putc('{', fp);
 
175
                        subtype = *++p;
 
176
                        if (subtype == VSLENGTH)
 
177
                                putc('#', fp);
 
178
 
 
179
                        while (*p != '=')
 
180
                                putc(*p++, fp);
 
181
 
 
182
                        if (subtype & VSNUL)
 
183
                                putc(':', fp);
 
184
 
 
185
                        switch (subtype & VSTYPE) {
 
186
                        case VSNORMAL:
 
187
                                putc('}', fp);
 
188
                                break;
 
189
                        case VSMINUS:
 
190
                                putc('-', fp);
 
191
                                break;
 
192
                        case VSPLUS:
 
193
                                putc('+', fp);
 
194
                                break;
 
195
                        case VSQUESTION:
 
196
                                putc('?', fp);
 
197
                                break;
 
198
                        case VSASSIGN:
 
199
                                putc('=', fp);
 
200
                                break;
 
201
                        case VSTRIMLEFT:
 
202
                                putc('#', fp);
 
203
                                break;
 
204
                        case VSTRIMLEFTMAX:
 
205
                                putc('#', fp);
 
206
                                putc('#', fp);
 
207
                                break;
 
208
                        case VSTRIMRIGHT:
 
209
                                putc('%', fp);
 
210
                                break;
 
211
                        case VSTRIMRIGHTMAX:
 
212
                                putc('%', fp);
 
213
                                putc('%', fp);
 
214
                                break;
 
215
                        case VSLENGTH:
 
216
                                break;
 
217
                        default:
 
218
                                printf("<subtype %d>", subtype);
 
219
                        }
 
220
                        break;
 
221
                case CTLENDVAR:
 
222
                     putc('}', fp);
 
223
                     break;
 
224
                case CTLBACKQ:
 
225
                case CTLBACKQ|CTLQUOTE:
 
226
                        putc('$', fp);
 
227
                        putc('(', fp);
 
228
                        shtree(bqlist->n, -1, NULL, fp);
 
229
                        putc(')', fp);
 
230
                        break;
 
231
                default:
 
232
                        putc(*p, fp);
 
233
                        break;
 
234
                }
 
235
        }
 
236
}
 
237
 
 
238
 
 
239
static void
 
240
indent(int amount, char *pfx, FILE *fp)
 
241
{
 
242
        int i;
 
243
 
 
244
        for (i = 0 ; i < amount ; i++) {
 
245
                if (pfx && i == amount - 1)
 
246
                        fputs(pfx, fp);
 
247
                putc('\t', fp);
 
248
        }
 
249
}
 
250
 
 
251
 
 
252
 
 
253
/*
 
254
 * Debugging stuff.
 
255
 */
 
256
 
 
257
 
 
258
FILE *tracefile;
 
259
 
 
260
 
 
261
void
 
262
trputc(int c)
 
263
{
 
264
        if (debug != 1)
 
265
                return;
 
266
        putc(c, tracefile);
 
267
}
 
268
 
 
269
void
 
270
trace(const char *fmt, ...)
 
271
{
 
272
        va_list va;
 
273
 
 
274
        if (debug != 1)
 
275
                return;
 
276
        va_start(va, fmt);
 
277
        (void) vfprintf(tracefile, fmt, va);
 
278
        va_end(va);
 
279
}
 
280
 
 
281
void
 
282
tracev(const char *fmt, va_list va)
 
283
{
 
284
        if (debug != 1)
 
285
                return;
 
286
        (void) vfprintf(tracefile, fmt, va);
 
287
}
 
288
 
 
289
 
 
290
void
 
291
trputs(const char *s)
 
292
{
 
293
        if (debug != 1)
 
294
                return;
 
295
        fputs(s, tracefile);
 
296
}
 
297
 
 
298
 
 
299
static void
 
300
trstring(char *s)
 
301
{
 
302
        char *p;
 
303
        char c;
 
304
 
 
305
        if (debug != 1)
 
306
                return;
 
307
        putc('"', tracefile);
 
308
        for (p = s ; *p ; p++) {
 
309
                switch (*p) {
 
310
                case '\n':  c = 'n';  goto backslash;
 
311
                case '\t':  c = 't';  goto backslash;
 
312
                case '\r':  c = 'r';  goto backslash;
 
313
                case '"':  c = '"';  goto backslash;
 
314
                case '\\':  c = '\\';  goto backslash;
 
315
                case CTLESC:  c = 'e';  goto backslash;
 
316
                case CTLVAR:  c = 'v';  goto backslash;
 
317
                case CTLVAR+CTLQUOTE:  c = 'V';  goto backslash;
 
318
                case CTLBACKQ:  c = 'q';  goto backslash;
 
319
                case CTLBACKQ+CTLQUOTE:  c = 'Q';  goto backslash;
 
320
backslash:        putc('\\', tracefile);
 
321
                        putc(c, tracefile);
 
322
                        break;
 
323
                default:
 
324
                        if (*p >= ' ' && *p <= '~')
 
325
                                putc(*p, tracefile);
 
326
                        else {
 
327
                                putc('\\', tracefile);
 
328
                                putc(*p >> 6 & 03, tracefile);
 
329
                                putc(*p >> 3 & 07, tracefile);
 
330
                                putc(*p & 07, tracefile);
 
331
                        }
 
332
                        break;
 
333
                }
 
334
        }
 
335
        putc('"', tracefile);
 
336
}
 
337
 
 
338
 
 
339
void
 
340
trargs(char **ap)
 
341
{
 
342
        if (debug != 1)
 
343
                return;
 
344
        while (*ap) {
 
345
                trstring(*ap++);
 
346
                if (*ap)
 
347
                        putc(' ', tracefile);
 
348
                else
 
349
                        putc('\n', tracefile);
 
350
        }
 
351
}
 
352
 
 
353
 
 
354
void
 
355
opentrace(void)
 
356
{
 
357
        char s[100];
 
358
#ifdef O_APPEND
 
359
        int flags;
 
360
#endif
 
361
 
 
362
        if (debug != 1) {
 
363
                if (tracefile)
 
364
                        fflush(tracefile);
 
365
                /* leave open because libedit might be using it */
 
366
                return;
 
367
        }
 
368
#ifdef not_this_way
 
369
        {
 
370
                char *p;
 
371
                if ((p = getenv(homestr)) == NULL) {
 
372
                        if (geteuid() == 0)
 
373
                                p = "/";
 
374
                        else
 
375
                                p = "/tmp";
 
376
                }
 
377
                scopy(p, s);
 
378
                strcat(s, "/trace");
 
379
        }
 
380
#else
 
381
        scopy("./trace", s);
 
382
#endif /* not_this_way */
 
383
        if (tracefile) {
 
384
                if (!freopen(s, "a", tracefile)) {
 
385
                        fprintf(stderr, "Can't re-open %s\n", s);
 
386
                        debug = 0;
 
387
                        return;
 
388
                }
 
389
        } else {
 
390
                if ((tracefile = fopen(s, "a")) == NULL) {
 
391
                        fprintf(stderr, "Can't open %s\n", s);
 
392
                        debug = 0;
 
393
                        return;
 
394
                }
 
395
        }
 
396
#ifdef O_APPEND
 
397
        if ((flags = fcntl(fileno(tracefile), F_GETFL, 0)) >= 0)
 
398
                fcntl(fileno(tracefile), F_SETFL, flags | O_APPEND);
 
399
#endif
 
400
        setlinebuf(tracefile);
 
401
        fputs("\nTracing started.\n", tracefile);
 
402
}
 
403
#endif /* DEBUG */