1*47144Sbostic /*- 2*47144Sbostic * Copyright (c) 1991 The Regents of the University of California. 3*47144Sbostic * All rights reserved. 4*47144Sbostic * 5*47144Sbostic * This code is derived from software contributed to Berkeley by 6*47144Sbostic * Kenneth Almquist. 7*47144Sbostic * 8*47144Sbostic * %sccs.include.redist.c% 9*47144Sbostic */ 10*47144Sbostic 11*47144Sbostic #ifndef lint 12*47144Sbostic static char sccsid[] = "@(#)show.c 5.1 (Berkeley) 03/07/91"; 13*47144Sbostic #endif /* not lint */ 14*47144Sbostic 15*47144Sbostic #include <stdio.h> 16*47144Sbostic #include "shell.h" 17*47144Sbostic #include "parser.h" 18*47144Sbostic #include "nodes.h" 19*47144Sbostic #include "mystring.h" 20*47144Sbostic 21*47144Sbostic 22*47144Sbostic #ifdef DEBUG 23*47144Sbostic static shtree(), shcmd(), sharg(), indent(); 24*47144Sbostic 25*47144Sbostic 26*47144Sbostic showtree(n) 27*47144Sbostic union node *n; 28*47144Sbostic { 29*47144Sbostic trputs("showtree called\n"); 30*47144Sbostic shtree(n, 1, NULL, stdout); 31*47144Sbostic } 32*47144Sbostic 33*47144Sbostic 34*47144Sbostic static 35*47144Sbostic shtree(n, ind, pfx, fp) 36*47144Sbostic union node *n; 37*47144Sbostic char *pfx; 38*47144Sbostic FILE *fp; 39*47144Sbostic { 40*47144Sbostic struct nodelist *lp; 41*47144Sbostic char *s; 42*47144Sbostic 43*47144Sbostic indent(ind, pfx, fp); 44*47144Sbostic switch(n->type) { 45*47144Sbostic case NSEMI: 46*47144Sbostic s = "; "; 47*47144Sbostic goto binop; 48*47144Sbostic case NAND: 49*47144Sbostic s = " && "; 50*47144Sbostic goto binop; 51*47144Sbostic case NOR: 52*47144Sbostic s = " || "; 53*47144Sbostic binop: 54*47144Sbostic shtree(n->nbinary.ch1, ind, NULL, fp); 55*47144Sbostic /* if (ind < 0) */ 56*47144Sbostic fputs(s, fp); 57*47144Sbostic shtree(n->nbinary.ch2, ind, NULL, fp); 58*47144Sbostic break; 59*47144Sbostic case NCMD: 60*47144Sbostic shcmd(n, fp); 61*47144Sbostic if (ind >= 0) 62*47144Sbostic putc('\n', fp); 63*47144Sbostic break; 64*47144Sbostic case NPIPE: 65*47144Sbostic for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) { 66*47144Sbostic shcmd(lp->n, fp); 67*47144Sbostic if (lp->next) 68*47144Sbostic fputs(" | ", fp); 69*47144Sbostic } 70*47144Sbostic if (n->npipe.backgnd) 71*47144Sbostic fputs(" &", fp); 72*47144Sbostic if (ind >= 0) 73*47144Sbostic putc('\n', fp); 74*47144Sbostic break; 75*47144Sbostic default: 76*47144Sbostic fprintf(fp, "<node type %d>", n->type); 77*47144Sbostic if (ind >= 0) 78*47144Sbostic putc('\n', fp); 79*47144Sbostic break; 80*47144Sbostic } 81*47144Sbostic } 82*47144Sbostic 83*47144Sbostic 84*47144Sbostic 85*47144Sbostic static 86*47144Sbostic shcmd(cmd, fp) 87*47144Sbostic union node *cmd; 88*47144Sbostic FILE *fp; 89*47144Sbostic { 90*47144Sbostic union node *np; 91*47144Sbostic int first; 92*47144Sbostic char *s; 93*47144Sbostic int dftfd; 94*47144Sbostic 95*47144Sbostic first = 1; 96*47144Sbostic for (np = cmd->ncmd.args ; np ; np = np->narg.next) { 97*47144Sbostic if (! first) 98*47144Sbostic putchar(' '); 99*47144Sbostic sharg(np, fp); 100*47144Sbostic first = 0; 101*47144Sbostic } 102*47144Sbostic for (np = cmd->ncmd.redirect ; np ; np = np->nfile.next) { 103*47144Sbostic if (! first) 104*47144Sbostic putchar(' '); 105*47144Sbostic switch (np->nfile.type) { 106*47144Sbostic case NTO: s = ">"; dftfd = 1; break; 107*47144Sbostic case NAPPEND: s = ">>"; dftfd = 1; break; 108*47144Sbostic case NTOFD: s = ">&"; dftfd = 1; break; 109*47144Sbostic case NFROM: s = "<"; dftfd = 0; break; 110*47144Sbostic case NFROMFD: s = "<&"; dftfd = 0; break; 111*47144Sbostic } 112*47144Sbostic if (np->nfile.fd != dftfd) 113*47144Sbostic fprintf(fp, "%d", np->nfile.fd); 114*47144Sbostic fputs(s, fp); 115*47144Sbostic if (np->nfile.type == NTOFD || np->nfile.type == NFROMFD) { 116*47144Sbostic fprintf(fp, "%d", np->ndup.dupfd); 117*47144Sbostic } else { 118*47144Sbostic sharg(np->nfile.fname, fp); 119*47144Sbostic } 120*47144Sbostic first = 0; 121*47144Sbostic } 122*47144Sbostic } 123*47144Sbostic 124*47144Sbostic 125*47144Sbostic 126*47144Sbostic static 127*47144Sbostic sharg(arg, fp) 128*47144Sbostic union node *arg; 129*47144Sbostic FILE *fp; 130*47144Sbostic { 131*47144Sbostic char *p; 132*47144Sbostic struct nodelist *bqlist; 133*47144Sbostic int subtype; 134*47144Sbostic 135*47144Sbostic if (arg->type != NARG) { 136*47144Sbostic printf("<node type %d>\n", arg->type); 137*47144Sbostic fflush(stdout); 138*47144Sbostic abort(); 139*47144Sbostic } 140*47144Sbostic bqlist = arg->narg.backquote; 141*47144Sbostic for (p = arg->narg.text ; *p ; p++) { 142*47144Sbostic switch (*p) { 143*47144Sbostic case CTLESC: 144*47144Sbostic putc(*++p, fp); 145*47144Sbostic break; 146*47144Sbostic case CTLVAR: 147*47144Sbostic putc('$', fp); 148*47144Sbostic putc('{', fp); 149*47144Sbostic subtype = *++p; 150*47144Sbostic while (*p != '=') 151*47144Sbostic putc(*p++, fp); 152*47144Sbostic if (subtype & VSNUL) 153*47144Sbostic putc(':', fp); 154*47144Sbostic switch (subtype & VSTYPE) { 155*47144Sbostic case VSNORMAL: 156*47144Sbostic putc('}', fp); 157*47144Sbostic break; 158*47144Sbostic case VSMINUS: 159*47144Sbostic putc('-', fp); 160*47144Sbostic break; 161*47144Sbostic case VSPLUS: 162*47144Sbostic putc('+', fp); 163*47144Sbostic break; 164*47144Sbostic case VSQUESTION: 165*47144Sbostic putc('?', fp); 166*47144Sbostic break; 167*47144Sbostic case VSASSIGN: 168*47144Sbostic putc('=', fp); 169*47144Sbostic break; 170*47144Sbostic default: 171*47144Sbostic printf("<subtype %d>", subtype); 172*47144Sbostic } 173*47144Sbostic break; 174*47144Sbostic case CTLENDVAR: 175*47144Sbostic putc('}', fp); 176*47144Sbostic break; 177*47144Sbostic case CTLBACKQ: 178*47144Sbostic case CTLBACKQ|CTLQUOTE: 179*47144Sbostic putc('$', fp); 180*47144Sbostic putc('(', fp); 181*47144Sbostic shtree(bqlist->n, -1, NULL, fp); 182*47144Sbostic putc(')', fp); 183*47144Sbostic break; 184*47144Sbostic default: 185*47144Sbostic putc(*p, fp); 186*47144Sbostic break; 187*47144Sbostic } 188*47144Sbostic } 189*47144Sbostic } 190*47144Sbostic 191*47144Sbostic 192*47144Sbostic static 193*47144Sbostic indent(amount, pfx, fp) 194*47144Sbostic char *pfx; 195*47144Sbostic FILE *fp; 196*47144Sbostic { 197*47144Sbostic int i; 198*47144Sbostic 199*47144Sbostic for (i = 0 ; i < amount ; i++) { 200*47144Sbostic if (pfx && i == amount - 1) 201*47144Sbostic fputs(pfx, fp); 202*47144Sbostic putc('\t', fp); 203*47144Sbostic } 204*47144Sbostic } 205*47144Sbostic #endif 206*47144Sbostic 207*47144Sbostic 208*47144Sbostic 209*47144Sbostic /* 210*47144Sbostic * Debugging stuff. 211*47144Sbostic */ 212*47144Sbostic 213*47144Sbostic 214*47144Sbostic FILE *tracefile; 215*47144Sbostic 216*47144Sbostic 217*47144Sbostic 218*47144Sbostic trputc(c) { 219*47144Sbostic #ifdef DEBUG 220*47144Sbostic if (tracefile == NULL) 221*47144Sbostic return; 222*47144Sbostic putc(c, tracefile); 223*47144Sbostic if (c == '\n') 224*47144Sbostic fflush(tracefile); 225*47144Sbostic #endif 226*47144Sbostic } 227*47144Sbostic 228*47144Sbostic 229*47144Sbostic trace(fmt, a1, a2, a3, a4, a5, a6, a7, a8) 230*47144Sbostic char *fmt; 231*47144Sbostic { 232*47144Sbostic #ifdef DEBUG 233*47144Sbostic if (tracefile == NULL) 234*47144Sbostic return; 235*47144Sbostic fprintf(tracefile, fmt, a1, a2, a3, a4, a5, a6, a7, a8); 236*47144Sbostic if (strchr(fmt, '\n')) 237*47144Sbostic fflush(tracefile); 238*47144Sbostic #endif 239*47144Sbostic } 240*47144Sbostic 241*47144Sbostic 242*47144Sbostic trputs(s) 243*47144Sbostic char *s; 244*47144Sbostic { 245*47144Sbostic #ifdef DEBUG 246*47144Sbostic if (tracefile == NULL) 247*47144Sbostic return; 248*47144Sbostic fputs(s, tracefile); 249*47144Sbostic if (strchr(s, '\n')) 250*47144Sbostic fflush(tracefile); 251*47144Sbostic #endif 252*47144Sbostic } 253*47144Sbostic 254*47144Sbostic 255*47144Sbostic trstring(s) 256*47144Sbostic char *s; 257*47144Sbostic { 258*47144Sbostic register char *p; 259*47144Sbostic char c; 260*47144Sbostic 261*47144Sbostic #ifdef DEBUG 262*47144Sbostic if (tracefile == NULL) 263*47144Sbostic return; 264*47144Sbostic putc('"', tracefile); 265*47144Sbostic for (p = s ; *p ; p++) { 266*47144Sbostic switch (*p) { 267*47144Sbostic case '\n': c = 'n'; goto backslash; 268*47144Sbostic case '\t': c = 't'; goto backslash; 269*47144Sbostic case '\r': c = 'r'; goto backslash; 270*47144Sbostic case '"': c = '"'; goto backslash; 271*47144Sbostic case '\\': c = '\\'; goto backslash; 272*47144Sbostic case CTLESC: c = 'e'; goto backslash; 273*47144Sbostic case CTLVAR: c = 'v'; goto backslash; 274*47144Sbostic case CTLVAR+CTLQUOTE: c = 'V'; goto backslash; 275*47144Sbostic case CTLBACKQ: c = 'q'; goto backslash; 276*47144Sbostic case CTLBACKQ+CTLQUOTE: c = 'Q'; goto backslash; 277*47144Sbostic backslash: putc('\\', tracefile); 278*47144Sbostic putc(c, tracefile); 279*47144Sbostic break; 280*47144Sbostic default: 281*47144Sbostic if (*p >= ' ' && *p <= '~') 282*47144Sbostic putc(*p, tracefile); 283*47144Sbostic else { 284*47144Sbostic putc('\\', tracefile); 285*47144Sbostic putc(*p >> 6 & 03, tracefile); 286*47144Sbostic putc(*p >> 3 & 07, tracefile); 287*47144Sbostic putc(*p & 07, tracefile); 288*47144Sbostic } 289*47144Sbostic break; 290*47144Sbostic } 291*47144Sbostic } 292*47144Sbostic putc('"', tracefile); 293*47144Sbostic #endif 294*47144Sbostic } 295*47144Sbostic 296*47144Sbostic 297*47144Sbostic trargs(ap) 298*47144Sbostic char **ap; 299*47144Sbostic { 300*47144Sbostic #ifdef DEBUG 301*47144Sbostic if (tracefile == NULL) 302*47144Sbostic return; 303*47144Sbostic while (*ap) { 304*47144Sbostic trstring(*ap++); 305*47144Sbostic if (*ap) 306*47144Sbostic putc(' ', tracefile); 307*47144Sbostic else 308*47144Sbostic putc('\n', tracefile); 309*47144Sbostic } 310*47144Sbostic fflush(tracefile); 311*47144Sbostic #endif 312*47144Sbostic } 313*47144Sbostic 314*47144Sbostic 315*47144Sbostic opentrace() { 316*47144Sbostic char s[100]; 317*47144Sbostic char *p; 318*47144Sbostic char *getenv(); 319*47144Sbostic int flags; 320*47144Sbostic 321*47144Sbostic #ifdef DEBUG 322*47144Sbostic if ((p = getenv("HOME")) == NULL) 323*47144Sbostic p = "/tmp"; 324*47144Sbostic scopy(p, s); 325*47144Sbostic strcat(s, "/trace"); 326*47144Sbostic if ((tracefile = fopen(s, "a")) == NULL) { 327*47144Sbostic fprintf(stderr, "Can't open %s\n", s); 328*47144Sbostic exit(2); 329*47144Sbostic } 330*47144Sbostic #ifdef O_APPEND 331*47144Sbostic if ((flags = fcntl(fileno(tracefile), F_GETFL, 0)) >= 0) 332*47144Sbostic fcntl(fileno(tracefile), F_SETFL, flags | O_APPEND); 333*47144Sbostic #endif 334*47144Sbostic fputs("\nTracing started.\n", tracefile); 335*47144Sbostic fflush(tracefile); 336*47144Sbostic #endif 337*47144Sbostic } 338