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

📄 moc.cpp

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/******************************************************************************** Copyright (C) 1992-2006 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://www.trolltech.com/products/qt/opensource.html**** If you are unsure which license is appropriate for your use, please** review the following information:** http://www.trolltech.com/products/qt/licensing.html or contact the** sales department at sales@trolltech.com.**** 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 "moc.h"#include "generator.h"#include "qdatetime.h"#include "utils.h"#include "outputrevision.h"#include <stdio.h>#include <stdlib.h>// WARNING: a copy of this function is in qmetaobject.cppstatic QByteArray normalizeTypeInternal(const char *t, const char *e, bool fixScope = false, bool adjustConst = true){    int len = e - t;    /*      Convert 'char const *' into 'const char *'. Start at index 1,      not 0, because 'const char *' is already OK.    */    QByteArray constbuf;    for (int i = 1; i < len; i++) {        if ( t[i] == 'c'             && strncmp(t + i + 1, "onst", 4) == 0             && (i + 5 >= len || !is_ident_char(t[i + 5]))             && !is_ident_char(t[i-1])            ) {            constbuf = QByteArray(t, len);            if (is_space(t[i-1]))                constbuf.remove(i-1, 6);            else                constbuf.remove(i, 5);            constbuf.prepend("const ");            t = constbuf.data();            e = constbuf.data() + constbuf.length();            break;        }        /*          We musn't convert 'char * const *' into 'const char **'          and we must beware of 'Bar<const Bla>'.        */        if (t[i] == '&' || t[i] == '*' ||t[i] == '<')            break;    }    if (adjustConst && e > t + 6 && strncmp("const ", t, 6) == 0) {        if (*(e-1) == '&') { // treat const reference as value            t += 6;            --e;        } else if (is_ident_char(*(e-1))) { // treat const value as value            t += 6;        }    }    QByteArray result;    result.reserve(len);    // some type substitutions for 'unsigned x'    if (strncmp("unsigned ", t, 9) == 0) {        if (strncmp("int", t+9, 3) == 0) {            t += 9+3;            result += "uint";        } else if (strncmp("long", t+9, 4) == 0                   // preserve '[unsigned] long int'                   && (strlen(t + 9 + 4) < 4                       || strncmp(t + 9 + 4, " int", 4) != 0                      )                   // preserve '[unsigned] long long'                   && (strlen(t + 9 + 4) < 5                       || strncmp(t + 9 + 4, " long", 5) != 0                      )                  ) {            t += 9+4;            result += "ulong";        }    }    while (t != e) {        char c = *t++;        if (fixScope && c == ':' && *t == ':' ) {            ++t;            c = *t++;            int i = result.size() - 1;            while (i >= 0 && is_ident_char(result.at(i)))                   --i;            result.resize(i + 1);        }        result += c;        if (c == '<') {            //template recursion            const char* tt = t;            int templdepth = 1;            while (t != e) {                c = *t++;                if (c == '<')                    ++templdepth;                if (c == '>')                    --templdepth;                if (templdepth == 0) {                    result += normalizeTypeInternal(tt, t-1, fixScope, false);                    result += c;                    if (*t == '>')                        result += ' '; // avoid >>                    break;                }            }        }    }    return result;}// only moc needs this functionQByteArray normalizeType(const char *s, bool fixScope){    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))            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;}static const char *error_msg = 0;#ifdef Q_CC_MSVC#define ErrorFormatString "%s(%d): "#else#define ErrorFormatString "%s:%d: "#endifvoid Moc::error(int rollback) {    index -= rollback;    error();}void Moc::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 Moc::warning(const char *msg) {    if (displayWarnings && msg)        fprintf(stderr, ErrorFormatString "Warning: %s\n",                filename.constData(), qMax(0, symbol().lineNum), msg);}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: ;        }    }    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;        default: break;        }        if (t == target            && braceCount <= 0            && brackCount <= 0            && parenCount <= 0            && (target != RANGLE || angleCount <= 0))            return true;        if (braceCount < 0 || brackCount < 0 || parenCount < 0            || (target == RANGLE && angleCount < 0)) {            --index;            break;        }    }    return false;}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::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);    next(IDENTIFIER);    QByteArray name = lexem();    // support "class IDENT name" and "class IDENT(IDENT) name"    if (test(LPAREN)) {        until(RPAREN);        next(IDENTIFIER);        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));    }    next(LBRACE);    def->begin = index - 1;    until(RBRACE);    def->end = index ;    index = def->begin + 1;    return true;}Type Moc::parseType(){    Type type;    bool hasSignedOrUnsigned = false;    bool isVoid = false;    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;            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) == '>')                    type.name += ' ';            }        }        if (test(SCOPE)) {            type.name += lexem();            type.isScoped = true;        } else {            break;        }    }

⌨️ 快捷键说明

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