File indexing completed on 2024-04-21 05:46:12

0001 /*
0002     SPDX-FileCopyrightText: 2007 Nicolas Ternisien <nicolas.ternisien@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include <QFile>
0008 #include <QList>
0009 #include <QMap>
0010 #include <QStringList>
0011 #include <QTextStream>
0012 #include <QWidget>
0013 
0014 #include <kio/netaccess.h>
0015 #include <qtest_kde.h>
0016 
0017 #include "ksystemlog_debug.h"
0018 
0019 class FindIncompatibleKioTest : public QObject
0020 {
0021     Q_OBJECT
0022 
0023 private Q_SLOTS:
0024 
0025     void initTestCase();
0026 
0027     void find();
0028 
0029 private:
0030     void displayFoundMethods(const QStringList &methods, const QUrl &url, QTextStream &out);
0031 
0032     QStringList headerContent(const QUrl &url);
0033     QString convertMethod(const QString &method);
0034 
0035     QMap<QString, bool> findMethods(const QStringList &methods, const QUrl &url);
0036 };
0037 
0038 void FindIncompatibleKioTest::initTestCase()
0039 {
0040 }
0041 
0042 void FindIncompatibleKioTest::find()
0043 {
0044     QString kdelibs = QLatin1String("/home/nicolas/workspace/kdelibs");
0045     QString kdebase = QLatin1String("/home/nicolas/workspace/kdebase");
0046 
0047     QString outputPath = QLatin1String("/home/nicolas/compatibleKioSlaves.html");
0048 
0049     QStringList existingMethods;
0050     existingMethods << QLatin1String("void SlaveBase::openConnection(void)");
0051     existingMethods << QLatin1String("void SlaveBase::closeConnection(void)");
0052     existingMethods << QLatin1String("void SlaveBase::stat(QUrl const &)");
0053     existingMethods << QLatin1String("void SlaveBase::put(QUrl const &, int, bool, bool)");
0054     existingMethods << QLatin1String("void SlaveBase::special(const QByteArray &)");
0055     existingMethods << QLatin1String("void SlaveBase::listDir(QUrl const &)");
0056     existingMethods << QLatin1String("void SlaveBase::get(QUrl const & )");
0057     existingMethods << QLatin1String("void SlaveBase::open(QUrl const &, QIODevice::OpenMode)");
0058     existingMethods << QLatin1String("void SlaveBase::read(KIO::filesize_t)");
0059     existingMethods << QLatin1String("void SlaveBase::write(const QByteArray &)");
0060     existingMethods << QLatin1String("void SlaveBase::seek(KIO::filesize_t)");
0061     existingMethods << QLatin1String("void SlaveBase::close()");
0062     existingMethods << QLatin1String("void SlaveBase::mimetype(QUrl const &url)");
0063     existingMethods << QLatin1String("void SlaveBase::rename(QUrl const &, QUrl const &, bool)");
0064     existingMethods << QLatin1String("void SlaveBase::symlink(QString const &, QUrl const &, bool)");
0065     existingMethods << QLatin1String("void SlaveBase::copy(QUrl const &, QUrl const &, int, bool)");
0066     existingMethods << QLatin1String("void SlaveBase::del(QUrl const &, bool)");
0067     existingMethods << QLatin1String("void SlaveBase::setLinkDest(const QUrl &, const QString&)");
0068     existingMethods << QLatin1String("void SlaveBase::mkdir(QUrl const &, int)");
0069     existingMethods << QLatin1String("void SlaveBase::chmod(QUrl const &, int)");
0070     existingMethods << QLatin1String("void SlaveBase::setModificationTime(QUrl const &, const QDateTime&)");
0071     existingMethods << QLatin1String("void SlaveBase::chown(QUrl const &, const QString &, const QString &)");
0072     existingMethods << QLatin1String("void SlaveBase::setSubUrl(QUrl const &)");
0073     existingMethods << QLatin1String("void SlaveBase::multiGet(const QByteArray &)");
0074 
0075     // qCDebug(KSYSTEMLOG) << existingMethods << endl;
0076 
0077     QFile file(outputPath);
0078     if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
0079         logError() << "Unable to open the output file" << outputPath << endl;
0080         return;
0081     }
0082 
0083     QTextStream out(&file);
0084 
0085     out << "<html>" << endl;
0086     out << "<head>" << endl;
0087     out << "<style type='text/css'>" << endl;
0088     out << ".found { color:green }" << endl;
0089     out << ".notFound { color:red }" << endl;
0090     out << "</style>" << endl;
0091     out << "</head>" << endl;
0092     out << "<body>" << endl;
0093 
0094     out << "<div style='text-align:center; font-size:26px; font-variant:small-caps; margin-bottom:40px'>KIO "
0095            "Slaves Analyzing</div>"
0096         << endl;
0097     out << "<div style='font-style:italic'>Generated by <a "
0098            "href='https://commits.kde.org/ksystemlog?path=tests/"
0099            "findIncompatibleKioTest.cpp'>https://commits.kde.org/ksystemlog?path=tests/"
0100            "findIncompatibleKioTest.cpp</a></div>"
0101         << endl;
0102 
0103     QList<QUrl> parsingUrls;
0104 
0105     parsingUrls.append(QUrl::fromLocalFile(kdelibs + QLatin1String("/kioslave/http/http.h")));
0106     parsingUrls.append(QUrl::fromLocalFile(kdelibs + QLatin1String("/kioslave/ftp/ftp.h")));
0107     parsingUrls.append(QUrl::fromLocalFile(kdelibs + QLatin1String("/kioslave/file/file.h")));
0108     parsingUrls.append(QUrl::fromLocalFile(kdelibs + QLatin1String("/kioslave/metainfo/metainfo.h")));
0109 
0110     parsingUrls.append(QUrl::fromLocalFile(kdebase + QLatin1String("/runtime/kioslave/about/kio_about.h")));
0111     parsingUrls.append(QUrl::fromLocalFile(kdebase + QLatin1String("/runtime/kioslave/cgi/cgi.h")));
0112     parsingUrls.append(QUrl::fromLocalFile(kdebase + QLatin1String("/runtime/kioslave/filter/filter.h")));
0113     parsingUrls.append(QUrl::fromLocalFile(kdebase + QLatin1String("/runtime/kioslave/finger/kio_finger.h")));
0114     parsingUrls.append(QUrl::fromLocalFile(kdebase + QLatin1String("/runtime/kioslave/fish/fish.h")));
0115     parsingUrls.append(QUrl::fromLocalFile(kdebase + QLatin1String("/runtime/kioslave/floppy/kio_floppy.h")));
0116     parsingUrls.append(QUrl::fromLocalFile(kdebase + QLatin1String("/runtime/kioslave/info/info.h")));
0117     parsingUrls.append(QUrl::fromLocalFile(kdebase + QLatin1String("/runtime/kioslave/man/kio_man.h")));
0118     parsingUrls.append(QUrl::fromLocalFile(kdebase + QLatin1String("/runtime/kioslave/media/kio_media.h")));
0119     parsingUrls.append(QUrl::fromLocalFile(kdebase + QLatin1String("/runtime/kioslave/nfs/kio_nfs.h")));
0120     parsingUrls.append(QUrl::fromLocalFile(kdebase + QLatin1String("/runtime/kioslave/remote/kio_remote.h")));
0121     parsingUrls.append(QUrl::fromLocalFile(kdebase + QLatin1String("/runtime/kioslave/settings/kio_settings.cc")));
0122     parsingUrls.append(QUrl::fromLocalFile(kdebase + QLatin1String("/runtime/kioslave/sftp/kio_sftp.h")));
0123     parsingUrls.append(QUrl::fromLocalFile(kdebase + QLatin1String("/runtime/kioslave/smb/kio_smb.h")));
0124     // parsingUrls.append(QUrl::fromLocalFile(kdebase + QLatin1String("/runtime/kioslave/tar/tar.h")));
0125     parsingUrls.append(QUrl::fromLocalFile(kdebase + QLatin1String("/runtime/kioslave/thumbnail/thumbnail.h")));
0126     parsingUrls.append(QUrl::fromLocalFile(kdebase + QLatin1String("/runtime/kioslave/trash/kio_trash.h")));
0127 
0128     out << "<hr />" << endl;
0129     out << "<h1>Analyzed KIO Slaves</h1>" << endl;
0130     out << "<ul>" << endl;
0131     foreach (const QUrl &url, parsingUrls) {
0132         out << "<li><a href='#" << url.fileName() << "'>" << url.path() << "</a></li>" << endl;
0133     }
0134     out << "</ul>" << endl;
0135 
0136     foreach (const QUrl &url, parsingUrls) {
0137         displayFoundMethods(existingMethods, url, out);
0138     }
0139 
0140     out << "<hr />" << endl;
0141     out << "<h1>SlaveBase methods to implement</h1>" << endl;
0142     out << "<ul>" << endl;
0143     foreach (const QString &method, existingMethods) {
0144         out << "<li>" << method << "</li>" << endl;
0145     }
0146     out << "</ul>" << endl;
0147 
0148     out << "</body>" << endl;
0149     out << "</html>" << endl;
0150 
0151     file.close();
0152 }
0153 
0154 void FindIncompatibleKioTest::displayFoundMethods(const QStringList &methods, const QUrl &url, QTextStream &out)
0155 {
0156     QMap<QString, bool> foundMethods = findMethods(methods, url);
0157 
0158     out << endl;
0159     out << "<hr />" << endl;
0160     out << "<h1 id='" << url.fileName() << "'>" << url.path() << "</h1>" << endl;
0161 
0162     if (foundMethods.isEmpty()) {
0163         out << "No file found" << endl;
0164         out << "<hr />" << endl;
0165         return;
0166     }
0167 
0168     out << "<hr />" << endl;
0169     out << "<h2><span class='found'>Found</span> and <span class='notFound'>Not Found</span> methods : </h2>" << endl;
0170     out << "<ul>" << endl;
0171 
0172     // Found methods
0173     QMapIterator<QString, bool> i(foundMethods);
0174     while (i.hasNext()) {
0175         i.next();
0176 
0177         if (i.value() == true) {
0178             out << "<li class='found'>" << i.key() << "</li>" << endl;
0179         }
0180     }
0181 
0182     // Found methods
0183     i = foundMethods;
0184     while (i.hasNext()) {
0185         i.next();
0186 
0187         if (i.value() == false) {
0188             out << "<li class='notFound'>" << i.key() << "</li>" << endl;
0189         }
0190     }
0191 
0192     out << "</ul>" << endl;
0193 }
0194 
0195 QMap<QString, bool> FindIncompatibleKioTest::findMethods(const QStringList &methods, const QUrl &url)
0196 {
0197     QStringList lines = headerContent(url);
0198     if (lines.isEmpty()) {
0199         return QMap<QString, bool>();
0200     }
0201 
0202     QMap<QString, bool> foundMethods;
0203     foreach (const QString &method, methods) {
0204         foundMethods.insert(method, false);
0205     }
0206 
0207     foreach (QString line, lines) {
0208         line = convertMethod(line);
0209 
0210         if (line.contains(QLatin1String("void")) == false) {
0211             continue;
0212         }
0213 
0214         // qCDebug(KSYSTEMLOG) << "Line" << convertMethod(line) << endl;
0215 
0216         foreach (const QString &method, methods) {
0217             if (line == convertMethod(method)) {
0218                 foundMethods.insert(method, true);
0219             }
0220             /*
0221              else {
0222              qCDebug(KSYSTEMLOG) << method << " != " << line << endl;
0223              }
0224              */
0225         }
0226     }
0227 
0228     qCDebug(KSYSTEMLOG) << endl;
0229 
0230     return foundMethods;
0231 }
0232 
0233 QString FindIncompatibleKioTest::convertMethod(const QString &method)
0234 {
0235     QString result(method);
0236     result.remove(QLatin1String("SlaveBase::"));
0237     result.remove(QLatin1String("virtual"));
0238     //  result = result.remove(QLatin1String(" "));
0239     //  result = result.replace('\t', ' ');
0240     result.remove(QLatin1String(";"));
0241     result = result.simplified();
0242 
0243     int firstParenthesis = result.indexOf(QLatin1Char('('));
0244     int lastParenthesis = result.indexOf(QLatin1Char(')'));
0245     if (firstParenthesis != -1 && lastParenthesis != -1) {
0246         result.remove(firstParenthesis + 1, lastParenthesis - firstParenthesis - 1);
0247     }
0248 
0249     return result;
0250 }
0251 
0252 QStringList FindIncompatibleKioTest::headerContent(const QUrl &url)
0253 {
0254     QStringList kioHeaderContent;
0255 
0256     QString tmpFile;
0257     if (KIO::NetAccess::download(url, tmpFile, new QWidget())) {
0258         QFile file(tmpFile);
0259         file.open(QIODevice::ReadOnly);
0260 
0261         // If the file does not exist
0262         if (!file.exists()) {
0263             return QStringList();
0264         }
0265 
0266         QTextStream inputStream(&file);
0267         while (inputStream.atEnd() == false) {
0268             kioHeaderContent.append(inputStream.readLine());
0269         }
0270 
0271         file.close();
0272 
0273         KIO::NetAccess::removeTempFile(tmpFile);
0274     } else {
0275         qCDebug(KSYSTEMLOG) << KIO::NetAccess::lastErrorString() << endl;
0276     }
0277 
0278     return kioHeaderContent;
0279 }
0280 
0281 QTEST_KDEMAIN(FindIncompatibleKioTest, GUI)
0282 
0283 #include "findIncompatibleKioTest.moc"