home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / bin / sh / show.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-15  |  7.2 KB  |  375 lines

  1. /*-
  2.  * Copyright (c) 1991 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * This code is derived from software contributed to Berkeley by
  6.  * Kenneth Almquist.
  7.  *
  8.  * Redistribution and use in source and binary forms, with or without
  9.  * modification, are permitted provided that the following conditions
  10.  * are met:
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer.
  13.  * 2. Redistributions in binary form must reproduce the above copyright
  14.  *    notice, this list of conditions and the following disclaimer in the
  15.  *    documentation and/or other materials provided with the distribution.
  16.  * 3. All advertising materials mentioning features or use of this software
  17.  *    must display the following acknowledgement:
  18.  *    This product includes software developed by the University of
  19.  *    California, Berkeley and its contributors.
  20.  * 4. Neither the name of the University nor the names of its contributors
  21.  *    may be used to endorse or promote products derived from this software
  22.  *    without specific prior written permission.
  23.  *
  24.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  25.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  26.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  27.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  28.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  29.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  30.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  31.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  32.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  33.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  34.  * SUCH DAMAGE.
  35.  */
  36.  
  37. #ifndef lint
  38. static char sccsid[] = "@(#)show.c    5.2 (Berkeley) 4/12/91";
  39. #endif /* not lint */
  40.  
  41. #include <stdio.h>
  42. #include "shell.h"
  43. #include "parser.h"
  44. #include "nodes.h"
  45. #include "mystring.h"
  46.  
  47.  
  48. #ifdef DEBUG
  49. static shtree(), shcmd(), sharg(), indent();
  50.  
  51.  
  52. showtree(n)
  53.     union node *n;
  54.     {
  55.     trputs("showtree called\n");
  56.     shtree(n, 1, NULL, stdout);
  57. }
  58.  
  59.  
  60. static
  61. shtree(n, ind, pfx, fp)
  62.     union node *n;
  63.     char *pfx;
  64.     FILE *fp;
  65.     {
  66.     struct nodelist *lp;
  67.     char *s;
  68.  
  69.     indent(ind, pfx, fp);
  70.     switch(n->type) {
  71.     case NSEMI:
  72.         s = "; ";
  73.         goto binop;
  74.     case NAND:
  75.         s = " && ";
  76.         goto binop;
  77.     case NOR:
  78.         s = " || ";
  79. binop:
  80.         shtree(n->nbinary.ch1, ind, NULL, fp);
  81.        /*    if (ind < 0) */
  82.             fputs(s, fp);
  83.         shtree(n->nbinary.ch2, ind, NULL, fp);
  84.         break;
  85.     case NCMD:
  86.         shcmd(n, fp);
  87.         if (ind >= 0)
  88.             putc('\n', fp);
  89.         break;
  90.     case NPIPE:
  91.         for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) {
  92.             shcmd(lp->n, fp);
  93.             if (lp->next)
  94.                 fputs(" | ", fp);
  95.         }
  96.         if (n->npipe.backgnd)
  97.             fputs(" &", fp);
  98.         if (ind >= 0)
  99.             putc('\n', fp);
  100.         break;
  101.     default:
  102.         fprintf(fp, "<node type %d>", n->type);
  103.         if (ind >= 0)
  104.             putc('\n', fp);
  105.         break;
  106.     }
  107. }
  108.  
  109.  
  110.  
  111. static
  112. shcmd(cmd, fp)
  113.     union node *cmd;
  114.     FILE *fp;
  115.     {
  116.     union node *np;
  117.     int first;
  118.     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 NAPPEND:    s = ">>"; dftfd = 1; break;
  134.             case NTOFD:    s = ">&"; dftfd = 1; break;
  135.             case NFROM:    s = "<";  dftfd = 0; break;
  136.             case NFROMFD:    s = "<&"; dftfd = 0; break;
  137.         }
  138.         if (np->nfile.fd != dftfd)
  139.             fprintf(fp, "%d", np->nfile.fd);
  140.         fputs(s, fp);
  141.         if (np->nfile.type == NTOFD || np->nfile.type == NFROMFD) {
  142.             fprintf(fp, "%d", np->ndup.dupfd);
  143.         } else {
  144.             sharg(np->nfile.fname, fp);
  145.         }
  146.         first = 0;
  147.     }
  148. }
  149.  
  150.  
  151.  
  152. static
  153. sharg(arg, fp)
  154.     union node *arg;
  155.     FILE *fp;
  156.     {
  157.     char *p;
  158.     struct nodelist *bqlist;
  159.     int subtype;
  160.  
  161.     if (arg->type != NARG) {
  162.         printf("<node type %d>\n", arg->type);
  163.         fflush(stdout);
  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.             while (*p != '=')
  177.                 putc(*p++, fp);
  178.             if (subtype & VSNUL)
  179.                 putc(':', fp);
  180.             switch (subtype & VSTYPE) {
  181.             case VSNORMAL:
  182.                 putc('}', fp);
  183.                 break;
  184.             case VSMINUS:
  185.                 putc('-', fp);
  186.                 break;
  187.             case VSPLUS:
  188.                 putc('+', fp);
  189.                 break;
  190.             case VSQUESTION:
  191.                 putc('?', fp);
  192.                 break;
  193.             case VSASSIGN:
  194.                 putc('=', fp);
  195.                 break;
  196.             default:
  197.                 printf("<subtype %d>", subtype);
  198.             }
  199.             break;
  200.         case CTLENDVAR:
  201.              putc('}', fp);
  202.              break;
  203.         case CTLBACKQ:
  204.         case CTLBACKQ|CTLQUOTE:
  205.             putc('$', fp);
  206.             putc('(', fp);
  207.             shtree(bqlist->n, -1, NULL, fp);
  208.             putc(')', fp);
  209.             break;
  210.         default:
  211.             putc(*p, fp);
  212.             break;
  213.         }
  214.     }
  215. }
  216.  
  217.  
  218. static
  219. indent(amount, pfx, fp)
  220.     char *pfx;
  221.     FILE *fp;
  222.     {
  223.     int i;
  224.  
  225.     for (i = 0 ; i < amount ; i++) {
  226.         if (pfx && i == amount - 1)
  227.             fputs(pfx, fp);
  228.         putc('\t', fp);
  229.     }
  230. }
  231. #endif
  232.  
  233.  
  234.  
  235. /*
  236.  * Debugging stuff.
  237.  */
  238.  
  239.  
  240. FILE *tracefile;
  241.  
  242. #if DEBUG == 2
  243. int debug = 1;
  244. #else
  245. int debug = 0;
  246. #endif
  247.  
  248.  
  249. trputc(c) {
  250. #ifdef DEBUG
  251.     if (tracefile == NULL)
  252.         return;
  253.     putc(c, tracefile);
  254.     if (c == '\n')
  255.         fflush(tracefile);
  256. #endif
  257. }
  258.  
  259.  
  260. trace(fmt, a1, a2, a3, a4, a5, a6, a7, a8)
  261.     char *fmt;
  262.     {
  263. #ifdef DEBUG
  264.     if (tracefile == NULL)
  265.         return;
  266.     fprintf(tracefile, fmt, a1, a2, a3, a4, a5, a6, a7, a8);
  267.     if (strchr(fmt, '\n'))
  268.         fflush(tracefile);
  269. #endif
  270. }
  271.  
  272.  
  273. trputs(s)
  274.     char *s;
  275.     {
  276. #ifdef DEBUG
  277.     if (tracefile == NULL)
  278.         return;
  279.     fputs(s, tracefile);
  280.     if (strchr(s, '\n'))
  281.         fflush(tracefile);
  282. #endif
  283. }
  284.  
  285.  
  286. trstring(s)
  287.     char *s;
  288.     {
  289.     register char *p;
  290.     char c;
  291.  
  292. #ifdef DEBUG
  293.     if (tracefile == NULL)
  294.         return;
  295.     putc('"', tracefile);
  296.     for (p = s ; *p ; p++) {
  297.         switch (*p) {
  298.         case '\n':  c = 'n';  goto backslash;
  299.         case '\t':  c = 't';  goto backslash;
  300.         case '\r':  c = 'r';  goto backslash;
  301.         case '"':  c = '"';  goto backslash;
  302.         case '\\':  c = '\\';  goto backslash;
  303.         case CTLESC:  c = 'e';  goto backslash;
  304.         case CTLVAR:  c = 'v';  goto backslash;
  305.         case CTLVAR+CTLQUOTE:  c = 'V';  goto backslash;
  306.         case CTLBACKQ:  c = 'q';  goto backslash;
  307.         case CTLBACKQ+CTLQUOTE:  c = 'Q';  goto backslash;
  308. backslash:      putc('\\', tracefile);
  309.             putc(c, tracefile);
  310.             break;
  311.         default:
  312.             if (*p >= ' ' && *p <= '~')
  313.                 putc(*p, tracefile);
  314.             else {
  315.                 putc('\\', tracefile);
  316.                 putc(*p >> 6 & 03, tracefile);
  317.                 putc(*p >> 3 & 07, tracefile);
  318.                 putc(*p & 07, tracefile);
  319.             }
  320.             break;
  321.         }
  322.     }
  323.     putc('"', tracefile);
  324. #endif
  325. }
  326.  
  327.  
  328. trargs(ap)
  329.     char **ap;
  330.     {
  331. #ifdef DEBUG
  332.     if (tracefile == NULL)
  333.         return;
  334.     while (*ap) {
  335.         trstring(*ap++);
  336.         if (*ap)
  337.             putc(' ', tracefile);
  338.         else
  339.             putc('\n', tracefile);
  340.     }
  341.     fflush(tracefile);
  342. #endif
  343. }
  344.  
  345.  
  346. opentrace() {
  347.     char s[100];
  348.     char *p;
  349.     char *getenv();
  350.     int flags;
  351.  
  352. #ifdef DEBUG
  353.     if (!debug)
  354.         return;
  355.     if ((p = getenv("HOME")) == NULL) {
  356.         if (getuid() == 0)
  357.             p = "/";
  358.         else
  359.             p = "/tmp";
  360.     }
  361.     scopy(p, s);
  362.     strcat(s, "/trace");
  363.     if ((tracefile = fopen(s, "a")) == NULL) {
  364.         fprintf(stderr, "Can't open %s\n", s);
  365.         return;
  366.     }
  367. #ifdef O_APPEND
  368.     if ((flags = fcntl(fileno(tracefile), F_GETFL, 0)) >= 0)
  369.         fcntl(fileno(tracefile), F_SETFL, flags | O_APPEND);
  370. #endif
  371.     fputs("\nTracing started.\n", tracefile);
  372.     fflush(tracefile);
  373. #endif
  374. }
  375.