diff --git a/src_main/code/picodeinfo.cpp b/src_main/code/picodeinfo.cpp index c245ba4f..dac4f296 100755 --- a/src_main/code/picodeinfo.cpp +++ b/src_main/code/picodeinfo.cpp @@ -38,5 +38,6 @@ int PICodeInfo::EnumInfo::memberValue(const PIString & name_) const { PIMap * PICodeInfo::classesInfo; PIMap * PICodeInfo::enumsInfo; +PIMap * PICodeInfo::accessFunctions; bool __PICodeInfoInitializer__::_inited_ = false; diff --git a/src_main/code/picodeinfo.h b/src_main/code/picodeinfo.h index 339ac088..e195ffbd 100755 --- a/src_main/code/picodeinfo.h +++ b/src_main/code/picodeinfo.h @@ -41,6 +41,7 @@ enum PIP_EXPORT TypeFlag { typedef PIFlags TypeFlags; typedef PIMap MetaMap; +typedef PIByteArray(*AccessFunction)(const void *, const char *); struct PIP_EXPORT TypeInfo { TypeInfo(const PIString & n = PIString(), const PIString & t = PIString(), PICodeInfo::TypeFlags f = 0, int b = -1) {name = n; type = t; flags = f; bits = b;} @@ -151,6 +152,14 @@ inline PICout operator <<(PICout s, const PICodeInfo::EnumInfo & v) { extern PIMap * classesInfo; extern PIMap * enumsInfo; +extern PIMap * accessFunctions; + +inline PIByteArray getMember(const void * p, const char * class_name, const char * member_name) { + if (!p || !class_name || !member_name || !accessFunctions) return PIByteArray(); + AccessFunction af = accessFunctions->value(PIStringAscii(class_name), (AccessFunction)0); + if (!af) return PIByteArray(); + return af(p, member_name); +} } @@ -161,6 +170,7 @@ public: _inited_ = true; PICodeInfo::classesInfo = new PIMap; PICodeInfo::enumsInfo = new PIMap; + PICodeInfo::accessFunctions = new PIMap; } static bool _inited_; }; diff --git a/utils/code_model_generator/main.cpp b/utils/code_model_generator/main.cpp index d7c44744..732e6932 100755 --- a/utils/code_model_generator/main.cpp +++ b/utils/code_model_generator/main.cpp @@ -54,6 +54,22 @@ void usage() { } +PIString toCName(const PIString &s) { + PIString ret(s.trimmed()); + if (ret.isEmpty()) return ret; + ret.replaceAll('<', '_').replaceAll('>', '_'); + for (int i = 0; i < ret.size_s(); ++i) { + if (i == 0) { + if (!(ret[i].isAlpha() || ret[i].toAscii() == '_')) {ret.pop_front(); --i;} + } else { + if (!(ret[i].isAlpha() || ret[i].isDigit() || ret[i].toAscii() == '_')) {ret.remove(i); --i;} + } + } + ret.replaceAll("__", "_"); + return ret; +} + + void makeClassInfo(PIFile & f, const PICodeParser::Entity * e) { f << "\n\tci = new ClassInfo();\n"; f << "\tci->type = \"" << e->type << "\";\n"; @@ -270,20 +286,21 @@ void makeClassStreamHeader(PIFile & f, const PICodeParser::Entity * e) { void makeGetter(PIFile & f, const PICodeParser::Entity * e) { - f << "\nPIByteArray getMember(const " << e->name << " * p, const char * name) {\n"; + f << "\nPIByteArray getter" << toCName(e->name) << "(const void * p, const char * name) {\n"; f << "\tPIByteArray ret;\n"; - f << "\tif (!p) return ret;\n"; + f << "\tif (!p || !name) return ret;\n"; + f << "\t" << e->name << " * o = (" << e->name << "*)p;\n"; piForeachC (PICodeParser::Member & m, e->members) { if (m.is_type_ptr || m.isBitfield() || !m.dims.isEmpty() || (m.visibility != PICodeParser::Public)) continue; - f << "\tif (strcmp(name, \"" << m.name << "\") == 0) {ret << p->" << m.name << "; return ret;}\n"; + f << "\tif (strcmp(name, \"" << m.name << "\") == 0) {ret << o->" << m.name << "; return ret;}\n"; } f << "\treturn ret;\n}\n"; } void makeGetterHeader(PIFile & f, const PICodeParser::Entity * e) { - f << "\nPIByteArray getMember(const " << e->name << " * p, const char * name);"; + f << "\nPIByteArray getter" << toCName(e->name) << "(const void * p, const char * name);"; } @@ -351,7 +368,8 @@ void writeModel(PICodeParser & parser, PICLI & cli, const PIString out, bool met ventities << e; } */ - if (meta || enums) { + + if (meta || enums || getters) { 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) { @@ -374,6 +392,13 @@ void writeModel(PICodeParser & parser, PICLI & cli, const PIString out, bool met piForeachC (PICodeParser::Enum & e, parser.enums) makeEnumInfo(f, &e); } + if (getters) { + f << "\n// Getters\n"; + piForeachC (PICodeParser::Entity * e, parser.entities) { + if (!e->has_name || e->name.startsWith("_PI")) continue; + f << "\t(*accessFunctions)[\"" << e->name << "\"] = getter" << toCName(e->name) << ";\n"; + } + } f << "}\n"; f << "\n\nbool __ClassInfo_" << defname << "_Initializer__::_inited_ = false;\n"; } @@ -422,11 +447,6 @@ void writeModel(PICodeParser & parser, PICLI & cli, const PIString out, bool met const PIVariant & arg1 = PIVariant(), const PIVariant & arg2 = PIVariant(), const PIVariant & arg3 = PIVariant());"; } */ - if (meta || enums) { - 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) { @@ -440,6 +460,12 @@ const PIVariant & arg1 = PIVariant(), const PIVariant & arg2 = PIVariant(), cons if (!e->has_name || e->name.startsWith("_PI")) continue; makeGetterHeader(f, e); } + f << "\n"; + } + if (meta || enums || getters) { + 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"; } f << "\n\n#endif // " << defname << "\n"; f.close();