summaryrefslogtreecommitdiffstats
path: root/src/tools/moc
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/moc')
-rw-r--r--src/tools/moc/generator.cpp1333
-rw-r--r--src/tools/moc/generator.h82
-rw-r--r--src/tools/moc/keywords.cpp1003
-rw-r--r--src/tools/moc/main.cpp448
-rw-r--r--src/tools/moc/moc.cpp1453
-rw-r--r--src/tools/moc/moc.h264
-rw-r--r--src/tools/moc/moc.pri16
-rw-r--r--src/tools/moc/moc.pro18
-rw-r--r--src/tools/moc/mwerks_mac.cpp240
-rw-r--r--src/tools/moc/mwerks_mac.h67
-rw-r--r--src/tools/moc/outputrevision.h48
-rw-r--r--src/tools/moc/parser.cpp87
-rw-r--r--src/tools/moc/parser.h110
-rw-r--r--src/tools/moc/ppkeywords.cpp248
-rw-r--r--src/tools/moc/preprocessor.cpp978
-rw-r--r--src/tools/moc/preprocessor.h102
-rw-r--r--src/tools/moc/symbols.h147
-rw-r--r--src/tools/moc/token.cpp224
-rw-r--r--src/tools/moc/token.h276
-rwxr-xr-xsrc/tools/moc/util/generate.sh48
-rw-r--r--src/tools/moc/util/generate_keywords.cpp469
-rw-r--r--src/tools/moc/util/generate_keywords.pro12
-rw-r--r--src/tools/moc/util/licenseheader.txt41
-rw-r--r--src/tools/moc/utils.h111
24 files changed, 7825 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
diff --git a/src/tools/moc/generator.h b/src/tools/moc/generator.h
new file mode 100644
index 0000000000..fa5885f0e1
--- /dev/null
+++ b/src/tools/moc/generator.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef GENERATOR_H
+#define GENERATOR_H
+
+#include "moc.h"
+
+QT_BEGIN_NAMESPACE
+
+class Generator
+{
+ FILE *out;
+ ClassDef *cdef;
+ QVector<uint> meta_data;
+public:
+ Generator(ClassDef *classDef, const QList<QByteArray> &metaTypes, FILE *outfile = 0);
+ void generateCode();
+ QMetaObject *generateMetaObject(bool ignoreProperties);
+private:
+ void generateClassInfos();
+ void generateFunctions(QList<FunctionDef> &list, const char *functype, int type);
+ void generateFunctionRevisions(QList<FunctionDef>& list, const char *functype);
+ void generateEnums(int index);
+ void generateProperties();
+ void generateMetacall();
+ void generateStaticMetacall();
+ void generateSignal(FunctionDef *def, int index);
+
+ // used by binary QMetaObject generator
+ void _generateClassInfos();
+ void _generateFunctions(QList<FunctionDef> &list, int type);
+ void _generateEnums(int index);
+ void _generateProperties();
+
+ int strreg(const char *); // registers a string and returns its id
+ QList<QByteArray> strings;
+ QByteArray purestSuperClass;
+ QList<QByteArray> metaTypes;
+};
+
+QT_END_NAMESPACE
+
+#endif // GENERATOR_H
diff --git a/src/tools/moc/keywords.cpp b/src/tools/moc/keywords.cpp
new file mode 100644
index 0000000000..9a8aa416e8
--- /dev/null
+++ b/src/tools/moc/keywords.cpp
@@ -0,0 +1,1003 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+// auto generated
+// DO NOT EDIT.
+
+static const short keyword_trans[][128] = {
+ {0,0,0,0,0,0,0,0,0,541,538,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 541,252,539,542,0,38,239,540,25,26,236,234,30,235,27,237,
+ 22,22,22,22,22,22,22,22,22,22,34,41,23,39,24,43,
+ 0,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,21,8,8,8,8,8,8,8,8,8,31,543,32,238,8,
+ 0,1,2,3,4,5,6,7,8,9,8,8,10,11,12,13,
+ 14,8,15,16,17,18,19,20,8,8,8,36,245,37,248,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,192,0,173,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,240,0,0,0,0,0,287,
+ 0,0,341,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,109,0,0,0,0,0,0,280,0,0,0,121,0,0,80,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,229,0,0,0,0,0,0,0,0,0,312,
+ 0,0,0,0,0,0,0,0,0,44,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,327,0,133,0,
+ 0,0,0,0,0,0,0,0,168,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,308,0,0,339,
+ 0,0,116,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,326,0,0,0,0,0,0,0,198,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,125,0,0,0,227,0,0,0,0,0,0,0,0,0,253,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,150,0,0,163,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,290,222,0,0,461,0,0,0,
+ 0,0,0,0,55,0,0,330,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,97,0,0,94,0,0,0,0,0,0,0,
+ 0,0,107,0,0,0,0,0,0,89,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,140,0,
+ 0,0,0,194,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,144,0,0,0,0,0,208,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,283,0,0,0,0,335,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,485,0,0,0,0,0,0,0,0,0,0,357,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,36,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,33,0,263,272,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,273,264,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,42,0,0,0,28,0,
+ 546,546,546,546,546,546,546,546,546,546,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,40,0,0,0,32,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,259,37,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,56,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,136,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,176,0,66,0,0,0,0,0,0,
+ 0,0,0,0,353,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,249,81,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,82,345,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,113,0,0,0,0,92,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,95,0,0,0,0,0,0,
+ 0,0,104,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,319,110,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,141,0,0,0,0,0,0,
+ 0,0,0,302,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,151,0,0,0,0,0,156,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 169,0,0,0,182,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,203,0,0,170,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,199,0,0,0,
+ 0,0,0,0,294,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,317,0,0,209,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,298,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,223,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,321,0,0,0,0,0,230,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,276,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,277,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,256,278,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,545,0,0,0,0,544,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,258,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,274,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,261,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,242,0,0,0,0,0,0,0,0,0,0,0,0,0,246,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,262,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,275,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,458,0,0,0,300,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,439,388,378,383,364,0,448,0,0,0,0,0,358,
+ 370,0,530,436,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,475,0,0,0,0,0,372,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,418,396,0,0,401,0,0,0,410,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,513,0,437,0,0,0,465,0,0,471,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,450,0,506,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 522,0,0,481,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,497,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,486,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
+};
+
+static const struct
+{
+ Token token;
+ short next;
+ char defchar;
+ short defnext;
+ Token ident;
+} keywords[] = {
+ {NOTOKEN, 0, 0, 0, NOTOKEN},
+ {CHARACTER, 1, 0, 0, NOTOKEN},
+ {CHARACTER, 2, 0, 0, NOTOKEN},
+ {CHARACTER, 3, 0, 0, NOTOKEN},
+ {CHARACTER, 4, 0, 0, NOTOKEN},
+ {CHARACTER, 5, 0, 0, NOTOKEN},
+ {CHARACTER, 6, 0, 0, NOTOKEN},
+ {CHARACTER, 0, 111, 350, NOTOKEN},
+ {CHARACTER, 0, 0, 0, NOTOKEN},
+ {CHARACTER, 7, 0, 0, NOTOKEN},
+ {CHARACTER, 0, 111, 295, NOTOKEN},
+ {CHARACTER, 0, 117, 186, NOTOKEN},
+ {CHARACTER, 8, 0, 0, NOTOKEN},
+ {CHARACTER, 0, 112, 215, NOTOKEN},
+ {CHARACTER, 9, 0, 0, NOTOKEN},
+ {CHARACTER, 0, 101, 65, NOTOKEN},
+ {CHARACTER, 10, 0, 0, NOTOKEN},
+ {CHARACTER, 11, 0, 0, NOTOKEN},
+ {CHARACTER, 12, 0, 0, NOTOKEN},
+ {CHARACTER, 13, 0, 0, NOTOKEN},
+ {CHARACTER, 14, 0, 0, NOTOKEN},
+ {CHARACTER, 15, 0, 0, NOTOKEN},
+ {DIGIT, 0, 0, 0, NOTOKEN},
+ {LANGLE, 16, 0, 0, NOTOKEN},
+ {RANGLE, 17, 0, 0, NOTOKEN},
+ {LPAREN, 0, 0, 0, NOTOKEN},
+ {RPAREN, 0, 0, 0, NOTOKEN},
+ {DOT, 18, 0, 0, NOTOKEN},
+ {INCOMPLETE, 0, 46, 29, NOTOKEN},
+ {ELIPSIS, 0, 0, 0, NOTOKEN},
+ {COMMA, 0, 0, 0, NOTOKEN},
+ {LBRACK, 0, 0, 0, NOTOKEN},
+ {RBRACK, 0, 0, 0, NOTOKEN},
+ {LBRACK, 0, 58, 35, NOTOKEN},
+ {COLON, 19, 0, 0, NOTOKEN},
+ {LANGLE_SCOPE, 0, 0, 0, NOTOKEN},
+ {LBRACE, 0, 0, 0, NOTOKEN},
+ {RBRACE, 0, 0, 0, NOTOKEN},
+ {PERCENT, 20, 0, 0, NOTOKEN},
+ {EQ, 0, 61, 267, NOTOKEN},
+ {SCOPE, 0, 0, 0, NOTOKEN},
+ {SEMIC, 0, 0, 0, NOTOKEN},
+ {DOTSTAR, 0, 0, 0, NOTOKEN},
+ {QUESTION, 0, 0, 0, NOTOKEN},
+ {CHARACTER, 0, 110, 45, CHARACTER},
+ {CHARACTER, 0, 97, 46, CHARACTER},
+ {CHARACTER, 0, 109, 47, CHARACTER},
+ {CHARACTER, 0, 105, 48, CHARACTER},
+ {CHARACTER, 0, 99, 49, CHARACTER},
+ {CHARACTER, 0, 95, 50, CHARACTER},
+ {CHARACTER, 0, 99, 51, CHARACTER},
+ {CHARACTER, 0, 97, 52, CHARACTER},
+ {CHARACTER, 0, 115, 53, CHARACTER},
+ {CHARACTER, 0, 116, 54, CHARACTER},
+ {DYNAMIC_CAST, 0, 0, 0, CHARACTER},
+ {CHARACTER, 21, 0, 0, CHARACTER},
+ {CHARACTER, 0, 116, 57, CHARACTER},
+ {CHARACTER, 0, 105, 58, CHARACTER},
+ {CHARACTER, 0, 99, 59, CHARACTER},
+ {STATIC, 0, 95, 60, CHARACTER},
+ {CHARACTER, 0, 99, 61, CHARACTER},
+ {CHARACTER, 0, 97, 62, CHARACTER},
+ {CHARACTER, 0, 115, 63, CHARACTER},
+ {CHARACTER, 0, 116, 64, CHARACTER},
+ {STATIC_CAST, 0, 0, 0, CHARACTER},
+ {CHARACTER, 22, 0, 0, CHARACTER},
+ {CHARACTER, 0, 110, 67, CHARACTER},
+ {CHARACTER, 0, 116, 68, CHARACTER},
+ {CHARACTER, 0, 101, 69, CHARACTER},
+ {CHARACTER, 0, 114, 70, CHARACTER},
+ {CHARACTER, 0, 112, 71, CHARACTER},
+ {CHARACTER, 0, 114, 72, CHARACTER},
+ {CHARACTER, 0, 101, 73, CHARACTER},
+ {CHARACTER, 0, 116, 74, CHARACTER},
+ {CHARACTER, 0, 95, 75, CHARACTER},
+ {CHARACTER, 0, 99, 76, CHARACTER},
+ {CHARACTER, 0, 97, 77, CHARACTER},
+ {CHARACTER, 0, 115, 78, CHARACTER},
+ {CHARACTER, 0, 116, 79, CHARACTER},
+ {REINTERPRET_CAST, 0, 0, 0, CHARACTER},
+ {CHARACTER, 23, 0, 0, CHARACTER},
+ {CHARACTER, 24, 0, 0, CHARACTER},
+ {CHARACTER, 0, 116, 83, CHARACTER},
+ {CONST, 0, 95, 84, CHARACTER},
+ {CHARACTER, 0, 99, 85, CHARACTER},
+ {CHARACTER, 0, 97, 86, CHARACTER},
+ {CHARACTER, 0, 115, 87, CHARACTER},
+ {CHARACTER, 0, 116, 88, CHARACTER},
+ {CONST_CAST, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 112, 90, CHARACTER},
+ {CHARACTER, 0, 101, 91, CHARACTER},
+ {CHARACTER, 25, 0, 0, CHARACTER},
+ {CHARACTER, 0, 100, 93, CHARACTER},
+ {TYPEID, 0, 0, 0, CHARACTER},
+ {CHARACTER, 26, 0, 0, CHARACTER},
+ {CHARACTER, 0, 115, 96, CHARACTER},
+ {THIS, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 109, 98, CHARACTER},
+ {CHARACTER, 0, 112, 99, CHARACTER},
+ {CHARACTER, 0, 108, 100, CHARACTER},
+ {CHARACTER, 0, 97, 101, CHARACTER},
+ {CHARACTER, 0, 116, 102, CHARACTER},
+ {CHARACTER, 0, 101, 103, CHARACTER},
+ {TEMPLATE, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 111, 105, CHARACTER},
+ {CHARACTER, 0, 119, 106, CHARACTER},
+ {THROW, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 121, 108, CHARACTER},
+ {TRY, 0, 0, 0, CHARACTER},
+ {CHARACTER, 27, 0, 0, CHARACTER},
+ {CHARACTER, 0, 99, 111, CHARACTER},
+ {CHARACTER, 0, 104, 112, CHARACTER},
+ {CATCH, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 101, 114, CHARACTER},
+ {CHARACTER, 0, 102, 115, CHARACTER},
+ {TYPEDEF, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 105, 117, CHARACTER},
+ {CHARACTER, 0, 101, 118, CHARACTER},
+ {CHARACTER, 0, 110, 119, CHARACTER},
+ {CHARACTER, 0, 100, 120, CHARACTER},
+ {FRIEND, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 97, 122, CHARACTER},
+ {CHARACTER, 0, 115, 123, CHARACTER},
+ {CHARACTER, 0, 115, 124, CHARACTER},
+ {CLASS, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 109, 126, CHARACTER},
+ {CHARACTER, 0, 101, 127, CHARACTER},
+ {CHARACTER, 0, 115, 128, CHARACTER},
+ {CHARACTER, 0, 112, 129, CHARACTER},
+ {CHARACTER, 0, 97, 130, CHARACTER},
+ {CHARACTER, 0, 99, 131, CHARACTER},
+ {CHARACTER, 0, 101, 132, CHARACTER},
+ {NAMESPACE, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 117, 134, CHARACTER},
+ {CHARACTER, 0, 109, 135, CHARACTER},
+ {ENUM, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 117, 137, CHARACTER},
+ {CHARACTER, 0, 99, 138, CHARACTER},
+ {CHARACTER, 0, 116, 139, CHARACTER},
+ {STRUCT, 0, 0, 0, CHARACTER},
+ {CHARACTER, 28, 0, 0, CHARACTER},
+ {CHARACTER, 0, 111, 142, CHARACTER},
+ {CHARACTER, 0, 110, 143, CHARACTER},
+ {UNION, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 114, 145, CHARACTER},
+ {CHARACTER, 0, 116, 146, CHARACTER},
+ {CHARACTER, 0, 117, 147, CHARACTER},
+ {CHARACTER, 0, 97, 148, CHARACTER},
+ {CHARACTER, 0, 108, 149, CHARACTER},
+ {VIRTUAL, 0, 0, 0, CHARACTER},
+ {CHARACTER, 29, 0, 0, CHARACTER},
+ {CHARACTER, 0, 118, 152, CHARACTER},
+ {CHARACTER, 0, 97, 153, CHARACTER},
+ {CHARACTER, 0, 116, 154, CHARACTER},
+ {CHARACTER, 0, 101, 155, CHARACTER},
+ {PRIVATE, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 116, 157, CHARACTER},
+ {CHARACTER, 0, 101, 158, CHARACTER},
+ {CHARACTER, 0, 99, 159, CHARACTER},
+ {CHARACTER, 0, 116, 160, CHARACTER},
+ {CHARACTER, 0, 101, 161, CHARACTER},
+ {CHARACTER, 0, 100, 162, CHARACTER},
+ {PROTECTED, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 98, 164, CHARACTER},
+ {CHARACTER, 0, 108, 165, CHARACTER},
+ {CHARACTER, 0, 105, 166, CHARACTER},
+ {CHARACTER, 0, 99, 167, CHARACTER},
+ {PUBLIC, 0, 0, 0, CHARACTER},
+ {CHARACTER, 30, 0, 0, CHARACTER},
+ {CHARACTER, 31, 0, 0, CHARACTER},
+ {CHARACTER, 0, 114, 171, CHARACTER},
+ {CHARACTER, 0, 116, 172, CHARACTER},
+ {EXPORT, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 116, 174, CHARACTER},
+ {CHARACTER, 0, 111, 175, CHARACTER},
+ {AUTO, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 105, 177, CHARACTER},
+ {CHARACTER, 0, 115, 178, CHARACTER},
+ {CHARACTER, 0, 116, 179, CHARACTER},
+ {CHARACTER, 0, 101, 180, CHARACTER},
+ {CHARACTER, 0, 114, 181, CHARACTER},
+ {REGISTER, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 101, 183, CHARACTER},
+ {CHARACTER, 0, 114, 184, CHARACTER},
+ {CHARACTER, 0, 110, 185, CHARACTER},
+ {EXTERN, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 116, 187, CHARACTER},
+ {CHARACTER, 0, 97, 188, CHARACTER},
+ {CHARACTER, 0, 98, 189, CHARACTER},
+ {CHARACTER, 0, 108, 190, CHARACTER},
+ {CHARACTER, 0, 101, 191, CHARACTER},
+ {MUTABLE, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 109, 193, CHARACTER},
+ {ASM, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 105, 195, CHARACTER},
+ {CHARACTER, 0, 110, 196, CHARACTER},
+ {CHARACTER, 0, 103, 197, CHARACTER},
+ {USING, 0, 0, 0, CHARACTER},
+ {CHARACTER, 32, 0, 0, CHARACTER},
+ {CHARACTER, 0, 105, 200, CHARACTER},
+ {CHARACTER, 0, 110, 201, CHARACTER},
+ {CHARACTER, 0, 101, 202, CHARACTER},
+ {INLINE, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 105, 204, CHARACTER},
+ {CHARACTER, 0, 99, 205, CHARACTER},
+ {CHARACTER, 0, 105, 206, CHARACTER},
+ {CHARACTER, 0, 116, 207, CHARACTER},
+ {EXPLICIT, 0, 0, 0, CHARACTER},
+ {CHARACTER, 33, 0, 0, CHARACTER},
+ {CHARACTER, 0, 97, 210, CHARACTER},
+ {CHARACTER, 0, 116, 211, CHARACTER},
+ {CHARACTER, 0, 105, 212, CHARACTER},
+ {CHARACTER, 0, 108, 213, CHARACTER},
+ {CHARACTER, 0, 101, 214, CHARACTER},
+ {VOLATILE, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 101, 216, CHARACTER},
+ {CHARACTER, 0, 114, 217, CHARACTER},
+ {CHARACTER, 0, 97, 218, CHARACTER},
+ {CHARACTER, 0, 116, 219, CHARACTER},
+ {CHARACTER, 0, 111, 220, CHARACTER},
+ {CHARACTER, 0, 114, 221, CHARACTER},
+ {OPERATOR, 0, 0, 0, CHARACTER},
+ {CHARACTER, 34, 0, 0, CHARACTER},
+ {CHARACTER, 0, 101, 224, CHARACTER},
+ {CHARACTER, 0, 111, 225, CHARACTER},
+ {CHARACTER, 0, 102, 226, CHARACTER},
+ {SIZEOF, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 119, 228, CHARACTER},
+ {NEW, 0, 0, 0, CHARACTER},
+ {CHARACTER, 35, 0, 0, CHARACTER},
+ {CHARACTER, 0, 101, 231, CHARACTER},
+ {CHARACTER, 0, 116, 232, CHARACTER},
+ {CHARACTER, 0, 101, 233, CHARACTER},
+ {DELETE, 0, 0, 0, CHARACTER},
+ {PLUS, 36, 0, 0, NOTOKEN},
+ {MINUS, 37, 0, 0, NOTOKEN},
+ {STAR, 0, 61, 257, NOTOKEN},
+ {SLASH, 38, 0, 0, NOTOKEN},
+ {HAT, 0, 61, 260, NOTOKEN},
+ {AND, 39, 0, 0, NOTOKEN},
+ {CHARACTER, 0, 116, 241, CHARACTER},
+ {CHARACTER, 40, 0, 0, CHARACTER},
+ {CHARACTER, 0, 110, 243, CHARACTER},
+ {CHARACTER, 0, 100, 244, CHARACTER},
+ {AND, 0, 0, 0, CHARACTER},
+ {OR, 41, 0, 0, NOTOKEN},
+ {CHARACTER, 0, 114, 247, CHARACTER},
+ {OR, 0, 0, 0, CHARACTER},
+ {TILDE, 0, 0, 0, NOTOKEN},
+ {CHARACTER, 0, 112, 250, CHARACTER},
+ {CHARACTER, 0, 108, 251, CHARACTER},
+ {TILDE, 0, 0, 0, CHARACTER},
+ {NOT, 0, 61, 268, NOTOKEN},
+ {CHARACTER, 0, 116, 254, CHARACTER},
+ {NOT, 0, 95, 269, CHARACTER},
+ {PLUS_EQ, 0, 0, 0, NOTOKEN},
+ {MINUS_EQ, 0, 0, 0, NOTOKEN},
+ {STAR_EQ, 0, 0, 0, NOTOKEN},
+ {SLASH_EQ, 0, 0, 0, NOTOKEN},
+ {PERCENT_EQ, 0, 0, 0, NOTOKEN},
+ {HAT_EQ, 0, 0, 0, NOTOKEN},
+ {AND_EQ, 0, 0, 0, NOTOKEN},
+ {OR_EQ, 0, 0, 0, NOTOKEN},
+ {LTLT, 0, 61, 266, NOTOKEN},
+ {GTGT, 0, 61, 265, NOTOKEN},
+ {GTGT_EQ, 0, 0, 0, NOTOKEN},
+ {LTLT_EQ, 0, 0, 0, NOTOKEN},
+ {EQEQ, 0, 0, 0, NOTOKEN},
+ {NE, 0, 0, 0, NOTOKEN},
+ {CHARACTER, 0, 101, 270, CHARACTER},
+ {CHARACTER, 0, 113, 271, CHARACTER},
+ {NE, 0, 0, 0, CHARACTER},
+ {LE, 0, 0, 0, NOTOKEN},
+ {GE, 0, 0, 0, NOTOKEN},
+ {ANDAND, 0, 0, 0, NOTOKEN},
+ {OROR, 0, 0, 0, NOTOKEN},
+ {INCR, 0, 0, 0, NOTOKEN},
+ {DECR, 0, 0, 0, NOTOKEN},
+ {ARROW, 0, 42, 279, NOTOKEN},
+ {ARROW_STAR, 0, 0, 0, NOTOKEN},
+ {CHARACTER, 0, 97, 281, CHARACTER},
+ {CHARACTER, 0, 114, 282, CHARACTER},
+ {CHAR, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 104, 284, CHARACTER},
+ {CHARACTER, 0, 97, 285, CHARACTER},
+ {CHARACTER, 0, 114, 286, CHARACTER},
+ {WCHAR, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 111, 288, CHARACTER},
+ {CHARACTER, 0, 108, 289, CHARACTER},
+ {BOOL, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 111, 291, CHARACTER},
+ {CHARACTER, 0, 114, 292, CHARACTER},
+ {CHARACTER, 0, 116, 293, CHARACTER},
+ {SHORT, 0, 0, 0, CHARACTER},
+ {INT, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 110, 296, CHARACTER},
+ {CHARACTER, 0, 103, 297, CHARACTER},
+ {LONG, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 110, 299, CHARACTER},
+ {CHARACTER, 42, 0, 0, CHARACTER},
+ {CHARACTER, 0, 100, 301, CHARACTER},
+ {SIGNED, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 105, 303, CHARACTER},
+ {CHARACTER, 0, 103, 304, CHARACTER},
+ {CHARACTER, 0, 110, 305, CHARACTER},
+ {CHARACTER, 0, 101, 306, CHARACTER},
+ {CHARACTER, 0, 100, 307, CHARACTER},
+ {UNSIGNED, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 111, 309, CHARACTER},
+ {CHARACTER, 0, 97, 310, CHARACTER},
+ {CHARACTER, 0, 116, 311, CHARACTER},
+ {FLOAT, 0, 0, 0, CHARACTER},
+ {DO, 0, 117, 313, CHARACTER},
+ {CHARACTER, 0, 98, 314, CHARACTER},
+ {CHARACTER, 0, 108, 315, CHARACTER},
+ {CHARACTER, 0, 101, 316, CHARACTER},
+ {DOUBLE, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 100, 318, CHARACTER},
+ {VOID, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 101, 320, CHARACTER},
+ {CASE, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 97, 322, CHARACTER},
+ {CHARACTER, 0, 117, 323, CHARACTER},
+ {CHARACTER, 0, 108, 324, CHARACTER},
+ {CHARACTER, 0, 116, 325, CHARACTER},
+ {DEFAULT, 0, 0, 0, CHARACTER},
+ {IF, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 115, 328, CHARACTER},
+ {CHARACTER, 0, 101, 329, CHARACTER},
+ {ELSE, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 105, 331, CHARACTER},
+ {CHARACTER, 0, 116, 332, CHARACTER},
+ {CHARACTER, 0, 99, 333, CHARACTER},
+ {CHARACTER, 0, 104, 334, CHARACTER},
+ {SWITCH, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 105, 336, CHARACTER},
+ {CHARACTER, 0, 108, 337, CHARACTER},
+ {CHARACTER, 0, 101, 338, CHARACTER},
+ {WHILE, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 114, 340, CHARACTER},
+ {FOR, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 101, 342, CHARACTER},
+ {CHARACTER, 0, 97, 343, CHARACTER},
+ {CHARACTER, 0, 107, 344, CHARACTER},
+ {BREAK, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 105, 346, CHARACTER},
+ {CHARACTER, 0, 110, 347, CHARACTER},
+ {CHARACTER, 0, 117, 348, CHARACTER},
+ {CHARACTER, 0, 101, 349, CHARACTER},
+ {CONTINUE, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 116, 351, CHARACTER},
+ {CHARACTER, 0, 111, 352, CHARACTER},
+ {GOTO, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 117, 354, CHARACTER},
+ {CHARACTER, 0, 114, 355, CHARACTER},
+ {CHARACTER, 0, 110, 356, CHARACTER},
+ {RETURN, 0, 0, 0, CHARACTER},
+ {CHARACTER, 43, 0, 0, CHARACTER},
+ {CHARACTER, 0, 66, 359, CHARACTER},
+ {CHARACTER, 0, 74, 360, CHARACTER},
+ {CHARACTER, 0, 69, 361, CHARACTER},
+ {CHARACTER, 0, 67, 362, CHARACTER},
+ {CHARACTER, 0, 84, 363, CHARACTER},
+ {Q_OBJECT_TOKEN, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 65, 365, CHARACTER},
+ {CHARACTER, 0, 68, 366, CHARACTER},
+ {CHARACTER, 0, 71, 367, CHARACTER},
+ {CHARACTER, 0, 69, 368, CHARACTER},
+ {CHARACTER, 0, 84, 369, CHARACTER},
+ {Q_GADGET_TOKEN, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 82, 371, CHARACTER},
+ {CHARACTER, 44, 0, 0, CHARACTER},
+ {CHARACTER, 0, 80, 373, CHARACTER},
+ {CHARACTER, 0, 69, 374, CHARACTER},
+ {CHARACTER, 0, 82, 375, CHARACTER},
+ {CHARACTER, 0, 84, 376, CHARACTER},
+ {CHARACTER, 0, 89, 377, CHARACTER},
+ {Q_PROPERTY_TOKEN, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 78, 379, CHARACTER},
+ {CHARACTER, 0, 85, 380, CHARACTER},
+ {CHARACTER, 0, 77, 381, CHARACTER},
+ {CHARACTER, 0, 83, 382, CHARACTER},
+ {Q_ENUMS_TOKEN, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 76, 384, CHARACTER},
+ {CHARACTER, 0, 65, 385, CHARACTER},
+ {CHARACTER, 0, 71, 386, CHARACTER},
+ {CHARACTER, 0, 83, 387, CHARACTER},
+ {Q_FLAGS_TOKEN, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 69, 389, CHARACTER},
+ {CHARACTER, 0, 67, 390, CHARACTER},
+ {CHARACTER, 0, 76, 391, CHARACTER},
+ {CHARACTER, 0, 65, 392, CHARACTER},
+ {CHARACTER, 0, 82, 393, CHARACTER},
+ {CHARACTER, 0, 69, 394, CHARACTER},
+ {CHARACTER, 0, 95, 395, CHARACTER},
+ {CHARACTER, 45, 0, 0, CHARACTER},
+ {CHARACTER, 0, 76, 397, CHARACTER},
+ {CHARACTER, 0, 65, 398, CHARACTER},
+ {CHARACTER, 0, 71, 399, CHARACTER},
+ {CHARACTER, 0, 83, 400, CHARACTER},
+ {Q_DECLARE_FLAGS_TOKEN, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 78, 402, CHARACTER},
+ {CHARACTER, 0, 84, 403, CHARACTER},
+ {CHARACTER, 0, 69, 404, CHARACTER},
+ {CHARACTER, 0, 82, 405, CHARACTER},
+ {CHARACTER, 0, 70, 406, CHARACTER},
+ {CHARACTER, 0, 65, 407, CHARACTER},
+ {CHARACTER, 0, 67, 408, CHARACTER},
+ {CHARACTER, 0, 69, 409, CHARACTER},
+ {Q_DECLARE_INTERFACE_TOKEN, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 69, 411, CHARACTER},
+ {CHARACTER, 0, 84, 412, CHARACTER},
+ {CHARACTER, 0, 65, 413, CHARACTER},
+ {CHARACTER, 0, 84, 414, CHARACTER},
+ {CHARACTER, 0, 89, 415, CHARACTER},
+ {CHARACTER, 0, 80, 416, CHARACTER},
+ {CHARACTER, 0, 69, 417, CHARACTER},
+ {Q_DECLARE_METATYPE_TOKEN, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 88, 419, CHARACTER},
+ {CHARACTER, 0, 84, 420, CHARACTER},
+ {CHARACTER, 0, 69, 421, CHARACTER},
+ {CHARACTER, 0, 78, 422, CHARACTER},
+ {CHARACTER, 0, 83, 423, CHARACTER},
+ {CHARACTER, 0, 73, 424, CHARACTER},
+ {CHARACTER, 0, 79, 425, CHARACTER},
+ {CHARACTER, 0, 78, 426, CHARACTER},
+ {CHARACTER, 0, 95, 427, CHARACTER},
+ {CHARACTER, 0, 73, 428, CHARACTER},
+ {CHARACTER, 0, 78, 429, CHARACTER},
+ {CHARACTER, 0, 84, 430, CHARACTER},
+ {CHARACTER, 0, 69, 431, CHARACTER},
+ {CHARACTER, 0, 82, 432, CHARACTER},
+ {CHARACTER, 0, 70, 433, CHARACTER},
+ {CHARACTER, 0, 65, 434, CHARACTER},
+ {CHARACTER, 0, 67, 435, CHARACTER},
+ {CHARACTER, 0, 69, 409, CHARACTER},
+ {CHARACTER, 46, 0, 0, CHARACTER},
+ {CHARACTER, 0, 84, 438, CHARACTER},
+ {CHARACTER, 0, 83, 387, CHARACTER},
+ {CHARACTER, 0, 76, 440, CHARACTER},
+ {CHARACTER, 0, 65, 441, CHARACTER},
+ {CHARACTER, 0, 83, 442, CHARACTER},
+ {CHARACTER, 0, 83, 443, CHARACTER},
+ {CHARACTER, 0, 73, 444, CHARACTER},
+ {CHARACTER, 0, 78, 445, CHARACTER},
+ {CHARACTER, 0, 70, 446, CHARACTER},
+ {CHARACTER, 0, 79, 447, CHARACTER},
+ {Q_CLASSINFO_TOKEN, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 78, 449, CHARACTER},
+ {CHARACTER, 47, 0, 0, CHARACTER},
+ {CHARACTER, 0, 69, 451, CHARACTER},
+ {CHARACTER, 0, 82, 452, CHARACTER},
+ {CHARACTER, 0, 70, 453, CHARACTER},
+ {CHARACTER, 0, 65, 454, CHARACTER},
+ {CHARACTER, 0, 67, 455, CHARACTER},
+ {CHARACTER, 0, 69, 456, CHARACTER},
+ {CHARACTER, 0, 83, 457, CHARACTER},
+ {Q_INTERFACES_TOKEN, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 108, 459, CHARACTER},
+ {CHARACTER, 0, 115, 460, CHARACTER},
+ {SIGNALS, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 111, 462, CHARACTER},
+ {CHARACTER, 0, 116, 463, CHARACTER},
+ {CHARACTER, 0, 115, 464, CHARACTER},
+ {SLOTS, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 71, 466, CHARACTER},
+ {CHARACTER, 0, 78, 467, CHARACTER},
+ {CHARACTER, 0, 65, 468, CHARACTER},
+ {CHARACTER, 0, 76, 469, CHARACTER},
+ {Q_SIGNAL_TOKEN, 0, 83, 470, CHARACTER},
+ {Q_SIGNALS_TOKEN, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 79, 472, CHARACTER},
+ {CHARACTER, 0, 84, 473, CHARACTER},
+ {Q_SLOT_TOKEN, 0, 83, 474, CHARACTER},
+ {Q_SLOTS_TOKEN, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 86, 476, CHARACTER},
+ {CHARACTER, 0, 65, 477, CHARACTER},
+ {CHARACTER, 0, 84, 478, CHARACTER},
+ {CHARACTER, 0, 69, 479, CHARACTER},
+ {CHARACTER, 0, 95, 480, CHARACTER},
+ {CHARACTER, 48, 0, 0, CHARACTER},
+ {CHARACTER, 0, 76, 482, CHARACTER},
+ {CHARACTER, 0, 79, 483, CHARACTER},
+ {CHARACTER, 0, 84, 484, CHARACTER},
+ {Q_PRIVATE_SLOT_TOKEN, 0, 0, 0, CHARACTER},
+ {CHARACTER, 49, 0, 0, CHARACTER},
+ {CHARACTER, 0, 77, 487, CHARACTER},
+ {CHARACTER, 0, 79, 488, CHARACTER},
+ {CHARACTER, 0, 67, 489, CHARACTER},
+ {CHARACTER, 0, 95, 490, CHARACTER},
+ {CHARACTER, 0, 67, 491, CHARACTER},
+ {CHARACTER, 0, 79, 492, CHARACTER},
+ {CHARACTER, 0, 77, 493, CHARACTER},
+ {CHARACTER, 0, 80, 494, CHARACTER},
+ {CHARACTER, 0, 65, 495, CHARACTER},
+ {CHARACTER, 0, 84, 496, CHARACTER},
+ {Q_MOC_COMPAT_TOKEN, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 95, 498, CHARACTER},
+ {CHARACTER, 0, 83, 499, CHARACTER},
+ {CHARACTER, 0, 85, 500, CHARACTER},
+ {CHARACTER, 0, 80, 501, CHARACTER},
+ {CHARACTER, 0, 80, 502, CHARACTER},
+ {CHARACTER, 0, 79, 503, CHARACTER},
+ {CHARACTER, 0, 82, 504, CHARACTER},
+ {CHARACTER, 0, 84, 505, CHARACTER},
+ {Q_QT3_SUPPORT_TOKEN, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 79, 507, CHARACTER},
+ {CHARACTER, 0, 75, 508, CHARACTER},
+ {CHARACTER, 0, 65, 509, CHARACTER},
+ {CHARACTER, 0, 66, 510, CHARACTER},
+ {CHARACTER, 0, 76, 511, CHARACTER},
+ {CHARACTER, 0, 69, 512, CHARACTER},
+ {Q_INVOKABLE_TOKEN, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 82, 514, CHARACTER},
+ {CHARACTER, 0, 73, 515, CHARACTER},
+ {CHARACTER, 0, 80, 516, CHARACTER},
+ {CHARACTER, 0, 84, 517, CHARACTER},
+ {CHARACTER, 0, 65, 518, CHARACTER},
+ {CHARACTER, 0, 66, 519, CHARACTER},
+ {CHARACTER, 0, 76, 520, CHARACTER},
+ {CHARACTER, 0, 69, 521, CHARACTER},
+ {Q_SCRIPTABLE_TOKEN, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 82, 523, CHARACTER},
+ {CHARACTER, 0, 79, 524, CHARACTER},
+ {CHARACTER, 0, 80, 525, CHARACTER},
+ {CHARACTER, 0, 69, 526, CHARACTER},
+ {CHARACTER, 0, 82, 527, CHARACTER},
+ {CHARACTER, 0, 84, 528, CHARACTER},
+ {CHARACTER, 0, 89, 529, CHARACTER},
+ {Q_PRIVATE_PROPERTY_TOKEN, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 69, 531, CHARACTER},
+ {CHARACTER, 0, 86, 532, CHARACTER},
+ {CHARACTER, 0, 73, 533, CHARACTER},
+ {CHARACTER, 0, 83, 534, CHARACTER},
+ {CHARACTER, 0, 73, 535, CHARACTER},
+ {CHARACTER, 0, 79, 536, CHARACTER},
+ {CHARACTER, 0, 78, 537, CHARACTER},
+ {Q_REVISION_TOKEN, 0, 0, 0, CHARACTER},
+ {NEWLINE, 0, 0, 0, NOTOKEN},
+ {QUOTE, 0, 0, 0, NOTOKEN},
+ {SINGLEQUOTE, 0, 0, 0, NOTOKEN},
+ {WHITESPACE, 0, 0, 0, NOTOKEN},
+ {HASH, 0, 0, 0, HASH},
+ {BACKSLASH, 0, 0, 0, NOTOKEN},
+ {CPP_COMMENT, 0, 0, 0, NOTOKEN},
+ {C_COMMENT, 0, 0, 0, NOTOKEN},
+ {FLOATING_LITERAL, 0, 0, 0, NOTOKEN}
+};
diff --git a/src/tools/moc/main.cpp b/src/tools/moc/main.cpp
new file mode 100644
index 0000000000..ecff10555a
--- /dev/null
+++ b/src/tools/moc/main.cpp
@@ -0,0 +1,448 @@
+/****************************************************************************
+**
+** 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 "preprocessor.h"
+#include "moc.h"
+#include "outputrevision.h"
+#include "../../corelib/global/qconfig.cpp"
+#include <QFile>
+#include <QFileInfo>
+#include <QDir>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+QT_BEGIN_NAMESPACE
+
+/*
+ This function looks at two file names and returns the name of the
+ infile with a path relative to outfile.
+
+ Examples:
+
+ /tmp/abc, /tmp/bcd -> abc
+ xyz/a/bc, xyz/b/ac -> ../a/bc
+ /tmp/abc, xyz/klm -> /tmp/abc
+ */
+
+static QByteArray combinePath(const char *infile, const char *outfile)
+{
+ QFileInfo inFileInfo(QDir::current(), QFile::decodeName(infile));
+ QFileInfo outFileInfo(QDir::current(), QFile::decodeName(outfile));
+ int numCommonComponents = 0;
+
+ QStringList inSplitted = inFileInfo.dir().canonicalPath().split(QLatin1Char('/'));
+ QStringList outSplitted = outFileInfo.dir().canonicalPath().split(QLatin1Char('/'));
+
+ while (!inSplitted.isEmpty() && !outSplitted.isEmpty() &&
+ inSplitted.first() == outSplitted.first()) {
+ inSplitted.removeFirst();
+ outSplitted.removeFirst();
+ numCommonComponents++;
+ }
+
+ if (numCommonComponents < 2)
+ /*
+ The paths don't have the same drive, or they don't have the
+ same root directory. Use an absolute path.
+ */
+ return QFile::encodeName(inFileInfo.absoluteFilePath());
+ /*
+ The paths have something in common. Use a path relative to
+ the output file.
+ */
+ while (!outSplitted.isEmpty()) {
+ outSplitted.removeFirst();
+ inSplitted.prepend(QLatin1String(".."));
+ }
+ inSplitted.append(inFileInfo.fileName());
+ return QFile::encodeName(inSplitted.join(QLatin1String("/")));
+}
+
+
+void error(const char *msg = "Invalid argument")
+{
+ if (msg)
+ fprintf(stderr, "moc: %s\n", msg);
+ fprintf(stderr, "Usage: moc [options] <header-file>\n"
+ " -o<file> write output to file rather than stdout\n"
+ " -I<dir> add dir to the include path for header files\n"
+ " -E preprocess only; do not generate meta object code\n"
+ " -D<macro>[=<def>] define macro, with optional definition\n"
+ " -U<macro> undefine macro\n"
+ " -i do not generate an #include statement\n"
+ " -p<path> path prefix for included file\n"
+ " -f[<file>] force #include, optional file name\n"
+ " -nn do not display notes\n"
+ " -nw do not display warnings\n"
+ " @<file> read additional options from file\n"
+ " -v display version of moc\n");
+ exit(1);
+}
+
+
+static inline bool hasNext(const Symbols &symbols, int i)
+{ return (i < symbols.size()); }
+
+static inline const Symbol &next(const Symbols &symbols, int &i)
+{ return symbols.at(i++); }
+
+
+QByteArray composePreprocessorOutput(const Symbols &symbols) {
+ QByteArray output;
+ int lineNum = 1;
+ Token last = PP_NOTOKEN;
+ Token secondlast = last;
+ int i = 0;
+ while (hasNext(symbols, i)) {
+ Symbol sym = next(symbols, i);
+ switch (sym.token) {
+ case PP_NEWLINE:
+ case PP_WHITESPACE:
+ if (last != PP_WHITESPACE) {
+ secondlast = last;
+ last = PP_WHITESPACE;
+ output += ' ';
+ }
+ continue;
+ case PP_STRING_LITERAL:
+ if (last == PP_STRING_LITERAL)
+ output.chop(1);
+ else if (secondlast == PP_STRING_LITERAL && last == PP_WHITESPACE)
+ output.chop(2);
+ else
+ break;
+ output += sym.lexem().mid(1);
+ secondlast = last;
+ last = PP_STRING_LITERAL;
+ continue;
+ case MOC_INCLUDE_BEGIN:
+ lineNum = 0;
+ continue;
+ case MOC_INCLUDE_END:
+ lineNum = sym.lineNum;
+ continue;
+ default:
+ break;
+ }
+ secondlast = last;
+ last = sym.token;
+
+ const int padding = sym.lineNum - lineNum;
+ if (padding > 0) {
+ output.resize(output.size() + padding);
+ qMemSet(output.data() + output.size() - padding, '\n', padding);
+ lineNum = sym.lineNum;
+ }
+
+ output += sym.lexem();
+ }
+
+ return output;
+}
+
+
+int runMoc(int _argc, char **_argv)
+{
+ bool autoInclude = true;
+ Preprocessor pp;
+ Moc moc;
+ pp.macros["Q_MOC_RUN"];
+ pp.macros["__cplusplus"];
+ QByteArray filename;
+ QByteArray output;
+ FILE *in = 0;
+ FILE *out = 0;
+ bool ignoreConflictingOptions = false;
+
+ QVector<QByteArray> argv;
+ argv.resize(_argc - 1);
+ for (int n = 1; n < _argc; ++n)
+ argv[n - 1] = _argv[n];
+ int argc = argv.count();
+
+ for (int n = 0; n < argv.count(); ++n) {
+ if (argv.at(n).startsWith('@')) {
+ QByteArray optionsFile = argv.at(n);
+ optionsFile.remove(0, 1);
+ if (optionsFile.isEmpty())
+ error("The @ option requires an input file");
+ QFile f(QString::fromLatin1(optionsFile.constData()));
+ if (!f.open(QIODevice::ReadOnly | QIODevice::Text))
+ error("Cannot open options file specified with @");
+ argv.remove(n);
+ while (!f.atEnd()) {
+ QByteArray line = f.readLine().trimmed();
+ if (!line.isEmpty())
+ argv.insert(n++, line);
+ }
+ }
+ }
+
+ argc = argv.count();
+
+ for (int n = 0; n < argc; ++n) {
+ QByteArray arg(argv[n]);
+ if (arg[0] != '-') {
+ if (filename.isEmpty()) {
+ filename = arg;
+ continue;
+ }
+ error("Too many input files specified");
+ }
+ QByteArray opt = arg.mid(1);
+ bool more = (opt.size() > 1);
+ switch (opt[0]) {
+ case 'o': // output redirection
+ if (!more) {
+ if (!(n < argc-1))
+ error("Missing output file name");
+ output = argv[++n];
+ } else
+ output = opt.mid(1);
+ break;
+ case 'E': // only preprocessor
+ pp.preprocessOnly = true;
+ break;
+ case 'i': // no #include statement
+ if (more)
+ error();
+ moc.noInclude = true;
+ autoInclude = false;
+ break;
+ case 'f': // produce #include statement
+ if (ignoreConflictingOptions)
+ break;
+ moc.noInclude = false;
+ autoInclude = false;
+ if (opt[1]) // -fsomething.h
+ moc.includeFiles.append(opt.mid(1));
+ break;
+ case 'p': // include file path
+ if (ignoreConflictingOptions)
+ break;
+ if (!more) {
+ if (!(n < argc-1))
+ error("Missing path name for the -p option.");
+ moc.includePath = argv[++n];
+ } else {
+ moc.includePath = opt.mid(1);
+ }
+ break;
+ case 'I': // produce #include statement
+ if (!more) {
+ if (!(n < argc-1))
+ error("Missing path name for the -I option.");
+ pp.includes += Preprocessor::IncludePath(argv[++n]);
+ } else {
+ pp.includes += Preprocessor::IncludePath(opt.mid(1));
+ }
+ break;
+ case 'F': // minimalistic framework support for the mac
+ if (!more) {
+ if (!(n < argc-1))
+ error("Missing path name for the -F option.");
+ Preprocessor::IncludePath p(argv[++n]);
+ p.isFrameworkPath = true;
+ pp.includes += p;
+ } else {
+ Preprocessor::IncludePath p(opt.mid(1));
+ p.isFrameworkPath = true;
+ pp.includes += p;
+ }
+ break;
+ case 'D': // define macro
+ {
+ QByteArray name;
+ QByteArray value("1");
+ if (!more) {
+ if (n < argc-1)
+ name = argv[++n];
+ } else
+ name = opt.mid(1);
+ int eq = name.indexOf('=');
+ if (eq >= 0) {
+ value = name.mid(eq + 1);
+ name = name.left(eq);
+ }
+ if (name.isEmpty())
+ error("Missing macro name");
+ Macro macro;
+ macro.symbols += Symbol(0, PP_IDENTIFIER, value);
+ pp.macros.insert(name, macro);
+
+ }
+ break;
+ case 'U':
+ {
+ QByteArray macro;
+ if (!more) {
+ if (n < argc-1)
+ macro = argv[++n];
+ } else
+ macro = opt.mid(1);
+ if (macro.isEmpty())
+ error("Missing macro name");
+ pp.macros.remove(macro);
+
+ }
+ break;
+ case 'v': // version number
+ if (more && opt != "version")
+ error();
+ fprintf(stderr, "Qt Meta Object Compiler version %d (Qt %s)\n",
+ mocOutputRevision, QT_VERSION_STR);
+ return 1;
+ case 'n': // don't display warnings
+ if (ignoreConflictingOptions)
+ break;
+ if (opt == "nw")
+ moc.displayWarnings = moc.displayNotes = false;
+ else if (opt == "nn")
+ moc.displayNotes = false;
+ else
+ error();
+ break;
+ case 'h': // help
+ if (more && opt != "help")
+ error();
+ else
+ error(0); // 0 means usage only
+ break;
+ case '-':
+ if (more && arg == "--ignore-option-clashes") {
+ // -- ignore all following moc specific options that conflict
+ // with for example gcc, like -pthread conflicting with moc's
+ // -p option.
+ ignoreConflictingOptions = true;
+ break;
+ }
+ // fall through
+ default:
+ error();
+ }
+ }
+
+
+ if (autoInclude) {
+ int spos = filename.lastIndexOf(QDir::separator().toLatin1());
+ int ppos = filename.lastIndexOf('.');
+ // spos >= -1 && ppos > spos => ppos >= 0
+ moc.noInclude = (ppos > spos && tolower(filename[ppos + 1]) != 'h');
+ }
+ if (moc.includeFiles.isEmpty()) {
+ if (moc.includePath.isEmpty()) {
+ if (filename.size()) {
+ if (output.size())
+ moc.includeFiles.append(combinePath(filename, output));
+ else
+ moc.includeFiles.append(filename);
+ }
+ } else {
+ moc.includeFiles.append(combinePath(filename, filename));
+ }
+ }
+
+ if (filename.isEmpty()) {
+ filename = "standard input";
+ in = stdin;
+ } else {
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+ if (fopen_s(&in, filename.data(), "rb")) {
+#else
+ in = fopen(filename.data(), "rb");
+ if (!in) {
+#endif
+ fprintf(stderr, "moc: %s: No such file\n", (const char*)filename);
+ return 1;
+ }
+ moc.filename = filename;
+ }
+
+ moc.currentFilenames.push(filename);
+
+ // 1. preprocess
+ moc.symbols = pp.preprocessed(moc.filename, in);
+ fclose(in);
+
+ if (!pp.preprocessOnly) {
+ // 2. parse
+ moc.parse();
+ }
+
+ // 3. and output meta object code
+
+ if (output.size()) { // output file specified
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+ if (fopen_s(&out, output.data(), "w"))
+#else
+ out = fopen(output.data(), "w"); // create output file
+ if (!out)
+#endif
+ {
+ fprintf(stderr, "moc: Cannot create %s\n", (const char*)output);
+ return 1;
+ }
+ } else { // use stdout
+ out = stdout;
+ }
+
+ if (pp.preprocessOnly) {
+ fprintf(out, "%s\n", composePreprocessorOutput(moc.symbols).constData());
+ } else {
+ if (moc.classList.isEmpty())
+ moc.note("No relevant classes found. No output generated.");
+ else
+ moc.generate(out);
+ }
+
+ if (output.size())
+ fclose(out);
+
+ return 0;
+}
+
+QT_END_NAMESPACE
+
+int main(int _argc, char **_argv)
+{
+ return QT_PREPEND_NAMESPACE(runMoc)(_argc, _argv);
+}
diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp
new file mode 100644
index 0000000000..4a2ba68b80
--- /dev/null
+++ b/src/tools/moc/moc.cpp
@@ -0,0 +1,1453 @@
+/****************************************************************************
+**
+** 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 "moc.h"
+#include "generator.h"
+#include "qdatetime.h"
+#include "utils.h"
+#include "outputrevision.h"
+
+// for normalizeTypeInternal
+#include <private/qmetaobject_p.h>
+
+QT_BEGIN_NAMESPACE
+
+// only moc needs this function
+static QByteArray normalizeType(const char *s, bool fixScope = false)
+{
+ int len = qstrlen(s);
+ char stackbuf[64];
+ char *buf = (len >= 64 ? new char[len + 1] : stackbuf);
+ char *d = buf;
+ char last = 0;
+ while(*s && is_space(*s))
+ s++;
+ while (*s) {
+ while (*s && !is_space(*s))
+ last = *d++ = *s++;
+ while (*s && is_space(*s))
+ s++;
+ if (*s && ((is_ident_char(*s) && is_ident_char(last))
+ || ((*s == ':') && (last == '<')))) {
+ last = *d++ = ' ';
+ }
+ }
+ *d = '\0';
+ QByteArray result;
+ if (strncmp("void", buf, d - buf) != 0)
+ result = normalizeTypeInternal(buf, d, fixScope);
+ if (buf != stackbuf)
+ delete [] buf;
+ return result;
+}
+
+bool Moc::parseClassHead(ClassDef *def)
+{
+ // figure out whether this is a class declaration, or only a
+ // forward or variable declaration.
+ int i = 0;
+ Token token;
+ do {
+ token = lookup(i++);
+ if (token == COLON || token == LBRACE)
+ break;
+ if (token == SEMIC || token == RANGLE)
+ return false;
+ } while (token);
+
+ if (!test(IDENTIFIER)) // typedef struct { ... }
+ return false;
+ QByteArray name = lexem();
+
+ // support "class IDENT name" and "class IDENT(IDENT) name"
+ if (test(LPAREN)) {
+ until(RPAREN);
+ if (!test(IDENTIFIER))
+ return false;
+ name = lexem();
+ } else if (test(IDENTIFIER)) {
+ name = lexem();
+ }
+
+ def->qualified += name;
+ while (test(SCOPE)) {
+ def->qualified += lexem();
+ if (test(IDENTIFIER)) {
+ name = lexem();
+ def->qualified += name;
+ }
+ }
+ def->classname = name;
+ if (test(COLON)) {
+ do {
+ test(VIRTUAL);
+ FunctionDef::Access access = FunctionDef::Public;
+ if (test(PRIVATE))
+ access = FunctionDef::Private;
+ else if (test(PROTECTED))
+ access = FunctionDef::Protected;
+ else
+ test(PUBLIC);
+ test(VIRTUAL);
+ const QByteArray type = parseType().name;
+ // ignore the 'class Foo : BAR(Baz)' case
+ if (test(LPAREN)) {
+ until(RPAREN);
+ } else {
+ def->superclassList += qMakePair(type, access);
+ }
+ } while (test(COMMA));
+ }
+ if (!test(LBRACE))
+ return false;
+ def->begin = index - 1;
+ bool foundRBrace = until(RBRACE);
+ def->end = index;
+ index = def->begin + 1;
+ return foundRBrace;
+}
+
+Type Moc::parseType()
+{
+ Type type;
+ bool hasSignedOrUnsigned = false;
+ bool isVoid = false;
+ type.firstToken = lookup();
+ for (;;) {
+ switch (next()) {
+ case SIGNED:
+ case UNSIGNED:
+ hasSignedOrUnsigned = true;
+ // fall through
+ case CONST:
+ case VOLATILE:
+ type.name += lexem();
+ type.name += ' ';
+ if (lookup(0) == VOLATILE)
+ type.isVolatile = true;
+ continue;
+ case Q_MOC_COMPAT_TOKEN:
+ case Q_QT3_SUPPORT_TOKEN:
+ case Q_INVOKABLE_TOKEN:
+ case Q_SCRIPTABLE_TOKEN:
+ case Q_SIGNALS_TOKEN:
+ case Q_SLOTS_TOKEN:
+ case Q_SIGNAL_TOKEN:
+ case Q_SLOT_TOKEN:
+ type.name += lexem();
+ return type;
+ default:
+ prev();
+ break;
+ }
+ break;
+ }
+ test(ENUM) || test(CLASS) || test(STRUCT);
+ for(;;) {
+ switch (next()) {
+ case IDENTIFIER:
+ // void mySlot(unsigned myArg)
+ if (hasSignedOrUnsigned) {
+ prev();
+ break;
+ }
+ case CHAR:
+ case SHORT:
+ case INT:
+ case LONG:
+ type.name += lexem();
+ // preserve '[unsigned] long long', 'short int', 'long int', 'long double'
+ if (test(LONG) || test(INT) || test(DOUBLE)) {
+ type.name += ' ';
+ prev();
+ continue;
+ }
+ break;
+ case FLOAT:
+ case DOUBLE:
+ case VOID:
+ case BOOL:
+ type.name += lexem();
+ isVoid |= (lookup(0) == VOID);
+ break;
+ default:
+ prev();
+ ;
+ }
+ if (test(LANGLE)) {
+ QByteArray templ = lexemUntil(RANGLE);
+ for (int i = 0; i < templ.size(); ++i) {
+ type.name += templ.at(i);
+ if ((templ.at(i) == '<' && i < templ.size()-1 && templ.at(i+1) == ':')
+ || (templ.at(i) == '>' && i < templ.size()-1 && templ.at(i+1) == '>')) {
+ type.name += ' ';
+ }
+ }
+ }
+ if (test(SCOPE)) {
+ type.name += lexem();
+ type.isScoped = true;
+ } else {
+ break;
+ }
+ }
+ while (test(CONST) || test(VOLATILE) || test(SIGNED) || test(UNSIGNED)
+ || test(STAR) || test(AND) || test(ANDAND)) {
+ type.name += ' ';
+ type.name += lexem();
+ if (lookup(0) == AND)
+ type.referenceType = Type::Reference;
+ else if (lookup(0) == ANDAND)
+ type.referenceType = Type::RValueReference;
+ else if (lookup(0) == STAR)
+ type.referenceType = Type::Pointer;
+ }
+ // transform stupid things like 'const void' or 'void const' into 'void'
+ if (isVoid && type.referenceType == Type::NoReference) {
+ type.name = "void";
+ }
+ return type;
+}
+
+bool Moc::parseEnum(EnumDef *def)
+{
+ bool isTypdefEnum = false; // typedef enum { ... } Foo;
+
+ if (test(IDENTIFIER)) {
+ def->name = lexem();
+ } else {
+ if (lookup(-1) != TYPEDEF)
+ return false; // anonymous enum
+ isTypdefEnum = true;
+ }
+ if (!test(LBRACE))
+ return false;
+ do {
+ if (lookup() == RBRACE) // accept trailing comma
+ break;
+ next(IDENTIFIER);
+ def->values += lexem();
+ } while (test(EQ) ? until(COMMA) : test(COMMA));
+ next(RBRACE);
+ if (isTypdefEnum) {
+ if (!test(IDENTIFIER))
+ return false;
+ def->name = lexem();
+ }
+ return true;
+}
+
+void Moc::parseFunctionArguments(FunctionDef *def)
+{
+ Q_UNUSED(def);
+ while (hasNext()) {
+ ArgumentDef arg;
+ arg.type = parseType();
+ if (arg.type.name == "void")
+ break;
+ if (test(IDENTIFIER))
+ arg.name = lexem();
+ while (test(LBRACK)) {
+ arg.rightType += lexemUntil(RBRACK);
+ }
+ if (test(CONST) || test(VOLATILE)) {
+ arg.rightType += ' ';
+ arg.rightType += lexem();
+ }
+ arg.normalizedType = normalizeType(QByteArray(arg.type.name + ' ' + arg.rightType));
+ arg.typeNameForCast = normalizeType(QByteArray(noRef(arg.type.name) + "(*)" + arg.rightType));
+ if (test(EQ))
+ arg.isDefault = true;
+ def->arguments += arg;
+ if (!until(COMMA))
+ break;
+ }
+}
+
+bool Moc::testFunctionAttribute(FunctionDef *def)
+{
+ if (index < symbols.size() && testFunctionAttribute(symbols.at(index).token, def)) {
+ ++index;
+ return true;
+ }
+ return false;
+}
+
+bool Moc::testFunctionAttribute(Token tok, FunctionDef *def)
+{
+ switch (tok) {
+ case Q_MOC_COMPAT_TOKEN:
+ case Q_QT3_SUPPORT_TOKEN:
+ def->isCompat = true;
+ return true;
+ case Q_INVOKABLE_TOKEN:
+ def->isInvokable = true;
+ return true;
+ case Q_SIGNAL_TOKEN:
+ def->isSignal = true;
+ return true;
+ case Q_SLOT_TOKEN:
+ def->isSlot = true;
+ return true;
+ case Q_SCRIPTABLE_TOKEN:
+ def->isInvokable = def->isScriptable = true;
+ return true;
+ default: break;
+ }
+ return false;
+}
+
+bool Moc::testFunctionRevision(FunctionDef *def)
+{
+ if (test(Q_REVISION_TOKEN)) {
+ next(LPAREN);
+ QByteArray revision = lexemUntil(RPAREN);
+ revision.remove(0, 1);
+ revision.chop(1);
+ bool ok = false;
+ def->revision = revision.toInt(&ok);
+ if (!ok || def->revision < 0)
+ error("Invalid revision");
+ return true;
+ }
+
+ return false;
+}
+
+// returns false if the function should be ignored
+bool Moc::parseFunction(FunctionDef *def, bool inMacro)
+{
+ def->isVirtual = false;
+ def->isStatic = false;
+ //skip modifiers and attributes
+ while (test(INLINE) || (test(STATIC) && (def->isStatic = true)) ||
+ (test(VIRTUAL) && (def->isVirtual = true)) //mark as virtual
+ || testFunctionAttribute(def) || testFunctionRevision(def)) {}
+ bool templateFunction = (lookup() == TEMPLATE);
+ def->type = parseType();
+ if (def->type.name.isEmpty()) {
+ if (templateFunction)
+ error("Template function as signal or slot");
+ else
+ error();
+ }
+ bool scopedFunctionName = false;
+ if (test(LPAREN)) {
+ def->name = def->type.name;
+ scopedFunctionName = def->type.isScoped;
+ def->type = Type("int");
+ } else {
+ Type tempType = parseType();;
+ while (!tempType.name.isEmpty() && lookup() != LPAREN) {
+ if (testFunctionAttribute(def->type.firstToken, def))
+ ; // fine
+ else if (def->type.firstToken == Q_SIGNALS_TOKEN)
+ error();
+ else if (def->type.firstToken == Q_SLOTS_TOKEN)
+ error();
+ else {
+ if (!def->tag.isEmpty())
+ def->tag += ' ';
+ def->tag += def->type.name;
+ }
+ def->type = tempType;
+ tempType = parseType();
+ }
+ next(LPAREN, "Not a signal or slot declaration");
+ def->name = tempType.name;
+ scopedFunctionName = tempType.isScoped;
+ }
+
+ // we don't support references as return types, it's too dangerous
+ if (def->type.referenceType == Type::Reference)
+ def->type = Type("void");
+
+ def->normalizedType = normalizeType(def->type.name);
+
+ if (!test(RPAREN)) {
+ parseFunctionArguments(def);
+ next(RPAREN);
+ }
+
+ // support optional macros with compiler specific options
+ while (test(IDENTIFIER))
+ ;
+
+ def->isConst = test(CONST);
+
+ while (test(IDENTIFIER))
+ ;
+
+ if (inMacro) {
+ next(RPAREN);
+ prev();
+ } else {
+ if (test(THROW)) {
+ next(LPAREN);
+ until(RPAREN);
+ }
+ if (test(SEMIC))
+ ;
+ else if ((def->inlineCode = test(LBRACE)))
+ until(RBRACE);
+ else if ((def->isAbstract = test(EQ)))
+ until(SEMIC);
+ else
+ error();
+ }
+
+ if (scopedFunctionName) {
+ QByteArray msg("Function declaration ");
+ msg += def->name;
+ msg += " contains extra qualification. Ignoring as signal or slot.";
+ warning(msg.constData());
+ return false;
+ }
+ return true;
+}
+
+// like parseFunction, but never aborts with an error
+bool Moc::parseMaybeFunction(const ClassDef *cdef, FunctionDef *def)
+{
+ def->isVirtual = false;
+ def->isStatic = false;
+ //skip modifiers and attributes
+ while (test(EXPLICIT) || test(INLINE) || (test(STATIC) && (def->isStatic = true)) ||
+ (test(VIRTUAL) && (def->isVirtual = true)) //mark as virtual
+ || testFunctionAttribute(def) || testFunctionRevision(def)) {}
+ bool tilde = test(TILDE);
+ def->type = parseType();
+ if (def->type.name.isEmpty())
+ return false;
+ bool scopedFunctionName = false;
+ if (test(LPAREN)) {
+ def->name = def->type.name;
+ scopedFunctionName = def->type.isScoped;
+ if (def->name == cdef->classname) {
+ def->isDestructor = tilde;
+ def->isConstructor = !tilde;
+ def->type = Type();
+ } else {
+ def->type = Type("int");
+ }
+ } else {
+ Type tempType = parseType();;
+ while (!tempType.name.isEmpty() && lookup() != LPAREN) {
+ if (testFunctionAttribute(def->type.firstToken, def))
+ ; // fine
+ else if (def->type.name == "Q_SIGNAL")
+ def->isSignal = true;
+ else if (def->type.name == "Q_SLOT")
+ def->isSlot = true;
+ else {
+ if (!def->tag.isEmpty())
+ def->tag += ' ';
+ def->tag += def->type.name;
+ }
+ def->type = tempType;
+ tempType = parseType();
+ }
+ if (!test(LPAREN))
+ return false;
+ def->name = tempType.name;
+ scopedFunctionName = tempType.isScoped;
+ }
+
+ // we don't support references as return types, it's too dangerous
+ if (def->type.referenceType == Type::Reference)
+ def->type = Type("void");
+
+ def->normalizedType = normalizeType(def->type.name);
+
+ if (!test(RPAREN)) {
+ parseFunctionArguments(def);
+ if (!test(RPAREN))
+ return false;
+ }
+ def->isConst = test(CONST);
+ if (scopedFunctionName
+ && (def->isSignal || def->isSlot || def->isInvokable)) {
+ QByteArray msg("parsemaybe: Function declaration ");
+ msg += def->name;
+ msg += " contains extra qualification. Ignoring as signal or slot.";
+ warning(msg.constData());
+ return false;
+ }
+ return true;
+}
+
+
+void Moc::parse()
+{
+ QList<NamespaceDef> namespaceList;
+ bool templateClass = false;
+ while (hasNext()) {
+ Token t = next();
+ switch (t) {
+ case NAMESPACE: {
+ int rewind = index;
+ if (test(IDENTIFIER)) {
+ if (test(EQ)) {
+ // namespace Foo = Bar::Baz;
+ until(SEMIC);
+ } else if (!test(SEMIC)) {
+ NamespaceDef def;
+ def.name = lexem();
+ next(LBRACE);
+ def.begin = index - 1;
+ until(RBRACE);
+ def.end = index;
+ index = def.begin + 1;
+ namespaceList += def;
+ index = rewind;
+ }
+ }
+ break;
+ }
+ case SEMIC:
+ case RBRACE:
+ templateClass = false;
+ break;
+ case TEMPLATE:
+ templateClass = true;
+ break;
+ case MOC_INCLUDE_BEGIN:
+ currentFilenames.push(symbol().unquotedLexem());
+ break;
+ case MOC_INCLUDE_END:
+ currentFilenames.pop();
+ break;
+ case Q_DECLARE_INTERFACE_TOKEN:
+ parseDeclareInterface();
+ break;
+ case Q_DECLARE_METATYPE_TOKEN:
+ parseDeclareMetatype();
+ break;
+ case USING:
+ if (test(NAMESPACE)) {
+ while (test(SCOPE) || test(IDENTIFIER))
+ ;
+ next(SEMIC);
+ }
+ break;
+ case CLASS:
+ case STRUCT: {
+ if (currentFilenames.size() <= 1)
+ break;
+
+ ClassDef def;
+ if (!parseClassHead(&def))
+ continue;
+
+ while (inClass(&def) && hasNext()) {
+ if (next() == Q_OBJECT_TOKEN) {
+ def.hasQObject = true;
+ break;
+ }
+ }
+
+ if (!def.hasQObject)
+ continue;
+
+ for (int i = namespaceList.size() - 1; i >= 0; --i)
+ if (inNamespace(&namespaceList.at(i)))
+ def.qualified.prepend(namespaceList.at(i).name + "::");
+
+ knownQObjectClasses.insert(def.classname);
+ knownQObjectClasses.insert(def.qualified);
+
+ continue; }
+ default: break;
+ }
+ if ((t != CLASS && t != STRUCT)|| currentFilenames.size() > 1)
+ continue;
+ ClassDef def;
+ if (parseClassHead(&def)) {
+ FunctionDef::Access access = FunctionDef::Private;
+ for (int i = namespaceList.size() - 1; i >= 0; --i)
+ if (inNamespace(&namespaceList.at(i)))
+ def.qualified.prepend(namespaceList.at(i).name + "::");
+ while (inClass(&def) && hasNext()) {
+ switch ((t = next())) {
+ case PRIVATE:
+ access = FunctionDef::Private;
+ if (test(Q_SIGNALS_TOKEN))
+ error("Signals cannot have access specifier");
+ break;
+ case PROTECTED:
+ access = FunctionDef::Protected;
+ if (test(Q_SIGNALS_TOKEN))
+ error("Signals cannot have access specifier");
+ break;
+ case PUBLIC:
+ access = FunctionDef::Public;
+ if (test(Q_SIGNALS_TOKEN))
+ error("Signals cannot have access specifier");
+ break;
+ case CLASS: {
+ ClassDef nestedDef;
+ if (parseClassHead(&nestedDef)) {
+ while (inClass(&nestedDef) && inClass(&def)) {
+ t = next();
+ if (t >= Q_META_TOKEN_BEGIN && t < Q_META_TOKEN_END)
+ error("Meta object features not supported for nested classes");
+ }
+ }
+ } break;
+ case Q_SIGNALS_TOKEN:
+ parseSignals(&def);
+ break;
+ case Q_SLOTS_TOKEN:
+ switch (lookup(-1)) {
+ case PUBLIC:
+ case PROTECTED:
+ case PRIVATE:
+ parseSlots(&def, access);
+ break;
+ default:
+ error("Missing access specifier for slots");
+ }
+ break;
+ case Q_OBJECT_TOKEN:
+ def.hasQObject = true;
+ if (templateClass)
+ error("Template classes not supported by Q_OBJECT");
+ if (def.classname != "Qt" && def.classname != "QObject" && def.superclassList.isEmpty())
+ error("Class contains Q_OBJECT macro but does not inherit from QObject");
+ break;
+ case Q_GADGET_TOKEN:
+ def.hasQGadget = true;
+ if (templateClass)
+ error("Template classes not supported by Q_GADGET");
+ break;
+ case Q_PROPERTY_TOKEN:
+ parseProperty(&def);
+ break;
+ case Q_ENUMS_TOKEN:
+ parseEnumOrFlag(&def, false);
+ break;
+ case Q_FLAGS_TOKEN:
+ parseEnumOrFlag(&def, true);
+ break;
+ case Q_DECLARE_FLAGS_TOKEN:
+ parseFlag(&def);
+ break;
+ case Q_CLASSINFO_TOKEN:
+ parseClassInfo(&def);
+ break;
+ case Q_INTERFACES_TOKEN:
+ parseInterfaces(&def);
+ break;
+ case Q_PRIVATE_SLOT_TOKEN:
+ parseSlotInPrivate(&def, access);
+ break;
+ case Q_PRIVATE_PROPERTY_TOKEN:
+ parsePrivateProperty(&def);
+ break;
+ case ENUM: {
+ EnumDef enumDef;
+ if (parseEnum(&enumDef))
+ def.enumList += enumDef;
+ } break;
+ case SEMIC:
+ case COLON:
+ break;
+ default:
+ FunctionDef funcDef;
+ funcDef.access = access;
+ int rewind = index--;
+ if (parseMaybeFunction(&def, &funcDef)) {
+ if (funcDef.isConstructor) {
+ if ((access == FunctionDef::Public) && funcDef.isInvokable) {
+ def.constructorList += funcDef;
+ while (funcDef.arguments.size() > 0 && funcDef.arguments.last().isDefault) {
+ funcDef.wasCloned = true;
+ funcDef.arguments.removeLast();
+ def.constructorList += funcDef;
+ }
+ }
+ } else if (funcDef.isDestructor) {
+ // don't care about destructors
+ } else {
+ if (access == FunctionDef::Public)
+ def.publicList += funcDef;
+ if (funcDef.isSlot) {
+ def.slotList += funcDef;
+ while (funcDef.arguments.size() > 0 && funcDef.arguments.last().isDefault) {
+ funcDef.wasCloned = true;
+ funcDef.arguments.removeLast();
+ def.slotList += funcDef;
+ }
+ if (funcDef.revision > 0)
+ ++def.revisionedMethods;
+ } else if (funcDef.isSignal) {
+ def.signalList += funcDef;
+ while (funcDef.arguments.size() > 0 && funcDef.arguments.last().isDefault) {
+ funcDef.wasCloned = true;
+ funcDef.arguments.removeLast();
+ def.signalList += funcDef;
+ }
+ if (funcDef.revision > 0)
+ ++def.revisionedMethods;
+ } else if (funcDef.isInvokable) {
+ def.methodList += funcDef;
+ while (funcDef.arguments.size() > 0 && funcDef.arguments.last().isDefault) {
+ funcDef.wasCloned = true;
+ funcDef.arguments.removeLast();
+ def.methodList += funcDef;
+ }
+ if (funcDef.revision > 0)
+ ++def.revisionedMethods;
+ }
+ }
+ } else {
+ index = rewind;
+ }
+ }
+ }
+
+ next(RBRACE);
+
+ if (!def.hasQObject && !def.hasQGadget && def.signalList.isEmpty() && def.slotList.isEmpty()
+ && def.propertyList.isEmpty() && def.enumDeclarations.isEmpty())
+ continue; // no meta object code required
+
+
+ if (!def.hasQObject && !def.hasQGadget)
+ error("Class declarations lacks Q_OBJECT macro.");
+
+ checkSuperClasses(&def);
+ checkProperties(&def);
+
+ classList += def;
+ knownQObjectClasses.insert(def.classname);
+ knownQObjectClasses.insert(def.qualified);
+ }
+ }
+}
+
+void Moc::generate(FILE *out)
+{
+
+ QDateTime dt = QDateTime::currentDateTime();
+ QByteArray dstr = dt.toString().toLatin1();
+ QByteArray fn = filename;
+ int i = filename.length()-1;
+ while (i>0 && filename[i-1] != '/' && filename[i-1] != '\\')
+ --i; // skip path
+ if (i >= 0)
+ fn = filename.mid(i);
+ fprintf(out, "/****************************************************************************\n"
+ "** Meta object code from reading C++ file '%s'\n**\n" , (const char*)fn);
+ fprintf(out, "** Created: %s\n"
+ "** by: The Qt Meta Object Compiler version %d (Qt %s)\n**\n" , dstr.data(), mocOutputRevision, QT_VERSION_STR);
+ fprintf(out, "** WARNING! All changes made in this file will be lost!\n"
+ "*****************************************************************************/\n\n");
+
+
+ if (!noInclude) {
+ if (includePath.size() && !includePath.endsWith('/'))
+ includePath += '/';
+ for (int i = 0; i < includeFiles.size(); ++i) {
+ QByteArray inc = includeFiles.at(i);
+ if (inc[0] != '<' && inc[0] != '"') {
+ if (includePath.size() && includePath != "./")
+ inc.prepend(includePath);
+ inc = '\"' + inc + '\"';
+ }
+ fprintf(out, "#include %s\n", inc.constData());
+ }
+ }
+ if (classList.size() && classList.first().classname == "Qt")
+ fprintf(out, "#include <QtCore/qobject.h>\n");
+
+ if (mustIncludeQMetaTypeH)
+ fprintf(out, "#include <QtCore/qmetatype.h>\n");
+
+ fprintf(out, "#if !defined(Q_MOC_OUTPUT_REVISION)\n"
+ "#error \"The header file '%s' doesn't include <QObject>.\"\n", (const char *)fn);
+ fprintf(out, "#elif Q_MOC_OUTPUT_REVISION != %d\n", mocOutputRevision);
+ fprintf(out, "#error \"This file was generated using the moc from %s."
+ " It\"\n#error \"cannot be used with the include files from"
+ " this version of Qt.\"\n#error \"(The moc has changed too"
+ " much.)\"\n", QT_VERSION_STR);
+ fprintf(out, "#endif\n\n");
+
+ fprintf(out, "QT_BEGIN_MOC_NAMESPACE\n");
+
+ for (i = 0; i < classList.size(); ++i) {
+ Generator generator(&classList[i], metaTypes, out);
+ generator.generateCode();
+ }
+
+ fprintf(out, "QT_END_MOC_NAMESPACE\n");
+}
+
+
+QList<QMetaObject*> Moc::generate(bool ignoreProperties)
+{
+ QList<QMetaObject*> result;
+ for (int i = 0; i < classList.size(); ++i) {
+ Generator generator(&classList[i], metaTypes);
+ result << generator.generateMetaObject(ignoreProperties);
+ }
+ return result;
+}
+
+void Moc::parseSlots(ClassDef *def, FunctionDef::Access access)
+{
+ int defaultRevision = -1;
+ if (test(Q_REVISION_TOKEN)) {
+ next(LPAREN);
+ QByteArray revision = lexemUntil(RPAREN);
+ revision.remove(0, 1);
+ revision.chop(1);
+ bool ok = false;
+ defaultRevision = revision.toInt(&ok);
+ if (!ok || defaultRevision < 0)
+ error("Invalid revision");
+ }
+
+ next(COLON);
+ while (inClass(def) && hasNext()) {
+ switch (next()) {
+ case PUBLIC:
+ case PROTECTED:
+ case PRIVATE:
+ case Q_SIGNALS_TOKEN:
+ case Q_SLOTS_TOKEN:
+ prev();
+ return;
+ case SEMIC:
+ continue;
+ case FRIEND:
+ until(SEMIC);
+ continue;
+ case USING:
+ error("'using' directive not supported in 'slots' section");
+ default:
+ prev();
+ }
+
+ FunctionDef funcDef;
+ funcDef.access = access;
+ if (!parseFunction(&funcDef))
+ continue;
+ if (funcDef.revision > 0) {
+ ++def->revisionedMethods;
+ } else if (defaultRevision != -1) {
+ funcDef.revision = defaultRevision;
+ ++def->revisionedMethods;
+ }
+ def->slotList += funcDef;
+ while (funcDef.arguments.size() > 0 && funcDef.arguments.last().isDefault) {
+ funcDef.wasCloned = true;
+ funcDef.arguments.removeLast();
+ def->slotList += funcDef;
+ }
+ }
+}
+
+void Moc::parseSignals(ClassDef *def)
+{
+ int defaultRevision = -1;
+ if (test(Q_REVISION_TOKEN)) {
+ next(LPAREN);
+ QByteArray revision = lexemUntil(RPAREN);
+ revision.remove(0, 1);
+ revision.chop(1);
+ bool ok = false;
+ defaultRevision = revision.toInt(&ok);
+ if (!ok || defaultRevision < 0)
+ error("Invalid revision");
+ }
+
+ next(COLON);
+ while (inClass(def) && hasNext()) {
+ switch (next()) {
+ case PUBLIC:
+ case PROTECTED:
+ case PRIVATE:
+ case Q_SIGNALS_TOKEN:
+ case Q_SLOTS_TOKEN:
+ prev();
+ return;
+ case SEMIC:
+ continue;
+ case FRIEND:
+ until(SEMIC);
+ continue;
+ case USING:
+ error("'using' directive not supported in 'signals' section");
+ default:
+ prev();
+ }
+ FunctionDef funcDef;
+ funcDef.access = FunctionDef::Protected;
+ parseFunction(&funcDef);
+ if (funcDef.isVirtual)
+ warning("Signals cannot be declared virtual");
+ if (funcDef.inlineCode)
+ error("Not a signal declaration");
+ if (funcDef.revision > 0) {
+ ++def->revisionedMethods;
+ } else if (defaultRevision != -1) {
+ funcDef.revision = defaultRevision;
+ ++def->revisionedMethods;
+ }
+ def->signalList += funcDef;
+ while (funcDef.arguments.size() > 0 && funcDef.arguments.last().isDefault) {
+ funcDef.wasCloned = true;
+ funcDef.arguments.removeLast();
+ def->signalList += funcDef;
+ }
+ }
+}
+
+void Moc::createPropertyDef(PropertyDef &propDef)
+{
+ QByteArray type = parseType().name;
+ if (type.isEmpty())
+ error();
+ propDef.designable = propDef.scriptable = propDef.stored = "true";
+ propDef.user = "false";
+ /*
+ The Q_PROPERTY construct cannot contain any commas, since
+ commas separate macro arguments. We therefore expect users
+ to type "QMap" instead of "QMap<QString, QVariant>". For
+ coherence, we also expect the same for
+ QValueList<QVariant>, the other template class supported by
+ QVariant.
+ */
+ type = normalizeType(type);
+ if (type == "QMap")
+ type = "QMap<QString,QVariant>";
+ else if (type == "QValueList")
+ type = "QValueList<QVariant>";
+ else if (type == "LongLong")
+ type = "qlonglong";
+ else if (type == "ULongLong")
+ type = "qulonglong";
+ else if (type == "qreal")
+ mustIncludeQMetaTypeH = true;
+
+ propDef.type = type;
+
+ next();
+ propDef.name = lexem();
+ while (test(IDENTIFIER)) {
+ QByteArray l = lexem();
+ if (l[0] == 'C' && l == "CONSTANT") {
+ propDef.constant = true;
+ continue;
+ } else if(l[0] == 'F' && l == "FINAL") {
+ propDef.final = true;
+ continue;
+ }
+
+ QByteArray v, v2;
+ if (test(LPAREN)) {
+ v = lexemUntil(RPAREN);
+ } else if (test(INTEGER_LITERAL)) {
+ v = lexem();
+ if (l != "REVISION")
+ error(1);
+ } else {
+ next(IDENTIFIER);
+ v = lexem();
+ if (test(LPAREN))
+ v2 = lexemUntil(RPAREN);
+ else if (v != "true" && v != "false")
+ v2 = "()";
+ }
+ switch (l[0]) {
+ case 'R':
+ if (l == "READ")
+ propDef.read = v;
+ else if (l == "RESET")
+ propDef.reset = v + v2;
+ else if (l == "REVISION") {
+ bool ok = false;
+ propDef.revision = v.toInt(&ok);
+ if (!ok || propDef.revision < 0)
+ error(1);
+ } else
+ error(2);
+ break;
+ case 'S':
+ if (l == "SCRIPTABLE")
+ propDef.scriptable = v + v2;
+ else if (l == "STORED")
+ propDef.stored = v + v2;
+ else
+ error(2);
+ break;
+ case 'W': if (l != "WRITE") error(2);
+ propDef.write = v;
+ break;
+ case 'D': if (l != "DESIGNABLE") error(2);
+ propDef.designable = v + v2;
+ break;
+ case 'E': if (l != "EDITABLE") error(2);
+ propDef.editable = v + v2;
+ break;
+ case 'N': if (l != "NOTIFY") error(2);
+ propDef.notify = v;
+ break;
+ case 'U': if (l != "USER") error(2);
+ propDef.user = v + v2;
+ break;
+ default:
+ error(2);
+ }
+ }
+ if (propDef.read.isNull()) {
+ QByteArray msg;
+ msg += "Property declaration ";
+ msg += propDef.name;
+ msg += " has no READ accessor function. The property will be invalid.";
+ warning(msg.constData());
+ }
+ if (propDef.constant && !propDef.write.isNull()) {
+ QByteArray msg;
+ msg += "Property declaration ";
+ msg += propDef.name;
+ msg += " is both WRITEable and CONSTANT. CONSTANT will be ignored.";
+ propDef.constant = false;
+ warning(msg.constData());
+ }
+ if (propDef.constant && !propDef.notify.isNull()) {
+ QByteArray msg;
+ msg += "Property declaration ";
+ msg += propDef.name;
+ msg += " is both NOTIFYable and CONSTANT. CONSTANT will be ignored.";
+ propDef.constant = false;
+ warning(msg.constData());
+ }
+}
+
+void Moc::parseProperty(ClassDef *def)
+{
+ next(LPAREN);
+ PropertyDef propDef;
+ createPropertyDef(propDef);
+ next(RPAREN);
+
+
+ if(!propDef.notify.isEmpty())
+ def->notifyableProperties++;
+ if (propDef.revision > 0)
+ ++def->revisionedProperties;
+ def->propertyList += propDef;
+}
+
+void Moc::parsePrivateProperty(ClassDef *def)
+{
+ next(LPAREN);
+ PropertyDef propDef;
+ next(IDENTIFIER);
+ propDef.inPrivateClass = lexem();
+ while (test(SCOPE)) {
+ propDef.inPrivateClass += lexem();
+ next(IDENTIFIER);
+ propDef.inPrivateClass += lexem();
+ }
+ // also allow void functions
+ if (test(LPAREN)) {
+ next(RPAREN);
+ propDef.inPrivateClass += "()";
+ }
+
+ next(COMMA);
+
+ createPropertyDef(propDef);
+
+ if(!propDef.notify.isEmpty())
+ def->notifyableProperties++;
+ if (propDef.revision > 0)
+ ++def->revisionedProperties;
+
+ def->propertyList += propDef;
+}
+
+void Moc::parseEnumOrFlag(ClassDef *def, bool isFlag)
+{
+ next(LPAREN);
+ QByteArray identifier;
+ while (test(IDENTIFIER)) {
+ identifier = lexem();
+ while (test(SCOPE) && test(IDENTIFIER)) {
+ identifier += "::";
+ identifier += lexem();
+ }
+ def->enumDeclarations[identifier] = isFlag;
+ }
+ next(RPAREN);
+}
+
+void Moc::parseFlag(ClassDef *def)
+{
+ next(LPAREN);
+ QByteArray flagName, enumName;
+ while (test(IDENTIFIER)) {
+ flagName = lexem();
+ while (test(SCOPE) && test(IDENTIFIER)) {
+ flagName += "::";
+ flagName += lexem();
+ }
+ }
+ next(COMMA);
+ while (test(IDENTIFIER)) {
+ enumName = lexem();
+ while (test(SCOPE) && test(IDENTIFIER)) {
+ enumName += "::";
+ enumName += lexem();
+ }
+ }
+
+ def->flagAliases.insert(enumName, flagName);
+ next(RPAREN);
+}
+
+void Moc::parseClassInfo(ClassDef *def)
+{
+ next(LPAREN);
+ ClassInfoDef infoDef;
+ next(STRING_LITERAL);
+ infoDef.name = symbol().unquotedLexem();
+ next(COMMA);
+ if (test(STRING_LITERAL)) {
+ infoDef.value = symbol().unquotedLexem();
+ } else {
+ // support Q_CLASSINFO("help", QT_TR_NOOP("blah"))
+ next(IDENTIFIER);
+ next(LPAREN);
+ next(STRING_LITERAL);
+ infoDef.value = symbol().unquotedLexem();
+ next(RPAREN);
+ }
+ next(RPAREN);
+ def->classInfoList += infoDef;
+}
+
+void Moc::parseInterfaces(ClassDef *def)
+{
+ next(LPAREN);
+ while (test(IDENTIFIER)) {
+ QList<ClassDef::Interface> iface;
+ iface += ClassDef::Interface(lexem());
+ while (test(SCOPE)) {
+ iface.last().className += lexem();
+ next(IDENTIFIER);
+ iface.last().className += lexem();
+ }
+ while (test(COLON)) {
+ next(IDENTIFIER);
+ iface += ClassDef::Interface(lexem());
+ while (test(SCOPE)) {
+ iface.last().className += lexem();
+ next(IDENTIFIER);
+ iface.last().className += lexem();
+ }
+ }
+ // resolve from classnames to interface ids
+ for (int i = 0; i < iface.count(); ++i) {
+ const QByteArray iid = interface2IdMap.value(iface.at(i).className);
+ if (iid.isEmpty())
+ error("Undefined interface");
+
+ iface[i].interfaceId = iid;
+ }
+ def->interfaceList += iface;
+ }
+ next(RPAREN);
+}
+
+void Moc::parseDeclareInterface()
+{
+ next(LPAREN);
+ QByteArray interface;
+ next(IDENTIFIER);
+ interface += lexem();
+ while (test(SCOPE)) {
+ interface += lexem();
+ next(IDENTIFIER);
+ interface += lexem();
+ }
+ next(COMMA);
+ QByteArray iid;
+ if (test(STRING_LITERAL)) {
+ iid = lexem();
+ } else {
+ next(IDENTIFIER);
+ iid = lexem();
+ }
+ interface2IdMap.insert(interface, iid);
+ next(RPAREN);
+}
+
+void Moc::parseDeclareMetatype()
+{
+ next(LPAREN);
+ QByteArray typeName = lexemUntil(RPAREN);
+ typeName.remove(0, 1);
+ typeName.chop(1);
+ metaTypes.append(typeName);
+}
+
+void Moc::parseSlotInPrivate(ClassDef *def, FunctionDef::Access access)
+{
+ next(LPAREN);
+ FunctionDef funcDef;
+ next(IDENTIFIER);
+ funcDef.inPrivateClass = lexem();
+ // also allow void functions
+ if (test(LPAREN)) {
+ next(RPAREN);
+ funcDef.inPrivateClass += "()";
+ }
+ next(COMMA);
+ funcDef.access = access;
+ parseFunction(&funcDef, true);
+ def->slotList += funcDef;
+ while (funcDef.arguments.size() > 0 && funcDef.arguments.last().isDefault) {
+ funcDef.wasCloned = true;
+ funcDef.arguments.removeLast();
+ def->slotList += funcDef;
+ }
+ if (funcDef.revision > 0)
+ ++def->revisionedMethods;
+
+}
+
+QByteArray Moc::lexemUntil(Token target)
+{
+ int from = index;
+ until(target);
+ QByteArray s;
+ while (from <= index) {
+ QByteArray n = symbols.at(from++-1).lexem();
+ if (s.size() && n.size()
+ && is_ident_char(s.at(s.size()-1))
+ && is_ident_char(n.at(0)))
+ s += ' ';
+ s += n;
+ }
+ return s;
+}
+
+bool Moc::until(Token target) {
+ int braceCount = 0;
+ int brackCount = 0;
+ int parenCount = 0;
+ int angleCount = 0;
+ if (index) {
+ switch(symbols.at(index-1).token) {
+ case LBRACE: ++braceCount; break;
+ case LBRACK: ++brackCount; break;
+ case LPAREN: ++parenCount; break;
+ case LANGLE: ++angleCount; break;
+ default: break;
+ }
+ }
+
+ //when searching commas within the default argument, we should take care of template depth (anglecount)
+ // unfortunatelly, we do not have enough semantic information to know if '<' is the operator< or
+ // the beginning of a template type. so we just use heuristics.
+ int possible = -1;
+
+ while (index < symbols.size()) {
+ Token t = symbols.at(index++).token;
+ switch (t) {
+ case LBRACE: ++braceCount; break;
+ case RBRACE: --braceCount; break;
+ case LBRACK: ++brackCount; break;
+ case RBRACK: --brackCount; break;
+ case LPAREN: ++parenCount; break;
+ case RPAREN: --parenCount; break;
+ case LANGLE: ++angleCount; break;
+ case RANGLE: --angleCount; break;
+ case GTGT: angleCount -= 2; t = RANGLE; break;
+ default: break;
+ }
+ if (t == target
+ && braceCount <= 0
+ && brackCount <= 0
+ && parenCount <= 0
+ && (target != RANGLE || angleCount <= 0)) {
+ if (target != COMMA || angleCount <= 0)
+ return true;
+ possible = index;
+ }
+
+ if (target == COMMA && t == EQ && possible != -1) {
+ index = possible;
+ return true;
+ }
+
+ if (braceCount < 0 || brackCount < 0 || parenCount < 0
+ || (target == RANGLE && angleCount < 0)) {
+ --index;
+ break;
+ }
+ }
+
+ if(target == COMMA && angleCount != 0 && possible != -1) {
+ index = possible;
+ return true;
+ }
+
+ return false;
+}
+
+void Moc::checkSuperClasses(ClassDef *def)
+{
+ const QByteArray firstSuperclass = def->superclassList.value(0).first;
+
+ if (!knownQObjectClasses.contains(firstSuperclass)) {
+ // enable once we /require/ include paths
+#if 0
+ QByteArray msg;
+ msg += "Class ";
+ msg += def->className;
+ msg += " contains the Q_OBJECT macro and inherits from ";
+ msg += def->superclassList.value(0);
+ msg += " but that is not a known QObject subclass. You may get compilation errors.";
+ warning(msg.constData());
+#endif
+ return;
+ }
+ for (int i = 1; i < def->superclassList.count(); ++i) {
+ const QByteArray superClass = def->superclassList.at(i).first;
+ if (knownQObjectClasses.contains(superClass)) {
+ QByteArray msg;
+ msg += "Class ";
+ msg += def->classname;
+ msg += " inherits from two QObject subclasses ";
+ msg += firstSuperclass;
+ msg += " and ";
+ msg += superClass;
+ msg += ". This is not supported!";
+ warning(msg.constData());
+ }
+
+ if (interface2IdMap.contains(superClass)) {
+ bool registeredInterface = false;
+ for (int i = 0; i < def->interfaceList.count(); ++i)
+ if (def->interfaceList.at(i).first().className == superClass) {
+ registeredInterface = true;
+ break;
+ }
+
+ if (!registeredInterface) {
+ QByteArray msg;
+ msg += "Class ";
+ msg += def->classname;
+ msg += " implements the interface ";
+ msg += superClass;
+ msg += " but does not list it in Q_INTERFACES. qobject_cast to ";
+ msg += superClass;
+ msg += " will not work!";
+ warning(msg.constData());
+ }
+ }
+ }
+}
+
+void Moc::checkProperties(ClassDef *cdef)
+{
+ //
+ // 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;
+ }
+ if(!p.notify.isEmpty()) {
+ int notifyId = -1;
+ for (int j = 0; j < cdef->signalList.count(); ++j) {
+ const FunctionDef &f = cdef->signalList.at(j);
+ if(f.name != p.notify) {
+ continue;
+ } else {
+ notifyId = j /* Signal indexes start from 0 */;
+ break;
+ }
+ }
+ p.notifyId = notifyId;
+ if (notifyId == -1) {
+ QByteArray msg = "NOTIFY signal '" + p.notify + "' of property '" + p.name
+ + "' does not exist in class " + cdef->classname + ".";
+ error(msg.constData());
+ }
+ }
+ }
+}
+
+
+
+QT_END_NAMESPACE
diff --git a/src/tools/moc/moc.h b/src/tools/moc/moc.h
new file mode 100644
index 0000000000..4049534e74
--- /dev/null
+++ b/src/tools/moc/moc.h
@@ -0,0 +1,264 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef MOC_H
+#define MOC_H
+
+#include "parser.h"
+#include <QStringList>
+#include <QMap>
+#include <QPair>
+#include <stdio.h>
+#include <ctype.h>
+
+QT_BEGIN_NAMESPACE
+
+struct QMetaObject;
+
+struct Type
+{
+ enum ReferenceType { NoReference, Reference, RValueReference, Pointer };
+
+ inline Type() : isVolatile(false), isScoped(false), firstToken(NOTOKEN), referenceType(NoReference) {}
+ inline explicit Type(const QByteArray &_name) : name(_name), isVolatile(false), isScoped(false), firstToken(NOTOKEN), referenceType(NoReference) {}
+ QByteArray name;
+ uint isVolatile : 1;
+ uint isScoped : 1;
+ Token firstToken;
+ ReferenceType referenceType;
+};
+
+struct EnumDef
+{
+ QByteArray name;
+ QList<QByteArray> values;
+};
+
+struct ArgumentDef
+{
+ ArgumentDef() : isDefault(false) {}
+ Type type;
+ QByteArray rightType, normalizedType, name;
+ QByteArray typeNameForCast; // type name to be used in cast from void * in metacall
+ bool isDefault;
+};
+
+struct FunctionDef
+{
+ FunctionDef(): returnTypeIsVolatile(false), access(Private), isConst(false), isVirtual(false), isStatic(false),
+ inlineCode(false), wasCloned(false), isCompat(false), isInvokable(false),
+ isScriptable(false), isSlot(false), isSignal(false),
+ isConstructor(false), isDestructor(false), isAbstract(false), revision(0) {}
+ Type type;
+ QByteArray normalizedType;
+ QByteArray tag;
+ QByteArray name;
+ bool returnTypeIsVolatile;
+
+ QList<ArgumentDef> arguments;
+
+ enum Access { Private, Protected, Public };
+ Access access;
+ bool isConst;
+ bool isVirtual;
+ bool isStatic;
+ bool inlineCode;
+ bool wasCloned;
+
+ QByteArray inPrivateClass;
+ bool isCompat;
+ bool isInvokable;
+ bool isScriptable;
+ bool isSlot;
+ bool isSignal;
+ bool isConstructor;
+ bool isDestructor;
+ bool isAbstract;
+
+ int revision;
+};
+
+struct PropertyDef
+{
+ PropertyDef():notifyId(-1), constant(false), final(false), gspec(ValueSpec), revision(0){}
+ QByteArray name, type, read, write, reset, designable, scriptable, editable, stored, user, notify, inPrivateClass;
+ int notifyId;
+ bool constant;
+ bool final;
+ enum Specification { ValueSpec, ReferenceSpec, PointerSpec };
+ Specification gspec;
+ bool stdCppSet() const {
+ QByteArray s("set");
+ s += toupper(name[0]);
+ s += name.mid(1);
+ return (s == write);
+ }
+ int revision;
+};
+
+
+struct ClassInfoDef
+{
+ QByteArray name;
+ QByteArray value;
+};
+
+struct ClassDef {
+ ClassDef():
+ hasQObject(false), hasQGadget(false), notifyableProperties(0)
+ , revisionedMethods(0), revisionedProperties(0), begin(0), end(0){}
+ QByteArray classname;
+ QByteArray qualified;
+ QList<QPair<QByteArray, FunctionDef::Access> > superclassList;
+
+ struct Interface
+ {
+ inline explicit Interface(const QByteArray &_className)
+ : className(_className) {}
+ QByteArray className;
+ QByteArray interfaceId;
+ };
+ QList<QList<Interface> >interfaceList;
+
+ bool hasQObject;
+ bool hasQGadget;
+
+ QList<FunctionDef> constructorList;
+ QList<FunctionDef> signalList, slotList, methodList, publicList;
+ int notifyableProperties;
+ QList<PropertyDef> propertyList;
+ QList<ClassInfoDef> classInfoList;
+ QMap<QByteArray, bool> enumDeclarations;
+ QList<EnumDef> enumList;
+ QMap<QByteArray, QByteArray> flagAliases;
+ int revisionedMethods;
+ int revisionedProperties;
+
+ int begin;
+ int end;
+};
+
+struct NamespaceDef {
+ QByteArray name;
+ int begin;
+ int end;
+};
+
+class Moc : public Parser
+{
+public:
+ Moc()
+ : noInclude(false), generatedCode(false), mustIncludeQMetaTypeH(false)
+ {}
+
+ QByteArray filename;
+
+ bool noInclude;
+ bool generatedCode;
+ bool mustIncludeQMetaTypeH;
+ QByteArray includePath;
+ QList<QByteArray> includeFiles;
+ QList<ClassDef> classList;
+ QMap<QByteArray, QByteArray> interface2IdMap;
+ QList<QByteArray> metaTypes;
+ QSet<QByteArray> knownQObjectClasses;
+
+ void parse();
+ void generate(FILE *out);
+ QList<QMetaObject*> generate(bool ignoreProperties);
+
+ bool parseClassHead(ClassDef *def);
+ inline bool inClass(const ClassDef *def) const {
+ return index > def->begin && index < def->end - 1;
+ }
+
+ inline bool inNamespace(const NamespaceDef *def) const {
+ return index > def->begin && index < def->end - 1;
+ }
+
+ Type parseType();
+
+ bool parseEnum(EnumDef *def);
+
+ bool parseFunction(FunctionDef *def, bool inMacro = false);
+ bool parseMaybeFunction(const ClassDef *cdef, FunctionDef *def);
+
+ void parseSlots(ClassDef *def, FunctionDef::Access access);
+ void parseSignals(ClassDef *def);
+ void parseProperty(ClassDef *def);
+ void createPropertyDef(PropertyDef &def);
+ void parseEnumOrFlag(ClassDef *def, bool isFlag);
+ void parseFlag(ClassDef *def);
+ void parseClassInfo(ClassDef *def);
+ void parseInterfaces(ClassDef *def);
+ void parseDeclareInterface();
+ void parseDeclareMetatype();
+ void parseSlotInPrivate(ClassDef *def, FunctionDef::Access access);
+ void parsePrivateProperty(ClassDef *def);
+
+ void parseFunctionArguments(FunctionDef *def);
+
+ QByteArray lexemUntil(Token);
+ bool until(Token);
+
+ // test for Q_INVOCABLE, Q_SCRIPTABLE, etc. and set the flags
+ // in FunctionDef accordingly
+ bool testFunctionAttribute(FunctionDef *def);
+ bool testFunctionAttribute(Token tok, FunctionDef *def);
+ bool testFunctionRevision(FunctionDef *def);
+
+ void checkSuperClasses(ClassDef *def);
+ void checkProperties(ClassDef* cdef);
+};
+
+inline QByteArray noRef(const QByteArray &type)
+{
+ if (type.endsWith('&')) {
+ if (type.endsWith("&&"))
+ return type.left(type.length()-2);
+ return type.left(type.length()-1);
+ }
+ return type;
+}
+
+QT_END_NAMESPACE
+
+#endif // MOC_H
diff --git a/src/tools/moc/moc.pri b/src/tools/moc/moc.pri
new file mode 100644
index 0000000000..b689a35478
--- /dev/null
+++ b/src/tools/moc/moc.pri
@@ -0,0 +1,16 @@
+
+INCLUDEPATH += $$PWD
+
+HEADERS = $$PWD/moc.h \
+ $$PWD/preprocessor.h \
+ $$PWD/parser.h \
+ $$PWD/symbols.h \
+ $$PWD/token.h \
+ $$PWD/utils.h \
+ $$PWD/generator.h \
+ $$PWD/outputrevision.h
+SOURCES = $$PWD/moc.cpp \
+ $$PWD/preprocessor.cpp \
+ $$PWD/generator.cpp \
+ $$PWD/parser.cpp \
+ $$PWD/token.cpp
diff --git a/src/tools/moc/moc.pro b/src/tools/moc/moc.pro
new file mode 100644
index 0000000000..0b8ddbe31e
--- /dev/null
+++ b/src/tools/moc/moc.pro
@@ -0,0 +1,18 @@
+TEMPLATE = app
+TARGET = moc
+
+DEFINES += QT_MOC
+DESTDIR = ../../../bin
+INCLUDEPATH += .
+DEPENDPATH += .
+LIBS =
+OBJECTS_DIR = .
+
+include(moc.pri)
+HEADERS += qdatetime_p.h
+SOURCES += main.cpp
+include(../bootstrap/bootstrap.pri)
+
+target.path=$$[QT_INSTALL_BINS]
+INSTALLS += target
+include(../../qt_targets.pri)
diff --git a/src/tools/moc/mwerks_mac.cpp b/src/tools/moc/mwerks_mac.cpp
new file mode 100644
index 0000000000..c2f5d189c7
--- /dev/null
+++ b/src/tools/moc/mwerks_mac.cpp
@@ -0,0 +1,240 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#ifdef MOC_MWERKS_PLUGIN
+
+#include "mwerks_mac.h"
+#include "qt_mac.h"
+
+/* compiler headers */
+#include "DropInCompilerLinker.h"
+#include "CompilerMapping.h"
+#include "CWPluginErrors.h"
+
+/* standard headers */
+#include <stdio.h>
+#include <string.h>
+
+QT_BEGIN_NAMESPACE
+
+//qglobal.cpp
+const unsigned char * p_str(const char * c);
+QCString pstring2qstring(const unsigned char *c);
+
+#if CW_USE_PRAGMA_EXPORT
+#pragma export on
+#endif
+
+CWPLUGIN_ENTRY(CWPlugin_GetDropInFlags)(const DropInFlags** flags, long* flagsSize)
+{
+ static const DropInFlags sFlags = {
+ kCurrentDropInFlagsVersion,
+ CWDROPINCOMPILERTYPE,
+ DROPINCOMPILERLINKERAPIVERSION_7,
+ kCompAlwaysReload|kCompRequiresProjectBuildStartedMsg,
+ Lang_C_CPP,
+ DROPINCOMPILERLINKERAPIVERSION
+ };
+ *flags = &sFlags;
+ *flagsSize = sizeof(sFlags);
+ return cwNoErr;
+}
+
+
+
+CWPLUGIN_ENTRY(CWPlugin_GetDropInName)(const char** dropinName)
+{
+ static const char sDropInName[] = "McMoc";
+ *dropinName = sDropInName;
+ return cwNoErr;
+}
+
+CWPLUGIN_ENTRY(CWPlugin_GetDisplayName)(const char** displayName)
+{
+ static const char sDisplayName[] = "McMoc";
+ *displayName = sDisplayName;
+ return cwNoErr;
+}
+
+CWPLUGIN_ENTRY(CWPlugin_GetTargetList)(const CWTargetList** targetList)
+{
+ static CWDataType sCPU = targetCPUAny;
+ static CWDataType sOS = targetOSMacintosh;
+ static CWTargetList sTargetList = {kCurrentCWTargetListVersion, 1, &sCPU, 1, &sOS};
+ *targetList = &sTargetList;
+ return cwNoErr;
+}
+
+CWPLUGIN_ENTRY(CWPlugin_GetDefaultMappingList)(const CWExtMapList** defaultMappingList)
+{
+ static CWExtensionMapping sExtension[] = { {'TEXT', ".mocs", kPrecompile } };
+ static CWExtMapList sExtensionMapList = {kCurrentCWExtMapListVersion, 3, sExtension};
+ *defaultMappingList = &sExtensionMapList;
+ return cwNoErr;
+}
+
+#if CW_USE_PRAGMA_EXPORT
+#pragma export off
+#endif
+typedef short CWFileRef;
+
+static int line_count = 0;
+moc_status do_moc(CWPluginContext, const QCString &, const QCString &, CWFileSpec *, bool);
+
+static CWResult mocify(CWPluginContext context, const QCString &source)
+{
+ CWDisplayLines(context, line_count++);
+
+ source.stripWhiteSpace();
+
+ CWResult err;
+ bool dotmoc=false;
+ QCString stem = source, ext;
+ int dotpos = stem.findRev('.');
+ if(dotpos != -1) {
+ ext = stem.right(stem.length() - (dotpos+1));
+ stem = stem.left(dotpos);
+ if(ext == "cpp")
+ dotmoc = true;
+ } else {
+ //whoa!
+ }
+ QCString dest;
+ if(dotmoc)
+ dest = stem + ".moc";
+ else
+ dest = "moc_" + stem + ".cpp";
+
+ //moc it
+ CWFileSpec destSpec;
+ moc_status mocd = do_moc(context, source, dest, &destSpec, dotmoc);
+
+#if 0
+ QCString derr = "Weird";
+ switch(mocd) {
+ case moc_success: derr = "Success"; break;
+ case moc_parse_error: derr = "Parser Error"; break;
+ case moc_no_qobject:derr = "No QOBJECT"; break;
+ case moc_not_time: derr = "Not Time"; break;
+ case moc_no_source: derr = "No Source"; break;
+ case moc_general_error: derr = "General Error"; break;
+ }
+ char dmsg[200];
+ sprintf(dmsg, "\"%s\" %s", source.data(), derr.data());
+ CWReportMessage(context, NULL, dmsg, NULL, messagetypeError, 0);
+#endif
+
+ //handle project
+ if(mocd == moc_no_qobject) {
+ char msg[400];
+ sprintf(msg, "\"%s\" No relevant classes found. No output generated.", source.data());
+ CWReportMessage(context, NULL, msg, NULL, messagetypeWarning, 0);
+ } else if ((mocd == moc_success || mocd == moc_not_time) && !dotmoc)
+ {
+ long whichFile;
+ CWNewProjectEntryInfo ei;
+ memset(&ei, '\0', sizeof(ei));
+ ei.groupPath = "QtGenerated";
+ err = CWAddProjectEntry(context, &destSpec, true, &ei, &whichFile);
+ if (!CWSUCCESS(err))
+ {
+ char msg[200];
+ sprintf(msg, "\"%s\" not added", dest.data());
+ CWReportMessage(context, NULL, msg, NULL, messagetypeWarning, 0);
+ }
+ if(mocd == moc_success)
+ CWSetModDate(context, &destSpec, NULL, true);
+ }
+ return cwNoErr;
+}
+
+pascal short main(CWPluginContext context)
+{
+ short result;
+ long request;
+
+ if (CWGetPluginRequest(context, &request) != cwNoErr)
+ return cwErrRequestFailed;
+ result = cwErrInvalidParameter;
+
+ /* dispatch on compiler request */
+ switch (request)
+ {
+ case reqInitCompiler:
+ case reqTermCompiler:
+ result = cwNoErr;
+ break;
+
+ case reqCompile:
+ {
+ line_count = 0;
+ const char *files = NULL;
+ long filelen;
+ CWGetMainFileText(context, &files, &filelen);
+ const char *beg = files;
+ for(int x = 0; x < filelen; x++) {
+ if(*(files++) == '\r') {
+ char file[1024];
+ memcpy(file, beg, files - beg);
+ file[(files-beg)-1] = '\0';
+ mocify(context, file);
+ beg = files;
+ }
+ }
+ if(beg != files) {
+ char file[1024];
+ memcpy(file, beg, files - beg);
+ file[(files-beg)] = '\0';
+ mocify(context, file);
+ }
+
+ result = cwNoErr;
+ break;
+ }
+ }
+
+ /* return result code */
+ return result;
+}
+
+#endif
+
+QT_END_NAMESPACE
diff --git a/src/tools/moc/mwerks_mac.h b/src/tools/moc/mwerks_mac.h
new file mode 100644
index 0000000000..fe0141e7af
--- /dev/null
+++ b/src/tools/moc/mwerks_mac.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef MWERKS_MAC_H
+#define MWERKS_MAC_H
+
+#include <QtGlobal>
+
+QT_BEGIN_NAMESPACE
+
+#ifdef Q_OS_MAC
+
+#define macintosh
+
+/*make moc a plugin*/
+enum moc_status {
+ moc_success = 1,
+ moc_parse_error = 2,
+ moc_no_qobject = 3,
+ moc_not_time = 4,
+ moc_no_source = 5,
+ moc_general_error = 6
+};
+
+#endif
+
+QT_END_NAMESPACE
+
+#endif // MWERKS_MAC_H
diff --git a/src/tools/moc/outputrevision.h b/src/tools/moc/outputrevision.h
new file mode 100644
index 0000000000..104a3738dd
--- /dev/null
+++ b/src/tools/moc/outputrevision.h
@@ -0,0 +1,48 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef OUTPUTREVISION_H
+#define OUTPUTREVISION_H
+
+// if the output revision changes, you MUST change it in qobjectdefs.h too
+enum { mocOutputRevision = 63 }; // moc format output revision
+
+#endif // OUTPUTREVISION_H
diff --git a/src/tools/moc/parser.cpp b/src/tools/moc/parser.cpp
new file mode 100644
index 0000000000..b6f0837c55
--- /dev/null
+++ b/src/tools/moc/parser.cpp
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** 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 "parser.h"
+#include "utils.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifdef USE_LEXEM_STORE
+Symbol::LexemStore Symbol::lexemStore;
+#endif
+
+static const char *error_msg = 0;
+
+#ifdef Q_CC_MSVC
+#define ErrorFormatString "%s(%d): "
+#else
+#define ErrorFormatString "%s:%d: "
+#endif
+
+void Parser::error(int rollback) {
+ index -= rollback;
+ error();
+}
+void Parser::error(const char *msg) {
+ if (msg || error_msg)
+ qWarning(ErrorFormatString "Error: %s",
+ currentFilenames.top().constData(), symbol().lineNum, msg?msg:error_msg);
+ else
+ qWarning(ErrorFormatString "Parse error at \"%s\"",
+ currentFilenames.top().constData(), symbol().lineNum, symbol().lexem().data());
+ exit(EXIT_FAILURE);
+}
+
+void Parser::warning(const char *msg) {
+ if (displayWarnings && msg)
+ fprintf(stderr, ErrorFormatString "Warning: %s\n",
+ currentFilenames.top().constData(), qMax(0, index > 0 ? symbol().lineNum : 0), msg);
+}
+
+void Parser::note(const char *msg) {
+ if (displayNotes && msg)
+ fprintf(stderr, ErrorFormatString "Note: %s\n",
+ currentFilenames.top().constData(), qMax(0, index > 0 ? symbol().lineNum : 0), msg);
+}
+
+QT_END_NAMESPACE
diff --git a/src/tools/moc/parser.h b/src/tools/moc/parser.h
new file mode 100644
index 0000000000..a874248f5e
--- /dev/null
+++ b/src/tools/moc/parser.h
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef PARSER_H
+#define PARSER_H
+
+#include <QStack>
+#include "symbols.h"
+
+QT_BEGIN_NAMESPACE
+
+class Parser
+{
+public:
+ Parser():index(0), displayWarnings(true), displayNotes(true) {}
+ Symbols symbols;
+ int index;
+ bool displayWarnings;
+ bool displayNotes;
+
+ QStack<QByteArray> currentFilenames;
+
+ inline bool hasNext() const { return (index < symbols.size()); }
+ inline Token next() { if (index >= symbols.size()) return NOTOKEN; return symbols.at(index++).token; }
+ bool test(Token);
+ void next(Token);
+ void next(Token, const char *msg);
+ inline void prev() {--index;}
+ inline Token lookup(int k = 1);
+ inline const Symbol &symbol_lookup(int k = 1) { return symbols.at(index-1+k);}
+ inline Token token() { return symbols.at(index-1).token;}
+ inline QByteArray lexem() { return symbols.at(index-1).lexem();}
+ inline QByteArray unquotedLexem() { return symbols.at(index-1).unquotedLexem();}
+ inline const Symbol &symbol() { return symbols.at(index-1);}
+
+ void error(int rollback);
+ void error(const char *msg = 0);
+ void warning(const char * = 0);
+ void note(const char * = 0);
+
+};
+
+inline bool Parser::test(Token token)
+{
+ if (index < symbols.size() && symbols.at(index).token == token) {
+ ++index;
+ return true;
+ }
+ return false;
+}
+
+inline Token Parser::lookup(int k)
+{
+ const int l = index - 1 + k;
+ return l < symbols.size() ? symbols.at(l).token : NOTOKEN;
+}
+
+inline void Parser::next(Token token)
+{
+ if (!test(token))
+ error();
+}
+
+inline void Parser::next(Token token, const char *msg)
+{
+ if (!test(token))
+ error(msg);
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/tools/moc/ppkeywords.cpp b/src/tools/moc/ppkeywords.cpp
new file mode 100644
index 0000000000..69aa72a05d
--- /dev/null
+++ b/src/tools/moc/ppkeywords.cpp
@@ -0,0 +1,248 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+// auto generated
+// DO NOT EDIT.
+
+static const short pp_keyword_trans[][128] = {
+ {0,0,0,0,0,0,0,0,0,98,12,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 98,76,96,13,0,60,62,97,9,10,58,56,11,57,102,59,
+ 6,6,6,6,6,6,6,6,6,6,92,0,7,81,8,91,
+ 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,1,1,1,0,101,0,61,1,
+ 0,1,2,3,4,1,1,1,1,1,1,1,1,1,5,1,
+ 1,1,1,1,1,1,1,1,1,1,1,0,68,0,71,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,79,87,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,88,80,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,93,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,14,34,0,0,0,20,0,0,0,0,0,0,
+ 0,0,0,0,0,22,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,21,0,0,0,0,0,0,0,44,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,27,0,0,0,0,0,0,0,0,0,30,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,35,0,40,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,36,0,0,0,0,0,0,
+ 0,0,0,38,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,100,0,0,0,0,99,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,65,0,0,0,0,0,0,0,0,0,0,0,0,0,69,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 103,103,103,103,103,103,103,103,103,103,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
+};
+
+static const struct
+{
+ PP_Token token;
+ short next;
+ char defchar;
+ short defnext;
+ PP_Token ident;
+} pp_keywords[] = {
+ {PP_NOTOKEN, 0, 0, 0, PP_NOTOKEN},
+ {PP_CHARACTER, 0, 0, 0, PP_NOTOKEN},
+ {PP_CHARACTER, 0, 105, 63, PP_NOTOKEN},
+ {PP_CHARACTER, 0, 111, 72, PP_NOTOKEN},
+ {PP_CHARACTER, 0, 101, 50, PP_NOTOKEN},
+ {PP_CHARACTER, 0, 111, 77, PP_NOTOKEN},
+ {PP_DIGIT, 0, 0, 0, PP_NOTOKEN},
+ {PP_LANGLE, 1, 0, 0, PP_NOTOKEN},
+ {PP_RANGLE, 2, 0, 0, PP_NOTOKEN},
+ {PP_LPAREN, 0, 0, 0, PP_NOTOKEN},
+ {PP_RPAREN, 0, 0, 0, PP_NOTOKEN},
+ {PP_COMMA, 0, 0, 0, PP_NOTOKEN},
+ {PP_NEWLINE, 0, 0, 0, PP_NOTOKEN},
+ {PP_HASH, 3, 0, 0, PP_HASH},
+ {PP_HASH, 0, 101, 15, PP_HASH},
+ {PP_HASH, 0, 102, 16, PP_HASH},
+ {PP_HASH, 0, 105, 17, PP_HASH},
+ {PP_HASH, 0, 110, 18, PP_HASH},
+ {PP_HASH, 0, 101, 19, PP_HASH},
+ {PP_DEFINE, 0, 0, 0, PP_HASH},
+ {PP_HASH, 4, 0, 0, PP_HASH},
+ {PP_IF, 5, 0, 0, PP_HASH},
+ {PP_HASH, 0, 110, 23, PP_HASH},
+ {PP_HASH, 0, 100, 24, PP_HASH},
+ {PP_HASH, 0, 101, 25, PP_HASH},
+ {PP_HASH, 0, 102, 26, PP_HASH},
+ {PP_UNDEF, 0, 0, 0, PP_HASH},
+ {PP_HASH, 0, 101, 28, PP_HASH},
+ {PP_HASH, 0, 102, 29, PP_HASH},
+ {PP_IFDEF, 0, 0, 0, PP_HASH},
+ {PP_HASH, 0, 100, 31, PP_HASH},
+ {PP_HASH, 0, 101, 32, PP_HASH},
+ {PP_HASH, 0, 102, 33, PP_HASH},
+ {PP_IFNDEF, 0, 0, 0, PP_HASH},
+ {PP_HASH, 6, 0, 0, PP_HASH},
+ {PP_HASH, 7, 0, 0, PP_HASH},
+ {PP_HASH, 0, 102, 37, PP_HASH},
+ {PP_ELIF, 0, 0, 0, PP_HASH},
+ {PP_HASH, 0, 101, 39, PP_HASH},
+ {PP_ELSE, 0, 0, 0, PP_HASH},
+ {PP_HASH, 0, 100, 41, PP_HASH},
+ {PP_HASH, 0, 105, 42, PP_HASH},
+ {PP_HASH, 0, 102, 43, PP_HASH},
+ {PP_ENDIF, 0, 0, 0, PP_HASH},
+ {PP_HASH, 0, 99, 45, PP_HASH},
+ {PP_HASH, 0, 108, 46, PP_HASH},
+ {PP_HASH, 0, 117, 47, PP_HASH},
+ {PP_HASH, 0, 100, 48, PP_HASH},
+ {PP_HASH, 0, 101, 49, PP_HASH},
+ {PP_INCLUDE, 0, 0, 0, PP_HASH},
+ {PP_CHARACTER, 0, 102, 51, PP_CHARACTER},
+ {PP_CHARACTER, 0, 105, 52, PP_CHARACTER},
+ {PP_CHARACTER, 0, 110, 53, PP_CHARACTER},
+ {PP_CHARACTER, 0, 101, 54, PP_CHARACTER},
+ {PP_CHARACTER, 0, 100, 55, PP_CHARACTER},
+ {PP_DEFINED, 0, 0, 0, PP_CHARACTER},
+ {PP_PLUS, 0, 0, 0, PP_NOTOKEN},
+ {PP_MINUS, 0, 0, 0, PP_NOTOKEN},
+ {PP_STAR, 0, 0, 0, PP_NOTOKEN},
+ {PP_SLASH, 8, 0, 0, PP_NOTOKEN},
+ {PP_PERCENT, 0, 58, 94, PP_NOTOKEN},
+ {PP_HAT, 0, 0, 0, PP_NOTOKEN},
+ {PP_AND, 0, 38, 89, PP_NOTOKEN},
+ {PP_CHARACTER, 0, 116, 64, PP_CHARACTER},
+ {PP_CHARACTER, 9, 0, 0, PP_CHARACTER},
+ {PP_CHARACTER, 0, 110, 66, PP_CHARACTER},
+ {PP_CHARACTER, 0, 100, 67, PP_CHARACTER},
+ {PP_AND, 0, 0, 0, PP_CHARACTER},
+ {PP_OR, 0, 124, 90, PP_NOTOKEN},
+ {PP_CHARACTER, 0, 114, 70, PP_CHARACTER},
+ {PP_OR, 0, 0, 0, PP_CHARACTER},
+ {PP_TILDE, 0, 0, 0, PP_NOTOKEN},
+ {PP_CHARACTER, 0, 109, 73, PP_CHARACTER},
+ {PP_CHARACTER, 0, 112, 74, PP_CHARACTER},
+ {PP_CHARACTER, 0, 108, 75, PP_CHARACTER},
+ {PP_TILDE, 0, 0, 0, PP_CHARACTER},
+ {PP_NOT, 0, 61, 83, PP_NOTOKEN},
+ {PP_CHARACTER, 0, 116, 78, PP_CHARACTER},
+ {PP_NOT, 0, 95, 84, PP_CHARACTER},
+ {PP_LTLT, 0, 0, 0, PP_NOTOKEN},
+ {PP_GTGT, 0, 0, 0, PP_NOTOKEN},
+ {PP_INCOMPLETE, 0, 61, 82, PP_NOTOKEN},
+ {PP_EQEQ, 0, 0, 0, PP_NOTOKEN},
+ {PP_NE, 0, 0, 0, PP_NOTOKEN},
+ {PP_CHARACTER, 0, 101, 85, PP_CHARACTER},
+ {PP_CHARACTER, 0, 113, 86, PP_CHARACTER},
+ {PP_NE, 0, 0, 0, PP_CHARACTER},
+ {PP_LE, 0, 0, 0, PP_NOTOKEN},
+ {PP_GE, 0, 0, 0, PP_NOTOKEN},
+ {PP_ANDAND, 0, 0, 0, PP_NOTOKEN},
+ {PP_OROR, 0, 0, 0, PP_NOTOKEN},
+ {PP_QUESTION, 0, 0, 0, PP_NOTOKEN},
+ {PP_COLON, 0, 0, 0, PP_NOTOKEN},
+ {PP_HASHHASH, 0, 0, 0, PP_NOTOKEN},
+ {PP_INCOMPLETE, 0, 37, 95, PP_NOTOKEN},
+ {PP_INCOMPLETE, 0, 58, 93, PP_NOTOKEN},
+ {PP_QUOTE, 0, 0, 0, PP_NOTOKEN},
+ {PP_SINGLEQUOTE, 0, 0, 0, PP_NOTOKEN},
+ {PP_WHITESPACE, 0, 0, 0, PP_NOTOKEN},
+ {PP_CPP_COMMENT, 0, 0, 0, PP_NOTOKEN},
+ {PP_C_COMMENT, 0, 0, 0, PP_NOTOKEN},
+ {PP_BACKSLASH, 0, 0, 0, PP_NOTOKEN},
+ {PP_INCOMPLETE, 10, 0, 0, PP_NOTOKEN},
+ {PP_FLOATING_LITERAL, 0, 0, 0, PP_NOTOKEN}
+};
diff --git a/src/tools/moc/preprocessor.cpp b/src/tools/moc/preprocessor.cpp
new file mode 100644
index 0000000000..fbea82d7fa
--- /dev/null
+++ b/src/tools/moc/preprocessor.cpp
@@ -0,0 +1,978 @@
+/****************************************************************************
+**
+** 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 "preprocessor.h"
+#include "utils.h"
+#include <QStringList>
+#include <QFile>
+#include <QDir>
+#include <QFileInfo>
+
+QT_BEGIN_NAMESPACE
+
+#include "ppkeywords.cpp"
+#include "keywords.cpp"
+
+// transform \r\n into \n
+// \r into \n (os9 style)
+// backslash-newlines into newlines
+static QByteArray cleaned(const QByteArray &input)
+{
+ QByteArray result;
+ result.reserve(input.size());
+ const char *data = input;
+ char *output = result.data();
+
+ int newlines = 0;
+ while (*data) {
+ while (*data && is_space(*data))
+ ++data;
+ bool takeLine = (*data == '#');
+ if (*data == '%' && *(data+1) == ':') {
+ takeLine = true;
+ ++data;
+ }
+ if (takeLine) {
+ *output = '#';
+ ++output;
+ do ++data; while (*data && is_space(*data));
+ }
+ while (*data) {
+ // handle \\\n, \\\r\n and \\\r
+ if (*data == '\\') {
+ if (*(data + 1) == '\r') {
+ ++data;
+ }
+ if (*data && (*(data + 1) == '\n' || (*data) == '\r')) {
+ ++newlines;
+ data += 1;
+ if (*data != '\r')
+ data += 1;
+ continue;
+ }
+ } else if (*data == '\r' && *(data + 1) == '\n') { // reduce \r\n to \n
+ ++data;
+ }
+
+ char ch = *data;
+ if (ch == '\r') // os9: replace \r with \n
+ ch = '\n';
+ *output = ch;
+ ++output;
+
+ if (*data == '\n') {
+ // output additional newlines to keep the correct line-numbering
+ // for the lines following the backslash-newline sequence(s)
+ while (newlines) {
+ *output = '\n';
+ ++output;
+ --newlines;
+ }
+ ++data;
+ break;
+ }
+ ++data;
+ }
+ }
+ result.resize(output - result.constData());
+ return result;
+}
+
+bool Preprocessor::preprocessOnly = false;
+void Preprocessor::skipUntilEndif()
+{
+ while(index < symbols.size() - 1 && symbols.at(index).token != PP_ENDIF){
+ switch (symbols.at(index).token) {
+ case PP_IF:
+ case PP_IFDEF:
+ case PP_IFNDEF:
+ ++index;
+ skipUntilEndif();
+ break;
+ default:
+ ;
+ }
+ ++index;
+ }
+}
+
+bool Preprocessor::skipBranch()
+{
+ while (index < symbols.size() - 1
+ && (symbols.at(index).token != PP_ENDIF
+ && symbols.at(index).token != PP_ELIF
+ && symbols.at(index).token != PP_ELSE)
+ ){
+ switch (symbols.at(index).token) {
+ case PP_IF:
+ case PP_IFDEF:
+ case PP_IFNDEF:
+ ++index;
+ skipUntilEndif();
+ break;
+ default:
+ ;
+ }
+ ++index;
+ }
+ return (index < symbols.size() - 1);
+}
+
+
+enum TokenizeMode { TokenizeCpp, TokenizePreprocessor, PreparePreprocessorStatement, TokenizePreprocessorStatement, TokenizeInclude };
+static Symbols tokenize(const QByteArray &input, int lineNum = 1, TokenizeMode mode = TokenizeCpp)
+{
+ Symbols symbols;
+ const char *begin = input;
+ const char *data = begin;
+ while (*data) {
+ if (mode == TokenizeCpp) {
+ int column = 0;
+
+ const char *lexem = data;
+ int state = 0;
+ Token token = NOTOKEN;
+ for (;;) {
+ if (static_cast<signed char>(*data) < 0) {
+ ++data;
+ continue;
+ }
+ int nextindex = keywords[state].next;
+ int next = 0;
+ if (*data == keywords[state].defchar)
+ next = keywords[state].defnext;
+ else if (!state || nextindex)
+ next = keyword_trans[nextindex][(int)*data];
+ if (!next)
+ break;
+ state = next;
+ token = keywords[state].token;
+ ++data;
+ }
+
+ // suboptimal, is_ident_char should use a table
+ if (keywords[state].ident && is_ident_char(*data))
+ token = keywords[state].ident;
+
+ if (token == NOTOKEN) {
+ // an error really
+ ++data;
+ continue;
+ }
+
+ ++column;
+
+ if (token > SPECIAL_TREATMENT_MARK) {
+ switch (token) {
+ case QUOTE:
+ data = skipQuote(data);
+ token = STRING_LITERAL;
+ // concatenate multi-line strings for easier
+ // STRING_LITERAAL handling in moc
+ if (!Preprocessor::preprocessOnly
+ && !symbols.isEmpty()
+ && symbols.last().token == STRING_LITERAL) {
+
+ QByteArray newString = symbols.last().unquotedLexem();
+ newString += input.mid(lexem - begin + 1, data - lexem - 2);
+ newString.prepend('\"');
+ newString.append('\"');
+ symbols.last() = Symbol(symbols.last().lineNum,
+ STRING_LITERAL,
+ newString);
+ continue;
+ }
+ break;
+ case SINGLEQUOTE:
+ while (*data && (*data != '\''
+ || (*(data-1)=='\\'
+ && *(data-2)!='\\')))
+ ++data;
+ if (*data)
+ ++data;
+ token = CHARACTER_LITERAL;
+ break;
+ case LANGLE_SCOPE:
+ // split <:: into two tokens, < and ::
+ token = LANGLE;
+ data -= 2;
+ break;
+ case DIGIT:
+ while (is_digit_char(*data))
+ ++data;
+ if (!*data || *data != '.') {
+ token = INTEGER_LITERAL;
+ if (data - lexem == 1 &&
+ (*data == 'x' || *data == 'X')
+ && *lexem == '0') {
+ ++data;
+ while (is_hex_char(*data))
+ ++data;
+ }
+ break;
+ }
+ token = FLOATING_LITERAL;
+ ++data;
+ // fall through
+ case FLOATING_LITERAL:
+ while (is_digit_char(*data))
+ ++data;
+ if (*data == '+' || *data == '-')
+ ++data;
+ if (*data == 'e' || *data == 'E') {
+ ++data;
+ while (is_digit_char(*data))
+ ++data;
+ }
+ if (*data == 'f' || *data == 'F'
+ || *data == 'l' || *data == 'L')
+ ++data;
+ break;
+ case HASH:
+ if (column == 1) {
+ mode = PreparePreprocessorStatement;
+ while (*data && (*data == ' ' || *data == '\t'))
+ ++data;
+ if (is_ident_char(*data))
+ mode = TokenizePreprocessorStatement;
+ continue;
+ }
+ break;
+ case NEWLINE:
+ ++lineNum;
+ continue;
+ case BACKSLASH:
+ {
+ const char *rewind = data;
+ while (*data && (*data == ' ' || *data == '\t'))
+ ++data;
+ if (*data && *data == '\n') {
+ ++data;
+ continue;
+ }
+ data = rewind;
+ } break;
+ case CHARACTER:
+ while (is_ident_char(*data))
+ ++data;
+ token = IDENTIFIER;
+ break;
+ case C_COMMENT:
+ if (*data) {
+ if (*data == '\n')
+ ++lineNum;
+ ++data;
+ if (*data) {
+ if (*data == '\n')
+ ++lineNum;
+ ++data;
+ }
+ }
+ while (*data && (*(data-1) != '/' || *(data-2) != '*')) {
+ if (*data == '\n')
+ ++lineNum;
+ ++data;
+ }
+ token = WHITESPACE; // one comment, one whitespace
+ // fall through;
+ case WHITESPACE:
+ if (column == 1)
+ column = 0;
+ while (*data && (*data == ' ' || *data == '\t'))
+ ++data;
+ if (Preprocessor::preprocessOnly) // tokenize whitespace
+ break;
+ continue;
+ case CPP_COMMENT:
+ while (*data && *data != '\n')
+ ++data;
+ continue; // ignore safely, the newline is a separator
+ default:
+ continue; //ignore
+ }
+ }
+#ifdef USE_LEXEM_STORE
+ if (!Preprocessor::preprocessOnly
+ && token != IDENTIFIER
+ && token != STRING_LITERAL
+ && token != FLOATING_LITERAL
+ && token != INTEGER_LITERAL)
+ symbols += Symbol(lineNum, token);
+ else
+#endif
+ symbols += Symbol(lineNum, token, input, lexem-begin, data-lexem);
+
+ } else { // Preprocessor
+
+ const char *lexem = data;
+ int state = 0;
+ Token token = NOTOKEN;
+ if (mode == TokenizePreprocessorStatement) {
+ state = pp_keyword_trans[0][(int)'#'];
+ mode = TokenizePreprocessor;
+ }
+ for (;;) {
+ if (static_cast<signed char>(*data) < 0) {
+ ++data;
+ continue;
+ }
+
+ int nextindex = pp_keywords[state].next;
+ int next = 0;
+ if (*data == pp_keywords[state].defchar)
+ next = pp_keywords[state].defnext;
+ else if (!state || nextindex)
+ next = pp_keyword_trans[nextindex][(int)*data];
+ if (!next)
+ break;
+ state = next;
+ token = pp_keywords[state].token;
+ ++data;
+ }
+ // suboptimal, is_ident_char should use a table
+ if (pp_keywords[state].ident && is_ident_char(*data))
+ token = pp_keywords[state].ident;
+
+ switch (token) {
+ case NOTOKEN:
+ ++data;
+ break;
+ case PP_IFDEF:
+ symbols += Symbol(lineNum, PP_IF);
+ symbols += Symbol(lineNum, PP_DEFINED);
+ continue;
+ case PP_IFNDEF:
+ symbols += Symbol(lineNum, PP_IF);
+ symbols += Symbol(lineNum, PP_NOT);
+ symbols += Symbol(lineNum, PP_DEFINED);
+ continue;
+ case PP_INCLUDE:
+ mode = TokenizeInclude;
+ break;
+ case PP_QUOTE:
+ data = skipQuote(data);
+ token = PP_STRING_LITERAL;
+ break;
+ case PP_SINGLEQUOTE:
+ while (*data && (*data != '\''
+ || (*(data-1)=='\\'
+ && *(data-2)!='\\')))
+ ++data;
+ if (*data)
+ ++data;
+ token = PP_CHARACTER_LITERAL;
+ break;
+ case PP_DIGIT:
+ while (is_digit_char(*data))
+ ++data;
+ if (!*data || *data != '.') {
+ token = PP_INTEGER_LITERAL;
+ if (data - lexem == 1 &&
+ (*data == 'x' || *data == 'X')
+ && *lexem == '0') {
+ ++data;
+ while (is_hex_char(*data))
+ ++data;
+ }
+ break;
+ }
+ token = PP_FLOATING_LITERAL;
+ ++data;
+ // fall through
+ case PP_FLOATING_LITERAL:
+ while (is_digit_char(*data))
+ ++data;
+ if (*data == '+' || *data == '-')
+ ++data;
+ if (*data == 'e' || *data == 'E') {
+ ++data;
+ while (is_digit_char(*data))
+ ++data;
+ }
+ if (*data == 'f' || *data == 'F'
+ || *data == 'l' || *data == 'L')
+ ++data;
+ break;
+ case PP_CHARACTER:
+ if (mode == PreparePreprocessorStatement) {
+ // rewind entire token to begin
+ data = lexem;
+ mode = TokenizePreprocessorStatement;
+ continue;
+ }
+ while (is_ident_char(*data))
+ ++data;
+ token = PP_IDENTIFIER;
+ break;
+ case PP_C_COMMENT:
+ if (*data) {
+ if (*data == '\n')
+ ++lineNum;
+ ++data;
+ if (*data) {
+ if (*data == '\n')
+ ++lineNum;
+ ++data;
+ }
+ }
+ while (*data && (*(data-1) != '/' || *(data-2) != '*')) {
+ if (*data == '\n')
+ ++lineNum;
+ ++data;
+ }
+ token = PP_WHITESPACE; // one comment, one whitespace
+ // fall through;
+ case PP_WHITESPACE:
+ while (*data && (*data == ' ' || *data == '\t'))
+ ++data;
+ continue; // the preprocessor needs no whitespace
+ case PP_CPP_COMMENT:
+ while (*data && *data != '\n')
+ ++data;
+ continue; // ignore safely, the newline is a separator
+ case PP_NEWLINE:
+ ++lineNum;
+ mode = TokenizeCpp;
+ break;
+ case PP_BACKSLASH:
+ {
+ const char *rewind = data;
+ while (*data && (*data == ' ' || *data == '\t'))
+ ++data;
+ if (*data && *data == '\n') {
+ ++data;
+ continue;
+ }
+ data = rewind;
+ } break;
+ case PP_LANGLE:
+ if (mode != TokenizeInclude)
+ break;
+ token = PP_STRING_LITERAL;
+ while (*data && *data != '\n' && *(data-1) != '>')
+ ++data;
+ break;
+ default:
+ break;
+ }
+ if (mode == PreparePreprocessorStatement)
+ continue;
+#ifdef USE_LEXEM_STORE
+ if (token != PP_IDENTIFIER
+ && token != PP_STRING_LITERAL
+ && token != PP_FLOATING_LITERAL
+ && token != PP_INTEGER_LITERAL)
+ symbols += Symbol(lineNum, token);
+ else
+#endif
+ symbols += Symbol(lineNum, token, input, lexem-begin, data-lexem);
+ }
+ }
+ symbols += Symbol(); // eof symbol
+ return symbols;
+}
+
+void Preprocessor::substituteMacro(const MacroName &macro, Symbols &substituted, MacroSafeSet safeset)
+{
+ Symbols saveSymbols = symbols;
+ int saveIndex = index;
+
+ symbols = macros.value(macro).symbols;
+ index = 0;
+
+ safeset += macro;
+ substituteUntilNewline(substituted, safeset);
+
+ symbols = saveSymbols;
+ index = saveIndex;
+}
+
+
+
+void Preprocessor::substituteUntilNewline(Symbols &substituted, MacroSafeSet safeset)
+{
+ while (hasNext()) {
+ Token token = next();
+ if (token == PP_IDENTIFIER) {
+ MacroName macro = symbol();
+ if (macros.contains(macro) && !safeset.contains(macro)) {
+ substituteMacro(macro, substituted, safeset);
+ continue;
+ }
+ } else if (token == PP_DEFINED) {
+ test(PP_LPAREN);
+ next(PP_IDENTIFIER);
+ Symbol definedOrNotDefined = symbol();
+ definedOrNotDefined.token = macros.contains(definedOrNotDefined)? PP_MOC_TRUE : PP_MOC_FALSE;
+ substituted += definedOrNotDefined;
+ test(PP_RPAREN);
+ continue;
+ } else if (token == PP_NEWLINE) {
+ substituted += symbol();
+ break;
+ }
+ substituted += symbol();
+ }
+}
+
+
+class PP_Expression : public Parser
+{
+public:
+ int value() { index = 0; return unary_expression_lookup() ? conditional_expression() : 0; }
+
+ int conditional_expression();
+ int logical_OR_expression();
+ int logical_AND_expression();
+ int inclusive_OR_expression();
+ int exclusive_OR_expression();
+ int AND_expression();
+ int equality_expression();
+ int relational_expression();
+ int shift_expression();
+ int additive_expression();
+ int multiplicative_expression();
+ int unary_expression();
+ bool unary_expression_lookup();
+ int primary_expression();
+ bool primary_expression_lookup();
+};
+
+int PP_Expression::conditional_expression()
+{
+ int value = logical_OR_expression();
+ if (test(PP_QUESTION)) {
+ int alt1 = conditional_expression();
+ int alt2 = test(PP_COLON) ? conditional_expression() : 0;
+ return value ? alt1 : alt2;
+ }
+ return value;
+}
+
+int PP_Expression::logical_OR_expression()
+{
+ int value = logical_AND_expression();
+ if (test(PP_OROR))
+ return logical_OR_expression() || value;
+ return value;
+}
+
+int PP_Expression::logical_AND_expression()
+{
+ int value = inclusive_OR_expression();
+ if (test(PP_ANDAND))
+ return logical_AND_expression() && value;
+ return value;
+}
+
+int PP_Expression::inclusive_OR_expression()
+{
+ int value = exclusive_OR_expression();
+ if (test(PP_OR))
+ return value | inclusive_OR_expression();
+ return value;
+}
+
+int PP_Expression::exclusive_OR_expression()
+{
+ int value = AND_expression();
+ if (test(PP_HAT))
+ return value ^ exclusive_OR_expression();
+ return value;
+}
+
+int PP_Expression::AND_expression()
+{
+ int value = equality_expression();
+ if (test(PP_AND))
+ return value & AND_expression();
+ return value;
+}
+
+int PP_Expression::equality_expression()
+{
+ int value = relational_expression();
+ switch (next()) {
+ case PP_EQEQ:
+ return value == equality_expression();
+ case PP_NE:
+ return value != equality_expression();
+ default:
+ prev();
+ return value;
+ }
+}
+
+int PP_Expression::relational_expression()
+{
+ int value = shift_expression();
+ switch (next()) {
+ case PP_LANGLE:
+ return value < relational_expression();
+ case PP_RANGLE:
+ return value > relational_expression();
+ case PP_LE:
+ return value <= relational_expression();
+ case PP_GE:
+ return value >= relational_expression();
+ default:
+ prev();
+ return value;
+ }
+}
+
+int PP_Expression::shift_expression()
+{
+ int value = additive_expression();
+ switch (next()) {
+ case PP_LTLT:
+ return value << shift_expression();
+ case PP_GTGT:
+ return value >> shift_expression();
+ default:
+ prev();
+ return value;
+ }
+}
+
+int PP_Expression::additive_expression()
+{
+ int value = multiplicative_expression();
+ switch (next()) {
+ case PP_PLUS:
+ return value + additive_expression();
+ case PP_MINUS:
+ return value - additive_expression();
+ default:
+ prev();
+ return value;
+ }
+}
+
+int PP_Expression::multiplicative_expression()
+{
+ int value = unary_expression();
+ switch (next()) {
+ case PP_STAR:
+ return value * multiplicative_expression();
+ case PP_PERCENT:
+ {
+ int remainder = multiplicative_expression();
+ return remainder ? value % remainder : 0;
+ }
+ case PP_SLASH:
+ {
+ int div = multiplicative_expression();
+ return div ? value / div : 0;
+ }
+ default:
+ prev();
+ return value;
+ };
+}
+
+int PP_Expression::unary_expression()
+{
+ switch (next()) {
+ case PP_PLUS:
+ return unary_expression();
+ case PP_MINUS:
+ return -unary_expression();
+ case PP_NOT:
+ return !unary_expression();
+ case PP_TILDE:
+ return ~unary_expression();
+ case PP_MOC_TRUE:
+ return 1;
+ case PP_MOC_FALSE:
+ return 0;
+ default:
+ prev();
+ return primary_expression();
+ }
+}
+
+bool PP_Expression::unary_expression_lookup()
+{
+ Token t = lookup();
+ return (primary_expression_lookup()
+ || t == PP_PLUS
+ || t == PP_MINUS
+ || t == PP_NOT
+ || t == PP_TILDE
+ || t == PP_DEFINED);
+}
+
+int PP_Expression::primary_expression()
+{
+ int value;
+ if (test(PP_LPAREN)) {
+ value = conditional_expression();
+ test(PP_RPAREN);
+ } else {
+ next();
+ value = lexem().toInt(0, 0);
+ }
+ return value;
+}
+
+bool PP_Expression::primary_expression_lookup()
+{
+ Token t = lookup();
+ return (t == PP_IDENTIFIER
+ || t == PP_INTEGER_LITERAL
+ || t == PP_FLOATING_LITERAL
+ || t == PP_MOC_TRUE
+ || t == PP_MOC_FALSE
+ || t == PP_LPAREN);
+}
+
+int Preprocessor::evaluateCondition()
+{
+ PP_Expression expression;
+ expression.currentFilenames = currentFilenames;
+
+ substituteUntilNewline(expression.symbols);
+
+ return expression.value();
+}
+
+void Preprocessor::preprocess(const QByteArray &filename, Symbols &preprocessed)
+{
+ currentFilenames.push(filename);
+ preprocessed.reserve(preprocessed.size() + symbols.size());
+ while (hasNext()) {
+ Token token = next();
+
+ switch (token) {
+ case PP_INCLUDE:
+ {
+ int lineNum = symbol().lineNum;
+ QByteArray include;
+ bool local = false;
+ if (test(PP_STRING_LITERAL)) {
+ local = lexem().startsWith('\"');
+ include = unquotedLexem();
+ } else
+ continue;
+ until(PP_NEWLINE);
+
+ // #### stringery
+ QFileInfo fi;
+ if (local)
+ fi.setFile(QFileInfo(QString::fromLocal8Bit(filename)).dir(), QString::fromLocal8Bit(include));
+ for (int j = 0; j < Preprocessor::includes.size() && !fi.exists(); ++j) {
+ const IncludePath &p = Preprocessor::includes.at(j);
+ if (p.isFrameworkPath) {
+ const int slashPos = include.indexOf('/');
+ if (slashPos == -1)
+ continue;
+ QByteArray frameworkCandidate = include.left(slashPos);
+ frameworkCandidate.append(".framework/Headers/");
+ fi.setFile(QString::fromLocal8Bit(QByteArray(p.path + '/' + frameworkCandidate)), QString::fromLocal8Bit(include.mid(slashPos + 1)));
+ } else {
+ fi.setFile(QString::fromLocal8Bit(p.path), QString::fromLocal8Bit(include));
+ }
+ // try again, maybe there's a file later in the include paths with the same name
+ // (186067)
+ if (fi.isDir()) {
+ fi = QFileInfo();
+ continue;
+ }
+ }
+
+ if (!fi.exists() || fi.isDir())
+ continue;
+ include = fi.canonicalFilePath().toLocal8Bit();
+
+ if (Preprocessor::preprocessedIncludes.contains(include))
+ continue;
+ Preprocessor::preprocessedIncludes.insert(include);
+
+ QFile file(QString::fromLocal8Bit(include));
+ if (!file.open(QFile::ReadOnly))
+ continue;
+
+ QByteArray input = file.readAll();
+ file.close();
+ if (input.isEmpty())
+ continue;
+
+ Symbols saveSymbols = symbols;
+ int saveIndex = index;
+
+ // phase 1: get rid of backslash-newlines
+ input = cleaned(input);
+
+ // phase 2: tokenize for the preprocessor
+ symbols = tokenize(input);
+ input.clear();
+
+ index = 0;
+
+ // phase 3: preprocess conditions and substitute macros
+ preprocessed += Symbol(0, MOC_INCLUDE_BEGIN, include);
+ preprocess(include, preprocessed);
+ preprocessed += Symbol(lineNum, MOC_INCLUDE_END, include);
+
+ symbols = saveSymbols;
+ index = saveIndex;
+ continue;
+ }
+ case PP_DEFINE:
+ {
+ next(IDENTIFIER);
+ QByteArray name = lexem();
+ int start = index;
+ until(PP_NEWLINE);
+ Macro macro;
+ macro.symbols.reserve(index - start - 1);
+ for (int i = start; i < index - 1; ++i)
+ macro.symbols += symbols.at(i);
+ macros.insert(name, macro);
+ continue;
+ }
+ case PP_UNDEF: {
+ next(IDENTIFIER);
+ QByteArray name = lexem();
+ until(PP_NEWLINE);
+ macros.remove(name);
+ continue;
+ }
+ case PP_IDENTIFIER:
+ {
+// if (macros.contains(symbol()))
+// ;
+ }
+ // we _could_ easily substitute macros by the following
+ // four lines, but we choose not to.
+ /*
+ if (macros.contains(sym.lexem())) {
+ preprocessed += substitute(macros, symbols, i);
+ continue;
+ }
+ */
+ break;
+ case PP_HASH:
+ until(PP_NEWLINE);
+ continue; // skip unknown preprocessor statement
+ case PP_IFDEF:
+ case PP_IFNDEF:
+ case PP_IF:
+ while (!evaluateCondition()) {
+ if (!skipBranch())
+ break;
+ if (test(PP_ELIF)) {
+ } else {
+ until(PP_NEWLINE);
+ break;
+ }
+ }
+ continue;
+ case PP_ELIF:
+ case PP_ELSE:
+ skipUntilEndif();
+ // fall through
+ case PP_ENDIF:
+ until(PP_NEWLINE);
+ continue;
+ case SIGNALS:
+ case SLOTS: {
+ Symbol sym = symbol();
+ if (macros.contains("QT_NO_KEYWORDS"))
+ sym.token = IDENTIFIER;
+ else
+ sym.token = (token == SIGNALS ? Q_SIGNALS_TOKEN : Q_SLOTS_TOKEN);
+ preprocessed += sym;
+ } continue;
+ default:
+ break;
+ }
+ preprocessed += symbol();
+ }
+
+ currentFilenames.pop();
+}
+
+Symbols Preprocessor::preprocessed(const QByteArray &filename, FILE *file)
+{
+ QFile qfile;
+ qfile.open(file, QFile::ReadOnly);
+ QByteArray input = qfile.readAll();
+ if (input.isEmpty())
+ return symbols;
+
+ // phase 1: get rid of backslash-newlines
+ input = cleaned(input);
+
+ // phase 2: tokenize for the preprocessor
+ symbols = tokenize(input);
+
+#if 0
+ for (int j = 0; j < symbols.size(); ++j)
+ fprintf(stderr, "line %d: %s(%s)\n",
+ symbols[j].lineNum,
+ symbols[j].lexem().constData(),
+ tokenTypeName(symbols[j].token));
+#endif
+
+ // phase 3: preprocess conditions and substitute macros
+ Symbols result;
+ preprocess(filename, result);
+
+#if 0
+ for (int j = 0; j < result.size(); ++j)
+ fprintf(stderr, "line %d: %s(%s)\n",
+ result[j].lineNum,
+ result[j].lexem().constData(),
+ tokenTypeName(result[j].token));
+#endif
+
+ return result;
+}
+
+void Preprocessor::until(Token t)
+{
+ while(hasNext() && next() != t)
+ ;
+}
+
+QT_END_NAMESPACE
diff --git a/src/tools/moc/preprocessor.h b/src/tools/moc/preprocessor.h
new file mode 100644
index 0000000000..c1b3569dcf
--- /dev/null
+++ b/src/tools/moc/preprocessor.h
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef PREPROCESSOR_H
+#define PREPROCESSOR_H
+
+#include "parser.h"
+#include <QList>
+#include <QSet>
+#include <stdio.h>
+
+QT_BEGIN_NAMESPACE
+
+struct Macro
+{
+ Symbols symbols;
+};
+
+#ifdef USE_LEXEM_STORE
+typedef QByteArray MacroName;
+#else
+typedef SubArray MacroName;
+#endif
+typedef QHash<MacroName, Macro> Macros;
+typedef QVector<MacroName> MacroSafeSet;
+
+
+class Preprocessor : public Parser
+{
+public:
+ Preprocessor(){}
+ static bool preprocessOnly;
+ struct IncludePath
+ {
+ inline explicit IncludePath(const QByteArray &_path)
+ : path(_path), isFrameworkPath(false) {}
+ QByteArray path;
+ bool isFrameworkPath;
+ };
+ QList<IncludePath> includes;
+ QList<QByteArray> frameworks;
+ QSet<QByteArray> preprocessedIncludes;
+ Macros macros;
+ Symbols preprocessed(const QByteArray &filename, FILE *file);
+
+
+ void skipUntilEndif();
+ bool skipBranch();
+
+ void substituteMacro(const MacroName &macro, Symbols &substituted, MacroSafeSet safeset = MacroSafeSet());
+ void substituteUntilNewline(Symbols &substituted, MacroSafeSet safeset = MacroSafeSet());
+
+ int evaluateCondition();
+
+
+private:
+ void until(Token);
+
+ void preprocess(const QByteArray &filename, Symbols &preprocessed);
+};
+
+QT_END_NAMESPACE
+
+#endif // PREPROCESSOR_H
diff --git a/src/tools/moc/symbols.h b/src/tools/moc/symbols.h
new file mode 100644
index 0000000000..3eed7061ac
--- /dev/null
+++ b/src/tools/moc/symbols.h
@@ -0,0 +1,147 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef SYMBOLS_H
+#define SYMBOLS_H
+
+#include "token.h"
+#include <QString>
+#include <QHash>
+#include <QVector>
+#include <QDebug>
+
+QT_BEGIN_NAMESPACE
+
+//#define USE_LEXEM_STORE
+
+struct SubArray
+{
+ inline SubArray():from(0),len(-1){}
+ inline SubArray(const QByteArray &a):array(a),from(0), len(a.size()){}
+ inline SubArray(const char *s):array(s),from(0) { len = array.size(); }
+ inline SubArray(const QByteArray &a, int from, int len):array(a), from(from), len(len){}
+ QByteArray array;
+ int from, len;
+ inline bool operator==(const SubArray &other) const {
+ if (len != other.len)
+ return false;
+ for (int i = 0; i < len; ++i)
+ if (array.at(from + i) != other.array.at(other.from + i))
+ return false;
+ return true;
+ }
+};
+
+inline uint qHash(const SubArray &key)
+{
+ const uchar *p = reinterpret_cast<const uchar *>(key.array.data() + key.from);
+ int n = key.len;
+ uint h = 0;
+ uint g;
+
+ while (n--) {
+ h = (h << 4) + *p++;
+ if ((g = (h & 0xf0000000)) != 0)
+ h ^= g >> 23;
+ h &= ~g;
+ }
+ return h;
+}
+
+
+struct Symbol
+{
+
+#ifdef USE_LEXEM_STORE
+ typedef QHash<SubArray, QHashDummyValue> LexemStore;
+ static LexemStore lexemStore;
+
+ inline Symbol() : lineNum(-1),token(NOTOKEN){}
+ inline Symbol(int lineNum, Token token):
+ lineNum(lineNum), token(token){}
+ inline Symbol(int lineNum, Token token, const QByteArray &lexem):
+ lineNum(lineNum), token(token),lex(lexem){}
+ inline Symbol(int lineNum, Token token, const QByteArray &lexem, int from, int len):
+ lineNum(lineNum), token(token){
+ LexemStore::const_iterator it = lexemStore.constFind(SubArray(lexem, from, len));
+
+ if (it != lexemStore.constEnd()) {
+ lex = it.key().array;
+ } else {
+ lex = lexem.mid(from, len);
+ lexemStore.insert(lex, QHashDummyValue());
+ }
+ }
+ int lineNum;
+ Token token;
+ inline QByteArray unquotedLexem() const { return lex.mid(1, lex.length()-2); }
+ inline QByteArray lexem() const { return lex; }
+ inline operator QByteArray() const { return lex; }
+ QByteArray lex;
+
+#else
+
+ inline Symbol() : lineNum(-1),token(NOTOKEN), from(0),len(-1) {}
+ inline Symbol(int lineNum, Token token):
+ lineNum(lineNum), token(token), from(0), len(-1) {}
+ inline Symbol(int lineNum, Token token, const QByteArray &lexem):
+ lineNum(lineNum), token(token), lex(lexem), from(0) { len = lex.size(); }
+ inline Symbol(int lineNum, Token token, const QByteArray &lexem, int from, int len):
+ lineNum(lineNum), token(token),lex(lexem),from(from), len(len){}
+ int lineNum;
+ Token token;
+ inline QByteArray lexem() const { return lex.mid(from, len); }
+ inline QByteArray unquotedLexem() const { return lex.mid(from+1, len-2); }
+ inline operator QByteArray() const { return lex.mid(from, len); }
+ inline operator SubArray() const { return SubArray(lex, from, len); }
+ QByteArray lex;
+ int from, len;
+
+#endif
+};
+Q_DECLARE_TYPEINFO(Symbol, Q_MOVABLE_TYPE);
+
+
+typedef QVector<Symbol> Symbols;
+
+QT_END_NAMESPACE
+
+#endif // SYMBOLS_H
diff --git a/src/tools/moc/token.cpp b/src/tools/moc/token.cpp
new file mode 100644
index 0000000000..9d07c4867a
--- /dev/null
+++ b/src/tools/moc/token.cpp
@@ -0,0 +1,224 @@
+/****************************************************************************
+**
+** 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 "token.h"
+
+QT_BEGIN_NAMESPACE
+
+#if defined(DEBUG_MOC)
+const char *tokenTypeName(Token t)
+{
+ switch (t) {
+ case NOTOKEN: return "NOTOKEN";
+ case IDENTIFIER: return "IDENTIFIER";
+ case INTEGER_LITERAL: return "INTEGER_LITERAL";
+ case CHARACTER_LITERAL: return "CHARACTER_LITERAL";
+ case STRING_LITERAL: return "STRING_LITERAL";
+ case BOOLEAN_LITERAL: return "BOOLEAN_LITERAL";
+ case HEADER_NAME: return "HEADER_NAME";
+ case LANGLE: return "LANGLE";
+ case RANGLE: return "RANGLE";
+ case LPAREN: return "LPAREN";
+ case RPAREN: return "RPAREN";
+ case ELIPSIS: return "ELIPSIS";
+ case LBRACK: return "LBRACK";
+ case RBRACK: return "RBRACK";
+ case LBRACE: return "LBRACE";
+ case RBRACE: return "RBRACE";
+ case EQ: return "EQ";
+ case SCOPE: return "SCOPE";
+ case SEMIC: return "SEMIC";
+ case COLON: return "COLON";
+ case DOTSTAR: return "DOTSTAR";
+ case QUESTION: return "QUESTION";
+ case DOT: return "DOT";
+ case DYNAMIC_CAST: return "DYNAMIC_CAST";
+ case STATIC_CAST: return "STATIC_CAST";
+ case REINTERPRET_CAST: return "REINTERPRET_CAST";
+ case CONST_CAST: return "CONST_CAST";
+ case TYPEID: return "TYPEID";
+ case THIS: return "THIS";
+ case TEMPLATE: return "TEMPLATE";
+ case THROW: return "THROW";
+ case TRY: return "TRY";
+ case CATCH: return "CATCH";
+ case TYPEDEF: return "TYPEDEF";
+ case FRIEND: return "FRIEND";
+ case CLASS: return "CLASS";
+ case NAMESPACE: return "NAMESPACE";
+ case ENUM: return "ENUM";
+ case STRUCT: return "STRUCT";
+ case UNION: return "UNION";
+ case VIRTUAL: return "VIRTUAL";
+ case PRIVATE: return "PRIVATE";
+ case PROTECTED: return "PROTECTED";
+ case PUBLIC: return "PUBLIC";
+ case EXPORT: return "EXPORT";
+ case AUTO: return "AUTO";
+ case REGISTER: return "REGISTER";
+ case EXTERN: return "EXTERN";
+ case MUTABLE: return "MUTABLE";
+ case ASM: return "ASM";
+ case USING: return "USING";
+ case INLINE: return "INLINE";
+ case EXPLICIT: return "EXPLICIT";
+ case STATIC: return "STATIC";
+ case CONST: return "CONST";
+ case VOLATILE: return "VOLATILE";
+ case OPERATOR: return "OPERATOR";
+ case SIZEOF: return "SIZEOF";
+ case NEW: return "NEW";
+ case DELETE: return "DELETE";
+ case PLUS: return "PLUS";
+ case MINUS: return "MINUS";
+ case STAR: return "STAR";
+ case SLASH: return "SLASH";
+ case PERCENT: return "PERCENT";
+ case HAT: return "HAT";
+ case AND: return "AND";
+ case OR: return "OR";
+ case TILDE: return "TILDE";
+ case NOT: return "NOT";
+ case PLUS_EQ: return "PLUS_EQ";
+ case MINUS_EQ: return "MINUS_EQ";
+ case STAR_EQ: return "STAR_EQ";
+ case SLASH_EQ: return "SLASH_EQ";
+ case PERCENT_EQ: return "PERCENT_EQ";
+ case HAT_EQ: return "HAT_EQ";
+ case AND_EQ: return "AND_EQ";
+ case OR_EQ: return "OR_EQ";
+ case LTLT: return "LTLT";
+ case GTGT: return "GTGT";
+ case GTGT_EQ: return "GTGT_EQ";
+ case LTLT_EQ: return "LTLT_EQ";
+ case EQEQ: return "EQEQ";
+ case NE: return "NE";
+ case LE: return "LE";
+ case GE: return "GE";
+ case ANDAND: return "ANDAND";
+ case OROR: return "OROR";
+ case INCR: return "INCR";
+ case DECR: return "DECR";
+ case COMMA: return "COMMA";
+ case ARROW_STAR: return "ARROW_STAR";
+ case ARROW: return "ARROW";
+ case CHAR: return "CHAR";
+ case WCHAR: return "WCHAR";
+ case BOOL: return "BOOL";
+ case SHORT: return "SHORT";
+ case INT: return "INT";
+ case LONG: return "LONG";
+ case SIGNED: return "SIGNED";
+ case UNSIGNED: return "UNSIGNED";
+ case FLOAT: return "FLOAT";
+ case DOUBLE: return "DOUBLE";
+ case VOID: return "VOID";
+ case CASE: return "CASE";
+ case DEFAULT: return "DEFAULT";
+ case IF: return "IF";
+ case ELSE: return "ELSE";
+ case SWITCH: return "SWITCH";
+ case WHILE: return "WHILE";
+ case DO: return "DO";
+ case FOR: return "FOR";
+ case BREAK: return "BREAK";
+ case CONTINUE: return "CONTINUE";
+ case GOTO: return "GOTO";
+ case SIGNALS: return "SIGNALS";
+ case SLOTS: return "SLOTS";
+ case RETURN: return "RETURN";
+ case Q_OBJECT_TOKEN: return "Q_OBJECT_TOKEN";
+ case Q_GADGET_TOKEN: return "Q_GADGET_TOKEN";
+ case Q_PROPERTY_TOKEN: return "Q_PROPERTY_TOKEN";
+ case Q_ENUMS_TOKEN: return "Q_ENUMS_TOKEN";
+ case Q_FLAGS_TOKEN: return "Q_FLAGS_TOKEN";
+ case Q_DECLARE_FLAGS_TOKEN: return "Q_DECLARE_FLAGS_TOKEN";
+ case Q_DECLARE_INTERFACE_TOKEN: return "Q_DECLARE_INTERFACE_TOKEN";
+ case Q_CLASSINFO_TOKEN: return "Q_CLASSINFO_TOKEN";
+ case Q_INTERFACES_TOKEN: return "Q_INTERFACES_TOKEN";
+ case Q_SIGNALS_TOKEN: return "Q_SIGNALS_TOKEN";
+ case Q_SLOTS_TOKEN: return "Q_SLOTS_TOKEN";
+ case Q_SIGNAL_TOKEN: return "Q_SIGNAL_TOKEN";
+ case Q_SLOT_TOKEN: return "Q_SLOT_TOKEN";
+ case Q_PRIVATE_SLOT_TOKEN: return "Q_PRIVATE_SLOT_TOKEN";
+ case Q_PRIVATE_PROPERTY_TOKEN: return "Q_PRIVATE_PROPERTY_TOKEN";
+ case Q_REVISION_TOKEN: return "Q_REVISION_TOKEN";
+ case SPECIAL_TREATMENT_MARK: return "SPECIAL_TREATMENT_MARK";
+ case MOC_INCLUDE_BEGIN: return "MOC_INCLUDE_BEGIN";
+ case MOC_INCLUDE_END: return "MOC_INCLUDE_END";
+ case CPP_COMMENT: return "CPP_COMMENT";
+ case C_COMMENT: return "C_COMMENT";
+ case FLOATING_LITERAL: return "FLOATING_LITERAL";
+ case HASH: return "HASH";
+ case QUOTE: return "QUOTE";
+ case SINGLEQUOTE: return "SINGLEQUOTE";
+ case DIGIT: return "DIGIT";
+ case CHARACTER: return "CHARACTER";
+ case NEWLINE: return "NEWLINE";
+ case WHITESPACE: return "WHITESPACE";
+ case BACKSLASH: return "BACKSLASH";
+ case INCOMPLETE: return "INCOMPLETE";
+ case PP_DEFINE: return "PP_DEFINE";
+ case PP_UNDEF: return "PP_UNDEF";
+ case PP_IF: return "PP_IF";
+ case PP_IFDEF: return "PP_IFDEF";
+ case PP_IFNDEF: return "PP_IFNDEF";
+ case PP_ELIF: return "PP_ELIF";
+ case PP_ELSE: return "PP_ELSE";
+ case PP_ENDIF: return "PP_ENDIF";
+ case PP_INCLUDE: return "PP_INCLUDE";
+ case PP_HASHHASH: return "PP_HASHHASH";
+ case PP_HASH: return "PP_HASH";
+ case PP_DEFINED: return "PP_DEFINED";
+ case PP_INCOMPLETE: return "PP_INCOMPLETE";
+ case PP_MOC_TRUE: return "PP_MOC_TRUE";
+ case PP_MOC_FALSE: return "PP_MOC_FALSE";
+ case Q_DECLARE_METATYPE_TOKEN: return "Q_DECLARE_METATYPE_TOKEN";
+ case Q_MOC_COMPAT_TOKEN: return "Q_MOC_COMPAT_TOKEN";
+ case Q_QT3_SUPPORT_TOKEN: return "Q_QT3_SUPPORT_TOKEN";
+ case Q_INVOKABLE_TOKEN: return "Q_INVOKABLE_TOKEN";
+ case Q_SCRIPTABLE_TOKEN: return "Q_SCRIPTABLE_TOKEN";
+ }
+ return "";
+}
+#endif
+
+QT_END_NAMESPACE
diff --git a/src/tools/moc/token.h b/src/tools/moc/token.h
new file mode 100644
index 0000000000..95f17c2598
--- /dev/null
+++ b/src/tools/moc/token.h
@@ -0,0 +1,276 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef TOKEN_H
+#define TOKEN_H
+
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_NAMESPACE
+
+enum Token {
+ NOTOKEN,
+ IDENTIFIER,
+ INTEGER_LITERAL,
+ CHARACTER_LITERAL,
+ STRING_LITERAL,
+ BOOLEAN_LITERAL,
+ HEADER_NAME,
+ LANGLE,
+ RANGLE,
+ LPAREN,
+ RPAREN,
+ ELIPSIS,
+ LBRACK,
+ RBRACK,
+ LBRACE,
+ RBRACE,
+ EQ,
+ SCOPE,
+ SEMIC,
+ COLON,
+ DOTSTAR,
+ QUESTION,
+ DOT,
+ DYNAMIC_CAST,
+ STATIC_CAST,
+ REINTERPRET_CAST,
+ CONST_CAST,
+ TYPEID,
+ THIS,
+ TEMPLATE,
+ THROW,
+ TRY,
+ CATCH,
+ TYPEDEF,
+ FRIEND,
+ CLASS,
+ NAMESPACE,
+ ENUM,
+ STRUCT,
+ UNION,
+ VIRTUAL,
+ PRIVATE,
+ PROTECTED,
+ PUBLIC,
+ EXPORT,
+ AUTO,
+ REGISTER,
+ EXTERN,
+ MUTABLE,
+ ASM,
+ USING,
+ INLINE,
+ EXPLICIT,
+ STATIC,
+ CONST,
+ VOLATILE,
+ OPERATOR,
+ SIZEOF,
+ NEW,
+ DELETE,
+ PLUS,
+ MINUS,
+ STAR,
+ SLASH,
+ PERCENT,
+ HAT,
+ AND,
+ OR,
+ TILDE,
+ NOT,
+ PLUS_EQ,
+ MINUS_EQ,
+ STAR_EQ,
+ SLASH_EQ,
+ PERCENT_EQ,
+ HAT_EQ,
+ AND_EQ,
+ OR_EQ,
+ LTLT,
+ GTGT,
+ GTGT_EQ,
+ LTLT_EQ,
+ EQEQ,
+ NE,
+ LE,
+ GE,
+ ANDAND,
+ OROR,
+ INCR,
+ DECR,
+ COMMA,
+ ARROW_STAR,
+ ARROW,
+ CHAR,
+ WCHAR,
+ BOOL,
+ SHORT,
+ INT,
+ LONG,
+ SIGNED,
+ UNSIGNED,
+ FLOAT,
+ DOUBLE,
+ VOID,
+ CASE,
+ DEFAULT,
+ IF,
+ ELSE,
+ SWITCH,
+ WHILE,
+ DO,
+ FOR,
+ BREAK,
+ CONTINUE,
+ GOTO,
+ SIGNALS,
+ SLOTS,
+ RETURN,
+ Q_META_TOKEN_BEGIN,
+ Q_OBJECT_TOKEN = Q_META_TOKEN_BEGIN,
+ Q_GADGET_TOKEN,
+ Q_PROPERTY_TOKEN,
+ Q_ENUMS_TOKEN,
+ Q_FLAGS_TOKEN,
+ Q_DECLARE_FLAGS_TOKEN,
+ Q_DECLARE_INTERFACE_TOKEN,
+ Q_DECLARE_METATYPE_TOKEN,
+ Q_CLASSINFO_TOKEN,
+ Q_INTERFACES_TOKEN,
+ Q_SIGNALS_TOKEN,
+ Q_SLOTS_TOKEN,
+ Q_SIGNAL_TOKEN,
+ Q_SLOT_TOKEN,
+ Q_PRIVATE_SLOT_TOKEN,
+ Q_MOC_COMPAT_TOKEN,
+ Q_QT3_SUPPORT_TOKEN,
+ Q_INVOKABLE_TOKEN,
+ Q_SCRIPTABLE_TOKEN,
+ Q_PRIVATE_PROPERTY_TOKEN,
+ Q_REVISION_TOKEN,
+ Q_META_TOKEN_END,
+ SPECIAL_TREATMENT_MARK = Q_META_TOKEN_END,
+ MOC_INCLUDE_BEGIN,
+ MOC_INCLUDE_END,
+ CPP_COMMENT,
+ C_COMMENT,
+ FLOATING_LITERAL,
+ HASH,
+ QUOTE,
+ SINGLEQUOTE,
+ LANGLE_SCOPE,
+ DIGIT,
+ CHARACTER,
+ NEWLINE,
+ WHITESPACE,
+ BACKSLASH,
+ INCOMPLETE,
+
+ PP_DEFINE,
+ PP_UNDEF,
+ PP_IF,
+ PP_IFDEF,
+ PP_IFNDEF,
+ PP_ELIF,
+ PP_ELSE,
+ PP_ENDIF,
+ PP_INCLUDE,
+ PP_HASHHASH,
+ PP_HASH,
+ PP_DEFINED,
+ PP_INCOMPLETE,
+
+ PP_MOC_TRUE,
+ PP_MOC_FALSE,
+
+ PP_NOTOKEN = NOTOKEN,
+ PP_IDENTIFIER = IDENTIFIER,
+ PP_INTEGER_LITERAL = INTEGER_LITERAL,
+ PP_CHARACTER_LITERAL = CHARACTER_LITERAL,
+ PP_STRING_LITERAL = STRING_LITERAL,
+ PP_LANGLE = LANGLE,
+ PP_RANGLE = RANGLE,
+ PP_LPAREN = LPAREN,
+ PP_RPAREN = RPAREN,
+ PP_COMMA = COMMA,
+ PP_PLUS = PLUS,
+ PP_MINUS = MINUS,
+ PP_STAR = STAR,
+ PP_SLASH = SLASH,
+ PP_PERCENT = PERCENT,
+ PP_HAT = HAT,
+ PP_AND = AND,
+ PP_OR = OR,
+ PP_TILDE = TILDE,
+ PP_NOT = NOT,
+ PP_LTLT = LTLT,
+ PP_GTGT = GTGT,
+ PP_EQEQ = EQEQ,
+ PP_NE = NE,
+ PP_LE = LE,
+ PP_GE = GE,
+ PP_ANDAND = ANDAND,
+ PP_OROR = OROR,
+ PP_QUESTION = QUESTION,
+ PP_COLON = COLON,
+ PP_FLOATING_LITERAL = FLOATING_LITERAL,
+ PP_QUOTE = QUOTE,
+ PP_SINGLEQUOTE = SINGLEQUOTE,
+ PP_DIGIT = DIGIT,
+ PP_CHARACTER = CHARACTER,
+ PP_WHITESPACE = WHITESPACE,
+ PP_NEWLINE = NEWLINE,
+ PP_CPP_COMMENT = CPP_COMMENT,
+ PP_C_COMMENT = C_COMMENT,
+ PP_BACKSLASH = BACKSLASH
+};
+
+// for debugging only
+#if defined(DEBUG_MOC)
+const char *tokenTypeName(Token t);
+#endif
+
+typedef Token PP_Token;
+
+QT_END_NAMESPACE
+
+#endif // TOKEN_H
diff --git a/src/tools/moc/util/generate.sh b/src/tools/moc/util/generate.sh
new file mode 100755
index 0000000000..ebfd4f789e
--- /dev/null
+++ b/src/tools/moc/util/generate.sh
@@ -0,0 +1,48 @@
+#!/bin/sh
+#############################################################################
+##
+## Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+## All rights reserved.
+## Contact: Nokia Corporation (qt-info@nokia.com)
+##
+## This file is the build configuration utility 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$
+##
+#############################################################################
+
+qmake
+make
+cat licenseheader.txt > ../keywords.cpp
+cat licenseheader.txt > ../ppkeywords.cpp
+./generate_keywords >> ../keywords.cpp
+./generate_keywords preprocessor >> ../ppkeywords.cpp
diff --git a/src/tools/moc/util/generate_keywords.cpp b/src/tools/moc/util/generate_keywords.cpp
new file mode 100644
index 0000000000..26f7a191da
--- /dev/null
+++ b/src/tools/moc/util/generate_keywords.cpp
@@ -0,0 +1,469 @@
+/****************************************************************************
+**
+** 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 <stdio.h>
+#include <string.h>
+#include <qbytearray.h>
+#include <qlist.h>
+
+struct Keyword
+{
+ const char *lexem;
+ const char *token;
+};
+
+static const Keyword pp_keywords[] = {
+ { "<", "PP_LANGLE" },
+ { ">", "PP_RANGLE" },
+ { "(", "PP_LPAREN"},
+ { ")", "PP_RPAREN"},
+ { ",", "PP_COMMA"},
+ { "\n", "PP_NEWLINE"},
+ { "#define", "PP_DEFINE"},
+ { "#if", "PP_IF"},
+ { "#undef", "PP_UNDEF"},
+ { "#ifdef", "PP_IFDEF"},
+ { "#ifndef", "PP_IFNDEF"},
+ { "#elif", "PP_ELIF"},
+ { "#else", "PP_ELSE"},
+ { "#endif", "PP_ENDIF"},
+ { "#include", "PP_INCLUDE"},
+ { "defined", "PP_DEFINED"},
+ { "+", "PP_PLUS" },
+ { "-", "PP_MINUS" },
+ { "*", "PP_STAR" },
+ { "/", "PP_SLASH" },
+ { "%", "PP_PERCENT" },
+ { "^", "PP_HAT" },
+ { "&", "PP_AND" },
+ { "bitand", "PP_AND" },
+ { "|", "PP_OR" },
+ { "bitor", "PP_OR" },
+ { "~", "PP_TILDE" },
+ { "compl", "PP_TILDE" },
+ { "!", "PP_NOT" },
+ { "not", "PP_NOT" },
+ { "<<", "PP_LTLT" },
+ { ">>", "PP_GTGT" },
+ { "==", "PP_EQEQ" },
+ { "!=", "PP_NE" },
+ { "not_eq", "PP_NE" },
+ { "<=", "PP_LE" },
+ { ">=", "PP_GE" },
+ { "&&", "PP_ANDAND" },
+ { "||", "PP_OROR" },
+ { "?", "PP_QUESTION" },
+ { ":", "PP_COLON" },
+ { "##", "PP_HASHHASH"},
+ { "%:%:", "PP_HASHHASH"},
+ { "#", "PP_HASH"},
+ { "\"", "PP_QUOTE"},
+ { "\'", "PP_SINGLEQUOTE"},
+ { " ", "PP_WHITESPACE" },
+ { "\t", "PP_WHITESPACE" },
+ { "//", "PP_CPP_COMMENT" },
+ { "/*", "PP_C_COMMENT" },
+ { "\\", "PP_BACKSLASH" },
+ { 0, "PP_NOTOKEN"}
+};
+
+static const Keyword keywords[] = {
+ { "<", "LANGLE" },
+ { ">", "RANGLE" },
+ { "(", "LPAREN" },
+ { ")", "RPAREN" },
+ { "...", "ELIPSIS" },
+ { ",", "COMMA" },
+ { "[", "LBRACK" },
+ { "]", "RBRACK" },
+ { "<:", "LBRACK" },
+ { ":>", "RBRACK" },
+ { "<::", "LANGLE_SCOPE" },
+ { "{", "LBRACE" },
+ { "<%", "LBRACE" },
+ { "}", "RBRACE" },
+ { "%>", "RBRACE" },
+ { "=", "EQ" },
+ { "::", "SCOPE" },
+ { ";", "SEMIC" },
+ { ":", "COLON" },
+ { ".*", "DOTSTAR" },
+ { "?", "QUESTION" },
+ { ".", "DOT" },
+ { "dynamic_cast", "DYNAMIC_CAST" },
+ { "static_cast", "STATIC_CAST" },
+ { "reinterpret_cast", "REINTERPRET_CAST" },
+ { "const_cast", "CONST_CAST" },
+ { "typeid", "TYPEID" },
+ { "this", "THIS" },
+ { "template", "TEMPLATE" },
+ { "throw", "THROW" },
+ { "try", "TRY" },
+ { "catch", "CATCH" },
+ { "typedef", "TYPEDEF" },
+ { "friend", "FRIEND" },
+ { "class", "CLASS" },
+ { "namespace", "NAMESPACE" },
+ { "enum", "ENUM" },
+ { "struct", "STRUCT" },
+ { "union", "UNION" },
+ { "virtual", "VIRTUAL" },
+ { "private", "PRIVATE" },
+ { "protected", "PROTECTED" },
+ { "public", "PUBLIC" },
+ { "export", "EXPORT" },
+ { "auto", "AUTO" },
+ { "register", "REGISTER" },
+ { "extern", "EXTERN" },
+ { "mutable", "MUTABLE" },
+ { "asm", "ASM" },
+ { "using", "USING" },
+ { "inline", "INLINE" },
+ { "explicit", "EXPLICIT" },
+ { "static", "STATIC" },
+ { "const", "CONST" },
+ { "volatile", "VOLATILE" },
+ { "operator", "OPERATOR" },
+ { "sizeof", "SIZEOF" },
+ { "new", "NEW" },
+ { "delete", "DELETE" },
+ { "+", "PLUS" },
+ { "-", "MINUS" },
+ { "*", "STAR" },
+ { "/", "SLASH" },
+ { "%", "PERCENT" },
+ { "^", "HAT" },
+ { "&", "AND" },
+ { "bitand", "AND" },
+ { "|", "OR" },
+ { "bitor", "OR" },
+ { "~", "TILDE" },
+ { "compl", "TILDE" },
+ { "!", "NOT" },
+ { "not", "NOT" },
+ { "+=", "PLUS_EQ" },
+ { "-=", "MINUS_EQ" },
+ { "*=", "STAR_EQ" },
+ { "/=", "SLASH_EQ" },
+ { "%=", "PERCENT_EQ" },
+ { "^=", "HAT_EQ" },
+ { "&=", "AND_EQ" },
+ { "|=", "OR_EQ" },
+ { "<<", "LTLT" },
+ { ">>", "GTGT" },
+ { ">>=", "GTGT_EQ" },
+ { "<<=", "LTLT_EQ" },
+ { "==", "EQEQ" },
+ { "!=", "NE" },
+ { "not_eq", "NE" },
+ { "<=", "LE" },
+ { ">=", "GE" },
+ { "&&", "ANDAND" },
+ { "||", "OROR" },
+ { "++", "INCR" },
+ { "--", "DECR" },
+ { ",", "COMMA" },
+ { "->*", "ARROW_STAR" },
+ { "->", "ARROW" },
+ { "char", "CHAR" },
+ { "wchar", "WCHAR" },
+ { "bool", "BOOL" },
+ { "short", "SHORT" },
+ { "int", "INT" },
+ { "long", "LONG" },
+ { "signed", "SIGNED" },
+ { "unsigned", "UNSIGNED" },
+ { "float", "FLOAT" },
+ { "double", "DOUBLE" },
+ { "void", "VOID" },
+ { "case", "CASE" },
+ { "default", "DEFAULT" },
+ { "if", "IF" },
+ { "else", "ELSE" },
+ { "switch", "SWITCH" },
+ { "while", "WHILE" },
+ { "do", "DO" },
+ { "for", "FOR" },
+ { "break", "BREAK" },
+ { "continue", "CONTINUE" },
+ { "goto", "GOTO" },
+ { "return", "RETURN" },
+ { "Q_OBJECT", "Q_OBJECT_TOKEN" },
+ { "Q_GADGET", "Q_GADGET_TOKEN" },
+ { "Q_PROPERTY", "Q_PROPERTY_TOKEN" },
+ { "Q_ENUMS", "Q_ENUMS_TOKEN" },
+ { "Q_FLAGS", "Q_FLAGS_TOKEN" },
+ { "Q_DECLARE_FLAGS", "Q_DECLARE_FLAGS_TOKEN" },
+ { "Q_DECLARE_INTERFACE", "Q_DECLARE_INTERFACE_TOKEN" },
+ { "Q_DECLARE_METATYPE", "Q_DECLARE_METATYPE_TOKEN" },
+ { "Q_DECLARE_EXTENSION_INTERFACE", "Q_DECLARE_INTERFACE_TOKEN" },
+ { "Q_SETS", "Q_FLAGS_TOKEN" },
+ { "Q_CLASSINFO", "Q_CLASSINFO_TOKEN" },
+ { "Q_INTERFACES", "Q_INTERFACES_TOKEN" },
+ { "signals", "SIGNALS" },
+ { "slots", "SLOTS" },
+ { "Q_SIGNALS", "Q_SIGNALS_TOKEN" },
+ { "Q_SLOTS", "Q_SLOTS_TOKEN" },
+ { "Q_PRIVATE_SLOT", "Q_PRIVATE_SLOT_TOKEN" },
+ { "QT_MOC_COMPAT", "Q_MOC_COMPAT_TOKEN" },
+ { "QT3_SUPPORT", "Q_QT3_SUPPORT_TOKEN" },
+ { "Q_INVOKABLE", "Q_INVOKABLE_TOKEN" },
+ { "Q_SIGNAL", "Q_SIGNAL_TOKEN" },
+ { "Q_SLOT", "Q_SLOT_TOKEN" },
+ { "Q_SCRIPTABLE", "Q_SCRIPTABLE_TOKEN" },
+ { "Q_PRIVATE_PROPERTY", "Q_PRIVATE_PROPERTY_TOKEN" },
+ { "Q_REVISION", "Q_REVISION_TOKEN" },
+ { "\n", "NEWLINE" },
+ { "\"", "QUOTE" },
+ { "\'", "SINGLEQUOTE" },
+ { " ", "WHITESPACE" },
+ { "\t", "WHITESPACE" },
+ { "#", "HASH" },
+ { "\\", "BACKSLASH" },
+ { "//", "CPP_COMMENT" },
+ { "/*", "C_COMMENT" },
+ { 0, "NOTOKEN"}
+};
+
+
+inline bool is_ident_start(char s)
+{
+ return ((s >= 'a' && s <= 'z')
+ || (s >= 'A' && s <= 'Z')
+ || s == '_'
+ );
+}
+
+inline bool is_ident_char(char s)
+{
+ return ((s >= 'a' && s <= 'z')
+ || (s >= 'A' && s <= 'Z')
+ || (s >= '0' && s <= '9')
+ || s == '_'
+ );
+}
+struct State
+{
+ State(const char* token):token(token), nextindex(0),
+ defchar(0), defnext(0), ident(0) {
+ memset( next, 0, sizeof(next));
+ }
+ QByteArray token;
+ int next[128];
+ int nextindex;
+
+ char defchar;
+ int defnext;
+
+ const char *ident;
+
+ bool operator==(const State& o) const
+ {
+ return (token == o.token
+ && nextindex == o.nextindex
+ && defchar == o.defchar
+ && defnext == o.defnext
+ && ident == o.ident);
+ }
+};
+
+void newState(QList<State> &states, const char *token, const char *lexem, bool pre)
+{
+ const char * ident = 0;
+ if (is_ident_start(*lexem))
+ ident = pre?"PP_CHARACTER" : "CHARACTER";
+ else if (*lexem == '#')
+ ident = pre?"PP_HASH" : "HASH";
+
+ int state = 0;
+ while (*lexem) {
+ int next = states[state].next[(int)*lexem];
+ if (!next) {
+ const char * t = 0;
+ if (ident)
+ t = ident;
+ else
+ t = pre?"PP_INCOMPLETE":"INCOMPLETE";
+ next = states.size();
+ states += State(t);
+ states[state].next[(int)*lexem] = next;
+ states[next].ident = ident;
+ }
+ state = next;
+ ++lexem;
+ if (ident && !is_ident_char(*lexem))
+ ident = 0;
+ }
+ states[state].token = token;
+}
+
+void newState(QList<State> &states, const char *token, char lexem)
+{
+ int next = states[0].next[(int)lexem];
+ if (!next) {
+ next = states.size();
+ states += State(token);
+ states[0].next[(int)lexem] = next;
+ } else {
+ states[next].token = token;
+ }
+}
+
+
+void makeTable(const Keyword keywords[])
+{
+ int i,c;
+ bool pre = (keywords == pp_keywords);
+ QList<State> states;
+ states += State(pre?"PP_NOTOKEN":"NOTOKEN");
+
+ // identifiers
+ for (c = 'a'; c <= 'z'; ++c)
+ newState(states, pre?"PP_CHARACTER":"CHARACTER", c);
+ for (c = 'A'; c <= 'Z'; ++c)
+ newState(states, pre?"PP_CHARACTER":"CHARACTER", c);
+ c = '_';
+ newState(states, pre?"PP_CHARACTER":"CHARACTER", c);
+
+ // add digits
+ for (c = '0'; c <= '9'; ++c)
+ newState(states, pre?"PP_DIGIT":"DIGIT", c);
+
+ // keywords
+ for (i = 0; keywords[i].lexem; ++i)
+ newState(states, keywords[i].token, keywords[i].lexem, pre);
+
+ // some floats
+ for (c = '0'; c <= '9'; ++c)
+ newState(states, pre?"PP_FLOATING_LITERAL":"FLOATING_LITERAL",
+ QByteArray(".") + char(c), pre);
+
+ // simplify table with default transitions
+ int transindex = -1;
+ for (i = 0; i < states.size(); ++i) {
+ int n = 0;
+ int defchar = -1;
+ for (c = 0; c < 128; ++c)
+ if (states[i].next[c]) {
+ ++n;
+ defchar = c;
+ }
+ if (!n)
+ continue;
+ if (n == 1) {
+ states[i].defnext = states[i].next[defchar];
+ states[i].defchar = defchar;
+ continue;
+ }
+ states[i].nextindex = ++transindex;
+ }
+
+#if 1
+ // compress table
+ int j, k;
+ for (i = 0; i < states.size(); ++i) {
+ for (j = i + 1; j < states.size(); ++j) {
+ if ( states[i] == states[j] ) {
+ for (k = 0; k < states.size(); ++k) {
+ if (states[k].defnext == j)
+ states[k].defnext = i;
+ if (states[k].defnext > j)
+ --states[k].defnext;
+ for (c = 0; c < 128; ++c) {
+ if (states[k].next[c] == j)
+ states[k].next[c] = i;
+ if (states[k].next[c] > j)
+ --states[k].next[c];
+ }
+ }
+ states.removeAt(j);
+ --j;
+ }
+ }
+ }
+#endif
+ printf("static const short %skeyword_trans[][128] = {\n",
+ pre?"pp_":"");
+ for (i = 0; i < states.size(); ++i) {
+ if (i && !states[i].nextindex)
+ continue;
+ printf("%s {", i?",\n":"");
+ for (c = 0; c < 128; ++c)
+ printf("%s%s%d",
+ c?",":"",
+ (!c || c%16)?"":"\n ",
+ states[i].next[c]
+ );
+ printf("}");
+ }
+ printf("\n};\n\n");
+
+ printf("static const struct\n{\n"
+ " %sToken token;\n"
+ " short next;\n"
+ " char defchar;\n"
+ " short defnext;\n"
+ " %sToken ident;\n"
+ "} %skeywords[] = {\n",
+ pre ? "PP_":"",
+ pre ? "PP_":"",
+ pre ? "pp_":"");
+ for (i = 0; i < states.size(); ++i) {
+ printf("%s {%s, %d, %d, %d, %s}",
+ i?",\n":"",
+ states[i].token.data(),
+ states[i].nextindex,
+ states[i].defchar,
+ states[i].defnext,
+ states[i].ident?states[i].ident:(pre?"PP_NOTOKEN":"NOTOKEN"));
+ }
+ printf("\n};\n");
+}
+
+int main(int argc, char **)
+{
+ printf("// auto generated\n"
+ "// DO NOT EDIT.\n\n");
+ if ( argc > 1 )
+ makeTable(pp_keywords);
+ else
+ makeTable(keywords);
+ return 0;
+}
diff --git a/src/tools/moc/util/generate_keywords.pro b/src/tools/moc/util/generate_keywords.pro
new file mode 100644
index 0000000000..eb04409922
--- /dev/null
+++ b/src/tools/moc/util/generate_keywords.pro
@@ -0,0 +1,12 @@
+######################################################################
+# Automatically generated by qmake (1.08a) Mon Feb 23 13:08:28 2004
+######################################################################
+
+TEMPLATE = app
+CONFIG -= moc
+mac:CONFIG -= app_bundle
+INCLUDEPATH += .
+
+# Input
+SOURCES += generate_keywords.cpp
+CONFIG += qt create_prl link_prl
diff --git a/src/tools/moc/util/licenseheader.txt b/src/tools/moc/util/licenseheader.txt
new file mode 100644
index 0000000000..ac5571e7ab
--- /dev/null
+++ b/src/tools/moc/util/licenseheader.txt
@@ -0,0 +1,41 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
diff --git a/src/tools/moc/utils.h b/src/tools/moc/utils.h
new file mode 100644
index 0000000000..758f4a6454
--- /dev/null
+++ b/src/tools/moc/utils.h
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef UTILS_H
+#define UTILS_H
+
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_NAMESPACE
+
+inline bool is_whitespace(char s)
+{
+ return (s == ' ' || s == '\t' || s == '\n');
+}
+
+inline bool is_space(char s)
+{
+ return (s == ' ' || s == '\t');
+}
+
+inline bool is_ident_start(char s)
+{
+ return ((s >= 'a' && s <= 'z')
+ || (s >= 'A' && s <= 'Z')
+ || s == '_'
+ );
+}
+
+inline bool is_ident_char(char s)
+{
+ return ((s >= 'a' && s <= 'z')
+ || (s >= 'A' && s <= 'Z')
+ || (s >= '0' && s <= '9')
+ || s == '_'
+ );
+}
+
+inline bool is_digit_char(char s)
+{
+ return (s >= '0' && s <= '9');
+}
+
+inline bool is_octal_char(char s)
+{
+ return (s >= '0' && s <= '7');
+}
+
+inline bool is_hex_char(char s)
+{
+ return ((s >= 'a' && s <= 'f')
+ || (s >= 'A' && s <= 'F')
+ || (s >= '0' && s <= '9')
+ );
+}
+
+inline const char *skipQuote(const char *data)
+{
+ while (*data && (*data != '\"')) {
+ if (*data == '\\') {
+ ++data;
+ if (!*data) break;
+ }
+ ++data;
+ }
+
+ if (*data) //Skip last quote
+ ++data;
+ return data;
+}
+
+QT_END_NAMESPACE
+
+#endif // UTILS_H