/* 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 . */ #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 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 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 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; }