optimize minify operations
This commit is contained in:
parent
04abba0dfd
commit
04ef171515
5 changed files with 134 additions and 44 deletions
|
|
@ -9,12 +9,8 @@
|
|||
void minify_var(_obj* in, std::regex const& exclude);
|
||||
void minify_fct(_obj* in, std::regex const& exclude);
|
||||
|
||||
bool delete_unused_fct(_obj* in, std::regex const& exclude);
|
||||
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);
|
||||
|
||||
void minify_quotes(_obj* in);
|
||||
|
||||
void minify_generic(_obj* in);
|
||||
|
||||
#endif //MINIFY_HPP
|
||||
|
|
|
|||
|
|
@ -35,7 +35,6 @@ countmap_t combine_common(countmap_t const& a, countmap_t const& b);
|
|||
|
||||
/** map get functions (optimizations) **/
|
||||
|
||||
|
||||
// rescans
|
||||
void require_rescan_all();
|
||||
void require_rescan_var();
|
||||
|
|
@ -46,6 +45,8 @@ void require_rescan_cmd();
|
|||
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);
|
||||
void fctcmdmap_get(_obj* in, std::regex const& exclude_fct, std::regex const& exclude_cmd);
|
||||
void allmaps_get(_obj* in, std::regex const& exclude_var, std::regex const& exclude_fct, std::regex const& exclude_cmd);
|
||||
|
||||
/** util functions **/
|
||||
#ifdef DEBUG_MODE
|
||||
|
|
@ -75,8 +76,12 @@ 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);
|
||||
bool r_get_fct(_obj* in, countmap_t* fct_map);
|
||||
bool r_get_fctcmd(_obj* in, countmap_t* all_cmds, countmap_t* fct_map);
|
||||
bool r_get_all(_obj* in, countmap_t* defmap, countmap_t* callmap, countmap_t* all_cmds, countmap_t* fct_map);
|
||||
bool r_delete_fct(_obj* in, set_t* fcts);
|
||||
bool r_delete_var(_obj* in, set_t* vars);
|
||||
bool r_delete_varfct(_obj* in, set_t* vars, set_t* fcts);
|
||||
bool r_do_string_processor(_obj* in);
|
||||
|
||||
/** Processing **/
|
||||
|
||||
|
|
|
|||
13
src/main.cpp
13
src/main.cpp
|
|
@ -198,13 +198,20 @@ int main(int argc, char* argv[])
|
|||
if(options['m'])
|
||||
{
|
||||
opt_minify=true;
|
||||
string_processors(sh);
|
||||
minify_generic(sh);
|
||||
}
|
||||
if(options["minify-var"])
|
||||
if(options["minify-var"] && options["minify-fct"]) {
|
||||
// optimization: get everything in one go
|
||||
allmaps_get(sh, re_var_exclude, re_fct_exclude, regex_null);
|
||||
minify_var( sh, re_var_exclude );
|
||||
if(options["minify-fct"])
|
||||
minify_fct( sh, re_fct_exclude );
|
||||
}
|
||||
else if(options["minify-var"]) {
|
||||
minify_var( sh, re_var_exclude );
|
||||
}
|
||||
else if(options["minify-fct"]) {
|
||||
minify_fct( sh, re_fct_exclude );
|
||||
}
|
||||
// other processing
|
||||
if(options["unset-var"])
|
||||
add_unset_variables( sh, re_var_exclude );
|
||||
|
|
|
|||
|
|
@ -224,11 +224,11 @@ bool r_minify_useless_quotes(_obj* in)
|
|||
redirect* t = dynamic_cast<redirect*>(in);
|
||||
if(t->here_document != nullptr)
|
||||
{
|
||||
minify_quotes(t->target);
|
||||
recurse(r_minify_useless_quotes, t->target);
|
||||
for(auto it: t->here_document->sa)
|
||||
{
|
||||
if(it->type!=_obj::subarg_string) {
|
||||
minify_quotes(it);
|
||||
recurse(r_minify_useless_quotes, it);
|
||||
}
|
||||
}
|
||||
// don't recurse on the rest
|
||||
|
|
@ -324,8 +324,7 @@ void minify_fct(_obj* in, std::regex const& exclude)
|
|||
set_t excluded, unsets;
|
||||
strmap_t fctmap;
|
||||
// get fcts and cmds
|
||||
fctmap_get(in, exclude);
|
||||
cmdmap_get(in, regex_null);
|
||||
fctcmdmap_get(in, exclude, regex_null);
|
||||
recurse(r_get_unsets, in, &unsets);
|
||||
// concatenate cmds, excluded and reserved
|
||||
excluded=map_to_set(m_cmds);
|
||||
|
|
@ -346,8 +345,7 @@ bool delete_unused_fct(_obj* in, std::regex const& exclude)
|
|||
{
|
||||
set_t unused;
|
||||
// get fcts and cmds
|
||||
fctmap_get(in, exclude);
|
||||
cmdmap_get(in, regex_null);
|
||||
fctcmdmap_get(in, exclude, regex_null);
|
||||
// find unused fcts
|
||||
for(auto it: m_fcts)
|
||||
{
|
||||
|
|
@ -387,15 +385,35 @@ bool delete_unused_var(_obj* in, std::regex const& exclude)
|
|||
return false;
|
||||
}
|
||||
|
||||
void minify_quotes(_obj* in)
|
||||
bool delete_unused_both(_obj* in, std::regex const& var_exclude, std::regex const& fct_exclude)
|
||||
{
|
||||
recurse(r_minify_useless_quotes, in);
|
||||
set_t unused_var, unused_fct;
|
||||
// get all
|
||||
allmaps_get(in, var_exclude, fct_exclude, regex_null);
|
||||
// find unused
|
||||
for(auto it: m_vardefs)
|
||||
{
|
||||
if(it.first!="" && m_varcalls.find(it.first) == m_varcalls.end())
|
||||
unused_var.insert(it.first);
|
||||
}
|
||||
for(auto it: m_fcts)
|
||||
{
|
||||
if(m_cmds.find(it.first) == m_cmds.end())
|
||||
unused_fct.insert(it.first);
|
||||
}
|
||||
if(unused_var.size()>0 || unused_fct.size()>0)
|
||||
{
|
||||
recurse(r_delete_varfct, in, &unused_var, &unused_fct);
|
||||
require_rescan_all();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
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));
|
||||
// keep deleting until both no function and no variables were deleted
|
||||
while(delete_unused_both(in, var_exclude, fct_exclude));
|
||||
// keep deleting until both no deletion
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -424,7 +442,7 @@ bool r_minify_empty_manip(_obj* in)
|
|||
char c = ss->val[0];
|
||||
// if its first would extend the var name: skip
|
||||
if(is_alphanum(c) || c == '_')
|
||||
return true;
|
||||
continue;
|
||||
}
|
||||
// if has no actual manipulation operation: set it to not manip
|
||||
if(ss->var->manip == nullptr || ss->var->manip->sa.size() == 0)
|
||||
|
|
@ -468,39 +486,53 @@ bool r_minify_single_block(_obj* in)
|
|||
switch(in->type)
|
||||
{
|
||||
case _obj::_pipeline: {
|
||||
pipeline* t = dynamic_cast<pipeline*>(in);
|
||||
for(uint32_t i=0; i<t->cmds.size(); i++)
|
||||
bool has_operated=false;
|
||||
do
|
||||
{
|
||||
block* ret = do_one_minify_single_block(t->cmds[i]);
|
||||
if(ret != nullptr) {
|
||||
// concatenate redirects
|
||||
for(uint32_t j=0; j<t->cmds[i]->redirs.size(); j++)
|
||||
// loop operating on current
|
||||
// (if has operated, current object has changed)
|
||||
has_operated=false;
|
||||
pipeline* t = dynamic_cast<pipeline*>(in);
|
||||
for(uint32_t i=0; i<t->cmds.size(); i++)
|
||||
{
|
||||
block* ret = do_one_minify_single_block(t->cmds[i]);
|
||||
if(ret != nullptr) {
|
||||
// concatenate redirects
|
||||
for(uint32_t j=0; j<t->cmds[i]->redirs.size(); j++)
|
||||
ret->redirs.insert(ret->redirs.begin()+j, t->cmds[i]->redirs[j]);
|
||||
|
||||
// deindex
|
||||
t->cmds[i]->redirs.resize(0);
|
||||
if(t->cmds[i]->type == _obj::block_brace)
|
||||
// deindex
|
||||
t->cmds[i]->redirs.resize(0);
|
||||
if(t->cmds[i]->type == _obj::block_brace)
|
||||
dynamic_cast<brace*>(t->cmds[i])->lst->cls[0]->pls[0]->cmds[0] = nullptr;
|
||||
else if(t->cmds[i]->type == _obj::block_subshell)
|
||||
else if(t->cmds[i]->type == _obj::block_subshell)
|
||||
dynamic_cast<subshell*>(t->cmds[i])->lst->cls[0]->pls[0]->cmds[0] = nullptr;
|
||||
|
||||
// replace value
|
||||
delete t->cmds[i];
|
||||
t->cmds[i] = ret;
|
||||
// replace value
|
||||
delete t->cmds[i];
|
||||
t->cmds[i] = ret;
|
||||
|
||||
recurse(r_minify_single_block, in);
|
||||
return false;
|
||||
has_operated=true;
|
||||
}
|
||||
}
|
||||
}
|
||||
while(has_operated);
|
||||
}; break;
|
||||
default: break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool r_minify(_obj* in)
|
||||
{
|
||||
r_minify_empty_manip(in);
|
||||
r_minify_single_block(in);
|
||||
r_minify_useless_quotes(in);
|
||||
r_do_string_processor(in);
|
||||
return true;
|
||||
}
|
||||
|
||||
void minify_generic(_obj* in)
|
||||
{
|
||||
recurse(r_minify_empty_manip, in);
|
||||
recurse(r_minify_single_block, in);
|
||||
minify_quotes(in);
|
||||
recurse(r_minify, in);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ 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()
|
||||
|
|
@ -214,6 +213,39 @@ void cmdmap_get(_obj* in, std::regex const& exclude)
|
|||
}
|
||||
}
|
||||
|
||||
void fctcmdmap_get(_obj* in, std::regex const& exclude_fct, std::regex const& exclude_cmd)
|
||||
{
|
||||
if(!b_gotcmd && !b_gotfct) {
|
||||
b_gotcmd = b_gotfct = true;
|
||||
recurse(r_get_fctcmd, in, &m_cmds, &m_fcts);
|
||||
m_excluded_fct = prune_matching(m_cmds, exclude_cmd);
|
||||
concat_sets(m_excluded_fct, prune_matching(m_fcts, exclude_fct));
|
||||
}
|
||||
else {
|
||||
cmdmap_get(in, exclude_fct);
|
||||
fctmap_get(in, exclude_cmd);
|
||||
}
|
||||
}
|
||||
|
||||
void allmaps_get(_obj* in, std::regex const& exclude_var, std::regex const& exclude_fct, std::regex const& exclude_cmd)
|
||||
{
|
||||
if(!b_gotvar && !b_gotcmd && !b_gotfct)
|
||||
{
|
||||
b_gotvar = b_gotcmd = b_gotfct = true;
|
||||
recurse(r_get_all, in, &m_vardefs, &m_varcalls, &m_cmds, &m_fcts);
|
||||
m_excluded_fct = prune_matching(m_cmds, exclude_cmd);
|
||||
concat_sets(m_excluded_fct, prune_matching(m_fcts, exclude_fct));
|
||||
m_vars = combine_maps(m_vardefs, m_varcalls);
|
||||
m_excluded_var = prune_matching(m_vars, exclude_var);
|
||||
}
|
||||
else
|
||||
{
|
||||
varmap_get(in, exclude_var);
|
||||
cmdmap_get(in, exclude_fct);
|
||||
fctmap_get(in, exclude_fct);
|
||||
}
|
||||
}
|
||||
|
||||
/** OUTPUT **/
|
||||
|
||||
void list_vars(_obj* in, std::regex const& exclude)
|
||||
|
|
@ -324,11 +356,6 @@ bool r_get_unsets(_obj* in, set_t* unsets)
|
|||
cmd* t = dynamic_cast<cmd*>(in);
|
||||
if(t->is("unset"))
|
||||
{
|
||||
for(auto it: t->var_assigns)
|
||||
{
|
||||
if(it.first != nullptr)
|
||||
unsets->insert(it.first->varname);
|
||||
}
|
||||
for(auto it: t->cmd_var_assigns)
|
||||
{
|
||||
if(it.first != nullptr)
|
||||
|
|
@ -370,6 +397,21 @@ bool r_get_fct(_obj* in, countmap_t* fct_map)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool r_get_fctcmd(_obj* in, countmap_t* all_cmds, countmap_t* fct_map)
|
||||
{
|
||||
r_get_cmd(in, all_cmds);
|
||||
r_get_fct(in, fct_map);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool r_get_all(_obj* in, countmap_t* defmap, countmap_t* callmap, countmap_t* all_cmds, countmap_t* fct_map)
|
||||
{
|
||||
r_get_var(in, defmap, callmap);
|
||||
r_get_cmd(in, all_cmds);
|
||||
r_get_fct(in, fct_map);
|
||||
return true;
|
||||
}
|
||||
|
||||
// DELETE //
|
||||
|
||||
bool r_delete_fct(_obj* in, set_t* fcts)
|
||||
|
|
@ -461,6 +503,13 @@ bool r_delete_var(_obj* in, set_t* vars)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool r_delete_varfct(_obj* in, set_t* vars, set_t* fcts)
|
||||
{
|
||||
r_delete_var(in, vars);
|
||||
r_delete_fct(in, fcts);
|
||||
return true;
|
||||
}
|
||||
|
||||
std::set<std::string> find_lxsh_commands(shmain* sh)
|
||||
{
|
||||
std::set<std::string> ret;
|
||||
|
|
@ -533,7 +582,8 @@ bool r_do_string_processor(_obj* in)
|
|||
|
||||
void string_processors(_obj* in)
|
||||
{
|
||||
recurse(r_do_string_processor, in);
|
||||
// recurse(r_do_string_processor, in);
|
||||
;
|
||||
}
|
||||
|
||||
/** JSON **/
|
||||
|
|
|
|||
Loading…
Reference in a new issue