14887Schin /*********************************************************************** 24887Schin * * 34887Schin * This software is part of the ast package * 4*8462SApril.Chin@Sun.COM * Copyright (c) 1982-2008 AT&T Intellectual Property * 54887Schin * and is licensed under the * 64887Schin * Common Public License, Version 1.0 * 7*8462SApril.Chin@Sun.COM * by AT&T Intellectual Property * 84887Schin * * 94887Schin * A copy of the License is available at * 104887Schin * http://www.opensource.org/licenses/cpl1.0.txt * 114887Schin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 124887Schin * * 134887Schin * Information and Software Systems Research * 144887Schin * AT&T Research * 154887Schin * Florham Park NJ * 164887Schin * * 174887Schin * David Korn <dgk@research.att.com> * 184887Schin * * 194887Schin ***********************************************************************/ 204887Schin #pragma prototyped 214887Schin /* 224887Schin * David Korn 234887Schin * AT&T Labs 244887Schin * 254887Schin * shell parse tree dump 264887Schin * 274887Schin */ 284887Schin 294887Schin #include <ccode.h> 304887Schin #include "defs.h" 314887Schin #include "shnodes.h" 324887Schin #include "path.h" 334887Schin #include "io.h" 344887Schin 354887Schin static int p_comlist(const struct dolnod*); 364887Schin static int p_arg(const struct argnod*); 374887Schin static int p_comarg(const struct comnod*); 384887Schin static int p_redirect(const struct ionod*); 394887Schin static int p_switch(const struct regnod*); 404887Schin static int p_tree(const Shnode_t*); 414887Schin static int p_string(const char*); 424887Schin 434887Schin static Sfio_t *outfile; 444887Schin 454887Schin int sh_tdump(Sfio_t *out, const Shnode_t *t) 464887Schin { 474887Schin outfile = out; 484887Schin return(p_tree(t)); 494887Schin } 504887Schin 514887Schin /* 524887Schin * convert to ASCII to write and back again if needed 534887Schin */ 544887Schin static int outstring(Sfio_t *out, const char *string, int n) 554887Schin { 564887Schin int r; 574887Schin char *cp = (char*)string; 584887Schin ccmaps(cp, n, CC_NATIVE, CC_ASCII); 594887Schin r = sfwrite(out,cp,n); 604887Schin ccmaps(cp, n, CC_ASCII, CC_NATIVE); 614887Schin return(r); 624887Schin } 634887Schin 644887Schin /* 654887Schin * print script corresponding to shell tree <t> 664887Schin */ 674887Schin static int p_tree(register const Shnode_t *t) 684887Schin { 694887Schin if(!t) 704887Schin return(sfputl(outfile,-1)); 714887Schin if(sfputl(outfile,t->tre.tretyp)<0) 724887Schin return(-1); 734887Schin switch(t->tre.tretyp&COMMSK) 744887Schin { 754887Schin case TTIME: 764887Schin case TPAR: 774887Schin return(p_tree(t->par.partre)); 784887Schin case TCOM: 794887Schin return(p_comarg((struct comnod*)t)); 804887Schin case TSETIO: 814887Schin case TFORK: 824887Schin if(sfputu(outfile,t->fork.forkline)<0) 834887Schin return(-1); 844887Schin if(p_tree(t->fork.forktre)<0) 854887Schin return(-1); 864887Schin return(p_redirect(t->fork.forkio)); 874887Schin case TIF: 884887Schin if(p_tree(t->if_.iftre)<0) 894887Schin return(-1); 904887Schin if(p_tree(t->if_.thtre)<0) 914887Schin return(-1); 924887Schin return(p_tree(t->if_.eltre)); 934887Schin case TWH: 944887Schin if(t->wh.whinc) 954887Schin { 964887Schin if(p_tree((Shnode_t*)(t->wh.whinc))<0) 974887Schin return(-1); 984887Schin } 994887Schin else 1004887Schin { 1014887Schin if(sfputl(outfile,-1)<0) 1024887Schin return(-1); 1034887Schin } 1044887Schin if(p_tree(t->wh.whtre)<0) 1054887Schin return(-1); 1064887Schin return(p_tree(t->wh.dotre)); 1074887Schin case TLST: 1084887Schin case TAND: 1094887Schin case TORF: 1104887Schin case TFIL: 1114887Schin if(p_tree(t->lst.lstlef)<0) 1124887Schin return(-1); 1134887Schin return(p_tree(t->lst.lstrit)); 1144887Schin case TARITH: 1154887Schin if(sfputu(outfile,t->ar.arline)<0) 1164887Schin return(-1); 1174887Schin return(p_arg(t->ar.arexpr)); 1184887Schin case TFOR: 1194887Schin if(sfputu(outfile,t->for_.forline)<0) 1204887Schin return(-1); 1214887Schin if(p_tree(t->for_.fortre)<0) 1224887Schin return(-1); 1234887Schin if(p_string(t->for_.fornam)<0) 1244887Schin return(-1); 1254887Schin return(p_tree((Shnode_t*)t->for_.forlst)); 1264887Schin case TSW: 1274887Schin if(sfputu(outfile,t->sw.swline)<0) 1284887Schin return(-1); 1294887Schin if(p_arg(t->sw.swarg)<0) 1304887Schin return(-1); 1314887Schin return(p_switch(t->sw.swlst)); 1324887Schin case TFUN: 1334887Schin if(sfputu(outfile,t->funct.functline)<0) 1344887Schin return(-1); 1354887Schin if(p_string(t->funct.functnam)<0) 1364887Schin return(-1); 1374887Schin if(p_tree(t->funct.functtre)<0) 1384887Schin return(-1); 1394887Schin return(p_tree((Shnode_t*)t->funct.functargs)); 1404887Schin case TTST: 1414887Schin if(sfputu(outfile,t->tst.tstline)<0) 1424887Schin return(-1); 1434887Schin if((t->tre.tretyp&TPAREN)==TPAREN) 1444887Schin return(p_tree(t->lst.lstlef)); 1454887Schin else 1464887Schin { 1474887Schin if(p_arg(&(t->lst.lstlef->arg))<0) 1484887Schin return(-1); 1494887Schin if((t->tre.tretyp&TBINARY)) 1504887Schin return(p_arg(&(t->lst.lstrit->arg))); 1514887Schin return(0); 1524887Schin } 1534887Schin } 1544887Schin return(-1); 1554887Schin } 1564887Schin 1574887Schin static int p_arg(register const struct argnod *arg) 1584887Schin { 1594887Schin register int n; 1604887Schin struct fornod *fp; 1614887Schin while(arg) 1624887Schin { 163*8462SApril.Chin@Sun.COM if((n = strlen(arg->argval)) || (arg->argflag&~(ARG_APPEND|ARG_MESSAGE|ARG_QUOTED))) 1644887Schin fp=0; 1654887Schin else 1664887Schin { 1674887Schin fp=(struct fornod*)arg->argchn.ap; 1684887Schin n = strlen(fp->fornam)+1; 1694887Schin } 1704887Schin sfputu(outfile,n+1); 1714887Schin if(fp) 1724887Schin { 1734887Schin sfputc(outfile,0); 1744887Schin outstring(outfile,fp->fornam,n-1); 1754887Schin } 1764887Schin else 1774887Schin outstring(outfile,arg->argval,n); 1784887Schin sfputc(outfile,arg->argflag); 1794887Schin if(fp) 1804887Schin { 1814887Schin sfputu(outfile,fp->fortyp); 1824887Schin p_tree(fp->fortre); 1834887Schin } 1844887Schin arg = arg->argnxt.ap; 1854887Schin } 1864887Schin return(sfputu(outfile,0)); 1874887Schin } 1884887Schin 1894887Schin static int p_redirect(register const struct ionod *iop) 1904887Schin { 1914887Schin while(iop) 1924887Schin { 1934887Schin if(iop->iovname) 1944887Schin sfputl(outfile,iop->iofile|IOVNM); 1954887Schin else 1964887Schin sfputl(outfile,iop->iofile); 1974887Schin p_string(iop->ioname); 1984887Schin if(iop->iodelim) 1994887Schin { 2004887Schin p_string(iop->iodelim); 2014887Schin sfputl(outfile,iop->iosize); 2024887Schin sfseek(sh.heredocs,iop->iooffset,SEEK_SET); 2034887Schin sfmove(sh.heredocs,outfile, iop->iosize,-1); 2044887Schin } 2054887Schin else 2064887Schin sfputu(outfile,0); 2074887Schin if(iop->iovname) 2084887Schin p_string(iop->iovname); 2094887Schin iop = iop->ionxt; 2104887Schin } 2114887Schin return(sfputl(outfile,-1)); 2124887Schin } 2134887Schin 2144887Schin static int p_comarg(register const struct comnod *com) 2154887Schin { 2164887Schin p_redirect(com->comio); 2174887Schin p_arg(com->comset); 2184887Schin if(!com->comarg) 2194887Schin sfputl(outfile,-1); 2204887Schin else if(com->comtyp&COMSCAN) 2214887Schin p_arg(com->comarg); 2224887Schin else 2234887Schin p_comlist((struct dolnod*)com->comarg); 2244887Schin return(sfputu(outfile,com->comline)); 2254887Schin } 2264887Schin 2274887Schin static int p_comlist(const struct dolnod *dol) 2284887Schin { 2294887Schin register char *cp, *const*argv; 2304887Schin register int n; 2314887Schin argv = dol->dolval+ARG_SPARE; 2324887Schin while(cp = *argv) 2334887Schin argv++; 2344887Schin n = argv - (dol->dolval+1); 2354887Schin sfputl(outfile,n); 2364887Schin argv = dol->dolval+ARG_SPARE; 2374887Schin while(cp = *argv++) 2384887Schin p_string(cp); 2394887Schin return(sfputu(outfile,0)); 2404887Schin } 2414887Schin 2424887Schin static int p_switch(register const struct regnod *reg) 2434887Schin { 2444887Schin while(reg) 2454887Schin { 2464887Schin sfputl(outfile,reg->regflag); 2474887Schin p_arg(reg->regptr); 2484887Schin p_tree(reg->regcom); 2494887Schin reg = reg->regnxt; 2504887Schin } 2514887Schin return(sfputl(outfile,-1)); 2524887Schin } 2534887Schin 2544887Schin static int p_string(register const char *string) 2554887Schin { 2564887Schin register size_t n=strlen(string); 2574887Schin if(sfputu(outfile,n+1)<0) 2584887Schin return(-1); 2594887Schin return(outstring(outfile,string,n)); 2604887Schin } 261