Mercurial > hg > vamp-plugin-load-checker
comparison plugincandidates.cpp @ 2:2288c1d05c28
Simple Qt-based class to invoke the helper
author | Chris Cannam |
---|---|
date | Tue, 12 Apr 2016 17:38:57 +0100 |
parents | |
children | 3bae396cf8e0 |
comparison
equal
deleted
inserted
replaced
1:fbffc249990c | 2:2288c1d05c28 |
---|---|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ | |
2 | |
3 #include "plugincandidates.h" | |
4 | |
5 #include <set> | |
6 #include <stdexcept> | |
7 #include <iostream> | |
8 | |
9 #include <QProcess> | |
10 #include <QDir> | |
11 | |
12 #ifdef _WIN32 | |
13 #define PLUGIN_GLOB "*.dll" | |
14 #define PATH_SEPARATOR ';' | |
15 #else | |
16 #define PATH_SEPARATOR ':' | |
17 #ifdef __APPLE__ | |
18 #define PLUGIN_GLOB "*.dylib *.so" | |
19 #else | |
20 #define PLUGIN_GLOB "*.so" | |
21 #endif | |
22 #endif | |
23 | |
24 using namespace std; | |
25 | |
26 PluginCandidates::PluginCandidates(string helperExecutableName) : | |
27 m_helper(helperExecutableName) | |
28 { | |
29 } | |
30 | |
31 vector<string> | |
32 PluginCandidates::getCandidateLibrariesFor(string tag) | |
33 { | |
34 return m_candidates[tag]; | |
35 } | |
36 | |
37 vector<PluginCandidates::FailureRec> | |
38 PluginCandidates::getFailedLibrariesFor(string tag) | |
39 { | |
40 return m_failures[tag]; | |
41 } | |
42 | |
43 vector<string> | |
44 PluginCandidates::getLibrariesInPath(vector<string> path) | |
45 { | |
46 vector<string> candidates; | |
47 | |
48 for (string dirname: path) { | |
49 | |
50 //#ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE | |
51 cerr << "getLibrariesInPath: scanning directory " << dirname << endl; | |
52 //#endif | |
53 | |
54 QDir dir(dirname.c_str(), PLUGIN_GLOB, | |
55 QDir::Name | QDir::IgnoreCase, | |
56 QDir::Files | QDir::Readable); | |
57 | |
58 for (unsigned int i = 0; i < dir.count(); ++i) { | |
59 QString soname = dir.filePath(dir[i]); | |
60 candidates.push_back(soname.toStdString()); | |
61 } | |
62 } | |
63 | |
64 return candidates; | |
65 } | |
66 | |
67 void | |
68 PluginCandidates::scan(string tag, | |
69 vector<string> pluginPath, | |
70 string descriptorFunctionName) | |
71 { | |
72 vector<string> libraries = getLibrariesInPath(pluginPath); | |
73 vector<string> remaining = libraries; | |
74 | |
75 int runlimit = 20; | |
76 int runcount = 0; | |
77 | |
78 vector<string> result; | |
79 | |
80 while (result.size() < libraries.size() && runcount < runlimit) { | |
81 vector<string> output = runHelper(remaining, descriptorFunctionName); | |
82 result.insert(result.end(), output.begin(), output.end()); | |
83 int shortfall = int(remaining.size()) - int(output.size()); | |
84 if (shortfall > 0) { | |
85 // Helper bailed out for some reason presumably associated | |
86 // with the plugin following the last one it reported | |
87 // on. Add a null entry for that one and continue with the | |
88 // following ones. | |
89 result.push_back(""); | |
90 if (shortfall == 1) { | |
91 remaining = vector<string>(); | |
92 } else { | |
93 remaining = vector<string> | |
94 (remaining.rbegin(), remaining.rbegin() + shortfall - 1); | |
95 } | |
96 } | |
97 ++runcount; | |
98 } | |
99 | |
100 recordResult(tag, result); | |
101 } | |
102 | |
103 vector<string> | |
104 PluginCandidates::runHelper(vector<string> libraries, string descriptor) | |
105 { | |
106 vector<string> output; | |
107 cerr << "running helper with following library list:" << endl; | |
108 for (auto &lib: libraries) cerr << lib << endl; | |
109 | |
110 QProcess process; | |
111 process.setReadChannel(QProcess::StandardOutput); | |
112 process.start(m_helper.c_str(), { descriptor.c_str() }); | |
113 if (!process.waitForStarted()) { | |
114 cerr << "helper failed to start" << endl; | |
115 throw runtime_error("plugin load helper failed to start"); | |
116 } | |
117 for (auto &lib: libraries) { | |
118 process.write(lib.c_str(), lib.size()); | |
119 process.write("\n", 1); | |
120 } | |
121 | |
122 int buflen = 4096; | |
123 while (process.waitForReadyRead()) { | |
124 char buf[buflen]; | |
125 qint64 linelen = process.readLine(buf, buflen); | |
126 // cerr << "read line: " << buf; | |
127 if (linelen < 0) { | |
128 cerr << "read failed from plugin load helper" << endl; | |
129 return output; | |
130 } | |
131 output.push_back(buf); | |
132 if (output.size() == libraries.size()) { | |
133 process.close(); | |
134 process.waitForFinished(); | |
135 break; | |
136 } | |
137 } | |
138 | |
139 return output; | |
140 } | |
141 | |
142 void | |
143 PluginCandidates::recordResult(string tag, vector<string> result) | |
144 { | |
145 cerr << "recordResult: not yet implemented, but result was:" << endl; | |
146 for (auto &r: result) cerr << r; | |
147 cerr << "(ends)" << endl; | |
148 } | |
149 | |
150 int main(int argc, char **argv) | |
151 { | |
152 //!!! just a test | |
153 PluginCandidates candidates("./helper"); | |
154 candidates.scan("vamp", | |
155 { "/usr/lib/vamp", "/usr/local/lib/vamp" }, | |
156 "vampGetPluginDescriptor"); | |
157 } | |
158 |