diff --git a/Makefile b/Makefile index d9141d0..2abda07 100644 --- a/Makefile +++ b/Makefile @@ -65,7 +65,7 @@ test: $(BINDIR)/$(NAME) $(BINDIR)/$(NAME) clean: - rm $(ODIR)/*.o + rm $(ODIR)/*.o gmon.out clear: rm $(BINDIR)/$(NAME) diff --git a/README.md b/README.md index f0e8d2b..132ee7c 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/include/debashify.hpp b/include/debashify.hpp new file mode 100644 index 0000000..5a8a174 --- /dev/null +++ b/include/debashify.hpp @@ -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 diff --git a/include/struc.hpp b/include/struc.hpp index 169af79..16ba85f 100644 --- a/include/struc.hpp +++ b/include/struc.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); diff --git a/src/debashify.cpp b/src/debashify.cpp new file mode 100644 index 0000000..41fbe01 --- /dev/null +++ b/src/debashify.cpp @@ -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; iredirs.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(o); + debashify_replace_combined_redirects(t); + } break; + case _obj::block_brace: { + brace* t = dynamic_cast(o); + debashify_replace_combined_redirects(t); + } break; + case _obj::block_main: { + shmain* t = dynamic_cast(o); + debashify_replace_combined_redirects(t); + } break; + case _obj::block_cmd: { + cmd* t = dynamic_cast(o); + debashify_replace_combined_redirects(t); + debashify_replace_bashtest(t); + } break; + case _obj::block_function: { + function* t = dynamic_cast(o); + debashify_replace_combined_redirects(t); + } break; + case _obj::block_case: { + case_block* t = dynamic_cast(o); + debashify_replace_combined_redirects(t); + } break; + case _obj::block_if: { + if_block* t = dynamic_cast(o); + debashify_replace_combined_redirects(t); + } break; + case _obj::block_while: { + while_block* t = dynamic_cast(o); + debashify_replace_combined_redirects(t); + } break; + case _obj::block_for: { + for_block* t = dynamic_cast(o); + debashify_replace_combined_redirects(t); + } break; + default: break; + } + return true; +} + +void debashify(shmain* sh) +{ + recurse(r_debashify, sh); +} diff --git a/src/main.cpp b/src/main.cpp index f3cd1ca..8aea7b3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -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']) diff --git a/src/parse.cpp b/src/parse.cpp index 57152ae..6de3eb4 100644 --- a/src/parse.cpp +++ b/src/parse.cpp @@ -441,6 +441,8 @@ std::pair 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') + i++; is_redirect=true; needs_arg=true; }