OSDN Git Service

remove redundant sources from shared linguist
authorIvailo Monev <xakepa10@gmail.com>
Tue, 7 Jun 2016 18:02:54 +0000 (21:02 +0300)
committerIvailo Monev <xakepa10@gmail.com>
Tue, 7 Jun 2016 18:02:54 +0000 (21:02 +0300)
Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
src/shared/linguist/linguist.cmake
src/shared/linguist/po.cpp [deleted file]
src/shared/linguist/qm.cpp [deleted file]
src/shared/linguist/qph.cpp [deleted file]
src/shared/linguist/ts.cpp [deleted file]

index b0e48ca..7621403 100644 (file)
@@ -21,10 +21,6 @@ set(SHAREDLINGUIST_SOURCES
     ${CMAKE_SOURCE_DIR}/src/shared/linguist/numerus.cpp
     ${CMAKE_SOURCE_DIR}/src/shared/linguist/translator.cpp
     ${CMAKE_SOURCE_DIR}/src/shared/linguist/translatormessage.cpp
-    ${CMAKE_SOURCE_DIR}/src/shared/linguist/qm.cpp
-    ${CMAKE_SOURCE_DIR}/src/shared/linguist/qph.cpp
-    ${CMAKE_SOURCE_DIR}/src/shared/linguist/po.cpp
-    ${CMAKE_SOURCE_DIR}/src/shared/linguist/ts.cpp
 )
 
 set(SHAREDLINGUIST_HEADERS
diff --git a/src/shared/linguist/po.cpp b/src/shared/linguist/po.cpp
deleted file mode 100644 (file)
index 6c4375d..0000000
+++ /dev/null
@@ -1,902 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the Qt Linguist of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file.  Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "translator.h"
-
-#include <QtCore/QDebug>
-#include <QtCore/QIODevice>
-#include <QtCore/QHash>
-#include <QtCore/QString>
-#include <QtCore/QTextCodec>
-#include <QtCore/QTextStream>
-
-#include <ctype.h>
-
-// Uncomment if you wish to hard wrap long lines in .po files. Note that this
-// affects only msg strings, not comments.
-//#define HARD_WRAP_LONG_WORDS
-
-QT_BEGIN_NAMESPACE
-
-static const int MAX_LEN = 79;
-
-static QString poEscapedString(const QString &prefix, const QString &keyword,
-                               bool noWrap, const QString &ba)
-{
-    QStringList lines;
-    int off = 0;
-    QString res;
-    while (off < ba.length()) {
-        ushort c = ba[off++].unicode();
-        switch (c) {
-        case '\n':
-            res += QLatin1String("\\n");
-            lines.append(res);
-            res.clear();
-            break;
-        case '\r':
-            res += QLatin1String("\\r");
-            break;
-        case '\t':
-            res += QLatin1String("\\t");
-            break;
-        case '\v':
-            res += QLatin1String("\\v");
-            break;
-        case '\a':
-            res += QLatin1String("\\a");
-            break;
-        case '\b':
-            res += QLatin1String("\\b");
-            break;
-        case '\f':
-            res += QLatin1String("\\f");
-            break;
-        case '"':
-            res += QLatin1String("\\\"");
-            break;
-        case '\\':
-            res += QLatin1String("\\\\");
-            break;
-        default:
-            if (c < 32) {
-                res += QLatin1String("\\x");
-                res += QString::number(c, 16);
-                if (off < ba.length() && isxdigit(ba[off].unicode()))
-                    res += QLatin1String("\"\"");
-            } else {
-                res += QChar(c);
-            }
-            break;
-        }
-    }
-    if (!res.isEmpty())
-        lines.append(res);
-    if (!lines.isEmpty()) {
-        if (!noWrap) {
-            if (lines.count() != 1 ||
-                lines.first().length() > MAX_LEN - keyword.length() - prefix.length() - 3)
-            {
-                QStringList olines = lines;
-                lines = QStringList(QString());
-                const int maxlen = MAX_LEN - prefix.length() - 2;
-                foreach (const QString &line, olines) {
-                    int off = 0;
-                    while (off + maxlen < line.length()) {
-                        int idx = line.lastIndexOf(QLatin1Char(' '), off + maxlen - 1) + 1;
-                        if (idx == off) {
-#ifdef HARD_WRAP_LONG_WORDS
-                            // This doesn't seem too nice, but who knows ...
-                            idx = off + maxlen;
-#else
-                            idx = line.indexOf(QLatin1Char(' '), off + maxlen) + 1;
-                            if (!idx)
-                                break;
-#endif
-                        }
-                        lines.append(line.mid(off, idx - off));
-                        off = idx;
-                    }
-                    lines.append(line.mid(off));
-                }
-            }
-        } else if (lines.count() > 1) {
-            lines.prepend(QString());
-        }
-    }
-    return prefix + keyword + QLatin1String(" \"") +
-           lines.join(QLatin1String("\"\n") + prefix + QLatin1Char('"')) +
-           QLatin1String("\"\n");
-}
-
-static QString poEscapedLines(const QString &prefix, bool addSpace, const QStringList &lines)
-{
-    QString out;
-    foreach (const QString &line, lines) {
-        out += prefix;
-        if (addSpace && !line.isEmpty())
-            out += QLatin1Char(' ' );
-        out += line;
-        out += QLatin1Char('\n');
-    }
-    return out;
-}
-
-static QString poEscapedLines(const QString &prefix, bool addSpace, const QString &in0)
-{
-    QString in = in0;
-    if (in.endsWith(QLatin1Char('\n')))
-        in.chop(1);
-    return poEscapedLines(prefix, addSpace, in.split(QLatin1Char('\n')));
-}
-
-static QString poWrappedEscapedLines(const QString &prefix, bool addSpace, const QString &line)
-{
-    const int maxlen = MAX_LEN - prefix.length();
-    QStringList lines;
-    int off = 0;
-    while (off + maxlen < line.length()) {
-        int idx = line.lastIndexOf(QLatin1Char(' '), off + maxlen - 1);
-        if (idx < off) {
-#if 0 //def HARD_WRAP_LONG_WORDS
-            // This cannot work without messing up semantics, so do not even try.
-#else
-            idx = line.indexOf(QLatin1Char(' '), off + maxlen);
-            if (idx < 0)
-                break;
-#endif
-        }
-        lines.append(line.mid(off, idx - off));
-        off = idx + 1;
-    }
-    lines.append(line.mid(off));
-    return poEscapedLines(prefix, addSpace, lines);
-}
-
-struct PoItem
-{
-public:
-    PoItem()
-      : isPlural(false), isFuzzy(false)
-    {}
-
-
-public:
-    QByteArray id;
-    QByteArray context;
-    QByteArray tscomment;
-    QByteArray oldTscomment;
-    QByteArray lineNumber;
-    QByteArray fileName;
-    QByteArray references;
-    QByteArray translatorComments;
-    QByteArray automaticComments;
-    QByteArray msgId;
-    QByteArray oldMsgId;
-    QList<QByteArray> msgStr;
-    bool isPlural;
-    bool isFuzzy;
-    QHash<QString, QString> extra;
-};
-
-
-static bool isTranslationLine(const QByteArray &line)
-{
-    return line.startsWith("#~ msgstr") || line.startsWith("msgstr");
-}
-
-static QByteArray slurpEscapedString(const QList<QByteArray> &lines, int &l,
-        int offset, const QByteArray &prefix, ConversionData &cd)
-{
-    QByteArray msg;
-    int stoff;
-
-    for (; l < lines.size(); ++l) {
-        const QByteArray &line = lines.at(l);
-        if (line.isEmpty() || !line.startsWith(prefix))
-            break;
-        while (isspace(line[offset])) // No length check, as string has no trailing spaces.
-            offset++;
-        if (line[offset] != '"')
-            break;
-        offset++;
-        forever {
-            if (offset == line.length())
-                goto premature_eol;
-            uchar c = line[offset++];
-            if (c == '"') {
-                if (offset == line.length())
-                    break;
-                while (isspace(line[offset]))
-                    offset++;
-                if (line[offset++] != '"') {
-                    cd.appendError(QString::fromLatin1(
-                            "PO parsing error: extra characters on line %1.")
-                            .arg(l + 1));
-                    break;
-                }
-                continue;
-            }
-            if (c == '\\') {
-                if (offset == line.length())
-                    goto premature_eol;
-                c = line[offset++];
-                switch (c) {
-                case 'r':
-                    msg += '\r'; // Maybe just throw it away?
-                    break;
-                case 'n':
-                    msg += '\n';
-                    break;
-                case 't':
-                    msg += '\t';
-                    break;
-                case 'v':
-                    msg += '\v';
-                    break;
-                case 'a':
-                    msg += '\a';
-                    break;
-                case 'b':
-                    msg += '\b';
-                    break;
-                case 'f':
-                    msg += '\f';
-                    break;
-                case '"':
-                    msg += '"';
-                    break;
-                case '\\':
-                    msg += '\\';
-                    break;
-                case '0':
-                case '1':
-                case '2':
-                case '3':
-                case '4':
-                case '5':
-                case '6':
-                case '7':
-                    stoff = offset - 1;
-                    while ((c = line[offset]) >= '0' && c <= '7')
-                        if (++offset == line.length())
-                            goto premature_eol;
-                    msg += line.mid(stoff, offset - stoff).toUInt(0, 8);
-                    break;
-                case 'x':
-                    stoff = offset;
-                    while (isxdigit(line[offset]))
-                        if (++offset == line.length())
-                            goto premature_eol;
-                    msg += line.mid(stoff, offset - stoff).toUInt(0, 16);
-                    break;
-                default:
-                    cd.appendError(QString::fromLatin1(
-                            "PO parsing error: invalid escape '\\%1' (line %2).")
-                            .arg(QChar((uint)c)).arg(l + 1));
-                    msg += '\\';
-                    msg += c;
-                    break;
-                }
-            } else {
-                msg += c;
-            }
-        }
-        offset = prefix.size();
-    }
-    --l;
-    return msg;
-
-premature_eol:
-    cd.appendError(QString::fromLatin1(
-            "PO parsing error: premature end of line %1.").arg(l + 1));
-    return QByteArray();
-}
-
-static void slurpComment(QByteArray &msg, const QList<QByteArray> &lines, int & l)
-{
-    QByteArray prefix = lines.at(l);
-    for (int i = 1; ; i++) {
-        if (prefix.at(i) != ' ') {
-            prefix.truncate(i);
-            break;
-        }
-    }
-    for (; l < lines.size(); ++l) {
-        const QByteArray &line = lines.at(l);
-        if (line.startsWith(prefix))
-            msg += line.mid(prefix.size());
-        else if (line != "#")
-            break;
-        msg += '\n';
-    }
-    --l;
-}
-
-static void splitContext(QByteArray *comment, QByteArray *context)
-{
-    char *data = comment->data();
-    int len = comment->size();
-    int sep = -1, j = 0;
-
-    for (int i = 0; i < len; i++, j++) {
-        if (data[i] == '~' && i + 1 < len)
-            i++;
-        else if (data[i] == '|')
-            sep = j;
-        data[j] = data[i];
-    }
-    if (sep >= 0) {
-        QByteArray tmp = comment->mid(sep + 1, j - sep - 1);
-        comment->truncate(sep);
-        *context = *comment;
-        *comment = tmp;
-    } else {
-        comment->truncate(j);
-    }
-}
-
-static QString makePoHeader(const QString &str)
-{
-    return QLatin1String("po-header-") + str.toLower().replace(QLatin1Char('-'), QLatin1Char('_'));
-}
-
-static QByteArray QByteArrayList_join(const QList<QByteArray> &that, char sep)
-{
-    int totalLength = 0;
-    const int size = that.size();
-
-    for (int i = 0; i < size; ++i)
-        totalLength += that.at(i).size();
-
-    if (size > 0)
-        totalLength += size - 1;
-
-    QByteArray res;
-    if (totalLength == 0)
-        return res;
-    res.reserve(totalLength);
-    for (int i = 0; i < that.size(); ++i) {
-        if (i)
-            res += sep;
-        res += that.at(i);
-    }
-    return res;
-}
-
-bool loadPO(Translator &translator, QIODevice &dev, ConversionData &cd)
-{
-    QTextCodec *codec = QTextCodec::codecForName(
-            cd.m_codecForSource.isEmpty() ? QByteArray("UTF-8") : cd.m_codecForSource);
-    bool error = false;
-
-    // format of a .po file entry:
-    // white-space
-    // #  translator-comments
-    // #. automatic-comments
-    // #: reference...
-    // #, flag...
-    // #~ msgctxt, msgid*, msgstr - used for obsoleted messages
-    // #| msgctxt, msgid* previous untranslated-string - for fuzzy message
-    // msgctx string-context
-    // msgid untranslated-string
-    // -- For singular:
-    // msgstr translated-string
-    // -- For plural:
-    // msgid_plural untranslated-string-plural
-    // msgstr[0] translated-string
-    // ...
-
-    // we need line based lookahead below.
-    QList<QByteArray> lines;
-    while (!dev.atEnd())
-        lines.append(dev.readLine().trimmed());
-    lines.append(QByteArray());
-
-    int l = 0, lastCmtLine = -1;
-    bool qtContexts = false;
-    PoItem item;
-    for (; l != lines.size(); ++l) {
-        QByteArray line = lines.at(l);
-        if (line.isEmpty())
-           continue;
-        if (isTranslationLine(line)) {
-            bool isObsolete = line.startsWith("#~ msgstr");
-            const QByteArray prefix = isObsolete ? "#~ " : "";
-            while (true) {
-                int idx = line.indexOf(' ', prefix.length());
-                QByteArray str = slurpEscapedString(lines, l, idx, prefix, cd);
-                item.msgStr.append(str);
-                if (l + 1 >= lines.size() || !isTranslationLine(lines.at(l + 1)))
-                    break;
-                ++l;
-                line = lines.at(l);
-            }
-            if (item.msgId.isEmpty()) {
-                QHash<QString, QByteArray> extras;
-                QList<QByteArray> hdrOrder;
-                QByteArray pluralForms;
-                foreach (const QByteArray &hdr, item.msgStr.first().split('\n')) {
-                    if (hdr.isEmpty())
-                        continue;
-                    int idx = hdr.indexOf(':');
-                    if (idx < 0) {
-                        cd.appendError(QString::fromLatin1("Unexpected PO header format '%1'")
-                            .arg(QString::fromLatin1(hdr)));
-                        error = true;
-                        break;
-                    }
-                    QByteArray hdrName = hdr.left(idx).trimmed();
-                    QByteArray hdrValue = hdr.mid(idx + 1).trimmed();
-                    hdrOrder << hdrName;
-                    if (hdrName == "X-Language") {
-                        translator.setLanguageCode(QString::fromLatin1(hdrValue));
-                    } else if (hdrName == "X-Source-Language") {
-                        translator.setSourceLanguageCode(QString::fromLatin1(hdrValue));
-                    } else if (hdrName == "X-Qt-Contexts") {
-                        qtContexts = (hdrValue == "true");
-                    } else if (hdrName == "Plural-Forms") {
-                        pluralForms  = hdrValue;
-                    } else if (hdrName == "MIME-Version") {
-                        // just assume it is 1.0
-                    } else if (hdrName == "Content-Type") {
-                        if (cd.m_codecForSource.isEmpty()) {
-                            if (!hdrValue.startsWith("text/plain; charset=")) {
-                                cd.appendError(QString::fromLatin1("Unexpected Content-Type header '%1'")
-                                    .arg(QString::fromLatin1(hdrValue)));
-                                error = true;
-                                // This will avoid a flood of conversion errors.
-                                codec = QTextCodec::codecForName("latin1");
-                            } else {
-                                QByteArray cod = hdrValue.mid(20);
-                                QTextCodec *cdc = QTextCodec::codecForName(cod);
-                                if (!cdc) {
-                                    cd.appendError(QString::fromLatin1("Unsupported codec '%1'")
-                                            .arg(QString::fromLatin1(cod)));
-                                    error = true;
-                                    // This will avoid a flood of conversion errors.
-                                    codec = QTextCodec::codecForName("latin1");
-                                } else {
-                                    codec = cdc;
-                                }
-                            }
-                        }
-                    } else if (hdrName == "Content-Transfer-Encoding") {
-                        if (hdrValue != "8bit") {
-                            cd.appendError(QString::fromLatin1("Unexpected Content-Transfer-Encoding '%1'")
-                                .arg(QString::fromLatin1(hdrValue)));
-                            return false;
-                        }
-                    } else if (hdrName == "X-Virgin-Header") {
-                        // legacy
-                    } else {
-                        extras[makePoHeader(QString::fromLatin1(hdrName))] = hdrValue;
-                    }
-                }
-                if (!pluralForms.isEmpty()) {
-                    if (translator.languageCode().isEmpty()) {
-                        extras[makePoHeader(QLatin1String("Plural-Forms"))] = pluralForms;
-                    } else {
-                         // FIXME: have fun with making a consistency check ...
-                    }
-                }
-                // Eliminate the field if only headers we added are present in standard order.
-                // Keep in sync with savePO
-                static const char * const dfltHdrs[] = {
-                    "MIME-Version", "Content-Type", "Content-Transfer-Encoding",
-                    "Plural-Forms", "X-Language", "X-Source-Language", "X-Qt-Contexts"
-                };
-                uint cdh = 0;
-                for (int cho = 0; cho < hdrOrder.length(); cho++) {
-                    for (;; cdh++) {
-                        if (cdh == sizeof(dfltHdrs)/sizeof(dfltHdrs[0])) {
-                            extras[QLatin1String("po-headers")] =
-                                    QByteArrayList_join(hdrOrder, ',');
-                            goto doneho;
-                        }
-                        if (hdrOrder.at(cho) == dfltHdrs[cdh]) {
-                            cdh++;
-                            break;
-                        }
-                    }
-                }
-              doneho:
-                if (lastCmtLine != -1)
-                    extras[QLatin1String("po-header_comment")] =
-                            QByteArrayList_join(lines.mid(0, lastCmtLine + 1), '\n');
-                for (QHash<QString, QByteArray>::ConstIterator it = extras.constBegin(),
-                                                               end = extras.constEnd();
-                     it != end; ++it)
-                    translator.setExtra(it.key(), codec->toUnicode(it.value()));
-                item = PoItem();
-                continue;
-            }
-            // build translator message
-            TranslatorMessage msg;
-            msg.setContext(codec->toUnicode(item.context));
-            if (!item.references.isEmpty()) {
-                QString xrefs;
-                foreach (const QString &ref,
-                         codec->toUnicode(item.references).split(
-                                 QRegExp(QLatin1String("\\s")), QString::SkipEmptyParts)) {
-                    int pos = ref.indexOf(QLatin1Char(':'));
-                    int lpos = ref.lastIndexOf(QLatin1Char(':'));
-                    if (pos != -1 && pos == lpos) {
-                        bool ok;
-                        int lno = ref.mid(pos + 1).toInt(&ok);
-                        if (ok) {
-                            msg.addReference(ref.left(pos), lno);
-                            continue;
-                        }
-                    }
-                    if (!xrefs.isEmpty())
-                        xrefs += QLatin1Char(' ');
-                    xrefs += ref;
-                }
-                if (!xrefs.isEmpty())
-                    item.extra[QLatin1String("po-references")] = xrefs;
-            }
-            msg.setId(codec->toUnicode(item.id));
-            msg.setSourceText(codec->toUnicode(item.msgId));
-            msg.setOldSourceText(codec->toUnicode(item.oldMsgId));
-            msg.setComment(codec->toUnicode(item.tscomment));
-            msg.setOldComment(codec->toUnicode(item.oldTscomment));
-            msg.setExtraComment(codec->toUnicode(item.automaticComments));
-            msg.setTranslatorComment(codec->toUnicode(item.translatorComments));
-            msg.setPlural(item.isPlural || item.msgStr.size() > 1);
-            QStringList translations;
-            foreach (const QByteArray &bstr, item.msgStr) {
-                QString str = codec->toUnicode(bstr);
-                str.replace(QChar(Translator::TextVariantSeparator),
-                            QChar(Translator::BinaryVariantSeparator));
-                translations << str;
-            }
-            msg.setTranslations(translations);
-            if (isObsolete)
-                msg.setType(TranslatorMessage::Obsolete);
-            else if (item.isFuzzy || (!msg.sourceText().isEmpty() && !msg.isTranslated()))
-                msg.setType(TranslatorMessage::Unfinished);
-            else
-                msg.setType(TranslatorMessage::Finished);
-            msg.setExtras(item.extra);
-
-            //qDebug() << "WRITE: " << context;
-            //qDebug() << "SOURCE: " << msg.sourceText();
-            //qDebug() << flags << msg.m_extra;
-            translator.append(msg);
-            item = PoItem();
-        } else if (line.startsWith('#')) {
-            switch (line.size() < 2 ? 0 : line.at(1)) {
-                case ':':
-                    item.references += line.mid(3);
-                    item.references += '\n';
-                    break;
-                case ',': {
-                    QStringList flags =
-                            QString::fromLatin1(line.mid(2)).split(
-                                    QRegExp(QLatin1String("[, ]")), QString::SkipEmptyParts);
-                    if (flags.removeOne(QLatin1String("fuzzy")))
-                        item.isFuzzy = true;
-                    flags.removeOne(QLatin1String("qt-format"));
-                    TranslatorMessage::ExtraData::const_iterator it =
-                            item.extra.constFind(QLatin1String("po-flags"));
-                    if (it != item.extra.constEnd())
-                        flags.prepend(*it);
-                    if (!flags.isEmpty())
-                        item.extra[QLatin1String("po-flags")] = flags.join(QLatin1String(", "));
-                    break;
-                }
-                case 0:
-                    item.translatorComments += '\n';
-                    break;
-                case ' ':
-                    slurpComment(item.translatorComments, lines, l);
-                    break;
-                case '.':
-                    if (line.startsWith("#. ts-context ")) { // legacy
-                        item.context = line.mid(14);
-                    } else if (line.startsWith("#. ts-id ")) {
-                        item.id = line.mid(9);
-                    } else {
-                        item.automaticComments += line.mid(3);
-                        item.automaticComments += '\n';
-                    }
-                    break;
-                case '|':
-                    if (line.startsWith("#| msgid ")) {
-                        item.oldMsgId = slurpEscapedString(lines, l, 9, "#| ", cd);
-                    } else if (line.startsWith("#| msgid_plural ")) {
-                        QByteArray extra = slurpEscapedString(lines, l, 16, "#| ", cd);
-                        if (extra != item.oldMsgId)
-                            item.extra[QLatin1String("po-old_msgid_plural")] =
-                                    codec->toUnicode(extra);
-                    } else if (line.startsWith("#| msgctxt ")) {
-                        item.oldTscomment = slurpEscapedString(lines, l, 11, "#| ", cd);
-                        if (qtContexts)
-                            splitContext(&item.oldTscomment, &item.context);
-                    } else {
-                        cd.appendError(QString(QLatin1String("PO-format parse error in line %1: '%2'"))
-                            .arg(l + 1).arg(codec->toUnicode(lines[l])));
-                        error = true;
-                    }
-                    break;
-                case '~':
-                    if (line.startsWith("#~ msgid ")) {
-                        item.msgId = slurpEscapedString(lines, l, 9, "#~ ", cd);
-                    } else if (line.startsWith("#~ msgid_plural ")) {
-                        QByteArray extra = slurpEscapedString(lines, l, 16, "#~ ", cd);
-                        if (extra != item.msgId)
-                            item.extra[QLatin1String("po-msgid_plural")] =
-                                    codec->toUnicode(extra);
-                        item.isPlural = true;
-                    } else if (line.startsWith("#~ msgctxt ")) {
-                        item.tscomment = slurpEscapedString(lines, l, 11, "#~ ", cd);
-                        if (qtContexts)
-                            splitContext(&item.tscomment, &item.context);
-                    } else {
-                        cd.appendError(QString(QLatin1String("PO-format parse error in line %1: '%2'"))
-                            .arg(l + 1).arg(codec->toUnicode(lines[l])));
-                        error = true;
-                    }
-                    break;
-                default:
-                    cd.appendError(QString(QLatin1String("PO-format parse error in line %1: '%2'"))
-                        .arg(l + 1).arg(codec->toUnicode(lines[l])));
-                    error = true;
-                    break;
-            }
-            lastCmtLine = l;
-        } else if (line.startsWith("msgctxt ")) {
-            item.tscomment = slurpEscapedString(lines, l, 8, QByteArray(), cd);
-            if (qtContexts)
-                splitContext(&item.tscomment, &item.context);
-        } else if (line.startsWith("msgid ")) {
-            item.msgId = slurpEscapedString(lines, l, 6, QByteArray(), cd);
-        } else if (line.startsWith("msgid_plural ")) {
-            QByteArray extra = slurpEscapedString(lines, l, 13, QByteArray(), cd);
-            if (extra != item.msgId)
-                item.extra[QLatin1String("po-msgid_plural")] = codec->toUnicode(extra);
-            item.isPlural = true;
-        } else {
-            cd.appendError(QString(QLatin1String("PO-format error in line %1: '%2'"))
-                .arg(l + 1).arg(codec->toUnicode(lines[l])));
-            error = true;
-        }
-    }
-    return !error && cd.errors().isEmpty();
-}
-
-static void addPoHeader(Translator::ExtraData &headers, QStringList &hdrOrder,
-                        const char *name, const QString &value)
-{
-    QString qName = QLatin1String(name);
-    if (!hdrOrder.contains(qName))
-        hdrOrder << qName;
-    headers[makePoHeader(qName)] = value;
-}
-
-static QString escapeComment(const QString &in, bool escape)
-{
-    QString out = in;
-    if (escape) {
-        out.replace(QLatin1Char('~'), QLatin1String("~~"));
-        out.replace(QLatin1Char('|'), QLatin1String("~|"));
-    }
-    return out;
-}
-
-bool savePO(const Translator &translator, QIODevice &dev, ConversionData &cd)
-{
-    QString str_format = QLatin1String("-format");
-
-    bool ok = true;
-    QTextStream out(&dev);
-    out.setCodec(cd.m_outputCodec.isEmpty() ? QByteArray("UTF-8") : cd.m_outputCodec);
-
-    bool qtContexts = false;
-    foreach (const TranslatorMessage &msg, translator.messages())
-        if (!msg.context().isEmpty()) {
-            qtContexts = true;
-            break;
-        }
-
-    QString cmt = translator.extra(QLatin1String("po-header_comment"));
-    if (!cmt.isEmpty())
-        out << cmt << '\n';
-    out << "msgid \"\"\n";
-    Translator::ExtraData headers = translator.extras();
-    QStringList hdrOrder = translator.extra(QLatin1String("po-headers")).split(
-            QLatin1Char(','), QString::SkipEmptyParts);
-    // Keep in sync with loadPO
-    addPoHeader(headers, hdrOrder, "MIME-Version", QLatin1String("1.0"));
-    addPoHeader(headers, hdrOrder, "Content-Type",
-                QLatin1String("text/plain; charset=" + out.codec()->name()));
-    addPoHeader(headers, hdrOrder, "Content-Transfer-Encoding", QLatin1String("8bit"));
-    if (!translator.languageCode().isEmpty()) {
-        QLocale::Language l;
-        QLocale::Country c;
-        Translator::languageAndCountry(translator.languageCode(), &l, &c);
-        const char *gettextRules;
-        if (getNumerusInfo(l, c, 0, 0, &gettextRules))
-            addPoHeader(headers, hdrOrder, "Plural-Forms", QLatin1String(gettextRules));
-        addPoHeader(headers, hdrOrder, "X-Language", translator.languageCode());
-    }
-    if (!translator.sourceLanguageCode().isEmpty())
-        addPoHeader(headers, hdrOrder, "X-Source-Language", translator.sourceLanguageCode());
-    if (qtContexts)
-        addPoHeader(headers, hdrOrder, "X-Qt-Contexts", QLatin1String("true"));
-    QString hdrStr;
-    foreach (const QString &hdr, hdrOrder) {
-        hdrStr += hdr;
-        hdrStr += QLatin1String(": ");
-        hdrStr += headers.value(makePoHeader(hdr));
-        hdrStr += QLatin1Char('\n');
-    }
-    out << poEscapedString(QString(), QString::fromLatin1("msgstr"), true, hdrStr);
-
-    foreach (const TranslatorMessage &msg, translator.messages()) {
-        out << endl;
-
-        if (!msg.translatorComment().isEmpty())
-            out << poEscapedLines(QLatin1String("#"), true, msg.translatorComment());
-
-        if (!msg.extraComment().isEmpty())
-            out << poEscapedLines(QLatin1String("#."), true, msg.extraComment());
-
-        if (!msg.id().isEmpty())
-            out << QLatin1String("#. ts-id ") << msg.id() << '\n';
-
-        QString xrefs = msg.extra(QLatin1String("po-references"));
-        if (!msg.fileName().isEmpty() || !xrefs.isEmpty()) {
-            QStringList refs;
-            foreach (const TranslatorMessage::Reference &ref, msg.allReferences())
-                refs.append(QString(QLatin1String("%2:%1"))
-                                    .arg(ref.lineNumber()).arg(ref.fileName()));
-            if (!xrefs.isEmpty())
-                refs << xrefs;
-            out << poWrappedEscapedLines(QLatin1String("#:"), true, refs.join(QLatin1String(" ")));
-        }
-
-        bool noWrap = false;
-        bool skipFormat = false;
-        QStringList flags;
-        if (msg.type() == TranslatorMessage::Unfinished && msg.isTranslated())
-            flags.append(QLatin1String("fuzzy"));
-        TranslatorMessage::ExtraData::const_iterator itr =
-                msg.extras().constFind(QLatin1String("po-flags"));
-        if (itr != msg.extras().constEnd()) {
-            QStringList atoms = itr->split(QLatin1String(", "));
-            foreach (const QString &atom, atoms)
-                if (atom.endsWith(str_format)) {
-                    skipFormat = true;
-                    break;
-                }
-            if (atoms.contains(QLatin1String("no-wrap")))
-                noWrap = true;
-            flags.append(*itr);
-        }
-        if (!skipFormat) {
-            QString source = msg.sourceText();
-            // This is fuzzy logic, as we don't know whether the string is
-            // actually used with QString::arg().
-            for (int off = 0; (off = source.indexOf(QLatin1Char('%'), off)) >= 0; ) {
-                if (++off >= source.length())
-                    break;
-                if (source.at(off) == QLatin1Char('n') || source.at(off).isDigit()) {
-                    flags.append(QLatin1String("qt-format"));
-                    break;
-                }
-            }
-        }
-        if (!flags.isEmpty())
-            out << "#, " << flags.join(QLatin1String(", ")) << '\n';
-
-        QString prefix = QLatin1String("#| ");
-        if (!msg.oldComment().isEmpty())
-            out << poEscapedString(prefix, QLatin1String("msgctxt"), noWrap,
-                                   escapeComment(msg.oldComment(), qtContexts));
-        if (!msg.oldSourceText().isEmpty())
-            out << poEscapedString(prefix, QLatin1String("msgid"), noWrap, msg.oldSourceText());
-        QString plural = msg.extra(QLatin1String("po-old_msgid_plural"));
-        if (!plural.isEmpty())
-            out << poEscapedString(prefix, QLatin1String("msgid_plural"), noWrap, plural);
-        prefix = QLatin1String((msg.type() == TranslatorMessage::Obsolete) ? "#~ " : "");
-        if (!msg.context().isEmpty())
-            out << poEscapedString(prefix, QLatin1String("msgctxt"), noWrap,
-                                   escapeComment(msg.context(), true) + QLatin1Char('|')
-                                   + escapeComment(msg.comment(), true));
-        else if (!msg.comment().isEmpty())
-            out << poEscapedString(prefix, QLatin1String("msgctxt"), noWrap,
-                                   escapeComment(msg.comment(), qtContexts));
-        out << poEscapedString(prefix, QLatin1String("msgid"), noWrap, msg.sourceText());
-        if (!msg.isPlural()) {
-            QString transl = msg.translation();
-            transl.replace(QChar(Translator::BinaryVariantSeparator),
-                           QChar(Translator::TextVariantSeparator));
-            out << poEscapedString(prefix, QLatin1String("msgstr"), noWrap, transl);
-        } else {
-            QString plural = msg.extra(QLatin1String("po-msgid_plural"));
-            if (plural.isEmpty())
-                plural = msg.sourceText();
-            out << poEscapedString(prefix, QLatin1String("msgid_plural"), noWrap, plural);
-            const QStringList &translations = msg.translations();
-            for (int i = 0; i != translations.size(); ++i) {
-                QString str = translations.at(i);
-                str.replace(QChar(Translator::BinaryVariantSeparator),
-                            QChar(Translator::TextVariantSeparator));
-                out << poEscapedString(prefix, QString::fromLatin1("msgstr[%1]").arg(i), noWrap,
-                                       str);
-            }
-        }
-    }
-    return ok;
-}
-
-static bool savePOT(const Translator &translator, QIODevice &dev, ConversionData &cd)
-{
-    Translator ttor = translator;
-    ttor.dropTranslations();
-    return savePO(ttor, dev, cd);
-}
-
-int initPO()
-{
-    Translator::FileFormat format;
-    format.extension = QLatin1String("po");
-    format.description = QObject::tr("GNU Gettext localization files");
-    format.loader = &loadPO;
-    format.saver = &savePO;
-    format.fileType = Translator::FileFormat::TranslationSource;
-    format.priority = 1;
-    Translator::registerFileFormat(format);
-    format.extension = QLatin1String("pot");
-    format.description = QObject::tr("GNU Gettext localization template files");
-    format.loader = &loadPO;
-    format.saver = &savePOT;
-    format.fileType = Translator::FileFormat::TranslationSource;
-    format.priority = -1;
-    Translator::registerFileFormat(format);
-    return 1;
-}
-
-Q_CONSTRUCTOR_FUNCTION(initPO)
-
-QT_END_NAMESPACE
diff --git a/src/shared/linguist/qm.cpp b/src/shared/linguist/qm.cpp
deleted file mode 100644 (file)
index 8a0fbf2..0000000
+++ /dev/null
@@ -1,789 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the Qt Linguist of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file.  Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "translator.h"
-
-#ifndef QT_BOOTSTRAPPED
-#include <QtCore/QCoreApplication>
-#endif
-#include <QtCore/QDebug>
-#include <QtCore/QDir>
-#include <QtCore/QFile>
-#include <QtCore/QFileInfo>
-#include <QtCore/QMap>
-#include <QtCore/QString>
-#include <QtCore/QTextCodec>
-
-QT_BEGIN_NAMESPACE
-
-// magic number for the file
-static const int MagicLength = 16;
-static const uchar magic[MagicLength] = {
-    0x3c, 0xb8, 0x64, 0x18, 0xca, 0xef, 0x9c, 0x95,
-    0xcd, 0x21, 0x1c, 0xbf, 0x60, 0xa1, 0xbd, 0xdd
-};
-
-
-namespace {
-
-enum Tag {
-    Tag_End          = 1,
-    Tag_SourceText16 = 2,
-    Tag_Translation  = 3,
-    Tag_Context16    = 4,
-    Tag_Obsolete1    = 5,
-    Tag_SourceText   = 6,
-    Tag_Context      = 7,
-    Tag_Comment      = 8,
-    Tag_Obsolete2    = 9
-};
-
-enum Prefix {
-    NoPrefix,
-    Hash,
-    HashContext,
-    HashContextSourceText,
-    HashContextSourceTextComment
-};
-
-} // namespace anon
-
-static uint elfHash(const QByteArray &ba)
-{
-    const uchar *k = (const uchar *)ba.data();
-    uint h = 0;
-    uint g;
-
-    if (k) {
-        while (*k) {
-            h = (h << 4) + *k++;
-            if ((g = (h & 0xf0000000)) != 0)
-                h ^= g >> 24;
-            h &= ~g;
-        }
-    }
-    if (!h)
-        h = 1;
-    return h;
-}
-
-class ByteTranslatorMessage
-{
-public:
-    ByteTranslatorMessage(
-            const QByteArray &context,
-            const QByteArray &sourceText,
-            const QByteArray &comment,
-            const QStringList &translations) :
-        m_context(context),
-        m_sourcetext(sourceText),
-        m_comment(comment),
-        m_translations(translations)
-    {}
-    const QByteArray &context() const { return m_context; }
-    const QByteArray &sourceText() const { return m_sourcetext; }
-    const QByteArray &comment() const { return m_comment; }
-    const QStringList &translations() const { return m_translations; }
-    bool operator<(const ByteTranslatorMessage& m) const;
-
-private:
-    QByteArray m_context;
-    QByteArray m_sourcetext;
-    QByteArray m_comment;
-    QStringList m_translations;
-};
-
-Q_DECLARE_TYPEINFO(ByteTranslatorMessage, Q_MOVABLE_TYPE);
-
-bool ByteTranslatorMessage::operator<(const ByteTranslatorMessage& m) const
-{
-    if (m_context != m.m_context)
-        return m_context < m.m_context;
-    if (m_sourcetext != m.m_sourcetext)
-        return m_sourcetext < m.m_sourcetext;
-    return m_comment < m.m_comment;
-}
-
-class Releaser
-{
-public:
-    struct Offset {
-        Offset()
-            : h(0), o(0)
-        {}
-        Offset(uint hash, uint offset)
-            : h(hash), o(offset)
-        {}
-
-        bool operator<(const Offset &other) const {
-            return (h != other.h) ? h < other.h : o < other.o;
-        }
-        bool operator==(const Offset &other) const {
-            return h == other.h && o == other.o;
-        }
-        uint h;
-        uint o;
-    };
-
-    enum { Contexts = 0x2f, Hashes = 0x42, Messages = 0x69, NumerusRules = 0x88 };
-
-    Releaser() : m_codec(0) {}
-
-    void setCodecName(const QByteArray &codecName)
-    {
-        m_codec = QTextCodec::codecForName(codecName);
-    }
-
-    bool save(QIODevice *iod);
-
-    void insert(const TranslatorMessage &msg, const QStringList &tlns, bool forceComment);
-    void insertIdBased(const TranslatorMessage &message, const QStringList &tlns);
-
-    void squeeze(TranslatorSaveMode mode);
-
-    void setNumerusRules(const QByteArray &rules);
-
-private:
-    Q_DISABLE_COPY(Releaser)
-
-    // This should reproduce the byte array fetched from the source file, which
-    // on turn should be the same as passed to the actual tr(...) calls
-    QByteArray originalBytes(const QString &str, bool isUtf8) const;
-
-    void insertInternal(const TranslatorMessage &message, const QStringList &tlns,
-                        bool forceComment, bool isUtf8);
-
-    static Prefix commonPrefix(const ByteTranslatorMessage &m1, const ByteTranslatorMessage &m2);
-
-    static uint msgHash(const ByteTranslatorMessage &msg);
-
-    void writeMessage(const ByteTranslatorMessage & msg, QDataStream & stream,
-        TranslatorSaveMode strip, Prefix prefix) const;
-
-    // for squeezed but non-file data, this is what needs to be deleted
-    QByteArray m_messageArray;
-    QByteArray m_offsetArray;
-    QByteArray m_contextArray;
-    QMap<ByteTranslatorMessage, void *> m_messages;
-    QByteArray m_numerusRules;
-
-    // Used to reproduce the original bytes
-    QTextCodec *m_codec;
-};
-
-QByteArray Releaser::originalBytes(const QString &str, bool isUtf8) const
-{
-    if (str.isEmpty()) {
-        // Do not use QByteArray() here as the result of the serialization
-        // will be different.
-        return QByteArray("");
-    }
-    if (isUtf8)
-        return str.toUtf8();
-    return m_codec ? m_codec->fromUnicode(str) : str.toLatin1();
-}
-
-uint Releaser::msgHash(const ByteTranslatorMessage &msg)
-{
-    return elfHash(msg.sourceText() + msg.comment());
-}
-
-Prefix Releaser::commonPrefix(const ByteTranslatorMessage &m1, const ByteTranslatorMessage &m2)
-{
-    if (msgHash(m1) != msgHash(m2))
-        return NoPrefix;
-    if (m1.context() != m2.context())
-        return Hash;
-    if (m1.sourceText() != m2.sourceText())
-        return HashContext;
-    if (m1.comment() != m2.comment())
-        return HashContextSourceText;
-    return HashContextSourceTextComment;
-}
-
-void Releaser::writeMessage(const ByteTranslatorMessage &msg, QDataStream &stream,
-    TranslatorSaveMode mode, Prefix prefix) const
-{
-    for (int i = 0; i < msg.translations().count(); ++i)
-        stream << quint8(Tag_Translation) << msg.translations().at(i);
-
-    if (mode == SaveEverything)
-        prefix = HashContextSourceTextComment;
-
-    // lrelease produces "wrong" QM files for QByteArrays that are .isNull().
-    switch (prefix) {
-    default:
-    case HashContextSourceTextComment:
-        stream << quint8(Tag_Comment) << msg.comment();
-        // fall through
-    case HashContextSourceText:
-        stream << quint8(Tag_SourceText) << msg.sourceText();
-        // fall through
-    case HashContext:
-        stream << quint8(Tag_Context) << msg.context();
-        break;
-    }
-
-    stream << quint8(Tag_End);
-}
-
-
-bool Releaser::save(QIODevice *iod)
-{
-    QDataStream s(iod);
-    s.writeRawData((const char *)magic, MagicLength);
-
-    if (!m_offsetArray.isEmpty()) {
-        quint32 oas = quint32(m_offsetArray.size());
-        s << quint8(Hashes) << oas;
-        s.writeRawData(m_offsetArray.constData(), oas);
-    }
-    if (!m_messageArray.isEmpty()) {
-        quint32 mas = quint32(m_messageArray.size());
-        s << quint8(Messages) << mas;
-        s.writeRawData(m_messageArray.constData(), mas);
-    }
-    if (!m_contextArray.isEmpty()) {
-        quint32 cas = quint32(m_contextArray.size());
-        s << quint8(Contexts) << cas;
-        s.writeRawData(m_contextArray.constData(), cas);
-    }
-    if (!m_numerusRules.isEmpty()) {
-        quint32 nrs = m_numerusRules.size();
-        s << quint8(NumerusRules) << nrs;
-        s.writeRawData(m_numerusRules.constData(), nrs);
-    }
-    return true;
-}
-
-void Releaser::squeeze(TranslatorSaveMode mode)
-{
-    if (m_messages.isEmpty() && mode == SaveEverything)
-        return;
-
-    QMap<ByteTranslatorMessage, void *> messages = m_messages;
-
-    // re-build contents
-    m_messageArray.clear();
-    m_offsetArray.clear();
-    m_contextArray.clear();
-    m_messages.clear();
-
-    QMap<Offset, void *> offsets;
-
-    QDataStream ms(&m_messageArray, QIODevice::WriteOnly);
-    QMap<ByteTranslatorMessage, void *>::const_iterator it, next;
-    int cpPrev = 0, cpNext = 0;
-    for (it = messages.constBegin(); it != messages.constEnd(); ++it) {
-        cpPrev = cpNext;
-        next = it;
-        ++next;
-        if (next == messages.constEnd())
-            cpNext = 0;
-        else
-            cpNext = commonPrefix(it.key(), next.key());
-        offsets.insert(Offset(msgHash(it.key()), ms.device()->pos()), (void *)0);
-        writeMessage(it.key(), ms, mode, Prefix(qMax(cpPrev, cpNext + 1)));
-    }
-
-    QMap<Offset, void *>::Iterator offset;
-    offset = offsets.begin();
-    QDataStream ds(&m_offsetArray, QIODevice::WriteOnly);
-    while (offset != offsets.end()) {
-        Offset k = offset.key();
-        ++offset;
-        ds << quint32(k.h) << quint32(k.o);
-    }
-
-    if (mode == SaveStripped) {
-        QMap<QByteArray, int> contextSet;
-        for (it = messages.constBegin(); it != messages.constEnd(); ++it)
-            ++contextSet[it.key().context()];
-
-        quint16 hTableSize;
-        if (contextSet.size() < 200)
-            hTableSize = (contextSet.size() < 60) ? 151 : 503;
-        else if (contextSet.size() < 2500)
-            hTableSize = (contextSet.size() < 750) ? 1511 : 5003;
-        else
-            hTableSize = (contextSet.size() < 10000) ? 15013 : 3 * contextSet.size() / 2;
-
-        QMultiMap<int, QByteArray> hashMap;
-        QMap<QByteArray, int>::const_iterator c;
-        for (c = contextSet.constBegin(); c != contextSet.constEnd(); ++c)
-            hashMap.insert(elfHash(c.key()) % hTableSize, c.key());
-
-        /*
-          The contexts found in this translator are stored in a hash
-          table to provide fast lookup. The context array has the
-          following format:
-
-              quint16 hTableSize;
-              quint16 hTable[hTableSize];
-              quint8  contextPool[...];
-
-          The context pool stores the contexts as Pascal strings:
-
-              quint8  len;
-              quint8  data[len];
-
-          Let's consider the look-up of context "FunnyDialog".  A
-          hash value between 0 and hTableSize - 1 is computed, say h.
-          If hTable[h] is 0, "FunnyDialog" is not covered by this
-          translator. Else, we check in the contextPool at offset
-          2 * hTable[h] to see if "FunnyDialog" is one of the
-          contexts stored there, until we find it or we meet the
-          empty string.
-        */
-        m_contextArray.resize(2 + (hTableSize << 1));
-        QDataStream t(&m_contextArray, QIODevice::WriteOnly);
-
-        quint16 *hTable = new quint16[hTableSize];
-        memset(hTable, 0, hTableSize * sizeof(quint16));
-
-        t << hTableSize;
-        t.device()->seek(2 + (hTableSize << 1));
-        t << quint16(0); // the entry at offset 0 cannot be used
-        uint upto = 2;
-
-        QMap<int, QByteArray>::const_iterator entry = hashMap.constBegin();
-        while (entry != hashMap.constEnd()) {
-            int i = entry.key();
-            hTable[i] = quint16(upto >> 1);
-
-            do {
-                const char *con = entry.value().constData();
-                uint len = uint(entry.value().length());
-                len = qMin(len, 255u);
-                t << quint8(len);
-                t.writeRawData(con, len);
-                upto += 1 + len;
-                ++entry;
-            } while (entry != hashMap.constEnd() && entry.key() == i);
-            if (upto & 0x1) {
-                // offsets have to be even
-                t << quint8(0); // empty string
-                ++upto;
-            }
-        }
-        t.device()->seek(2);
-        for (int j = 0; j < hTableSize; j++)
-            t << hTable[j];
-        delete [] hTable;
-
-        if (upto > 131072) {
-            qWarning("Releaser::squeeze: Too many contexts");
-            m_contextArray.clear();
-        }
-    }
-}
-
-void Releaser::insertInternal(const TranslatorMessage &message, const QStringList &tlns,
-                              bool forceComment, bool isUtf8)
-{
-    ByteTranslatorMessage bmsg(originalBytes(message.context(), isUtf8),
-                               originalBytes(message.sourceText(), isUtf8),
-                               originalBytes(message.comment(), isUtf8),
-                               tlns);
-    if (!forceComment) {
-        ByteTranslatorMessage bmsg2(
-                bmsg.context(), bmsg.sourceText(), QByteArray(""), bmsg.translations());
-        if (!m_messages.contains(bmsg2)) {
-            m_messages.insert(bmsg2, 0);
-            return;
-        }
-    }
-    m_messages.insert(bmsg, 0);
-}
-
-void Releaser::insert(const TranslatorMessage &message, const QStringList &tlns, bool forceComment)
-{
-    insertInternal(message, tlns, forceComment, message.isUtf8());
-    if (message.isUtf8() && message.isNonUtf8())
-        insertInternal(message, tlns, forceComment, false);
-}
-
-void Releaser::insertIdBased(const TranslatorMessage &message, const QStringList &tlns)
-{
-    ByteTranslatorMessage bmsg("", originalBytes(message.id(), false), "", tlns);
-    m_messages.insert(bmsg, 0);
-}
-
-void Releaser::setNumerusRules(const QByteArray &rules)
-{
-    m_numerusRules = rules;
-}
-
-static quint8 read8(const uchar *data)
-{
-    return *data;
-}
-
-static quint32 read32(const uchar *data)
-{
-    return (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | (data[3]);
-}
-
-static void fromBytes(const char *str, int len, QTextCodec *codec, QTextCodec *utf8Codec,
-                      QString *out, QString *utf8Out,
-                      bool *isSystem, bool *isUtf8, bool *needs8Bit)
-{
-    for (int i = 0; i < len; ++i)
-        if (str[i] & 0x80) {
-            if (utf8Codec) {
-                QTextCodec::ConverterState cvtState;
-                *utf8Out = utf8Codec->toUnicode(str, len, &cvtState);
-                *isUtf8 = !cvtState.invalidChars;
-            }
-            QTextCodec::ConverterState cvtState;
-            *out = codec->toUnicode(str, len, &cvtState);
-            *isSystem = !cvtState.invalidChars;
-            *needs8Bit = true;
-            return;
-        }
-    *out = QString::fromLatin1(str, len);
-    *isSystem = true;
-    if (utf8Codec) {
-        *utf8Out = *out;
-        *isUtf8 = true;
-    }
-    *needs8Bit = false;
-}
-
-bool loadQM(Translator &translator, QIODevice &dev, ConversionData &cd)
-{
-    QByteArray ba = dev.readAll();
-    const uchar *data = (uchar*)ba.data();
-    int len = ba.size();
-    if (len < MagicLength || memcmp(data, magic, MagicLength) != 0) {
-        cd.appendError(QLatin1String("QM-Format error: magic marker missing"));
-        return false;
-    }
-
-    enum { Contexts = 0x2f, Hashes = 0x42, Messages = 0x69, NumerusRules = 0x88 };
-
-    // for squeezed but non-file data, this is what needs to be deleted
-    const uchar *messageArray = 0;
-    const uchar *offsetArray = 0;
-    uint offsetLength = 0;
-
-    bool ok = true;
-    const uchar *end = data + len;
-
-    data += MagicLength;
-
-    while (data < end - 4) {
-        quint8 tag = read8(data++);
-        quint32 blockLen = read32(data);
-        //qDebug() << "TAG:" << tag <<  "BLOCKLEN:" << blockLen;
-        data += 4;
-        if (!tag || !blockLen)
-            break;
-        if (data + blockLen > end) {
-            ok = false;
-            break;
-        }
-
-        if (tag == Hashes) {
-            offsetArray = data;
-            offsetLength = blockLen;
-            //qDebug() << "HASHES: " << blockLen << QByteArray((const char *)data, blockLen).toHex();
-        } else if (tag == Messages) {
-            messageArray = data;
-            //qDebug() << "MESSAGES: " << blockLen << QByteArray((const char *)data, blockLen).toHex();
-        }
-
-        data += blockLen;
-    }
-
-
-    size_t numItems = offsetLength / (2 * sizeof(quint32));
-    //qDebug() << "NUMITEMS: " << numItems;
-
-    QTextCodec *codec = QTextCodec::codecForName(
-        cd.m_codecForSource.isEmpty() ? QByteArray("Latin1") : cd.m_codecForSource);
-    QTextCodec *utf8Codec = 0;
-    if (codec->name() != "UTF-8")
-        utf8Codec = QTextCodec::codecForName("UTF-8");
-
-    QString strProN = QLatin1String("%n");
-    QLocale::Language l;
-    QLocale::Country c;
-    Translator::languageAndCountry(translator.languageCode(), &l, &c);
-    QStringList numerusForms;
-    bool guessPlurals = true;
-    if (getNumerusInfo(l, c, 0, &numerusForms, 0))
-        guessPlurals = (numerusForms.count() == 1);
-
-    QString context, contextUtf8;
-    bool contextIsSystem, contextIsUtf8, contextNeeds8Bit;
-    QString sourcetext, sourcetextUtf8;
-    bool sourcetextIsSystem, sourcetextIsUtf8, sourcetextNeeds8Bit;
-    QString comment, commentUtf8;
-    bool commentIsSystem, commentIsUtf8, commentNeeds8Bit;
-    QStringList translations;
-
-    for (const uchar *start = offsetArray; start != offsetArray + (numItems << 3); start += 8) {
-        //quint32 hash = read32(start);
-        quint32 ro = read32(start + 4);
-        //qDebug() << "\nHASH:" << hash;
-        const uchar *m = messageArray + ro;
-
-        for (;;) {
-            uchar tag = read8(m++);
-            //qDebug() << "Tag:" << tag << " ADDR: " << m;
-            switch(tag) {
-            case Tag_End:
-                goto end;
-            case Tag_Translation: {
-                int len = read32(m);
-                if (len % 1) {
-                    cd.appendError(QLatin1String("QM-Format error"));
-                    return false;
-                }
-                m += 4;
-                QString str = QString((const QChar *)m, len/2);
-                if (QSysInfo::ByteOrder == QSysInfo::LittleEndian) {
-                    for (int i = 0; i < str.length(); ++i)
-                        str[i] = QChar((str.at(i).unicode() >> 8) +
-                            ((str.at(i).unicode() << 8) & 0xff00));
-                }
-                translations << str;
-                m += len;
-                break;
-            }
-            case Tag_Obsolete1:
-                m += 4;
-                //qDebug() << "OBSOLETE";
-                break;
-            case Tag_SourceText: {
-                quint32 len = read32(m);
-                m += 4;
-                //qDebug() << "SOURCE LEN: " << len;
-                //qDebug() << "SOURCE: " << QByteArray((const char*)m, len);
-                fromBytes((const char*)m, len, codec, utf8Codec,
-                          &sourcetext, &sourcetextUtf8,
-                          &sourcetextIsSystem, &sourcetextIsUtf8, &sourcetextNeeds8Bit);
-                m += len;
-                break;
-            }
-            case Tag_Context: {
-                quint32 len = read32(m);
-                m += 4;
-                //qDebug() << "CONTEXT LEN: " << len;
-                //qDebug() << "CONTEXT: " << QByteArray((const char*)m, len);
-                fromBytes((const char*)m, len, codec, utf8Codec,
-                          &context, &contextUtf8,
-                          &contextIsSystem, &contextIsUtf8, &contextNeeds8Bit);
-                m += len;
-                break;
-            }
-            case Tag_Comment: {
-                quint32 len = read32(m);
-                m += 4;
-                //qDebug() << "COMMENT LEN: " << len;
-                //qDebug() << "COMMENT: " << QByteArray((const char*)m, len);
-                fromBytes((const char*)m, len, codec, utf8Codec,
-                          &comment, &commentUtf8,
-                          &commentIsSystem, &commentIsUtf8, &commentNeeds8Bit);
-                m += len;
-                break;
-            }
-            default:
-                //qDebug() << "UNKNOWN TAG" << tag;
-                break;
-            }
-        }
-    end:;
-        TranslatorMessage msg;
-        msg.setType(TranslatorMessage::Finished);
-        if (translations.count() > 1) {
-            // If guessPlurals is not false here, plural form discard messages
-            // will be spewn out later.
-            msg.setPlural(true);
-        } else if (guessPlurals) {
-            // This might cause false positives, so it is a fallback only.
-            if (sourcetext.contains(strProN))
-                msg.setPlural(true);
-        }
-        msg.setTranslations(translations);
-        translations.clear();
-        if (contextNeeds8Bit || sourcetextNeeds8Bit || commentNeeds8Bit) {
-            if (utf8Codec && contextIsUtf8 && sourcetextIsUtf8 && commentIsUtf8) {
-                // The message is utf-8, but file is not.
-                msg.setUtf8(true);
-                msg.setContext(contextUtf8);
-                msg.setSourceText(sourcetextUtf8);
-                msg.setComment(commentUtf8);
-                translator.append(msg);
-                continue;
-            }
-            if (!(contextIsSystem && sourcetextIsSystem && commentIsSystem)) {
-                cd.appendError(QLatin1String(
-                        "Cannot read file with specified input codec"));
-                return false;
-            }
-            // The message is 8-bit in the file's encoding (utf-8 or not).
-        }
-        msg.setContext(context);
-        msg.setSourceText(sourcetext);
-        msg.setComment(comment);
-        translator.append(msg);
-    }
-    return ok;
-}
-
-
-
-static bool containsStripped(const Translator &translator, const TranslatorMessage &msg)
-{
-    foreach (const TranslatorMessage &tmsg, translator.messages())
-        if (tmsg.sourceText() == msg.sourceText()
-            && tmsg.context() == msg.context()
-            && tmsg.comment().isEmpty())
-        return true;
-    return false;
-}
-
-bool saveQM(const Translator &translator, QIODevice &dev, ConversionData &cd)
-{
-    Releaser releaser;
-    QLocale::Language l;
-    QLocale::Country c;
-    Translator::languageAndCountry(translator.languageCode(), &l, &c);
-    QByteArray rules;
-    if (getNumerusInfo(l, c, &rules, 0, 0))
-        releaser.setNumerusRules(rules);
-    releaser.setCodecName(translator.codecName());
-
-    int finished = 0;
-    int unfinished = 0;
-    int untranslated = 0;
-    int missingIds = 0;
-    int droppedData = 0;
-
-    for (int i = 0; i != translator.messageCount(); ++i) {
-        const TranslatorMessage &msg = translator.message(i);
-        TranslatorMessage::Type typ = msg.type();
-        if (typ != TranslatorMessage::Obsolete) {
-            if (cd.m_idBased && msg.id().isEmpty()) {
-                ++missingIds;
-                continue;
-            }
-            if (typ == TranslatorMessage::Unfinished) {
-                if (msg.translation().isEmpty() && !cd.m_idBased && cd.m_unTrPrefix.isEmpty()) {
-                    ++untranslated;
-                    continue;
-                } else {
-                    if (cd.ignoreUnfinished())
-                        continue;
-                    ++unfinished;
-                }
-            } else {
-                ++finished;
-            }
-            QStringList tlns = msg.translations();
-            if (msg.type() == TranslatorMessage::Unfinished
-                && (cd.m_idBased || !cd.m_unTrPrefix.isEmpty()))
-                for (int j = 0; j < tlns.size(); ++j)
-                    if (tlns.at(j).isEmpty())
-                        tlns[j] = cd.m_unTrPrefix + msg.sourceText();
-            if (cd.m_idBased) {
-                if (!msg.context().isEmpty() || !msg.comment().isEmpty())
-                    ++droppedData;
-                releaser.insertIdBased(msg, tlns);
-            } else {
-                // Drop the comment in (context, sourceText, comment),
-                // unless the context is empty,
-                // unless (context, sourceText, "") already exists or
-                // unless we already dropped the comment of (context,
-                // sourceText, comment0).
-                bool forceComment =
-                        msg.comment().isEmpty()
-                        || msg.context().isEmpty()
-                        || containsStripped(translator, msg);
-                releaser.insert(msg, tlns, forceComment);
-            }
-        }
-    }
-
-    if (missingIds)
-        cd.appendError(QCoreApplication::translate("LRelease",
-            "Dropped %n message(s) which had no ID.", 0,
-            QCoreApplication::CodecForTr, missingIds));
-    if (droppedData)
-        cd.appendError(QCoreApplication::translate("LRelease",
-            "Excess context/disambiguation dropped from %n message(s).", 0,
-            QCoreApplication::CodecForTr, droppedData));
-
-    releaser.squeeze(cd.m_saveMode);
-    bool saved = releaser.save(&dev);
-    if (saved && cd.isVerbose()) {
-        int generatedCount = finished + unfinished;
-        cd.appendError(QCoreApplication::translate("LRelease",
-            "    Generated %n translation(s) (%1 finished and %2 unfinished)", 0,
-            QCoreApplication::CodecForTr, generatedCount).arg(finished).arg(unfinished));
-        if (untranslated)
-            cd.appendError(QCoreApplication::translate("LRelease",
-                "    Ignored %n untranslated source text(s)", 0,
-                QCoreApplication::CodecForTr, untranslated));
-    }
-    return saved;
-}
-
-int initQM()
-{
-    Translator::FileFormat format;
-
-    format.extension = QLatin1String("qm");
-    format.description = QObject::tr("Compiled Qt translations");
-    format.fileType = Translator::FileFormat::TranslationBinary;
-    format.priority = 0;
-    format.loader = &loadQM;
-    format.saver = &saveQM;
-    Translator::registerFileFormat(format);
-
-    return 1;
-}
-
-Q_CONSTRUCTOR_FUNCTION(initQM)
-
-QT_END_NAMESPACE
diff --git a/src/shared/linguist/qph.cpp b/src/shared/linguist/qph.cpp
deleted file mode 100644 (file)
index eeb9305..0000000
+++ /dev/null
@@ -1,207 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the Qt Linguist of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file.  Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "translator.h"
-
-#include <QtCore/QByteArray>
-#include <QtCore/QDebug>
-#include <QtCore/QTextCodec>
-#include <QtCore/QTextStream>
-
-#include <QtXml/QXmlStreamReader>
-#include <QtXml/qxmlstream.h>
-
-QT_BEGIN_NAMESPACE
-
-class QPHReader : public QXmlStreamReader
-{
-public:
-    QPHReader(QIODevice &dev)
-      : QXmlStreamReader(&dev)
-    {}
-
-    // the "real thing"
-    bool read(Translator &translator);
-
-private:
-    bool isWhiteSpace() const
-    {
-        return isCharacters() && text().toString().trimmed().isEmpty();
-    }
-
-    enum DataField { NoField, SourceField, TargetField, DefinitionField };
-    DataField m_currentField;
-    QString m_currentSource;
-    QString m_currentTarget;
-    QString m_currentDefinition;
-};
-
-bool QPHReader::read(Translator &translator)
-{
-    m_currentField = NoField;
-    QString result;
-    while (!atEnd()) {
-        readNext();
-        if (isStartElement()) {
-            if (name() == QLatin1String("source")) {
-                m_currentField = SourceField;
-            } else if (name() == QLatin1String("target")) {
-                m_currentField = TargetField;
-            } else if (name() == QLatin1String("definition")) {
-                m_currentField = DefinitionField;
-            } else {
-                m_currentField = NoField;
-                if (name() == QLatin1String("QPH")) {
-                    QXmlStreamAttributes atts = attributes();
-                    translator.setLanguageCode(atts.value(QLatin1String("language")).toString());
-                    translator.setSourceLanguageCode(atts.value(QLatin1String("sourcelanguage")).toString());
-                }
-            }
-        } else if (isWhiteSpace()) {
-            // ignore these
-        } else if (isCharacters()) {
-            if (m_currentField == SourceField)
-                m_currentSource += text();
-            else if (m_currentField == TargetField)
-                m_currentTarget += text();
-            else if (m_currentField == DefinitionField)
-                m_currentDefinition += text();
-        } else if (isEndElement() && name() == QLatin1String("phrase")) {
-            m_currentTarget.replace(QChar(Translator::TextVariantSeparator),
-                                    QChar(Translator::BinaryVariantSeparator));
-            TranslatorMessage msg;
-            msg.setSourceText(m_currentSource);
-            msg.setTranslation(m_currentTarget);
-            msg.setComment(m_currentDefinition);
-            translator.append(msg);
-            m_currentSource.clear();
-            m_currentTarget.clear();
-            m_currentDefinition.clear();
-        }
-    }
-    return true;
-}
-
-static bool loadQPH(Translator &translator, QIODevice &dev, ConversionData &)
-{
-    translator.setLocationsType(Translator::NoLocations);
-    QPHReader reader(dev);
-    return reader.read(translator);
-}
-
-static QString protect(const QString &str)
-{
-    QString result;
-    result.reserve(str.length() * 12 / 10);
-    for (int i = 0; i != str.size(); ++i) {
-        uint c = str.at(i).unicode();
-        switch (c) {
-        case '\"':
-            result += QLatin1String("&quot;");
-            break;
-        case '&':
-            result += QLatin1String("&amp;");
-            break;
-        case '>':
-            result += QLatin1String("&gt;");
-            break;
-        case '<':
-            result += QLatin1String("&lt;");
-            break;
-        case '\'':
-            result += QLatin1String("&apos;");
-            break;
-        default:
-            if (c < 0x20 && c != '\r' && c != '\n' && c != '\t')
-                result += QString(QLatin1String("&#%1;")).arg(c);
-            else // this also covers surrogates
-                result += QChar(c);
-        }
-    }
-    return result;
-}
-
-static bool saveQPH(const Translator &translator, QIODevice &dev, ConversionData &)
-{
-    QTextStream t(&dev);
-    t.setCodec(QTextCodec::codecForName("UTF-8"));
-    t << "<!DOCTYPE QPH>\n<QPH";
-    QString languageCode = translator.languageCode();
-    if (!languageCode.isEmpty() && languageCode != QLatin1String("C"))
-        t << " language=\"" << languageCode << "\"";
-    languageCode = translator.sourceLanguageCode();
-    if (!languageCode.isEmpty() && languageCode != QLatin1String("C"))
-        t << " sourcelanguage=\"" << languageCode << "\"";
-    t << ">\n";
-    foreach (const TranslatorMessage &msg, translator.messages()) {
-        t << "<phrase>\n";
-        t << "    <source>" << protect(msg.sourceText()) << "</source>\n";
-        QString str = msg.translations().join(QLatin1String("@"));
-        str.replace(QChar(Translator::BinaryVariantSeparator),
-                    QChar(Translator::TextVariantSeparator));
-        t << "    <target>" << protect(str)
-            << "</target>\n";
-        if (!msg.comment().isEmpty())
-            t << "    <definition>" << protect(msg.comment()) << "</definition>\n";
-        t << "</phrase>\n";
-    }
-    t << "</QPH>\n";
-    return true;
-}
-
-int initQPH()
-{
-    Translator::FileFormat format;
-
-    format.extension = QLatin1String("qph");
-    format.description = QObject::tr("Qt Linguist 'Phrase Book'");
-    format.fileType = Translator::FileFormat::TranslationSource;
-    format.priority = 0;
-    format.loader = &loadQPH;
-    format.saver = &saveQPH;
-    Translator::registerFileFormat(format);
-
-    return 1;
-}
-
-Q_CONSTRUCTOR_FUNCTION(initQPH)
-
-QT_END_NAMESPACE
diff --git a/src/shared/linguist/ts.cpp b/src/shared/linguist/ts.cpp
deleted file mode 100644 (file)
index 02e4c58..0000000
+++ /dev/null
@@ -1,781 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the Qt Linguist of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file.  Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "translator.h"
-
-#include <QtCore/QByteArray>
-#include <QtCore/QDebug>
-#include <QtCore/QTextCodec>
-#include <QtCore/QTextStream>
-
-#include <QtXml/QXmlStreamReader>
-#include <QtXml/qxmlstream.h>
-
-#define STRINGIFY_INTERNAL(x) #x
-#define STRINGIFY(x) STRINGIFY_INTERNAL(x)
-#define STRING(s) static QString str##s(QLatin1String(STRINGIFY(s)))
-
-QT_BEGIN_NAMESPACE
-
-/*
- * The encodings are a total mess.
- * A Translator has a codecForTr(). Each message's text will be passed to tr()
- * in that encoding or as UTF-8 to trUtf8() if it is flagged as such.
- * For ts 2.0, the file content is always uniformly in UTF-8. The file stores
- * the codecForTr default and marks deviating messages accordingly.
- * For ts 1.1, the file content is in mixed encoding. Each message is encoded
- * the way it will be passed to tr() (with 8-bit characters encoded as numeric
- * entities) or trUtf8(). The file stores the encoding and codecForTr in one
- * attribute, for both the default and each deviating message.
- */
-
-
-QDebug &operator<<(QDebug &d, const QXmlStreamAttribute &attr)
-{
-    return d << "[" << attr.name().toString() << "," << attr.value().toString() << "]";
-}
-
-
-class TSReader : public QXmlStreamReader
-{
-public:
-    TSReader(QIODevice &dev, ConversionData &cd)
-      : QXmlStreamReader(&dev), m_cd(cd)
-    {}
-
-    // the "real thing"
-    bool read(Translator &translator);
-
-private:
-    bool elementStarts(const QString &str) const
-    {
-        return isStartElement() && name() == str;
-    }
-
-    bool isWhiteSpace() const
-    {
-        return isCharacters() && text().toString().trimmed().isEmpty();
-    }
-
-    // needed to expand <byte ... />
-    QString readContents();
-    // needed to join <lengthvariant>s
-    QString readTransContents();
-
-    void handleError();
-
-    ConversionData &m_cd;
-};
-
-void TSReader::handleError()
-{
-    if (isComment())
-        return;
-    if (hasError() && error() == CustomError) // raised by readContents
-        return;
-
-    const QString loc = QString::fromLatin1("at %3:%1:%2")
-        .arg(lineNumber()).arg(columnNumber()).arg(m_cd.m_sourceFileName);
-
-    switch (tokenType()) {
-    case NoToken: // Cannot happen
-    default: // likewise
-    case Invalid:
-        raiseError(QString::fromLatin1("Parse error %1: %2").arg(loc, errorString()));
-        break;
-    case StartElement:
-        raiseError(QString::fromLatin1("Unexpected tag <%1> %2").arg(name().toString(), loc));
-        break;
-    case Characters:
-        {
-            QString tok = text().toString();
-            if (tok.length() > 30)
-                tok = tok.left(30) + QLatin1String("[...]");
-            raiseError(QString::fromLatin1("Unexpected characters '%1' %2").arg(tok, loc));
-        }
-        break;
-    case EntityReference:
-        raiseError(QString::fromLatin1("Unexpected entity '&%1;' %2").arg(name().toString(), loc));
-        break;
-    case ProcessingInstruction:
-        raiseError(QString::fromLatin1("Unexpected processing instruction %1").arg(loc));
-        break;
-    }
-}
-
-static QString byteValue(QString value)
-{
-    int base = 10;
-    if (value.startsWith(QLatin1String("x"))) {
-        base = 16;
-        value.remove(0, 1);
-    }
-    int n = value.toUInt(0, base);
-    return (n != 0) ? QString(QChar(n)) : QString();
-}
-
-QString TSReader::readContents()
-{
-    STRING(byte);
-    STRING(value);
-
-    QString result;
-    while (!atEnd()) {
-        readNext();
-        if (isEndElement()) {
-            break;
-        } else if (isCharacters()) {
-            result += text();
-        } else if (elementStarts(strbyte)) {
-            // <byte value="...">
-            result += byteValue(attributes().value(strvalue).toString());
-            readNext();
-            if (!isEndElement()) {
-                handleError();
-                break;
-            }
-        } else {
-            handleError();
-            break;
-        }
-    }
-    //qDebug() << "TEXT: " << result;
-    return result;
-}
-
-QString TSReader::readTransContents()
-{
-    STRING(lengthvariant);
-    STRING(variants);
-    STRING(yes);
-
-    if (attributes().value(strvariants) == stryes) {
-        QString result;
-        while (!atEnd()) {
-            readNext();
-            if (isEndElement()) {
-                break;
-            } else if (isWhiteSpace()) {
-                // ignore these, just whitespace
-            } else if (elementStarts(strlengthvariant)) {
-                if (!result.isEmpty())
-                    result += QChar(Translator::BinaryVariantSeparator);
-                result += readContents();
-            } else {
-                handleError();
-                break;
-            }
-        }
-        return result;
-    } else {
-        return readContents();
-    }
-}
-
-bool TSReader::read(Translator &translator)
-{
-    STRING(both);
-    STRING(byte);
-    STRING(comment);
-    STRING(context);
-    STRING(defaultcodec);
-    STRING(encoding);
-    STRING(extracomment);
-    STRING(filename);
-    STRING(id);
-    STRING(language);
-    STRING(line);
-    STRING(location);
-    STRING(message);
-    STRING(name);
-    STRING(numerus);
-    STRING(numerusform);
-    STRING(obsolete);
-    STRING(oldcomment);
-    STRING(oldsource);
-    STRING(source);
-    STRING(sourcelanguage);
-    STRING(translation);
-    STRING(translatorcomment);
-    STRING(true);
-    STRING(TS);
-    STRING(type);
-    STRING(unfinished);
-    STRING(userdata);
-    STRING(utf8);
-    STRING(value);
-    //STRING(version);
-    STRING(yes);
-
-    static const QString strextrans(QLatin1String("extra-"));
-    static const QString strUtf8(QLatin1String("UTF-8"));
-
-    while (!atEnd()) {
-        readNext();
-        if (isStartDocument()) {
-            // <!DOCTYPE TS>
-            //qDebug() << attributes();
-        } else if (isEndDocument()) {
-            // <!DOCTYPE TS>
-            //qDebug() << attributes();
-        } else if (isDTD()) {
-            // <!DOCTYPE TS>
-            //qDebug() << tokenString();
-        } else if (elementStarts(strTS)) {
-            // <TS>
-            //qDebug() << "TS " << attributes();
-            QHash<QString, int> currentLine;
-            QString currentFile;
-            bool maybeRelative = false, maybeAbsolute = false;
-
-            QXmlStreamAttributes atts = attributes();
-            //QString version = atts.value(strversion).toString();
-            translator.setLanguageCode(atts.value(strlanguage).toString());
-            translator.setSourceLanguageCode(atts.value(strsourcelanguage).toString());
-            while (!atEnd()) {
-                readNext();
-                if (isEndElement()) {
-                    // </TS> found, finish local loop
-                    break;
-                } else if (isWhiteSpace()) {
-                    // ignore these, just whitespace
-                } else if (elementStarts(strdefaultcodec)) {
-                    // <defaultcodec>
-                    const QString &codec = readElementText();
-                    if (!codec.isEmpty())
-                        translator.setCodecName(codec.toLatin1());
-                    // </defaultcodec>
-                } else if (isStartElement()
-                        && name().toString().startsWith(strextrans)) {
-                    // <extra-...>
-                    QString tag = name().toString();
-                    translator.setExtra(tag.mid(6), readContents());
-                    // </extra-...>
-                } else if (elementStarts(strcontext)) {
-                    // <context>
-                    QString context;
-                    while (!atEnd()) {
-                        readNext();
-                        if (isEndElement()) {
-                            // </context> found, finish local loop
-                            break;
-                        } else if (isWhiteSpace()) {
-                            // ignore these, just whitespace
-                        } else if (elementStarts(strname)) {
-                            // <name>
-                            context = readElementText();
-                            // </name>
-                        } else if (elementStarts(strmessage)) {
-                            // <message>
-                            TranslatorMessage::References refs;
-                            QString currentMsgFile = currentFile;
-
-                            TranslatorMessage msg;
-                            msg.setId(attributes().value(strid).toString());
-                            msg.setContext(context);
-                            msg.setType(TranslatorMessage::Finished);
-                            msg.setPlural(attributes().value(strnumerus) == stryes);
-                            const QStringRef &utf8Attr = attributes().value(strutf8);
-                            msg.setNonUtf8(utf8Attr == strboth);
-                            msg.setUtf8(msg.isNonUtf8() || utf8Attr == strtrue
-                                 ||  attributes().value(strencoding) == strUtf8);
-                            while (!atEnd()) {
-                                readNext();
-                                if (isEndElement()) {
-                                    // </message> found, finish local loop
-                                    msg.setReferences(refs);
-                                    translator.append(msg);
-                                    break;
-                                } else if (isWhiteSpace()) {
-                                    // ignore these, just whitespace
-                                } else if (elementStarts(strsource)) {
-                                    // <source>...</source>
-                                    msg.setSourceText(readContents());
-                                } else if (elementStarts(stroldsource)) {
-                                    // <oldsource>...</oldsource>
-                                    msg.setOldSourceText(readContents());
-                                } else if (elementStarts(stroldcomment)) {
-                                    // <oldcomment>...</oldcomment>
-                                    msg.setOldComment(readContents());
-                                } else if (elementStarts(strextracomment)) {
-                                    // <extracomment>...</extracomment>
-                                    msg.setExtraComment(readContents());
-                                } else if (elementStarts(strtranslatorcomment)) {
-                                    // <translatorcomment>...</translatorcomment>
-                                    msg.setTranslatorComment(readContents());
-                                } else if (elementStarts(strlocation)) {
-                                    // <location/>
-                                    maybeAbsolute = true;
-                                    QXmlStreamAttributes atts = attributes();
-                                    QString fileName = atts.value(strfilename).toString();
-                                    if (fileName.isEmpty()) {
-                                        fileName = currentMsgFile;
-                                        maybeRelative = true;
-                                    } else {
-                                        if (refs.isEmpty())
-                                            currentFile = fileName;
-                                        currentMsgFile = fileName;
-                                    }
-                                    const QString lin = atts.value(strline).toString();
-                                    if (lin.isEmpty()) {
-                                        refs.append(TranslatorMessage::Reference(fileName, -1));
-                                    } else {
-                                        bool bOK;
-                                        int lineNo = lin.toInt(&bOK);
-                                        if (bOK) {
-                                            if (lin.startsWith(QLatin1Char('+')) || lin.startsWith(QLatin1Char('-'))) {
-                                                lineNo = (currentLine[fileName] += lineNo);
-                                                maybeRelative = true;
-                                            }
-                                            refs.append(TranslatorMessage::Reference(fileName, lineNo));
-                                        }
-                                    }
-                                    readContents();
-                                } else if (elementStarts(strcomment)) {
-                                    // <comment>...</comment>
-                                    msg.setComment(readContents());
-                                } else if (elementStarts(struserdata)) {
-                                    // <userdata>...</userdata>
-                                    msg.setUserData(readContents());
-                                } else if (elementStarts(strtranslation)) {
-                                    // <translation>
-                                    QXmlStreamAttributes atts = attributes();
-                                    QStringRef type = atts.value(strtype);
-                                    if (type == strunfinished)
-                                        msg.setType(TranslatorMessage::Unfinished);
-                                    else if (type == strobsolete)
-                                        msg.setType(TranslatorMessage::Obsolete);
-                                    if (msg.isPlural()) {
-                                        QStringList translations;
-                                        while (!atEnd()) {
-                                            readNext();
-                                            if (isEndElement()) {
-                                                break;
-                                            } else if (isWhiteSpace()) {
-                                                // ignore these, just whitespace
-                                            } else if (elementStarts(strnumerusform)) {
-                                                translations.append(readTransContents());
-                                            } else {
-                                                handleError();
-                                                break;
-                                            }
-                                        }
-                                        msg.setTranslations(translations);
-                                    } else {
-                                        msg.setTranslation(readTransContents());
-                                    }
-                                    // </translation>
-                                } else if (isStartElement()
-                                        && name().toString().startsWith(strextrans)) {
-                                    // <extra-...>
-                                    QString tag = name().toString();
-                                    msg.setExtra(tag.mid(6), readContents());
-                                    // </extra-...>
-                                } else {
-                                    handleError();
-                                }
-                            }
-                            // </message>
-                        } else {
-                            handleError();
-                        }
-                    }
-                    // </context>
-                } else {
-                    handleError();
-                }
-                translator.setLocationsType(maybeRelative ? Translator::RelativeLocations :
-                                            maybeAbsolute ? Translator::AbsoluteLocations :
-                                                            Translator::NoLocations);
-            } // </TS>
-        } else {
-            handleError();
-        }
-    }
-    if (hasError()) {
-        m_cd.appendError(errorString());
-        return false;
-    }
-    return true;
-}
-
-static QString numericEntity(int ch)
-{
-    return QString(ch <= 0x20 ? QLatin1String("<byte value=\"x%1\"/>")
-        : QLatin1String("&#x%1;")) .arg(ch, 0, 16);
-}
-
-static QString protect(const QString &str)
-{
-    QString result;
-    result.reserve(str.length() * 12 / 10);
-    for (int i = 0; i != str.size(); ++i) {
-        uint c = str.at(i).unicode();
-        switch (c) {
-        case '\"':
-            result += QLatin1String("&quot;");
-            break;
-        case '&':
-            result += QLatin1String("&amp;");
-            break;
-        case '>':
-            result += QLatin1String("&gt;");
-            break;
-        case '<':
-            result += QLatin1String("&lt;");
-            break;
-        case '\'':
-            result += QLatin1String("&apos;");
-            break;
-        default:
-            if (c < 0x20 && c != '\r' && c != '\n' && c != '\t')
-                result += numericEntity(c);
-            else // this also covers surrogates
-                result += QChar(c);
-        }
-    }
-    return result;
-}
-
-static QString evilBytes(const QString& str,
-    bool isUtf8, int format, const QByteArray &codecName)
-{
-    //qDebug() << "EVIL: " << str << isUtf8 << format << codecName;
-    if (isUtf8)
-        return protect(str);
-    if (format == 20)
-        return protect(str);
-    if (codecName == "UTF-8")
-        return protect(str);
-    QTextCodec *codec = QTextCodec::codecForName(codecName);
-    if (!codec)
-        return protect(str);
-    QString t = QString::fromLatin1(codec->fromUnicode(protect(str)).data());
-    int len = (int) t.length();
-    QString result;
-    // FIXME: Factor is sensible only for latin scripts, probably.
-    result.reserve(t.length() * 2);
-    for (int k = 0; k < len; k++) {
-        if (t[k].unicode() >= 0x7f)
-            result += numericEntity(t[k].unicode());
-        else
-            result += t[k];
-    }
-    return result;
-}
-
-static void writeExtras(QTextStream &t, const char *indent,
-                        const TranslatorMessage::ExtraData &extras, const QRegExp &drops)
-{
-    for (Translator::ExtraData::ConstIterator it = extras.begin(); it != extras.end(); ++it) {
-        if (!drops.exactMatch(it.key())) {
-            t << indent << "<extra-" << it.key() << '>'
-              << protect(it.value())
-              << "</extra-" << it.key() << ">\n";
-        }
-    }
-}
-
-static void writeVariants(QTextStream &t, const char *indent, const QString &input)
-{
-    int offset;
-    if ((offset = input.indexOf(QChar(Translator::BinaryVariantSeparator))) >= 0) {
-        t << " variants=\"yes\">";
-        int start = 0;
-        forever {
-            t << "\n    " << indent << "<lengthvariant>"
-              << protect(input.mid(start, offset - start))
-              << "</lengthvariant>";
-            if (offset == input.length())
-                break;
-            start = offset + 1;
-            offset = input.indexOf(QChar(Translator::BinaryVariantSeparator), start);
-            if (offset < 0)
-                offset = input.length();
-        }
-        t << "\n" << indent;
-    } else {
-        t << ">" << protect(input);
-    }
-}
-
-bool saveTS(const Translator &translator, QIODevice &dev, ConversionData &cd, int format)
-{
-    bool result = true;
-    QTextStream t(&dev);
-    t.setCodec(QTextCodec::codecForName("UTF-8"));
-    bool trIsUtf8 = (translator.codecName() == "UTF-8");
-    //qDebug() << translator.codecName();
-    bool fileIsUtf8 = (format == 20 || trIsUtf8);
-
-    // The xml prolog allows processors to easily detect the correct encoding
-    t << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!DOCTYPE TS>\n";
-
-    if (format == 11)
-        t << "<TS version=\"1.1\"";
-    else
-        t << "<TS version=\"2.0\"";
-
-    QString languageCode = translator.languageCode();
-    if (!languageCode.isEmpty() && languageCode != QLatin1String("C"))
-        t << " language=\"" << languageCode << "\"";
-    if (format == 20) {
-        languageCode = translator.sourceLanguageCode();
-        if (!languageCode.isEmpty() && languageCode != QLatin1String("C"))
-            t << " sourcelanguage=\"" << languageCode << "\"";
-    }
-    t << ">\n";
-
-    QByteArray codecName = translator.codecName();
-    if (codecName != "ISO-8859-1")
-        t << "<defaultcodec>" << codecName << "</defaultcodec>\n";
-
-    QRegExp drops(cd.dropTags().join(QLatin1String("|")));
-
-    if (format == 20)
-        writeExtras(t, "    ", translator.extras(), drops);
-
-    QHash<QString, QList<TranslatorMessage> > messageOrder;
-    QList<QString> contextOrder;
-    foreach (const TranslatorMessage &msg, translator.messages()) {
-        // no need for such noise
-        if (msg.type() == TranslatorMessage::Obsolete && msg.translation().isEmpty())
-            continue;
-
-        QList<TranslatorMessage> &context = messageOrder[msg.context()];
-        if (context.isEmpty())
-            contextOrder.append(msg.context());
-        context.append(msg);
-    }
-    if (cd.sortContexts())
-        qSort(contextOrder);
-
-    QHash<QString, int> currentLine;
-    QString currentFile;
-    foreach (const QString &context, contextOrder) {
-        const TranslatorMessage &firstMsg = messageOrder[context].first();
-        t << "<context" << ((!fileIsUtf8 && firstMsg.isUtf8()) ? " encoding=\"UTF-8\"" : "") << ">\n";
-
-        t << "    <name>"
-          << evilBytes(context, firstMsg.isUtf8() || fileIsUtf8, format, codecName)
-          << "</name>\n";
-        foreach (const TranslatorMessage &msg, messageOrder[context]) {
-            //msg.dump();
-
-            bool isUtf8 = msg.isUtf8();
-            bool second = false;
-            forever {
-
-                t << "    <message";
-                if (!msg.id().isEmpty())
-                    t << " id=\"" << msg.id() << "\"";
-                if (!trIsUtf8) {
-                    if (format == 11) {
-                        if (isUtf8)
-                            t << " encoding=\"UTF-8\"";
-                    } else {
-                        if (msg.isUtf8()) {
-                            if (msg.isNonUtf8())
-                                t << " utf8=\"both\"";
-                            else
-                                t << " utf8=\"true\"";
-                        }
-                    }
-                }
-                if (msg.isPlural())
-                    t << " numerus=\"yes\"";
-                t << ">\n";
-                if (translator.locationsType() != Translator::NoLocations) {
-                    QString cfile = currentFile;
-                    bool first = true;
-                    foreach (const TranslatorMessage::Reference &ref, msg.allReferences()) {
-                        QString fn = cd.m_targetDir.relativeFilePath(ref.fileName())
-                                    .replace(QLatin1Char('\\'),QLatin1Char('/'));
-                        int ln = ref.lineNumber();
-                        QString ld;
-                        if (translator.locationsType() == Translator::RelativeLocations) {
-                            if (ln != -1) {
-                                int dlt = ln - currentLine[fn];
-                                if (dlt >= 0)
-                                    ld.append(QLatin1Char('+'));
-                                ld.append(QString::number(dlt));
-                                currentLine[fn] = ln;
-                            }
-
-                            if (fn != cfile) {
-                                if (first)
-                                    currentFile = fn;
-                                cfile = fn;
-                            } else {
-                                fn.clear();
-                            }
-                            first = false;
-                        } else {
-                            if (ln != -1)
-                                ld = QString::number(ln);
-                        }
-                        t << "        <location";
-                        if (!fn.isEmpty())
-                            t << " filename=\"" << fn << "\"";
-                        if (!ld.isEmpty())
-                            t << " line=\"" << ld << "\"";
-                        t << "/>\n";
-                    }
-                }
-
-                t << "        <source>"
-                  << evilBytes(msg.sourceText(), isUtf8, format, codecName)
-                  << "</source>\n";
-
-                if (format != 11 && !msg.oldSourceText().isEmpty())
-                    t << "        <oldsource>" << protect(msg.oldSourceText()) << "</oldsource>\n";
-
-                if (!msg.comment().isEmpty()) {
-                    t << "        <comment>"
-                      << evilBytes(msg.comment(), isUtf8, format, codecName)
-                      << "</comment>\n";
-                }
-
-                if (format != 11) {
-
-                    if (!msg.oldComment().isEmpty())
-                        t << "        <oldcomment>" << protect(msg.oldComment()) << "</oldcomment>\n";
-
-                    if (!msg.extraComment().isEmpty())
-                        t << "        <extracomment>" << protect(msg.extraComment())
-                          << "</extracomment>\n";
-
-                    if (!msg.translatorComment().isEmpty())
-                        t << "        <translatorcomment>" << protect(msg.translatorComment())
-                          << "</translatorcomment>\n";
-
-                }
-
-                t << "        <translation";
-                if (msg.type() == TranslatorMessage::Unfinished)
-                    t << " type=\"unfinished\"";
-                else if (msg.type() == TranslatorMessage::Obsolete)
-                    t << " type=\"obsolete\"";
-                if (msg.isPlural()) {
-                    t << ">";
-                    const QStringList &translns = msg.translations();
-                    for (int j = 0; j < translns.count(); ++j) {
-                        t << "\n            <numerusform";
-                        writeVariants(t, "            ", translns[j]);
-                        t << "</numerusform>";
-                    }
-                    t << "\n        ";
-                } else {
-                    writeVariants(t, "        ", msg.translation());
-                }
-                t << "</translation>\n";
-
-                if (format != 11)
-                    writeExtras(t, "        ", msg.extras(), drops);
-
-                if (!msg.userData().isEmpty())
-                    t << "        <userdata>" << msg.userData() << "</userdata>\n";
-                t << "    </message>\n";
-
-                if (format != 11 || second || !msg.isUtf8() || !msg.isNonUtf8())
-                    break;
-                isUtf8 = false;
-                second = true;
-            }
-        }
-        t << "</context>\n";
-    }
-
-    t << "</TS>\n";
-    return result;
-}
-
-bool loadTS(Translator &translator, QIODevice &dev, ConversionData &cd)
-{
-    TSReader reader(dev, cd);
-    return reader.read(translator);
-}
-
-bool saveTS11(const Translator &translator, QIODevice &dev, ConversionData &cd)
-{
-    return saveTS(translator, dev, cd, 11);
-}
-
-bool saveTS20(const Translator &translator, QIODevice &dev, ConversionData &cd)
-{
-    return saveTS(translator, dev, cd, 20);
-}
-
-int initTS()
-{
-    Translator::FileFormat format;
-
-    format.extension = QLatin1String("ts11");
-    format.fileType = Translator::FileFormat::TranslationSource;
-    format.priority = -1;
-    format.description = QObject::tr("Qt translation sources (format 1.1)");
-    format.loader = &loadTS;
-    format.saver = &saveTS11;
-    Translator::registerFileFormat(format);
-
-    format.extension = QLatin1String("ts20");
-    format.fileType = Translator::FileFormat::TranslationSource;
-    format.priority = -1;
-    format.description = QObject::tr("Qt translation sources (format 2.0)");
-    format.loader = &loadTS;
-    format.saver = &saveTS20;
-    Translator::registerFileFormat(format);
-
-    // "ts" is always the latest. right now it's ts20.
-    format.extension = QLatin1String("ts");
-    format.fileType = Translator::FileFormat::TranslationSource;
-    format.priority = 0;
-    format.description = QObject::tr("Qt translation sources (latest format)");
-    format.loader = &loadTS;
-    format.saver = &saveTS20;
-    Translator::registerFileFormat(format);
-
-    return 1;
-}
-
-Q_CONSTRUCTOR_FUNCTION(initTS)
-
-QT_END_NAMESPACE