git-svn-id: svn://db.shs.com.ru/pip@553 12ceb7fc-bf1f-11e4-8940-5bc7170c53b5
This commit is contained in:
@@ -42,10 +42,12 @@ enum TypeFlag {
|
||||
typedef PIFlags<PICodeInfo::TypeFlag> 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<PICodeInfo::TypeInfo> variables;
|
||||
PIVector<PICodeInfo::FunctionInfo> functions;
|
||||
PIVector<PICodeInfo::ClassInfo * > children_info;
|
||||
};
|
||||
|
||||
struct EnumeratorInfo {
|
||||
|
||||
@@ -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 = "<unnamed_" + PIString::fromNumber(anon_num++) + ">";
|
||||
//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;
|
||||
|
||||
@@ -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<Entity * > parents;
|
||||
//PIVector<Entity * > children;
|
||||
PIVector<Entity * > children;
|
||||
PIVector<Member> functions;
|
||||
PIVector<Member> members;
|
||||
PIVector<Typedef> 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<Entity * > tree;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user