diff --git a/autotests/kpluginloadertest.cpp b/autotests/kpluginloadertest.cpp index 09902fd..2a733c8 100644 --- a/autotests/kpluginloadertest.cpp +++ b/autotests/kpluginloadertest.cpp @@ -1,458 +1,458 @@ /* * Copyright 2014 Alex Merry * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) version 3, or any * later version accepted by the membership of KDE e.V. (or its * successor approved by the membership of KDE e.V.), which shall * act as a proxy defined in Section 6 of version 3 of the license. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see * . */ #include #include #include #include class LibraryPathRestorer { public: explicit LibraryPathRestorer(const QStringList &paths) : mPaths(paths) {} ~LibraryPathRestorer() { QCoreApplication::setLibraryPaths(mPaths); } private: QStringList mPaths; }; class KPluginLoaderTest : public QObject { Q_OBJECT private Q_SLOTS: void testFindPlugin_missing() { const QString location = KPluginLoader::findPlugin(QStringLiteral("idonotexist")); QVERIFY2(location.isEmpty(), qPrintable(location)); } void testFindPlugin() { const QString location = KPluginLoader::findPlugin(QStringLiteral("jsonplugin")); QVERIFY2(!location.isEmpty(), qPrintable(location)); } void testPluginVersion() { KPluginLoader vplugin(QStringLiteral("versionedplugin")); QCOMPARE(vplugin.pluginVersion(), quint32(5)); KPluginLoader vplugin2(QStringLiteral("versionedplugin")); QCOMPARE(vplugin2.pluginVersion(), quint32(5)); KPluginLoader uplugin(QStringLiteral("unversionedplugin")); QCOMPARE(uplugin.pluginVersion(), quint32(-1)); KPluginLoader jplugin(KPluginName(QStringLiteral("jsonplugin"))); QCOMPARE(jplugin.pluginVersion(), quint32(-1)); KPluginLoader eplugin(KPluginName::fromErrorString(QStringLiteral("there was an error"))); QCOMPARE(eplugin.pluginVersion(), quint32(-1)); KPluginLoader noplugin(QStringLiteral("idonotexist")); QCOMPARE(noplugin.pluginVersion(), quint32(-1)); } void testPluginName() { KPluginLoader vplugin(QStringLiteral("versionedplugin")); QCOMPARE(vplugin.pluginName(), QString::fromLatin1("versionedplugin")); KPluginLoader jplugin(KPluginName(QStringLiteral("jsonplugin"))); QCOMPARE(jplugin.pluginName(), QString::fromLatin1("jsonplugin")); KPluginLoader eplugin(KPluginName::fromErrorString(QStringLiteral("there was an error"))); QVERIFY2(eplugin.pluginName().isEmpty(), qPrintable(eplugin.pluginName())); KPluginLoader noplugin(QStringLiteral("idonotexist")); QCOMPARE(noplugin.pluginName(), QString::fromLatin1("idonotexist")); } void testFactory() { KPluginLoader vplugin(QStringLiteral("versionedplugin")); QVERIFY(vplugin.factory()); KPluginLoader jplugin(KPluginName(QStringLiteral("jsonplugin"))); QVERIFY(jplugin.factory()); KPluginLoader eplugin(KPluginName::fromErrorString(QStringLiteral("there was an error"))); QVERIFY(!eplugin.factory()); KPluginLoader noplugin(QStringLiteral("idonotexist")); QVERIFY(!noplugin.factory()); } void testErrorString() { KPluginLoader eplugin(KPluginName::fromErrorString(QStringLiteral("there was an error"))); QCOMPARE(eplugin.errorString(), QString::fromLatin1("there was an error")); } void testFileName() { KPluginLoader vplugin(QStringLiteral("versionedplugin")); QCOMPARE(QFileInfo(vplugin.fileName()).canonicalFilePath(), QFileInfo(QStringLiteral(VERSIONEDPLUGIN_FILE)).canonicalFilePath()); KPluginLoader jplugin(KPluginName(QStringLiteral("jsonplugin"))); QCOMPARE(QFileInfo(jplugin.fileName()).canonicalFilePath(), QFileInfo(QStringLiteral(JSONPLUGIN_FILE)).canonicalFilePath()); KPluginLoader eplugin(KPluginName::fromErrorString(QStringLiteral("there was an error"))); QVERIFY2(eplugin.fileName().isEmpty(), qPrintable(eplugin.fileName())); KPluginLoader noplugin(QStringLiteral("idonotexist")); QVERIFY2(noplugin.fileName().isEmpty(), qPrintable(noplugin.fileName())); } void testInstance() { KPluginLoader vplugin(QStringLiteral("versionedplugin")); QVERIFY(vplugin.instance()); KPluginLoader jplugin(KPluginName(QStringLiteral("jsonplugin"))); QVERIFY(jplugin.instance()); KPluginLoader eplugin(KPluginName::fromErrorString(QStringLiteral("there was an error"))); QVERIFY(!eplugin.instance()); KPluginLoader noplugin(QStringLiteral("idonotexist")); QVERIFY(!noplugin.instance()); } void testIsLoaded() { KPluginLoader vplugin(QStringLiteral("versionedplugin")); QVERIFY(!vplugin.isLoaded()); QVERIFY(vplugin.load()); QVERIFY(vplugin.isLoaded()); KPluginLoader jplugin(KPluginName(QStringLiteral("jsonplugin"))); QVERIFY(!jplugin.isLoaded()); QVERIFY(jplugin.load()); QVERIFY(jplugin.isLoaded()); KPluginLoader aplugin(QStringLiteral("alwaysunloadplugin")); QVERIFY(!aplugin.isLoaded()); QVERIFY(aplugin.load()); QVERIFY(aplugin.isLoaded()); if (aplugin.unload()) { QVERIFY(!aplugin.isLoaded()); } else { qDebug() << "Could not unload alwaysunloadplugin:" << aplugin.errorString(); } KPluginLoader eplugin(KPluginName::fromErrorString(QStringLiteral("there was an error"))); QVERIFY(!eplugin.isLoaded()); QVERIFY(!eplugin.load()); QVERIFY(!eplugin.isLoaded()); KPluginLoader noplugin(QStringLiteral("idonotexist")); QVERIFY(!noplugin.isLoaded()); QVERIFY(!noplugin.load()); QVERIFY(!noplugin.isLoaded()); } void testLoad() { KPluginLoader vplugin(QStringLiteral("versionedplugin")); QVERIFY(vplugin.load()); KPluginLoader jplugin(KPluginName(QStringLiteral("jsonplugin"))); QVERIFY(jplugin.load()); KPluginLoader eplugin(KPluginName::fromErrorString(QStringLiteral("there was an error"))); QVERIFY(!eplugin.load()); KPluginLoader noplugin(QStringLiteral("idonotexist")); QVERIFY(!noplugin.load()); } void testLoadHints() { KPluginLoader aplugin(QStringLiteral("alwaysunloadplugin")); aplugin.setLoadHints(QLibrary::ResolveAllSymbolsHint); QCOMPARE(aplugin.loadHints(), QLibrary::ResolveAllSymbolsHint); } void testMetaData() { KPluginLoader aplugin(QStringLiteral("alwaysunloadplugin")); QJsonObject ametadata = aplugin.metaData(); QVERIFY(!ametadata.isEmpty()); QVERIFY(ametadata.keys().contains(QLatin1String("IID"))); QJsonValue ametadata_metadata = ametadata.value(QStringLiteral("MetaData")); QVERIFY(ametadata_metadata.toObject().isEmpty()); QVERIFY(!aplugin.isLoaded()); // didn't load anything KPluginLoader jplugin(KPluginName(QStringLiteral("jsonplugin"))); QJsonObject jmetadata = jplugin.metaData(); QVERIFY(!jmetadata.isEmpty()); QJsonValue jmetadata_metadata = jmetadata.value(QStringLiteral("MetaData")); QVERIFY(jmetadata_metadata.isObject()); QJsonObject jmetadata_obj = jmetadata_metadata.toObject(); QVERIFY(!jmetadata_obj.isEmpty()); QJsonValue comment = jmetadata_obj.value(QStringLiteral("KPlugin")).toObject().value(QStringLiteral("Description")); QVERIFY(comment.isString()); QCOMPARE(comment.toString(), QString::fromLatin1("This is a plugin")); KPluginLoader eplugin(KPluginName::fromErrorString(QStringLiteral("there was an error"))); QVERIFY(eplugin.metaData().isEmpty()); KPluginLoader noplugin(QStringLiteral("idonotexist")); QVERIFY(noplugin.metaData().isEmpty()); } void testUnload() { KPluginLoader aplugin(QStringLiteral("alwaysunloadplugin")); QVERIFY(aplugin.load()); // may need QEXPECT_FAIL on some platforms... QVERIFY(aplugin.unload()); } void testInstantiatePlugins() { const QString plugin1Path = KPluginLoader::findPlugin(QStringLiteral("jsonplugin")); QVERIFY2(!plugin1Path.isEmpty(), qPrintable(plugin1Path)); const QString plugin2Path = KPluginLoader::findPlugin(QStringLiteral("unversionedplugin")); QVERIFY2(!plugin2Path.isEmpty(), qPrintable(plugin2Path)); const QString plugin3Path = KPluginLoader::findPlugin(QStringLiteral("jsonplugin2")); QVERIFY2(!plugin3Path.isEmpty(), qPrintable(plugin3Path)); QTemporaryDir temp; QVERIFY(temp.isValid()); QDir dir(temp.path()); QVERIFY2(QFile::copy(plugin1Path, dir.absoluteFilePath(QFileInfo(plugin1Path).fileName())), qPrintable(dir.absoluteFilePath(QFileInfo(plugin1Path).fileName()))); QVERIFY2(QFile::copy(plugin2Path, dir.absoluteFilePath(QFileInfo(plugin2Path).fileName())), qPrintable(dir.absoluteFilePath(QFileInfo(plugin2Path).fileName()))); QVERIFY2(QFile::copy(plugin3Path, dir.absoluteFilePath(QFileInfo(plugin3Path).fileName())), qPrintable(dir.absoluteFilePath(QFileInfo(plugin3Path).fileName()))); // only jsonplugin, since unversionedplugin has no json metadata QList plugins = KPluginLoader::instantiatePlugins(temp.path()); QCOMPARE(plugins.size(), 2); QStringList classNames = QStringList() << QString::fromLatin1(plugins[0]->metaObject()->className()) << QString::fromLatin1(plugins[1]->metaObject()->className()); classNames.sort(); QCOMPARE(classNames[0], QStringLiteral("jsonplugin2")); QCOMPARE(classNames[1], QStringLiteral("jsonpluginfa")); qDeleteAll(plugins); //try filter plugins = KPluginLoader::instantiatePlugins(temp.path(), [](const KPluginMetaData & md) { - return md.pluginId() == QStringLiteral("jsonplugin"); + return md.pluginId() == QLatin1String("jsonplugin"); }); QCOMPARE(plugins.size(), 1); QCOMPARE(plugins[0]->metaObject()->className(), "jsonpluginfa"); qDeleteAll(plugins); plugins = KPluginLoader::instantiatePlugins(temp.path(), [](const KPluginMetaData & md) { - return md.pluginId() == QStringLiteral("unversionedplugin"); + return md.pluginId() == QLatin1String("unversionedplugin"); }); QCOMPARE(plugins.size(), 0); plugins = KPluginLoader::instantiatePlugins(temp.path(), [](const KPluginMetaData & md) { - return md.pluginId() == QStringLiteral("foobar"); // ID does not match file name, is set in JSON + return md.pluginId() == QLatin1String("foobar"); // ID does not match file name, is set in JSON }); QCOMPARE(plugins.size(), 1); QCOMPARE(plugins[0]->metaObject()->className(), "jsonplugin2"); qDeleteAll(plugins); // check that parent gets set plugins = KPluginLoader::instantiatePlugins(temp.path(), [](const KPluginMetaData&) { return true; }, this); QCOMPARE(plugins.size(), 2); QCOMPARE(plugins[0]->parent(), this); QCOMPARE(plugins[1]->parent(), this); qDeleteAll(plugins); const QString subDirName = dir.dirName(); QVERIFY(dir.cdUp()); // should now point to /tmp on Linux LibraryPathRestorer restorer(QCoreApplication::libraryPaths()); // instantiate using relative path // make sure library path is set up correctly QCoreApplication::setLibraryPaths(QStringList() << dir.absolutePath()); QVERIFY(!QDir::isAbsolutePath(subDirName)); plugins = KPluginLoader::instantiatePlugins(subDirName); QCOMPARE(plugins.size(), 2); classNames = QStringList() << QString::fromLatin1(plugins[0]->metaObject()->className()) << QString::fromLatin1(plugins[1]->metaObject()->className()); classNames.sort(); QCOMPARE(classNames[0], QStringLiteral("jsonplugin2")); QCOMPARE(classNames[1], QStringLiteral("jsonpluginfa")); qDeleteAll(plugins); } void testFindPlugins() { const QString plugin1Path = KPluginLoader::findPlugin(QStringLiteral("jsonplugin")); QVERIFY2(!plugin1Path.isEmpty(), qPrintable(plugin1Path)); const QString plugin2Path = KPluginLoader::findPlugin(QStringLiteral("unversionedplugin")); QVERIFY2(!plugin2Path.isEmpty(), qPrintable(plugin2Path)); const QString plugin3Path = KPluginLoader::findPlugin(QStringLiteral("jsonplugin2")); QVERIFY2(!plugin3Path.isEmpty(), qPrintable(plugin3Path)); QTemporaryDir temp; QVERIFY(temp.isValid()); QDir dir(temp.path()); QVERIFY(dir.mkdir(QStringLiteral("kpluginmetadatatest"))); QVERIFY(dir.cd(QStringLiteral("kpluginmetadatatest"))); QVERIFY2(QFile::copy(plugin1Path, dir.absoluteFilePath(QFileInfo(plugin1Path).fileName())), qPrintable(dir.absoluteFilePath(QFileInfo(plugin1Path).fileName()))); QVERIFY2(QFile::copy(plugin2Path, dir.absoluteFilePath(QFileInfo(plugin2Path).fileName())), qPrintable(dir.absoluteFilePath(QFileInfo(plugin2Path).fileName()))); QVERIFY2(QFile::copy(plugin3Path, dir.absoluteFilePath(QFileInfo(plugin3Path).fileName())), qPrintable(dir.absoluteFilePath(QFileInfo(plugin3Path).fileName()))); LibraryPathRestorer restorer(QCoreApplication::libraryPaths()); // we only want plugins from our temporary dir QCoreApplication::setLibraryPaths(QStringList() << temp.path()); auto sortPlugins = [](const KPluginMetaData &a, const KPluginMetaData &b) { return a.pluginId() < b.pluginId(); }; // it should find jsonplugin and jsonplugin2 since unversionedplugin does not have any meta data auto plugins = KPluginLoader::findPlugins(QStringLiteral("kpluginmetadatatest")); std::sort(plugins.begin(), plugins.end(), sortPlugins); QCOMPARE(plugins.size(), 2); QCOMPARE(plugins[0].pluginId(), QStringLiteral("foobar")); // ID is not the filename, it is set in the JSON metadata QCOMPARE(plugins[0].description(), QStringLiteral("This is another plugin")); QCOMPARE(plugins[1].pluginId(), QStringLiteral("jsonplugin")); QCOMPARE(plugins[1].description(), QStringLiteral("This is a plugin")); // filter accepts none plugins = KPluginLoader::findPlugins(QStringLiteral("kpluginmetadatatest"), [](const KPluginMetaData &) { return false; }); std::sort(plugins.begin(), plugins.end(), sortPlugins); QCOMPARE(plugins.size(), 0); // filter accepts all plugins = KPluginLoader::findPlugins(QStringLiteral("kpluginmetadatatest"), [](const KPluginMetaData &) { return true; }); std::sort(plugins.begin(), plugins.end(), sortPlugins); QCOMPARE(plugins.size(), 2); QCOMPARE(plugins[0].description(), QStringLiteral("This is another plugin")); QCOMPARE(plugins[1].description(), QStringLiteral("This is a plugin")); // invalid std::function as filter plugins = KPluginLoader::findPlugins(QStringLiteral("kpluginmetadatatest")); std::sort(plugins.begin(), plugins.end(), sortPlugins); QCOMPARE(plugins.size(), 2); QCOMPARE(plugins[0].description(), QStringLiteral("This is another plugin")); QCOMPARE(plugins[1].description(), QStringLiteral("This is a plugin")); // by plugin id plugins = KPluginLoader::findPluginsById(dir.absolutePath(), QStringLiteral("foobar")); QCOMPARE(plugins.size(), 1); QCOMPARE(plugins[0].description(), QStringLiteral("This is another plugin")); // by plugin invalid id plugins = KPluginLoader::findPluginsById(dir.absolutePath(), QStringLiteral("invalidid")); QCOMPARE(plugins.size(), 0); // absolute path, no filter plugins = KPluginLoader::findPlugins(dir.absolutePath()); std::sort(plugins.begin(), plugins.end(), sortPlugins); QCOMPARE(plugins.size(), 2); QCOMPARE(plugins[0].description(), QStringLiteral("This is another plugin")); QCOMPARE(plugins[1].description(), QStringLiteral("This is a plugin")); } void testForEachPlugin() { const QString jsonPluginSrc = KPluginLoader::findPlugin(QStringLiteral("jsonplugin")); QVERIFY2(!jsonPluginSrc.isEmpty(), qPrintable(jsonPluginSrc)); const QString unversionedPluginSrc = KPluginLoader::findPlugin(QStringLiteral("unversionedplugin")); QVERIFY2(!unversionedPluginSrc.isEmpty(), qPrintable(unversionedPluginSrc)); const QString jsonPlugin2Src = KPluginLoader::findPlugin(QStringLiteral("jsonplugin2")); QVERIFY2(!jsonPlugin2Src.isEmpty(), qPrintable(jsonPlugin2Src)); QTemporaryDir temp; QVERIFY(temp.isValid()); QDir dir(temp.path()); QVERIFY(dir.mkdir(QStringLiteral("for-each-plugin"))); QVERIFY(dir.cd(QStringLiteral("for-each-plugin"))); const QString jsonPluginDest = dir.absoluteFilePath(QFileInfo(jsonPluginSrc).fileName()); QVERIFY2(QFile::copy(jsonPluginSrc, jsonPluginDest), qPrintable(jsonPluginDest)); const QString unversionedPluginDest = dir.absoluteFilePath(QFileInfo(unversionedPluginSrc).fileName()); QVERIFY2(QFile::copy(unversionedPluginSrc, unversionedPluginDest), qPrintable(unversionedPluginDest)); // copy jsonplugin2 to a "for-each-plugin" subdirectory in a different directory QTemporaryDir temp2; QVERIFY(temp2.isValid()); QDir dir2(temp2.path()); QVERIFY(dir2.mkdir(QStringLiteral("for-each-plugin"))); QVERIFY(dir2.cd(QStringLiteral("for-each-plugin"))); const QString jsonPlugin2Dest = dir2.absoluteFilePath(QFileInfo(jsonPlugin2Src).fileName()); QVERIFY2(QFile::copy(jsonPlugin2Src, jsonPlugin2Dest), qPrintable(jsonPlugin2Dest)); QStringList foundPlugins; QStringList expectedPlugins; const auto addToFoundPlugins = [&](const QString &path) { QVERIFY(!path.isEmpty()); foundPlugins.append(path); }; // test finding with absolute path expectedPlugins = QStringList() << jsonPluginDest << unversionedPluginDest; expectedPlugins.sort(); KPluginLoader::forEachPlugin(dir.path(), addToFoundPlugins); foundPlugins.sort(); QCOMPARE(foundPlugins, expectedPlugins); expectedPlugins = QStringList() << jsonPlugin2Dest; expectedPlugins.sort(); foundPlugins.clear(); KPluginLoader::forEachPlugin(dir2.path(), addToFoundPlugins); foundPlugins.sort(); QCOMPARE(foundPlugins, expectedPlugins); // now test relative paths LibraryPathRestorer restorer(QCoreApplication::libraryPaths()); QCoreApplication::setLibraryPaths(QStringList() << temp.path()); expectedPlugins = QStringList() << jsonPluginDest << unversionedPluginDest; expectedPlugins.sort(); foundPlugins.clear(); KPluginLoader::forEachPlugin(QStringLiteral("for-each-plugin"), addToFoundPlugins); foundPlugins.sort(); QCOMPARE(foundPlugins, expectedPlugins); QCoreApplication::setLibraryPaths(QStringList() << temp2.path()); expectedPlugins = QStringList() << jsonPlugin2Dest; expectedPlugins.sort(); foundPlugins.clear(); KPluginLoader::forEachPlugin(QStringLiteral("for-each-plugin"), addToFoundPlugins); foundPlugins.sort(); QCOMPARE(foundPlugins, expectedPlugins); QCoreApplication::setLibraryPaths(QStringList() << temp.path() << temp2.path()); expectedPlugins = QStringList() << jsonPluginDest << unversionedPluginDest << jsonPlugin2Dest; expectedPlugins.sort(); foundPlugins.clear(); KPluginLoader::forEachPlugin(QStringLiteral("for-each-plugin"), addToFoundPlugins); foundPlugins.sort(); QCOMPARE(foundPlugins, expectedPlugins); } }; QTEST_MAIN(KPluginLoaderTest) #include "kpluginloadertest.moc" diff --git a/autotests/kprocesslisttest.cpp b/autotests/kprocesslisttest.cpp index 9422276..c95b639 100644 --- a/autotests/kprocesslisttest.cpp +++ b/autotests/kprocesslisttest.cpp @@ -1,95 +1,95 @@ /* * This file is part of the KDE project * Copyright (C) 2019 David Hallas * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License version 2 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "kprocesslisttest.h" #include "kprocesslist.h" #include "kuser.h" #include #include #include namespace { QString getTestExeName() { static QString testExeName = QCoreApplication::instance()->applicationFilePath().section(QLatin1Char('/'), -1); return testExeName; } } QTEST_MAIN(KProcessListTest) void KProcessListTest::testKProcessInfoConstructionAssignment() { KProcessList::KProcessInfo processInfoDefaultConstructed; QVERIFY(processInfoDefaultConstructed.isValid() == false); const qint64 pid(42); const QString name(QStringLiteral("/bin/some_exe")); const QString user(QStringLiteral("some_user")); KProcessList::KProcessInfo processInfo(pid, name, user); QVERIFY(processInfo.isValid() == true); QCOMPARE(processInfo.pid(), pid); QCOMPARE(processInfo.name(), name); QCOMPARE(processInfo.user(), user); KProcessList::KProcessInfo processInfoCopy(processInfo); QVERIFY(processInfoCopy.isValid() == true); QCOMPARE(processInfoCopy.pid(), pid); QCOMPARE(processInfoCopy.name(), name); QCOMPARE(processInfoCopy.user(), user); KProcessList::KProcessInfo processInfoAssignment; processInfoAssignment = processInfo; QVERIFY(processInfoAssignment.isValid() == true); QCOMPARE(processInfoAssignment.pid(), pid); QCOMPARE(processInfoAssignment.name(), name); QCOMPARE(processInfoAssignment.user(), user); } void KProcessListTest::testProcessInfoList() { KProcessList::KProcessInfoList processInfoList = KProcessList::processInfoList(); QVERIFY(processInfoList.empty() == false); auto testProcessIterator = std::find_if(processInfoList.begin(), processInfoList.end(), [](const KProcessList::KProcessInfo& info) { - return info.command().endsWith(QStringLiteral("/") + getTestExeName()); + return info.command().endsWith(QLatin1String("/") + getTestExeName()); }); QVERIFY(testProcessIterator != processInfoList.end()); const auto& processInfo = *testProcessIterator; QVERIFY(processInfo.isValid() == true); - QVERIFY(processInfo.command().endsWith(QStringLiteral("/") + getTestExeName())); + QVERIFY(processInfo.command().endsWith(QLatin1String("/") + getTestExeName())); QCOMPARE(processInfo.name(), getTestExeName()); QCOMPARE(processInfo.pid(), QCoreApplication::applicationPid()); QCOMPARE(processInfo.user(), KUser().loginName()); } void KProcessListTest::testProcessInfo() { const qint64 testExePid = QCoreApplication::applicationPid(); KProcessList::KProcessInfo processInfo = KProcessList::processInfo(testExePid); QVERIFY(processInfo.isValid() == true); - QVERIFY(processInfo.command().endsWith(QStringLiteral("/") + getTestExeName())); + QVERIFY(processInfo.command().endsWith(QLatin1String("/") + getTestExeName())); QCOMPARE(processInfo.pid(), testExePid); QCOMPARE(processInfo.user(), KUser().loginName()); } void KProcessListTest::testProcessInfoNotFound() { KProcessList::KProcessInfo processInfo = KProcessList::processInfo(-1); QVERIFY(processInfo.isValid() == false); } diff --git a/src/lib/text/kmacroexpander_unix.cpp b/src/lib/text/kmacroexpander_unix.cpp index e12975e..1123f3b 100644 --- a/src/lib/text/kmacroexpander_unix.cpp +++ b/src/lib/text/kmacroexpander_unix.cpp @@ -1,260 +1,260 @@ /* This file is part of the KDE libraries Copyright (c) 2002-2003 Oswald Buddenhagen Copyright (c) 2003 Waldo Bastian This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kmacroexpander_p.h" #include #include #include namespace KMacroExpander { enum Quoting { noquote, singlequote, doublequote, dollarquote, paren, subst, group, math }; typedef struct { Quoting current; bool dquote; } State; typedef struct { QString str; int pos; } Save; } using namespace KMacroExpander; #pragma message("TODO: Import these methods into Qt") inline static bool isSpecial(QChar cUnicode) { static const uchar iqm[] = { 0xff, 0xff, 0xff, 0xff, 0xdf, 0x07, 0x00, 0xd8, 0x00, 0x00, 0x00, 0x38, 0x01, 0x00, 0x00, 0x78 }; // 0-32 \'"$`<>|;&(){}*?#!~[] uint c = cUnicode.unicode(); return (c < sizeof(iqm) * 8) && (iqm[c / 8] & (1 << (c & 7))); } static QString quoteArg(const QString &arg) { if (!arg.length()) { return QStringLiteral("''"); } for (int i = 0; i < arg.length(); i++) if (isSpecial(arg.unicode()[i])) { QChar q(QLatin1Char('\'')); return q + QString(arg).replace(q, QLatin1String("'\\''")) + q; } return arg; } static QString joinArgs(const QStringList &args) { QString ret; for (QStringList::ConstIterator it = args.begin(); it != args.end(); ++it) { if (!ret.isEmpty()) { ret.append(QLatin1Char(' ')); } ret.append(quoteArg(*it)); } return ret; } bool KMacroExpanderBase::expandMacrosShellQuote(QString &str, int &pos) { int len; int pos2; ushort ec = d->escapechar.unicode(); State state = { noquote, false }; QStack sstack; QStack ostack; QStringList rst; QString rsts; while (pos < str.length()) { ushort cc = str.unicode()[pos].unicode(); if (ec != 0) { if (cc != ec) { goto nohit; } if (!(len = expandEscapedMacro(str, pos, rst))) { goto nohit; } } else { if (!(len = expandPlainMacro(str, pos, rst))) { goto nohit; } } if (len < 0) { pos -= len; continue; } if (state.dquote) { - rsts = rst.join(QLatin1String(" ")); + rsts = rst.join(QLatin1Char(' ')); rsts.replace(QRegExp(QStringLiteral("([$`\"\\\\])")), QStringLiteral("\\\\1")); } else if (state.current == dollarquote) { - rsts = rst.join(QLatin1String(" ")); + rsts = rst.join(QLatin1Char(' ')); rsts.replace(QRegExp(QStringLiteral("(['\\\\])")), QStringLiteral("\\\\1")); } else if (state.current == singlequote) { - rsts = rst.join(QLatin1String(" ")); + rsts = rst.join(QLatin1Char(' ')); rsts.replace(QLatin1Char('\''), QLatin1String("'\\''")); } else { if (rst.isEmpty()) { str.remove(pos, len); continue; } else { rsts = joinArgs(rst); } } rst.clear(); str.replace(pos, len, rsts); pos += rsts.length(); continue; nohit: if (state.current == singlequote) { if (cc == '\'') { state = sstack.pop(); } } else if (cc == '\\') { // always swallow the char -> prevent anomalies due to expansion pos += 2; continue; } else if (state.current == dollarquote) { if (cc == '\'') { state = sstack.pop(); } } else if (cc == '$') { cc = str.unicode()[++pos].unicode(); if (cc == '(') { sstack.push(state); if (str.unicode()[pos + 1].unicode() == '(') { Save sav = { str, pos + 2 }; ostack.push(sav); state.current = math; pos += 2; continue; } else { state.current = paren; state.dquote = false; } } else if (cc == '{') { sstack.push(state); state.current = subst; } else if (!state.dquote) { if (cc == '\'') { sstack.push(state); state.current = dollarquote; } else if (cc == '"') { sstack.push(state); state.current = doublequote; state.dquote = true; } } // always swallow the char -> prevent anomalies due to expansion } else if (cc == '`') { str.replace(pos, 1, QStringLiteral("$( ")); // add space -> avoid creating $(( pos2 = pos += 3; for (;;) { if (pos2 >= str.length()) { pos = pos2; return false; } cc = str.unicode()[pos2].unicode(); if (cc == '`') { break; } if (cc == '\\') { cc = str.unicode()[++pos2].unicode(); if (cc == '$' || cc == '`' || cc == '\\' || (cc == '"' && state.dquote)) { str.remove(pos2 - 1, 1); continue; } } pos2++; } str[pos2] = QLatin1Char(')'); sstack.push(state); state.current = paren; state.dquote = false; continue; } else if (state.current == doublequote) { if (cc == '"') { state = sstack.pop(); } } else if (cc == '\'') { if (!state.dquote) { sstack.push(state); state.current = singlequote; } } else if (cc == '"') { if (!state.dquote) { sstack.push(state); state.current = doublequote; state.dquote = true; } } else if (state.current == subst) { if (cc == '}') { state = sstack.pop(); } } else if (cc == ')') { if (state.current == math) { if (str.unicode()[pos + 1].unicode() == ')') { state = sstack.pop(); pos += 2; } else { // false hit: the $(( was a $( ( in fact // ash does not care, but bash does pos = ostack.top().pos; str = ostack.top().str; ostack.pop(); state.current = paren; state.dquote = false; sstack.push(state); } continue; } else if (state.current == paren) { state = sstack.pop(); } else { break; } } else if (cc == '}') { if (state.current == KMacroExpander::group) { state = sstack.pop(); } else { break; } } else if (cc == '(') { sstack.push(state); state.current = paren; } else if (cc == '{') { sstack.push(state); state.current = KMacroExpander::group; } pos++; } return sstack.empty(); } diff --git a/src/lib/text/kmacroexpander_win.cpp b/src/lib/text/kmacroexpander_win.cpp index e33a00b..5d61423 100644 --- a/src/lib/text/kmacroexpander_win.cpp +++ b/src/lib/text/kmacroexpander_win.cpp @@ -1,125 +1,125 @@ /* This file is part of the KDE libraries Copyright (c) 2008 Oswald Buddenhagen This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kmacroexpander_p.h" #include "kshell_p.h" #include "kshell.h" #include #include bool KMacroExpanderBase::expandMacrosShellQuote(QString &str, int &pos) { int len; int pos2; ushort uc; ushort ec = d->escapechar.unicode(); bool shellQuote = false; // shell is in quoted state bool crtQuote = false; // c runtime is in quoted state bool escaped = false; // previous char was a circumflex int bslashes = 0; // previous chars were backslashes int parens = 0; // parentheses nesting level QStringList rst; QString rsts; while (pos < str.length()) { ushort cc = str.unicode()[pos].unicode(); if (escaped) { // prevent anomalies due to expansion goto notcf; } if (ec != 0) { if (cc != ec) { goto nohit; } if (!(len = expandEscapedMacro(str, pos, rst))) { goto nohit; } } else { if (!(len = expandPlainMacro(str, pos, rst))) { goto nohit; } } if (len < 0) { pos -= len; continue; } if (shellQuote != crtQuote) { // Silly, isn't it? Ahoy to Redmond. return false; } if (shellQuote) { - rsts = KShell::quoteArgInternal(rst.join(QLatin1String(" ")), true); + rsts = KShell::quoteArgInternal(rst.join(QLatin1Char(' ')), true); } else { if (rst.isEmpty()) { str.remove(pos, len); continue; } rsts = KShell::joinArgs(rst); } pos2 = 0; while (pos2 < rsts.length() && ((uc = rsts.unicode()[pos2].unicode()) == '\\' || uc == '^')) { pos2++; } if (pos2 < rsts.length() && rsts.unicode()[pos2].unicode() == '"') { QString bsl; bsl.reserve(bslashes); for (; bslashes; bslashes--) { bsl.append(QLatin1String("\\")); } rsts.prepend(bsl); } bslashes = 0; rst.clear(); str.replace(pos, len, rsts); pos += rsts.length(); continue; nohit: if (!escaped && !shellQuote && cc == '^') { escaped = true; } else { notcf: if (cc == '\\') { bslashes++; } else { if (cc == '"') { if (!escaped) { shellQuote = !shellQuote; } if (!(bslashes & 1)) { crtQuote = !crtQuote; } } else if (!shellQuote) { if (cc == '(') { parens++; } else if (cc == ')') if (--parens < 0) { break; } } bslashes = 0; } escaped = false; } pos++; } return true; }