Example #1
0
/**
 * Check if the key check is direct below the key key or not.
 *
 @verbatim
Example:
key user/sw/app
check user/sw/app/key

returns true because check is below key

Example:
key user/sw/app
check user/sw/app/folder/key

does not return true, because there is only a indirect relation
@endverbatim
 *
 * @param key the key object to work with
 * @param check the key to find the relative position of
 * @retval 1 if check is below key
 * @retval 0 if it is not below or if it is the same key
 * @retval -1 on null pointer
 * @see keyIsBelow(), keySetName(), keyGetName()
 * @ingroup keytest
 *
 */
int keyIsDirectBelow (const Key * key, const Key * check)
{
	if (!key || !check) return -1;

	if (!keyIsBelow (key, check)) return 0;


	const char * checkname = keyUnescapedName (check);
	ssize_t keysize = keyGetUnescapedNameSize (key);
	ssize_t checksize = keyGetUnescapedNameSize (check);

	char * startPtr = NULL;

	if (keyName (key)[0] != '/')
	{
		startPtr = strrchr (checkname + keysize, '\0');
	}
	else
	{
		if (keyName (check)[0] != '/')
		{
			startPtr = strrchr (checkname, '\0');
			startPtr = strrchr (startPtr + keysize, '\0');
		}
		else
		{
			startPtr = strrchr (checkname + keysize, '\0');
		}
	}
	if (startPtr == checkname + checksize - 1) return 1;

	return 0;
}
Example #2
0
// keyRel2 helper, returns how many levels check is below key, or 0 if check isn't below
int keyGetLevelsBelow (const Key * key, const Key * check)
{
	const char * keyUName = keyUnescapedName (key);
	size_t keyUSize = keyGetUnescapedNameSize (key);
	const char * keyUNameEnd = keyUName + keyUSize;

	const char * checkUName = keyUnescapedName (check);
	size_t checkUSize = keyGetUnescapedNameSize (check);
	const char * checkUNameEnd = checkUName + checkUSize;

	while (strcmp (keyUName, checkUName) == 0)
	{
		keyUName = strchr (keyUName, '\0') + 1;
		checkUName = strchr (checkUName, '\0') + 1;

		if (keyUName >= keyUNameEnd)
		{
			int levels = 0;
			while (checkUName < checkUNameEnd)
			{
				checkUName = strchr (checkUName, '\0') + 1;
				++levels;
			}

			return levels;
		}

		if (checkUName >= checkUNameEnd)
		{
			break;
		}
	}

	return 0;
}
Example #3
0
/**
 * Check if the key check is direct below the key key or not.
 *
@verbatim
Example:
key user/sw/app
check user/sw/app/key

returns true because check is below key

Example:
key user/sw/app
check user/sw/app/folder/key

does not return true, because there is only a indirect relation
@endverbatim
 *
 * @param key the key object to work with
 * @param check the key to find the relative position of
 * @retval 1 if check is below key
 * @retval 0 if it is not below or if it is the same key
 * @retval -1 on null pointer
 * @see keyIsBelow(), keySetName(), keyGetName()
 * @ingroup keytest
 *
 */
int keyIsDirectBelow(const Key *key, const Key *check)
{
	if (!key || !check) return -1;

	if (!keyIsBelow(key, check)) return 0;


	const char * checkname = keyUnescapedName(check);
	ssize_t keysize = keyGetUnescapedNameSize(key);
	ssize_t checksize = keyGetUnescapedNameSize(check);
	if (strchr(checkname + keysize, '\0') == checkname + checksize - 1) return 1;

	return 0;
}
Example #4
0
int keyIsBelow (const Key * key, const Key * check)
{
	const char * keyname = 0;
	const char * checkname = 0;
	const char * ukeyname = 0;
	const char * ucheckname = 0;
	ssize_t keysize = 0;
	ssize_t checksize = 0;
	ssize_t ukeysize = 0;
	ssize_t uchecksize = 0;

	if (!key || !check) return -1;

	keyname = keyName (key);
	checkname = keyName (check);
	ukeyname = keyUnescapedName (key);
	ucheckname = keyUnescapedName (check);
	keysize = keyGetNameSize (key);
	checksize = keyGetNameSize (check);
	ukeysize = keyGetUnescapedNameSize (key);
	uchecksize = keyGetUnescapedNameSize (check);
	if (!strcmp (checkname, "/")) return 0;
	if (!strcmp (keyname, "/"))
	{
		if (checkname[0] == '/') return 1;
		if (strchr (checkname, '/')) return 1;
	}
	else if (checkname[0] == '/')
	{
		if (keyname[0] == '/')
		{
			if (!strncmp (keyname, checkname, keysize - 1))
			{
				if (ucheckname[ukeysize - 1] == '\0' && uchecksize > ukeysize)
				{
					return 1;
				}
			}
		}
		else
		{
			size_t size = 0;
			char * ptr = (char *)keyname;
			ptr = keyNameGetOneLevel (ptr, &size);
			if (size == (size_t)keysize)
			{
				return 1;
			}
			keyname += size;
			keysize = elektraStrLen (keyname);
			ptr = strrchr (ukeyname, '\0');
			ukeysize -= (ptr - ukeyname);
			if (!strncmp (keyname, checkname, keysize - 1))
			{
				if (ucheckname[ukeysize - 1] == '\0' && uchecksize > ukeysize)
				{
					return 1;
				}
			}
		}
	}
	else if (keyname[0] == '/')
	{
		size_t size = 0;
		char * ptr = (char *)checkname;
		ptr = keyNameGetOneLevel (ptr, &size);
		if (size == (size_t)checksize)
		{
			return 0;
		}
		checkname += size;
		checksize = elektraStrLen (checkname);
		ptr = strrchr (ucheckname, '\0');
		uchecksize -= (ptr - ucheckname);
		ucheckname = ptr;
		if (!strncmp (keyname, checkname, keysize - 1))
		{
			if (ucheckname[ukeysize - 1] == '\0' && uchecksize > ukeysize)
			{
				return 1;
			}
		}
	}
	else if (!strncmp (keyname, checkname, keysize - 1))
	{
		if ((ucheckname[ukeysize - 1] == '\0') && (uchecksize > ukeysize)) return 1;
	}
	return 0;
}