Mercurial > hg > vamp-plugin-load-checker
view plugincandidates.cpp @ 3:3bae396cf8e0
Start to organise as a Qt project, with a main (command-line) executable
author | Chris Cannam |
---|---|
date | Wed, 13 Apr 2016 09:12:04 +0100 |
parents | 2288c1d05c28 |
children | 6f891a9c6434 |
line wrap: on
line source
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ #include "plugincandidates.h" #include <set> #include <stdexcept> #include <iostream> #include <QProcess> #include <QDir> #ifdef _WIN32 #define PLUGIN_GLOB "*.dll" #define PATH_SEPARATOR ';' #else #define PATH_SEPARATOR ':' #ifdef __APPLE__ #define PLUGIN_GLOB "*.dylib *.so" #else #define PLUGIN_GLOB "*.so" #endif #endif using namespace std; PluginCandidates::PluginCandidates(string helperExecutableName) : m_helper(helperExecutableName) { } vector<string> PluginCandidates::getCandidateLibrariesFor(string tag) { return m_candidates[tag]; } vector<PluginCandidates::FailureRec> PluginCandidates::getFailedLibrariesFor(string tag) { return m_failures[tag]; } vector<string> PluginCandidates::getLibrariesInPath(vector<string> path) { vector<string> candidates; for (string dirname: path) { //#ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE cerr << "getLibrariesInPath: scanning directory " << dirname << endl; //#endif QDir dir(dirname.c_str(), PLUGIN_GLOB, QDir::Name | QDir::IgnoreCase, QDir::Files | QDir::Readable); for (unsigned int i = 0; i < dir.count(); ++i) { QString soname = dir.filePath(dir[i]); candidates.push_back(soname.toStdString()); } } return candidates; } void PluginCandidates::scan(string tag, vector<string> pluginPath, string descriptorFunctionName) { vector<string> libraries = getLibrariesInPath(pluginPath); vector<string> remaining = libraries; int runlimit = 20; int runcount = 0; vector<string> result; while (result.size() < libraries.size() && runcount < runlimit) { vector<string> output = runHelper(remaining, descriptorFunctionName); result.insert(result.end(), output.begin(), output.end()); int shortfall = int(remaining.size()) - int(output.size()); if (shortfall > 0) { // Helper bailed out for some reason presumably associated // with the plugin following the last one it reported // on. Add a null entry for that one and continue with the // following ones. result.push_back(""); if (shortfall == 1) { remaining = vector<string>(); } else { remaining = vector<string> (remaining.rbegin(), remaining.rbegin() + shortfall - 1); } } ++runcount; } recordResult(tag, result); } vector<string> PluginCandidates::runHelper(vector<string> libraries, string descriptor) { vector<string> output; cerr << "running helper with following library list:" << endl; for (auto &lib: libraries) cerr << lib << endl; QProcess process; process.setReadChannel(QProcess::StandardOutput); process.start(m_helper.c_str(), { descriptor.c_str() }); if (!process.waitForStarted()) { cerr << "helper failed to start" << endl; throw runtime_error("plugin load helper failed to start"); } for (auto &lib: libraries) { process.write(lib.c_str(), lib.size()); process.write("\n", 1); } int buflen = 4096; while (process.waitForReadyRead()) { char buf[buflen]; qint64 linelen = process.readLine(buf, buflen); // cerr << "read line: " << buf; if (linelen < 0) { cerr << "read failed from plugin load helper" << endl; return output; } output.push_back(buf); if (output.size() == libraries.size()) { process.close(); process.waitForFinished(); break; } } return output; } void PluginCandidates::recordResult(string tag, vector<string> result) { cerr << "recordResult: not yet implemented, but result was:" << endl; for (auto &r: result) cerr << r; cerr << "(ends)" << endl; }