Mercurial > hg > vamp-plugin-load-checker
comparison src/plugincandidates.cpp @ 40:40c6936c2fc9 errorcode
Return numerical error codes, so the caller can apply i18n on display; distinguish explicitly the common win32 architecture problems
author | Chris Cannam |
---|---|
date | Wed, 29 Aug 2018 17:40:22 +0100 |
parents | cf18645ff411 |
children | 46e45b4a4a03 |
comparison
equal
deleted
inserted
replaced
38:a43d7a2867d2 | 40:40c6936c2fc9 |
---|---|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ | 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ |
2 /* | 2 /* |
3 Copyright (c) 2016 Queen Mary, University of London | 3 Copyright (c) 2016-2018 Queen Mary, University of London |
4 | 4 |
5 Permission is hereby granted, free of charge, to any person | 5 Permission is hereby granted, free of charge, to any person |
6 obtaining a copy of this software and associated documentation | 6 obtaining a copy of this software and associated documentation |
7 files (the "Software"), to deal in the Software without | 7 files (the "Software"), to deal in the Software without |
8 restriction, including without limitation the rights to use, copy, | 8 restriction, including without limitation the rights to use, copy, |
27 dealings in this Software without prior written authorization. | 27 dealings in this Software without prior written authorization. |
28 */ | 28 */ |
29 | 29 |
30 #include "plugincandidates.h" | 30 #include "plugincandidates.h" |
31 | 31 |
32 #include "../version.h" | |
33 | |
32 #include <set> | 34 #include <set> |
33 #include <stdexcept> | 35 #include <stdexcept> |
34 #include <iostream> | 36 #include <iostream> |
35 | 37 |
36 #include <QProcess> | 38 #include <QProcess> |
110 void | 112 void |
111 PluginCandidates::scan(string tag, | 113 PluginCandidates::scan(string tag, |
112 vector<string> pluginPath, | 114 vector<string> pluginPath, |
113 string descriptorSymbolName) | 115 string descriptorSymbolName) |
114 { | 116 { |
117 string helperVersion = getHelperCompatibilityVersion(); | |
118 if (helperVersion != CHECKER_COMPATIBILITY_VERSION) { | |
119 log("wrong plugin checker helper version found: expected v" + | |
120 string(CHECKER_COMPATIBILITY_VERSION) + ", found v" + | |
121 helperVersion); | |
122 return; | |
123 } | |
124 | |
115 vector<string> libraries = getLibrariesInPath(pluginPath); | 125 vector<string> libraries = getLibrariesInPath(pluginPath); |
116 vector<string> remaining = libraries; | 126 vector<string> remaining = libraries; |
117 | 127 |
118 int runlimit = 20; | 128 int runlimit = 20; |
119 int runcount = 0; | 129 int runcount = 0; |
139 } | 149 } |
140 | 150 |
141 recordResult(tag, result); | 151 recordResult(tag, result); |
142 } | 152 } |
143 | 153 |
144 vector<string> | 154 string |
145 PluginCandidates::runHelper(vector<string> libraries, string descriptor) | 155 PluginCandidates::getHelperCompatibilityVersion() |
146 { | 156 { |
147 vector<string> output; | |
148 | |
149 log("running helper " + m_helper + " with following library list:"); | |
150 for (auto &lib: libraries) log(lib); | |
151 | |
152 QProcess process; | 157 QProcess process; |
153 process.setReadChannel(QProcess::StandardOutput); | 158 process.setReadChannel(QProcess::StandardOutput); |
154 process.setProcessChannelMode(QProcess::ForwardedErrorChannel); | 159 process.setProcessChannelMode(QProcess::ForwardedErrorChannel); |
155 process.start(m_helper.c_str(), { descriptor.c_str() }); | 160 process.start(m_helper.c_str(), { "--version" }); |
161 | |
156 if (!process.waitForStarted()) { | 162 if (!process.waitForStarted()) { |
157 QProcess::ProcessError err = process.error(); | 163 QProcess::ProcessError err = process.error(); |
158 if (err == QProcess::FailedToStart) { | 164 if (err == QProcess::FailedToStart) { |
159 std::cerr << "Unable to start helper process " << m_helper | 165 std::cerr << "Unable to start helper process " << m_helper |
160 << std::endl; | 166 << std::endl; |
166 << " failed on startup with error code " | 172 << " failed on startup with error code " |
167 << err << std::endl; | 173 << err << std::endl; |
168 } | 174 } |
169 throw runtime_error("plugin load helper failed to start"); | 175 throw runtime_error("plugin load helper failed to start"); |
170 } | 176 } |
177 process.waitForFinished(); | |
178 | |
179 QByteArray output = process.readAllStandardOutput(); | |
180 while (output.endsWith('\n') || output.endsWith('\r')) { | |
181 output.chop(1); | |
182 } | |
183 | |
184 string versionString = output.toStdString(); | |
185 log("read version string from helper: " + versionString); | |
186 return versionString; | |
187 } | |
188 | |
189 vector<string> | |
190 PluginCandidates::runHelper(vector<string> libraries, string descriptor) | |
191 { | |
192 vector<string> output; | |
193 | |
194 log("running helper " + m_helper + " with following library list:"); | |
195 for (auto &lib: libraries) log(lib); | |
196 | |
197 QProcess process; | |
198 process.setReadChannel(QProcess::StandardOutput); | |
199 process.setProcessChannelMode(QProcess::ForwardedErrorChannel); | |
200 process.start(m_helper.c_str(), { descriptor.c_str() }); | |
201 | |
202 if (!process.waitForStarted()) { | |
203 QProcess::ProcessError err = process.error(); | |
204 if (err == QProcess::FailedToStart) { | |
205 std::cerr << "Unable to start helper process " << m_helper | |
206 << std::endl; | |
207 } else if (err == QProcess::Crashed) { | |
208 std::cerr << "Helper process " << m_helper | |
209 << " crashed on startup" << std::endl; | |
210 } else { | |
211 std::cerr << "Helper process " << m_helper | |
212 << " failed on startup with error code " | |
213 << err << std::endl; | |
214 } | |
215 throw runtime_error("plugin load helper failed to start"); | |
216 } | |
217 | |
171 for (auto &lib: libraries) { | 218 for (auto &lib: libraries) { |
172 process.write(lib.c_str(), lib.size()); | 219 process.write(lib.c_str(), lib.size()); |
173 process.write("\n", 1); | 220 process.write("\n", 1); |
174 } | 221 } |
175 | 222 |
233 } | 280 } |
234 | 281 |
235 string status = bits[0].toStdString(); | 282 string status = bits[0].toStdString(); |
236 | 283 |
237 string library = bits[1].toStdString(); | 284 string library = bits[1].toStdString(); |
238 if (bits.size() == 2) library = bits[1].trimmed().toStdString(); | 285 if (bits.size() == 2) { |
239 | 286 library = bits[1].trimmed().toStdString(); |
240 string message = ""; | 287 } |
241 if (bits.size() > 2) message = bits[2].trimmed().toStdString(); | 288 |
242 | |
243 if (status == "SUCCESS") { | 289 if (status == "SUCCESS") { |
244 m_candidates[tag].push_back(library); | 290 m_candidates[tag].push_back(library); |
245 | 291 |
246 } else if (status == "FAILURE") { | 292 } else if (status == "FAILURE") { |
247 m_failures[tag].push_back({ library, message }); | 293 |
294 QString messageAndCode = ""; | |
295 if (bits.size() > 2) { | |
296 messageAndCode = bits[2].trimmed(); | |
297 } | |
298 | |
299 PluginCheckCode code = PluginCheckCode::FAIL_OTHER; | |
300 string message = ""; | |
301 | |
302 QRegExp codeRE("^(.*) *\\[([0-9]+)\\]$"); | |
303 if (codeRE.exactMatch(messageAndCode)) { | |
304 QStringList caps(codeRE.capturedTexts()); | |
305 if (caps.length() == 3) { | |
306 message = caps[1].toStdString(); | |
307 code = PluginCheckCode(caps[2].toInt()); | |
308 log("split failure report into message and failure code " | |
309 + caps[2].toStdString()); | |
310 } else { | |
311 log("unable to split out failure code from report"); | |
312 } | |
313 } else { | |
314 log("failure message does not give a failure code"); | |
315 } | |
316 | |
317 if (message == "") { | |
318 message = messageAndCode.toStdString(); | |
319 } | |
320 | |
321 m_failures[tag].push_back({ library, code, message }); | |
248 | 322 |
249 } else { | 323 } else { |
250 log("unexpected status \"" + status + "\" in output line"); | 324 log("unexpected status \"" + status + "\" in output line"); |
251 } | 325 } |
252 } | 326 } |