implement separated variables on assigns and cmdvars
This commit is contained in:
parent
38845e8652
commit
e7d868de9e
9 changed files with 93 additions and 44 deletions
|
|
@ -44,7 +44,9 @@ void fctmap_get(_obj* in, std::regex const& exclude);
|
|||
void cmdmap_get(_obj* in, std::regex const& exclude);
|
||||
|
||||
/** util functions **/
|
||||
#ifdef DEBUG_MODE
|
||||
std::string gen_json_struc(_obj* in);
|
||||
#endif
|
||||
|
||||
// gen regexes
|
||||
std::regex var_exclude_regex(std::string const& in, bool include_reserved);
|
||||
|
|
|
|||
|
|
@ -126,6 +126,11 @@ void recurse(bool (&fct)(_obj*, Args...), _obj* o, Args... args)
|
|||
recurse(fct, it.first, args...);
|
||||
recurse(fct, it.second, args...);
|
||||
}
|
||||
for(auto it: t->cmd_var_assigns)
|
||||
{
|
||||
recurse(fct, it.first, args...);
|
||||
recurse(fct, it.second, args...);
|
||||
}
|
||||
|
||||
for(auto it: t->redirs)
|
||||
recurse(fct, it, args...);
|
||||
|
|
|
|||
|
|
@ -371,6 +371,10 @@ public:
|
|||
delete it.first;
|
||||
delete it.second;
|
||||
}
|
||||
for(auto it: cmd_var_assigns) {
|
||||
delete it.first;
|
||||
delete it.second;
|
||||
}
|
||||
}
|
||||
|
||||
static const std::string empty_string;
|
||||
|
|
@ -387,6 +391,8 @@ public:
|
|||
|
||||
// is a cmdvar type
|
||||
bool is_cmdvar;
|
||||
// var assigns on cmdvar
|
||||
std::vector<std::pair<variable*,arg*>> cmd_var_assigns;
|
||||
|
||||
// check if cmd is this (ex: unset)
|
||||
bool is(std::string const& in);
|
||||
|
|
|
|||
|
|
@ -135,9 +135,9 @@ void warn(std::string const& in)
|
|||
|
||||
std::string get_declare_opt(cmd* in)
|
||||
{
|
||||
if(in->var_assigns[0].second!=nullptr)
|
||||
if(in->cmd_var_assigns[0].second!=nullptr)
|
||||
{
|
||||
return in->var_assigns[0].second->string();
|
||||
return in->cmd_var_assigns[0].second->string();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
|
@ -307,19 +307,19 @@ bool debashify_readonly(list* in)
|
|||
{
|
||||
has_found=true;
|
||||
c1->is_cmdvar=false;
|
||||
for(uint32_t i=0; i<c1->var_assigns.size(); i++)
|
||||
for(uint32_t i=0; i<c1->cmd_var_assigns.size(); i++)
|
||||
{
|
||||
if(c1->var_assigns[i].first == nullptr || c1->var_assigns[i].second == nullptr)
|
||||
if(c1->cmd_var_assigns[i].first == nullptr || c1->cmd_var_assigns[i].second == nullptr)
|
||||
{
|
||||
if(c1->var_assigns[i].first != nullptr)
|
||||
delete c1->var_assigns[i].first;
|
||||
if(c1->var_assigns[i].second != nullptr)
|
||||
delete c1->var_assigns[i].second;
|
||||
c1->var_assigns.erase(c1->var_assigns.begin()+i);
|
||||
if(c1->cmd_var_assigns[i].first != nullptr)
|
||||
delete c1->cmd_var_assigns[i].first;
|
||||
if(c1->cmd_var_assigns[i].second != nullptr)
|
||||
delete c1->cmd_var_assigns[i].second;
|
||||
c1->cmd_var_assigns.erase(c1->cmd_var_assigns.begin()+i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
if(c1->var_assigns.size() == 0)
|
||||
if(c1->cmd_var_assigns.size() == 0)
|
||||
{
|
||||
delete in->cls[i];
|
||||
in->cls.erase(in->cls.begin()+i);
|
||||
|
|
@ -329,6 +329,8 @@ bool debashify_readonly(list* in)
|
|||
{
|
||||
delete c1->args;
|
||||
c1->args = new arglist;
|
||||
c1->var_assigns=c1->cmd_var_assigns;
|
||||
c1->cmd_var_assigns.resize(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -351,7 +353,7 @@ bool debashify_declare(list* in, debashify_params* params)
|
|||
std::string const& op = get_declare_opt(c1);
|
||||
if(op == "-a")
|
||||
{
|
||||
for(auto it: c1->var_assigns)
|
||||
for(auto it: c1->cmd_var_assigns)
|
||||
{
|
||||
if(it.first != nullptr)
|
||||
params->arrays[it.first->varname] = false;
|
||||
|
|
@ -359,7 +361,7 @@ bool debashify_declare(list* in, debashify_params* params)
|
|||
}
|
||||
else if(op == "-A")
|
||||
{
|
||||
for(auto it: c1->var_assigns)
|
||||
for(auto it: c1->cmd_var_assigns)
|
||||
{
|
||||
if(it.first != nullptr)
|
||||
params->arrays[it.first->varname] = true;
|
||||
|
|
|
|||
|
|
@ -333,22 +333,6 @@ std::string cmd::generate(int ind, generate_context* ctx)
|
|||
{
|
||||
std::string ret;
|
||||
|
||||
// is a varassign cmd
|
||||
if(is_cmdvar)
|
||||
{
|
||||
ret += args->generate(ind) + ' ';
|
||||
for(auto it: var_assigns)
|
||||
{
|
||||
if(it.first != nullptr)
|
||||
ret += it.first->generate(ind);
|
||||
if(it.second != nullptr)
|
||||
ret += it.second->generate(ind);
|
||||
ret += ' ';
|
||||
}
|
||||
ret.pop_back();
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool has_args=false;
|
||||
|
||||
// pre-cmd var assigns
|
||||
|
|
@ -362,6 +346,22 @@ std::string cmd::generate(int ind, generate_context* ctx)
|
|||
ret += ' ';
|
||||
}
|
||||
|
||||
// is a varassign cmd
|
||||
if(is_cmdvar)
|
||||
{
|
||||
ret += args->generate(ind) + ' ';
|
||||
for(auto it: cmd_var_assigns)
|
||||
{
|
||||
if(it.first != nullptr)
|
||||
ret += it.first->generate(ind);
|
||||
if(it.second != nullptr)
|
||||
ret += it.second->generate(ind);
|
||||
ret += ' ';
|
||||
}
|
||||
ret.pop_back();
|
||||
return ret;
|
||||
}
|
||||
|
||||
// cmd itself
|
||||
if(args!=nullptr && args->size()>0)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ ztd::option_set options( {
|
|||
ztd::option("remove-unused", false, "Remove unused functions and variables"),
|
||||
ztd::option("list-cmd", false, "List all commands invoked in the script"),
|
||||
ztd::option("\r [Variable processing]"),
|
||||
ztd::option("exclude-var", true, "List of matching regex to ignore for variable processing, separated by comma", "list"),
|
||||
ztd::option("exclude-var", true, "List of matching regex to ignore for variable processing, separated by spaces", "list"),
|
||||
ztd::option("no-exclude-reserved",false, "Don't exclude reserved variables"),
|
||||
ztd::option("minify-var", false, "Minify variable names"),
|
||||
ztd::option("list-var", false, "List all variables set and invoked in the script"),
|
||||
|
|
@ -45,7 +45,7 @@ ztd::option_set options( {
|
|||
ztd::option("list-var-call", false, "List all variables invoked in the script"),
|
||||
ztd::option("unset-var", false, "Add 'unset' to all variables at the start of the script to avoid environment interference"),
|
||||
ztd::option("\r [Function processing]"),
|
||||
ztd::option("exclude-fct", true, "List of matching regex to ignore for function processing, separated by comma", "list"),
|
||||
ztd::option("exclude-fct", true, "List of matching regex to ignore for function processing, separated by spaces", "list"),
|
||||
ztd::option("minify-fct", false, "Minify function names"),
|
||||
ztd::option("list-fct", false, "List all functions defined in the script")
|
||||
} );
|
||||
|
|
|
|||
|
|
@ -1174,7 +1174,7 @@ std::pair<function*, parse_context> parse_function(parse_context ctx, const char
|
|||
}
|
||||
|
||||
// parse only var assigns
|
||||
parse_context parse_cmd_varassigns(cmd* ret, parse_context ctx, bool cmdassign=false, std::string const& cmd="")
|
||||
parse_context parse_cmd_varassigns(cmd* in, parse_context ctx, bool cmdassign=false, std::string const& cmd="")
|
||||
{
|
||||
bool forbid_assign=false;
|
||||
bool forbid_special=false;
|
||||
|
|
@ -1183,6 +1183,10 @@ parse_context parse_cmd_varassigns(cmd* ret, parse_context ctx, bool cmdassign=f
|
|||
if(cmdassign && (forbid_special || cmd == "export") )
|
||||
forbid_special=true;
|
||||
|
||||
std::vector<std::pair<variable*,arg*>>* ret=&in->var_assigns;
|
||||
if(cmdassign)
|
||||
ret=&in->cmd_var_assigns;
|
||||
|
||||
while(ctx.i<ctx.size && !is_in(ctx[ctx.i], ARGLIST_END))
|
||||
{
|
||||
auto vp=parse_var(ctx, false, true);
|
||||
|
|
@ -1245,7 +1249,7 @@ parse_context parse_cmd_varassigns(cmd* ret, parse_context ctx, bool cmdassign=f
|
|||
ctx=pp.second;
|
||||
}
|
||||
ta->insert(0, strop);
|
||||
ret->var_assigns.push_back(std::make_pair(vp.first, ta));
|
||||
ret->push_back(std::make_pair(vp.first, ta));
|
||||
ctx.i=skip_chars(ctx, SPACES);
|
||||
}
|
||||
else
|
||||
|
|
@ -1254,14 +1258,14 @@ parse_context parse_cmd_varassigns(cmd* ret, parse_context ctx, bool cmdassign=f
|
|||
{
|
||||
if(vp.first != nullptr && is_in(newct[newct.i], ARG_END) )
|
||||
{
|
||||
ret->var_assigns.push_back(std::make_pair(vp.first, nullptr));
|
||||
ret->push_back(std::make_pair(vp.first, nullptr));
|
||||
ctx=newct;
|
||||
}
|
||||
else
|
||||
{
|
||||
delete vp.first;
|
||||
auto pp=parse_arg(ctx);
|
||||
ret->var_assigns.push_back(std::make_pair(nullptr, pp.first));
|
||||
ret->push_back(std::make_pair(nullptr, pp.first));
|
||||
ctx=pp.second;
|
||||
}
|
||||
ctx.i=skip_chars(ctx, SPACES);
|
||||
|
|
@ -1281,7 +1285,6 @@ parse_context parse_cmd_varassigns(cmd* ret, parse_context ctx, bool cmdassign=f
|
|||
std::pair<cmd*, parse_context> parse_cmd(parse_context ctx)
|
||||
{
|
||||
cmd* ret = new cmd;
|
||||
uint32_t start=ctx.i;
|
||||
|
||||
ctx = parse_cmd_varassigns(ret, ctx);
|
||||
|
||||
|
|
@ -1292,10 +1295,6 @@ std::pair<cmd*, parse_context> parse_cmd(parse_context ctx)
|
|||
{
|
||||
parse_error("bash specific: "+wp.first, ctx);
|
||||
}
|
||||
if(ret->var_assigns.size()>0)
|
||||
{
|
||||
parse_error("Unallowed preceding variables on "+wp.first, ctx, start);
|
||||
}
|
||||
|
||||
ret->args = new arglist;
|
||||
ret->args->add(new arg(wp.first));
|
||||
|
|
@ -1305,14 +1304,13 @@ std::pair<cmd*, parse_context> parse_cmd(parse_context ctx)
|
|||
|
||||
ctx = parse_cmd_varassigns(ret, ctx, true, wp.first);
|
||||
}
|
||||
|
||||
if(!is_in(ctx[ctx.i], ARGLIST_END))
|
||||
else if(!is_in(ctx[ctx.i], ARGLIST_END))
|
||||
{
|
||||
auto pp=parse_arglist(ctx, true, &ret->redirs);
|
||||
ret->args = pp.first;
|
||||
ctx = pp.second;
|
||||
}
|
||||
else if(ret->var_assigns.size() <= 0)
|
||||
else if( ret->var_assigns.size() <= 0 )
|
||||
{
|
||||
parse_error( unexpected_token(ctx[ctx.i]), ctx );
|
||||
ctx.i++;
|
||||
|
|
|
|||
|
|
@ -250,7 +250,7 @@ void add_unset_variables(shmain* sh, std::regex const& exclude)
|
|||
unset_cmd->is_cmdvar=true;
|
||||
for(auto it: m_vars)
|
||||
{
|
||||
unset_cmd->var_assigns.push_back(std::make_pair(new variable(it.first), nullptr));
|
||||
unset_cmd->cmd_var_assigns.push_back(std::make_pair(new variable(it.first), nullptr));
|
||||
}
|
||||
condlist* cl = new condlist(unset_cmd);
|
||||
sh->lst->cls.insert(sh->lst->cls.begin(), cl);
|
||||
|
|
@ -296,6 +296,11 @@ bool r_get_unsets(_obj* in, set_t* unsets)
|
|||
if(it.first != nullptr)
|
||||
unsets->insert(it.first->varname);
|
||||
}
|
||||
for(auto it: t->cmd_var_assigns)
|
||||
{
|
||||
if(it.first != nullptr)
|
||||
unsets->insert(it.first->varname);
|
||||
}
|
||||
}
|
||||
}; break;
|
||||
default: break;
|
||||
|
|
@ -391,6 +396,22 @@ bool r_delete_var(_obj* in, set_t* vars)
|
|||
if(has_deleted && c->var_assigns.size()<=0 && (c->arglist_size()<=0 || c->is_cmdvar) )
|
||||
to_delete=true;
|
||||
|
||||
for(uint32_t j=0; j<c->cmd_var_assigns.size(); j++)
|
||||
{
|
||||
if( c->cmd_var_assigns[j].first != nullptr && vars->find(c->cmd_var_assigns[j].first->varname) != vars->end() )
|
||||
{
|
||||
if(c->cmd_var_assigns[j].first != nullptr)
|
||||
delete c->cmd_var_assigns[j].first;
|
||||
if(c->cmd_var_assigns[j].second != nullptr)
|
||||
delete c->cmd_var_assigns[j].second;
|
||||
c->cmd_var_assigns.erase(c->cmd_var_assigns.begin()+j);
|
||||
has_deleted=true;
|
||||
j--;
|
||||
}
|
||||
}
|
||||
if(has_deleted && c->cmd_var_assigns.size()<=0 && (c->arglist_size()<=0 || c->is_cmdvar) )
|
||||
to_delete=true;
|
||||
|
||||
}
|
||||
if(to_delete)
|
||||
{
|
||||
|
|
@ -482,6 +503,8 @@ void string_processors(_obj* in)
|
|||
|
||||
/** JSON **/
|
||||
|
||||
#ifdef DEBUG_MODE
|
||||
|
||||
std::string quote_string(std::string const& in)
|
||||
{
|
||||
return '"' + stringReplace(in, "\"", "\\\"") + '"';
|
||||
|
|
@ -519,7 +542,6 @@ std::string boolstring(bool in)
|
|||
return "false";
|
||||
}
|
||||
|
||||
#ifdef DEBUG_MODE
|
||||
std::string gen_json_struc(_obj* o)
|
||||
{
|
||||
if(o==nullptr)
|
||||
|
|
@ -681,6 +703,15 @@ std::string gen_json_struc(_obj* o)
|
|||
aa.push_back(gen_json(ttvec));
|
||||
}
|
||||
vec.push_back(std::make_pair( quote_string("var_assigns"), gen_json(aa)));
|
||||
std::vector<std::string> bb;
|
||||
for(auto it: t->cmd_var_assigns)
|
||||
{
|
||||
std::vector<std::pair<std::string,std::string>> ttvec;
|
||||
ttvec.push_back( std::make_pair(quote_string("var"), gen_json_struc(it.first)) );
|
||||
ttvec.push_back( std::make_pair(quote_string("value"), gen_json_struc(it.second)) );
|
||||
bb.push_back(gen_json(ttvec));
|
||||
}
|
||||
vec.push_back(std::make_pair( quote_string("cmd_var_assigns"), gen_json(bb)));
|
||||
|
||||
std::vector<std::string> tvec;
|
||||
for(auto it: t->redirs)
|
||||
|
|
|
|||
|
|
@ -403,6 +403,11 @@ bool r_resolve(_obj* o, parse_context* ct)
|
|||
resolve_arg(it.second, *ct, true); // force quoted
|
||||
resolve(it.second, ct);
|
||||
}
|
||||
for(auto it: t->cmd_var_assigns) // var assigns
|
||||
{
|
||||
resolve_arg(it.second, *ct, true); // force quoted
|
||||
resolve(it.second, ct);
|
||||
}
|
||||
for(auto it: t->redirs)
|
||||
resolve(it, ct);
|
||||
resolve(t->args, ct);
|
||||
|
|
|
|||
Loading…
Reference in a new issue