1 /***********************************************************************
3 * This software is part of the ast package *
4 * Copyright (c) 1982-2010 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Common Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
9 * A copy of the License is available at *
10 * http://www.opensource.org/licenses/cpl1.0.txt *
11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
13 * Information and Software Systems Research *
17 * David Korn <dgk@research.att.com> *
19 ***********************************************************************/
25 * shell parse tree dump
35 static int p_comlist(const struct dolnod
*);
36 static int p_arg(const struct argnod
*);
37 static int p_comarg(const struct comnod
*);
38 static int p_redirect(const struct ionod
*);
39 static int p_switch(const struct regnod
*);
40 static int p_tree(const Shnode_t
*);
41 static int p_string(const char*);
43 static Sfio_t
*outfile
;
45 int sh_tdump(Sfio_t
*out
, const Shnode_t
*t
)
52 * convert to ASCII to write and back again if needed
54 static int outstring(Sfio_t
*out
, const char *string
, int n
)
57 char *cp
= (char*)string
;
58 ccmaps(cp
, n
, CC_NATIVE
, CC_ASCII
);
59 r
= sfwrite(out
,cp
,n
);
60 ccmaps(cp
, n
, CC_ASCII
, CC_NATIVE
);
65 * print script corresponding to shell tree <t>
67 static int p_tree(register const Shnode_t
*t
)
70 return(sfputl(outfile
,-1));
71 if(sfputl(outfile
,t
->tre
.tretyp
)<0)
73 switch(t
->tre
.tretyp
&COMMSK
)
77 return(p_tree(t
->par
.partre
));
79 return(p_comarg((struct comnod
*)t
));
82 if(sfputu(outfile
,t
->fork
.forkline
)<0)
84 if(p_tree(t
->fork
.forktre
)<0)
86 return(p_redirect(t
->fork
.forkio
));
88 if(p_tree(t
->if_
.iftre
)<0)
90 if(p_tree(t
->if_
.thtre
)<0)
92 return(p_tree(t
->if_
.eltre
));
96 if(p_tree((Shnode_t
*)(t
->wh
.whinc
))<0)
101 if(sfputl(outfile
,-1)<0)
104 if(p_tree(t
->wh
.whtre
)<0)
106 return(p_tree(t
->wh
.dotre
));
111 if(p_tree(t
->lst
.lstlef
)<0)
113 return(p_tree(t
->lst
.lstrit
));
115 if(sfputu(outfile
,t
->ar
.arline
)<0)
117 return(p_arg(t
->ar
.arexpr
));
119 if(sfputu(outfile
,t
->for_
.forline
)<0)
121 if(p_tree(t
->for_
.fortre
)<0)
123 if(p_string(t
->for_
.fornam
)<0)
125 return(p_tree((Shnode_t
*)t
->for_
.forlst
));
127 if(sfputu(outfile
,t
->sw
.swline
)<0)
129 if(p_arg(t
->sw
.swarg
)<0)
131 return(p_switch(t
->sw
.swlst
));
133 if(sfputu(outfile
,t
->funct
.functline
)<0)
135 if(p_string(t
->funct
.functnam
)<0)
137 if(p_tree(t
->funct
.functtre
)<0)
139 return(p_tree((Shnode_t
*)t
->funct
.functargs
));
141 if(sfputu(outfile
,t
->tst
.tstline
)<0)
143 if((t
->tre
.tretyp
&TPAREN
)==TPAREN
)
144 return(p_tree(t
->lst
.lstlef
));
147 if(p_arg(&(t
->lst
.lstlef
->arg
))<0)
149 if((t
->tre
.tretyp
&TBINARY
))
150 return(p_arg(&(t
->lst
.lstrit
->arg
)));
157 static int p_arg(register const struct argnod
*arg
)
163 if((n
= strlen(arg
->argval
)) || (arg
->argflag
&~(ARG_APPEND
|ARG_MESSAGE
|ARG_QUOTED
)))
167 fp
=(struct fornod
*)arg
->argchn
.ap
;
168 n
= strlen(fp
->fornam
)+1;
174 outstring(outfile
,fp
->fornam
,n
-1);
177 outstring(outfile
,arg
->argval
,n
);
178 sfputc(outfile
,arg
->argflag
);
181 sfputu(outfile
,fp
->fortyp
);
184 arg
= arg
->argnxt
.ap
;
186 return(sfputu(outfile
,0));
189 static int p_redirect(register const struct ionod
*iop
)
194 sfputl(outfile
,iop
->iofile
|IOVNM
);
196 sfputl(outfile
,iop
->iofile
);
197 p_string(iop
->ioname
);
200 p_string(iop
->iodelim
);
201 sfputl(outfile
,iop
->iosize
);
202 sfseek(sh
.heredocs
,iop
->iooffset
,SEEK_SET
);
203 sfmove(sh
.heredocs
,outfile
, iop
->iosize
,-1);
208 p_string(iop
->iovname
);
211 return(sfputl(outfile
,-1));
214 static int p_comarg(register const struct comnod
*com
)
216 p_redirect(com
->comio
);
220 else if(com
->comtyp
&COMSCAN
)
223 p_comlist((struct dolnod
*)com
->comarg
);
224 return(sfputu(outfile
,com
->comline
));
227 static int p_comlist(const struct dolnod
*dol
)
229 register char *cp
, *const*argv
;
231 argv
= dol
->dolval
+ARG_SPARE
;
234 n
= argv
- (dol
->dolval
+1);
236 argv
= dol
->dolval
+ARG_SPARE
;
239 return(sfputu(outfile
,0));
242 static int p_switch(register const struct regnod
*reg
)
246 sfputl(outfile
,reg
->regflag
);
251 return(sfputl(outfile
,-1));
254 static int p_string(register const char *string
)
256 register size_t n
=strlen(string
);
257 if(sfputu(outfile
,n
+1)<0)
259 return(outstring(outfile
,string
,n
));