add new kvp glist function;

fix bug with how bags of guids are deleted


git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@9396 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Linas Vepstas 2003-09-21 23:04:42 +00:00
parent 0fe939e688
commit ef3cce26b8
4 changed files with 88 additions and 15 deletions

View File

@ -75,6 +75,13 @@ void gnc_kvp_gemini (KvpFrame *kvp_root, time_t secs,
const char *first_name, ...);
/** The gnc_kvp_bag_merge() routine will move the bag contents from
* the 'kvp_from', to the 'into' bag. It will then delete the
* 'from' bag from the kvp tree.
*/
void gnc_kvp_bag_merge (KvpFrame *kvp_into, const char *intopath,
KvpFrame *kvp_from, const char *frompath);
/** The gnc_kvp_bag_find_by_guid() routine examines the bag pointed
* located at root. It looks for a frame in that bag that has the
* guid value of "desired_guid" filed under the key name "guid_name".

View File

@ -133,16 +133,49 @@ gnc_kvp_bag_find_by_guid (KvpFrame *root, const char * path,
/* ================================================================ */
#define KILL_MATCH(elt) \
if (fr == kvp_value_get_frame (elt)) { \
KvpValue *old_val = kvp_frame_replace_value_nc (root, path, NULL); \
kvp_value_replace_frame_nc (old_val, NULL); \
kvp_value_delete (old_val); \
return; \
}
void
gnc_kvp_bag_remove_frame (KvpFrame *root, const char *path, KvpFrame *fr)
{
KvpValue *arr;
KvpValueType valtype;
GList *node, *listhead;
arr = kvp_frame_get_value (root, path);
valtype = kvp_value_get_type (arr);
if (KVP_TYPE_FRAME == valtype)
{
if (fr == kvp_value_get_frame (arr))
{
KvpValue *old_val = kvp_frame_replace_value_nc (root, path, NULL);
kvp_value_replace_frame_nc (old_val, NULL);
kvp_value_delete (old_val);
}
return;
}
/* Its gotta be a single isolated frame, or a list of them. */
if (KVP_TYPE_GLIST != valtype) return;
listhead = kvp_value_get_glist(arr);
for (node = listhead; node; node=node->next)
{
KvpValue *va = node->data;
if (fr == kvp_value_get_frame (va))
{
listhead = g_list_remove_link (listhead, node);
g_list_free_1 (node);
kvp_value_replace_glist_nc (va, listhead);
kvp_value_replace_frame_nc (va, NULL);
kvp_value_delete (va);
return;
}
}
}
/* ================================================================ */
static KvpFrame *
gnc_kvp_bag_get_first (KvpFrame *root, const char * path)
{
KvpValue *arr;
KvpValueType valtype;
@ -152,17 +185,31 @@ gnc_kvp_bag_remove_frame (KvpFrame *root, const char *path, KvpFrame *fr)
valtype = kvp_value_get_type (arr);
if (KVP_TYPE_FRAME == valtype)
{
KILL_MATCH (arr);
return;
return kvp_value_get_frame(arr);
}
/* Its gotta be a single isolated frame, or a list of them. */
if (KVP_TYPE_GLIST != valtype) return;
if (KVP_TYPE_GLIST != valtype) return NULL;
for (node = kvp_value_get_glist(arr); node; node=node->next)
node = kvp_value_get_glist(arr);
{
KvpValue *va = node->data;
KILL_MATCH (va);
return kvp_value_get_frame(va);
}
}
void
gnc_kvp_bag_merge (KvpFrame *kvp_into, const char *intopath,
KvpFrame *kvp_from, const char *frompath)
{
KvpFrame *fr;
fr = gnc_kvp_bag_get_first (kvp_from, frompath);
while (fr)
{
gnc_kvp_bag_remove_frame (kvp_from, frompath, fr);
kvp_frame_add_frame_nc (kvp_into, intopath, fr);
fr = gnc_kvp_bag_get_first (kvp_from, frompath);
}
}

View File

@ -72,7 +72,7 @@ struct _KvpValue
};
/* This static indicates the debugging module that this .o belongs to. */
static short module = MOD_ENGINE;
static short module = MOD_KVP;
/********************************************************************
* KvpFrame functions
@ -529,6 +529,7 @@ kvp_frame_add_value_nc(KvpFrame * frame, const char * path, KvpValue *value)
frame = (KvpFrame *) get_trailer_or_null (frame, path, &key);
oldvalue = kvp_frame_get_slot (frame, key);
ENTER ("old frame=%s", kvp_frame_to_string(frame));
if (oldvalue)
{
/* If already a glist here, just append */
@ -550,12 +551,14 @@ kvp_frame_add_value_nc(KvpFrame * frame, const char * path, KvpValue *value)
kvp_frame_replace_slot_nc (frame, key, klist);
}
LEAVE ("new frame=%s", kvp_frame_to_string(frame));
return frame;
}
/* Hmm, if we are here, the path doesn't exist. We need to
* create the path, add the value to it. */
frame = kvp_frame_set_value_nc (frame, path, value);
LEAVE ("new frame=%s", kvp_frame_to_string(frame));
return frame;
}
@ -1408,6 +1411,7 @@ KvpFrame *
kvp_value_replace_frame_nc(KvpValue *value, KvpFrame * newframe)
{
KvpFrame *oldframe;
if (!value) return NULL;
if (KVP_TYPE_FRAME != value->type) return NULL;
oldframe = value->value.frame;
@ -1415,6 +1419,18 @@ kvp_value_replace_frame_nc(KvpValue *value, KvpFrame * newframe)
return oldframe;
}
GList *
kvp_value_replace_glist_nc(KvpValue * value, GList *newlist)
{
GList *oldlist;
if (!value) return NULL;
if (KVP_TYPE_GLIST != value->type) return NULL;
oldlist = value->value.list;
value->value.list = newlist;
return oldlist;
}
/* manipulators */
KvpValue *

View File

@ -507,9 +507,12 @@ void kvp_value_delete(KvpValue * value);
/** This is a deep value copy. */
KvpValue * kvp_value_copy(const KvpValue * value);
/** replace old frame value with new, return old frame */
/** Replace old frame value with new, return old frame */
KvpFrame * kvp_value_replace_frame_nc(KvpValue *value, KvpFrame * newframe);
/** Replace old glist value with new, return old glist */
GList * kvp_value_replace_glist_nc(KvpValue *value, GList *newlist);
/*@}*/