From 2b1e7c008b117e6ee6c9ece8d232f2c6f9876282 Mon Sep 17 00:00:00 2001 From: zawwz Date: Wed, 6 Jan 2021 16:37:08 +0100 Subject: [PATCH] restructure struc object extensions --- include/parse.hpp | 36 +++++++++ include/struc.hpp | 13 ++-- include/struc_helper.hpp | 12 +++ src/parse.cpp | 14 +--- src/processing.cpp | 4 +- src/struc.cpp | 143 +--------------------------------- src/struc_helper.cpp | 164 ++++++++++++++++++++++++++++++++++++--- 7 files changed, 216 insertions(+), 170 deletions(-) create mode 100644 include/struc_helper.hpp diff --git a/include/parse.hpp b/include/parse.hpp index de5f722..bd292bd 100644 --- a/include/parse.hpp +++ b/include/parse.hpp @@ -4,6 +4,8 @@ #include "struc.hpp" #include +#include +#include #include @@ -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 parse_list_until(const char* in, uint32_t size, uint32_t start, char end_c, const char* expecting=NULL); +std::pair parse_list_until(const char* in, uint32_t size, uint32_t start, std::string const& end_word); +std::tuple parse_list_until(const char* in, uint32_t size, uint32_t start, std::vector const& end_words, const char* expecting=NULL); +// name +std::pair parse_varname(const char* in, uint32_t size, uint32_t start); + +// subarg parsers +std::pair parse_arithmetic(const char* in, uint32_t size, uint32_t start); +std::pair parse_manipulation(const char* in, uint32_t size, uint32_t start); +// arg parser +std::pair 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 parse_redirect(const char* in, uint32_t size, uint32_t start); +// arglist parser +std::pair parse_arglist(const char* in, uint32_t size, uint32_t start, bool hard_error=false, std::vector* redirs=nullptr); +// block parsers +std::pair parse_block(const char* in, uint32_t size, uint32_t start); +std::pair parse_cmd(const char* in, uint32_t size, uint32_t start); +std::pair parse_function(const char* in, uint32_t size, uint32_t start, const char* after="()"); +std::pair parse_subshell(const char* in, uint32_t size, uint32_t start); +std::pair parse_brace(const char* in, uint32_t size, uint32_t start); +std::pair parse_case(const char* in, uint32_t size, uint32_t start); +std::pair parse_if(const char* in, uint32_t size, uint32_t start); +std::pair parse_for(const char* in, uint32_t size, uint32_t start); +std::pair parse_while(const char* in, uint32_t size, uint32_t start); +// pipeline parser +std::pair parse_pipeline(const char* in, uint32_t size, uint32_t start); +// condlist parser +std::pair parse_condlist(const char* in, uint32_t size, uint32_t start); + #endif //PARSE_HPP diff --git a/include/struc.hpp b/include/struc.hpp index ff574bd..e6b4ff2 100644 --- a/include/struc.hpp +++ b/include/struc.hpp @@ -78,8 +78,6 @@ typedef std::vector arglist_t; extern std::string g_origin; -cmd* make_cmd(std::vector 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 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 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 diff --git a/include/struc_helper.hpp b/include/struc_helper.hpp new file mode 100644 index 0000000..8d3f4f0 --- /dev/null +++ b/include/struc_helper.hpp @@ -0,0 +1,12 @@ +#ifndef STRUC_HELPER_HPP +#define STRUC_HELPER_HPP + +#include "struc.hpp" + +cmd* make_cmd(std::vector 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 diff --git a/src/parse.cpp b/src/parse.cpp index cb44197..1b26203 100644 --- a/src/parse.cpp +++ b/src/parse.cpp @@ -125,8 +125,6 @@ uint32_t skip_unread(const char* in, uint32_t size, uint32_t start) // parse fcts -std::pair parse_subshell(const char* in, uint32_t size, uint32_t start); - std::pair parse_varname(const char* in, uint32_t size, uint32_t start) { uint32_t i=start; @@ -178,8 +176,6 @@ std::pair parse_arithmetic(const char* in, uint32_ return std::make_pair(ret, i); } -std::pair 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 parse_manipulation(const char* in, uint32_t size, uint32_t start) { manipulation_subarg* ret = new manipulation_subarg; @@ -526,7 +522,7 @@ std::pair 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 parse_arglist(const char* in, uint32_t size, uint32_t start, bool hard_error=false, std::vector* redirs=nullptr) +std::pair parse_arglist(const char* in, uint32_t size, uint32_t start, bool hard_error, std::vector* redirs) { uint32_t i=start; arglist* ret = nullptr; @@ -592,8 +588,6 @@ std::pair parse_arglist(const char* in, uint32_t size, uint3 return std::make_pair(ret, i); } -std::pair 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 parse_condlist(const char* in, uint32_t size, uin return std::make_pair(ret, i); } -std::pair parse_list_until(const char* in, uint32_t size, uint32_t start, char end_c, const char* expecting=NULL) +std::pair 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 parse_list_until(const char* in, uint32_t size, uint3 } -std::tuple parse_list_until(const char* in, uint32_t size, uint32_t start, std::vector const& end_words, const char* expecting=NULL) +std::tuple parse_list_until(const char* in, uint32_t size, uint32_t start, std::vector const& end_words, const char* expecting) { list* ret = new list; uint32_t i=skip_unread(in, size, start);; @@ -896,7 +890,7 @@ std::pair 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 parse_function(const char* in, uint32_t size, uint32_t start, const char* after="()") +std::pair parse_function(const char* in, uint32_t size, uint32_t start, const char* after) { uint32_t i=start; function* ret = new function; diff --git a/src/processing.cpp b/src/processing.cpp index 97f1ac0..bb35a69 100644 --- a/src/processing.cpp +++ b/src/processing.cpp @@ -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); } diff --git a/src/struc.cpp b/src/struc.cpp index 4da20e7..c2eeb40 100644 --- a/src/struc.cpp +++ b/src/struc.cpp @@ -9,144 +9,9 @@ std::string g_origin=""; const std::string cmd::empty_string=""; -std::vector arglist::strargs(uint32_t start) +condlist::condlist(block* bl) { - std::vector ret; - bool t=opt_minimize; - opt_minimize=true; - for(uint32_t i=start; igenerate(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(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(pls[0]->cmds[0]); - else - return nullptr; -} - -cmd* block::single_cmd() -{ - if(this->type == _obj::block_subshell) - { - return dynamic_cast(this)->single_cmd(); - } - if(this->type == _obj::block_brace) - { - return dynamic_cast(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((*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((*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(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; inegated = !pls[i]->negated; - // invert bool operators - for(uint32_t i=0; iargs.size()>0 && args->args[0]->sa.size() == 1 && args->args[0]->sa[0]->type == _obj::subarg_string) - return dynamic_cast(args->args[0]->sa[0])->val; - return cmd::empty_string; + type=_obj::_condlist; + parallel=false; + this->add(new pipeline(bl)); } diff --git a/src/struc_helper.cpp b/src/struc_helper.cpp index 03ebc19..ee47c7d 100644 --- a/src/struc_helper.cpp +++ b/src/struc_helper.cpp @@ -1,6 +1,11 @@ -#include "struc.hpp" +#include "struc_helper.hpp" -cmd* make_cmd(std::vector args) +#include "parse.hpp" +#include "options.hpp" + +// ** FUNCTIONS ** // + +cmd* make_cmd(std::vector const& args) { cmd* ret = new cmd(); ret->args = new arglist(); @@ -11,24 +16,161 @@ cmd* make_cmd(std::vector 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(sa[0])->val; +} + +std::vector arglist::strargs(uint32_t start) +{ + std::vector ret; + bool t=opt_minimize; + opt_minimize=true; + for(uint32_t i=start; igenerate(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(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(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((*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((*lst)[0]->pls[0]->cmds[0]); // return command + return nullptr; +} + +cmd* block::single_cmd() +{ + if(this->type == _obj::block_subshell) + return dynamic_cast(this)->single_cmd(); + if(this->type == _obj::block_brace) + return dynamic_cast(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; inegated = !pls[i]->negated; + // invert bool operators + for(uint32_t i=0; i