Chris@4: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ Chris@4: Chris@4: #include "knownplugins.h" Chris@4: Chris@4: #include Chris@4: Chris@4: using namespace std; Chris@4: Chris@4: #if defined(_WIN32) Chris@4: #define PATH_SEPARATOR ';' Chris@4: #else Chris@4: #define PATH_SEPARATOR ':' Chris@4: #endif Chris@4: Chris@4: KnownPlugins::KnownPlugins() : Chris@4: m_candidates("./helper") //!!!??? wot to do Chris@4: { Chris@4: m_known = { Chris@4: { Chris@4: VampPlugin, Chris@4: { Chris@4: "vamp", Chris@4: expandConventionalPath(VampPlugin, "VAMP_PATH"), Chris@4: "vampGetPluginDescriptor" Chris@4: }, Chris@4: }, { Chris@4: LADSPAPlugin, Chris@4: { Chris@4: "ladspa", Chris@4: expandConventionalPath(LADSPAPlugin, "LADSPA_PATH"), Chris@4: "ladspa_descriptor" Chris@4: }, Chris@4: }, { Chris@4: DSSIPlugin, Chris@4: { Chris@4: "dssi", Chris@4: expandConventionalPath(DSSIPlugin, "DSSI_PATH"), Chris@4: "dssi_descriptor" Chris@4: } Chris@4: } Chris@4: }; Chris@4: Chris@4: for (const auto &k: m_known) { Chris@4: m_candidates.scan(k.second.tag, k.second.path, k.second.descriptor); Chris@4: } Chris@4: } Chris@4: Chris@4: string Chris@4: KnownPlugins::getDefaultPath(PluginType type) Chris@4: { Chris@4: switch (type) { Chris@4: Chris@4: #if defined(_WIN32) Chris@4: Chris@4: case VampPlugin: Chris@4: return "%ProgramFiles%\\Vamp Plugins"; Chris@4: case LADSPAPlugin: Chris@4: return "%ProgramFiles%\\LADSPA Plugins;%ProgramFiles%\\Audacity\\Plug-Ins"; Chris@4: case DSSIPlugin: Chris@4: return "%ProgramFiles%\\DSSI Plugins"; Chris@4: Chris@4: #elif defined(__APPLE__) Chris@4: Chris@4: case VampPlugin: Chris@4: return "$HOME/Library/Audio/Plug-Ins/Vamp:/Library/Audio/Plug-Ins/Vamp"; Chris@4: case LADSPAPlugin: Chris@4: return "$HOME/Library/Audio/Plug-Ins/LADSPA:/Library/Audio/Plug-Ins/LADSPA"; Chris@4: case DSSIPlugin: Chris@4: return "$HOME/Library/Audio/Plug-Ins/DSSI:/Library/Audio/Plug-Ins/DSSI"; Chris@4: Chris@4: #else /* Linux, BSDs, etc */ Chris@4: Chris@4: case VampPlugin: Chris@4: return "$HOME/vamp:$HOME/.vamp:/usr/local/lib/vamp:/usr/lib/vamp"; Chris@4: case LADSPAPlugin: Chris@4: return "$HOME/ladspa:$HOME/.ladspa:/usr/local/lib/ladspa:/usr/lib/ladspa"; Chris@4: case DSSIPlugin: Chris@4: return "$HOME/dssi:$HOME/.dssi:/usr/local/lib/dssi:/usr/lib/dssi"; Chris@4: #endif Chris@4: } Chris@4: Chris@4: throw logic_error("unknown or unhandled plugin type"); Chris@4: } Chris@4: Chris@4: vector Chris@4: KnownPlugins::expandConventionalPath(PluginType type, string var) Chris@4: { Chris@4: vector pathList; Chris@4: string path; Chris@4: Chris@4: char *cpath = getenv(var.c_str()); Chris@4: if (cpath) path = cpath; Chris@4: Chris@4: if (path == "") { Chris@4: Chris@4: path = getDefaultPath(type); Chris@4: Chris@4: if (path != "") { Chris@4: Chris@4: char *home = getenv("HOME"); Chris@4: if (home) { Chris@4: string::size_type f; Chris@4: while ((f = path.find("$HOME")) != string::npos && Chris@4: f < path.length()) { Chris@4: path.replace(f, 5, home); Chris@4: } Chris@4: } Chris@4: Chris@4: #ifdef _WIN32 Chris@4: char *pfiles = getenv("ProgramFiles"); Chris@4: if (!pfiles) pfiles = "C:\\Program Files"; Chris@4: { Chris@4: string::size_type f; Chris@4: while ((f = path.find("%ProgramFiles%")) != string::npos && Chris@4: f < path.length()) { Chris@4: path.replace(f, 14, pfiles); Chris@4: } Chris@4: } Chris@4: #endif Chris@4: } Chris@4: } Chris@4: Chris@4: string::size_type index = 0, newindex = 0; Chris@4: Chris@4: while ((newindex = path.find(PATH_SEPARATOR, index)) < path.size()) { Chris@4: pathList.push_back(path.substr(index, newindex - index).c_str()); Chris@4: index = newindex + 1; Chris@4: } Chris@4: Chris@4: pathList.push_back(path.substr(index)); Chris@4: Chris@4: return pathList; Chris@4: } Chris@4: Chris@4: string Chris@4: KnownPlugins::getFailureReport() const Chris@4: { Chris@4: vector failures; Chris@4: Chris@4: for (auto t: getKnownPluginTypes()) { Chris@4: auto ff = m_candidates.getFailedLibrariesFor(getTagFor(t)); Chris@4: failures.insert(failures.end(), ff.begin(), ff.end()); Chris@4: } Chris@4: Chris@4: if (failures.empty()) return ""; Chris@4: Chris@4: int n = failures.size(); Chris@4: int i = 0; Chris@4: Chris@4: ostringstream os; Chris@4: Chris@4: os << "
    "; Chris@4: for (auto f: failures) { Chris@4: os << "
  • " + f.library; Chris@4: if (f.message != "") { Chris@4: os << " (" + f.message + ")"; Chris@4: } else { Chris@4: os << " (unknown error)"; Chris@4: } Chris@4: os << "
  • "; Chris@4: Chris@4: if (n > 10) { Chris@4: if (++i == 5) { Chris@4: os << "
  • (... and " << (n - i) << " further failures)
  • "; Chris@4: break; Chris@4: } Chris@4: } Chris@4: } Chris@4: os << "
"; Chris@4: Chris@4: return os.str(); Chris@4: }