fix(bash): fix procsub redirect on block

This commit is contained in:
zawz 2022-02-04 16:39:30 +01:00
parent bce1d4b455
commit 8f0fd6f956
3 changed files with 28 additions and 13 deletions

View file

@ -132,9 +132,10 @@ std::string redirect_t::generate(int ind)
std::string ret=op;
if(target!=nullptr)
{
if(!opt_minify)
std::string targetret=target->generate(0);
if(!(opt_minify && !is_in(targetret[0], "<>")))
ret += ' ';
ret += target->generate(0);
ret += targetret;
}
return ret;
}

View file

@ -664,6 +664,18 @@ parse_context parse_heredocument(parse_context ctx)
return ctx;
}
std::pair<arg_t*, parse_context> parse_bash_procsub(parse_context ctx)
{
if(!ctx.bash)
{
parse_error(strf("bash specific: %c()", ctx[ctx.i]), ctx);
}
bool is_output = ctx[ctx.i] == '>';
ctx.i+=2;
auto ps = parse_subshell(ctx);
return std::make_pair(new arg_t(new subarg_procsub_t(is_output, ps.first)), ps.second);
}
std::pair<redirect_t*, parse_context> parse_redirect(parse_context ctx)
{
bool is_redirect=false;
@ -789,8 +801,12 @@ std::pair<redirect_t*, parse_context> parse_redirect(parse_context ctx)
}
else
{
auto pa = parse_arg(ctx);
ret->target = pa.first;
std::pair<arg_t*, parse_context> pa;
if(ctx.i+1 < ctx.size && (ctx[ctx.i] == '<' || ctx[ctx.i] == '>') && ctx[ctx.i+1] == '(' ) // bash specific <()
pa = parse_bash_procsub(ctx);
else
pa = parse_arg(ctx);
ret->target=pa.first;
ctx=pa.second;
}
}
@ -860,17 +876,11 @@ std::pair<arglist_t*, parse_context> parse_arglist(parse_context ctx, bool hard_
{
if(ctx.i+1 < ctx.size && (ctx[ctx.i] == '<' || ctx[ctx.i] == '>') && ctx[ctx.i+1] == '(' ) // bash specific <()
{
if(!ctx.bash)
{
parse_error(strf("bash specific: %c()", ctx[ctx.i]), ctx);
}
bool is_output = ctx[ctx.i] == '>';
ctx.i+=2;
auto pa=parse_bash_procsub(ctx);
if(ret == nullptr)
ret = new arglist_t;
auto ps = parse_subshell(ctx);
ret->add(new arg_t(new subarg_procsub_t(is_output, ps.first)));
ctx=ps.second;
ret->add(pa.first);
ctx=pa.second;
}
else if(redirs!=nullptr)
{

View file

@ -41,3 +41,7 @@ echo ${!BAR}
a=a
[[ $a = a && foo = fo* && bar =~ b.r || 2 < 3 ]]
for I in A B C ; do
echo "$I"
done > >(cat)