first debashify implementation: replace &> and >& redirects
This commit is contained in:
parent
afa07b3c5e
commit
c199969b63
7 changed files with 115 additions and 2 deletions
2
Makefile
2
Makefile
|
|
@ -65,7 +65,7 @@ test: $(BINDIR)/$(NAME)
|
|||
$(BINDIR)/$(NAME)
|
||||
|
||||
clean:
|
||||
rm $(ODIR)/*.o
|
||||
rm $(ODIR)/*.o gmon.out
|
||||
|
||||
clear:
|
||||
rm $(BINDIR)/$(NAME)
|
||||
|
|
|
|||
|
|
@ -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
10
include/debashify.hpp
Normal 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
|
||||
|
|
@ -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
92
src/debashify.cpp
Normal 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);
|
||||
}
|
||||
|
|
@ -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'])
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue