implement var_assign structure to cmdvar + added internal json structure generator
This commit is contained in:
parent
9342464590
commit
7d26587dd2
10 changed files with 558 additions and 112 deletions
|
|
@ -26,6 +26,8 @@
|
|||
// bash specific
|
||||
#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);
|
||||
|
||||
|
|
|
|||
|
|
@ -21,9 +21,6 @@ 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;
|
||||
|
|
@ -46,6 +43,7 @@ void fctmap_get(_obj* in, std::regex const& exclude);
|
|||
void cmdmap_get(_obj* in, std::regex const& exclude);
|
||||
|
||||
/** util functions **/
|
||||
std::string gen_json_struc(_obj* in);
|
||||
|
||||
// gen regexes
|
||||
std::regex var_exclude_regex(std::string const& in, bool include_reserved);
|
||||
|
|
|
|||
|
|
@ -86,13 +86,13 @@ public:
|
|||
subarg_string, subarg_variable, subarg_subshell, subarg_arithmetic, subarg_manipulation, subarg_procsub,
|
||||
_variable,
|
||||
_redirect,
|
||||
_arg, arg_procsub,
|
||||
_arg,
|
||||
_arglist,
|
||||
_pipeline,
|
||||
_condlist,
|
||||
_list,
|
||||
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;
|
||||
|
||||
virtual ~_obj() {;}
|
||||
|
|
@ -128,8 +128,10 @@ public:
|
|||
|
||||
void insert(uint32_t i, subarg* val);
|
||||
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); }
|
||||
void add(std::string const& in);
|
||||
inline size_t size() { return sa.size(); }
|
||||
|
||||
std::vector<subarg*> sa;
|
||||
|
|
@ -288,7 +290,7 @@ public:
|
|||
class cmd : public block
|
||||
{
|
||||
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() {
|
||||
if(args!=nullptr) delete args;
|
||||
for(auto it: var_assigns) {
|
||||
|
|
@ -309,6 +311,9 @@ public:
|
|||
// preceding var assigns
|
||||
std::vector<std::pair<variable*,arg*>> var_assigns;
|
||||
|
||||
// is a cmdvar type
|
||||
bool is_cmdvar;
|
||||
|
||||
// check if cmd is this (ex: unset)
|
||||
bool is(std::string const& in);
|
||||
// for var assigns in special cmds (export, unset, read, local)
|
||||
|
|
|
|||
|
|
@ -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::string delete_brackets(std::string const& in);
|
||||
|
|
|
|||
|
|
@ -313,8 +313,29 @@ std::string cmd::generate(int ind)
|
|||
{
|
||||
std::string ret;
|
||||
// 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)
|
||||
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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -62,22 +62,6 @@ bool r_replace_var(_obj* in, strmap_t* varmap)
|
|||
if(el!=varmap->end())
|
||||
t->varname = el->second;
|
||||
}; 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;
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
160
src/parse.cpp
160
src/parse.cpp
|
|
@ -18,6 +18,9 @@ bool g_bash=false;
|
|||
#define PARSE_ERROR(str, i) ztd::format_error(str, "", in, i)
|
||||
|
||||
// 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_operators = { "+", "-", "*", "/", "=", "==", "!=", "&", "|", "^", "<<", ">>", "&&", "||" };
|
||||
|
||||
|
|
@ -339,7 +342,7 @@ 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->add(new string_subarg(tmpstr));
|
||||
ret->add(tmpstr);
|
||||
// get arithmetic
|
||||
auto r=parse_arithmetic(in, size, i+3);
|
||||
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
|
||||
std::string tmpstr=std::string(in+j, i-j);
|
||||
if(tmpstr!="")
|
||||
ret->add(new string_subarg(tmpstr));
|
||||
ret->add(tmpstr);
|
||||
// get subshell
|
||||
auto r=parse_subshell(in, size, i+2);
|
||||
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
|
||||
std::string tmpstr=std::string(in+j, i-j);
|
||||
if(tmpstr!="")
|
||||
ret->add(new string_subarg(tmpstr));
|
||||
ret->add(tmpstr);
|
||||
// get manipulation
|
||||
auto r=parse_manipulation(in, size, i+2);
|
||||
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
|
||||
std::string tmpstr=std::string(in+j, i-j);
|
||||
if(tmpstr!="")
|
||||
ret->add(new string_subarg(tmpstr));
|
||||
ret->add(tmpstr);
|
||||
// add var
|
||||
ret->add(new variable_subarg(r.first, true));
|
||||
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
|
||||
std::string tmpstr=std::string(in+j, i-j);
|
||||
if(tmpstr!="")
|
||||
ret->add(new string_subarg(tmpstr));
|
||||
ret->add(tmpstr);
|
||||
// get arithmetic
|
||||
auto r=parse_arithmetic(in, size, i+3);
|
||||
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
|
||||
std::string tmpstr=std::string(in+j, i-j);
|
||||
if(tmpstr!="")
|
||||
ret->add(new string_subarg(tmpstr));
|
||||
ret->add(tmpstr);
|
||||
// get subshell
|
||||
auto r=parse_subshell(in, size, i+2);
|
||||
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
|
||||
std::string tmpstr=std::string(in+j, i-j);
|
||||
if(tmpstr!="")
|
||||
ret->add(new string_subarg(tmpstr));
|
||||
ret->add(tmpstr);
|
||||
// get manipulation
|
||||
auto r=parse_manipulation(in, size, i+2);
|
||||
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
|
||||
std::string tmpstr=std::string(in+j, i-j);
|
||||
if(tmpstr!="")
|
||||
ret->add(new string_subarg(tmpstr));
|
||||
ret->add(tmpstr);
|
||||
// add var
|
||||
ret->add(new variable_subarg(r.first));
|
||||
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
|
||||
std::string val=std::string(in+j, i-j);
|
||||
if(val != "")
|
||||
ret->add(new string_subarg(val));
|
||||
ret->add(val);
|
||||
|
||||
#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);
|
||||
auto pval = parse_arg(tmpparse.c_str(), tmpparse.size(), 0, NULL);
|
||||
ret->target = pval.first;
|
||||
ret->target->insert(0, new string_subarg(delimitor+"\n"));
|
||||
ret->target->insert(0, delimitor+"\n");
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
// 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
|
||||
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
|
||||
;
|
||||
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(vp.first != nullptr && vp.second<size && in[vp.second] == '=') // is a var assign
|
||||
{
|
||||
vp.first->definition=true;
|
||||
i=vp.second+1;
|
||||
arg* ta;
|
||||
if(g_bash && in[i] == '(')
|
||||
{
|
||||
auto pp=parse_arg(in, size, i+1, ")");
|
||||
ta=pp.first;
|
||||
ta->insert(0, new string_subarg("=(") );
|
||||
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(!g_bash && is_in_vector(wp.first, bash_cmdvar))
|
||||
throw PARSE_ERROR("bash specific: "+wp.first, i);
|
||||
if(ret->var_assigns.size()>0)
|
||||
throw PARSE_ERROR("Unallowed preceding variables on "+wp.first, start);
|
||||
|
||||
ret->args = new arglist;
|
||||
ret->args->add(new arg(wp.first));
|
||||
ret->is_cmdvar=true;
|
||||
i=skip_chars(in, size, wp.second, SPACES);
|
||||
|
||||
i=parse_cmd_varassigns(ret, in, size, i, true, wp.first);
|
||||
}
|
||||
|
||||
if(!is_in(in[i], SPECIAL_TOKENS))
|
||||
|
|
|
|||
|
|
@ -13,10 +13,6 @@ 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;
|
||||
|
|
@ -158,15 +154,12 @@ std::string get_varname(arg* in)
|
|||
|
||||
bool cmd_is_argvar(std::string const& in)
|
||||
{
|
||||
for(auto it: argvar_cmds)
|
||||
if(in == it)
|
||||
return true;
|
||||
return false;
|
||||
return is_in_vector(in, posix_cmdvar) || is_in_vector(in, bash_cmdvar);
|
||||
}
|
||||
|
||||
bool cmd::is_argvar()
|
||||
{
|
||||
return cmd_is_argvar(this->firstarg_string());
|
||||
return is_cmdvar;
|
||||
}
|
||||
|
||||
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;
|
||||
unset_cmd->add(new arg("unset"));
|
||||
unset_cmd->is_cmdvar=true;
|
||||
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);
|
||||
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]++;
|
||||
}
|
||||
}; 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;
|
||||
}
|
||||
return true;
|
||||
|
|
@ -301,9 +285,10 @@ bool r_get_unsets(_obj* in, set_t* unsets)
|
|||
cmd* t = dynamic_cast<cmd*>(in);
|
||||
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;
|
||||
|
|
@ -379,37 +364,25 @@ bool r_delete_var(_obj* in, set_t* vars)
|
|||
{
|
||||
block* tb = t->cls[i]->first_block();
|
||||
bool to_delete=false;
|
||||
bool has_deleted=false;
|
||||
if(tb != nullptr && tb->type == _obj::block_cmd)
|
||||
{
|
||||
cmd* c = dynamic_cast<cmd*>(tb);
|
||||
|
||||
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;
|
||||
delete c->var_assigns[j].second;
|
||||
if(c->var_assigns[j].first != nullptr)
|
||||
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);
|
||||
has_deleted=true;
|
||||
j--;
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
if(has_deleted && c->var_assigns.size()<=0 && (c->arglist_size()<=0 || c->is_cmdvar) )
|
||||
to_delete=true;
|
||||
|
||||
}
|
||||
|
|
@ -425,3 +398,374 @@ bool r_delete_var(_obj* in, set_t* vars)
|
|||
}
|
||||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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::vector<arg*> ret;
|
||||
if(in == nullptr)
|
||||
{
|
||||
return std::make_pair(ret, false);
|
||||
}
|
||||
arg* ta=nullptr;
|
||||
bool has_resolved=false;
|
||||
uint32_t j=0;
|
||||
|
|
|
|||
|
|
@ -215,6 +215,15 @@ void condlist::prune_first_cmd()
|
|||
|
||||
// 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)
|
||||
{
|
||||
sa.insert(sa.begin()+i, val);
|
||||
|
|
|
|||
Loading…
Reference in a new issue