LCOV - code coverage report
Current view: top level - src/libs/tools/src - plugindatabase.cpp (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 199 255 78.0 %
Date: 2019-09-12 12:28:41 Functions: 28 28 100.0 %

          Line data    Source code
       1             : /**
       2             :  * @file
       3             :  *
       4             :  * @brief Implementation of PluginDatabase(s)
       5             :  *
       6             :  * @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
       7             :  *
       8             :  */
       9             : 
      10             : #include <plugindatabase.hpp>
      11             : 
      12             : #include <modules.hpp>
      13             : 
      14             : #include <set>
      15             : 
      16             : #include <algorithm>
      17             : #include <helper/keyhelper.hpp>
      18             : #include <kdbconfig.h>
      19             : #include <kdblogger.h>
      20             : #include <kdbmacros.h>
      21             : 
      22             : #ifdef HAVE_GLOB
      23             : #include <glob.h>
      24             : #endif
      25             : 
      26             : namespace kdb
      27             : {
      28             : 
      29             : namespace tools
      30             : {
      31             : 
      32             : class ModulesPluginDatabase::Impl
      33             : {
      34             : public:
      35             :         Impl ()
      36         442 :         {
      37             :         }
      38             :         ~Impl ()
      39         442 :         {
      40             :         }
      41             :         Modules modules;
      42             : };
      43             : 
      44        1326 : ModulesPluginDatabase::ModulesPluginDatabase () : impl (new ModulesPluginDatabase::Impl ())
      45             : {
      46         442 : }
      47             : 
      48         442 : ModulesPluginDatabase::~ModulesPluginDatabase ()
      49             : {
      50         442 : }
      51             : 
      52          28 : std::vector<std::string> ModulesPluginDatabase::listAllPlugins () const
      53             : {
      54          28 :         std::vector<std::string> ret;
      55             : #ifdef ELEKTRA_SHARED
      56             : #ifdef HAVE_GLOB
      57             :         std::set<std::string> toIgnore = {
      58             :                 "proposal", "core", "ease", "meta", "plugin", "full", "kdb", "static",
      59         588 :         };
      60             :         glob_t pglob;
      61          28 :         if (glob (BUILTIN_PLUGIN_FOLDER "/libelektra-*", GLOB_NOSORT, NULL, &pglob) == 0)
      62             :         {
      63             :                 ELEKTRA_LOG ("has glob %zd", pglob.gl_pathc);
      64           0 :                 for (size_t i = 0; i < pglob.gl_pathc; ++i)
      65             :                 {
      66           0 :                         std::string fn (pglob.gl_pathv[i]);
      67           0 :                         size_t start = fn.find_last_of ('-');
      68           0 :                         if (start == std::string::npos) continue; // ignore wrong file
      69           0 :                         std::string name = fn.substr (start + 1);
      70           0 :                         size_t end = name.find_first_of ('.');
      71           0 :                         name = name.substr (0, end);
      72           0 :                         if (end == std::string::npos) continue;                // ignore wrong file
      73           0 :                         if (toIgnore.find (name) != toIgnore.end ()) continue; // ignore
      74           0 :                         ret.push_back (name);
      75             :                 }
      76           0 :                 globfree (&pglob);
      77             :         }
      78             : #endif
      79          28 :         if (!ret.empty ())
      80             :         {
      81           0 :                 std::sort (ret.begin (), ret.end ());
      82             :                 return ret;
      83             :         }
      84             : // if we did not find plugins, return buildinPlugins
      85             : // (even if they might be wrong for ELEKTRA_SHARED)
      86             : #endif
      87          84 :         std::string buildinPlugins = ELEKTRA_PLUGINS;
      88          56 :         std::istringstream ss (buildinPlugins);
      89          28 :         std::string plugin;
      90        6048 :         while (getline (ss, plugin, ';'))
      91             :         {
      92        2996 :                 ret.push_back (plugin);
      93             :         }
      94             :         // remove duplicates:
      95          56 :         std::sort (ret.begin (), ret.end ());
      96         196 :         ret.erase (std::unique (ret.begin (), ret.end ()), ret.end ());
      97             :         return ret;
      98             : }
      99             : 
     100             : 
     101             : namespace
     102             : {
     103             : 
     104          54 : bool hasProvides (PluginDatabase const & pd, std::string which)
     105             : {
     106         108 :         std::vector<std::string> allPlugins = pd.listAllPlugins ();
     107             : 
     108         278 :         for (auto const & plugin : allPlugins)
     109             :         {
     110         696 :                 std::istringstream ss (pd.lookupInfo (
     111         348 :                         PluginSpec (
     112             :                                 plugin,
     113         464 :                                 KeySet (5, *Key ("system/module", KEY_VALUE, "this plugin was loaded without a config", KEY_END), KS_END)),
     114         410 :                         "provides"));
     115          62 :                 std::string provide;
     116         284 :                 while (ss >> provide)
     117             :                 {
     118          80 :                         if (provide == which)
     119             :                         {
     120         108 :                                 return true;
     121             :                         }
     122             :                 }
     123             :         }
     124             :         return false;
     125             : }
     126             : } // namespace
     127             : 
     128             : 
     129             : // TODO: directly use data from CONTRACT.ini
     130      127260 : const std::map<std::string, int> PluginDatabase::statusMap = {
     131             :         // clang-format off
     132             :    {"default",      64000},
     133             :    {"recommended",  32000},
     134             :    {"productive",    8000},
     135             :    {"maintained",    4000},
     136             :    {"reviewed",      4000},
     137             :    {"conformant",    2000},
     138             :    {"compatible",    2000},
     139             :    {"coverage",      2000},
     140             :    {"specific",      1000},
     141             : 
     142             :    {"unittest",      1000},
     143             :    {"shelltest",     1000},
     144             :    {"tested",         500},
     145             :    {"nodep",          250},
     146             :    {"libc",           250},
     147             :    {"configurable",    50},
     148             :    {"final",           50},
     149             :    {"global",           1},
     150             :    {"readonly",         0},
     151             :    {"writeonly",        0},
     152             :    {"preview",        -50},
     153             :    {"memleak",       -250},
     154             :    {"experimental",  -500},
     155             :    {"difficult",     -500},
     156             :    {"limited",       -750},
     157             :    {"unfinished",   -1000},
     158             :    {"old",          -1000},
     159             :    {"nodoc",        -1000},
     160             :    {"concept",      -2000},
     161             :    {"orphan",       -4000},
     162             :    {"obsolete",     -4000},
     163             :    {"discouraged", -32000},
     164             : 
     165             :         // clang-format on
     166             : };
     167             : 
     168             : 
     169         111 : int PluginDatabase::calculateStatus (std::string statusString)
     170             : {
     171         111 :         int ret = 0;
     172         222 :         std::istringstream ss (statusString);
     173         111 :         std::string status;
     174         558 :         while (ss >> status)
     175             :         {
     176         168 :                 auto it = statusMap.find (status);
     177         168 :                 if (it != statusMap.end ())
     178             :                 {
     179         136 :                         ret += it->second;
     180             :                 }
     181             :                 else
     182             :                 {
     183             :                         try
     184             :                         {
     185          18 :                                 ret += stoi (status);
     186             :                         }
     187          14 :                         catch (std::invalid_argument const &)
     188             :                         {
     189             :                         }
     190             :                 }
     191             :         }
     192         222 :         return ret;
     193             : }
     194             : 
     195        1053 : PluginDatabase::Status ModulesPluginDatabase::status (PluginSpec const & spec) const
     196             : {
     197        2106 :         PluginPtr plugin;
     198             :         try
     199             :         {
     200        2106 :                 KeySet conf = spec.getConfig ();
     201        3159 :                 conf.append (Key ("system/module", KEY_VALUE, "this plugin was loaded for the status", KEY_END));
     202        3159 :                 plugin = impl->modules.load (spec.getName (), conf);
     203        1053 :                 return real;
     204             :         }
     205           0 :         catch (...)
     206             :         {
     207           0 :                 if (hasProvides (*this, spec.getName ()))
     208             :                 {
     209             :                         return provides;
     210             :                 }
     211             :                 else
     212             :                 {
     213           0 :                         return missing;
     214             :                 }
     215             :         }
     216             : }
     217             : 
     218        9358 : std::string ModulesPluginDatabase::lookupInfo (PluginSpec const & spec, std::string const & which) const
     219             : {
     220       46790 :         PluginPtr plugin = impl->modules.load (spec.getName (), spec.getConfig ());
     221       74864 :         return plugin->lookupInfo (which);
     222             : }
     223             : 
     224        1048 : PluginDatabase::func_t ModulesPluginDatabase::getSymbol (PluginSpec const & spec, std::string const & which) const
     225             : {
     226             :         try
     227             :         {
     228        5240 :                 PluginPtr plugin = impl->modules.load (spec.getName (), spec.getConfig ());
     229        3144 :                 return plugin->getSymbol (which);
     230             :         }
     231        1030 :         catch (...)
     232             :         {
     233             :                 return NULL;
     234             :         }
     235             : }
     236             : 
     237          25 : PluginSpec ModulesPluginDatabase::lookupMetadata (std::string const & which) const
     238             : {
     239          50 :         std::vector<std::string> allPlugins = listAllPlugins ();
     240          50 :         std::map<int, PluginSpec> foundPlugins;
     241             : 
     242          50 :         std::string errors;
     243             :         // collect possible plugins
     244        1097 :         for (auto const & plugin : allPlugins)
     245             :         {
     246             :                 try
     247             :                 {
     248             :                         // TODO remove /module hack
     249        5982 :                         std::istringstream ss (lookupInfo (
     250        2991 :                                 PluginSpec (plugin,
     251        1994 :                                             KeySet (5,
     252        1994 :                                                     *Key ("system/module", KEY_VALUE, "this plugin was loaded without a config", KEY_END),
     253             :                                                     KS_END)),
     254        3988 :                                 "metadata"));
     255         997 :                         std::string metadata;
     256        3352 :                         while (ss >> metadata)
     257             :                         {
     258         714 :                                 if (metadata == which)
     259             :                                 {
     260         210 :                                         int s = calculateStatus (lookupInfo (
     261         175 :                                                 PluginSpec (plugin, KeySet (5,
     262          70 :                                                                             *Key ("system/module", KEY_VALUE,
     263             :                                                                                   "this plugin was loaded without a config", KEY_END),
     264             :                                                                             KS_END)),
     265          70 :                                                 "status"));
     266         245 :                                         foundPlugins.insert (std::make_pair (s, PluginSpec (plugin)));
     267             :                                         break;
     268             :                                 }
     269             :                         }
     270             :                 }
     271           0 :                 catch (std::exception const & e)
     272             :                 {
     273           0 :                         errors += e.what ();
     274           0 :                         errors += ",";
     275             :                 } // assume not loaded
     276             :         }
     277             : 
     278          25 :         if (foundPlugins.empty ())
     279             :         {
     280           0 :                 if (!errors.empty ())
     281           0 :                         throw NoPlugin ("No plugin that provides " + which + " could be found, got errors: " + errors);
     282             :                 else
     283           0 :                         throw NoPlugin ("No plugin that provides " + which + " could be found");
     284             :         }
     285             : 
     286             :         // the largest element of the map contains the best-suited plugin:
     287          75 :         return foundPlugins.rbegin ()->second;
     288             : }
     289             : 
     290        1207 : PluginSpec ModulesPluginDatabase::lookupProvides (std::string const & which) const
     291             : {
     292             :         // check if plugin with provider name exists:
     293        6035 :         if (status (PluginSpec (which)) == real)
     294             :         {
     295        4620 :                 return PluginSpec (which);
     296             :         }
     297             : 
     298          52 :         std::map<int, PluginSpec> foundPlugins;
     299             :         try
     300             :         {
     301         156 :                 foundPlugins = lookupAllProvidesWithStatus (which);
     302             :         }
     303           0 :         catch (kdb::tools::NoPlugin const & e)
     304             :         {
     305           0 :                 throw;
     306             :         }
     307             : 
     308             :         // the largest element of the map contains the best-suited plugin:
     309         104 :         return foundPlugins.rbegin ()->second;
     310             : }
     311             : 
     312          54 : std::map<int, PluginSpec> ModulesPluginDatabase::lookupAllProvidesWithStatus (std::string const & which) const
     313             : {
     314         108 :         std::string errors;
     315         108 :         std::vector<std::string> allPlugins = listAllPlugins ();
     316          54 :         std::map<int, PluginSpec> foundPlugins;
     317         600 :         for (auto const & plugin : allPlugins)
     318             :         {
     319             :                 // TODO: make sure (non)-equal plugins (i.e. with same/different contract) are handled correctly
     320             :                 try
     321             :                 {
     322             :                         PluginSpec spec = PluginSpec (
     323             :                                 plugin,
     324        2686 :                                 KeySet (5, *Key ("system/module", KEY_VALUE, "this plugin was loaded without a config", KEY_END), KS_END));
     325             : 
     326             :                         // lets see if there is a plugin named after the required provider
     327         384 :                         if (plugin == which)
     328             :                         {
     329          10 :                                 int s = calculateStatus (lookupInfo (spec, "status"));
     330          14 :                                 foundPlugins.insert (std::make_pair (s, PluginSpec (plugin)));
     331             :                                 continue; // we are done with this plugin
     332             :                         }
     333             : 
     334             :                         // TODO: support for generic plugins with config
     335        2292 :                         std::istringstream ss (lookupInfo (spec, "provides"));
     336         382 :                         std::string provide;
     337        1576 :                         while (ss >> provide)
     338             :                         {
     339         406 :                                 if (provide == which)
     340             :                                 {
     341         330 :                                         int s = calculateStatus (lookupInfo (spec, "status"));
     342         462 :                                         foundPlugins.insert (std::make_pair (s, PluginSpec (plugin)));
     343             :                                 }
     344             :                         }
     345             :                 }
     346           0 :                 catch (std::exception const & e)
     347             :                 {
     348           0 :                         errors += e.what ();
     349           0 :                         errors += ",";
     350             :                 } // assume not loaded
     351             :         }
     352             : 
     353          54 :         if (foundPlugins.empty ())
     354             :         {
     355           0 :                 if (!errors.empty ())
     356           0 :                         throw NoPlugin ("No plugin that provides " + which + " could be found, got errors: " + errors);
     357             :                 else
     358           0 :                         throw NoPlugin ("No plugin that provides " + which + " could be found");
     359             :         }
     360             : 
     361          54 :         return foundPlugins;
     362             : }
     363             : 
     364           1 : std::vector<PluginSpec> ModulesPluginDatabase::lookupAllProvides (std::string const & which) const
     365             : {
     366             :         try
     367             :         {
     368           2 :                 const std::map<int, PluginSpec> foundPlugins = lookupAllProvidesWithStatus (which);
     369             : 
     370             :                 // we found some plugins, lets convert the map into a vector
     371           2 :                 std::vector<PluginSpec> plugins;
     372           1 :                 plugins.reserve (foundPlugins.size ());
     373             :                 std::for_each (foundPlugins.begin (), foundPlugins.end (),
     374           6 :                                [&plugins](const std::map<int, PluginSpec>::value_type & elem) { plugins.push_back (elem.second); });
     375           1 :                 return plugins;
     376             :         }
     377           0 :         catch (kdb::tools::NoPlugin const & e)
     378             :         {
     379             :                 // if no plugins were found, return an empty vector
     380           0 :                 return std::vector<PluginSpec> ();
     381             :         }
     382             : }
     383             : 
     384             : 
     385             : class PluginVariantDatabase::VariantImpl
     386             : {
     387             : public:
     388          12 :         explicit VariantImpl (const KeySet & conf) : pluginconf (conf)
     389             :         {
     390             :         }
     391             :         ~VariantImpl ()
     392          12 :         {
     393             :         }
     394             :         KeySet pluginconf;
     395             : };
     396             : 
     397           6 : PluginVariantDatabase::PluginVariantDatabase (const KeySet & conf)
     398          18 : : ModulesPluginDatabase (), variantImpl (new PluginVariantDatabase::VariantImpl (conf))
     399             : {
     400           6 : }
     401             : 
     402          12 : PluginVariantDatabase::~PluginVariantDatabase ()
     403             : {
     404           6 : }
     405             : 
     406           6 : std::vector<std::string> PluginVariantDatabase::listAllPlugins () const
     407             : {
     408           6 :         std::vector<std::string> plugins (ModulesPluginDatabase::listAllPlugins ());
     409           6 :         plugins.erase (std::remove_if (plugins.begin (), plugins.end (),
     410        1284 :                                        [this](const std::string & elem) {
     411        1284 :                                                Key k ("system/elektra/plugins", KEY_END);
     412         642 :                                                k.addBaseName (elem);
     413        2568 :                                                k.addBaseName ("disable");
     414        2568 :                                                Key res = this->variantImpl->pluginconf.lookup (k);
     415        1934 :                                                return res && res.getString () == "1";
     416          18 :                                        }),
     417          24 :                        plugins.end ());
     418           6 :         return plugins;
     419             : }
     420             : 
     421           4 : std::vector<PluginSpec> PluginVariantDatabase::getPluginVariants (PluginSpec const & whichplugin) const
     422             : {
     423          12 :         PluginPtr plugin = this->impl->modules.load (whichplugin);
     424          16 :         KeySet ksSysconf (this->variantImpl->pluginconf);
     425           8 :         KeySet ksGenconf;
     426             : 
     427             :         // read plugin variants via genconf
     428             :         try
     429             :         {
     430          18 :                 auto funcGenconf = reinterpret_cast<void (*) (ckdb::KeySet *, ckdb::Key *)> (plugin->getSymbol ("genconf"));
     431           2 :                 funcGenconf (ksGenconf.getKeySet (), 0);
     432             :         }
     433           4 :         catch (kdb::tools::MissingSymbol const & e)
     434             :         {
     435             :                 // no genconf, but maybe sysconf variants
     436           4 :                 KeySet placeholder;
     437           2 :                 return this->getPluginVariantsFromSysconf (whichplugin, ksSysconf, placeholder);
     438             :         }
     439             : 
     440             :         // get plugin variants from genconf, but also consider sysconf for disable/override
     441           2 :         return this->getPluginVariantsFromGenconf (whichplugin, ksGenconf, ksSysconf);
     442             : }
     443             : 
     444           4 : std::vector<PluginSpec> PluginVariantDatabase::getPluginVariantsFromSysconf (PluginSpec const & whichplugin, KeySet const & sysconf,
     445             :                                                                              KeySet const & genconfToIgnore) const
     446             : {
     447           4 :         std::vector<PluginSpec> result;
     448             : 
     449           8 :         KeySet ksSysconf (sysconf);
     450             : 
     451             :         // first find possible variants
     452           8 :         Key kVariantBase ("system/elektra/plugins", KEY_END);
     453           8 :         kVariantBase.addBaseName (whichplugin.getName ());
     454          16 :         kVariantBase.addBaseName ("variants");
     455             : 
     456          16 :         KeySet ksPluginVariantSysconf (ksSysconf.cut (kVariantBase));
     457           8 :         KeySet ksToIterate (ksPluginVariantSysconf);
     458          12 :         for (auto kCurrent : ksToIterate)
     459             :         {
     460           0 :                 Key kCurrentTest (kVariantBase);
     461           0 :                 kCurrentTest.addBaseName (kCurrent.getBaseName ());
     462           0 :                 if (kCurrentTest == kCurrent)
     463             :                 {
     464           0 :                         PluginSpec variant (whichplugin);
     465           0 :                         KeySet ksVariantConfToAdd;
     466             : 
     467             :                         // new base for plugin conf
     468           0 :                         Key kVariantPluginConf ("system/", KEY_END);
     469             : 
     470             :                         // add system conf for plugin variant
     471           0 :                         Key kVariantSysconf (this->buildVariantSysconfKey (whichplugin, kCurrent.getBaseName (), "config"));
     472           0 :                         this->addKeysBelowKeyToConf (kVariantSysconf, ksPluginVariantSysconf, kVariantPluginConf, ksVariantConfToAdd);
     473             : 
     474             :                         // check if the variant was disabled : system/elektra/plugins/simpleini/variants/space/disable
     475           0 :                         Key kDisable = sysconf.lookup (this->buildVariantSysconfKey (whichplugin, kCurrent.getBaseName (), "disable"));
     476           0 :                         if (kDisable && kDisable.getString () == "1")
     477             :                         {
     478           0 :                                 continue; // skip this variant
     479             :                         }
     480             : 
     481             :                         // check if the variant is in the genconfToIgnore list
     482           0 :                         Key kGenconfVariant (kVariantPluginConf);
     483           0 :                         kGenconfVariant.addBaseName (kCurrent.getBaseName ());
     484           0 :                         Key kIgnore = genconfToIgnore.lookup (kGenconfVariant);
     485           0 :                         if (kIgnore)
     486             :                         {
     487           0 :                                 continue; // this variant was added by genconf already
     488             :                         }
     489             : 
     490           0 :                         if (ksVariantConfToAdd.size () == 0)
     491             :                         {
     492             :                                 continue; // no config means no variant
     493             :                         }
     494             : 
     495           0 :                         variant.appendConfig (ksVariantConfToAdd);
     496           0 :                         result.push_back (variant);
     497             :                 }
     498             :         }
     499             : 
     500           4 :         return result;
     501             : }
     502             : 
     503           2 : std::vector<PluginSpec> PluginVariantDatabase::getPluginVariantsFromGenconf (PluginSpec const & whichplugin, KeySet const & genconf,
     504             :                                                                              KeySet const & sysconf) const
     505             : {
     506           2 :         std::vector<PluginSpec> result;
     507             : 
     508           4 :         KeySet ksToIterate (genconf);
     509        6336 :         for (auto kCurrent : ksToIterate)
     510             :         {
     511        8440 :                 Key kCurrentTest (kCurrent.getNamespace () + "/", KEY_END);
     512        4220 :                 kCurrentTest.addBaseName (kCurrent.getBaseName ()); // e.g. system/space
     513        2110 :                 if (kCurrentTest == kCurrent)
     514             :                 {
     515         844 :                         PluginSpec variant (whichplugin);
     516         844 :                         KeySet ksVariantConfToAdd;
     517             : 
     518             :                         // new base for plugin conf
     519         844 :                         Key kVariantPluginConf ("system/", KEY_END);
     520             : 
     521             :                         // take variant config from genconf and transform it to proper plugin conf,
     522             :                         // e.g. system/space/config/format -> system/format
     523         844 :                         Key kVariantConf (kCurrentTest);
     524        1688 :                         kVariantConf.addBaseName ("config"); // e.g. system/space/config
     525         422 :                         this->addKeysBelowKeyToConf (kVariantConf, genconf, kVariantPluginConf, ksVariantConfToAdd);
     526             : 
     527             :                         // TODO plugin infos
     528             : 
     529             :                         // check if the variant was disabled : system/elektra/plugins/simpleini/variants/space/disable
     530        3798 :                         Key kDisable = sysconf.lookup (this->buildVariantSysconfKey (whichplugin, kCurrent.getBaseName (), "disable"));
     531         844 :                         if (kDisable && kDisable.getString () == "1")
     532             :                         {
     533           0 :                                 continue; // skip this variant
     534             :                         }
     535             : 
     536             :                         // check if an override is available : system/elektra/plugins/simpleini/variants/space/override
     537        3798 :                         Key kOverride = sysconf.lookup (this->buildVariantSysconfKey (whichplugin, kCurrent.getBaseName (), "override"));
     538         844 :                         if (kOverride && kOverride.getString () == "1")
     539             :                         {
     540             :                                 // first delete config from genconf entirely
     541           0 :                                 ksVariantConfToAdd.clear ();
     542           0 :                                 Key kVariantSysconf (this->buildVariantSysconfKey (whichplugin, kCurrent.getBaseName (), "config"));
     543           0 :                                 this->addKeysBelowKeyToConf (kVariantSysconf, sysconf, kVariantPluginConf, ksVariantConfToAdd);
     544             :                         }
     545             : 
     546         422 :                         if (ksVariantConfToAdd.size () == 0)
     547             :                         {
     548             :                                 continue; // no config means no variant
     549             :                         }
     550             : 
     551         844 :                         variant.appendConfig (ksVariantConfToAdd);
     552         422 :                         result.push_back (variant);
     553             :                 }
     554             :         }
     555             : 
     556           4 :         std::vector<PluginSpec> resFromSysconf (this->getPluginVariantsFromSysconf (whichplugin, sysconf, genconf));
     557           8 :         result.insert (result.end (), resFromSysconf.begin (), resFromSysconf.end ());
     558             : 
     559           2 :         return result;
     560             : }
     561             : 
     562         844 : Key PluginVariantDatabase::buildVariantSysconfKey (PluginSpec const & whichplugin, std::string const & variant,
     563             :                                                    const std::string attr) const
     564             : {
     565         844 :         Key result ("system/elektra/plugins", KEY_END);
     566        1688 :         result.addBaseName (whichplugin.getName ());
     567        3376 :         result.addBaseName ("variants");
     568         844 :         result.addBaseName (variant);
     569         844 :         result.addBaseName (attr);
     570         844 :         return result;
     571             : }
     572             : 
     573         422 : void PluginVariantDatabase::addKeysBelowKeyToConf (Key const & below, KeySet const & conf, Key const & newbase, KeySet & targetconf) const
     574             : {
     575         844 :         KeySet confCp (conf);
     576        1688 :         KeySet ksVariantSysConf = confCp.cut (below);
     577        2954 :         for (auto kVariantCurrent : ksVariantSysConf)
     578             :         {
     579         844 :                 if (!kVariantCurrent.isBelow (below)) continue;
     580        1266 :                 targetconf.append (helper::rebaseKey (kVariantCurrent, below, newbase));
     581             :         }
     582         422 : }
     583             : 
     584             : 
     585         122 : std::vector<std::string> MockPluginDatabase::listAllPlugins () const
     586             : {
     587         122 :         std::vector<std::string> plugins;
     588         742 :         for (auto const & plugin : data)
     589             :         {
     590        1128 :                 plugins.push_back (plugin.first.getName ());
     591             :         }
     592         122 :         return plugins;
     593             : }
     594             : 
     595         172 : PluginDatabase::Status MockPluginDatabase::status (PluginSpec const & spec) const
     596             : {
     597         344 :         auto it = data.find (spec);
     598         344 :         if (it != data.end ())
     599             :         {
     600             :                 return real;
     601             :         }
     602             : 
     603         108 :         if (hasProvides (*this, spec.getName ()))
     604             :         {
     605             :                 return provides;
     606             :         }
     607             : 
     608           0 :         return missing;
     609             : }
     610             : 
     611             : 
     612        1238 : std::string MockPluginDatabase::lookupInfo (PluginSpec const & spec, std::string const & which) const
     613             : {
     614        2476 :         auto it = data.find (spec);
     615        2476 :         if (it != data.end ())
     616             :         {
     617        2476 :                 return it->second[which];
     618             :         }
     619             : 
     620           0 :         return "";
     621             : }
     622             : 
     623         158 : PluginDatabase::func_t MockPluginDatabase::getSymbol (PluginSpec const & spec ELEKTRA_UNUSED, std::string const & which) const
     624             : {
     625         158 :         if (which == "checkconf")
     626             :         {
     627         158 :                 return reinterpret_cast<func_t> (checkconf);
     628             :         }
     629             :         return NULL;
     630             : }
     631             : 
     632          12 : void MockPluginDatabase::setCheckconfFunction (const MockPluginDatabase::checkConfPtr newCheckconf)
     633             : {
     634          12 :         checkconf = newCheckconf;
     635          12 : }
     636             : } // namespace tools
     637       10908 : } // namespace kdb

Generated by: LCOV version 1.13