restructure struc functions

This commit is contained in:
zawwz 2021-01-08 15:03:25 +01:00
parent 6f35028e84
commit 142a91e68a
7 changed files with 134 additions and 77 deletions

View file

@ -21,11 +21,15 @@ extern std::regex re_var_exclude;
extern std::regex re_fct_exclude;
extern const std::regex regex_null;
// globals
extern const std::vector<std::string> argvar_cmds;
// 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) **/

View file

@ -115,6 +115,12 @@ public:
void set(std::string const& str);
void insert(uint32_t i, subarg* val);
void insert(uint32_t i, arg const& a);
inline void add(subarg* in) { sa.push_back(in); }
inline size_t size() { return sa.size(); }
std::vector<subarg*> sa;
// return if is a string and only one subarg
@ -134,14 +140,15 @@ public:
arglist(arg* in) { type=_obj::_arglist; this->add(in); }
~arglist() { for( auto it: args ) delete it; }
inline void add(arg* in) { args.push_back(in); }
inline void push_back(arg* in) { args.push_back(in); }
std::vector<arg*> args;
std::vector<std::string> strargs(uint32_t start);
inline uint64_t size() { return args.size(); }
inline arg* operator[](uint32_t i) { return args[i]; }
void insert(uint32_t i, arg* val);
void insert(uint32_t i, arglist const& lst);
inline size_t size() { return args.size(); }
std::string generate(int ind);
};
@ -205,6 +212,7 @@ public:
bool parallel; // & at the end
void add(pipeline* pl, bool or_op=false);
// don't push_back here, use add() instead
std::vector<pipeline*> pls;
std::vector<bool> or_ops; // size of 1 less than pls, defines separator between pipelines
@ -227,7 +235,7 @@ public:
~list() { for(auto it: cls) delete it; }
std::vector<condlist*> cls;
void add(condlist* in) { cls.push_back(in); }
inline void add(condlist* in) { cls.push_back(in); }
condlist* last_cond() { return cls[cls.size()-1]; }
@ -235,7 +243,6 @@ public:
void insert(uint32_t i, list const& lst);
size_t size() { return cls.size(); }
condlist* operator[](uint32_t i) { return cls[i]; }
std::string generate(int ind, bool first_indent);
std::string generate(int ind) { return this->generate(ind, true); }

View file

@ -5,17 +5,39 @@
#include "parse.hpp"
#include "struc_helper.hpp"
bool debashify_replace_bashtest(cmd* in)
bool debashify_bashtest(cmd* in)
{
if(in->firstarg_string() == "[[")
throw std::runtime_error("Debashify on '[[ ]]' not implemented yet");
throw std::runtime_error("Cannot debashify '[[ ]]'");
return false;
}
bool debashify_declare(cmd* in)
{
if(in->firstarg_string() == "declare")
throw std::runtime_error("Cannot debashify 'declare'");
return false;
}
bool debashify_array_def(cmd* in)
{
for(auto it: in->var_assigns)
{
if(it.second->size()>0 && it.second->sa[0]->type == _obj::subarg_string && it.second->sa[0]->generate(0) == "(")
throw std::runtime_error("Cannot debashify VAR=() variable arrays");
}
return false;
}
bool debashify_herestring(pipeline* pl)
{
return false;
}
// replace &>, &>> and >&:
// add 2>&1 as redirect
bool debashify_replace_combined_redirects(block* in)
bool debashify_combined_redirects(block* in)
{
bool has_replaced=false;
@ -46,7 +68,7 @@ bool debashify_replace_combined_redirects(block* in)
// replace <<< and
// <<< : TODO
bool debashify_replace_extended_redirects(pipeline* in)
bool debashify_extended_redirects(pipeline* in)
{
return false;
}
@ -70,7 +92,7 @@ TO:
CMD "$fifoN"
wait "$jobN"
*/
bool debashify_replace_procsub(list* lst)
bool debashify_procsub(list* lst)
{
bool has_replaced=false;
for(uint32_t li=0; li<lst->cls.size(); li++)
@ -88,7 +110,7 @@ bool debashify_replace_procsub(list* lst)
{
for(auto ait: t->args->args)
{
if(ait->sa.size() == 1 && ait->sa[0]->type == _obj::subarg_procsub)
if(ait->size() == 1 && ait->sa[0]->type == _obj::subarg_procsub)
{
procsub_subarg* st = dynamic_cast<procsub_subarg*>(ait->sa[0]);
affected_args.push_back( std::make_pair(ait, st->is_output) );
@ -135,8 +157,8 @@ bool debashify_replace_procsub(list* lst)
// replace the arg
delete affected_args[i].first->sa[0];
affected_args[i].first->sa[0] = new string_subarg("\"");
affected_args[i].first->sa.push_back( new variable_subarg(strf("__lxshfifo%u", i)) );
affected_args[i].first->sa.push_back( new string_subarg("\"") );
affected_args[i].first->add( new variable_subarg(strf("__lxshfifo%u", i)) );
affected_args[i].first->add( new string_subarg("\"") );
}
lst->insert(li, *lst_insert );
li+= lst_insert->size();
@ -162,45 +184,47 @@ bool r_debashify(_obj* o, bool* need_random_func)
{
case _obj::_list: {
list* t = dynamic_cast<list*>(o);
if(debashify_replace_procsub(t))
if(debashify_procsub(t))
*need_random_func = true;
} break;
case _obj::block_subshell: {
subshell* t = dynamic_cast<subshell*>(o);
debashify_replace_combined_redirects(t);
} break;
case _obj::block_brace: {
brace* t = dynamic_cast<brace*>(o);
debashify_replace_combined_redirects(t);
} break;
case _obj::block_main: {
shmain* t = dynamic_cast<shmain*>(o);
debashify_replace_combined_redirects(t);
} break;
case _obj::block_cmd: {
cmd* t = dynamic_cast<cmd*>(o);
debashify_replace_combined_redirects(t);
debashify_replace_bashtest(t);
debashify_combined_redirects(t);
debashify_bashtest(t);
debashify_declare(t);
debashify_array_def(t);
} break;
case _obj::block_subshell: {
subshell* t = dynamic_cast<subshell*>(o);
debashify_combined_redirects(t);
} break;
case _obj::block_brace: {
brace* t = dynamic_cast<brace*>(o);
debashify_combined_redirects(t);
} break;
case _obj::block_main: {
shmain* t = dynamic_cast<shmain*>(o);
debashify_combined_redirects(t);
} break;
case _obj::block_function: {
function* t = dynamic_cast<function*>(o);
debashify_replace_combined_redirects(t);
debashify_combined_redirects(t);
} break;
case _obj::block_case: {
case_block* t = dynamic_cast<case_block*>(o);
debashify_replace_combined_redirects(t);
debashify_combined_redirects(t);
} break;
case _obj::block_if: {
if_block* t = dynamic_cast<if_block*>(o);
debashify_replace_combined_redirects(t);
debashify_combined_redirects(t);
} break;
case _obj::block_while: {
while_block* t = dynamic_cast<while_block*>(o);
debashify_replace_combined_redirects(t);
debashify_combined_redirects(t);
} break;
case _obj::block_for: {
for_block* t = dynamic_cast<for_block*>(o);
debashify_replace_combined_redirects(t);
debashify_combined_redirects(t);
} break;
default: break;
}

View file

@ -249,10 +249,10 @@ std::pair<arg*, uint32_t> parse_arg(const char* in, uint32_t size, uint32_t star
// add previous subarg
std::string tmpstr=std::string(in+j, i-j);
if(tmpstr!="")
ret->sa.push_back(new string_subarg(tmpstr));
ret->add(new string_subarg(tmpstr));
// get arithmetic
auto r=parse_arithmetic(in, size, i+3);
ret->sa.push_back(r.first);
ret->add(r.first);
j = i = r.second;
}
else if( word_eq("$(", in, size, i) ) // substitution
@ -260,10 +260,10 @@ std::pair<arg*, uint32_t> parse_arg(const char* in, uint32_t size, uint32_t star
// add previous subarg
std::string tmpstr=std::string(in+j, i-j);
if(tmpstr!="")
ret->sa.push_back(new string_subarg(tmpstr));
ret->add(new string_subarg(tmpstr));
// get subshell
auto r=parse_subshell(in, size, i+2);
ret->sa.push_back(new subshell_subarg(r.first, true));
ret->add(new subshell_subarg(r.first, true));
j = i = r.second;
}
else if( word_eq("${", in, size, i) ) // variable manipulation
@ -271,10 +271,10 @@ std::pair<arg*, uint32_t> parse_arg(const char* in, uint32_t size, uint32_t star
// add previous subarg
std::string tmpstr=std::string(in+j, i-j);
if(tmpstr!="")
ret->sa.push_back(new string_subarg(tmpstr));
ret->add(new string_subarg(tmpstr));
// get manipulation
auto r=parse_manipulation(in, size, i+2);
ret->sa.push_back(r.first);
ret->add(r.first);
j = i = r.second;
}
else if( in[i] == '$' )
@ -285,9 +285,9 @@ std::pair<arg*, uint32_t> parse_arg(const char* in, uint32_t size, uint32_t star
// add previous subarg
std::string tmpstr=std::string(in+j, i-j);
if(tmpstr!="")
ret->sa.push_back(new string_subarg(tmpstr));
ret->add(new string_subarg(tmpstr));
// add varname
ret->sa.push_back(new variable_subarg(r.first));
ret->add(new variable_subarg(r.first));
j = i = r.second;
}
else
@ -316,10 +316,10 @@ std::pair<arg*, uint32_t> parse_arg(const char* in, uint32_t size, uint32_t star
// add previous subarg
std::string tmpstr=std::string(in+j, i-j);
if(tmpstr!="")
ret->sa.push_back(new string_subarg(tmpstr));
ret->add(new string_subarg(tmpstr));
// get arithmetic
auto r=parse_arithmetic(in, size, i+3);
ret->sa.push_back(r.first);
ret->add(r.first);
j = i = r.second;
}
else if( word_eq("$(", in, size, i) ) // substitution
@ -327,10 +327,10 @@ std::pair<arg*, uint32_t> parse_arg(const char* in, uint32_t size, uint32_t star
// add previous subarg
std::string tmpstr=std::string(in+j, i-j);
if(tmpstr!="")
ret->sa.push_back(new string_subarg(tmpstr));
ret->add(new string_subarg(tmpstr));
// get subshell
auto r=parse_subshell(in, size, i+2);
ret->sa.push_back(new subshell_subarg(r.first, false));
ret->add(new subshell_subarg(r.first, false));
j = i = r.second;
}
else if( word_eq("${", in, size, i) ) // variable manipulation
@ -338,10 +338,10 @@ std::pair<arg*, uint32_t> parse_arg(const char* in, uint32_t size, uint32_t star
// add previous subarg
std::string tmpstr=std::string(in+j, i-j);
if(tmpstr!="")
ret->sa.push_back(new string_subarg(tmpstr));
ret->add(new string_subarg(tmpstr));
// get manipulation
auto r=parse_manipulation(in, size, i+2);
ret->sa.push_back(r.first);
ret->add(r.first);
j = i = r.second;
}
else if( in[i] == '$' )
@ -352,9 +352,9 @@ std::pair<arg*, uint32_t> parse_arg(const char* in, uint32_t size, uint32_t star
// add previous subarg
std::string tmpstr=std::string(in+j, i-j);
if(tmpstr!="")
ret->sa.push_back(new string_subarg(tmpstr));
ret->add(new string_subarg(tmpstr));
// add varname
ret->sa.push_back(new variable_subarg(r.first));
ret->add(new variable_subarg(r.first));
j = i = r.second;
}
else
@ -367,7 +367,7 @@ std::pair<arg*, uint32_t> parse_arg(const char* in, uint32_t size, uint32_t star
// add string subarg
std::string val=std::string(in+j, i-j);
if(val != "")
ret->sa.push_back(new string_subarg(val));
ret->add(new string_subarg(val));
#ifndef NO_PARSE_CATCH
}
@ -498,15 +498,11 @@ std::pair<redirect*, uint32_t> parse_redirect(const char* in, uint32_t size, uin
else
{
i = size;
// maybe at end of file with no \n
// if(strstr(in+size-delimitor.size(), std::string("\n"+delimitor).c_str())!=NULL)
// i = size-delimitor.size();
// else // not found: end of file
}
std::string tmpparse=std::string(in+j, i-j);
auto pval = parse_arg(tmpparse.c_str(), tmpparse.size(), 0, NULL);
ret->target = pval.first;
ret->target->sa.insert(ret->target->sa.begin(), new string_subarg(delimitor+"\n"));
ret->target->insert(0, new string_subarg(delimitor+"\n"));
}
else
{
@ -559,7 +555,7 @@ std::pair<arglist*, uint32_t> parse_arglist(const char* in, uint32_t size, uint3
if(ret == nullptr)
ret = new arglist;
auto ps = parse_subshell(in, size, i);
ret->args.push_back(new arg(new procsub_subarg(is_output, ps.first)));
ret->add(new arg(new procsub_subarg(is_output, ps.first)));
i=ps.second;
}
else if(redirs!=nullptr)
@ -579,7 +575,7 @@ std::pair<arglist*, uint32_t> parse_arglist(const char* in, uint32_t size, uint3
if(ret == nullptr)
ret = new arglist;
auto pp=parse_arg(in, size, i);
ret->args.push_back(pp.first);
ret->add(pp.first);
i = pp.second;
}
i = skip_chars(in, size, i, SPACES);
@ -712,7 +708,7 @@ std::pair<list*, uint32_t> parse_list_until(const char* in, uint32_t size, uint3
while(in[i] != end_c)
{
auto pp=parse_condlist(in, size, i);
ret->cls.push_back(pp.first);
ret->add(pp.first);
i=pp.second;
if(i < size)
@ -775,7 +771,7 @@ std::pair<list*, uint32_t> parse_list_until(const char* in, uint32_t size, uint3
}
// do a parse
auto pp=parse_condlist(in, size, i);
ret->cls.push_back(pp.first);
ret->add(pp.first);
i=pp.second;
if(i<size)
{
@ -846,7 +842,7 @@ std::tuple<list*, uint32_t, std::string> parse_list_until(const char* in, uint32
break;
// do a parse
auto pp=parse_condlist(in, size, i);
ret->cls.push_back(pp.first);
ret->add(pp.first);
i=pp.second;
if(in[i] == '#')
; // skip here
@ -1065,7 +1061,7 @@ std::pair<case_block*, uint32_t> parse_case(const char* in, uint32_t size, uint3
{
pa = parse_arg(in, size, i);
cc->first.push_back(pa.first);
if(pa.first->sa.size() <= 0)
if(pa.first->size() <= 0)
throw PARSE_ERROR("Empty case value", i);
i=skip_unread(in, size, pa.second);
if(i>=size)

View file

@ -13,6 +13,10 @@ std::regex re_fct_exclude;
const std::regex regex_null;
// globals
const std::vector<std::string> argvar_cmds = { "export", "unset", "local", "read", "readonly", "declare" };
// Object maps
countmap_t m_vars, m_vardefs, m_varcalls;
@ -21,6 +25,7 @@ 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()
@ -153,7 +158,10 @@ std::string get_varname(arg* in)
bool cmd_is_argvar(std::string const& in)
{
return in == "export" || in == "unset" || in == "local" || in == "read";
for(auto it: argvar_cmds)
if(in == it)
return true;
return false;
}
bool cmd::is_argvar()

View file

@ -229,7 +229,7 @@ std::pair< std::vector<arg*> , bool > resolve_arg(arg* in, shmain* parent, bool
arg* ta=nullptr;
bool has_resolved=false;
uint32_t j=0;
for(uint32_t i=0 ; i<in->sa.size() ; i++)
for(uint32_t i=0 ; i<in->size() ; i++)
{
if(in->sa[i]->type != _obj::subarg_subshell) // skip if not subshell
continue;
@ -289,14 +289,14 @@ std::pair< std::vector<arg*> , bool > resolve_arg(arg* in, shmain* parent, bool
if(ta == nullptr)
ta = new arg;
ta->sa.insert(ta->sa.end(), in->sa.begin()+j, in->sa.begin()+i);
ta->sa.push_back(new string_subarg(strargs[i]));
ta->add(new string_subarg(strargs[i]));
j=i+1;
delete in->sa[i];
for(uint32_t li=1 ; li<strargs.size() ; li++)
{
ret.push_back(ta);
ta = new arg;
ta->sa.push_back(new string_subarg(strargs[li]));
ta->add(new string_subarg(strargs[li]));
}
} // end pack
@ -353,7 +353,7 @@ bool r_resolve(_obj* o, shmain* parent)
case _obj::_arglist :
{
auto t = dynamic_cast<arglist*>(o);
for(uint32_t i=0 ; i<t->args.size() ; i++)
for(uint32_t i=0 ; i<t->size() ; i++)
{
auto r=resolve_arg(t->args[i], parent);
if(r.first.size()>0)

View file

@ -94,21 +94,21 @@ cmd* condlist::first_cmd()
cmd* brace::single_cmd()
{
if( lst->size() == 1 && // only one condlist
(*lst)[0]->pls.size() == 1 && // only one pipeline
(*lst)[0]->pls[0]->cmds.size() == 1 && // only one block
(*lst)[0]->pls[0]->cmds[0]->type == _obj::block_cmd) // block is a command
return dynamic_cast<cmd*>((*lst)[0]->pls[0]->cmds[0]); // return command
if( lst->cls.size() == 1 && // only one condlist
lst->cls[0]->pls.size() == 1 && // only one pipeline
lst->cls[0]->pls[0]->cmds.size() == 1 && // only one block
lst->cls[0]->pls[0]->cmds[0]->type == _obj::block_cmd) // block is a command
return dynamic_cast<cmd*>(lst->cls[0]->pls[0]->cmds[0]); // return command
return nullptr;
}
cmd* subshell::single_cmd()
{
if( lst->size() == 1 && // only one condlist
(*lst)[0]->pls.size() == 1 && // only one pipeline
(*lst)[0]->pls[0]->cmds.size() == 1 && // only one block
(*lst)[0]->pls[0]->cmds[0]->type == _obj::block_cmd) // block is a command
return dynamic_cast<cmd*>((*lst)[0]->pls[0]->cmds[0]); // return command
if( lst->cls.size() == 1 && // only one condlist
lst->cls[0]->pls.size() == 1 && // only one pipeline
lst->cls[0]->pls[0]->cmds.size() == 1 && // only one block
lst->cls[0]->pls[0]->cmds[0]->type == _obj::block_cmd) // block is a command
return dynamic_cast<cmd*>(lst->cls[0]->pls[0]->cmds[0]); // return command
return nullptr;
}
@ -144,12 +144,30 @@ void condlist::prune_first_cmd()
// add/extend
void arg::insert(uint32_t i, subarg* val)
{
sa.insert(sa.begin()+i, val);
}
void arg::insert(uint32_t i, arg const& a)
{
sa.insert(sa.begin()+i, a.sa.begin(), a.sa.end());
}
void arglist::insert(uint32_t i, arg* val)
{
args.insert(args.begin()+i, val);
}
void arglist::insert(uint32_t i, arglist const& lst)
{
args.insert(args.begin()+i, lst.args.begin(), lst.args.end());
}
void cmd::add(arg* in)
{
if(args==nullptr)
args = new arglist;
args->push_back(in);
args->add(in);
}
void condlist::add(pipeline* pl, bool or_op)