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.cpp

    r651 r846  
    22/****************************************************************************
    33**
    4 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     4** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    55** All rights reserved.
    66** Contact: Nokia Corporation (qt-info@nokia.com)
     
    4040**
    4141****************************************************************************/
     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
     64QT_BEGIN_NAMESPACE
     65
     66class LU {
     67    Q_DECLARE_TR_FUNCTIONS(LUpdate)
     68};
    4269
    4370class QScriptGrammar
     
    174201  }
    175202};
    176 
    177203
    178204const char *const QScriptGrammar::spell [] = {
     
    748774  -1, -1};
    749775
    750 
    751 #define Q_SCRIPT_REGEXPLITERAL_RULE1 7
    752 
    753 #define Q_SCRIPT_REGEXPLITERAL_RULE2 8
    754 
    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_NAMESPACE
    769 
    770776static void recordMessage(
    771777    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)
    773780{
    774781    TranslatorMessage msg(
     
    777784        TranslatorMessage::Unfinished, plural);
    778785    msg.setExtraComment(extracomment.simplified());
     786    msg.setId(msgid);
     787    msg.setExtras(extra);
    779788    tor->extend(msg);
    780789}
     
    784793{
    785794
     795class CommentProcessor
     796{
     797public:
     798    virtual ~CommentProcessor() {}
     799    virtual void processComment(const QChar *chars, int length) = 0;
     800};
     801
    786802class Lexer
    787803{
    788804public:
    789     Lexer();
     805    Lexer(CommentProcessor *);
    790806    ~Lexer();
    791807
    792     void setCode(const QString &c, int lineno);
     808    void setCode(const QString &c, const QString &fileName, int lineno);
    793809    int lex();
    794810
     811    QString fileName() const { return yyfilename; }
    795812    int currentLineNo() const { return yylineno; }
    796813    int currentColumnNo() const { return yycolumn; }
     
    872889
    873890private:
     891    QString yyfilename;
    874892    int yylineno;
    875893    bool done;
     
    925943    void syncProhibitAutomaticSemicolon();
    926944
     945    void processComment(const QChar *, int);
     946
    927947    const QChar *code;
    928948    uint length;
     
    951971    int parenthesesCount;
    952972    bool prohibitAutomaticSemicolon;
     973
     974    CommentProcessor *commentProcessor;
    953975};
    954976
     
    10271049} // namespace QScript
    10281050
    1029 QScript::Lexer::Lexer()
     1051QScript::Lexer::Lexer(QScript::CommentProcessor *proc)
    10301052    :
    10311053      yylineno(0),
     
    10381060      check_reserved(true),
    10391061      parenthesesState(IgnoreParentheses),
    1040       prohibitAutomaticSemicolon(false)
     1062      prohibitAutomaticSemicolon(false),
     1063      commentProcessor(proc)
    10411064{
    10421065    // allocate space for read buffers
     
    10531076}
    10541077
    1055 void QScript::Lexer::setCode(const QString &c, int lineno)
     1078void QScript::Lexer::setCode(const QString &c, const QString &fileName, int lineno)
    10561079{
    10571080    errmsg = QString();
     1081    yyfilename = fileName;
    10581082    yylineno = lineno;
    10591083    yycolumn = 1;
     
    14041428                recordStartPos();
    14051429                shift(1);
     1430                Q_ASSERT(pos16 == 0);
    14061431                state = InSingleLineComment;
    14071432            } else if (current == '/' && next1 == '*') {
    14081433                recordStartPos();
    14091434                shift(1);
     1435                Q_ASSERT(pos16 == 0);
    14101436                state = InMultiLineComment;
    14111437            } else if (current == 0) {
     
    14661492                    setDone(Bad);
    14671493                    err = IllegalCharacter;
    1468                     errmsg = QLatin1String("Illegal character");
     1494                    errmsg = LU::tr("Illegal character");
    14691495                }
    14701496            }
     
    14771503                setDone(Bad);
    14781504                err = UnclosedStringLiteral;
    1479                 errmsg = QLatin1String("Unclosed string at end of line");
     1505                errmsg = LU::tr("Unclosed string at end of line");
    14801506            } else if (current == '\\') {
    14811507                state = InEscapeSequence;
     
    15031529                    setDone(Bad);
    15041530                    err = IllegalEscapeSequence;
    1505                     errmsg = QLatin1String("Illegal escape squence");
     1531                    errmsg = LU::tr("Illegal escape squence");
    15061532                }
    15071533            } else if (current == 'x')
     
    15421568                setDone(Bad);
    15431569                err = IllegalUnicodeEscapeSequence;
    1544                 errmsg = QLatin1String("Illegal unicode escape sequence");
     1570                errmsg = LU::tr("Illegal unicode escape sequence");
    15451571            }
    15461572            break;
    15471573        case InSingleLineComment:
    15481574            if (isLineTerminator()) {
     1575                record16(current); // include newline
     1576                processComment(buffer16, pos16);
    15491577                shiftWindowsLineBreak();
    15501578                yylineno++;
    15511579                yycolumn = 0;
     1580                pos16 = 0;
    15521581                terminator = true;
    15531582                bol = true;
     
    15591588            } else if (current == 0) {
    15601589                setDone(Eof);
     1590            } else {
     1591                record16(current);
    15611592            }
    15621593            break;
     
    15651596                setDone(Bad);
    15661597                err = UnclosedComment;
    1567                 errmsg = QLatin1String("Unclosed comment at end of file");
     1598                errmsg = LU::tr("Unclosed comment at end of file");
    15681599            } else if (isLineTerminator()) {
    15691600                shiftWindowsLineBreak();
    15701601                yylineno++;
    15711602            } else if (current == '*' && next1 == '/') {
     1603                processComment(buffer16, pos16);
     1604                pos16 = 0;
    15721605                state = Start;
    15731606                shift(1);
     1607            } else {
     1608                record16(current);
    15741609            }
    15751610            break;
     
    16491684                setDone(Bad);
    16501685                err = IllegalExponentIndicator;
    1651                 errmsg = QLatin1String("Illegal syntax for exponential number");
     1686                errmsg = LU::tr("Illegal syntax for exponential number");
    16521687            }
    16531688            break;
     
    16751710        state = Bad;
    16761711        err = IllegalIdentifier;
    1677         errmsg = QLatin1String("Identifier cannot start with numeric literal");
     1712        errmsg = LU::tr("Identifier cannot start with numeric literal");
    16781713    }
    16791714
     
    19942029    while (1) {
    19952030        if (isLineTerminator() || current == 0) {
    1996             errmsg = QLatin1String("Unterminated regular expression literal");
     2031            errmsg = LU::tr("Unterminated regular expression literal");
    19972032            return false;
    19982033        }
     
    20332068}
    20342069
     2070void QScript::Lexer::processComment(const QChar *chars, int length)
     2071{
     2072    commentProcessor->processComment(chars, length);
     2073}
     2074
    20352075
    20362076class Translator;
    20372077
    2038 class QScriptParser: protected QScriptGrammar
     2078class QScriptParser: protected QScriptGrammar, public QScript::CommentProcessor
    20392079{
    20402080public:
     
    20522092    ~QScriptParser();
    20532093
    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(); }
    20582100    inline QString errorMessage() const
    20592101    { return error_message; }
     
    20712113    inline Location &loc(int index)
    20722114    { return location_stack [tos + index - 2]; }
     2115
     2116    std::ostream &yyMsg(int line = 0);
     2117
     2118    virtual void processComment(const QChar *, int);
    20732119
    20742120protected:
     
    20812127    int error_lineno;
    20822128    int error_column;
     2129
     2130private:
     2131    QScript::Lexer *lexer;
     2132    QString extracomment;
     2133    QString msgid;
     2134    QString sourcetext;
     2135    TranslatorMessage::ExtraData extra;
    20832136};
    20842137
     
    21072160    sym_stack(0),
    21082161    state_stack(0),
    2109     location_stack(0)
     2162    location_stack(0),
     2163    lexer(0)
    21102164{
    21112165}
     
    21292183}
    21302184
    2131 bool QScriptParser::parse(QScript::Lexer *lexer,
    2132                     const QString &fileName,
    2133                     Translator *translator)
    2134 {
     2185void QScriptParser::setLexer(QScript::Lexer *lex)
     2186{
     2187    lexer = lex;
     2188}
     2189
     2190bool QScriptParser::parse(Translator *translator)
     2191{
     2192  Q_ASSERT(lexer != 0);
    21352193  const int INITIAL_STATE = 0;
    21362194
     
    22142272    QString name = sym(1).toString();
    22152273    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));
    22162276        QVariantList args = sym(2).toList();
    22172277        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));
    22202279        } else {
    22212280            if ((args.at(0).type() != QVariant::String)
    22222281                || (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));
    22252283            } else {
    22262284                QString context = args.at(0).toString();
    22272285                QString text = args.at(1).toString();
    22282286                QString comment = args.value(2).toString();
    2229                 QString extracomment;
    22302287                bool plural = (args.size() > 4);
    22312288                recordMessage(translator, context, text, comment, extracomment,
    2232                               plural, fileName, identLineNo);
     2289                              msgid, extra, plural, fileName(), identLineNo);
    22332290            }
    22342291        }
     2292        sourcetext.clear();
     2293        extracomment.clear();
     2294        msgid.clear();
     2295        extra.clear();
    22352296    } 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));
    22362299        QVariantList args = sym(2).toList();
    22372300        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));
    22402302        } else {
    22412303            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));
    22442305            } else {
    2245                 QString context = QFileInfo(fileName).baseName();
     2306                QString context = QFileInfo(fileName()).baseName();
    22462307                QString text = args.at(0).toString();
    22472308                QString comment = args.value(1).toString();
    2248                 QString extracomment;
    22492309                bool plural = (args.size() > 2);
    22502310                recordMessage(translator, context, text, comment, extracomment,
    2251                               plural, fileName, identLineNo);
     2311                              msgid, extra, plural, fileName(), identLineNo);
    22522312            }
    22532313        }
     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();
    22542338    }
    22552339} break;
     
    22772361        sym(1) = QVariant();
    22782362} 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;
    22792401
    22802402          } // switch
     
    23322454                {
    23332455                  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 ");
    23352459                  else
    23362460                    error_message += QLatin1String (", ");
     
    23562480}
    23572481
     2482std::ostream &QScriptParser::yyMsg(int line)
     2483{
     2484    return std::cerr << qPrintable(fileName()) << ':' << (line ? line : lexer->startLineNo()) << ": ";
     2485}
     2486
     2487void 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
    23582539
    23592540bool loadQScript(Translator &translator, const QString &filename, ConversionData &cd)
     
    23612542    QFile file(filename);
    23622543    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()));
    23652545        return false;
    23662546    }
     
    23752555
    23762556    QString code = ts.readAll();
    2377     QScript::Lexer lexer;
    2378     lexer.setCode(code, /*lineNumber=*/1);
    23792557    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;
    23832564        return false;
    23842565    }
Note: See TracChangeset for help on using the changeset viewer.