1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-03-09 15:50:02 +00:00

Add support for process substitutions to the deparser (#288)

Like tdump() and trestore() before commit 32d1abb1, sh_deparse() fails
to handle process substitutions correctly. This limitation of the shell
deparser is rather minor since it's unused. However, seeing as the
deparser was left in the code base intentionally it should at least
function properly.

src/cmd/ksh93/sh/deparse.c:
- Add a PROCSUBST flag for handling process substitutions in
  sh_deparse().
- If we're handling a process substitution, add an ending ')'
  without an extra newline.
- Avoid adding an extra ' &' to commands inside of a process
  substitution. An extra ' &' is only added if the FAMP and FINT
  flags are set, which indicates the command was spawned as a separate
  job with '&'.
- Add process substitution handling to 'p_redirect' by calling p_tree()
  when encountering a process substitution.
This commit is contained in:
Johnothan King 2021-04-25 16:12:29 -07:00 committed by GitHub
parent 295cce2c6d
commit 1d9093e603
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -40,9 +40,10 @@
/* flags that can be specified with p_tree() */ /* flags that can be specified with p_tree() */
#define NO_NEWLINE 1 #define NO_NEWLINE (1 << 0)
#define NEED_BRACE 2 #define NEED_BRACE (1 << 1)
#define NO_BRACKET 4 #define NO_BRACKET (1 << 2)
#define PROCSUBST (1 << 3)
static void p_comlist(const struct dolnod*,int); static void p_comlist(const struct dolnod*,int);
static void p_arg(const struct argnod*, int endchar, int opts); static void p_arg(const struct argnod*, int endchar, int opts);
@ -62,8 +63,6 @@ static const struct ionod *here_doc;
static Sfio_t *outfile; static Sfio_t *outfile;
static const char *forinit = ""; static const char *forinit = "";
extern void sh_deparse(Sfio_t*, const Shnode_t*,int);
void sh_deparse(Sfio_t *out, const Shnode_t *t,int tflags) void sh_deparse(Sfio_t *out, const Shnode_t *t,int tflags)
{ {
outfile = out; outfile = out;
@ -77,9 +76,12 @@ static void p_tree(register const Shnode_t *t,register int tflags)
register char *cp; register char *cp;
int save = end_line; int save = end_line;
int needbrace = (tflags&NEED_BRACE); int needbrace = (tflags&NEED_BRACE);
int procsub = (tflags&PROCSUBST);
tflags &= ~NEED_BRACE; tflags &= ~NEED_BRACE;
if(tflags&NO_NEWLINE) if(tflags&NO_NEWLINE)
end_line = ' '; end_line = ' ';
else if(procsub)
end_line = ')';
else else
end_line = '\n'; end_line = '\n';
switch(t->tre.tretyp&COMMSK) switch(t->tre.tretyp&COMMSK)
@ -113,7 +115,7 @@ static void p_tree(register const Shnode_t *t,register int tflags)
case TFORK: case TFORK:
if(needbrace) if(needbrace)
tflags |= NEED_BRACE; tflags |= NEED_BRACE;
if(t->tre.tretyp&(FAMP|FCOOP)) if((t->tre.tretyp&(FAMP|FCOOP)) && (t->tre.tretyp&(FAMP|FINT))!=FAMP)
{ {
tflags = NEED_BRACE|NO_NEWLINE; tflags = NEED_BRACE|NO_NEWLINE;
end_line = ' '; end_line = ' ';
@ -125,12 +127,12 @@ static void p_tree(register const Shnode_t *t,register int tflags)
p_redirect(t->fork.forkio); p_redirect(t->fork.forkio);
if(t->tre.tretyp&FCOOP) if(t->tre.tretyp&FCOOP)
{ {
sfputr(outfile,"|&",'\n'); sfputr(outfile,"|&",procsub?')':'\n');
begin_line = 1; begin_line = 1;
} }
else if(t->tre.tretyp&FAMP) else if((t->tre.tretyp&(FAMP|FINT))==(FAMP|FINT))
{ {
sfputr(outfile,"&",'\n'); sfputr(outfile,"&",procsub?')':'\n');
begin_line = 1; begin_line = 1;
} }
break; break;
@ -403,11 +405,11 @@ static void p_arg(register const struct argnod *arg,register int endchar,int opt
cp = arg->argval; cp = arg->argval;
if(*cp==0 && (arg->argflag&ARG_EXP) && arg->argchn.ap) if(*cp==0 && (arg->argflag&ARG_EXP) && arg->argchn.ap)
{ {
/* process substitution */
int c = (arg->argflag&ARG_RAW)?'>':'<'; int c = (arg->argflag&ARG_RAW)?'>':'<';
sfputc(outfile,c); sfputc(outfile,c);
sfputc(outfile,'('); sfputc(outfile,'(');
p_tree((Shnode_t*)arg->argchn.ap,0); p_tree((Shnode_t*)arg->argchn.ap,PROCSUBST);
sfputc(outfile,')');
} }
else if(*cp==0 && opts==POST && arg->argchn.ap) else if(*cp==0 && opts==POST && arg->argchn.ap)
{ {
@ -489,7 +491,17 @@ static void p_redirect(register const struct ionod *iop)
} }
if((iof&IOLSEEK) && (iof&IOARITH)) if((iof&IOLSEEK) && (iof&IOARITH))
iof2 = iof, iof = ' '; iof2 = iof, iof = ' ';
if(iop->iodelim) 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)) if(!(iop->iofile&IODOC))
sfwrite(outfile,"''",2); sfwrite(outfile,"''",2);