git-svn-id: svn://db.shs.com.ru/pip@155 12ceb7fc-bf1f-11e4-8940-5bc7170c53b5

This commit is contained in:
2015-09-19 19:44:48 +00:00
parent 7b54e3afb9
commit a35a0b5914

View File

@@ -26,17 +26,28 @@ using namespace PICoutManipulators;
void usage() {
piCout << Bold << "PIP Code model generator";
piCout << Cyan << "Version" << Bold << PIPVersion() << NewLine;
piCout << Green << Bold << "Usage:" << Default << "\"pip_cmg [-hqPpEs] -o <output_file> [-I<include_dir1>] [-I<include_dir1>] [...] [-D<define1>] [-D<define1>] [...] <file1> [<file2>] [<file3>] [...]\"" << NewLine;
piCout << Green << Bold << "Usage:" << Default << "\"pip_cmg [-hqPpsAMEST] -o <output_file> [-I<include_dir1>] [-I<include_dir1>] [...] [-D<define1>] [-D<define1>] [...] <file1> [<file2>] [<file3>] [...]\"" << NewLine;
piCout << Green << Bold << "Details:";
piCout << Bold << "Debug control";
piCout << "-h " << Green << "- display this message and exit";
piCout << "-q " << Green << "- quiet, no debug output to console";
piCout << "-P " << Green << "- print list of all parsed files to console before exit";
piCout << "-p " << Green << "- print list of all parsed files without file with \"main\" function to console before exit";
piCout << "-E " << Green << "- write only enums";
piCout << "";
piCout << Bold << "Parsing control";
piCout << "-s " << Green << "- single file (don`t follow includes)";
piCout << "-o <output_file> " << Green << "- output file for code model without extension (e.g. \"ccm\" - files \"ccm.h\" and \"ccm.cpp\" will be created)";
piCout << "-I<include_dir> " << Green << "- add include dir (e.g. -I.. -I../some_dir -I/usr/include)";
piCout << "-D<define> " << Green << "- add define to preprocessor, define PICODE is always defined (e.g. -DMY_DEFINE will add MY_DEFINE define)";
piCout << "";
piCout << Bold << "Output control";
piCout << "-A " << Green << "- write all";
piCout << "-M " << Green << "- write metainfo";
piCout << "-E " << Green << "- write enums";
piCout << "-S " << Green << "- write stream operators";
piCout << "-T " << Green << "- write text serialize functions";
piCout << "-o <output_file> " << Green << "- output file for code model without extension (e.g. \"ccm\" - files \"ccm.h\" and \"ccm.cpp\" will be created)";
piCout << "";
piCout << Bold << "Input control";
piCout << "<file> " << Green << "- add file to code model, all includes of this file will be proceed (e.g. \"main.cpp\")";
}
@@ -111,7 +122,38 @@ void makeEnumInfo(PIFile & f, const PICodeParser::Enum * e) {
}
void writeModel(PICodeParser & parser, const PIString out, bool only_enums) {
void makeClassStream(PIFile & f, const PICodeParser::Entity * e) {
PIStringList ml;
piForeachC (PICodeParser::Member & m, e->members) {
if (m.is_type_ptr) continue;
ml << m.name;
}
if (ml.isEmpty()) return;
f << "\nPIByteArray & operator <<(PIByteArray & s, const " << e->name << " & v) {\n";
f << "\ts";
piForeachC (PIString & m, ml)
f << " << " << m << "\n\t";
f << ";\n}\nPIByteArray & operator >>(PIByteArray & s, " << e->name << " & v) {\n";
f << "\ts";
piForeachC (PIString & m, ml)
f << " >> " << m << "\n\t";
f << ";\n}\n";
}
void makeClassStreamHeader(PIFile & f, const PICodeParser::Entity * e) {
PIStringList ml;
piForeachC (PICodeParser::Member & m, e->members) {
if (m.is_type_ptr) continue;
ml << m.name;
}
if (ml.isEmpty()) return;
f << "\nPIByteArray & operator <<(PIByteArray & s, const " << e->name << " & v);";
f << "\nPIByteArray & operator >>(PIByteArray & s, " << e->name << " & v);\n";
}
void writeModel(PICodeParser & parser, const PIString out, bool meta, bool enums, bool streams, bool texts) {
PIVector<const PICodeParser::Entity * > ventities;
PIString defname = out.replaceAll(".", "_").replaceAll("/", "_").replaceAll(":", "_").replaceAll("-", "_").toUpperCase() + "_H";
@@ -125,13 +167,15 @@ void writeModel(PICodeParser & parser, const PIString out, bool only_enums) {
f.open(PIIODevice::WriteOnly);
f << "// Generated by \"PIP Code model generator\" " << PIDateTime::current().toString("dd.MM.yyyy hh:mm:ss\n\n");
f << "#include <string.h>\n#include \"" << out << ".h\"\n\nusing namespace PICodeInfo;\n\n";
if (!only_enums) {
if (streams || texts) {
PIVector<PIString> incf = inc_files.toVector();
piForeachC (PIString & i, incf) {
if (i != parser.mainFile())
f << "#include \"" << i << "\"\n";
}
f << "\n";
}
/*
PIString entry, argtype, rettype, args;
piForeachC (PICodeParser::Entity * e, parser.entities) {
if (e->name.find("::") >= 0 || e->name.startsWith("_PI")) continue;
@@ -176,26 +220,35 @@ void writeModel(PICodeParser & parser, const PIString out, bool only_enums) {
<< e->type << " \\\"" << e->name << "\\\"!\";\n\treturn PIVariant();\n}\n";
ventities << e;
}
*/
if (meta) {
f << "\n\n// Metainformation\n\n__ClassInfo_" << defname << "_Initializer__::__ClassInfo_" << defname << "_Initializer__() {\n";
f << "\tif (_inited_) return;\n\t_inited_ = true;\n\n";
//if (!enums)
f << "\tClassInfo * ci;\n\tTypeInfo * ni;\n\tFunctionInfo * fi;\n";
f << "\tEnumInfo * ei;\n";
f << "\t(*enumsInfo)[\"\"] = new EnumInfo();\n";
//if (!enums) {
f << "\n\n// Classes\n";
piForeachC (PICodeParser::Entity * e, parser.entities) {
if (e->name.startsWith("_PI")) continue;
makeClassInfo(f, e);
}
//}
f << "\n// Enums\n";
piForeachC (PICodeParser::Enum & e, parser.enums)
makeEnumInfo(f, &e);
f << "}\n";
f << "\n\nbool __ClassInfo_" << defname << "_Initializer__::_inited_ = false;\n";
}
f << "\n\n__ClassInfo_" << defname << "_Initializer__::__ClassInfo_" << defname << "_Initializer__() {\n";
f << "\tif (_inited_) return;\n\t_inited_ = true;\n\n";
if (!only_enums)
f << "\tClassInfo * ci;\n\tTypeInfo * ni;\n\tFunctionInfo * fi;\n";
f << "\tEnumInfo * ei;\n";
f << "\t(*enumsInfo)[\"\"] = new EnumInfo();\n";
if (!only_enums) {
f << "\n\n// Classes\n";
if (streams) {
f << "\n\n// Stream operators\n";
piForeachC (PICodeParser::Entity * e, parser.entities) {
if (e->name.startsWith("_PI")) continue;
makeClassInfo(f, e);
makeClassStream(f, e);
}
}
f << "\n// Enums\n";
piForeachC (PICodeParser::Enum & e, parser.enums)
makeEnumInfo(f, &e);
f << "}\n";
f << "\n\nbool __ClassInfo_" << defname << "_Initializer__::_inited_ = false;\n";
f.close();
@@ -205,7 +258,7 @@ void writeModel(PICodeParser & parser, const PIString out, bool only_enums) {
f << "// Generated by \"PIP Code model generator\" " << PIDateTime::current().toString("dd.MM.yyyy hh:mm:ss\n\n");
f << "#ifndef " << defname << "\n#define " << defname << "\n\n";
f << "#include \"pivariant.h\"\n#include \"picodeinfo.h\"";
if (!only_enums) {
/*
f << "\n\n";
piForeachC (PICodeParser::Entity * e, ventities)
f << e->type << " " << e->name << ";\n";
@@ -214,10 +267,19 @@ void writeModel(PICodeParser & parser, const PIString out, bool only_enums) {
f << "\nPIVariant execFunction(" << e->name << " * object, const char * function, const PIVariant & arg0 = PIVariant(), \
const PIVariant & arg1 = PIVariant(), const PIVariant & arg2 = PIVariant(), const PIVariant & arg3 = PIVariant());";
}
*/
if (meta) {
f << "\n\n// Metainformation\n\nclass __ClassInfo_" << defname << "_Initializer__ {\n";
f << "public:\n\t__ClassInfo_" << defname << "_Initializer__();\n\tstatic bool _inited_;\n};\n";
f << "\nstatic __ClassInfo_" << defname << "_Initializer__ __classinfo_" << defname.toLowerCase() << "_initializer__;\n";
}
if (streams) {
f << "\n\n// Stream operators\n";
piForeachC (PICodeParser::Entity * e, parser.entities) {
if (e->name.startsWith("_PI")) continue;
makeClassStreamHeader(f, e);
}
}
f << "\n\n\nclass __ClassInfo_" << defname << "_Initializer__ {\n";
f << "public:\n\t__ClassInfo_" << defname << "_Initializer__();\n\tstatic bool _inited_;\n};\n";
f << "\nstatic __ClassInfo_" << defname << "_Initializer__ __classinfo_" << defname.toLowerCase() << "_initializer__;\n";
f << "\n\n#endif // " << defname << "\n";
f.close();
}
@@ -229,7 +291,11 @@ int main(int argc, char * argv[]) {
cli.addArgument("output", true);
cli.addArgument("help");
cli.addArgument("quiet");
cli.addArgument("All");
cli.addArgument("Metainfo");
cli.addArgument("Enum");
cli.addArgument("Stream");
cli.addArgument("Text");
cli.addArgument("print");
cli.addArgument("Print");
cli.addArgument("single");
@@ -250,7 +316,11 @@ int main(int argc, char * argv[]) {
parser.parseFiles(files, !cli.hasArgument("single"));
piCout << Cyan << Bold << "Parsing done";
piCout << Cyan << Bold << "Writing code model ...";
writeModel(parser, cli.argumentValue("output"), cli.hasArgument("Enum"));
bool all = cli.hasArgument("All");
writeModel(parser, cli.argumentValue("output"), cli.hasArgument("Metainfo") || 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");