first debashify implementation: replace &> and >& redirects

This commit is contained in:
zawwz 2021-01-06 11:10:45 +01:00
parent afa07b3c5e
commit c199969b63
7 changed files with 115 additions and 2 deletions

View file

@ -65,7 +65,7 @@ test: $(BINDIR)/$(NAME)
$(BINDIR)/$(NAME)
clean:
rm $(ODIR)/*.o
rm $(ODIR)/*.o gmon.out
clear:
rm $(BINDIR)/$(NAME)

View file

@ -88,6 +88,7 @@ However not all bash syntax is supported yet.
## incomplete POSIX features
- `$(())` arithmetics are not minimized
- Variables in `$(())` arithmetics are not accounted for in variable processing
## Known bash issues

10
include/debashify.hpp Normal file
View file

@ -0,0 +1,10 @@
#ifndef DEBASHIFY_HPP
#define DEBASHIFY_HPP
#include "struc.hpp"
bool r_debashify(_obj* o);
void debashify(shmain* sh);
#endif //DEBASHIFY_HPP

View file

@ -148,7 +148,9 @@ public:
class redirect : public _obj
{
public:
redirect(arg* in=nullptr) { type=_obj::_redirect; target=in; }
redirect(std::string strop="") { type=_obj::_redirect; op=strop; target=nullptr; }
redirect(arg* in) { type=_obj::_redirect; target=in; }
redirect(std::string strop, arg* in) { type=_obj::_redirect; op=strop; target=in; }
~redirect() { if(target != nullptr) delete target; }
std::string generate(int ind);

92
src/debashify.cpp Normal file
View file

@ -0,0 +1,92 @@
#include "debashify.hpp"
#include "recursive.hpp"
bool debashify_replace_bashtest(cmd* in)
{
if(in->firstarg_string() == "[[")
throw std::runtime_error("Debashify on '[[' not implemented yet");
return false;
}
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 == ">&")
{
// resolve new operator
std::string newop = ">";
if( in->redirs[i]->op == "&>>" )
newop = ">>";
// create new redir with target
redirect* newredir = new redirect(newop, in->redirs[i]->target);
in->redirs[i]->target=nullptr;
// replace old redir
delete in->redirs[i];
in->redirs[i] = newredir;
// insert merge redir
i++;
in->redirs.insert(in->redirs.begin()+i, new redirect("2>&1"));
has_replaced=true;
}
}
return has_replaced;
}
bool r_debashify(_obj* o)
{
switch(o->type)
{
case _obj::block_subshell: {
subshell* t = dynamic_cast<subshell*>(o);
debashify_replace_combined_redirects(t);
} break;
case _obj::block_brace: {
brace* t = dynamic_cast<brace*>(o);
debashify_replace_combined_redirects(t);
} break;
case _obj::block_main: {
shmain* t = dynamic_cast<shmain*>(o);
debashify_replace_combined_redirects(t);
} break;
case _obj::block_cmd: {
cmd* t = dynamic_cast<cmd*>(o);
debashify_replace_combined_redirects(t);
debashify_replace_bashtest(t);
} break;
case _obj::block_function: {
function* t = dynamic_cast<function*>(o);
debashify_replace_combined_redirects(t);
} break;
case _obj::block_case: {
case_block* t = dynamic_cast<case_block*>(o);
debashify_replace_combined_redirects(t);
} break;
case _obj::block_if: {
if_block* t = dynamic_cast<if_block*>(o);
debashify_replace_combined_redirects(t);
} break;
case _obj::block_while: {
while_block* t = dynamic_cast<while_block*>(o);
debashify_replace_combined_redirects(t);
} break;
case _obj::block_for: {
for_block* t = dynamic_cast<for_block*>(o);
debashify_replace_combined_redirects(t);
} break;
default: break;
}
return true;
}
void debashify(shmain* sh)
{
recurse(r_debashify, sh);
}

View file

@ -15,6 +15,7 @@
#include "minimize.hpp"
#include "resolve.hpp"
#include "processing.hpp"
#include "debashify.hpp"
#include "version.h"
#include "g_version.h"
@ -150,6 +151,11 @@ int main(int argc, char* argv[])
break;
} // end of argument parse
if(options["debashify"])
{
debashify(sh);
}
// processing before output
// minimize
if(options['m'])

View file

@ -441,6 +441,8 @@ std::pair<redirect*, uint32_t> parse_redirect(const char* in, uint32_t size, uin
if(!g_bash)
throw PARSE_ERROR("bash specific: '&>'. Use --debashify to remove bashisms", i);
i+=2;
if(i<size && in[i] == '>')
i++;
is_redirect=true;
needs_arg=true;
}