summaryrefslogtreecommitdiffstats
path: root/tools/linguist/lupdate/qscript.g
diff options
context:
space:
mode:
authorQt Continuous Integration System <qt-info@nokia.com>2010-08-25 01:42:44 (GMT)
committerQt Continuous Integration System <qt-info@nokia.com>2010-08-25 01:42:44 (GMT)
commite141cb25e57b40af839abf872f65895724a39e88 (patch)
treeda07d2abc2e5b58dd9d1dadaf5f819b28dcf7231 /tools/linguist/lupdate/qscript.g
parent675188b766b7b0f7eb65c2e9f3ee7d6017e63453 (diff)
parented1fecfe6b7ce370184ef4dfb421fb387807633b (diff)
downloadQt-e141cb25e57b40af839abf872f65895724a39e88.zip
Qt-e141cb25e57b40af839abf872f65895724a39e88.tar.gz
Qt-e141cb25e57b40af839abf872f65895724a39e88.tar.bz2
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/oslo-staging-1 into 4.7-integration
* '4.7' of scm.dev.nokia.troll.no:qt/oslo-staging-1: (50 commits) Add the missing license headers to the QString benchmark data Fix building of qsimd.cpp on Windows CE Use QElapsedTimer for the benchlib tests. Properly implement the CPU feature disabling in qsimd.cpp. Report the detected CPU features in the corelib boilerplate Detect CPU features on ARM by reading the ELF auxvec. Split the CPU-detection code into multiple functions for readability Fixed delivering gestures to a toplevel widget. Unroll the SSSE3 code even more to avoid the need to keep an extra variable for inverting the result Don't try to compile the SSE2 and SSSE3 code with compilers that don't support them (e.g. ARM) Improve on the SSSE3 with alternate aligning function. Add the beginnings of a new SSSE3-based aligning algorithm Small fixup Update the SSSE3-with-alignment function to use aligned loads. Add an ucstrncmp that uses SSSE3 with aligning. Add an SSSE3 version of ucstrncmp Optimise the tail comparison of ucstrncmp Add a version of ucstrncmp with SSE2 with aligning. Add an SSE2-optimised version of ucstrncmp Add the ucstrncmp benchmarks ...
Diffstat (limited to 'tools/linguist/lupdate/qscript.g')
-rw-r--r--tools/linguist/lupdate/qscript.g249
1 files changed, 219 insertions, 30 deletions
diff --git a/tools/linguist/lupdate/qscript.g b/tools/linguist/lupdate/qscript.g
index 857c58a..e4c2d22 100644
--- a/tools/linguist/lupdate/qscript.g
+++ b/tools/linguist/lupdate/qscript.g
@@ -101,13 +101,16 @@ QT_BEGIN_NAMESPACE
static void recordMessage(
Translator *tor, const QString &context, const QString &text, const QString &comment,
- const QString &extracomment, bool plural, const QString &fileName, int lineNo)
+ const QString &extracomment, const QString &msgid, const TranslatorMessage::ExtraData &extra,
+ bool plural, const QString &fileName, int lineNo)
{
TranslatorMessage msg(
context, text, comment, QString(),
fileName, lineNo, QStringList(),
TranslatorMessage::Unfinished, plural);
msg.setExtraComment(extracomment.simplified());
+ msg.setId(msgid);
+ msg.setExtras(extra);
tor->extend(msg);
}
@@ -115,15 +118,23 @@ static void recordMessage(
namespace QScript
{
+class CommentProcessor
+{
+public:
+ virtual ~CommentProcessor() {}
+ virtual void processComment(const QChar *chars, int length) = 0;
+};
+
class Lexer
{
public:
- Lexer();
+ Lexer(CommentProcessor *);
~Lexer();
- void setCode(const QString &c, int lineno);
+ void setCode(const QString &c, const QString &fileName, int lineno);
int lex();
+ QString fileName() const { return yyfilename; }
int currentLineNo() const { return yylineno; }
int currentColumnNo() const { return yycolumn; }
@@ -203,6 +214,7 @@ public:
{ err = NoError; }
private:
+ QString yyfilename;
int yylineno;
bool done;
char *buffer8;
@@ -256,6 +268,8 @@ private:
void syncProhibitAutomaticSemicolon();
+ void processComment(const QChar *, int);
+
const QChar *code;
uint length;
int yycolumn;
@@ -282,6 +296,8 @@ private:
ParenthesesState parenthesesState;
int parenthesesCount;
bool prohibitAutomaticSemicolon;
+
+ CommentProcessor *commentProcessor;
};
} // namespace QScript
@@ -358,7 +374,7 @@ double integerFromString(const char *buf, int size, int radix)
} // namespace QScript
-QScript::Lexer::Lexer()
+QScript::Lexer::Lexer(QScript::CommentProcessor *proc)
:
yylineno(0),
size8(128), size16(128), restrKeyword(false),
@@ -369,7 +385,8 @@ QScript::Lexer::Lexer()
err(NoError),
check_reserved(true),
parenthesesState(IgnoreParentheses),
- prohibitAutomaticSemicolon(false)
+ prohibitAutomaticSemicolon(false),
+ commentProcessor(proc)
{
// allocate space for read buffers
buffer8 = new char[size8];
@@ -384,9 +401,10 @@ QScript::Lexer::~Lexer()
delete [] buffer16;
}
-void QScript::Lexer::setCode(const QString &c, int lineno)
+void QScript::Lexer::setCode(const QString &c, const QString &fileName, int lineno)
{
errmsg = QString();
+ yyfilename = fileName;
yylineno = lineno;
yycolumn = 1;
restrKeyword = false;
@@ -735,10 +753,12 @@ int QScript::Lexer::lex()
} else if (current == '/' && next1 == '/') {
recordStartPos();
shift(1);
+ Q_ASSERT(pos16 == 0);
state = InSingleLineComment;
} else if (current == '/' && next1 == '*') {
recordStartPos();
shift(1);
+ Q_ASSERT(pos16 == 0);
state = InMultiLineComment;
} else if (current == 0) {
syncProhibitAutomaticSemicolon();
@@ -878,9 +898,12 @@ int QScript::Lexer::lex()
break;
case InSingleLineComment:
if (isLineTerminator()) {
+ record16(current); // include newline
+ processComment(buffer16, pos16);
shiftWindowsLineBreak();
yylineno++;
yycolumn = 0;
+ pos16 = 0;
terminator = true;
bol = true;
if (restrKeyword) {
@@ -890,6 +913,8 @@ int QScript::Lexer::lex()
state = Start;
} else if (current == 0) {
setDone(Eof);
+ } else {
+ record16(current);
}
break;
case InMultiLineComment:
@@ -901,8 +926,12 @@ int QScript::Lexer::lex()
shiftWindowsLineBreak();
yylineno++;
} else if (current == '*' && next1 == '/') {
+ processComment(buffer16, pos16);
+ pos16 = 0;
state = Start;
shift(1);
+ } else {
+ record16(current);
}
break;
case InIdentifier:
@@ -1364,10 +1393,15 @@ void QScript::Lexer::syncProhibitAutomaticSemicolon()
}
}
+void QScript::Lexer::processComment(const QChar *chars, int length)
+{
+ commentProcessor->processComment(chars, length);
+}
+
class Translator;
-class QScriptParser: protected $table
+class QScriptParser: protected $table, public QScript::CommentProcessor
{
public:
QVariant val;
@@ -1383,10 +1417,12 @@ public:
QScriptParser();
~QScriptParser();
- bool parse(QScript::Lexer *lexer,
- const QString &fileName,
- Translator *translator);
+ void setLexer(QScript::Lexer *);
+ bool parse(Translator *translator);
+
+ QString fileName() const
+ { return lexer->fileName(); }
inline QString errorMessage() const
{ return error_message; }
inline int errorLineNumber() const
@@ -1403,6 +1439,10 @@ protected:
inline Location &loc(int index)
{ return location_stack [tos + index - 2]; }
+ std::ostream &yyMsg(int line = 0);
+
+ virtual void processComment(const QChar *, int);
+
protected:
int tos;
int stack_size;
@@ -1412,6 +1452,13 @@ protected:
QString error_message;
int error_lineno;
int error_column;
+
+private:
+ QScript::Lexer *lexer;
+ QString extracomment;
+ QString msgid;
+ QString sourcetext;
+ TranslatorMessage::ExtraData extra;
};
inline void QScriptParser::reallocateStack()
@@ -1438,7 +1485,8 @@ QScriptParser::QScriptParser():
stack_size(0),
sym_stack(0),
state_stack(0),
- location_stack(0)
+ location_stack(0),
+ lexer(0)
{
}
@@ -1460,10 +1508,14 @@ static inline QScriptParser::Location location(QScript::Lexer *lexer)
return loc;
}
-bool QScriptParser::parse(QScript::Lexer *lexer,
- const QString &fileName,
- Translator *translator)
+void QScriptParser::setLexer(QScript::Lexer *lex)
{
+ lexer = lex;
+}
+
+bool QScriptParser::parse(Translator *translator)
+{
+ Q_ASSERT(lexer != 0);
const int INITIAL_STATE = 0;
int yytoken = -1;
@@ -1630,44 +1682,70 @@ CallExpression: MemberExpression Arguments ;
case $rule_number: {
QString name = sym(1).toString();
if ((name == QLatin1String("qsTranslate")) || (name == QLatin1String("QT_TRANSLATE_NOOP"))) {
+ if (!sourcetext.isEmpty())
+ yyMsg(identLineNo) << "//% cannot be used with " << qPrintable(name) << "(). Ignoring\n";
QVariantList args = sym(2).toList();
if (args.size() < 2) {
- std::cerr << qPrintable(fileName) << ':' << identLineNo << ": "
- << qPrintable(name) << "() requires at least two arguments.\n";
+ yyMsg(identLineNo) << qPrintable(name) << "() requires at least two arguments.\n";
} else {
if ((args.at(0).type() != QVariant::String)
|| (args.at(1).type() != QVariant::String)) {
- std::cerr << qPrintable(fileName) << ':' << identLineNo << ": "
- << qPrintable(name) << "(): both arguments must be literal strings.\n";
+ yyMsg(identLineNo) << qPrintable(name) << "(): both arguments must be literal strings.\n";
} else {
QString context = args.at(0).toString();
QString text = args.at(1).toString();
QString comment = args.value(2).toString();
- QString extracomment;
bool plural = (args.size() > 4);
recordMessage(translator, context, text, comment, extracomment,
- plural, fileName, identLineNo);
+ msgid, extra, plural, fileName(), identLineNo);
}
}
+ sourcetext.clear();
+ extracomment.clear();
+ msgid.clear();
+ extra.clear();
} else if ((name == QLatin1String("qsTr")) || (name == QLatin1String("QT_TR_NOOP"))) {
+ if (!sourcetext.isEmpty())
+ yyMsg(identLineNo) << "//% cannot be used with " << qPrintable(name) << "(). Ignoring\n";
QVariantList args = sym(2).toList();
if (args.size() < 1) {
- std::cerr << qPrintable(fileName) << ':' << identLineNo << ": "
- << qPrintable(name) << "() requires at least one argument.\n";
+ yyMsg(identLineNo) << qPrintable(name) << "() requires at least one argument.\n";
} else {
if (args.at(0).type() != QVariant::String) {
- std::cerr << qPrintable(fileName) << ':' << identLineNo << ": "
- << qPrintable(name) << "(): text to translate must be a literal string.\n";
+ yyMsg(identLineNo) << qPrintable(name) << "(): text to translate must be a literal string.\n";
} else {
- QString context = QFileInfo(fileName).baseName();
+ QString context = QFileInfo(fileName()).baseName();
QString text = args.at(0).toString();
QString comment = args.value(1).toString();
- QString extracomment;
bool plural = (args.size() > 2);
recordMessage(translator, context, text, comment, extracomment,
- plural, fileName, identLineNo);
+ msgid, extra, plural, fileName(), identLineNo);
+ }
+ }
+ sourcetext.clear();
+ extracomment.clear();
+ msgid.clear();
+ extra.clear();
+ } else if ((name == QLatin1String("qsTrId")) || (name == QLatin1String("QT_TRID_NOOP"))) {
+ if (!msgid.isEmpty())
+ yyMsg(identLineNo) << "//= cannot be used with " << qPrintable(name) << "(). Ignoring\n";
+ QVariantList args = sym(2).toList();
+ if (args.size() < 1) {
+ yyMsg(identLineNo) << qPrintable(name) << "() requires at least one argument.\n";
+ } else {
+ if (args.at(0).type() != QVariant::String) {
+ yyMsg(identLineNo) << qPrintable(name) << "(): identifier must be a literal string.\n";
+ } else {
+ msgid = args.at(0).toString();
+ bool plural = (args.size() > 1);
+ recordMessage(translator, QString(), sourcetext, QString(), extracomment,
+ msgid, extra, plural, fileName(), identLineNo);
}
}
+ sourcetext.clear();
+ extracomment.clear();
+ msgid.clear();
+ extra.clear();
}
} break;
./
@@ -1813,20 +1891,73 @@ ExpressionNotInOpt: ;
ExpressionNotInOpt: ExpressionNotIn ;
Statement: Block ;
+/.
+ case $rule_number:
+./
Statement: VariableStatement ;
+/.
+ case $rule_number:
+./
Statement: EmptyStatement ;
+/.
+ case $rule_number:
+./
Statement: ExpressionStatement ;
+/.
+ case $rule_number:
+./
Statement: IfStatement ;
+/.
+ case $rule_number:
+./
Statement: IterationStatement ;
+/.
+ case $rule_number:
+./
Statement: ContinueStatement ;
+/.
+ case $rule_number:
+./
Statement: BreakStatement ;
+/.
+ case $rule_number:
+./
Statement: ReturnStatement ;
+/.
+ case $rule_number:
+./
Statement: WithStatement ;
+/.
+ case $rule_number:
+./
Statement: LabelledStatement ;
+/.
+ case $rule_number:
+./
Statement: SwitchStatement ;
+/.
+ case $rule_number:
+./
Statement: ThrowStatement ;
+/.
+ case $rule_number:
+./
Statement: TryStatement ;
+/.
+ case $rule_number:
+./
Statement: DebuggerStatement ;
+/.
+ case $rule_number:
+ if (!sourcetext.isEmpty() || !extracomment.isEmpty() || !msgid.isEmpty() || !extra.isEmpty()) {
+ yyMsg() << "Discarding unconsumed meta data\n";
+ sourcetext.clear();
+ extracomment.clear();
+ msgid.clear();
+ extra.clear();
+ }
+ break;
+./
Block: T_LBRACE StatementListOpt T_RBRACE ;
StatementList: Statement ;
@@ -1988,6 +2119,63 @@ PropertyNameAndValueListOpt: PropertyNameAndValueList ;
return false;
}
+std::ostream &QScriptParser::yyMsg(int line)
+{
+ return std::cerr << qPrintable(fileName()) << ':' << (line ? line : lexer->startLineNo()) << ": ";
+}
+
+void QScriptParser::processComment(const QChar *chars, int length)
+{
+ if (!length)
+ return;
+ // Try to match the logic of the C++ parser.
+ if (*chars == QLatin1Char(':') && chars[1].isSpace()) {
+ extracomment += QString(chars+2, length-2);
+ } else if (*chars == QLatin1Char('=') && chars[1].isSpace()) {
+ msgid = QString(chars+2, length-2).simplified();
+ } else if (*chars == QLatin1Char('~') && chars[1].isSpace()) {
+ QString text = QString(chars+2, length-2).trimmed();
+ int k = text.indexOf(QLatin1Char(' '));
+ if (k > -1)
+ extra.insert(text.left(k), text.mid(k + 1).trimmed());
+ } else if (*chars == QLatin1Char('%') && chars[1].isSpace()) {
+ sourcetext.reserve(sourcetext.length() + length-2);
+ ushort *ptr = (ushort *)sourcetext.data() + sourcetext.length();
+ int p = 2, c;
+ forever {
+ if (p >= length)
+ break;
+ c = chars[p++].unicode();
+ if (isspace(c))
+ continue;
+ if (c != '"') {
+ yyMsg() << "Unexpected character in meta string\n";
+ break;
+ }
+ forever {
+ if (p >= length) {
+ whoops:
+ yyMsg() << "Unterminated meta string\n";
+ break;
+ }
+ c = chars[p++].unicode();
+ if (c == '"')
+ break;
+ if (c == '\\') {
+ if (p >= length)
+ goto whoops;
+ c = chars[p++].unicode();
+ if (c == '\n')
+ goto whoops;
+ *ptr++ = '\\';
+ }
+ *ptr++ = c;
+ }
+ }
+ sourcetext.resize(ptr - (ushort *)sourcetext.data());
+ }
+}
+
bool loadQScript(Translator &translator, const QString &filename, ConversionData &cd)
{
@@ -2007,10 +2195,11 @@ bool loadQScript(Translator &translator, const QString &filename, ConversionData
ts.setAutoDetectUnicode(true);
QString code = ts.readAll();
- QScript::Lexer lexer;
- lexer.setCode(code, /*lineNumber=*/1);
QScriptParser parser;
- if (!parser.parse(&lexer, filename, &translator)) {
+ QScript::Lexer lexer(&parser);
+ lexer.setCode(code, filename, /*lineNumber=*/1);
+ parser.setLexer(&lexer);
+ if (!parser.parse(&translator)) {
std::cerr << qPrintable(filename) << ':' << parser.errorLineNumber() << ": "
<< qPrintable(parser.errorMessage()) << std::endl;
return false;