File indexing completed on 2024-05-05 03:54:33

0001 /*
0002     This file is part of the KDE project
0003     SPDX-FileCopyrightText: 2010 Luigi Toscano <luigi.toscano@tiscali.it>
0004 
0005     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0006 */
0007 
0008 #include "loggingcategory.h"
0009 
0010 #include <QCoreApplication>
0011 #include <QDir>
0012 #include <QFile>
0013 #include <QIODevice>
0014 #include <QList>
0015 #include <QPair>
0016 #include <QRegularExpression>
0017 #include <QStringList>
0018 #include <QTextStream>
0019 
0020 class LangListType : public QList<QPair<QString, QString>>
0021 {
0022 public:
0023     int searchLang(const QString &el)
0024     {
0025         for (int i = 0; i < size(); ++i) {
0026             if (at(i).first == el) {
0027                 return i;
0028             }
0029         }
0030         return -1;
0031     }
0032 };
0033 
0034 int writeLangFile(const QString &fname, const QString &dtdPath, const LangListType &langMap)
0035 {
0036     QFile outFile(fname);
0037     if (!outFile.open(QIODevice::WriteOnly)) {
0038         qCCritical(KDocToolsLog) << QStringLiteral("Could not write %1").arg(outFile.fileName());
0039         return (1);
0040     }
0041 
0042     QTextStream outStream(&outFile);
0043     outStream << "<?xml version='1.0'?>\n";
0044     outStream << QStringLiteral("<!DOCTYPE l:i18n SYSTEM \"%1\">").arg(dtdPath) << QLatin1Char('\n');
0045 
0046     if (!langMap.isEmpty()) {
0047         outStream << "<l:i18n xmlns:l=\"http://docbook.sourceforge.net/xmlns/l10n/1.0\">" << QLatin1Char('\n');
0048         LangListType::const_iterator i = langMap.constBegin();
0049         while (i != langMap.constEnd()) {
0050             outStream << QStringLiteral("<l:l10n language=\"%1\" href=\"%2\"/>").arg((*i).first).arg((*i).second) << QLatin1Char('\n');
0051             ++i;
0052         }
0053         outStream << "</l:i18n>\n";
0054     }
0055 
0056     outFile.close();
0057 
0058     return (0);
0059 }
0060 
0061 inline const QString addTrailingSlash(const QString &p)
0062 {
0063     return p.endsWith(QStringLiteral("/")) ? p : p + QStringLiteral("/");
0064 }
0065 
0066 int main(int argc, char **argv)
0067 {
0068     QCoreApplication app(argc, argv);
0069 
0070     const QStringList arguments = app.arguments();
0071     if (arguments.count() != 4) {
0072         qCCritical(KDocToolsLog) << "wrong argument count";
0073         return (1);
0074     }
0075 
0076     const QString l10nDir = addTrailingSlash(arguments[1]);
0077     const QString l10nCustomDir = addTrailingSlash(arguments[2]);
0078     const QString destDir = addTrailingSlash(arguments[3]);
0079 
0080     QFile i18nFile(l10nDir + QStringLiteral("common/l10n.xml"));
0081 
0082     if (!i18nFile.open(QIODevice::ReadOnly)) {
0083         qCCritical(KDocToolsLog) << i18nFile.fileName() << " not found";
0084         return (1);
0085     }
0086 
0087     /*
0088      * for each language defined in the original l10n.xml, copy
0089      * it into all-l10n.xml and store it in a list;
0090      **/
0091     const QRegularExpression rxDocType(QStringLiteral("^\\s*<!DOCTYPE\\s+l:i18n\\s+SYSTEM\\s+\"l10n\\.dtd\"\\s*>$"));
0092     const QRegularExpression rxEntity(QStringLiteral("^\\s*<l:l10n language=\"([^\\s]+)\"\\s+href=\"([^\\s]+)\"/>\\s*$"));
0093     QTextStream inStream(&i18nFile);
0094     int parsingState = 0;
0095 
0096     LangListType allLangs;
0097 
0098     while (!inStream.atEnd()) {
0099         QString line = inStream.readLine();
0100 
0101         switch (parsingState) {
0102         case 0:
0103             if (rxDocType.match(line).hasMatch()) {
0104                 parsingState = 1;
0105                 // qCDebug(KDocToolsLog) << "DTD found";
0106             }
0107             break;
0108         case 1:
0109             const QRegularExpressionMatch match = rxEntity.match(line);
0110             if (match.hasMatch()) {
0111                 const QString langCode = match.captured(1);
0112                 const QString langFile = l10nDir + QStringLiteral("common/") + match.captured(2);
0113                 allLangs += qMakePair(langCode, langFile);
0114                 // qCDebug(KDocToolsLog) << langCode << " - " << langFile;
0115             }
0116             break;
0117         }
0118     }
0119     i18nFile.close();
0120 
0121     /* read the list of locally-available custom languages */
0122     QDir outDir(l10nCustomDir);
0123 
0124     QStringList dirFileFilters;
0125     dirFileFilters << QStringLiteral("*.xml");
0126     QStringList customLangFiles = outDir.entryList(dirFileFilters, QDir::Files, QDir::Name);
0127     /* the following two calls to removeOne should not be needed, as
0128      * the customization directory from the sources should not contain
0129      * those files
0130      */
0131     customLangFiles.removeOne(QStringLiteral("all-l10n.xml"));
0132     customLangFiles.removeOne(QStringLiteral("kde-custom-l10n.xml"));
0133     // qCDebug(KDocToolsLog) << "customLangFiles:" << customLangFiles;
0134 
0135     /*
0136      * for each custom language (from directory listing), if it is not
0137      * in the list of upstream languages, add it to all-l10n.xml,
0138      * otherwise add it to kde-custom-l10n.xml
0139      */
0140     QStringList::const_iterator i = customLangFiles.constBegin();
0141     while (i != customLangFiles.constEnd()) {
0142         QString langFile = (*i);
0143         /* remove trailing .xml */
0144         QString langCode = langFile.left(langFile.length() - 4);
0145 
0146         QPair<QString, QString> cl = qMakePair(langCode, langFile);
0147         if ((allLangs.searchLang(langCode)) < 0) {
0148             /* custom language not found in upstream list */
0149             allLangs += cl;
0150         }
0151         ++i;
0152     }
0153 
0154     const QString all10nFName = destDir + QStringLiteral("all-l10n.xml");
0155     return writeLangFile(all10nFName, l10nDir + QStringLiteral("common/l10n.dtd"), allLangs);
0156 }