Logo Search packages:      
Sourcecode: dash version File versions

show.c

/*    $NetBSD: show.c,v 1.24 2003/01/22 20:36:04 dsl Exp $  */

/*-
 * Copyright (c) 1991, 1993
 *    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.
 */

#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)show.c  8.3 (Berkeley) 5/4/95";
#else
__RCSID("$NetBSD: show.c,v 1.24 2003/01/22 20:36:04 dsl Exp $");
#endif
#endif /* not lint */

#include <stdio.h>
#include <stdarg.h>

#include "shell.h"
#include "parser.h"
#include "nodes.h"
#include "mystring.h"
#include "show.h"
#include "options.h"


#ifdef DEBUG
static void shtree(union node *, int, char *, FILE*);
static void shcmd(union node *, FILE *);
static void sharg(union node *, FILE *);
static void indent(int, char *, FILE *);
static void trstring(char *);


void
showtree(union node *n)
{
      trputs("showtree called\n");
      shtree(n, 1, NULL, stdout);
}


static void
shtree(union node *n, int ind, char *pfx, FILE *fp)
{
      struct nodelist *lp;
      const char *s;

      if (n == NULL)
            return;

      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 void
shcmd(union node *cmd, FILE *fp)
{
      union node *np;
      int first;
      const 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 NCLOBBER:    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;
                  case NFROMTO:     s = "<>"; dftfd = 0; break;
                  default:    s = "*error*"; 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 void
sharg(union node *arg, FILE *fp)
{
      char *p;
      struct nodelist *bqlist;
      int subtype;

      if (arg->type != NARG) {
            printf("<node type %d>\n", arg->type);
            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;
                  if (subtype == VSLENGTH)
                        putc('#', fp);

                  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;
                  case VSTRIMLEFT:
                        putc('#', fp);
                        break;
                  case VSTRIMLEFTMAX:
                        putc('#', fp);
                        putc('#', fp);
                        break;
                  case VSTRIMRIGHT:
                        putc('%', fp);
                        break;
                  case VSTRIMRIGHTMAX:
                        putc('%', fp);
                        putc('%', fp);
                        break;
                  case VSLENGTH:
                        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 void
indent(int amount, char *pfx, FILE *fp)
{
      int i;

      for (i = 0 ; i < amount ; i++) {
            if (pfx && i == amount - 1)
                  fputs(pfx, fp);
            putc('\t', fp);
      }
}



/*
 * Debugging stuff.
 */


FILE *tracefile;


void
trputc(int c)
{
      if (debug != 1)
            return;
      putc(c, tracefile);
}

void
trace(const char *fmt, ...)
{
      va_list va;

      if (debug != 1)
            return;
      va_start(va, fmt);
      (void) vfprintf(tracefile, fmt, va);
      va_end(va);
}

void
tracev(const char *fmt, va_list va)
{
      if (debug != 1)
            return;
      (void) vfprintf(tracefile, fmt, va);
}


void
trputs(const char *s)
{
      if (debug != 1)
            return;
      fputs(s, tracefile);
}


static void
trstring(char *s)
{
      char *p;
      char c;

      if (debug != 1)
            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);
}


void
trargs(char **ap)
{
      if (debug != 1)
            return;
      while (*ap) {
            trstring(*ap++);
            if (*ap)
                  putc(' ', tracefile);
            else
                  putc('\n', tracefile);
      }
}


void
opentrace(void)
{
      char s[100];
#ifdef O_APPEND
      int flags;
#endif

      if (debug != 1) {
            if (tracefile)
                  fflush(tracefile);
            /* leave open because libedit might be using it */
            return;
      }
#ifdef not_this_way
      {
            char *p;
            if ((p = getenv(homestr)) == NULL) {
                  if (geteuid() == 0)
                        p = "/";
                  else
                        p = "/tmp";
            }
            scopy(p, s);
            strcat(s, "/trace");
      }
#else
      scopy("./trace", s);
#endif /* not_this_way */
      if (tracefile) {
            if (!freopen(s, "a", tracefile)) {
                  fprintf(stderr, "Can't re-open %s\n", s);
                  debug = 0;
                  return;
            }
      } else {
            if ((tracefile = fopen(s, "a")) == NULL) {
                  fprintf(stderr, "Can't open %s\n", s);
                  debug = 0;
                  return;
            }
      }
#ifdef O_APPEND
      if ((flags = fcntl(fileno(tracefile), F_GETFL, 0)) >= 0)
            fcntl(fileno(tracefile), F_SETFL, flags | O_APPEND);
#endif
      setlinebuf(tracefile);
      fputs("\nTracing started.\n", tracefile);
}
#endif /* DEBUG */

Generated by  Doxygen 1.6.0   Back to index