src/libs/elektra/keyset.c
/**
 * Appends a Key to the end of @p ks.
 *
 * Will take ownership of the key @p toAppend.
 * That means ksDel(ks) will remove the key unless
 * the key:
 * - was duplicated before inserting
 * - got its refcount incremented by keyIncRef() before inserting
 * - was also inserted into another keyset with ksAppendKey()
 *
 * The reference counter of the key will be incremented
 * to show this ownership, and thus @p toAppend is not const.
 *
 * @copydetails doxygenFlatCopy
 *
 * @see keyGetRef().
 *
 * If the keyname already existed in the keyset, it will be replaced with
 * the new key.
 *
 * The KeySet internal cursor will be set to the new key.
 *
 * It is save to directly append newly created keys:
 * @snippet keyset.c simple append
 *
 * If you want the key to outlive the keyset, make sure to
 * do proper ref counting:
 * @snippet keyset.c ref append
 *
 * Or if you want to avoid aliasing at all, you can duplicate the key.
 * But then key in the keyset has another identity:
 * @snippet keyset.c dup append
 *
 *
 * @return the size of the KeySet after insertion
 * @retval -1 on NULL pointers
 * @retval -1 if insertion failed, the key will be deleted then.
 * @param ks KeySet that will receive the key
 * @param toAppend Key that will be appended to ks or deleted
 * @see ksAppend(), keyNew(), ksDel()
 * @see keyIncRef()
 *
 */
Appends a Key to the end of @p ks.
Will take ownership of the key @p toAppend.
That means ksDel(ks) will remove the key unless
the key:
- was duplicated before inserting
- got its refcount incremented by keyIncRef() before inserting
- was also inserted into another keyset with ksAppendKey()

The reference counter of the key will be incremented
to show this ownership, and thus @p toAppend is not const.





If the keyname already existed in the keyset, it will be replaced with
the new key.

The KeySet internal cursor will be set to the new key.

It is save to directly append newly created keys:
@snippet keyset.c simple append

If you want the key to outlive the keyset, make sure to
do proper ref counting:
@snippet keyset.c ref append

Or if you want to avoid aliasing at all, you can duplicate the key.
But then key in the keyset has another identity:
@snippet keyset.c dup append

@return the size of the KeySet after insertion
@retval -1 on NULL pointers
@retval -1 if insertion failed, the key will be deleted then.
@param ks KeySet that will receive the key
@param toAppend Key that will be appended to ks or deleted
@see ksAppend(), keyNew(), ksDel()
@see keyIncRef()
Appends a Key to the end of @p ks . Will take ownership of the key @p toAppend . That means ksDel ( ks ) will remove the key unless the key : - was duplicated before inserting - got its refcount incremented by keyIncRef () before inserting - was also inserted into another keyset with ksAppendKey () The reference counter of the key will be incremented to show this ownership and thus @p toAppend is not const . If the keyname already existed in the keyset it will be replaced with the new key . The KeySet internal cursor will be set to the new key . It is save to directly append newly created keys : @snippet keyset . c simple append If you want the key to outlive the keyset make sure to do proper ref counting : @snippet keyset . c ref append Or if you want to avoid aliasing at all you can duplicate the key . But then key in the keyset has another identity : @snippet keyset . c dup append @return the size of the KeySet after insertion @retval - 1 on NULL pointers @retval - 1 if insertion failed the key will be deleted then . @param ks KeySet that will receive the key @param toAppend Key that will be appended to ks or deleted @see ksAppend () keyNew () ksDel () @see keyIncRef ()
ssize_t ksAppendKey (KeySet * ks, Key * toAppend)
{
	ssize_t result = -1;
	if (!ks) return -1;
	if (!toAppend) return -1;
	if (!toAppend->key)
	{
		keyDel (toAppend);
		return -1;
	}
	elektraKeyLock (toAppend, KEY_LOCK_NAME);
	result = ksSearchInternal (ks, toAppend);
	if (result >= 0)
	{
		if (toAppend == ks->array[result])
		{
			return ks->size;
		}
		keyDecRef (ks->array[result]);
		keyDel (ks->array[result]);
		keyIncRef (toAppend);
		ks->array[result] = toAppend;
		ksSetCursor (ks, result);
	}
	else
	{
		ssize_t insertpos = -result - 1;
		++ks->size;
		if (ks->size >= ks->alloc) ksResize (ks, ks->alloc * 2 - 1);
		keyIncRef (toAppend);
		if (insertpos == (ssize_t)ks->size - 1)
		{
			ks->array[ks->size - 1] = toAppend;
			ks->array[ks->size] = 0;
			ksSetCursor (ks, ks->size - 1);
		}
		else
		{
			size_t n = ks->size - insertpos;
			memmove (ks->array + (insertpos + 1), ks->array + insertpos, n * sizeof (struct Key *));
			ks->array[insertpos] = toAppend;
			ksSetCursor (ks, insertpos);
		}
	}
	return ks->size;
}
ssize_t ksAppendKey ( KeySet * ks , Key * toAppend ) { ssize_t result = -1 ; if ( ! ks ) return -1 ; if ( ! toAppend ) return -1 ; if ( ! toAppend -> key ) { keyDel ( toAppend ) ; return -1 ; } elektraKeyLock ( toAppend , KEY_LOCK_NAME ) ; result = ksSearchInternal ( ks , toAppend ) ; if ( result >= 0 ) { if ( toAppend == ks -> array [ result ] ) { return ks -> size ; } keyDecRef ( ks -> array [ result ] ) ; keyDel ( ks -> array [ result ] ) ; keyIncRef ( toAppend ) ; ks -> array [ result ] = toAppend ; ksSetCursor ( ks , result ) ; } else { ssize_t insertpos = - result - 1 ; ++ ks -> size ; if ( ks -> size >= ks -> alloc ) ksResize ( ks , ks -> alloc * 2 - 1 ) ; keyIncRef ( toAppend ) ; if ( insertpos == ( ssize_t ) ks -> size - 1 ) { ks -> array [ ks -> size - 1 ] = toAppend ; ks -> array [ ks -> size ] = 0 ; ksSetCursor ( ks , ks -> size - 1 ) ; } else { size_t n = ks -> size - insertpos ; memmove ( ks -> array + ( insertpos + 1 ) , ks -> array + insertpos , n * sizeof ( struct Key * ) ) ; ks -> array [ insertpos ] = toAppend ; ksSetCursor ( ks , insertpos ) ; } } return ks -> size ; }
Appends a Key to the end of @p ks.
Appends a Key to the end of @p ks .
// needed for ksAppendKey(ks, keyNew(0)) /* Seems like the key already exist. */ /* user tried to insert the same key again */ /* Pop the key in the result */ /* And use the other one instead */ /* We want to append a new key
		  in position insertpos */ /* Append it to the very end */ /*
			printf ("memmove -- ks->size: %zd insertpos: %zd n: %zd\n",
				ks->size, insertpos, n);
			*/