diff --git a/include/minimize.hpp b/include/minimize.hpp index e5b4188..114da7e 100644 --- a/include/minimize.hpp +++ b/include/minimize.hpp @@ -6,29 +6,6 @@ #include #include -typedef std::map countmap_t; - -extern std::regex re_var_exclude; -extern std::regex re_fct_exclude; - -extern const std::regex regex_null; - -#define RESERVED_VARIABLES "HOME", "PATH", "SHELL", "PWD", "OPTIND", "OPTARG" - -void require_rescan_all(); -void require_rescan_var(); -void require_rescan_fct(); -void require_rescan_cmd(); - -std::regex var_exclude_regex(std::string const& in, bool include_reserved); -std::regex fct_exclude_regex(std::string const& in); - -void list_vars(_obj* in, std::regex const& exclude); -void list_var_defs(_obj* in, std::regex const& exclude); -void list_var_calls(_obj* in, std::regex const& exclude); -void list_fcts(_obj* in, std::regex const& exclude); -void list_cmds(_obj* in, std::regex const& exclude); - void minimize_var(_obj* in, std::regex const& exclude); void minimize_fct(_obj* in, std::regex const& exclude); diff --git a/include/parse.hpp b/include/parse.hpp index b13b979..de5f722 100644 --- a/include/parse.hpp +++ b/include/parse.hpp @@ -21,10 +21,6 @@ #define SPECIAL_VARS "!#*@$?" -inline bool is_num(char c) { return (c >= '0' && c <= '9'); } -inline bool is_alpha(char c) { return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); } -inline bool is_alphanum(char c) { return is_alpha(c) || is_num(c); } - std::string import_file(std::string const& path); shmain* parse_text(const char* in, uint32_t size, std::string const& filename=""); diff --git a/include/processing.hpp b/include/processing.hpp new file mode 100644 index 0000000..84ba12b --- /dev/null +++ b/include/processing.hpp @@ -0,0 +1,70 @@ +#ifndef PROCESSING_HPP +#define PROCESSING_HPP + +#include +#include +#include +#include + +#include "struc.hpp" + +// constants +#define RESERVED_VARIABLES "HOME", "PATH", "SHELL", "PWD", "OPTIND", "OPTARG" + +// types +typedef std::map countmap_t; +typedef std::map strmap_t; +typedef std::set set_t; + +// regexes +extern std::regex re_var_exclude; +extern std::regex re_fct_exclude; +extern const std::regex regex_null; + +// Object maps (optimizations) +extern countmap_t m_vars, m_vardefs, m_varcalls; +extern countmap_t m_fcts, m_cmds; +extern set_t m_excluded_var, m_excluded_fct, m_excluded_cmd; + +extern bool b_gotvar, b_gotfct, b_gotcmd; + +/** map get functions (optimizations) **/ + +// rescans +void require_rescan_all(); +void require_rescan_var(); +void require_rescan_fct(); +void require_rescan_cmd(); + +// get objects +void varmap_get(_obj* in, std::regex const& exclude); +void fctmap_get(_obj* in, std::regex const& exclude); +void cmdmap_get(_obj* in, std::regex const& exclude); + +/** functions **/ + +// gen regexes +std::regex var_exclude_regex(std::string const& in, bool include_reserved); +std::regex fct_exclude_regex(std::string const& in); + +// varnames +bool is_varname(std::string const& in); +std::string get_varname(std::string const& in); +std::string get_varname(arg* in); + +// list objects +void list_map(countmap_t const& map); +void list_vars(_obj* in, std::regex const& exclude); +void list_var_defs(_obj* in, std::regex const& exclude); +void list_var_calls(_obj* in, std::regex const& exclude); +void list_fcts(_obj* in, std::regex const& exclude); +void list_cmds(_obj* in, std::regex const& exclude); + +// recursives +bool r_get_var(_obj* in, countmap_t* defmap, countmap_t* callmap); +bool r_get_cmd(_obj* in, countmap_t* all_cmds); +bool r_get_fct(_obj* in, countmap_t* fct_map); +bool r_delete_fct(_obj* in, set_t* fcts); +bool r_delete_var(_obj* in, set_t* vars); + +#endif //PROCESSING_HPP diff --git a/include/util.hpp b/include/util.hpp index 59cc11e..0877205 100644 --- a/include/util.hpp +++ b/include/util.hpp @@ -28,6 +28,10 @@ std::vector split(std::string const& in, char c); std::string escape_str(std::string const& in); +inline bool is_num(char c) { return (c >= '0' && c <= '9'); } +inline bool is_alpha(char c) { return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); } +inline bool is_alphanum(char c) { return is_alpha(c) || is_num(c); } + template std::string strf( const std::string& format, Args ... args ) { diff --git a/src/main.cpp b/src/main.cpp index ae5c0bf..e4b5290 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -14,6 +14,7 @@ #include "recursive.hpp" #include "minimize.hpp" #include "resolve.hpp" +#include "processing.hpp" #include "version.h" #include "g_version.h" diff --git a/src/minimize.cpp b/src/minimize.cpp index 109686b..e16015e 100644 --- a/src/minimize.cpp +++ b/src/minimize.cpp @@ -1,163 +1,9 @@ #include "minimize.hpp" -#include -#include -#include - #include "recursive.hpp" -#include "parse.hpp" +#include "processing.hpp" #include "util.hpp" -std::regex re_var_exclude; -std::regex re_fct_exclude; - -const std::regex regex_null; - -countmap_t m_vars, m_vardefs, m_varcalls; -countmap_t m_fcts, m_cmds; -std::set m_excluded_var, m_excluded_fct, m_excluded_cmd; - -bool b_gotvar=false, b_gotfct=false, b_gotcmd=false; - -// requires - -void require_rescan_var() -{ - b_gotvar = false; - m_vars.clear(); - m_vardefs.clear(); - m_varcalls.clear(); - m_excluded_var.clear(); -} -void require_rescan_fct() -{ - b_gotcmd = false; - m_fcts.clear(); - m_excluded_fct.clear(); -} -void require_rescan_cmd() -{ - b_gotfct = false; - m_cmds.clear(); - m_excluded_cmd.clear(); -} - -void require_rescan_all() -{ - require_rescan_var(); - require_rescan_fct(); - require_rescan_cmd(); -} - -// tools - -countmap_t combine_maps(countmap_t const& a, countmap_t const& b) -{ - countmap_t ret; - for(auto it: a) - { - if(!ret.insert( it ).second) - ret[it.first] += it.second; - } - for(auto it: b) - { - if(!ret.insert( it ).second) - ret[it.first] += it.second; - } - return ret; -} - -void list_map(countmap_t const& map) -{ - uint32_t max=0; - for(auto it: map) - if(it.second > max) - max=it.second; - for(auto it: map) - printf("%*d %s\n", (uint32_t)log10(max)+1, it.second, it.first.c_str()); -} - -std::vector get_list(std::string const& in) -{ - return split(in, ", \t\n"); -} - -std::regex gen_regex_from_list(std::vector const& in) -{ - std::string re; - for(auto it: in) - re += '('+it+")|"; - if(re.size()>0) - re.pop_back(); - return std::regex(re); -} - -std::vector gen_var_excludes(std::string const& in, bool include_reserved) -{ - std::vector ret; - if(include_reserved) - { - ret = {RESERVED_VARIABLES, strf("[0-9%s]", SPECIAL_VARS)}; - } - auto t = get_list(in); - ret.insert(ret.end(), t.begin(), t.end()); - return ret; -} - -std::regex var_exclude_regex(std::string const& in, bool include_reserved) -{ - return gen_regex_from_list(gen_var_excludes(in, include_reserved)); -} -std::regex fct_exclude_regex(std::string const& in) -{ - return gen_regex_from_list(get_list(in)); -} - -bool is_varname(std::string const& in) -{ - if(in.size() <= 0 || !(is_alpha(in[0]) || in[0]== '_') ) - return false; - uint32_t i=1; - while(isa.size() < 1 || in->sa[0]->type != _obj::subarg_string) - return ""; - std::string str = in->sa[0]->generate(0); - if(in->sa.size() >= 1 && is_varname(str)) - return get_varname(str); - return ""; -} - -bool cmd_is_argvar(std::string const& in) -{ - return in == "export" || in == "unset" || in == "local" || in == "read"; -} - -bool cmd::is_argvar() -{ - return cmd_is_argvar(this->firstarg_string()); -} - std::vector cmd::subarg_vars() { std::vector ret; @@ -181,40 +27,24 @@ std::vector cmd::subarg_vars() /** RECURSIVES **/ -// GET // - -bool r_get_var(_obj* in, countmap_t* defmap, countmap_t* callmap) +bool r_replace_fct(_obj* in, strmap_t* fctmap) { switch(in->type) { - case _obj::subarg_variable: { - variable_subarg* t = dynamic_cast(in); - if(!callmap->insert( std::make_pair(t->varname, 1) ).second) - (*callmap)[t->varname]++; - }; break; - case _obj::subarg_manipulation: { - manipulation_subarg* t = dynamic_cast(in); - if(!callmap->insert( std::make_pair(t->varname, 1) ).second) - (*callmap)[t->varname]++; - }; break; - case _obj::block_for: { - for_block* t = dynamic_cast(in); - if(!defmap->insert( std::make_pair(t->varname, 1) ).second) - (*defmap)[t->varname]++; + case _obj::block_function: { + function* t = dynamic_cast(in); + auto el=fctmap->find(t->name); + if(el!=fctmap->end()) + t->name = el->second; }; break; case _obj::block_cmd: { cmd* t = dynamic_cast(in); - for(auto it: t->var_assigns) - if(!defmap->insert( std::make_pair(it.first, 1) ).second) - (*defmap)[it.first]++; - if(t->is_argvar()) + std::string cmdname = t->firstarg_string(); + auto el=fctmap->find(cmdname); + if(el!=fctmap->end()) { - for(uint32_t i=1; iargs->size(); i++) - { - std::string varname=get_varname(t->args->args[i]); - if( varname != "" && !defmap->insert( std::make_pair(varname, 1) ).second ) - (*defmap)[varname]++; - } + delete t->args->args[0]; + t->args->args[0] = new arg(el->second); } }; break; default: break; @@ -222,38 +52,7 @@ bool r_get_var(_obj* in, countmap_t* defmap, countmap_t* callmap) return true; } -bool r_get_cmd(_obj* in, countmap_t* all_cmds) -{ - switch(in->type) - { - case _obj::block_cmd: { - cmd* t = dynamic_cast(in); - std::string cmdname = t->firstarg_string(); - if(cmdname != "" && !all_cmds->insert( std::make_pair(cmdname, 1) ).second) - (*all_cmds)[cmdname]++; - }; break; - default: break; - } - return true; -} - -bool r_get_fct(_obj* in, countmap_t* fct_map) -{ - switch(in->type) - { - case _obj::block_function: { - function* t = dynamic_cast(in); - if(!fct_map->insert( std::make_pair(t->name, 1) ).second) - (*fct_map)[t->name]++; - }; break; - default: break; - } - return true; -} - -// REPLACE // - -bool r_replace_var(_obj* in, std::map* varmap) +bool r_replace_var(_obj* in, strmap_t* varmap) { switch(in->type) { @@ -302,115 +101,6 @@ bool r_replace_var(_obj* in, std::map* varmap) return true; } -bool r_replace_fct(_obj* in, std::map* fctmap) -{ - switch(in->type) - { - case _obj::block_function: { - function* t = dynamic_cast(in); - auto el=fctmap->find(t->name); - if(el!=fctmap->end()) - t->name = el->second; - }; break; - case _obj::block_cmd: { - cmd* t = dynamic_cast(in); - std::string cmdname = t->firstarg_string(); - auto el=fctmap->find(cmdname); - if(el!=fctmap->end()) - { - delete t->args->args[0]; - t->args->args[0] = new arg(el->second); - } - }; break; - default: break; - } - return true; -} - -// DELETE // - -bool r_delete_fct(_obj* in, std::set* fcts) -{ - switch(in->type) - { - case _obj::_list: { - list* t = dynamic_cast(in); - for(uint32_t i=0; icls.size(); i++) - { - block* tb = t->cls[i]->first_block(); - if(tb != nullptr && tb->type == _obj::block_function) - { - function* fc = dynamic_cast(tb); - if(fcts->find(fc->name)!=fcts->end()) - { - delete t->cls[i]; - t->cls.erase(t->cls.begin()+i); - i--; - } - } - } - } - default: break; - } - return true; -} - -bool r_delete_var(_obj* in, std::set* vars) -{ - switch(in->type) - { - case _obj::_list: { - list* t = dynamic_cast(in); - for(uint32_t i=0; icls.size(); i++) - { - block* tb = t->cls[i]->first_block(); - bool to_delete=false; - if(tb != nullptr && tb->type == _obj::block_cmd) - { - cmd* c = dynamic_cast(tb); - - for(uint32_t j=0; jvar_assigns.size(); j++) - { - if( vars->find(c->var_assigns[j].first) != vars->end() ) - { - delete c->var_assigns[j].second; - c->var_assigns.erase(c->var_assigns.begin()+j); - j--; - } - } - - if(c->is_argvar()) - { - for(uint32_t j=1; jargs->size(); j++) - { - std::string varname=get_varname(c->args->args[j]); - if( varname != "" && vars->find( varname ) != vars->end() ) - { - delete c->args->args[j]; - c->args->args.erase(c->args->args.begin()+j); - j--; - } - } - if(c->args->size()<=1) - to_delete=true; - } - if(c->var_assigns.size()<=0 && c->arglist_size()<=0) - to_delete=true; - - } - if(to_delete) - { - delete t->cls[i]; - t->cls.erase(t->cls.begin()+i); - i--; - } - } - } - default: break; - } - return true; -} - /** NAME MINIMIZING **/ char nchar(uint32_t n) @@ -451,9 +141,11 @@ std::string minimal_name(uint32_t n) } } -std::map gen_minimal_map(countmap_t const& vars, std::set excluded) +// vars: input variables +// excluded: excluded variables to make sure there is no collision +strmap_t gen_minimal_map(countmap_t const& vars, set_t const& excluded) { - std::map ret; + strmap_t ret; auto ordered = sort_by_value(vars); uint32_t n=0; for(std::pair it: ordered) @@ -468,46 +160,13 @@ std::map gen_minimal_map(countmap_t const& vars, std::s return ret; } -// map getters - -void varmap_get(_obj* in, std::regex const& exclude) -{ - if(!b_gotvar) - { - b_gotvar=true; - recurse(r_get_var, in, &m_vardefs, &m_varcalls); - m_vars = combine_maps(m_vardefs, m_varcalls); - m_excluded_var = prune_matching(m_vars, exclude); - } -} - -void fctmap_get(_obj* in, std::regex const& exclude) -{ - if(!b_gotfct) - { - b_gotfct=true; - recurse(r_get_fct, in, &m_fcts); - m_excluded_fct = prune_matching(m_fcts, exclude); - } -} - -void cmdmap_get(_obj* in, std::regex const& exclude) -{ - if(!b_gotcmd) - { - b_gotcmd=true; - recurse(r_get_cmd, in, &m_cmds); - m_excluded_fct = prune_matching(m_cmds, exclude); - } -} - // calls void minimize_var(_obj* in, std::regex const& exclude) { // countmap_t vars; - std::set excluded; - std::map varmap; + set_t excluded; + strmap_t varmap; // get vars varmap_get(in, exclude); // create mapping @@ -520,8 +179,8 @@ void minimize_var(_obj* in, std::regex const& exclude) void minimize_fct(_obj* in, std::regex const& exclude) { // countmap_t fcts, cmdmap; - std::set allcmds, excluded; - std::map fctmap; + set_t allcmds, excluded; + strmap_t fctmap; // get fcts and cmds fctmap_get(in, exclude); cmdmap_get(in, regex_null); @@ -538,7 +197,7 @@ void minimize_fct(_obj* in, std::regex const& exclude) bool delete_unused_fct(_obj* in, std::regex const& exclude) { - std::set unused; + set_t unused; // get fcts and cmds fctmap_get(in, exclude); cmdmap_get(in, regex_null); @@ -561,7 +220,7 @@ bool delete_unused_fct(_obj* in, std::regex const& exclude) bool delete_unused_var(_obj* in, std::regex const& exclude) { - std::set unused; + set_t unused; // get fcts and cmds varmap_get(in, exclude); // find unused vars @@ -584,34 +243,5 @@ bool delete_unused_var(_obj* in, std::regex const& exclude) void delete_unused(_obj* in, std::regex const& var_exclude, std::regex const& fct_exclude) { while(delete_unused_fct(in, fct_exclude) || delete_unused_var(in, var_exclude)); -} - -void list_vars(_obj* in, std::regex const& exclude) -{ - varmap_get(in, exclude); - list_map(m_vars); -} - -void list_var_defs(_obj* in, std::regex const& exclude) -{ - varmap_get(in, exclude); - list_map(m_vardefs); -} - -void list_var_calls(_obj* in, std::regex const& exclude) -{ - varmap_get(in, exclude); - list_map(m_varcalls); -} - -void list_fcts(_obj* in, std::regex const& exclude) -{ - fctmap_get(in, exclude); - list_map(m_fcts); -} - -void list_cmds(_obj* in, std::regex const& exclude) -{ - cmdmap_get(in, exclude); - list_map(m_cmds); + // keep deleting until both no function and no variables were deleted } diff --git a/src/options.cpp b/src/options.cpp index 889eed5..5cd5e61 100644 --- a/src/options.cpp +++ b/src/options.cpp @@ -1,6 +1,6 @@ #include "options.hpp" -#include "minimize.hpp" +#include "processing.hpp" ztd::option_set options = gen_options(); bool opt_minimize=false; @@ -37,8 +37,8 @@ ztd::option_set gen_options() ztd::option("list-var-call", false, "List all variables invoked in the script"), ztd::option("list-fct", false, "List all functions defined in the script"), ztd::option("list-cmd", false, "List all commands invoked in the script"), - // ztd::option("unset-var", false, "Add 'unset' to all vars at the start of the script to avoid environment interference"), - ztd::option("remove-unused", false, "Remove unused functions") + ztd::option("remove-unused", false, "Remove unused functions and variables") + // ztd::option("unset-var", false, "Add 'unset' to all vars at the start of the script to avoid environment interference") ); return ret; } diff --git a/src/processing.cpp b/src/processing.cpp new file mode 100644 index 0000000..a4a1c0d --- /dev/null +++ b/src/processing.cpp @@ -0,0 +1,384 @@ +#include "processing.hpp" + +#include + +#include "recursive.hpp" +#include "parse.hpp" +#include "util.hpp" + +// Global regex + +std::regex re_var_exclude; +std::regex re_fct_exclude; + +const std::regex regex_null; + +// Object maps + +countmap_t m_vars, m_vardefs, m_varcalls; +countmap_t m_fcts, m_cmds; +set_t m_excluded_var, m_excluded_fct, m_excluded_cmd; + +bool b_gotvar=false, b_gotfct=false, b_gotcmd=false; + +// requires + +void require_rescan_var() +{ + b_gotvar = false; + m_vars.clear(); + m_vardefs.clear(); + m_varcalls.clear(); + m_excluded_var.clear(); +} +void require_rescan_fct() +{ + b_gotcmd = false; + m_fcts.clear(); + m_excluded_fct.clear(); +} +void require_rescan_cmd() +{ + b_gotfct = false; + m_cmds.clear(); + m_excluded_cmd.clear(); +} + +void require_rescan_all() +{ + require_rescan_var(); + require_rescan_fct(); + require_rescan_cmd(); +} + +/** TOOLS **/ + +// type tools +countmap_t combine_maps(countmap_t const& a, countmap_t const& b) +{ + countmap_t ret; + for(auto it: a) + { + if(!ret.insert( it ).second) + ret[it.first] += it.second; + } + for(auto it: b) + { + if(!ret.insert( it ).second) + ret[it.first] += it.second; + } + return ret; +} + +void list_map(countmap_t const& map) +{ + uint32_t max=0; + for(auto it: map) + if(it.second > max) + max=it.second; + for(auto it: map) + printf("%*d %s\n", (uint32_t)log10(max)+1, it.second, it.first.c_str()); +} + +inline std::vector get_list(std::string const& in) +{ + return split(in, ", \t\n"); +} + +std::regex gen_regex_from_list(std::vector const& in) +{ + std::string re; + for(auto it: in) + re += '('+it+")|"; + if(re.size()>0) + re.pop_back(); + return std::regex(re); +} + +std::vector gen_var_excludes(std::string const& in, bool include_reserved) +{ + std::vector ret; + if(include_reserved) + { + ret = {RESERVED_VARIABLES, strf("[0-9%s]", SPECIAL_VARS)}; + } + auto t = get_list(in); + ret.insert(ret.end(), t.begin(), t.end()); + return ret; +} + +std::regex var_exclude_regex(std::string const& in, bool include_reserved) +{ + return gen_regex_from_list(gen_var_excludes(in, include_reserved)); +} +std::regex fct_exclude_regex(std::string const& in) +{ + return gen_regex_from_list(get_list(in)); +} + +// Variable checks and extensions + +bool is_varname(std::string const& in) +{ + if(in.size() <= 0 || !(is_alpha(in[0]) || in[0]== '_') ) + return false; + uint32_t i=1; + while(isa.size() < 1 || in->sa[0]->type != _obj::subarg_string) + return ""; + std::string str = in->sa[0]->generate(0); + if(in->sa.size() >= 1 && is_varname(str)) + return get_varname(str); + return ""; +} + +bool cmd_is_argvar(std::string const& in) +{ + return in == "export" || in == "unset" || in == "local" || in == "read"; +} + +bool cmd::is_argvar() +{ + return cmd_is_argvar(this->firstarg_string()); +} + +/** GETTERS **/ + +void varmap_get(_obj* in, std::regex const& exclude) +{ + if(!b_gotvar) + { + b_gotvar=true; + recurse(r_get_var, in, &m_vardefs, &m_varcalls); + m_vars = combine_maps(m_vardefs, m_varcalls); + m_excluded_var = prune_matching(m_vars, exclude); + } +} + +void fctmap_get(_obj* in, std::regex const& exclude) +{ + if(!b_gotfct) + { + b_gotfct=true; + recurse(r_get_fct, in, &m_fcts); + m_excluded_fct = prune_matching(m_fcts, exclude); + } +} + +void cmdmap_get(_obj* in, std::regex const& exclude) +{ + if(!b_gotcmd) + { + b_gotcmd=true; + recurse(r_get_cmd, in, &m_cmds); + m_excluded_fct = prune_matching(m_cmds, exclude); + } +} + +/** OUTPUT **/ + + +void list_vars(_obj* in, std::regex const& exclude) +{ + varmap_get(in, exclude); + list_map(m_vars); +} + +void list_var_defs(_obj* in, std::regex const& exclude) +{ + varmap_get(in, exclude); + list_map(m_vardefs); +} + +void list_var_calls(_obj* in, std::regex const& exclude) +{ + varmap_get(in, exclude); + list_map(m_varcalls); +} + +void list_fcts(_obj* in, std::regex const& exclude) +{ + fctmap_get(in, exclude); + list_map(m_fcts); +} + +void list_cmds(_obj* in, std::regex const& exclude) +{ + cmdmap_get(in, exclude); + list_map(m_cmds); +} + +/** RECURSIVES **/ + +// GET // + +bool r_get_var(_obj* in, countmap_t* defmap, countmap_t* callmap) +{ + switch(in->type) + { + case _obj::subarg_variable: { + variable_subarg* t = dynamic_cast(in); + if(!callmap->insert( std::make_pair(t->varname, 1) ).second) + (*callmap)[t->varname]++; + }; break; + case _obj::subarg_manipulation: { + manipulation_subarg* t = dynamic_cast(in); + if(!callmap->insert( std::make_pair(t->varname, 1) ).second) + (*callmap)[t->varname]++; + }; break; + case _obj::block_for: { + for_block* t = dynamic_cast(in); + if(!defmap->insert( std::make_pair(t->varname, 1) ).second) + (*defmap)[t->varname]++; + }; break; + case _obj::block_cmd: { + cmd* t = dynamic_cast(in); + for(auto it: t->var_assigns) + if(!defmap->insert( std::make_pair(it.first, 1) ).second) + (*defmap)[it.first]++; + if(t->is_argvar()) + { + for(uint32_t i=1; iargs->size(); i++) + { + std::string varname=get_varname(t->args->args[i]); + if( varname != "" && !defmap->insert( std::make_pair(varname, 1) ).second ) + (*defmap)[varname]++; + } + } + }; break; + default: break; + } + return true; +} + +bool r_get_cmd(_obj* in, countmap_t* all_cmds) +{ + switch(in->type) + { + case _obj::block_cmd: { + cmd* t = dynamic_cast(in); + std::string cmdname = t->firstarg_string(); + if(cmdname != "" && !all_cmds->insert( std::make_pair(cmdname, 1) ).second) + (*all_cmds)[cmdname]++; + }; break; + default: break; + } + return true; +} + +bool r_get_fct(_obj* in, countmap_t* fct_map) +{ + switch(in->type) + { + case _obj::block_function: { + function* t = dynamic_cast(in); + if(!fct_map->insert( std::make_pair(t->name, 1) ).second) + (*fct_map)[t->name]++; + }; break; + default: break; + } + return true; +} + +// DELETE // + +bool r_delete_fct(_obj* in, set_t* fcts) +{ + switch(in->type) + { + case _obj::_list: { + list* t = dynamic_cast(in); + for(uint32_t i=0; icls.size(); i++) + { + block* tb = t->cls[i]->first_block(); + if(tb != nullptr && tb->type == _obj::block_function) + { + function* fc = dynamic_cast(tb); + if(fcts->find(fc->name)!=fcts->end()) + { + delete t->cls[i]; + t->cls.erase(t->cls.begin()+i); + i--; + } + } + } + } + default: break; + } + return true; +} + +bool r_delete_var(_obj* in, set_t* vars) +{ + switch(in->type) + { + case _obj::_list: { + list* t = dynamic_cast(in); + for(uint32_t i=0; icls.size(); i++) + { + block* tb = t->cls[i]->first_block(); + bool to_delete=false; + if(tb != nullptr && tb->type == _obj::block_cmd) + { + cmd* c = dynamic_cast(tb); + + for(uint32_t j=0; jvar_assigns.size(); j++) + { + if( vars->find(c->var_assigns[j].first) != vars->end() ) + { + delete c->var_assigns[j].second; + c->var_assigns.erase(c->var_assigns.begin()+j); + j--; + } + } + + if(c->is_argvar()) + { + for(uint32_t j=1; jargs->size(); j++) + { + std::string varname=get_varname(c->args->args[j]); + if( varname != "" && vars->find( varname ) != vars->end() ) + { + delete c->args->args[j]; + c->args->args.erase(c->args->args.begin()+j); + j--; + } + } + if(c->args->size()<=1) + to_delete=true; + } + if(c->var_assigns.size()<=0 && c->arglist_size()<=0) + to_delete=true; + + } + if(to_delete) + { + delete t->cls[i]; + t->cls.erase(t->cls.begin()+i); + i--; + } + } + } + default: break; + } + return true; +}