comparison src/knownplugins.cpp @ 35:4154894d638c plugin-path-config

Trim KnownPlugins class down to static info and environment variable lookup; introduce KnownPluginCandidates to provide its former API
author Chris Cannam
date Wed, 06 Jun 2018 15:54:26 +0100
parents 6905d8b146f6
children ae74d39e9e4e
comparison
equal deleted inserted replaced
34:6905d8b146f6 35:4154894d638c
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 "knownplugins.h" 30 #include "knownplugins.h"
31 31
32 #include <sstream>
33
34 using namespace std; 32 using namespace std;
35 33
36 #if defined(_WIN32) 34 #if defined(_WIN32)
37 #define PATH_SEPARATOR ';' 35 #define PATH_SEPARATOR ';'
38 #else 36 #else
39 #define PATH_SEPARATOR ':' 37 #define PATH_SEPARATOR ':'
40 #endif 38 #endif
41 39
42 KnownPlugins::KnownPlugins(string helperExecutableName, 40 KnownPlugins::KnownPlugins(BinaryFormat format) :
43 PluginCandidates::LogCallback *cb) : 41 m_format(format)
44 m_candidates(helperExecutableName),
45 m_helperExecutableName(helperExecutableName)
46 { 42 {
47 m_candidates.setLogCallback(cb); 43 string variableSuffix = "";
48 44 if (m_format == FormatNonNative32Bit) {
49 std::string variableSuffix = "";
50 if (is32bit()) {
51 variableSuffix = "_32"; 45 variableSuffix = "_32";
52 } 46 }
53 47
54 m_known[VampPlugin] = { 48 m_known[VampPlugin] = {
55 "vamp", 49 "vamp",
56 "VAMP_PATH" + variableSuffix, 50 "VAMP_PATH" + variableSuffix,
57 expandConventionalPath(VampPlugin, "VAMP_PATH" + variableSuffix), 51 {}, {},
58 "vampGetPluginDescriptor" 52 "vampGetPluginDescriptor"
59 }; 53 };
60 54
61 m_known[LADSPAPlugin] = { 55 m_known[LADSPAPlugin] = {
62 "ladspa", 56 "ladspa",
63 "LADSPA_PATH" + variableSuffix, 57 "LADSPA_PATH" + variableSuffix,
64 expandConventionalPath(LADSPAPlugin, "LADSPA_PATH" + variableSuffix), 58 {}, {},
65 "ladspa_descriptor" 59 "ladspa_descriptor"
66 }; 60 };
67 61
68 m_known[DSSIPlugin] = { 62 m_known[DSSIPlugin] = {
69 "dssi", 63 "dssi",
70 "DSSI_PATH" + variableSuffix, 64 "DSSI_PATH" + variableSuffix,
71 expandConventionalPath(DSSIPlugin, "DSSI_PATH" + variableSuffix), 65 {}, {},
72 "dssi_descriptor" 66 "dssi_descriptor"
73 }; 67 };
74 68
75 for (const auto &k: m_known) { 69 for (auto &k: m_known) {
76 m_candidates.scan(k.second.tag, k.second.path, k.second.descriptor); 70 k.second.defaultPath = expandPathString(getDefaultPathString(k.first));
71 k.second.path = expandConventionalPath(k.first, k.second.variable);
77 } 72 }
78 } 73 }
79 74
80 std::vector<KnownPlugins::PluginType> 75 vector<KnownPlugins::PluginType>
81 KnownPlugins::getKnownPluginTypes() const 76 KnownPlugins::getKnownPluginTypes() const
82 { 77 {
83 std::vector<PluginType> kt; 78 vector<PluginType> kt;
84 79
85 for (const auto &k: m_known) { 80 for (const auto &k: m_known) {
86 kt.push_back(k.first); 81 kt.push_back(k.first);
87 } 82 }
88 83
89 return kt; 84 return kt;
90 } 85 }
91 86
92 bool
93 KnownPlugins::is32bit() const
94 {
95 return m_helperExecutableName.find("-32") != std::string::npos;
96 }
97
98 string 87 string
99 KnownPlugins::getDefaultPath(PluginType type) 88 KnownPlugins::getUnexpandedDefaultPathString(PluginType type)
100 { 89 {
101 switch (type) { 90 switch (type) {
102 91
103 #if defined(_WIN32) 92 #if defined(_WIN32)
104 93
130 } 119 }
131 120
132 throw logic_error("unknown or unhandled plugin type"); 121 throw logic_error("unknown or unhandled plugin type");
133 } 122 }
134 123
124 string
125 KnownPlugins::getDefaultPathString(PluginType type)
126 {
127 string path = getUnexpandedDefaultPathString(type);
128
129 if (path == "") {
130 return path;
131 }
132
133 char *home = getenv("HOME");
134 if (home) {
135 string::size_type f;
136 while ((f = path.find("$HOME")) != string::npos &&
137 f < path.length()) {
138 path.replace(f, 5, home);
139 }
140 }
141
142 #ifdef _WIN32
143 const char *pfiles = 0;
144 const char *pfiles32 = 0;
145
146 pfiles = getenv("ProgramFiles");
147 if (!pfiles) {
148 pfiles = "C:\\Program Files";
149 }
150
151 pfiles32 = getenv("ProgramFiles(x86)");
152 if (!pfiles32) {
153 pfiles32 = "C:\\Program Files (x86)";
154 }
155
156 string::size_type f;
157 while ((f = path.find("%ProgramFiles%")) != string::npos &&
158 f < path.length()) {
159 if (m_format == FormatNonNative32Bit) {
160 path.replace(f, 14, pfiles32);
161 } else {
162 path.replace(f, 14, pfiles);
163 }
164 }
165 #endif
166
167 return path;
168 }
169
135 vector<string> 170 vector<string>
136 KnownPlugins::expandConventionalPath(PluginType type, string var) 171 KnownPlugins::expandPathString(string path)
137 { 172 {
138 vector<string> pathList; 173 vector<string> pathList;
139 string path;
140
141 char *cpath = getenv(var.c_str());
142 if (cpath) path = cpath;
143
144 if (path == "") {
145
146 path = getDefaultPath(type);
147
148 if (path != "") {
149
150 char *home = getenv("HOME");
151 if (home) {
152 string::size_type f;
153 while ((f = path.find("$HOME")) != string::npos &&
154 f < path.length()) {
155 path.replace(f, 5, home);
156 }
157 }
158
159 #ifdef _WIN32
160 const char *pfiles = 0;
161 const char *pfiles32 = 0;
162
163 pfiles = getenv("ProgramFiles");
164 if (!pfiles) {
165 pfiles = "C:\\Program Files";
166 }
167
168 pfiles32 = getenv("ProgramFiles(x86)");
169 if (!pfiles32) {
170 pfiles32 = "C:\\Program Files (x86)";
171 }
172
173 string::size_type f;
174 while ((f = path.find("%ProgramFiles%")) != string::npos &&
175 f < path.length()) {
176 if (is32bit()) {
177 path.replace(f, 14, pfiles32);
178 } else {
179 path.replace(f, 14, pfiles);
180 }
181 }
182 #endif
183 }
184 }
185 174
186 string::size_type index = 0, newindex = 0; 175 string::size_type index = 0, newindex = 0;
187 176
188 while ((newindex = path.find(PATH_SEPARATOR, index)) < path.size()) { 177 while ((newindex = path.find(PATH_SEPARATOR, index)) < path.size()) {
189 pathList.push_back(path.substr(index, newindex - index).c_str()); 178 pathList.push_back(path.substr(index, newindex - index).c_str());
193 pathList.push_back(path.substr(index)); 182 pathList.push_back(path.substr(index));
194 183
195 return pathList; 184 return pathList;
196 } 185 }
197 186
198 string 187 vector<string>
199 KnownPlugins::getFailureReport() const 188 KnownPlugins::expandConventionalPath(PluginType type, string var)
200 { 189 {
201 vector<PluginCandidates::FailureRec> failures; 190 string path;
202 191
203 for (auto t: getKnownPluginTypes()) { 192 char *cpath = getenv(var.c_str());
204 auto ff = m_candidates.getFailedLibrariesFor(getTagFor(t)); 193 if (cpath) path = cpath;
205 failures.insert(failures.end(), ff.begin(), ff.end()); 194 if (path == "") {
195 path = getDefaultPathString(type);
206 } 196 }
207 197
208 if (failures.empty()) return ""; 198 return expandPathString(path);
209
210 int n = int(failures.size());
211 int i = 0;
212
213 ostringstream os;
214
215 os << "<ul>";
216 for (auto f: failures) {
217 os << "<li>" + f.library;
218 if (f.message != "") {
219 os << "<br><i>" + f.message + "</i>";
220 } else {
221 os << "<br><i>unknown error</i>";
222 }
223 os << "</li>";
224
225 if (n > 10) {
226 if (++i == 5) {
227 os << "<li>(... and " << (n - i) << " further failures)</li>";
228 break;
229 }
230 }
231 }
232 os << "</ul>";
233
234 return os.str();
235 } 199 }