add offset generation in pip_cmg for retrieve bytes offset of struct member add pip_cmg -V doc
122 lines
4.3 KiB
C++
122 lines
4.3 KiB
C++
/*
|
|
PIP - Platform Independent Primitives
|
|
Code model generator
|
|
Ivan Pelipenko peri4ko@yandex.ru
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU Lesser General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "getter.h"
|
|
|
|
#include "stream.h"
|
|
|
|
|
|
void writeGetterTypeMembers(Runtime & rt, const PICodeParser::Entity * e, 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.visibility != PICodeParser::Public)) continue;
|
|
auto type = findEntity(rt, m.type);
|
|
if (type) {
|
|
if (type->is_anonymous) {
|
|
writeGetterTypeMembers(rt, type, var_prefix + m.name);
|
|
continue;
|
|
}
|
|
}
|
|
rt.ts << "\tif (strcmp(name, \"" << var_prefix << m.name << "\") == 0) return \"" << m.type;
|
|
// if (m.isBitfield()) rt.ts << ":" << m.bits;
|
|
rt.ts << "\";\n";
|
|
}
|
|
}
|
|
|
|
|
|
void writeGetterValueMembers(Runtime & rt, const PICodeParser::Entity * e, 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.visibility != PICodeParser::Public)) continue;
|
|
auto type = findEntity(rt, m.type);
|
|
if (type) {
|
|
if (type->is_anonymous) {
|
|
writeGetterValueMembers(rt, type, var_prefix + m.name);
|
|
continue;
|
|
}
|
|
}
|
|
rt.ts << "\tif (strcmp(name, \"" << var_prefix << m.name << "\") == 0) {";
|
|
if (m.isBitfield()) {
|
|
rt.ts << "ret = piSerialize(static_cast<" << m.type << ">(o->" << var_prefix << m.name << "));";
|
|
} else
|
|
rt.ts << "serialize(ret, o->" << var_prefix << m.name << ");";
|
|
rt.ts << " return ret;}\n";
|
|
}
|
|
}
|
|
|
|
|
|
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 (!needClassGetter(e)) return;
|
|
rt.ts << "\nconst char * getterType" << toCName(e->name) << "(const char * name) {\n";
|
|
rt.ts << "\tif (!name) return \"\";\n";
|
|
writeGetterTypeMembers(rt, e);
|
|
rt.ts << "\treturn \"\";\n}\n";
|
|
}
|
|
|
|
|
|
void makeGetterValue(Runtime & rt, const PICodeParser::Entity * e) {
|
|
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";
|
|
rt.ts << "\t" << e->name << " * o = (" << e->name << "*)p;\n";
|
|
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;
|
|
}
|