home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / AP / ASH / ASH-LINU.2 / ASH-LINU / ash-linux-0.2 / show.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-24  |  7.3 KB  |  376 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[] = "from: @(#)show.c    5.2 (Berkeley) 4/12/91";*/
  39. static char rcsid[] = "show.c,v 1.4 1993/08/01 18:58:00 mycroft Exp";
  40. #endif /* not lint */
  41.  
  42. #include <stdio.h>
  43. #include "shell.h"
  44. #include "parser.h"
  45. #include "nodes.h"
  46. #include "mystring.h"
  47.  
  48.  
  49. #ifdef DEBUG
  50. static shtree(), shcmd(), sharg(), indent();
  51.  
  52.  
  53. showtree(n)
  54.     union node *n;
  55.     {
  56.     trputs("showtree called\n");
  57.     shtree(n, 1, NULL, stdout);
  58. }
  59.  
  60.  
  61. static
  62. shtree(n, ind, pfx, fp)
  63.     union node *n;
  64.     char *pfx;
  65.     FILE *fp;
  66.     {
  67.     struct nodelist *lp;
  68.     char *s;
  69.  
  70.     indent(ind, pfx, fp);
  71.     switch(n->type) {
  72.     case NSEMI:
  73.         s = "; ";
  74.         goto binop;
  75.     case NAND:
  76.         s = " && ";
  77.         goto binop;
  78.     case NOR:
  79.         s = " || ";
  80. binop:
  81.         shtree(n->nbinary.ch1, ind, NULL, fp);
  82.        /*    if (ind < 0) */
  83.             fputs(s, fp);
  84.         shtree(n->nbinary.ch2, ind, NULL, fp);
  85.         break;
  86.     case NCMD:
  87.         shcmd(n, fp);
  88.         if (ind >= 0)
  89.             putc('\n', fp);
  90.         break;
  91.     case NPIPE:
  92.         for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) {
  93.             shcmd(lp->n, fp);
  94.             if (lp->next)
  95.                 fputs(" | ", fp);
  96.         }
  97.         if (n->npipe.backgnd)
  98.             fputs(" &", fp);
  99.         if (ind >= 0)
  100.             putc('\n', fp);
  101.         break;
  102.     default:
  103.         fprintf(fp, "<node type %d>", n->type);
  104.         if (ind >= 0)
  105.             putc('\n', fp);
  106.         break;
  107.     }
  108. }
  109.  
  110.  
  111.  
  112. static
  113. shcmd(cmd, fp)
  114.     union node *cmd;
  115.     FILE *fp;
  116.     {
  117.     union node *np;
  118.     int first;
  119.     char *s;
  120.     int dftfd;
  121.  
  122.     first = 1;
  123.     for (np = cmd->ncmd.args ; np ; np = np->narg.next) {
  124.         if (! first)
  125.             putchar(' ');
  126.         sharg(np, fp);
  127.         first = 0;
  128.     }
  129.     for (np = cmd->ncmd.redirect ; np ; np = np->nfile.next) {
  130.         if (! first)
  131.             putchar(' ');
  132.         switch (np->nfile.type) {
  133.             case NTO:    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.         }
  139.         if (np->nfile.fd != dftfd)
  140.             fprintf(fp, "%d", np->nfile.fd);
  141.         fputs(s, fp);
  142.         if (np->nfile.type == NTOFD || np->nfile.type == NFROMFD) {
  143.             fprintf(fp, "%d", np->ndup.dupfd);
  144.         } else {
  145.             sharg(np->nfile.fname, fp);
  146.         }
  147.         first = 0;
  148.     }
  149. }
  150.  
  151.  
  152.  
  153. static
  154. sharg(arg, fp)
  155.     union node *arg;
  156.     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.         fflush(stdout);
  165.         abort();
  166.     }
  167.     bqlist = arg->narg.backquote;
  168.     for (p = arg->narg.text ; *p ; p++) {
  169.         switch (*p) {
  170.         case CTLESC:
  171.             putc(*++p, fp);
  172.             break;
  173.         case CTLVAR:
  174.             putc('$', fp);
  175.             putc('{', fp);
  176.             subtype = *++p;
  177.             while (*p != '=')
  178.                 putc(*p++, fp);
  179.             if (subtype & VSNUL)
  180.                 putc(':', fp);
  181.             switch (subtype & VSTYPE) {
  182.             case VSNORMAL:
  183.                 putc('}', fp);
  184.                 break;
  185.             case VSMINUS:
  186.                 putc('-', fp);
  187.                 break;
  188.             case VSPLUS:
  189.                 putc('+', fp);
  190.                 break;
  191.             case VSQUESTION:
  192.                 putc('?', fp);
  193.                 break;
  194.             case VSASSIGN:
  195.                 putc('=', fp);
  196.                 break;
  197.             default:
  198.                 printf("<subtype %d>", subtype);
  199.             }
  200.             break;
  201.         case CTLENDVAR:
  202.              putc('}', fp);
  203.              break;
  204.         case CTLBACKQ:
  205.         case CTLBACKQ|CTLQUOTE:
  206.             putc('$', fp);
  207.             putc('(', fp);
  208.             shtree(bqlist->n, -1, NULL, fp);
  209.             putc(')', fp);
  210.             break;
  211.         default:
  212.             putc(*p, fp);
  213.             break;
  214.         }
  215.     }
  216. }
  217.  
  218.  
  219. static
  220. indent(amount, pfx, fp)
  221.     char *pfx;
  222.     FILE *fp;
  223.     {
  224.     int i;
  225.  
  226.     for (i = 0 ; i < amount ; i++) {
  227.         if (pfx && i == amount - 1)
  228.             fputs(pfx, fp);
  229.         putc('\t', fp);
  230.     }
  231. }
  232. #endif
  233.  
  234.  
  235.  
  236. /*
  237.  * Debugging stuff.
  238.  */
  239.  
  240.  
  241. FILE *tracefile;
  242.  
  243. #if DEBUG == 2
  244. int debug = 1;
  245. #else
  246. int debug = 0;
  247. #endif
  248.  
  249.  
  250. trputc(c) {
  251. #ifdef DEBUG
  252.     if (tracefile == NULL)
  253.         return;
  254.     putc(c, tracefile);
  255.     if (c == '\n')
  256.         fflush(tracefile);
  257. #endif
  258. }
  259.  
  260.  
  261. trace(fmt, a1, a2, a3, a4, a5, a6, a7, a8)
  262.     char *fmt;
  263.     {
  264. #ifdef DEBUG
  265.     if (tracefile == NULL)
  266.         return;
  267.     fprintf(tracefile, fmt, a1, a2, a3, a4, a5, a6, a7, a8);
  268.     if (strchr(fmt, '\n'))
  269.         fflush(tracefile);
  270. #endif
  271. }
  272.  
  273.  
  274. trputs(s)
  275.     char *s;
  276.     {
  277. #ifdef DEBUG
  278.     if (tracefile == NULL)
  279.         return;
  280.     fputs(s, tracefile);
  281.     if (strchr(s, '\n'))
  282.         fflush(tracefile);
  283. #endif
  284. }
  285.  
  286.  
  287. trstring(s)
  288.     char *s;
  289.     {
  290.     register char *p;
  291.     char c;
  292.  
  293. #ifdef DEBUG
  294.     if (tracefile == NULL)
  295.         return;
  296.     putc('"', tracefile);
  297.     for (p = s ; *p ; p++) {
  298.         switch (*p) {
  299.         case '\n':  c = 'n';  goto backslash;
  300.         case '\t':  c = 't';  goto backslash;
  301.         case '\r':  c = 'r';  goto backslash;
  302.         case '"':  c = '"';  goto backslash;
  303.         case '\\':  c = '\\';  goto backslash;
  304.         case CTLESC:  c = 'e';  goto backslash;
  305.         case CTLVAR:  c = 'v';  goto backslash;
  306.         case CTLVAR+CTLQUOTE:  c = 'V';  goto backslash;
  307.         case CTLBACKQ:  c = 'q';  goto backslash;
  308.         case CTLBACKQ+CTLQUOTE:  c = 'Q';  goto backslash;
  309. backslash:      putc('\\', tracefile);
  310.             putc(c, tracefile);
  311.             break;
  312.         default:
  313.             if (*p >= ' ' && *p <= '~')
  314.                 putc(*p, tracefile);
  315.             else {
  316.                 putc('\\', tracefile);
  317.                 putc(*p >> 6 & 03, tracefile);
  318.                 putc(*p >> 3 & 07, tracefile);
  319.                 putc(*p & 07, tracefile);
  320.             }
  321.             break;
  322.         }
  323.     }
  324.     putc('"', tracefile);
  325. #endif
  326. }
  327.  
  328.  
  329. trargs(ap)
  330.     char **ap;
  331.     {
  332. #ifdef DEBUG
  333.     if (tracefile == NULL)
  334.         return;
  335.     while (*ap) {
  336.         trstring(*ap++);
  337.         if (*ap)
  338.             putc(' ', tracefile);
  339.         else
  340.             putc('\n', tracefile);
  341.     }
  342.     fflush(tracefile);
  343. #endif
  344. }
  345.  
  346.  
  347. opentrace() {
  348.     char s[100];
  349.     char *p;
  350.     char *getenv();
  351.     int flags;
  352.  
  353. #ifdef DEBUG
  354.     if (!debug)
  355.         return;
  356.     if ((p = getenv("HOME")) == NULL) {
  357.         if (getuid() == 0)
  358.             p = "/";
  359.         else
  360.             p = "/tmp";
  361.     }
  362.     scopy(p, s);
  363.     strcat(s, "/trace");
  364.     if ((tracefile = fopen(s, "a")) == NULL) {
  365.         fprintf(stderr, "Can't open %s\n", s);
  366.         return;
  367.     }
  368. #ifdef O_APPEND
  369.     if ((flags = fcntl(fileno(tracefile), F_GETFL, 0)) >= 0)
  370.         fcntl(fileno(tracefile), F_SETFL, flags | O_APPEND);
  371. #endif
  372.     fputs("\nTracing started.\n", tracefile);
  373.     fflush(tracefile);
  374. #endif
  375. }
  376.