implement var_assign structure to cmdvar + added internal json structure generator

This commit is contained in:
zawz 2021-02-05 14:42:46 +01:00
parent 9342464590
commit 7d26587dd2
10 changed files with 558 additions and 112 deletions

View file

@ -26,6 +26,8 @@
// bash specific // bash specific
#define ARRAY_ARG_END " \t\n;#()&|<>]" #define ARRAY_ARG_END " \t\n;#()&|<>]"
extern const std::vector<std::string> posix_cmdvar;
extern const std::vector<std::string> bash_cmdvar;
std::string import_file(std::string const& path); std::string import_file(std::string const& path);

View file

@ -21,9 +21,6 @@ extern std::regex re_var_exclude;
extern std::regex re_fct_exclude; extern std::regex re_fct_exclude;
extern const std::regex regex_null; extern const std::regex regex_null;
// globals
extern const std::vector<std::string> argvar_cmds;
// Object maps (optimizations) // Object maps (optimizations)
extern countmap_t m_vars, m_vardefs, m_varcalls; extern countmap_t m_vars, m_vardefs, m_varcalls;
extern countmap_t m_fcts, m_cmds; extern countmap_t m_fcts, m_cmds;
@ -46,6 +43,7 @@ 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 **/
std::string gen_json_struc(_obj* in);
// 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);

View file

@ -86,13 +86,13 @@ public:
subarg_string, subarg_variable, subarg_subshell, subarg_arithmetic, subarg_manipulation, subarg_procsub, subarg_string, subarg_variable, subarg_subshell, subarg_arithmetic, subarg_manipulation, subarg_procsub,
_variable, _variable,
_redirect, _redirect,
_arg, arg_procsub, _arg,
_arglist, _arglist,
_pipeline, _pipeline,
_condlist, _condlist,
_list, _list,
arithmetic_operation, arithmetic_number, arithmetic_variable, arithmetic_parenthesis, arithmetic_subshell, arithmetic_operation, arithmetic_number, arithmetic_variable, arithmetic_parenthesis, arithmetic_subshell,
block_subshell, block_brace, block_main, block_cmd, block_function, block_case, block_if, block_for, block_while, block_until }; block_subshell, block_brace, block_main, block_cmd, block_function, block_case, block_if, block_for, block_while };
_objtype type; _objtype type;
virtual ~_obj() {;} virtual ~_obj() {;}
@ -128,8 +128,10 @@ public:
void insert(uint32_t i, subarg* val); void insert(uint32_t i, subarg* val);
void insert(uint32_t i, arg const& a); void insert(uint32_t i, arg const& a);
void insert(uint32_t i, std::string const& in);
inline void add(subarg* in) { sa.push_back(in); } inline void add(subarg* in) { sa.push_back(in); }
void add(std::string const& in);
inline size_t size() { return sa.size(); } inline size_t size() { return sa.size(); }
std::vector<subarg*> sa; std::vector<subarg*> sa;
@ -288,7 +290,7 @@ public:
class cmd : public block class cmd : public block
{ {
public: public:
cmd(arglist* in=nullptr) { type=_obj::block_cmd; args=in; } cmd(arglist* in=nullptr) { type=_obj::block_cmd; args=in; is_cmdvar=false; }
~cmd() { ~cmd() {
if(args!=nullptr) delete args; if(args!=nullptr) delete args;
for(auto it: var_assigns) { for(auto it: var_assigns) {
@ -309,6 +311,9 @@ public:
// preceding var assigns // preceding var assigns
std::vector<std::pair<variable*,arg*>> var_assigns; std::vector<std::pair<variable*,arg*>> var_assigns;
// is a cmdvar type
bool is_cmdvar;
// 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);
// for var assigns in special cmds (export, unset, read, local) // for var assigns in special cmds (export, unset, read, local)

View file

@ -128,6 +128,15 @@ void concat_sets(std::set<T>& a, std::set<T> const& b)
} }
} }
template <class T>
bool is_in_vector(T el, std::vector<T> vec)
{
for(auto it: vec)
if(it == el)
return true;
return false;
}
std::set<std::string> prune_matching(std::set<std::string>& in, std::regex re); std::set<std::string> prune_matching(std::set<std::string>& in, std::regex re);
std::string delete_brackets(std::string const& in); std::string delete_brackets(std::string const& in);

View file

@ -313,8 +313,29 @@ std::string cmd::generate(int ind)
{ {
std::string ret; std::string ret;
// var assigns // var assigns
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;
}
for(auto it: var_assigns) for(auto it: var_assigns)
ret += it.first->generate(ind) + it.second->generate(ind) + ' '; {
if(it.first != nullptr)
ret += it.first->generate(ind);
if(it.second != nullptr)
ret += it.second->generate(ind);
ret += ' ';
}
if(args!=nullptr && args->size()>0) if(args!=nullptr && args->size()>0)
{ {

View file

@ -62,22 +62,6 @@ bool r_replace_var(_obj* in, strmap_t* varmap)
if(el!=varmap->end()) if(el!=varmap->end())
t->varname = el->second; t->varname = el->second;
}; break; }; break;
case _obj::block_cmd: {
cmd* t = dynamic_cast<cmd*>(in);
for(auto it: t->subarg_vars())
{
string_subarg* tss = dynamic_cast<string_subarg*>(it);
auto el=varmap->find(get_varname(tss->val));
if(el!=varmap->end())
{
size_t tpos=tss->val.find('=');
if(tpos == std::string::npos)
tss->val = el->second;
else
tss->val = el->second + tss->val.substr(tpos);
}
}
}; break;
default: break; default: break;
} }
return true; return true;

View file

@ -18,6 +18,9 @@ bool g_bash=false;
#define PARSE_ERROR(str, i) ztd::format_error(str, "", in, i) #define PARSE_ERROR(str, i) ztd::format_error(str, "", in, i)
// constants // constants
const std::vector<std::string> posix_cmdvar = { "export", "unset", "local", "read" };
const std::vector<std::string> bash_cmdvar = { "readonly", "declare", "typeset" };
const std::vector<std::string> arithmetic_precedence_operators = { "!", "~", "+", "-" }; const std::vector<std::string> arithmetic_precedence_operators = { "!", "~", "+", "-" };
const std::vector<std::string> arithmetic_operators = { "+", "-", "*", "/", "=", "==", "!=", "&", "|", "^", "<<", ">>", "&&", "||" }; const std::vector<std::string> arithmetic_operators = { "+", "-", "*", "/", "=", "==", "!=", "&", "|", "^", "<<", ">>", "&&", "||" };
@ -339,7 +342,7 @@ std::pair<arg*, uint32_t> parse_arg(const char* in, uint32_t size, uint32_t star
// add previous subarg // add previous subarg
std::string tmpstr=std::string(in+j, i-j); std::string tmpstr=std::string(in+j, i-j);
if(tmpstr!="") if(tmpstr!="")
ret->add(new string_subarg(tmpstr)); ret->add(tmpstr);
// get arithmetic // get arithmetic
auto r=parse_arithmetic(in, size, i+3); auto r=parse_arithmetic(in, size, i+3);
arithmetic_subarg* tt = new arithmetic_subarg(r.first); arithmetic_subarg* tt = new arithmetic_subarg(r.first);
@ -356,7 +359,7 @@ std::pair<arg*, uint32_t> parse_arg(const char* in, uint32_t size, uint32_t star
// add previous subarg // add previous subarg
std::string tmpstr=std::string(in+j, i-j); std::string tmpstr=std::string(in+j, i-j);
if(tmpstr!="") if(tmpstr!="")
ret->add(new string_subarg(tmpstr)); ret->add(tmpstr);
// get subshell // get subshell
auto r=parse_subshell(in, size, i+2); auto r=parse_subshell(in, size, i+2);
ret->add(new subshell_subarg(r.first, true)); ret->add(new subshell_subarg(r.first, true));
@ -367,7 +370,7 @@ std::pair<arg*, uint32_t> parse_arg(const char* in, uint32_t size, uint32_t star
// add previous subarg // add previous subarg
std::string tmpstr=std::string(in+j, i-j); std::string tmpstr=std::string(in+j, i-j);
if(tmpstr!="") if(tmpstr!="")
ret->add(new string_subarg(tmpstr)); ret->add(tmpstr);
// get manipulation // get manipulation
auto r=parse_manipulation(in, size, i+2); auto r=parse_manipulation(in, size, i+2);
r.first->quoted=true; r.first->quoted=true;
@ -382,7 +385,7 @@ std::pair<arg*, uint32_t> parse_arg(const char* in, uint32_t size, uint32_t star
// add previous subarg // add previous subarg
std::string tmpstr=std::string(in+j, i-j); std::string tmpstr=std::string(in+j, i-j);
if(tmpstr!="") if(tmpstr!="")
ret->add(new string_subarg(tmpstr)); ret->add(tmpstr);
// add var // add var
ret->add(new variable_subarg(r.first, true)); ret->add(new variable_subarg(r.first, true));
j = i = r.second; j = i = r.second;
@ -413,7 +416,7 @@ std::pair<arg*, uint32_t> parse_arg(const char* in, uint32_t size, uint32_t star
// add previous subarg // add previous subarg
std::string tmpstr=std::string(in+j, i-j); std::string tmpstr=std::string(in+j, i-j);
if(tmpstr!="") if(tmpstr!="")
ret->add(new string_subarg(tmpstr)); ret->add(tmpstr);
// get arithmetic // get arithmetic
auto r=parse_arithmetic(in, size, i+3); auto r=parse_arithmetic(in, size, i+3);
ret->add(new arithmetic_subarg(r.first)); ret->add(new arithmetic_subarg(r.first));
@ -428,7 +431,7 @@ std::pair<arg*, uint32_t> parse_arg(const char* in, uint32_t size, uint32_t star
// add previous subarg // add previous subarg
std::string tmpstr=std::string(in+j, i-j); std::string tmpstr=std::string(in+j, i-j);
if(tmpstr!="") if(tmpstr!="")
ret->add(new string_subarg(tmpstr)); ret->add(tmpstr);
// get subshell // get subshell
auto r=parse_subshell(in, size, i+2); auto r=parse_subshell(in, size, i+2);
ret->add(new subshell_subarg(r.first, false)); ret->add(new subshell_subarg(r.first, false));
@ -439,7 +442,7 @@ std::pair<arg*, uint32_t> parse_arg(const char* in, uint32_t size, uint32_t star
// add previous subarg // add previous subarg
std::string tmpstr=std::string(in+j, i-j); std::string tmpstr=std::string(in+j, i-j);
if(tmpstr!="") if(tmpstr!="")
ret->add(new string_subarg(tmpstr)); ret->add(tmpstr);
// get manipulation // get manipulation
auto r=parse_manipulation(in, size, i+2); auto r=parse_manipulation(in, size, i+2);
ret->add(r.first); ret->add(r.first);
@ -453,7 +456,7 @@ std::pair<arg*, uint32_t> parse_arg(const char* in, uint32_t size, uint32_t star
// add previous subarg // add previous subarg
std::string tmpstr=std::string(in+j, i-j); std::string tmpstr=std::string(in+j, i-j);
if(tmpstr!="") if(tmpstr!="")
ret->add(new string_subarg(tmpstr)); ret->add(tmpstr);
// add var // add var
ret->add(new variable_subarg(r.first)); ret->add(new variable_subarg(r.first));
j = i = r.second; j = i = r.second;
@ -468,7 +471,7 @@ std::pair<arg*, uint32_t> parse_arg(const char* in, uint32_t size, uint32_t star
// add string subarg // add string subarg
std::string val=std::string(in+j, i-j); std::string val=std::string(in+j, i-j);
if(val != "") if(val != "")
ret->add(new string_subarg(val)); ret->add(val);
#ifndef NO_PARSE_CATCH #ifndef NO_PARSE_CATCH
} }
@ -603,7 +606,7 @@ std::pair<redirect*, uint32_t> parse_redirect(const char* in, uint32_t size, uin
std::string tmpparse=std::string(in+j, i-j); std::string tmpparse=std::string(in+j, i-j);
auto pval = parse_arg(tmpparse.c_str(), tmpparse.size(), 0, NULL); auto pval = parse_arg(tmpparse.c_str(), tmpparse.size(), 0, NULL);
ret->target = pval.first; ret->target = pval.first;
ret->target->insert(0, new string_subarg(delimitor+"\n")); ret->target->insert(0, delimitor+"\n");
} }
else else
{ {
@ -1099,6 +1102,93 @@ std::pair<function*, uint32_t> parse_function(const char* in, uint32_t size, uin
return std::make_pair(ret, i); return std::make_pair(ret, i);
} }
// parse only var assigns
uint32_t parse_cmd_varassigns(cmd* ret, const char* in, uint32_t size, uint32_t start, bool cmdassign=false, std::string const& cmd="")
{
uint32_t i=start;
bool forbid_assign=false;
bool forbid_special=false;
if(cmdassign && (cmd == "read" || cmd == "unset") )
forbid_assign=true;
if(cmdassign && (forbid_special || cmd == "export") )
forbid_special=true;
while(i<size && !is_in(in[i], PIPELINE_END))
{
auto vp=parse_var(in, size, i, false, true);
if(vp.first != nullptr)
vp.first->definition=true;
if(vp.first != nullptr && vp.second<size && (in[vp.second] == '=' || word_eq("+=", in, size, vp.second) )) // is a var assign
{
if(forbid_assign)
throw PARSE_ERROR("Unallowed assign", i);
std::string strop = "=";
i=vp.second+1;
if( word_eq("+=", in, size, vp.second) ) // bash var+=
{
if(!g_bash)
throw PARSE_ERROR("bash specific: var+=", i);
if(forbid_special)
throw PARSE_ERROR("Unallowed special assign", i);
strop = "+=";
i++;
}
arg* ta;
if(in[i] == '(') // bash var=()
{
if(!g_bash)
throw PARSE_ERROR("bash specific: var=()", i);
if(forbid_special)
throw PARSE_ERROR("Unallowed special assign", i);
auto pp=parse_arg(in, size, i+1, ")");
ta=pp.first;
ta->insert(0,"(");
ta->add(")");
i=pp.second+1;
}
else if( is_in(in[i], ARG_END) ) // no value : give empty value
{
ta = new arg;
}
else
{
auto pp=parse_arg(in, size, i);
ta=pp.first;
i=pp.second;
}
ta->insert(0, strop);
ret->var_assigns.push_back(std::make_pair(vp.first, ta));
i=skip_chars(in, size, i, SPACES);
}
else
{
if(cmdassign)
{
if(vp.first != nullptr && is_in(in[vp.second], ARG_END) )
{
ret->var_assigns.push_back(std::make_pair(vp.first, nullptr));
i=vp.second;
}
else
{
delete vp.first;
auto pp=parse_arg(in, size, i);
ret->var_assigns.push_back(std::make_pair(nullptr, pp.first));
i=pp.second;
}
i=skip_chars(in, size, i, SPACES);
}
else
{
if(vp.first != nullptr)
delete vp.first;
break;
}
}
}
return i;
}
// must start at read char // must start at read char
std::pair<cmd*, uint32_t> parse_cmd(const char* in, uint32_t size, uint32_t start) std::pair<cmd*, uint32_t> parse_cmd(const char* in, uint32_t size, uint32_t start)
{ {
@ -1110,42 +1200,22 @@ std::pair<cmd*, uint32_t> parse_cmd(const char* in, uint32_t size, uint32_t star
{ {
#endif #endif
; ;
while(true) // parse var assigns i=parse_cmd_varassigns(ret, in, size, i);
auto wp=get_word(in, size, i, ARG_END);
if(is_in_vector(wp.first, posix_cmdvar) || is_in_vector(wp.first, bash_cmdvar))
{ {
auto vp=parse_var(in, size, i, false, true); if(!g_bash && is_in_vector(wp.first, bash_cmdvar))
if(vp.first != nullptr && vp.second<size && in[vp.second] == '=') // is a var assign throw PARSE_ERROR("bash specific: "+wp.first, i);
{ if(ret->var_assigns.size()>0)
vp.first->definition=true; throw PARSE_ERROR("Unallowed preceding variables on "+wp.first, start);
i=vp.second+1;
arg* ta; ret->args = new arglist;
if(g_bash && in[i] == '(') ret->args->add(new arg(wp.first));
{ ret->is_cmdvar=true;
auto pp=parse_arg(in, size, i+1, ")"); i=skip_chars(in, size, wp.second, SPACES);
ta=pp.first;
ta->insert(0, new string_subarg("=(") ); i=parse_cmd_varassigns(ret, in, size, i, true, wp.first);
ta->add(new string_subarg(")") );
i=pp.second+1;
}
else if( is_in(in[i], ARG_END) ) // no value : give empty value
{
ta = new arg("=");
}
else
{
auto pp=parse_arg(in, size, i);
ta=pp.first;
ta->insert(0, new string_subarg("="));
i=pp.second;
}
ret->var_assigns.push_back(std::make_pair(vp.first, ta));
i=skip_chars(in, size, i, " \t");
}
else
{
if(vp.first != nullptr)
delete vp.first;
break;
}
} }
if(!is_in(in[i], SPECIAL_TOKENS)) if(!is_in(in[i], SPECIAL_TOKENS))

View file

@ -13,10 +13,6 @@ std::regex re_fct_exclude;
const std::regex regex_null; const std::regex regex_null;
// globals
const std::vector<std::string> argvar_cmds = { "export", "unset", "local", "read", "readonly", "declare" };
// Object maps // Object maps
countmap_t m_vars, m_vardefs, m_varcalls; countmap_t m_vars, m_vardefs, m_varcalls;
@ -158,15 +154,12 @@ std::string get_varname(arg* in)
bool cmd_is_argvar(std::string const& in) bool cmd_is_argvar(std::string const& in)
{ {
for(auto it: argvar_cmds) return is_in_vector(in, posix_cmdvar) || is_in_vector(in, bash_cmdvar);
if(in == it)
return true;
return false;
} }
bool cmd::is_argvar() bool cmd::is_argvar()
{ {
return cmd_is_argvar(this->firstarg_string()); return is_cmdvar;
} }
bool cmd::is(std::string const& in) bool cmd::is(std::string const& in)
@ -248,8 +241,11 @@ void add_unset_variables(shmain* sh, std::regex const& exclude)
{ {
cmd* unset_cmd = new cmd; cmd* unset_cmd = new cmd;
unset_cmd->add(new arg("unset")); unset_cmd->add(new arg("unset"));
unset_cmd->is_cmdvar=true;
for(auto it: m_vars) for(auto it: m_vars)
unset_cmd->add(new arg(it.first)); {
unset_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);
} }
@ -276,18 +272,6 @@ bool r_get_var(_obj* in, countmap_t* defmap, countmap_t* callmap)
(*callmap)[t->varname]++; (*callmap)[t->varname]++;
} }
}; break; }; break;
case _obj::block_cmd: {
cmd* t = dynamic_cast<cmd*>(in);
if(t->is_argvar())
{
for(uint32_t i=1; i<t->args->size(); i++)
{
std::string varname=get_varname(t->args->args[i]);
if( varname != "" && !defmap->insert( std::make_pair(varname, 1) ).second )
(*defmap)[varname]++;
}
}
}; break;
default: break; default: break;
} }
return true; return true;
@ -301,9 +285,10 @@ bool r_get_unsets(_obj* in, set_t* unsets)
cmd* t = dynamic_cast<cmd*>(in); cmd* t = dynamic_cast<cmd*>(in);
if(t->is("unset")) if(t->is("unset"))
{ {
for(uint32_t i=1; i<t->args->size(); i++) for(auto it: t->var_assigns)
{ {
unsets->insert(t->args->args[i]->string()); if(it.first != nullptr)
unsets->insert(it.first->varname);
} }
} }
}; break; }; break;
@ -379,37 +364,25 @@ bool r_delete_var(_obj* in, set_t* vars)
{ {
block* tb = t->cls[i]->first_block(); block* tb = t->cls[i]->first_block();
bool to_delete=false; bool to_delete=false;
bool has_deleted=false;
if(tb != nullptr && tb->type == _obj::block_cmd) if(tb != nullptr && tb->type == _obj::block_cmd)
{ {
cmd* c = dynamic_cast<cmd*>(tb); cmd* c = dynamic_cast<cmd*>(tb);
for(uint32_t j=0; j<c->var_assigns.size(); j++) for(uint32_t j=0; j<c->var_assigns.size(); j++)
{ {
if( vars->find(c->var_assigns[j].first->varname) != vars->end() ) if( c->var_assigns[j].first == nullptr || vars->find(c->var_assigns[j].first->varname) != vars->end() )
{ {
delete c->var_assigns[j].first; if(c->var_assigns[j].first != nullptr)
delete c->var_assigns[j].second; delete c->var_assigns[j].first;
if(c->var_assigns[j].second != nullptr)
delete c->var_assigns[j].second;
c->var_assigns.erase(c->var_assigns.begin()+j); c->var_assigns.erase(c->var_assigns.begin()+j);
has_deleted=true;
j--; j--;
} }
} }
if(has_deleted && c->var_assigns.size()<=0 && (c->arglist_size()<=0 || c->is_cmdvar) )
if(c->is_argvar())
{
for(uint32_t j=1; j<c->args->size(); j++)
{
std::string varname=get_varname(c->args->args[j]);
if( varname != "" && vars->find( varname ) != vars->end() )
{
delete c->args->args[j];
c->args->args.erase(c->args->args.begin()+j);
j--;
}
}
if(c->args->size()<=1)
to_delete=true;
}
if(c->var_assigns.size()<=0 && c->arglist_size()<=0)
to_delete=true; to_delete=true;
} }
@ -425,3 +398,374 @@ bool r_delete_var(_obj* in, set_t* vars)
} }
return true; return true;
} }
std::string quote_string(std::string const& in)
{
return '"' + stringReplace(in, "\"", "\\\"") + '"';
}
std::string gen_json(std::vector<std::pair<std::string,std::string>> const& vec)
{
std::string ret;
for(auto it: vec)
{
ret += it.first + ":" + it.second + ',';
}
if(ret != "")
ret.pop_back();
return "{" + ret + "}";
}
std::string gen_json(std::vector<std::string> const& vec)
{
std::string ret;
for(auto it: vec)
{
ret += it + ',';
}
if(ret != "")
ret.pop_back();
return "[" + ret + "]";
}
std::string boolstring(bool in)
{
if(in)
return "true";
else
return "false";
}
std::string gen_json_struc(_obj* o)
{
if(o==nullptr)
return "{}";
std::vector<std::pair<std::string,std::string>> vec;
switch(o->type)
{
case _obj::_variable :
{
variable* t = dynamic_cast<variable*>(o);
vec.push_back(std::make_pair(quote_string("type"), quote_string("variable") ) );
vec.push_back(std::make_pair(quote_string("varname"), quote_string(t->varname)));
vec.push_back(std::make_pair(quote_string("definition"), boolstring(t->definition)));
vec.push_back(std::make_pair(quote_string("index"), gen_json_struc(t->index)));
break;
}
case _obj::_redirect :
{
redirect* t = dynamic_cast<redirect*>(o);
vec.push_back(std::make_pair(quote_string("type"), quote_string("redirect") ) );
vec.push_back(std::make_pair(quote_string("op"), quote_string(t->op)));
vec.push_back(std::make_pair(quote_string("target"), gen_json_struc(t->target)));
break;
}
case _obj::_arg :
{
arg* t = dynamic_cast<arg*>(o);
vec.push_back(std::make_pair(quote_string("type"), quote_string("arg") ) );
std::vector<std::string> tvec;
for(auto it: t->sa)
tvec.push_back(gen_json_struc(it));
vec.push_back(std::make_pair(quote_string("sa"), gen_json(tvec)));
break;
}
case _obj::_arglist :
{
arglist* t = dynamic_cast<arglist*>(o);
vec.push_back(std::make_pair(quote_string("type"), quote_string("arglist") ) );
std::vector<std::string> tvec;
for(auto it: t->args)
tvec.push_back(gen_json_struc(it));
vec.push_back(std::make_pair(quote_string("args"), gen_json(tvec)));
break;
}
case _obj::_pipeline :
{
pipeline* t = dynamic_cast<pipeline*>(o);
vec.push_back(std::make_pair(quote_string("type"), quote_string("pipeline") ) );
vec.push_back(std::make_pair(quote_string("negated"), boolstring(t->negated) ) );
std::vector<std::string> tvec;
for(auto it: t->cmds)
tvec.push_back(gen_json_struc(it));
vec.push_back(std::make_pair(quote_string("cmds"), gen_json(tvec)));
break;
}
case _obj::_condlist :
{
condlist* t = dynamic_cast<condlist*>(o);
vec.push_back(std::make_pair(quote_string("type"), quote_string("condlist") ) );
vec.push_back(std::make_pair(quote_string("parallel"), boolstring(t->parallel) ) );
std::vector<std::string> tvec;
for(auto it: t->pls)
tvec.push_back(gen_json_struc(it));
vec.push_back(std::make_pair(quote_string("pls"), gen_json(tvec)));
std::vector<std::string> ttvec;
for(auto it: t->or_ops)
{
ttvec.push_back(boolstring(it));
}
vec.push_back(std::make_pair(quote_string("or_ops"), gen_json(ttvec)));
break;
}
case _obj::_list :
{
list* t = dynamic_cast<list*>(o);
vec.push_back(std::make_pair(quote_string("type"), quote_string("list") ) );
std::vector<std::string> tvec;
for(auto it: t->cls)
tvec.push_back(gen_json_struc(it));
vec.push_back(std::make_pair(quote_string("cls"), gen_json(tvec)));
break;
}
case _obj::block_subshell :
{
subshell* t = dynamic_cast<subshell*>(o);
vec.push_back(std::make_pair(quote_string("type"), quote_string("subshell") ) );
vec.push_back(std::make_pair(quote_string("lst"), gen_json_struc(t->lst)));
std::vector<std::string> tvec;
for(auto it: t->redirs)
tvec.push_back(gen_json_struc(it));
vec.push_back(std::make_pair(quote_string("redirs"), gen_json(tvec)));
break;
}
case _obj::block_brace :
{
brace* t = dynamic_cast<brace*>(o);
vec.push_back(std::make_pair(quote_string("type"), quote_string("brace") ) );
vec.push_back(std::make_pair(quote_string("lst"), gen_json_struc(t->lst)));
std::vector<std::string> tvec;
for(auto it: t->redirs)
tvec.push_back(gen_json_struc(it));
vec.push_back(std::make_pair(quote_string("redirs"), gen_json(tvec)));
break;
}
case _obj::block_main :
{
shmain* t = dynamic_cast<shmain*>(o);
vec.push_back(std::make_pair(quote_string("type"), quote_string("main") ) );
vec.push_back(std::make_pair(quote_string("shebang"), quote_string(t->shebang) ) );
vec.push_back(std::make_pair(quote_string("lst"), gen_json_struc(t->lst)));
std::vector<std::string> tvec;
for(auto it: t->redirs)
tvec.push_back(gen_json_struc(it));
vec.push_back(std::make_pair(quote_string("redirs"), gen_json(tvec)));
break;
}
case _obj::block_function :
{
function* t = dynamic_cast<function*>(o);
vec.push_back(std::make_pair(quote_string("type"), quote_string("function") ) );
vec.push_back(std::make_pair(quote_string("name"), quote_string(t->name) ) );
vec.push_back(std::make_pair(quote_string("lst"), gen_json_struc(t->lst)));
std::vector<std::string> tvec;
for(auto it: t->redirs)
tvec.push_back(gen_json_struc(it));
vec.push_back(std::make_pair(quote_string("redirs"), gen_json(tvec)));
break;
}
case _obj::block_cmd :
{
cmd* t = dynamic_cast<cmd*>(o);
vec.push_back(std::make_pair(quote_string("type"), quote_string("cmd") ) );
vec.push_back(std::make_pair(quote_string("args"), gen_json_struc(t->args)));
vec.push_back(std::make_pair(quote_string("is_cmdvar"), boolstring(t->is_cmdvar)));
std::vector<std::string> aa;
for(auto it: t->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)) );
aa.push_back(gen_json(ttvec));
}
vec.push_back(std::make_pair( quote_string("var_assigns"), gen_json(aa)));
std::vector<std::string> tvec;
for(auto it: t->redirs)
tvec.push_back(gen_json_struc(it));
vec.push_back(std::make_pair(quote_string("redirs"), gen_json(tvec)));
break;
}
case _obj::block_case :
{
case_block* t = dynamic_cast<case_block*>(o);
vec.push_back(std::make_pair(quote_string("type"), quote_string("case") ) );
vec.push_back(std::make_pair(quote_string("carg"), gen_json_struc(t->carg)));
// [ {matchers:[], exec:{}} ]
// cases
std::vector<std::string> tt;
for(auto sc: t->cases)
{
std::vector<std::pair<std::string,std::string>> onecase;
std::vector<std::string> matchers;
for(auto it: sc.first)
matchers.push_back(gen_json_struc(it));
onecase.push_back( std::make_pair(quote_string("matcher"), gen_json(matchers)) );
onecase.push_back( std::make_pair(quote_string("execution"), gen_json_struc(sc.second)) );
tt.push_back(gen_json(onecase));
}
vec.push_back( std::make_pair(quote_string("cases"),gen_json(tt)) );
std::vector<std::string> tvec;
for(auto it: t->redirs)
tvec.push_back(gen_json_struc(it));
vec.push_back(std::make_pair(quote_string("redirs"), gen_json(tvec)));
break;
}
case _obj::block_if :
{
if_block* t = dynamic_cast<if_block*>(o);
vec.push_back(std::make_pair(quote_string("type"), quote_string("if") ) );
std::vector<std::string> condblocks;
// ifs
for(auto sc: t->blocks)
{
std::vector<std::pair<std::string, std::string> > one_cond;
one_cond.push_back(std::make_pair(quote_string("condition"), gen_json_struc(sc.first) ) );
one_cond.push_back(std::make_pair(quote_string("execution"), gen_json_struc(sc.second) ) );
condblocks.push_back(gen_json(one_cond));
}
vec.push_back( std::make_pair(quote_string("blocks"), gen_json(condblocks)) );
// else
vec.push_back(std::make_pair(quote_string("else_lst"), gen_json_struc(t->else_lst)));
std::vector<std::string> tvec;
for(auto it: t->redirs)
tvec.push_back(gen_json_struc(it));
vec.push_back(std::make_pair(quote_string("redirs"), gen_json(tvec)));
break;
}
case _obj::block_for :
{
for_block* t = dynamic_cast<for_block*>(o);
vec.push_back(std::make_pair(quote_string("type"), quote_string("for") ) );
vec.push_back(std::make_pair(quote_string("var"), gen_json_struc(t->var)));
vec.push_back(std::make_pair(quote_string("iter"), gen_json_struc(t->iter)));
vec.push_back(std::make_pair(quote_string("ops"), gen_json_struc(t->ops)));
std::vector<std::string> tvec;
for(auto it: t->redirs)
tvec.push_back(gen_json_struc(it));
vec.push_back(std::make_pair(quote_string("redirs"), gen_json(tvec)));
break;
}
case _obj::block_while :
{
while_block* t = dynamic_cast<while_block*>(o);
vec.push_back(std::make_pair(quote_string("type"), quote_string("while") ) );
vec.push_back(std::make_pair(quote_string("cond"), gen_json_struc(t->cond) ) );
vec.push_back(std::make_pair(quote_string("ops"), gen_json_struc(t->ops) ) );
std::vector<std::string> tvec;
for(auto it: t->redirs)
tvec.push_back(gen_json_struc(it));
vec.push_back(std::make_pair(quote_string("redirs"), gen_json(tvec)));
break;
}
case _obj::subarg_variable :
{
variable_subarg* t = dynamic_cast<variable_subarg*>(o);
vec.push_back(std::make_pair(quote_string("type"), quote_string("subarg_variable") ) );
vec.push_back(std::make_pair(quote_string("var"), gen_json_struc(t->var) ) );
break;
}
case _obj::subarg_subshell :
{
subshell_subarg* t = dynamic_cast<subshell_subarg*>(o);
vec.push_back(std::make_pair(quote_string("type"), quote_string("subarg_subshell") ) );
vec.push_back(std::make_pair(quote_string("sbsh"), gen_json_struc(t->sbsh) ) );
break;
}
case _obj::subarg_manipulation :
{
manipulation_subarg* t = dynamic_cast<manipulation_subarg*>(o);
vec.push_back(std::make_pair(quote_string("type"), quote_string("subarg_manipulation") ) );
vec.push_back(std::make_pair(quote_string("size"), boolstring(t->size) ) );
vec.push_back(std::make_pair(quote_string("var"), gen_json_struc(t->var) ) );
vec.push_back(std::make_pair(quote_string("manip"), gen_json_struc(t->manip) ) );
break;
}
case _obj::subarg_procsub :
{
procsub_subarg* t = dynamic_cast<procsub_subarg*>(o);
vec.push_back(std::make_pair(quote_string("type"), quote_string("subarg_procsub") ) );
vec.push_back(std::make_pair(quote_string("is_output"), boolstring(t->is_output) ) );
vec.push_back(std::make_pair(quote_string("sbsh"), gen_json_struc(t->sbsh) ) );
break;
}
case _obj::subarg_arithmetic :
{
arithmetic_subarg* t = dynamic_cast<arithmetic_subarg*>(o);
vec.push_back(std::make_pair(quote_string("type"), quote_string("subarg_arithmetic") ) );
vec.push_back(std::make_pair(quote_string("arith"), gen_json_struc(t->arith) ) );
break;
}
case _obj::subarg_string :
{
string_subarg* t = dynamic_cast<string_subarg*>(o);
vec.push_back(std::make_pair(quote_string("type"), quote_string("subarg_string") ) );
vec.push_back(std::make_pair(quote_string("val"), quote_string(t->val) ) );
break;
}
case _obj::arithmetic_variable :
{
variable_arithmetic* t = dynamic_cast<variable_arithmetic*>(o);
vec.push_back(std::make_pair(quote_string("type"), quote_string("arithmetic_variable") ) );
vec.push_back(std::make_pair(quote_string("var"), gen_json_struc(t->var) ) );
break;
}
case _obj::arithmetic_subshell :
{
subshell_arithmetic* t = dynamic_cast<subshell_arithmetic*>(o);
vec.push_back(std::make_pair(quote_string("type"), quote_string("arithmetic_subshell") ) );
vec.push_back(std::make_pair(quote_string("sbsh"), gen_json_struc(t->sbsh) ) );
break;
}
case _obj::arithmetic_operation :
{
operation_arithmetic* t = dynamic_cast<operation_arithmetic*>(o);
vec.push_back(std::make_pair(quote_string("type"), quote_string("arithmetic_operation") ) );
vec.push_back(std::make_pair(quote_string("val1"), gen_json_struc(t->val1) ) );
vec.push_back(std::make_pair(quote_string("val2"), gen_json_struc(t->val2) ) );
break;
}
case _obj::arithmetic_parenthesis :
{
parenthesis_arithmetic* t = dynamic_cast<parenthesis_arithmetic*>(o);
vec.push_back(std::make_pair(quote_string("type"), quote_string("arithmetic_parenthesis") ) );
vec.push_back(std::make_pair(quote_string("val"), gen_json_struc(t->val) ) );
break;
}
case _obj::arithmetic_number :
{
number_arithmetic* t = dynamic_cast<number_arithmetic*>(o);
vec.push_back(std::make_pair(quote_string("type"), quote_string("arithmetic_number") ) );
vec.push_back(std::make_pair(quote_string("val"), quote_string(t->val) ) );
break;
}
}
return gen_json(vec);
}

View file

@ -226,6 +226,10 @@ std::pair< std::vector<condlist*> , bool > resolve_condlist(condlist* in, shmain
std::pair< std::vector<arg*> , bool > resolve_arg(arg* in, shmain* parent, bool forcequote=false) std::pair< std::vector<arg*> , bool > resolve_arg(arg* in, shmain* parent, bool forcequote=false)
{ {
std::vector<arg*> ret; std::vector<arg*> ret;
if(in == nullptr)
{
return std::make_pair(ret, false);
}
arg* ta=nullptr; arg* ta=nullptr;
bool has_resolved=false; bool has_resolved=false;
uint32_t j=0; uint32_t j=0;

View file

@ -215,6 +215,15 @@ void condlist::prune_first_cmd()
// add/extend // add/extend
void arg::insert(uint32_t i, std::string const& in)
{
this->insert(i, new string_subarg(in));
}
void arg::add(std::string const& in)
{
this->add(new string_subarg(in));
}
void arg::insert(uint32_t i, subarg* val) void arg::insert(uint32_t i, subarg* val)
{ {
sa.insert(sa.begin()+i, val); sa.insert(sa.begin()+i, val);