LCOV - code coverage report
Current view: top level - src/plugins/yanlr - yanlr.cpp (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 35 37 94.6 %
Date: 2019-09-12 12:28:41 Functions: 5 6 83.3 %

          Line data    Source code
       1             : /**
       2             :  * @file
       3             :  *
       4             :  * @brief Source for yanlr plugin
       5             :  *
       6             :  * @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
       7             :  *
       8             :  */
       9             : 
      10             : // -- Imports ------------------------------------------------------------------------------------------------------------------------------
      11             : 
      12             : #include <iostream>
      13             : 
      14             : #include <kdb.hpp>
      15             : #include <kdberrors.h>
      16             : 
      17             : #include <antlr4-runtime.h>
      18             : 
      19             : #include "YAML.h"
      20             : #include "error_listener.hpp"
      21             : #include "listener.hpp"
      22             : #include "yaml_lexer.hpp"
      23             : #include "yanlr.hpp"
      24             : 
      25             : using CppKey = kdb::Key;
      26             : using CppKeySet = kdb::KeySet;
      27             : 
      28             : using yanlr::ErrorListener;
      29             : using yanlr::KeyListener;
      30             : using yanlr::YAML;
      31             : using yanlr::YAMLLexer;
      32             : 
      33             : using antlr4::ANTLRInputStream;
      34             : using antlr4::CommonTokenStream;
      35             : using antlr4::DiagnosticErrorListener;
      36             : using ParserATNSimulator = antlr4::atn::ParserATNSimulator;
      37             : using PredictionMode = antlr4::atn::PredictionMode;
      38             : using ParseTree = antlr4::tree::ParseTree;
      39             : using ParseTreeWalker = antlr4::tree::ParseTreeWalker;
      40             : 
      41             : using std::ifstream;
      42             : 
      43             : // -- Functions ----------------------------------------------------------------------------------------------------------------------------
      44             : 
      45             : namespace
      46             : {
      47             : /**
      48             :  * @brief This function returns a key set containing the contract of this plugin.
      49             :  *
      50             :  * @return A contract describing the functionality of this plugin.
      51             :  */
      52         160 : CppKeySet getContract ()
      53             : {
      54             :         return CppKeySet{ 30,
      55             :                           keyNew ("system/elektra/modules/yanlr", KEY_VALUE, "yanlr plugin waits for your orders", KEY_END),
      56             :                           keyNew ("system/elektra/modules/yanlr/exports", KEY_END),
      57             :                           keyNew ("system/elektra/modules/yanlr/exports/get", KEY_FUNC, elektraYanlrGet, KEY_END),
      58             : #include ELEKTRA_README
      59             :                           keyNew ("system/elektra/modules/yanlr/infos/version", KEY_VALUE, PLUGINVERSION, KEY_END),
      60         160 :                           KS_END };
      61             : }
      62             : 
      63             : /**
      64             :  * @brief This function parses the content of a YAML file and saves the result in the given key set.
      65             :  *
      66             :  * @param file This file contains the YAML content this function should parse.
      67             :  * @param keys The function adds the key set representing `file` in this key set, if the parsing process finished successfully.
      68             :  * @param parent The function uses this parameter to emit error information.
      69             :  *
      70             :  * @retval ELEKTRA_PLUGIN_STATUS_NO_UPDATE If parsing was successful and `keys` was not updated
      71             :  * @retval ELEKTRA_PLUGIN_STATUS_SUCCESS If parsing was successful and `keys` was updated
      72             :  * @retval ELEKTRA_PLUGIN_STATUS_ERROR If there was an error parsing `file`
      73             :  */
      74          31 : int parseYAML (ifstream & file, CppKeySet & keys, CppKey & parent)
      75             : {
      76          62 :         ANTLRInputStream input{ file };
      77          62 :         YAMLLexer lexer{ &input };
      78          62 :         CommonTokenStream tokens{ &lexer };
      79          62 :         YAML parser{ &tokens };
      80          93 :         ParseTreeWalker walker{};
      81          93 :         KeyListener listener{ parent };
      82             : 
      83          93 :         ErrorListener errorListener{ parent.getString () };
      84          31 :         parser.removeErrorListeners ();
      85          31 :         parser.addErrorListener (&errorListener);
      86             : #if DEBUG
      87          62 :         DiagnosticErrorListener diagErrorListener;
      88          31 :         parser.addErrorListener (&diagErrorListener);
      89          62 :         parser.getInterpreter<ParserATNSimulator> ()->setPredictionMode (PredictionMode::LL_EXACT_AMBIG_DETECTION);
      90             : #endif
      91             : 
      92          31 :         ParseTree * tree = parser.yaml ();
      93          31 :         if (parser.getNumberOfSyntaxErrors () > 0)
      94             :         {
      95           6 :                 ELEKTRA_SET_VALIDATION_SYNTACTIC_ERROR (parent.getKey (), errorListener.message ());
      96             :                 return ELEKTRA_PLUGIN_STATUS_ERROR;
      97             :         }
      98          28 :         walker.walk (&listener, tree);
      99             : 
     100          28 :         auto readKeys = listener.keySet ();
     101          28 :         keys.append (readKeys);
     102          28 :         return readKeys.size () <= 0 ? ELEKTRA_PLUGIN_STATUS_NO_UPDATE : ELEKTRA_PLUGIN_STATUS_SUCCESS;
     103             : }
     104             : 
     105             : } // end namespace
     106             : 
     107             : extern "C" {
     108             : // ====================
     109             : // = Plugin Interface =
     110             : // ====================
     111             : 
     112             : /** @see elektraDocGet */
     113         191 : int elektraYanlrGet (Plugin * handle ELEKTRA_UNUSED, KeySet * returned, Key * parentKey)
     114             : {
     115         382 :         CppKey parent{ parentKey };
     116         382 :         CppKeySet keys{ returned };
     117             : 
     118         573 :         if (parent.getName () == "system/elektra/modules/yanlr")
     119             :         {
     120         480 :                 keys.append (getContract ());
     121         160 :                 keys.release ();
     122             :                 parent.release ();
     123             : 
     124             :                 return ELEKTRA_PLUGIN_STATUS_SUCCESS;
     125             :         }
     126             : 
     127          93 :         ifstream file (parent.getString ());
     128          31 :         if (!file.is_open ())
     129             :         {
     130           0 :                 ELEKTRA_SET_RESOURCE_ERRORF (parent.getKey (), "Unable to open file '%s'", parent.getString ().c_str ());
     131           0 :                 return ELEKTRA_PLUGIN_STATUS_ERROR;
     132             :         }
     133             : 
     134          31 :         int status = parseYAML (file, keys, parent);
     135             : 
     136          31 :         keys.release ();
     137             :         parent.release ();
     138             : 
     139             :         return status;
     140             : }
     141             : 
     142         356 : Plugin * ELEKTRA_PLUGIN_EXPORT
     143             : {
     144         356 :         return elektraPluginExport ("yanlr", ELEKTRA_PLUGIN_GET, &elektraYanlrGet, ELEKTRA_PLUGIN_END);
     145             : }
     146             : 
     147         140 : } // end extern "C"

Generated by: LCOV version 1.13