optimize minify operations

This commit is contained in:
zawz 2021-08-19 17:48:46 +02:00
parent 04abba0dfd
commit 04ef171515
5 changed files with 134 additions and 44 deletions

View file

@ -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

View file

@ -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 **/

View file

@ -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 );

View file

@ -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);
}

View file

@ -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 **/