Implement <() bash process substitution

This commit is contained in:
zawwz 2021-01-06 12:15:31 +01:00
parent c199969b63
commit 36dfd9266e
5 changed files with 51 additions and 11 deletions

View file

@ -193,6 +193,12 @@ void recurse(bool (&fct)(_obj*, Args...), _obj* o, Args... args)
recurse(fct, t->sbsh, args...);
break;
}
case _obj::subarg_procsub :
{
procsub_subarg* t = dynamic_cast<procsub_subarg*>(o);
recurse(fct, t->sbsh, args...);
break;
}
default: break; //do nothing
}

View file

@ -54,8 +54,12 @@ arg:
subarg: can be one of
- string
- block: subshell (substitution)
- subshell (command substitution)
- arithmetic
- variable
- variable manipulation
- procsub (bash specific process substitution)
> NOTE: MUST be the only subarg in the arg
*/
@ -81,9 +85,9 @@ class _obj
{
public:
enum _objtype {
subarg_string, subarg_variable, subarg_subshell, subarg_arithmetic, subarg_manipulation,
subarg_string, subarg_variable, subarg_subshell, subarg_arithmetic, subarg_manipulation, subarg_procsub,
_redirect,
_arg,
_arg, arg_procsub,
_arglist,
_pipeline,
_condlist,
@ -108,6 +112,7 @@ class arg : public _obj
public:
arg() { type=_obj::_arg; }
arg(std::string const& str) { type=_obj::_arg; this->setstring(str);}
arg(subarg* in) { type=_obj::_arg; sa.push_back(in); }
~arg() { for(auto it: sa) delete it; }
void setstring(std::string const& str);
@ -477,5 +482,18 @@ public:
std::string generate(int ind);
};
class procsub_subarg : public subarg
{
public:
procsub_subarg() { type=_obj::subarg_procsub; sbsh=nullptr; is_output=false; }
procsub_subarg(bool output, subshell* in) { type=_obj::subarg_procsub; sbsh=in; is_output=output; }
~procsub_subarg() { if(sbsh!=nullptr) delete sbsh; }
bool is_output;
subshell* sbsh;
std::string generate(int ind);
};
#endif //STRUC_HPP

View file

@ -5,7 +5,7 @@
bool debashify_replace_bashtest(cmd* in)
{
if(in->firstarg_string() == "[[")
throw std::runtime_error("Debashify on '[[' not implemented yet");
throw std::runtime_error("Debashify on '[[ ]]' not implemented yet");
return false;
}
@ -14,7 +14,6 @@ bool debashify_replace_combined_redirects(block* in)
{
bool has_replaced=false;
for(uint32_t i=0; i<in->redirs.size() ; i++)
{
if(in->redirs[i]->op == "&>" || in->redirs[i]->op == "&>>" || in->redirs[i]->op == ">&")

View file

@ -350,6 +350,14 @@ std::string manipulation_subarg::generate(int ind)
return "${" + varname + manip->generate(ind) + "}";
}
std::string procsub_subarg::generate(int ind)
{
if(is_output)
return '>' + sbsh->generate(ind);
else
return '<' + sbsh->generate(ind);
}
// TEMPLATE
// std::string thing::generate(int ind)

View file

@ -542,7 +542,17 @@ std::pair<arglist*, uint32_t> parse_arglist(const char* in, uint32_t size, uint3
}
while(i<size)
{
if(redirs!=nullptr)
if(i+1 < size && (in[i] == '<' || in[i] == '>') && in[i+1] == '(' ) // bash specific <()
{
bool is_output = in[i] == '>';
i+=2;
if(ret == nullptr)
ret = new arglist;
auto ps = parse_subshell(in, size, i);
ret->args.push_back(new arg(new procsub_subarg(is_output, ps.first)));
i=ps.second+1;
}
else if(redirs!=nullptr)
{
auto pr = parse_redirect(in, size, i);
if(pr.first != nullptr)
@ -555,7 +565,7 @@ std::pair<arglist*, uint32_t> parse_arglist(const char* in, uint32_t size, uint3
}
else
{
argparse:
argparse:
if(ret == nullptr)
ret = new arglist;
auto pp=parse_arg(in, size, i);
@ -564,10 +574,9 @@ argparse:
}
i = skip_chars(in, size, i, SPACES);
if(word_eq("&>", in, size, i))
// throw PARSE_ERROR("Unsupported &>", i);
continue;
continue; // &> has to be managed in redirects
if(word_eq("|&", in, size, i))
throw PARSE_ERROR("Unsupported |&, use '2>&1 |' instead", i);
throw PARSE_ERROR("Unsupported '|&', use '2>&1 |' instead", i);
if(i>=size)
return std::make_pair(ret, i);
if( is_in(in[i], SPECIAL_TOKENS) )
@ -1119,7 +1128,7 @@ std::pair<for_block*, uint32_t> parse_for(const char* in, uint32_t size, uint32_
if(wp.first == "in")
{
i=skip_chars(in, size, wp.second, SPACES);
auto pp = parse_arglist(in, size, i);
auto pp = parse_arglist(in, size, i, false);
ret->iter = pp.first;
i = pp.second;
}