Exemple #1
0
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:%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 );
}
Exemple #2
0
static void parse( MetaTranslator *tor, const char *initialContext,
           const char *defaultContext )
{
    QMap<QByteArray, QByteArray> qualifiedContexts;
    QByteArray context;
    QByteArray text;
    QByteArray com;
    QByteArray functionContext = initialContext;
    QByteArray prefix;
    bool utf8 = false;

    yyTok = getToken();
    while ( yyTok != Tok_Eof ) {
        switch ( yyTok ) {
        case Tok_class:
                yyTok = getToken();
                functionContext = yyIdent;
                yyTok = getToken();
                break;
            case Tok_tr:
            case Tok_trUtf8:
                utf8 = (yyTok == Tok_trUtf8 || (yyCodecForTr && strcmp(yyCodecForTr->name(), "UTF-8") == 0));
                yyTok = getToken();
                if (match(Tok_LeftParen) && matchString(&text))
                {
                    com = "";
                    bool plural = false;

                    if (match(Tok_RightParen))
                    {
                        // There is no comment or plural arguments.
                    }
                    else if (match(Tok_Comma) && matchStringOrNone(&com))
                    {
                        // There is a comment argument.
                        if (match(Tok_RightParen))
                        {
                            // There is no plural argument.
                        }
                        else if (match(Tok_Comma))
                        {
                            // There is a plural argument.
                            plural = true;
                        }
                    }

                    if (prefix.isNull())
                        context = defaultContext;
                    else if (qstrcmp(prefix, "self") == 0)
                        context = functionContext;
                    else
                        context = prefix;

                    prefix = (const char *) 0;

                    if (qualifiedContexts.contains(context))
                        context = qualifiedContexts[context];

                    if (!text.isEmpty())
                    {
                        tor->insert(MetaTranslatorMessage(context, text, com, 
                                yyFileName, yyParenLineNo,
                                QStringList(), utf8,
                                MetaTranslatorMessage::Unfinished, plural));
                    }
                }
                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) && matchStringOrNone(&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;
                        }
                    }
                    if (!text.isEmpty())
                    {
                        tor->insert( MetaTranslatorMessage(context, text, com, 
                                                        yyFileName, yyParenLineNo,
                                                        QStringList(), utf8,
                                                        MetaTranslatorMessage::Unfinished,
                                                        plural) );
                    }
                }
                break;
            case Tok_Ident:
                if ( !prefix.isNull() )
                    prefix += ".";
                prefix += yyIdent;
                yyTok = getToken();
                if ( yyTok != Tok_Dot )
                    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,
                                                        yyFileName, yyParenLineNo,
                                                        QStringList(), false) );
    
                    }
                }
                yyTok = getToken();
                break;
            default:
                yyTok = getToken();
        }
    }

    if ( yyParenDepth != 0 )
        qWarning( "%s: Unbalanced parentheses in Python code",
            (const char *) yyFileName );
}