LCOV - code coverage report
Current view: top level - tests/abi - testabi_ks.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 1971 1979 99.6 %
Date: 2022-05-21 16:19:22 Functions: 57 57 100.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 <tests.h>
      10             : 
      11             : #define NUMBER_OF_NAMESPACES 5
      12             : 
      13             : char * namespaces[] = { "spec:/", "proc:/", "dir:/", "user:/", "system:/", 0 };
      14             : 
      15           3 : static void test_ksNew (void)
      16             : {
      17           3 :         KeySet * ks = 0;
      18           3 :         KeySet * keys = ksNew (15, KS_END);
      19           3 :         KeySet * config;
      20             : 
      21           3 :         printf ("Test ks creation\n");
      22           3 :         exit_if_fail ((ks = ksNew (0, KS_END)) != 0, "could not create new keyset");
      23             : 
      24           3 :         succeed_if (ksAppendKey (ks, keyNew ("user:/a", KEY_END)) == 1, "could not append a key");
      25           3 :         succeed_if (ksAppendKey (ks, keyNew ("user:/b", KEY_END)) == 2, "could not append a key");
      26           3 :         succeed_if (ksAppendKey (ks, keyNew ("user:/c", KEY_END)) == 3, "could not append a key");
      27           3 :         succeed_if (ksGetSize (ks) == 3, "size not correct after 3 keys");
      28             : 
      29           3 :         KeySet * ks2 = ksNew (0, KS_END);
      30           3 :         ksCopy (ks2, ks);
      31          15 :         compare_keyset (ks, ks2);
      32             : 
      33           3 :         succeed_if (ksAppendKey (ks, keyNew ("user:/d", KEY_END)) == 4, "could not append a key");
      34           3 :         succeed_if (ksAppendKey (ks, keyNew ("user:/e", KEY_END)) == 5, "could not append a key");
      35           3 :         succeed_if (ksAppendKey (ks, keyNew ("user:/f", KEY_END)) == 6, "could not append a key");
      36           3 :         succeed_if (ksGetSize (ks) == 6, "could not append 3 more keys");
      37             : 
      38           3 :         ksCopy (ks2, ks);
      39          24 :         compare_keyset (ks, ks2);
      40             : 
      41           3 :         ksClear (ks2); // useless, just test for double free
      42           3 :         ksCopy (ks2, ks);
      43          24 :         compare_keyset (ks, ks2);
      44             : 
      45           3 :         succeed_if (ksDel (ks) == 0, "could not delete keyset");
      46             : 
      47             : 
      48           3 :         succeed_if (ksGetSize (keys) == 0, "could not append 3 more keys");
      49             :         // succeed_if(ksGetAlloc(keys) == 15, "allocation size wrong");
      50           3 :         succeed_if (ksDel (keys) == 0, "could not delete keyset");
      51             : 
      52           3 :         config = ksNew (100, keyNew ("user:/sw/app/fixedConfiguration/key1", KEY_VALUE, "value1", KEY_END),
      53             :                         keyNew ("user:/sw/app/fixedConfiguration/key2", KEY_VALUE, "value2", KEY_END),
      54             :                         keyNew ("user:/sw/app/fixedConfiguration/key3", KEY_VALUE, "value3", KEY_END), KS_END);
      55           3 :         succeed_if (ksGetSize (config) == 3, "could not append 3 keys in keyNew");
      56             :         // this behaviour might change, do not build on it,
      57             :         // and there is no compatible way to get the alloc info
      58             :         // succeed_if(ksGetAlloc(config) == 100, "allocation size wrong");
      59           3 :         keyDel (ksPop (config));
      60             :         // succeed_if(ksGetAlloc(config) == 49, "allocation size wrong");
      61           3 :         keyDel (ksPop (config));
      62             :         // succeed_if(ksGetAlloc(config) == 24, "allocation size wrong");
      63           3 :         keyDel (ksPop (config));
      64             :         // succeed_if(ksGetAlloc(config) == 15, "allocation size wrong");
      65           3 :         succeed_if (ksDel (config) == 0, "could not delete keyset");
      66             : 
      67           3 :         config = ksNew (10, keyNew ("user:/sw/app/fixedConfiguration/key1", KEY_VALUE, "value1", KEY_END),
      68             :                         keyNew ("user:/sw/app/fixedConfiguration/key2", KEY_VALUE, "value2", KEY_END),
      69             :                         keyNew ("user:/sw/app/fixedConfiguration/key3", KEY_VALUE, "value1", KEY_END),
      70             :                         keyNew ("user:/sw/app/fixedConfiguration/key4", KEY_VALUE, "value3", KEY_END), KS_END);
      71             : 
      72           3 :         succeed_if (ksGetSize (config) == 4, "could not append 5 keys in keyNew");
      73             :         // succeed_if(ksGetAlloc(config) == 15, "allocation size wrong");
      74           3 :         ksAppendKey (config, keyNew ("user:/sw/app/fixedConfiguration/key6", KEY_VALUE, "value4", KEY_END));
      75             : 
      76           3 :         ksClear (ks2);
      77           3 :         ksCopy (ks2, config);
      78          21 :         compare_keyset (config, ks2);
      79             : 
      80           3 :         succeed_if (ksDel (config) == 0, "could not delete keyset");
      81           3 :         succeed_if (ksDel (ks2) == 0, "could not delete keyset");
      82             : 
      83           3 :         KeySet * ks_c = ksNew (5, keyNew ("user:/valid/key1", KEY_END), keyNew ("user:/valid/key2", KEY_END),
      84             :                                keyNew ("system:/valid/key1", KEY_END), keyNew ("system:/valid/key2", KEY_END), KS_END);
      85             : 
      86           3 :         succeed_if (ksCurrent (ks_c) == 0, "should be rewinded");
      87           3 :         ksDel (ks_c);
      88             : 
      89           3 :         succeed_if (ksDel (0) == -1, "No error on NULL pointer");
      90           3 : }
      91             : 
      92           3 : static void test_ksEmpty (void)
      93             : {
      94           3 :         printf ("Test empty keysets\n");
      95           3 :         KeySet * ks;
      96           3 :         KeySet * ks2;
      97           3 :         Key * current;
      98             : 
      99           3 :         ks = ksNew (0, KS_END);
     100           3 :         succeed_if (ksGetSize (ks) == 0, "size not correct");
     101           3 :         succeed_if (ksPop (ks) == 0, "pop empty keyset");
     102           3 :         succeed_if (ksGetSize (ks) == 0, "size not correct");
     103           3 :         ksDel (ks);
     104             : 
     105           3 :         ks = ksNew (1, current = keyNew ("user:/test", KEY_END), KS_END);
     106           3 :         succeed_if (ksGetSize (ks) == 1, "size not correct");
     107           3 :         succeed_if (ksPop (ks) == current, "pop empty keyset");
     108           3 :         succeed_if (ksGetSize (ks) == 0, "size not correct");
     109           3 :         succeed_if (ksPop (ks) == 0, "pop empty keyset");
     110           3 :         succeed_if (ksGetSize (ks) == 0, "size not correct");
     111           3 :         keyDel (current);
     112           3 :         ksDel (ks);
     113             : 
     114           3 :         ks = ksNew (0, KS_END);
     115           3 :         ks2 = ksNew (0, KS_END);
     116           3 :         succeed_if (ksAppend (ks, ks2) == 0, "could not append empty keyset");
     117           3 :         succeed_if (ksGetSize (ks) == 0, "empty keyset does not have correct size");
     118           3 :         succeed_if (ksGetSize (ks2) == 0, "empty keyset does not have correct size");
     119           3 :         succeed_if (ksPop (ks) == 0, "could not pop empty keyset");
     120           3 :         succeed_if (ksPop (ks2) == 0, "could not pop empty keyset2");
     121           3 :         ksDel (ks);
     122           3 :         ksDel (ks2);
     123             : 
     124           3 :         ks = ksNew (1, current = keyNew ("user:/test", KEY_END), KS_END);
     125           3 :         ks2 = ksNew (0, KS_END);
     126           3 :         succeed_if (ksGetSize (ks) == 1, "empty keyset does not have correct size");
     127           3 :         succeed_if (ksGetSize (ks2) == 0, "empty keyset does not have correct size");
     128           3 :         succeed_if (ksAppend (ks, ks2) == 1, "could not append empty keyset");
     129           3 :         succeed_if (ksGetSize (ks) == 1, "empty keyset does not have correct size");
     130           3 :         succeed_if (ksGetSize (ks2) == 0, "empty keyset does not have correct size");
     131           3 :         succeed_if (ksPop (ks) == current, "could not pop keyset");
     132           3 :         succeed_if (ksPop (ks2) == 0, "could not pop empty keyset2");
     133           3 :         succeed_if (ksGetSize (ks) == 0, "empty keyset does not have correct size");
     134           3 :         succeed_if (ksGetSize (ks2) == 0, "empty keyset does not have correct size");
     135           3 :         succeed_if (ksAppend (ks, ks2) == 0, "could not append empty keyset");
     136           3 :         succeed_if (ksGetSize (ks) == 0, "empty keyset does not have correct size");
     137           3 :         succeed_if (ksGetSize (ks2) == 0, "empty keyset does not have correct size");
     138           3 :         keyDel (current);
     139           3 :         ksDel (ks);
     140           3 :         ksDel (ks2);
     141             : 
     142             : 
     143           3 :         ks = ksNew (0, KS_END);
     144           3 :         ks2 = ksNew (1, current = keyNew ("user:/test", KEY_END), KS_END);
     145           3 :         succeed_if (ksGetSize (ks) == 0, "empty keyset does not have correct size");
     146           3 :         succeed_if (ksGetSize (ks2) == 1, "empty keyset does not have correct size");
     147           3 :         succeed_if (ksAppend (ks, ks2) == 1, "could not append empty keyset");
     148           3 :         succeed_if (ksGetSize (ks) == 1, "empty keyset does not have correct size");
     149           3 :         succeed_if (ksGetSize (ks2) == 1, "empty keyset does not have correct size");
     150           3 :         succeed_if (ksPop (ks) == current, "could not pop keyset");
     151           3 :         succeed_if (ksPop (ks2) == current, "could not pop empty keyset2");
     152           3 :         succeed_if (ksGetSize (ks) == 0, "empty keyset does not have correct size");
     153           3 :         succeed_if (ksGetSize (ks2) == 0, "empty keyset does not have correct size");
     154           3 :         succeed_if (ksAppend (ks, ks2) == 0, "could not append empty keyset");
     155           3 :         succeed_if (ksGetSize (ks) == 0, "empty keyset does not have correct size");
     156           3 :         succeed_if (ksGetSize (ks2) == 0, "empty keyset does not have correct size");
     157           3 :         keyDel (current); // only one keyDel, because ksPop decrements counter
     158           3 :         ksDel (ks);
     159           3 :         ksDel (ks2);
     160           3 : }
     161             : 
     162             : #define NR_KEYSETS 10
     163             : 
     164           3 : static void test_ksReference (void)
     165             : {
     166           3 :         KeySet * ks = 0;
     167           3 :         KeySet * ks1;
     168           3 :         Key *k1, *k2;
     169           3 :         KeySet * kss[NR_KEYSETS];
     170           3 :         int i;
     171             : 
     172           3 :         printf ("Test reference of key\n");
     173             : 
     174           3 :         ks = ksNew (0, KS_END);
     175           3 :         k1 = keyNew ("user:/aname", KEY_END);
     176             : 
     177           3 :         succeed_if (ksHead (0) == 0, "Not NULL on NULL KeySet");
     178           3 :         succeed_if (ksTail (0) == 0, "Not NULL on NULL KeySet");
     179             : 
     180           3 :         succeed_if (ksHead (ks) == 0, "Not NULL on empty KeySet");
     181           3 :         succeed_if (ksTail (ks) == 0, "Not NULL on empty KeySet");
     182             : 
     183           3 :         succeed_if (keyGetRef (k1) == 0, "reference counter of new key");
     184           3 :         succeed_if (ksAppendKey (ks, k1) == 1, "size should be one");
     185           3 :         succeed_if (keyGetRef (k1) == 1, "reference counter of inserted key");
     186           3 :         succeed_if (ksGetSize (ks) == 1, "wrong size, should stay after inserting duplication");
     187           3 :         succeed_if (ksHead (ks) == k1, "head wrong");
     188           3 :         succeed_if (ksTail (ks) == k1, "tail wrong");
     189             : 
     190           3 :         k2 = keyDup (k1, KEY_CP_ALL);
     191           3 :         keySetString (k2, "newvalue");
     192             : 
     193           3 :         succeed_if (keyGetRef (k2) == 0, "reference counter not resetted");
     194           3 :         succeed_if (ksAppendKey (ks, k2) == 1, "size should stay at 1");
     195             :         // k1 should be freed by now and instead k2 in the keyset
     196           3 :         succeed_if (ksGetSize (ks) == 1, "wrong size, should stay after inserting duplication");
     197             : 
     198           3 :         ksRewind (ks);
     199           3 :         ksNext (ks);
     200           3 :         succeed_if_same_string (keyValue (ksCurrent (ks)), "newvalue");
     201             : 
     202           3 :         ksDel (ks);
     203             : 
     204           3 :         ks = ksNew (5, keyNew ("user:/key", KEY_END), keyNew ("system:/key", KEY_END), KS_END);
     205             : 
     206           3 :         k1 = ksLookupByName (ks, "system:/key", 0);
     207           3 :         k2 = ksLookupByName (ks, "user:/key", 0);
     208           3 :         succeed_if (keyGetRef (k1) == 1, "reference counter of new inserted key");
     209           3 :         succeed_if (keyGetRef (k2) == 1, "reference counter of new inserted key");
     210           3 :         succeed_if (ksHead (ks) == k2, "head wrong");
     211           3 :         succeed_if (ksTail (ks) == k1, "tail wrong");
     212             : 
     213           3 :         ksDel (ks);
     214             : 
     215           3 :         ks = ksNew (5, keyNew ("user:/key", KEY_END), keyNew ("system:/key", KEY_END), KS_END);
     216             : 
     217           3 :         k1 = ksLookupByName (ks, "system:/key", 0);
     218           3 :         k2 = ksLookupByName (ks, "user:/key", 0);
     219           3 :         succeed_if (keyGetRef (k1) == 1, "reference counter of new inserted key");
     220           3 :         succeed_if (keyGetRef (k2) == 1, "reference counter of new inserted key");
     221           3 :         ks1 = ksDup (ks);
     222           3 :         succeed_if (ksHead (ks1) == k2, "head in dup wrong");
     223           3 :         succeed_if (ksTail (ks1) == k1, "tail in dup wrong");
     224             : 
     225           3 :         succeed_if (keyGetRef (k1) == 2, "reference counter after duplication of keyset");
     226           3 :         succeed_if (keyGetRef (k2) == 2, "reference counter after ksdup");
     227           3 :         k1 = ksPop (ks);
     228           3 :         succeed_if (keyGetRef (k1) == 1, "reference counter after pop");
     229           3 :         keyDel (k1);
     230           3 :         succeed_if (keyGetRef (k1) == 1, "reference counter");
     231           3 :         succeed_if (keyGetRef (k2) == 2, "reference counter should not be influenced");
     232             : 
     233           3 :         ksDel (ks);
     234           3 :         succeed_if (keyGetRef (k1) == 1, "reference counter, delete from first keyset");
     235           3 :         succeed_if (keyGetRef (k2) == 1, "reference counter, delete from first keyset");
     236           3 :         ksDel (ks1); // k1 and k2 deleted
     237             : 
     238           3 :         ks1 = ksNew (0, KS_END);
     239           3 :         k1 = keyNew ("user:/k1", KEY_END);
     240           3 :         succeed_if (keyGetRef (k1) == 0, "reference counter of new inserted key");
     241           3 :         succeed_if (ksAppendKey (ks1, k1) == 1, "appending did not work");
     242           3 :         succeed_if (ksGetSize (ks1) == 1, "size did not match");
     243           3 :         succeed_if (keyGetRef (k1) == 1, "reference counter of new inserted key");
     244           3 :         succeed_if (ksAppendKey (ks1, k1) == 1, "appending the very same key");
     245           3 :         succeed_if (ksGetSize (ks1) == 1, "size did not match");
     246           3 :         succeed_if (keyGetRef (k1) == 1, "reference counter of new inserted key should stay the same");
     247             : 
     248           3 :         k1 = ksPop (ks1);
     249           3 :         succeed_if (keyGetRef (k1) == 0, "reference counter of new inserted key");
     250           3 :         succeed_if (keyDel (k1) == 0, "keyDel did not work");
     251             : 
     252           3 :         succeed_if (ksDel (ks1) == 0, "could not delete key");
     253             : 
     254             : 
     255           3 :         kss[0] = ksNew (5, k1 = keyNew ("user:/key", KEY_END), k2 = keyNew ("system:/key", KEY_END), KS_END);
     256          30 :         for (i = 1; i < NR_KEYSETS; i++)
     257             :         {
     258          27 :                 succeed_if (keyGetRef (k1) == i, "reference counter");
     259          27 :                 succeed_if (keyGetRef (k2) == 1, "reference counter");
     260          27 :                 kss[i] = ksDup (kss[i - 1]);
     261          27 :                 succeed_if (keyGetRef (k2) == 2, "reference counter");
     262          27 :                 succeed_if_same_string (keyName (ksPop (kss[i - 1])), "system:/key");
     263          27 :                 succeed_if (keyGetRef (k2) == 1, "reference counter");
     264          27 :                 succeed_if (keyDel (k2) == 1, "delete key");
     265          27 :                 succeed_if (keyGetRef (k2) == 1, "reference counter");
     266             :         }
     267           3 :         succeed_if (keyGetRef (k1) == NR_KEYSETS, "reference counter");
     268           3 :         succeed_if (keyGetRef (k2) == 1, "reference counter");
     269             : 
     270          33 :         for (i = 0; i < NR_KEYSETS; i++)
     271             :         {
     272          30 :                 succeed_if (keyGetRef (k1) == NR_KEYSETS - i, "reference counter");
     273          30 :                 ksDel (kss[i]);
     274             :         }
     275           3 : }
     276             : 
     277           3 : static void test_ksDup (void)
     278             : {
     279           3 :         KeySet * ks = 0;
     280           3 :         KeySet * other = 0;
     281             : 
     282           3 :         printf ("Test ks duplication\n");
     283             : 
     284           3 :         succeed_if (ksDup (0) == 0, "No error on NULL pointer");
     285             : 
     286           3 :         exit_if_fail ((ks = ksNew (0, KS_END)) != 0, "could not create new keyset");
     287           3 :         other = ksDup (ks);
     288           3 :         succeed_if (other, "other creation failed");
     289           3 :         succeed_if (ksGetSize (ks) == 0, "ks has keys");
     290           3 :         succeed_if (ksGetSize (other) == 0, "other has keys");
     291           3 :         ksDel (other);
     292           3 :         ksDel (ks);
     293             : 
     294           3 :         exit_if_fail ((ks = ksNew (1, keyNew ("user:/anything", KEY_END), KS_END)) != 0, "could not create new keyset");
     295           3 :         other = ksDup (ks);
     296           3 :         succeed_if (other, "other creation failed");
     297           3 :         succeed_if (ksGetSize (ks) == 1, "ks has no keys");
     298           3 :         succeed_if (ksGetSize (other) == 1, "other has no keys");
     299           3 :         ksDel (other);
     300           3 :         ksDel (ks);
     301             : 
     302           3 :         exit_if_fail ((ks = ksNew (1, keyNew ("system:/some", KEY_END), KS_END)) != 0, "could not create new keyset");
     303           3 :         succeed_if (ksAppendKey (ks, keyNew ("user:/test1", KEY_END)) == 2, "could not append a key");
     304           3 :         succeed_if (ksAppendKey (ks, keyNew ("user:/test2", KEY_END)) == 3, "could not append a key");
     305           3 :         succeed_if (ksAppendKey (ks, keyNew ("user:/test3", KEY_END)) == 4, "could not append a key");
     306           3 :         other = ksDup (ks);
     307           3 :         succeed_if (other, "other creation failed");
     308           3 :         succeed_if (ksGetSize (ks) == 4, "ks has no keys");
     309           3 :         succeed_if (ksGetSize (other) == 4, "other has no keys");
     310           3 :         ksDel (other);
     311           3 :         ksDel (ks);
     312             : 
     313           3 :         exit_if_fail ((ks = ksNew (1, keyNew ("user:/any123", KEY_END), KS_END)) != 0, "could not create new keyset");
     314           3 :         succeed_if (ksAppendKey (ks, keyNew ("user:/test1", KEY_END)) == 2, "could not append a key");
     315           3 :         succeed_if (ksAppendKey (ks, keyNew ("user:/test2", KEY_END)) == 3, "could not append a key");
     316           3 :         succeed_if (ksAppendKey (ks, keyNew ("user:/test3", KEY_END)) == 4, "could not append a key");
     317           3 :         other = ksDup (ks);
     318           3 :         succeed_if (other, "other creation failed");
     319           3 :         keyDel (ksPop (other));
     320           3 :         succeed_if (ksGetSize (ks) == 4, "ks has no keys");
     321           3 :         succeed_if (ksGetSize (other) == 3, "other has no keys");
     322           3 :         ksDel (other);
     323           3 :         ksDel (ks);
     324             : 
     325           3 :         exit_if_fail ((ks = ksNew (1, keyNew ("system:/test", KEY_END), KS_END)) != 0, "could not create new keyset");
     326           3 :         succeed_if (ksAppendKey (ks, keyNew ("user:/test1", KEY_END)) == 2, "could not append a key");
     327           3 :         succeed_if (ksAppendKey (ks, keyNew ("user:/test2", KEY_END)) == 3, "could not append a key");
     328           3 :         succeed_if (ksAppendKey (ks, keyNew ("user:/test3", KEY_END)) == 4, "could not append a key");
     329           3 :         other = ksDup (ks);
     330           3 :         succeed_if (other, "other creation failed");
     331           3 :         keyDel (ksPop (other));
     332           3 :         succeed_if (ksAppendKey (ks, keyNew ("user:/test4", KEY_END)) == 5, "could not append a key");
     333           3 :         succeed_if (ksGetSize (ks) == 5, "ks has no keys");
     334           3 :         succeed_if (ksGetSize (other) == 3, "other has no keys");
     335           3 :         ksDel (other);
     336           3 :         ksDel (ks);
     337           3 : }
     338             : 
     339           3 : static void test_ksCopy (void)
     340             : {
     341           3 :         KeySet * ks = 0;
     342           3 :         KeySet * other = 0;
     343             : 
     344           3 :         printf ("Test ks copy\n");
     345             : 
     346           3 :         exit_if_fail ((ks = ksNew (1, keyNew ("user:/testro", KEY_END), KS_END)) != 0, "could not create new keyset");
     347           3 :         succeed_if (ksAppendKey (ks, keyNew ("user:/test1", KEY_END)) == 2, "could not append a key");
     348           3 :         succeed_if (ksAppendKey (ks, keyNew ("user:/test2", KEY_END)) == 3, "could not append a key");
     349           3 :         succeed_if (ksAppendKey (ks, keyNew ("user:/test3", KEY_END)) == 4, "could not append a key");
     350           3 :         succeed_if (ksCopy (0, ks) == -1, "No error on NULL pointer");
     351           3 :         succeed_if (ksCopy (ks, 0) == 0, "Could not delete ks with ksCopy");
     352           3 :         succeed_if (ksGetSize (ks) == 0, "ks has keys after deleting with ksCopy");
     353           3 :         ksDel (ks);
     354             : 
     355           3 :         other = ksNew (0, KS_END);
     356           3 :         exit_if_fail ((ks = ksNew (0, KS_END)) != 0, "could not create new keyset");
     357           3 :         succeed_if (ksCopy (other, ks) == 1, "Copy failed");
     358           3 :         succeed_if (other, "other creation failed");
     359           3 :         succeed_if (ksGetSize (ks) == 0, "ks has keys");
     360           3 :         succeed_if (ksGetSize (other) == 0, "other has keys");
     361           3 :         ksDel (other);
     362           3 :         ksDel (ks);
     363             : 
     364           3 :         other = ksNew (0, KS_END);
     365           3 :         exit_if_fail ((ks = ksNew (1, keyNew ("user:/test3", KEY_END), KS_END)) != 0, "could not create new keyset");
     366           3 :         succeed_if (ksCopy (other, ks) == 1, "Copy failed");
     367           3 :         succeed_if (other, "other creation failed");
     368           3 :         succeed_if (ksGetSize (ks) == 1, "ks has no keys");
     369           3 :         succeed_if (ksGetSize (other) == 1, "other has no keys");
     370           3 :         ksDel (other);
     371           3 :         ksDel (ks);
     372             : 
     373           3 :         other = ksNew (0, KS_END);
     374           3 :         exit_if_fail ((ks = ksNew (1, keyNew ("user:/testro", KEY_END), KS_END)) != 0, "could not create new keyset");
     375           3 :         succeed_if (ksAppendKey (ks, keyNew ("user:/test1", KEY_END)) == 2, "could not append a key");
     376           3 :         succeed_if (ksAppendKey (ks, keyNew ("user:/test2", KEY_END)) == 3, "could not append a key");
     377           3 :         succeed_if (ksAppendKey (ks, keyNew ("user:/test3", KEY_END)) == 4, "could not append a key");
     378           3 :         succeed_if (ksCopy (other, ks) == 1, "Copy failed");
     379           3 :         succeed_if (other, "other creation failed");
     380           3 :         succeed_if (ksGetSize (ks) == 4, "ks has no keys");
     381           3 :         succeed_if (ksGetSize (other) == 4, "other has no keys");
     382           3 :         ksDel (other);
     383           3 :         ksDel (ks);
     384             : 
     385           3 :         other = ksNew (0, KS_END);
     386           3 :         exit_if_fail ((ks = ksNew (1, keyNew ("system:/test", KEY_END), KS_END)) != 0, "could not create new keyset");
     387           3 :         succeed_if (ksAppendKey (ks, keyNew ("user:/test1", KEY_END)) == 2, "could not append a key");
     388           3 :         succeed_if (ksAppendKey (ks, keyNew ("user:/test2", KEY_END)) == 3, "could not append a key");
     389           3 :         succeed_if (ksAppendKey (ks, keyNew ("user:/test3", KEY_END)) == 4, "could not append a key");
     390           3 :         succeed_if (ksCopy (other, ks) == 1, "Copy failed");
     391           3 :         succeed_if (other, "other creation failed");
     392           3 :         keyDel (ksPop (other));
     393           3 :         succeed_if (ksGetSize (ks) == 4, "ks has no keys");
     394           3 :         succeed_if (ksGetSize (other) == 3, "other has no keys");
     395           3 :         ksDel (other);
     396           3 :         ksDel (ks);
     397             : 
     398           3 :         other = ksNew (0, KS_END);
     399           3 :         exit_if_fail ((ks = ksNew (1, keyNew ("user:/mykeys", KEY_END), KS_END)) != 0, "could not create new keyset");
     400           3 :         succeed_if (ksAppendKey (ks, keyNew ("user:/test1", KEY_END)) == 2, "could not append a key");
     401           3 :         succeed_if (ksAppendKey (ks, keyNew ("user:/test2", KEY_END)) == 3, "could not append a key");
     402           3 :         succeed_if (ksAppendKey (ks, keyNew ("user:/test3", KEY_END)) == 4, "could not append a key");
     403           3 :         succeed_if (ksCopy (other, ks) == 1, "Copy failed");
     404           3 :         succeed_if (other, "other creation failed");
     405           3 :         keyDel (ksPop (other));
     406           3 :         succeed_if (ksAppendKey (ks, keyNew ("user:/test", KEY_END)) == 5, "could not append a key");
     407           3 :         succeed_if (ksGetSize (ks) == 5, "ks has no keys");
     408           3 :         succeed_if (ksGetSize (other) == 3, "other has no keys");
     409           3 :         ksDel (other);
     410           3 :         ksDel (ks);
     411             : 
     412           3 :         other = ksNew (0, KS_END);
     413           3 :         exit_if_fail ((ks = ksNew (1, keyNew ("user:/a/b/c", KEY_END), KS_END)) != 0, "could not create new keyset");
     414           3 :         succeed_if (ksAppendKey (ks, keyNew ("user:/a/test", KEY_END)) == 2, "could not append a key");
     415           3 :         succeed_if (ksAppendKey (ks, keyNew ("user:/a/b/test", KEY_END)) == 3, "could not append a key");
     416           3 :         succeed_if (ksAppendKey (ks, keyNew ("user:/a/b/ctest", KEY_END)) == 4, "could not append a key");
     417           3 :         succeed_if (ksCopy (other, ks) == 1, "Copy failed");
     418           3 :         succeed_if (other, "other creation failed");
     419           3 :         keyDel (ksPop (other));
     420           3 :         succeed_if (ksAppendKey (ks, keyNew ("user:/test", KEY_END)) == 5, "could not append a key");
     421           3 :         succeed_if (ksGetSize (ks) == 5, "ks has no keys");
     422           3 :         succeed_if (ksGetSize (other) == 3, "other has no keys");
     423             : 
     424           3 :         succeed_if (ksCopy (ks, 0) == 0, "Clear failed");
     425           3 :         succeed_if (ksGetSize (ks) == 0, "ks has keys");
     426             : 
     427           3 :         succeed_if (ksCopy (other, 0) == 0, "Clear failed");
     428           3 :         succeed_if (ksGetSize (other) == 0, "other has keys");
     429           3 :         ksDel (other);
     430           3 :         ksDel (ks);
     431             : 
     432             : 
     433           3 :         ks = ksNew (0, KS_END);
     434           3 :         ksAppendKey (ks, keyNew ("user:/abc", KEY_META, "def", "egh", KEY_END));
     435             : 
     436           3 :         other = ksNew (0, KS_END);
     437           3 :         ksCopy (other, ks);
     438           9 :         compare_keyset (ks, other);
     439             : 
     440           3 :         ksDel (other);
     441           3 :         ksDel (ks);
     442           3 : }
     443             : 
     444           3 : static void test_ksIterate (void)
     445             : {
     446           3 :         KeySet * ks = ksNew (0, KS_END);
     447           3 :         KeySet * other = ksNew (0, KS_END);
     448           3 :         Key * key;
     449           3 :         int i;
     450           3 :         char name[] = "user:/n";
     451             : 
     452           3 :         printf ("Test keyset iterate\n");
     453           3 :         succeed_if (ksNext (0) == 0, "No NULL pointer on NULL pointer keyset");
     454           3 :         succeed_if (ksCurrent (0) == 0, "No NULL pointer on NULL pointer keyset");
     455           3 :         succeed_if (ksRewind (0) == -1, "No error on NULL pointer");
     456             : 
     457           3 :         succeed_if (ksCurrent (ks) == 0, "No NULL pointer on empty keyset");
     458           3 :         succeed_if (ksNext (ks) == 0, "No NULL pointer on empty keyset");
     459           3 :         succeed_if (ksRewind (ks) == 0, "Cannot rewind empty keyset");
     460             : 
     461           3 :         ksAppendKey (ks, keyNew ("user:/1", KEY_END));
     462           3 :         ksAppendKey (ks, keyNew ("user:/2", KEY_END));
     463           3 :         ksAppendKey (ks, keyNew ("user:/3", KEY_END));
     464           3 :         ksAppendKey (ks, keyNew ("user:/4", KEY_END));
     465           3 :         ksAppendKey (ks, keyNew ("user:/5", KEY_END));
     466           3 :         succeed_if (ksGetSize (ks) == 5, "could not append 5 keys");
     467             : 
     468           3 :         succeed_if (ksRewind (ks) == 0, "Could not rewind keyset");
     469           3 :         succeed_if (ksRewind (ks) == 0, "Could not rewind keyset twice");
     470             : 
     471           3 :         succeed_if (ksGetCursor (ks) == -1, "Internal cursor after rewinding is set");
     472             : 
     473           3 :         succeed_if (ksNext (ks) != 0, "Could not get first key");
     474           3 :         succeed_if_same_string (keyName (ksCurrent (ks)), "user:/1");
     475             : 
     476           3 :         succeed_if (ksNext (ks) != 0, "Could not get second key");
     477           3 :         succeed_if_same_string (keyName (ksCurrent (ks)), "user:/2");
     478             : 
     479           3 :         succeed_if (ksNext (ks) != 0, "Could not get third key");
     480           3 :         succeed_if_same_string (keyName (ksCurrent (ks)), "user:/3");
     481             : 
     482           3 :         succeed_if (ksNext (ks) != 0, "Could not get fourth key");
     483           3 :         succeed_if_same_string (keyName (ksCurrent (ks)), "user:/4");
     484             : 
     485           3 :         succeed_if (ksNext (ks) != 0, "Could not get fifth key");
     486           3 :         succeed_if_same_string (keyName (ksCurrent (ks)), "user:/5");
     487             : 
     488           3 :         succeed_if (ksNext (ks) == 0, "Could not iterate over last");
     489           3 :         succeed_if (ksCurrent (ks) == 0, "This is not the beyond last key");
     490             : 
     491           3 :         succeed_if (ksNext (ks) == 0, "Could not iterate over last (again)");
     492           3 :         succeed_if (ksCurrent (ks) == 0, "This is not the beyond last key (again)");
     493             : 
     494           3 :         key = ksPop (ks);
     495           3 :         succeed_if_same_string (keyName (key), "user:/5");
     496           3 :         succeed_if (keyDel (key) == 0, "could not del popped key");
     497             : 
     498           3 :         succeed_if (ksAppend (other, ks) == 4, "could not append keys");
     499             : 
     500          15 :         for (i = 4; i >= 1; i--)
     501             :         {
     502          12 :                 key = ksPop (other);
     503          12 :                 succeed_if (key != 0, "got null pointer key");
     504          12 :                 name[6] = '0' + i;
     505          12 :                 succeed_if_same_string (keyName (key), name);
     506          12 :                 keyDel (key);
     507             :         }
     508             : 
     509           3 :         succeed_if (ksAppendKey (other, keyNew ("user:/3", KEY_END)) == 1, "could not append one key");
     510           3 :         key = ksPop (other);
     511           3 :         succeed_if (key != 0, "got null pointer key");
     512           3 :         succeed_if_same_string (keyName (key), "user:/3");
     513           3 :         succeed_if (keyDel (key) == 0, "could not del popped key");
     514           3 :         ksDel (other);
     515           3 :         ksDel (ks);
     516             : 
     517           3 :         ks = ksNew (10, keyNew ("user:/0", KEY_END), keyNew ("user:/1", KEY_END), keyNew ("user:/2", KEY_END), keyNew ("user:/3", KEY_END),
     518             :                     KS_END);
     519             : 
     520           3 :         other = ksNew (10, keyNew ("user:/4", KEY_END), keyNew ("user:/5", KEY_END), keyNew ("user:/6", KEY_END),
     521             :                        keyNew ("user:/7", KEY_END), KS_END);
     522             : 
     523           3 :         succeed_if (ksAppend (ks, other) == 8, "could not append keys");
     524             : 
     525          27 :         for (i = 7; i >= 0; i--)
     526             :         {
     527          24 :                 key = ksPop (ks);
     528          24 :                 succeed_if (key != 0, "got null pointer key");
     529          24 :                 name[6] = '0' + i;
     530          24 :                 succeed_if_same_string (keyName (key), name);
     531          24 :                 keyDel (key);
     532             :         }
     533           3 :         ksDel (ks);
     534           3 :         ksDel (other);
     535           3 : }
     536             : 
     537           3 : static void test_ksCursor (void)
     538             : {
     539           3 :         KeySet * ks = ksNew (0, KS_END);
     540           3 :         Key * key;
     541           3 :         elektraCursor cursor;
     542           3 :         Key * cur;
     543           3 :         int i;
     544           3 :         char name[] = "user:/n";
     545             : 
     546           3 :         printf ("Test keyset cursor\n");
     547             : 
     548           3 :         ksAppendKey (ks, cur = keyNew ("user:/1", KEY_END));
     549           3 :         succeed_if (ksCurrent (ks) == cur, "cursor not set after append key");
     550           3 :         ksAppendKey (ks, cur = keyNew ("user:/2", KEY_END));
     551           3 :         succeed_if (ksCurrent (ks) == cur, "cursor not set after append key");
     552           3 :         ksAppendKey (ks, cur = keyNew ("user:/3", KEY_END));
     553           3 :         succeed_if (ksCurrent (ks) == cur, "cursor not set after append key");
     554           3 :         cursor = ksGetCursor (ks);
     555           3 :         succeed_if_same_string (keyName (ksAtCursor (ks, cursor)), "user:/3");
     556           3 :         ksAppendKey (ks, cur = keyNew ("user:/4", KEY_END));
     557           3 :         succeed_if (ksCurrent (ks) == cur, "cursor not set after append key");
     558           3 :         ksAppendKey (ks, cur = keyNew ("user:/5", KEY_END));
     559           3 :         succeed_if (ksCurrent (ks) == cur, "cursor not set after append key");
     560           3 :         succeed_if (ksGetSize (ks) == 5, "could not append 5 keys");
     561             : 
     562           3 :         succeed_if_same_string (keyName (ksAtCursor (ks, cursor)), "user:/3");
     563           3 :         ksSetCursor (ks, cursor);
     564           3 :         succeed_if (cursor == ksGetCursor (ks), "cursor not set to 3");
     565           3 :         succeed_if_same_string (keyName (ksAtCursor (ks, cursor)), "user:/3");
     566           3 :         ksSetCursor (ks, cursor);
     567           3 :         succeed_if (cursor == ksGetCursor (ks), "cursor not set to 3 (again)");
     568             : 
     569           3 :         cursor = ksGetCursor (ks);
     570           3 :         key = ksPop (ks);
     571           3 :         succeed_if (cursor == ksGetCursor (ks), "cursor should stay the same");
     572           3 :         succeed_if_same_string (keyName (key), "user:/5");
     573           3 :         succeed_if (keyDel (key) == 0, "could not del popped key");
     574             : 
     575           3 :         ksRewind (ks);
     576          18 :         for (i = 0; i < 5; i++)
     577             :         {
     578          15 :                 ksNext (ks);
     579          15 :                 if (i == 1)
     580             :                 {
     581           3 :                         cursor = ksGetCursor (ks);
     582           3 :                         name[6] = '0' + i;
     583             :                 }
     584             :         }
     585           3 :         ksSetCursor (ks, cursor);
     586           3 :         ksCurrent (ks);
     587             : 
     588           3 :         ksDel (ks);
     589             : 
     590           3 :         ks = ksNew (10, keyNew ("user:/0", KEY_END), keyNew ("user:/1", KEY_END), keyNew ("user:/2", KEY_END), keyNew ("user:/3", KEY_END),
     591             :                     KS_END);
     592             : 
     593           3 :         ksRewind (ks);
     594          15 :         for (i = 0; i < 4; i++)
     595             :         {
     596          12 :                 ksNext (ks);
     597          12 :                 if (i == 1)
     598             :                 {
     599           3 :                         cursor = ksGetCursor (ks);
     600           3 :                         name[6] = '0' + i;
     601             :                 }
     602             :         }
     603             : 
     604           3 :         ksSetCursor (ks, cursor);
     605           3 :         key = ksCurrent (ks);
     606           3 :         succeed_if_same_string (keyName (key), name);
     607             : 
     608           3 :         ksDel (ks);
     609             : 
     610           3 :         ks = ksNew (10, keyNew ("user:/0", KEY_END), keyNew ("user:/1", KEY_END), keyNew ("user:/2", KEY_END), keyNew ("user:/3", KEY_END),
     611             :                     KS_END);
     612             : 
     613           3 :         ksRewind (ks);
     614          15 :         for (i = 0; i < 4; i++)
     615             :         {
     616          12 :                 ksNext (ks);
     617          12 :                 cursor = ksGetCursor (ks);
     618          12 :                 name[6] = '0' + i;
     619          12 :                 succeed_if_same_string (keyName (ksAtCursor (ks, cursor)), name);
     620             :         }
     621             : 
     622           3 :         succeed_if_same_string (keyName (ksAtCursor (ks, 0)), "user:/0");
     623           3 :         succeed_if_same_string (keyName (ksAtCursor (ks, 1)), "user:/1");
     624           3 :         succeed_if_same_string (keyName (ksAtCursor (ks, 2)), "user:/2");
     625           3 :         succeed_if_same_string (keyName (ksAtCursor (ks, 3)), "user:/3");
     626           3 :         succeed_if (ksAtCursor (ks, -1) == 0, "bounds check not correct");
     627           3 :         succeed_if (ksAtCursor (ks, 4) == 0, "bounds check not correct");
     628             : 
     629           3 :         ksDel (ks);
     630           3 : }
     631             : 
     632           3 : static void test_ksAtCursor (void)
     633             : {
     634           3 :         KeySet * ks;
     635           3 :         Key * current;
     636           3 :         Key * testKeys[5];
     637           3 :         ks = ksNew (0, KS_END);
     638             : 
     639           3 :         testKeys[0] = keyNew ("user:/test1", KEY_END);
     640           3 :         testKeys[1] = keyNew ("user:/test2", KEY_END);
     641           3 :         testKeys[2] = keyNew ("user:/test3", KEY_END);
     642           3 :         testKeys[3] = keyNew ("user:/test4", KEY_END);
     643           3 :         testKeys[4] = keyNew ("user:/test5", KEY_END);
     644             : 
     645          18 :         for (size_t index = 0; index < 5; index++)
     646             :         {
     647          15 :                 ksAppendKey (ks, testKeys[index]);
     648             :         }
     649             : 
     650           3 :         ksRewind (ks);
     651             : 
     652           3 :         elektraCursor cursor;
     653             : 
     654             :         /* test whether the correct key is returned */
     655          18 :         for (size_t index = 0; index < 5; index++)
     656             :         {
     657          15 :                 current = testKeys[index];
     658          15 :                 ksNext (ks);
     659          15 :                 cursor = ksGetCursor (ks);
     660          15 :                 Key * other = ksAtCursor (ks, cursor);
     661          15 :                 succeed_if_same_string (keyName (current), keyName (other));
     662             :         }
     663             : 
     664           3 :         succeed_if (ksAtCursor (ks, 5) == 0, "Not NULL on invalid cursor position");
     665             : 
     666             :         /* test whether the correct key is returned even if
     667             :          * the internal cursor is positioned somewhere else */
     668           3 :         ksRewind (ks);
     669           3 :         ksNext (ks);
     670           3 :         cursor = ksGetCursor (ks);
     671           3 :         ksNext (ks);
     672           3 :         ksNext (ks);
     673           3 :         current = ksAtCursor (ks, cursor);
     674           3 :         succeed_if_same_string (keyName (current), "user:/test1");
     675             : 
     676             :         /* test whether the internal cursor is modified */
     677           3 :         ksRewind (ks);
     678           3 :         ksNext (ks);
     679           3 :         cursor = ksGetCursor (ks);
     680           3 :         ksNext (ks);
     681           3 :         current = ksAtCursor (ks, cursor);
     682           3 :         succeed_if_same_string (keyName (current), "user:/test1");
     683           3 :         current = ksNext (ks);
     684           3 :         succeed_if_same_string (keyName (current), "user:/test3");
     685             : 
     686             :         /* test postconditions */
     687           3 :         succeed_if (!ksAtCursor (0, cursor), "did not return NULL on NULL keyset");
     688           3 :         succeed_if (!ksAtCursor (ks, -1), "did not return NULL on negative cursor");
     689           3 :         succeed_if (!ksAtCursor (ks, 10), "did not return NULL on invalid cursor");
     690             : 
     691           3 :         ksDel (ks);
     692           3 : }
     693             : 
     694           3 : static void test_ksSort (void)
     695             : {
     696           3 :         KeySet * ks;
     697           3 :         Key *key, *k1, *k2;
     698           3 :         int i;
     699             : 
     700           3 :         printf ("Test ks sort\n");
     701             : 
     702           3 :         ks = ksNew (0, KS_END);
     703           3 :         ksAppendKey (ks, keyNew ("user:/bname", KEY_END));
     704           3 :         ksAppendKey (ks, keyNew ("user:/aname", KEY_END));
     705           3 :         ksAppendKey (ks, keyNew ("user:/cname", KEY_END));
     706             : 
     707           3 :         ksRewind (ks);
     708           3 :         key = ksNext (ks);
     709           3 :         succeed_if_same_string (keyName (key), "user:/aname");
     710             : 
     711           3 :         key = ksNext (ks);
     712           3 :         succeed_if_same_string (keyName (key), "user:/bname");
     713             : 
     714           3 :         key = ksNext (ks);
     715           3 :         succeed_if_same_string (keyName (key), "user:/cname");
     716           3 :         ksDel (ks);
     717             : 
     718           3 :         ks = ksNew (0, KS_END);
     719           3 :         ksAppendKey (ks, keyNew ("user:/a", KEY_END));
     720           3 :         ksAppendKey (ks, keyNew ("user:/e", KEY_END));
     721           3 :         ksAppendKey (ks, keyNew ("user:/b1", KEY_END));
     722           3 :         ksAppendKey (ks, keyNew ("user:/h2", KEY_END));
     723           3 :         ksAppendKey (ks, keyNew ("user:/b2", KEY_END));
     724           3 :         ksAppendKey (ks, keyNew ("user:/d", KEY_END));
     725           3 :         ksAppendKey (ks, keyNew ("user:/a", KEY_END));
     726           3 :         ksAppendKey (ks, keyNew ("user:/g", KEY_END));
     727           3 :         ksAppendKey (ks, keyNew ("user:/g", KEY_END));
     728           3 :         ksAppendKey (ks, keyNew ("user:/c2", KEY_END));
     729           3 :         ksAppendKey (ks, keyNew ("user:/c1", KEY_END));
     730           3 :         ksAppendKey (ks, keyNew ("user:/g", KEY_END));
     731           3 :         ksAppendKey (ks, keyNew ("user:/h1", KEY_END));
     732           3 :         ksAppendKey (ks, keyNew ("user:/f", KEY_END));
     733             : 
     734           3 :         ksRewind (ks);
     735          36 :         for (i = 0; (key = ksNext (ks)) != 0; i++)
     736             :         {
     737          33 :                 switch (i)
     738             :                 {
     739           3 :                 case 0:
     740           3 :                         succeed_if_same_string (keyName (key), "user:/a");
     741             :                         break;
     742           3 :                 case 1:
     743           3 :                         succeed_if_same_string (keyName (key), "user:/b1");
     744             :                         break;
     745           3 :                 case 2:
     746           3 :                         succeed_if_same_string (keyName (key), "user:/b2");
     747             :                         break;
     748           3 :                 case 3:
     749           3 :                         succeed_if_same_string (keyName (key), "user:/c1");
     750             :                         break;
     751           3 :                 case 4:
     752           3 :                         succeed_if_same_string (keyName (key), "user:/c2");
     753             :                         break;
     754           3 :                 case 5:
     755           3 :                         succeed_if_same_string (keyName (key), "user:/d");
     756             :                         break;
     757           3 :                 case 6:
     758           3 :                         succeed_if_same_string (keyName (key), "user:/e");
     759             :                         break;
     760           3 :                 case 7:
     761           3 :                         succeed_if_same_string (keyName (key), "user:/f");
     762             :                         break;
     763           3 :                 case 8:
     764           3 :                         succeed_if_same_string (keyName (key), "user:/g");
     765             :                         break;
     766           3 :                 case 9:
     767           3 :                         succeed_if_same_string (keyName (key), "user:/h1");
     768             :                         break;
     769           3 :                 case 10:
     770           3 :                         succeed_if_same_string (keyName (key), "user:/h2");
     771             :                         break;
     772           0 :                 default:
     773           0 :                         succeed_if (0, "should not reach");
     774             :                         break;
     775             :                 }
     776             :         }
     777           3 :         ksDel (ks);
     778             : 
     779           3 :         ks = ksNew (0, KS_END);
     780           3 :         k1 = keyNew ("user:/xname", KEY_END);
     781           3 :         ksAppendKey (ks, k1);
     782             : 
     783           3 :         k2 = keyDup (k1, KEY_CP_ALL);
     784             : 
     785           3 :         succeed_if (keyGetRef (k2) == 0, "reference counter not resetted");
     786           3 :         ksAppendKey (ks, k2);
     787           3 :         succeed_if (keyGetRef (k2) == 1, "reference counter not incremented after insertion");
     788             : 
     789           3 :         ksRewind (ks);
     790           3 :         ksNext (ks);
     791           3 :         ksDel (ks);
     792             : 
     793           3 :         ks = ksNew (0, KS_END);
     794           3 :         k1 = keyNew ("user:/yname", KEY_END);
     795           3 :         k2 = keyDup (k1, KEY_CP_ALL);
     796           3 :         ksAppendKey (ks, k2);
     797           3 :         ksAppendKey (ks, k1);
     798             : 
     799           3 :         ksRewind (ks);
     800           3 :         ksNext (ks);
     801           3 :         ksDel (ks);
     802             : 
     803           3 :         ks = ksNew (0, KS_END);
     804           3 :         ksAppendKey (ks, keyNew ("user:/a", KEY_END));
     805           3 :         ksAppendKey (ks, keyNew ("user:/e", KEY_END));
     806           3 :         ksAppendKey (ks, keyNew ("user:/b", KEY_END));
     807           3 :         ksAppendKey (ks, keyNew ("user:/b", KEY_END));
     808           3 :         ksAppendKey (ks, keyNew ("user:/d", KEY_END));
     809           3 :         ksAppendKey (ks, keyNew ("user:/c", KEY_END));
     810           3 :         ksAppendKey (ks, keyNew ("user:/c", KEY_END));
     811           3 :         ksAppendKey (ks, keyNew ("user:/g", KEY_END));
     812           3 :         ksAppendKey (ks, keyNew ("user:/h", KEY_END));
     813           3 :         ksAppendKey (ks, keyNew ("user:/h", KEY_END));
     814           3 :         ksAppendKey (ks, keyNew ("user:/f", KEY_END));
     815             : 
     816           3 :         ksRewind (ks);
     817          27 :         for (i = 0; (key = ksNext (ks)) != 0; i++)
     818             :         {
     819          24 :                 switch (i)
     820             :                 {
     821           3 :                 case 0:
     822           3 :                         succeed_if_same_string (keyName (key), "user:/a");
     823             :                         break;
     824           3 :                 case 1:
     825           3 :                         succeed_if_same_string (keyName (key), "user:/b");
     826             :                         break;
     827           3 :                 case 2:
     828           3 :                         succeed_if_same_string (keyName (key), "user:/c");
     829             :                         break;
     830           3 :                 case 3:
     831           3 :                         succeed_if_same_string (keyName (key), "user:/d");
     832             :                         break;
     833           3 :                 case 4:
     834           3 :                         succeed_if_same_string (keyName (key), "user:/e");
     835             :                         break;
     836           3 :                 case 5:
     837           3 :                         succeed_if_same_string (keyName (key), "user:/f");
     838             :                         break;
     839           3 :                 case 6:
     840           3 :                         succeed_if_same_string (keyName (key), "user:/g");
     841             :                         break;
     842           3 :                 case 7:
     843           3 :                         succeed_if_same_string (keyName (key), "user:/h");
     844             :                         break;
     845           0 :                 default:
     846           0 :                         succeed_if (0, "should not reach");
     847             :                         break;
     848             :                 }
     849             :         }
     850           3 :         ksDel (ks);
     851             : 
     852             : 
     853           3 :         ks = ksNew (0, KS_END);
     854           3 :         ksAppendKey (ks, keyNew ("user:/a", KEY_END));
     855           3 :         ksAppendKey (ks, keyNew ("user:/e", KEY_END));
     856           3 :         ksAppendKey (ks, keyNew ("user:/b/a", KEY_END));
     857           3 :         ksAppendKey (ks, keyNew ("user:/b", KEY_END));
     858           3 :         ksAppendKey (ks, keyNew ("user:/d", KEY_END));
     859           3 :         ksAppendKey (ks, keyNew ("user:/c", KEY_END));
     860           3 :         ksAppendKey (ks, keyNew ("user:/c/a", KEY_END));
     861           3 :         ksAppendKey (ks, keyNew ("user:/g", KEY_END));
     862           3 :         ksAppendKey (ks, keyNew ("user:/h/a", KEY_END));
     863           3 :         ksAppendKey (ks, keyNew ("user:/h", KEY_END));
     864           3 :         ksAppendKey (ks, keyNew ("user:/f", KEY_END));
     865             : 
     866           3 :         ksRewind (ks);
     867             :         // output_keyset(ks,0);
     868          36 :         for (i = 0; (key = ksNext (ks)) != 0; i++)
     869             :         {
     870          33 :                 switch (i)
     871             :                 {
     872           3 :                 case 10:
     873           3 :                         succeed_if_same_string (keyName (key), "user:/h/a");
     874             :                         break;
     875           3 :                 case 9:
     876           3 :                         succeed_if_same_string (keyName (key), "user:/h");
     877             :                         break;
     878           3 :                 case 8:
     879           3 :                         succeed_if_same_string (keyName (key), "user:/g");
     880             :                         break;
     881           3 :                 case 7:
     882           3 :                         succeed_if_same_string (keyName (key), "user:/f");
     883             :                         break;
     884           3 :                 case 6:
     885           3 :                         succeed_if_same_string (keyName (key), "user:/e");
     886             :                         break;
     887           3 :                 case 5:
     888           3 :                         succeed_if_same_string (keyName (key), "user:/d");
     889             :                         break;
     890           3 :                 case 4:
     891           3 :                         succeed_if_same_string (keyName (key), "user:/c/a");
     892             :                         break;
     893           3 :                 case 3:
     894           3 :                         succeed_if_same_string (keyName (key), "user:/c");
     895             :                         break;
     896           3 :                 case 2:
     897           3 :                         succeed_if_same_string (keyName (key), "user:/b/a");
     898             :                         break;
     899           3 :                 case 1:
     900           3 :                         succeed_if_same_string (keyName (key), "user:/b");
     901             :                         break;
     902           3 :                 case 0:
     903           3 :                         succeed_if_same_string (keyName (key), "user:/a");
     904             :                         break;
     905           0 :                 default:
     906           0 :                         succeed_if (0, "should not reach");
     907             :                         break;
     908             :                 }
     909             :         }
     910           3 :         ksDel (ks);
     911             : 
     912           3 :         ks = ksNew (0, KS_END);
     913           3 :         ksAppendKey (ks, keyNew ("user:/dir1/key1", KEY_END));
     914           3 :         ksAppendKey (ks, keyNew ("user:/dir1/key2", KEY_END));
     915           3 :         ksAppendKey (ks, keyNew ("user:/dir1/key3", KEY_END));
     916           3 :         ksAppendKey (ks, keyNew ("user:/dir2", KEY_END));
     917           3 :         ksAppendKey (ks, keyNew ("user:/dir2/key1", KEY_END));
     918           3 :         ksAppendKey (ks, keyNew ("user:/dir3/key1", KEY_END));
     919           3 :         ksAppendKey (ks, keyNew ("user:/dir3", KEY_END));
     920           3 :         ksAppendKey (ks, keyNew ("user:/dir3/key2", KEY_END));
     921           3 :         ksAppendKey (ks, keyNew ("user:/dir4", KEY_END));
     922           3 :         ksAppendKey (ks, keyNew ("user:/dir5/key1", KEY_END));
     923           3 :         ksAppendKey (ks, keyNew ("user:/dir6/key1", KEY_END));
     924             : 
     925           3 :         ksRewind (ks);
     926             :         // output_keyset(ks,0);
     927          36 :         for (i = 0; (key = ksNext (ks)) != 0; i++)
     928             :         {
     929          33 :                 switch (i)
     930             :                 {
     931           3 :                 case 9:
     932           3 :                         succeed_if_same_string (keyName (key), "user:/dir5/key1");
     933             :                         break;
     934           3 :                 case 4:
     935           3 :                         succeed_if_same_string (keyName (key), "user:/dir2/key1");
     936             :                         break;
     937           3 :                 case 3:
     938           3 :                         succeed_if_same_string (keyName (key), "user:/dir2");
     939             :                         break;
     940           3 :                 case 2:
     941           3 :                         succeed_if_same_string (keyName (key), "user:/dir1/key3");
     942             :                         break;
     943           3 :                 case 0:
     944           3 :                         succeed_if_same_string (keyName (key), "user:/dir1/key1");
     945             :                         break;
     946           3 :                 case 1:
     947           3 :                         succeed_if_same_string (keyName (key), "user:/dir1/key2");
     948             :                         break;
     949           3 :                 case 5:
     950           3 :                         succeed_if_same_string (keyName (key), "user:/dir3");
     951             :                         break;
     952           3 :                 case 6:
     953           3 :                         succeed_if_same_string (keyName (key), "user:/dir3/key1");
     954             :                         break;
     955           3 :                 case 7:
     956           3 :                         succeed_if_same_string (keyName (key), "user:/dir3/key2");
     957             :                         break;
     958           3 :                 case 8:
     959           3 :                         succeed_if_same_string (keyName (key), "user:/dir4");
     960             :                         break;
     961           3 :                 case 10:
     962           3 :                         succeed_if_same_string (keyName (key), "user:/dir6/key1");
     963             :                         break;
     964           0 :                 default:
     965           0 :                         succeed_if (0, "should not reach");
     966             :                         break;
     967             :                 }
     968             :         }
     969           3 :         ksDel (ks);
     970           3 : }
     971             : 
     972         600 : static void ksUnsort (KeySet * ks)
     973             : {
     974         600 :         KeySet * randks = ksNew (0, KS_END); /*This is the final randomized keyset*/
     975         600 :         KeySet * tempks = ksNew (0, KS_END); /*Temporary storage for keys not chosen to be inserted*/
     976             : 
     977       14604 :         while (ksGetSize (ks) > 0)
     978             :         {
     979       14004 :                 ksRewind (ks);
     980       14004 :                 size_t size = ksGetSize (ks);
     981             :                 /* printf ("iterating %d\n", size); */
     982       14004 :                 Key * cur;
     983      189492 :                 while ((cur = ksPop (ks)) != 0)
     984             :                 {
     985             :                         /* printf ("\titerating %s\n", keyName(cur)); */
     986      175488 :                         if (!(rand () % size))
     987       13800 :                                 ksAppendKey (randks, cur);
     988             :                         else
     989      161688 :                                 ksAppendKey (tempks, cur);
     990             :                 }
     991       14004 :                 ksAppend (ks, tempks);
     992       14004 :                 ksCopy (tempks, 0);
     993             :         }
     994             : 
     995         600 :         ksCopy (ks, randks);
     996             : 
     997         600 :         ksDel (randks);
     998         600 :         ksDel (tempks);
     999         600 : }
    1000             : 
    1001           3 : static void test_ksLookup (void)
    1002             : {
    1003           3 :         printf ("Test lookup\n");
    1004             : 
    1005           3 :         Key * simpleKey = keyNew ("user:/find_me", KEY_END);
    1006           3 :         KeySet * simple = ksNew (5, simpleKey, KS_END);
    1007             : 
    1008           3 :         Key * foundKey = ksLookup (simple, simpleKey, 0);
    1009           3 :         succeed_if (foundKey == simpleKey, "could not find key in keyset");
    1010             : 
    1011           3 :         Key * simpleKey2 = keyNew ("user:/find_me/a", KEY_END);
    1012           3 :         ksAppendKey (simple, simpleKey2);
    1013             : 
    1014           3 :         foundKey = ksLookup (simple, simpleKey, 0);
    1015           3 :         succeed_if (foundKey == simpleKey, "could not find key in keyset again");
    1016             :         // output_key(foundKey);
    1017             : 
    1018           3 :         foundKey = ksLookup (simple, simpleKey2, 0);
    1019           3 :         succeed_if (foundKey == simpleKey2, "could not find other key in keyset");
    1020             :         // output_keyset(simple);
    1021           3 :         ksDel (simple);
    1022             : 
    1023           3 :         int i, j;
    1024           3 :         Key * k[1000];
    1025           3 :         KeySet * ks = ksNew (30,
    1026             :                              // clang-format off
    1027             :                        /* keys that are searched */
    1028           3 :                        k[0] = keyNew ("user:/rem3", KEY_END),
    1029           3 :                        k[1] = keyNew ("user:/rem2", KEY_END),
    1030           3 :                        k[2] = keyNew ("user:/rem1/key2", KEY_END),
    1031           3 :                        k[3] = keyNew ("user:/rem1/key1", KEY_END),
    1032           3 :                        k[4] = keyNew ("user:/rem1", KEY_END),
    1033           3 :                        k[5] = keyNew ("user:/dir1", KEY_END),
    1034           3 :                        k[6] = keyNew ("user:/dir1/key1", KEY_VALUE, "value1", KEY_END),
    1035           3 :                        k[7] = keyNew ("user:/dir1/key2", KEY_VALUE, "value2", KEY_END),
    1036           3 :                        k[8] = keyNew ("user:/dir1/key3", KEY_VALUE, "value3", KEY_END),
    1037           3 :                        k[9] = keyNew ("user:/dir1/key4", KEY_VALUE, "value4", KEY_END),
    1038           3 :                        k[10] = keyNew ("user:/dir1/.inactive1", KEY_META, "comment/#0", "key is inactive", KEY_END),
    1039           3 :                        k[11] = keyNew ("user:/dir1/.inactive2", KEY_META, "comment/#0", "additional information", KEY_END),
    1040           3 :                        k[12] = keyNew ("user:/dir2", KEY_END),
    1041           3 :                        k[13] = keyNew ("user:/dir2/key1", KEY_VALUE, "value1", KEY_END),
    1042           3 :                        k[14] = keyNew ("user:/dir2/key2", KEY_VALUE, "value2", KEY_END),
    1043           3 :                        k[15] = keyNew ("user:/dir2/key3", KEY_VALUE, "value3", KEY_END),
    1044           3 :                        k[16] = keyNew ("user:/dir2/key4", KEY_VALUE, "value4", KEY_END),
    1045           3 :                        k[17] = keyNew ("user:/dir3", KEY_END),
    1046           3 :                        k[18] = keyNew ("user:/dir3/key1", KEY_VALUE, "value1", KEY_END),
    1047           3 :                        k[19] = keyNew ("user:/dir3/.inactive1", KEY_META, "comment/#0", "key is inactive", KEY_END),
    1048           3 :                        k[20] = keyNew ("user:/dir3/.inactive2", KEY_META, "comment/#0", "a users comment", KEY_END),
    1049           3 :                        k[21] = keyNew ("user:/dir4", KEY_END),
    1050           3 :                        k[22] = keyNew ("user:/dir5", KEY_END),
    1051             :                              // clang-format on
    1052             :                              KS_END);
    1053             : 
    1054           3 :         KeySet * lookupKeys = ksNew (30,
    1055             :                                      /* lookup keys, keyset only for ksDel */
    1056             :                                      // clang-format off
    1057           3 :                                      k[23] = keyNew ("user:/DiR1", KEY_END),
    1058           3 :                                      k[24] = keyNew ("user:/DiR1/KEY1", KEY_END),
    1059           3 :                                      k[25] = keyNew ("user:/DiR1/KEY1", KEY_END),
    1060           3 :                                      k[26] = keyNew ("user:/DiR1/KEY1", KEY_END),
    1061           3 :                                      k[27] = keyNew ("user:/dir1/key1", KEY_END),
    1062           3 :                                      k[28] = keyNew ("user:/dir1/key1", KEY_END),
    1063           3 :                                      k[29] = keyNew ("user:/dir2/key1", KEY_END),
    1064           3 :                                      k[30] = keyNew ("user:/dir2/key1", KEY_END),
    1065           3 :                                      k[31] = keyNew ("user:/dir2/key1", KEY_END),
    1066           3 :                                      k[32] = keyNew ("/dir1/key1", KEY_END),
    1067           3 :                                      k[33] = keyNew ("/dirX/keyY", KEY_END),
    1068             :                                      // clang-format on
    1069             :                                      KS_END);
    1070           3 :         succeed_if (keyGetNameSize (k[32]) == 11, "initial size of name wrong");
    1071           3 :         succeed_if (keyGetNameSize (k[33]) == 11, "initial size of name wrong");
    1072             : 
    1073           3 :         srand (23);
    1074             : 
    1075           3 :         succeed_if (ksLookup (0, k[23], 0) == 0, "null pointer");
    1076           3 :         succeed_if (ksLookup (ks, 0, 0) == 0, "null pointer");
    1077             : 
    1078         303 :         for (i = 0; i < 100; i++)
    1079             :         {
    1080         300 :                 ksUnsort (ks);
    1081        7200 :                 for (j = 0; j < 23; j++)
    1082             :                 {
    1083        6900 :                         succeed_if (ksLookup (ks, k[j], 0) == k[j], "did not find key");
    1084             :                 }
    1085         300 :                 succeed_if (ksLookup (ks, k[23], 0) == 0, "found wrong key");
    1086         300 :                 succeed_if (ksLookup (ks, k[26], 0) == 0, "found wrong key");
    1087         300 :                 succeed_if (ksLookup (ks, k[28], 0) == k[6], "did not find key");
    1088         300 :                 succeed_if (ksLookup (ks, k[32], 0) == k[6], "did not find key");
    1089         300 :                 succeed_if (ksLookup (ks, k[33], 0) == 0, "found wrong key");
    1090             : 
    1091         300 :                 succeed_if (keyGetNameSize (k[32]) == 11, "size of name was changed");
    1092         300 :                 succeed_if (keyGetNameSize (k[33]) == 11, "size of name was changed");
    1093             :                 /* Empty lines to add more tests:
    1094             :                 succeed_if (ksLookup(ks, k[], ) == k[], "did not find key");
    1095             :                 succeed_if (ksLookup(ks, k[], ) == 0, "found wrong key");
    1096             :                 */
    1097             :         }
    1098             : 
    1099           3 :         ksDel (ks);
    1100           3 :         ksDel (lookupKeys);
    1101           3 : }
    1102             : 
    1103           3 : static void test_ksLookupByName (void)
    1104             : {
    1105           3 :         printf ("Test lookup by name\n");
    1106             : 
    1107           3 :         int i, j;
    1108           3 :         char * name[1000];
    1109           3 :         Key * k[1000];
    1110           3 :         KeySet * ks = ksNew (30, k[0] = keyNew (name[0] = "user:/rem3", KEY_END), k[1] = keyNew (name[1] = "user:/rem2", KEY_END),
    1111           3 :                              k[2] = keyNew (name[2] = "user:/rem1/key2", KEY_END), k[3] = keyNew (name[3] = "user:/rem1/key1", KEY_END),
    1112           3 :                              k[4] = keyNew (name[4] = "user:/rem1", KEY_END), k[5] = keyNew (name[5] = "user:/dir1", KEY_END),
    1113           3 :                              k[6] = keyNew (name[6] = "user:/dir1/key1", KEY_VALUE, "value1", KEY_END),
    1114           3 :                              k[7] = keyNew (name[7] = "user:/dir1/key2", KEY_VALUE, "value2", KEY_END),
    1115           3 :                              k[8] = keyNew (name[8] = "user:/dir1/key3", KEY_VALUE, "value3", KEY_END),
    1116           3 :                              k[9] = keyNew (name[9] = "user:/dir1/key4", KEY_VALUE, "value4", KEY_END),
    1117           3 :                              k[10] = keyNew (name[10] = "user:/dir1/.inactive1", KEY_META, "comment/#0", "key is inactive", KEY_END),
    1118           3 :                              k[11] = keyNew (name[11] = "user:/dir1/.inactive2", KEY_META, "comment/#0", "additional information", KEY_END),
    1119           3 :                              k[12] = keyNew (name[12] = "user:/dir2", KEY_END),
    1120           3 :                              k[13] = keyNew (name[13] = "user:/dir2/key1", KEY_VALUE, "value1", KEY_END),
    1121           3 :                              k[14] = keyNew (name[14] = "user:/dir2/key2", KEY_VALUE, "value2", KEY_END),
    1122           3 :                              k[15] = keyNew (name[15] = "user:/dir2/key3", KEY_VALUE, "value3", KEY_END),
    1123           3 :                              k[16] = keyNew (name[16] = "user:/dir2/key4", KEY_VALUE, "value4", KEY_END),
    1124           3 :                              k[17] = keyNew (name[17] = "user:/dir3", KEY_END),
    1125           3 :                              k[18] = keyNew (name[18] = "user:/dir3/key1", KEY_VALUE, "value1", KEY_END),
    1126           3 :                              k[19] = keyNew (name[19] = "user:/dir3/.inactive1", KEY_META, "comment/#0", "key is inactive", KEY_END),
    1127           3 :                              k[20] = keyNew (name[20] = "user:/dir3/.inactive2", KEY_META, "comment/#0", "a users comment", KEY_END),
    1128           3 :                              k[21] = keyNew (name[21] = "user:/dir4", KEY_END), k[22] = keyNew (name[22] = "user:/dir5", KEY_END), KS_END);
    1129             : 
    1130           3 :         name[23] = "user:/DiR1";
    1131           3 :         name[24] = "user:/DiR1/KEY1";
    1132           3 :         name[25] = "user:/DiR1/KEY1";
    1133           3 :         name[26] = "user:/DiR1/KEY1";
    1134           3 :         name[27] = "user:/dir1/key1";
    1135           3 :         name[28] = "user:/dir1/key1";
    1136           3 :         name[29] = "user:/dir2/key1";
    1137           3 :         name[30] = "user:/dir2/key1";
    1138           3 :         name[31] = "user:/dir2/key1";
    1139           3 :         name[32] = "user://dir1";
    1140           3 :         name[33] = "user:///dir1";
    1141           3 :         name[34] = "user:///./dir1";
    1142           3 :         name[35] = "user:///./../dir1";
    1143           3 :         name[36] = "user:///./../dir1/";
    1144           3 :         name[37] = "user:///./../dir1//";
    1145             : 
    1146           3 :         srand (23);
    1147             : 
    1148           3 :         succeed_if (ksLookupByName (0, name[23], 0) == 0, "null pointer");
    1149           3 :         succeed_if (ksLookup (ks, 0, 0) == 0, "null pointer");
    1150             : 
    1151         303 :         for (i = 0; i < 100; i++)
    1152             :         {
    1153         300 :                 ksUnsort (ks);
    1154        7200 :                 for (j = 0; j < 23; j++)
    1155        6900 :                         succeed_if (ksLookupByName (ks, name[j], 0) == k[j], "did not find key");
    1156         300 :                 succeed_if (ksLookupByName (ks, name[23], 0) == 0, "found wrong key");
    1157         300 :                 succeed_if (ksLookupByName (ks, name[24], 0) == 0, "found wrong key");
    1158         300 :                 succeed_if (ksLookupByName (ks, name[28], 0) == k[6], "did not find key");
    1159        2100 :                 for (int n = 32; n < 38; ++n)
    1160        2100 :                         succeed_if (ksLookupByName (ks, name[n], 0) == k[5], "did not find key");
    1161             :                 /* Empty lines to add more tests:
    1162             :                 succeed_if (ksLookupByName(ks, name[], ) == name[], "did not find key");
    1163             :                 succeed_if (ksLookupByName(ks, name[], ) == 0, "found wrong key");
    1164             :                 */
    1165             :         }
    1166             : 
    1167           3 :         ksDel (ks);
    1168           3 : }
    1169             : 
    1170             : 
    1171             : #ifdef __SANITIZE_ADDRESS__
    1172             : ELEKTRA_UNUSED
    1173             : #endif
    1174           3 : static void test_ksLookupName (void)
    1175             : {
    1176           3 :         Key * found;
    1177           3 :         KeySet * ks = ksNew (0, KS_END);
    1178             : 
    1179           3 :         printf ("Test lookup functions\n");
    1180             : 
    1181           3 :         ksAppendKey (ks, keyNew ("user:/domain/key", KEY_VALUE, "domainvalue", KEY_END));
    1182           3 :         ksAppendKey (ks, keyNew ("user:/single/key", KEY_VALUE, "singlevalue", KEY_END));
    1183           3 :         ksAppendKey (ks, keyNew ("user:/named/key", KEY_VALUE, "myvalue", KEY_END));
    1184           3 :         ksAppendKey (ks, keyNew ("system:/named/syskey", KEY_VALUE, "syskey", KEY_END));
    1185           3 :         ksAppendKey (ks, keyNew ("system:/sysonly/key", KEY_VALUE, "sysonlykey", KEY_END));
    1186           3 :         ksAppendKey (ks, keyNew ("user:/named/bin", KEY_BINARY, KEY_SIZE, strlen ("binary\1\2data"), KEY_VALUE, "binary\1\2data", KEY_END));
    1187           3 :         ksAppendKey (ks, keyNew ("system:/named/bin", KEY_BINARY, KEY_SIZE, strlen ("sys\1bin\2"), KEY_VALUE, "sys\1bin\2", KEY_END));
    1188           3 :         ksAppendKey (ks, keyNew ("system:/named/key", KEY_BINARY, KEY_SIZE, strlen ("syskey"), KEY_VALUE, "syskey", KEY_END));
    1189           3 :         succeed_if (ksGetSize (ks) == 8, "could not append all keys");
    1190             : 
    1191             :         // a positive test case
    1192           3 :         found = ksLookupByName (ks, "user:/named/key", 0);
    1193           3 :         succeed_if (ksCurrent (ks) == found, "current not set correctly");
    1194             : 
    1195           3 :         succeed_if (found != 0, "did not find correct name");
    1196           3 :         succeed_if (ksCurrent (ks) == found, "current not set correctly");
    1197           3 :         succeed_if_same_string (keyName (found), "user:/named/key");
    1198           3 :         succeed_if_same_string (keyValue (found), "myvalue");
    1199             : 
    1200           3 :         ksAppendKey (ks, found = keyNew ("user:/single/key", KEY_VALUE, "singlevalue", KEY_END));
    1201           3 :         succeed_if (ksCurrent (ks) == found, "current update after append");
    1202           3 :         succeed_if_same_string (keyName (found), "user:/single/key");
    1203           3 :         succeed_if_same_string (keyValue (found), "singlevalue");
    1204             : 
    1205             :         // here you can't find the keys
    1206           3 :         succeed_if (ksLookupByName (ks, "named/key", 0) == 0, "not valid keyname");
    1207           3 :         succeed_if (ksLookupByName (ks, "u/named/key", 0) == 0, "not valid keyname");
    1208           3 :         succeed_if (ksLookupByName (ks, "usea/named/key", 0) == 0, "not valid keyname");
    1209           3 :         succeed_if (ksLookupByName (ks, " user:/named/key", 0) == 0, "found key with bad prefix");
    1210             : 
    1211           3 :         succeed_if (ksLookupByName (ks, "user:/named/Key", 0) == 0, "found wrong case key");
    1212           3 :         succeed_if (ksLookupByName (ks, "User:/Named/key", 0) == 0, "found wrong case key");
    1213           3 :         succeed_if (ksLookupByName (ks, "User:/named/key", 0) == 0, "found wrong case key");
    1214           3 :         succeed_if (ksLookupByName (ks, "user:/NAMED/key", 0) == 0, "found wrong case key");
    1215           3 :         succeed_if (ksLookupByName (ks, "USER:/NAMED/KEY", 0) == 0, "found wrong case key");
    1216             : 
    1217           3 :         succeed_if (ksLookupByName (ks, "user:/named/keys", 0) == 0, "wrong postfix");
    1218           3 :         succeed_if (ksLookupByName (ks, "user:/named/key_", 0) == 0, "wrong postfix");
    1219             : 
    1220           3 :         succeed_if (ksLookupByName (ks, "user:/named/k/ey", 0) == 0, "seperation that should be");
    1221           3 :         succeed_if (ksLookupByName (ks, "user:/na/med/key", 0) == 0, "seperation that should be");
    1222             : 
    1223           3 :         succeed_if (ksLookupByName (ks, "system:/domain/key", 0) == 0, "found key in wrong domain");
    1224             : 
    1225             :         // broken names
    1226           3 :         succeed_if (ksLookupByName (ks, "sys", 0) == 0, "found key with broken entry");
    1227           3 :         succeed_if (ksLookupByName (ks, "what", 0) == 0, "found key with broken entry");
    1228           3 :         succeed_if (ksLookupByName (ks, "", 0) == 0, "found key with empty entry");
    1229           3 :         succeed_if (ksLookupByName (ks, "_", 0) == 0, "found key with broken entry");
    1230             : #ifdef COMPAT
    1231             :         succeed_if (ksLookupByName (ks, "\\", 0) == 0, "found key with broken entry");
    1232             : #endif
    1233           3 :         succeed_if (ksLookupByName (ks, "\\/", 0) == 0, "found key with broken entry");
    1234             : 
    1235             :         // now try to find them, and compare value
    1236           3 :         found = ksLookupByName (ks, "user:/domain/key", 0);
    1237           3 :         succeed_if (ksCurrent (ks) == found, "current not set correctly");
    1238           3 :         exit_if_fail (found != 0, "did not find correct name");
    1239           3 :         succeed_if_same_string (keyName (found), "user:/domain/key");
    1240           3 :         succeed_if_same_string (keyValue (found), "domainvalue");
    1241             : 
    1242           3 :         found = ksLookupByName (ks, "user:/single/key", 0);
    1243           3 :         succeed_if (ksCurrent (ks) == found, "current not set correctly");
    1244           3 :         succeed_if (found != 0, "did not find correct name");
    1245           3 :         succeed_if_same_string (keyName (found), "user:/single/key");
    1246           3 :         succeed_if_same_string (keyValue (found), "singlevalue");
    1247             : 
    1248           3 :         found = ksLookupByName (ks, "system:/named/key", 0);
    1249           3 :         succeed_if (ksCurrent (ks) == found, "current not set correctly");
    1250           3 :         succeed_if (found != 0, "did not find correct name");
    1251           3 :         succeed_if_same_string (keyName (found), "system:/named/key");
    1252           3 :         succeed_if (strncmp (keyValue (found), "syskey", strlen ("syskey")) == 0, "not correct value in found key");
    1253             : 
    1254           3 :         found = ksLookupByName (ks, "user:/named/bin", 0);
    1255           3 :         succeed_if (ksCurrent (ks) == found, "current not set correctly");
    1256           3 :         succeed_if (found != 0, "did not find correct name");
    1257           3 :         succeed_if_same_string (keyName (found), "user:/named/bin");
    1258           3 :         succeed_if (strncmp (keyValue (found), "binary\1\2data", strlen ("binary\1\2data")) == 0, "not correct value in found key");
    1259             : 
    1260           3 :         found = ksLookupByName (ks, "user:/named/key", 0);
    1261           3 :         succeed_if (ksCurrent (ks) == found, "current not set correctly");
    1262           3 :         succeed_if (found != 0, "could not find same key again");
    1263           3 :         succeed_if_same_string (keyName (found), "user:/named/key");
    1264           3 :         succeed_if_same_string (keyValue (found), "myvalue");
    1265             : 
    1266           3 :         ksDel (ks);
    1267           3 : }
    1268             : 
    1269           3 : static void test_ksLookupNameCascading (void)
    1270             : {
    1271           3 :         Key * found;
    1272           3 :         KeySet * ks = ksNew (0, KS_END);
    1273             : 
    1274           3 :         printf ("Test cascading lookup functions\n");
    1275             : 
    1276           3 :         succeed_if (ksLookupByName (ks, "/named/", 0) == 0, "found in empty keyset");
    1277           3 :         succeed_if (ksLookupByName (ks, "//named/", 0) == 0, "found in empty keyset");
    1278           3 :         succeed_if (ksLookupByName (ks, "////named/", 0) == 0, "found in empty keyset");
    1279           3 :         succeed_if (ksLookupByName (ks, "//Person/Visits", 0) == 0, "found in empty keyset");
    1280             : 
    1281           3 :         ksAppendKey (ks, keyNew ("user:/named/key", KEY_VALUE, "myvalue", KEY_END));
    1282           3 :         ksAppendKey (ks, keyNew ("system:/named/key", KEY_VALUE, "wrong value", KEY_END));
    1283           3 :         ksAppendKey (ks, keyNew ("user:/single/key", KEY_VALUE, "singlevalue", KEY_END));
    1284           3 :         ksAppendKey (ks, keyNew ("system:/sysonly/key", KEY_VALUE, "sysonlykey", KEY_END));
    1285           3 :         ksAppendKey (ks, keyNew ("user:/named/otherkey", KEY_VALUE, "singlevalue", KEY_END));
    1286             : 
    1287           3 :         found = ksLookupByName (ks, "/named/key", 0);
    1288           3 :         succeed_if (ksCurrent (ks) == found, "current not set correctly");
    1289           3 :         succeed_if (found != 0, "cascading search failed");
    1290           3 :         succeed_if_same_string (keyName (found), "user:/named/key");
    1291           3 :         succeed_if_same_string (keyValue (found), "myvalue");
    1292             : 
    1293           3 :         found = ksLookupByName (ks, "/sysonly/key", 0);
    1294           3 :         succeed_if (ksCurrent (ks) == found, "current not set correctly");
    1295           3 :         succeed_if (found != 0, "could not find same key again, nocase used");
    1296           3 :         succeed_if_same_string (keyName (found), "system:/sysonly/key");
    1297           3 :         succeed_if_same_string (keyValue (found), "sysonlykey");
    1298             : 
    1299           3 :         succeed_if (ksLookupByName (ks, "/named/", 0) == 0, "found part of key with cascading");
    1300           3 :         succeed_if (ksLookupByName (ks, "/named/keyd", 0) == 0, "found part of key with cascading, bad postfix");
    1301             : 
    1302             : 
    1303             :         // cascading double slash
    1304             : 
    1305           3 :         found = ksLookupByName (ks, "///named/key", 0);
    1306           3 :         succeed_if (ksCurrent (ks) == found, "current not set correctly");
    1307           3 :         succeed_if (found != 0, "cascading search failed");
    1308           3 :         succeed_if_same_string (keyName (found), "user:/named/key");
    1309           3 :         succeed_if_same_string (keyValue (found), "myvalue");
    1310             : 
    1311           3 :         found = ksLookupByName (ks, "//sysonly/key", 0);
    1312           3 :         succeed_if (ksCurrent (ks) == found, "current not set correctly");
    1313           3 :         succeed_if (found != 0, "could not find same key again, nocase used");
    1314           3 :         succeed_if_same_string (keyName (found), "system:/sysonly/key");
    1315           3 :         succeed_if_same_string (keyValue (found), "sysonlykey");
    1316             : 
    1317           3 :         succeed_if (ksLookupByName (ks, "//Person/Visits", 0) == 0, "found part of key with cascading");
    1318           3 :         succeed_if (ksLookupByName (ks, "////named/", 0) == 0, "found part of key with cascading");
    1319           3 :         succeed_if (ksLookupByName (ks, "/////named/keyd", 0) == 0, "found part of key with cascading, bad postfix");
    1320             : 
    1321           3 :         ksAppendKey (ks, keyNew ("user:/named/key", KEY_VALUE, "myvalue", KEY_END));
    1322           3 :         found = ksLookupByName (ks, "//named/key", KDB_O_POP);
    1323           3 :         succeed_if (ksGetSize (ks) == 4, "did not pop key");
    1324           3 :         succeed_if (ksCurrent (ks) == 0, "current not set correctly");
    1325           3 :         succeed_if (found != 0, "cascading search failed");
    1326           3 :         succeed_if_same_string (keyName (found), "user:/named/key");
    1327           3 :         succeed_if_same_string (keyValue (found), "myvalue");
    1328           3 :         succeed_if (keyDel (found) == 0, "could not del popped key");
    1329             : 
    1330           3 :         ksDel (ks);
    1331             : 
    1332             : 
    1333           3 :         ks = ksNew (10, KS_END);
    1334           3 :         ksAppendKey (ks, keyNew ("system:/test/myapp/key", KEY_VALUE, "wrong", KEY_END));
    1335           3 :         ksAppendKey (ks, keyNew ("user:/test/myapp/key", KEY_VALUE, "correct", KEY_END));
    1336             : 
    1337           3 :         succeed_if_same_string (keyString (ksLookupByName (ks, "/test/myapp/key", 0)), "correct");
    1338           3 :         Key * s = 0;
    1339           3 :         succeed_if_same_string (keyString (s = ksLookupByName (ks, "/test/myapp/key", KDB_O_POP)), "correct");
    1340           3 :         keyDel (s);
    1341           3 :         succeed_if_same_string (keyString (s = ksLookupByName (ks, "/test/myapp/key", KDB_O_POP)), "wrong");
    1342           3 :         keyDel (s);
    1343           3 :         ksDel (ks);
    1344             : 
    1345             : 
    1346           3 :         ks = ksNew (10, KS_END);
    1347           3 :         Key * k1;
    1348           3 :         Key * k2;
    1349           3 :         ksAppendKey (ks, k1 = keyNew ("system:/test/myapp/key", KEY_VALUE, "wrong", KEY_END));
    1350           3 :         ksAppendKey (ks, k2 = keyNew ("user:/test/myapp/key", KEY_VALUE, "correct", KEY_END));
    1351           3 :         ksAppendKey (ks, keyDup ((s = keyNew ("/test/myapp/key", KEY_END)), KEY_CP_ALL));
    1352           3 :         succeed_if (ksGetSize (ks) == 3, "initial size of keyset");
    1353           3 :         succeed_if (keyGetNameSize (s) == 16, "initial name size");
    1354             : 
    1355           3 :         succeed_if (ksLookup (ks, s, 0) == k2, "got wrong key (not user)");
    1356           3 :         succeed_if (ksLookup (ks, s, 0) != k1, "got system key first");
    1357           3 :         succeed_if (ksLookup (ks, s, 0) != s, "got cascading key");
    1358           3 :         succeed_if_same_string (keyString (ksLookup (ks, s, 0)), "correct");
    1359           3 :         succeed_if (ksGetSize (ks) == 3, "lookup without pop changed size");
    1360           3 :         succeed_if (keyGetNameSize (s) == 16, "size changed after lookup");
    1361             : 
    1362           3 :         succeed_if_same_string (keyString (ksLookup (ks, s, KDB_O_POP)), "correct");
    1363           3 :         succeed_if (ksGetSize (ks) == 2, "lookup with pop did not change size");
    1364           3 :         succeed_if (keyGetNameSize (s) == 16, "size changed after lookup");
    1365             : 
    1366           3 :         succeed_if (ksLookup (ks, s, 0) == k1, "got wrong key (not system)");
    1367           3 :         succeed_if (ksLookup (ks, s, 0) != k2, "got user key again");
    1368           3 :         succeed_if (ksLookup (ks, s, 0) != s, "got cascading key");
    1369           3 :         succeed_if_same_string (keyString (ksLookup (ks, s, KDB_O_POP)), "wrong");
    1370           3 :         succeed_if (ksGetSize (ks) == 1, "lookup with pop did not change size");
    1371           3 :         succeed_if (keyGetNameSize (s) == 16, "size changed after lookup");
    1372           3 :         ksDel (ks);
    1373           3 :         keyDel (s);
    1374           3 :         keyDel (k1);
    1375           3 :         keyDel (k2);
    1376             : 
    1377             : 
    1378           3 :         ks = ksNew (10, KS_END);
    1379           3 :         ksAppendKey (ks, k1 = keyNew ("system:/test/myapp/key", KEY_VALUE, "wrong", KEY_END));
    1380           3 :         ksAppendKey (ks, k2 = keyNew ("user:/test/myapp/key", KEY_VALUE, "correct", KEY_END));
    1381             : 
    1382           3 :         succeed_if_same_string (keyString (ksLookup (ks, k2, KDB_O_POP)), "correct");
    1383           3 :         succeed_if_same_string (keyString (ksLookup (ks, k1, KDB_O_POP)), "wrong");
    1384             : 
    1385           3 :         keyDel (k1);
    1386           3 :         keyDel (k2);
    1387           3 :         ksDel (ks);
    1388             : 
    1389             : 
    1390           3 :         ks = ksNew (10, KS_END);
    1391           3 :         ksAppendKey (ks, k1 = keyNew ("system:/test/myapp/key", KEY_VALUE, "wrong", KEY_END));
    1392           3 :         ksAppendKey (ks, k2 = keyNew ("user:/test/myapp/key", KEY_VALUE, "correct", KEY_END));
    1393             : 
    1394           3 :         succeed_if_same_string (keyString (ksLookup (ks, k1, KDB_O_POP)), "wrong");
    1395           3 :         succeed_if_same_string (keyString (ksLookup (ks, k2, KDB_O_POP)), "correct");
    1396             : 
    1397           3 :         keyDel (k1);
    1398           3 :         keyDel (k2);
    1399           3 :         ksDel (ks);
    1400           3 : }
    1401             : 
    1402           3 : static void test_ksExample (void)
    1403             : {
    1404           3 :         KeySet * ks = ksNew (0, KS_END);
    1405           3 :         Key * key;
    1406             : 
    1407           3 :         ksAppendKey (ks, keyNew ("user:/test", KEY_END)); // an empty key
    1408             : 
    1409           3 :         ksAppendKey (ks, keyNew ("user:/sw", // the name of the key
    1410             :                                  KEY_END));  // no more args
    1411             : 
    1412           3 :         ksAppendKey (ks, keyNew ("user:/tmp/ex1", KEY_VALUE, "some data", // set a string value
    1413             :                                  KEY_END));                               // end of args
    1414             : 
    1415           3 :         ksAppendKey (ks, keyNew ("user:/tmp/ex4",
    1416             :                                  KEY_BINARY,             // key type
    1417             :                                  KEY_SIZE, 7,            // assume binary length 7
    1418             :                                  KEY_VALUE, "some data", // value that will be truncated in 7 bytes
    1419             :                                  KEY_META, "comment/#0", "value is truncated",
    1420             :                                  KEY_END)); // end of args
    1421             : 
    1422           3 :         ksAppendKey (ks, keyNew ("user:/tmp/ex5",
    1423             :                                  KEY_BINARY,                          // binary value
    1424             :                                  KEY_SIZE, 7, KEY_VALUE, "some data", // value that will be truncated in 7 bytes
    1425             :                                  KEY_META, "comment/#0", "value is truncated",
    1426             :                                  KEY_END)); // end of args
    1427             : 
    1428           3 :         ksRewind (ks);
    1429             : 
    1430           3 :         key = ksNext (ks);
    1431           3 :         succeed_if (key != NULL, "no next key");
    1432           3 :         succeed_if_same_string (keyName (key), "user:/sw");
    1433             : 
    1434           3 :         key = ksNext (ks);
    1435           3 :         succeed_if (key != NULL, "no next key");
    1436           3 :         succeed_if_same_string (keyName (key), "user:/test");
    1437             : 
    1438           3 :         key = ksNext (ks);
    1439           3 :         succeed_if (key != NULL, "no next key");
    1440           3 :         succeed_if_same_string (keyName (key), "user:/tmp/ex1");
    1441             : 
    1442           3 :         key = ksNext (ks);
    1443           3 :         succeed_if (key != NULL, "no next key");
    1444           3 :         succeed_if_same_string (keyName (key), "user:/tmp/ex4");
    1445             : 
    1446           3 :         key = ksNext (ks);
    1447           3 :         succeed_if (key != NULL, "no next key");
    1448           3 :         succeed_if_same_string (keyName (key), "user:/tmp/ex5");
    1449             : 
    1450           3 :         ksDel (ks);
    1451           3 : }
    1452             : 
    1453           3 : static void test_ksAppend (void)
    1454             : {
    1455           3 :         int i;
    1456             : 
    1457           3 :         printf ("Test appending keys\n");
    1458             : 
    1459           3 :         Key * key = keyNew ("user:/test", KEY_END);
    1460           3 :         KeySet * ks = ksNew (0, KS_END);
    1461           3 :         succeed_if (ksAppendKey (0, key) == -1, "No error on NULL pointer");
    1462           3 :         succeed_if (ksAppendKey (ks, 0) == -1, "No error on NULL pointer");
    1463           3 :         ksDel (ks);
    1464           3 :         keyDel (key);
    1465             : 
    1466           3 :         KeySet * returned =
    1467             : #include "data_keyset.c"
    1468           3 :                 KeySet * testDirectBelow =
    1469             : #include "data_dbelow.c"
    1470           3 :                         KeySet * testReturned =
    1471             : #include "data_others.c"
    1472           3 :                                 Key * parentKey[2];
    1473           3 :         parentKey[0] = keyNew ("user:/test/keyset", KEY_END);
    1474           3 :         parentKey[1] = keyNew ("user:/test/keyset/dir1", KEY_END);
    1475             : 
    1476             :         /* A real world example out in kdb.c */
    1477           9 :         for (i = 0; i < 2; i++)
    1478             :         {
    1479           6 :                 KeySet * tmp = ksNew (ksGetSize (returned), KS_END);
    1480           6 :                 KeySet * keys = ksNew (0, KS_END);
    1481             : 
    1482             :                 /* add all keys direct below parentKey */
    1483           6 :                 ksRewind (returned);
    1484           6 :                 Key * current;
    1485         618 :                 while ((current = ksPop (returned)) != 0)
    1486             :                 {
    1487         612 :                         if (keyIsDirectlyBelow (parentKey[i], current))
    1488             :                         {
    1489          81 :                                 ksAppendKey (keys, current);
    1490             :                         }
    1491             :                         else
    1492             :                         {
    1493         531 :                                 ksAppendKey (tmp, current);
    1494             :                         }
    1495             :                 }
    1496           6 :                 ksAppend (returned, tmp);
    1497             : 
    1498             :                 /*
    1499             :                 ksOutput (tmp, stdout, KDB_O_HEADER);
    1500             :                 ksOutput (returned, stdout, KDB_O_HEADER);
    1501             :                 printf (" ----- keys -------\n");
    1502             :                 ksOutput (keys, stdout, KDB_O_HEADER);
    1503             :                 */
    1504             : 
    1505           6 :                 if (!i)
    1506             :                 {
    1507         501 :                         compare_keyset (returned, testReturned);
    1508          87 :                         compare_keyset (keys, testDirectBelow);
    1509             : 
    1510           3 :                         succeed_if (ksGetSize (tmp) == 84, "size not correct");
    1511           3 :                         succeed_if (ksGetSize (returned) == 84, "size not correct");
    1512           3 :                         succeed_if (ksGetSize (keys) == 18, "size not correct");
    1513             : 
    1514             :                         // succeed_if (ksGetAlloc (tmp) == 102, "alloc not correct");
    1515             :                         // succeed_if (ksGetAlloc (returned) == 127, "alloc not correct");
    1516             :                         // succeed_if (ksGetAlloc (keys) == 31, "alloc not correct");
    1517             :                 }
    1518             : 
    1519           6 :                 ksAppend (returned, keys); /* add the keys back */
    1520             : 
    1521           6 :                 ksDel (tmp);
    1522           6 :                 ksDel (keys);
    1523             :         }
    1524             : 
    1525           3 :         keyDel (parentKey[0]);
    1526           3 :         keyDel (parentKey[1]);
    1527             : 
    1528           3 :         ksDel (testReturned);
    1529           3 :         ksDel (testDirectBelow);
    1530           3 :         ksDel (returned);
    1531             : 
    1532           3 :         ks = ksNew (0, KS_END);
    1533           3 :         ksAppendKey (ks, keyNew ("user:/abc", KEY_META, "xyz", "egh", KEY_END));
    1534             : 
    1535           3 :         KeySet * other = ksNew (0, KS_END);
    1536           3 :         ksAppend (other, ks);
    1537           9 :         compare_keyset (ks, other);
    1538           3 :         compare_keyset (ks, ks);
    1539             : 
    1540           3 :         succeed_if (ksAppend (ks, 0) == -1, "No error on NULL pointer");
    1541           3 :         succeed_if (ksAppend (0, ks) == -1, "No error on NULL pointer");
    1542             : 
    1543           3 :         ksDel (other);
    1544           3 :         ksDel (ks);
    1545           3 : }
    1546             : 
    1547             : 
    1548             : /**A functional mode to keys.
    1549             :  *
    1550             :  * Instead of writing your own loop you can write
    1551             :  * a function working with a key and pass it to
    1552             :  * this method.
    1553             :  *
    1554             :  * The function will be executed for all keys in
    1555             :  * the keyset.
    1556             :  *
    1557             :  * @param ks the keyset to work with
    1558             :  * @param func the function to execute on every key of the keyset
    1559             :  * @return the sum of all return values
    1560             :  * @return -1 if any function returned -1, the execution will stop there, but
    1561             :  *      ksCurrent() will tell you where it stopped.
    1562             :  * @see ksFilter()
    1563             :  */
    1564          12 : int ksForEach (KeySet * ks, int (*func) (Key * k))
    1565             : {
    1566          12 :         int ret = 0;
    1567          12 :         Key * current;
    1568             : 
    1569          12 :         elektraCursor cursor = ksGetCursor (ks);
    1570          12 :         ksRewind (ks);
    1571          69 :         while ((current = ksNext (ks)) != 0)
    1572             :         {
    1573          60 :                 int rc = func (current);
    1574          60 :                 if (rc == -1) return -1;
    1575          57 :                 ret += rc;
    1576             :         }
    1577           9 :         ksSetCursor (ks, cursor);
    1578           9 :         return ret;
    1579             : }
    1580             : 
    1581             : 
    1582             : /**Filter a keyset.
    1583             :  *
    1584             :  * filter is executed for every key in the keyset result. When it returns 0,
    1585             :  * the key will be dropped, when it returns 1 it will be ksAppendKey()ed to result,
    1586             :  * when it returns -1 the processing will be stopped. You can use ksCurrent()
    1587             :  * on input to see where the problem was. Because of this input is not const,
    1588             :  * apart from ksCurrent() the input will not be changed. The keys that have
    1589             :  * been in result before will stay untouched.
    1590             :  *
    1591             :  * @param result is the keyset where keys are added.
    1592             :  * @param input is the keyset the filter works on.
    1593             :  * @param filter is the function to execute on every key of the keyset to decide if
    1594             :  *      it should be ksAppendKey()ed to the result.
    1595             :  * @return the number of keys added on success
    1596             :  * @return 0 when nothing was done
    1597             :  * @return -1 when filter returned an error (-1), ksCurrent() of input will
    1598             :  *      be the problematic key.
    1599             :  * @see ksForEach()
    1600             :  **/
    1601          12 : int ksFilter (KeySet * result, KeySet * input, int (*filter) (Key * k))
    1602             : {
    1603          12 :         int ret = 0;
    1604          12 :         Key * current;
    1605             : 
    1606          12 :         elektraCursor cursor = ksGetCursor (input);
    1607          12 :         ksRewind (input);
    1608         108 :         while ((current = ksNext (input)) != 0)
    1609             :         {
    1610          84 :                 int rc = filter (current);
    1611          84 :                 if (rc == -1)
    1612             :                         return -1;
    1613          84 :                 else if (rc != 0)
    1614             :                 {
    1615          42 :                         ++ret;
    1616          42 :                         ksAppendKey (result, keyDup (current, KEY_CP_ALL));
    1617             :                 }
    1618             :         }
    1619          12 :         ksSetCursor (input, cursor);
    1620          12 :         return ret;
    1621             : }
    1622             : 
    1623             : 
    1624             : Key * global_a;
    1625             : 
    1626          21 : int add_string (Key * check)
    1627             : {
    1628          21 :         return keySetString (check, "string");
    1629             : }
    1630             : // int add_comment (Key *check) { return keySetComment (check, "comment"); }
    1631          21 : int has_a (Key * check)
    1632             : {
    1633          21 :         return keyName (check)[6] == 'a';
    1634             : }
    1635          21 : int below_a (Key * check)
    1636             : {
    1637          21 :         return keyIsBelow (global_a, check);
    1638             : }
    1639          21 : int direct_below_a (Key * check)
    1640             : {
    1641          21 :         return keyIsDirectlyBelow (global_a, check);
    1642             : }
    1643             : 
    1644          30 : int sum_helper (Key * check)
    1645             : {
    1646          30 :         return atoi (keyValue (check));
    1647             : }
    1648          21 : int below_30 (Key * check)
    1649             : {
    1650          21 :         return atoi (keyValue (check)) < 30;
    1651             : }
    1652           9 : int find_80 (Key * check)
    1653             : {
    1654           9 :         int n = atoi (keyValue (check));
    1655           9 :         return n > 70 ? -1 : 1;
    1656             : }
    1657             : 
    1658           3 : static void test_ksFunctional (void)
    1659             : {
    1660           3 :         Key * found;
    1661           3 :         Key * current;
    1662           3 :         KeySet * out;
    1663           3 :         KeySet * ks = ksNew (64, keyNew ("user:/a/1", KEY_END), keyNew ("user:/a/2", KEY_END), keyNew ("user:/a/b/1", KEY_END),
    1664             :                              keyNew ("user:/a/b/2", KEY_END), keyNew ("user:/ab/2", KEY_END), keyNew ("user:/b/1", KEY_END),
    1665             :                              keyNew ("user:/b/2", KEY_END), KS_END);
    1666           3 :         global_a = keyNew ("user:/a", KEY_END);
    1667             : 
    1668           3 :         printf ("Test functional style\n");
    1669             : 
    1670           3 :         ksForEach (ks, add_string);
    1671             :         // ksForEach (ks, add_comment);
    1672             : 
    1673           3 :         ksRewind (ks);
    1674          27 :         while ((current = ksNext (ks)) != 0)
    1675             :         {
    1676          45 :                 succeed_if_same_string (keyValue (current), "string");
    1677             :                 // succeed_if_same_string (keyComment (current), "comment");
    1678             :         }
    1679             : 
    1680           3 :         out = ksNew (0, KS_END);
    1681           3 :         succeed_if (ksGetSize (ks) == 7, "initial size wrong");
    1682           3 :         succeed_if (ksGetSize (out) == 0, "initial size wrong");
    1683           3 :         ksFilter (out, ks, has_a);
    1684           3 :         succeed_if (ksGetSize (out) == 5, "has_a cut more than the user:/b");
    1685           3 :         ksDel (out);
    1686             : 
    1687           3 :         out = ksNew (0, KS_END);
    1688           3 :         ksFilter (out, ks, below_a);
    1689           3 :         succeed_if (ksGetSize (out) == 4, "below_a cut more than the user:/ab/2");
    1690           3 :         ksDel (out);
    1691             : 
    1692           3 :         out = ksNew (0, KS_END);
    1693           3 :         ksFilter (out, ks, direct_below_a);
    1694           3 :         succeed_if (ksGetSize (out) == 2, "direct_below_a cut more than the user:/a/b/*");
    1695           3 :         ksDel (out);
    1696             : 
    1697           3 :         ksDel (ks);
    1698           3 :         keyDel (global_a);
    1699           3 :         global_a = 0;
    1700             : 
    1701           3 :         KeySet * values = ksNew (64, keyNew ("user:/a", KEY_VALUE, "40", KEY_END), keyNew ("user:/b", KEY_VALUE, "20", KEY_END),
    1702             :                                  keyNew ("user:/c", KEY_VALUE, "80", KEY_END), keyNew ("user:/d", KEY_VALUE, "24", KEY_END),
    1703             :                                  keyNew ("user:/e", KEY_VALUE, "32", KEY_END), keyNew ("user:/f", KEY_VALUE, "12", KEY_END),
    1704             :                                  keyNew ("user:/g", KEY_VALUE, "43", KEY_END), KS_END);
    1705             : 
    1706           3 :         succeed_if (ksForEach (values, sum_helper) == 251, "could not sum up");
    1707             : 
    1708           3 :         KeySet * values_below_30 = ksNew (0, KS_END);
    1709           3 :         ksFilter (values_below_30, values, below_30);
    1710           3 :         succeed_if (ksGetSize (values_below_30) == 3, "could not filter out everything above 30");
    1711           3 :         succeed_if (ksForEach (values_below_30, sum_helper) == 56, "could not sum up");
    1712             : 
    1713           3 :         succeed_if (ksForEach (values, find_80) == -1, "did not find 80");
    1714           3 :         found = ksCurrent (values);
    1715           3 :         succeed_if (ksLookupByName (values, "user:/c", 0) == found, "did not find 80");
    1716             :         /*succeed_if (ksLookupByString (values, "80", 0) == found, "lookup by value did not find 80");*/
    1717           3 :         ksDel (values);
    1718           3 :         ksDel (values_below_30);
    1719           3 : }
    1720             : 
    1721             : #ifdef __SANITIZE_ADDRESS__
    1722             : ELEKTRA_UNUSED
    1723             : #endif
    1724           3 : static void test_ksLookupPop (void)
    1725             : {
    1726           3 :         printf ("Test ksLookup with KDB_O_POP\n");
    1727             : 
    1728           3 :         Key * found;
    1729           3 :         Key *a, *b, *c;
    1730           3 :         KeySet * small =
    1731           3 :                 ksNew (5, a = keyNew ("user:/a", KEY_END), b = keyNew ("user:/b", KEY_END), c = keyNew ("user:/c", KEY_END), KS_END);
    1732             : 
    1733           3 :         ksRewind (small);
    1734           3 :         ksNext (small);
    1735           3 :         succeed_if (ksCurrent (small) == a, "current not set correctly");
    1736             : 
    1737           3 :         succeed_if (ksGetSize (small) == 3, "could not append all keys");
    1738           3 :         found = ksLookupByName (small, "user:/a", KDB_O_POP);
    1739           3 :         succeed_if (found == a, "not correct key");
    1740           3 :         succeed_if_same_string (keyName (found), "user:/a");
    1741           3 :         succeed_if (ksCurrent (small) == 0, "current not set correctly");
    1742           3 :         succeed_if (keyDel (found) == 0, "could not del popped key");
    1743             : 
    1744           3 :         ksNext (small);
    1745           3 :         ksNext (small);
    1746           3 :         succeed_if (ksCurrent (small) == c, "current not set correctly");
    1747             : 
    1748           3 :         succeed_if (ksGetSize (small) == 2, "could not append all keys");
    1749           3 :         found = ksLookupByName (small, "user:/b", KDB_O_POP);
    1750           3 :         succeed_if (found == b, "not correct key");
    1751           3 :         succeed_if_same_string (keyName (found), "user:/b");
    1752           3 :         succeed_if (ksCurrent (small) == 0, "current not set correctly");
    1753           3 :         succeed_if (keyDel (found) == 0, "could not del popped key");
    1754             : 
    1755           3 :         succeed_if (ksGetSize (small) == 1, "could not append all keys");
    1756           3 :         found = ksLookupByName (small, "user:/b", KDB_O_POP);
    1757           3 :         succeed_if (found == 0, "found something, but should not");
    1758           3 :         succeed_if (ksCurrent (small) == 0, "current not set correctly");
    1759             : 
    1760           3 :         succeed_if (ksGetSize (small) == 1, "could not append all keys");
    1761           3 :         found = ksLookupByName (small, "user:/c", KDB_O_POP);
    1762           3 :         succeed_if (found == c, "not correct key");
    1763           3 :         succeed_if_same_string (keyName (found), "user:/c");
    1764           3 :         succeed_if (ksCurrent (small) == 0, "current not set correctly");
    1765           3 :         succeed_if (keyDel (found) == 0, "could not del popped key");
    1766             : 
    1767           3 :         succeed_if (ksGetSize (small) == 0, "could not append all keys");
    1768           3 :         found = ksLookupByName (small, "user:/d", KDB_O_POP);
    1769           3 :         succeed_if (found == 0, "found something, but should not");
    1770           3 :         succeed_if (ksCurrent (small) == 0, "current not set correctly");
    1771             : 
    1772           3 :         ksDel (small);
    1773             : 
    1774           3 :         KeySet * ks = ksNew (0, KS_END);
    1775             : 
    1776           3 :         ksAppendKey (ks, keyNew ("user:/domain/key", KEY_VALUE, "domainvalue", KEY_END));
    1777           3 :         ksAppendKey (ks, keyNew ("user:/single/key", KEY_VALUE, "singlevalue", KEY_END));
    1778           3 :         ksAppendKey (ks, keyNew ("user:/named/key", KEY_VALUE, "myvalue", KEY_END));
    1779           3 :         ksAppendKey (ks, keyNew ("system:/named/skey", KEY_VALUE, "syskey", KEY_END));
    1780           3 :         ksAppendKey (ks, keyNew ("system:/sysonly/key", KEY_VALUE, "sysonlykey", KEY_END));
    1781           3 :         ksAppendKey (ks, keyNew ("user:/named/bin", KEY_BINARY, KEY_SIZE, strlen ("binary\1\2data"), KEY_VALUE, "binary\1\2data", KEY_END));
    1782           3 :         ksAppendKey (ks, keyNew ("system:/named/bin", KEY_BINARY, KEY_SIZE, strlen ("sys\1bin\2"), KEY_VALUE, "sys\1bin\2", KEY_END));
    1783           3 :         ksAppendKey (ks, keyNew ("system:/named/key", KEY_BINARY, KEY_SIZE, strlen ("syskey"), KEY_VALUE, "syskey", KEY_END));
    1784           3 :         succeed_if (ksGetSize (ks) == 8, "could not append all keys");
    1785             : 
    1786             :         // a positive test case
    1787           3 :         found = ksLookupByName (ks, "user:/named/key", KDB_O_POP);
    1788           3 :         succeed_if (ksGetSize (ks) == 7, "did not pop key");
    1789           3 :         succeed_if (ksCurrent (ks) == 0, "current not set correctly");
    1790           3 :         succeed_if (found != 0, "did not find correct name");
    1791           3 :         succeed_if (ksCurrent (ks) == 0, "current not set correctly");
    1792           3 :         succeed_if_same_string (keyName (found), "user:/named/key");
    1793           3 :         succeed_if_same_string (keyValue (found), "myvalue");
    1794           3 :         succeed_if (keyDel (found) == 0, "could not del popped key");
    1795             : 
    1796           3 :         ksAppendKey (ks, keyNew ("user:/named/key", KEY_VALUE, "singlevalue", KEY_END));
    1797           3 :         succeed_if (ksGetSize (ks) == 8, "did not append key");
    1798             : 
    1799             :         // here you can't find the keys
    1800           3 :         succeed_if (ksLookupByName (ks, "named/key", KDB_O_POP) == 0, "not valid keyname");
    1801           3 :         succeed_if (ksLookupByName (ks, "u/named/key", KDB_O_POP) == 0, "not valid keyname");
    1802           3 :         succeed_if (ksLookupByName (ks, "usea/named/key", KDB_O_POP) == 0, "not valid keyname");
    1803           3 :         succeed_if (ksLookupByName (ks, " user:/named/key", KDB_O_POP) == 0, "found key with bad prefix");
    1804             : 
    1805           3 :         succeed_if (ksLookupByName (ks, "user:/named/Key", KDB_O_POP) == 0, "found wrong case key");
    1806           3 :         succeed_if (ksLookupByName (ks, "User:/Named/key", KDB_O_POP) == 0, "found wrong case key");
    1807           3 :         succeed_if (ksLookupByName (ks, "User:/named/key", KDB_O_POP) == 0, "found wrong case key");
    1808           3 :         succeed_if (ksLookupByName (ks, "user:/NAMED/key", KDB_O_POP) == 0, "found wrong case key");
    1809           3 :         succeed_if (ksLookupByName (ks, "USER:/NAMED/KEY", KDB_O_POP) == 0, "found wrong case key");
    1810             : 
    1811           3 :         succeed_if (ksLookupByName (ks, "user:/named/keys", KDB_O_POP) == 0, "wrong postfix");
    1812           3 :         succeed_if (ksLookupByName (ks, "user:/named/key_", KDB_O_POP) == 0, "wrong postfix");
    1813             : 
    1814           3 :         succeed_if (ksLookupByName (ks, "user:/named/k/ey", KDB_O_POP) == 0, "seperation that should be");
    1815           3 :         succeed_if (ksLookupByName (ks, "user:/na/med/key", KDB_O_POP) == 0, "seperation that should be");
    1816             : 
    1817             :         // a positive test case
    1818           3 :         found = ksLookupByName (ks, "user:/named/key", KDB_O_POP);
    1819           3 :         succeed_if (ksGetSize (ks) == 7, "did not pop key");
    1820           3 :         succeed_if (ksCurrent (ks) == 0, "current not set correctly");
    1821           3 :         succeed_if (found != 0, "did not find correct name");
    1822           3 :         succeed_if (ksCurrent (ks) == 0, "current not set correctly");
    1823           3 :         succeed_if_same_string (keyName (found), "user:/named/key");
    1824           3 :         succeed_if_same_string (keyValue (found), "singlevalue");
    1825           3 :         succeed_if (keyDel (found) == 0, "could not del popped key");
    1826             : 
    1827           3 :         ksAppendKey (ks, keyNew ("user:/named/otherkey", KEY_VALUE, "singlevalue", KEY_END));
    1828           3 :         succeed_if (ksGetSize (ks) == 8, "did not append key");
    1829             : 
    1830           3 :         succeed_if (ksLookupByName (ks, "system:/domain/key", KDB_O_POP) == 0, "found key in wrong domain");
    1831             : 
    1832             :         // now try to find them, and compare value
    1833           3 :         found = ksLookupByName (ks, "user:/domain/key", KDB_O_POP);
    1834           3 :         succeed_if (ksGetSize (ks) == 7, "did not pop key");
    1835           3 :         succeed_if (ksCurrent (ks) == 0, "current not set correctly");
    1836           3 :         succeed_if (found != 0, "did not find correct name");
    1837           3 :         succeed_if_same_string (keyName (found), "user:/domain/key");
    1838           3 :         succeed_if_same_string (keyValue (found), "domainvalue");
    1839           3 :         succeed_if (keyDel (found) == 0, "could not del popped key");
    1840             : 
    1841           3 :         found = ksLookupByName (ks, "user:/single/key", KDB_O_POP);
    1842           3 :         succeed_if (ksGetSize (ks) == 6, "did not pop key");
    1843           3 :         succeed_if (ksCurrent (ks) == 0, "current not set correctly");
    1844           3 :         succeed_if (found != 0, "did not find correct name");
    1845           3 :         succeed_if_same_string (keyName (found), "user:/single/key");
    1846           3 :         succeed_if_same_string (keyValue (found), "singlevalue");
    1847           3 :         succeed_if (keyDel (found) == 0, "could not del popped key");
    1848             : 
    1849           3 :         found = ksLookupByName (ks, "system:/named/key", KDB_O_POP);
    1850           3 :         succeed_if (ksGetSize (ks) == 5, "did not pop key");
    1851           3 :         succeed_if (ksCurrent (ks) == 0, "current not set correctly");
    1852           3 :         succeed_if (found != 0, "did not find correct name");
    1853           3 :         succeed_if_same_string (keyName (found), "system:/named/key");
    1854           3 :         succeed_if (strncmp (keyValue (found), "syskey", strlen ("syskey")) == 0, "not correct value in found key");
    1855           3 :         succeed_if (keyDel (found) == 0, "could not del popped key");
    1856             : 
    1857           3 :         found = ksLookupByName (ks, "user:/named/bin", KDB_O_POP);
    1858           3 :         succeed_if (ksGetSize (ks) == 4, "pop key");
    1859           3 :         succeed_if (ksCurrent (ks) == 0, "current not set correctly");
    1860           3 :         succeed_if (found != 0, "did not find correct name");
    1861           3 :         succeed_if_same_string (keyName (found), "user:/named/bin");
    1862           3 :         succeed_if (strncmp (keyValue (found), "binary\1\2data", strlen ("binary\1\2data")) == 0, "not correct value in found key");
    1863           3 :         succeed_if (keyDel (found) == 0, "could not del popped key");
    1864             : 
    1865           3 :         found = ksLookupByName (ks, "user:/named/key", KDB_O_POP);
    1866           3 :         succeed_if (ksGetSize (ks) == 4, "did not pop key");
    1867           3 :         succeed_if (ksCurrent (ks) == 0, "current not set correctly");
    1868           3 :         succeed_if (found == 0, "could find same key again");
    1869             : 
    1870             :         // cascading
    1871             : 
    1872           3 :         ksAppendKey (ks, keyNew ("user:/named/key", KEY_VALUE, "myvalue", KEY_END));
    1873           3 :         printf ("Test cascading lookup functions\n");
    1874           3 :         found = ksLookupByName (ks, "/named/key", KDB_O_POP);
    1875           3 :         succeed_if (ksGetSize (ks) == 4, "did not pop key");
    1876           3 :         succeed_if (ksCurrent (ks) == 0, "current not set correctly");
    1877           3 :         succeed_if (found != 0, "cascading search failed");
    1878           3 :         succeed_if_same_string (keyName (found), "user:/named/key");
    1879           3 :         succeed_if_same_string (keyValue (found), "myvalue");
    1880           3 :         succeed_if (keyDel (found) == 0, "could not del popped key");
    1881             : 
    1882           3 :         ksDel (ks);
    1883           3 : }
    1884             : 
    1885           3 : static void test_ksDoubleFree (void)
    1886             : {
    1887             :         /* Valgrind only test */
    1888           3 :         KeySet * ks1 = ksNew (5, keyNew ("user:/abc1", KEY_VALUE, "abc1", KEY_END), keyNew ("user:/abc2", KEY_VALUE, "abc1", KEY_END),
    1889             :                               keyNew ("user:/abc3", KEY_VALUE, "abc1", KEY_END), KS_END);
    1890             : 
    1891           3 :         KeySet * ks2 = ksNew (5, keyNew ("user:/abc1", KEY_VALUE, "abc2", KEY_END), keyNew ("user:/abc2", KEY_VALUE, "abc2", KEY_END),
    1892             :                               keyNew ("user:/abc3", KEY_VALUE, "abc2", KEY_END), KS_END);
    1893             : 
    1894           3 :         Key * cur;
    1895           3 :         ksRewind (ks1);
    1896          12 :         while ((cur = ksNext (ks1)) != 0)
    1897             :         {
    1898           9 :                 ksAppendKey (ks2, cur);
    1899             :         }
    1900             : 
    1901           3 :         ksDel (ks1);
    1902           3 :         ksDel (ks2);
    1903           3 : }
    1904             : 
    1905           3 : static void test_ksDoubleAppend (void)
    1906             : {
    1907           3 :         printf ("Test double appending\n");
    1908             : 
    1909           3 :         KeySet * ks1 = ksNew (5, keyNew ("user:/abc1", KEY_VALUE, "abc1", KEY_END), keyNew ("user:/abc2", KEY_VALUE, "abc1", KEY_END),
    1910             :                               keyNew ("user:/abc3", KEY_VALUE, "abc1", KEY_END), KS_END);
    1911             : 
    1912           3 :         KeySet * ks2 = ksNew (5, keyNew ("user:/abc1", KEY_VALUE, "abc2", KEY_END), keyNew ("user:/abc2", KEY_VALUE, "abc2", KEY_END),
    1913             :                               keyNew ("user:/abc3", KEY_VALUE, "abc2", KEY_END), KS_END);
    1914             : 
    1915           3 :         ksAppend (ks1, ks2);
    1916           3 :         succeed_if (ksGetSize (ks1) == 3, "size not correct");
    1917           3 :         succeed_if (ksGetSize (ks2) == 3, "size not correct");
    1918             : 
    1919           3 :         ksDel (ks1);
    1920           3 :         ksDel (ks2);
    1921           3 : }
    1922             : 
    1923           3 : static void test_ksDoubleAppendKey (void)
    1924             : {
    1925           3 :         printf ("Test double appending of key\n");
    1926             : 
    1927           3 :         Key * k = keyNew ("user:/my_double_key", KEY_END);
    1928           3 :         KeySet * ks = ksNew (0, KS_END);
    1929             : 
    1930           3 :         ksAppendKey (ks, k);
    1931           3 :         succeed_if (ksGetSize (ks) == 1, "size not correct");
    1932             : 
    1933           3 :         ksAppendKey (ks, k);
    1934           3 :         succeed_if (ksGetSize (ks) == 1, "size not correct");
    1935             : 
    1936           3 :         ksAppendKey (ks, k);
    1937           3 :         succeed_if (ksGetSize (ks) == 1, "size not correct");
    1938             : 
    1939           3 :         Key * k2 = keyNew ("user:/other", KEY_END);
    1940             : 
    1941           3 :         ksAppendKey (ks, k2);
    1942           3 :         succeed_if (ksGetSize (ks) == 2, "size not correct");
    1943             : 
    1944           3 :         keyDel (k); // has no effect
    1945             : 
    1946           3 :         ksDel (ks);
    1947             :         // don't free key here!!
    1948           3 : }
    1949             : 
    1950           3 : static void test_ksAppendKey (void)
    1951             : {
    1952           3 :         printf ("Test cursor after appending key\n");
    1953           3 :         KeySet * ks = 0;
    1954           3 :         Key * cur;
    1955             : 
    1956           3 :         exit_if_fail ((ks = ksNew (0, KS_END)) != 0, "could not create new keyset");
    1957             : 
    1958           3 :         succeed_if (ksAppendKey (ks, cur = keyNew ("user:/a", KEY_END)) == 1, "could not append a key");
    1959           3 :         succeed_if (ksCurrent (ks) == cur, "did not update current position");
    1960           3 :         succeed_if (ksAppendKey (ks, cur = keyNew ("user:/b", KEY_END)) == 2, "could not append a key");
    1961           3 :         succeed_if (ksCurrent (ks) == cur, "did not update current position");
    1962           3 :         succeed_if (ksAppendKey (ks, cur = keyNew ("user:/x", KEY_END)) == 3, "could not append a key");
    1963           3 :         succeed_if (ksCurrent (ks) == cur, "did not update current position");
    1964           3 :         succeed_if (ksGetSize (ks) == 3, "size not correct after 3 keys");
    1965             : 
    1966           3 :         succeed_if (ksAppendKey (ks, cur = keyNew ("user:/b", KEY_END)) == 3, "could not append a key");
    1967           3 :         succeed_if (ksCurrent (ks) == cur, "did not update current position (same key)");
    1968           3 :         succeed_if (ksGetSize (ks) == 3, "size not correct after double append");
    1969             : 
    1970           3 :         succeed_if (ksAppendKey (ks, cur = keyNew ("user:/0", KEY_END)) == 4, "could not append a key");
    1971           3 :         succeed_if (ksCurrent (ks) == cur, "did not update current position (front key)");
    1972           3 :         succeed_if (ksGetSize (ks) == 4, "size not correct after 4 keys");
    1973             : 
    1974           3 :         succeed_if (ksAppendKey (ks, cur = keyNew ("user:/c", KEY_END)) == 5, "could not append a key");
    1975           3 :         succeed_if (ksCurrent (ks) == cur, "did not update current position (key in between)");
    1976           3 :         succeed_if (ksGetSize (ks) == 5, "size not correct after 5 keys");
    1977             : 
    1978           3 :         ksDel (ks);
    1979             : 
    1980           3 :         exit_if_fail ((ks = ksNew (0, KS_END)) != 0, "could not create new keyset");
    1981           3 :         succeed_if (ksAppendKey (ks, cur = keyNew ("user:/", KEY_END)) == 1, "could not append a key");
    1982           3 :         succeed_if (ksCurrent (ks) == cur, "did not update current position");
    1983           3 :         succeed_if (ksGetSize (ks) == 1, "size not correct after 1 keys");
    1984             : 
    1985           3 :         succeed_if (ksAppendKey (ks, cur = keyNew ("user:/tests", KEY_END)) == 2, "could not append a key");
    1986           3 :         succeed_if (ksCurrent (ks) == cur, "did not update current position");
    1987           3 :         succeed_if (ksGetSize (ks) == 2, "size not correct after 2 keys");
    1988             : 
    1989           3 :         succeed_if (ksAppendKey (ks, cur = keyNew ("user:/tests/folder", KEY_END)) == 3, "could not append a key");
    1990           3 :         succeed_if (ksCurrent (ks) == cur, "did not update current position");
    1991           3 :         succeed_if (ksGetSize (ks) == 3, "size not correct after 3 keys");
    1992             : 
    1993           3 :         succeed_if (ksAppendKey (ks, cur = keyNew ("user:/tests/folder/bool_key", KEY_END)) == 4, "could not append a key");
    1994           3 :         succeed_if (ksCurrent (ks) == cur, "did not update current position");
    1995           3 :         succeed_if (ksGetSize (ks) == 4, "size not correct after 4 keys");
    1996             : 
    1997           3 :         Key * newKey = keyDup (cur, KEY_CP_ALL);
    1998           3 :         keySetBaseName (newKey, "second_bool_key");
    1999             : 
    2000           3 :         succeed_if (ksAppendKey (ks, newKey) == 5, "could not append a key");
    2001           3 :         succeed_if (ksCurrent (ks) == newKey, "did not update current position");
    2002           3 :         succeed_if (ksGetSize (ks) == 5, "size not correct after 5 keys");
    2003           3 :         ksDel (ks);
    2004           3 : }
    2005             : 
    2006           3 : static void test_ksModifyKey (void)
    2007             : {
    2008           3 :         printf ("Test modify key after insertion\n");
    2009             : 
    2010           3 :         KeySet * ks = 0;
    2011           3 :         Key * cur;
    2012             : 
    2013           3 :         exit_if_fail ((ks = ksNew (0, KS_END)) != 0, "could not create new keyset");
    2014             : 
    2015           3 :         succeed_if (ksAppendKey (ks, cur = keyNew ("user:/a", KEY_END)) == 1, "could not append a key");
    2016           3 :         succeed_if (ksCurrent (ks) == cur, "did not update current position");
    2017           3 :         succeed_if (keySetName (cur, "user:/b") == -1, "set name with appended key should be disallowed");
    2018           3 :         succeed_if (keySetString (cur, "x") > 0, "changing value is ok");
    2019           3 :         succeed_if (keySetMeta (cur, "x", "y") > 0, "changing meta is ok");
    2020           3 :         succeed_if (ksCurrent (ks) == cur, "did not update current position");
    2021             : 
    2022           3 :         ksDel (ks);
    2023           3 : }
    2024             : 
    2025           3 : static void test_ksOrder (void)
    2026             : {
    2027           3 :         KeySet * ks = ksNew (20, keyNew ("user:/test/test", KEY_END), keyNew ("user:/test/test/bar", KEY_END),
    2028             :                              keyNew ("user:/test/test/foo", KEY_END), keyNew ("user:/test/test-foo", KEY_END), KS_END);
    2029             : 
    2030           3 :         ksNext (ks);
    2031           3 :         succeed_if_same_string (keyName (ksCurrent (ks)), "user:/test/test");
    2032           3 :         ksNext (ks);
    2033           3 :         succeed_if_same_string (keyName (ksCurrent (ks)), "user:/test/test/bar");
    2034           3 :         ksNext (ks);
    2035           3 :         succeed_if_same_string (keyName (ksCurrent (ks)), "user:/test/test/foo");
    2036           3 :         ksNext (ks);
    2037           3 :         succeed_if_same_string (keyName (ksCurrent (ks)), "user:/test/test-foo");
    2038             : 
    2039           3 :         ksDel (ks);
    2040             : 
    2041           3 :         ks = ksNew (20, keyNew ("user:/x", KEY_END), keyNew ("user:/x/%", KEY_END), keyNew ("user:/x/%/a", KEY_END),
    2042             :                     keyNew ("user:/x/%/b", KEY_END), keyNew ("user:/x/\\%", KEY_END), keyNew ("user:/x/\\%/a", KEY_END),
    2043             :                     keyNew ("user:/x/\\%/b", KEY_END), keyNew ("user:/x/A", KEY_END), keyNew ("user:/x/A/a", KEY_END),
    2044             :                     keyNew ("user:/x/A/b", KEY_END), keyNew ("user:/x/%a", KEY_END), keyNew ("user:/x/%b", KEY_END),
    2045             :                     keyNew ("user:/x/a\\/", KEY_END), keyNew ("user:/x/a\\/b", KEY_END), keyNew ("user:/x/a\\/b/a", KEY_END),
    2046             :                     keyNew ("user:/x/a\\/b/b", KEY_END), keyNew ("user:/x/aA", KEY_END), keyNew ("user:/x/aA/a", KEY_END),
    2047             :                     keyNew ("user:/x/aA/b", KEY_END), keyNew ("user:/x/aa", KEY_END), keyNew ("user:/x/aa/a", KEY_END),
    2048             :                     keyNew ("user:/x/aa/b", KEY_END), KS_END);
    2049             : 
    2050           3 :         succeed_if (ksCurrent (ks) == 0, "not rewinded");
    2051           3 :         ksNext (ks);
    2052           3 :         succeed_if_same_string (keyName (ksCurrent (ks)), "user:/x");
    2053           3 :         ksNext (ks);
    2054           3 :         succeed_if_same_string (keyName (ksCurrent (ks)), "user:/x/%");
    2055           3 :         ksNext (ks);
    2056           3 :         succeed_if_same_string (keyName (ksCurrent (ks)), "user:/x/%/a");
    2057           3 :         ksNext (ks);
    2058           3 :         succeed_if_same_string (keyName (ksCurrent (ks)), "user:/x/%/b");
    2059           3 :         ksNext (ks);
    2060           3 :         succeed_if_same_string (keyName (ksCurrent (ks)), "user:/x/\\%");
    2061           3 :         ksNext (ks);
    2062           3 :         succeed_if_same_string (keyName (ksCurrent (ks)), "user:/x/\\%/a");
    2063           3 :         ksNext (ks);
    2064           3 :         succeed_if_same_string (keyName (ksCurrent (ks)), "user:/x/\\%/b");
    2065           3 :         ksNext (ks);
    2066           3 :         succeed_if_same_string (keyName (ksCurrent (ks)), "user:/x/%a");
    2067           3 :         ksNext (ks);
    2068           3 :         succeed_if_same_string (keyName (ksCurrent (ks)), "user:/x/%b");
    2069           3 :         ksNext (ks);
    2070           3 :         succeed_if_same_string (keyName (ksCurrent (ks)), "user:/x/A");
    2071           3 :         ksNext (ks);
    2072           3 :         succeed_if_same_string (keyName (ksCurrent (ks)), "user:/x/A/a");
    2073           3 :         ksNext (ks);
    2074           3 :         succeed_if_same_string (keyName (ksCurrent (ks)), "user:/x/A/b");
    2075           3 :         ksNext (ks);
    2076           3 :         succeed_if_same_string (keyName (ksCurrent (ks)), "user:/x/a\\/");
    2077           3 :         ksNext (ks);
    2078           3 :         succeed_if_same_string (keyName (ksCurrent (ks)), "user:/x/a\\/b");
    2079           3 :         ksNext (ks);
    2080           3 :         succeed_if_same_string (keyName (ksCurrent (ks)), "user:/x/a\\/b/a");
    2081           3 :         ksNext (ks);
    2082           3 :         succeed_if_same_string (keyName (ksCurrent (ks)), "user:/x/a\\/b/b");
    2083           3 :         ksNext (ks);
    2084           3 :         succeed_if_same_string (keyName (ksCurrent (ks)), "user:/x/aA");
    2085           3 :         ksNext (ks);
    2086           3 :         succeed_if_same_string (keyName (ksCurrent (ks)), "user:/x/aA/a");
    2087           3 :         ksNext (ks);
    2088           3 :         succeed_if_same_string (keyName (ksCurrent (ks)), "user:/x/aA/b");
    2089           3 :         ksNext (ks);
    2090           3 :         succeed_if_same_string (keyName (ksCurrent (ks)), "user:/x/aa");
    2091           3 :         ksNext (ks);
    2092           3 :         succeed_if_same_string (keyName (ksCurrent (ks)), "user:/x/aa/a");
    2093           3 :         ksNext (ks);
    2094           3 :         succeed_if_same_string (keyName (ksCurrent (ks)), "user:/x/aa/b");
    2095           3 :         ksDel (ks);
    2096           3 : }
    2097             : 
    2098           3 : static void test_ksOrderNs (void)
    2099             : {
    2100           3 :         Key * cascadingKey = keyNew ("/key", KEY_END);
    2101           3 :         Key * metaKey = keyNew ("meta:/key", KEY_END);
    2102           3 :         Key * specKey = keyNew ("spec:/key", KEY_END);
    2103           3 :         Key * procKey = keyNew ("proc:/key", KEY_END);
    2104           3 :         Key * dirKey = keyNew ("dir:/key", KEY_END);
    2105           3 :         Key * userKey = keyNew ("user:/key", KEY_END);
    2106           3 :         Key * systemKey = keyNew ("system:/key", KEY_END);
    2107           3 :         Key * defaultKey = keyNew ("default:/key", KEY_END);
    2108             : 
    2109           3 :         KeySet * ks = ksNew (8, systemKey, userKey, metaKey, defaultKey, cascadingKey, specKey, procKey, dirKey, KS_END);
    2110             : 
    2111           3 :         succeed_if (ksAtCursor (ks, 0) == cascadingKey, "cascading not first");
    2112           3 :         succeed_if (ksAtCursor (ks, 1) == metaKey, "meta not second");
    2113           3 :         succeed_if (ksAtCursor (ks, 2) == specKey, "spec not third");
    2114           3 :         succeed_if (ksAtCursor (ks, 3) == procKey, "proc not fourth");
    2115           3 :         succeed_if (ksAtCursor (ks, 4) == dirKey, "dir not fifth");
    2116           3 :         succeed_if (ksAtCursor (ks, 5) == userKey, "user not sixth");
    2117           3 :         succeed_if (ksAtCursor (ks, 6) == systemKey, "system not seventh");
    2118           3 :         succeed_if (ksAtCursor (ks, 7) == defaultKey, "default not last");
    2119             : 
    2120           3 :         ksDel (ks);
    2121           3 : }
    2122             : 
    2123           3 : KeySet * fill_vaargs (size_t size, ...)
    2124             : {
    2125           3 :         va_list ap;
    2126           3 :         va_start (ap, size);
    2127           3 :         KeySet * ks = ksVNew (size, ap);
    2128           3 :         va_end (ap);
    2129           3 :         return ks;
    2130             : }
    2131             : 
    2132           3 : static void test_keyVNew (void)
    2133             : {
    2134           3 :         printf ("Test keyVNew\n");
    2135             : 
    2136           3 :         KeySet * ks = 0;
    2137             : 
    2138             :         /*
    2139             :                 Not possible on some platforms:
    2140             : 
    2141             :                 ks = ksVNew(0, *(va_list*)KS_END);
    2142             :                 succeed_if (ks != 0, "did not create KeySet");
    2143             :                 ksDel(ks);
    2144             : 
    2145             :                 ks = ksVNew(10, *(va_list*)KS_END);
    2146             :                 succeed_if (ks != 0, "did not create KeySet");
    2147             :                 ksDel(ks);
    2148             :         */
    2149             : 
    2150           3 :         ks = fill_vaargs (20, keyNew ("user:/a", KEY_END), KS_END);
    2151           3 :         succeed_if (ks != 0, "did not create KeySet");
    2152           3 :         succeed_if (ksGetSize (ks) == 1, "KeySet wrong size");
    2153           3 :         succeed_if (ksLookupByName (ks, "user:/a", 0) != 0, "could not lookup key");
    2154           3 :         ksDel (ks);
    2155           3 : }
    2156             : 
    2157             : 
    2158          48 : static KeySet * set_a (void)
    2159             : {
    2160          48 :         return ksNew (16, keyNew ("user:/0", KEY_END), keyNew ("user:/a", KEY_END), keyNew ("user:/a/a", KEY_END),
    2161             :                       keyNew ("user:/a/a/a", KEY_END), keyNew ("user:/a/a/b", KEY_END), keyNew ("user:/a/b", KEY_END),
    2162             :                       keyNew ("user:/a/b/a", KEY_END), keyNew ("user:/a/b/b", KEY_END), keyNew ("user:/a/c", KEY_END),
    2163             :                       keyNew ("user:/a/d", KEY_END), keyNew ("user:/a/x/a", KEY_END), keyNew ("user:/a/x/b", KEY_END),
    2164             :                       keyNew ("user:/a/x/c", KEY_END), keyNew ("user:/a/x/c/a", KEY_END), keyNew ("user:/a/x/c/b", KEY_END),
    2165             :                       keyNew ("user:/x", KEY_END), KS_END);
    2166             : }
    2167             : 
    2168           6 : static KeySet * set_oa (void)
    2169             : {
    2170           6 :         return ksNew (14, keyNew ("user:/a", KEY_END), keyNew ("user:/a/a", KEY_END), keyNew ("user:/a/a/a", KEY_END),
    2171             :                       keyNew ("user:/a/a/b", KEY_END), keyNew ("user:/a/b", KEY_END), keyNew ("user:/a/b/a", KEY_END),
    2172             :                       keyNew ("user:/a/b/b", KEY_END), keyNew ("user:/a/c", KEY_END), keyNew ("user:/a/d", KEY_END),
    2173             :                       keyNew ("user:/a/x/a", KEY_END), keyNew ("user:/a/x/b", KEY_END), keyNew ("user:/a/x/c", KEY_END),
    2174             :                       keyNew ("user:/a/x/c/a", KEY_END), keyNew ("user:/a/x/c/b", KEY_END), KS_END);
    2175             : }
    2176             : 
    2177             : 
    2178           3 : static void test_cut (void)
    2179             : {
    2180           3 :         printf ("Testing operation cut\n");
    2181             : 
    2182           3 :         KeySet * orig;
    2183           3 :         Key * cutpoint;
    2184           3 :         KeySet * result;
    2185           3 :         KeySet * real_orig;
    2186             : 
    2187           3 :         orig = ksNew (0, KS_END);
    2188           3 :         cutpoint = keyNew ("user:/b", KEY_END);
    2189             : 
    2190           3 :         succeed_if (ksCut (0, cutpoint) == 0, "No Error on NULL pointer");
    2191           3 :         succeed_if (ksCut (orig, 0) == 0, "No Error on NULL pointer");
    2192             : 
    2193           3 :         result = ksCut (orig, cutpoint);
    2194           3 :         succeed_if (result, "result is null");
    2195           3 :         succeed_if (ksGetSize (result) == 0, "result not empty");
    2196           3 :         ksDel (orig);
    2197           3 :         ksDel (result);
    2198           3 :         keyDel (cutpoint);
    2199             : 
    2200           3 :         orig = set_oa ();
    2201           3 :         cutpoint = keyNew ("user:/a", KEY_END);
    2202           3 :         result = ksCut (orig, cutpoint);
    2203           3 :         succeed_if (ksGetSize (orig) == 0, "orig not empty");
    2204           3 :         real_orig = set_oa ();
    2205          48 :         compare_keyset (result, real_orig);
    2206           3 :         ksDel (orig);
    2207           3 :         ksDel (result);
    2208           3 :         ksDel (real_orig);
    2209           3 :         keyDel (cutpoint);
    2210             : 
    2211             : 
    2212           3 :         KeySet * cmp_orig[16];
    2213           3 :         KeySet * cmp_result[16];
    2214             : #include "data_cut.c"
    2215             : 
    2216          51 :         for (int i = 0; i < 16; ++i)
    2217             :         {
    2218          48 :                 orig = set_a ();
    2219          48 :                 cutpoint = keyDup (ksAtCursor (orig, i), KEY_CP_ALL);
    2220          48 :                 result = ksCut (orig, cutpoint);
    2221             : 
    2222         201 :                 compare_keyset (result, cmp_result[i]);
    2223         759 :                 compare_keyset (orig, cmp_orig[i]);
    2224             : 
    2225             :                 /*
    2226             :                 Key *key;
    2227             :                 printf ("orig[%d] = ksNew (%zd, ", i, ksGetSize(orig));
    2228             :                 ksRewind(orig); while ((key=ksNext(orig))!= 0) printf ("keyNew (\"%s\", KEY_END), ", keyName(key));
    2229             :                 printf ("KS_END);\n");
    2230             : 
    2231             :                 printf ("result[%d] = ksNew (%zd, ", i, ksGetSize(result));
    2232             :                 ksRewind(result); while ((key=ksNext(result))!= 0) printf ("keyNew (\"%s\", KEY_END), ", keyName(key));
    2233             :                 printf ("KS_END);\n");
    2234             :                 */
    2235             : 
    2236          48 :                 keyDel (cutpoint);
    2237          48 :                 ksDel (result);
    2238          48 :                 ksDel (orig);
    2239          48 :                 ksDel (cmp_orig[i]);
    2240          48 :                 ksDel (cmp_result[i]);
    2241             :         }
    2242           3 : }
    2243             : 
    2244           3 : static void test_cutpoint (void)
    2245             : {
    2246           3 :         printf ("Testing operation cut point\n");
    2247             : 
    2248           3 :         Key * cutpoint = keyNew ("user:/a/b/c", KEY_END);
    2249           3 :         KeySet * orig =
    2250           3 :                 ksNew (30, keyNew ("user:/a", KEY_END), keyNew ("user:/a/b", KEY_END), cutpoint, keyNew ("user:/a/b/c/d", KEY_END),
    2251             :                        keyNew ("user:/a/b/c/d/e", KEY_END), keyNew ("user:/a/b/c/e", KEY_END), keyNew ("user:/a/b/c/e/d", KEY_END), KS_END);
    2252           3 :         ksRewind (orig);
    2253           3 :         ksNext (orig);
    2254           3 :         succeed_if_same_string (keyName (ksCurrent (orig)), "user:/a");
    2255           3 :         ksNext (orig);
    2256           3 :         succeed_if_same_string (keyName (ksCurrent (orig)), "user:/a/b");
    2257             : 
    2258           3 :         KeySet * part = ksCut (orig, cutpoint);
    2259             : 
    2260           3 :         succeed_if_same_string (keyName (ksCurrent (orig)), "user:/a/b");
    2261             : 
    2262           3 :         KeySet * cmp_orig = ksNew (15, keyNew ("user:/a", KEY_END), keyNew ("user:/a/b", KEY_END), KS_END);
    2263          12 :         compare_keyset (orig, cmp_orig);
    2264           3 :         ksDel (orig);
    2265           3 :         ksDel (cmp_orig);
    2266             : 
    2267           3 :         KeySet * cmp_part = ksNew (15, cutpoint, keyNew ("user:/a/b/c/d", KEY_END), keyNew ("user:/a/b/c/d/e", KEY_END),
    2268             :                                    keyNew ("user:/a/b/c/e", KEY_END), keyNew ("user:/a/b/c/e/d", KEY_END), KS_END);
    2269          21 :         compare_keyset (part, cmp_part);
    2270           3 :         ksDel (part);
    2271           3 :         ksDel (cmp_part);
    2272           3 : }
    2273             : 
    2274           3 : static void test_cascadingCutpoint (void)
    2275             : {
    2276           3 :         printf ("Testing operation cascading cut point\n");
    2277             : 
    2278           3 :         Key * cutpoint = keyNew ("/a/b/c", KEY_END);
    2279           3 :         KeySet * orig =
    2280             : #include <data_nscut.c>
    2281           3 :                 ksRewind (orig);
    2282           3 :         ksNext (orig);
    2283           3 :         succeed_if_same_string (keyName (ksCurrent (orig)), "spec:/a");
    2284           3 :         ksNext (orig);
    2285           3 :         succeed_if_same_string (keyName (ksCurrent (orig)), "spec:/a/b");
    2286             : 
    2287           3 :         KeySet * part = ksCut (orig, cutpoint);
    2288             : 
    2289           3 :         succeed_if_same_string (keyName (ksCurrent (orig)), "spec:/a/b");
    2290             : 
    2291           3 :         KeySet * cmp_orig = ksNew (15, keyNew ("spec:/a", KEY_END), keyNew ("spec:/a/b", KEY_END),
    2292             : 
    2293             :                                    keyNew ("proc:/a", KEY_END), keyNew ("proc:/a/b", KEY_END),
    2294             : 
    2295             :                                    keyNew ("dir:/a", KEY_END), keyNew ("dir:/a/b", KEY_END),
    2296             : 
    2297             :                                    keyNew ("user:/a", KEY_END), keyNew ("user:/a/b", KEY_END),
    2298             : 
    2299             :                                    keyNew ("system:/a", KEY_END), keyNew ("system:/a/b", KEY_END), KS_END);
    2300          36 :         compare_keyset (orig, cmp_orig);
    2301             :         // output_keyset(orig);
    2302           3 :         ksDel (orig);
    2303           3 :         ksDel (cmp_orig);
    2304             : 
    2305           3 :         KeySet * cmp_part =
    2306           3 :                 ksNew (25, keyNew ("spec:/a/b/c", KEY_END), keyNew ("spec:/a/b/c/d", KEY_END), keyNew ("spec:/a/b/c/d/e", KEY_END),
    2307             :                        keyNew ("spec:/a/b/c/e", KEY_END), keyNew ("spec:/a/b/c/e/d", KEY_END),
    2308             : 
    2309             :                        keyNew ("proc:/a/b/c", KEY_END), keyNew ("proc:/a/b/c/d", KEY_END), keyNew ("proc:/a/b/c/d/e", KEY_END),
    2310             :                        keyNew ("proc:/a/b/c/e", KEY_END), keyNew ("proc:/a/b/c/e/d", KEY_END),
    2311             : 
    2312             :                        keyNew ("dir:/a/b/c", KEY_END), keyNew ("dir:/a/b/c/d", KEY_END), keyNew ("dir:/a/b/c/d/e", KEY_END),
    2313             :                        keyNew ("dir:/a/b/c/e", KEY_END), keyNew ("dir:/a/b/c/e/d", KEY_END),
    2314             : 
    2315             :                        keyNew ("user:/a/b/c", KEY_END), keyNew ("user:/a/b/c/d", KEY_END), keyNew ("user:/a/b/c/d/e", KEY_END),
    2316             :                        keyNew ("user:/a/b/c/e", KEY_END), keyNew ("user:/a/b/c/e/d", KEY_END),
    2317             : 
    2318             :                        keyNew ("system:/a/b/c", KEY_END), keyNew ("system:/a/b/c/d", KEY_END), keyNew ("system:/a/b/c/d/e", KEY_END),
    2319             :                        keyNew ("system:/a/b/c/e", KEY_END), keyNew ("system:/a/b/c/e/d", KEY_END), KS_END);
    2320          81 :         compare_keyset (part, cmp_part);
    2321             :         // output_keyset(part);
    2322           3 :         ksDel (part);
    2323           3 :         ksDel (cmp_part);
    2324           3 :         keyDel (cutpoint);
    2325           3 : }
    2326             : 
    2327           3 : static void test_cascadingRootCutpoint (void)
    2328             : {
    2329           3 :         printf ("Testing operation cascading root cut point\n");
    2330             : 
    2331           3 :         Key * cutpoint = keyNew ("/", KEY_END);
    2332           3 :         KeySet * orig =
    2333             : #include <data_nscut.c>
    2334           3 :                 ksRewind (orig);
    2335           3 :         ksNext (orig);
    2336           3 :         succeed_if_same_string (keyName (ksCurrent (orig)), "spec:/a");
    2337           3 :         ksNext (orig);
    2338           3 :         succeed_if_same_string (keyName (ksCurrent (orig)), "spec:/a/b");
    2339             : 
    2340           3 :         KeySet * part = ksCut (orig, cutpoint);
    2341             : 
    2342           3 :         succeed_if (ksGetSize (orig) == 0, "keyset not empty");
    2343           3 :         succeed_if (ksCurrent (orig) == 0, "empty keyset not rewinded");
    2344           3 :         ksDel (orig);
    2345             : 
    2346           3 :         KeySet * cmp_part =
    2347             : #include <data_nscut.c>
    2348         111 :                 compare_keyset (part, cmp_part);
    2349             :         // output_keyset(part);
    2350           3 :         ksDel (part);
    2351           3 :         ksDel (cmp_part);
    2352           3 :         keyDel (cutpoint);
    2353           3 : }
    2354             : 
    2355           3 : static void test_cutpointRoot (void)
    2356             : {
    2357           3 :         printf ("Testing operation cut root point\n");
    2358             : 
    2359           3 :         Key * cutpoint = keyNew ("user:/", KEY_END);
    2360           3 :         KeySet * orig = ksNew (30, keyNew ("dir:/a", KEY_END), keyNew ("user:/a", KEY_END), keyNew ("user:/a/b", KEY_END),
    2361             :                                keyNew ("user:/a/b/c", KEY_END), keyNew ("user:/a/b/c/d", KEY_END), keyNew ("user:/a/b/c/d/e", KEY_END),
    2362             :                                keyNew ("user:/a/b/c/e", KEY_END), keyNew ("user:/a/b/c/e/d", KEY_END), KS_END);
    2363           3 :         ksRewind (orig);
    2364           3 :         ksNext (orig);
    2365           3 :         ksNext (orig);
    2366           3 :         succeed_if_same_string (keyName (ksCurrent (orig)), "user:/a");
    2367             : 
    2368           3 :         KeySet * part = ksCut (orig, cutpoint);
    2369             : 
    2370           3 :         succeed_if_same_string (keyName (ksCurrent (orig)), "dir:/a");
    2371             : 
    2372           3 :         KeySet * cmp_orig = ksNew (15, keyNew ("dir:/a", KEY_END), KS_END);
    2373           9 :         compare_keyset (orig, cmp_orig);
    2374           3 :         ksDel (orig);
    2375           3 :         ksDel (cmp_orig);
    2376             : 
    2377           3 :         KeySet * cmp_part = ksNew (15, keyNew ("user:/a", KEY_END), keyNew ("user:/a/b", KEY_END), keyNew ("user:/a/b/c", KEY_END),
    2378             :                                    keyNew ("user:/a/b/c/d", KEY_END), keyNew ("user:/a/b/c/d/e", KEY_END),
    2379             :                                    keyNew ("user:/a/b/c/e", KEY_END), keyNew ("user:/a/b/c/e/d", KEY_END), KS_END);
    2380          27 :         compare_keyset (part, cmp_part);
    2381           3 :         ksDel (part);
    2382           3 :         ksDel (cmp_part);
    2383           3 :         keyDel (cutpoint);
    2384           3 : }
    2385             : 
    2386             : 
    2387           3 : static void test_cutpoint_1 (void)
    2388             : {
    2389           3 :         printf ("Testing operation cut point 1\n");
    2390             : 
    2391           3 :         Key * cutpoint = keyNew ("user:/a/b/c", KEY_END);
    2392           3 :         KeySet * orig =
    2393           3 :                 ksNew (30, keyNew ("user:/a", KEY_END), keyNew ("user:/a/b", KEY_END), cutpoint, keyNew ("user:/a/b/c/d", KEY_END),
    2394             :                        keyNew ("user:/a/b/c/d/e", KEY_END), keyNew ("user:/a/b/c/e", KEY_END), keyNew ("user:/a/b/c/e/d", KEY_END), KS_END);
    2395           3 :         ksRewind (orig);
    2396           3 :         ksNext (orig);
    2397           3 :         succeed_if_same_string (keyName (ksCurrent (orig)), "user:/a");
    2398           3 :         ksNext (orig);
    2399           3 :         succeed_if_same_string (keyName (ksCurrent (orig)), "user:/a/b");
    2400           3 :         ksNext (orig);
    2401           3 :         succeed_if_same_string (keyName (ksCurrent (orig)), "user:/a/b/c");
    2402             : 
    2403           3 :         KeySet * part = ksCut (orig, cutpoint);
    2404             : 
    2405           3 :         succeed_if_same_string (keyName (ksCurrent (orig)), "user:/a/b");
    2406             : 
    2407           3 :         KeySet * cmp_orig = ksNew (15, keyNew ("user:/a", KEY_END), keyNew ("user:/a/b", KEY_END), KS_END);
    2408          12 :         compare_keyset (orig, cmp_orig);
    2409           3 :         ksDel (orig);
    2410           3 :         ksDel (cmp_orig);
    2411             : 
    2412           3 :         KeySet * cmp_part = ksNew (15, cutpoint, keyNew ("user:/a/b/c/d", KEY_END), keyNew ("user:/a/b/c/d/e", KEY_END),
    2413             :                                    keyNew ("user:/a/b/c/e", KEY_END), keyNew ("user:/a/b/c/e/d", KEY_END), KS_END);
    2414          21 :         compare_keyset (part, cmp_part);
    2415           3 :         ksDel (part);
    2416           3 :         ksDel (cmp_part);
    2417           3 : }
    2418             : 
    2419           3 : static void test_unique_cutpoint (void)
    2420             : {
    2421           3 :         printf ("Testing operation cut with unique cutpoint\n");
    2422             : 
    2423           3 :         Key * cutpoint = keyNew ("user:/a/b/c", KEY_END);
    2424           3 :         KeySet * orig = ksNew (30, keyNew ("user:/a", KEY_END), keyNew ("user:/a/b", KEY_END), keyNew ("user:/a/b/c", KEY_END),
    2425             :                                keyNew ("user:/a/b/c/d", KEY_END), keyNew ("user:/a/b/c/d/e", KEY_END), keyNew ("user:/a/b/c/e", KEY_END),
    2426             :                                keyNew ("user:/a/b/c/e/d", KEY_END), KS_END);
    2427             : 
    2428           3 :         KeySet * part = ksCut (orig, cutpoint);
    2429             : 
    2430           3 :         KeySet * cmp_orig = ksNew (15, keyNew ("user:/a", KEY_END), keyNew ("user:/a/b", KEY_END), KS_END);
    2431          12 :         compare_keyset (orig, cmp_orig);
    2432           3 :         ksDel (orig);
    2433           3 :         ksDel (cmp_orig);
    2434             : 
    2435           3 :         KeySet * cmp_part =
    2436           3 :                 ksNew (15, keyNew ("user:/a/b/c", KEY_END), keyNew ("user:/a/b/c/d", KEY_END), keyNew ("user:/a/b/c/d/e", KEY_END),
    2437             :                        keyNew ("user:/a/b/c/e", KEY_END), keyNew ("user:/a/b/c/e/d", KEY_END), KS_END);
    2438          21 :         compare_keyset (part, cmp_part);
    2439           3 :         ksDel (part);
    2440           3 :         ksDel (cmp_part);
    2441           3 :         keyDel (cutpoint);
    2442           3 : }
    2443             : 
    2444           3 : static void test_cutbelow (void)
    2445             : {
    2446           3 :         printf ("Testing cutting below some keys\n");
    2447             : 
    2448           3 :         Key * cutpoint = keyNew ("user:/export", KEY_END);
    2449           3 :         KeySet * orig =
    2450           3 :                 ksNew (30, keyNew ("user:/export/a", KEY_END), keyNew ("user:/export/c", KEY_END), keyNew ("user:/export/c/x", KEY_END),
    2451             :                        keyNew ("user:/export/c/x/b/blah", KEY_END), keyNew ("user:/export/xyz", KEY_END),
    2452             :                        keyNew ("user:/export-backup/b", KEY_END), keyNew ("user:/export-backup-2/x", KEY_END), KS_END);
    2453           3 :         ksRewind (orig);
    2454           3 :         ksNext (orig);
    2455           3 :         succeed_if_same_string (keyName (ksCurrent (orig)), "user:/export/a");
    2456           3 :         ksLookupByName (orig, "user:/export-backup/b", 0);
    2457           3 :         succeed_if_same_string (keyName (ksCurrent (orig)), "user:/export-backup/b");
    2458             : 
    2459           3 :         KeySet * part = ksCut (orig, cutpoint);
    2460             : 
    2461           3 :         succeed_if_same_string (keyName (ksCurrent (orig)), "user:/export-backup/b");
    2462             : 
    2463           3 :         KeySet * cmp_orig = ksNew (15, keyNew ("user:/export-backup-2/x", KEY_END), keyNew ("user:/export-backup/b", KEY_END), KS_END);
    2464          12 :         compare_keyset (orig, cmp_orig);
    2465           3 :         ksDel (orig);
    2466           3 :         ksDel (cmp_orig);
    2467             : 
    2468           3 :         KeySet * cmp_part =
    2469           3 :                 ksNew (15, keyNew ("user:/export/a", KEY_END), keyNew ("user:/export/c", KEY_END), keyNew ("user:/export/c/x", KEY_END),
    2470             :                        keyNew ("user:/export/c/x/b/blah", KEY_END), keyNew ("user:/export/xyz", KEY_END), KS_END);
    2471          21 :         compare_keyset (part, cmp_part);
    2472           3 :         ksDel (part);
    2473           3 :         ksDel (cmp_part);
    2474           3 :         keyDel (cutpoint);
    2475           3 : }
    2476             : 
    2477           3 : static void test_cascading_cutbelow (void)
    2478             : {
    2479           3 :         printf ("Testing cutting below some keys (cascading)\n");
    2480             : 
    2481           3 :         Key * cutpoint = keyNew ("/export", KEY_END);
    2482           3 :         KeySet * orig = ksNew (30, keyNew ("/export/a", KEY_END), keyNew ("/export/c", KEY_END), keyNew ("/export/c/x", KEY_END),
    2483             :                                keyNew ("/export/c/x/b/blah", KEY_END), keyNew ("/export/xyz", KEY_END),
    2484             :                                keyNew ("/export-backup/b", KEY_END), keyNew ("/export-backup-2/x", KEY_END), KS_END);
    2485           3 :         ksRewind (orig);
    2486           3 :         ksNext (orig);
    2487           3 :         succeed_if_same_string (keyName (ksCurrent (orig)), "/export/a");
    2488           3 :         ksLookupByName (orig, "/export-backup/b", 0);
    2489           3 :         succeed_if_same_string (keyName (ksCurrent (orig)), "/export-backup/b");
    2490             : 
    2491           3 :         KeySet * part = ksCut (orig, cutpoint);
    2492             : 
    2493           3 :         succeed_if_same_string (keyName (ksCurrent (orig)), "/export-backup/b");
    2494             : 
    2495           3 :         KeySet * cmp_orig = ksNew (15, keyNew ("/export-backup-2/x", KEY_END), keyNew ("/export-backup/b", KEY_END), KS_END);
    2496          12 :         compare_keyset (orig, cmp_orig);
    2497           3 :         ksDel (orig);
    2498           3 :         ksDel (cmp_orig);
    2499             : 
    2500           3 :         KeySet * cmp_part = ksNew (15, keyNew ("/export/a", KEY_END), keyNew ("/export/c", KEY_END), keyNew ("/export/c/x", KEY_END),
    2501             :                                    keyNew ("/export/c/x/b/blah", KEY_END), keyNew ("/export/xyz", KEY_END), KS_END);
    2502          21 :         compare_keyset (part, cmp_part);
    2503           3 :         ksDel (part);
    2504           3 :         ksDel (cmp_part);
    2505           3 :         keyDel (cutpoint);
    2506           3 : }
    2507             : 
    2508           6 : KeySet * set_simple (void)
    2509             : {
    2510           6 :         return ksNew (50, keyNew ("system:/elektra/mountpoints/simple", KEY_END),
    2511             : 
    2512             :                       keyNew ("system:/elektra/mountpoints/simple/config", KEY_END),
    2513             :                       keyNew ("system:/elektra/mountpoints/simple/config/anything", KEY_VALUE, "backend", KEY_END),
    2514             :                       keyNew ("system:/elektra/mountpoints/simple/config/more", KEY_END),
    2515             :                       keyNew ("system:/elektra/mountpoints/simple/config/more/config", KEY_END),
    2516             :                       keyNew ("system:/elektra/mountpoints/simple/config/more/config/below", KEY_END),
    2517             :                       keyNew ("system:/elektra/mountpoints/simple/config/path", KEY_END),
    2518             : 
    2519             :                       keyNew ("system:/elektra/mountpoints/simple/getplugins", KEY_END),
    2520             :                       keyNew ("system:/elektra/mountpoints/simple/getplugins/#1tracer", KEY_VALUE, "tracer", KEY_END),
    2521             :                       keyNew ("system:/elektra/mountpoints/simple/getplugins/#1tracer/config", KEY_END),
    2522             :                       keyNew ("system:/elektra/mountpoints/simple/getplugins/#1tracer/config/anything", KEY_VALUE, "plugin", KEY_END),
    2523             :                       keyNew ("system:/elektra/mountpoints/simple/getplugins/#1tracer/config/more", KEY_END),
    2524             :                       keyNew ("system:/elektra/mountpoints/simple/getplugins/#1tracer/config/more/config", KEY_END),
    2525             :                       keyNew ("system:/elektra/mountpoints/simple/getplugins/#1tracer/config/more/config/below", KEY_END),
    2526             :                       keyNew ("system:/elektra/mountpoints/simple/getplugins/#1tracer/config/path", KEY_END),
    2527             : 
    2528             :                       keyNew ("system:/elektra/mountpoints/simple/mountpoint", KEY_VALUE, "user:/tests/backend/simple", KEY_END),
    2529             : 
    2530             :                       keyNew ("system:/elektra/mountpoints/simple/setplugins", KEY_END),
    2531             :                       keyNew ("system:/elektra/mountpoints/simple/setplugins/#1tracer", KEY_VALUE, "tracer", KEY_END), KS_END);
    2532             : }
    2533             : 
    2534           3 : static void test_simple (void)
    2535             : {
    2536           3 :         KeySet * config = set_simple ();
    2537           3 :         KeySet * result_res = ksNew (16, keyNew ("system:/elektra/mountpoints/simple/config", KEY_END),
    2538             :                                      keyNew ("system:/elektra/mountpoints/simple/config/anything", KEY_VALUE, "backend", KEY_END),
    2539             :                                      keyNew ("system:/elektra/mountpoints/simple/config/more", KEY_END),
    2540             :                                      keyNew ("system:/elektra/mountpoints/simple/config/more/config", KEY_END),
    2541             :                                      keyNew ("system:/elektra/mountpoints/simple/config/more/config/below", KEY_END),
    2542             :                                      keyNew ("system:/elektra/mountpoints/simple/config/path", KEY_END), KS_END);
    2543           3 :         KeySet * result_config =
    2544           3 :                 ksNew (22, keyNew ("system:/elektra/mountpoints/simple", KEY_END),
    2545             :                        keyNew ("system:/elektra/mountpoints/simple/getplugins", KEY_END),
    2546             :                        keyNew ("system:/elektra/mountpoints/simple/getplugins/#1tracer", KEY_VALUE, "tracer", KEY_END),
    2547             :                        keyNew ("system:/elektra/mountpoints/simple/getplugins/#1tracer/config", KEY_END),
    2548             :                        keyNew ("system:/elektra/mountpoints/simple/getplugins/#1tracer/config/anything", KEY_VALUE, "plugin", KEY_END),
    2549             :                        keyNew ("system:/elektra/mountpoints/simple/getplugins/#1tracer/config/more", KEY_END),
    2550             :                        keyNew ("system:/elektra/mountpoints/simple/getplugins/#1tracer/config/more/config", KEY_END),
    2551             :                        keyNew ("system:/elektra/mountpoints/simple/getplugins/#1tracer/config/more/config/below", KEY_END),
    2552             :                        keyNew ("system:/elektra/mountpoints/simple/getplugins/#1tracer/config/path", KEY_END),
    2553             :                        keyNew ("system:/elektra/mountpoints/simple/mountpoint", KEY_VALUE, "user:/tests/backend/simple", KEY_END),
    2554             :                        keyNew ("system:/elektra/mountpoints/simple/setplugins", KEY_END),
    2555             :                        keyNew ("system:/elektra/mountpoints/simple/setplugins/#1tracer", KEY_VALUE, "tracer", KEY_END), KS_END);
    2556           3 :         Key * key = ksLookup (config, keyNew ("system:/elektra/mountpoints/simple/config", KEY_END), KDB_O_DEL);
    2557           3 :         succeed_if (ksGetCursor (config) == 1, "cursor not set correctly");
    2558           3 :         KeySet * res = ksCut (config, key);
    2559           3 :         succeed_if (ksGetCursor (config) == 0, "cursor should stay as is");
    2560          42 :         compare_keyset (config, result_config);
    2561          24 :         compare_keyset (res, result_res);
    2562             : 
    2563           3 :         ksDel (result_config);
    2564           3 :         ksDel (result_res);
    2565           3 :         ksDel (res);
    2566           3 :         ksDel (config);
    2567           3 : }
    2568             : 
    2569           3 : static void test_cursor (void)
    2570             : {
    2571           3 :         printf ("test cut cursor\n");
    2572             : 
    2573           3 :         KeySet * config = set_simple ();
    2574             : 
    2575           3 :         succeed_if (ksGetCursor (0) == -1, "No error on NULL pointer");
    2576             : 
    2577           3 :         ksRewind (config);
    2578           3 :         succeed_if (ksGetCursor (config) == -1, "should be invalid cursor");
    2579           3 :         succeed_if (ksNext (config) != 0, "should be root key");
    2580           3 :         succeed_if (ksGetCursor (config) == 0, "cursor on first position");
    2581           3 :         succeed_if_same_string (keyName (ksCurrent (config)), "system:/elektra/mountpoints/simple");
    2582           3 :         succeed_if (ksNext (config) != 0, "should be on config");
    2583           3 :         succeed_if (ksGetCursor (config) == 1, "cursor on config");
    2584           3 :         succeed_if_same_string (keyName (ksCurrent (config)), "system:/elektra/mountpoints/simple/config");
    2585             : 
    2586           3 :         KeySet * res = ksCut (config, ksCurrent (config));
    2587           3 :         succeed_if (ksGetCursor (config) == 0, "cursor on first position");
    2588           3 :         succeed_if_same_string (keyName (ksCurrent (config)), "system:/elektra/mountpoints/simple");
    2589             : 
    2590           3 :         succeed_if (ksNext (config) != 0, "should be on config");
    2591           3 :         succeed_if (ksGetCursor (config) == 1, "cursor on getplugins");
    2592           3 :         succeed_if_same_string (keyName (ksCurrent (config)), "system:/elektra/mountpoints/simple/getplugins");
    2593             : 
    2594           3 :         KeySet * getplugins = ksCut (config, ksCurrent (config));
    2595           3 :         succeed_if (ksGetCursor (getplugins) == -1, "should be invalid cursor");
    2596           3 :         succeed_if (ksNext (getplugins) != 0, "should be root key");
    2597           3 :         succeed_if (ksGetCursor (getplugins) == 0, "cursor on first position");
    2598             : 
    2599           3 :         succeed_if (ksNext (getplugins) != 0, "should be tracer");
    2600           3 :         succeed_if (ksGetCursor (getplugins) == 1, "cursor not correct");
    2601             : 
    2602           3 :         KeySet * gettracer = ksCut (getplugins, ksCurrent (getplugins));
    2603           3 :         succeed_if (ksNext (getplugins) == 0, "should be no more getplugins");
    2604             : 
    2605           3 :         succeed_if (ksNext (config) != 0, "next did not work");
    2606           3 :         succeed_if (ksGetCursor (config) == 1, "cursor not correct");
    2607           3 :         succeed_if_same_string (keyName (ksCurrent (config)), "system:/elektra/mountpoints/simple/mountpoint");
    2608             : 
    2609           3 :         succeed_if (ksNext (config) != 0, "next did not work");
    2610           3 :         succeed_if (ksGetCursor (config) == 2, "cursor not correct");
    2611           3 :         succeed_if_same_string (keyName (ksCurrent (config)), "system:/elektra/mountpoints/simple/setplugins");
    2612             : 
    2613           3 :         KeySet * setplugins = ksCut (config, ksCurrent (config));
    2614           3 :         succeed_if (ksNext (config) == 0, "should be no more config");
    2615           3 :         succeed_if (ksNext (setplugins) != 0, "ksnext did not work");
    2616           3 :         succeed_if_same_string (keyName (ksCurrent (setplugins)), "system:/elektra/mountpoints/simple/setplugins");
    2617           3 :         succeed_if (ksNext (setplugins) != 0, "ksnext did not work");
    2618             : 
    2619           3 :         KeySet * settracer = ksCut (setplugins, ksCurrent (setplugins));
    2620           3 :         succeed_if (ksNext (setplugins) == 0, "should be no more setplugins");
    2621           3 :         succeed_if (ksGetSize (settracer) == 1, "should be only one key");
    2622             : 
    2623           3 :         succeed_if (ksGetSize (config) == 2, "should be only three keys remaining: root, mountpoint");
    2624             : 
    2625           3 :         succeed_if (ksSetCursor (0, 1) == -1, "No error on NULL keyset");
    2626           3 :         succeed_if (ksSetCursor (config, -1) == 0, "No error on invalid position");
    2627           3 :         succeed_if (ksSetCursor (config, 2) == 1, "Can not set cursor to KeySet");
    2628             : 
    2629           3 :         ksDel (setplugins);
    2630           3 :         ksDel (getplugins);
    2631           3 :         ksDel (settracer);
    2632           3 :         ksDel (gettracer);
    2633           3 :         ksDel (config);
    2634           3 :         ksDel (res);
    2635           3 : }
    2636             : 
    2637           3 : static void test_morecut (void)
    2638             : {
    2639           3 :         printf ("More cut test cases\n");
    2640             : 
    2641           3 :         KeySet * ks = ksNew (5, keyNew ("user:/valid/key1", KEY_END), keyNew ("user:/valid/key2", KEY_END),
    2642             :                              keyNew ("system:/valid/key1", KEY_END), keyNew ("system:/valid/key2", KEY_END), KS_END);
    2643           3 :         succeed_if (ksCurrent (ks) == 0, "should be rewinded");
    2644           3 :         ksNext (ks);
    2645           3 :         succeed_if_same_string (keyName (ksCurrent (ks)), "user:/valid/key1");
    2646           3 :         ksNext (ks);
    2647           3 :         succeed_if_same_string (keyName (ksCurrent (ks)), "user:/valid/key2");
    2648           3 :         ksNext (ks);
    2649           3 :         succeed_if_same_string (keyName (ksCurrent (ks)), "system:/valid/key1");
    2650           3 :         ksNext (ks);
    2651           3 :         succeed_if_same_string (keyName (ksCurrent (ks)), "system:/valid/key2");
    2652             : 
    2653           3 :         KeySet * split1 = ksNew (3, keyNew ("user:/valid/key1", KEY_END), keyNew ("user:/valid/key2", KEY_END), KS_END);
    2654           3 :         KeySet * split2 = ksNew (3, keyNew ("system:/valid/key1", KEY_END), keyNew ("system:/valid/key2", KEY_END), KS_END);
    2655             : 
    2656           3 :         Key * userKey = keyNew ("user:/", KEY_END);
    2657             : 
    2658           3 :         KeySet * cut = ksCut (ks, userKey);
    2659             : 
    2660          12 :         compare_keyset (cut, split1);
    2661          12 :         compare_keyset (ks, split2);
    2662           3 :         ksDel (cut);
    2663             : 
    2664           3 :         keyDel (userKey);
    2665             : 
    2666           3 :         ksDel (ks);
    2667           3 :         ksDel (split1);
    2668           3 :         ksDel (split2);
    2669           3 : }
    2670             : 
    2671           3 : static void test_cutafter (void)
    2672             : {
    2673           3 :         printf ("More cut after\n");
    2674             : 
    2675           3 :         KeySet * ks = ksNew (5, keyNew ("user:/a/valid/key", KEY_END), keyNew ("user:/a/x/valid/key", KEY_END),
    2676             :                              keyNew ("user:/b/valid/key", KEY_END), keyNew ("user:/b/x/valid/key", KEY_END),
    2677             :                              keyNew ("user:/c/valid/key", KEY_END), keyNew ("user:/c/x/valid/key", KEY_END), KS_END);
    2678           3 :         ksRewind (ks);
    2679           3 :         ksNext (ks);
    2680           3 :         succeed_if_same_string (keyName (ksCurrent (ks)), "user:/a/valid/key");
    2681           3 :         ksNext (ks);
    2682           3 :         succeed_if_same_string (keyName (ksCurrent (ks)), "user:/a/x/valid/key");
    2683           3 :         ksNext (ks);
    2684           3 :         succeed_if_same_string (keyName (ksCurrent (ks)), "user:/b/valid/key");
    2685           3 :         ksNext (ks);
    2686           3 :         succeed_if_same_string (keyName (ksCurrent (ks)), "user:/b/x/valid/key");
    2687           3 :         ksNext (ks);
    2688           3 :         succeed_if_same_string (keyName (ksCurrent (ks)), "user:/c/valid/key");
    2689             :         // printf ("%s\n", keyName(ksCurrent(ks)));
    2690             : 
    2691           3 :         KeySet * split1 = ksNew (8, keyNew ("user:/b/valid/key", KEY_END), keyNew ("user:/b/x/valid/key", KEY_END), KS_END);
    2692           3 :         KeySet * split2 = ksNew (8, keyNew ("user:/a/valid/key", KEY_END), keyNew ("user:/a/x/valid/key", KEY_END),
    2693             :                                  keyNew ("user:/c/valid/key", KEY_END), keyNew ("user:/c/x/valid/key", KEY_END), KS_END);
    2694             : 
    2695           3 :         Key * userKey = keyNew ("user:/b", KEY_END);
    2696             : 
    2697           3 :         KeySet * cut = ksCut (ks, userKey);
    2698             :         // printf ("%s\n", keyName(ksCurrent(ks)));
    2699           3 :         succeed_if_same_string (keyName (ksCurrent (ks)), "user:/c/valid/key");
    2700             : 
    2701          12 :         compare_keyset (cut, split1);
    2702          18 :         compare_keyset (ks, split2);
    2703           3 :         ksDel (cut);
    2704             : 
    2705           3 :         keyDel (userKey);
    2706             : 
    2707           3 :         ksDel (ks);
    2708           3 :         ksDel (split1);
    2709           3 :         ksDel (split2);
    2710           3 : }
    2711             : 
    2712           3 : static void test_simpleLookup (void)
    2713             : {
    2714           3 :         printf ("Test simple lookup\n");
    2715             : 
    2716           3 :         KeySet * ks = ksNew (10, KS_END);
    2717             : 
    2718           3 :         Key * searchKey = keyNew ("user:/something", KEY_VALUE, "a value", KEY_END);
    2719           3 :         Key * k0 = ksLookup (ks, searchKey, 0);
    2720           3 :         succeed_if (!k0, "we have a problem: found not inserted key");
    2721             : 
    2722           3 :         Key * dup = keyDup (searchKey, KEY_CP_ALL);
    2723           3 :         succeed_if_same_string (keyName (dup), "user:/something");
    2724           3 :         succeed_if_same_string (keyString (dup), "a value");
    2725           3 :         ksAppendKey (ks, dup);
    2726             :         // output_keyset(ks);
    2727             : 
    2728           3 :         Key * k1 = ksLookup (ks, searchKey, 0);
    2729           3 :         succeed_if (k1, "we have a problem: did not find key");
    2730           3 :         succeed_if (k1 != searchKey, "same key, even though dup was used");
    2731           3 :         succeed_if_same_string (keyName (k1), "user:/something");
    2732           3 :         succeed_if_same_string (keyString (k1), "a value");
    2733             : 
    2734           3 :         Key * returnedKey;
    2735           3 :         returnedKey = ksLookup (ks, searchKey, KDB_O_DEL);
    2736           3 :         succeed_if_same_string (keyName (returnedKey), keyName (dup));
    2737           3 :         succeed_if_same_string (keyString (returnedKey), keyString (dup));
    2738           3 :         succeed_if (ksGetSize (ks) == 1, "key deleted from keyset");
    2739             : 
    2740           3 :         ksDel (ks);
    2741           3 : }
    2742             : 
    2743           3 : static void test_nsLookup (void)
    2744             : {
    2745           3 :         printf ("Test lookup in all namespaces\n");
    2746             : 
    2747           3 :         KeySet * ks =
    2748             : #include <data_ns.c>
    2749             : 
    2750          18 :                 for (int i = 0; i < NUMBER_OF_NAMESPACES; ++i)
    2751             :         {
    2752          15 :                 Key * searchKey = keyNew (namespaces[i], KEY_VALUE, "value1", KEY_META, "comment/#0", "comment1", KEY_END);
    2753          15 :                 keyAddName (searchKey, "test/keyset/dir7/key1");
    2754             : 
    2755          15 :                 Key * lookupKey = keyNew (namespaces[i], KEY_END);
    2756          15 :                 keyAddName (lookupKey, "something/not/found");
    2757          15 :                 Key * k0 = ksLookup (ks, lookupKey, 0);
    2758          15 :                 succeed_if (!k0, "we have a problem: found not inserted key");
    2759             : 
    2760          15 :                 keySetName (lookupKey, namespaces[i]);
    2761          15 :                 keyAddName (lookupKey, "test/keyset/dir7/key1");
    2762          15 :                 Key * k1 = ksLookup (ks, lookupKey, 0);
    2763          30 :                 compare_key (k1, searchKey);
    2764             : 
    2765          15 :                 keySetName (lookupKey, "/test/keyset/dir7/key1");
    2766          15 :                 if (strcmp (namespaces[i], "spec:/") == 0)
    2767             :                 {
    2768           3 :                         keySetName (searchKey, "proc:/");
    2769           3 :                         keyAddName (searchKey, "test/keyset/dir7/key1");
    2770           3 :                         Key * k2 = ksLookup (ks, lookupKey, 0);
    2771           6 :                         compare_key (k2, searchKey);
    2772             :                 }
    2773             :                 else
    2774             :                 {
    2775          12 :                         Key * k2 = ksLookup (ks, lookupKey, 0);
    2776          24 :                         compare_key (k2, searchKey);
    2777             :                 }
    2778             : 
    2779          15 :                 keySetName (lookupKey, namespaces[i]);
    2780          15 :                 ksDel (ksCut (ks, lookupKey));
    2781             : 
    2782          15 :                 keySetName (lookupKey, namespaces[i]);
    2783          15 :                 keyAddName (lookupKey, "test/keyset/dir7/key1");
    2784          15 :                 Key * k3 = ksLookup (ks, lookupKey, 0);
    2785          15 :                 succeed_if (!k3, "we have a problem: found key cut out");
    2786             : 
    2787          15 :                 keyDel (lookupKey);
    2788          15 :                 keyDel (searchKey);
    2789             :         }
    2790           3 :         ksDel (ks);
    2791           3 : }
    2792             : 
    2793           3 : static void test_ksAppend2 (void)
    2794             : {
    2795           3 :         printf ("Test more involved appending\n");
    2796             : 
    2797           3 :         Key * inks = keyNew ("user:/key_with_meta_data", KEY_END);
    2798           3 :         KeySet * ks = ksNew (0, KS_END);
    2799           3 :         ksAppendKey (ks, inks);
    2800             : 
    2801           3 :         succeed_if (keyGetMeta (inks, "hello") == 0, "hello was not set up to now");
    2802           3 :         succeed_if (keyGetMeta (inks, "error") == 0, "hello was not set up to now");
    2803             : 
    2804           3 :         keySetMeta (inks, "hello", "hello_world");
    2805           3 :         succeed_if_same_string (keyValue (keyGetMeta (inks, "hello")), "hello_world");
    2806           3 :         succeed_if (keyGetMeta (inks, "error") == 0, "hello was not set up to now");
    2807             : 
    2808           3 :         KeySet * ks2 = ksDup (ks);
    2809           3 :         ksRewind (ks2);
    2810           3 :         ksNext (ks2);
    2811           3 :         succeed_if_same_string (keyValue (keyGetMeta (ksCurrent (ks2), "hello")), "hello_world");
    2812           3 :         succeed_if (keyGetMeta (ksCurrent (ks2), "error") == 0, "hello was not set up to now");
    2813             : 
    2814           3 :         Key * dup = keyDup (inks, KEY_CP_ALL);
    2815           3 :         succeed_if_same_string (keyValue (keyGetMeta (inks, "hello")), "hello_world");
    2816           3 :         succeed_if (keyGetMeta (inks, "error") == 0, "hello was not set up to now");
    2817             : 
    2818           3 :         succeed_if_same_string (keyValue (keyGetMeta (dup, "hello")), "hello_world");
    2819           3 :         succeed_if (keyGetMeta (dup, "error") == 0, "hello was not set up to now");
    2820             : 
    2821           3 :         keySetMeta (inks, "error", "some error information");
    2822           3 :         succeed_if_same_string (keyValue (keyGetMeta (inks, "hello")), "hello_world");
    2823           3 :         succeed_if_same_string (keyValue (keyGetMeta (inks, "error")), "some error information");
    2824             : 
    2825           3 :         succeed_if_same_string (keyValue (keyGetMeta (dup, "hello")), "hello_world");
    2826           3 :         succeed_if (keyGetMeta (dup, "error") == 0, "hello was not set up to now");
    2827             : 
    2828           3 :         ksDel (ks);
    2829           3 :         keyDel (dup);
    2830           3 :         ksDel (ks2);
    2831             : 
    2832           3 :         Key * parent = keyNew ("user:/test/rename", KEY_END);
    2833           3 :         succeed_if (keyGetRef (parent) == 0, "ref wrong");
    2834           3 :         ks = ksNew (0, KS_END);
    2835           3 :         ksAppendKey (ks, parent);
    2836           3 :         succeed_if (keyGetRef (parent) == 1, "ref wrong");
    2837           3 :         KeySet * iter = ksDup (ks);
    2838           3 :         succeed_if (keyGetRef (parent) == 2, "ref wrong");
    2839           3 :         ksRewind (iter);
    2840           3 :         Key * key = ksNext (iter);
    2841           3 :         succeed_if (keyGetMeta (key, "name") == 0, "no such meta exists");
    2842           3 :         Key * result = keyDup (key, KEY_CP_ALL);
    2843           3 :         succeed_if (keyGetRef (parent) == 2, "ref wrong");
    2844           3 :         succeed_if (keyGetRef (result) == 0, "ref wrong");
    2845           3 :         keySetName (result, keyName (parent));
    2846           3 :         keyAddBaseName (result, "cut");
    2847           3 :         Key * lok = ksLookup (ks, key, KDB_O_POP);
    2848           3 :         keyDel (lok);
    2849           3 :         succeed_if (keyGetRef (parent) == 1, "ref wrong");
    2850           3 :         succeed_if (keyGetRef (key) == 1, "ref wrong");
    2851           3 :         succeed_if (keyGetRef (result) == 0, "ref wrong");
    2852           3 :         ksAppendKey (ks, result);
    2853           3 :         succeed_if (keyGetRef (parent) == 1, "ref wrong");
    2854           3 :         succeed_if (keyGetRef (key) == 1, "ref wrong");
    2855           3 :         succeed_if (keyGetRef (result) == 1, "ref wrong");
    2856           3 :         keyDel (result);
    2857           3 :         keyDel (key);
    2858           3 :         ksDel (iter);
    2859             :         // parent+key removed!
    2860           3 :         succeed_if (ksLookupByName (ks, "user:/test/rename/cut", 0) != 0, "did not find key");
    2861           3 :         succeed_if (ksGetSize (ks) == 1, "only result in it") ksDel (ks);
    2862             : 
    2863           3 :         parent = keyNew ("user:/test/rename", KEY_END);
    2864           3 :         ks = ksNew (0, KS_END);
    2865           3 :         ksAppendKey (ks, parent);
    2866           3 :         Key * lk = ksLookup (ks, parent, KDB_O_POP);
    2867           3 :         keyDel (lk);
    2868           3 :         ksDel (ks);
    2869           3 : }
    2870             : 
    2871           3 : static void test_ksAppend3 (void)
    2872             : {
    2873           3 :         printf ("Test appending same key\n");
    2874             : 
    2875           3 :         Key * key = keyNew ("user:/key", KEY_END);
    2876           3 :         KeySet * ks = ksNew (0, KS_END);
    2877             : 
    2878           3 :         succeed_if (ksAppendKey (ks, key) == 1, "could not append key");
    2879           3 :         succeed_if (ksLookupByName (ks, "user:/key", 0) == key, "did not find key");
    2880           3 :         succeed_if (ksAppendKey (ks, key) == 1, "could not append key");
    2881           3 :         succeed_if (ksLookupByName (ks, "user:/key", 0) == key, "did not find key again");
    2882             : 
    2883           3 :         ksDel (ks);
    2884           3 : }
    2885             : 
    2886             : 
    2887           3 : int main (int argc, char ** argv)
    2888             : {
    2889           3 :         printf ("KEYSET ABI   TESTS\n");
    2890           3 :         printf ("==================\n\n");
    2891             : 
    2892           3 :         init (argc, argv);
    2893             : 
    2894           3 :         test_ksNew ();
    2895           3 :         test_ksEmpty ();
    2896           3 :         test_ksReference ();
    2897           3 :         test_ksDup ();
    2898           3 :         test_ksCopy ();
    2899           3 :         test_ksIterate ();
    2900           3 :         test_ksCursor ();
    2901           3 :         test_ksAtCursor ();
    2902           3 :         test_ksSort ();
    2903           3 :         test_ksLookup ();
    2904           3 :         test_ksLookupByName ();
    2905             : #ifndef __SANITIZE_ADDRESS__
    2906           3 :         test_ksLookupName ();
    2907             : #endif
    2908           3 :         test_ksLookupNameCascading ();
    2909           3 :         test_ksExample ();
    2910           3 :         test_ksAppend ();
    2911           3 :         test_ksFunctional ();
    2912             : #ifndef __SANITIZE_ADDRESS__
    2913           3 :         test_ksLookupPop ();
    2914             : #endif
    2915           3 :         test_ksDoubleFree ();
    2916           3 :         test_ksDoubleAppend ();
    2917           3 :         test_ksDoubleAppendKey ();
    2918           3 :         test_ksAppendKey ();
    2919           3 :         test_keyVNew ();
    2920           3 :         test_ksModifyKey ();
    2921           3 :         test_cut ();
    2922           3 :         test_cutpoint ();
    2923           3 :         test_cascadingCutpoint ();
    2924           3 :         test_cascadingRootCutpoint ();
    2925           3 :         test_cutpoint_1 ();
    2926           3 :         test_cutpointRoot ();
    2927           3 :         test_unique_cutpoint ();
    2928           3 :         test_cutbelow ();
    2929           3 :         test_cascading_cutbelow ();
    2930           3 :         test_simple ();
    2931           3 :         test_cursor ();
    2932           3 :         test_morecut ();
    2933           3 :         test_cutafter ();
    2934           3 :         test_ksOrder ();
    2935           3 :         test_simpleLookup ();
    2936           3 :         test_nsLookup ();
    2937           3 :         test_ksAppend2 ();
    2938           3 :         test_ksAppend3 ();
    2939           3 :         test_ksOrderNs ();
    2940             : 
    2941           3 :         printf ("\ntestabi_ks RESULTS: %d test(s) done. %d error(s).\n", nbTest, nbError);
    2942             : 
    2943           3 :         return nbError;
    2944             : }

Generated by: LCOV version 1.13