Changeset 846 for trunk/tools/linguist/lupdate/qscript.cpp
- 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.cpp
r651 r846 2 2 /**************************************************************************** 3 3 ** 4 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).4 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 5 5 ** All rights reserved. 6 6 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 40 40 ** 41 41 ****************************************************************************/ 42 43 44 #define Q_SCRIPT_REGEXPLITERAL_RULE1 7 45 46 #define Q_SCRIPT_REGEXPLITERAL_RULE2 8 47 48 #include <translator.h> 49 50 #include <QtCore/QCoreApplication> 51 #include <QtCore/qdebug.h> 52 #include <QtCore/qnumeric.h> 53 #include <QtCore/qstring.h> 54 #include <QtCore/qtextcodec.h> 55 #include <QtCore/qvariant.h> 56 57 #include <iostream> 58 59 #include <ctype.h> 60 #include <stdlib.h> 61 #include <stdio.h> 62 #include <string.h> 63 64 QT_BEGIN_NAMESPACE 65 66 class LU { 67 Q_DECLARE_TR_FUNCTIONS(LUpdate) 68 }; 42 69 43 70 class QScriptGrammar … … 174 201 } 175 202 }; 176 177 203 178 204 const char *const QScriptGrammar::spell [] = { … … 748 774 -1, -1}; 749 775 750 751 #define Q_SCRIPT_REGEXPLITERAL_RULE1 7752 753 #define Q_SCRIPT_REGEXPLITERAL_RULE2 8754 755 #include <translator.h>756 757 #include <QtCore/qdebug.h>758 #include <QtCore/qnumeric.h>759 #include <QtCore/qstring.h>760 #include <QtCore/qtextcodec.h>761 #include <QtCore/qvariant.h>762 763 #include <ctype.h>764 #include <stdlib.h>765 #include <stdio.h>766 #include <string.h>767 768 QT_BEGIN_NAMESPACE769 770 776 static void recordMessage( 771 777 Translator *tor, const QString &context, const QString &text, const QString &comment, 772 const QString &extracomment, bool plural, const QString &fileName, int lineNo) 778 const QString &extracomment, const QString &msgid, const TranslatorMessage::ExtraData &extra, 779 bool plural, const QString &fileName, int lineNo) 773 780 { 774 781 TranslatorMessage msg( … … 777 784 TranslatorMessage::Unfinished, plural); 778 785 msg.setExtraComment(extracomment.simplified()); 786 msg.setId(msgid); 787 msg.setExtras(extra); 779 788 tor->extend(msg); 780 789 } … … 784 793 { 785 794 795 class CommentProcessor 796 { 797 public: 798 virtual ~CommentProcessor() {} 799 virtual void processComment(const QChar *chars, int length) = 0; 800 }; 801 786 802 class Lexer 787 803 { 788 804 public: 789 Lexer( );805 Lexer(CommentProcessor *); 790 806 ~Lexer(); 791 807 792 void setCode(const QString &c, int lineno);808 void setCode(const QString &c, const QString &fileName, int lineno); 793 809 int lex(); 794 810 811 QString fileName() const { return yyfilename; } 795 812 int currentLineNo() const { return yylineno; } 796 813 int currentColumnNo() const { return yycolumn; } … … 872 889 873 890 private: 891 QString yyfilename; 874 892 int yylineno; 875 893 bool done; … … 925 943 void syncProhibitAutomaticSemicolon(); 926 944 945 void processComment(const QChar *, int); 946 927 947 const QChar *code; 928 948 uint length; … … 951 971 int parenthesesCount; 952 972 bool prohibitAutomaticSemicolon; 973 974 CommentProcessor *commentProcessor; 953 975 }; 954 976 … … 1027 1049 } // namespace QScript 1028 1050 1029 QScript::Lexer::Lexer( )1051 QScript::Lexer::Lexer(QScript::CommentProcessor *proc) 1030 1052 : 1031 1053 yylineno(0), … … 1038 1060 check_reserved(true), 1039 1061 parenthesesState(IgnoreParentheses), 1040 prohibitAutomaticSemicolon(false) 1062 prohibitAutomaticSemicolon(false), 1063 commentProcessor(proc) 1041 1064 { 1042 1065 // allocate space for read buffers … … 1053 1076 } 1054 1077 1055 void QScript::Lexer::setCode(const QString &c, int lineno)1078 void QScript::Lexer::setCode(const QString &c, const QString &fileName, int lineno) 1056 1079 { 1057 1080 errmsg = QString(); 1081 yyfilename = fileName; 1058 1082 yylineno = lineno; 1059 1083 yycolumn = 1; … … 1404 1428 recordStartPos(); 1405 1429 shift(1); 1430 Q_ASSERT(pos16 == 0); 1406 1431 state = InSingleLineComment; 1407 1432 } else if (current == '/' && next1 == '*') { 1408 1433 recordStartPos(); 1409 1434 shift(1); 1435 Q_ASSERT(pos16 == 0); 1410 1436 state = InMultiLineComment; 1411 1437 } else if (current == 0) { … … 1466 1492 setDone(Bad); 1467 1493 err = IllegalCharacter; 1468 errmsg = QLatin1String("Illegal character");1494 errmsg = LU::tr("Illegal character"); 1469 1495 } 1470 1496 } … … 1477 1503 setDone(Bad); 1478 1504 err = UnclosedStringLiteral; 1479 errmsg = QLatin1String("Unclosed string at end of line");1505 errmsg = LU::tr("Unclosed string at end of line"); 1480 1506 } else if (current == '\\') { 1481 1507 state = InEscapeSequence; … … 1503 1529 setDone(Bad); 1504 1530 err = IllegalEscapeSequence; 1505 errmsg = QLatin1String("Illegal escape squence");1531 errmsg = LU::tr("Illegal escape squence"); 1506 1532 } 1507 1533 } else if (current == 'x') … … 1542 1568 setDone(Bad); 1543 1569 err = IllegalUnicodeEscapeSequence; 1544 errmsg = QLatin1String("Illegal unicode escape sequence");1570 errmsg = LU::tr("Illegal unicode escape sequence"); 1545 1571 } 1546 1572 break; 1547 1573 case InSingleLineComment: 1548 1574 if (isLineTerminator()) { 1575 record16(current); // include newline 1576 processComment(buffer16, pos16); 1549 1577 shiftWindowsLineBreak(); 1550 1578 yylineno++; 1551 1579 yycolumn = 0; 1580 pos16 = 0; 1552 1581 terminator = true; 1553 1582 bol = true; … … 1559 1588 } else if (current == 0) { 1560 1589 setDone(Eof); 1590 } else { 1591 record16(current); 1561 1592 } 1562 1593 break; … … 1565 1596 setDone(Bad); 1566 1597 err = UnclosedComment; 1567 errmsg = QLatin1String("Unclosed comment at end of file");1598 errmsg = LU::tr("Unclosed comment at end of file"); 1568 1599 } else if (isLineTerminator()) { 1569 1600 shiftWindowsLineBreak(); 1570 1601 yylineno++; 1571 1602 } else if (current == '*' && next1 == '/') { 1603 processComment(buffer16, pos16); 1604 pos16 = 0; 1572 1605 state = Start; 1573 1606 shift(1); 1607 } else { 1608 record16(current); 1574 1609 } 1575 1610 break; … … 1649 1684 setDone(Bad); 1650 1685 err = IllegalExponentIndicator; 1651 errmsg = QLatin1String("Illegal syntax for exponential number");1686 errmsg = LU::tr("Illegal syntax for exponential number"); 1652 1687 } 1653 1688 break; … … 1675 1710 state = Bad; 1676 1711 err = IllegalIdentifier; 1677 errmsg = QLatin1String("Identifier cannot start with numeric literal");1712 errmsg = LU::tr("Identifier cannot start with numeric literal"); 1678 1713 } 1679 1714 … … 1994 2029 while (1) { 1995 2030 if (isLineTerminator() || current == 0) { 1996 errmsg = QLatin1String("Unterminated regular expression literal");2031 errmsg = LU::tr("Unterminated regular expression literal"); 1997 2032 return false; 1998 2033 } … … 2033 2068 } 2034 2069 2070 void QScript::Lexer::processComment(const QChar *chars, int length) 2071 { 2072 commentProcessor->processComment(chars, length); 2073 } 2074 2035 2075 2036 2076 class Translator; 2037 2077 2038 class QScriptParser: protected QScriptGrammar 2078 class QScriptParser: protected QScriptGrammar, public QScript::CommentProcessor 2039 2079 { 2040 2080 public: … … 2052 2092 ~QScriptParser(); 2053 2093 2054 bool parse(QScript::Lexer *lexer, 2055 const QString &fileName, 2056 Translator *translator); 2057 2094 void setLexer(QScript::Lexer *); 2095 2096 bool parse(Translator *translator); 2097 2098 QString fileName() const 2099 { return lexer->fileName(); } 2058 2100 inline QString errorMessage() const 2059 2101 { return error_message; } … … 2071 2113 inline Location &loc(int index) 2072 2114 { return location_stack [tos + index - 2]; } 2115 2116 std::ostream &yyMsg(int line = 0); 2117 2118 virtual void processComment(const QChar *, int); 2073 2119 2074 2120 protected: … … 2081 2127 int error_lineno; 2082 2128 int error_column; 2129 2130 private: 2131 QScript::Lexer *lexer; 2132 QString extracomment; 2133 QString msgid; 2134 QString sourcetext; 2135 TranslatorMessage::ExtraData extra; 2083 2136 }; 2084 2137 … … 2107 2160 sym_stack(0), 2108 2161 state_stack(0), 2109 location_stack(0) 2162 location_stack(0), 2163 lexer(0) 2110 2164 { 2111 2165 } … … 2129 2183 } 2130 2184 2131 bool QScriptParser::parse(QScript::Lexer *lexer, 2132 const QString &fileName, 2133 Translator *translator) 2134 { 2185 void QScriptParser::setLexer(QScript::Lexer *lex) 2186 { 2187 lexer = lex; 2188 } 2189 2190 bool QScriptParser::parse(Translator *translator) 2191 { 2192 Q_ASSERT(lexer != 0); 2135 2193 const int INITIAL_STATE = 0; 2136 2194 … … 2214 2272 QString name = sym(1).toString(); 2215 2273 if ((name == QLatin1String("qsTranslate")) || (name == QLatin1String("QT_TRANSLATE_NOOP"))) { 2274 if (!sourcetext.isEmpty()) 2275 yyMsg(identLineNo) << qPrintable(LU::tr("//% cannot be used with %1(). Ignoring\n").arg(name)); 2216 2276 QVariantList args = sym(2).toList(); 2217 2277 if (args.size() < 2) { 2218 qWarning("%s:%d: %s() requires at least two arguments", 2219 qPrintable(fileName), identLineNo, qPrintable(name)); 2278 yyMsg(identLineNo) << qPrintable(LU::tr("%1() requires at least two arguments.\n").arg(name)); 2220 2279 } else { 2221 2280 if ((args.at(0).type() != QVariant::String) 2222 2281 || (args.at(1).type() != QVariant::String)) { 2223 qWarning("%s:%d: %s(): both arguments must be literal strings", 2224 qPrintable(fileName), identLineNo, qPrintable(name)); 2282 yyMsg(identLineNo) << qPrintable(LU::tr("%1(): both arguments must be literal strings.\n").arg(name)); 2225 2283 } else { 2226 2284 QString context = args.at(0).toString(); 2227 2285 QString text = args.at(1).toString(); 2228 2286 QString comment = args.value(2).toString(); 2229 QString extracomment;2230 2287 bool plural = (args.size() > 4); 2231 2288 recordMessage(translator, context, text, comment, extracomment, 2232 plural, fileName, identLineNo);2289 msgid, extra, plural, fileName(), identLineNo); 2233 2290 } 2234 2291 } 2292 sourcetext.clear(); 2293 extracomment.clear(); 2294 msgid.clear(); 2295 extra.clear(); 2235 2296 } else if ((name == QLatin1String("qsTr")) || (name == QLatin1String("QT_TR_NOOP"))) { 2297 if (!sourcetext.isEmpty()) 2298 yyMsg(identLineNo) << qPrintable(LU::tr("//% cannot be used with %1(). Ignoring\n").arg(name)); 2236 2299 QVariantList args = sym(2).toList(); 2237 2300 if (args.size() < 1) { 2238 qWarning("%s:%d: %s() requires at least one argument", 2239 qPrintable(fileName), identLineNo, qPrintable(name)); 2301 yyMsg(identLineNo) << qPrintable(LU::tr("%1() requires at least one argument.\n").arg(name)); 2240 2302 } else { 2241 2303 if (args.at(0).type() != QVariant::String) { 2242 qWarning("%s:%d: %s(): text to translate must be a literal string", 2243 qPrintable(fileName), identLineNo, qPrintable(name)); 2304 yyMsg(identLineNo) << qPrintable(LU::tr("%1(): text to translate must be a literal string.\n").arg(name)); 2244 2305 } else { 2245 QString context = QFileInfo(fileName ).baseName();2306 QString context = QFileInfo(fileName()).baseName(); 2246 2307 QString text = args.at(0).toString(); 2247 2308 QString comment = args.value(1).toString(); 2248 QString extracomment;2249 2309 bool plural = (args.size() > 2); 2250 2310 recordMessage(translator, context, text, comment, extracomment, 2251 plural, fileName, identLineNo);2311 msgid, extra, plural, fileName(), identLineNo); 2252 2312 } 2253 2313 } 2314 sourcetext.clear(); 2315 extracomment.clear(); 2316 msgid.clear(); 2317 extra.clear(); 2318 } else if ((name == QLatin1String("qsTrId")) || (name == QLatin1String("QT_TRID_NOOP"))) { 2319 if (!msgid.isEmpty()) 2320 yyMsg(identLineNo) << qPrintable(LU::tr("//= cannot be used with %1(). Ignoring\n").arg(name)); 2321 QVariantList args = sym(2).toList(); 2322 if (args.size() < 1) { 2323 yyMsg(identLineNo) << qPrintable(LU::tr("%1() requires at least one argument.\n").arg(name)); 2324 } else { 2325 if (args.at(0).type() != QVariant::String) { 2326 yyMsg(identLineNo) << qPrintable(LU::tr("%1(): identifier must be a literal string.\n").arg(name)); 2327 } else { 2328 msgid = args.at(0).toString(); 2329 bool plural = (args.size() > 1); 2330 recordMessage(translator, QString(), sourcetext, QString(), extracomment, 2331 msgid, extra, plural, fileName(), identLineNo); 2332 } 2333 } 2334 sourcetext.clear(); 2335 extracomment.clear(); 2336 msgid.clear(); 2337 extra.clear(); 2254 2338 } 2255 2339 } break; … … 2277 2361 sym(1) = QVariant(); 2278 2362 } break; 2363 2364 case 171: 2365 2366 case 172: 2367 2368 case 173: 2369 2370 case 174: 2371 2372 case 175: 2373 2374 case 176: 2375 2376 case 177: 2377 2378 case 178: 2379 2380 case 179: 2381 2382 case 180: 2383 2384 case 181: 2385 2386 case 182: 2387 2388 case 183: 2389 2390 case 184: 2391 2392 case 185: 2393 if (!sourcetext.isEmpty() || !extracomment.isEmpty() || !msgid.isEmpty() || !extra.isEmpty()) { 2394 yyMsg() << qPrintable(LU::tr("Discarding unconsumed meta data\n")); 2395 sourcetext.clear(); 2396 extracomment.clear(); 2397 msgid.clear(); 2398 extra.clear(); 2399 } 2400 break; 2279 2401 2280 2402 } // switch … … 2332 2454 { 2333 2455 if (first) 2334 error_message += QLatin1String ("Expected "); 2456 //: Beginning of the string that contains 2457 //: comma-separated list of expected tokens 2458 error_message += LU::tr("Expected "); 2335 2459 else 2336 2460 error_message += QLatin1String (", "); … … 2356 2480 } 2357 2481 2482 std::ostream &QScriptParser::yyMsg(int line) 2483 { 2484 return std::cerr << qPrintable(fileName()) << ':' << (line ? line : lexer->startLineNo()) << ": "; 2485 } 2486 2487 void QScriptParser::processComment(const QChar *chars, int length) 2488 { 2489 if (!length) 2490 return; 2491 // Try to match the logic of the C++ parser. 2492 if (*chars == QLatin1Char(':') && chars[1].isSpace()) { 2493 extracomment += QString(chars+2, length-2); 2494 } else if (*chars == QLatin1Char('=') && chars[1].isSpace()) { 2495 msgid = QString(chars+2, length-2).simplified(); 2496 } else if (*chars == QLatin1Char('~') && chars[1].isSpace()) { 2497 QString text = QString(chars+2, length-2).trimmed(); 2498 int k = text.indexOf(QLatin1Char(' ')); 2499 if (k > -1) 2500 extra.insert(text.left(k), text.mid(k + 1).trimmed()); 2501 } else if (*chars == QLatin1Char('%') && chars[1].isSpace()) { 2502 sourcetext.reserve(sourcetext.length() + length-2); 2503 ushort *ptr = (ushort *)sourcetext.data() + sourcetext.length(); 2504 int p = 2, c; 2505 forever { 2506 if (p >= length) 2507 break; 2508 c = chars[p++].unicode(); 2509 if (isspace(c)) 2510 continue; 2511 if (c != '"') { 2512 yyMsg() << qPrintable(LU::tr("Unexpected character in meta string\n")); 2513 break; 2514 } 2515 forever { 2516 if (p >= length) { 2517 whoops: 2518 yyMsg() << qPrintable(LU::tr("Unterminated meta string\n")); 2519 break; 2520 } 2521 c = chars[p++].unicode(); 2522 if (c == '"') 2523 break; 2524 if (c == '\\') { 2525 if (p >= length) 2526 goto whoops; 2527 c = chars[p++].unicode(); 2528 if (c == '\n') 2529 goto whoops; 2530 *ptr++ = '\\'; 2531 } 2532 *ptr++ = c; 2533 } 2534 } 2535 sourcetext.resize(ptr - (ushort *)sourcetext.data()); 2536 } 2537 } 2538 2358 2539 2359 2540 bool loadQScript(Translator &translator, const QString &filename, ConversionData &cd) … … 2361 2542 QFile file(filename); 2362 2543 if (!file.open(QIODevice::ReadOnly)) { 2363 cd.appendError(QString::fromLatin1("Cannot open %1: %2") 2364 .arg(filename, file.errorString())); 2544 cd.appendError(LU::tr("Cannot open %1: %2").arg(filename, file.errorString())); 2365 2545 return false; 2366 2546 } … … 2375 2555 2376 2556 QString code = ts.readAll(); 2377 QScript::Lexer lexer;2378 lexer.setCode(code, /*lineNumber=*/1);2379 2557 QScriptParser parser; 2380 if (!parser.parse(&lexer, filename, &translator)) { 2381 qWarning("%s:%d: %s", qPrintable(filename), parser.errorLineNumber(), 2382 qPrintable(parser.errorMessage())); 2558 QScript::Lexer lexer(&parser); 2559 lexer.setCode(code, filename, /*lineNumber=*/1); 2560 parser.setLexer(&lexer); 2561 if (!parser.parse(&translator)) { 2562 std::cerr << qPrintable(filename) << ':' << parser.errorLineNumber() << ": " 2563 << qPrintable(parser.errorMessage()) << std::endl; 2383 2564 return false; 2384 2565 }
Note:
See TracChangeset
for help on using the changeset viewer.