LCOV - code coverage report
Current view: top level - src/plugins/line - line.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 48 61 78.7 %
Date: 2022-05-21 16:19:22 Functions: 5 6 83.3 %

          Line data    Source code
       1             : /**
       2             :  * @file
       3             :  *
       4             :  * @brief A plugin that reads configuration files and saves keys on a line by line basis *
       5             :  * @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
       6             :  *
       7             :  */
       8             : 
       9             : #ifndef HAVE_KDBCONFIG
      10             : #include "kdbconfig.h"
      11             : #endif
      12             : 
      13             : #include "line.h"
      14             : 
      15             : #include <kdbease.h>
      16             : #include <kdberrors.h>
      17             : 
      18             : #include <errno.h>
      19             : #include <stddef.h>
      20             : // The definition `_WITH_GETLINE` is required for FreeBSD
      21             : #define _WITH_GETLINE
      22             : #include <stdio.h>
      23             : #include <stdlib.h>
      24             : #include <string.h>
      25             : 
      26          60 : static inline KeySet * elektraLineContract (void)
      27             : {
      28          60 :         return ksNew (30, keyNew ("system:/elektra/modules/line", KEY_VALUE, "line plugin waits for your orders", KEY_END),
      29             :                       keyNew ("system:/elektra/modules/line/exports", KEY_END),
      30             :                       keyNew ("system:/elektra/modules/line/exports/get", KEY_FUNC, elektraLineGet, KEY_END),
      31             :                       keyNew ("system:/elektra/modules/line/exports/set", KEY_FUNC, elektraLineSet, KEY_END),
      32             : #include "readme_line.c"
      33             :                       keyNew ("system:/elektra/modules/line/infos/version", KEY_VALUE, PLUGINVERSION, KEY_END), KS_END);
      34             : }
      35             : 
      36          23 : int elektraLineRead (FILE * fp, KeySet * returned)
      37             : {
      38          23 :         char * value = NULL;
      39          23 :         size_t len = 0;
      40          23 :         ssize_t n = 0;
      41          23 :         Key * read = NULL;
      42             : 
      43             :         // Read in each line
      44         162 :         while ((n = getline (&value, &len, fp)) != -1)
      45             :         {
      46             :                 // Remove trailing newline
      47         139 :                 if (value[n - 1] == '\n')
      48             :                 {
      49         139 :                         value[n - 1] = '\0';
      50             :                 }
      51         139 :                 read = keyDup (ksTail (returned), KEY_CP_ALL);
      52         139 :                 if (elektraArrayIncName (read) == -1)
      53             :                 {
      54           0 :                         elektraFree (value);
      55           0 :                         keyDel (read);
      56           0 :                         return -1;
      57             :                 }
      58         139 :                 keySetString (read, value);
      59             : 
      60         139 :                 ksAppendKey (returned, read);
      61             :         }
      62          23 :         elektraFree (value);
      63             : 
      64          23 :         return 1;
      65             : }
      66             : 
      67             : 
      68          83 : int elektraLineGet (Plugin * handle ELEKTRA_UNUSED, KeySet * returned, Key * parentKey)
      69             : {
      70             :         /* get all keys */
      71             : 
      72          83 :         if (!strcmp (keyName (parentKey), "system:/elektra/modules/line"))
      73             :         {
      74          60 :                 KeySet * moduleConfig = elektraLineContract ();
      75          60 :                 ksAppend (returned, moduleConfig);
      76          60 :                 ksDel (moduleConfig);
      77          60 :                 return 1;
      78             :         }
      79             : 
      80          23 :         int errnosave = errno;
      81          23 :         FILE * fp = fopen (keyString (parentKey), "r");
      82             : 
      83          23 :         if (!fp)
      84             :         {
      85           0 :                 ELEKTRA_SET_ERROR_GET (parentKey);
      86           0 :                 errno = errnosave;
      87           0 :                 return -1;
      88             :         }
      89             : 
      90          23 :         Key * b = keyNew (keyName (parentKey), KEY_END);
      91          23 :         ksAppendKey (returned, keyDup (b, KEY_CP_ALL)); // start with parentKey
      92          23 :         keyAddName (b, "#");                          // start point for our array
      93          23 :         ksAppendKey (returned, b);
      94             : 
      95          23 :         int ret = elektraLineRead (fp, returned);
      96             : 
      97             :         // get rid of startpoint, if it was an empty file
      98          23 :         keyDel (ksLookup (returned, b, KDB_O_POP));
      99             : 
     100          23 :         if (ret == -1)
     101             :         {
     102           0 :                 ELEKTRA_SET_VALIDATION_SYNTACTIC_ERRORF (parentKey, "Could not increment array from %s", keyName (ksTail (returned)));
     103           0 :                 ret = -1;
     104             :         }
     105          23 :         else if (feof (fp) == 0)
     106             :         {
     107           0 :                 ELEKTRA_SET_VALIDATION_SYNTACTIC_ERROR (parentKey, "Invalid line encountered: not at the end of file");
     108           0 :                 ret = -1;
     109             :         }
     110             : 
     111          23 :         fclose (fp);
     112             : 
     113          23 :         return ret; /* success */
     114             : }
     115             : 
     116           6 : int elektraLineSet (Plugin * handle ELEKTRA_UNUSED, KeySet * returned, Key * parentKey)
     117             : {
     118             :         /* set all keys */
     119             : 
     120           6 :         int errnosave = errno;
     121           6 :         FILE * fp = fopen (keyString (parentKey), "w");
     122             : 
     123           6 :         if (!fp)
     124             :         {
     125           0 :                 ELEKTRA_SET_ERROR_SET (parentKey);
     126           0 :                 errno = errnosave;
     127           0 :                 return -1;
     128             :         }
     129             : 
     130           6 :         Key * cur;
     131           6 :         if (!ksLookup (returned, parentKey, 0))
     132             :         {
     133             :                 // ignore parentKey if found
     134           1 :                 ksRewind (returned);
     135             :         }
     136             : 
     137          20 :         while ((cur = ksNext (returned)) != 0)
     138             :         {
     139          14 :                 fprintf (fp, "%s\n", keyString (cur));
     140             :         }
     141             : 
     142           6 :         fclose (fp);
     143             : 
     144           6 :         return 1; /* success */
     145             : }
     146             : 
     147         147 : Plugin * ELEKTRA_PLUGIN_EXPORT
     148             : {
     149             :         // clang-format off
     150         147 :         return elektraPluginExport("line",
     151             :                 ELEKTRA_PLUGIN_GET,     &elektraLineGet,
     152             :                 ELEKTRA_PLUGIN_SET,     &elektraLineSet,
     153             :                 ELEKTRA_PLUGIN_END);
     154             : }

Generated by: LCOV version 1.13