summaryrefslogtreecommitdiffstats
path: root/src/tools/moc/generator.cpp
diff options
context:
space:
mode:
authorQt by Nokia <qt-info@nokia.com>2011-04-27 12:05:43 +0200
committeraxis <qt-info@nokia.com>2011-04-27 12:05:43 +0200
commit38be0d13830efd2d98281c645c3a60afe05ffece (patch)
tree6ea73f3ec77f7d153333779883e8120f82820abe /src/tools/moc/generator.cpp
Initial import from the monolithic Qt.
This is the beginning of revision history for this module. If you want to look at revision history older than this, please refer to the Qt Git wiki for how to use Git history grafting. At the time of writing, this wiki is located here: http://qt.gitorious.org/qt/pages/GitIntroductionWithQt If you have already performed the grafting and you don't see any history beyond this commit, try running "git log" with the "--follow" argument. Branched from the monolithic repo, Qt master branch, at commit 896db169ea224deb96c59ce8af800d019de63f12
Diffstat (limited to 'src/tools/moc/generator.cpp')
-rw-r--r--src/tools/moc/generator.cpp1333
1 files changed, 1333 insertions, 0 deletions
diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp
new file mode 100644
index 0000000000..aea156da18
--- /dev/null
+++ b/src/tools/moc/generator.cpp
@@ -0,0 +1,1333 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "generator.h"
+#include "outputrevision.h"
+#include "utils.h"
+#include <QtCore/qmetatype.h>
+#include <stdio.h>
+
+#include <private/qmetaobject_p.h> //for the flags.
+
+QT_BEGIN_NAMESPACE
+
+uint qvariant_nameToType(const char* name)
+{
+ if (!name)
+ return 0;
+
+ if (strcmp(name, "QVariant") == 0)
+ return 0xffffffff;
+ if (strcmp(name, "QCString") == 0)
+ return QMetaType::QByteArray;
+ if (strcmp(name, "Q_LLONG") == 0)
+ return QMetaType::LongLong;
+ if (strcmp(name, "Q_ULLONG") == 0)
+ return QMetaType::ULongLong;
+ if (strcmp(name, "QIconSet") == 0)
+ return QMetaType::QIcon;
+
+ uint tp = QMetaType::type(name);
+ return tp < QMetaType::User ? tp : 0;
+}
+
+/*
+ Returns true if the type is a QVariant types.
+*/
+bool isVariantType(const char* type)
+{
+ return qvariant_nameToType(type) != 0;
+}
+
+/*!
+ Returns true if the type is qreal.
+*/
+static bool isQRealType(const char *type)
+{
+ return strcmp(type, "qreal") == 0;
+}
+
+Generator::Generator(ClassDef *classDef, const QList<QByteArray> &metaTypes, FILE *outfile)
+ : out(outfile), cdef(classDef), metaTypes(metaTypes)
+{
+ if (cdef->superclassList.size())
+ purestSuperClass = cdef->superclassList.first().first;
+}
+
+static inline int lengthOfEscapeSequence(const QByteArray &s, int i)
+{
+ if (s.at(i) != '\\' || i >= s.length() - 1)
+ return 1;
+ const int startPos = i;
+ ++i;
+ char ch = s.at(i);
+ if (ch == 'x') {
+ ++i;
+ while (i < s.length() && is_hex_char(s.at(i)))
+ ++i;
+ } else if (is_octal_char(ch)) {
+ while (i < startPos + 4
+ && i < s.length()
+ && is_octal_char(s.at(i))) {
+ ++i;
+ }
+ } else { // single character escape sequence
+ i = qMin(i + 1, s.length());
+ }
+ return i - startPos;
+}
+
+int Generator::strreg(const char *s)
+{
+ int idx = 0;
+ if (!s)
+ s = "";
+ for (int i = 0; i < strings.size(); ++i) {
+ const QByteArray &str = strings.at(i);
+ if (str == s)
+ return idx;
+ idx += str.length() + 1;
+ for (int i = 0; i < str.length(); ++i) {
+ if (str.at(i) == '\\') {
+ int cnt = lengthOfEscapeSequence(str, i) - 1;
+ idx -= cnt;
+ i += cnt;
+ }
+ }
+ }
+ strings.append(s);
+ return idx;
+}
+
+void Generator::generateCode()
+{
+ bool isQt = (cdef->classname == "Qt");
+ bool isQObject = (cdef->classname == "QObject");
+ bool isConstructible = !cdef->constructorList.isEmpty();
+
+//
+// build the data array
+//
+ int i = 0;
+
+
+ // filter out undeclared enumerators and sets
+ {
+ QList<EnumDef> enumList;
+ for (i = 0; i < cdef->enumList.count(); ++i) {
+ EnumDef def = cdef->enumList.at(i);
+ if (cdef->enumDeclarations.contains(def.name)) {
+ enumList += def;
+ }
+ QByteArray alias = cdef->flagAliases.value(def.name);
+ if (cdef->enumDeclarations.contains(alias)) {
+ def.name = alias;
+ enumList += def;
+ }
+ }
+ cdef->enumList = enumList;
+ }
+
+
+ QByteArray qualifiedClassNameIdentifier = cdef->qualified;
+ qualifiedClassNameIdentifier.replace(':', '_');
+
+ int index = 14;
+ fprintf(out, "static const uint qt_meta_data_%s[] = {\n", qualifiedClassNameIdentifier.constData());
+ fprintf(out, "\n // content:\n");
+ fprintf(out, " %4d, // revision\n", 6);
+ fprintf(out, " %4d, // classname\n", strreg(cdef->qualified));
+ fprintf(out, " %4d, %4d, // classinfo\n", cdef->classInfoList.count(), cdef->classInfoList.count() ? index : 0);
+ index += cdef->classInfoList.count() * 2;
+
+ int methodCount = cdef->signalList.count() + cdef->slotList.count() + cdef->methodList.count();
+ fprintf(out, " %4d, %4d, // methods\n", methodCount, methodCount ? index : 0);
+ index += methodCount * 5;
+ if (cdef->revisionedMethods)
+ index += methodCount;
+ fprintf(out, " %4d, %4d, // properties\n", cdef->propertyList.count(), cdef->propertyList.count() ? index : 0);
+ index += cdef->propertyList.count() * 3;
+ if(cdef->notifyableProperties)
+ index += cdef->propertyList.count();
+ if (cdef->revisionedProperties)
+ index += cdef->propertyList.count();
+ fprintf(out, " %4d, %4d, // enums/sets\n", cdef->enumList.count(), cdef->enumList.count() ? index : 0);
+
+ int enumsIndex = index;
+ for (i = 0; i < cdef->enumList.count(); ++i)
+ index += 4 + (cdef->enumList.at(i).values.count() * 2);
+ fprintf(out, " %4d, %4d, // constructors\n", isConstructible ? cdef->constructorList.count() : 0,
+ isConstructible ? index : 0);
+
+ fprintf(out, " %4d, // flags\n", 0);
+ fprintf(out, " %4d, // signalCount\n", cdef->signalList.count());
+
+
+//
+// Build classinfo array
+//
+ generateClassInfos();
+
+//
+// Build signals array first, otherwise the signal indices would be wrong
+//
+ generateFunctions(cdef->signalList, "signal", MethodSignal);
+
+//
+// Build slots array
+//
+ generateFunctions(cdef->slotList, "slot", MethodSlot);
+
+//
+// Build method array
+//
+ generateFunctions(cdef->methodList, "method", MethodMethod);
+
+//
+// Build method version arrays
+//
+ if (cdef->revisionedMethods) {
+ generateFunctionRevisions(cdef->signalList, "signal");
+ generateFunctionRevisions(cdef->slotList, "slot");
+ generateFunctionRevisions(cdef->methodList, "method");
+ }
+
+//
+// Build property array
+//
+ generateProperties();
+
+//
+// Build enums array
+//
+ generateEnums(enumsIndex);
+
+//
+// Build constructors array
+//
+ if (isConstructible)
+ generateFunctions(cdef->constructorList, "constructor", MethodConstructor);
+
+//
+// Terminate data array
+//
+ fprintf(out, "\n 0 // eod\n};\n\n");
+
+//
+// Build stringdata array
+//
+ fprintf(out, "static const char qt_meta_stringdata_%s[] = {\n", qualifiedClassNameIdentifier.constData());
+ fprintf(out, " \"");
+ int col = 0;
+ int len = 0;
+ for (i = 0; i < strings.size(); ++i) {
+ QByteArray s = strings.at(i);
+ len = s.length();
+ if (col && col + len >= 72) {
+ fprintf(out, "\"\n \"");
+ col = 0;
+ } else if (len && s.at(0) >= '0' && s.at(0) <= '9') {
+ fprintf(out, "\"\"");
+ len += 2;
+ }
+ int idx = 0;
+ while (idx < s.length()) {
+ if (idx > 0) {
+ col = 0;
+ fprintf(out, "\"\n \"");
+ }
+ int spanLen = qMin(70, s.length() - idx);
+ // don't cut escape sequences at the end of a line
+ int backSlashPos = s.lastIndexOf('\\', idx + spanLen - 1);
+ if (backSlashPos >= idx) {
+ int escapeLen = lengthOfEscapeSequence(s, backSlashPos);
+ spanLen = qBound(spanLen, backSlashPos + escapeLen - idx, s.length() - idx);
+ }
+ fwrite(s.constData() + idx, 1, spanLen, out);
+ idx += spanLen;
+ col += spanLen;
+ }
+
+ fputs("\\0", out);
+ col += len + 2;
+ }
+ fprintf(out, "\"\n};\n\n");
+
+//
+// Generate internal qt_static_metacall() function
+//
+ if (cdef->hasQObject && !isQt)
+ generateStaticMetacall();
+
+//
+// Build extra array
+//
+ QList<QByteArray> extraList;
+ for (int i = 0; i < cdef->propertyList.count(); ++i) {
+ const PropertyDef &p = cdef->propertyList.at(i);
+ if (!isVariantType(p.type) && !metaTypes.contains(p.type) && !p.type.contains('*') &&
+ !p.type.contains('<') && !p.type.contains('>')) {
+ int s = p.type.lastIndexOf("::");
+ if (s > 0) {
+ QByteArray scope = p.type.left(s);
+ if (scope != "Qt" && scope != cdef->classname && !extraList.contains(scope))
+ extraList += scope;
+ }
+ }
+ }
+ if (!extraList.isEmpty()) {
+ fprintf(out, "#ifdef Q_NO_DATA_RELOCATION\n");
+ fprintf(out, "static const QMetaObjectAccessor qt_meta_extradata_%s[] = {\n ", qualifiedClassNameIdentifier.constData());
+ for (int i = 0; i < extraList.count(); ++i) {
+ fprintf(out, " %s::getStaticMetaObject,\n", extraList.at(i).constData());
+ }
+ fprintf(out, "#else\n");
+ fprintf(out, "static const QMetaObject *qt_meta_extradata_%s[] = {\n ", qualifiedClassNameIdentifier.constData());
+ for (int i = 0; i < extraList.count(); ++i) {
+ fprintf(out, " &%s::staticMetaObject,\n", extraList.at(i).constData());
+ }
+ fprintf(out, "#endif //Q_NO_DATA_RELOCATION\n");
+ fprintf(out, " 0\n};\n\n");
+ }
+
+ bool hasExtraData = (cdef->hasQObject && !isQt) || !extraList.isEmpty();
+ if (hasExtraData) {
+ fprintf(out, "const QMetaObjectExtraData %s::staticMetaObjectExtraData = {\n ",
+ cdef->qualified.constData());
+ if (extraList.isEmpty())
+ fprintf(out, "0, ");
+ else
+ fprintf(out, "qt_meta_extradata_%s, ", qualifiedClassNameIdentifier.constData());
+
+ if (cdef->hasQObject && !isQt)
+ fprintf(out, " qt_static_metacall");
+ else
+ fprintf(out, " 0");
+ fprintf(out, " \n};\n\n");
+ }
+
+//
+// Finally create and initialize the static meta object
+//
+ if (isQt)
+ fprintf(out, "const QMetaObject QObject::staticQtMetaObject = {\n");
+ else
+ fprintf(out, "const QMetaObject %s::staticMetaObject = {\n", cdef->qualified.constData());
+
+ if (isQObject)
+ fprintf(out, " { 0, ");
+ else if (cdef->superclassList.size())
+ fprintf(out, " { &%s::staticMetaObject, ", purestSuperClass.constData());
+ else
+ fprintf(out, " { 0, ");
+ fprintf(out, "qt_meta_stringdata_%s,\n qt_meta_data_%s, ",
+ qualifiedClassNameIdentifier.constData(), qualifiedClassNameIdentifier.constData());
+ if (!hasExtraData)
+ fprintf(out, "0 }\n");
+ else
+ fprintf(out, "&staticMetaObjectExtraData }\n");
+ fprintf(out, "};\n");
+
+ if(isQt)
+ return;
+
+//
+// Generate static meta object accessor (needed for symbian, because DLLs do not support data imports.
+//
+ fprintf(out, "\n#ifdef Q_NO_DATA_RELOCATION\n");
+ fprintf(out, "const QMetaObject &%s::getStaticMetaObject() { return staticMetaObject; }\n", cdef->qualified.constData());
+ fprintf(out, "#endif //Q_NO_DATA_RELOCATION\n");
+
+ if (!cdef->hasQObject)
+ return;
+
+ fprintf(out, "\nconst QMetaObject *%s::metaObject() const\n{\n return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject;\n}\n",
+ cdef->qualified.constData());
+
+//
+// Generate smart cast function
+//
+ fprintf(out, "\nvoid *%s::qt_metacast(const char *_clname)\n{\n", cdef->qualified.constData());
+ fprintf(out, " if (!_clname) return 0;\n");
+ fprintf(out, " if (!strcmp(_clname, qt_meta_stringdata_%s))\n"
+ " return static_cast<void*>(const_cast< %s*>(this));\n",
+ qualifiedClassNameIdentifier.constData(), cdef->classname.constData());
+ for (int i = 1; i < cdef->superclassList.size(); ++i) { // for all superclasses but the first one
+ if (cdef->superclassList.at(i).second == FunctionDef::Private)
+ continue;
+ const char *cname = cdef->superclassList.at(i).first;
+ fprintf(out, " if (!strcmp(_clname, \"%s\"))\n return static_cast< %s*>(const_cast< %s*>(this));\n",
+ cname, cname, cdef->classname.constData());
+ }
+ for (int i = 0; i < cdef->interfaceList.size(); ++i) {
+ const QList<ClassDef::Interface> &iface = cdef->interfaceList.at(i);
+ for (int j = 0; j < iface.size(); ++j) {
+ fprintf(out, " if (!strcmp(_clname, %s))\n return ", iface.at(j).interfaceId.constData());
+ for (int k = j; k >= 0; --k)
+ fprintf(out, "static_cast< %s*>(", iface.at(k).className.constData());
+ fprintf(out, "const_cast< %s*>(this)%s;\n",
+ cdef->classname.constData(), QByteArray(j+1, ')').constData());
+ }
+ }
+ if (!purestSuperClass.isEmpty() && !isQObject) {
+ QByteArray superClass = purestSuperClass;
+ // workaround for VC6
+ if (superClass.contains("::")) {
+ fprintf(out, " typedef %s QMocSuperClass;\n", superClass.constData());
+ superClass = "QMocSuperClass";
+ }
+ fprintf(out, " return %s::qt_metacast(_clname);\n", superClass.constData());
+ } else {
+ fprintf(out, " return 0;\n");
+ }
+ fprintf(out, "}\n");
+
+//
+// Generate internal qt_metacall() function
+//
+ generateMetacall();
+
+//
+// Generate internal signal functions
+//
+ for (int signalindex = 0; signalindex < cdef->signalList.size(); ++signalindex)
+ generateSignal(&cdef->signalList[signalindex], signalindex);
+}
+
+
+void Generator::generateClassInfos()
+{
+ if (cdef->classInfoList.isEmpty())
+ return;
+
+ fprintf(out, "\n // classinfo: key, value\n");
+
+ for (int i = 0; i < cdef->classInfoList.size(); ++i) {
+ const ClassInfoDef &c = cdef->classInfoList.at(i);
+ fprintf(out, " %4d, %4d,\n", strreg(c.name), strreg(c.value));
+ }
+}
+
+void Generator::generateFunctions(QList<FunctionDef>& list, const char *functype, int type)
+{
+ if (list.isEmpty())
+ return;
+ fprintf(out, "\n // %ss: signature, parameters, type, tag, flags\n", functype);
+
+ for (int i = 0; i < list.count(); ++i) {
+ const FunctionDef &f = list.at(i);
+
+ QByteArray sig = f.name + '(';
+ QByteArray arguments;
+
+ for (int j = 0; j < f.arguments.count(); ++j) {
+ const ArgumentDef &a = f.arguments.at(j);
+ if (j) {
+ sig += ",";
+ arguments += ",";
+ }
+ sig += a.normalizedType;
+ arguments += a.name;
+ }
+ sig += ')';
+
+ unsigned char flags = type;
+ if (f.access == FunctionDef::Private)
+ flags |= AccessPrivate;
+ else if (f.access == FunctionDef::Public)
+ flags |= AccessPublic;
+ else if (f.access == FunctionDef::Protected)
+ flags |= AccessProtected;
+ if (f.access == FunctionDef::Private)
+ flags |= AccessPrivate;
+ else if (f.access == FunctionDef::Public)
+ flags |= AccessPublic;
+ else if (f.access == FunctionDef::Protected)
+ flags |= AccessProtected;
+ if (f.isCompat)
+ flags |= MethodCompatibility;
+ if (f.wasCloned)
+ flags |= MethodCloned;
+ if (f.isScriptable)
+ flags |= MethodScriptable;
+ if (f.revision > 0)
+ flags |= MethodRevisioned;
+ fprintf(out, " %4d, %4d, %4d, %4d, 0x%02x,\n", strreg(sig),
+ strreg(arguments), strreg(f.normalizedType), strreg(f.tag), flags);
+ }
+}
+
+void Generator::generateFunctionRevisions(QList<FunctionDef>& list, const char *functype)
+{
+ if (list.count())
+ fprintf(out, "\n // %ss: revision\n", functype);
+ for (int i = 0; i < list.count(); ++i) {
+ const FunctionDef &f = list.at(i);
+ fprintf(out, " %4d,\n", f.revision);
+ }
+}
+
+void Generator::generateProperties()
+{
+ //
+ // Create meta data
+ //
+
+ if (cdef->propertyList.count())
+ fprintf(out, "\n // properties: name, type, flags\n");
+ for (int i = 0; i < cdef->propertyList.count(); ++i) {
+ const PropertyDef &p = cdef->propertyList.at(i);
+ uint flags = Invalid;
+ if (!isVariantType(p.type)) {
+ flags |= EnumOrFlag;
+ } else if (!isQRealType(p.type)) {
+ flags |= qvariant_nameToType(p.type) << 24;
+ }
+ if (!p.read.isEmpty())
+ flags |= Readable;
+ if (!p.write.isEmpty()) {
+ flags |= Writable;
+ if (p.stdCppSet())
+ flags |= StdCppSet;
+ }
+ if (!p.reset.isEmpty())
+ flags |= Resettable;
+
+// if (p.override)
+// flags |= Override;
+
+ if (p.designable.isEmpty())
+ flags |= ResolveDesignable;
+ else if (p.designable != "false")
+ flags |= Designable;
+
+ if (p.scriptable.isEmpty())
+ flags |= ResolveScriptable;
+ else if (p.scriptable != "false")
+ flags |= Scriptable;
+
+ if (p.stored.isEmpty())
+ flags |= ResolveStored;
+ else if (p.stored != "false")
+ flags |= Stored;
+
+ if (p.editable.isEmpty())
+ flags |= ResolveEditable;
+ else if (p.editable != "false")
+ flags |= Editable;
+
+ if (p.user.isEmpty())
+ flags |= ResolveUser;
+ else if (p.user != "false")
+ flags |= User;
+
+ if (p.notifyId != -1)
+ flags |= Notify;
+
+ if (p.revision > 0)
+ flags |= Revisioned;
+
+ if (p.constant)
+ flags |= Constant;
+ if (p.final)
+ flags |= Final;
+
+ fprintf(out, " %4d, %4d, ",
+ strreg(p.name),
+ strreg(p.type));
+ if (!(flags >> 24) && isQRealType(p.type))
+ fprintf(out, "(QMetaType::QReal << 24) | ");
+ fprintf(out, "0x%.8x,\n", flags);
+ }
+
+ if(cdef->notifyableProperties) {
+ fprintf(out, "\n // properties: notify_signal_id\n");
+ for (int i = 0; i < cdef->propertyList.count(); ++i) {
+ const PropertyDef &p = cdef->propertyList.at(i);
+ if(p.notifyId == -1)
+ fprintf(out, " %4d,\n",
+ 0);
+ else
+ fprintf(out, " %4d,\n",
+ p.notifyId);
+ }
+ }
+ if (cdef->revisionedProperties) {
+ fprintf(out, "\n // properties: revision\n");
+ for (int i = 0; i < cdef->propertyList.count(); ++i) {
+ const PropertyDef &p = cdef->propertyList.at(i);
+ fprintf(out, " %4d,\n", p.revision);
+ }
+ }
+}
+
+void Generator::generateEnums(int index)
+{
+ if (cdef->enumDeclarations.isEmpty())
+ return;
+
+ fprintf(out, "\n // enums: name, flags, count, data\n");
+ index += 4 * cdef->enumList.count();
+ int i;
+ for (i = 0; i < cdef->enumList.count(); ++i) {
+ const EnumDef &e = cdef->enumList.at(i);
+ fprintf(out, " %4d, 0x%.1x, %4d, %4d,\n",
+ strreg(e.name),
+ cdef->enumDeclarations.value(e.name) ? 1 : 0,
+ e.values.count(),
+ index);
+ index += e.values.count() * 2;
+ }
+
+ fprintf(out, "\n // enum data: key, value\n");
+ for (i = 0; i < cdef->enumList.count(); ++i) {
+ const EnumDef &e = cdef->enumList.at(i);
+ for (int j = 0; j < e.values.count(); ++j) {
+ const QByteArray &val = e.values.at(j);
+ fprintf(out, " %4d, uint(%s::%s),\n",
+ strreg(val),
+ cdef->qualified.constData(),
+ val.constData());
+ }
+ }
+}
+
+void Generator::generateMetacall()
+{
+ bool isQObject = (cdef->classname == "QObject");
+
+ fprintf(out, "\nint %s::qt_metacall(QMetaObject::Call _c, int _id, void **_a)\n{\n",
+ cdef->qualified.constData());
+
+ if (!purestSuperClass.isEmpty() && !isQObject) {
+ QByteArray superClass = purestSuperClass;
+ // workaround for VC6
+ if (superClass.contains("::")) {
+ fprintf(out, " typedef %s QMocSuperClass;\n", superClass.constData());
+ superClass = "QMocSuperClass";
+ }
+ fprintf(out, " _id = %s::qt_metacall(_c, _id, _a);\n", superClass.constData());
+ }
+
+ fprintf(out, " if (_id < 0)\n return _id;\n");
+ fprintf(out, " ");
+
+ bool needElse = false;
+ QList<FunctionDef> methodList;
+ methodList += cdef->signalList;
+ methodList += cdef->slotList;
+ methodList += cdef->methodList;
+
+ if (methodList.size()) {
+ needElse = true;
+ fprintf(out, "if (_c == QMetaObject::InvokeMetaMethod) {\n");
+ fprintf(out, " if (_id < %d)\n", methodList.size());
+ fprintf(out, " qt_static_metacall(this, _c, _id, _a);\n");
+ fprintf(out, " _id -= %d;\n }", methodList.size());
+ }
+
+ if (cdef->propertyList.size()) {
+ bool needGet = false;
+ bool needTempVarForGet = false;
+ bool needSet = false;
+ bool needReset = false;
+ bool needDesignable = false;
+ bool needScriptable = false;
+ bool needStored = false;
+ bool needEditable = false;
+ bool needUser = false;
+ for (int i = 0; i < cdef->propertyList.size(); ++i) {
+ const PropertyDef &p = cdef->propertyList.at(i);
+ needGet |= !p.read.isEmpty();
+ if (!p.read.isEmpty())
+ needTempVarForGet |= (p.gspec != PropertyDef::PointerSpec
+ && p.gspec != PropertyDef::ReferenceSpec);
+
+ needSet |= !p.write.isEmpty();
+ needReset |= !p.reset.isEmpty();
+ needDesignable |= p.designable.endsWith(')');
+ needScriptable |= p.scriptable.endsWith(')');
+ needStored |= p.stored.endsWith(')');
+ needEditable |= p.editable.endsWith(')');
+ needUser |= p.user.endsWith(')');
+ }
+ fprintf(out, "\n#ifndef QT_NO_PROPERTIES\n ");
+
+ if (needElse)
+ fprintf(out, " else ");
+ fprintf(out, "if (_c == QMetaObject::ReadProperty) {\n");
+ if (needGet) {
+ if (needTempVarForGet)
+ fprintf(out, " void *_v = _a[0];\n");
+ fprintf(out, " switch (_id) {\n");
+ for (int propindex = 0; propindex < cdef->propertyList.size(); ++propindex) {
+ const PropertyDef &p = cdef->propertyList.at(propindex);
+ if (p.read.isEmpty())
+ continue;
+ QByteArray prefix;
+ if (p.inPrivateClass.size()) {
+ prefix = p.inPrivateClass;
+ prefix.append("->");
+ }
+ if (p.gspec == PropertyDef::PointerSpec)
+ fprintf(out, " case %d: _a[0] = const_cast<void*>(reinterpret_cast<const void*>(%s%s())); break;\n",
+ propindex, prefix.constData(), p.read.constData());
+ else if (p.gspec == PropertyDef::ReferenceSpec)
+ fprintf(out, " case %d: _a[0] = const_cast<void*>(reinterpret_cast<const void*>(&%s%s())); break;\n",
+ propindex, prefix.constData(), p.read.constData());
+ else if (cdef->enumDeclarations.value(p.type, false))
+ fprintf(out, " case %d: *reinterpret_cast<int*>(_v) = QFlag(%s%s()); break;\n",
+ propindex, prefix.constData(), p.read.constData());
+ else
+ fprintf(out, " case %d: *reinterpret_cast< %s*>(_v) = %s%s(); break;\n",
+ propindex, p.type.constData(), prefix.constData(), p.read.constData());
+ }
+ fprintf(out, " }\n");
+ }
+
+ fprintf(out,
+ " _id -= %d;\n"
+ " }", cdef->propertyList.count());
+
+ fprintf(out, " else ");
+ fprintf(out, "if (_c == QMetaObject::WriteProperty) {\n");
+
+ if (needSet) {
+ fprintf(out, " void *_v = _a[0];\n");
+ fprintf(out, " switch (_id) {\n");
+ for (int propindex = 0; propindex < cdef->propertyList.size(); ++propindex) {
+ const PropertyDef &p = cdef->propertyList.at(propindex);
+ if (p.write.isEmpty())
+ continue;
+ QByteArray prefix;
+ if (p.inPrivateClass.size()) {
+ prefix = p.inPrivateClass;
+ prefix.append("->");
+ }
+ if (cdef->enumDeclarations.value(p.type, false)) {
+ fprintf(out, " case %d: %s%s(QFlag(*reinterpret_cast<int*>(_v))); break;\n",
+ propindex, prefix.constData(), p.write.constData());
+ } else {
+ fprintf(out, " case %d: %s%s(*reinterpret_cast< %s*>(_v)); break;\n",
+ propindex, prefix.constData(), p.write.constData(), p.type.constData());
+ }
+ }
+ fprintf(out, " }\n");
+ }
+
+ fprintf(out,
+ " _id -= %d;\n"
+ " }", cdef->propertyList.count());
+
+ fprintf(out, " else ");
+ fprintf(out, "if (_c == QMetaObject::ResetProperty) {\n");
+ if (needReset) {
+ fprintf(out, " switch (_id) {\n");
+ for (int propindex = 0; propindex < cdef->propertyList.size(); ++propindex) {
+ const PropertyDef &p = cdef->propertyList.at(propindex);
+ if (!p.reset.endsWith(')'))
+ continue;
+ QByteArray prefix;
+ if (p.inPrivateClass.size()) {
+ prefix = p.inPrivateClass;
+ prefix.append("->");
+ }
+ fprintf(out, " case %d: %s%s; break;\n",
+ propindex, prefix.constData(), p.reset.constData());
+ }
+ fprintf(out, " }\n");
+ }
+ fprintf(out,
+ " _id -= %d;\n"
+ " }", cdef->propertyList.count());
+
+ fprintf(out, " else ");
+ fprintf(out, "if (_c == QMetaObject::QueryPropertyDesignable) {\n");
+ if (needDesignable) {
+ fprintf(out, " bool *_b = reinterpret_cast<bool*>(_a[0]);\n");
+ fprintf(out, " switch (_id) {\n");
+ for (int propindex = 0; propindex < cdef->propertyList.size(); ++propindex) {
+ const PropertyDef &p = cdef->propertyList.at(propindex);
+ if (!p.designable.endsWith(')'))
+ continue;
+ fprintf(out, " case %d: *_b = %s; break;\n",
+ propindex, p.designable.constData());
+ }
+ fprintf(out, " }\n");
+ }
+ fprintf(out,
+ " _id -= %d;\n"
+ " }", cdef->propertyList.count());
+
+ fprintf(out, " else ");
+ fprintf(out, "if (_c == QMetaObject::QueryPropertyScriptable) {\n");
+ if (needScriptable) {
+ fprintf(out, " bool *_b = reinterpret_cast<bool*>(_a[0]);\n");
+ fprintf(out, " switch (_id) {\n");
+ for (int propindex = 0; propindex < cdef->propertyList.size(); ++propindex) {
+ const PropertyDef &p = cdef->propertyList.at(propindex);
+ if (!p.scriptable.endsWith(')'))
+ continue;
+ fprintf(out, " case %d: *_b = %s; break;\n",
+ propindex, p.scriptable.constData());
+ }
+ fprintf(out, " }\n");
+ }
+ fprintf(out,
+ " _id -= %d;\n"
+ " }", cdef->propertyList.count());
+
+ fprintf(out, " else ");
+ fprintf(out, "if (_c == QMetaObject::QueryPropertyStored) {\n");
+ if (needStored) {
+ fprintf(out, " bool *_b = reinterpret_cast<bool*>(_a[0]);\n");
+ fprintf(out, " switch (_id) {\n");
+ for (int propindex = 0; propindex < cdef->propertyList.size(); ++propindex) {
+ const PropertyDef &p = cdef->propertyList.at(propindex);
+ if (!p.stored.endsWith(')'))
+ continue;
+ fprintf(out, " case %d: *_b = %s; break;\n",
+ propindex, p.stored.constData());
+ }
+ fprintf(out, " }\n");
+ }
+ fprintf(out,
+ " _id -= %d;\n"
+ " }", cdef->propertyList.count());
+
+ fprintf(out, " else ");
+ fprintf(out, "if (_c == QMetaObject::QueryPropertyEditable) {\n");
+ if (needEditable) {
+ fprintf(out, " bool *_b = reinterpret_cast<bool*>(_a[0]);\n");
+ fprintf(out, " switch (_id) {\n");
+ for (int propindex = 0; propindex < cdef->propertyList.size(); ++propindex) {
+ const PropertyDef &p = cdef->propertyList.at(propindex);
+ if (!p.editable.endsWith(')'))
+ continue;
+ fprintf(out, " case %d: *_b = %s; break;\n",
+ propindex, p.editable.constData());
+ }
+ fprintf(out, " }\n");
+ }
+ fprintf(out,
+ " _id -= %d;\n"
+ " }", cdef->propertyList.count());
+
+
+ fprintf(out, " else ");
+ fprintf(out, "if (_c == QMetaObject::QueryPropertyUser) {\n");
+ if (needUser) {
+ fprintf(out, " bool *_b = reinterpret_cast<bool*>(_a[0]);\n");
+ fprintf(out, " switch (_id) {\n");
+ for (int propindex = 0; propindex < cdef->propertyList.size(); ++propindex) {
+ const PropertyDef &p = cdef->propertyList.at(propindex);
+ if (!p.user.endsWith(')'))
+ continue;
+ fprintf(out, " case %d: *_b = %s; break;\n",
+ propindex, p.user.constData());
+ }
+ fprintf(out, " }\n");
+ }
+ fprintf(out,
+ " _id -= %d;\n"
+ " }", cdef->propertyList.count());
+
+
+ fprintf(out, "\n#endif // QT_NO_PROPERTIES");
+ }
+ if (methodList.size() || cdef->signalList.size() || cdef->propertyList.size())
+ fprintf(out, "\n ");
+ fprintf(out,"return _id;\n}\n");
+}
+
+void Generator::generateStaticMetacall()
+{
+ fprintf(out, "void %s::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)\n{\n",
+ cdef->qualified.constData());
+
+ bool needElse = false;
+ bool isUsed_a = false;
+
+ if (!cdef->constructorList.isEmpty()) {
+ fprintf(out, " if (_c == QMetaObject::CreateInstance) {\n");
+ fprintf(out, " switch (_id) {\n");
+ for (int ctorindex = 0; ctorindex < cdef->constructorList.count(); ++ctorindex) {
+ fprintf(out, " case %d: { %s *_r = new %s(", ctorindex,
+ cdef->classname.constData(), cdef->classname.constData());
+ const FunctionDef &f = cdef->constructorList.at(ctorindex);
+ int offset = 1;
+ for (int j = 0; j < f.arguments.count(); ++j) {
+ const ArgumentDef &a = f.arguments.at(j);
+ if (j)
+ fprintf(out, ",");
+ fprintf(out, "(*reinterpret_cast< %s>(_a[%d]))", a.typeNameForCast.constData(), offset++);
+ }
+ fprintf(out, ");\n");
+ fprintf(out, " if (_a[0]) *reinterpret_cast<QObject**>(_a[0]) = _r; } break;\n");
+ }
+ fprintf(out, " }\n");
+ fprintf(out, " }");
+ needElse = true;
+ isUsed_a = true;
+ }
+
+ QList<FunctionDef> methodList;
+ methodList += cdef->signalList;
+ methodList += cdef->slotList;
+ methodList += cdef->methodList;
+
+ if (!methodList.isEmpty()) {
+ if (needElse)
+ fprintf(out, " else ");
+ else
+ fprintf(out, " ");
+ fprintf(out, "if (_c == QMetaObject::InvokeMetaMethod) {\n");
+#ifndef QT_NO_DEBUG
+ fprintf(out, " Q_ASSERT(staticMetaObject.cast(_o));\n");
+#endif
+ fprintf(out, " %s *_t = static_cast<%s *>(_o);\n", cdef->classname.constData(), cdef->classname.constData());
+ fprintf(out, " switch (_id) {\n");
+ for (int methodindex = 0; methodindex < methodList.size(); ++methodindex) {
+ const FunctionDef &f = methodList.at(methodindex);
+ fprintf(out, " case %d: ", methodindex);
+ if (f.normalizedType.size())
+ fprintf(out, "{ %s _r = ", noRef(f.normalizedType).constData());
+ fprintf(out, "_t->");
+ if (f.inPrivateClass.size())
+ fprintf(out, "%s->", f.inPrivateClass.constData());
+ fprintf(out, "%s(", f.name.constData());
+ int offset = 1;
+ for (int j = 0; j < f.arguments.count(); ++j) {
+ const ArgumentDef &a = f.arguments.at(j);
+ if (j)
+ fprintf(out, ",");
+ fprintf(out, "(*reinterpret_cast< %s>(_a[%d]))",a.typeNameForCast.constData(), offset++);
+ isUsed_a = true;
+ }
+ fprintf(out, ");");
+ if (f.normalizedType.size()) {
+ fprintf(out, "\n if (_a[0]) *reinterpret_cast< %s*>(_a[0]) = _r; } ",
+ noRef(f.normalizedType).constData());
+ isUsed_a = true;
+ }
+ fprintf(out, " break;\n");
+ }
+ fprintf(out, " default: ;\n");
+ fprintf(out, " }\n");
+ fprintf(out, " }");
+ needElse = true;
+ }
+
+ if (needElse)
+ fprintf(out, "\n");
+
+ if (methodList.isEmpty()) {
+ fprintf(out, " Q_UNUSED(_o);\n");
+ if (cdef->constructorList.isEmpty()) {
+ fprintf(out, " Q_UNUSED(_id);\n");
+ fprintf(out, " Q_UNUSED(_c);\n");
+ }
+ }
+ if (!isUsed_a)
+ fprintf(out, " Q_UNUSED(_a);\n");
+
+ fprintf(out, "}\n\n");
+}
+
+void Generator::generateSignal(FunctionDef *def,int index)
+{
+ if (def->wasCloned || def->isAbstract)
+ return;
+ fprintf(out, "\n// SIGNAL %d\n%s %s::%s(",
+ index, def->type.name.constData(), cdef->qualified.constData(), def->name.constData());
+
+ QByteArray thisPtr = "this";
+ const char *constQualifier = "";
+
+ if (def->isConst) {
+ thisPtr = "const_cast< ";
+ thisPtr += cdef->qualified;
+ thisPtr += " *>(this)";
+ constQualifier = "const";
+ }
+
+ if (def->arguments.isEmpty() && def->normalizedType.isEmpty()) {
+ fprintf(out, ")%s\n{\n"
+ " QMetaObject::activate(%s, &staticMetaObject, %d, 0);\n"
+ "}\n", constQualifier, thisPtr.constData(), index);
+ return;
+ }
+
+ int offset = 1;
+ for (int j = 0; j < def->arguments.count(); ++j) {
+ const ArgumentDef &a = def->arguments.at(j);
+ if (j)
+ fprintf(out, ", ");
+ fprintf(out, "%s _t%d%s", a.type.name.constData(), offset++, a.rightType.constData());
+ }
+ fprintf(out, ")%s\n{\n", constQualifier);
+ if (def->type.name.size() && def->normalizedType.size())
+ fprintf(out, " %s _t0;\n", noRef(def->normalizedType).constData());
+
+ fprintf(out, " void *_a[] = { ");
+ if (def->normalizedType.isEmpty()) {
+ fprintf(out, "0");
+ } else {
+ if (def->returnTypeIsVolatile)
+ fprintf(out, "const_cast<void*>(reinterpret_cast<const volatile void*>(&_t0))");
+ else
+ fprintf(out, "const_cast<void*>(reinterpret_cast<const void*>(&_t0))");
+ }
+ int i;
+ for (i = 1; i < offset; ++i)
+ if (def->arguments.at(i - 1).type.isVolatile)
+ fprintf(out, ", const_cast<void*>(reinterpret_cast<const volatile void*>(&_t%d))", i);
+ else
+ fprintf(out, ", const_cast<void*>(reinterpret_cast<const void*>(&_t%d))", i);
+ fprintf(out, " };\n");
+ fprintf(out, " QMetaObject::activate(%s, &staticMetaObject, %d, _a);\n", thisPtr.constData(), index);
+ if (def->normalizedType.size())
+ fprintf(out, " return _t0;\n");
+ fprintf(out, "}\n");
+}
+
+//
+// Functions used when generating QMetaObject directly
+//
+// Much of this code is copied from the corresponding
+// C++ code-generating functions; we can change the
+// two generators so that more of the code is shared.
+// The key difference from the C++ code generator is
+// that instead of calling fprintf(), we append bytes
+// to a buffer.
+//
+
+QMetaObject *Generator::generateMetaObject(bool ignoreProperties)
+{
+//
+// build the data array
+//
+
+ // filter out undeclared enumerators and sets
+ {
+ QList<EnumDef> enumList;
+ for (int i = 0; i < cdef->enumList.count(); ++i) {
+ EnumDef def = cdef->enumList.at(i);
+ if (cdef->enumDeclarations.contains(def.name)) {
+ enumList += def;
+ }
+ QByteArray alias = cdef->flagAliases.value(def.name);
+ if (cdef->enumDeclarations.contains(alias)) {
+ def.name = alias;
+ enumList += def;
+ }
+ }
+ cdef->enumList = enumList;
+ }
+
+ int index = 10;
+ meta_data
+ << 1 // revision
+ << strreg(cdef->qualified) // classname
+ << cdef->classInfoList.count() << (cdef->classInfoList.count() ? index : 0) // classinfo
+ ;
+ index += cdef->classInfoList.count() * 2;
+
+ int methodCount = cdef->signalList.count() + cdef->slotList.count() + cdef->methodList.count();
+ meta_data << methodCount << (methodCount ? index : 0); // methods
+ index += methodCount * 5;
+ if (!ignoreProperties) {
+ meta_data << cdef->propertyList.count() << (cdef->propertyList.count() ? index : 0); // properties
+ index += cdef->propertyList.count() * 3;
+ } else {
+ meta_data << 0 << 0; // properties
+ }
+ meta_data << cdef->enumList.count() << (cdef->enumList.count() ? index : 0); // enums/sets
+
+//
+// Build classinfo array
+//
+ _generateClassInfos();
+
+//
+// Build signals array first, otherwise the signal indices would be wrong
+//
+ _generateFunctions(cdef->signalList, MethodSignal);
+
+//
+// Build slots array
+//
+ _generateFunctions(cdef->slotList, MethodSlot);
+
+//
+// Build method array
+//
+ _generateFunctions(cdef->methodList, MethodMethod);
+
+
+//
+// Build property array
+//
+ if (!ignoreProperties)
+ _generateProperties();
+
+//
+// Build enums array
+//
+ _generateEnums(index);
+
+//
+// Terminate data array
+//
+ meta_data << 0;
+
+//
+// Build stringdata array
+//
+ QVector<char> string_data;
+ for (int i = 0; i < strings.size(); ++i) {
+ const char *s = strings.at(i).constData();
+ char c;
+ do {
+ c = *(s++);
+ string_data << c;
+ } while (c != '\0');
+ }
+
+//
+// Finally create and initialize the static meta object
+//
+ const int meta_object_offset = 0;
+ const int meta_object_size = sizeof(QMetaObject);
+ const int meta_data_offset = meta_object_offset + meta_object_size;
+ const int meta_data_size = meta_data.count() * sizeof(uint);
+ const int string_data_offset = meta_data_offset + meta_data_size;
+ const int string_data_size = string_data.count();
+ const int total_size = string_data_offset + string_data_size;
+
+ char *blob = new char[total_size];
+
+ char *string_data_output = blob + string_data_offset;
+ const char *string_data_src = string_data.constData();
+ for (int i = 0; i < string_data.count(); ++i)
+ string_data_output[i] = string_data_src[i];
+
+ uint *meta_data_output = reinterpret_cast<uint *>(blob + meta_data_offset);
+ const uint *meta_data_src = meta_data.constData();
+ for (int i = 0; i < meta_data.count(); ++i)
+ meta_data_output[i] = meta_data_src[i];
+
+ QMetaObject *meta_object = new (blob + meta_object_offset)QMetaObject;
+ meta_object->d.superdata = 0;
+ meta_object->d.stringdata = string_data_output;
+ meta_object->d.data = meta_data_output;
+ meta_object->d.extradata = 0;
+ return meta_object;
+}
+
+void Generator::_generateClassInfos()
+{
+ for (int i = 0; i < cdef->classInfoList.size(); ++i) {
+ const ClassInfoDef &c = cdef->classInfoList.at(i);
+ meta_data << strreg(c.name) << strreg(c.value);
+ }
+}
+
+void Generator::_generateFunctions(QList<FunctionDef> &list, int type)
+{
+ for (int i = 0; i < list.count(); ++i) {
+ const FunctionDef &f = list.at(i);
+
+ QByteArray sig = f.name + '(';
+ QByteArray arguments;
+
+ for (int j = 0; j < f.arguments.count(); ++j) {
+ const ArgumentDef &a = f.arguments.at(j);
+ if (j) {
+ sig += ',';
+ arguments += ',';
+ }
+ sig += a.normalizedType;
+ arguments += a.name;
+ }
+ sig += ')';
+
+ char flags = type;
+ if (f.access == FunctionDef::Private)
+ flags |= AccessPrivate;
+ else if (f.access == FunctionDef::Public)
+ flags |= AccessPublic;
+ else if (f.access == FunctionDef::Protected)
+ flags |= AccessProtected;
+ if (f.access == FunctionDef::Private)
+ flags |= AccessPrivate;
+ else if (f.access == FunctionDef::Public)
+ flags |= AccessPublic;
+ else if (f.access == FunctionDef::Protected)
+ flags |= AccessProtected;
+ if (f.isCompat)
+ flags |= MethodCompatibility;
+ if (f.wasCloned)
+ flags |= MethodCloned;
+ if (f.isScriptable)
+ flags |= MethodScriptable;
+
+ meta_data << strreg(sig)
+ << strreg(arguments)
+ << strreg(f.normalizedType)
+ << strreg(f.tag)
+ << flags;
+ }
+}
+
+void Generator::_generateEnums(int index)
+{
+ index += 4 * cdef->enumList.count();
+ int i;
+ for (i = 0; i < cdef->enumList.count(); ++i) {
+ const EnumDef &e = cdef->enumList.at(i);
+ meta_data << strreg(e.name) << (cdef->enumDeclarations.value(e.name) ? 1 : 0)
+ << e.values.count() << index;
+ index += e.values.count() * 2;
+ }
+
+ for (i = 0; i < cdef->enumList.count(); ++i) {
+ const EnumDef &e = cdef->enumList.at(i);
+ for (int j = 0; j < e.values.count(); ++j) {
+ const QByteArray &val = e.values.at(j);
+ meta_data << strreg(val) << 0; // we don't know the value itself
+ }
+ }
+}
+
+void Generator::_generateProperties()
+{
+ //
+ // specify get function, for compatibiliy we accept functions
+ // returning pointers, or const char * for QByteArray.
+ //
+ for (int i = 0; i < cdef->propertyList.count(); ++i) {
+ PropertyDef &p = cdef->propertyList[i];
+ if (p.read.isEmpty())
+ continue;
+ for (int j = 0; j < cdef->publicList.count(); ++j) {
+ const FunctionDef &f = cdef->publicList.at(j);
+ if (f.name != p.read)
+ continue;
+ if (!f.isConst) // get functions must be const
+ continue;
+ if (f.arguments.size()) // and must not take any arguments
+ continue;
+ PropertyDef::Specification spec = PropertyDef::ValueSpec;
+ QByteArray tmp = f.normalizedType;
+ if (p.type == "QByteArray" && tmp == "const char *")
+ tmp = "QByteArray";
+ if (tmp.left(6) == "const ")
+ tmp = tmp.mid(6);
+ if (p.type != tmp && tmp.endsWith('*')) {
+ tmp.chop(1);
+ spec = PropertyDef::PointerSpec;
+ } else if (f.type.name.endsWith('&')) { // raw type, not normalized type
+ spec = PropertyDef::ReferenceSpec;
+ }
+ if (p.type != tmp)
+ continue;
+ p.gspec = spec;
+ break;
+ }
+ }
+
+
+ //
+ // Create meta data
+ //
+
+ for (int i = 0; i < cdef->propertyList.count(); ++i) {
+ const PropertyDef &p = cdef->propertyList.at(i);
+ uint flags = Invalid;
+ if (!isVariantType(p.type)) {
+ flags |= EnumOrFlag;
+ } else {
+ flags |= qvariant_nameToType(p.type) << 24;
+ }
+ if (!p.read.isEmpty())
+ flags |= Readable;
+ if (!p.write.isEmpty()) {
+ flags |= Writable;
+ if (p.stdCppSet())
+ flags |= StdCppSet;
+ }
+ if (!p.reset.isEmpty())
+ flags |= Resettable;
+
+// if (p.override)
+// flags |= Override;
+
+ if (p.designable.isEmpty())
+ flags |= ResolveDesignable;
+ else if (p.designable != "false")
+ flags |= Designable;
+
+ if (p.scriptable.isEmpty())
+ flags |= ResolveScriptable;
+ else if (p.scriptable != "false")
+ flags |= Scriptable;
+
+ if (p.stored.isEmpty())
+ flags |= ResolveStored;
+ else if (p.stored != "false")
+ flags |= Stored;
+
+ if (p.editable.isEmpty())
+ flags |= ResolveEditable;
+ else if (p.editable != "false")
+ flags |= Editable;
+
+ if (p.user.isEmpty())
+ flags |= ResolveUser;
+ else if (p.user != "false")
+ flags |= User;
+
+ meta_data << strreg(p.name) << strreg(p.type) << flags;
+ }
+}
+
+QT_END_NAMESPACE