PICODEINFO::accessOffsetFunction
add offset generation in pip_cmg for retrieve bytes offset of struct member add pip_cmg -V doc
This commit is contained in:
@@ -46,8 +46,15 @@ const char help_string[] = "-M (Metainfo)\n"
|
||||
"with simple << and >> operators.\n"
|
||||
"If PIMETA(no-stream) presence, then class or struct ignored.\n"
|
||||
"\n"
|
||||
"-J (JSON serialization)\n"
|
||||
"Generate serialize/deserialize methods for classes and structures.\n"
|
||||
"These methods uses by PIJSON::serialize(T v) and PIJSON::deserialize(json)\n"
|
||||
"allow automatic conversion to/from PIJSON. Use member name as key.\n"
|
||||
"Member can be skipped by providing PIMETA(id=-).\n"
|
||||
"If PIMETA(no-json) presence, then class or struct ignored.\n"
|
||||
"\n"
|
||||
"-G (Getter functions)\n"
|
||||
"Generate anonymous access methods for member typenames and values.\n"
|
||||
"Generate anonymous access methods for member typenames, values and offsets.\n"
|
||||
"Every class or struct member typename can be obtained with:\n"
|
||||
"const char * getMemberType(const char * class_name, const char * member_name)\n"
|
||||
"Member value can be obtained with:\n"
|
||||
@@ -55,6 +62,7 @@ const char help_string[] = "-M (Metainfo)\n"
|
||||
"where \"p\" - class or struct pointer, and returns serialized value.\n"
|
||||
"PIVariant getMemberAsVariant(const void * p, const char * class_name, const char * member_name)\n"
|
||||
"where \"p\" - class or struct pointer, and returns value as registered PIVariant.\n"
|
||||
"If PIMETA(no-getter) presence, then class or struct ignored.\n"
|
||||
"";
|
||||
|
||||
|
||||
|
||||
@@ -63,8 +63,26 @@ void writeGetterValueMembers(Runtime & rt, const PICodeParser::Entity * e, PIStr
|
||||
}
|
||||
|
||||
|
||||
void writeGetterOffsetMembers(Runtime & rt, const PICodeParser::Entity * e, PIString entity_name, PIString var_prefix) {
|
||||
if (var_prefix.isNotEmpty() && !var_prefix.endsWith('.')) var_prefix += ".";
|
||||
PISet<int> used_id;
|
||||
for (const PICodeParser::Member & m: e->members) {
|
||||
if (m.is_type_ptr || !m.dims.isEmpty() || m.isBitfield() || (m.visibility != PICodeParser::Public)) continue;
|
||||
auto type = findEntity(rt, m.type);
|
||||
if (type) {
|
||||
if (type->is_anonymous) {
|
||||
writeGetterOffsetMembers(rt, type, entity_name, var_prefix + m.name);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
rt.ts << "\tif (strcmp(name, \"" << var_prefix << m.name << "\") == 0) ";
|
||||
rt.ts << "return PICODEINFO_OFFSET(" << entity_name << ", " << var_prefix << m.name << ");\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void makeGetterType(Runtime & rt, const PICodeParser::Entity * e) {
|
||||
if (!needClassStream(e)) return;
|
||||
if (!needClassGetter(e)) return;
|
||||
rt.ts << "\nconst char * getterType" << toCName(e->name) << "(const char * name) {\n";
|
||||
rt.ts << "\tif (!name) return \"\";\n";
|
||||
writeGetterTypeMembers(rt, e);
|
||||
@@ -73,7 +91,7 @@ void makeGetterType(Runtime & rt, const PICodeParser::Entity * e) {
|
||||
|
||||
|
||||
void makeGetterValue(Runtime & rt, const PICodeParser::Entity * e) {
|
||||
if (!needClassStream(e)) return;
|
||||
if (!needClassGetter(e)) return;
|
||||
rt.ts << "\nPIByteArray getterValue" << toCName(e->name) << "(const void * p, const char * name) {\n";
|
||||
rt.ts << "\tPIByteArray ret;\n";
|
||||
rt.ts << "\tif (!p || !name) return ret;\n";
|
||||
@@ -81,3 +99,23 @@ void makeGetterValue(Runtime & rt, const PICodeParser::Entity * e) {
|
||||
writeGetterValueMembers(rt, e);
|
||||
rt.ts << "\treturn ret;\n}\n";
|
||||
}
|
||||
|
||||
|
||||
void makeGetterOffset(Runtime & rt, const PICodeParser::Entity * e) {
|
||||
if (!needClassGetter(e)) return;
|
||||
rt.ts << "\nint getterOffset" << toCName(e->name) << "(const char * name) {\n";
|
||||
rt.ts << "\tif (!name) return 0;\n";
|
||||
writeGetterOffsetMembers(rt, e, e->name);
|
||||
rt.ts << "\treturn 0;\n}\n";
|
||||
}
|
||||
|
||||
|
||||
bool needClassGetter(const PICodeParser::Entity * e) {
|
||||
if (e->meta.contains("no-getter")) return false;
|
||||
for (const PICodeParser::Member & m: e->members) {
|
||||
if (m.is_type_ptr || !m.dims.isEmpty() || (m.visibility != PICodeParser::Public)) continue;
|
||||
if (m.attributes[PICodeParser::Static]) continue;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,10 @@
|
||||
|
||||
void writeGetterTypeMembers(Runtime & rt, const PICodeParser::Entity * e, PIString var_prefix = {});
|
||||
void writeGetterValueMembers(Runtime & rt, const PICodeParser::Entity * e, PIString var_prefix = {});
|
||||
void writeGetterOffsetMembers(Runtime & rt, const PICodeParser::Entity * e, PIString entity_name, PIString var_prefix = {});
|
||||
void makeGetterType(Runtime & rt, const PICodeParser::Entity * e);
|
||||
void makeGetterValue(Runtime & rt, const PICodeParser::Entity * e);
|
||||
void makeGetterOffset(Runtime & rt, const PICodeParser::Entity * e);
|
||||
bool needClassGetter(const PICodeParser::Entity * e);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -66,11 +66,15 @@ bool writeModel(PICodeParser & parser,
|
||||
if (meta || enums || getters) {
|
||||
if (getters) {
|
||||
ts << "\n\n// Getter funtions\n";
|
||||
ts << "\n#define PICODEINFO_OFFSET(type, member) reinterpret_cast<size_t>(&reinterpret_cast<const char &>((((type "
|
||||
"*)nullptr)->member)))\n";
|
||||
for (const PICodeParser::Entity * e: parser.entities) {
|
||||
if (e->is_anonymous || e->name.startsWith("_PI")) continue;
|
||||
makeGetterType(rt, e);
|
||||
makeGetterValue(rt, e);
|
||||
makeGetterOffset(rt, e);
|
||||
}
|
||||
ts << "\n#undef PICODEINFO_OFFSET\n";
|
||||
}
|
||||
ts << "\n\n// Metainformation\n\n__ClassInfo_" << defname << "_Initializer__::__ClassInfo_" << defname << "_Initializer__() {\n";
|
||||
ts << "\tstatic __ClassInfo_" << defname << "_Initializer__::Content content;\n";
|
||||
@@ -83,6 +87,7 @@ bool writeModel(PICodeParser & parser,
|
||||
if (getters) {
|
||||
ts << "\tauto & ci_avf(*ci_ins->accessValueFunctions);\n";
|
||||
ts << "\tauto & ci_atf(*ci_ins->accessTypeFunctions);\n";
|
||||
ts << "\tauto & ci_aof(*ci_ins->accessOffsetFunctions);\n";
|
||||
}
|
||||
|
||||
if (meta) {
|
||||
@@ -109,8 +114,10 @@ bool writeModel(PICodeParser & parser,
|
||||
for (const PICodeParser::Entity * e: parser.entities) {
|
||||
if (!needClassStream(e)) continue;
|
||||
if (e->is_anonymous || e->name.startsWith("_PI")) continue;
|
||||
ts << "\tci_avf[\"" << e->name << "\"] = getterValue" << toCName(e->name) << ";\n";
|
||||
ts << "\tci_atf[\"" << e->name << "\"] = getterType" << toCName(e->name) << ";\n";
|
||||
auto cname = toCName(e->name);
|
||||
ts << "\tci_avf[\"" << e->name << "\"] = getterValue" << cname << ";\n";
|
||||
ts << "\tci_atf[\"" << e->name << "\"] = getterType" << cname << ";\n";
|
||||
ts << "\tci_aof[\"" << e->name << "\"] = getterOffset" << cname << ";\n";
|
||||
}
|
||||
}
|
||||
ts << "}\n\n";
|
||||
@@ -121,6 +128,7 @@ bool writeModel(PICodeParser & parser,
|
||||
if (getters) {
|
||||
ts << "\tauto & ci_avf(*ci_ins->accessValueFunctions);\n";
|
||||
ts << "\tauto & ci_atf(*ci_ins->accessTypeFunctions);\n";
|
||||
ts << "\tauto & ci_aof(*ci_ins->accessOffsetFunctions);\n";
|
||||
}
|
||||
if (meta) {
|
||||
ts << "\n// Classes clean\n";
|
||||
@@ -146,6 +154,7 @@ bool writeModel(PICodeParser & parser,
|
||||
if (e->is_anonymous || e->name.startsWith("_PI")) continue;
|
||||
ts << "\tci_avf.remove(\"" << e->name << "\");\n";
|
||||
ts << "\tci_atf.remove(\"" << e->name << "\");\n";
|
||||
ts << "\tci_aof.remove(\"" << e->name << "\");\n";
|
||||
}
|
||||
}
|
||||
ts << "}\n";
|
||||
|
||||
Reference in New Issue
Block a user