1*4887Schin /*********************************************************************** 2*4887Schin * * 3*4887Schin * This software is part of the ast package * 4*4887Schin * Copyright (c) 1982-2007 AT&T Knowledge Ventures * 5*4887Schin * and is licensed under the * 6*4887Schin * Common Public License, Version 1.0 * 7*4887Schin * by AT&T Knowledge Ventures * 8*4887Schin * * 9*4887Schin * A copy of the License is available at * 10*4887Schin * http://www.opensource.org/licenses/cpl1.0.txt * 11*4887Schin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 12*4887Schin * * 13*4887Schin * Information and Software Systems Research * 14*4887Schin * AT&T Research * 15*4887Schin * Florham Park NJ * 16*4887Schin * * 17*4887Schin * David Korn <dgk@research.att.com> * 18*4887Schin * * 19*4887Schin ***********************************************************************/ 20*4887Schin #pragma prototyped 21*4887Schin /* 22*4887Schin * David Korn 23*4887Schin * AT&T Labs 24*4887Schin * 25*4887Schin * shell parse tree dump 26*4887Schin * 27*4887Schin */ 28*4887Schin 29*4887Schin #include <ccode.h> 30*4887Schin #include "defs.h" 31*4887Schin #include "shnodes.h" 32*4887Schin #include "path.h" 33*4887Schin #include "io.h" 34*4887Schin 35*4887Schin static int p_comlist(const struct dolnod*); 36*4887Schin static int p_arg(const struct argnod*); 37*4887Schin static int p_comarg(const struct comnod*); 38*4887Schin static int p_redirect(const struct ionod*); 39*4887Schin static int p_switch(const struct regnod*); 40*4887Schin static int p_tree(const Shnode_t*); 41*4887Schin static int p_string(const char*); 42*4887Schin 43*4887Schin static Sfio_t *outfile; 44*4887Schin 45*4887Schin int sh_tdump(Sfio_t *out, const Shnode_t *t) 46*4887Schin { 47*4887Schin outfile = out; 48*4887Schin return(p_tree(t)); 49*4887Schin } 50*4887Schin 51*4887Schin /* 52*4887Schin * convert to ASCII to write and back again if needed 53*4887Schin */ 54*4887Schin static int outstring(Sfio_t *out, const char *string, int n) 55*4887Schin { 56*4887Schin int r; 57*4887Schin char *cp = (char*)string; 58*4887Schin ccmaps(cp, n, CC_NATIVE, CC_ASCII); 59*4887Schin r = sfwrite(out,cp,n); 60*4887Schin ccmaps(cp, n, CC_ASCII, CC_NATIVE); 61*4887Schin return(r); 62*4887Schin } 63*4887Schin 64*4887Schin /* 65*4887Schin * print script corresponding to shell tree <t> 66*4887Schin */ 67*4887Schin static int p_tree(register const Shnode_t *t) 68*4887Schin { 69*4887Schin if(!t) 70*4887Schin return(sfputl(outfile,-1)); 71*4887Schin if(sfputl(outfile,t->tre.tretyp)<0) 72*4887Schin return(-1); 73*4887Schin switch(t->tre.tretyp&COMMSK) 74*4887Schin { 75*4887Schin case TTIME: 76*4887Schin case TPAR: 77*4887Schin return(p_tree(t->par.partre)); 78*4887Schin case TCOM: 79*4887Schin return(p_comarg((struct comnod*)t)); 80*4887Schin case TSETIO: 81*4887Schin case TFORK: 82*4887Schin if(sfputu(outfile,t->fork.forkline)<0) 83*4887Schin return(-1); 84*4887Schin if(p_tree(t->fork.forktre)<0) 85*4887Schin return(-1); 86*4887Schin return(p_redirect(t->fork.forkio)); 87*4887Schin case TIF: 88*4887Schin if(p_tree(t->if_.iftre)<0) 89*4887Schin return(-1); 90*4887Schin if(p_tree(t->if_.thtre)<0) 91*4887Schin return(-1); 92*4887Schin return(p_tree(t->if_.eltre)); 93*4887Schin case TWH: 94*4887Schin if(t->wh.whinc) 95*4887Schin { 96*4887Schin if(p_tree((Shnode_t*)(t->wh.whinc))<0) 97*4887Schin return(-1); 98*4887Schin } 99*4887Schin else 100*4887Schin { 101*4887Schin if(sfputl(outfile,-1)<0) 102*4887Schin return(-1); 103*4887Schin } 104*4887Schin if(p_tree(t->wh.whtre)<0) 105*4887Schin return(-1); 106*4887Schin return(p_tree(t->wh.dotre)); 107*4887Schin case TLST: 108*4887Schin case TAND: 109*4887Schin case TORF: 110*4887Schin case TFIL: 111*4887Schin if(p_tree(t->lst.lstlef)<0) 112*4887Schin return(-1); 113*4887Schin return(p_tree(t->lst.lstrit)); 114*4887Schin case TARITH: 115*4887Schin if(sfputu(outfile,t->ar.arline)<0) 116*4887Schin return(-1); 117*4887Schin return(p_arg(t->ar.arexpr)); 118*4887Schin case TFOR: 119*4887Schin if(sfputu(outfile,t->for_.forline)<0) 120*4887Schin return(-1); 121*4887Schin if(p_tree(t->for_.fortre)<0) 122*4887Schin return(-1); 123*4887Schin if(p_string(t->for_.fornam)<0) 124*4887Schin return(-1); 125*4887Schin return(p_tree((Shnode_t*)t->for_.forlst)); 126*4887Schin case TSW: 127*4887Schin if(sfputu(outfile,t->sw.swline)<0) 128*4887Schin return(-1); 129*4887Schin if(p_arg(t->sw.swarg)<0) 130*4887Schin return(-1); 131*4887Schin return(p_switch(t->sw.swlst)); 132*4887Schin case TFUN: 133*4887Schin if(sfputu(outfile,t->funct.functline)<0) 134*4887Schin return(-1); 135*4887Schin if(p_string(t->funct.functnam)<0) 136*4887Schin return(-1); 137*4887Schin if(p_tree(t->funct.functtre)<0) 138*4887Schin return(-1); 139*4887Schin return(p_tree((Shnode_t*)t->funct.functargs)); 140*4887Schin case TTST: 141*4887Schin if(sfputu(outfile,t->tst.tstline)<0) 142*4887Schin return(-1); 143*4887Schin if((t->tre.tretyp&TPAREN)==TPAREN) 144*4887Schin return(p_tree(t->lst.lstlef)); 145*4887Schin else 146*4887Schin { 147*4887Schin if(p_arg(&(t->lst.lstlef->arg))<0) 148*4887Schin return(-1); 149*4887Schin if((t->tre.tretyp&TBINARY)) 150*4887Schin return(p_arg(&(t->lst.lstrit->arg))); 151*4887Schin return(0); 152*4887Schin } 153*4887Schin } 154*4887Schin return(-1); 155*4887Schin } 156*4887Schin 157*4887Schin static int p_arg(register const struct argnod *arg) 158*4887Schin { 159*4887Schin register int n; 160*4887Schin struct fornod *fp; 161*4887Schin while(arg) 162*4887Schin { 163*4887Schin if((n = strlen(arg->argval)) || (arg->argflag&~ARG_APPEND)) 164*4887Schin fp=0; 165*4887Schin else 166*4887Schin { 167*4887Schin fp=(struct fornod*)arg->argchn.ap; 168*4887Schin n = strlen(fp->fornam)+1; 169*4887Schin } 170*4887Schin sfputu(outfile,n+1); 171*4887Schin if(fp) 172*4887Schin { 173*4887Schin sfputc(outfile,0); 174*4887Schin outstring(outfile,fp->fornam,n-1); 175*4887Schin } 176*4887Schin else 177*4887Schin outstring(outfile,arg->argval,n); 178*4887Schin sfputc(outfile,arg->argflag); 179*4887Schin if(fp) 180*4887Schin { 181*4887Schin sfputu(outfile,fp->fortyp); 182*4887Schin p_tree(fp->fortre); 183*4887Schin } 184*4887Schin arg = arg->argnxt.ap; 185*4887Schin } 186*4887Schin return(sfputu(outfile,0)); 187*4887Schin } 188*4887Schin 189*4887Schin static int p_redirect(register const struct ionod *iop) 190*4887Schin { 191*4887Schin while(iop) 192*4887Schin { 193*4887Schin if(iop->iovname) 194*4887Schin sfputl(outfile,iop->iofile|IOVNM); 195*4887Schin else 196*4887Schin sfputl(outfile,iop->iofile); 197*4887Schin p_string(iop->ioname); 198*4887Schin if(iop->iodelim) 199*4887Schin { 200*4887Schin p_string(iop->iodelim); 201*4887Schin sfputl(outfile,iop->iosize); 202*4887Schin sfseek(sh.heredocs,iop->iooffset,SEEK_SET); 203*4887Schin sfmove(sh.heredocs,outfile, iop->iosize,-1); 204*4887Schin } 205*4887Schin else 206*4887Schin sfputu(outfile,0); 207*4887Schin if(iop->iovname) 208*4887Schin p_string(iop->iovname); 209*4887Schin iop = iop->ionxt; 210*4887Schin } 211*4887Schin return(sfputl(outfile,-1)); 212*4887Schin } 213*4887Schin 214*4887Schin static int p_comarg(register const struct comnod *com) 215*4887Schin { 216*4887Schin p_redirect(com->comio); 217*4887Schin p_arg(com->comset); 218*4887Schin if(!com->comarg) 219*4887Schin sfputl(outfile,-1); 220*4887Schin else if(com->comtyp&COMSCAN) 221*4887Schin p_arg(com->comarg); 222*4887Schin else 223*4887Schin p_comlist((struct dolnod*)com->comarg); 224*4887Schin return(sfputu(outfile,com->comline)); 225*4887Schin } 226*4887Schin 227*4887Schin static int p_comlist(const struct dolnod *dol) 228*4887Schin { 229*4887Schin register char *cp, *const*argv; 230*4887Schin register int n; 231*4887Schin argv = dol->dolval+ARG_SPARE; 232*4887Schin while(cp = *argv) 233*4887Schin argv++; 234*4887Schin n = argv - (dol->dolval+1); 235*4887Schin sfputl(outfile,n); 236*4887Schin argv = dol->dolval+ARG_SPARE; 237*4887Schin while(cp = *argv++) 238*4887Schin p_string(cp); 239*4887Schin return(sfputu(outfile,0)); 240*4887Schin } 241*4887Schin 242*4887Schin static int p_switch(register const struct regnod *reg) 243*4887Schin { 244*4887Schin while(reg) 245*4887Schin { 246*4887Schin sfputl(outfile,reg->regflag); 247*4887Schin p_arg(reg->regptr); 248*4887Schin p_tree(reg->regcom); 249*4887Schin reg = reg->regnxt; 250*4887Schin } 251*4887Schin return(sfputl(outfile,-1)); 252*4887Schin } 253*4887Schin 254*4887Schin static int p_string(register const char *string) 255*4887Schin { 256*4887Schin register size_t n=strlen(string); 257*4887Schin if(sfputu(outfile,n+1)<0) 258*4887Schin return(-1); 259*4887Schin return(outstring(outfile,string,n)); 260*4887Schin } 261