changeset 37 | 758a864f9613 |
parent 33 | 3e2da88830cd |
36:ef0373b55136 | 37:758a864f9613 |
---|---|
45 |
45 |
46 #define Q_SCRIPT_REGEXPLITERAL_RULE2 8 |
46 #define Q_SCRIPT_REGEXPLITERAL_RULE2 8 |
47 |
47 |
48 #include <translator.h> |
48 #include <translator.h> |
49 |
49 |
50 #include <QtCore/QCoreApplication> |
|
50 #include <QtCore/qdebug.h> |
51 #include <QtCore/qdebug.h> |
51 #include <QtCore/qnumeric.h> |
52 #include <QtCore/qnumeric.h> |
52 #include <QtCore/qstring.h> |
53 #include <QtCore/qstring.h> |
53 #include <QtCore/qtextcodec.h> |
54 #include <QtCore/qtextcodec.h> |
54 #include <QtCore/qvariant.h> |
55 #include <QtCore/qvariant.h> |
59 #include <stdlib.h> |
60 #include <stdlib.h> |
60 #include <stdio.h> |
61 #include <stdio.h> |
61 #include <string.h> |
62 #include <string.h> |
62 |
63 |
63 QT_BEGIN_NAMESPACE |
64 QT_BEGIN_NAMESPACE |
65 |
|
66 class LU { |
|
67 Q_DECLARE_TR_FUNCTIONS(LUpdate) |
|
68 }; |
|
64 |
69 |
65 class QScriptGrammar |
70 class QScriptGrammar |
66 { |
71 { |
67 public: |
72 public: |
68 enum { |
73 enum { |
768 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
773 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
769 -1, -1}; |
774 -1, -1}; |
770 |
775 |
771 static void recordMessage( |
776 static void recordMessage( |
772 Translator *tor, const QString &context, const QString &text, const QString &comment, |
777 Translator *tor, const QString &context, const QString &text, const QString &comment, |
773 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) |
|
774 { |
780 { |
775 TranslatorMessage msg( |
781 TranslatorMessage msg( |
776 context, text, comment, QString(), |
782 context, text, comment, QString(), |
777 fileName, lineNo, QStringList(), |
783 fileName, lineNo, QStringList(), |
778 TranslatorMessage::Unfinished, plural); |
784 TranslatorMessage::Unfinished, plural); |
779 msg.setExtraComment(extracomment.simplified()); |
785 msg.setExtraComment(extracomment.simplified()); |
786 msg.setId(msgid); |
|
787 msg.setExtras(extra); |
|
780 tor->extend(msg); |
788 tor->extend(msg); |
781 } |
789 } |
782 |
790 |
783 |
791 |
784 namespace QScript |
792 namespace QScript |
785 { |
793 { |
786 |
794 |
795 class CommentProcessor |
|
796 { |
|
797 public: |
|
798 virtual ~CommentProcessor() {} |
|
799 virtual void processComment(const QChar *chars, int length) = 0; |
|
800 }; |
|
801 |
|
787 class Lexer |
802 class Lexer |
788 { |
803 { |
789 public: |
804 public: |
790 Lexer(); |
805 Lexer(CommentProcessor *); |
791 ~Lexer(); |
806 ~Lexer(); |
792 |
807 |
793 void setCode(const QString &c, int lineno); |
808 void setCode(const QString &c, const QString &fileName, int lineno); |
794 int lex(); |
809 int lex(); |
795 |
810 |
811 QString fileName() const { return yyfilename; } |
|
796 int currentLineNo() const { return yylineno; } |
812 int currentLineNo() const { return yylineno; } |
797 int currentColumnNo() const { return yycolumn; } |
813 int currentColumnNo() const { return yycolumn; } |
798 |
814 |
799 int startLineNo() const { return startlineno; } |
815 int startLineNo() const { return startlineno; } |
800 int startColumnNo() const { return startcolumn; } |
816 int startColumnNo() const { return startcolumn; } |
870 { return err; } |
886 { return err; } |
871 void clearError() |
887 void clearError() |
872 { err = NoError; } |
888 { err = NoError; } |
873 |
889 |
874 private: |
890 private: |
891 QString yyfilename; |
|
875 int yylineno; |
892 int yylineno; |
876 bool done; |
893 bool done; |
877 char *buffer8; |
894 char *buffer8; |
878 QChar *buffer16; |
895 QChar *buffer16; |
879 uint size8, size16; |
896 uint size8, size16; |
923 |
940 |
924 int findReservedWord(const QChar *buffer, int size) const; |
941 int findReservedWord(const QChar *buffer, int size) const; |
925 |
942 |
926 void syncProhibitAutomaticSemicolon(); |
943 void syncProhibitAutomaticSemicolon(); |
927 |
944 |
945 void processComment(const QChar *, int); |
|
946 |
|
928 const QChar *code; |
947 const QChar *code; |
929 uint length; |
948 uint length; |
930 int yycolumn; |
949 int yycolumn; |
931 int startlineno; |
950 int startlineno; |
932 int startcolumn; |
951 int startcolumn; |
949 bool check_reserved; |
968 bool check_reserved; |
950 |
969 |
951 ParenthesesState parenthesesState; |
970 ParenthesesState parenthesesState; |
952 int parenthesesCount; |
971 int parenthesesCount; |
953 bool prohibitAutomaticSemicolon; |
972 bool prohibitAutomaticSemicolon; |
973 |
|
974 CommentProcessor *commentProcessor; |
|
954 }; |
975 }; |
955 |
976 |
956 } // namespace QScript |
977 } // namespace QScript |
957 |
978 |
958 extern double qstrtod(const char *s00, char const **se, bool *ok); |
979 extern double qstrtod(const char *s00, char const **se, bool *ok); |
1025 return result; |
1046 return result; |
1026 } |
1047 } |
1027 |
1048 |
1028 } // namespace QScript |
1049 } // namespace QScript |
1029 |
1050 |
1030 QScript::Lexer::Lexer() |
1051 QScript::Lexer::Lexer(QScript::CommentProcessor *proc) |
1031 : |
1052 : |
1032 yylineno(0), |
1053 yylineno(0), |
1033 size8(128), size16(128), restrKeyword(false), |
1054 size8(128), size16(128), restrKeyword(false), |
1034 stackToken(-1), pos(0), |
1055 stackToken(-1), pos(0), |
1035 code(0), length(0), |
1056 code(0), length(0), |
1036 bol(true), |
1057 bol(true), |
1037 current(0), next1(0), next2(0), next3(0), |
1058 current(0), next1(0), next2(0), next3(0), |
1038 err(NoError), |
1059 err(NoError), |
1039 check_reserved(true), |
1060 check_reserved(true), |
1040 parenthesesState(IgnoreParentheses), |
1061 parenthesesState(IgnoreParentheses), |
1041 prohibitAutomaticSemicolon(false) |
1062 prohibitAutomaticSemicolon(false), |
1063 commentProcessor(proc) |
|
1042 { |
1064 { |
1043 // allocate space for read buffers |
1065 // allocate space for read buffers |
1044 buffer8 = new char[size8]; |
1066 buffer8 = new char[size8]; |
1045 buffer16 = new QChar[size16]; |
1067 buffer16 = new QChar[size16]; |
1046 flags = 0; |
1068 flags = 0; |
1051 { |
1073 { |
1052 delete [] buffer8; |
1074 delete [] buffer8; |
1053 delete [] buffer16; |
1075 delete [] buffer16; |
1054 } |
1076 } |
1055 |
1077 |
1056 void QScript::Lexer::setCode(const QString &c, int lineno) |
1078 void QScript::Lexer::setCode(const QString &c, const QString &fileName, int lineno) |
1057 { |
1079 { |
1058 errmsg = QString(); |
1080 errmsg = QString(); |
1081 yyfilename = fileName; |
|
1059 yylineno = lineno; |
1082 yylineno = lineno; |
1060 yycolumn = 1; |
1083 yycolumn = 1; |
1061 restrKeyword = false; |
1084 restrKeyword = false; |
1062 delimited = false; |
1085 delimited = false; |
1063 stackToken = -1; |
1086 stackToken = -1; |
1402 if (isWhiteSpace()) { |
1425 if (isWhiteSpace()) { |
1403 // do nothing |
1426 // do nothing |
1404 } else if (current == '/' && next1 == '/') { |
1427 } else if (current == '/' && next1 == '/') { |
1405 recordStartPos(); |
1428 recordStartPos(); |
1406 shift(1); |
1429 shift(1); |
1430 Q_ASSERT(pos16 == 0); |
|
1407 state = InSingleLineComment; |
1431 state = InSingleLineComment; |
1408 } else if (current == '/' && next1 == '*') { |
1432 } else if (current == '/' && next1 == '*') { |
1409 recordStartPos(); |
1433 recordStartPos(); |
1410 shift(1); |
1434 shift(1); |
1435 Q_ASSERT(pos16 == 0); |
|
1411 state = InMultiLineComment; |
1436 state = InMultiLineComment; |
1412 } else if (current == 0) { |
1437 } else if (current == 0) { |
1413 syncProhibitAutomaticSemicolon(); |
1438 syncProhibitAutomaticSemicolon(); |
1414 if (!terminator && !delimited && !prohibitAutomaticSemicolon) { |
1439 if (!terminator && !delimited && !prohibitAutomaticSemicolon) { |
1415 // automatic semicolon insertion if program incomplete |
1440 // automatic semicolon insertion if program incomplete |
1464 setDone(Other); |
1489 setDone(Other); |
1465 } |
1490 } |
1466 else { |
1491 else { |
1467 setDone(Bad); |
1492 setDone(Bad); |
1468 err = IllegalCharacter; |
1493 err = IllegalCharacter; |
1469 errmsg = QLatin1String("Illegal character"); |
1494 errmsg = LU::tr("Illegal character"); |
1470 } |
1495 } |
1471 } |
1496 } |
1472 break; |
1497 break; |
1473 case InString: |
1498 case InString: |
1474 if (current == stringType) { |
1499 if (current == stringType) { |
1475 shift(1); |
1500 shift(1); |
1476 setDone(String); |
1501 setDone(String); |
1477 } else if (current == 0 || isLineTerminator()) { |
1502 } else if (current == 0 || isLineTerminator()) { |
1478 setDone(Bad); |
1503 setDone(Bad); |
1479 err = UnclosedStringLiteral; |
1504 err = UnclosedStringLiteral; |
1480 errmsg = QLatin1String("Unclosed string at end of line"); |
1505 errmsg = LU::tr("Unclosed string at end of line"); |
1481 } else if (current == '\\') { |
1506 } else if (current == '\\') { |
1482 state = InEscapeSequence; |
1507 state = InEscapeSequence; |
1483 } else { |
1508 } else { |
1484 record16(current); |
1509 record16(current); |
1485 } |
1510 } |
1501 record16(convertOctal('0', '0', current)); |
1526 record16(convertOctal('0', '0', current)); |
1502 state = InString; |
1527 state = InString; |
1503 } else { |
1528 } else { |
1504 setDone(Bad); |
1529 setDone(Bad); |
1505 err = IllegalEscapeSequence; |
1530 err = IllegalEscapeSequence; |
1506 errmsg = QLatin1String("Illegal escape squence"); |
1531 errmsg = LU::tr("Illegal escape squence"); |
1507 } |
1532 } |
1508 } else if (current == 'x') |
1533 } else if (current == 'x') |
1509 state = InHexEscape; |
1534 state = InHexEscape; |
1510 else if (current == 'u') |
1535 else if (current == 'u') |
1511 state = InUnicodeEscape; |
1536 state = InUnicodeEscape; |
1540 shift(1); |
1565 shift(1); |
1541 setDone(String); |
1566 setDone(String); |
1542 } else { |
1567 } else { |
1543 setDone(Bad); |
1568 setDone(Bad); |
1544 err = IllegalUnicodeEscapeSequence; |
1569 err = IllegalUnicodeEscapeSequence; |
1545 errmsg = QLatin1String("Illegal unicode escape sequence"); |
1570 errmsg = LU::tr("Illegal unicode escape sequence"); |
1546 } |
1571 } |
1547 break; |
1572 break; |
1548 case InSingleLineComment: |
1573 case InSingleLineComment: |
1549 if (isLineTerminator()) { |
1574 if (isLineTerminator()) { |
1575 record16(current); // include newline |
|
1576 processComment(buffer16, pos16); |
|
1550 shiftWindowsLineBreak(); |
1577 shiftWindowsLineBreak(); |
1551 yylineno++; |
1578 yylineno++; |
1552 yycolumn = 0; |
1579 yycolumn = 0; |
1580 pos16 = 0; |
|
1553 terminator = true; |
1581 terminator = true; |
1554 bol = true; |
1582 bol = true; |
1555 if (restrKeyword) { |
1583 if (restrKeyword) { |
1556 token = QScriptGrammar::T_SEMICOLON; |
1584 token = QScriptGrammar::T_SEMICOLON; |
1557 setDone(Other); |
1585 setDone(Other); |
1558 } else |
1586 } else |
1559 state = Start; |
1587 state = Start; |
1560 } else if (current == 0) { |
1588 } else if (current == 0) { |
1561 setDone(Eof); |
1589 setDone(Eof); |
1590 } else { |
|
1591 record16(current); |
|
1562 } |
1592 } |
1563 break; |
1593 break; |
1564 case InMultiLineComment: |
1594 case InMultiLineComment: |
1565 if (current == 0) { |
1595 if (current == 0) { |
1566 setDone(Bad); |
1596 setDone(Bad); |
1567 err = UnclosedComment; |
1597 err = UnclosedComment; |
1568 errmsg = QLatin1String("Unclosed comment at end of file"); |
1598 errmsg = LU::tr("Unclosed comment at end of file"); |
1569 } else if (isLineTerminator()) { |
1599 } else if (isLineTerminator()) { |
1570 shiftWindowsLineBreak(); |
1600 shiftWindowsLineBreak(); |
1571 yylineno++; |
1601 yylineno++; |
1572 } else if (current == '*' && next1 == '/') { |
1602 } else if (current == '*' && next1 == '/') { |
1603 processComment(buffer16, pos16); |
|
1604 pos16 = 0; |
|
1573 state = Start; |
1605 state = Start; |
1574 shift(1); |
1606 shift(1); |
1607 } else { |
|
1608 record16(current); |
|
1575 } |
1609 } |
1576 break; |
1610 break; |
1577 case InIdentifier: |
1611 case InIdentifier: |
1578 if (isIdentLetter(current) || isDecimalDigit(current)) { |
1612 if (isIdentLetter(current) || isDecimalDigit(current)) { |
1579 record16(current); |
1613 record16(current); |
1647 record8(current); |
1681 record8(current); |
1648 state = InExponent; |
1682 state = InExponent; |
1649 } else { |
1683 } else { |
1650 setDone(Bad); |
1684 setDone(Bad); |
1651 err = IllegalExponentIndicator; |
1685 err = IllegalExponentIndicator; |
1652 errmsg = QLatin1String("Illegal syntax for exponential number"); |
1686 errmsg = LU::tr("Illegal syntax for exponential number"); |
1653 } |
1687 } |
1654 break; |
1688 break; |
1655 case InExponent: |
1689 case InExponent: |
1656 if (isDecimalDigit(current)) { |
1690 if (isDecimalDigit(current)) { |
1657 record8(current); |
1691 record8(current); |
1673 // no identifiers allowed directly after numeric literal, e.g. "3in" is bad |
1707 // no identifiers allowed directly after numeric literal, e.g. "3in" is bad |
1674 if ((state == Number || state == Octal || state == Hex) |
1708 if ((state == Number || state == Octal || state == Hex) |
1675 && isIdentLetter(current)) { |
1709 && isIdentLetter(current)) { |
1676 state = Bad; |
1710 state = Bad; |
1677 err = IllegalIdentifier; |
1711 err = IllegalIdentifier; |
1678 errmsg = QLatin1String("Identifier cannot start with numeric literal"); |
1712 errmsg = LU::tr("Identifier cannot start with numeric literal"); |
1679 } |
1713 } |
1680 |
1714 |
1681 // terminate string |
1715 // terminate string |
1682 buffer8[pos8] = '\0'; |
1716 buffer8[pos8] = '\0'; |
1683 |
1717 |
1992 if (prefix == EqualPrefix) |
2026 if (prefix == EqualPrefix) |
1993 record16(QLatin1Char('=')); |
2027 record16(QLatin1Char('=')); |
1994 |
2028 |
1995 while (1) { |
2029 while (1) { |
1996 if (isLineTerminator() || current == 0) { |
2030 if (isLineTerminator() || current == 0) { |
1997 errmsg = QLatin1String("Unterminated regular expression literal"); |
2031 errmsg = LU::tr("Unterminated regular expression literal"); |
1998 return false; |
2032 return false; |
1999 } |
2033 } |
2000 else if (current != '/' || lastWasEscape == true) |
2034 else if (current != '/' || lastWasEscape == true) |
2001 { |
2035 { |
2002 record16(current); |
2036 record16(current); |
2031 } else { |
2065 } else { |
2032 prohibitAutomaticSemicolon = false; |
2066 prohibitAutomaticSemicolon = false; |
2033 } |
2067 } |
2034 } |
2068 } |
2035 |
2069 |
2070 void QScript::Lexer::processComment(const QChar *chars, int length) |
|
2071 { |
|
2072 commentProcessor->processComment(chars, length); |
|
2073 } |
|
2074 |
|
2036 |
2075 |
2037 class Translator; |
2076 class Translator; |
2038 |
2077 |
2039 class QScriptParser: protected QScriptGrammar |
2078 class QScriptParser: protected QScriptGrammar, public QScript::CommentProcessor |
2040 { |
2079 { |
2041 public: |
2080 public: |
2042 QVariant val; |
2081 QVariant val; |
2043 |
2082 |
2044 struct Location { |
2083 struct Location { |
2050 |
2089 |
2051 public: |
2090 public: |
2052 QScriptParser(); |
2091 QScriptParser(); |
2053 ~QScriptParser(); |
2092 ~QScriptParser(); |
2054 |
2093 |
2055 bool parse(QScript::Lexer *lexer, |
2094 void setLexer(QScript::Lexer *); |
2056 const QString &fileName, |
2095 |
2057 Translator *translator); |
2096 bool parse(Translator *translator); |
2058 |
2097 |
2098 QString fileName() const |
|
2099 { return lexer->fileName(); } |
|
2059 inline QString errorMessage() const |
2100 inline QString errorMessage() const |
2060 { return error_message; } |
2101 { return error_message; } |
2061 inline int errorLineNumber() const |
2102 inline int errorLineNumber() const |
2062 { return error_lineno; } |
2103 { return error_lineno; } |
2063 inline int errorColumnNumber() const |
2104 inline int errorColumnNumber() const |
2069 inline QVariant &sym(int index) |
2110 inline QVariant &sym(int index) |
2070 { return sym_stack [tos + index - 1]; } |
2111 { return sym_stack [tos + index - 1]; } |
2071 |
2112 |
2072 inline Location &loc(int index) |
2113 inline Location &loc(int index) |
2073 { return location_stack [tos + index - 2]; } |
2114 { return location_stack [tos + index - 2]; } |
2115 |
|
2116 std::ostream &yyMsg(int line = 0); |
|
2117 |
|
2118 virtual void processComment(const QChar *, int); |
|
2074 |
2119 |
2075 protected: |
2120 protected: |
2076 int tos; |
2121 int tos; |
2077 int stack_size; |
2122 int stack_size; |
2078 QVector<QVariant> sym_stack; |
2123 QVector<QVariant> sym_stack; |
2079 int *state_stack; |
2124 int *state_stack; |
2080 Location *location_stack; |
2125 Location *location_stack; |
2081 QString error_message; |
2126 QString error_message; |
2082 int error_lineno; |
2127 int error_lineno; |
2083 int error_column; |
2128 int error_column; |
2129 |
|
2130 private: |
|
2131 QScript::Lexer *lexer; |
|
2132 QString extracomment; |
|
2133 QString msgid; |
|
2134 QString sourcetext; |
|
2135 TranslatorMessage::ExtraData extra; |
|
2084 }; |
2136 }; |
2085 |
2137 |
2086 inline void QScriptParser::reallocateStack() |
2138 inline void QScriptParser::reallocateStack() |
2087 { |
2139 { |
2088 if (! stack_size) |
2140 if (! stack_size) |
2105 QScriptParser::QScriptParser(): |
2157 QScriptParser::QScriptParser(): |
2106 tos(0), |
2158 tos(0), |
2107 stack_size(0), |
2159 stack_size(0), |
2108 sym_stack(0), |
2160 sym_stack(0), |
2109 state_stack(0), |
2161 state_stack(0), |
2110 location_stack(0) |
2162 location_stack(0), |
2163 lexer(0) |
|
2111 { |
2164 { |
2112 } |
2165 } |
2113 |
2166 |
2114 QScriptParser::~QScriptParser() |
2167 QScriptParser::~QScriptParser() |
2115 { |
2168 { |
2127 loc.endLine = lexer->endLineNo(); |
2180 loc.endLine = lexer->endLineNo(); |
2128 loc.endColumn = lexer->endColumnNo(); |
2181 loc.endColumn = lexer->endColumnNo(); |
2129 return loc; |
2182 return loc; |
2130 } |
2183 } |
2131 |
2184 |
2132 bool QScriptParser::parse(QScript::Lexer *lexer, |
2185 void QScriptParser::setLexer(QScript::Lexer *lex) |
2133 const QString &fileName, |
2186 { |
2134 Translator *translator) |
2187 lexer = lex; |
2135 { |
2188 } |
2189 |
|
2190 bool QScriptParser::parse(Translator *translator) |
|
2191 { |
|
2192 Q_ASSERT(lexer != 0); |
|
2136 const int INITIAL_STATE = 0; |
2193 const int INITIAL_STATE = 0; |
2137 |
2194 |
2138 int yytoken = -1; |
2195 int yytoken = -1; |
2139 int saved_yytoken = -1; |
2196 int saved_yytoken = -1; |
2140 int identLineNo = -1; |
2197 int identLineNo = -1; |
2212 } break; |
2269 } break; |
2213 |
2270 |
2214 case 66: { |
2271 case 66: { |
2215 QString name = sym(1).toString(); |
2272 QString name = sym(1).toString(); |
2216 if ((name == QLatin1String("qsTranslate")) || (name == QLatin1String("QT_TRANSLATE_NOOP"))) { |
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)); |
|
2217 QVariantList args = sym(2).toList(); |
2276 QVariantList args = sym(2).toList(); |
2218 if (args.size() < 2) { |
2277 if (args.size() < 2) { |
2219 std::cerr << qPrintable(fileName) << ':' << identLineNo << ": " |
2278 yyMsg(identLineNo) << qPrintable(LU::tr("%1() requires at least two arguments.\n").arg(name)); |
2220 << qPrintable(name) << "() requires at least two arguments.\n"; |
|
2221 } else { |
2279 } else { |
2222 if ((args.at(0).type() != QVariant::String) |
2280 if ((args.at(0).type() != QVariant::String) |
2223 || (args.at(1).type() != QVariant::String)) { |
2281 || (args.at(1).type() != QVariant::String)) { |
2224 std::cerr << qPrintable(fileName) << ':' << identLineNo << ": " |
2282 yyMsg(identLineNo) << qPrintable(LU::tr("%1(): both arguments must be literal strings.\n").arg(name)); |
2225 << qPrintable(name) << "(): both arguments must be literal strings.\n"; |
|
2226 } else { |
2283 } else { |
2227 QString context = args.at(0).toString(); |
2284 QString context = args.at(0).toString(); |
2228 QString text = args.at(1).toString(); |
2285 QString text = args.at(1).toString(); |
2229 QString comment = args.value(2).toString(); |
2286 QString comment = args.value(2).toString(); |
2230 QString extracomment; |
|
2231 bool plural = (args.size() > 4); |
2287 bool plural = (args.size() > 4); |
2232 recordMessage(translator, context, text, comment, extracomment, |
2288 recordMessage(translator, context, text, comment, extracomment, |
2233 plural, fileName, identLineNo); |
2289 msgid, extra, plural, fileName(), identLineNo); |
2234 } |
2290 } |
2235 } |
2291 } |
2292 sourcetext.clear(); |
|
2293 extracomment.clear(); |
|
2294 msgid.clear(); |
|
2295 extra.clear(); |
|
2236 } else if ((name == QLatin1String("qsTr")) || (name == QLatin1String("QT_TR_NOOP"))) { |
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)); |
|
2237 QVariantList args = sym(2).toList(); |
2299 QVariantList args = sym(2).toList(); |
2238 if (args.size() < 1) { |
2300 if (args.size() < 1) { |
2239 std::cerr << qPrintable(fileName) << ':' << identLineNo << ": " |
2301 yyMsg(identLineNo) << qPrintable(LU::tr("%1() requires at least one argument.\n").arg(name)); |
2240 << qPrintable(name) << "() requires at least one argument.\n"; |
|
2241 } else { |
2302 } else { |
2242 if (args.at(0).type() != QVariant::String) { |
2303 if (args.at(0).type() != QVariant::String) { |
2243 std::cerr << qPrintable(fileName) << ':' << identLineNo << ": " |
2304 yyMsg(identLineNo) << qPrintable(LU::tr("%1(): text to translate must be a literal string.\n").arg(name)); |
2244 << qPrintable(name) << "(): text to translate must be a literal string.\n"; |
|
2245 } else { |
2305 } else { |
2246 QString context = QFileInfo(fileName).baseName(); |
2306 QString context = QFileInfo(fileName()).baseName(); |
2247 QString text = args.at(0).toString(); |
2307 QString text = args.at(0).toString(); |
2248 QString comment = args.value(1).toString(); |
2308 QString comment = args.value(1).toString(); |
2249 QString extracomment; |
|
2250 bool plural = (args.size() > 2); |
2309 bool plural = (args.size() > 2); |
2251 recordMessage(translator, context, text, comment, extracomment, |
2310 recordMessage(translator, context, text, comment, extracomment, |
2252 plural, fileName, identLineNo); |
2311 msgid, extra, plural, fileName(), identLineNo); |
2253 } |
2312 } |
2254 } |
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(); |
|
2255 } |
2338 } |
2256 } break; |
2339 } break; |
2257 |
2340 |
2258 case 70: { |
2341 case 70: { |
2259 sym(1) = QVariantList(); |
2342 sym(1) = QVariantList(); |
2275 if ((sym(1).type() == QVariant::String) || (sym(3).type() == QVariant::String)) |
2358 if ((sym(1).type() == QVariant::String) || (sym(3).type() == QVariant::String)) |
2276 sym(1) = sym(1).toString() + sym(3).toString(); |
2359 sym(1) = sym(1).toString() + sym(3).toString(); |
2277 else |
2360 else |
2278 sym(1) = QVariant(); |
2361 sym(1) = QVariant(); |
2279 } break; |
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; |
|
2280 |
2401 |
2281 } // switch |
2402 } // switch |
2282 |
2403 |
2283 state_stack [tos] = nt_action (act, lhs [r] - TERMINAL_COUNT); |
2404 state_stack [tos] = nt_action (act, lhs [r] - TERMINAL_COUNT); |
2284 |
2405 |
2330 bool first = true; |
2451 bool first = true; |
2331 |
2452 |
2332 for (int s = 0; s < shifts; ++s) |
2453 for (int s = 0; s < shifts; ++s) |
2333 { |
2454 { |
2334 if (first) |
2455 if (first) |
2335 error_message += QLatin1String ("Expected "); |
2456 //: Beginning of the string that contains |
2457 //: comma-separated list of expected tokens |
|
2458 error_message += LU::tr("Expected "); |
|
2336 else |
2459 else |
2337 error_message += QLatin1String (", "); |
2460 error_message += QLatin1String (", "); |
2338 |
2461 |
2339 first = false; |
2462 first = false; |
2340 error_message += QLatin1String("`"); |
2463 error_message += QLatin1String("`"); |
2354 } |
2477 } |
2355 |
2478 |
2356 return false; |
2479 return false; |
2357 } |
2480 } |
2358 |
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 |
|
2359 |
2539 |
2360 bool loadQScript(Translator &translator, const QString &filename, ConversionData &cd) |
2540 bool loadQScript(Translator &translator, const QString &filename, ConversionData &cd) |
2361 { |
2541 { |
2362 QFile file(filename); |
2542 QFile file(filename); |
2363 if (!file.open(QIODevice::ReadOnly)) { |
2543 if (!file.open(QIODevice::ReadOnly)) { |
2364 cd.appendError(QString::fromLatin1("Cannot open %1: %2") |
2544 cd.appendError(LU::tr("Cannot open %1: %2").arg(filename, file.errorString())); |
2365 .arg(filename, file.errorString())); |
|
2366 return false; |
2545 return false; |
2367 } |
2546 } |
2368 QTextStream ts(&file); |
2547 QTextStream ts(&file); |
2369 QByteArray codecName; |
2548 QByteArray codecName; |
2370 if (!cd.m_codecForSource.isEmpty()) |
2549 if (!cd.m_codecForSource.isEmpty()) |
2373 codecName = translator.codecName(); // Just because it should be latin1 already |
2552 codecName = translator.codecName(); // Just because it should be latin1 already |
2374 ts.setCodec(QTextCodec::codecForName(codecName)); |
2553 ts.setCodec(QTextCodec::codecForName(codecName)); |
2375 ts.setAutoDetectUnicode(true); |
2554 ts.setAutoDetectUnicode(true); |
2376 |
2555 |
2377 QString code = ts.readAll(); |
2556 QString code = ts.readAll(); |
2378 QScript::Lexer lexer; |
|
2379 lexer.setCode(code, /*lineNumber=*/1); |
|
2380 QScriptParser parser; |
2557 QScriptParser parser; |
2381 if (!parser.parse(&lexer, filename, &translator)) { |
2558 QScript::Lexer lexer(&parser); |
2559 lexer.setCode(code, filename, /*lineNumber=*/1); |
|
2560 parser.setLexer(&lexer); |
|
2561 if (!parser.parse(&translator)) { |
|
2382 std::cerr << qPrintable(filename) << ':' << parser.errorLineNumber() << ": " |
2562 std::cerr << qPrintable(filename) << ':' << parser.errorLineNumber() << ": " |
2383 << qPrintable(parser.errorMessage()) << std::endl; |
2563 << qPrintable(parser.errorMessage()) << std::endl; |
2384 return false; |
2564 return false; |
2385 } |
2565 } |
2386 |
2566 |