Optimize var operations on get argument var definitions
This commit is contained in:
parent
269427af3d
commit
b3f02ce06d
6 changed files with 149 additions and 98 deletions
|
|
@ -6,21 +6,26 @@
|
||||||
#include <regex>
|
#include <regex>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
typedef std::map<std::string,uint32_t> countmap_t;
|
||||||
|
|
||||||
extern std::regex re_var_exclude;
|
extern std::regex re_var_exclude;
|
||||||
extern std::regex re_fct_exclude;
|
extern std::regex re_fct_exclude;
|
||||||
|
|
||||||
|
extern const std::regex regex_null;
|
||||||
|
|
||||||
#define RESERVED_VARIABLES "HOME", "PATH", "SHELL", "PWD", "OPTIND", "OPTARG"
|
#define RESERVED_VARIABLES "HOME", "PATH", "SHELL", "PWD", "OPTIND", "OPTARG"
|
||||||
|
|
||||||
std::regex var_exclude_regex(std::string const& in);
|
std::regex var_exclude_regex(std::string const& in);
|
||||||
std::regex fct_exclude_regex(std::string const& in);
|
std::regex fct_exclude_regex(std::string const& in);
|
||||||
|
|
||||||
void list_vars(_obj* in, std::regex exclude);
|
void list_vars(_obj* in, std::regex const& exclude);
|
||||||
void list_fcts(_obj* in, std::regex exclude);
|
void list_fcts(_obj* in, std::regex const& exclude);
|
||||||
void list_cmds(_obj* in, std::regex exclude);
|
void list_cmds(_obj* in, std::regex const& exclude);
|
||||||
|
|
||||||
void minimize_var(_obj* in, std::regex exclude);
|
void minimize_var(_obj* in, std::regex const& exclude);
|
||||||
void minimize_fct(_obj* in, std::regex exclude);
|
void minimize_fct(_obj* in, std::regex const& exclude);
|
||||||
|
|
||||||
void delete_unused_fct(_obj* in, std::regex exclude);
|
void delete_unused_fct(_obj* in, std::regex const& exclude);
|
||||||
|
// void delete_unused_var(_obj* in, std::regex const& exclude);
|
||||||
|
|
||||||
#endif //MINIMIZE_HPP
|
#endif //MINIMIZE_HPP
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,10 @@
|
||||||
|
|
||||||
#define SPECIAL_VARS "!#*@$?"
|
#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);
|
std::string import_file(std::string const& path);
|
||||||
|
|
||||||
shmain* parse_text(const char* in, uint32_t size, std::string const& filename="");
|
shmain* parse_text(const char* in, uint32_t size, std::string const& filename="");
|
||||||
|
|
|
||||||
|
|
@ -6,19 +6,6 @@
|
||||||
#include "options.hpp"
|
#include "options.hpp"
|
||||||
#include "parse.hpp"
|
#include "parse.hpp"
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_sub_special_cmd(std::string in)
|
bool is_sub_special_cmd(std::string in)
|
||||||
{
|
{
|
||||||
return in == "%include_sub" || in == "%resolve_sub";
|
return in == "%include_sub" || in == "%resolve_sub";
|
||||||
|
|
|
||||||
|
|
@ -160,9 +160,9 @@ int main(int argc, char* argv[])
|
||||||
if(options["list-var"])
|
if(options["list-var"])
|
||||||
list_vars(sh, re_var_exclude);
|
list_vars(sh, re_var_exclude);
|
||||||
else if(options["list-fct"])
|
else if(options["list-fct"])
|
||||||
list_fcts(sh, re_var_exclude);
|
list_fcts(sh, re_fct_exclude);
|
||||||
else if(options["list-cmd"])
|
else if(options["list-cmd"])
|
||||||
list_cmds(sh, re_var_exclude);
|
list_cmds(sh, regex_null);
|
||||||
else if(is_exec)
|
else if(is_exec)
|
||||||
{
|
{
|
||||||
ret = execute(sh, args);
|
ret = execute(sh, args);
|
||||||
|
|
|
||||||
196
src/minimize.cpp
196
src/minimize.cpp
|
|
@ -11,6 +11,14 @@
|
||||||
std::regex re_var_exclude;
|
std::regex re_var_exclude;
|
||||||
std::regex re_fct_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<std::string> m_excluded_var, m_excluded_fct, m_excluded_cmd;
|
||||||
|
|
||||||
|
bool b_gotvar=false, b_gotfct=false, b_gotcmd=false;
|
||||||
|
|
||||||
std::vector<std::string> get_list(std::string const& in)
|
std::vector<std::string> get_list(std::string const& in)
|
||||||
{
|
{
|
||||||
return split(in, ", \t\n");
|
return split(in, ", \t\n");
|
||||||
|
|
@ -43,6 +51,20 @@ std::regex fct_exclude_regex(std::string const& in)
|
||||||
return gen_regex_from_list(get_list(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(i<in.size() && (is_alphanum(in[i]) || in[i] == '_'))
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if(i<in.size() && in[i]!='=')
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<subarg*> cmd::arg_vars()
|
std::vector<subarg*> cmd::arg_vars()
|
||||||
{
|
{
|
||||||
std::vector<subarg*> ret;
|
std::vector<subarg*> ret;
|
||||||
|
|
@ -57,16 +79,8 @@ std::vector<subarg*> cmd::arg_vars()
|
||||||
arg* ta = args->args[i];
|
arg* ta = args->args[i];
|
||||||
if(ta->sa.size() < 1 || ta->sa[0]->type != _obj::subarg_string)
|
if(ta->sa.size() < 1 || ta->sa[0]->type != _obj::subarg_string)
|
||||||
continue;
|
continue;
|
||||||
if(ta->sa.size() == 1)
|
if(ta->sa.size() >= 1 && is_varname(ta->sa[0]->generate(0)))
|
||||||
{
|
ret.push_back(ta->sa[0]);
|
||||||
if( std::regex_match(ta->sa[0]->generate(0), std::regex("[a-zA-Z_][0-9a-zA-Z_]*([=](.*)?)?") ) )
|
|
||||||
ret.push_back(ta->sa[0]);
|
|
||||||
}
|
|
||||||
else if(ta->sa.size() > 1)
|
|
||||||
{
|
|
||||||
if( std::regex_match(ta->sa[0]->generate(0), std::regex("[a-zA-Z_][0-9a-zA-Z_]*=.*") ) )
|
|
||||||
ret.push_back(ta->sa[0]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -87,37 +101,35 @@ std::string get_varname(subarg* in)
|
||||||
|
|
||||||
/** VAR RECURSE **/
|
/** VAR RECURSE **/
|
||||||
|
|
||||||
bool get_map_varname(_obj* in, std::map<std::string,uint32_t>* variable_map)
|
bool get_var(_obj* in, countmap_t* defmap, countmap_t* callmap)
|
||||||
{
|
{
|
||||||
if(variable_map == nullptr)
|
|
||||||
return false;
|
|
||||||
switch(in->type)
|
switch(in->type)
|
||||||
{
|
{
|
||||||
case _obj::subarg_variable: {
|
case _obj::subarg_variable: {
|
||||||
variable_subarg* t = dynamic_cast<variable_subarg*>(in);
|
variable_subarg* t = dynamic_cast<variable_subarg*>(in);
|
||||||
if(!variable_map->insert( std::make_pair(t->varname, 1) ).second)
|
if(!callmap->insert( std::make_pair(t->varname, 1) ).second)
|
||||||
(*variable_map)[t->varname]++;
|
(*callmap)[t->varname]++;
|
||||||
}; break;
|
}; break;
|
||||||
case _obj::subarg_manipulation: {
|
case _obj::subarg_manipulation: {
|
||||||
manipulation_subarg* t = dynamic_cast<manipulation_subarg*>(in);
|
manipulation_subarg* t = dynamic_cast<manipulation_subarg*>(in);
|
||||||
if(!variable_map->insert( std::make_pair(t->varname, 1) ).second)
|
if(!callmap->insert( std::make_pair(t->varname, 1) ).second)
|
||||||
(*variable_map)[t->varname]++;
|
(*callmap)[t->varname]++;
|
||||||
}; break;
|
}; break;
|
||||||
case _obj::block_for: {
|
case _obj::block_for: {
|
||||||
for_block* t = dynamic_cast<for_block*>(in);
|
for_block* t = dynamic_cast<for_block*>(in);
|
||||||
if(!variable_map->insert( std::make_pair(t->varname, 1) ).second)
|
if(!defmap->insert( std::make_pair(t->varname, 1) ).second)
|
||||||
(*variable_map)[t->varname]++;
|
(*defmap)[t->varname]++;
|
||||||
}; break;
|
}; break;
|
||||||
case _obj::block_cmd: {
|
case _obj::block_cmd: {
|
||||||
cmd* t = dynamic_cast<cmd*>(in);
|
cmd* t = dynamic_cast<cmd*>(in);
|
||||||
for(auto it: t->var_assigns)
|
for(auto it: t->var_assigns)
|
||||||
if(!variable_map->insert( std::make_pair(it.first, 1) ).second)
|
if(!defmap->insert( std::make_pair(it.first, 1) ).second)
|
||||||
(*variable_map)[it.first]++;
|
(*defmap)[it.first]++;
|
||||||
for(auto it: t->arg_vars())
|
for(auto it: t->arg_vars())
|
||||||
{
|
{
|
||||||
std::string varname=get_varname(it);
|
std::string varname=get_varname(it);
|
||||||
if(!variable_map->insert( std::make_pair(varname, 1) ).second)
|
if(!defmap->insert( std::make_pair(varname, 1) ).second)
|
||||||
(*variable_map)[varname]++;
|
(*defmap)[varname]++;
|
||||||
}
|
}
|
||||||
}; break;
|
}; break;
|
||||||
default: break;
|
default: break;
|
||||||
|
|
@ -176,7 +188,7 @@ bool replace_varname(_obj* in, std::map<std::string,std::string>* varmap)
|
||||||
|
|
||||||
/** FCT RECURSE **/
|
/** FCT RECURSE **/
|
||||||
|
|
||||||
bool get_map_cmd(_obj* in, std::map<std::string,uint32_t>* all_cmds)
|
bool get_cmd(_obj* in, countmap_t* all_cmds)
|
||||||
{
|
{
|
||||||
switch(in->type)
|
switch(in->type)
|
||||||
{
|
{
|
||||||
|
|
@ -191,7 +203,7 @@ bool get_map_cmd(_obj* in, std::map<std::string,uint32_t>* all_cmds)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool get_map_fctname(_obj* in, std::map<std::string,uint32_t>* fct_map)
|
bool get_fct(_obj* in, countmap_t* fct_map)
|
||||||
{
|
{
|
||||||
switch(in->type)
|
switch(in->type)
|
||||||
{
|
{
|
||||||
|
|
@ -296,7 +308,54 @@ std::string minimal_name(uint32_t n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<std::string,std::string> gen_map(std::map<std::string,uint32_t> const& vars, std::set<std::string> excluded)
|
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 varmap_get(_obj* in, std::regex const& exclude)
|
||||||
|
{
|
||||||
|
if(!b_gotvar)
|
||||||
|
{
|
||||||
|
b_gotvar=true;
|
||||||
|
recurse(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(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(get_cmd, in, &m_cmds);
|
||||||
|
m_excluded_fct = prune_matching(m_cmds, exclude);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<std::string,std::string> gen_minimal_map(countmap_t const& vars, std::set<std::string> excluded)
|
||||||
{
|
{
|
||||||
std::map<std::string,std::string> ret;
|
std::map<std::string,std::string> ret;
|
||||||
auto ordered = sort_by_value(vars);
|
auto ordered = sort_by_value(vars);
|
||||||
|
|
@ -313,65 +372,71 @@ std::map<std::string,std::string> gen_map(std::map<std::string,uint32_t> const&
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void minimize_var(_obj* in, std::regex exclude)
|
void minimize_var(_obj* in, std::regex const& exclude)
|
||||||
{
|
{
|
||||||
std::map<std::string,uint32_t> vars;
|
// countmap_t vars;
|
||||||
std::set<std::string> excluded;
|
std::set<std::string> excluded;
|
||||||
std::map<std::string,std::string> varmap;
|
std::map<std::string,std::string> varmap;
|
||||||
// get vars
|
// get vars
|
||||||
recurse(get_map_varname, in, &vars);
|
varmap_get(in, exclude);
|
||||||
// remove excluded
|
|
||||||
excluded = prune_matching(vars, exclude);
|
|
||||||
// create mapping
|
// create mapping
|
||||||
varmap=gen_map(vars, excluded);
|
varmap=gen_minimal_map(m_vars, m_excluded_var);
|
||||||
// perform replace
|
// perform replace
|
||||||
recurse(replace_varname, in, &varmap);
|
recurse(replace_varname, in, &varmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
void minimize_fct(_obj* in, std::regex exclude)
|
void minimize_fct(_obj* in, std::regex const& exclude)
|
||||||
{
|
{
|
||||||
std::map<std::string,uint32_t> fcts, cmdmap;
|
// countmap_t fcts, cmdmap;
|
||||||
std::set<std::string> allcmds, excluded;
|
std::set<std::string> allcmds, excluded;
|
||||||
std::map<std::string,std::string> fctmap;
|
std::map<std::string,std::string> fctmap;
|
||||||
// get fcts
|
// get fcts and cmds
|
||||||
recurse(get_map_fctname, in, &fcts);
|
fctmap_get(in, exclude);
|
||||||
// get cmds
|
cmdmap_get(in, regex_null);
|
||||||
recurse(get_map_cmd, in, &cmdmap);
|
// concatenate cmds and excluded commands
|
||||||
allcmds=map_to_set(cmdmap);
|
allcmds=map_to_set(m_cmds);
|
||||||
// remove excluded
|
concat_sets(allcmds, m_excluded_fct);
|
||||||
excluded = prune_matching(fcts, exclude);
|
|
||||||
// concatenate excluded to commands
|
|
||||||
concat_sets(allcmds, excluded);
|
|
||||||
// create mapping
|
// create mapping
|
||||||
fctmap=gen_map(fcts, allcmds);
|
fctmap=gen_minimal_map(m_fcts, allcmds);
|
||||||
// perform replace
|
// perform replace
|
||||||
recurse(replace_fctname, in, &fctmap);
|
recurse(replace_fctname, in, &fctmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
void delete_unused_fct(_obj* in, std::regex exclude)
|
void delete_unused_fct(_obj* in, std::regex const& exclude)
|
||||||
{
|
{
|
||||||
std::map<std::string,uint32_t> fctmap, cmdmap;
|
|
||||||
std::set<std::string> unused;
|
std::set<std::string> unused;
|
||||||
// get fcts
|
// get fcts and cmds
|
||||||
recurse(get_map_fctname, in, &fctmap);
|
fctmap_get(in, exclude);
|
||||||
// get cmds
|
cmdmap_get(in, regex_null);
|
||||||
recurse(get_map_cmd, in, &cmdmap);
|
// find unused fcts
|
||||||
// remove excluded
|
for(auto it: m_fcts)
|
||||||
prune_matching(fctmap, exclude);
|
|
||||||
for(auto it: fctmap)
|
|
||||||
{
|
{
|
||||||
if(cmdmap.find(it.first) == cmdmap.end())
|
if(m_cmds.find(it.first) == m_cmds.end())
|
||||||
unused.insert(it.first);
|
unused.insert(it.first);
|
||||||
}
|
}
|
||||||
|
// perform deletion
|
||||||
if(unused.size()>0)
|
if(unused.size()>0)
|
||||||
recurse(delete_fcts, in, &unused);
|
recurse(delete_fcts, in, &unused);
|
||||||
}
|
}
|
||||||
|
|
||||||
void list_stuff(_obj* in, std::regex exclude, bool (&fct)(_obj*,std::map<std::string,uint32_t>*) )
|
void delete_unused_var(_obj* in, std::regex const& exclude)
|
||||||
|
{
|
||||||
|
std::set<std::string> unused;
|
||||||
|
// get fcts and cmds
|
||||||
|
varmap_get(in, exclude);
|
||||||
|
// find unused vars
|
||||||
|
for(auto it: m_vardefs)
|
||||||
|
{
|
||||||
|
if(m_varcalls.find(it.first) == m_varcalls.end())
|
||||||
|
unused.insert(it.first);
|
||||||
|
}
|
||||||
|
// perform deletion
|
||||||
|
if(unused.size()>0)
|
||||||
|
recurse(delete_fcts, in, &unused);
|
||||||
|
}
|
||||||
|
|
||||||
|
void list_map(countmap_t const& map)
|
||||||
{
|
{
|
||||||
std::map<std::string,uint32_t> map;
|
|
||||||
recurse(fct, in, &map);
|
|
||||||
prune_matching(map, exclude);
|
|
||||||
uint32_t max=0;
|
uint32_t max=0;
|
||||||
for(auto it: map)
|
for(auto it: map)
|
||||||
if(it.second > max)
|
if(it.second > max)
|
||||||
|
|
@ -380,17 +445,20 @@ void list_stuff(_obj* in, std::regex exclude, bool (&fct)(_obj*,std::map<std::st
|
||||||
printf("%*d %s\n", (uint32_t)log10(max)+1, it.second, it.first.c_str());
|
printf("%*d %s\n", (uint32_t)log10(max)+1, it.second, it.first.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void list_vars(_obj* in, std::regex exclude)
|
void list_vars(_obj* in, std::regex const& exclude)
|
||||||
{
|
{
|
||||||
list_stuff(in, exclude, get_map_varname);
|
varmap_get(in, exclude);
|
||||||
|
list_map(m_vars);
|
||||||
}
|
}
|
||||||
|
|
||||||
void list_fcts(_obj* in, std::regex exclude)
|
void list_fcts(_obj* in, std::regex const& exclude)
|
||||||
{
|
{
|
||||||
list_stuff(in, exclude, get_map_fctname);
|
fctmap_get(in, exclude);
|
||||||
|
list_map(m_fcts);
|
||||||
}
|
}
|
||||||
|
|
||||||
void list_cmds(_obj* in, std::regex exclude)
|
void list_cmds(_obj* in, std::regex const& exclude)
|
||||||
{
|
{
|
||||||
list_stuff(in, exclude, get_map_cmd);
|
cmdmap_get(in, exclude);
|
||||||
|
list_map(m_cmds);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,19 +44,6 @@ bool has_common_char(const char* str1, const char* str2)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool valid_name(std::string const& str)
|
bool valid_name(std::string const& str)
|
||||||
{
|
{
|
||||||
if(!is_alpha(str[0]) && str[0] != '_') return false;
|
if(!is_alpha(str[0]) && str[0] != '_') return false;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue