From 6cbe77c5b694970f72e6a517af3f3596b4837faf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9F=D0=B5=D0=BB=D0=B8=D0=BF=D0=B5=D0=BD=D0=BA=D0=BE=20?= =?UTF-8?q?=D0=98=D0=B2=D0=B0=D0=BD?= Date: Fri, 17 Nov 2017 11:54:54 +0000 Subject: [PATCH] git-svn-id: svn://db.shs.com.ru/pip@553 12ceb7fc-bf1f-11e4-8940-5bc7170c53b5 --- src_main/code/picodeinfo.h | 8 ++- src_main/code/picodeparser.cpp | 75 +++++++++++++++++++++++------ src_main/code/picodeparser.h | 16 ++++-- src_main/containers/pimap.h | 6 ++- src_main/core/pistring.h | 13 +++++ src_main/piversion.h | 2 +- utils/code_model_generator/main.cpp | 37 +++++++++----- 7 files changed, 121 insertions(+), 36 deletions(-) diff --git a/src_main/code/picodeinfo.h b/src_main/code/picodeinfo.h index e91f6f38..12dd655e 100755 --- a/src_main/code/picodeinfo.h +++ b/src_main/code/picodeinfo.h @@ -42,10 +42,12 @@ enum TypeFlag { typedef PIFlags TypeFlags; struct TypeInfo { - TypeInfo(const PIString & n = PIString(), const PIString & t = PIString(), PICodeInfo::TypeFlags f = 0) {name = n; type = t; flags = f;} + TypeInfo(const PIString & n = PIString(), const PIString & t = PIString(), PICodeInfo::TypeFlags f = 0, int b = -1) {name = n; type = t; flags = f; bits = b;} + const bool isBitfield() const {return bits > 0;} PIString name; PIString type; PICodeInfo::TypeFlags flags; + int bits; }; struct FunctionInfo { @@ -55,10 +57,14 @@ struct FunctionInfo { }; struct ClassInfo { + ClassInfo() {has_name = true;} + bool has_name; + PIString type; PIString name; PIStringList parents; PIVector variables; PIVector functions; + PIVector children_info; }; struct EnumeratorInfo { diff --git a/src_main/code/picodeparser.cpp b/src_main/code/picodeparser.cpp index b1aad987..fef6aa95 100755 --- a/src_main/code/picodeparser.cpp +++ b/src_main/code/picodeparser.cpp @@ -84,7 +84,16 @@ PICodeParser::PICodeParser() { void PICodeParser::parseFile(const PIString & file, bool follow_includes) { clear(); parseFileInternal(file, follow_includes); - /*piCout << "\n\nDefines:"; + /*piForeachC (Entity * c, entities) { + piCout << ""; + piCout << c->type << c->name << c->parent_scope << c->parents << c->children; + if (c->parent_scope) + piCout << "parent" << c->parent_scope->name; + piForeachC (Member & m, c->members) { + piCout << m.type << m.name; + } + } + piCout << "\n\nDefines:"; piForeachC (Define & m, defines) piCout << "define" << m.first << m.second; piCout << "\n\nMacros:"; @@ -171,6 +180,7 @@ void PICodeParser::clear() { main_file.clear(); evaluator.clearCustomVariables(); cur_def_vis = Global; + anon_num = 0; defines << Define("PICODE", "") << custom_defines; } @@ -277,19 +287,19 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) { else pfc.takeSymbol(); continue; } - if (pfc.left(5) == "class" || pfc.left(6) == "struct") { + if (pfc.left(5) == "class" || pfc.left(6) == "struct" || pfc.left(5) == "union") { int dind = pfc.find("{", 0), find = pfc.find(";", 0); if (dind < 0 && find < 0) {pfc.cutLeft(6); continue;} if (dind < 0 || find < dind) {pfc.cutLeft(6); continue;} ccmn = pfc.left(dind) + "{\n" + pfc.mid(dind).takeRange('{', '}') + "\n}\n"; pfc.remove(0, ccmn.size()); - parseClass(ccmn); + parseClass(0, ccmn); continue; } if (pfc.left(4) == "enum") { pfc.cutLeft(4); tmp = pfc.takeCWord(); - parseEnum(cur_namespace + tmp, pfc.takeRange("{", "}")); + parseEnum(0, cur_namespace + tmp, pfc.takeRange("{", "}")); pfc.takeSymbol(); continue; } @@ -337,13 +347,18 @@ PICodeParser::Entity * PICodeParser::parseClassDeclaration(const PIString & fc) else parents << pe; } } - bool is_class = cd.left(5) == "class"; + PIString typename_ = cd.left(6).trim(); + bool is_class = typename_ == "class"; cur_def_vis = (is_class ? Private : Public); PIString cn = cd.mid(6).trim(); + bool has_name = !cn.isEmpty(); + if (cn.isEmpty()) cn = ""; + //piCout << "found " << typename_ << cn; if (cn.isEmpty()) return 0; Entity * e = new Entity(); e->name = cur_namespace + cn; - e->type = (is_class ? "class" : "struct"); + e->type = typename_;//(is_class ? "class" : "struct"); + e->has_name = has_name; e->parents = parents; e->file = cur_file; entities << e; @@ -351,15 +366,18 @@ PICodeParser::Entity * PICodeParser::parseClassDeclaration(const PIString & fc) } -PIString PICodeParser::parseClass(PIString & fc) { +PIString PICodeParser::parseClass(Entity * parent, PIString & fc) { Visibility prev_vis = cur_def_vis; int dind = fc.find("{"), find = fc.find(";"), end = 0; if (dind < 0 && find < 0) return PIString(); if (dind < 0 || find < dind) return fc.left(find); + //piCout << "parse class <****\n" << fc.left(20) << "\n****>"; Entity * ce = parseClassDeclaration(fc.takeLeft(dind)); fc.trim().cutLeft(1).cutRight(1).trim(); //piCout << "found class <****\n" << fc << "\n****>"; if (!ce) return PIString(); + if (parent) parent->children << ce; + ce->parent_scope = parent; int ps = -1; bool def = false; PIString prev_namespace = cur_namespace, stmp; @@ -369,12 +387,23 @@ PIString PICodeParser::parseClass(PIString & fc) { while (!fc.isEmpty()) { PIString cw = fc.takeCWord(), tmp; //piCout << "\ntaked word" << cw; - if (cw == "public") {cur_def_vis = Public; fc.cutLeft(1); continue;} + if (cw == "public") {cur_def_vis = Public; fc.cutLeft(1); continue;} if (cw == "protected") {cur_def_vis = Protected; fc.cutLeft(1); continue;} - if (cw == "private") {cur_def_vis = Private; fc.cutLeft(1); continue;} - if (cw == "class") {if (isDeclaration(fc, 0, &end)) {fc.cutLeft(end); fc.takeSymbol(); continue;} tmp = fc.takeLeft(fc.find("{")); stmp = fc.takeRange("{", "}"); fc.takeSymbol(); stmp = "class " + tmp + "{" + stmp + "}"; parseClass(stmp); continue;} - if (cw == "struct") {if (isDeclaration(fc, 0, &end)) {fc.cutLeft(end); fc.takeSymbol(); continue;} tmp = fc.takeLeft(fc.find("{")); stmp = fc.takeRange("{", "}"); fc.takeSymbol(); stmp = "struct " + tmp + "{" + stmp + "}"; parseClass(stmp); continue;} - if (cw == "enum") {tmp = fc.takeCWord(); parseEnum(cur_namespace + tmp, fc.takeRange("{", "}")); fc.takeSymbol(); continue;} + if (cw == "private") {cur_def_vis = Private; fc.cutLeft(1); continue;} + if (cw == "class" || cw == "struct" || cw == "union") { + if (isDeclaration(fc, 0, &end)) { + fc.cutLeft(end); + fc.takeSymbol(); + continue; + } + tmp = fc.takeLeft(fc.find("{")); + stmp = fc.takeRange("{", "}"); + fc.takeSymbol(); + stmp = cw + " " + tmp + "{" + stmp + "}"; + parseClass(ce, stmp); + continue; + } + if (cw == "enum") {tmp = fc.takeCWord(); parseEnum(ce, cur_namespace + tmp, fc.takeRange("{", "}")); fc.takeSymbol(); continue;} if (cw == "friend") {fc.cutLeft(fc.find(";") + 1); continue;} if (cw == "typedef") {ce->typedefs << parseTypedef(fc.takeLeft(fc.find(";"))); typedefs << ce->typedefs.back(); typedefs.back().first.insert(0, cur_namespace); if (ce->typedefs.back().first.isEmpty()) ce->typedefs.pop_back(); fc.takeSymbol(); continue;} if (cw == "template") { @@ -400,7 +429,7 @@ PIString PICodeParser::parseClass(PIString & fc) { } -bool PICodeParser::parseEnum(const PIString & name, PIString fc) { +bool PICodeParser::parseEnum(Entity * parent, const PIString & name, PIString fc) { //piCout << "enum" << name << fc; Enum e(name); PIStringList vl(fc.split(",")); @@ -511,8 +540,10 @@ bool PICodeParser::parseMember(Entity * parent, PIString & fc) { } else { if (fc.endsWith(";")) fc.cutRight(1); if (fc.startsWith("using") || !(fc.contains(' ') || fc.contains('\t') || fc.contains('\n'))) return true; + int bits = extractMemberBits(fc); tl = fc.split(","); - //piCout << "\tmember" << fc; + //piCout << "member" << fc; + //piCout << "member after eb" << fc << ", bits =" << bits; if (tl.isEmpty()) return true; bool vn = true; ctemp = tl.front(); @@ -562,7 +593,9 @@ bool PICodeParser::parseMember(Entity * parent, PIString & fc) { } me.is_type_ptr = (me.type.right(1) == "]" || me.type.right(1) == "*"); me.type += crepl; - //piCout << "var" << me.type << me.name << me.is_const << me.is_static; + me.bits = bits; + //PICout(PICoutManipulators::AddAll) << "var" << me.type << me.name << me.bits; + //piCout << "var" << v; parent->members << me; } } @@ -571,6 +604,16 @@ bool PICodeParser::parseMember(Entity * parent, PIString & fc) { } +int PICodeParser::extractMemberBits(PIString & fc) { + int i = fc.findLast(":"); + if (i <= 0) return -1; + if (fc[i - 1].toAscii() == ':') return -1; + PIString bs = fc.takeMid(i).mid(1).trim(); + if (bs.isEmpty()) return -1; + return bs.toInt(); +} + + void PICodeParser::normalizeEntityNamespace(PIString & n) { PIString suff, pref; for (int i = n.size_s() - 1; i > 0; --i) @@ -713,7 +756,7 @@ PICodeParser::Entity * PICodeParser::findEntityByName(const PIString & en) { bool PICodeParser::isDeclaration(const PIString & fc, int start, int * end) { int dind = fc.find("{", start), find = fc.find(";", start); - //piCout << "isDeclaration" << dind << find; + //piCout << "isDeclaration" << dind << find << fc.left(10); if (dind < 0 && find < 0) {if (end) *end = -1; return true;} if (dind < 0 || find < dind) {if (end) *end = find; return true;} if (end) *end = dind; diff --git a/src_main/code/picodeparser.h b/src_main/code/picodeparser.h index 4eacc94f..9da2f284 100755 --- a/src_main/code/picodeparser.h +++ b/src_main/code/picodeparser.h @@ -66,9 +66,11 @@ public: Member() { visibility = Global; size = 0; + bits = -1; is_type_ptr = false; attributes = NoAttributes; } + const bool isBitfield() const {return bits > 0;} PIString type; PIString name; PIStringList arguments_full; @@ -77,20 +79,25 @@ public: Attributes attributes; bool is_type_ptr; int size; + int bits; }; struct PIP_EXPORT Entity { Entity() { visibility = Global; + has_name = true; size = 0; + parent_scope = 0; } PIString type; PIString name; PIString file; Visibility visibility; int size; + bool has_name; + Entity * parent_scope; PIVector parents; - //PIVector children; + PIVector children; PIVector functions; PIVector members; PIVector typedefs; @@ -130,10 +137,11 @@ private: bool parseFileContent(PIString & fc, bool main); bool parseDirective(PIString d); Entity * parseClassDeclaration(const PIString & fc); - PIString parseClass(PIString & fc); - bool parseEnum(const PIString & name, PIString fc); + PIString parseClass(Entity * parent, PIString & fc); + bool parseEnum(Entity * parent, const PIString & name, PIString fc); Typedef parseTypedef(PIString fc); bool parseMember(Entity * parent, PIString & fc); + int extractMemberBits(PIString & fc); void restoreTmpTemp(Member * e); bool macroCondition(const PIString & mif, PIString mifcond); bool isDefineExists(const PIString & dn); @@ -144,7 +152,7 @@ private: bool isMainFile(const PIString & fc); void normalizeEntityNamespace(PIString & n); - int macros_iter; + int macros_iter, anon_num; bool with_includes; PIEvaluator evaluator; //PIVector tree; diff --git a/src_main/containers/pimap.h b/src_main/containers/pimap.h index c8e9753f..204832db 100644 --- a/src_main/containers/pimap.h +++ b/src_main/containers/pimap.h @@ -182,11 +182,13 @@ public: if (other.isEmpty()) return *this; if (other.size() == 1) {insert(other.pim_index[0].key, other.pim_content[0]); return *this;} if (other.size() == 2) {insert(other.pim_index[0].key, other.pim_content[0]); insert(other.pim_index[1].key, other.pim_content[1]); return *this;} - pim_content << other.pim_content; + /*pim_content << other.pim_content; size_t si = pim_index.size(); for (int i = 0; i < other.pim_index.size_s(); ++i) pim_index << MapIndex(other.pim_index[i].key, other.pim_index[i].index + si); - _sort(); + _sort();*/ + for (int i = 0; i < other.pim_index.size_s(); ++i) + insert(other.pim_index[i].key, other.pim_content[other.pim_index[i].index]); return *this; } diff --git a/src_main/core/pistring.h b/src_main/core/pistring.h index 61c03c2f..69b415cc 100755 --- a/src_main/core/pistring.h +++ b/src_main/core/pistring.h @@ -471,6 +471,19 @@ public: PIString toNativeDecimalPoints() const; + + //! \brief Returns if string contains "str" + bool contains(const char str) const {return contains(PIString(str));} + + //! \brief Returns if string contains "str" + bool contains(const PIChar str) const {return contains(PIString(str));} + + //! \brief Returns if string contains "str" + bool contains(const char * str) const {return contains(PIString(str));} + + //! \brief Returns if string contains "str" + bool contains(const PIString & str) const {return find(str) >= 0;} + //! \brief Search substring "str" from symbol at index "start" and return first occur position //! \details Example: \snippet pistring.cpp PIString::find diff --git a/src_main/piversion.h b/src_main/piversion.h index d223d1b9..dddd3807 100644 --- a/src_main/piversion.h +++ b/src_main/piversion.h @@ -5,6 +5,6 @@ #define PIP_VERSION_MAJOR 1 #define PIP_VERSION_MINOR 0 #define PIP_VERSION_REVISION 0 -#define PIP_VERSION_SUFFIX "_rc7" +#define PIP_VERSION_SUFFIX "" #endif // PIVERSION_H diff --git a/utils/code_model_generator/main.cpp b/utils/code_model_generator/main.cpp index 316287d8..52037dfc 100755 --- a/utils/code_model_generator/main.cpp +++ b/utils/code_model_generator/main.cpp @@ -54,8 +54,14 @@ void usage() { void makeClassInfo(PIFile & f, const PICodeParser::Entity * e) { f << "\n\tci = new ClassInfo();\n"; - f << "\t(*classesInfo)[\"" << e->name << "\"] = ci;\n"; + f << "\tci->type = \"" << e->type << "\";\n"; f << "\tci->name = \"" << e->name << "\";\n"; + f << "\tci->has_name = " << (e->has_name ? "true" : "false") << ";\n"; + f << "\t(*classesInfo)[ci->name] = ci;\n"; + if (e->parent_scope) { + f << "\tpci = " << "classesInfo->value(\"" << e->parent_scope->name << "\", 0);\n"; + f << "\tif (pci) pci->children_info << ci;\n"; + } piForeachC (PICodeParser::Entity * p, e->parents) f << "\tci->parents << \"" << p->name << "\";\n"; piForeachC (PICodeParser::Member & m, e->members) { @@ -63,13 +69,18 @@ void makeClassInfo(PIFile & f, const PICodeParser::Entity * e) { if (m.attributes != 0) { bool fir = true; f << ", "; - if (m.attributes[PICodeParser::Const]) {if (fir) fir = false; else f << " | "; f << "Const";} - if (m.attributes[PICodeParser::Static]) {if (fir) fir = false; else f << " | "; f << "Static";} - if (m.attributes[PICodeParser::Mutable]) {if (fir) fir = false; else f << " | "; f << "Mutable";} + if (m.attributes[PICodeParser::Const ]) {if (fir) fir = false; else f << " | "; f << "Const";} + if (m.attributes[PICodeParser::Static ]) {if (fir) fir = false; else f << " | "; f << "Static";} + if (m.attributes[PICodeParser::Mutable ]) {if (fir) fir = false; else f << " | "; f << "Mutable";} if (m.attributes[PICodeParser::Volatile]) {if (fir) fir = false; else f << " | "; f << "Volatile";} - if (m.attributes[PICodeParser::Inline]) {if (fir) fir = false; else f << " | "; f << "Inline";} - if (m.attributes[PICodeParser::Virtual]) {if (fir) fir = false; else f << " | "; f << "Virtual";} + if (m.attributes[PICodeParser::Inline ]) {if (fir) fir = false; else f << " | "; f << "Inline";} + if (m.attributes[PICodeParser::Virtual ]) {if (fir) fir = false; else f << " | "; f << "Virtual";} + } else { + if (m.isBitfield()) + f << ", 0"; } + if (m.isBitfield()) + f << ", " << m.bits; f << ");\n"; } PIString arg; @@ -81,7 +92,7 @@ void makeClassInfo(PIFile & f, const PICodeParser::Entity * e) { if (m.attributes[PICodeParser::Const] || m.attributes[PICodeParser::Static]) { bool fir = true; f << ", "; - if (m.attributes[PICodeParser::Const]) {if (fir) fir = false; else f << " | "; f << "Const";} + if (m.attributes[PICodeParser::Const ]) {if (fir) fir = false; else f << " | "; f << "Const";} if (m.attributes[PICodeParser::Static]) {if (fir) fir = false; else f << " | "; f << "Static";} } f << ");\n"; @@ -224,8 +235,10 @@ void writeModel(PICodeParser & parser, PICLI & cli, const PIString out, bool met if (meta || enums) { f << "\n\n// Metainformation\n\n__ClassInfo_" << defname << "_Initializer__::__ClassInfo_" << defname << "_Initializer__() {\n"; f << "\tif (_inited_) return;\n\t_inited_ = true;\n\n"; - if (meta) - f << "\tClassInfo * ci;\n\tTypeInfo * ni;\n\tFunctionInfo * fi;\n"; + if (meta) { + f << "\tClassInfo * ci, * pci = new ClassInfo();\n\tTypeInfo * ni;\n\tFunctionInfo * fi;\n"; + f << "\t(*classesInfo)[\"\"] = pci;\n"; + } if (enums) { f << "\tEnumInfo * ei;\n"; f << "\t(*enumsInfo)[\"\"] = new EnumInfo();\n"; @@ -327,9 +340,9 @@ int main(int argc, char * argv[]) { piCout << Cyan << Bold << "Writing code model ..."; bool all = cli.hasArgument("All"); writeModel(parser, cli, cli.argumentValue("output"), cli.hasArgument("Metainfo") || all, - cli.hasArgument("Enum") || all, - cli.hasArgument("Stream") || all, - cli.hasArgument("Text") || all); + cli.hasArgument("Enum") || all, + cli.hasArgument("Stream") || all, + cli.hasArgument("Text") || all); piCout << Cyan << Bold << "Writing done"; if (cli.hasArgument("print") || cli.hasArgument("Print")) { bool womain = cli.hasArgument("print");