static void test_ksPop (const size_t storagePlugin, const char * tmpFile) { Key * parentKey = keyNew (TEST_ROOT_KEY, KEY_VALUE, tmpFile, KEY_END); open_storage_plugin (storagePlugin); Plugin * plugin = plugins[storagePlugin]; KeySet * ks = simpleTestKeySet (); succeed_if (plugin->kdbSet (plugin, ks, parentKey) == 1, "kdbSet was not successful"); succeed_if (plugin->kdbGet (plugin, ks, parentKey) == 1, "kdbGet was not successful"); KeySet * poppedKeys = ksNew (0, KS_END); succeed_if (ksAppendKey (poppedKeys, ksPop (ks)) != -1, "ksAppendKey failed"); succeed_if (ksAppendKey (poppedKeys, ksPop (ks)) != -1, "ksAppendKey failed"); succeed_if (ksGetSize (ks) == 1, "ksGetSize after ksPop should be decremented"); succeed_if (ksAppendKey (poppedKeys, ksPop (ks)) != -1, "ksAppendKey failed"); succeed_if (ksGetSize (poppedKeys) == 3, "expecting three keys to be in ks"); succeed_if (ksPop (ks) == 0, "ks should be empty"); succeed_if (ksAppendKey (poppedKeys, ksPop (ks)) == -1, "ks should be empty, but is not"); KeySet * test = simpleTestKeySet (); compare_keyset (poppedKeys, test); ksDel (test); ksDel (poppedKeys); keyDel (parentKey); ksDel (ks); closeStoragePlugin (storagePlugin); }
/** * @brief Takes the first key and cuts off this common part * for all other keys, instead name will be prepended * * @return a new allocated keyset with keys in user namespace. * * The first key is removed in the resulting keyset. */ KeySet* elektraRenameKeys(KeySet *config, const char* name) { Key *root; Key *cur; ssize_t rootSize = 0; ksRewind(config); root = ksNext (config); rootSize = keyGetNameSize(root); keyDel (ksLookup (config, root, KDB_O_POP)); KeySet *newConfig = ksNew(ksGetSize(config), KS_END); if (rootSize == -1) return newConfig; while ((cur = ksPop(config)) != 0) { Key *dupKey = keyDup(cur); keySetName(dupKey, name); keyAddName(dupKey, keyName(cur)+rootSize-1); ksAppendKey(newConfig, dupKey); keyDel(cur); } return newConfig; }
/** * * Return the next key in the given array. * The function will automatically allocate memory * for a new key and name it accordingly. * * @pre The supplied keyset must contain only valid array keys. * * The caller has to keyDel the resulting key. * * @param arraykeys the array where the new key will belong to * * @return the new array key on success * @retval NULL if the passed array is empty * @retval NULL on NULL pointers or if an error occurs */ Key *elektraArrayGetNextKey(KeySet *arrayKeys) { if (!arrayKeys) return 0; Key *last = ksPop(arrayKeys); if (!last) return 0; ksAppendKey(arrayKeys, last); Key *newKey = keyDup(last); int ret = elektraArrayIncName(newKey); if (ret == -1) { keyDel(newKey); return 0; } return newKey; }
/** * @brief Pop key at given cursor position * * @param ks the keyset to pop key from * @param c where to pop * * The internal cursor will be rewinded using ksRewind(). You can use * ksGetCursor() and ksSetCursor() jump back to the previous position. * e.g. to pop at current position within ksNext() loop: * @code * cursor_t c = ksGetCursor(ks); * keyDel (ksPopAtCursor(ks, c)); * ksSetCursor(ks, c); * ksPrev(ks); // to have correct key after next ksNext() * @endcode * * @warning do not use, will be superseded by external iterator API * * @return the popped key * @retval 0 if ks is 0 */ Key *ksPopAtCursor(KeySet *ks, cursor_t pos) { if (!ks) return 0; if (pos<0) return 0; if (pos>SSIZE_MAX) return 0; size_t c = pos; if (c>=ks->size) return 0; if (c != ks->size-1) { Key ** found = ks->array+c; Key * k = *found; /* Move the array over the place where key was found * * e.g. c = 2 * size = 6 * * 0 1 2 3 4 5 6 * |--|--|c |--|--|--|size * move to (c/pos is overwritten): * |--|--|--|--|--| * * */ memmove (found, found+1, (ks->size-c-1) * sizeof(Key *)); *(ks->array+ks->size-1) = k; // prepare last element to pop } else { // if c is on last position it is just a ksPop.. // so do nothing.. } ksRewind(ks); return ksPop(ks); }
static void test_ksResize () { int i; KeySet * ks = 0; KeySet * copy = ksNew (0, KS_END); char name[NAME_SIZE]; ks = ksNew (20, keyNew ("user/test01", KEY_END), keyNew ("user/test02", KEY_END), keyNew ("user/test03", KEY_END), keyNew ("user/test04", KEY_END), keyNew ("user/test05", KEY_END), keyNew ("user/test11", KEY_END), keyNew ("user/test12", KEY_END), keyNew ("user/test13", KEY_END), keyNew ("user/test14", KEY_END), keyNew ("user/test15", KEY_END), keyNew ("user/test21", KEY_END), keyNew ("user/test22", KEY_END), keyNew ("user/test23", KEY_END), keyNew ("user/test24", KEY_END), keyNew ("user/test25", KEY_END), keyNew ("user/test31", KEY_END), keyNew ("user/test32", KEY_END), keyNew ("user/test33", KEY_END), keyNew ("user/test34", KEY_END), keyNew ("user/test35", KEY_END), KS_END); succeed_if (ksGetAlloc (ks) == 20, "20 keys with alloc 20 should work"); ksDel (ks); printf ("Test resize of keyset\n"); exit_if_fail ((ks = ksNew (0, KS_END)) != 0, "could not create new keyset"); for (i = 0; i < 100; i++) { snprintf (name, NAME_SIZE, "user/test%d", i); ksAppendKey (ks, keyNew (name, KEY_END)); if (i >= 63) { succeed_if (ksGetAlloc (ks) == 127, "allocation size wrong"); } else if (i >= 31) { succeed_if (ksGetAlloc (ks) == 63, "allocation size wrong"); } else if (i >= 15) { succeed_if (ksGetAlloc (ks) == 31, "allocation size wrong"); } else if (i >= 0) { succeed_if (ksGetAlloc (ks) == 15, "allocation size wrong"); } } succeed_if (ksGetSize (ks) == 100, "could not append 100 keys"); succeed_if (ksGetAlloc (ks) == 127, "allocation size wrong"); for (i = 100; i >= 0; i--) { keyDel (ksPop (ks)); if (i >= 64) { succeed_if (ksGetAlloc (ks) == 127, "allocation size wrong"); } else if (i >= 32) { succeed_if (ksGetAlloc (ks) == 63, "allocation size wrong"); } else if (i >= 16) { succeed_if (ksGetAlloc (ks) == 31, "allocation size wrong"); } else if (i >= 0) { succeed_if (ksGetAlloc (ks) == 15, "allocation size wrong"); } } succeed_if (ksGetSize (ks) == 0, "could not pop 100 keys"); succeed_if (ksGetAlloc (ks) == 15, "allocation size wrong"); ksDel (ks); exit_if_fail ((ks = ksNew (0, KS_END)) != 0, "could not create new keyset"); ksResize (ks, 100); succeed_if (ksGetAlloc (ks) == 100, "allocation size wrong"); for (i = 0; i < 100; i++) { snprintf (name, NAME_SIZE, "user/test%d", i); ksAppendKey (ks, keyNew (name, KEY_END)); succeed_if (ksGetAlloc (ks) == 100, "allocation size wrong"); } succeed_if (ksGetSize (ks) == 100, "could not append 100 keys"); succeed_if (ksGetAlloc (ks) == 100, "allocation size wrong"); ksDel (ks); ks = #include "data_keyset.c" succeed_if (ksGetSize (ks) == 102, "Problem loading keyset with 102 keys"); succeed_if (ksGetAlloc (ks) == 102, "alloc size wrong"); ksCopy (copy, ks); succeed_if (ksGetSize (copy) == 102, "Problem copy keyset with 102 keys"); succeed_if (ksGetAlloc (copy) == 127, "alloc of copy size wrong"); compare_keyset (copy, ks); ksClear (copy); // useless, just test for double free ksCopy (copy, ks); succeed_if (ksGetSize (copy) == 102, "Problem copy keyset with 102 keys"); succeed_if (ksGetAlloc (copy) == 127, "alloc of copy size wrong"); compare_keyset (copy, ks); ksDel (copy); ksDel (ks); }