diff --git a/CMakeLists.txt b/CMakeLists.txt index d1491cf5..cd352a25 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) diff --git a/libs/main/code/picodeinfo.cpp b/libs/main/code/picodeinfo.cpp index 7ecb800e..2c7990b7 100644 --- a/libs/main/code/picodeinfo.cpp +++ b/libs/main/code/picodeinfo.cpp @@ -55,11 +55,12 @@ PIVariant PICodeInfo::getMemberAsVariant(const void * p, const char * class_name PICodeInfo::__Storage__::__Storage__() { - classesInfo = new PIMap; - enumsInfo = new PIMap; - accessValueFunctions = new PIMap; - accessTypeFunctions = new PIMap; - (*enumsInfo)[""] = new EnumInfo(); + classesInfo = new PIMap; + enumsInfo = new PIMap; + accessValueFunctions = new PIMap; + accessTypeFunctions = new PIMap; + accessOffsetFunctions = new PIMap; + (*enumsInfo)[""] = new EnumInfo(); } @@ -70,6 +71,7 @@ PICodeInfo::__Storage__::~__Storage__() { piDeleteSafety(enumsInfo); piDeleteSafety(accessValueFunctions); piDeleteSafety(accessTypeFunctions); + piDeleteSafety(accessOffsetFunctions); } diff --git a/libs/main/code/picodeinfo.h b/libs/main/code/picodeinfo.h index 6936493a..96c275ae 100644 --- a/libs/main/code/picodeinfo.h +++ b/libs/main/code/picodeinfo.h @@ -58,6 +58,7 @@ typedef PIFlags TypeFlags; typedef PIMap MetaMap; typedef PIByteArray (*AccessValueFunction)(const void *, const char *); typedef const char * (*AccessTypeFunction)(const char *); +typedef int (*AccessOffsetFunction)(const char *); //! \~english Type information @@ -120,15 +121,15 @@ struct PIP_EXPORT FunctionInfo { //! \~english Class or struct information //! \~russian Информация о классе или структуре struct PIP_EXPORT ClassInfo { - ClassInfo() { has_name = true; } + ClassInfo() { is_anonymous = false; } //! \~english Custom PIMETA content //! \~russian Произвольное содержимое PIMETA MetaMap meta; - //! \~english Has name or not - //! \~russian Имеет или нет имя - bool has_name; + //! \~english Anonymous or not + //! \~russian Анонимный или нет + bool is_anonymous; //! \~english Type //! \~russian Тип @@ -289,66 +290,77 @@ public: PIMap * enumsInfo; PIMap * accessValueFunctions; PIMap * accessTypeFunctions; + PIMap * accessOffsetFunctions; private: NO_COPY_CLASS(__Storage__) }; -class PIP_EXPORT __StorageAccess__ { -public: - //! \~english Getter for single storage of PICodeInfo::ClassInfo, access by name - //! \~russian Доступ к единому хранилищу PICodeInfo::ClassInfo, доступ по имени - static const PIMap & classes() { return *(__Storage__::instance()->classesInfo); } +class PIP_EXPORT +__StorageAccess__{public: + //! \~english Getter for single storage of PICodeInfo::ClassInfo, access by name + //! \~russian Доступ к единому хранилищу PICodeInfo::ClassInfo, доступ по имени + static const PIMap & classes(){return *(__Storage__::instance()->classesInfo); +} // namespace PICodeInfo - //! \~english Getter for single storage of PICodeInfo::EnumInfo, access by name - //! \~russian Доступ к единому хранилищу хранилище PICodeInfo::EnumInfo, доступ по имени - static const PIMap & enums() { return *(__Storage__::instance()->enumsInfo); } +//! \~english Getter for single storage of PICodeInfo::EnumInfo, access by name +//! \~russian Доступ к единому хранилищу хранилище PICodeInfo::EnumInfo, доступ по имени +static const PIMap & enums() { + return *(__Storage__::instance()->enumsInfo); +} - static const PIMap & accessValueFunctions() { - return *(__Storage__::instance()->accessValueFunctions); - } +static const PIMap & accessValueFunctions() { + return *(__Storage__::instance()->accessValueFunctions); +} - static const PIMap & accessTypeFunctions() { - return *(__Storage__::instance()->accessTypeFunctions); - } -}; +static const PIMap & accessTypeFunctions() { + return *(__Storage__::instance()->accessTypeFunctions); +} + +static const PIMap & accessOffsetFunctions() { + return *(__Storage__::instance()->accessOffsetFunctions); +} +} +; #define PICODEINFO PICodeInfo::__StorageAccess__ -class PIP_EXPORT ClassInfoInterface { -public: - const PIMap * operator->() const DEPRECATEDM("use PICODEINFO::classes()") { - return __Storage__::instance()->classesInfo; - } -}; +class PIP_EXPORT +ClassInfoInterface{public: const PIMap * operator->() const DEPRECATEDM("use PICODEINFO::classes()"){ + return __Storage__::instance() -> classesInfo; +} +} +; static ClassInfoInterface classesInfo; -class PIP_EXPORT EnumsInfoInterface { -public: - const PIMap * operator->() const DEPRECATEDM("use PICODEINFO::enums()") { - return __Storage__::instance()->enumsInfo; - } -}; +class PIP_EXPORT +EnumsInfoInterface{public: const PIMap * operator->() const DEPRECATEDM("use PICODEINFO::enums()"){ + return __Storage__::instance() -> enumsInfo; +} +} +; static EnumsInfoInterface enumsInfo; -class PIP_EXPORT AccessValueFunctionInterface { -public: - const PIMap * operator->() const DEPRECATEDM("use PICODEINFO::accessValueFunctions()") { - return __Storage__::instance()->accessValueFunctions; - } -}; +class PIP_EXPORT AccessValueFunctionInterface{ + public: const PIMap * operator->() + const DEPRECATEDM("use PICODEINFO::accessValueFunctions()"){ + return __Storage__::instance() -> accessValueFunctions; +} +} +; static AccessValueFunctionInterface accessValueFunctions; -class PIP_EXPORT AccessTypeFunctionInterface { -public: - const PIMap * operator->() const DEPRECATEDM("use PICODEINFO::accessTypeFunctions()") { - return __Storage__::instance()->accessTypeFunctions; - } -}; +class PIP_EXPORT AccessTypeFunctionInterface{ + public: const PIMap * operator->() + const DEPRECATEDM("use PICODEINFO::accessTypeFunctions()"){ + return __Storage__::instance() -> accessTypeFunctions; +} +} +; static AccessTypeFunctionInterface accessTypeFunctions; diff --git a/libs/main/code/picodeparser.cpp b/libs/main/code/picodeparser.cpp index 4c0ca331..545059e3 100644 --- a/libs/main/code/picodeparser.cpp +++ b/libs/main/code/picodeparser.cpp @@ -19,6 +19,8 @@ #include "picodeparser.h" +#include "piliterals_string.h" + PIString PICodeParser::Macro::expand(PIString args_, bool * ok) const { PIStringList arg_vals; @@ -92,10 +94,10 @@ void PICodeParser::parseFile(const PIString & file, bool follow_includes) { if (c->parent_scope) piCout << "parent" << c->parent_scope->name; piCout << "Functions:"; - for (const auto & m: c->functions) + for (const auto & m: c->functions) piCout << m.type << m.name << m.meta; piCout << "Members:"; - for (const auto & m: c->members) + for (const auto & m: c->members) piCout << m.type << m.name << m.meta; } piCout << "\n\nDefines:"; @@ -108,7 +110,7 @@ void PICodeParser::parseFile(const PIString & file, bool follow_includes) { piCout << "\n\nEnums:"; for (const auto & c: enums) { piCout << PIStringAscii("enum") << c.name << c.meta; - for (const auto & e: c.members) + for (const auto & e: c.members) piCout << " " << e.name << '=' << e.value << e.meta; } piCout << "\n\nTypedefs:"; @@ -135,7 +137,7 @@ void PICodeParser::parseFiles(const PIStringList & files, bool follow_includes) piCout << PIStringAscii("enum") << c.name << c.members; piCout << "\n\nTypedefs:"; for (const auto & c: typedefs) - piCout << PIStringAscii("typedef") << c;*/ + piCout << PIStringAscii("typedef") << c;*/ } @@ -328,7 +330,7 @@ void PICodeParser::clear() { << "a2" << "n2" << "a3" - << "n3"); + << "n3"); } @@ -454,7 +456,7 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) { cur_namespace += pfc.takeCWord() + s_ns; ccmn = pfc.takeRange('{', '}'); // piCout << "namespace" << cur_namespace; - parseClass(0, ccmn, true); + parseClass(nullptr, ccmn, true); cur_namespace = prev_namespace; continue; } @@ -483,8 +485,8 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) { continue; } ccmn = pfc.left(dind) + s_bo + pfc.mid(dind).takeRange('{', '}') + s_bc; - pfc.remove(0, ccmn.size()); - parseClass(0, ccmn, false); + pfc.remove(0, ccmn.size() - 2); + parseClass(nullptr, ccmn, false); continue; } if (pfc.left(4) == s_enum) { @@ -499,17 +501,59 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) { meta << smeta; } // piCout << "pfc E" << cur_namespace << "," << tmp; - parseEnum(0, cur_namespace + tmp, pfc.takeRange('{', '}'), meta); + parseEnum(nullptr, cur_namespace + tmp, pfc.takeRange('{', '}'), meta); pfc.takeSymbol(); continue; } if (pfc.left(7) == s_typedef) { pfc.cutLeft(7); - typedefs << parseTypedef(pfc.takeLeft(pfc.find(';'))); - if (typedefs.back().first.isEmpty()) - typedefs.pop_back(); - else - root_.typedefs << typedefs.back(); + PIString typedef_type = pfc.takeCWord(); + if (typedef_type == s_class || typedef_type == s_struct || typedef_type == s_union) { + int dind = pfc.find('{', 0), find = pfc.find(';', 0); + if (dind < 0 && find < 0) { + pfc.cutLeft(6); + continue; + } + if (dind < 0 || find < dind) { + pfc.cutLeft(find + 1); + continue; + } + PIString cname = pfc.left(dind); + ccmn = cname + s_bo + pfc.mid(dind).takeRange('{', '}') + s_bc; + pfc.remove(0, ccmn.size() - 3); + if (cname.trimmed().isEmpty()) { + cname = pfc.takeCWord(); + ccmn.prepend(cname); + } + ccmn.prepend(typedef_type + " "_a); + parseClass(nullptr, ccmn, false); + } else if (typedef_type == s_enum) { + tmp = pfc.takeCWord(); + pfc.trim(); + MetaMap meta = maybeMeta(pfc); + if (tmp == s_class || tmp == s_struct) { + tmp = pfc.takeCWord(); + pfc.trim(); + MetaMap smeta = maybeMeta(pfc); + meta << smeta; + } + ccmn = pfc.takeRange('{', '}'); + if (tmp.isEmpty()) { + tmp = pfc.takeCWord(); + } + // piCout << "pfc E" << cur_namespace << "," << tmp; + parseEnum(nullptr, cur_namespace + tmp, ccmn, meta); + } else { + pfc.prepend(typedef_type); + } + PIString last = pfc.takeLeft(pfc.find(';')).trim(); + if (last.isNotEmpty()) { + typedefs << parseTypedef(last); + if (typedefs.back().first.isEmpty()) + typedefs.pop_back(); + else + root_.typedefs << typedefs.back(); + } pfc.takeSymbol(); continue; } @@ -567,24 +611,23 @@ PICodeParser::Entity * PICodeParser::parseClassDeclaration(const PIString & fc) Visibility vis = cur_def_vis; cur_def_vis = (is_class ? Private : Public); PIString cn = cd.mid(6).trim(); - bool has_name = !cn.isEmpty(); + bool is_anonymous = cn.isEmpty(); if (cn.isEmpty()) cn = PIStringAscii("'; // piCout << "found " << typename_ << cn; - if (cn.isEmpty()) return nullptr; - Entity * e = new Entity(); - e->meta = meta; - e->name = cur_namespace + cn; - e->type = typename_; - e->has_name = has_name; - e->parents = parents; - e->visibility = vis; - e->file = cur_file; + Entity * e = new Entity(); + e->meta = meta; + e->name = cur_namespace + cn; + e->type = typename_; + e->is_anonymous = is_anonymous; + e->parents = parents; + e->visibility = vis; + e->file = cur_file; entities << e; return e; } -void PICodeParser::parseClass(Entity * parent, PIString & fc, bool is_namespace) { +PICodeParser::Entity * PICodeParser::parseClass(Entity * parent, PIString & fc, bool is_namespace) { static const PIString s_ns = PIStringAscii("::"); static const PIString s_public = PIStringAscii("public"); static const PIString s_protected = PIStringAscii("protected"); @@ -599,7 +642,7 @@ void PICodeParser::parseClass(Entity * parent, PIString & fc, bool is_namespace) static const PIString s_template = PIStringAscii("template"); Visibility prev_vis = cur_def_vis; int dind = fc.find('{'), find = fc.find(';'), end = 0; - if (dind < 0 && find < 0) return; + if (dind < 0 && find < 0) return nullptr; // piCout << "parse class <****\n" << fc << "\n****>"; Entity * ce = parent; if (!is_namespace) { @@ -608,7 +651,6 @@ void PICodeParser::parseClass(Entity * parent, PIString & fc, bool is_namespace) } // piCout << "found class <****\n" << fc << "\n****>"; if (ce) { - if (parent) parent->children << ce; ce->parent_scope = parent; } int ps = -1; @@ -650,11 +692,29 @@ void PICodeParser::parseClass(Entity * parent, PIString & fc, bool is_namespace) fc.takeSymbol(); continue; } - tmp = fc.takeLeft(fc.find('{')); - stmp = fc.takeRange('{', '}'); - fc.takeSymbol(); - stmp = cw + ' ' + tmp + '{' + stmp + '}'; - parseClass(ce, stmp, false); + tmp = fc.takeLeft(fc.find('{')).trim(); + stmp = fc.takeRange('{', '}'); + stmp = cw + ' ' + tmp + '{' + stmp + '}'; + auto new_entity = parseClass(ce, stmp, false); + // piCout << "!!! > \"" << fc << "\""; + PIStringList vars; + PIString var; + do { + var = fc.takeCWord(); + if (var.isNotEmpty()) vars << var; + if (fc.takeSymbol() == ";") break; + } while (var.isNotEmpty()); + if (new_entity) { + Member me; + me.visibility = cur_def_vis; + me.type = new_entity->name; + if (tmp.isEmpty() && vars.isEmpty()) vars = {""}; + for (const auto & v: vars) { + me.name = v; + ce->members << me; + } + } + // piCout << "!!! <" << vars; continue; } if (cw == s_enum) { @@ -710,6 +770,7 @@ void PICodeParser::parseClass(Entity * parent, PIString & fc, bool is_namespace) } cur_def_vis = prev_vis; cur_namespace = prev_namespace; + return ce; } @@ -766,7 +827,7 @@ bool PICodeParser::parseEnum(Entity * parent, const PIString & name, PIString fc PICodeParser::Typedef PICodeParser::parseTypedef(PIString fc) { - // piCout << "parse typedef" << fc; + // piCout << "parse typedef \"" << fc << "\""; Typedef td; fc.replaceAll('\t', ' '); @@ -1197,7 +1258,7 @@ void PICodeParser::replaceMeta(PIString & dn) { PICodeParser::Entity * PICodeParser::findEntityByName(const PIString & en) { for (auto * e: entities) if (e->name == en) return e; - return 0; + return nullptr; } diff --git a/libs/main/code/picodeparser.h b/libs/main/code/picodeparser.h index e9aea9e6..5444f569 100644 --- a/libs/main/code/picodeparser.h +++ b/libs/main/code/picodeparser.h @@ -100,7 +100,7 @@ public: struct PIP_EXPORT Entity { Entity() { visibility = Global; - has_name = true; + is_anonymous = false; size = 0; parent_scope = 0; } @@ -110,10 +110,9 @@ public: PIString file; Visibility visibility; int size; - bool has_name; + bool is_anonymous; Entity * parent_scope; PIVector parents; - PIVector children; PIVector functions; PIVector members; PIVector typedefs; @@ -164,7 +163,7 @@ private: bool parseFileContent(PIString & fc, bool main); bool parseDirective(PIString d); Entity * parseClassDeclaration(const PIString & fc); - void parseClass(Entity * parent, PIString & fc, bool is_namespace); + Entity * parseClass(Entity * parent, PIString & fc, bool is_namespace); MetaMap parseMeta(PIString & fc); bool parseEnum(Entity * parent, const PIString & name, PIString fc, const MetaMap & meta); Typedef parseTypedef(PIString fc); diff --git a/libs/main/types/pivariant.cpp b/libs/main/types/pivariant.cpp index dddc0f2f..604d0714 100644 --- a/libs/main/types/pivariant.cpp +++ b/libs/main/types/pivariant.cpp @@ -225,17 +225,20 @@ bool PIVariant::operator==(const PIVariant & v) const { PIVariant::Type PIVariant::typeFromName(const PIString & tname) { PIString s = tname.trimmed().toLowerCase().replaceAll(" ", ""); if (s == "bool" || s == "boolean") return PIVariant::pivBool; - if (s == "char" || s == "sbyte") return PIVariant::pivChar; - if (s == "short" || s == "shortint" || s == "signedshort" || s == "signedshortint" || s == "sword") return PIVariant::pivShort; - if (s == "int" || s == "signed" || s == "signedint") return PIVariant::pivInt; + if (s == "char" || s == "sbyte" || s == "int8_t") return PIVariant::pivChar; + if (s == "short" || s == "shortint" || s == "signedshort" || s == "signedshortint" || s == "sword" || s == "int16_t") + return PIVariant::pivShort; + if (s == "int" || s == "signed" || s == "signedint" || s == "int32_t") return PIVariant::pivInt; if (s == "long" || s == "longint" || s == "signedlong" || s == "signedlongint" || s == "sdword") return PIVariant::pivInt; - if (s == "llong" || s == "longlong" || s == "longlongint" || s == "signedlonglong" || s == "signedlonglongint" || s == "sqword") + if (s == "llong" || s == "longlong" || s == "longlongint" || s == "signedlonglong" || s == "signedlonglongint" || s == "sqword" || + s == "int64_t") return PIVariant::pivLLong; - if (s == "uchar" || s == "byte") return PIVariant::pivUChar; - if (s == "ushort" || s == "unsignedshort" || s == "unsignedshortint" || s == "word") return PIVariant::pivUShort; - if (s == "uint" || s == "unsigned" || s == "unsignedint") return PIVariant::pivUInt; + if (s == "uchar" || s == "byte" || s == "uint8_t") return PIVariant::pivUChar; + if (s == "ushort" || s == "unsignedshort" || s == "unsignedshortint" || s == "word" || s == "uint16_t") return PIVariant::pivUShort; + if (s == "uint" || s == "unsigned" || s == "unsignedint" || s == "uint32_t") return PIVariant::pivUInt; if (s == "ulong" || s == "unsignedlong" || s == "unsignedlongint" || s == "dword") return PIVariant::pivUInt; - if (s == "ullong" || s == "unsignedlonglong" || s == "unsignedlonglongint" || s == "qword") return PIVariant::pivULLong; + if (s == "ullong" || s == "unsignedlonglong" || s == "unsignedlonglongint" || s == "qword" || s == "uint64_t") + return PIVariant::pivULLong; if (s == "float") return PIVariant::pivFloat; if (s == "double" || s == "real") return PIVariant::pivDouble; if (s == "ldouble" || s == "longdouble") return PIVariant::pivLDouble; diff --git a/utils/code_model_generator/common.cpp b/utils/code_model_generator/common.cpp index 94af3357..c2204632 100644 --- a/utils/code_model_generator/common.cpp +++ b/utils/code_model_generator/common.cpp @@ -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" ""; @@ -126,3 +134,8 @@ PIString toCName(const PIString & s) { ret.replaceAll("__", "_"); return ret; } + + +PICodeParser::Entity * findEntity(Runtime & rt, const PIString & type) { + return rt.parser.findEntityByName(type); +} diff --git a/utils/code_model_generator/common.h b/utils/code_model_generator/common.h index d91f92e4..4a509b6b 100644 --- a/utils/code_model_generator/common.h +++ b/utils/code_model_generator/common.h @@ -35,5 +35,6 @@ void usage(); void help(); PIString toCName(const PIString & s); +PICodeParser::Entity * findEntity(Runtime & rt, const PIString & type); #endif diff --git a/utils/code_model_generator/getter.cpp b/utils/code_model_generator/getter.cpp index 31f4d448..5f76f16c 100644 --- a/utils/code_model_generator/getter.cpp +++ b/utils/code_model_generator/getter.cpp @@ -22,27 +22,100 @@ #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 (!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"; - for (const PICodeParser::Member & m: e->members) { - if (m.is_type_ptr || m.isBitfield() || !m.dims.isEmpty() || (m.visibility != PICodeParser::Public)) continue; - rt.ts << "\tif (strcmp(name, \"" << m.name << "\") == 0) return \"" << m.type << "\";\n"; - } + writeGetterTypeMembers(rt, e); rt.ts << "\treturn \"\";\n}\n"; } 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"; rt.ts << "\t" << e->name << " * o = (" << e->name << "*)p;\n"; - for (const PICodeParser::Member & m: e->members) { - if (m.is_type_ptr || m.isBitfield() || !m.dims.isEmpty() || (m.visibility != PICodeParser::Public)) continue; - rt.ts << "\tif (strcmp(name, \"" << m.name << "\") == 0) {serialize(ret, o->" << m.name << "); return ret;}\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; +} diff --git a/utils/code_model_generator/getter.h b/utils/code_model_generator/getter.h index 58b68c5f..1e34d770 100644 --- a/utils/code_model_generator/getter.h +++ b/utils/code_model_generator/getter.h @@ -22,7 +22,12 @@ #include "common.h" +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 diff --git a/utils/code_model_generator/json.cpp b/utils/code_model_generator/json.cpp index 5c08753f..16ae6b97 100644 --- a/utils/code_model_generator/json.cpp +++ b/utils/code_model_generator/json.cpp @@ -22,7 +22,8 @@ #include "pitranslator.h" -bool writeClassJSONMembersOut(Runtime & rt, const PICodeParser::Entity * e) { +bool writeClassJSONMembersOut(Runtime & rt, const PICodeParser::Entity * e, PIString var_prefix) { + if (var_prefix.isNotEmpty() && !var_prefix.endsWith('.')) var_prefix += "."; PIVector ml; for (const PICodeParser::Member & m: e->members) { if (m.is_type_ptr || (m.visibility != PICodeParser::Public)) continue; @@ -30,12 +31,19 @@ bool writeClassJSONMembersOut(Runtime & rt, const PICodeParser::Entity * e) { } bool is_union = e->type == "union"; for (const PICodeParser::Member & m: ml) { - if (is_union && m.isBitfield()) continue; + if (m.isBitfield()) continue; if (m.attributes[PICodeParser::Static]) continue; if (m.meta.value("id") == "-") continue; // if (m.meta.contains("id")) cnt = m.meta.value("id").toInt(); + auto type = findEntity(rt, m.type); + if (type) { + if (type->is_anonymous) { + writeClassJSONMembersOut(rt, type, var_prefix + m.name); + continue; + } + } if (m.dims.isEmpty()) { - rt.ts << "\tret[\"" << m.name << "\"] = piSerializeJSON(v." << m.name << ");\n"; + rt.ts << "\tret[\"" << var_prefix << m.name << "\"] = piSerializeJSON(v." << var_prefix << m.name << ");\n"; } else { PIString ptype = m.type.left(m.type.find('[')).trim(); PIString size = m.dims[0]; @@ -43,21 +51,22 @@ bool writeClassJSONMembersOut(Runtime & rt, const PICodeParser::Entity * e) { size += " * "; size += m.dims[i]; } - rt.ts << "\tret[\"" << m.name << "\"] = piSerializeJSON(PIVector<" << ptype << " >((const " << ptype << " *)(v." << m.name - << "), " << size << "));\n"; + rt.ts << "\tret[\"" << var_prefix << m.name << "\"] = piSerializeJSON(PIVector<" << ptype << " >((const " << ptype << " *)(v." + << var_prefix << m.name << "), " << size << "));\n"; } if (is_union) break; } if (is_union) return true; - for (const PICodeParser::Entity * ce: e->children) { - if (ce->has_name) continue; + /*for (const PICodeParser::Entity * ce: e->children) { + if (!ce->is_anonymous) continue; if (!writeClassJSONMembersOut(rt, ce)) return false; - } + }*/ return true; } -bool writeClassJSONMembersIn(Runtime & rt, const PICodeParser::Entity * e) { +bool writeClassJSONMembersIn(Runtime & rt, const PICodeParser::Entity * e, PIString var_prefix) { + if (var_prefix.isNotEmpty() && !var_prefix.endsWith('.')) var_prefix += "."; PIVector ml; for (const PICodeParser::Member & m: e->members) { if (m.is_type_ptr || (m.visibility != PICodeParser::Public)) continue; @@ -66,12 +75,19 @@ bool writeClassJSONMembersIn(Runtime & rt, const PICodeParser::Entity * e) { bool is_union = e->type == "union"; PISet used_id; for (const PICodeParser::Member & m: ml) { - if (is_union && m.isBitfield()) continue; + if (m.isBitfield()) continue; if (m.attributes[PICodeParser::Static]) continue; if (m.meta.value("id") == "-") continue; + auto type = findEntity(rt, m.type); + if (type) { + if (type->is_anonymous) { + writeClassJSONMembersIn(rt, type, var_prefix + m.name); + continue; + } + } // if (m.meta.contains("id")) cnt = m.meta.value("id").toInt(); if (m.dims.isEmpty()) { - rt.ts << "\tpiDeserializeJSON(v." << m.name << ", js[\"" << m.name << "\"]);\n"; + rt.ts << "\tpiDeserializeJSON(v." << var_prefix << m.name << ", js[\"" << var_prefix << m.name << "\"]);\n"; } else { PIString ptype = m.type.left(m.type.find('[')).trim(); PIString size = m.dims[0]; @@ -80,19 +96,19 @@ bool writeClassJSONMembersIn(Runtime & rt, const PICodeParser::Entity * e) { size += m.dims[i]; } rt.ts << "\t{\n\t\tPIVector<" << ptype << " > d;\n"; - rt.ts << "\t\tpiDeserializeJSON(d, js[\"" << m.name << "\"]);\n"; + rt.ts << "\t\tpiDeserializeJSON(d, js[\"" << var_prefix << m.name << "\"]);\n"; rt.ts << "\t\tint cnt = piMini(d.size_s(), " << size << ");\n"; rt.ts << "\t\tfor (int i = 0; i < cnt; ++i)\n"; - rt.ts << "\t\t\t((" << ptype << " *)(v." << m.name << "))[i] = d[i];\n"; + rt.ts << "\t\t\t((" << ptype << " *)(v." << var_prefix << m.name << "))[i] = d[i];\n"; rt.ts << "\t}\n"; } if (is_union) break; } if (is_union) return true; - for (const PICodeParser::Entity * ce: e->children) { - if (ce->has_name) continue; + /*for (const PICodeParser::Entity * ce: e->children) { + if (!ce->is_anonymous) continue; if (!writeClassJSONMembersIn(rt, ce)) return false; - } + }*/ return true; } diff --git a/utils/code_model_generator/json.h b/utils/code_model_generator/json.h index 9b206040..e187f1c2 100644 --- a/utils/code_model_generator/json.h +++ b/utils/code_model_generator/json.h @@ -22,8 +22,8 @@ #include "common.h" -bool writeClassJSONMembersOut(Runtime & rt, const PICodeParser::Entity * e); -bool writeClassJSONMembersIn(Runtime & rt, const PICodeParser::Entity * e); +bool writeClassJSONMembersOut(Runtime & rt, const PICodeParser::Entity * e, PIString var_prefix = {}); +bool writeClassJSONMembersIn(Runtime & rt, const PICodeParser::Entity * e, PIString var_prefix = {}); bool needClassJSON(const PICodeParser::Entity * e); bool makeClassJSON(Runtime & rt, const PICodeParser::Entity * e); diff --git a/utils/code_model_generator/main.cpp b/utils/code_model_generator/main.cpp index c3bf2d93..1240c760 100755 --- a/utils/code_model_generator/main.cpp +++ b/utils/code_model_generator/main.cpp @@ -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(&reinterpret_cast((((type " + "*)nullptr)->member)))\n"; for (const PICodeParser::Entity * e: parser.entities) { - if (!e->has_name || e->name.startsWith("_PI")) continue; + 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) { @@ -95,7 +100,7 @@ bool writeModel(PICodeParser & parser, if (meta) { ts << "\n\n// Classes\n"; for (const PICodeParser::Entity * e: parser.entities) { - if (e->name.startsWith("_PI")) continue; + if (e->name.startsWith("_PI") || e->is_anonymous) continue; makeClassInfo(rt, e); } } @@ -108,9 +113,11 @@ bool writeModel(PICodeParser & parser, ts << "\n// Getters\n"; for (const PICodeParser::Entity * e: parser.entities) { if (!needClassStream(e)) continue; - if (!e->has_name || 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"; + if (e->is_anonymous || e->name.startsWith("_PI")) continue; + 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,11 +128,12 @@ 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"; for (const PICodeParser::Entity * e: parser.entities) { - if (e->name.startsWith("_PI")) continue; + if (e->name.startsWith("_PI") || e->is_anonymous) continue; ts << "\tpiDeleteSafety(ci_ci[\"" << e->name << "\"]);\n"; ts << "\tci_ins->classesInfo->remove(\"" << e->name << "\");\n"; } @@ -143,9 +151,10 @@ bool writeModel(PICodeParser & parser, ts << "\n// Getters clean\n"; for (const PICodeParser::Entity * e: parser.entities) { if (!needClassStream(e)) continue; - if (!e->has_name || e->name.startsWith("_PI")) continue; + 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"; @@ -173,7 +182,7 @@ bool writeModel(PICodeParser & parser, if (streams) { ts << "\n\n// Stream operators\n"; for (const PICodeParser::Entity * e: parser.entities) { - if (!e->has_name || e->name.startsWith("_PI") || + if (e->is_anonymous || e->name.startsWith("_PI") || !(e->visibility == PICodeParser::Global || e->visibility == PICodeParser::Public)) continue; if (!makeClassStream(rt, e)) return false; @@ -182,7 +191,7 @@ bool writeModel(PICodeParser & parser, if (json) { ts << "\n\n// JSON serialization\n"; for (const PICodeParser::Entity * e: parser.entities) { - if (!e->has_name || e->name.startsWith("_PI") || + if (e->is_anonymous || e->name.startsWith("_PI") || !(e->visibility == PICodeParser::Global || e->visibility == PICodeParser::Public)) continue; if (!makeClassJSON(rt, e)) return false; diff --git a/utils/code_model_generator/metainfo.cpp b/utils/code_model_generator/metainfo.cpp index bd6c5d2a..c7664d7c 100644 --- a/utils/code_model_generator/metainfo.cpp +++ b/utils/code_model_generator/metainfo.cpp @@ -20,27 +20,17 @@ #include "metainfo.h" -void makeClassInfo(Runtime & rt, const PICodeParser::Entity * e) { - rt.ts << "\n\t{\n\tClassInfo * ci = new ClassInfo();\n"; - rt.ts << "\tci->type = \"" << e->type << "\";\n"; - rt.ts << "\tci->name = \"" << e->name << "\";\n"; - rt.ts << "\tci->has_name = " << (e->has_name ? "true" : "false") << ";\n"; - if (!e->meta.isEmpty()) { - auto i = e->meta.makeIterator(); - while (i.next()) - rt.ts << "\tci->meta[\"" << i.key() << "\"] = PIString::fromUTF8(\"" << i.value() << "\");\n"; - } - rt.ts << "\tci_ci[ci->name] = ci;\n"; - if (e->parent_scope) { - rt.ts << "\tpci = " - << "ci_ci.value(\"" << e->parent_scope->name << "\", 0);\n"; - rt.ts << "\tif (pci) pci->children_info << ci;\n"; - } - for (const PICodeParser::Entity * p: e->parents) - rt.ts << "\tci->parents << \"" << p->name << "\";\n"; - if (!e->members.isEmpty()) rt.ts << "\n\tTypeInfo ti;\n"; +void writeClassInfoMembers(Runtime & rt, const PICodeParser::Entity * e, PIString var_prefix) { + if (var_prefix.isNotEmpty() && !var_prefix.endsWith('.')) var_prefix += "."; for (const PICodeParser::Member & m: e->members) { - rt.ts << "\tti = TypeInfo(\"" << m.name << "\", \"" << m.type << "\""; + auto type = findEntity(rt, m.type); + if (type) { + if (type->is_anonymous) { + writeClassInfoMembers(rt, type, var_prefix + m.name); + continue; + } + } + rt.ts << "\tti = TypeInfo(\"" << var_prefix << m.name << "\", \"" << m.type << "\""; if (m.attributes != 0) { bool fir = true; rt.ts << ", "; @@ -97,6 +87,29 @@ void makeClassInfo(Runtime & rt, const PICodeParser::Entity * e) { } rt.ts << "\tci->variables << ti;\n"; } +} + + +void makeClassInfo(Runtime & rt, const PICodeParser::Entity * e) { + rt.ts << "\n\t{\n\tClassInfo * ci = new ClassInfo();\n"; + rt.ts << "\tci->type = \"" << e->type << "\";\n"; + rt.ts << "\tci->name = \"" << e->name << "\";\n"; + // rt.ts << "\tci->is_anonymous = " << (e->is_anonymous ? "true" : "false") << ";\n"; + if (!e->meta.isEmpty()) { + auto i = e->meta.makeIterator(); + while (i.next()) + rt.ts << "\tci->meta[\"" << i.key() << "\"] = PIString::fromUTF8(\"" << i.value() << "\");\n"; + } + rt.ts << "\tci_ci[ci->name] = ci;\n"; + if (e->parent_scope) { + rt.ts << "\tpci = " + << "ci_ci.value(\"" << e->parent_scope->name << "\", 0);\n"; + rt.ts << "\tif (pci) pci->children_info << ci;\n"; + } + for (const PICodeParser::Entity * p: e->parents) + rt.ts << "\tci->parents << \"" << p->name << "\";\n"; + if (!e->members.isEmpty()) rt.ts << "\n\tTypeInfo ti;\n"; + writeClassInfoMembers(rt, e); PIString arg; bool has_fi = false; for (const PICodeParser::Member & m: e->functions) { diff --git a/utils/code_model_generator/metainfo.h b/utils/code_model_generator/metainfo.h index 127a52b9..cf6e7f93 100644 --- a/utils/code_model_generator/metainfo.h +++ b/utils/code_model_generator/metainfo.h @@ -22,6 +22,7 @@ #include "common.h" +void writeClassInfoMembers(Runtime & rt, const PICodeParser::Entity * e, PIString var_prefix = {}); void makeClassInfo(Runtime & rt, const PICodeParser::Entity * e); #endif diff --git a/utils/code_model_generator/stream.cpp b/utils/code_model_generator/stream.cpp index 3439d4d1..f560d29e 100644 --- a/utils/code_model_generator/stream.cpp +++ b/utils/code_model_generator/stream.cpp @@ -22,7 +22,8 @@ #include "pitranslator.h" -bool writeClassStreamMembersOut(Runtime & rt, const PICodeParser::Entity * e, int & cnt, bool simple) { +bool writeClassStreamMembersOut(Runtime & rt, const PICodeParser::Entity * e, int & cnt, bool simple, PIString var_prefix) { + if (var_prefix.isNotEmpty() && !var_prefix.endsWith('.')) var_prefix += "."; PIVector ml; for (const PICodeParser::Member & m: e->members) { if (m.is_type_ptr || (m.visibility != PICodeParser::Public)) continue; @@ -31,9 +32,16 @@ bool writeClassStreamMembersOut(Runtime & rt, const PICodeParser::Entity * e, in bool is_union = e->type == "union"; PISet used_id; for (const PICodeParser::Member & m: ml) { - if (is_union && m.isBitfield()) continue; + if (m.isBitfield()) continue; if (m.attributes[PICodeParser::Static]) continue; if (m.meta.value("id") == "-") continue; + auto type = findEntity(rt, m.type); + if (type) { + if (type->is_anonymous) { + if (!writeClassStreamMembersOut(rt, type, cnt, simple, var_prefix + m.name)) return false; + continue; + } + } ++cnt; if (m.meta.contains("id")) cnt = m.meta.value("id").toInt(); if (used_id[cnt]) { @@ -44,11 +52,11 @@ bool writeClassStreamMembersOut(Runtime & rt, const PICodeParser::Entity * e, in if (simple) { rt.ts << "\ts << "; if (rt.parser.isEnum(m.type)) rt.ts << "(int)"; - rt.ts << "v." << m.name << ";\n"; + rt.ts << "v." << var_prefix << m.name << ";\n"; } else { rt.ts << "\tcs.add(" << cnt << ", "; if (rt.parser.isEnum(m.type)) rt.ts << "(int)"; - rt.ts << "v." << m.name << ");\n"; + rt.ts << "v." << var_prefix << m.name << ");\n"; } } else { PIString ptype = m.type.left(m.type.find('[')).trim(); @@ -59,24 +67,22 @@ bool writeClassStreamMembersOut(Runtime & rt, const PICodeParser::Entity * e, in } if (simple) { rt.ts << "\tfor (int i = 0; i < " << size << "; ++i)\n"; - rt.ts << "\t\ts << ((const " << ptype << " *)(v." << m.name << "))[i];\n"; + rt.ts << "\t\ts << ((const " << ptype << " *)(" << "v." << var_prefix << m.name << "))[i];\n"; } else { - rt.ts << "\tcs << cs.chunk(" << cnt << ", PIVector<" << ptype << " >((const " << ptype << " *)(v." << m.name << "), "; + rt.ts << "\tcs << cs.chunk(" << cnt << ", PIVector<" << ptype << " >((const " << ptype << " *)(" << "v." << var_prefix + << m.name << "), "; rt.ts << size << "));\n"; } } if (is_union) break; } if (is_union) return true; - for (const PICodeParser::Entity * ce: e->children) { - if (ce->has_name) continue; - if (!writeClassStreamMembersOut(rt, ce, cnt, simple)) return false; - } return true; } -bool writeClassStreamMembersIn(Runtime & rt, const PICodeParser::Entity * e, int & cnt, bool simple) { +bool writeClassStreamMembersIn(Runtime & rt, const PICodeParser::Entity * e, int & cnt, bool simple, PIString var_prefix) { + if (var_prefix.isNotEmpty() && !var_prefix.endsWith('.')) var_prefix += "."; PIVector ml; for (const PICodeParser::Member & m: e->members) { if (m.is_type_ptr || (m.visibility != PICodeParser::Public)) continue; @@ -85,9 +91,16 @@ bool writeClassStreamMembersIn(Runtime & rt, const PICodeParser::Entity * e, int bool is_union = e->type == "union"; PISet used_id; for (const PICodeParser::Member & m: ml) { - if (is_union && m.isBitfield()) continue; + if (m.isBitfield()) continue; if (m.attributes[PICodeParser::Static]) continue; if (m.meta.value("id") == "-") continue; + auto type = findEntity(rt, m.type); + if (type) { + if (type->is_anonymous) { + if (!writeClassStreamMembersIn(rt, type, cnt, simple, var_prefix + m.name)) return false; + continue; + } + } ++cnt; if (m.meta.contains("id")) cnt = m.meta.value("id").toInt(); if (used_id[cnt]) { @@ -104,8 +117,8 @@ bool writeClassStreamMembersIn(Runtime & rt, const PICodeParser::Entity * e, int if (is_enum) rt.ts << "i;"; else - rt.ts << "v." << m.name << ";"; - if (is_enum) rt.ts << " v." << m.name << " = (" << m.type << ")i;}"; + rt.ts << "v." << var_prefix << m.name << ";"; + if (is_enum) rt.ts << " v. << var_prefix" << m.name << " = (" << m.type << ")i;}"; rt.ts << "\n"; } else { rt.ts << "\t\tcase " << cnt << ":"; @@ -114,9 +127,9 @@ bool writeClassStreamMembersIn(Runtime & rt, const PICodeParser::Entity * e, int if (is_enum) rt.ts << "i"; else - rt.ts << "v." << m.name; + rt.ts << "v." << var_prefix << m.name; rt.ts << ");"; - if (is_enum) rt.ts << " v." << m.name << " = (" << m.type << ")i;}"; + if (is_enum) rt.ts << " v." << var_prefix << m.name << " = (" << m.type << ")i;}"; rt.ts << " break;\n"; } } else { @@ -128,12 +141,12 @@ bool writeClassStreamMembersIn(Runtime & rt, const PICodeParser::Entity * e, int } if (simple) { rt.ts << "\tfor (int i = 0; i < " << size << "; ++i)\n"; - rt.ts << "\t\ts >> ((" << ptype << " *)(v." << m.name << "))[i];\n"; + rt.ts << "\t\ts >> ((" << ptype << " *)(" << "v." << var_prefix << m.name << "))[i];\n"; } else { rt.ts << "\t\tcase " << cnt << ": {\n\t\t\tPIVector<" << ptype << " > d; cs.get(d);\n"; rt.ts << "\t\t\tint cnt = piMini(d.size_s(), " << size << ");\n"; rt.ts << "\t\t\tfor (int i = 0; i < cnt; ++i)\n"; - rt.ts << "\t\t\t\t((" << ptype << " *)(v." << m.name << "))[i] = d[i];\n"; + rt.ts << "\t\t\t\t((" << ptype << " *)(" << "v." << var_prefix << m.name << "))[i] = d[i];\n"; rt.ts << "\t\t\t}\n"; rt.ts << "\t\t\tbreak;\n"; } @@ -141,10 +154,6 @@ bool writeClassStreamMembersIn(Runtime & rt, const PICodeParser::Entity * e, int if (is_union) break; } if (is_union) return true; - for (const PICodeParser::Entity * ce: e->children) { - if (ce->has_name) continue; - if (!writeClassStreamMembersIn(rt, ce, cnt, simple)) return false; - } return true; } diff --git a/utils/code_model_generator/stream.h b/utils/code_model_generator/stream.h index 1de3dabe..171637ee 100644 --- a/utils/code_model_generator/stream.h +++ b/utils/code_model_generator/stream.h @@ -22,8 +22,8 @@ #include "common.h" -bool writeClassStreamMembersOut(Runtime & rt, const PICodeParser::Entity * e, int & cnt, bool simple); -bool writeClassStreamMembersIn(Runtime & rt, const PICodeParser::Entity * e, int & cnt, bool simple); +bool writeClassStreamMembersOut(Runtime & rt, const PICodeParser::Entity * e, int & cnt, bool simple, PIString var_prefix = {}); +bool writeClassStreamMembersIn(Runtime & rt, const PICodeParser::Entity * e, int & cnt, bool simple, PIString var_prefix = {}); bool needClassStream(const PICodeParser::Entity * e); bool makeClassStream(Runtime & rt, const PICodeParser::Entity * e);