diff plugin/PluginScan.cpp @ 1527:710e6250a401 zoom

Merge from default branch
author Chris Cannam
date Mon, 17 Sep 2018 13:51:14 +0100
parents d7fdc77252c6
children 830972646ccd
line wrap: on
line diff
--- a/plugin/PluginScan.cpp	Mon Dec 12 15:18:52 2016 +0000
+++ b/plugin/PluginScan.cpp	Mon Sep 17 13:51:14 2018 +0100
@@ -18,11 +18,7 @@
 #include "base/Preferences.h"
 #include "base/HelperExecPath.h"
 
-#ifdef HAVE_PLUGIN_CHECKER_HELPER
-#include "checker/knownplugins.h"
-#else
-class KnownPlugins {};
-#endif
+#include <sstream>
 
 #include <QMutex>
 #include <QCoreApplication>
@@ -57,6 +53,7 @@
     QMutexLocker locker(&m_mutex);
     clear();
     delete m_logger;
+    SVDEBUG << "PluginScan::~PluginScan completed" << endl;
 }
 
 void
@@ -72,7 +69,7 @@
                        HelperExecPath::NativeArchitectureOnly :
                        HelperExecPath::AllInstalled);
 
-    QString helperName("plugin-checker-helper");
+    QString helperName("vamp-plugin-load-checker");
     auto helpers = hep.getHelperExecutables(helperName);
 
     clear();
@@ -91,7 +88,7 @@
 
     for (auto p: helpers) {
         try {
-            KnownPlugins *kp = new KnownPlugins
+            KnownPluginCandidates *kp = new KnownPluginCandidates
                 (p.executable.toStdString(), m_logger);
             if (m_kp.find(p.tag) != m_kp.end()) {
                 SVDEBUG << "WARNING: PluginScan::scan: Duplicate tag " << p.tag
@@ -106,6 +103,7 @@
         }
     }
 
+    SVDEBUG << "PluginScan::scan complete" << endl;
 #endif
 }
 
@@ -149,7 +147,7 @@
 
     for (auto rec: m_kp) {
 
-        KnownPlugins *kp = rec.second;
+        KnownPluginCandidates *kp = rec.second;
         
         auto c = kp->getCandidateLibrariesFor(kpt);
 
@@ -180,6 +178,95 @@
 #endif
 }
 
+#ifdef HAVE_PLUGIN_CHECKER_HELPER
+QString
+PluginScan::formatFailureReport(QString tag,
+                                std::vector<PluginCandidates::FailureRec> failures) const
+{
+    int n = int(failures.size());
+    int i = 0;
+
+    std::ostringstream os;
+    
+    os << "<ul>";
+    for (auto f: failures) {
+        os << "<li>" + f.library;
+
+        SVDEBUG << "PluginScan::formatFailureReport: tag is \"" << tag
+                << "\", failure code is " << int(f.code) << ", message is \""
+                << f.message << "\"" << endl;
+        
+        QString userMessage = QString::fromStdString(f.message);
+
+        switch (f.code) {
+
+        case PluginCheckCode::FAIL_LIBRARY_NOT_FOUND:
+            userMessage = QObject::tr("Library file could not be opened");
+            break;
+
+        case PluginCheckCode::FAIL_WRONG_ARCHITECTURE:
+            if (tag == "64" || (sizeof(void *) == 8 && tag == "")) {
+                userMessage = QObject::tr
+                    ("Library has wrong architecture - possibly a 32-bit plugin installed in a 64-bit plugin folder");
+            } else if (tag == "32" || (sizeof(void *) == 4 && tag == "")) {
+                userMessage = QObject::tr
+                    ("Library has wrong architecture - possibly a 64-bit plugin installed in a 32-bit plugin folder");
+            }
+            break;
+
+        case PluginCheckCode::FAIL_DEPENDENCY_MISSING:
+            userMessage = QObject::tr
+                ("Library depends on another library that cannot be found: %1")
+                .arg(userMessage);
+            break;
+
+        case PluginCheckCode::FAIL_NOT_LOADABLE:
+            userMessage = QObject::tr
+                ("Library cannot be loaded: %1").arg(userMessage);
+            break;
+
+        case PluginCheckCode::FAIL_DESCRIPTOR_MISSING:
+            userMessage = QObject::tr
+                ("Not a valid plugin library (no descriptor found)");
+            break;
+
+        case PluginCheckCode::FAIL_NO_PLUGINS:
+            userMessage = QObject::tr
+                ("Library contains no plugins");
+            break;
+
+        case PluginCheckCode::FAIL_OTHER:
+            if (userMessage == "") {
+                userMessage = QObject::tr
+                    ("Unknown error");
+            }
+            break;
+
+        case PluginCheckCode::SUCCESS:
+            // success shouldn't happen here!
+            break;
+        }
+        
+        os << "<br><i>" + userMessage.toStdString() + "</i>";
+        os << "</li>";
+
+        if (n > 10) {
+            if (++i == 5) {
+                os << "<li>";
+                os << QObject::tr("... and %n further failure(s)",
+                                  "", n - i)
+                    .toStdString();
+                os << "</li>";
+                break;
+            }
+        }
+    }
+    os << "</ul>";
+
+    return QString::fromStdString(os.str());
+}
+#endif
+
 QString
 PluginScan::getStartupFailureReport() const
 {
@@ -188,29 +275,32 @@
     QMutexLocker locker(&m_mutex);
 
     if (!m_succeeded) {
-	return QObject::tr("<b>Failed to scan for plugins</b>"
-			   "<p>Failed to scan for plugins at startup. Possibly "
-                           "the plugin checker helper program was not correctly "
+        return QObject::tr("<b>Failed to scan for plugins</b>"
+                           "<p>Failed to scan for plugins at startup. Possibly "
+                           "the plugin checker program was not correctly "
                            "installed alongside %1?</p>")
             .arg(QCoreApplication::applicationName());
     }
     if (m_kp.empty()) {
-	return QObject::tr("<b>Did not scan for plugins</b>"
-			   "<p>Apparently no scan for plugins was attempted "
-			   "(internal error?)</p>");
+        return QObject::tr("<b>Did not scan for plugins</b>"
+                           "<p>Apparently no scan for plugins was attempted "
+                           "(internal error?)</p>");
     }
 
     QString report;
     for (auto kp: m_kp) {
-        report += QString::fromStdString(kp.second->getFailureReport());
+        auto failures = kp.second->getFailures();
+        if (!failures.empty()) {
+            report += formatFailureReport(kp.first, failures);
+        }
     }
     if (report == "") {
-	return report;
+        return report;
     }
 
     return QObject::tr("<b>Failed to load plugins</b>"
-		       "<p>Failed to load one or more plugin libraries:</p>")
-	+ report
+                       "<p>Failed to load one or more plugin libraries:</p>")
+        + report
         + QObject::tr("<p>These plugins may be incompatible with the system, "
                       "and will be ignored during this run of %1.</p>")
         .arg(QCoreApplication::applicationName());