Ignore:
Timestamp:
May 5, 2011, 5:36:53 AM (14 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/tools/linguist/lupdate/qscript.g

    r651 r846  
    11----------------------------------------------------------------------------
    22--
    3 -- Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3-- Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44-- All rights reserved.
    55-- Contact: Nokia Corporation (qt-info@nokia.com)
     
    8585#include <translator.h>
    8686
     87#include <QtCore/QCoreApplication>
    8788#include <QtCore/qdebug.h>
    8889#include <QtCore/qnumeric.h>
     
    9192#include <QtCore/qvariant.h>
    9293
     94#include <iostream>
     95
    9396#include <ctype.h>
    9497#include <stdlib.h>
     
    98101QT_BEGIN_NAMESPACE
    99102
     103class LU {
     104    Q_DECLARE_TR_FUNCTIONS(LUpdate)
     105};
     106
    100107static void recordMessage(
    101108    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)
    103111{
    104112    TranslatorMessage msg(
     
    107115        TranslatorMessage::Unfinished, plural);
    108116    msg.setExtraComment(extracomment.simplified());
    109     tor->replace(msg);
     117    msg.setId(msgid);
     118    msg.setExtras(extra);
     119    tor->extend(msg);
    110120}
    111121
     
    114124{
    115125
     126class CommentProcessor
     127{
     128public:
     129    virtual ~CommentProcessor() {}
     130    virtual void processComment(const QChar *chars, int length) = 0;
     131};
     132
    116133class Lexer
    117134{
    118135public:
    119     Lexer();
     136    Lexer(CommentProcessor *);
    120137    ~Lexer();
    121138
    122     void setCode(const QString &c, int lineno);
     139    void setCode(const QString &c, const QString &fileName, int lineno);
    123140    int lex();
    124141
     142    QString fileName() const { return yyfilename; }
    125143    int currentLineNo() const { return yylineno; }
    126144    int currentColumnNo() const { return yycolumn; }
     
    202220
    203221private:
     222    QString yyfilename;
    204223    int yylineno;
    205224    bool done;
     
    255274    void syncProhibitAutomaticSemicolon();
    256275
     276    void processComment(const QChar *, int);
     277
    257278    const QChar *code;
    258279    uint length;
     
    281302    int parenthesesCount;
    282303    bool prohibitAutomaticSemicolon;
     304
     305    CommentProcessor *commentProcessor;
    283306};
    284307
     
    357380} // namespace QScript
    358381
    359 QScript::Lexer::Lexer()
     382QScript::Lexer::Lexer(QScript::CommentProcessor *proc)
    360383    :
    361384      yylineno(0),
     
    368391      check_reserved(true),
    369392      parenthesesState(IgnoreParentheses),
    370       prohibitAutomaticSemicolon(false)
     393      prohibitAutomaticSemicolon(false),
     394      commentProcessor(proc)
    371395{
    372396    // allocate space for read buffers
     
    383407}
    384408
    385 void QScript::Lexer::setCode(const QString &c, int lineno)
     409void QScript::Lexer::setCode(const QString &c, const QString &fileName, int lineno)
    386410{
    387411    errmsg = QString();
     412    yyfilename = fileName;
    388413    yylineno = lineno;
    389414    yycolumn = 1;
     
    734759                recordStartPos();
    735760                shift(1);
     761                Q_ASSERT(pos16 == 0);
    736762                state = InSingleLineComment;
    737763            } else if (current == '/' && next1 == '*') {
    738764                recordStartPos();
    739765                shift(1);
     766                Q_ASSERT(pos16 == 0);
    740767                state = InMultiLineComment;
    741768            } else if (current == 0) {
     
    796823                    setDone(Bad);
    797824                    err = IllegalCharacter;
    798                     errmsg = QLatin1String("Illegal character");
     825                    errmsg = LU::tr("Illegal character");
    799826                }
    800827            }
     
    807834                setDone(Bad);
    808835                err = UnclosedStringLiteral;
    809                 errmsg = QLatin1String("Unclosed string at end of line");
     836                errmsg = LU::tr("Unclosed string at end of line");
    810837            } else if (current == '\\') {
    811838                state = InEscapeSequence;
     
    833860                    setDone(Bad);
    834861                    err = IllegalEscapeSequence;
    835                     errmsg = QLatin1String("Illegal escape squence");
     862                    errmsg = LU::tr("Illegal escape squence");
    836863                }
    837864            } else if (current == 'x')
     
    872899                setDone(Bad);
    873900                err = IllegalUnicodeEscapeSequence;
    874                 errmsg = QLatin1String("Illegal unicode escape sequence");
     901                errmsg = LU::tr("Illegal unicode escape sequence");
    875902            }
    876903            break;
    877904        case InSingleLineComment:
    878905            if (isLineTerminator()) {
     906                record16(current); // include newline
     907                processComment(buffer16, pos16);
    879908                shiftWindowsLineBreak();
    880909                yylineno++;
    881910                yycolumn = 0;
     911                pos16 = 0;
    882912                terminator = true;
    883913                bol = true;
     
    889919            } else if (current == 0) {
    890920                setDone(Eof);
     921            } else {
     922                record16(current);
    891923            }
    892924            break;
     
    895927                setDone(Bad);
    896928                err = UnclosedComment;
    897                 errmsg = QLatin1String("Unclosed comment at end of file");
     929                errmsg = LU::tr("Unclosed comment at end of file");
    898930            } else if (isLineTerminator()) {
    899931                shiftWindowsLineBreak();
    900932                yylineno++;
    901933            } else if (current == '*' && next1 == '/') {
     934                processComment(buffer16, pos16);
     935                pos16 = 0;
    902936                state = Start;
    903937                shift(1);
     938            } else {
     939                record16(current);
    904940            }
    905941            break;
     
    9791015                setDone(Bad);
    9801016                err = IllegalExponentIndicator;
    981                 errmsg = QLatin1String("Illegal syntax for exponential number");
     1017                errmsg = LU::tr("Illegal syntax for exponential number");
    9821018            }
    9831019            break;
     
    10051041        state = Bad;
    10061042        err = IllegalIdentifier;
    1007         errmsg = QLatin1String("Identifier cannot start with numeric literal");
     1043        errmsg = LU::tr("Identifier cannot start with numeric literal");
    10081044    }
    10091045
     
    13241360    while (1) {
    13251361        if (isLineTerminator() || current == 0) {
    1326             errmsg = QLatin1String("Unterminated regular expression literal");
     1362            errmsg = LU::tr("Unterminated regular expression literal");
    13271363            return false;
    13281364        }
     
    13631399}
    13641400
     1401void QScript::Lexer::processComment(const QChar *chars, int length)
     1402{
     1403    commentProcessor->processComment(chars, length);
     1404}
     1405
    13651406
    13661407class Translator;
    13671408
    1368 class QScriptParser: protected $table
     1409class QScriptParser: protected $table, public QScript::CommentProcessor
    13691410{
    13701411public:
     
    13821423    ~QScriptParser();
    13831424
    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(); }
    13881431    inline QString errorMessage() const
    13891432    { return error_message; }
     
    14011444    inline Location &loc(int index)
    14021445    { return location_stack [tos + index - 2]; }
     1446
     1447    std::ostream &yyMsg(int line = 0);
     1448
     1449    virtual void processComment(const QChar *, int);
    14031450
    14041451protected:
     
    14111458    int error_lineno;
    14121459    int error_column;
     1460
     1461private:
     1462    QScript::Lexer *lexer;
     1463    QString extracomment;
     1464    QString msgid;
     1465    QString sourcetext;
     1466    TranslatorMessage::ExtraData extra;
    14131467};
    14141468
     
    14371491    sym_stack(0),
    14381492    state_stack(0),
    1439     location_stack(0)
     1493    location_stack(0),
     1494    lexer(0)
    14401495{
    14411496}
     
    14591514}
    14601515
    1461 bool QScriptParser::parse(QScript::Lexer *lexer,
    1462                     const QString &fileName,
    1463                     Translator *translator)
    1464 {
     1516void QScriptParser::setLexer(QScript::Lexer *lex)
     1517{
     1518    lexer = lex;
     1519}
     1520
     1521bool QScriptParser::parse(Translator *translator)
     1522{
     1523  Q_ASSERT(lexer != 0);
    14651524  const int INITIAL_STATE = 0;
    14661525
     
    16291688    QString name = sym(1).toString();
    16301689    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));
    16311692        QVariantList args = sym(2).toList();
    16321693        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));
    16351695        } else {
    16361696            if ((args.at(0).type() != QVariant::String)
    16371697                || (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));
    16401699            } else {
    16411700                QString context = args.at(0).toString();
    16421701                QString text = args.at(1).toString();
    16431702                QString comment = args.value(2).toString();
    1644                 QString extracomment;
    16451703                bool plural = (args.size() > 4);
    16461704                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();
    16501712    } 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));
    16511715        QVariantList args = sym(2).toList();
    16521716        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));
    16551718        } else {
    16561719            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));
    16591721            } else {
    1660                 QString context = QFileInfo(fileName).baseName();
     1722                QString context = QFileInfo(fileName()).baseName();
    16611723                QString text = args.at(0).toString();
    16621724                QString comment = args.value(1).toString();
    1663                 QString extracomment;
    16641725                bool plural = (args.size() > 2);
    16651726                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();
    16691754    }
    16701755} break;
     
    18121897
    18131898Statement: Block ;
     1899/.
     1900    case $rule_number:
     1901./
    18141902Statement: VariableStatement ;
     1903/.
     1904    case $rule_number:
     1905./
    18151906Statement: EmptyStatement ;
     1907/.
     1908    case $rule_number:
     1909./
    18161910Statement: ExpressionStatement ;
     1911/.
     1912    case $rule_number:
     1913./
    18171914Statement: IfStatement ;
     1915/.
     1916    case $rule_number:
     1917./
    18181918Statement: IterationStatement ;
     1919/.
     1920    case $rule_number:
     1921./
    18191922Statement: ContinueStatement ;
     1923/.
     1924    case $rule_number:
     1925./
    18201926Statement: BreakStatement ;
     1927/.
     1928    case $rule_number:
     1929./
    18211930Statement: ReturnStatement ;
     1931/.
     1932    case $rule_number:
     1933./
    18221934Statement: WithStatement ;
     1935/.
     1936    case $rule_number:
     1937./
    18231938Statement: LabelledStatement ;
     1939/.
     1940    case $rule_number:
     1941./
    18241942Statement: SwitchStatement ;
     1943/.
     1944    case $rule_number:
     1945./
    18251946Statement: ThrowStatement ;
     1947/.
     1948    case $rule_number:
     1949./
    18261950Statement: TryStatement ;
     1951/.
     1952    case $rule_number:
     1953./
    18271954Statement: 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./
    18281966
    18291967Block: T_LBRACE StatementListOpt T_RBRACE ;
     
    19642102                  if (first)
    19652103                    error_message += QLatin1String ("Expected ");
     2104                    //: Beginning of the string that contains
     2105                    //: comma-separated list of expected tokens
     2106                    error_message += LU::tr("Expected ");
    19662107                  else
    19672108                    error_message += QLatin1String (", ");
     
    19872128}
    19882129
     2130std::ostream &QScriptParser::yyMsg(int line)
     2131{
     2132    return std::cerr << qPrintable(fileName()) << ':' << (line ? line : lexer->startLineNo()) << ": ";
     2133}
     2134
     2135void 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
    19892187
    19902188bool loadQScript(Translator &translator, const QString &filename, ConversionData &cd)
     
    19922190    QFile file(filename);
    19932191    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()));
    19962193        return false;
    19972194    }
     
    20062203
    20072204    QString code = ts.readAll();
    2008     QScript::Lexer lexer;
    2009     lexer.setCode(code, /*lineNumber=*/1);
    20102205    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;
    20142212        return false;
    20152213    }
Note: See TracChangeset for help on using the changeset viewer.