da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner* Copyright (c) 1982-2010 AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* http://www.opensource.org/licenses/cpl1.0.txt *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#pragma prototyped
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * David Korn
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * AT&T Labs
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * shell deparser
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "defs.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "shnodes.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "test.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define HUGE_INT (((unsigned)-1)>>1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define BEGIN 0
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define MIDDLE 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define END 2
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define PRE 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define POST 2
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* flags that can be specified with p_tree() */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define NO_NEWLINE 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define NEED_BRACE 2
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define NO_BRACKET 4
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void p_comlist(const struct dolnod*,int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void p_arg(const struct argnod*, int endchar, int opts);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void p_comarg(const struct comnod*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void p_keyword(const char*,int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void p_redirect(const struct ionod*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void p_switch(const struct regnod*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void here_body(const struct ionod*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void p_tree(const Shnode_t*,int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int level;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int begin_line;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int end_line;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char io_op[7];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char un_op[3] = "-?";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic const struct ionod *here_doc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Sfio_t *outfile;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic const char *forinit = "";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern void sh_deparse(Sfio_t*, const Shnode_t*,int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid sh_deparse(Sfio_t *out, const Shnode_t *t,int tflags)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin outfile = out;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_tree(t,tflags);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * print script corresponding to shell tree <t>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void p_tree(register const Shnode_t *t,register int tflags)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int save = end_line;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int needbrace = (tflags&NEED_BRACE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tflags &= ~NEED_BRACE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(tflags&NO_NEWLINE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin end_line = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin end_line = '\n';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch(t->tre.tretyp&COMMSK)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TTIME:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(t->tre.tretyp&COMSCAN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_keyword("!",BEGIN);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_keyword("time",BEGIN);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(t->par.partre)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_tree(t->par.partre,tflags);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin level--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TCOM:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(begin_line && level>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfnputc(outfile,'\t',level);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin begin_line = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_comarg((struct comnod*)t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TSETIO:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(t->tre.tretyp&FPCL)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tflags |= NEED_BRACE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tflags = NO_NEWLINE|NEED_BRACE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_tree(t->fork.forktre,tflags);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_redirect(t->fork.forkio);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TFORK:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(needbrace)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tflags |= NEED_BRACE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(t->tre.tretyp&(FAMP|FCOOP))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tflags = NEED_BRACE|NO_NEWLINE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin end_line = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(t->fork.forkio)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tflags = NO_NEWLINE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_tree(t->fork.forktre,tflags);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(t->fork.forkio)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_redirect(t->fork.forkio);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(t->tre.tretyp&FCOOP)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(outfile,"|&",'\n');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin begin_line = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(t->tre.tretyp&FAMP)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(outfile,"&",'\n');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin begin_line = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TIF:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_keyword("if",BEGIN);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_tree(t->if_.iftre,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_keyword("then",MIDDLE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_tree(t->if_.thtre,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(t->if_.eltre)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_keyword("else",MIDDLE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_tree(t->if_.eltre,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_keyword("fi",END);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TWH:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(t->wh.whinc)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = "for";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(t->tre.tretyp&COMSCAN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = "until";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = "while";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_keyword(cp,BEGIN);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(t->wh.whinc)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct argnod *arg = (t->wh.whtre)->ar.arexpr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(outfile,"(( %s; ",forinit);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin forinit = "";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(outfile,arg->argval,';');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin arg = (t->wh.whinc)->arexpr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(outfile," %s))\n",arg->argval);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_tree(t->wh.whtre,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = t->wh.dotre;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto dolist;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TLST:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Shnode_t *tr = t->lst.lstrit;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(tr->tre.tretyp==TWH && tr->wh.whinc && t->lst.lstlef->tre.tretyp==TARITH)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* arithmetic for statement */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct argnod *init = (t->lst.lstlef)->ar.arexpr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin forinit= init->argval;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_tree(t->lst.lstrit,tflags);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(needbrace)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_keyword("{",BEGIN);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_tree(t->lst.lstlef,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(needbrace)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tflags = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_tree(t->lst.lstrit,tflags);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(needbrace)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_keyword("}",END);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TAND:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = "&&";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto andor;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TORF:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = "||";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto andor;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TFIL:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = "|";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin andor:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int bracket = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(t->tre.tretyp&TTEST)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tflags |= NO_NEWLINE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(tflags&NO_BRACKET))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_keyword("[[",BEGIN);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tflags |= NO_BRACKET;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bracket=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_tree(t->lst.lstlef,NEED_BRACE|NO_NEWLINE|(tflags&NO_BRACKET));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(outfile,cp,here_doc?'\n':' ');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(here_doc)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin here_body(here_doc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin here_doc = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin level++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_tree(t->lst.lstrit,tflags|NEED_BRACE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(bracket)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_keyword("]]",END);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin level--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TPAR:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_keyword("(",BEGIN);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_tree(t->par.partre,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_keyword(")",END);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TARITH:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct argnod *ap = t->ar.arexpr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(begin_line && level)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfnputc(outfile,'\t',level);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(outfile,"(( %s ))%c",ap->argval,end_line);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(tflags&NO_NEWLINE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin begin_line=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TFOR:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = ((t->tre.tretyp&COMSCAN)?"select":"for");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_keyword(cp,BEGIN);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(outfile,t->for_.fornam,' ');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(t->for_.forlst)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(outfile,"in",' ');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tflags = end_line;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin end_line = '\n';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_comarg(t->for_.forlst);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin end_line = tflags;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputc(outfile,'\n');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin begin_line = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = t->for_.fortre;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dolist:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_keyword("do",MIDDLE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_tree(t,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_keyword("done",END);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TSW:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_keyword("case",BEGIN);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_arg(t->sw.swarg,' ',0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(t->sw.swlst)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin begin_line = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(outfile,"in",'\n');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tflags = end_line;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin end_line = '\n';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_switch(t->sw.swlst);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin end_line = tflags;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_keyword("esac",END);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TFUN:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(t->tre.tretyp&FPOSIX)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(outfile,"%s",t->funct.functnam);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_keyword("()\n",BEGIN);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_keyword("function",BEGIN);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tflags = (t->funct.functargs?' ':'\n');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(outfile,t->funct.functnam,tflags);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(t->funct.functargs)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tflags = end_line;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin end_line = '\n';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_comarg(t->funct.functargs);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin end_line = tflags;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin begin_line = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_keyword("{\n",MIDDLE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin begin_line = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_tree(t->funct.functtre,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_keyword("}",END);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* new test compound command */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TTST:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(tflags&NO_BRACKET))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_keyword("[[",BEGIN);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((t->tre.tretyp&TPAREN)==TPAREN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_keyword("(",BEGIN);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_tree(t->lst.lstlef,NO_BRACKET|NO_NEWLINE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_keyword(")",END);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int flags = (t->tre.tretyp)>>TSHIFT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(t->tre.tretyp&TNEGATE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(outfile,"!",' ');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(t->tre.tretyp&TUNARY)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin un_op[1] = flags;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(outfile,un_op,' ');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = ((char*)(shtab_testops+(flags&037)-1)->sh_name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_arg(&(t->lst.lstlef->arg),' ',0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(t->tre.tretyp&TBINARY)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(outfile,cp,' ');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_arg(&(t->lst.lstrit->arg),' ',0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(tflags&NO_BRACKET))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_keyword("]]",END);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(begin_line && here_doc)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin here_body(here_doc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin here_doc = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin end_line = save;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * print a keyword
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * increment indent level for flag==BEGIN
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * decrement indent level for flag==END
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void p_keyword(const char *word,int flag)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int sep;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flag==END)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sep = end_line;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(*word=='[' || *word=='(')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sep = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sep = '\t';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flag!=BEGIN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin level--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(begin_line && level)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfnputc(outfile,'\t',level);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(outfile,word,sep);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sep=='\n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin begin_line=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin begin_line=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flag!=END)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin level++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void p_arg(register const struct argnod *arg,register int endchar,int opts)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register const char *cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int flag;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!arg->argnxt.ap)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flag = endchar;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(opts&PRE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* case alternation lists in reverse order */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_arg(arg->argnxt.ap,'|',opts);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flag = endchar;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(opts)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flag = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = arg->argval;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*cp==0 && opts==POST && arg->argchn.ap)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* compound assignment */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct fornod *fp=(struct fornod*)arg->argchn.ap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(outfile,"%s=(\n",fp->fornam);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfnputc(outfile,'\t',++level);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_tree(fp->fortre,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(--level)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfnputc(outfile,'\t',level);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputc(outfile,')');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if((arg->argflag&ARG_RAW) && (cp[1] || (*cp!='[' && *cp!=']')))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = sh_fmtq(cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(outfile,cp,flag);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flag=='\n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin begin_line = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin arg = arg->argnxt.ap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while((opts&POST) && arg);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void p_redirect(register const struct ionod *iop)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int iof,iof2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(;iop;iop=iop->ionxt)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iof=iop->iofile;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = io_op;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(iop->iovname)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfwrite(outfile,"(;",2);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(outfile,iop->iovname,')');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *cp = '0'+(iof&IOUFD);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(iof&IOPUT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*cp == '1' && !iop->iovname)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin io_op[1] = '>';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*cp == '0' && !iop->iovname)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin io_op[1] = '<';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin io_op[2] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin io_op[3] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(iof&IOLSEEK)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin io_op[1] = '#';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(iof&IOARITH)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strcpy(&io_op[3]," ((");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(iof&IOMOV)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin io_op[2] = '&';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(iof&(IORDW|IOAPP))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin io_op[2] = '>';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(iof&IOCLOB)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin io_op[2] = '|';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(iop->iodelim)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* here document */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef xxx
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iop->iolink = (char*)here_doc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin here_doc = iop;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin io_op[2] = '<';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef future
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(iof&IOSTRIP)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin io_op[3] = '-';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(outfile,cp,' ');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(iop->ionxt)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iof = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((iof=end_line)=='\n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin begin_line = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((iof&IOLSEEK) && (iof&IOARITH))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iof2 = iof, iof = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(iop->iodelim)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(iop->iofile&IODOC))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfwrite(outfile,"''",2);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(outfile,sh_fmtq(iop->iodelim),iof);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(iop->iofile&IORAW)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(outfile,sh_fmtq(iop->ioname),iof);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(outfile,iop->ioname,iof);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((iof&IOLSEEK) && (iof&IOARITH))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(outfile, "))", iof2);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void p_comarg(register const struct comnod *com)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int flag = end_line;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(com->comarg || com->comio)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flag = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(com->comset)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_arg(com->comset,flag,POST);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(com->comarg)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!com->comio)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flag = end_line;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(com->comtyp&COMSCAN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_arg(com->comarg,flag,POST);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_comlist((struct dolnod*)com->comarg,flag);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(com->comio)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_redirect(com->comio);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void p_comlist(const struct dolnod *dol,int endchar)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *cp, *const*argv;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int flag = ' ', special;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv = dol->dolval+ARG_SPARE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = *argv;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin special = (*cp=='[' && cp[1]==0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(cp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = "";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*argv==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((flag=endchar)=='\n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin begin_line = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin special = (*cp==']' && cp[1]==0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(outfile,special?cp:sh_fmtq(cp),flag);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin special = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(cp = *argv);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void p_switch(register const struct regnod *reg)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(level>1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfnputc(outfile,'\t',level-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_arg(reg->regptr,')',PRE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin begin_line = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputc(outfile,'\t');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(reg->regcom)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_tree(reg->regcom,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin level++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(reg->regflag)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_keyword(";&",END);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_keyword(";;",END);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(reg->regnxt)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_switch(reg->regnxt);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * output here documents
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void here_body(register const struct ionod *iop)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfio_t *infile;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef xxx
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(iop->iolink)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin here_body((struct inode*)iop->iolink);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iop->iolink = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(iop->iofile&IOSTRG)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin infile = sfnew((Sfio_t*)0,iop->ioname,iop->iosize,-1,SF_STRING|SF_READ);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfseek(infile=sh.heredocs,iop->iooffset,SEEK_SET);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfmove(infile,outfile,iop->iosize,-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(iop->iofile&IOSTRG)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfclose(infile);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(outfile,iop->iodelim,'\n');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin