LCOV - code coverage report
Current view: top level - examples - functional.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 0 68 0.0 %
Date: 2019-09-12 12:28:41 Functions: 0 11 0.0 %

          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 <kdb.h>
      10             : 
      11             : // for keySetComment
      12             : #include <kdbextension.h>
      13             : 
      14             : #include <stdlib.h>
      15             : 
      16             : /**A functional access to keys.
      17             :  *
      18             :  * Instead of writing your own loop you can write
      19             :  * a function working with a key and pass it to
      20             :  * this method.
      21             :  *
      22             :  * The function will be executed for all keys in
      23             :  * the keyset.
      24             :  *
      25             :  * @param ks the keyset to work with
      26             :  * @param func the function to execute on every key of the keyset
      27             :  * @return the sum of all return values
      28             :  * @retval -1 if any function returned -1, the execution will stop there, but
      29             :  *      ksCurrent() will tell you where it stopped.
      30             :  * @see ksFilter()
      31             :  */
      32           0 : int ksForEach (KeySet * ks, int (*func) (Key * k))
      33             : {
      34           0 :         int ret = 0;
      35             :         Key * current;
      36             : 
      37           0 :         cursor_t cursor = ksGetCursor (ks);
      38           0 :         ksRewind (ks);
      39           0 :         while ((current = ksNext (ks)) != 0)
      40             :         {
      41           0 :                 int rc = func (current);
      42           0 :                 if (rc == -1) return -1;
      43           0 :                 ret += rc;
      44             :         }
      45           0 :         ksSetCursor (ks, cursor);
      46           0 :         return ret;
      47             : }
      48             : 
      49             : 
      50             : /**Filter a keyset.
      51             :  *
      52             :  * filter is executed for every key in the keyset result. When it returns 0,
      53             :  * the key will be dropped, when it returns 1 it will be ksAppendKey()ed to result,
      54             :  * when it returns -1 the processing will be stopped. You can use ksCurrent()
      55             :  * on input to see where the problem was. Because of this input is not const,
      56             :  * apart from ksCurrent() the input will not be changed. The keys that have
      57             :  * been in result before will stay untouched.
      58             :  *
      59             :  * @param result is the keyset where keys are added.
      60             :  * @param input is the keyset the filter works on.
      61             :  * @param filter is the function to execute on every key of the keyset to decide if
      62             :  *      it should be ksAppendKey()ed to the result.
      63             :  * @return the number of keys added on success
      64             :  * @retval 0 when nothing was done
      65             :  * @retval -1 when filter returned an error (-1), ksCurrent() of input will
      66             :  *      be the problematic key.
      67             :  * @see ksForEach()
      68             :  **/
      69           0 : int ksFilter (KeySet * result, KeySet * input, int (*filter) (Key * k))
      70             : {
      71           0 :         int ret = 0;
      72             :         Key * current;
      73             : 
      74           0 :         cursor_t cursor = ksGetCursor (input);
      75           0 :         ksRewind (input);
      76           0 :         while ((current = ksNext (input)) != 0)
      77             :         {
      78           0 :                 int rc = filter (current);
      79           0 :                 if (rc == -1)
      80             :                         return -1;
      81           0 :                 else if (rc != 0)
      82             :                 {
      83           0 :                         ++ret;
      84           0 :                         ksAppendKey (result, keyDup (current));
      85             :                 }
      86             :         }
      87           0 :         ksSetCursor (input, cursor);
      88           0 :         return ret;
      89             : }
      90             : 
      91             : 
      92             : Key * global_a;
      93             : 
      94           0 : int add_string (Key * check)
      95             : {
      96           0 :         return keySetString (check, "string");
      97             : }
      98           0 : int add_comment (Key * check)
      99             : {
     100           0 :         return keySetMeta (check, "comment", "comment");
     101             : }
     102           0 : int has_a (Key * check)
     103             : {
     104           0 :         return keyName (check)[5] == 'a';
     105             : }
     106           0 : int below_a (Key * check)
     107             : {
     108           0 :         return keyIsBelow (global_a, check);
     109             : }
     110           0 : int direct_below_a (Key * check)
     111             : {
     112           0 :         return keyIsDirectBelow (global_a, check);
     113             : }
     114             : 
     115           0 : int sum_helper (Key * check)
     116             : {
     117           0 :         return atoi (keyValue (check));
     118             : }
     119           0 : int below_30 (Key * check)
     120             : {
     121           0 :         return atoi (keyValue (check)) < 30;
     122             : }
     123           0 : int find_80 (Key * check)
     124             : {
     125           0 :         int n = atoi (keyValue (check));
     126           0 :         return n > 70 ? -1 : 1;
     127             : }
     128             : 
     129           0 : int main (void)
     130             : {
     131             :         KeySet * out;
     132           0 :         KeySet * ks = ksNew (64, keyNew ("user/a/1", KEY_END), keyNew ("user/a/2", KEY_END), keyNew ("user/a/b/1", KEY_END),
     133             :                              keyNew ("user/a/b/2", KEY_END), keyNew ("user/ab/2", KEY_END), keyNew ("user/b/1", KEY_END),
     134             :                              keyNew ("user/b/2", KEY_END), KS_END);
     135           0 :         KeySet * values = 0;
     136           0 :         KeySet * values_below_30 = 0;
     137             : 
     138           0 :         global_a = keyNew ("user/a", KEY_END);
     139             : 
     140           0 :         ksForEach (ks, add_string);
     141           0 :         ksForEach (ks, add_comment);
     142             : 
     143           0 :         out = ksNew (0, KS_END);
     144           0 :         ksFilter (out, ks, has_a);
     145           0 :         ksDel (out);
     146             : 
     147           0 :         out = ksNew (0, KS_END);
     148           0 :         ksFilter (out, ks, below_a);
     149           0 :         ksDel (out);
     150             : 
     151           0 :         out = ksNew (0, KS_END);
     152           0 :         ksFilter (out, ks, direct_below_a);
     153           0 :         ksDel (out);
     154             : 
     155           0 :         ksDel (ks);
     156           0 :         keyDel (global_a);
     157           0 :         global_a = 0;
     158             : 
     159           0 :         values = ksNew (64, keyNew ("user/a", KEY_VALUE, "40", KEY_END), keyNew ("user/b", KEY_VALUE, "20", KEY_END),
     160             :                         keyNew ("user/c", KEY_VALUE, "80", KEY_END), keyNew ("user/d", KEY_VALUE, "24", KEY_END),
     161             :                         keyNew ("user/e", KEY_VALUE, "32", KEY_END), keyNew ("user/f", KEY_VALUE, "12", KEY_END),
     162             :                         keyNew ("user/g", KEY_VALUE, "43", KEY_END), KS_END);
     163             : 
     164             :         /* add together */
     165           0 :         ksForEach (values, sum_helper);
     166             : 
     167           0 :         values_below_30 = ksNew (0, KS_END);
     168           0 :         ksFilter (values_below_30, values, below_30);
     169           0 :         ksForEach (values_below_30, sum_helper);
     170             : 
     171           0 :         ksForEach (values, find_80);
     172           0 :         ksCurrent (values);                   /* here is user/c */
     173           0 :         ksLookupByName (values, "user/c", 0); /* should find the same */
     174           0 :         ksDel (values);
     175           0 :         ksDel (values_below_30);
     176             : }

Generated by: LCOV version 1.13