示例#1
0
static KeySet * getGlobKeys (Key * parentKey, KeySet * keys, enum GlobDirection direction)
{
	KeySet * glob = ksNew (0, KS_END);
	Key * k = 0;
	size_t parentsize = keyGetNameSize (parentKey);

	Key * userGlobConfig = 0;
	Key * systemGlobConfig = 0;
	Key * userDirGlobConfig = 0;
	Key * systemDirGlobConfig = 0;

	userGlobConfig = keyNew ("user/glob", KEY_END);
	systemGlobConfig = keyNew ("system/glob", KEY_END);
	switch (direction)
	{
	case GET:
		userDirGlobConfig = keyNew ("user/glob/get", KEY_END);
		systemDirGlobConfig = keyNew ("system/glob/get", KEY_END);
		break;
	case SET:
		userDirGlobConfig = keyNew ("user/glob/set", KEY_END);
		systemDirGlobConfig = keyNew ("system/glob/set", KEY_END);
		break;
	}

	while ((k = ksNext (keys)) != 0)
	{
		/* use only glob keys for the current direction */
		if (keyIsDirectBelow (userGlobConfig, k) || keyIsDirectBelow (systemGlobConfig, k) ||
		    keyIsDirectBelow (userDirGlobConfig, k) || keyIsDirectBelow (systemDirGlobConfig, k))
		{
			keySetMeta (k, "glob/flags", getGlobFlags (keys, k));

			/* Look if we have a string */
			size_t valsize = keyGetValueSize (k);
			if (valsize < 2) continue;

			/* We now know we want that key.
			 Dup it to not change the configuration. */
			Key * ins = keyDup (k);
			/* Now look if we want cascading for the key */
			if (keyString (k)[0] == '/')
			{
				char * newstring = elektraMalloc (valsize + parentsize);
				strcpy (newstring, keyName (parentKey));
				strcat (newstring, keyString (k));
				keySetString (ins, newstring);
				elektraFree (newstring);
			}
			ksAppendKey (glob, ins);
		}
	}

	keyDel (userGlobConfig);
	keyDel (systemGlobConfig);
	keyDel (userDirGlobConfig);
	keyDel (systemDirGlobConfig);

	return glob;
}
示例#2
0
static void validateWildcardSubs (KeySet * ks, Key * key, Key * specKey)
{
	const Key * requiredMeta = keyGetMeta (specKey, "required");
	if (!requiredMeta) return;
	Key * tmpParent = keyDup (key);
	keySetBaseName (tmpParent, 0);
	Key * parent = ksLookup (ks, tmpParent, KDB_O_NONE);
	keyDel (tmpParent);
	if (parent == NULL) return;
	KeySet * ksCopy = ksDup (ks);
	KeySet * subKeys = ksCut (ksCopy, parent);
	Key * cur;
	long subCount = 0;
	while ((cur = ksNext (subKeys)) != NULL)
	{
		if (keyIsDirectBelow (parent, cur)) ++subCount;
	}
	long required = atol (keyString (requiredMeta));
	if (required != subCount)
	{
		char buffer[MAX_CHARS_IN_LONG + 1];
		snprintf (buffer, sizeof (buffer), "%ld", subCount);
		keySetMeta (parent, "conflict/invalid/subcount", buffer);
	}

	ksDel (subKeys);
	ksDel (ksCopy);
}
示例#3
0
/**
 * 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;
}
示例#4
0
static void validateArray (KeySet * ks, Key * arrayKey, Key * specKey)
{
	Key * tmpArrayParent = keyDup (arrayKey);
	keySetBaseName (tmpArrayParent, 0);
	Key * arrayParent = ksLookup (ks, tmpArrayParent, KDB_O_NONE);
	keyDel (tmpArrayParent);
	if (arrayParent == NULL) return;
	KeySet * ksCopy = ksDup (ks);
	KeySet * subKeys = ksCut (ksCopy, arrayParent);
	Key * cur;
	long validCount = 0;
	while ((cur = ksNext (subKeys)) != NULL)
	{
		if (!keyIsDirectBelow (arrayParent, cur)) continue;
		if (keyBaseName (cur)[0] == '#')
		{
			if (elektraArrayValidateName (cur) == 1)
			{
				++validCount;
				keySetMeta (cur, "spec/internal/valid", "");
			}
			else
			{
				KeySet * invalidCutKS = ksCut (subKeys, cur);
				Key * toMark;
				while ((toMark = ksNext (invalidCutKS)) != NULL)
				{
					if (strcmp (keyName (cur), keyName (toMark))) keySetMeta (toMark, "conflict/invalid", "");
					elektraMetaArrayAdd (arrayParent, "conflict/invalid/hasmember", keyName (toMark));
				}
				ksDel (invalidCutKS);
			}
		}
	}
	ksDel (subKeys);
	ksDel (ksCopy);
	validateArrayRange (arrayParent, validCount, specKey);
}
int direct_below_a (Key *check) {
    return keyIsDirectBelow(global_a, check);
}
示例#6
0
/**
 * @internal
 *
 * Returns true (1) for all keys that are part of the array
 * identified by the supplied array parent. Only the array
 * eleements themself, but no subkeys of them will be filtered
 *
 * @pre The supplied argument has to be of type (const Key *)
 * and is the parent of the array to be extracted. For example
 * if the keys of the array comment/# are to be extracted, a key
 * with the name "comment" has to be supplied
 *
 * @param key the key to be checked against the array
 * @param argument the array parent
 * @return 1 if the key is part of the array identified by the
 * array parent, 0 otherwise
 *
 */
static int arrayFilter(const Key *key, void *argument)
{
	const Key *arrayParent = (const Key *) argument;

	return keyIsDirectBelow(arrayParent, key) && elektraArrayValidateName(key);
}