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);
|
void cmdmap_get(_obj* in, std::regex const& exclude);
|
||||||
|
|
||||||
/** util functions **/
|
/** util functions **/
|
||||||
|
#ifdef DEBUG_MODE
|
||||||
std::string gen_json_struc(_obj* in);
|
std::string gen_json_struc(_obj* in);
|
||||||
|
#endif
|
||||||
|
|
||||||
// gen regexes
|
// gen regexes
|
||||||
std::regex var_exclude_regex(std::string const& in, bool include_reserved);
|
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.first, args...);
|
||||||
recurse(fct, it.second, 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)
|
for(auto it: t->redirs)
|
||||||
recurse(fct, it, args...);
|
recurse(fct, it, args...);
|
||||||
|
|
|
||||||
|
|
@ -371,6 +371,10 @@ public:
|
||||||
delete it.first;
|
delete it.first;
|
||||||
delete it.second;
|
delete it.second;
|
||||||
}
|
}
|
||||||
|
for(auto it: cmd_var_assigns) {
|
||||||
|
delete it.first;
|
||||||
|
delete it.second;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const std::string empty_string;
|
static const std::string empty_string;
|
||||||
|
|
@ -387,6 +391,8 @@ public:
|
||||||
|
|
||||||
// is a cmdvar type
|
// is a cmdvar type
|
||||||
bool is_cmdvar;
|
bool is_cmdvar;
|
||||||
|
// var assigns on cmdvar
|
||||||
|
std::vector<std::pair<variable*,arg*>> cmd_var_assigns;
|
||||||
|
|
||||||
// check if cmd is this (ex: unset)
|
// check if cmd is this (ex: unset)
|
||||||
bool is(std::string const& in);
|
bool is(std::string const& in);
|
||||||
|
|
|
||||||
|
|
@ -135,9 +135,9 @@ void warn(std::string const& in)
|
||||||
|
|
||||||
std::string get_declare_opt(cmd* 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 "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
@ -307,19 +307,19 @@ bool debashify_readonly(list* in)
|
||||||
{
|
{
|
||||||
has_found=true;
|
has_found=true;
|
||||||
c1->is_cmdvar=false;
|
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)
|
if(c1->cmd_var_assigns[i].first != nullptr)
|
||||||
delete c1->var_assigns[i].first;
|
delete c1->cmd_var_assigns[i].first;
|
||||||
if(c1->var_assigns[i].second != nullptr)
|
if(c1->cmd_var_assigns[i].second != nullptr)
|
||||||
delete c1->var_assigns[i].second;
|
delete c1->cmd_var_assigns[i].second;
|
||||||
c1->var_assigns.erase(c1->var_assigns.begin()+i);
|
c1->cmd_var_assigns.erase(c1->cmd_var_assigns.begin()+i);
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(c1->var_assigns.size() == 0)
|
if(c1->cmd_var_assigns.size() == 0)
|
||||||
{
|
{
|
||||||
delete in->cls[i];
|
delete in->cls[i];
|
||||||
in->cls.erase(in->cls.begin()+i);
|
in->cls.erase(in->cls.begin()+i);
|
||||||
|
|
@ -329,6 +329,8 @@ bool debashify_readonly(list* in)
|
||||||
{
|
{
|
||||||
delete c1->args;
|
delete c1->args;
|
||||||
c1->args = new arglist;
|
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);
|
std::string const& op = get_declare_opt(c1);
|
||||||
if(op == "-a")
|
if(op == "-a")
|
||||||
{
|
{
|
||||||
for(auto it: c1->var_assigns)
|
for(auto it: c1->cmd_var_assigns)
|
||||||
{
|
{
|
||||||
if(it.first != nullptr)
|
if(it.first != nullptr)
|
||||||
params->arrays[it.first->varname] = false;
|
params->arrays[it.first->varname] = false;
|
||||||
|
|
@ -359,7 +361,7 @@ bool debashify_declare(list* in, debashify_params* params)
|
||||||
}
|
}
|
||||||
else if(op == "-A")
|
else if(op == "-A")
|
||||||
{
|
{
|
||||||
for(auto it: c1->var_assigns)
|
for(auto it: c1->cmd_var_assigns)
|
||||||
{
|
{
|
||||||
if(it.first != nullptr)
|
if(it.first != nullptr)
|
||||||
params->arrays[it.first->varname] = true;
|
params->arrays[it.first->varname] = true;
|
||||||
|
|
|
||||||
|
|
@ -333,22 +333,6 @@ std::string cmd::generate(int ind, generate_context* ctx)
|
||||||
{
|
{
|
||||||
std::string ret;
|
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;
|
bool has_args=false;
|
||||||
|
|
||||||
// pre-cmd var assigns
|
// pre-cmd var assigns
|
||||||
|
|
@ -362,6 +346,22 @@ std::string cmd::generate(int ind, generate_context* ctx)
|
||||||
ret += ' ';
|
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
|
// cmd itself
|
||||||
if(args!=nullptr && args->size()>0)
|
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("remove-unused", false, "Remove unused functions and variables"),
|
||||||
ztd::option("list-cmd", false, "List all commands invoked in the script"),
|
ztd::option("list-cmd", false, "List all commands invoked in the script"),
|
||||||
ztd::option("\r [Variable processing]"),
|
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("no-exclude-reserved",false, "Don't exclude reserved variables"),
|
||||||
ztd::option("minify-var", false, "Minify variable names"),
|
ztd::option("minify-var", false, "Minify variable names"),
|
||||||
ztd::option("list-var", false, "List all variables set and invoked in the script"),
|
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("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("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("\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("minify-fct", false, "Minify function names"),
|
||||||
ztd::option("list-fct", false, "List all functions defined in the script")
|
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 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_assign=false;
|
||||||
bool forbid_special=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") )
|
if(cmdassign && (forbid_special || cmd == "export") )
|
||||||
forbid_special=true;
|
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))
|
while(ctx.i<ctx.size && !is_in(ctx[ctx.i], ARGLIST_END))
|
||||||
{
|
{
|
||||||
auto vp=parse_var(ctx, false, true);
|
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;
|
ctx=pp.second;
|
||||||
}
|
}
|
||||||
ta->insert(0, strop);
|
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);
|
ctx.i=skip_chars(ctx, SPACES);
|
||||||
}
|
}
|
||||||
else
|
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) )
|
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;
|
ctx=newct;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
delete vp.first;
|
delete vp.first;
|
||||||
auto pp=parse_arg(ctx);
|
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=pp.second;
|
||||||
}
|
}
|
||||||
ctx.i=skip_chars(ctx, SPACES);
|
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)
|
std::pair<cmd*, parse_context> parse_cmd(parse_context ctx)
|
||||||
{
|
{
|
||||||
cmd* ret = new cmd;
|
cmd* ret = new cmd;
|
||||||
uint32_t start=ctx.i;
|
|
||||||
|
|
||||||
ctx = parse_cmd_varassigns(ret, ctx);
|
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);
|
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 = new arglist;
|
||||||
ret->args->add(new arg(wp.first));
|
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);
|
ctx = parse_cmd_varassigns(ret, ctx, true, wp.first);
|
||||||
}
|
}
|
||||||
|
else if(!is_in(ctx[ctx.i], ARGLIST_END))
|
||||||
if(!is_in(ctx[ctx.i], ARGLIST_END))
|
|
||||||
{
|
{
|
||||||
auto pp=parse_arglist(ctx, true, &ret->redirs);
|
auto pp=parse_arglist(ctx, true, &ret->redirs);
|
||||||
ret->args = pp.first;
|
ret->args = pp.first;
|
||||||
ctx = pp.second;
|
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 );
|
parse_error( unexpected_token(ctx[ctx.i]), ctx );
|
||||||
ctx.i++;
|
ctx.i++;
|
||||||
|
|
|
||||||
|
|
@ -250,7 +250,7 @@ void add_unset_variables(shmain* sh, std::regex const& exclude)
|
||||||
unset_cmd->is_cmdvar=true;
|
unset_cmd->is_cmdvar=true;
|
||||||
for(auto it: m_vars)
|
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);
|
condlist* cl = new condlist(unset_cmd);
|
||||||
sh->lst->cls.insert(sh->lst->cls.begin(), cl);
|
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)
|
if(it.first != nullptr)
|
||||||
unsets->insert(it.first->varname);
|
unsets->insert(it.first->varname);
|
||||||
}
|
}
|
||||||
|
for(auto it: t->cmd_var_assigns)
|
||||||
|
{
|
||||||
|
if(it.first != nullptr)
|
||||||
|
unsets->insert(it.first->varname);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}; break;
|
}; break;
|
||||||
default: 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) )
|
if(has_deleted && c->var_assigns.size()<=0 && (c->arglist_size()<=0 || c->is_cmdvar) )
|
||||||
to_delete=true;
|
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)
|
if(to_delete)
|
||||||
{
|
{
|
||||||
|
|
@ -482,6 +503,8 @@ void string_processors(_obj* in)
|
||||||
|
|
||||||
/** JSON **/
|
/** JSON **/
|
||||||
|
|
||||||
|
#ifdef DEBUG_MODE
|
||||||
|
|
||||||
std::string quote_string(std::string const& in)
|
std::string quote_string(std::string const& in)
|
||||||
{
|
{
|
||||||
return '"' + stringReplace(in, "\"", "\\\"") + '"';
|
return '"' + stringReplace(in, "\"", "\\\"") + '"';
|
||||||
|
|
@ -519,7 +542,6 @@ std::string boolstring(bool in)
|
||||||
return "false";
|
return "false";
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_MODE
|
|
||||||
std::string gen_json_struc(_obj* o)
|
std::string gen_json_struc(_obj* o)
|
||||||
{
|
{
|
||||||
if(o==nullptr)
|
if(o==nullptr)
|
||||||
|
|
@ -681,6 +703,15 @@ std::string gen_json_struc(_obj* o)
|
||||||
aa.push_back(gen_json(ttvec));
|
aa.push_back(gen_json(ttvec));
|
||||||
}
|
}
|
||||||
vec.push_back(std::make_pair( quote_string("var_assigns"), gen_json(aa)));
|
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;
|
std::vector<std::string> tvec;
|
||||||
for(auto it: t->redirs)
|
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_arg(it.second, *ct, true); // force quoted
|
||||||
resolve(it.second, ct);
|
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)
|
for(auto it: t->redirs)
|
||||||
resolve(it, ct);
|
resolve(it, ct);
|
||||||
resolve(t->args, ct);
|
resolve(t->args, ct);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue