Changeset 846 for trunk/tools/linguist/lupdate/qscript.g
- Timestamp:
- May 5, 2011, 5:36:53 AM (14 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk
- Property svn:mergeinfo changed
/branches/vendor/nokia/qt/4.7.2 (added) merged: 845 /branches/vendor/nokia/qt/current merged: 844 /branches/vendor/nokia/qt/4.6.3 removed
- Property svn:mergeinfo changed
-
trunk/tools/linguist/lupdate/qscript.g
r651 r846 1 1 ---------------------------------------------------------------------------- 2 2 -- 3 -- Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 -- Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 -- All rights reserved. 5 5 -- Contact: Nokia Corporation (qt-info@nokia.com) … … 85 85 #include <translator.h> 86 86 87 #include <QtCore/QCoreApplication> 87 88 #include <QtCore/qdebug.h> 88 89 #include <QtCore/qnumeric.h> … … 91 92 #include <QtCore/qvariant.h> 92 93 94 #include <iostream> 95 93 96 #include <ctype.h> 94 97 #include <stdlib.h> … … 98 101 QT_BEGIN_NAMESPACE 99 102 103 class LU { 104 Q_DECLARE_TR_FUNCTIONS(LUpdate) 105 }; 106 100 107 static void recordMessage( 101 108 Translator *tor, const QString &context, const QString &text, const QString &comment, 102 const QString &extracomment, bool plural, const QString &fileName, int lineNo) 109 const QString &extracomment, const QString &msgid, const TranslatorMessage::ExtraData &extra, 110 bool plural, const QString &fileName, int lineNo) 103 111 { 104 112 TranslatorMessage msg( … … 107 115 TranslatorMessage::Unfinished, plural); 108 116 msg.setExtraComment(extracomment.simplified()); 109 tor->replace(msg); 117 msg.setId(msgid); 118 msg.setExtras(extra); 119 tor->extend(msg); 110 120 } 111 121 … … 114 124 { 115 125 126 class CommentProcessor 127 { 128 public: 129 virtual ~CommentProcessor() {} 130 virtual void processComment(const QChar *chars, int length) = 0; 131 }; 132 116 133 class Lexer 117 134 { 118 135 public: 119 Lexer( );136 Lexer(CommentProcessor *); 120 137 ~Lexer(); 121 138 122 void setCode(const QString &c, int lineno);139 void setCode(const QString &c, const QString &fileName, int lineno); 123 140 int lex(); 124 141 142 QString fileName() const { return yyfilename; } 125 143 int currentLineNo() const { return yylineno; } 126 144 int currentColumnNo() const { return yycolumn; } … … 202 220 203 221 private: 222 QString yyfilename; 204 223 int yylineno; 205 224 bool done; … … 255 274 void syncProhibitAutomaticSemicolon(); 256 275 276 void processComment(const QChar *, int); 277 257 278 const QChar *code; 258 279 uint length; … … 281 302 int parenthesesCount; 282 303 bool prohibitAutomaticSemicolon; 304 305 CommentProcessor *commentProcessor; 283 306 }; 284 307 … … 357 380 } // namespace QScript 358 381 359 QScript::Lexer::Lexer( )382 QScript::Lexer::Lexer(QScript::CommentProcessor *proc) 360 383 : 361 384 yylineno(0), … … 368 391 check_reserved(true), 369 392 parenthesesState(IgnoreParentheses), 370 prohibitAutomaticSemicolon(false) 393 prohibitAutomaticSemicolon(false), 394 commentProcessor(proc) 371 395 { 372 396 // allocate space for read buffers … … 383 407 } 384 408 385 void QScript::Lexer::setCode(const QString &c, int lineno)409 void QScript::Lexer::setCode(const QString &c, const QString &fileName, int lineno) 386 410 { 387 411 errmsg = QString(); 412 yyfilename = fileName; 388 413 yylineno = lineno; 389 414 yycolumn = 1; … … 734 759 recordStartPos(); 735 760 shift(1); 761 Q_ASSERT(pos16 == 0); 736 762 state = InSingleLineComment; 737 763 } else if (current == '/' && next1 == '*') { 738 764 recordStartPos(); 739 765 shift(1); 766 Q_ASSERT(pos16 == 0); 740 767 state = InMultiLineComment; 741 768 } else if (current == 0) { … … 796 823 setDone(Bad); 797 824 err = IllegalCharacter; 798 errmsg = QLatin1String("Illegal character");825 errmsg = LU::tr("Illegal character"); 799 826 } 800 827 } … … 807 834 setDone(Bad); 808 835 err = UnclosedStringLiteral; 809 errmsg = QLatin1String("Unclosed string at end of line");836 errmsg = LU::tr("Unclosed string at end of line"); 810 837 } else if (current == '\\') { 811 838 state = InEscapeSequence; … … 833 860 setDone(Bad); 834 861 err = IllegalEscapeSequence; 835 errmsg = QLatin1String("Illegal escape squence");862 errmsg = LU::tr("Illegal escape squence"); 836 863 } 837 864 } else if (current == 'x') … … 872 899 setDone(Bad); 873 900 err = IllegalUnicodeEscapeSequence; 874 errmsg = QLatin1String("Illegal unicode escape sequence");901 errmsg = LU::tr("Illegal unicode escape sequence"); 875 902 } 876 903 break; 877 904 case InSingleLineComment: 878 905 if (isLineTerminator()) { 906 record16(current); // include newline 907 processComment(buffer16, pos16); 879 908 shiftWindowsLineBreak(); 880 909 yylineno++; 881 910 yycolumn = 0; 911 pos16 = 0; 882 912 terminator = true; 883 913 bol = true; … … 889 919 } else if (current == 0) { 890 920 setDone(Eof); 921 } else { 922 record16(current); 891 923 } 892 924 break; … … 895 927 setDone(Bad); 896 928 err = UnclosedComment; 897 errmsg = QLatin1String("Unclosed comment at end of file");929 errmsg = LU::tr("Unclosed comment at end of file"); 898 930 } else if (isLineTerminator()) { 899 931 shiftWindowsLineBreak(); 900 932 yylineno++; 901 933 } else if (current == '*' && next1 == '/') { 934 processComment(buffer16, pos16); 935 pos16 = 0; 902 936 state = Start; 903 937 shift(1); 938 } else { 939 record16(current); 904 940 } 905 941 break; … … 979 1015 setDone(Bad); 980 1016 err = IllegalExponentIndicator; 981 errmsg = QLatin1String("Illegal syntax for exponential number");1017 errmsg = LU::tr("Illegal syntax for exponential number"); 982 1018 } 983 1019 break; … … 1005 1041 state = Bad; 1006 1042 err = IllegalIdentifier; 1007 errmsg = QLatin1String("Identifier cannot start with numeric literal");1043 errmsg = LU::tr("Identifier cannot start with numeric literal"); 1008 1044 } 1009 1045 … … 1324 1360 while (1) { 1325 1361 if (isLineTerminator() || current == 0) { 1326 errmsg = QLatin1String("Unterminated regular expression literal");1362 errmsg = LU::tr("Unterminated regular expression literal"); 1327 1363 return false; 1328 1364 } … … 1363 1399 } 1364 1400 1401 void QScript::Lexer::processComment(const QChar *chars, int length) 1402 { 1403 commentProcessor->processComment(chars, length); 1404 } 1405 1365 1406 1366 1407 class Translator; 1367 1408 1368 class QScriptParser: protected $table 1409 class QScriptParser: protected $table, public QScript::CommentProcessor 1369 1410 { 1370 1411 public: … … 1382 1423 ~QScriptParser(); 1383 1424 1384 bool parse(QScript::Lexer *lexer, 1385 const QString &fileName, 1386 Translator *translator); 1387 1425 void setLexer(QScript::Lexer *); 1426 1427 bool parse(Translator *translator); 1428 1429 QString fileName() const 1430 { return lexer->fileName(); } 1388 1431 inline QString errorMessage() const 1389 1432 { return error_message; } … … 1401 1444 inline Location &loc(int index) 1402 1445 { return location_stack [tos + index - 2]; } 1446 1447 std::ostream &yyMsg(int line = 0); 1448 1449 virtual void processComment(const QChar *, int); 1403 1450 1404 1451 protected: … … 1411 1458 int error_lineno; 1412 1459 int error_column; 1460 1461 private: 1462 QScript::Lexer *lexer; 1463 QString extracomment; 1464 QString msgid; 1465 QString sourcetext; 1466 TranslatorMessage::ExtraData extra; 1413 1467 }; 1414 1468 … … 1437 1491 sym_stack(0), 1438 1492 state_stack(0), 1439 location_stack(0) 1493 location_stack(0), 1494 lexer(0) 1440 1495 { 1441 1496 } … … 1459 1514 } 1460 1515 1461 bool QScriptParser::parse(QScript::Lexer *lexer, 1462 const QString &fileName, 1463 Translator *translator) 1464 { 1516 void QScriptParser::setLexer(QScript::Lexer *lex) 1517 { 1518 lexer = lex; 1519 } 1520 1521 bool QScriptParser::parse(Translator *translator) 1522 { 1523 Q_ASSERT(lexer != 0); 1465 1524 const int INITIAL_STATE = 0; 1466 1525 … … 1629 1688 QString name = sym(1).toString(); 1630 1689 if ((name == QLatin1String("qsTranslate")) || (name == QLatin1String("QT_TRANSLATE_NOOP"))) { 1690 if (!sourcetext.isEmpty()) 1691 yyMsg(identLineNo) << qPrintable(LU::tr("//% cannot be used with %1(). Ignoring\n").arg(name)); 1631 1692 QVariantList args = sym(2).toList(); 1632 1693 if (args.size() < 2) { 1633 qWarning("%s:%d: %s() requires at least two arguments", 1634 qPrintable(fileName), identLineNo, qPrintable(name)); 1694 yyMsg(identLineNo) << qPrintable(LU::tr("%1() requires at least two arguments.\n").arg(name)); 1635 1695 } else { 1636 1696 if ((args.at(0).type() != QVariant::String) 1637 1697 || (args.at(1).type() != QVariant::String)) { 1638 qWarning("%s:%d: %s(): both arguments must be literal strings", 1639 qPrintable(fileName), identLineNo, qPrintable(name)); 1698 yyMsg(identLineNo) << qPrintable(LU::tr("%1(): both arguments must be literal strings.\n").arg(name)); 1640 1699 } else { 1641 1700 QString context = args.at(0).toString(); 1642 1701 QString text = args.at(1).toString(); 1643 1702 QString comment = args.value(2).toString(); 1644 QString extracomment;1645 1703 bool plural = (args.size() > 4); 1646 1704 recordMessage(translator, context, text, comment, extracomment, 1647 plural, fileName, identLineNo); 1648 } 1649 } 1705 msgid, extra, plural, fileName(), identLineNo); 1706 } 1707 } 1708 sourcetext.clear(); 1709 extracomment.clear(); 1710 msgid.clear(); 1711 extra.clear(); 1650 1712 } else if ((name == QLatin1String("qsTr")) || (name == QLatin1String("QT_TR_NOOP"))) { 1713 if (!sourcetext.isEmpty()) 1714 yyMsg(identLineNo) << qPrintable(LU::tr("//% cannot be used with %1(). Ignoring\n").arg(name)); 1651 1715 QVariantList args = sym(2).toList(); 1652 1716 if (args.size() < 1) { 1653 qWarning("%s:%d: %s() requires at least one argument", 1654 qPrintable(fileName), identLineNo, qPrintable(name)); 1717 yyMsg(identLineNo) << qPrintable(LU::tr("%1() requires at least one argument.\n").arg(name)); 1655 1718 } else { 1656 1719 if (args.at(0).type() != QVariant::String) { 1657 qWarning("%s:%d: %s(): text to translate must be a literal string", 1658 qPrintable(fileName), identLineNo, qPrintable(name)); 1720 yyMsg(identLineNo) << qPrintable(LU::tr("%1(): text to translate must be a literal string.\n").arg(name)); 1659 1721 } else { 1660 QString context = QFileInfo(fileName ).baseName();1722 QString context = QFileInfo(fileName()).baseName(); 1661 1723 QString text = args.at(0).toString(); 1662 1724 QString comment = args.value(1).toString(); 1663 QString extracomment;1664 1725 bool plural = (args.size() > 2); 1665 1726 recordMessage(translator, context, text, comment, extracomment, 1666 plural, fileName, identLineNo); 1667 } 1668 } 1727 msgid, extra, plural, fileName(), identLineNo); 1728 } 1729 } 1730 sourcetext.clear(); 1731 extracomment.clear(); 1732 msgid.clear(); 1733 extra.clear(); 1734 } else if ((name == QLatin1String("qsTrId")) || (name == QLatin1String("QT_TRID_NOOP"))) { 1735 if (!msgid.isEmpty()) 1736 yyMsg(identLineNo) << qPrintable(LU::tr("//= cannot be used with %1(). Ignoring\n").arg(name)); 1737 QVariantList args = sym(2).toList(); 1738 if (args.size() < 1) { 1739 yyMsg(identLineNo) << qPrintable(LU::tr("%1() requires at least one argument.\n").arg(name)); 1740 } else { 1741 if (args.at(0).type() != QVariant::String) { 1742 yyMsg(identLineNo) << qPrintable(LU::tr("%1(): identifier must be a literal string.\n").arg(name)); 1743 } else { 1744 msgid = args.at(0).toString(); 1745 bool plural = (args.size() > 1); 1746 recordMessage(translator, QString(), sourcetext, QString(), extracomment, 1747 msgid, extra, plural, fileName(), identLineNo); 1748 } 1749 } 1750 sourcetext.clear(); 1751 extracomment.clear(); 1752 msgid.clear(); 1753 extra.clear(); 1669 1754 } 1670 1755 } break; … … 1812 1897 1813 1898 Statement: Block ; 1899 /. 1900 case $rule_number: 1901 ./ 1814 1902 Statement: VariableStatement ; 1903 /. 1904 case $rule_number: 1905 ./ 1815 1906 Statement: EmptyStatement ; 1907 /. 1908 case $rule_number: 1909 ./ 1816 1910 Statement: ExpressionStatement ; 1911 /. 1912 case $rule_number: 1913 ./ 1817 1914 Statement: IfStatement ; 1915 /. 1916 case $rule_number: 1917 ./ 1818 1918 Statement: IterationStatement ; 1919 /. 1920 case $rule_number: 1921 ./ 1819 1922 Statement: ContinueStatement ; 1923 /. 1924 case $rule_number: 1925 ./ 1820 1926 Statement: BreakStatement ; 1927 /. 1928 case $rule_number: 1929 ./ 1821 1930 Statement: ReturnStatement ; 1931 /. 1932 case $rule_number: 1933 ./ 1822 1934 Statement: WithStatement ; 1935 /. 1936 case $rule_number: 1937 ./ 1823 1938 Statement: LabelledStatement ; 1939 /. 1940 case $rule_number: 1941 ./ 1824 1942 Statement: SwitchStatement ; 1943 /. 1944 case $rule_number: 1945 ./ 1825 1946 Statement: ThrowStatement ; 1947 /. 1948 case $rule_number: 1949 ./ 1826 1950 Statement: TryStatement ; 1951 /. 1952 case $rule_number: 1953 ./ 1827 1954 Statement: DebuggerStatement ; 1955 /. 1956 case $rule_number: 1957 if (!sourcetext.isEmpty() || !extracomment.isEmpty() || !msgid.isEmpty() || !extra.isEmpty()) { 1958 yyMsg() << qPrintable(LU::tr("Discarding unconsumed meta data\n")); 1959 sourcetext.clear(); 1960 extracomment.clear(); 1961 msgid.clear(); 1962 extra.clear(); 1963 } 1964 break; 1965 ./ 1828 1966 1829 1967 Block: T_LBRACE StatementListOpt T_RBRACE ; … … 1964 2102 if (first) 1965 2103 error_message += QLatin1String ("Expected "); 2104 //: Beginning of the string that contains 2105 //: comma-separated list of expected tokens 2106 error_message += LU::tr("Expected "); 1966 2107 else 1967 2108 error_message += QLatin1String (", "); … … 1987 2128 } 1988 2129 2130 std::ostream &QScriptParser::yyMsg(int line) 2131 { 2132 return std::cerr << qPrintable(fileName()) << ':' << (line ? line : lexer->startLineNo()) << ": "; 2133 } 2134 2135 void QScriptParser::processComment(const QChar *chars, int length) 2136 { 2137 if (!length) 2138 return; 2139 // Try to match the logic of the C++ parser. 2140 if (*chars == QLatin1Char(':') && chars[1].isSpace()) { 2141 extracomment += QString(chars+2, length-2); 2142 } else if (*chars == QLatin1Char('=') && chars[1].isSpace()) { 2143 msgid = QString(chars+2, length-2).simplified(); 2144 } else if (*chars == QLatin1Char('~') && chars[1].isSpace()) { 2145 QString text = QString(chars+2, length-2).trimmed(); 2146 int k = text.indexOf(QLatin1Char(' ')); 2147 if (k > -1) 2148 extra.insert(text.left(k), text.mid(k + 1).trimmed()); 2149 } else if (*chars == QLatin1Char('%') && chars[1].isSpace()) { 2150 sourcetext.reserve(sourcetext.length() + length-2); 2151 ushort *ptr = (ushort *)sourcetext.data() + sourcetext.length(); 2152 int p = 2, c; 2153 forever { 2154 if (p >= length) 2155 break; 2156 c = chars[p++].unicode(); 2157 if (isspace(c)) 2158 continue; 2159 if (c != '"') { 2160 yyMsg() << qPrintable(LU::tr("Unexpected character in meta string\n")); 2161 break; 2162 } 2163 forever { 2164 if (p >= length) { 2165 whoops: 2166 yyMsg() << qPrintable(LU::tr("Unterminated meta string\n")); 2167 break; 2168 } 2169 c = chars[p++].unicode(); 2170 if (c == '"') 2171 break; 2172 if (c == '\\') { 2173 if (p >= length) 2174 goto whoops; 2175 c = chars[p++].unicode(); 2176 if (c == '\n') 2177 goto whoops; 2178 *ptr++ = '\\'; 2179 } 2180 *ptr++ = c; 2181 } 2182 } 2183 sourcetext.resize(ptr - (ushort *)sourcetext.data()); 2184 } 2185 } 2186 1989 2187 1990 2188 bool loadQScript(Translator &translator, const QString &filename, ConversionData &cd) … … 1992 2190 QFile file(filename); 1993 2191 if (!file.open(QIODevice::ReadOnly)) { 1994 cd.appendError(QString::fromLatin1("Cannot open %1: %2") 1995 .arg(filename, file.errorString())); 2192 cd.appendError(LU::tr("Cannot open %1: %2").arg(filename, file.errorString())); 1996 2193 return false; 1997 2194 } … … 2006 2203 2007 2204 QString code = ts.readAll(); 2008 QScript::Lexer lexer;2009 lexer.setCode(code, /*lineNumber=*/1);2010 2205 QScriptParser parser; 2011 if (!parser.parse(&lexer, filename, &translator)) { 2012 qWarning("%s:%d: %s", qPrintable(filename), parser.errorLineNumber(), 2013 qPrintable(parser.errorMessage())); 2206 QScript::Lexer lexer(&parser); 2207 lexer.setCode(code, filename, /*lineNumber=*/1); 2208 parser.setLexer(&lexer); 2209 if (!parser.parse(&translator)) { 2210 std::cerr << qPrintable(filename) << ':' << parser.errorLineNumber() << ": " 2211 << qPrintable(parser.errorMessage()) << std::endl; 2014 2212 return false; 2015 2213 }
Note:
See TracChangeset
for help on using the changeset viewer.