minify empty variable manipulation
This commit is contained in:
parent
56bd8a3db7
commit
4c984bdc39
3 changed files with 56 additions and 6 deletions
|
|
@ -15,4 +15,6 @@ void delete_unused(_obj* in, std::regex const& var_exclude, std::regex const& fc
|
||||||
|
|
||||||
void minify_quotes(_obj* in);
|
void minify_quotes(_obj* in);
|
||||||
|
|
||||||
|
void minify_generic(_obj* in);
|
||||||
|
|
||||||
#endif //MINIFY_HPP
|
#endif //MINIFY_HPP
|
||||||
|
|
|
||||||
|
|
@ -205,6 +205,7 @@ int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
opt_minify=true;
|
opt_minify=true;
|
||||||
string_processors(sh);
|
string_processors(sh);
|
||||||
|
minify_generic(sh);
|
||||||
}
|
}
|
||||||
if(options["minify-quotes"])
|
if(options["minify-quotes"])
|
||||||
minify_quotes(sh);
|
minify_quotes(sh);
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ bool r_replace_var(_obj* in, strmap_t* varmap)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* escaped_char=" \\\t!\"()|&*?~><#";
|
const char* singlequote_escape_char=" \\\t!\"()|&*?~><#";
|
||||||
const char* doublequote_escape_char=" \t'|&\\*()?~><#";
|
const char* doublequote_escape_char=" \t'|&\\*()?~><#";
|
||||||
uint32_t count_escape_chars(std::string const& in, bool doublequote)
|
uint32_t count_escape_chars(std::string const& in, bool doublequote)
|
||||||
{
|
{
|
||||||
|
|
@ -78,7 +78,7 @@ uint32_t count_escape_chars(std::string const& in, bool doublequote)
|
||||||
{
|
{
|
||||||
if(doublequote && is_in(in[i], doublequote_escape_char))
|
if(doublequote && is_in(in[i], doublequote_escape_char))
|
||||||
r++;
|
r++;
|
||||||
else if(!doublequote && is_in(in[i], escaped_char))
|
else if(!doublequote && is_in(in[i], singlequote_escape_char))
|
||||||
r++;
|
r++;
|
||||||
else if(in[i] == '\n') // \n: can't remove quotes
|
else if(in[i] == '\n') // \n: can't remove quotes
|
||||||
return 2;
|
return 2;
|
||||||
|
|
@ -170,17 +170,17 @@ void do_one_minify_quotes(string_subarg* in, bool prev_is_var, bool start_quoted
|
||||||
for(k=j; k<i-1; k++)
|
for(k=j; k<i-1; k++)
|
||||||
{
|
{
|
||||||
if( is_in(val[k], doublequote_escape_char) )
|
if( is_in(val[k], doublequote_escape_char) )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for(k=j; k<i-1; k++)
|
for(k=j; k<i-1; k++)
|
||||||
{
|
{
|
||||||
if( is_in(val[k], escaped_char) )
|
if( is_in(val[k], singlequote_escape_char) )
|
||||||
break;
|
break;
|
||||||
if( k+1<val.size() && val[k] == '$' && ( is_in(val[k+1], SPECIAL_VARS) || is_alpha(val[k+1]) || val[k+1] == '_' ) )
|
if( k+1<val.size() && val[k] == '$' && ( is_in(val[k+1], SPECIAL_VARS) || is_alpha(val[k+1]) || val[k+1] == '_' ) )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(k<i-1)
|
if(k<i-1)
|
||||||
|
|
@ -199,12 +199,15 @@ bool r_minify_useless_quotes(_obj* in)
|
||||||
arg* t = dynamic_cast<arg*>(in);
|
arg* t = dynamic_cast<arg*>(in);
|
||||||
for(uint32_t i=0; i<t->sa.size(); i++)
|
for(uint32_t i=0; i<t->sa.size(); i++)
|
||||||
{
|
{
|
||||||
|
// iterate subargs
|
||||||
if(t->sa[i]->type == _obj::subarg_string)
|
if(t->sa[i]->type == _obj::subarg_string)
|
||||||
{
|
{
|
||||||
|
// has to be a string
|
||||||
string_subarg* ss = dynamic_cast<string_subarg*>(t->sa[i]);
|
string_subarg* ss = dynamic_cast<string_subarg*>(t->sa[i]);
|
||||||
bool prev_is_var=false;
|
bool prev_is_var=false;
|
||||||
if(i>0 && t->sa[i-1]->type == _obj::subarg_variable)
|
if(i>0 && t->sa[i-1]->type == _obj::subarg_variable)
|
||||||
{
|
{
|
||||||
|
// previous subarg is a direct variable (removing a quote could change variable name)
|
||||||
variable_subarg* vs = dynamic_cast<variable_subarg*>(t->sa[i-1]);
|
variable_subarg* vs = dynamic_cast<variable_subarg*>(t->sa[i-1]);
|
||||||
if(vs->var != nullptr && vs->var->is_manip == false && vs->var->varname.size()>0 && !(is_in(vs->var->varname[0], SPECIAL_VARS) || is_alpha(vs->var->varname[0]) ) )
|
if(vs->var != nullptr && vs->var->is_manip == false && vs->var->varname.size()>0 && !(is_in(vs->var->varname[0], SPECIAL_VARS) || is_alpha(vs->var->varname[0]) ) )
|
||||||
prev_is_var=true;
|
prev_is_var=true;
|
||||||
|
|
@ -217,6 +220,7 @@ bool r_minify_useless_quotes(_obj* in)
|
||||||
}
|
}
|
||||||
}; break;
|
}; break;
|
||||||
case _obj::_redirect: {
|
case _obj::_redirect: {
|
||||||
|
// for redirects: don't minify quotes on here documents
|
||||||
redirect* t = dynamic_cast<redirect*>(in);
|
redirect* t = dynamic_cast<redirect*>(in);
|
||||||
if(t->here_document != nullptr)
|
if(t->here_document != nullptr)
|
||||||
{
|
{
|
||||||
|
|
@ -393,3 +397,46 @@ void delete_unused(_obj* in, std::regex const& var_exclude, std::regex const& fc
|
||||||
while(delete_unused_fct(in, fct_exclude) || delete_unused_var(in, var_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
|
// keep deleting until both no function and no variables were deleted
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// minify ${var} to $var
|
||||||
|
bool r_minify_empty_manip(_obj* in)
|
||||||
|
{
|
||||||
|
switch(in->type)
|
||||||
|
{
|
||||||
|
case _obj::_arg: {
|
||||||
|
arg* t = dynamic_cast<arg*>(in);
|
||||||
|
for(uint32_t i=0; i<t->sa.size(); i++)
|
||||||
|
{
|
||||||
|
if(t->sa[i]->type == _obj::subarg_variable)
|
||||||
|
{
|
||||||
|
// has to be a variable
|
||||||
|
variable_subarg* ss = dynamic_cast<variable_subarg*>(t->sa[i]);
|
||||||
|
if(ss->var->is_manip)
|
||||||
|
{
|
||||||
|
// if is a manip: possibility to skip it
|
||||||
|
if(i+1<t->sa.size() && t->sa[i+1]->type == _obj::subarg_string)
|
||||||
|
{
|
||||||
|
// if next subarg is a string: check its first char
|
||||||
|
string_subarg* ss = dynamic_cast<string_subarg*>(t->sa[i+1]);
|
||||||
|
char c = ss->val[0];
|
||||||
|
// if its first would extend the var name: skip
|
||||||
|
if(is_alphanum(c) || c == '_')
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// if has no actual manipulation operation: set it to not manip
|
||||||
|
if(ss->var->manip == nullptr || ss->var->manip->sa.size() == 0)
|
||||||
|
ss->var->is_manip = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}; break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void minify_generic(_obj* in)
|
||||||
|
{
|
||||||
|
recurse(r_minify_empty_manip, in);
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue