From d758d652e1b3950f9df6aa4c1bdef67ba9b88b15 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 15 Apr 2010 21:48:28 +0200 Subject: make QT_TR_NOOP work in static initializers do that by ignoring all equal signs and everything between and including brackets. this makes static initializers look effectively like function definitions, thus creating proper context. Task-number: QTBUG-9276 --- .../lupdate/testdata/good/parsecpp/main.cpp | 23 ++++++++++ .../testdata/good/parsecpp/project.ts.result | 17 +++++++ tools/linguist/lupdate/cpp.cpp | 53 +++++++++++++++++++--- 3 files changed, 87 insertions(+), 6 deletions(-) diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp b/tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp index 6e73d6d..0765bfc 100644 --- a/tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp +++ b/tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp @@ -252,3 +252,26 @@ class YetAnotherTest : QObject { //: This is a message without a source string QString test = qtTrId("yet_another_id"); + + + +// QTBUG-9276: context in static initializers +class Bogus : QObject { + Q_OBJECT + + static const char * const s_strings[]; +}; + +const char * const Bogus::s_strings[] = { + QT_TR_NOOP("this should be in Bogus") +}; + +const char * const Bogus::s_strings[SIZE] = { + QT_TR_NOOP("this should be in Bogus") +}; + +void bogosity() +{ + // no spaces here. test collateral damage from ignoring equal sign + Class::member=QObject::tr("just QObject"); +} diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result index 6d50c21..208191d 100644 --- a/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result +++ b/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result @@ -26,6 +26,15 @@ backslashed \ stuff. + Bogus + + + + this should be in Bogus + + + + Dialog2 @@ -184,6 +193,14 @@ backslashed \ stuff. + QObject + + + just QObject + + + + QTranslator diff --git a/tools/linguist/lupdate/cpp.cpp b/tools/linguist/lupdate/cpp.cpp index 3422212..4791450 100644 --- a/tools/linguist/lupdate/cpp.cpp +++ b/tools/linguist/lupdate/cpp.cpp @@ -212,13 +212,15 @@ public: private: struct IfdefState { IfdefState() {} - IfdefState(int _braceDepth, int _parenDepth) : + IfdefState(int _bracketDepth, int _braceDepth, int _parenDepth) : + bracketDepth(_bracketDepth), braceDepth(_braceDepth), parenDepth(_parenDepth), elseLine(-1) {} SavedState state; + int bracketDepth, bracketDepth1st; int braceDepth, braceDepth1st; int parenDepth, parenDepth1st; int elseLine; @@ -280,7 +282,7 @@ private: Tok_tr, Tok_trUtf8, Tok_translate, Tok_translateUtf8, Tok_trid, Tok_Q_OBJECT, Tok_Q_DECLARE_TR_FUNCTIONS, Tok_Ident, Tok_Comment, Tok_String, Tok_Arrow, Tok_Colon, Tok_ColonColon, - Tok_Equals, + Tok_Equals, Tok_LeftBracket, Tok_RightBracket, Tok_LeftBrace, Tok_RightBrace, Tok_LeftParen, Tok_RightParen, Tok_Comma, Tok_Semicolon, Tok_Null, Tok_Integer, Tok_QuotedInclude, Tok_AngledInclude, @@ -296,10 +298,12 @@ private: QString yyWord; qlonglong yyInteger; QStack yyIfdefStack; + int yyBracketDepth; int yyBraceDepth; int yyParenDepth; int yyLineNo; int yyCurLineNo; + int yyBracketLineNo; int yyBraceLineNo; int yyParenLineNo; @@ -336,9 +340,11 @@ CppParser::CppParser(ParseResults *_results) results = new ParseResults; directInclude = false; } + yyBracketDepth = 0; yyBraceDepth = 0; yyParenDepth = 0; yyCurLineNo = 1; + yyBracketLineNo = 1; yyBraceLineNo = 1; yyParenLineNo = 1; yyAtNewline = true; @@ -565,7 +571,7 @@ uint CppParser::getToken() yyCh = getChar(); if (yyCh == 'f') { // if, ifdef, ifndef - yyIfdefStack.push(IfdefState(yyBraceDepth, yyParenDepth)); + yyIfdefStack.push(IfdefState(yyBracketDepth, yyBraceDepth, yyParenDepth)); yyCh = getChar(); } else if (yyCh == 'n') { // include @@ -604,16 +610,20 @@ uint CppParser::getToken() if (!yyIfdefStack.isEmpty()) { IfdefState &is = yyIfdefStack.top(); if (is.elseLine != -1) { - if (yyBraceDepth != is.braceDepth1st || yyParenDepth != is.parenDepth1st) - qWarning("%s:%d: Parenthesis/brace mismatch between " + if (yyBracketDepth != is.bracketDepth1st + || yyBraceDepth != is.braceDepth1st + || yyParenDepth != is.parenDepth1st) + qWarning("%s:%d: Parenthesis/bracket/brace mismatch between " "#if and #else branches; using #if branch\n", qPrintable(yyFileName), is.elseLine); } else { + is.bracketDepth1st = yyBracketDepth; is.braceDepth1st = yyBraceDepth; is.parenDepth1st = yyParenDepth; saveState(&is.state); } is.elseLine = yyLineNo; + yyBracketDepth = is.bracketDepth; yyBraceDepth = is.braceDepth; yyParenDepth = is.parenDepth; } @@ -623,10 +633,13 @@ uint CppParser::getToken() if (!yyIfdefStack.isEmpty()) { IfdefState is = yyIfdefStack.pop(); if (is.elseLine != -1) { - if (yyBraceDepth != is.braceDepth1st || yyParenDepth != is.parenDepth1st) + if (yyBracketDepth != is.bracketDepth1st + || yyBraceDepth != is.braceDepth1st + || yyParenDepth != is.parenDepth1st) qWarning("%s:%d: Parenthesis/brace mismatch between " "#if and #else branches; using #if branch\n", qPrintable(yyFileName), is.elseLine); + yyBracketDepth = is.bracketDepth1st; yyBraceDepth = is.braceDepth1st; yyParenDepth = is.parenDepth1st; loadState(&is.state); @@ -899,6 +912,21 @@ uint CppParser::getToken() yyParenDepth--; yyCh = getChar(); return Tok_RightParen; + case '[': + if (yyBracketDepth == 0) + yyBracketLineNo = yyCurLineNo; + yyBracketDepth++; + yyCh = getChar(); + return Tok_LeftBracket; + case ']': + if (yyBracketDepth == 0) + qWarning("%s:%d: Excess closing bracket in C++ code" + " (or abuse of the C++ preprocessor)\n", + qPrintable(yyFileName), yyCurLineNo); + else + yyBracketDepth--; + yyCh = getChar(); + return Tok_RightBracket; case ',': yyCh = getChar(); return Tok_Comma; @@ -1534,6 +1562,12 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) yyCh = getChar(); yyTok = getToken(); while (yyTok != Tok_Eof) { + // these are array indexing operations. we ignore them entirely + // so they don't confuse our scoping of static initializers. + // we enter the loop by either reading a left bracket or by an + // #else popping the state. + while (yyBracketDepth) + yyTok = getToken(); //qDebug() << "TOKEN: " << yyTok; switch (yyTok) { case Tok_QuotedInclude: { @@ -2074,6 +2108,9 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) default: if (!yyParenDepth) prospectiveContext.clear(); + // fallthrough + case Tok_Equals: // for static initializers; other cases make no difference + case Tok_RightBracket: // ignoring indexing; same reason case_default: yyTok = getToken(); break; @@ -2088,6 +2125,10 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) qWarning("%s:%d: Unbalanced opening parenthesis in C++ code" " (or abuse of the C++ preprocessor)\n", qPrintable(yyFileName), yyParenLineNo); + else if (yyBracketDepth != 0) + qWarning("%s:%d: Unbalanced opening bracket in C++ code" + " (or abuse of the C++ preprocessor)\n", + qPrintable(yyFileName), yyBracketLineNo); } const ParseResults *CppParser::recordResults(bool isHeader) -- cgit v0.12