📄 fetchtr.cpp
字号:
static int yyTok;static bool match( int t ){ bool matches = ( yyTok == t ); if ( matches ) yyTok = getToken(); return matches;}static bool matchString( QCString *s ){ bool matches = ( yyTok == Tok_String ); *s = ""; while ( yyTok == Tok_String ) { *s += yyString; yyTok = getToken(); } return matches;}static bool matchEncoding( bool *utf8 ){ if ( yyTok == Tok_Ident ) { if ( strcmp(yyIdent, "QApplication") == 0 ) { yyTok = getToken(); if ( yyTok == Tok_Gulbrandsen ) yyTok = getToken(); } *utf8 = QString( yyIdent ).endsWith( QString("UTF8") ); yyTok = getToken(); return TRUE; } else { return FALSE; }}static void parse( MetaTranslator *tor, const char *initialContext, const char *defaultContext ){ QMap<QCString, QCString> qualifiedContexts; QStringList namespaces; QCString context; QCString text; QCString com; QCString functionContext = initialContext; QCString prefix; bool utf8 = FALSE; bool missing_Q_OBJECT = FALSE; yyTok = getToken(); while ( yyTok != Tok_Eof ) { switch ( yyTok ) { case Tok_class: /* Partial support for inlined functions. */ yyTok = getToken(); if ( yyBraceDepth == (int) namespaces.count() && yyParenDepth == 0 ) { do { /* This code should execute only once, but we play safe with impure definitions such as 'class Q_EXPORT QMessageBox', in which case 'QMessageBox' is the class name, not 'Q_EXPORT'. */ functionContext = yyIdent; yyTok = getToken(); } while ( yyTok == Tok_Ident ); while ( yyTok == Tok_Gulbrandsen ) { yyTok = getToken(); functionContext += "::"; functionContext += yyIdent; yyTok = getToken(); } if ( yyTok == Tok_Colon ) { missing_Q_OBJECT = TRUE; } else { functionContext = defaultContext; } } break; case Tok_namespace: yyTok = getToken(); if ( yyTok == Tok_Ident ) { QCString ns = yyIdent; yyTok = getToken(); if ( yyTok == Tok_LeftBrace && yyBraceDepth == (int) namespaces.count() + 1 ) namespaces.append( QString(ns) ); } break; case Tok_tr: case Tok_trUtf8: utf8 = ( yyTok == Tok_trUtf8 ); yyTok = getToken(); if ( match(Tok_LeftParen) && matchString(&text) ) { com = ""; if ( match(Tok_RightParen) || (match(Tok_Comma) && matchString(&com) && match(Tok_RightParen)) ) { if ( prefix.isNull() ) { context = functionContext; if ( !namespaces.isEmpty() ) context.prepend( (namespaces.join(QString("::")) + QString("::")).latin1() ); } else { context = prefix; } prefix = (const char *) 0; if ( qualifiedContexts.contains(context) ) context = qualifiedContexts[context]; tor->insert( MetaTranslatorMessage(context, text, com, QString::null, utf8) ); 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 = ""; if ( match(Tok_RightParen) || (match(Tok_Comma) && matchString(&com) && (match(Tok_RightParen) || match(Tok_Comma) && matchEncoding(&utf8) && match(Tok_RightParen))) ) tor->insert( MetaTranslatorMessage(context, text, com, QString::null, utf8) ); } break; case Tok_Q_OBJECT: missing_Q_OBJECT = FALSE; yyTok = getToken(); break; case Tok_Ident: if ( !prefix.isNull() ) prefix += "::"; prefix += yyIdent; yyTok = getToken(); if ( yyTok != Tok_Gulbrandsen ) prefix = (const char *) 0; break; case Tok_Comment: com = yyComment; com = com.simplifyWhiteSpace(); if ( com.left(sizeof(MagicComment) - 1) == MagicComment ) { com.remove( 0, sizeof(MagicComment) - 1 ); int k = com.find( ' ' ); if ( k == -1 ) { context = com; } else { context = com.left( k ); com.remove( 0, k + 1 ); tor->insert( MetaTranslatorMessage(context, "", com, QString::null, FALSE) ); } /* Provide a backdoor for people using "using namespace". See the manual for details. */ k = 0; while ( (k = context.find("::", 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? if ( yyBraceDepth == (int) namespaces.count() && yyParenDepth == 0 ) functionContext = prefix; yyTok = getToken(); break; case Tok_RightBrace: case Tok_Semicolon: if ( yyBraceDepth >= 0 && yyBraceDepth + 1 == (int) namespaces.count() ) namespaces.remove( namespaces.fromLast() ); if ( yyBraceDepth == (int) 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: Unbalanced braces in C++ code (or abuse of the C++" " preprocessor)\n", (const char *) yyFileName ); if ( yyParenDepth != 0 ) fprintf( stderr, "%s: Unbalanced parentheses in C++ code (or abuse of the C++" " preprocessor)\n", (const char *) yyFileName );}void fetchtr_cpp( const char *fileName, MetaTranslator *tor, const char *defaultContext, bool mustExist ){ yyInFile = fopen( fileName, "r" ); if ( yyInFile == 0 ) { if ( mustExist ) fprintf( stderr, "lupdate error: Cannot open C++ source file '%s': %s\n", fileName, strerror(errno) ); return; } startTokenizer( fileName, getCharFromFile ); 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 ); parse( tor, context, 0 ); yyInStr = QString::null;}class UiHandler : public QXmlDefaultHandler{public: UiHandler( MetaTranslator *translator, const char *fileName ) : tor( translator ), fname( fileName ), comment( "" ) { } 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 );private: void flush(); MetaTranslator *tor; QCString fname; QString context; QString source; QString comment; QString accum;};bool UiHandler::startElement( const QString& /* namespaceURI */, const QString& /* localName */, const QString& qName, const QXmlAttributes& atts ){ if ( qName == QString("item") ) { flush(); if ( !atts.value(QString("text")).isEmpty() ) source = atts.value( QString("text") ); } else if ( qName == QString("string") ) { flush(); } accum.truncate( 0 ); return TRUE;}bool UiHandler::endElement( const QString& /* namespaceURI */, const QString& /* localName */, const QString& qName ){ accum.replace( QRegExp(QString("\r\n")), "\n" ); if ( qName == QString("class") ) { if ( context.isEmpty() ) context = accum; } else if ( qName == QString("string") ) { source = accum; } else if ( qName == QString("comment") ) { comment = accum; flush(); } else if ( qName == QString("function") ) { fetchtr_inlined_cpp( (const char *) fname, accum, tor, context.latin1() ); } 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().latin1() ); fprintf( stderr, "XML error: %s\n", msg.latin1() ); return FALSE;}void UiHandler::flush(){ if ( !context.isEmpty() && !source.isEmpty() ) tor->insert( MetaTranslatorMessage(context.utf8(), source.utf8(), comment.utf8(), QString::null, TRUE) ); source.truncate( 0 ); comment.truncate( 0 );}void fetchtr_ui( const char *fileName, MetaTranslator *tor, const char * /* defaultContext */, bool mustExist ){ QFile f( fileName ); if ( !f.open(IO_ReadOnly) ) { if ( mustExist ) fprintf( stderr, "lupdate error: cannot open UI file '%s': %s\n", fileName, strerror(errno) ); return; } QTextStream t( &f ); QXmlInputSource in( t ); QXmlSimpleReader reader; reader.setFeature( "http://xml.org/sax/features/namespaces", FALSE ); reader.setFeature( "http://xml.org/sax/features/namespace-prefixes", TRUE ); reader.setFeature( "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 + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -