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