summaryrefslogtreecommitdiffstats
path: root/tools/linguist/lupdate/cpp.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/linguist/lupdate/cpp.cpp')
-rw-r--r--tools/linguist/lupdate/cpp.cpp163
1 files changed, 92 insertions, 71 deletions
diff --git a/tools/linguist/lupdate/cpp.cpp b/tools/linguist/lupdate/cpp.cpp
index db4bbca..6ea7299 100644
--- a/tools/linguist/lupdate/cpp.cpp
+++ b/tools/linguist/lupdate/cpp.cpp
@@ -50,11 +50,18 @@
#include <QtCore/QString>
#include <QtCore/QTextCodec>
#include <QtCore/QTextStream>
+#include <QtCore/QCoreApplication>
+
+#include <iostream>
#include <ctype.h> // for isXXX()
QT_BEGIN_NAMESPACE
+class LU {
+ Q_DECLARE_TR_FUNCTIONS(LUpdate)
+};
+
/* qmake ignore Q_OBJECT */
static QString MagicComment(QLatin1String("TRANSLATOR"));
@@ -226,6 +233,8 @@ private:
int elseLine;
};
+ std::ostream &yyMsg(int line = 0);
+
uint getChar();
uint getToken();
bool getMacroArgs();
@@ -352,6 +361,12 @@ CppParser::CppParser(ParseResults *_results)
inDefine = false;
}
+
+std::ostream &CppParser::yyMsg(int line)
+{
+ return std::cerr << qPrintable(yyFileName) << ':' << (line ? line : yyLineNo) << ": ";
+}
+
void CppParser::setInput(const QString &in)
{
yyInStr = in;
@@ -474,6 +489,7 @@ STRING(class);
STRING(findMessage);
STRING(friend);
STRING(namespace);
+STRING(operator);
STRING(qtTrId);
STRING(return);
STRING(struct);
@@ -613,9 +629,9 @@ uint CppParser::getToken()
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);
+ yyMsg(is.elseLine)
+ << qPrintable(LU::tr("Parenthesis/bracket/brace mismatch between "
+ "#if and #else branches; using #if branch\n"));
} else {
is.bracketDepth1st = yyBracketDepth;
is.braceDepth1st = yyBraceDepth;
@@ -636,9 +652,9 @@ uint CppParser::getToken()
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);
+ yyMsg(is.elseLine)
+ << qPrintable(LU::tr("Parenthesis/brace mismatch between "
+ "#if and #else branches; using #if branch\n"));
yyBracketDepth = is.bracketDepth1st;
yyBraceDepth = is.braceDepth1st;
yyParenDepth = is.parenDepth1st;
@@ -664,8 +680,7 @@ uint CppParser::getToken()
forever {
yyCh = getChar();
if (yyCh == EOF) {
- qWarning("%s:%d: Unterminated C++ comment\n",
- qPrintable(yyFileName), yyLineNo);
+ yyMsg() << qPrintable(LU::tr("Unterminated C++ comment\n"));
break;
}
@@ -739,6 +754,20 @@ uint CppParser::getToken()
if (yyWord == strnamespace)
return Tok_namespace;
break;
+ case 'o':
+ if (yyWord == stroperator) {
+ // Operator overload declaration/definition.
+ // We need to prevent those characters from confusing the followup
+ // parsing. Actually using them does not add value, so just eat them.
+ while (isspace(yyCh))
+ yyCh = getChar();
+ while (yyCh == '+' || yyCh == '-' || yyCh == '*' || yyCh == '/' || yyCh == '%'
+ || yyCh == '=' || yyCh == '<' || yyCh == '>' || yyCh == '!'
+ || yyCh == '&' || yyCh == '|' || yyCh == '~' || yyCh == '^'
+ || yyCh == '[' || yyCh == ']')
+ yyCh = getChar();
+ }
+ break;
case 'q':
if (yyWord == strqtTrId)
return Tok_trid;
@@ -795,8 +824,7 @@ uint CppParser::getToken()
forever {
yyCh = getChar();
if (yyCh == EOF) {
- qWarning("%s:%d: Unterminated C++ comment\n",
- qPrintable(yyFileName), yyLineNo);
+ yyMsg() << qPrintable(LU::tr("Unterminated C++ comment\n"));
break;
}
*ptr++ = yyCh;
@@ -829,8 +857,7 @@ uint CppParser::getToken()
yyWord.resize(ptr - (ushort *)yyWord.unicode());
if (yyCh != '"')
- qWarning("%s:%d: Unterminated C++ string\n",
- qPrintable(yyFileName), yyLineNo);
+ yyMsg() << qPrintable(LU::tr("Unterminated C++ string\n"));
else
yyCh = getChar();
return Tok_String;
@@ -867,8 +894,7 @@ uint CppParser::getToken()
forever {
if (yyCh == EOF || yyCh == '\n') {
- qWarning("%s:%d: Unterminated C++ character\n",
- qPrintable(yyFileName), yyLineNo);
+ yyMsg() << "Unterminated C++ character\n";
break;
}
yyCh = getChar();
@@ -887,9 +913,9 @@ uint CppParser::getToken()
case '}':
if (yyBraceDepth == yyMinBraceDepth) {
if (!inDefine)
- qWarning("%s:%d: Excess closing brace in C++ code"
- " (or abuse of the C++ preprocessor)\n",
- qPrintable(yyFileName), yyCurLineNo);
+ yyMsg(yyCurLineNo)
+ << qPrintable(LU::tr("Excess closing brace in C++ code"
+ " (or abuse of the C++ preprocessor)\n"));
// Avoid things getting messed up even more
yyCh = getChar();
return Tok_Semicolon;
@@ -905,9 +931,9 @@ uint CppParser::getToken()
return Tok_LeftParen;
case ')':
if (yyParenDepth == 0)
- qWarning("%s:%d: Excess closing parenthesis in C++ code"
- " (or abuse of the C++ preprocessor)\n",
- qPrintable(yyFileName), yyCurLineNo);
+ yyMsg(yyCurLineNo)
+ << qPrintable(LU::tr("Excess closing parenthesis in C++ code"
+ " (or abuse of the C++ preprocessor)\n"));
else
yyParenDepth--;
yyCh = getChar();
@@ -920,9 +946,9 @@ uint CppParser::getToken()
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);
+ yyMsg(yyCurLineNo)
+ << qPrintable(LU::tr("Excess closing bracket in C++ code"
+ " (or abuse of the C++ preprocessor)\n"));
else
yyBracketDepth--;
yyCh = getChar();
@@ -1290,8 +1316,7 @@ void CppParser::processInclude(const QString &file, ConversionData &cd,
QString cleanFile = QDir::cleanPath(file);
if (inclusions.contains(cleanFile)) {
- qWarning("%s:%d: circular inclusion of %s\n",
- qPrintable(yyFileName), yyLineNo, qPrintable(cleanFile));
+ yyMsg() << qPrintable(LU::tr("circular inclusion of %1\n").arg(cleanFile));
return;
}
@@ -1315,9 +1340,7 @@ void CppParser::processInclude(const QString &file, ConversionData &cd,
QFile f(cleanFile);
if (!f.open(QIODevice::ReadOnly)) {
- qWarning("%s:%d: Cannot open %s: %s\n",
- qPrintable(yyFileName), yyLineNo,
- qPrintable(cleanFile), qPrintable(f.errorString()));
+ yyMsg() << qPrintable(LU::tr("Cannot open %1: %2\n").arg(cleanFile, f.errorString()));
return;
}
@@ -1656,8 +1679,7 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
// Forward-declared class definitions can be namespaced.
NamespaceList nsl;
if (!fullyQualify(namespaces, quali, true, &nsl, 0)) {
- qWarning("%s:%d: Ignoring definition of undeclared qualified class\n",
- qPrintable(yyFileName), yyLineNo);
+ yyMsg() << "Ignoring definition of undeclared qualified class\n";
break;
}
namespaceDepths.push(namespaces.count());
@@ -1671,6 +1693,8 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
functionContextUnresolved.clear(); // Pointless
prospectiveContext.clear();
pendingContext.clear();
+
+ yyTok = getToken();
}
break;
case Tok_namespace:
@@ -1684,6 +1708,11 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
if (yyTok == Tok_LeftBrace) {
namespaceDepths.push(namespaces.count());
enterNamespace(&namespaces, ns);
+
+ functionContext = namespaces;
+ functionContextUnresolved.clear();
+ prospectiveContext.clear();
+ pendingContext.clear();
yyTok = getToken();
} else if (yyTok == Tok_Equals) {
// e.g. namespace Is = OuterSpace::InnerSpace;
@@ -1757,8 +1786,7 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
if (!tor)
goto case_default;
if (!sourcetext.isEmpty())
- qWarning("%s:%d: //%% cannot be used with tr() / QT_TR_NOOP(). Ignoring\n",
- qPrintable(yyFileName), yyLineNo);
+ yyMsg() << qPrintable(LU::tr("//% cannot be used with tr() / QT_TR_NOOP(). Ignoring\n"));
utf8 = (yyTok == Tok_trUtf8);
line = yyLineNo;
yyTok = getToken();
@@ -1779,10 +1807,8 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
QStringList unresolved;
if (!fullyQualify(namespaces, pendingContext, true, &functionContext, &unresolved)) {
functionContextUnresolved = unresolved.join(strColons);
- qWarning("%s:%d: Qualifying with unknown namespace/class %s::%s\n",
- qPrintable(yyFileName), yyLineNo,
- qPrintable(stringifyNamespace(functionContext)),
- qPrintable(unresolved.first()));
+ yyMsg() << qPrintable(LU::tr("Qualifying with unknown namespace/class %1::%2\n")
+ .arg(stringifyNamespace(functionContext)).arg(unresolved.first()));
}
pendingContext.clear();
}
@@ -1790,8 +1816,7 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
if (functionContextUnresolved.isEmpty()) {
int idx = functionContext.length();
if (idx < 2) {
- qWarning("%s:%d: tr() cannot be called without context\n",
- qPrintable(yyFileName), yyLineNo);
+ yyMsg() << qPrintable(LU::tr("tr() cannot be called without context\n"));
break;
}
Namespace *fctx;
@@ -1800,9 +1825,8 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
context = stringifyNamespace(functionContext);
fctx = findNamespace(functionContext)->classDef;
if (!fctx->complained) {
- qWarning("%s:%d: Class '%s' lacks Q_OBJECT macro\n",
- qPrintable(yyFileName), yyLineNo,
- qPrintable(context));
+ yyMsg() << qPrintable(LU::tr("Class '%1' lacks Q_OBJECT macro\n")
+ .arg(context));
fctx->complained = true;
}
goto gotctx;
@@ -1830,9 +1854,8 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
int last = prefix.lastIndexOf(strColons);
QString 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' ",
- qPrintable(yyFileName), yyLineNo,
- className.constData(), functionName.constData());
+ yyMsg() << qPrintable(LU::tr("It is not recommended to call tr() from within a constructor '%1::%2'\n")
+ .arg(className).arg(functionName));
}
#endif
prefix.chop(2);
@@ -1847,9 +1870,7 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
context = fctx->trQualification;
}
if (!fctx->hasTrFunctions && !fctx->complained) {
- qWarning("%s:%d: Class '%s' lacks Q_OBJECT macro\n",
- qPrintable(yyFileName), yyLineNo,
- qPrintable(context));
+ yyMsg() << qPrintable(LU::tr("Class '%1' lacks Q_OBJECT macro\n").arg(context));
fctx->complained = true;
}
} else {
@@ -1861,6 +1882,7 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
gotctx:
recordMessage(line, context, text, comment, extracomment, msgid, extra, utf8, plural);
}
+ sourcetext.clear(); // Will have warned about that already
extracomment.clear();
msgid.clear();
extra.clear();
@@ -1870,8 +1892,7 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
if (!tor)
goto case_default;
if (!sourcetext.isEmpty())
- qWarning("%s:%d: //%% cannot be used with translate() / QT_TRANSLATE_NOOP(). Ignoring\n",
- qPrintable(yyFileName), yyLineNo);
+ yyMsg() << qPrintable(LU::tr("//% cannot be used with translate() / QT_TRANSLATE_NOOP(). Ignoring\n"));
utf8 = (yyTok == Tok_translateUtf8);
line = yyLineNo;
yyTok = getToken();
@@ -1917,6 +1938,7 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
}
recordMessage(line, context, text, comment, extracomment, msgid, extra, utf8, plural);
}
+ sourcetext.clear(); // Will have warned about that already
extracomment.clear();
msgid.clear();
extra.clear();
@@ -1925,8 +1947,7 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
if (!tor)
goto case_default;
if (!msgid.isEmpty())
- qWarning("%s:%d: //= cannot be used with qtTrId() / QT_TRID_NOOP(). Ignoring\n",
- qPrintable(yyFileName), yyLineNo);
+ yyMsg() << qPrintable(LU::tr("//= cannot be used with qtTrId() / QT_TRID_NOOP(). Ignoring\n"));
//utf8 = false; // Maybe use //%% or something like that
line = yyLineNo;
yyTok = getToken();
@@ -1993,15 +2014,13 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
if (isspace(c))
continue;
if (c != '"') {
- qWarning("%s:%d: Unexpected character in meta string\n",
- qPrintable(yyFileName), yyLineNo);
+ yyMsg() << qPrintable(LU::tr("Unexpected character in meta string\n"));
break;
}
forever {
if (p >= yyWord.length()) {
whoops:
- qWarning("%s:%d: Unterminated meta string\n",
- qPrintable(yyFileName), yyLineNo);
+ yyMsg() << qPrintable(LU::tr("Unterminated meta string\n"));
break;
}
c = yyWord.unicode()[p++].unicode();
@@ -2054,8 +2073,7 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
case Tok_Arrow:
yyTok = getToken();
if (yyTok == Tok_tr || yyTok == Tok_trUtf8)
- qWarning("%s:%d: Cannot invoke tr() like this\n",
- qPrintable(yyFileName), yyLineNo);
+ yyMsg() << qPrintable(LU::tr("Cannot invoke tr() like this\n"));
break;
case Tok_ColonColon:
if (yyBraceDepth == namespaceDepths.count() && yyParenDepth == 0 && !yyTokColonSeen)
@@ -2087,9 +2105,13 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
case Tok_Semicolon:
prospectiveContext.clear();
prefix.clear();
- extracomment.clear();
- msgid.clear();
- extra.clear();
+ if (!sourcetext.isEmpty() || !extracomment.isEmpty() || !msgid.isEmpty() || !extra.isEmpty()) {
+ yyMsg() << qPrintable(LU::tr("Discarding unconsumed meta data\n"));
+ sourcetext.clear();
+ extracomment.clear();
+ msgid.clear();
+ extra.clear();
+ }
yyTokColonSeen = false;
yyTok = getToken();
break;
@@ -2123,17 +2145,17 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
}
if (yyBraceDepth != 0)
- qWarning("%s:%d: Unbalanced opening brace in C++ code"
- " (or abuse of the C++ preprocessor)\n",
- qPrintable(yyFileName), yyBraceLineNo);
+ yyMsg(yyBraceLineNo)
+ << qPrintable(LU::tr("Unbalanced opening brace in C++ code"
+ " (or abuse of the C++ preprocessor)\n"));
else if (yyParenDepth != 0)
- qWarning("%s:%d: Unbalanced opening parenthesis in C++ code"
- " (or abuse of the C++ preprocessor)\n",
- qPrintable(yyFileName), yyParenLineNo);
+ yyMsg(yyParenLineNo)
+ << qPrintable(LU::tr("Unbalanced opening parenthesis in C++ code"
+ " (or abuse of the C++ preprocessor)\n"));
else if (yyBracketDepth != 0)
- qWarning("%s:%d: Unbalanced opening bracket in C++ code"
- " (or abuse of the C++ preprocessor)\n",
- qPrintable(yyFileName), yyBracketLineNo);
+ yyMsg(yyBracketLineNo)
+ << qPrintable(LU::tr("Unbalanced opening bracket in C++ code"
+ " (or abuse of the C++ preprocessor)\n"));
}
const ParseResults *CppParser::recordResults(bool isHeader)
@@ -2194,8 +2216,7 @@ void loadCPP(Translator &translator, const QStringList &filenames, ConversionDat
QFile file(filename);
if (!file.open(QIODevice::ReadOnly)) {
- cd.appendError(QString::fromLatin1("Cannot open %1: %2")
- .arg(filename, file.errorString()));
+ cd.appendError(LU::tr("Cannot open %1: %2").arg(filename, file.errorString()));
continue;
}