From ef38fb178151487c2a667b01c1796747f95793c6 Mon Sep 17 00:00:00 2001 From: Michael Uleysky Date: Mon, 14 Sep 2015 19:52:17 +1000 Subject: [PATCH] Rearrange code. common.h now have all api for modules. --- src/common.h | 250 ++++++++++++++++++++++++++++++- src/debug.cpp | 19 --- src/debug.h | 8 - src/init.cpp | 148 +++++++++--------- src/init.h | 7 +- src/main.cpp | 2 - src/object.cpp | 38 +++++ src/object.h | 314 ++++----------------------------------- src/parser/grammatical.y | 1 - src/parser/lexical.l | 2 +- 10 files changed, 397 insertions(+), 392 deletions(-) delete mode 100644 src/debug.cpp delete mode 100644 src/debug.h diff --git a/src/common.h b/src/common.h index 3391b0f..77f00ea 100644 --- a/src/common.h +++ b/src/common.h @@ -1,15 +1,261 @@ #ifndef COMMON_H #define COMMON_H #include +#include +#include #include +#include +#include +#include +#include #define EXPORT __attribute__ ((visibility ("default"))) enum debug_level {INTERNALREQUEST,MOREDEBUG,DEBUG,INFO,NORMAL,WARNING,ERROR}; EXPORT std::ostream& COUT(debug_level dl); -class ObjectBase; -class ObjectList; +// Check if pointer is ObjectBase derivative class +#define IS_OTYPE(quo,equ) (std::type_index(typeid(*quo))==std::type_index(typeid(equ))) +#define IS_OTYPEI(quo,equ) (std::type_index(typeid(quo))==std::type_index(typeid(equ))) + +typedef std::set UsedType; + +// Base class for all objects +class EXPORT ObjectBase +{ +protected: +// No save by default +virtual const int8_t* Blob(size_t* size) const { *size=0; return 0; } +virtual void DeallocBlob(const void* ptr) const {}; +public: + + ObjectBase() = default; + ObjectBase(const ObjectBase&) = delete; + bool Save(const char* fname) const; + // Pure virtual api + virtual ~ObjectBase(){} + virtual ObjectBase* Copy() const=0; + virtual bool Print() const=0; + virtual std::string Type() const=0; + + // Virtual api with default functions. Modules types must not override them. + virtual std::string Dump() const {return "%"+Type()+"%";} + virtual ObjectBase* Evaluate(bool* err) {*err=false; return 0;} + virtual ObjectBase* ReplaceVar(const std::string& vname, ObjectBase* ob) {return 0;} + virtual void UsedFuncs(UsedType& funcs) const {} + virtual void UsedIdents(UsedType& ids) const {} +}; + +// Template for objects without specific constructor/destructor +template +class EXPORT ObjectSimple: public ObjectBase +{ +private: + T val; + static std::string type; + + const int8_t* Blob(size_t* size) const override {*size=sizeof(T); return reinterpret_cast(&val);} + +public: + ObjectSimple(T t):val(t) {} + ObjectSimple(const T* t):val(*t) {} + ~ObjectSimple() {} + // Pure virtual overrides + ObjectBase* Copy() const override {return new ObjectSimple(val);} + bool Print() const override + { + COUT(NORMAL)< ObjectBool; +typedef ObjectSimple ObjectInt; +typedef ObjectSimple ObjectReal; +typedef ObjectSimple ObjectString; + +template<> +inline const int8_t* ObjectString::Blob(size_t* size) const +{ + *size=val.length(); + return reinterpret_cast(val.c_str()); +} + +// Class for name-value pair +class EXPORT ObjectPair: public ObjectBase +{ +private: + std::string name; + std::shared_ptr val; + +public: + ObjectPair() {} + ObjectPair(const std::string& n, ObjectBase* v):name(n) {val.reset(v);} + ObjectPair(const std::string* n, ObjectBase* v):name(*n) {val.reset(v);} + ~ObjectPair() {} + // Pure virtual overrides + ObjectBase* Copy() const override + { + auto ret=new ObjectPair; + ret->name=name; ret->val=val; + return ret; + } + bool Print() const override + { + if(!Exist()) return false; + COUT(NORMAL)<Type()<ReplaceVar(vname,ob); + if(0!=p) val.reset(p); + return 0; + } + void UsedFuncs(UsedType& funcs) const override {return val->UsedFuncs(funcs);} + void UsedIdents(UsedType& ids) const override {return val->UsedIdents(ids);} + + // Own functions + bool Exist() const {return 0!=val.get();} + ObjectBase* Get(const std::string& gname) const + { + if(gname==name) return val->Copy(); + else return 0; + } + std::string Name() const {return name;} + void SetPair(const std::string& n, ObjectBase* v) {if(!Exist()) {name=n; val.reset(v);}} + const ObjectBase* Value() const {return val.get();} +}; + +// Class for objects list +class EXPORT ObjectList: public ObjectBase +{ +public: + typedef std::vector ListValues; +private: + std::shared_ptr vals; + +public: + ObjectList() {vals.reset(new ListValues, [](ListValues* p){for(auto& i: *p) delete i; delete p;});} + ObjectList(ObjectBase* o) {vals.reset(new ListValues, [](ListValues* p){for(auto& i: *p) delete i; delete p;}); PushBack(o);} + ~ObjectList() {} + // Pure virtual overrides + ObjectBase* Copy() const override + { + auto ret=new ObjectList; + ret->vals=vals; + return ret; + } + bool Print() const override + { + if(!Exist()) return false; + COUT(NORMAL)<Dump()+", "; + if(vals->size()!=0) s.resize(s.length()-2); + return s+")"; + } + ObjectBase* Evaluate(bool* err) override + { + ObjectBase* p; + for(auto& i: *vals) + { + p=i->Evaluate(err); + if(*err) + { + COUT(ERROR)<<" in list member "<Dump()<ReplaceVar(vname,ob); + if(0!=p) + { + delete i; + i=p; + } + } + return 0; + } + void UsedFuncs(UsedType& funcs) const override {for(auto& i: *vals) i->UsedFuncs(funcs);} + void UsedIdents(UsedType& ids) const override {for(auto& i: *vals) i->UsedIdents(ids);} + + // Own functions + const ObjectBase* At(ListValues::size_type i) const {return (*vals)[i];} + bool Exist() const {return 0!=vals->size();} + ObjectBase* Get(const std::string& gname) const + { + ObjectBase* p; + for(auto& i: *vals) + { + p=0; + if(IS_OTYPE(i,ObjectPair)) p=dynamic_cast(i)->Get(gname); + if(0!=p) return p; + if(IS_OTYPE(i,ObjectList)) p=dynamic_cast(i)->Get(gname); + if(0!=p) return p; + } + return 0; + } + ListValues::size_type Size() const {return vals->size();} + ObjectList* PushBack(ObjectBase* p) {vals->push_back(p); return this;} +}; + + typedef ObjectBase* (*Func)(ObjectList*); extern "C" { diff --git a/src/debug.cpp b/src/debug.cpp deleted file mode 100644 index 0c5579b..0000000 --- a/src/debug.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#include -#include "debug.h" - -std::ostream& COUT(debug_level dl) -{ - if(dl==ERROR) return std::cerr; - if(dl>=SetDebugLevel(INTERNALREQUEST)) std::cout.clear(); - else std::cout.setstate(std::cout.failbit); - return std::cout; -} - -debug_level SetDebugLevel(debug_level dl) -{ - static debug_level DEBUG_LEVEL=INFO; - if(dl==INTERNALREQUEST) return DEBUG_LEVEL; - debug_level s=DEBUG_LEVEL; - DEBUG_LEVEL=dl; - return s; -} diff --git a/src/debug.h b/src/debug.h deleted file mode 100644 index 6e2426e..0000000 --- a/src/debug.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef DEBUG_H -#define DEBUG_H -#include -#include "common.h" - -debug_level SetDebugLevel(debug_level dl=INTERNALREQUEST); - -#endif diff --git a/src/init.cpp b/src/init.cpp index e3c775f..beebf6d 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1,6 +1,5 @@ #include #include "init.h" -#include "debug.h" #include "object.h" #include "globals.h" #include "builtin.h" @@ -18,34 +17,58 @@ typedef void* yyscan_t; #undef YYSTYPE #undef YYLTYPE +int BuildDepTree(DepTree* deptree, UsedType& used) {return deptree->CreateGlobalTree(used);} -int ParseOptions(int argc, char** argv, struct program_options& options) + +int CheckFunctions() { - int opt=0; - const char* optstr="t:hdgiq"; + UsedType funcs; - optind=1; - do + for(auto& i:G_tosave) { - opt=getopt(argc,argv,optstr); - switch(opt) + i->UsedFuncs(funcs); + for(auto& f:funcs) if(G_funcs.find(f)==G_funcs.end()) { - case(-1): break; - case('t'):{options.threads=atoi(optarg); if(options.threads<1) return 1; else break;} - case('h'):{options.help=true; break;} - case('d'):{options.dump=true; break;} - case('g'):{options.dl=DEBUG; break;} - case('i'):{options.dl=INFO; break;} - case('q'):{options.dl=WARNING; break;} - default: return 1; + COUT(ERROR)<<"Unknown function "<Dump()<UsedFuncs(funcs); + for(auto& f:funcs) if(G_funcs.find(f)==G_funcs.end()) + { + COUT(ERROR)<<"Unknown function "<Dump()<UsedFuncs(funcs); + for(auto& f:funcs) if(G_funcs.find(f)==G_funcs.end()) + { + COUT(ERROR)<<"Unknown function "<Dump()<<";"<Dump()<<";"<CreateGlobalTree(used); -} - - -int CheckFunctions() +debug_level SetDebugLevel(debug_level dl) { - UsedType funcs; - - for(auto& i:G_tosave) - { - i->UsedFuncs(funcs); - for(auto& f:funcs) if(G_funcs.find(f)==G_funcs.end()) - { - COUT(ERROR)<<"Unknown function "<Dump()<UsedFuncs(funcs); - for(auto& f:funcs) if(G_funcs.find(f)==G_funcs.end()) - { - COUT(ERROR)<<"Unknown function "<Dump()<UsedFuncs(funcs); - for(auto& f:funcs) if(G_funcs.find(f)==G_funcs.end()) - { - COUT(ERROR)<<"Unknown function "<Dump()<<";"<Dump()<<";"<=SetDebugLevel(INTERNALREQUEST)) std::cout.clear(); + else std::cout.setstate(std::cout.failbit); + return std::cout; +} \ No newline at end of file diff --git a/src/init.h b/src/init.h index 40cb75f..727ebc5 100644 --- a/src/init.h +++ b/src/init.h @@ -10,11 +10,12 @@ struct program_options const char* config; }; -int ParseOptions(int argc, char** argv, struct program_options& options); -int ParseConfigFile(const char* config); -int RegisterBuiltinFunctions(); int BuildDepTree(DepTree* deptree, UsedType& used); int CheckFunctions(); void DumpConfig(); +int ParseConfigFile(const char* config); +int ParseOptions(int argc, char** argv, struct program_options& options); +int RegisterBuiltinFunctions(); +debug_level SetDebugLevel(debug_level dl=INTERNALREQUEST); #endif diff --git a/src/main.cpp b/src/main.cpp index e7c1a3b..63e340b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,6 +1,4 @@ -#include "debug.h" #include "init.h" -#include "globals.h" static void usage(const char* prg) { diff --git a/src/object.cpp b/src/object.cpp index e7193d2..44537ab 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -6,6 +6,44 @@ template<> EXPORT std::string ObjectSimple::type="integer"; template<> EXPORT std::string ObjectSimple::type="real"; template<> EXPORT std::string ObjectSimple::type="string"; +bool ObjectBase::Save(const char* fname) const +{ + size_t size,offset=0,wr; + const int8_t* dptr; + FILE* fd; + int serrno; + + fd=fopen(fname,"w"); + serrno=errno; + if(0==fd) + { + COUT(ERROR)<<"Can't open file "< #include #include -#include -#include -#include -#include -#include -#include -#include "debug.h" - -// Check if pointer is ObjectBase derivative class -#define IS_OTYPE(quo,equ) (std::type_index(typeid(*quo))==std::type_index(typeid(equ))) -#define IS_OTYPEI(quo,equ) (std::type_index(typeid(quo))==std::type_index(typeid(equ))) - -typedef std::set UsedType; - -// Base class for all objects -class EXPORT ObjectBase -{ -protected: -// No save by default -virtual const int8_t* Blob(size_t* size) const { *size=0; return 0; } -virtual void DeallocBlob(const void* ptr) const {}; -public: - - ObjectBase() = default; - ObjectBase(const ObjectBase&) = delete; - virtual ~ObjectBase(){} - virtual std::string Type() const=0; - virtual bool Print() const=0; - bool Save(const char* fname) const - { - size_t size,offset=0,wr; - const int8_t* dptr; - FILE* fd; - int serrno; - - fd=fopen(fname,"w"); - serrno=errno; - if(0==fd) - { - COUT(ERROR)<<"Can't open file "< -class EXPORT ObjectSimple: public ObjectBase -{ -private: - T val; - static std::string type; - - const int8_t* Blob(size_t* size) const override - { - *size=sizeof(T); - return reinterpret_cast(&val); - } - -public: - ObjectSimple(T t):val(t) {} - ObjectSimple(const T* t):val(*t) {} - ~ObjectSimple() {} - bool Print() const override - { - COUT(NORMAL)<(val);} -}; - -// Simple objects -typedef ObjectSimple ObjectBool; -typedef ObjectSimple ObjectInt; -typedef ObjectSimple ObjectReal; -typedef ObjectSimple ObjectString; - -template<> -inline const int8_t* ObjectString::Blob(size_t* size) const -{ - *size=val.length(); - return reinterpret_cast(val.c_str()); -} - -// Class for name-value pair -class EXPORT ObjectPair: public ObjectBase -{ -private: - std::string name; - std::shared_ptr val; - -public: - ObjectPair() {} - ObjectPair(const std::string& n, ObjectBase* v):name(n) {val.reset(v);} - ObjectPair(const std::string* n, ObjectBase* v):name(*n) {val.reset(v);} - ~ObjectPair() {} - bool Exist() const {return 0!=val.get();} - - bool Print() const override - { - if(!Exist()) return false; - COUT(NORMAL)<Type()<ReplaceVar(vname,ob); - if(0!=p) val.reset(p); - return 0; - } - ObjectBase* Get(const std::string& gname) const - { - if(gname==name) return val->Copy(); - else return 0; - } -}; - -// Class for objects list -class EXPORT ObjectList: public ObjectBase -{ -public: - typedef std::vector ListValues; -private: - std::shared_ptr vals; - -public: - ObjectList() {vals.reset(new ListValues, [](ListValues* p){for(auto& i: *p) delete i; delete p;});} - ObjectList(ObjectBase* o) {vals.reset(new ListValues, [](ListValues* p){for(auto& i: *p) delete i; delete p;}); PushBack(o);} - ~ObjectList() {} - bool Exist() const {return 0!=vals->size();} - - bool Print() const override - { - if(!Exist()) return false; - COUT(NORMAL)<size();} - std::string Type() const override {return "list";} - ObjectList* PushBack(ObjectBase* p) {vals->push_back(p); return this;} - const ObjectBase* At(ListValues::size_type i) const {return (*vals)[i];} - std::string Dump() const override - { - std::string s("("); - for(auto& i: *vals) s+=i->Dump()+", "; - if(vals->size()!=0) s.resize(s.length()-2); - return s+")"; - } - void UsedFuncs(UsedType& funcs) const override {for(auto& i: *vals) i->UsedFuncs(funcs);} - void UsedIdents(UsedType& ids) const override {for(auto& i: *vals) i->UsedIdents(ids);} - ObjectBase* Copy() const override - { - auto ret=new ObjectList; - ret->vals=vals; - return ret; - } - ObjectBase* Evaluate(bool* err) override - { - ObjectBase* p; - for(auto& i: *vals) - { - p=i->Evaluate(err); - if(*err) - { - COUT(ERROR)<<" in list member "<Dump()<ReplaceVar(vname,ob); - if(0!=p) - { - delete i; - i=p; - } - } - return 0; - } - ObjectBase* Get(const std::string& gname) const - { - ObjectBase* p; - for(auto& i: *vals) - { - p=0; - if(IS_OTYPE(i,ObjectPair)) p=dynamic_cast(i)->Get(gname); - if(0!=p) return p; - if(IS_OTYPE(i,ObjectList)) p=dynamic_cast(i)->Get(gname); - if(0!=p) return p; - } - return 0; - } -}; +#include "common.h" // Class for storing identifiers class OId: public ObjectBase @@ -285,17 +14,17 @@ class OId: public ObjectBase public: OId(const std::string* t):name(*t) {} ~OId() {} - bool Print() const override {return false;} - std::string Type() const override {return "IDENT";} - std::string Name() const {return name;} - void SetName(const std::string& s) {name=s;} - std::string Dump() const override {return name;}; - void UsedIdents(UsedType& ids) const override {ids.insert(name);} + // Pure virtual overrides ObjectBase* Copy() const override { COUT(WARNING)<<"OId::Copy: this call must never be happens."<Copy(); else return 0; } + void UsedIdents(UsedType& ids) const override {ids.insert(name);} + + // Own functions + std::string Name() const {return name;} +// void SetName(const std::string& s) {name=s;} }; // Class for storing functions @@ -326,23 +60,25 @@ public: else args=new ObjectList(p); } ~OFunc() {if(args!=0) delete args;} - bool Print() const override {return false;} - std::string Type() const override {return "FUNC";} - std::string Name() const {return name;} - void SetName(std::string s) {name=s;} - std::string Dump() const override {return Name()+args->Dump();}; - void UsedFuncs(UsedType& funcs) const override {funcs.insert(name); args->UsedFuncs(funcs);} - void UsedIdents(UsedType& ids) const override {args->UsedIdents(ids);} + // Pure virtual overrides ObjectBase* Copy() const override { COUT(WARNING)<<"OFunc::Copy: this call must never be happens."<Copy()); } + bool Print() const override {return false;} + std::string Type() const override {return "FUNC";} + + // Non-default overrides + std::string Dump() const override {return Name()+args->Dump();}; ObjectBase* Evaluate(bool* err) override; - ObjectBase* ReplaceVar(const std::string& vname, ObjectBase* ob) override - { - return args->ReplaceVar(vname,ob); - } + ObjectBase* ReplaceVar(const std::string& vname, ObjectBase* ob) override {return args->ReplaceVar(vname,ob);} + void UsedFuncs(UsedType& funcs) const override {funcs.insert(name); args->UsedFuncs(funcs);} + void UsedIdents(UsedType& ids) const override {args->UsedIdents(ids);} + + // Own functions + std::string Name() const {return name;} +// void SetName(std::string s) {name=s;} }; #endif diff --git a/src/parser/grammatical.y b/src/parser/grammatical.y index fbad0c3..1bddc3d 100644 --- a/src/parser/grammatical.y +++ b/src/parser/grammatical.y @@ -18,7 +18,6 @@ #include #include #include "parser.h" -#include "../debug.h" #include "../object.h" #include "../globals.h" // We can't include lexical.h before grammatical.h, because of strange errors, but grammatical.h only needs definition of yyscan_t diff --git a/src/parser/lexical.l b/src/parser/lexical.l index 2fa9534..95af407 100644 --- a/src/parser/lexical.l +++ b/src/parser/lexical.l @@ -15,7 +15,7 @@ %x INCLUDE %{ -#include "../debug.h" +#include "../common.h" #include "parser.h" // flex use register keyword, but it deprecated in C++11. #define register