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:
@@ -5,8 +5,8 @@ if (POLICY CMP0177)
|
||||
endif()
|
||||
project(PIP)
|
||||
set(PIP_MAJOR 5)
|
||||
set(PIP_MINOR 2)
|
||||
set(PIP_REVISION 1)
|
||||
set(PIP_MINOR 3)
|
||||
set(PIP_REVISION 0)
|
||||
set(PIP_SUFFIX )
|
||||
set(PIP_COMPANY SHS)
|
||||
set(PIP_DOMAIN org.SHS)
|
||||
|
||||
@@ -55,11 +55,12 @@ PIVariant PICodeInfo::getMemberAsVariant(const void * p, const char * class_name
|
||||
|
||||
|
||||
PICodeInfo::__Storage__::__Storage__() {
|
||||
classesInfo = new PIMap<PIConstChars, ClassInfo *>;
|
||||
enumsInfo = new PIMap<PIConstChars, EnumInfo *>;
|
||||
accessValueFunctions = new PIMap<PIConstChars, AccessValueFunction>;
|
||||
accessTypeFunctions = new PIMap<PIConstChars, AccessTypeFunction>;
|
||||
(*enumsInfo)[""] = new EnumInfo();
|
||||
classesInfo = new PIMap<PIConstChars, ClassInfo *>;
|
||||
enumsInfo = new PIMap<PIConstChars, EnumInfo *>;
|
||||
accessValueFunctions = new PIMap<PIConstChars, AccessValueFunction>;
|
||||
accessTypeFunctions = new PIMap<PIConstChars, AccessTypeFunction>;
|
||||
accessOffsetFunctions = new PIMap<PIConstChars, AccessOffsetFunction>;
|
||||
(*enumsInfo)[""] = new EnumInfo();
|
||||
}
|
||||
|
||||
|
||||
@@ -70,6 +71,7 @@ PICodeInfo::__Storage__::~__Storage__() {
|
||||
piDeleteSafety(enumsInfo);
|
||||
piDeleteSafety(accessValueFunctions);
|
||||
piDeleteSafety(accessTypeFunctions);
|
||||
piDeleteSafety(accessOffsetFunctions);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -58,6 +58,7 @@ typedef PIFlags<PICodeInfo::TypeFlag> TypeFlags;
|
||||
typedef PIMap<PIString, PIString> MetaMap;
|
||||
typedef PIByteArray (*AccessValueFunction)(const void *, const char *);
|
||||
typedef const char * (*AccessTypeFunction)(const char *);
|
||||
typedef int (*AccessOffsetFunction)(const char *);
|
||||
|
||||
|
||||
//! \~english Type information
|
||||
@@ -289,6 +290,7 @@ public:
|
||||
PIMap<PIConstChars, PICodeInfo::EnumInfo *> * enumsInfo;
|
||||
PIMap<PIConstChars, PICodeInfo::AccessValueFunction> * accessValueFunctions;
|
||||
PIMap<PIConstChars, PICodeInfo::AccessTypeFunction> * accessTypeFunctions;
|
||||
PIMap<PIConstChars, PICodeInfo::AccessOffsetFunction> * accessOffsetFunctions;
|
||||
|
||||
private:
|
||||
NO_COPY_CLASS(__Storage__)
|
||||
@@ -314,6 +316,10 @@ static const PIMap<PIConstChars, PICodeInfo::AccessValueFunction> & accessValueF
|
||||
static const PIMap<PIConstChars, PICodeInfo::AccessTypeFunction> & accessTypeFunctions() {
|
||||
return *(__Storage__::instance()->accessTypeFunctions);
|
||||
}
|
||||
|
||||
static const PIMap<PIConstChars, PICodeInfo::AccessOffsetFunction> & accessOffsetFunctions() {
|
||||
return *(__Storage__::instance()->accessOffsetFunctions);
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
@@ -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