cannam@138
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
cannam@138
|
2
|
cannam@138
|
3 #include "vamp-sdk/PluginHostAdapter.h"
|
cannam@138
|
4 #include "vamp-sdk/hostext/PluginChannelAdapter.h"
|
cannam@138
|
5 #include "vamp-sdk/hostext/PluginInputDomainAdapter.h"
|
cannam@138
|
6 #include "vamp-sdk/hostext/PluginLoader.h"
|
cannam@138
|
7 #include "vamp/vamp.h"
|
cannam@138
|
8
|
cannam@138
|
9 #include <iostream>
|
cannam@138
|
10 #include <fstream>
|
cannam@138
|
11 #include <sstream>
|
cannam@138
|
12 #include <sndfile.h>
|
cannam@138
|
13
|
cannam@138
|
14 #include <cmath>
|
cannam@138
|
15
|
cannam@138
|
16 using std::cout;
|
cannam@138
|
17 using std::cin;
|
cannam@138
|
18 using std::cerr;
|
cannam@138
|
19 using std::getline;
|
cannam@138
|
20 using std::endl;
|
cannam@138
|
21 using std::string;
|
cannam@138
|
22 using std::vector;
|
cannam@138
|
23 using std::ofstream;
|
cannam@138
|
24 using std::ios;
|
cannam@138
|
25
|
cannam@138
|
26 using Vamp::HostExt::PluginLoader;
|
cannam@138
|
27 using Vamp::Plugin;
|
cannam@138
|
28
|
cannam@138
|
29 string programURI = "http://www.vamp-plugins.org/doap.rdf#template-generator";
|
cannam@138
|
30
|
cannam@138
|
31 void usage()
|
cannam@138
|
32 {
|
cannam@144
|
33 cerr << "usage: template-generator -i vamp:soname[:plugin] [vamp:soname[:plugin] ...]" << endl;
|
cannam@144
|
34 cerr << "usage: template-generator PLUGIN_BASE_URI YOUR_URI vamp:soname[:plugin] [vamp:soname[:plugin] ...]" << endl;
|
cannam@138
|
35 exit(2);
|
cannam@138
|
36 }
|
cannam@138
|
37
|
cannam@138
|
38 template <class T>
|
cannam@138
|
39 inline string to_string (const T& t)
|
cannam@138
|
40 {
|
cannam@138
|
41 std::stringstream ss;
|
cannam@138
|
42 ss << t;
|
cannam@138
|
43 return ss.str();
|
cannam@138
|
44 }
|
cannam@138
|
45
|
cannam@144
|
46 string describe_namespaces(string pluginBundleBaseURI, string libname)
|
cannam@138
|
47 {
|
cannam@142
|
48 string res=\
|
cannam@142
|
49 "@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .\n\
|
cannam@138
|
50 @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .\n\
|
cannam@147
|
51 @prefix vamp: <http://purl.org/ontology/vamp/> .\n\
|
cannam@144
|
52 @prefix plugbase: <"+pluginBundleBaseURI+libname+"#> .\n\
|
cannam@138
|
53 @prefix owl: <http://www.w3.org/2002/07/owl#> .\n\
|
cannam@138
|
54 @prefix dc: <http://purl.org/dc/elements/1.1/> .\n\
|
cannam@138
|
55 @prefix af: <http://purl.org/ontology/af/> .\n\
|
cannam@138
|
56 @prefix foaf: <http://xmlns.com/foaf/0.1/> .\n\
|
cannam@138
|
57 @prefix cc: <http://web.resource.org/cc/> .\n\
|
cannam@138
|
58 @prefix : <> .\n\n";
|
cannam@138
|
59
|
cannam@142
|
60 return res;
|
cannam@138
|
61 }
|
cannam@138
|
62
|
cannam@144
|
63 string describe_doc(string describerURI, string pluginBundleBaseURI,
|
cannam@144
|
64 string libname)
|
cannam@138
|
65 {
|
cannam@142
|
66 string res=\
|
cannam@142
|
67 "<> a vamp:PluginDescription ;\n\
|
cannam@144
|
68 foaf:maker <"+describerURI+"> ;\n\
|
cannam@144
|
69 foaf:maker <"+programURI+"> ;\n\
|
cannam@144
|
70 foaf:primaryTopic <"+pluginBundleBaseURI+libname+"> .\n\n";
|
cannam@142
|
71 return res;
|
cannam@138
|
72 }
|
cannam@138
|
73
|
cannam@138
|
74
|
cannam@144
|
75 string describe_library(string libname, vector<Plugin *> plugins)
|
cannam@144
|
76 {
|
cannam@144
|
77 string res=\
|
cannam@144
|
78 ":"+libname+" a vamp:PluginLibrary ;\n\
|
cannam@144
|
79 vamp:identifier \""+libname+"\" ";
|
cannam@144
|
80
|
cannam@144
|
81 for (size_t i = 0; i < plugins.size(); ++i) {
|
cannam@144
|
82 res += "; \n\
|
cannam@145
|
83 vamp:available_plugin plugbase:"+plugins[i]->getIdentifier();
|
cannam@144
|
84 }
|
cannam@144
|
85
|
cannam@144
|
86 res += " .\n\n";
|
cannam@144
|
87 return res;
|
cannam@144
|
88 }
|
cannam@144
|
89
|
cannam@138
|
90 string describe_plugin(Plugin* plugin)
|
cannam@138
|
91 {
|
cannam@142
|
92 string res=\
|
cannam@142
|
93 "plugbase:"+plugin->getIdentifier()+" a vamp:Plugin ;\n\
|
cannam@138
|
94 dc:title \""+plugin->getName()+"\" ;\n\
|
cannam@139
|
95 vamp:name \""+plugin->getName()+"\" ;\n\
|
cannam@138
|
96 dc:description \""+plugin->getDescription()+"\" ;\n\
|
cannam@138
|
97 foaf:maker [ foaf:name \""+plugin->getMaker()+"\"] ; # FIXME could give plugin author's URI here\n\
|
cannam@138
|
98 cc:license <FIXME license for the plugin> ; \n\
|
cannam@138
|
99 vamp:identifier \""+plugin->getIdentifier()+"\" ;\n\
|
cannam@138
|
100 vamp:vamp_API_version vamp:api_version_"+to_string(plugin->getVampApiVersion())+" ;\n\
|
cannam@138
|
101 owl:versionInfo \""+to_string(plugin->getPluginVersion())+"\" ;\n";
|
cannam@142
|
102 if (plugin->getInputDomain() == Vamp::Plugin::FrequencyDomain)
|
cannam@142
|
103 res+=" vamp:input_domain vamp:FrequencyDomain ;\n\n";
|
cannam@142
|
104 else
|
cannam@142
|
105 res+=" vamp:input_domain vamp:TimeDomain ;\n\n";
|
cannam@138
|
106
|
cannam@138
|
107
|
cannam@142
|
108 Plugin::ParameterList params = plugin->getParameterDescriptors();
|
cannam@142
|
109 for (Plugin::ParameterList::const_iterator i = params.begin(); i != params.end(); i++)
|
cannam@144
|
110 res+=" vamp:parameter_descriptor plugbase:"+plugin->getIdentifier()+"_param_"+(*i).identifier+" ;\n";
|
cannam@142
|
111 res+="\n";
|
cannam@138
|
112
|
cannam@142
|
113 Plugin::OutputList outputs = plugin->getOutputDescriptors();
|
cannam@142
|
114 for (Plugin::OutputList::const_iterator i = outputs.begin(); i!= outputs.end(); i++)
|
cannam@144
|
115 res+=" vamp:output_descriptor plugbase:"+plugin->getIdentifier()+"_output_"+(*i).identifier+" ;\n";
|
cannam@142
|
116 res+=" .\n";
|
cannam@138
|
117
|
cannam@142
|
118 return res;
|
cannam@138
|
119 }
|
cannam@138
|
120
|
cannam@144
|
121 string describe_param(Plugin *plugin, Plugin::ParameterDescriptor p)
|
cannam@138
|
122 {
|
cannam@148
|
123
|
cannam@148
|
124 //FIXME: dc:format and vamp:unit are the same???
|
cannam@148
|
125 if(p.isQuantized){
|
cannam@148
|
126 string res=\
|
cannam@148
|
127 "plugbase:"+plugin->getIdentifier()+"_param_"+p.identifier+" a vamp:QuantizedParameterDescriptor ;\n\
|
cannam@148
|
128 vamp:identifier \""+p.identifier+"\" ;\n\
|
cannam@148
|
129 dc:title \""+p.name+"\" ;\n\
|
cannam@148
|
130 dc:format \""+p.unit+"\" ;\n\
|
cannam@148
|
131 vamp:min_value "+to_string(p.minValue)+" ;\n\
|
cannam@148
|
132 vamp:max_value "+to_string(p.maxValue)+" ;\n\
|
cannam@148
|
133 vamp:unit \""+p.unit+"\" ;\n\
|
cannam@148
|
134 vamo:quantize_step "+to_string(p.quantizeStep)+" ;\n\
|
cannam@148
|
135 vamp:default_value "+to_string(p.defaultValue)+" ;\n\
|
cannam@148
|
136 vamp:value_names (";
|
cannam@148
|
137
|
cannam@148
|
138 unsigned int i;
|
cannam@148
|
139 for (i=0; i+1 < p.valueNames.size(); i++)
|
cannam@148
|
140 res+=" \""+p.valueNames[i]+"\"";
|
cannam@148
|
141 if (i < p.valueNames.size())
|
cannam@148
|
142 res+=" \""+p.valueNames[i]+"\"";
|
cannam@148
|
143 res+=");\n";
|
cannam@148
|
144
|
cannam@148
|
145 res+=" .\n";
|
cannam@148
|
146
|
cannam@148
|
147 return res;
|
cannam@148
|
148
|
cannam@148
|
149 }else{
|
cannam@142
|
150 string res=\
|
cannam@144
|
151 "plugbase:"+plugin->getIdentifier()+"_param_"+p.identifier+" a vamp:ParameterDescriptor ;\n\
|
cannam@138
|
152 vamp:identifier \""+p.identifier+"\" ;\n\
|
cannam@138
|
153 dc:title \""+p.name+"\" ;\n\
|
cannam@138
|
154 dc:format \""+p.unit+"\" ;\n\
|
cannam@139
|
155 vamp:min_value "+to_string(p.minValue)+" ;\n\
|
cannam@139
|
156 vamp:max_value "+to_string(p.maxValue)+" ;\n\
|
cannam@148
|
157 vamp:unit \""+p.unit+"\" ;\n\
|
cannam@148
|
158 vamp:default_value "+to_string(p.defaultValue)+" ;\n\
|
cannam@148
|
159 vamp:value_names (";
|
cannam@148
|
160
|
cannam@148
|
161 unsigned int i;
|
cannam@148
|
162 for (i=0; i+1 < p.valueNames.size(); i++)
|
cannam@148
|
163 res+=" \""+p.valueNames[i]+"\"";
|
cannam@148
|
164 if (i < p.valueNames.size())
|
cannam@148
|
165 res+=" \""+p.valueNames[i]+"\"";
|
cannam@148
|
166 res+=");\n";
|
cannam@148
|
167
|
cannam@148
|
168 res+=" .\n";
|
cannam@148
|
169
|
cannam@142
|
170 return res;
|
cannam@148
|
171
|
cannam@148
|
172 }
|
cannam@138
|
173 }
|
cannam@138
|
174
|
cannam@144
|
175 string describe_output(Plugin *plugin, Plugin::OutputDescriptor o)
|
cannam@138
|
176 {
|
cannam@138
|
177
|
cannam@142
|
178 //we need to distinguish here between different output types:
|
cannam@148
|
179
|
cannam@148
|
180 //Quantize or not
|
cannam@148
|
181 //KnownExtents or not
|
cannam@148
|
182 //Data output classification:
|
cannam@142
|
183 //DenseOutput
|
cannam@142
|
184 //SparseOutput
|
cannam@142
|
185 //TrackLevelOutput
|
cannam@139
|
186
|
cannam@139
|
187
|
cannam@142
|
188 //SparseOutput: variable sample rate. Events are not evenly spaced so we need to record the time associated with the event as it its not ensured that we have an event after the next one (but there is not time to set the duration, it has to be calculated as the different between 2 different events). The timestamp must be read.
|
cannam@139
|
189
|
cannam@142
|
190 string res;
|
cannam@139
|
191
|
cannam@142
|
192 if (o.sampleType == Plugin::OutputDescriptor::VariableSampleRate)
|
cannam@142
|
193 {
|
cannam@139
|
194
|
cannam@142
|
195 res=\
|
cannam@144
|
196 "plugbase:"+plugin->getIdentifier()+"_output_"+o.identifier+" a vamp:SparseOutput ;\n\
|
cannam@139
|
197 vamp:identifier \""+o.identifier+"\" ;\n\
|
cannam@139
|
198 dc:title \""+o.name+"\" ;\n\
|
cannam@139
|
199 dc:description \""+o.description+"\" ;\n\
|
cannam@139
|
200 vamp:fixed_bin_count \""+(o.hasFixedBinCount == 1 ? "true" : "false")+"\" ;\n\
|
cannam@139
|
201 vamp:unit \""+(o.unit)+"\" ;\n";
|
cannam@139
|
202
|
cannam@148
|
203
|
cannam@148
|
204 //another type of output
|
cannam@148
|
205 if(o.isQuantized){
|
cannam@148
|
206
|
cannam@148
|
207 res+=" a vamp:QuantizedOutput ;\n";
|
cannam@148
|
208 res+=" vamp:quantize_step "+to_string(o.quantizeStep)+" ;\n";
|
cannam@148
|
209 }
|
cannam@148
|
210
|
cannam@148
|
211 //and yet another type
|
cannam@148
|
212 if(o.hasKnownExtents){
|
cannam@148
|
213
|
cannam@148
|
214 res+=" a vamp:KnownExtentsOutput ;\n";
|
cannam@148
|
215 res+=" vamp:min_value "+to_string(o.minValue)+" ;\n";
|
cannam@148
|
216 res+=" vamp:max_value "+to_string(o.maxValue)+" ;\n";
|
cannam@148
|
217 }
|
cannam@139
|
218
|
cannam@142
|
219 // FIXME ? Bin names may vary based on plugin setup, so including them here might be misleading...
|
cannam@142
|
220 if (o.hasFixedBinCount)
|
cannam@142
|
221 {
|
cannam@144
|
222 res+=" vamp:bin_count "+to_string(o.binCount)+" ;\n";
|
cannam@144
|
223 res+=" vamp:bin_names (";
|
cannam@138
|
224
|
cannam@142
|
225 unsigned int i;
|
cannam@142
|
226 for (i=0; i+1 < o.binNames.size(); i++)
|
cannam@142
|
227 res+=" \""+o.binNames[i]+"\"";
|
cannam@142
|
228 if (i < o.binNames.size())
|
cannam@142
|
229 res+=" \""+o.binNames[i]+"\"";
|
cannam@142
|
230 res+=");\n";
|
cannam@142
|
231 }
|
cannam@148
|
232
|
cannam@144
|
233 res+=" vamp:sample_type vamp:VariableSampleRate ;\n";
|
cannam@142
|
234 if (o.sampleRate > 0.0f)
|
cannam@144
|
235 res+=" vamp:sample_rate "+to_string(o.sampleRate)+" ;\n";
|
cannam@142
|
236
|
cannam@142
|
237 }
|
cannam@139
|
238
|
cannam@142
|
239 //If we do not have SparseOutput, then we have DenseOutput. TrackLevelOutput can not be inferred from the plugin directly without actually
|
cannam@142
|
240 //running the plugin.
|
cannam@142
|
241 else{
|
cannam@142
|
242
|
cannam@142
|
243 res=\
|
cannam@144
|
244 "plugbase:"+plugin->getIdentifier()+"_output_"+o.identifier+" a vamp:DenseOutput ;\n\
|
cannam@139
|
245 vamp:identifier \""+o.identifier+"\" ;\n\
|
cannam@139
|
246 dc:title \""+o.name+"\" ;\n\
|
cannam@139
|
247 dc:description \""+o.description+"\" ;\n\
|
cannam@139
|
248 vamp:fixed_bin_count \""+(o.hasFixedBinCount == 1 ? "true" : "false")+"\" ;\n\
|
cannam@139
|
249 vamp:unit \""+(o.unit)+"\" ;\n";
|
cannam@139
|
250
|
cannam@139
|
251
|
cannam@148
|
252 //another type of output
|
cannam@148
|
253 if(o.isQuantized){
|
cannam@148
|
254
|
cannam@148
|
255 res+=" a vamp:QuantizedOutput ;\n";
|
cannam@148
|
256 res+=" vamp:quantize_step "+to_string(o.quantizeStep)+" ;\n";
|
cannam@148
|
257 }
|
cannam@148
|
258
|
cannam@148
|
259 //and yet another type
|
cannam@148
|
260 if(o.hasKnownExtents){
|
cannam@148
|
261
|
cannam@148
|
262 res+=" a vamp:KnownExtentsOutput ;\n";
|
cannam@148
|
263 res+=" vamp:min_value "+to_string(o.minValue)+" ;\n";
|
cannam@148
|
264 res+=" vamp:max_value "+to_string(o.maxValue)+" ;\n";
|
cannam@148
|
265 }
|
cannam@139
|
266
|
cannam@142
|
267 // FIXME ? Bin names may vary based on plugin setup, so including them here might be misleading...
|
cannam@142
|
268 if (o.hasFixedBinCount)
|
cannam@142
|
269 {
|
cannam@144
|
270 res+=" vamp:bin_count "+to_string(o.binCount)+" ;\n";
|
cannam@144
|
271 res+=" vamp:bin_names (";
|
cannam@139
|
272
|
cannam@142
|
273 unsigned int i;
|
cannam@142
|
274 for (i=0; i+1 < o.binNames.size(); i++)
|
cannam@142
|
275 res+=" \""+o.binNames[i]+"\"";
|
cannam@142
|
276 if (i < o.binNames.size())
|
cannam@142
|
277 res+=" \""+o.binNames[i]+"\"";
|
cannam@142
|
278 res+=");\n";
|
cannam@139
|
279 }
|
cannam@139
|
280
|
cannam@142
|
281 else if (o.sampleType == Plugin::OutputDescriptor::FixedSampleRate)
|
cannam@142
|
282 {
|
cannam@144
|
283 res+=" vamp:sample_type vamp:FixedSampleRate ;\n";
|
cannam@144
|
284 res+=" vamp:sample_rate "+to_string(o.sampleRate)+" ;\n";
|
cannam@142
|
285 }
|
cannam@142
|
286 else if (o.sampleType == Plugin::OutputDescriptor::OneSamplePerStep)
|
cannam@144
|
287 res+=" vamp:sample_type vamp:OneSamplePerStep ;\n";
|
cannam@142
|
288 else
|
cannam@142
|
289 {
|
cannam@142
|
290 cerr<<"Incomprehensible sampleType for output descriptor "+o.identifier<<" !"<<endl;
|
cannam@142
|
291 exit(1);
|
cannam@142
|
292 }
|
cannam@142
|
293 }
|
cannam@142
|
294
|
cannam@142
|
295 //There is no way to know this in advance, but we can use the km a bit for this.
|
cannam@142
|
296 res+=" vamp:computes_feature_type <FIXME feature type URI> ;\n";
|
cannam@142
|
297 res+=" vamp:computes_event_type <FIXME event type URI> ;\n";
|
cannam@142
|
298 res+=" .\n";
|
cannam@142
|
299
|
cannam@142
|
300 return res;
|
cannam@138
|
301 }
|
cannam@139
|
302
|
cannam@144
|
303 string describe(vector<Plugin *> plugins, string pluginBundleBaseURI,
|
cannam@144
|
304 string describerURI, string libname)
|
cannam@138
|
305 {
|
cannam@144
|
306 string res = describe_namespaces(pluginBundleBaseURI, libname);
|
cannam@138
|
307
|
cannam@144
|
308 res += describe_doc(describerURI, pluginBundleBaseURI, libname);
|
cannam@138
|
309
|
cannam@144
|
310 res += describe_library(libname, plugins);
|
cannam@144
|
311
|
cannam@144
|
312 for (size_t i = 0; i < plugins.size(); ++i) {
|
cannam@144
|
313
|
cannam@144
|
314 Plugin *plugin = plugins[i];
|
cannam@144
|
315
|
cannam@144
|
316 res += describe_plugin(plugin);
|
cannam@138
|
317
|
cannam@144
|
318 Plugin::ParameterList params = plugin->getParameterDescriptors();
|
cannam@144
|
319 for (Plugin::ParameterList::const_iterator i = params.begin(); i != params.end(); i++)
|
cannam@144
|
320 res += describe_param(plugin, *i);
|
cannam@138
|
321
|
cannam@144
|
322 Plugin::OutputList outputs = plugin->getOutputDescriptors();
|
cannam@144
|
323 for (Plugin::OutputList::const_iterator i = outputs.begin(); i!= outputs.end(); i++)
|
cannam@144
|
324 res += describe_output(plugin, *i);
|
cannam@144
|
325 }
|
cannam@138
|
326
|
cannam@142
|
327 return res;
|
cannam@138
|
328 }
|
cannam@138
|
329
|
cannam@138
|
330 int main(int argc, char **argv)
|
cannam@138
|
331 {
|
cannam@144
|
332 if (argc < 3) usage();
|
cannam@138
|
333
|
cannam@144
|
334 bool interactive = false;
|
cannam@144
|
335 if (!strcmp(argv[1], "-i")) interactive = true;
|
cannam@138
|
336
|
cannam@144
|
337 if (!interactive && argc < 4) usage();
|
cannam@138
|
338
|
cannam@138
|
339 string pluginBundleBaseURI, describerURI;
|
cannam@144
|
340
|
cannam@144
|
341 int argidx = 2;
|
cannam@138
|
342
|
cannam@144
|
343 if (!interactive) {
|
cannam@138
|
344 pluginBundleBaseURI = argv[1];
|
cannam@138
|
345 describerURI = argv[2];
|
cannam@144
|
346 argidx = 3;
|
cannam@144
|
347 } else {
|
cannam@138
|
348 cerr << "Please enter the base URI for the plugin bundle : ";
|
cannam@138
|
349 getline(cin, pluginBundleBaseURI);
|
cannam@138
|
350 cerr << "Please enter your URI : ";
|
cannam@138
|
351 getline(cin, describerURI);
|
cannam@138
|
352 }
|
cannam@144
|
353
|
cannam@144
|
354 vector<Plugin *> plugins;
|
cannam@144
|
355 string libname;
|
cannam@144
|
356
|
cannam@144
|
357 PluginLoader *loader = PluginLoader::getInstance();
|
cannam@144
|
358
|
cannam@144
|
359 while (argidx < argc) {
|
cannam@144
|
360
|
cannam@144
|
361 string pluginName = argv[argidx];
|
cannam@144
|
362
|
cannam@144
|
363 if (pluginName.substr(0, 5) == "vamp:") {
|
cannam@144
|
364 pluginName = pluginName.substr(5);
|
cannam@144
|
365 }
|
cannam@144
|
366
|
cannam@144
|
367 string mylibname = pluginName.substr(0, pluginName.find(':'));
|
cannam@144
|
368
|
cannam@144
|
369 if (libname == "") libname = mylibname;
|
cannam@144
|
370 else if (libname != mylibname) {
|
cannam@144
|
371 cerr << "ERROR: All plugins specified on command line must originate in the same library" << endl;
|
cannam@144
|
372 exit(1);
|
cannam@144
|
373 }
|
cannam@144
|
374
|
cannam@144
|
375 if (mylibname == pluginName) { // pluginName is a library, not a plugin
|
cannam@144
|
376
|
cannam@144
|
377 PluginLoader::PluginKeyList list = loader->listPlugins();
|
cannam@144
|
378 for (size_t i = 0; i < list.size(); ++i) {
|
cannam@144
|
379 string thislibname = list[i].substr(0, list[i].find(':'));
|
cannam@144
|
380 if (thislibname != mylibname) continue;
|
cannam@144
|
381 Plugin *plugin = loader->loadPlugin(list[i], 44100);
|
cannam@144
|
382 if (!plugin) {
|
cannam@144
|
383 cerr << "ERROR: Plugin \"" << list[i] << "\" could not be loaded" << endl;
|
cannam@144
|
384 exit(1);
|
cannam@144
|
385 }
|
cannam@144
|
386 plugins.push_back(plugin);
|
cannam@144
|
387 }
|
cannam@144
|
388 } else { // pluginName is a plugin
|
cannam@144
|
389
|
cannam@144
|
390 Plugin *plugin = loader->loadPlugin(pluginName, size_t(44100));
|
cannam@144
|
391 if (!plugin) {
|
cannam@144
|
392 cerr << "ERROR: Plugin \"" << pluginName << "\" could not be loaded" << endl;
|
cannam@144
|
393 exit(1);
|
cannam@144
|
394 }
|
cannam@144
|
395 plugins.push_back(plugin);
|
cannam@144
|
396 }
|
cannam@144
|
397
|
cannam@144
|
398 ++argidx;
|
cannam@144
|
399 }
|
cannam@138
|
400
|
cannam@144
|
401 cout << describe(plugins, pluginBundleBaseURI, describerURI, libname) << endl;
|
cannam@138
|
402
|
cannam@138
|
403 return 0;
|
cannam@138
|
404 }
|
cannam@138
|
405
|
cannam@138
|
406
|