src/libs/elektra/keyset.c
/**
 * Cuts out a keyset at the cutpoint.
 *
 * Searches for the cutpoint inside the KeySet ks.
 * If found it cuts out everything which is below (see keyIsBelow()) this key.
 * These keys will be missing in the keyset @p ks.
 * Instead, they will be moved to the returned keyset.
 * If @p cutpoint is not found an empty keyset is returned and @p ks
 * is not changed.
 *
 * The cursor will stay at the same key as it was before.
 * If the cursor was inside the region of cut (moved)
 * keys, the cursor will be set to the key before
 * the cutpoint.
 *
 * If you use ksCut() on a keyset you got from kdbGet() and plan to make
 * a kdbSet() later, make sure that you keep all keys that should not
 * be removed permanently. You have to keep the KeySet that was returned
 * and the KeySet @p ks.
 *
 * @par Example:
 *
 * You have the keyset @p ks:
 * - @p system/mountpoint/interest
 * - @p system/mountpoint/interest/folder
 * - @p system/mountpoint/interest/folder/key1
 * - @p system/mountpoint/interest/folder/key2
 * - @p system/mountpoint/other/key1
 *
 * When you use
 * @snippet cut.c cut
 *
 * Then in @p returned are:
 * - @p system/mountpoint/interest
 * - @p system/mountpoint/interest/folder
 * - @p system/mountpoint/interest/folder/key1
 * - @p system/mountpoint/interest/folder/key2
 *
 * And in @p ks are:
 * - @p system/mountpoint/other/key1
 *
 * So kdbSet() permanently removes all keys below
 * @p system/mountpoint/interest.
 *
 * @see kdbGet() for explanation why you might get more keys than you
 * requested.
 *
 * @return a new allocated KeySet which needs to deleted with ksDel().
 *         The keyset consists of all keys (of the original keyset ks)
 *         below the cutpoint. If the key cutpoint exists, it will
 *         also be appended.
 * @retval 0 on null pointers, no key name or allocation problems
 * @param ks the keyset to cut. It will be modified by removing
 *           all keys below the cutpoint.
 *           The cutpoint itself will also be removed.
 * @param cutpoint the point where to cut out the keyset
 */
Cuts out a keyset at the cutpoint.
Searches for the cutpoint inside the KeySet ks.
If found it cuts out everything which is below ) this key.
These keys will be missing in the keyset @p ks.
Instead, they will be moved to the returned keyset.
If @p cutpoint is not found an empty keyset is returned and @p ks
is not changed.

The cursor will stay at the same key as it was before.
If the cursor was inside the region of cut (moved)
keys, the cursor will be set to the key before
the cutpoint.

If you use ksCut() on a keyset you got from kdbGet() and plan to make
a kdbSet() later, make sure that you keep all keys that should not
be removed permanently. You have to keep the KeySet that was returned
and the KeySet @p ks.

@par Example.



When you use
@snippet cut.c cut



And in @p ks are:
- @p system/mountpoint/other/key1

So kdbSet() permanently removes all keys below
@p system/mountpoint/interest.

@see kdbGet() for explanation why you might get more keys than you
requested.

@return a new allocated KeySet which needs to deleted with ksDel().
The keyset consists of all keys (of the original keyset ks)
below the cutpoint. If the key cutpoint exists, it will
also be appended.
@retval 0 on null pointers, no key name or allocation problems
@param ks the keyset to cut. It will be modified by removing
all keys below the cutpoint.
The cutpoint itself will also be removed.
@param cutpoint the point where to cut out the keyset
Cuts out a keyset at the cutpoint . Searches for the cutpoint inside the KeySet ks . If found it cuts out everything which is below ) this key . These keys will be missing in the keyset @p ks . Instead they will be moved to the returned keyset . If @p cutpoint is not found an empty keyset is returned and @p ks is not changed . The cursor will stay at the same key as it was before . If the cursor was inside the region of cut ( moved ) keys the cursor will be set to the key before the cutpoint . If you use ksCut () on a keyset you got from kdbGet () and plan to make a kdbSet () later make sure that you keep all keys that should not be removed permanently . You have to keep the KeySet that was returned and the KeySet @p ks . @par Example . When you use @snippet cut . c cut And in @p ks are : - @p system / mountpoint / other / key1 So kdbSet () permanently removes all keys below @p system / mountpoint / interest . @see kdbGet () for explanation why you might get more keys than you requested . @return a new allocated KeySet which needs to deleted with ksDel () . The keyset consists of all keys ( of the original keyset ks ) below the cutpoint . If the key cutpoint exists it will also be appended . @retval 0 on null pointers no key name or allocation problems @param ks the keyset to cut . It will be modified by removing all keys below the cutpoint . The cutpoint itself will also be removed . @param cutpoint the point where to cut out the keyset
KeySet * ksCut (KeySet * ks, const Key * cutpoint)
{
	KeySet * returned = 0;
	size_t found = 0;
	size_t it = 0;
	size_t newsize = 0;
	int set_cursor = 0;
	if (!ks) return 0;
	if (!cutpoint) return 0;
	char * name = cutpoint->key;
	if (!name) return 0;
	if (name[0] == '/')
	{
		Key * key = (Key *)cutpoint;
		size_t size = key->keySize;
		size_t usize = key->keyUSize;
		size_t length = strlen (name) + ELEKTRA_MAX_NAMESPACE_SIZE;
		char newname[length * 2];
		KeySet * ret = ksNew (0, KS_END);
		for (elektraNamespace ns = KEY_NS_FIRST; ns <= KEY_NS_LAST; ++ns)
		{
			int validNS = 1;
			switch (ns)
			{
			case KEY_NS_SPEC:
				strncpy (newname + 2, "spec", 4);
				strcpy (newname + 6, name);
				key->key = newname + 2;
				key->keySize = length - 2;
				if (!strcmp (name, "/")) key->keySize = 5;
				elektraFinalizeName (key);
				break;
			case KEY_NS_PROC:
				strncpy (newname + 2, "proc", 4);
				strcpy (newname + 6, name);
				key->key = newname + 2;
				key->keySize = length - 2;
				if (!strcmp (name, "/")) key->keySize = 5;
				elektraFinalizeName (key);
				break;
			case KEY_NS_DIR:
				strncpy (newname + 3, "dir", 3);
				strcpy (newname + 6, name);
				key->key = newname + 3;
				key->keySize = length - 3;
				if (!strcmp (name, "/")) key->keySize = 4;
				elektraFinalizeName (key);
				break;
			case KEY_NS_USER:
				strncpy (newname + 2, "user", 4);
				strcpy (newname + 6, name);
				key->key = newname + 2;
				key->keySize = length - 2;
				if (!strcmp (name, "/")) key->keySize = 5;
				elektraFinalizeName (key);
				break;
			case KEY_NS_SYSTEM:
				strncpy (newname, "system", 6);
				strcpy (newname + 6, name);
				key->key = newname;
				key->keySize = length;
				if (!strcmp (name, "/")) key->keySize = 7;
				elektraFinalizeName (key);
				break;
			case KEY_NS_EMPTY:
			case KEY_NS_NONE:
			case KEY_NS_META:
			case KEY_NS_CASCADING:
				validNS = 0;
			}
			if (validNS)
			{
				KeySet * n = ksCut (ks, key);
				ksAppend (ret, n);
				ksDel (n);
			}
		}
		key->key = name;
		key->keySize = size;
		key->keyUSize = usize;
		return ret;
	}
	while (it < ks->size && keyIsBelowOrSame (cutpoint, ks->array[it]) == 0)
	{
		++it;
	}
	if (it == ks->size) return ksNew (0, KS_END);
	found = it;
	while (it < ks->size && keyIsBelowOrSame (cutpoint, ks->array[it]) == 1)
	{
		++it;
	}
	if (ks->current >= found && ks->current < it)
	{
		if (found == 0)
		{
			ksRewind (ks);
		}
		else
		{
			ks->current = found - 1;
			set_cursor = 1;
		}
	}
	if (ks->current >= it)
	{
		if (it >= ks->size)
		{
			ksRewind (ks);
		}
		else
		{
			ks->current = found + ks->current - it;
			set_cursor = 1;
		}
	}
	newsize = it - found;
	returned = ksNew (newsize, KS_END);
	elektraMemcpy (returned->array, ks->array + found, newsize);
	returned->size = newsize;
	returned->array[returned->size] = 0;
	ksCopyInternal (ks, found, it);
	if (set_cursor) ks->cursor = ks->array[ks->current];
	return returned;
}
KeySet * ksCut ( KeySet * ks , const Key * cutpoint ) { KeySet * returned = 0 ; size_t found = 0 ; size_t it = 0 ; size_t newsize = 0 ; int set_cursor = 0 ; if ( ! ks ) return 0 ; if ( ! cutpoint ) return 0 ; char * name = cutpoint -> key ; if ( ! name ) return 0 ; if ( name [ 0 ] == ' ' ) { Key * key = ( Key * ) cutpoint ; size_t size = key -> keySize ; size_t usize = key -> keyUSize ; size_t length = strlen ( name ) + ELEKTRA_MAX_NAMESPACE_SIZE ; char newname [ length * 2 ] ; KeySet * ret = ksNew ( 0 , KS_END ) ; for ( elektraNamespace ns = KEY_NS_FIRST ; ns <= KEY_NS_LAST ; ++ ns ) { int validNS = 1 ; switch ( ns ) { case KEY_NS_SPEC : strncpy ( newname + 2 , " " , 4 ) ; strcpy ( newname + 6 , name ) ; key -> key = newname + 2 ; key -> keySize = length - 2 ; if ( ! strcmp ( name , " " ) ) key -> keySize = 5 ; elektraFinalizeName ( key ) ; break ; case KEY_NS_PROC : strncpy ( newname + 2 , " " , 4 ) ; strcpy ( newname + 6 , name ) ; key -> key = newname + 2 ; key -> keySize = length - 2 ; if ( ! strcmp ( name , " " ) ) key -> keySize = 5 ; elektraFinalizeName ( key ) ; break ; case KEY_NS_DIR : strncpy ( newname + 3 , " " , 3 ) ; strcpy ( newname + 6 , name ) ; key -> key = newname + 3 ; key -> keySize = length - 3 ; if ( ! strcmp ( name , " " ) ) key -> keySize = 4 ; elektraFinalizeName ( key ) ; break ; case KEY_NS_USER : strncpy ( newname + 2 , " " , 4 ) ; strcpy ( newname + 6 , name ) ; key -> key = newname + 2 ; key -> keySize = length - 2 ; if ( ! strcmp ( name , " " ) ) key -> keySize = 5 ; elektraFinalizeName ( key ) ; break ; case KEY_NS_SYSTEM : strncpy ( newname , " " , 6 ) ; strcpy ( newname + 6 , name ) ; key -> key = newname ; key -> keySize = length ; if ( ! strcmp ( name , " " ) ) key -> keySize = 7 ; elektraFinalizeName ( key ) ; break ; case KEY_NS_EMPTY : case KEY_NS_NONE : case KEY_NS_META : case KEY_NS_CASCADING : validNS = 0 ; } if ( validNS ) { KeySet * n = ksCut ( ks , key ) ; ksAppend ( ret , n ) ; ksDel ( n ) ; } } key -> key = name ; key -> keySize = size ; key -> keyUSize = usize ; return ret ; } while ( it < ks -> size && keyIsBelowOrSame ( cutpoint , ks -> array [ it ] ) == 0 ) { ++ it ; } if ( it == ks -> size ) return ksNew ( 0 , KS_END ) ; found = it ; while ( it < ks -> size && keyIsBelowOrSame ( cutpoint , ks -> array [ it ] ) == 1 ) { ++ it ; } if ( ks -> current >= found && ks -> current < it ) { if ( found == 0 ) { ksRewind ( ks ) ; } else { ks -> current = found - 1 ; set_cursor = 1 ; } } if ( ks -> current >= it ) { if ( it >= ks -> size ) { ksRewind ( ks ) ; } else { ks -> current = found + ks -> current - it ; set_cursor = 1 ; } } newsize = it - found ; returned = ksNew ( newsize , KS_END ) ; elektraMemcpy ( returned -> array , ks -> array + found , newsize ) ; returned -> size = newsize ; returned -> array [ returned -> size ] = 0 ; ksCopyInternal ( ks , found , it ) ; if ( set_cursor ) ks -> cursor = ks -> array [ ks -> current ] ; return returned ; }
Cuts out a keyset at the cutpoint.
Cuts out a keyset at the cutpoint .
// if (strcmp(name, "")) return 0; // restore old cascading name // search the cutpoint // we found nothing // we found the cutpoint // search the end of the keyset to cut // correct cursor if cursor is in cutted keyset // correct the cursor for the keys after the cutted keyset