LCOV - code coverage report
Current view: top level - src/tools/kdb - ls.cpp (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 40 48 83.3 %
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 <ls.hpp>
      10             : 
      11             : #include <climits>
      12             : #include <iostream>
      13             : 
      14             : #include <cmdline.hpp>
      15             : #include <kdb.hpp>
      16             : #include <keysetio.hpp>
      17             : 
      18             : using namespace kdb;
      19             : using namespace std;
      20             : 
      21         572 : LsCommand::LsCommand () : kdb (root)
      22             : {
      23         143 : }
      24             : 
      25          64 : int LsCommand::execute (Cmdline const & cl)
      26             : {
      27          64 :         checkArguments (cl);
      28             : 
      29          63 :         printWarnings (cerr, root, cl.verbose, cl.debug);
      30             : 
      31         189 :         root = cl.createKey (0);
      32             : 
      33          63 :         kdb.get (ks, root);
      34             : 
      35          63 :         if (cl.verbose) cout << "size of all keys in mount point: " << ks.size () << endl;
      36             : 
      37         300 :         KeySet part (ks.cut (root));
      38             : 
      39          63 :         if (cl.verbose) cout << "size of requested keys: " << part.size () << endl;
      40          60 :         cout.setf (std::ios_base::unitbuf);
      41          60 :         if (cl.null)
      42             :         {
      43             :                 cout.unsetf (std::ios_base::skipws);
      44             :         }
      45             : 
      46          60 :         printResults (part, getDepth (root), cl);
      47             : 
      48          60 :         printWarnings (cerr, root, cl.verbose, cl.debug);
      49             : 
      50         120 :         return 0;
      51             : }
      52             : 
      53          64 : void LsCommand::checkArguments (Cmdline const & cl)
      54             : {
      55         128 :         if (cl.arguments.size () != 1)
      56             :         {
      57           1 :                 throw invalid_argument ("1 argument required");
      58             :         }
      59          63 :         if (cl.maxDepth <= cl.minDepth)
      60             :         {
      61           0 :                 throw invalid_argument ("the maximum depth has to be larger than the minimum depth");
      62             :         }
      63          63 :         if (cl.maxDepth < 0)
      64             :         {
      65           0 :                 throw invalid_argument ("the maximum depth has to be a positive number");
      66             :         }
      67          63 :         if (cl.minDepth < 0)
      68             :         {
      69           0 :                 throw invalid_argument ("the minimum depth has to be a positive number");
      70             :         }
      71          63 : }
      72             : 
      73          60 : void LsCommand::printResults (KeySet const & part, const int rootDepth, Cmdline const & cl)
      74             : {
      75         420 :         const int offset = root.getBaseName ().empty () || shallShowNextLevel (cl.arguments[0]) ? 1 : 0;
      76          60 :         const int relativeMinDepth = rootDepth + cl.minDepth + offset;
      77             :         const int relativeMaxDepth =
      78         120 :                 std::max (cl.maxDepth, rootDepth > INT_MAX - cl.maxDepth - offset ? INT_MAX : rootDepth + cl.maxDepth + offset);
      79          60 :         if (cl.debug)
      80             :         {
      81           0 :                 cout << "The root depth is " << rootDepth << ", the relative minimum depth is " << relativeMinDepth
      82           0 :                      << " and the relative maximum depth is " << relativeMaxDepth << endl;
      83             :         }
      84             : 
      85        1245 :         for (const auto & it : part)
      86             :         {
      87         355 :                 const int depth = getDepth (it);
      88         355 :                 if ((depth >= relativeMinDepth && depth < relativeMaxDepth) || cl.debug)
      89             :                 {
      90         340 :                         cout << it;
      91         340 :                         if (cl.debug)
      92             :                         {
      93           0 :                                 cout << " " << depth;
      94             :                         }
      95             : 
      96         340 :                         if (cl.null)
      97             :                         {
      98           0 :                                 cout << '\0' << std::flush;
      99             :                         }
     100             :                         else
     101             :                         {
     102             :                                 cout << endl;
     103             :                         }
     104             :                 }
     105             :         }
     106          60 : }
     107             : 
     108         415 : int LsCommand::getDepth (Key const & key)
     109             : {
     110         830 :         return std::distance (key.begin (), key.end ());
     111             : }
     112             : 
     113           0 : bool LsCommand::shallShowNextLevel (const string argument)
     114             : {
     115          60 :         auto it = argument.rbegin ();
     116             :         // If the argument ends in / its an indicator to complete the next level (like done by shells), but not if its escaped
     117         264 :         return it != argument.rend () && (*it) == '/' && ((++it) == argument.rend () || (*it) != '\\');
     118             : }
     119             : 
     120         715 : LsCommand::~LsCommand ()
     121             : {
     122        7450 : }

Generated by: LCOV version 1.13