xref: /onnv-gate/usr/src/lib/libshell/common/sh/tdump.c (revision 12068:08a39a083754)
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