Implement <() bash process substitution
This commit is contained in:
parent
c199969b63
commit
36dfd9266e
5 changed files with 51 additions and 11 deletions
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 == ">&")
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue