LCOV - code coverage report
Current view: top level - src/tools/kdb/gen - template.cpp (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 69 77 89.6 %
Date: 2019-09-12 12:28:41 Functions: 17 20 85.0 %

          Line data    Source code
       1             : #include <utility>
       2             : 
       3             : /**
       4             :  * @file
       5             :  *
       6             :  * @brief
       7             :  *
       8             :  * @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
       9             :  */
      10             : 
      11             : #include "template.hpp"
      12             : 
      13             : #include <algorithm>
      14             : #include <command.hpp>
      15             : #include <fstream>
      16             : 
      17             : #include <gen/templates.hpp>
      18             : 
      19             : #include "highlevel/highlevel.hpp"
      20             : 
      21           9 : GenTemplate::GenTemplate (std::string templateBaseName, std::vector<std::string> allParts, std::vector<std::string> partials,
      22           9 :                           const std::unordered_map<std::string, bool> & parameters)
      23          27 : : _templateBaseName (std::move (templateBaseName)), _allParts (std::move (allParts)), _parts (), _partials (std::move (partials)),
      24          90 :   _parameters (), _requiredParameters ()
      25             : {
      26         162 :         std::for_each (parameters.begin (), parameters.end (), [this](const std::pair<std::string, bool> & p) {
      27         324 :                 _parameters[p.first] = "";
      28          81 :                 if (p.second)
      29             :                 {
      30           0 :                         _requiredParameters.insert (p.first);
      31             :                 }
      32         108 :         });
      33           9 : }
      34             : 
      35          27 : void GenTemplate::render (std::ostream & output, const std::string & outputName, const std::string & part, const kdb::KeySet & ks,
      36             :                           const std::string & parentKey) const
      37             : {
      38             :         using namespace kainjow::mustache;
      39             : 
      40             :         auto missingParam = std::find_if (_requiredParameters.begin (), _requiredParameters.end (),
      41         108 :                                           [this](const std::string & p) { return getParameter (p).empty (); });
      42             : 
      43          54 :         if (missingParam != _requiredParameters.end ())
      44             :         {
      45           0 :                 throw CommandAbortException ("missing required parameter " + *missingParam);
      46             :         }
      47             : 
      48         135 :         if (std::find (_parts.begin (), _parts.end (), part) == _parts.end ())
      49             :         {
      50           2 :                 return;
      51             :         }
      52             : 
      53          52 :         auto name = _templateBaseName + part;
      54         162 :         std::replace_if (name.begin (), name.end (), std::not1 (std::ptr_fun (isalnum)), '_');
      55             : 
      56          51 :         auto data = getTemplateData (outputName, part, ks, parentKey);
      57             : 
      58          26 :         if (data.is_false ())
      59             :         {
      60           2 :                 return;
      61             :         }
      62             : 
      63          48 :         auto tmpl = mustache (kdbgenTemplates.at (name));
      64         162 :         std::function<std::string (const std::string &)> escapeFunction = [this](const std::string & str) {
      65         162 :                 return this->escapeFunction (str);
      66         234 :         };
      67          24 :         tmpl.set_custom_escape (escapeFunction);
      68             : 
      69         408 :         for (const auto & partial : getPartials ())
      70             :         {
      71         624 :                 data[partial.first] = partial.second;
      72             :         }
      73          24 :         tmpl.render (data, output);
      74             : 
      75          24 :         if (!tmpl.is_valid ())
      76             :         {
      77           0 :                 throw CommandAbortException ("Error during template rendering: " + tmpl.error_message ());
      78             :         }
      79             : }
      80             : 
      81           0 : std::string GenTemplate::escapeFunction (const std::string & str) const
      82             : {
      83           0 :         return kainjow::mustache::html_escape (str);
      84             : }
      85             : 
      86         306 : std::string GenTemplate::getParameter (const std::string & name, const std::string & defaultValue) const
      87             : {
      88         612 :         auto search = _parameters.find (name);
      89        1251 :         auto param = search != _parameters.end () ? search->second : "";
      90         918 :         return param.empty () ? defaultValue : param;
      91             : }
      92             : 
      93          27 : bool GenTemplate::getBoolParameter (const std::string & name, bool defaultValue) const
      94             : {
      95         216 :         return getParameter<bool> (name, { { "", defaultValue }, { "0", false }, { "1", true } });
      96             : }
      97             : 
      98           4 : void GenTemplate::setParameter (const std::string & name, const std::string & value)
      99             : {
     100           8 :         auto param = _parameters.find (name);
     101           8 :         if (param != _parameters.end ())
     102             :         {
     103           4 :                 param->second = value;
     104             :         }
     105           4 : }
     106             : 
     107           0 : void GenTemplate::clearParameters ()
     108             : {
     109             :         std::for_each (_parameters.begin (), _parameters.end (),
     110         270 :                        [this](const std::pair<std::string, std::string> & param) { _parameters[param.first] = ""; });
     111           0 : }
     112             : 
     113           9 : std::vector<std::string> GenTemplate::getActualParts () const
     114             : {
     115           9 :         return _allParts;
     116             : }
     117             : 
     118           9 : void GenTemplate::loadParts ()
     119             : {
     120          18 :         _parts = getActualParts ();
     121           9 : }
     122             : 
     123           9 : const std::vector<std::string> & GenTemplate::getParts () const
     124             : {
     125           9 :         return _parts;
     126             : }
     127             : 
     128          24 : std::unordered_map<std::string, kainjow::mustache::partial> GenTemplate::getPartials () const
     129             : {
     130             :         using namespace kainjow::mustache;
     131             : 
     132             :         std::unordered_map<std::string, partial> partials;
     133             : 
     134         408 :         for (const auto & partialFile : _partials)
     135             :         {
     136        1007 :                 partials["partial." + partialFile] = [&]() {
     137         213 :                         auto name = _templateBaseName + "/" + partialFile;
     138         426 :                         std::replace_if (name.begin (), name.end (), std::not1 (std::ptr_fun (isalnum)), '_');
     139         213 :                         return kdbgenTemplates.at (name);
     140         936 :                 };
     141             :         }
     142             : 
     143          24 :         return partials;
     144             : }
     145             : 
     146             : template <class genClass>
     147           9 : void GenTemplateList::addTemplate (const std::string & name)
     148             : {
     149          27 :         std::unique_ptr<GenTemplate> tmpl (new genClass ());
     150          27 :         _templates[name] = std::move (tmpl);
     151           9 : }
     152             : 
     153           9 : const GenTemplate * GenTemplateList::getTemplate (const std::string & name,
     154             :                                                   const std::unordered_map<std::string, std::string> & parameters) const
     155             : {
     156          18 :         auto search = _templates.find (name);
     157          18 :         if (search == _templates.end ())
     158             :         {
     159           0 :                 return &EmptyGenTemplate::getInstance ();
     160             :         }
     161             : 
     162          18 :         auto tmpl = search->second.get ();
     163           9 :         tmpl->clearParameters ();
     164             :         std::for_each (parameters.begin (), parameters.end (),
     165          31 :                        [tmpl](const std::pair<std::string, std::string> & param) { tmpl->setParameter (param.first, param.second); });
     166           9 :         tmpl->loadParts ();
     167             :         return tmpl;
     168             : }
     169             : 
     170          18 : GenTemplateList::GenTemplateList () : _templates ()
     171             : {
     172          36 :         addTemplate<HighlevelGenTemplate> ("highlevel");
     173       10755 : }

Generated by: LCOV version 1.13