mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-02-15 04:32:24 +00:00
[v1.0] remove deparse.c
The shell code de-parser, which converts byte code back to shell source code, is unused. It was used in SHOPT_COSHELL, which was removed in3613da42
, and in ancient code for systems without fork(2), which was removed in7b0e0776
. Testing reveals it to be quite broken as it has not kept up with more recent changes in ksh. It is kept in the dev branch, as we intend to fix it up and use it for 'typeset -f FUNCTIONNAME' to output function definitions in a future release. (The current design, which outputs original source code direct from the source file, is fundamentally broken because the output of a function definition that was loaded from a file is corrupted if you edit the file after loading the function.)
This commit is contained in:
parent
89cec81b32
commit
a46c8e74f7
4 changed files with 2 additions and 617 deletions
|
@ -106,8 +106,7 @@ sh directory:
|
||||||
3. array.c contains the code for indexed and associative
|
3. array.c contains the code for indexed and associative
|
||||||
arrays.
|
arrays.
|
||||||
4. defs.c contains the data definitions for global symbols.
|
4. defs.c contains the data definitions for global symbols.
|
||||||
5. deparse.c contains code to generate shell script from
|
5. (removed)
|
||||||
a parse tree.
|
|
||||||
6. expand.c contains code for file name expansion and
|
6. expand.c contains code for file name expansion and
|
||||||
pathname expansion.
|
pathname expansion.
|
||||||
7. fault.c contains code for signal processing, trap
|
7. fault.c contains code for signal processing, trap
|
||||||
|
|
|
@ -322,17 +322,6 @@ make install
|
||||||
prev SHOPT.sh
|
prev SHOPT.sh
|
||||||
exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_PACKAGE_ast -D_API_ast=20100309 -DERROR_CONTEXT_T=Error_context_t -c bltins/cflow.c
|
exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_PACKAGE_ast -D_API_ast=20100309 -DERROR_CONTEXT_T=Error_context_t -c bltins/cflow.c
|
||||||
done cflow.o generated
|
done cflow.o generated
|
||||||
make deparse.o
|
|
||||||
make sh/deparse.c
|
|
||||||
prev include/test.h implicit
|
|
||||||
prev include/shnodes.h implicit
|
|
||||||
prev include/defs.h implicit
|
|
||||||
done sh/deparse.c
|
|
||||||
meta deparse.o %.c>%.o sh/deparse.c deparse
|
|
||||||
prev sh/deparse.c
|
|
||||||
prev SHOPT.sh
|
|
||||||
exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_API_ast=20100309 -D_PACKAGE_ast -DERROR_CONTEXT_T=Error_context_t -c sh/deparse.c
|
|
||||||
done deparse.o generated
|
|
||||||
make enum.o
|
make enum.o
|
||||||
make bltins/enum.c
|
make bltins/enum.c
|
||||||
prev include/defs.h implicit
|
prev include/defs.h implicit
|
||||||
|
@ -1376,7 +1365,7 @@ make install
|
||||||
prev SHOPT.sh
|
prev SHOPT.sh
|
||||||
exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_PACKAGE_ast -D_API_ast=20100309 -DERROR_CONTEXT_T=Error_context_t -c edit/hexpand.c
|
exec - ${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_PACKAGE_ast -D_API_ast=20100309 -DERROR_CONTEXT_T=Error_context_t -c edit/hexpand.c
|
||||||
done hexpand.o generated
|
done hexpand.o generated
|
||||||
exec - ${AR} rc libshell.a alarm.o cd_pwd.o cflow.o deparse.o enum.o getopts.o hist.o misc.o mkservice.o print.o read.o sleep.o trap.o test.o typeset.o ulimit.o umask.o whence.o main.o nvdisc.o nvtype.o arith.o args.o array.o completion.o defs.o edit.o expand.o regress.o fault.o fcin.o
|
exec - ${AR} rc libshell.a alarm.o cd_pwd.o cflow.o enum.o getopts.o hist.o misc.o mkservice.o print.o read.o sleep.o trap.o test.o typeset.o ulimit.o umask.o whence.o main.o nvdisc.o nvtype.o arith.o args.o array.o completion.o defs.o edit.o expand.o regress.o fault.o fcin.o
|
||||||
exec - ${AR} rc libshell.a history.o init.o io.o jobs.o lex.o macro.o name.o nvtree.o parse.o path.o string.o streval.o subshell.o tdump.o timers.o trestore.o waitevent.o xec.o limits.o msg.o strdata.o testops.o keywords.o options.o signals.o aliases.o builtins.o variables.o lexstates.o emacs.o vi.o hexpand.o
|
exec - ${AR} rc libshell.a history.o init.o io.o jobs.o lex.o macro.o name.o nvtree.o parse.o path.o string.o streval.o subshell.o tdump.o timers.o trestore.o waitevent.o xec.o limits.o msg.o strdata.o testops.o keywords.o options.o signals.o aliases.o builtins.o variables.o lexstates.o emacs.o vi.o hexpand.o
|
||||||
exec - (ranlib libshell.a) >/dev/null 2>&1 || true
|
exec - (ranlib libshell.a) >/dev/null 2>&1 || true
|
||||||
done libshell.a generated
|
done libshell.a generated
|
||||||
|
|
|
@ -120,7 +120,6 @@ extern Namval_t *sh_assignok(Namval_t*,int);
|
||||||
extern struct dolnod *sh_arguse(void);
|
extern struct dolnod *sh_arguse(void);
|
||||||
extern char *sh_checkid(char*,char*);
|
extern char *sh_checkid(char*,char*);
|
||||||
extern void sh_chktrap(void);
|
extern void sh_chktrap(void);
|
||||||
extern void sh_deparse(Sfio_t*,const Shnode_t*,int);
|
|
||||||
extern int sh_debug(const char*,const char*,const char*,char *const[],int);
|
extern int sh_debug(const char*,const char*,const char*,char *const[],int);
|
||||||
extern char **sh_envgen(void);
|
extern char **sh_envgen(void);
|
||||||
extern void sh_envnolocal(Namval_t*,void*);
|
extern void sh_envnolocal(Namval_t*,void*);
|
||||||
|
|
|
@ -1,602 +0,0 @@
|
||||||
/***********************************************************************
|
|
||||||
* *
|
|
||||||
* This software is part of the ast package *
|
|
||||||
* Copyright (c) 1982-2011 AT&T Intellectual Property *
|
|
||||||
* Copyright (c) 2020-2021 Contributors to ksh 93u+m *
|
|
||||||
* and is licensed under the *
|
|
||||||
* Eclipse Public License, Version 1.0 *
|
|
||||||
* by AT&T Intellectual Property *
|
|
||||||
* *
|
|
||||||
* A copy of the License is available at *
|
|
||||||
* http://www.eclipse.org/org/documents/epl-v10.html *
|
|
||||||
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
|
|
||||||
* *
|
|
||||||
* Information and Software Systems Research *
|
|
||||||
* AT&T Research *
|
|
||||||
* Florham Park NJ *
|
|
||||||
* *
|
|
||||||
* David Korn <dgk@research.att.com> *
|
|
||||||
* *
|
|
||||||
***********************************************************************/
|
|
||||||
/*
|
|
||||||
* David Korn
|
|
||||||
* AT&T Labs
|
|
||||||
*
|
|
||||||
* shell deparser
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "defs.h"
|
|
||||||
#include "shnodes.h"
|
|
||||||
#include "test.h"
|
|
||||||
|
|
||||||
|
|
||||||
#define HUGE_INT (((unsigned)-1)>>1)
|
|
||||||
#define BEGIN 0
|
|
||||||
#define MIDDLE 1
|
|
||||||
#define END 2
|
|
||||||
#define PRE 1
|
|
||||||
#define POST 2
|
|
||||||
|
|
||||||
|
|
||||||
/* flags that can be specified with p_tree() */
|
|
||||||
#define NO_NEWLINE (1 << 0)
|
|
||||||
#define NEED_BRACE (1 << 1)
|
|
||||||
#define NO_BRACKET (1 << 2)
|
|
||||||
#define PROCSUBST (1 << 3)
|
|
||||||
|
|
||||||
static void p_comlist(const struct dolnod*,int);
|
|
||||||
static void p_arg(const struct argnod*, int endchar, int opts);
|
|
||||||
static void p_comarg(const struct comnod*);
|
|
||||||
static void p_keyword(const char*,int);
|
|
||||||
static void p_redirect(const struct ionod*);
|
|
||||||
static void p_switch(const struct regnod*);
|
|
||||||
static void here_body(const struct ionod*);
|
|
||||||
static void p_tree(const Shnode_t*,int);
|
|
||||||
|
|
||||||
static int level;
|
|
||||||
static int begin_line;
|
|
||||||
static int end_line;
|
|
||||||
static char io_op[7];
|
|
||||||
static char un_op[3] = "-?";
|
|
||||||
static const struct ionod *here_doc;
|
|
||||||
static Sfio_t *outfile;
|
|
||||||
static const char *forinit = "";
|
|
||||||
|
|
||||||
void sh_deparse(Sfio_t *out, const Shnode_t *t,int tflags)
|
|
||||||
{
|
|
||||||
outfile = out;
|
|
||||||
p_tree(t,tflags);
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* print script corresponding to shell tree <t>
|
|
||||||
*/
|
|
||||||
static void p_tree(register const Shnode_t *t,register int tflags)
|
|
||||||
{
|
|
||||||
register char *cp=0;
|
|
||||||
int save = end_line;
|
|
||||||
int needbrace = (tflags&NEED_BRACE);
|
|
||||||
int procsub = (tflags&PROCSUBST);
|
|
||||||
tflags &= ~NEED_BRACE;
|
|
||||||
if(tflags&NO_NEWLINE)
|
|
||||||
end_line = ' ';
|
|
||||||
else if(procsub)
|
|
||||||
end_line = ')';
|
|
||||||
else
|
|
||||||
end_line = '\n';
|
|
||||||
switch(t->tre.tretyp&COMMSK)
|
|
||||||
{
|
|
||||||
case TTIME:
|
|
||||||
if(t->tre.tretyp&COMSCAN)
|
|
||||||
p_keyword("!",BEGIN);
|
|
||||||
else
|
|
||||||
p_keyword("time",BEGIN);
|
|
||||||
if(t->par.partre)
|
|
||||||
p_tree(t->par.partre,tflags);
|
|
||||||
level--;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TCOM:
|
|
||||||
if(begin_line && level>0)
|
|
||||||
sfnputc(outfile,'\t',level);
|
|
||||||
begin_line = 0;
|
|
||||||
p_comarg((struct comnod*)t);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TSETIO:
|
|
||||||
if(t->tre.tretyp&FPCL)
|
|
||||||
tflags |= NEED_BRACE;
|
|
||||||
else
|
|
||||||
tflags = NO_NEWLINE|NEED_BRACE;
|
|
||||||
p_tree(t->fork.forktre,tflags);
|
|
||||||
p_redirect(t->fork.forkio);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TFORK:
|
|
||||||
if(needbrace)
|
|
||||||
tflags |= NEED_BRACE;
|
|
||||||
if((t->tre.tretyp&(FAMP|FCOOP)) && (t->tre.tretyp&(FAMP|FINT))!=FAMP)
|
|
||||||
{
|
|
||||||
tflags = NEED_BRACE|NO_NEWLINE;
|
|
||||||
end_line = ' ';
|
|
||||||
}
|
|
||||||
else if(t->fork.forkio)
|
|
||||||
tflags = NO_NEWLINE;
|
|
||||||
p_tree(t->fork.forktre,tflags);
|
|
||||||
if(t->fork.forkio)
|
|
||||||
p_redirect(t->fork.forkio);
|
|
||||||
if(t->tre.tretyp&FCOOP)
|
|
||||||
{
|
|
||||||
sfputr(outfile,"|&",procsub?')':'\n');
|
|
||||||
begin_line = 1;
|
|
||||||
}
|
|
||||||
else if((t->tre.tretyp&(FAMP|FINT))==(FAMP|FINT))
|
|
||||||
{
|
|
||||||
sfputr(outfile,"&",procsub?')':'\n');
|
|
||||||
begin_line = 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TIF:
|
|
||||||
p_keyword("if",BEGIN);
|
|
||||||
p_tree(t->if_.iftre,0);
|
|
||||||
p_keyword("then",MIDDLE);
|
|
||||||
p_tree(t->if_.thtre,0);
|
|
||||||
if(t->if_.eltre)
|
|
||||||
{
|
|
||||||
p_keyword("else",MIDDLE);
|
|
||||||
p_tree(t->if_.eltre,0);
|
|
||||||
}
|
|
||||||
p_keyword("fi",END);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TWH:
|
|
||||||
if(t->wh.whinc)
|
|
||||||
cp = "for";
|
|
||||||
else if(t->tre.tretyp&COMSCAN)
|
|
||||||
cp = "until";
|
|
||||||
else
|
|
||||||
cp = "while";
|
|
||||||
p_keyword(cp,BEGIN);
|
|
||||||
if(t->wh.whinc)
|
|
||||||
{
|
|
||||||
struct argnod *arg = (t->wh.whtre)->ar.arexpr;
|
|
||||||
sfprintf(outfile,"(( %s; ",forinit);
|
|
||||||
forinit = "";
|
|
||||||
sfputr(outfile,arg->argval,';');
|
|
||||||
arg = (t->wh.whinc)->arexpr;
|
|
||||||
sfprintf(outfile," %s))\n",arg->argval);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
p_tree(t->wh.whtre,0);
|
|
||||||
t = t->wh.dotre;
|
|
||||||
goto dolist;
|
|
||||||
|
|
||||||
case TLST:
|
|
||||||
{
|
|
||||||
Shnode_t *tr = t->lst.lstrit;
|
|
||||||
if(tr->tre.tretyp==TWH && tr->wh.whinc && t->lst.lstlef->tre.tretyp==TARITH)
|
|
||||||
{
|
|
||||||
/* arithmetic for statement */
|
|
||||||
struct argnod *init = (t->lst.lstlef)->ar.arexpr;
|
|
||||||
forinit= init->argval;
|
|
||||||
p_tree(t->lst.lstrit,tflags);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(needbrace)
|
|
||||||
p_keyword("{",BEGIN);
|
|
||||||
p_tree(t->lst.lstlef,0);
|
|
||||||
if(needbrace)
|
|
||||||
tflags = 0;
|
|
||||||
p_tree(t->lst.lstrit,tflags);
|
|
||||||
if(needbrace)
|
|
||||||
p_keyword("}",END);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case TAND:
|
|
||||||
cp = "&&";
|
|
||||||
goto andor;
|
|
||||||
case TORF:
|
|
||||||
cp = "||";
|
|
||||||
goto andor;
|
|
||||||
case TFIL:
|
|
||||||
cp = "|";
|
|
||||||
andor:
|
|
||||||
{
|
|
||||||
int bracket = 0;
|
|
||||||
if(t->tre.tretyp&TTEST)
|
|
||||||
{
|
|
||||||
tflags |= NO_NEWLINE;
|
|
||||||
if(!(tflags&NO_BRACKET))
|
|
||||||
{
|
|
||||||
p_keyword("[[",BEGIN);
|
|
||||||
tflags |= NO_BRACKET;
|
|
||||||
bracket=1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
p_tree(t->lst.lstlef,NEED_BRACE|NO_NEWLINE|(tflags&NO_BRACKET));
|
|
||||||
if(tflags&FALTPIPE)
|
|
||||||
{
|
|
||||||
Shnode_t *tt = t->lst.lstrit;
|
|
||||||
if(tt->tre.tretyp!=TFIL || !(tt->lst.lstlef->tre.tretyp&FALTPIPE))
|
|
||||||
{
|
|
||||||
sfputc(outfile,'\n');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sfputr(outfile,cp,here_doc?'\n':' ');
|
|
||||||
if(here_doc)
|
|
||||||
{
|
|
||||||
here_body(here_doc);
|
|
||||||
here_doc = 0;
|
|
||||||
}
|
|
||||||
level++;
|
|
||||||
p_tree(t->lst.lstrit,tflags|NEED_BRACE);
|
|
||||||
if(bracket)
|
|
||||||
p_keyword("]]",END);
|
|
||||||
level--;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case TPAR:
|
|
||||||
p_keyword("(",BEGIN);
|
|
||||||
p_tree(t->par.partre,0);
|
|
||||||
p_keyword(")",END);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TARITH:
|
|
||||||
{
|
|
||||||
register struct argnod *ap = t->ar.arexpr;
|
|
||||||
if(begin_line && level)
|
|
||||||
sfnputc(outfile,'\t',level);
|
|
||||||
sfprintf(outfile,"(( %s ))%c",ap->argval,end_line);
|
|
||||||
if(!(tflags&NO_NEWLINE))
|
|
||||||
begin_line=1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case TFOR:
|
|
||||||
cp = ((t->tre.tretyp&COMSCAN)?"select":"for");
|
|
||||||
p_keyword(cp,BEGIN);
|
|
||||||
sfputr(outfile,t->for_.fornam,' ');
|
|
||||||
if(t->for_.forlst)
|
|
||||||
{
|
|
||||||
sfputr(outfile,"in",' ');
|
|
||||||
tflags = end_line;
|
|
||||||
end_line = '\n';
|
|
||||||
p_comarg(t->for_.forlst);
|
|
||||||
end_line = tflags;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
sfputc(outfile,'\n');
|
|
||||||
begin_line = 1;
|
|
||||||
t = t->for_.fortre;
|
|
||||||
dolist:
|
|
||||||
p_keyword("do",MIDDLE);
|
|
||||||
p_tree(t,0);
|
|
||||||
p_keyword("done",END);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TSW:
|
|
||||||
p_keyword("case",BEGIN);
|
|
||||||
p_arg(t->sw.swarg,' ',0);
|
|
||||||
if(t->sw.swlst)
|
|
||||||
{
|
|
||||||
begin_line = 1;
|
|
||||||
sfputr(outfile,"in",'\n');
|
|
||||||
tflags = end_line;
|
|
||||||
end_line = '\n';
|
|
||||||
p_switch(t->sw.swlst);
|
|
||||||
end_line = tflags;
|
|
||||||
}
|
|
||||||
p_keyword("esac",END);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TFUN:
|
|
||||||
if(t->tre.tretyp&FPOSIX)
|
|
||||||
{
|
|
||||||
sfprintf(outfile,"%s",t->funct.functnam);
|
|
||||||
p_keyword("()\n",BEGIN);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
p_keyword("function",BEGIN);
|
|
||||||
tflags = (t->funct.functargs?' ':'\n');
|
|
||||||
sfputr(outfile,t->funct.functnam,tflags);
|
|
||||||
if(t->funct.functargs)
|
|
||||||
{
|
|
||||||
tflags = end_line;
|
|
||||||
end_line = '\n';
|
|
||||||
p_comarg(t->funct.functargs);
|
|
||||||
end_line = tflags;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
begin_line = 1;
|
|
||||||
p_keyword("{\n",MIDDLE);
|
|
||||||
begin_line = 1;
|
|
||||||
p_tree(t->funct.functtre,0);
|
|
||||||
p_keyword("}",END);
|
|
||||||
break;
|
|
||||||
/* new test compound command */
|
|
||||||
case TTST:
|
|
||||||
if(!(tflags&NO_BRACKET))
|
|
||||||
p_keyword("[[",BEGIN);
|
|
||||||
if((t->tre.tretyp&TPAREN)==TPAREN)
|
|
||||||
{
|
|
||||||
p_keyword("(",BEGIN);
|
|
||||||
p_tree(t->lst.lstlef,NO_BRACKET|NO_NEWLINE);
|
|
||||||
p_keyword(")",END);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int flags = (t->tre.tretyp)>>TSHIFT;
|
|
||||||
if(t->tre.tretyp&TNEGATE)
|
|
||||||
sfputr(outfile,"!",' ');
|
|
||||||
if(t->tre.tretyp&TUNARY)
|
|
||||||
{
|
|
||||||
un_op[1] = flags;
|
|
||||||
sfputr(outfile,un_op,' ');
|
|
||||||
}
|
|
||||||
else
|
|
||||||
cp = ((char*)(shtab_testops+(flags&037)-1)->sh_name);
|
|
||||||
p_arg(&(t->lst.lstlef->arg),' ',0);
|
|
||||||
if(t->tre.tretyp&TBINARY)
|
|
||||||
{
|
|
||||||
sfputr(outfile,cp,' ');
|
|
||||||
p_arg(&(t->lst.lstrit->arg),' ',0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!(tflags&NO_BRACKET))
|
|
||||||
p_keyword("]]",END);
|
|
||||||
}
|
|
||||||
while(begin_line && here_doc)
|
|
||||||
{
|
|
||||||
here_body(here_doc);
|
|
||||||
here_doc = 0;
|
|
||||||
}
|
|
||||||
end_line = save;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* print a keyword
|
|
||||||
* increment indent level for flag==BEGIN
|
|
||||||
* decrement indent level for flag==END
|
|
||||||
*/
|
|
||||||
static void p_keyword(const char *word,int flag)
|
|
||||||
{
|
|
||||||
register int sep;
|
|
||||||
if(flag==END)
|
|
||||||
sep = end_line;
|
|
||||||
else if(*word=='[' || *word=='(')
|
|
||||||
sep = ' ';
|
|
||||||
else
|
|
||||||
sep = '\t';
|
|
||||||
if(flag!=BEGIN)
|
|
||||||
level--;
|
|
||||||
if(begin_line && level)
|
|
||||||
sfnputc(outfile,'\t',level);
|
|
||||||
sfputr(outfile,word,sep);
|
|
||||||
if(sep=='\n')
|
|
||||||
begin_line=1;
|
|
||||||
else
|
|
||||||
begin_line=0;
|
|
||||||
if(flag!=END)
|
|
||||||
level++;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void p_arg(register const struct argnod *arg,register int endchar,int opts)
|
|
||||||
{
|
|
||||||
register const char *cp;
|
|
||||||
register int flag=0;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if(!arg->argnxt.ap)
|
|
||||||
flag = endchar;
|
|
||||||
else if(opts&PRE)
|
|
||||||
{
|
|
||||||
/* case alternation lists in reverse order */
|
|
||||||
p_arg(arg->argnxt.ap,'|',opts);
|
|
||||||
flag = endchar;
|
|
||||||
}
|
|
||||||
else if(opts)
|
|
||||||
flag = ' ';
|
|
||||||
cp = arg->argval;
|
|
||||||
if(*cp==0 && (arg->argflag&ARG_EXP) && arg->argchn.ap)
|
|
||||||
{
|
|
||||||
/* process substitution */
|
|
||||||
int c = (arg->argflag&ARG_RAW)?'>':'<';
|
|
||||||
sfputc(outfile,c);
|
|
||||||
sfputc(outfile,'(');
|
|
||||||
p_tree((Shnode_t*)arg->argchn.ap,PROCSUBST);
|
|
||||||
}
|
|
||||||
else if(*cp==0 && opts==POST && arg->argchn.ap)
|
|
||||||
{
|
|
||||||
/* compound assignment */
|
|
||||||
struct fornod *fp=(struct fornod*)arg->argchn.ap;
|
|
||||||
sfprintf(outfile,"%s=(\n",fp->fornam);
|
|
||||||
sfnputc(outfile,'\t',++level);
|
|
||||||
p_tree(fp->fortre,0);
|
|
||||||
if(--level)
|
|
||||||
sfnputc(outfile,'\t',level);
|
|
||||||
sfputc(outfile,')');
|
|
||||||
}
|
|
||||||
else if((arg->argflag&ARG_RAW) && (cp[1] || (*cp!='[' && *cp!=']')))
|
|
||||||
cp = sh_fmtq(cp);
|
|
||||||
sfputr(outfile,cp,flag);
|
|
||||||
if(flag=='\n')
|
|
||||||
begin_line = 1;
|
|
||||||
arg = arg->argnxt.ap;
|
|
||||||
}
|
|
||||||
while((opts&POST) && arg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void p_redirect(register const struct ionod *iop)
|
|
||||||
{
|
|
||||||
register char *cp;
|
|
||||||
register int iof,iof2;
|
|
||||||
for(;iop;iop=iop->ionxt)
|
|
||||||
{
|
|
||||||
iof=iop->iofile;
|
|
||||||
cp = io_op;
|
|
||||||
if(iop->iovname)
|
|
||||||
{
|
|
||||||
sfwrite(outfile,"(;",2);
|
|
||||||
sfputr(outfile,iop->iovname,')');
|
|
||||||
cp++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
*cp = '0'+(iof&IOUFD);
|
|
||||||
if(iof&IOPUT)
|
|
||||||
{
|
|
||||||
if(*cp == '1' && !iop->iovname)
|
|
||||||
cp++;
|
|
||||||
io_op[1] = '>';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(*cp == '0' && !iop->iovname)
|
|
||||||
cp++;
|
|
||||||
io_op[1] = '<';
|
|
||||||
}
|
|
||||||
io_op[2] = 0;
|
|
||||||
io_op[3] = 0;
|
|
||||||
if(iof&IOLSEEK)
|
|
||||||
{
|
|
||||||
io_op[1] = '#';
|
|
||||||
if(iof&IOARITH)
|
|
||||||
strcpy(&io_op[3]," ((");
|
|
||||||
}
|
|
||||||
else if(iof&IOMOV)
|
|
||||||
io_op[2] = '&';
|
|
||||||
else if(iof&(IORDW|IOAPP))
|
|
||||||
io_op[2] = '>';
|
|
||||||
else if(iof&IOCLOB)
|
|
||||||
io_op[2] = '|';
|
|
||||||
if(iop->iodelim)
|
|
||||||
{
|
|
||||||
/* here document */
|
|
||||||
here_doc = iop;
|
|
||||||
io_op[2] = '<';
|
|
||||||
}
|
|
||||||
sfputr(outfile,cp,' ');
|
|
||||||
if(iop->ionxt)
|
|
||||||
iof = ' ';
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if((iof=end_line)=='\n')
|
|
||||||
begin_line = 1;
|
|
||||||
}
|
|
||||||
if((iof&IOLSEEK) && (iof&IOARITH))
|
|
||||||
iof2 = iof, iof = ' ';
|
|
||||||
if((iop->iofile & IOPROCSUB) && !(iop->iofile & IOLSEEK))
|
|
||||||
{
|
|
||||||
/* process substitution as argument to redirection */
|
|
||||||
if(iop->iofile & IOPUT)
|
|
||||||
sfwrite(outfile,">(",2);
|
|
||||||
else
|
|
||||||
sfwrite(outfile,"<(",2);
|
|
||||||
p_tree((Shnode_t*)iop->ioname,PROCSUBST);
|
|
||||||
sfputc(outfile,iof);
|
|
||||||
}
|
|
||||||
else if(iop->iodelim)
|
|
||||||
{
|
|
||||||
if(!(iop->iofile&IODOC))
|
|
||||||
sfwrite(outfile,"''",2);
|
|
||||||
sfputr(outfile,sh_fmtq(iop->iodelim),iof);
|
|
||||||
}
|
|
||||||
else if(iop->iofile&IORAW)
|
|
||||||
sfputr(outfile,sh_fmtq(iop->ioname),iof);
|
|
||||||
else
|
|
||||||
sfputr(outfile,iop->ioname,iof);
|
|
||||||
if((iof&IOLSEEK) && (iof&IOARITH))
|
|
||||||
sfputr(outfile, "))", iof2);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void p_comarg(register const struct comnod *com)
|
|
||||||
{
|
|
||||||
register int flag = end_line;
|
|
||||||
if(com->comtyp&FAMP)
|
|
||||||
sfwrite(outfile,"& ",2);
|
|
||||||
if(com->comarg || com->comio)
|
|
||||||
flag = ' ';
|
|
||||||
if(com->comset)
|
|
||||||
p_arg(com->comset,flag,POST);
|
|
||||||
if(com->comarg)
|
|
||||||
{
|
|
||||||
if(!com->comio)
|
|
||||||
flag = end_line;
|
|
||||||
if(com->comtyp&COMSCAN)
|
|
||||||
p_arg(com->comarg,flag,POST);
|
|
||||||
else
|
|
||||||
p_comlist((struct dolnod*)com->comarg,flag);
|
|
||||||
}
|
|
||||||
if(com->comio)
|
|
||||||
p_redirect(com->comio);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void p_comlist(const struct dolnod *dol,int endchar)
|
|
||||||
{
|
|
||||||
register char *cp, *const*argv;
|
|
||||||
register int flag = ' ', special;
|
|
||||||
argv = dol->dolval+ARG_SPARE;
|
|
||||||
cp = *argv;
|
|
||||||
special = (*cp=='[' && cp[1]==0);
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if(cp)
|
|
||||||
argv++;
|
|
||||||
else
|
|
||||||
cp = "";
|
|
||||||
if(*argv==0)
|
|
||||||
{
|
|
||||||
if((flag=endchar)=='\n')
|
|
||||||
begin_line = 1;
|
|
||||||
special = (*cp==']' && cp[1]==0);
|
|
||||||
}
|
|
||||||
sfputr(outfile,special?cp:sh_fmtq(cp),flag);
|
|
||||||
special = 0;
|
|
||||||
}
|
|
||||||
while(cp = *argv);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void p_switch(register const struct regnod *reg)
|
|
||||||
{
|
|
||||||
if(level>1)
|
|
||||||
sfnputc(outfile,'\t',level-1);
|
|
||||||
p_arg(reg->regptr,')',PRE);
|
|
||||||
begin_line = 0;
|
|
||||||
sfputc(outfile,'\t');
|
|
||||||
if(reg->regcom)
|
|
||||||
p_tree(reg->regcom,0);
|
|
||||||
level++;
|
|
||||||
if(reg->regflag)
|
|
||||||
p_keyword(";&",END);
|
|
||||||
else
|
|
||||||
p_keyword(";;",END);
|
|
||||||
if(reg->regnxt)
|
|
||||||
p_switch(reg->regnxt);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* output here documents
|
|
||||||
*/
|
|
||||||
static void here_body(register const struct ionod *iop)
|
|
||||||
{
|
|
||||||
Sfio_t *infile;
|
|
||||||
if(iop->iofile&IOSTRG)
|
|
||||||
infile = sfnew((Sfio_t*)0,iop->ioname,iop->iosize,-1,SF_STRING|SF_READ);
|
|
||||||
else
|
|
||||||
sfseek(infile=sh.heredocs,iop->iooffset,SEEK_SET);
|
|
||||||
sfmove(infile,outfile,iop->iosize,-1);
|
|
||||||
if(iop->iofile&IOSTRG)
|
|
||||||
sfclose(infile);
|
|
||||||
sfputr(outfile,iop->iodelim,'\n');
|
|
||||||
}
|
|
Loading…
Reference in a new issue