⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 generator.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the tools applications of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file.  Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "generator.h"#include "outputrevision.h"#include "utils.h"#include <QtCore/qmetatype.h>#include <stdio.h>// if the flags change, you MUST to change it in qmetaobject.cpp tooenum PropertyFlags  {    Invalid = 0x00000000,    Readable = 0x00000001,    Writable = 0x00000002,    Resettable = 0x00000004,    EnumOrFlag = 0x00000008,    StdCppSet = 0x00000100,//     Override = 0x00000200,    Designable = 0x00001000,    ResolveDesignable = 0x00002000,    Scriptable = 0x00004000,    ResolveScriptable = 0x00008000,    Stored = 0x00010000,    ResolveStored = 0x00020000,    Editable = 0x00040000,    ResolveEditable = 0x00080000,    User = 0x00100000,    ResolveUser = 0x00200000};enum MethodFlags {    AccessPrivate = 0x00,    AccessProtected = 0x01,    AccessPublic = 0x02,    MethodMethod = 0x00,    MethodSignal = 0x04,    MethodSlot = 0x08,    MethodCompatibility = 0x10,    MethodCloned = 0x20,    MethodScriptable = 0x40};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;}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");//// 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 = 10;    fprintf(out, "static const uint qt_meta_data_%s[] = {\n", qualifiedClassNameIdentifier.constData());    fprintf(out, "\n // content:\n");    fprintf(out, "    %4d,       // revision\n", 1);    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;    fprintf(out, "    %4d, %4d, // properties\n", cdef->propertyList.count(), cdef->propertyList.count() ? index : 0);    index += cdef->propertyList.count() * 3;    fprintf(out, "    %4d, %4d, // enums/sets\n", cdef->enumList.count(), cdef->enumList.count() ? index : 0);//// 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 property array//    generateProperties();//// Build enums array//    generateEnums(index);//// 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");//// 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)) {            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, "static const QMetaObject *qt_meta_extradata_%s[] = {\n    ", qualifiedClassNameIdentifier.constData());        for (int i = 0; i < extraList.count(); ++i) {            if (i)                fprintf(out, ",\n    ");            fprintf(out, "    &%s::staticMetaObject", extraList.at(i).constData());        }        fprintf(out, ",0\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 (extraList.isEmpty())        fprintf(out, "0 }\n");    else        fprintf(out, "qt_meta_extradata_%s }\n", qualifiedClassNameIdentifier.constData());    fprintf(out, "};\n");    if (isQt || !cdef->hasQObject)        return;    fprintf(out, "\nconst QMetaObject *%s::metaObject() const\n{\n    return &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"                  "\treturn 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\treturn 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\treturn ", 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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -