/** * Information about the relation in the hierarchy between * two keys. * * Unlike keyCmp() the number gives information * about hierarchical information. * * * - If the keys are the same 0 is returned. * So it is the key itself. @verbatim user/key user/key @endverbatim * *@code keySetName (key, "user/key/folder"); keySetName (check, "user/key/folder"); succeed_if (keyRel (key, check) == 0, "should be same"); *@endcode * * @note this relation can be checked with keyCmp() too. * * * - If the key is direct below the other one 1 is returned. * That means that, in terms of hierarchy, no other key is * between them - it is a direct child. @verbatim user/key/folder user/key/folder/child @endverbatim * *@code keySetName (key, "user/key/folder"); keySetName (check, "user/key/folder/child"); succeed_if (keyRel (key, check) == 1, "should be direct below"); *@endcode * * * - If the key is below the other one, but not directly 2 is returned. * This is also called grand-child. @verbatim user/key/folder user/key/folder/any/depth/deeper/grand-child @endverbatim * * *@code keySetName (key, "user/key/folder"); keySetName (check, "user/key/folder/any/depth/deeper/grand-child"); succeed_if (keyRel (key, check) >= 2, "should be below (but not direct)"); succeed_if (keyRel (key, check) > 0, "should be below"); succeed_if (keyRel (key, check) >= 0, "should be the same or below"); *@endcode * * * - If a invalid or null ptr key is passed, -1 is returned * * * - If the keys have no relations, but are not invalid, -2 is returned. * * * - If the keys are in the same hierarchy, a value smaller then -2 is returned. * It means that the key is not below. @verbatim user/key/myself user/key/sibling @endverbatim * * @code keySetName (key, "user/key/folder"); keySetName (check, "user/notsame/folder"); succeed_if (keyRel (key, check) < -2, "key is not below, but same namespace"); * @endcode * * @code * @endcode * * * TODO Below is an idea how it could be extended: * It could continue the search into the other direction * if any (grand-)parents are equal. * * - If the keys are direct below a key which is next to the key, -2 is returned. * This is also called nephew. (TODO not implemented) * @verbatim user/key/myself user/key/sibling @endverbatim * * - If the keys are direct below a key which is next to the key, -2 is returned. * This is also called nephew. (TODO not implemented) * @verbatim user/key/myself user/key/sibling/nephew @endverbatim * * - If the keys are below a key which is next to the key, -3 is returned. * This is also called grand-nephew. (TODO not implemented) @verbatim user/key/myself user/key/sibling/any/depth/deeper/grand-nephew @endverbatim * * The same holds true for the other direction, but with negative values. * For no relation INT_MIN is returned. * * @note to check if the keys are the same, you must use * keyCmp() == 0! * keyRel() does not give you the information if it did not * find a relation or if it is the same key. * * @return depending on the relation * @retval 2 if below * @retval 1 if direct below * @retval 0 if the same * @retval -1 on null or invalid keys * @retval -2 if none of any other relation * @retval -3 if same hierarchy (none of those below) * @retval -4 if sibling (in same hierarchy) * @retval -5 if nephew (in same hierarchy) * * @param key the key object to work with * @param check the second key object to check the relation with * @ingroup keytest */ int keyRel (const Key * key, const Key * check) { if (!key || !check) return -1; if (!key->key || !check->key) return -1; if (!keyCmp (key, check)) return 0; if (keyIsDirectBelow (key, check)) return 1; if (keyIsBelow (key, check)) return 2; if (keyIsUser (key) && keyIsUser (check)) return -3; if (keyIsSystem (key) && keyIsSystem (check)) return -3; // if (keyIsSibling(key, check)) return -4; // if (keyIsNephew(key, check)) return -5; return -2; }
/** * @brief Filter out keys not in the correct keyset * * @param split the split where to do it * @param i for which split * @param warningKey the key * @param handle where to do backend lookups * * @retval -1 on error (no backend, wrong namespace) * @retval 0 otherwise */ static int elektraSplitPostprocess (Split * split, int i, Key * warningKey, KDB * handle) { Key * cur = 0; Backend * curHandle = 0; ksRewind (split->keysets[i]); while ((cur = ksNext (split->keysets[i])) != 0) { curHandle = elektraMountGetBackend (handle, cur); if (!curHandle) return -1; keyClearSync (cur); if (curHandle != split->handles[i]) { elektraDropCurrentKey (split->keysets[i], warningKey, curHandle, "it is hidden by other mountpoint"); } else switch (keyGetNamespace (cur)) { case KEY_NS_SPEC: if (!keyIsSpec (split->parents[i])) elektraDropCurrentKey (split->keysets[i], warningKey, curHandle, "it is not spec"); break; case KEY_NS_DIR: if (!keyIsDir (split->parents[i])) elektraDropCurrentKey (split->keysets[i], warningKey, curHandle, "it is not dir"); break; case KEY_NS_USER: if (!keyIsUser (split->parents[i])) elektraDropCurrentKey (split->keysets[i], warningKey, curHandle, "it is not user"); break; case KEY_NS_SYSTEM: if (!keyIsSystem (split->parents[i])) elektraDropCurrentKey (split->keysets[i], warningKey, curHandle, "it is not system"); break; case KEY_NS_PROC: elektraDropCurrentKey (split->keysets[i], warningKey, curHandle, "it has a proc key name"); break; case KEY_NS_EMPTY: elektraDropCurrentKey (split->keysets[i], warningKey, curHandle, "it has an empty name"); break; case KEY_NS_META: elektraDropCurrentKey (split->keysets[i], warningKey, curHandle, "it has a meta name"); break; case KEY_NS_CASCADING: elektraDropCurrentKey (split->keysets[i], warningKey, curHandle, "it has a cascading name"); break; case KEY_NS_NONE: ELEKTRA_ASSERT (0 && "wrong key namespace, should not be none"); return -1; } } return 0; }
/** * Determines if the backend is already inserted or not. * * @warning If no parent Key is given, the default/root backends won't * be searched. * * @param split the split object to work with * @param backend the backend to search for * @param parent the key to check for domains in default/root backends. * @return pos of backend if it already exist * @retval -1 if it does not exist * @ingroup split */ ssize_t elektraSplitSearchBackend (Split * split, Backend * backend, Key * parent) { for (size_t i = 0; i < split->size; ++i) { if (backend == split->handles[i]) { if (test_bit (split->syncbits[i], SPLIT_FLAG_CASCADING)) { switch (keyGetNamespace (parent)) { case KEY_NS_SPEC: if (keyIsSpec (split->parents[i])) return i; break; case KEY_NS_DIR: if (keyIsDir (split->parents[i])) return i; break; case KEY_NS_USER: if (keyIsUser (split->parents[i])) return i; break; case KEY_NS_SYSTEM: if (keyIsSystem (split->parents[i])) return i; break; case KEY_NS_PROC: return -1; case KEY_NS_EMPTY: return -1; case KEY_NS_NONE: return -1; case KEY_NS_META: return -1; case KEY_NS_CASCADING: return -1; } continue; } /* We already have this backend, so leave */ return i; } } return -1; }
static void test_keyNamespace () { Key * key; printf ("Test namespaces\n"); succeed_if (keyGetNamespace (0) == KEY_NS_NONE, "null key"); key = keyNew (0); succeed_if (keyGetNamespace (key) == KEY_NS_EMPTY, "empty namespace not empty"); succeed_if (keyNameIsSystem (keyName (key)) == 0, "empty name is not system"); succeed_if (keyIsSystem (key) == 0, "empty key is not system"); succeed_if (keyNameIsUser (keyName (key)) == 0, "empty name is not user"); succeed_if (keyIsUser (key) == 0, "empty key is not user"); keyDel (key); key = keyNew ("", KEY_END); succeed_if (keyGetNamespace (key) == KEY_NS_EMPTY, "empty namespace not empty"); succeed_if (keyNameIsSystem (keyName (key)) == 0, "empty name is not system"); succeed_if (keyIsSystem (key) == 0, "empty key is not system"); succeed_if (keyNameIsUser (keyName (key)) == 0, "empty name is not user"); succeed_if (keyIsUser (key) == 0, "empty key is not user"); keyDel (key); key = keyNew ("user", KEY_END); succeed_if (keyGetNamespace (key) == KEY_NS_USER, "user namespace not KEY_NS_USER"); succeed_if (keyNameIsSystem (keyName (key)) == 0, "user name is not system"); succeed_if (keyIsSystem (key) == 0, "user key is not system"); succeed_if (keyNameIsUser (keyName (key)) == 1, "user name is not user"); succeed_if (keyIsUser (key) == 1, "user key is not user"); keyDel (key); key = keyNew ("user/key", KEY_END); succeed_if (keyGetNamespace (key) == KEY_NS_USER, "user namespace not KEY_NS_USER"); succeed_if (keyNameIsSystem (keyName (key)) == 0, "user name is not system"); succeed_if (keyIsSystem (key) == 0, "user key is not system"); succeed_if (keyNameIsUser (keyName (key)) == 1, "user name is not user"); succeed_if (keyIsUser (key) == 1, "user key is not user"); keyDel (key); key = keyNew ("user:owner/key", KEY_END); succeed_if (keyGetNamespace (key) == KEY_NS_USER, "user namespace not KEY_NS_USER"); succeed_if (keyNameIsSystem (keyName (key)) == 0, "user name is not system"); succeed_if (keyIsSystem (key) == 0, "user key is not system"); succeed_if (keyNameIsUser (keyName (key)) == 1, "user name is not user"); succeed_if (keyIsUser (key) == 1, "user key is not user"); keyDel (key); key = keyNew ("system", KEY_END); succeed_if (keyGetNamespace (key) == KEY_NS_SYSTEM, "system namespace not KEY_NS_SYSTEM"); succeed_if (keyNameIsSystem (keyName (key)) == 1, "system name is not system"); succeed_if (keyIsSystem (key) == 1, "system key is not system"); succeed_if (keyNameIsUser (keyName (key)) == 0, "system name is not system"); succeed_if (keyIsUser (key) == 0, "system key is not system"); keyDel (key); key = keyNew ("system/key", KEY_END); succeed_if (keyGetNamespace (key) == KEY_NS_SYSTEM, "system namespace not KEY_NS_SYSTEM"); succeed_if (keyNameIsSystem (keyName (key)) == 1, "system name is not system"); succeed_if (keyIsSystem (key) == 1, "system key is not system"); succeed_if (keyNameIsUser (keyName (key)) == 0, "system name is not system"); succeed_if (keyIsUser (key) == 0, "system key is not system"); keyDel (key); key = keyNew ("spec/key", KEY_END); succeed_if (keyGetNamespace (key) == KEY_NS_SPEC, "Spec namespace not KEY_NS_SPEC"); succeed_if (keyNameIsSpec (keyName (key)) == 1, "Spec name is not Spec"); succeed_if (keyIsSpec (key) == 1, "Spec key is not Spec"); succeed_if (keyNameIsUser (keyName (key)) == 0, "Spec name is not Spec"); succeed_if (keyIsUser (key) == 0, "Spec key is not Spec"); keyDel (key); key = keyNew ("/key", KEY_CASCADING_NAME, KEY_END); succeed_if (keyGetNamespace (key) == KEY_NS_CASCADING, "not correct namespace"); keyDel (key); key = keyNew ("type", KEY_META_NAME, KEY_END); succeed_if (keyGetNamespace (key) == KEY_NS_META, "not correct namespace"); keyDel (key); }