Magellan Linux

Annotation of /trunk/mkinitrd-magellan/klibc/usr/dash/show.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1122 - (hide annotations) (download)
Wed Aug 18 21:11:40 2010 UTC (13 years, 8 months ago) by niro
File MIME type: text/plain
File size: 7904 byte(s)
-updated to klibc-1.5.19
1 niro 532 /*-
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 ((signed char)*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     putc('$', fp);
226     putc('(', fp);
227     shtree(bqlist->n, -1, NULL, fp);
228     putc(')', fp);
229     break;
230     default:
231     putc(*p, fp);
232     break;
233     }
234     }
235     }
236    
237    
238     static void
239     indent(int amount, char *pfx, FILE *fp)
240     {
241     int i;
242    
243     for (i = 0 ; i < amount ; i++) {
244     if (pfx && i == amount - 1)
245     fputs(pfx, fp);
246     putc('\t', fp);
247     }
248     }
249    
250    
251    
252     /*
253     * Debugging stuff.
254     */
255    
256    
257     FILE *tracefile;
258    
259    
260     void
261     trputc(int c)
262     {
263     if (debug != 1)
264     return;
265     putc(c, tracefile);
266     }
267    
268     void
269     trace(const char *fmt, ...)
270     {
271     va_list va;
272    
273     if (debug != 1)
274     return;
275     va_start(va, fmt);
276     (void) vfprintf(tracefile, fmt, va);
277     va_end(va);
278     }
279    
280     void
281     tracev(const char *fmt, va_list va)
282     {
283     if (debug != 1)
284     return;
285     (void) vfprintf(tracefile, fmt, va);
286     }
287    
288    
289     void
290     trputs(const char *s)
291     {
292     if (debug != 1)
293     return;
294     fputs(s, tracefile);
295     }
296    
297    
298     static void
299     trstring(char *s)
300     {
301     char *p;
302     char c;
303    
304     if (debug != 1)
305     return;
306     putc('"', tracefile);
307     for (p = s ; *p ; p++) {
308     switch ((signed char)*p) {
309     case '\n': c = 'n'; goto backslash;
310     case '\t': c = 't'; goto backslash;
311     case '\r': c = 'r'; goto backslash;
312     case '"': c = '"'; goto backslash;
313     case '\\': c = '\\'; goto backslash;
314     case CTLESC: c = 'e'; goto backslash;
315     case CTLVAR: c = 'v'; goto backslash;
316     case CTLBACKQ: c = 'q'; goto backslash;
317     backslash: putc('\\', tracefile);
318     putc(c, tracefile);
319     break;
320     default:
321     if (*p >= ' ' && *p <= '~')
322     putc(*p, tracefile);
323     else {
324     putc('\\', tracefile);
325     putc(*p >> 6 & 03, tracefile);
326     putc(*p >> 3 & 07, tracefile);
327     putc(*p & 07, tracefile);
328     }
329     break;
330     }
331     }
332     putc('"', tracefile);
333     }
334    
335    
336     void
337     trargs(char **ap)
338     {
339     if (debug != 1)
340     return;
341     while (*ap) {
342     trstring(*ap++);
343     if (*ap)
344     putc(' ', tracefile);
345     else
346     putc('\n', tracefile);
347     }
348     }
349    
350    
351     void
352     opentrace(void)
353     {
354     char s[100];
355     #ifdef O_APPEND
356     int flags;
357     #endif
358    
359     if (debug != 1) {
360     if (tracefile)
361     fflush(tracefile);
362     /* leave open because libedit might be using it */
363     return;
364     }
365     #ifdef not_this_way
366     {
367     char *p;
368     if ((p = getenv(homestr)) == NULL) {
369     if (geteuid() == 0)
370     p = "/";
371     else
372     p = "/tmp";
373     }
374     scopy(p, s);
375     strcat(s, "/trace");
376     }
377     #else
378     scopy("./trace", s);
379     #endif /* not_this_way */
380     if (tracefile) {
381     if (!freopen(s, "a", tracefile)) {
382     fprintf(stderr, "Can't re-open %s\n", s);
383     debug = 0;
384     return;
385     }
386     } else {
387     if ((tracefile = fopen(s, "a")) == NULL) {
388     fprintf(stderr, "Can't open %s\n", s);
389     debug = 0;
390     return;
391     }
392     }
393     #ifdef O_APPEND
394     if ((flags = fcntl(fileno(tracefile), F_GETFL, 0)) >= 0)
395     fcntl(fileno(tracefile), F_SETFL, flags | O_APPEND);
396     #endif
397     setlinebuf(tracefile);
398     fputs("\nTracing started.\n", tracefile);
399     }
400     #endif /* DEBUG */