LCOV - code coverage report
Current view: top level - src/tools/kdb - get.cpp (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 94 100 94.0 %
Date: 2019-09-12 12:28:41 Functions: 8 9 88.9 %

          Line data    Source code
       1             : /**
       2             :  * @file
       3             :  *
       4             :  * @brief
       5             :  *
       6             :  * @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
       7             :  */
       8             : 
       9             : #include <get.hpp>
      10             : 
      11             : #include <cmdline.hpp>
      12             : #include <kdb.hpp>
      13             : 
      14             : #include <kdbmacros.h>
      15             : #include <kdbproposal.h> // for some options
      16             : 
      17             : #include <iostream>
      18             : 
      19             : #include <kdbmacros.h>
      20             : 
      21             : using namespace std;
      22             : using namespace kdb;
      23             : 
      24         374 : GetCommand::GetCommand ()
      25             : {
      26         374 : }
      27             : 
      28             : namespace
      29             : {
      30             : 
      31           2 : void printOptions (option_t options)
      32             : {
      33             :         // :'<,'>s/\(.*\)/^Iif(options \& \1) std::cout << "\1 ";
      34           2 :         if (options & KDB_O_DEL) std::cout << "KDB_O_DEL ";
      35           2 :         if (options & KDB_O_POP) std::cout << "KDB_O_POP ";
      36           2 :         if (options & KDB_O_NODIR) std::cout << "KDB_O_NODIR ";
      37           2 :         if (options & KDB_O_DIRONLY) std::cout << "KDB_O_DIRONLY ";
      38           2 :         if (options & KDB_O_NOREMOVE) std::cout << "KDB_O_NOREMOVE ";
      39           2 :         if (options & KDB_O_REMOVEONLY) std::cout << "KDB_O_REMOVEONLY ";
      40           2 :         if (options & KDB_O_INACTIVE) std::cout << "KDB_O_INACTIVE ";
      41           2 :         if (options & KDB_O_SYNC) std::cout << "KDB_O_SYNC ";
      42           2 :         if (options & KDB_O_SORT) std::cout << "KDB_O_SORT ";
      43           2 :         if (options & KDB_O_NORECURSIVE) std::cout << "KDB_O_NORECURSIVE ";
      44           2 :         if (options & KDB_O_NOCASE) std::cout << "KDB_O_NOCASE ";
      45           2 :         if (options & KDB_O_WITHOWNER) std::cout << "KDB_O_WITHOWNER ";
      46           2 :         if (options & KDB_O_NOALL) std::cout << "KDB_O_NOALL ";
      47             : 
      48           2 :         if (options & ckdb::KDB_O_SPEC) std::cout << "KDB_O_SPEC ";
      49           2 :         if (options & ckdb::KDB_O_CREATE) std::cout << "KDB_O_CREATE ";
      50           2 :         if (options & ckdb::KDB_O_NOCASCADING) std::cout << "KDB_O_NOCASCADING ";
      51           2 :         if (options & ckdb::KDB_O_NOSPEC) std::cout << "KDB_O_NOSPEC ";
      52           2 :         if (options & ckdb::KDB_O_NODEFAULT) std::cout << "KDB_O_NODEFAULT ";
      53           2 :         if (options & ckdb::KDB_O_CALLBACK) std::cout << "KDB_O_CALLBACK";
      54           2 : }
      55             : 
      56             : 
      57         379 : ckdb::Key * warnOnMeta (ELEKTRA_UNUSED ckdb::KeySet * ks, ELEKTRA_UNUSED ckdb::Key * key, ckdb::Key * found, option_t options)
      58             : {
      59         379 :         if (found && !strncmp (keyName (found), "spec/", 5) && options == ckdb::KDB_O_CALLBACK)
      60             :         {
      61           7 :                 const ckdb::Key * meta = keyGetMeta (found, "context");
      62           7 :                 if (meta)
      63             :                 {
      64             :                         std::cout << "WARNING " << keyName (found)
      65           0 :                                   << " is context dependent, shown result might be wrong, -v shows you the trace to the key" << std::endl;
      66             :                 }
      67             :         }
      68         379 :         return found;
      69             : }
      70             : 
      71          12 : std::string getCascadingName (std::string name)
      72             : {
      73          12 :         if (name[0] == '/') return name;
      74          15 :         if (name.find ('/') == std::string::npos) return "/";
      75           9 :         return name.substr (name.find ('/'));
      76             : }
      77             : } // namespace
      78             : 
      79           8 : ckdb::Key * printTrace (ELEKTRA_UNUSED ckdb::KeySet * ks, ckdb::Key * key, ckdb::Key * found, option_t options)
      80             : {
      81           8 :         warnOnMeta (ks, key, found, options);
      82             : 
      83          16 :         Key k (key);
      84          16 :         Key f (found);
      85             : 
      86          40 :         std::string lastKeyName = k.getMeta<std::string> ("callback/print_trace/last_key_name");
      87          32 :         int depth = k.getMeta<int> ("callback/print_trace/depth");
      88             : 
      89          20 :         for (int i = 0; i < depth; ++i)
      90          12 :                 std::cout << " ";
      91             : 
      92          32 :         std::cout << "searching " << (k.getName ()[0] == '/' ? "default of spec" : "") << k.getName ()
      93          59 :                   << ", found: " << (found ? f.getName () : "<nothing>");
      94             : 
      95           8 :         if (options)
      96             :         {
      97           2 :                 std::cout << ", options: ";
      98           2 :                 printOptions (options);
      99             :         }
     100           8 :         std::cout << std::endl;
     101             : 
     102          32 :         if (k.getName ().substr (0, 5) == "spec/" && (options & ckdb::KDB_O_CALLBACK))
     103             :         {
     104           2 :                 depth += 4;
     105           8 :                 k.setMeta<int> ("callback/print_trace/depth", depth);
     106             :         }
     107             :         else
     108             :         {
     109          42 :                 if (getCascadingName (lastKeyName) != getCascadingName (k.getName ()))
     110             :                 {
     111           3 :                         if (depth != 0)
     112             :                         {
     113           0 :                                 depth -= 2;
     114             :                         }
     115          12 :                         k.setMeta<int> ("callback/print_trace/depth", depth);
     116             :                 }
     117             :         }
     118          40 :         k.setMeta<string> ("callback/print_trace/last_key_name", k.getName ());
     119             : 
     120           8 :         f.release ();
     121           8 :         k.release ();
     122          16 :         return found;
     123             : }
     124             : 
     125             : 
     126         296 : int GetCommand::execute (Cmdline const & cl)
     127             : {
     128         592 :         if (cl.arguments.size () != 1) throw invalid_argument ("Need one argument");
     129             : 
     130         592 :         KeySet conf;
     131             : 
     132         592 :         kdb::Key root = cl.createKey (0);
     133         592 :         kdb::KDB kdb (root);
     134             : 
     135         592 :         std::string n;
     136         296 :         if (cl.all)
     137             :         {
     138           0 :                 n = root.getName ();
     139           0 :                 root.setName ("/");
     140             :         }
     141             : 
     142         296 :         kdb.get (conf, root);
     143             : 
     144         294 :         if (cl.all)
     145             :         {
     146           0 :                 root.setName (n);
     147             :         }
     148             : 
     149             :         // do a lookup without tracer to warm up default cache
     150         588 :         conf.lookup (root);
     151             : 
     152         294 :         root.setCallback (warnOnMeta);
     153         294 :         if (cl.verbose)
     154             :         {
     155          25 :                 cout << "got " << conf.size () << " keys" << std::endl;
     156           5 :                 root.setCallback (printTrace);
     157             :         }
     158         588 :         Key k = conf.lookup (root);
     159             : 
     160         294 :         int ret = 0;
     161             : 
     162         294 :         if (k)
     163             :         {
     164         286 :                 if (cl.verbose)
     165             :                 {
     166          15 :                         if (k.getName ()[0] == '/')
     167             :                         {
     168           1 :                                 cout << "The key was not found in any other namespace, taking the default from the metadata" << std::endl;
     169             :                         }
     170          25 :                         cout << "The resulting keyname is " << k.getName () << std::endl;
     171          15 :                         cout << "The resulting value size is " << k.getStringSize () << std::endl;
     172             :                 }
     173             : 
     174         286 :                 if (k.isBinary ())
     175             :                 {
     176          11 :                         if (cl.verbose)
     177             :                         {
     178           2 :                                 if (k.getBinarySize () == 0)
     179             :                                 {
     180           2 :                                         cout << "The key is null." << std::endl;
     181             :                                 }
     182             :                                 else
     183             :                                 {
     184           0 :                                         cout << "The key is binary." << std::endl;
     185             :                                 }
     186             :                         }
     187          11 :                         cout << std::hex;
     188             :                         const uint8_t * data = static_cast<const uint8_t *> (k.getValue ());
     189         130 :                         for (auto position = 0; position < k.getBinarySize (); position++)
     190             :                         {
     191         108 :                                 cout << "\\x" << unsigned(data[position]);
     192             :                         }
     193             :                         cout << std::dec;
     194             :                 }
     195             :                 else
     196             :                 {
     197         825 :                         cout << k.getString ();
     198             :                 }
     199             :         }
     200             :         else
     201             :         {
     202          32 :                 cerr << "Did not find key '" << root.getName () << "'";
     203           8 :                 ret = 11;
     204             :         }
     205             : 
     206         294 :         if (!cl.noNewline)
     207             :         {
     208             :                 cout << endl;
     209             :         }
     210             : 
     211         294 :         printWarnings (cerr, root, cl.verbose, cl.debug);
     212         294 :         printError (cerr, root, cl.verbose, cl.debug);
     213             : 
     214         588 :         return ret;
     215             : }
     216             : 
     217         374 : GetCommand::~GetCommand ()
     218             : {
     219        7538 : }

Generated by: LCOV version 1.13