2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* $XConsortium: deparse.c /main/3 1996/05/08 19:39:37 drk $ */
24 /***************************************************************
26 * AT&T - PROPRIETARY *
28 * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF *
29 * AT&T BELL LABORATORIES *
30 * AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN *
31 * ACCORDANCE WITH APPLICABLE AGREEMENTS *
33 * Copyright (c) 1995 AT&T Corp. *
34 * Unpublished & Not for Publication *
35 * All Rights Reserved *
37 * The copyright notice above does not evidence any *
38 * actual or intended publication of such source code *
40 * This software was created by the *
41 * Advanced Software Technology Department *
42 * AT&T Bell Laboratories *
44 * For further information contact *
45 * {research,attmail}!dgk *
47 ***************************************************************/
49 /* : : generated by proto : : */
51 #if !defined(__PROTO__)
52 #if defined(__STDC__) || defined(__cplusplus) || defined(_proto) || defined(c_plusplus)
53 #if defined(__cplusplus)
54 #define __MANGLE__ "C"
59 #define __PROTO__(x) x
61 #define __PARAM__(n,o) n
62 #if !defined(__STDC__) && !defined(__cplusplus)
63 #if !defined(c_plusplus)
74 #define __PROTO__(x) ()
75 #define __OTORP__(x) x
76 #define __PARAM__(n,o) o
84 #if defined(__cplusplus) || defined(c_plusplus)
85 #define __VARARG__ ...
89 #if defined(__STDARG__)
90 #define __VA_START__(p,a) va_start(p,a)
92 #define __VA_START__(p,a) va_start(p)
100 #define HUGE_INT (((unsigned)-1)>>1)
108 /* flags that can be specified with p_tree() */
112 static void p_comlist __PROTO__((const struct dolnod*,int));
113 static void p_arg __PROTO__((const struct argnod*, int endchar, int opts));
114 static void p_comarg __PROTO__((const struct comnod*));
115 static void p_keyword __PROTO__((const char*,int));
116 static void p_redirect __PROTO__((const struct ionod*));
117 static void p_switch __PROTO__((const struct regnod*));
118 static void here_body __PROTO__((const struct ionod*));
119 static void p_tree __PROTO__((const union anynode*,int));
122 static int begin_line;
124 static char io_op[5];
125 static char un_op[3] = "-?";
126 static const struct ionod *here_doc;
127 static Sfio_t *outfile;
128 static const char *forinit = "";
130 extern __MANGLE__ void sh_deparse __PROTO__((Sfio_t*, const union anynode*,int));
132 void sh_deparse __PARAM__((Sfio_t *out, const union anynode *t,int tflags), (out, t, tflags)) __OTORP__(Sfio_t *out; const union anynode *t;int tflags;){
137 * print script corresponding to shell tree <t>
139 static void p_tree __PARAM__((register const union anynode *t,register int tflags), (t, tflags)) __OTORP__(register const union anynode *t;register int tflags;){
142 int needbrace = (tflags&NEED_BRACE);
143 tflags &= ~NEED_BRACE;
144 if(tflags&NO_NEWLINE)
148 switch(t->tre.tretyp&COMMSK)
151 if(t->tre.tretyp&COMSCAN)
152 p_keyword("!",BEGIN);
154 p_keyword("time",BEGIN);
156 p_tree(t->par.partre,tflags);
161 if(begin_line && level>0)
162 sfnputc(outfile,'\t',level);
164 p_comarg((struct comnod*)t);
168 if(t->tre.tretyp&FPCL)
171 tflags = NO_NEWLINE|NEED_BRACE;
172 p_tree(t->fork.forktre,tflags);
173 p_redirect(t->fork.forkio);
178 tflags |= NEED_BRACE;
179 if(t->tre.tretyp&(FAMP|FCOOP))
181 tflags = NEED_BRACE|NO_NEWLINE;
184 else if(t->fork.forkio)
186 p_tree(t->fork.forktre,tflags);
188 p_redirect(t->fork.forkio);
189 if(t->tre.tretyp&FCOOP)
191 sfputr(outfile,"|&",'\n');
194 else if(t->tre.tretyp&FAMP)
196 sfputr(outfile,"&",'\n');
202 p_keyword("if",BEGIN);
203 p_tree(t->if_.iftre,0);
204 p_keyword("then",MIDDLE);
205 p_tree(t->if_.thtre,0);
208 p_keyword("else",MIDDLE);
209 p_tree(t->if_.eltre,0);
217 else if(t->tre.tretyp&COMSCAN)
224 struct argnod *arg = (t->wh.whtre)->ar.arexpr;
225 struct argnod *incr = (t->wh.whinc)->arexpr;
226 sfprintf(outfile,"(( %s; ",forinit);
228 sfputr(outfile,arg->argflag&ARG_RAW?sh_fmtq(arg->argval):arg->argval,';');
229 arg = (t->wh.whinc)->arexpr;
230 sfprintf(outfile," %s))\n",arg->argflag&ARG_RAW?sh_fmtq(arg->argval):arg->argval);
233 p_tree(t->wh.whtre,0);
239 union anynode *tr = t->lst.lstrit;
240 if(tr->tre.tretyp==TWH && tr->wh.whinc && t->lst.lstlef->tre.tretyp==TARITH)
242 /* arithmetic for statement */
243 struct argnod *init = (t->lst.lstlef)->ar.arexpr;
244 forinit= (init->argflag&ARG_RAW)?sh_fmtq(init->argval):tr->arg.argval;
245 p_tree(t->lst.lstrit,tflags);
249 p_keyword("{",BEGIN);
250 p_tree(t->lst.lstlef,0);
253 p_tree(t->lst.lstrit,tflags);
268 p_tree(t->lst.lstlef,NEED_BRACE|NO_NEWLINE);
269 sfputr(outfile,cp,' ');
271 p_tree(t->lst.lstrit,tflags|NEED_BRACE);
276 p_keyword("(",BEGIN);
277 p_tree(t->par.partre,0);
283 register struct argnod *ap = t->ar.arexpr;
284 if(begin_line && level)
285 sfnputc(outfile,'\t',level);
286 sfprintf(outfile,"(( %s ))%c",ap->argflag&ARG_RAW?sh_fmtq(ap->argval):ap->argval,end_line);
287 if(!(tflags&NO_NEWLINE))
293 cp = (t->tre.tretyp==TSELECT?"select":"for");
295 sfputr(outfile,t->for_.fornam,' ');
298 sfputr(outfile,"in",' ');
301 p_comarg(t->for_.forlst);
305 sfputc(outfile,'\n');
309 p_keyword("do",MIDDLE);
311 p_keyword("done",END);
315 p_keyword("case",BEGIN);
316 p_arg(t->sw.swarg,' ',0);
320 sfputr(outfile,"in",'\n');
323 p_switch(t->sw.swlst);
326 p_keyword("esac",END);
330 if(t->tre.tretyp&FPOSIX)
332 sfprintf(outfile,"%s",t->funct.functnam);
333 p_keyword("()\n",BEGIN);
337 p_keyword("function",BEGIN);
338 tflags = (t->funct.functargs?' ':'\n');
339 sfputr(outfile,t->funct.functnam,tflags);
340 if(t->funct.functargs)
344 p_comarg(t->funct.functargs);
349 p_keyword("{\n",MIDDLE);
351 p_tree(t->funct.functtre,0);
354 /* new test compound command */
356 p_keyword("[[",BEGIN);
357 if((t->tre.tretyp&TPAREN)==TPAREN)
359 p_keyword("(",BEGIN);
360 p_tree(t->funct.functtre,0);
365 tflags = (t->tre.tretyp)>>TSHIFT;
366 if(t->tre.tretyp&TNEGATE)
367 sfputr(outfile,"!",' ');
368 if(t->tre.tretyp&TUNARY)
371 sfputr(outfile,un_op,' ');
374 cp = ((char*)(shtab_testops+(tflags&037)-1)->sh_name);
375 p_arg(&(t->lst.lstlef->arg),' ',0);
376 if(t->tre.tretyp&TBINARY)
378 sfputr(outfile,cp,' ');
379 p_arg(&(t->lst.lstrit->arg),' ',0);
384 while(begin_line && here_doc)
395 * increment indent level for flag==BEGIN
396 * decrement indent level for flag==END
398 static void p_keyword __PARAM__((const char *word,int flag), (word, flag)) __OTORP__(const char *word;int flag;){
408 if(begin_line && level)
409 sfnputc(outfile,'\t',level);
410 sfputr(outfile,word,sep);
419 static void p_arg __PARAM__((register const struct argnod *arg,register int endchar,int opts), (arg, endchar, opts)) __OTORP__(register const struct argnod *arg;register int endchar;int opts;){
420 register const char *cp;
428 /* case alternation lists in reverse order */
429 p_arg(arg->argnxt.ap,'|',opts);
437 /* compound assignment */
438 struct fornod *fp=(struct fornod*)arg->argchn.ap;
439 sfprintf(outfile,"%s=(\n",fp->fornam);
440 sfnputc(outfile,'\t',++level);
441 p_tree(fp->fortre,0);
443 sfnputc(outfile,'\t',level);
446 else if((arg->argflag&ARG_RAW) && (cp[1] || (*cp!='[' && *cp!=']')))
448 sfputr(outfile,cp,flag);
451 arg = arg->argnxt.ap;
453 while((opts&POST) && arg);
457 static void p_redirect __PARAM__((register const struct ionod *iop), (iop)) __OTORP__(register const struct ionod *iop;){
460 for(;iop;iop=iop->ionxt)
464 *cp = '0'+(iof&IOUFD);
481 else if(iof&(IORDW|IOAPP))
489 iop->iolink = (char*)here_doc;
498 sfputr(outfile,cp,' ');
503 if((iof=end_line)=='\n')
508 if(!(iop->iofile&IODOC))
509 sfwrite(outfile,"''",2);
510 sfputr(outfile,sh_fmtq(iop->iodelim),iof);
512 else if(iop->iofile&IORAW)
513 sfputr(outfile,sh_fmtq(iop->ioname),iof);
515 sfputr(outfile,iop->ioname,iof);
520 static void p_comarg __PARAM__((const register struct comnod *com), (com)) __OTORP__(const register struct comnod *com;){
521 register int flag = end_line;
522 if(com->comarg || com->comio)
525 p_arg(com->comset,flag,POST);
530 if(com->comtyp&COMSCAN)
531 p_arg(com->comarg,flag,POST);
533 p_comlist((struct dolnod*)com->comarg,flag);
536 p_redirect(com->comio);
540 static void p_comlist __PARAM__((const struct dolnod *dol,int endchar), (dol, endchar)) __OTORP__(const struct dolnod *dol;int endchar;){
541 register char *cp, *const*argv;
542 register int flag = ' ', special;
543 argv = dol->dolval+ARG_SPARE;
545 special = (*cp=='[' && cp[1]==0);
554 if((flag=endchar)=='\n')
556 special = (*cp==']' && cp[1]==0);
558 sfputr(outfile,special?cp:sh_fmtq(cp),flag);
565 static void p_switch __PARAM__((register const struct regnod *reg), (reg)) __OTORP__(register const struct regnod *reg;){
567 sfnputc(outfile,'\t',level-1);
568 p_arg(reg->regptr,')',PRE);
570 sfputc(outfile,'\t');
572 p_tree(reg->regcom,0);
579 p_switch(reg->regnxt);
584 * output here documents
586 static void here_body __PARAM__((register const struct ionod *iop), (iop)) __OTORP__(register const struct ionod *iop;){
590 here_body((struct inode*)iop->iolink);
593 if(iop->iofile&IOSTRG)
594 infile = sfnew((Sfio_t*)0,iop->ioname,iop->iosize,-1,SF_STRING|SF_READ);
596 sfseek(infile=sh.heredocs,iop->iooffset,SEEK_SET);
597 sfmove(infile,outfile,iop->iosize,-1);
598 if(iop->iofile&IOSTRG)
600 sfputr(outfile,iop->iodelim,'\n');