Subversion Repositories HelenOS

Rev

Rev 2714 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*  $NetBSD: show.c,v 1.18 1999/10/08 21:10:44 pk Exp $ */
  2.  
  3. /*-
  4.  * Copyright (c) 1991, 1993
  5.  *  The Regents of the University of California.  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. All advertising materials mentioning features or use of this software
  19.  *    must display the following acknowledgement:
  20.  *  This product includes software developed by the University of
  21.  *  California, Berkeley and its contributors.
  22.  * 4. Neither the name of the University nor the names of its contributors
  23.  *    may be used to endorse or promote products derived from this software
  24.  *    without specific prior written permission.
  25.  *
  26.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  27.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  28.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  29.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  30.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  31.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  32.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  33.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  34.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  35.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  36.  * SUCH DAMAGE.
  37.  */
  38.  
  39. #include <sys/cdefs.h>
  40. #ifndef lint
  41. #if 0
  42. static char sccsid[] = "@(#)show.c  8.3 (Berkeley) 5/4/95";
  43. #else
  44. __RCSID("$NetBSD: show.c,v 1.18 1999/10/08 21:10:44 pk Exp $");
  45. #endif
  46. #endif /* not lint */
  47.  
  48. #include <stdio.h>
  49. #ifdef __STDC__
  50. #include <stdarg.h>
  51. #else
  52. #include <varargs.h>
  53. #endif
  54.  
  55. #include "shell.h"
  56. #include "parser.h"
  57. #include "nodes.h"
  58. #include "mystring.h"
  59. #include "show.h"
  60.  
  61.  
  62. #ifdef DEBUG
  63. static void shtree (union node *, int, char *, FILE*);
  64. static void shcmd (union node *, FILE *);
  65. static void sharg (union node *, FILE *);
  66. static void indent (int, char *, FILE *);
  67. static void trstring (char *);
  68.  
  69.  
  70. void
  71. showtree(n)
  72.     union node *n;
  73. {
  74.     trputs("showtree called\n");
  75.     shtree(n, 1, NULL, stdout);
  76. }
  77.  
  78.  
  79. static void
  80. shtree(n, ind, pfx, fp)
  81.     union node *n;
  82.     int ind;
  83.     char *pfx;
  84.     FILE *fp;
  85. {
  86.     struct nodelist *lp;
  87.     const char *s;
  88.  
  89.     if (n == NULL)
  90.         return;
  91.  
  92.     indent(ind, pfx, fp);
  93.     switch(n->type) {
  94.     case NSEMI:
  95.         s = "; ";
  96.         goto binop;
  97.     case NAND:
  98.         s = " && ";
  99.         goto binop;
  100.     case NOR:
  101.         s = " || ";
  102. binop:
  103.         shtree(n->nbinary.ch1, ind, NULL, fp);
  104.        /*    if (ind < 0) */
  105.             fputs(s, fp);
  106.         shtree(n->nbinary.ch2, ind, NULL, fp);
  107.         break;
  108.     case NCMD:
  109.         shcmd(n, fp);
  110.         if (ind >= 0)
  111.             putc('\n', fp);
  112.         break;
  113.     case NPIPE:
  114.         for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) {
  115.             shcmd(lp->n, fp);
  116.             if (lp->next)
  117.                 fputs(" | ", fp);
  118.         }
  119.         if (n->npipe.backgnd)
  120.             fputs(" &", fp);
  121.         if (ind >= 0)
  122.             putc('\n', fp);
  123.         break;
  124.     default:
  125.         fprintf(fp, "<node type %d>", n->type);
  126.         if (ind >= 0)
  127.             putc('\n', fp);
  128.         break;
  129.     }
  130. }
  131.  
  132.  
  133.  
  134. static void
  135. shcmd(cmd, fp)
  136.     union node *cmd;
  137.     FILE *fp;
  138. {
  139.     union node *np;
  140.     int first;
  141.     const char *s;
  142.     int dftfd;
  143.  
  144.     first = 1;
  145.     for (np = cmd->ncmd.args ; np ; np = np->narg.next) {
  146.         if (! first)
  147.             putchar(' ');
  148.         sharg(np, fp);
  149.         first = 0;
  150.     }
  151.     for (np = cmd->ncmd.redirect ; np ; np = np->nfile.next) {
  152.         if (! first)
  153.             putchar(' ');
  154.         switch (np->nfile.type) {
  155.             case NTO:   s = ">";  dftfd = 1; break;
  156.             case NAPPEND:   s = ">>"; dftfd = 1; break;
  157.             case NTOFD: s = ">&"; dftfd = 1; break;
  158.             case NTOOV: s = ">|"; dftfd = 1; break;
  159.             case NFROM: s = "<";  dftfd = 0; break;
  160.             case NFROMFD:   s = "<&"; dftfd = 0; break;
  161.             case NFROMTO:   s = "<>"; dftfd = 0; break;
  162.             default:    s = "*error*"; dftfd = 0; break;
  163.         }
  164.         if (np->nfile.fd != dftfd)
  165.             fprintf(fp, "%d", np->nfile.fd);
  166.         fputs(s, fp);
  167.         if (np->nfile.type == NTOFD || np->nfile.type == NFROMFD) {
  168.             fprintf(fp, "%d", np->ndup.dupfd);
  169.         } else {
  170.             sharg(np->nfile.fname, fp);
  171.         }
  172.         first = 0;
  173.     }
  174. }
  175.  
  176.  
  177.  
  178. static void
  179. sharg(arg, fp)
  180.     union node *arg;
  181.     FILE *fp;
  182.     {
  183.     char *p;
  184.     struct nodelist *bqlist;
  185.     int subtype;
  186.  
  187.     if (arg->type != NARG) {
  188.         printf("<node type %d>\n", arg->type);
  189.         fflush(stdout);
  190.         abort();
  191.     }
  192.     bqlist = arg->narg.backquote;
  193.     for (p = arg->narg.text ; *p ; p++) {
  194.         switch (*p) {
  195.         case CTLESC:
  196.             putc(*++p, fp);
  197.             break;
  198.         case CTLVAR:
  199.             putc('$', fp);
  200.             putc('{', fp);
  201.             subtype = *++p;
  202.             if (subtype == VSLENGTH)
  203.                 putc('#', fp);
  204.  
  205.             while (*p != '=')
  206.                 putc(*p++, fp);
  207.  
  208.             if (subtype & VSNUL)
  209.                 putc(':', fp);
  210.  
  211.             switch (subtype & VSTYPE) {
  212.             case VSNORMAL:
  213.                 putc('}', fp);
  214.                 break;
  215.             case VSMINUS:
  216.                 putc('-', fp);
  217.                 break;
  218.             case VSPLUS:
  219.                 putc('+', fp);
  220.                 break;
  221.             case VSQUESTION:
  222.                 putc('?', fp);
  223.                 break;
  224.             case VSASSIGN:
  225.                 putc('=', fp);
  226.                 break;
  227.             case VSTRIMLEFT:
  228.                 putc('#', fp);
  229.                 break;
  230.             case VSTRIMLEFTMAX:
  231.                 putc('#', fp);
  232.                 putc('#', fp);
  233.                 break;
  234.             case VSTRIMRIGHT:
  235.                 putc('%', fp);
  236.                 break;
  237.             case VSTRIMRIGHTMAX:
  238.                 putc('%', fp);
  239.                 putc('%', fp);
  240.                 break;
  241.             case VSLENGTH:
  242.                 break;
  243.             default:
  244.                 printf("<subtype %d>", subtype);
  245.             }
  246.             break;
  247.         case CTLENDVAR:
  248.              putc('}', fp);
  249.              break;
  250.         case CTLBACKQ:
  251.         case CTLBACKQ|CTLQUOTE:
  252.             putc('$', fp);
  253.             putc('(', fp);
  254.             shtree(bqlist->n, -1, NULL, fp);
  255.             putc(')', fp);
  256.             break;
  257.         default:
  258.             putc(*p, fp);
  259.             break;
  260.         }
  261.     }
  262. }
  263.  
  264.  
  265. static void
  266. indent(amount, pfx, fp)
  267.     int amount;
  268.     char *pfx;
  269.     FILE *fp;
  270. {
  271.     int i;
  272.  
  273.     for (i = 0 ; i < amount ; i++) {
  274.         if (pfx && i == amount - 1)
  275.             fputs(pfx, fp);
  276.         putc('\t', fp);
  277.     }
  278. }
  279. #endif
  280.  
  281.  
  282.  
  283. /*
  284.  * Debugging stuff.
  285.  */
  286.  
  287.  
  288. FILE *tracefile;
  289.  
  290. #if DEBUG == 2
  291. int debug = 1;
  292. #else
  293. int debug = 0;
  294. #endif
  295.  
  296.  
  297. #ifdef DEBUG
  298. void
  299. trputc(c)
  300.     int c;
  301. {
  302.     if (tracefile == NULL)
  303.         return;
  304.     putc(c, tracefile);
  305.     if (c == '\n')
  306.         fflush(tracefile);
  307. }
  308. #endif
  309.  
  310. void
  311. #ifdef __STDC__
  312. trace(const char *fmt, ...)
  313. #else
  314. trace(va_alist)
  315.     va_dcl
  316. #endif
  317. {
  318. #ifdef DEBUG
  319.     va_list va;
  320. #ifdef __STDC__
  321.     va_start(va, fmt);
  322. #else
  323.     char *fmt;
  324.     va_start(va);
  325.     fmt = va_arg(va, char *);
  326. #endif
  327.     if (tracefile != NULL) {
  328.         (void) vfprintf(tracefile, fmt, va);
  329.         if (strchr(fmt, '\n'))
  330.             (void) fflush(tracefile);
  331.     }
  332.     va_end(va);
  333. #endif
  334. }
  335.  
  336.  
  337. #ifdef DEBUG
  338. void
  339. trputs(s)
  340.     const char *s;
  341. {
  342.     if (tracefile == NULL)
  343.         return;
  344.     fputs(s, tracefile);
  345.     if (strchr(s, '\n'))
  346.         fflush(tracefile);
  347. }
  348.  
  349.  
  350. static void
  351. trstring(s)
  352.     char *s;
  353. {
  354.     char *p;
  355.     char c;
  356.  
  357.     if (tracefile == NULL)
  358.         return;
  359.     putc('"', tracefile);
  360.     for (p = s ; *p ; p++) {
  361.         switch (*p) {
  362.         case '\n':  c = 'n';  goto backslash;
  363.         case '\t':  c = 't';  goto backslash;
  364.         case '\r':  c = 'r';  goto backslash;
  365.         case '"':  c = '"';  goto backslash;
  366.         case '\\':  c = '\\';  goto backslash;
  367.         case CTLESC:  c = 'e';  goto backslash;
  368.         case CTLVAR:  c = 'v';  goto backslash;
  369.         case CTLVAR+CTLQUOTE:  c = 'V';  goto backslash;
  370.         case CTLBACKQ:  c = 'q';  goto backslash;
  371.         case CTLBACKQ+CTLQUOTE:  c = 'Q';  goto backslash;
  372. backslash:    putc('\\', tracefile);
  373.             putc(c, tracefile);
  374.             break;
  375.         default:
  376.             if (*p >= ' ' && *p <= '~')
  377.                 putc(*p, tracefile);
  378.             else {
  379.                 putc('\\', tracefile);
  380.                 putc(*p >> 6 & 03, tracefile);
  381.                 putc(*p >> 3 & 07, tracefile);
  382.                 putc(*p & 07, tracefile);
  383.             }
  384.             break;
  385.         }
  386.     }
  387.     putc('"', tracefile);
  388. }
  389. #endif
  390.  
  391.  
  392. void
  393. trargs(ap)
  394.     char **ap;
  395. {
  396. #ifdef DEBUG
  397.     if (tracefile == NULL)
  398.         return;
  399.     while (*ap) {
  400.         trstring(*ap++);
  401.         if (*ap)
  402.             putc(' ', tracefile);
  403.         else
  404.             putc('\n', tracefile);
  405.     }
  406.     fflush(tracefile);
  407. #endif
  408. }
  409.  
  410.  
  411. #ifdef DEBUG
  412. void
  413. opentrace() {
  414.     char s[100];
  415. #ifdef O_APPEND
  416.     int flags;
  417. #endif
  418.  
  419.     if (!debug)
  420.         return;
  421. #ifdef not_this_way
  422.     {
  423.         char *p;
  424.         if ((p = getenv("HOME")) == NULL) {
  425.             if (geteuid() == 0)
  426.                 p = "/";
  427.             else
  428.                 p = "/tmp";
  429.         }
  430.         scopy(p, s);
  431.         strcat(s, "/trace");
  432.     }
  433. #else
  434.     scopy("./trace", s);
  435. #endif /* not_this_way */
  436.     if ((tracefile = fopen(s, "a")) == NULL) {
  437.         fprintf(stderr, "Can't open %s\n", s);
  438.         return;
  439.     }
  440. #ifdef O_APPEND
  441.     if ((flags = fcntl(fileno(tracefile), F_GETFL, 0)) >= 0)
  442.         fcntl(fileno(tracefile), F_SETFL, flags | O_APPEND);
  443. #endif
  444.     fputs("\nTracing started.\n", tracefile);
  445.     fflush(tracefile);
  446. }
  447. #endif /* DEBUG */
  448.