fetchtr.cpp

来自「奇趣公司比较新的qt/emd版本」· C++ 代码 · 共 1,105 行 · 第 1/3 页

CPP
1,105
字号
            yyTok = getToken();            if ( match(Tok_LeftParen) && matchString(&text) ) {                com = "";                bool plural = false;                if ( match(Tok_RightParen) ) {                    // no comment                } else if (match(Tok_Comma) && matchStringOrNull(&com)) {   //comment                    if ( match(Tok_RightParen)) {                        // ok,                    } else if (match(Tok_Comma)) {                        plural = true;                    }                }                if ( prefix.isNull() ) {                    context = functionContext;                } else {#ifdef DIAGNOSE_RETRANSLATABILITY                    int last = prefix.lastIndexOf("::");                    QByteArray className = prefix.mid(last == -1 ? 0 : last + 2);                    if (!className.isEmpty() && className == functionName) {                        qWarning( "%s::%d: It is not recommended to call tr() from within a constructor '%s::%s' ",                                  (const char *) yyFileName, yyLineNo,                                  className.constData(), functionName.constData() );                    }#endif                    context = getFullyQualifiedClassName(classes, namespaces, prefix, true);                }                prefix = (const char *) 0;                if ( qualifiedContexts.contains(context) )                    context = qualifiedContexts[context];                tor->insert( MetaTranslatorMessage(context, text, com, QLatin1String(yyFileName), yyLineNo,                    QStringList(), utf8, MetaTranslatorMessage::Unfinished, plural) );                if ( lacks_Q_OBJECT.contains(context) ) {                    qWarning( "%s:%d: Class '%s' lacks Q_OBJECT macro",                              (const char *) yyFileName, yyLineNo,                              (const char *) context );                    lacks_Q_OBJECT.remove( context );                } else {                    needs_Q_OBJECT.insert( context, 0 );                }            }            break;        case Tok_translate:            utf8 = false;            yyTok = getToken();            if ( match(Tok_LeftParen) &&                 matchString(&context) &&                 match(Tok_Comma) &&                 matchString(&text) ) {                 com = "";                 bool plural = false;                 if (!match(Tok_RightParen)) {                    // look for comment                    if ( match(Tok_Comma) && matchStringOrNull(&com)) {                        if (!match(Tok_RightParen)) {                            // look for encoding                            if (match(Tok_Comma)) {                                if (matchEncoding(&utf8)) {                                    if (!match(Tok_RightParen)) {                                        // look for the plural quantifier,                                        // this can be a number, an identifier or a function call,                                        // so for simplicity we mark it as plural if we know we have a comma instead of an                                        // right parentheses.                                        plural = match(Tok_Comma);                                    }                                } else {                                    // This can be a QTranslator::translate("context", "source", "comment", n) plural translation                                    if (matchExpression() && match(Tok_RightParen)) {                                        plural = true;                                    } else {                                        break;                                    }                                }                            } else {                                break;                            }                        }                    } else {                        break;                    }                 }                tor->insert( MetaTranslatorMessage(context, text, com, QLatin1String(yyFileName), yyLineNo,                                                   QStringList(), utf8, MetaTranslatorMessage::Unfinished, plural) );            }            break;        case Tok_Q_OBJECT:            missing_Q_OBJECT = false;            yyTok = getToken();            break;        case Tok_Ident:            prefix += yyIdent;            yyTok = getToken();            if ( yyTok != Tok_Gulbrandsen )                prefix = (const char *) 0;            break;        case Tok_Comment:            com = yyComment;            com = com.simplified();            if ( com.left(sizeof(MagicComment) - 1) == MagicComment ) {                com.remove( 0, sizeof(MagicComment) - 1 );                int k = com.indexOf( ' ' );                if ( k == -1 ) {                    context = com;                } else {                    context = com.left( k );                    com.remove( 0, k + 1 );                    tor->insert( MetaTranslatorMessage(context, "", com, QLatin1String(yyFileName), yyLineNo,                                                       QStringList(), false) );                }                /*                  Provide a backdoor for people using "using                  namespace". See the manual for details.                */                k = 0;                while ( (k = context.indexOf("::", k)) != -1 ) {                    qualifiedContexts.insert( context.mid(k + 2), context );                    k++;                }            }            yyTok = getToken();            break;        case Tok_Arrow:            yyTok = getToken();            if ( yyTok == Tok_tr || yyTok == Tok_trUtf8 )                qWarning( "%s:%d: Cannot invoke tr() like this",                          (const char *) yyFileName, yyLineNo );            break;        case Tok_Gulbrandsen:            // at top level?            prefix+="::";            if ( yyBraceDepth == (int) namespaces.count() && yyParenDepth == 0 )                functionContext = ::getFullyQualifiedClassName(classes, namespaces, prefix);            yyTok = getToken();#ifdef DIAGNOSE_RETRANSLATABILITY            if ( yyTok == Tok_Ident && yyBraceDepth == (int) namespaces.count() && yyParenDepth == 0 ) {                functionName = yyIdent;            }#endif            break;        case Tok_RightBrace:        case Tok_Semicolon:            if ( yyBraceDepth >= 0 &&                 yyBraceDepth + 1 == namespaces.count() )                namespaces.removeLast();            if ( yyBraceDepth == namespaces.count() ) {                if ( missing_Q_OBJECT ) {                    if ( needs_Q_OBJECT.contains(functionContext) ) {                        qWarning( "%s:%d: Class '%s' lacks Q_OBJECT macro",                                  (const char *) yyFileName, yyLineNo,                                  (const char *) functionContext );                    } else {                        lacks_Q_OBJECT.insert( functionContext, 0 );                    }                }                functionContext = defaultContext;                missing_Q_OBJECT = false;            }            yyTok = getToken();            break;        default:            yyTok = getToken();        }    }    if ( yyBraceDepth != 0 )        fprintf( stderr,                 "%s:%d: Unbalanced braces in C++ code (or abuse of the C++"                  " preprocessor)\n",                  (const char *)yyFileName, yyBraceLineNo );    else if ( yyParenDepth != 0 )        fprintf( stderr,                 "%s:%d: Unbalanced parentheses in C++ code (or abuse of the C++"                 " preprocessor)\n",                 (const char *)yyFileName, yyParenLineNo );}void fetchtr_cpp( const char *fileName, MetaTranslator *tor,                  const char *defaultContext, bool mustExist, const QByteArray &codecForSource ){#if defined(_MSC_VER) && _MSC_VER >= 1400	if (fopen_s(&yyInFile, fileName, "r")) {		if ( mustExist ) {			char buf[100];			strerror_s(buf, sizeof(buf), errno);			fprintf( stderr,                     "lupdate error: Cannot open C++ source file '%s': %s\n",                     fileName, buf );		}#else    yyInFile = fopen( fileName, "r" );    if ( yyInFile == 0 ) {        if ( mustExist )            fprintf( stderr,                     "lupdate error: Cannot open C++ source file '%s': %s\n",                     fileName, strerror(errno) );#endif        return;    }    startTokenizer( fileName, getCharFromFile, tor->codecForTr(), QTextCodec::codecForName(codecForSource) );    parse( tor, 0, defaultContext );    fclose( yyInFile );}/*  In addition to C++, we support Qt Designer UI files.*//*  Fetches tr() calls in C++ code in UI files (inside "<function>"  tag). This mechanism is obsolete.*/void fetchtr_inlined_cpp( const char *fileName, const QString& in,                          MetaTranslator *tor, const char *context ){    yyInStr = in;    startTokenizer( fileName, getCharFromString, 0, 0 );    parse( tor, context, 0 );    yyInStr.clear();}class UiHandler : public QXmlDefaultHandler{public:    UiHandler( MetaTranslator *translator, const char *fileName )        : tor( translator ), fname( fileName ), comment( QLatin1String("") ), m_lineNumber(-1)  { }    virtual bool startElement( const QString& namespaceURI,                               const QString& localName, const QString& qName,                               const QXmlAttributes& atts );    virtual bool endElement( const QString& namespaceURI,                             const QString& localName, const QString& qName );    virtual bool characters( const QString& ch );    virtual bool fatalError( const QXmlParseException& exception );    virtual void setDocumentLocator(QXmlLocator *locator)    {        m_locator = locator;    }    QXmlLocator *m_locator;private:    void flush();    MetaTranslator *tor;    QByteArray fname;    QString context;    QString source;    QString comment;    QString accum;    int m_lineNumber;    bool trString;};bool UiHandler::startElement( const QString& /* namespaceURI */,                              const QString& /* localName */,                              const QString& qName,                              const QXmlAttributes& atts ){    if ( qName == QString(QLatin1String("item")) ) {        flush();        if ( !atts.value(QString(QLatin1String("text"))).isEmpty() )            source = atts.value( QString(QLatin1String("text")) );    } else if ( qName == QString(QLatin1String("string")) ) {        flush();        if (atts.value(QString(QLatin1String("notr"))).isEmpty() ||            atts.value(QString(QLatin1String("notr"))) != QString(QLatin1String("true"))) {            trString = true;            comment = atts.value(QString(QLatin1String("comment")));        } else {            trString = false;        }    }    if (trString) m_lineNumber = m_locator->lineNumber();    accum.truncate( 0 );    return true;}bool UiHandler::endElement( const QString& /* namespaceURI */,                            const QString& /* localName */,                            const QString& qName ){    accum.replace( QRegExp(QString(QLatin1String("\r\n"))), QLatin1String("\n") );    if ( qName == QString(QLatin1String("class")) ) {        if ( context.isEmpty() )            context = accum;    } else if ( qName == QString(QLatin1String("string")) && trString ) {        source = accum;    } else if ( qName == QString(QLatin1String("comment")) ) {        comment = accum;        flush();    } else if ( qName == QString(QLatin1String("function")) ) {        fetchtr_inlined_cpp( (const char *) fname, accum, tor,                             context.toLatin1() );    } else {        flush();    }    return true;}bool UiHandler::characters( const QString& ch ){    accum += ch;    return true;}bool UiHandler::fatalError( const QXmlParseException& exception ){    QString msg;    msg.sprintf( "Parse error at line %d, column %d (%s).",                 exception.lineNumber(), exception.columnNumber(),                 exception.message().toLatin1().data() );    fprintf( stderr, "XML error: %s\n", msg.toLatin1().data() );    return false;}void UiHandler::flush(){    if ( !context.isEmpty() && !source.isEmpty() )        tor->insert( MetaTranslatorMessage(context.toUtf8(), source.toUtf8(),                                           comment.toUtf8(), QLatin1String(fname), m_lineNumber,                                           QStringList(), true) );    source.truncate( 0 );    comment.truncate( 0 );}void fetchtr_ui( const char *fileName, MetaTranslator *tor,                 const char * /* defaultContext */, bool mustExist ){    QFile f( QString::fromLatin1(fileName) );    if ( !f.open(QIODevice::ReadOnly) ) {		if ( mustExist ) {#if defined(_MSC_VER) && _MSC_VER >= 1400			char buf[100];			strerror_s(buf, sizeof(buf), errno);			fprintf( stderr, "lupdate error: cannot open UI file '%s': %s\n",                     fileName, buf );#else            fprintf( stderr, "lupdate error: cannot open UI file '%s': %s\n",                     fileName, strerror(errno) );#endif		}        return;    }    QXmlInputSource in( &f );    QXmlSimpleReader reader;    reader.setFeature( QLatin1String("http://xml.org/sax/features/namespaces"), false );    reader.setFeature( QLatin1String("http://xml.org/sax/features/namespace-prefixes"), true );    reader.setFeature( QLatin1String("http://trolltech.com/xml/features/report-whitespace"                                     "-only-CharData"), false );    QXmlDefaultHandler *hand = new UiHandler( tor, fileName );    reader.setContentHandler( hand );    reader.setErrorHandler( hand );    if ( !reader.parse(in) )        fprintf( stderr, "%s: Parse error in UI file\n", fileName );    reader.setContentHandler( 0 );    reader.setErrorHandler( 0 );    delete hand;    f.close();}

⌨️ 快捷键说明

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