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

Generated by: LCOV version 1.13