diff --git a/include/processing.hpp b/include/processing.hpp index 5f1941f..dfa6158 100644 --- a/include/processing.hpp +++ b/include/processing.hpp @@ -70,6 +70,7 @@ void list_fcts(_obj* in, std::regex const& exclude); void list_cmds(_obj* in, std::regex const& exclude); // recursives +bool r_has_env_set(_obj* in, bool* result); bool r_get_unsets(_obj* in, set_t* unsets); bool r_get_var(_obj* in, countmap_t* defmap, countmap_t* callmap); bool r_get_cmd(_obj* in, countmap_t* all_cmds); @@ -81,6 +82,7 @@ bool r_delete_var(_obj* in, set_t* vars); std::set find_lxsh_commands(shmain* sh); void add_unset_variables(shmain* sh, std::regex const& exclude); +bool has_env_set(_obj* in); void string_processors(_obj* in); diff --git a/include/struc.hpp b/include/struc.hpp index 0f8e258..3f6ae6c 100644 --- a/include/struc.hpp +++ b/include/struc.hpp @@ -400,6 +400,9 @@ public: bool is_argvar(); std::vector subarg_vars(); + // returns true if command performs env var changes + bool has_var_assign(); + arglist* args; std::string generate(int ind, generate_context* ctx); diff --git a/src/main.cpp b/src/main.cpp index decb51f..739ff17 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -180,12 +180,6 @@ int main(int argc, char* argv[]) list_fcts(sh, re_fct_exclude); else if(options["list-cmd"]) list_cmds(sh, regex_null); -#ifdef DEBUG_MODE - else if(options['J']) - { - std::cout << gen_json_struc(sh) << std::endl; - } -#endif // output else { @@ -217,6 +211,14 @@ int main(int argc, char* argv[]) if(options["unset-var"]) add_unset_variables( sh, re_var_exclude ); + #ifdef DEBUG_MODE + if(options['J']) + { + std::cout << gen_json_struc(sh) << std::endl; + goto end; + } + #endif + if(options['o']) // file output { std::string destfile=options['o']; @@ -257,6 +259,7 @@ int main(int argc, char* argv[]) std::cerr << e.what() << std::endl; return ERR_RUNTIME; } +end: delete sh; diff --git a/src/minify.cpp b/src/minify.cpp index a639cb8..4a97000 100644 --- a/src/minify.cpp +++ b/src/minify.cpp @@ -436,7 +436,65 @@ bool r_minify_empty_manip(_obj* in) return true; } +block* do_one_minify_single_block(block* in) +{ + block* ret=nullptr; + list* l=nullptr; + if(in->type == _obj::block_brace) + l = dynamic_cast(in)->lst; + else if(in->type == _obj::block_subshell) + l = dynamic_cast(in)->lst; + + if(l == nullptr) + return nullptr; + + // not a single cmd/block: not applicable + if(l->cls.size() != 1 || l->cls[0]->pls.size() != 1 || l->cls[0]->pls[0]->cmds.size() != 1) + return nullptr; + + ret = l->cls[0]->pls[0]->cmds[0]; + + // if is a subshell and has some env set: don't remove it + if(in->type == _obj::block_subshell && has_env_set(in)) + return nullptr; + + return ret; +} + +bool r_minify_single_block(_obj* in) +{ + switch(in->type) + { + case _obj::_pipeline: { + pipeline* t = dynamic_cast(in); + for(uint32_t i=0; icmds.size(); i++) + { + block* ret = do_one_minify_single_block(t->cmds[i]); + if(ret != nullptr) { + // concatenate redirects + for(uint32_t i=0; icmds[i]->redirs.size(); i++) + ret->redirs.insert(ret->redirs.begin()+i, ret->redirs[i]); + + // deindex + t->cmds[i]->redirs.resize(0); + if(t->cmds[i]->type == _obj::block_brace) + dynamic_cast(t->cmds[i])->lst->cls[0]->pls[0] = nullptr; + else if(t->cmds[i]->type == _obj::block_subshell) + dynamic_cast(t->cmds[i])->lst->cls[0]->pls[0] = nullptr; + + // replace value + delete t->cmds[i]; + t->cmds[i] = ret; + } + } + }; break; + default: break; + } + return true; +} + void minify_generic(_obj* in) { recurse(r_minify_empty_manip, in); + recurse(r_minify_single_block, in); } diff --git a/src/processing.cpp b/src/processing.cpp index df30b57..6b95d29 100644 --- a/src/processing.cpp +++ b/src/processing.cpp @@ -265,8 +265,33 @@ void add_unset_variables(shmain* sh, std::regex const& exclude) } } +bool has_env_set(_obj* in) { + bool r=false; + recurse(r_has_env_set, in, &r); + return r; +} + /** RECURSIVES **/ +// CHECK // + +bool r_has_env_set(_obj* in, bool* result) +{ + switch(in->type) + { + case _obj::block_subshell: { + return false; + }; break; + case _obj::block_cmd: { + cmd* t = dynamic_cast(in); + if(t->has_var_assign()) + *result = true; + } + default: break; + } + return true; +} + // GET // bool r_get_var(_obj* in, countmap_t* defmap, countmap_t* callmap) diff --git a/src/struc_helper.cpp b/src/struc_helper.cpp index 85235c1..1f44bff 100644 --- a/src/struc_helper.cpp +++ b/src/struc_helper.cpp @@ -138,6 +138,15 @@ bool possibly_expands(arglist* in) // property getters +bool cmd::has_var_assign() +{ + if(this->args->size() == 0) + { + return this->var_assigns.size()>0; + } + return this->is_argvar(); +} + size_t cmd::arglist_size() { if(args==nullptr)