restructure struc object extensions

This commit is contained in:
zawwz 2021-01-06 16:37:08 +01:00
parent 44d71155cc
commit 2b1e7c008b
7 changed files with 216 additions and 170 deletions

View file

@ -4,6 +4,8 @@
#include "struc.hpp"
#include <string>
#include <utility>
#include <vector>
#include <ztd/filedat.hpp>
@ -27,4 +29,38 @@ shmain* parse_text(const char* in, uint32_t size, std::string const& filename=""
inline shmain* parse_text(std::string const& in, std::string const& filename="") { return parse_text(in.c_str(), in.size(), filename); }
inline shmain* parse(std::string const& file) { return parse_text(import_file(file), file); }
// ** unit parsers ** //
/* util parsers */
// list
std::pair<list*, uint32_t> parse_list_until(const char* in, uint32_t size, uint32_t start, char end_c, const char* expecting=NULL);
std::pair<list*, uint32_t> parse_list_until(const char* in, uint32_t size, uint32_t start, std::string const& end_word);
std::tuple<list*, uint32_t, std::string> parse_list_until(const char* in, uint32_t size, uint32_t start, std::vector<std::string> const& end_words, const char* expecting=NULL);
// name
std::pair<std::string, uint32_t> parse_varname(const char* in, uint32_t size, uint32_t start);
// subarg parsers
std::pair<arithmetic_subarg*, uint32_t> parse_arithmetic(const char* in, uint32_t size, uint32_t start);
std::pair<manipulation_subarg*, uint32_t> parse_manipulation(const char* in, uint32_t size, uint32_t start);
// arg parser
std::pair<arg*, uint32_t> parse_arg(const char* in, uint32_t size, uint32_t start, const char* end=ARG_END, const char* unexpected=SPECIAL_TOKENS, bool doquote=true);
// redirect parser
std::pair<redirect*, uint32_t> parse_redirect(const char* in, uint32_t size, uint32_t start);
// arglist parser
std::pair<arglist*, uint32_t> parse_arglist(const char* in, uint32_t size, uint32_t start, bool hard_error=false, std::vector<redirect*>* redirs=nullptr);
// block parsers
std::pair<block*, uint32_t> parse_block(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);
std::pair<function*, uint32_t> parse_function(const char* in, uint32_t size, uint32_t start, const char* after="()");
std::pair<subshell*, uint32_t> parse_subshell(const char* in, uint32_t size, uint32_t start);
std::pair<brace*, uint32_t> parse_brace(const char* in, uint32_t size, uint32_t start);
std::pair<case_block*, uint32_t> parse_case(const char* in, uint32_t size, uint32_t start);
std::pair<if_block*, uint32_t> parse_if(const char* in, uint32_t size, uint32_t start);
std::pair<for_block*, uint32_t> parse_for(const char* in, uint32_t size, uint32_t start);
std::pair<while_block*, uint32_t> parse_while(const char* in, uint32_t size, uint32_t start);
// pipeline parser
std::pair<pipeline*, uint32_t> parse_pipeline(const char* in, uint32_t size, uint32_t start);
// condlist parser
std::pair<condlist*, uint32_t> parse_condlist(const char* in, uint32_t size, uint32_t start);
#endif //PARSE_HPP

View file

@ -78,8 +78,6 @@ typedef std::vector<arg*> arglist_t;
extern std::string g_origin;
cmd* make_cmd(std::vector<std::string> args);
// meta object type
class _obj
{
@ -111,11 +109,11 @@ class arg : public _obj
{
public:
arg() { type=_obj::_arg; }
arg(std::string const& str) { type=_obj::_arg; this->setstring(str);}
arg(std::string const& str) { type=_obj::_arg; this->set(str);}
arg(subarg* in) { type=_obj::_arg; sa.push_back(in); }
~arg() { for(auto it: sa) delete it; }
void setstring(std::string const& str);
void set(std::string const& str);
std::vector<subarg*> sa;
@ -127,8 +125,6 @@ public:
std::string generate(int ind);
};
inline bool operator==(arg a, std::string const& b) { return a.equals(b); }
// arglist
class arglist : public _obj
@ -202,7 +198,7 @@ class condlist : public _obj
{
public:
condlist() { type=_obj::_condlist; parallel=false; }
condlist(pipeline* pl);
condlist(pipeline* pl) { type=_obj::_condlist; parallel=false; this->add(pl); }
condlist(block* bl);
~condlist() { for(auto it: pls) delete it; }
@ -231,6 +227,7 @@ public:
~list() { for(auto it: cls) delete it; }
std::vector<condlist*> cls;
void add(condlist* in) { cls.push_back(in); }
condlist* last_cond() { return cls[cls.size()-1]; }
@ -267,7 +264,7 @@ public:
size_t arglist_size();
void add_arg(arg* in);
void add(arg* in);
// preceding var assigns

12
include/struc_helper.hpp Normal file
View file

@ -0,0 +1,12 @@
#ifndef STRUC_HELPER_HPP
#define STRUC_HELPER_HPP
#include "struc.hpp"
cmd* make_cmd(std::vector<std::string> const& args);
cmd* make_cmd(std::string const& in);
condlist* make_condlist(std::string const& in);
inline bool operator==(arg a, std::string const& b) { return a.equals(b); }
#endif //STRUC_HELPER_HPP

View file

@ -125,8 +125,6 @@ uint32_t skip_unread(const char* in, uint32_t size, uint32_t start)
// parse fcts
std::pair<subshell*, uint32_t> parse_subshell(const char* in, uint32_t size, uint32_t start);
std::pair<std::string, uint32_t> parse_varname(const char* in, uint32_t size, uint32_t start)
{
uint32_t i=start;
@ -178,8 +176,6 @@ std::pair<arithmetic_subarg*, uint32_t> parse_arithmetic(const char* in, uint32_
return std::make_pair(ret, i);
}
std::pair<arg*, uint32_t> parse_arg(const char* in, uint32_t size, uint32_t start, const char* end=ARG_END, const char* unexpected=SPECIAL_TOKENS, bool doquote=true);
std::pair<manipulation_subarg*, uint32_t> parse_manipulation(const char* in, uint32_t size, uint32_t start)
{
manipulation_subarg* ret = new manipulation_subarg;
@ -526,7 +522,7 @@ std::pair<redirect*, uint32_t> parse_redirect(const char* in, uint32_t size, uin
// must start at a read char
// first char has to be read
// ends at either &|;\n#()
std::pair<arglist*, uint32_t> parse_arglist(const char* in, uint32_t size, uint32_t start, bool hard_error=false, std::vector<redirect*>* redirs=nullptr)
std::pair<arglist*, uint32_t> parse_arglist(const char* in, uint32_t size, uint32_t start, bool hard_error, std::vector<redirect*>* redirs)
{
uint32_t i=start;
arglist* ret = nullptr;
@ -592,8 +588,6 @@ std::pair<arglist*, uint32_t> parse_arglist(const char* in, uint32_t size, uint3
return std::make_pair(ret, i);
}
std::pair<block*, uint32_t> parse_block(const char* in, uint32_t size, uint32_t start);
// parse a pipeline
// must start at a read char
// separated by |
@ -680,7 +674,7 @@ std::pair<condlist*, uint32_t> parse_condlist(const char* in, uint32_t size, uin
return std::make_pair(ret, i);
}
std::pair<list*, uint32_t> parse_list_until(const char* in, uint32_t size, uint32_t start, char end_c, const char* expecting=NULL)
std::pair<list*, uint32_t> parse_list_until(const char* in, uint32_t size, uint32_t start, char end_c, const char* expecting)
{
list* ret = new list;
uint32_t i=skip_unread(in, size, start);
@ -778,7 +772,7 @@ std::pair<list*, uint32_t> parse_list_until(const char* in, uint32_t size, uint3
}
std::tuple<list*, uint32_t, std::string> parse_list_until(const char* in, uint32_t size, uint32_t start, std::vector<std::string> const& end_words, const char* expecting=NULL)
std::tuple<list*, uint32_t, std::string> parse_list_until(const char* in, uint32_t size, uint32_t start, std::vector<std::string> const& end_words, const char* expecting)
{
list* ret = new list;
uint32_t i=skip_unread(in, size, start);;
@ -896,7 +890,7 @@ std::pair<brace*, uint32_t> parse_brace(const char* in, uint32_t size, uint32_t
// parse a function
// must start right after the ()
// then parses a brace block
std::pair<function*, uint32_t> parse_function(const char* in, uint32_t size, uint32_t start, const char* after="()")
std::pair<function*, uint32_t> parse_function(const char* in, uint32_t size, uint32_t start, const char* after)
{
uint32_t i=start;
function* ret = new function;

View file

@ -239,9 +239,9 @@ void add_unset_variables(shmain* sh, std::regex const& exclude)
if(m_vars.size()>0)
{
cmd* unset_cmd = new cmd;
unset_cmd->add_arg(new arg("unset"));
unset_cmd->add(new arg("unset"));
for(auto it: m_vars)
unset_cmd->add_arg(new arg(it.first));
unset_cmd->add(new arg(it.first));
condlist* cl = new condlist(unset_cmd);
sh->lst->cls.insert(sh->lst->cls.begin(), cl);
}

View file

@ -9,144 +9,9 @@ std::string g_origin="";
const std::string cmd::empty_string="";
std::vector<std::string> arglist::strargs(uint32_t start)
condlist::condlist(block* bl)
{
std::vector<std::string> ret;
bool t=opt_minimize;
opt_minimize=true;
for(uint32_t i=start; i<args.size(); i++)
{
ret.push_back(args[i]->generate(0));
}
opt_minimize=t;
return ret;
}
void arg::setstring(std::string const& str)
{
for(auto it: sa)
delete it;
sa.resize(0);
sa.push_back(new string_subarg(str));
}
std::string arg::string()
{
if(sa.size() != 1 || sa[0]->type != subarg::subarg_string)
return "";
return dynamic_cast<string_subarg*>(sa[0])->val;
}
void condlist::prune_first_cmd()
{
if(pls.size()>0 && pls[0]->cmds.size()>0)
{
delete pls[0]->cmds[0];
pls[0]->cmds.erase(pls[0]->cmds.begin());
}
}
void condlist::add(pipeline* pl, bool or_op)
{
if(this->pls.size() > 0)
this->or_ops.push_back(or_op);
this->pls.push_back(pl);
}
block* condlist::first_block()
{
if(pls.size() > 0 && pls[0]->cmds.size() > 0)
return (pls[0]->cmds[0]);
else
return nullptr;
}
cmd* condlist::first_cmd()
{
if(pls.size() > 0 && pls[0]->cmds.size() > 0 && pls[0]->cmds[0]->type == _obj::block_cmd)
return dynamic_cast<cmd*>(pls[0]->cmds[0]);
else
return nullptr;
}
cmd* block::single_cmd()
{
if(this->type == _obj::block_subshell)
{
return dynamic_cast<subshell*>(this)->single_cmd();
}
if(this->type == _obj::block_brace)
{
return dynamic_cast<brace*>(this)->single_cmd();
}
return nullptr;
}
cmd* subshell::single_cmd()
{
if( lst->size() == 1 && // only one condlist
(*lst)[0]->pls.size() == 1 && // only one pipeline
(*lst)[0]->pls[0]->cmds.size() == 1 && // only one block
(*lst)[0]->pls[0]->cmds[0]->type == _obj::block_cmd) // block is a command
return dynamic_cast<cmd*>((*lst)[0]->pls[0]->cmds[0]); // return command
return nullptr;
}
size_t cmd::arglist_size()
{
if(args==nullptr)
return 0;
else
return args->size();
}
cmd* brace::single_cmd()
{
if( lst->size() == 1 && // only one condlist
(*lst)[0]->pls.size() == 1 && // only one pipeline
(*lst)[0]->pls[0]->cmds.size() == 1 && // only one block
(*lst)[0]->pls[0]->cmds[0]->type == _obj::block_cmd) // block is a command
return dynamic_cast<cmd*>((*lst)[0]->pls[0]->cmds[0]); // return command
return nullptr;
}
cmd* condlist::get_cmd(std::string const& cmdname)
{
for(auto pl: pls)
{
for(auto bl: pl->cmds)
{
if(bl->type == _obj::block_cmd)
{
cmd* c=dynamic_cast<cmd*>(bl);
if(c->args->size()>0 && (*c->args)[0]->equals(cmdname) )
return c;
}
}
}
return nullptr;
}
void shmain::concat(shmain* in)
{
this->lst->cls.insert(this->lst->cls.end(), in->lst->cls.begin(), in->lst->cls.end());
in->lst->cls.resize(0);
if(this->shebang == "")
this->shebang = in->shebang;
}
void condlist::negate()
{
// invert commands
for(uint32_t i=0; i<pls.size(); i++)
pls[i]->negated = !pls[i]->negated;
// invert bool operators
for(uint32_t i=0; i<or_ops.size(); i++)
or_ops[i] = !or_ops[i];
}
std::string const& cmd::firstarg_string()
{
if(args!=nullptr && args->args.size()>0 && args->args[0]->sa.size() == 1 && args->args[0]->sa[0]->type == _obj::subarg_string)
return dynamic_cast<string_subarg*>(args->args[0]->sa[0])->val;
return cmd::empty_string;
type=_obj::_condlist;
parallel=false;
this->add(new pipeline(bl));
}

View file

@ -1,6 +1,11 @@
#include "struc.hpp"
#include "struc_helper.hpp"
cmd* make_cmd(std::vector<std::string> args)
#include "parse.hpp"
#include "options.hpp"
// ** FUNCTIONS ** //
cmd* make_cmd(std::vector<std::string> const& args)
{
cmd* ret = new cmd();
ret->args = new arglist();
@ -11,24 +16,161 @@ cmd* make_cmd(std::vector<std::string> args)
return ret;
}
condlist::condlist(pipeline* pl)
cmd* make_cmd(std::string const& in)
{
type=_obj::_condlist;
parallel=false;
if(pl!=nullptr) this->add(pl);
return parse_cmd(in.c_str(), in.size(), 0).first;
}
condlist::condlist(block* bl)
condlist* make_condlist(std::string const& in)
{
type=_obj::_condlist;
parallel=false;
this->add(new pipeline(bl));
return parse_condlist(in.c_str(), in.size(), 0).first;
}
void cmd::add_arg(arg* in)
// ** CLASS EXTENSIONS ** //
/// GETTERS ///
// property getters
size_t cmd::arglist_size()
{
if(args==nullptr)
return 0;
else
return args->size();
}
// string getters
std::string arg::string()
{
if(sa.size() != 1 || sa[0]->type != subarg::subarg_string)
return "";
return dynamic_cast<string_subarg*>(sa[0])->val;
}
std::vector<std::string> arglist::strargs(uint32_t start)
{
std::vector<std::string> ret;
bool t=opt_minimize;
opt_minimize=true;
for(uint32_t i=start; i<args.size(); i++)
{
ret.push_back(args[i]->generate(0));
}
opt_minimize=t;
return ret;
}
std::string const& cmd::firstarg_string()
{
if(args!=nullptr && args->args.size()>0 && args->args[0]->sa.size() == 1 && args->args[0]->sa[0]->type == _obj::subarg_string)
return dynamic_cast<string_subarg*>(args->args[0]->sa[0])->val;
return cmd::empty_string;
}
// subobject getters
block* condlist::first_block()
{
if(pls.size() > 0 && pls[0]->cmds.size() > 0)
return (pls[0]->cmds[0]);
else
return nullptr;
}
cmd* condlist::first_cmd()
{
if(pls.size() > 0 && pls[0]->cmds.size() > 0 && pls[0]->cmds[0]->type == _obj::block_cmd)
return dynamic_cast<cmd*>(pls[0]->cmds[0]);
else
return nullptr;
}
cmd* brace::single_cmd()
{
if( lst->size() == 1 && // only one condlist
(*lst)[0]->pls.size() == 1 && // only one pipeline
(*lst)[0]->pls[0]->cmds.size() == 1 && // only one block
(*lst)[0]->pls[0]->cmds[0]->type == _obj::block_cmd) // block is a command
return dynamic_cast<cmd*>((*lst)[0]->pls[0]->cmds[0]); // return command
return nullptr;
}
cmd* subshell::single_cmd()
{
if( lst->size() == 1 && // only one condlist
(*lst)[0]->pls.size() == 1 && // only one pipeline
(*lst)[0]->pls[0]->cmds.size() == 1 && // only one block
(*lst)[0]->pls[0]->cmds[0]->type == _obj::block_cmd) // block is a command
return dynamic_cast<cmd*>((*lst)[0]->pls[0]->cmds[0]); // return command
return nullptr;
}
cmd* block::single_cmd()
{
if(this->type == _obj::block_subshell)
return dynamic_cast<subshell*>(this)->single_cmd();
if(this->type == _obj::block_brace)
return dynamic_cast<brace*>(this)->single_cmd();
return nullptr;
}
/// MODIFIERS ///
// simple setters
void arg::set(std::string const& str)
{
for(auto it: sa)
delete it;
sa.resize(0);
sa.push_back(new string_subarg(str));
}
void condlist::prune_first_cmd()
{
if(pls.size()>0 && pls[0]->cmds.size()>0)
{
delete pls[0]->cmds[0];
pls[0]->cmds.erase(pls[0]->cmds.begin());
}
}
// add/extend
void cmd::add(arg* in)
{
if(args==nullptr)
args = new arglist;
args->push_back(in);
}
void condlist::add(pipeline* pl, bool or_op)
{
if(pls.size() > 0)
or_ops.push_back(or_op);
pls.push_back(pl);
}
void shmain::concat(shmain* in)
{
this->lst->cls.insert(this->lst->cls.end(), in->lst->cls.begin(), in->lst->cls.end());
in->lst->cls.resize(0);
if(this->shebang == "")
this->shebang = in->shebang;
}
// special modifiers
void condlist::negate()
{
// invert commands
for(uint32_t i=0; i<pls.size(); i++)
pls[i]->negated = !pls[i]->negated;
// invert bool operators
for(uint32_t i=0; i<or_ops.size(); i++)
or_ops[i] = !or_ops[i];
}