14887Schin /***********************************************************************
24887Schin * *
34887Schin * This software is part of the ast package *
4*12068SRoger.Faulkner@Oracle.COM * Copyright (c) 1982-2010 AT&T Intellectual Property *
54887Schin * and is licensed under the *
64887Schin * Common Public License, Version 1.0 *
78462SApril.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 "defs.h"
304887Schin #include "shnodes.h"
314887Schin #include "path.h"
324887Schin #include "io.h"
33*12068SRoger.Faulkner@Oracle.COM #include <ccode.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
sh_tdump(Sfio_t * out,const Shnode_t * t)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 */
outstring(Sfio_t * out,const char * string,int n)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 */
p_tree(register const Shnode_t * t)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
p_arg(register const struct argnod * arg)1574887Schin static int p_arg(register const struct argnod *arg)
1584887Schin {
1594887Schin register int n;
1604887Schin struct fornod *fp;
1614887Schin while(arg)
1624887Schin {
1638462SApril.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
p_redirect(register const struct ionod * iop)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
p_comarg(register const struct comnod * com)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
p_comlist(const struct dolnod * dol)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
p_switch(register const struct regnod * reg)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
p_string(register const char * string)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