File indexing completed on 2025-02-16 13:03:31
0001 0002 #include "../config-kdoctools.h" 0003 #include "docbookxslt.h" 0004 #include "docbookxslt_p.h" 0005 #include "loggingcategory.h" 0006 #include "meinproc_common.h" 0007 0008 #include <QCoreApplication> 0009 #include <QDir> 0010 #include <QFile> 0011 #include <QFileInfo> 0012 #include <QList> 0013 #include <QStandardPaths> 0014 #include <QString> 0015 0016 #include <QUrl> 0017 0018 #include <libexslt/exslt.h> 0019 #include <libxml/HTMLtree.h> 0020 #include <libxml/debugXML.h> 0021 #include <libxml/parserInternals.h> 0022 #include <libxml/xmlIO.h> 0023 #include <libxml/xmlmemory.h> 0024 #include <libxml/xmlversion.h> 0025 #include <libxslt/transform.h> 0026 #include <libxslt/xsltInternals.h> 0027 #include <libxslt/xsltconfig.h> 0028 #include <libxslt/xsltutils.h> 0029 0030 #include <QCommandLineOption> 0031 #include <QCommandLineParser> 0032 #include <qplatformdefs.h> 0033 #include <string.h> 0034 0035 using namespace KDocTools; 0036 0037 #ifndef _WIN32 0038 extern "C" int xmlLoadExtDtdDefaultValue; 0039 #endif 0040 0041 #define DIE(x) \ 0042 do { \ 0043 qCCritical(KDocToolsLog) << "Error:" << x; \ 0044 exit(1); \ 0045 } while (0) 0046 0047 int main(int argc, char **argv) 0048 { 0049 // xsltSetGenericDebugFunc(stderr, NULL); 0050 0051 QCoreApplication app(argc, argv); 0052 app.setApplicationName(QStringLiteral("meinproc")); 0053 app.setApplicationVersion(QStringLiteral("5.0")); 0054 0055 QCommandLineParser parser; 0056 parser.setApplicationDescription(QCoreApplication::translate("main", "KDE Translator for XML")); 0057 parser.addHelpOption(); 0058 parser.addVersionOption(); 0059 parser.addOption( 0060 QCommandLineOption(QStringList() << QStringLiteral("stylesheet"), QCoreApplication::translate("main", "Stylesheet to use"), QStringLiteral("xsl"))); 0061 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("stdout"), QCoreApplication::translate("main", "Output whole document to stdout"))); 0062 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("o") << QStringLiteral("output"), 0063 QCoreApplication::translate("main", "Output whole document to file"), 0064 QStringLiteral("file"))); 0065 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("check"), QCoreApplication::translate("main", "Check the document for validity"))); 0066 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("cache"), 0067 QCoreApplication::translate("main", "Create a cache file for the document"), 0068 QStringLiteral("file"))); 0069 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("srcdir"), 0070 QCoreApplication::translate("main", "Set the srcdir, for kdoctools"), 0071 QStringLiteral("dir"))); 0072 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("param"), 0073 QCoreApplication::translate("main", "Parameters to pass to the stylesheet"), 0074 QStringLiteral("key=value"))); 0075 parser.addPositionalArgument(QStringLiteral("xml"), QCoreApplication::translate("main", "The file to transform")); 0076 parser.process(app); 0077 0078 const QStringList filesToRead = parser.positionalArguments(); 0079 if (filesToRead.count() != 1) { 0080 parser.showHelp(); 0081 return (1); 0082 } 0083 0084 exsltRegisterAll(); 0085 0086 // Need to set SRCDIR before calling setupStandardDirs 0087 QString srcdir; 0088 if (parser.isSet(QStringLiteral("srcdir"))) { 0089 srcdir = QDir(parser.value(QStringLiteral("srcdir"))).absolutePath(); 0090 } 0091 setupStandardDirs(srcdir); 0092 0093 LIBXML_TEST_VERSION 0094 0095 const QString checkFilename(filesToRead.first()); 0096 CheckFileResult ckr = checkFile(checkFilename); 0097 switch (ckr) { 0098 case CheckFileSuccess: 0099 break; 0100 case CheckFileDoesNotExist: 0101 DIE("File" << checkFilename << "does not exist."); 0102 case CheckFileIsNotFile: 0103 DIE(checkFilename << "is not a file."); 0104 case CheckFileIsNotReadable: 0105 DIE("File" << checkFilename << "is not readable."); 0106 } 0107 0108 if (parser.isSet(QStringLiteral("check"))) { 0109 QStringList lst = getKDocToolsCatalogs(); 0110 if (lst.isEmpty()) { 0111 DIE("Could not find kdoctools catalogs"); 0112 } 0113 QByteArray catalogs = lst.join(" ").toLocal8Bit(); 0114 QString exe; 0115 #if defined(XMLLINT) 0116 exe = QStringLiteral(XMLLINT); 0117 #endif 0118 if (!QFileInfo(exe).isExecutable()) { 0119 exe = QStandardPaths::findExecutable(QStringLiteral("xmllint")); 0120 } 0121 0122 CheckResult cr = check(checkFilename, exe, catalogs); 0123 switch (cr) { 0124 case CheckSuccess: 0125 break; 0126 case CheckNoXmllint: 0127 DIE("Could not find xmllint"); 0128 case CheckNoOut: 0129 DIE("`xmllint --noout` outputted text"); 0130 } 0131 } 0132 0133 QVector<const char *> params; 0134 { 0135 const QStringList paramList = parser.values(QStringLiteral("param")); 0136 for (const QString &tuple : paramList) { 0137 const int ch = tuple.indexOf(QLatin1Char('=')); 0138 if (ch == -1) { 0139 DIE("Key-Value tuple" << tuple << "lacks a '='!"); 0140 } 0141 params.append(qstrdup(tuple.left(ch).toUtf8().constData())); 0142 params.append(qstrdup(tuple.mid(ch + 1).toUtf8().constData())); 0143 } 0144 } 0145 params.append(nullptr); 0146 0147 QString tss = parser.value(QStringLiteral("stylesheet")); 0148 if (tss.isEmpty()) { 0149 tss = QStringLiteral("customization/kde-chunk.xsl"); 0150 } 0151 0152 QString tssPath = locateFileInDtdResource(tss); 0153 if (tssPath.isEmpty()) { 0154 DIE("Unable to find the stylesheet named" << tss << "in dtd resources"); 0155 } 0156 #ifndef MEINPROC_NO_KARCHIVE 0157 const QString cache = parser.value(QStringLiteral("cache")); 0158 #else 0159 if (parser.isSet("cache")) { 0160 qCWarning(KDocToolsLog) << QCoreApplication::translate( 0161 "main", 0162 "The cache option is not available, please re-compile with KArchive support. See MEINPROC_NO_KARCHIVE in KDocTools"); 0163 } 0164 #endif 0165 const bool usingStdOut = parser.isSet(QStringLiteral("stdout")); 0166 const bool usingOutput = parser.isSet(QStringLiteral("output")); 0167 const QString outputOption = parser.value(QStringLiteral("output")); 0168 0169 QString output = transform(checkFilename, tssPath, params); 0170 if (output.isEmpty()) { 0171 DIE("Unable to parse" << checkFilename); 0172 } 0173 0174 #ifndef MEINPROC_NO_KARCHIVE 0175 if (!cache.isEmpty()) { 0176 if (!saveToCache(output, cache)) { 0177 qCWarning(KDocToolsLog) << QCoreApplication::translate("main", "Could not write to cache file %1.").arg(cache); 0178 } 0179 goto end; 0180 } 0181 #endif 0182 0183 doOutput(output, usingStdOut, usingOutput, outputOption, true /* replaceCharset */); 0184 #ifndef MEINPROC_NO_KARCHIVE 0185 end: 0186 #endif 0187 xmlCleanupParser(); 0188 xmlMemoryDump(); 0189 return (0); 0190 }