summaryrefslogtreecommitdiffstats
path: root/src/tools/moc
diff options
context:
space:
mode:
authorQt by Nokia <qt-info@nokia.com>2011-04-27 12:05:43 +0200
committeraxis <qt-info@nokia.com>2011-04-27 12:05:43 +0200
commit38be0d13830efd2d98281c645c3a60afe05ffece (patch)
tree6ea73f3ec77f7d153333779883e8120f82820abe /src/tools/moc
Initial import from the monolithic Qt.
This is the beginning of revision history for this module. If you want to look at revision history older than this, please refer to the Qt Git wiki for how to use Git history grafting. At the time of writing, this wiki is located here: http://qt.gitorious.org/qt/pages/GitIntroductionWithQt If you have already performed the grafting and you don't see any history beyond this commit, try running "git log" with the "--follow" argument. Branched from the monolithic repo, Qt master branch, at commit 896db169ea224deb96c59ce8af800d019de63f12
Diffstat (limited to 'src/tools/moc')
-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