home *** CD-ROM | disk | FTP | other *** search
- /*-
- * Copyright (c) 1991 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Kenneth Almquist.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
- #ifndef lint
- static char sccsid[] = "@(#)show.c 5.2 (Berkeley) 4/12/91";
- #endif /* not lint */
-
- #include <stdio.h>
- #include "shell.h"
- #include "parser.h"
- #include "nodes.h"
- #include "mystring.h"
-
-
- #ifdef DEBUG
- static shtree(), shcmd(), sharg(), indent();
-
-
- showtree(n)
- union node *n;
- {
- trputs("showtree called\n");
- shtree(n, 1, NULL, stdout);
- }
-
-
- static
- shtree(n, ind, pfx, fp)
- union node *n;
- char *pfx;
- FILE *fp;
- {
- struct nodelist *lp;
- char *s;
-
- indent(ind, pfx, fp);
- switch(n->type) {
- case NSEMI:
- s = "; ";
- goto binop;
- case NAND:
- s = " && ";
- goto binop;
- case NOR:
- s = " || ";
- binop:
- shtree(n->nbinary.ch1, ind, NULL, fp);
- /* if (ind < 0) */
- fputs(s, fp);
- shtree(n->nbinary.ch2, ind, NULL, fp);
- break;
- case NCMD:
- shcmd(n, fp);
- if (ind >= 0)
- putc('\n', fp);
- break;
- case NPIPE:
- for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) {
- shcmd(lp->n, fp);
- if (lp->next)
- fputs(" | ", fp);
- }
- if (n->npipe.backgnd)
- fputs(" &", fp);
- if (ind >= 0)
- putc('\n', fp);
- break;
- default:
- fprintf(fp, "<node type %d>", n->type);
- if (ind >= 0)
- putc('\n', fp);
- break;
- }
- }
-
-
-
- static
- shcmd(cmd, fp)
- union node *cmd;
- FILE *fp;
- {
- union node *np;
- int first;
- char *s;
- int dftfd;
-
- first = 1;
- for (np = cmd->ncmd.args ; np ; np = np->narg.next) {
- if (! first)
- putchar(' ');
- sharg(np, fp);
- first = 0;
- }
- for (np = cmd->ncmd.redirect ; np ; np = np->nfile.next) {
- if (! first)
- putchar(' ');
- switch (np->nfile.type) {
- case NTO: s = ">"; dftfd = 1; break;
- case NAPPEND: s = ">>"; dftfd = 1; break;
- case NTOFD: s = ">&"; dftfd = 1; break;
- case NFROM: s = "<"; dftfd = 0; break;
- case NFROMFD: s = "<&"; dftfd = 0; break;
- }
- if (np->nfile.fd != dftfd)
- fprintf(fp, "%d", np->nfile.fd);
- fputs(s, fp);
- if (np->nfile.type == NTOFD || np->nfile.type == NFROMFD) {
- fprintf(fp, "%d", np->ndup.dupfd);
- } else {
- sharg(np->nfile.fname, fp);
- }
- first = 0;
- }
- }
-
-
-
- static
- sharg(arg, fp)
- union node *arg;
- FILE *fp;
- {
- char *p;
- struct nodelist *bqlist;
- int subtype;
-
- if (arg->type != NARG) {
- printf("<node type %d>\n", arg->type);
- fflush(stdout);
- abort();
- }
- bqlist = arg->narg.backquote;
- for (p = arg->narg.text ; *p ; p++) {
- switch (*p) {
- case CTLESC:
- putc(*++p, fp);
- break;
- case CTLVAR:
- putc('$', fp);
- putc('{', fp);
- subtype = *++p;
- while (*p != '=')
- putc(*p++, fp);
- if (subtype & VSNUL)
- putc(':', fp);
- switch (subtype & VSTYPE) {
- case VSNORMAL:
- putc('}', fp);
- break;
- case VSMINUS:
- putc('-', fp);
- break;
- case VSPLUS:
- putc('+', fp);
- break;
- case VSQUESTION:
- putc('?', fp);
- break;
- case VSASSIGN:
- putc('=', fp);
- break;
- default:
- printf("<subtype %d>", subtype);
- }
- break;
- case CTLENDVAR:
- putc('}', fp);
- break;
- case CTLBACKQ:
- case CTLBACKQ|CTLQUOTE:
- putc('$', fp);
- putc('(', fp);
- shtree(bqlist->n, -1, NULL, fp);
- putc(')', fp);
- break;
- default:
- putc(*p, fp);
- break;
- }
- }
- }
-
-
- static
- indent(amount, pfx, fp)
- char *pfx;
- FILE *fp;
- {
- int i;
-
- for (i = 0 ; i < amount ; i++) {
- if (pfx && i == amount - 1)
- fputs(pfx, fp);
- putc('\t', fp);
- }
- }
- #endif
-
-
-
- /*
- * Debugging stuff.
- */
-
-
- FILE *tracefile;
-
- #if DEBUG == 2
- int debug = 1;
- #else
- int debug = 0;
- #endif
-
-
- trputc(c) {
- #ifdef DEBUG
- if (tracefile == NULL)
- return;
- putc(c, tracefile);
- if (c == '\n')
- fflush(tracefile);
- #endif
- }
-
-
- trace(fmt, a1, a2, a3, a4, a5, a6, a7, a8)
- char *fmt;
- {
- #ifdef DEBUG
- if (tracefile == NULL)
- return;
- fprintf(tracefile, fmt, a1, a2, a3, a4, a5, a6, a7, a8);
- if (strchr(fmt, '\n'))
- fflush(tracefile);
- #endif
- }
-
-
- trputs(s)
- char *s;
- {
- #ifdef DEBUG
- if (tracefile == NULL)
- return;
- fputs(s, tracefile);
- if (strchr(s, '\n'))
- fflush(tracefile);
- #endif
- }
-
-
- trstring(s)
- char *s;
- {
- register char *p;
- char c;
-
- #ifdef DEBUG
- if (tracefile == NULL)
- return;
- putc('"', tracefile);
- for (p = s ; *p ; p++) {
- switch (*p) {
- case '\n': c = 'n'; goto backslash;
- case '\t': c = 't'; goto backslash;
- case '\r': c = 'r'; goto backslash;
- case '"': c = '"'; goto backslash;
- case '\\': c = '\\'; goto backslash;
- case CTLESC: c = 'e'; goto backslash;
- case CTLVAR: c = 'v'; goto backslash;
- case CTLVAR+CTLQUOTE: c = 'V'; goto backslash;
- case CTLBACKQ: c = 'q'; goto backslash;
- case CTLBACKQ+CTLQUOTE: c = 'Q'; goto backslash;
- backslash: putc('\\', tracefile);
- putc(c, tracefile);
- break;
- default:
- if (*p >= ' ' && *p <= '~')
- putc(*p, tracefile);
- else {
- putc('\\', tracefile);
- putc(*p >> 6 & 03, tracefile);
- putc(*p >> 3 & 07, tracefile);
- putc(*p & 07, tracefile);
- }
- break;
- }
- }
- putc('"', tracefile);
- #endif
- }
-
-
- trargs(ap)
- char **ap;
- {
- #ifdef DEBUG
- if (tracefile == NULL)
- return;
- while (*ap) {
- trstring(*ap++);
- if (*ap)
- putc(' ', tracefile);
- else
- putc('\n', tracefile);
- }
- fflush(tracefile);
- #endif
- }
-
-
- opentrace() {
- char s[100];
- char *p;
- char *getenv();
- int flags;
-
- #ifdef DEBUG
- if (!debug)
- return;
- if ((p = getenv("HOME")) == NULL) {
- if (getuid() == 0)
- p = "/";
- else
- p = "/tmp";
- }
- scopy(p, s);
- strcat(s, "/trace");
- if ((tracefile = fopen(s, "a")) == NULL) {
- fprintf(stderr, "Can't open %s\n", s);
- return;
- }
- #ifdef O_APPEND
- if ((flags = fcntl(fileno(tracefile), F_GETFL, 0)) >= 0)
- fcntl(fileno(tracefile), F_SETFL, flags | O_APPEND);
- #endif
- fputs("\nTracing started.\n", tracefile);
- fflush(tracefile);
- #endif
- }
-