mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
add kvp support for slash-separated keys for frame paths,
so now you can specify kvp paths /just/like/this a few additional routines added that use fewer mallocs/frees to poke data into kvp trees; account.c and transaction.c converted to use these routines (resulting in a few mem-leak fixes) git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@3637 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
parent
5c51a5f2ca
commit
eeb76cd05b
@ -1066,24 +1066,14 @@ xaccAccountSetDescription (Account *acc, const char *str) {
|
||||
}
|
||||
|
||||
void
|
||||
xaccAccountSetNotes (Account *acc, const char *str) {
|
||||
kvp_value *new_value;
|
||||
|
||||
xaccAccountSetNotes (Account *acc, const char *str)
|
||||
{
|
||||
if ((!acc) || (!str)) return;
|
||||
|
||||
xaccAccountBeginEdit(acc);
|
||||
{
|
||||
new_value = kvp_value_new_string(str);
|
||||
if(new_value) {
|
||||
kvp_frame_set_slot(xaccAccountGetSlots(acc), "notes", new_value);
|
||||
kvp_value_delete(new_value);
|
||||
}
|
||||
else {
|
||||
PERR ("failed to allocate kvp");
|
||||
}
|
||||
|
||||
mark_account (acc);
|
||||
}
|
||||
kvp_frame_set_slot_nc(acc->kvp_data, "notes",
|
||||
kvp_value_new_string(str));
|
||||
mark_account (acc);
|
||||
acc->core_dirty = TRUE;
|
||||
xaccAccountCommitEdit(acc);
|
||||
}
|
||||
@ -1344,11 +1334,12 @@ xaccAccountGetDescription (Account *acc)
|
||||
}
|
||||
|
||||
const char *
|
||||
xaccAccountGetNotes (Account *acc) {
|
||||
xaccAccountGetNotes (Account *acc)
|
||||
{
|
||||
kvp_value *v;
|
||||
|
||||
if (!acc) return NULL;
|
||||
v = kvp_frame_get_slot(xaccAccountGetSlots(acc), "notes");
|
||||
v = kvp_frame_get_slot(acc->kvp_data, "notes");
|
||||
if(v) return(kvp_value_get_string(v));
|
||||
return(NULL);
|
||||
}
|
||||
@ -1497,7 +1488,7 @@ xaccAccountGetTaxRelated (Account *account)
|
||||
if (!account)
|
||||
return FALSE;
|
||||
|
||||
kvp = kvp_frame_get_slot (xaccAccountGetSlots (account), "tax-related");
|
||||
kvp = kvp_frame_get_slot (account->kvp_data, "tax-related");
|
||||
if (!kvp)
|
||||
return FALSE;
|
||||
|
||||
@ -1518,15 +1509,9 @@ xaccAccountSetTaxRelated (Account *account, gboolean tax_related)
|
||||
new_value = NULL;
|
||||
|
||||
xaccAccountBeginEdit (account);
|
||||
{
|
||||
kvp_frame_set_slot(xaccAccountGetSlots (account),
|
||||
"tax-related", new_value);
|
||||
kvp_frame_set_slot_nc(account->kvp_data, "tax-related", new_value);
|
||||
|
||||
if (new_value)
|
||||
kvp_value_delete(new_value);
|
||||
|
||||
mark_account (account);
|
||||
}
|
||||
mark_account (account);
|
||||
account->core_dirty = TRUE;
|
||||
xaccAccountCommitEdit (account);
|
||||
}
|
||||
@ -1727,7 +1712,7 @@ xaccAccountGetReconcileLastDate (Account *account, time_t *last_date)
|
||||
if (!account)
|
||||
return FALSE;
|
||||
|
||||
value = kvp_frame_get_slot_path (xaccAccountGetSlots (account),
|
||||
value = kvp_frame_get_slot_path (account->kvp_data,
|
||||
"reconcile-info", "last-date", NULL);
|
||||
if (!value)
|
||||
return FALSE;
|
||||
@ -1745,30 +1730,27 @@ xaccAccountGetReconcileLastDate (Account *account, time_t *last_date)
|
||||
|
||||
/********************************************************************\
|
||||
\********************************************************************/
|
||||
|
||||
void
|
||||
xaccAccountSetReconcileLastDate (Account *account, time_t last_date)
|
||||
{
|
||||
kvp_frame *frame;
|
||||
if (!account)
|
||||
return;
|
||||
|
||||
xaccAccountBeginEdit (account);
|
||||
{
|
||||
kvp_value *value;
|
||||
value = kvp_value_new_gint64 (last_date);
|
||||
frame = kvp_frame_get_frame (account->kvp_data, "reconcile-info", NULL);
|
||||
kvp_frame_set_slot_nc (frame, "last-date",
|
||||
kvp_value_new_gint64 (last_date));
|
||||
|
||||
kvp_frame_set_slot_path (xaccAccountGetSlots (account), value,
|
||||
"reconcile-info", "last-date", NULL);
|
||||
|
||||
kvp_value_delete (value);
|
||||
|
||||
mark_account (account);
|
||||
}
|
||||
mark_account (account);
|
||||
account->core_dirty = TRUE;
|
||||
xaccAccountCommitEdit (account);
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
\********************************************************************/
|
||||
|
||||
gboolean
|
||||
xaccAccountGetReconcilePostponeDate (Account *account,
|
||||
time_t *postpone_date)
|
||||
@ -1778,7 +1760,7 @@ xaccAccountGetReconcilePostponeDate (Account *account,
|
||||
if (!account)
|
||||
return FALSE;
|
||||
|
||||
value = kvp_frame_get_slot_path (xaccAccountGetSlots (account),
|
||||
value = kvp_frame_get_slot_path (account->kvp_data,
|
||||
"reconcile-info", "postpone", "date", NULL);
|
||||
if (!value)
|
||||
return FALSE;
|
||||
@ -1796,32 +1778,30 @@ xaccAccountGetReconcilePostponeDate (Account *account,
|
||||
|
||||
/********************************************************************\
|
||||
\********************************************************************/
|
||||
|
||||
void
|
||||
xaccAccountSetReconcilePostponeDate (Account *account,
|
||||
time_t postpone_date)
|
||||
{
|
||||
kvp_frame *frame;
|
||||
if (!account)
|
||||
return;
|
||||
|
||||
xaccAccountBeginEdit (account);
|
||||
{
|
||||
kvp_value *value;
|
||||
frame = kvp_frame_get_frame (account->kvp_data,
|
||||
"reconcile-info", "postpone", NULL);
|
||||
|
||||
value = kvp_value_new_gint64 (postpone_date);
|
||||
kvp_frame_set_slot_nc (frame, "date",
|
||||
kvp_value_new_gint64 (postpone_date));
|
||||
|
||||
kvp_frame_set_slot_path (xaccAccountGetSlots (account), value,
|
||||
"reconcile-info", "postpone", "date", NULL);
|
||||
|
||||
kvp_value_delete (value);
|
||||
|
||||
mark_account (account);
|
||||
}
|
||||
mark_account (account);
|
||||
account->core_dirty = TRUE;
|
||||
xaccAccountCommitEdit (account);
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
\********************************************************************/
|
||||
|
||||
gboolean
|
||||
xaccAccountGetReconcilePostponeBalance (Account *account,
|
||||
gnc_numeric *balance)
|
||||
@ -1831,7 +1811,7 @@ xaccAccountGetReconcilePostponeBalance (Account *account,
|
||||
if (!account)
|
||||
return FALSE;
|
||||
|
||||
value = kvp_frame_get_slot_path (xaccAccountGetSlots (account),
|
||||
value = kvp_frame_get_slot_path (account->kvp_data,
|
||||
"reconcile-info", "postpone", "balance",
|
||||
NULL);
|
||||
if (!value)
|
||||
@ -1850,32 +1830,31 @@ xaccAccountGetReconcilePostponeBalance (Account *account,
|
||||
|
||||
/********************************************************************\
|
||||
\********************************************************************/
|
||||
|
||||
void
|
||||
xaccAccountSetReconcilePostponeBalance (Account *account,
|
||||
gnc_numeric balance)
|
||||
{
|
||||
kvp_frame *frame;
|
||||
if (!account)
|
||||
return;
|
||||
|
||||
xaccAccountBeginEdit (account);
|
||||
{
|
||||
kvp_value *value;
|
||||
frame = kvp_frame_get_frame (account->kvp_data,
|
||||
"reconcile-info", "postpone", NULL);
|
||||
|
||||
value = kvp_value_new_gnc_numeric (balance);
|
||||
kvp_frame_set_slot_nc (frame, "balance",
|
||||
kvp_value_new_gnc_numeric (balance));
|
||||
|
||||
kvp_frame_set_slot_path (xaccAccountGetSlots (account), value,
|
||||
"reconcile-info", "postpone", "balance", NULL);
|
||||
|
||||
kvp_value_delete (value);
|
||||
|
||||
mark_account (account);
|
||||
}
|
||||
mark_account (account);
|
||||
account->core_dirty = TRUE;
|
||||
xaccAccountCommitEdit (account);
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
|
||||
\********************************************************************/
|
||||
|
||||
void
|
||||
xaccAccountClearReconcilePostpone (Account *account)
|
||||
{
|
||||
@ -1884,7 +1863,7 @@ xaccAccountClearReconcilePostpone (Account *account)
|
||||
|
||||
xaccAccountBeginEdit (account);
|
||||
{
|
||||
kvp_frame_set_slot_path (xaccAccountGetSlots (account), NULL,
|
||||
kvp_frame_set_slot_path (account->kvp_data, NULL,
|
||||
"reconcile-info", "postpone", NULL);
|
||||
|
||||
mark_account (account);
|
||||
@ -1895,6 +1874,7 @@ xaccAccountClearReconcilePostpone (Account *account)
|
||||
|
||||
/********************************************************************\
|
||||
\********************************************************************/
|
||||
|
||||
const char *
|
||||
xaccAccountGetLastNum (Account *account)
|
||||
{
|
||||
@ -1903,7 +1883,7 @@ xaccAccountGetLastNum (Account *account)
|
||||
if (!account)
|
||||
return FALSE;
|
||||
|
||||
value = kvp_frame_get_slot (xaccAccountGetSlots (account), "last-num");
|
||||
value = kvp_frame_get_slot (account->kvp_data, "last-num");
|
||||
if (!value)
|
||||
return FALSE;
|
||||
|
||||
@ -1912,6 +1892,7 @@ xaccAccountGetLastNum (Account *account)
|
||||
|
||||
/********************************************************************\
|
||||
\********************************************************************/
|
||||
|
||||
void
|
||||
xaccAccountSetLastNum (Account *account, const char *num)
|
||||
{
|
||||
@ -1919,25 +1900,19 @@ xaccAccountSetLastNum (Account *account, const char *num)
|
||||
return;
|
||||
|
||||
xaccAccountBeginEdit (account);
|
||||
{
|
||||
kvp_value *value;
|
||||
|
||||
value = kvp_value_new_string (num);
|
||||
|
||||
kvp_frame_set_slot (xaccAccountGetSlots (account), "last-num", value);
|
||||
|
||||
kvp_value_delete (value);
|
||||
|
||||
mark_account (account);
|
||||
}
|
||||
kvp_frame_set_slot_nc (account->kvp_data, "last-num",
|
||||
kvp_value_new_string (num));
|
||||
mark_account (account);
|
||||
account->core_dirty = TRUE;
|
||||
xaccAccountCommitEdit (account);
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
\********************************************************************/
|
||||
|
||||
void
|
||||
xaccAccountSetPriceSrc(Account *acc, const char *src) {
|
||||
xaccAccountSetPriceSrc(Account *acc, const char *src)
|
||||
{
|
||||
|
||||
if(!acc) return;
|
||||
if(!src) return;
|
||||
@ -1947,16 +1922,10 @@ xaccAccountSetPriceSrc(Account *acc, const char *src) {
|
||||
GNCAccountType t = xaccAccountGetType(acc);
|
||||
|
||||
if((t == STOCK) || (t == MUTUAL)) {
|
||||
kvp_value *new_value = kvp_value_new_string(src);
|
||||
if(new_value) {
|
||||
kvp_frame_set_slot(xaccAccountGetSlots(acc),
|
||||
kvp_frame_set_slot_nc(acc->kvp_data,
|
||||
"old-price-source",
|
||||
new_value);
|
||||
kvp_value_delete(new_value);
|
||||
mark_account (acc);
|
||||
} else {
|
||||
PERR ("xaccAccountSetPriceSrc: failed to allocate kvp_value.");
|
||||
}
|
||||
kvp_value_new_string(src));
|
||||
mark_account (acc);
|
||||
}
|
||||
}
|
||||
acc->core_dirty = TRUE;
|
||||
@ -1967,22 +1936,19 @@ xaccAccountSetPriceSrc(Account *acc, const char *src) {
|
||||
\********************************************************************/
|
||||
|
||||
const char*
|
||||
xaccAccountGetPriceSrc(Account *acc) {
|
||||
const char *result = NULL;
|
||||
xaccAccountGetPriceSrc(Account *acc)
|
||||
{
|
||||
GNCAccountType t;
|
||||
if(!acc) return NULL;
|
||||
|
||||
if(!acc) {
|
||||
result = NULL;
|
||||
} else {
|
||||
GNCAccountType t = xaccAccountGetType(acc);
|
||||
if((t == STOCK) || (t == MUTUAL)) {
|
||||
kvp_value *value = kvp_frame_get_slot(xaccAccountGetSlots(acc),
|
||||
t = xaccAccountGetType(acc);
|
||||
if((t == STOCK) || (t == MUTUAL))
|
||||
{
|
||||
kvp_value *value = kvp_frame_get_slot(acc->kvp_data,
|
||||
"old-price-source");
|
||||
if(value) {
|
||||
result = kvp_value_get_string(value);
|
||||
}
|
||||
}
|
||||
if(value) return (kvp_value_get_string(value));
|
||||
}
|
||||
return(result);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
|
@ -1917,23 +1917,12 @@ xaccTransSetDescription (Transaction *trans, const char *desc)
|
||||
void
|
||||
xaccTransSetNotes (Transaction *trans, const char *notes)
|
||||
{
|
||||
kvp_value *new_value;
|
||||
|
||||
if (!trans || !notes) return;
|
||||
check_open (trans);
|
||||
|
||||
new_value = kvp_value_new_string (notes);
|
||||
|
||||
if (new_value)
|
||||
{
|
||||
kvp_frame_set_slot (xaccTransGetSlots (trans), "notes", new_value);
|
||||
kvp_value_delete (new_value);
|
||||
mark_trans (trans);
|
||||
}
|
||||
else
|
||||
{
|
||||
PERR ("failed to allocate kvp");
|
||||
}
|
||||
kvp_frame_set_slot_nc (trans->kvp_data, "notes",
|
||||
kvp_value_new_string (notes));
|
||||
mark_trans (trans);
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
@ -2226,11 +2215,10 @@ xaccSplitGetType(const Split *s)
|
||||
void
|
||||
xaccSplitMakeStockSplit(Split *s)
|
||||
{
|
||||
kvp_frame *frame = xaccSplitGetSlots(s);
|
||||
check_open (s->parent);
|
||||
|
||||
xaccSplitSetValue(s, gnc_numeric_zero());
|
||||
kvp_frame_set_slot(frame,
|
||||
kvp_frame_set_slot_nc(s->kvp_data,
|
||||
"split-type",
|
||||
kvp_value_new_string("stock-split"));
|
||||
mark_split(s);
|
||||
|
@ -88,14 +88,11 @@ back_associate_expense_accounts(Account *stock_account,
|
||||
|
||||
g_return_if_fail(xaccGUIDType(existing_acc_guid) == GNC_ID_NONE);
|
||||
|
||||
kvp_frame_set_slot(acc_frame, "associated-stock-account",
|
||||
kvp_frame_set_slot_nc(acc_frame, "associated-stock-account",
|
||||
stock_acc_guid_kvpval);
|
||||
|
||||
kvp_value_delete(stock_acc_guid_kvpval);
|
||||
|
||||
kvp_frame_set_slot(acc_frame, "associated-stock-account-category",
|
||||
kvp_frame_set_slot_nc(acc_frame, "associated-stock-account-category",
|
||||
stock_acc_category_kvpval);
|
||||
kvp_value_delete(stock_acc_category_kvpval);
|
||||
}
|
||||
|
||||
return;
|
||||
@ -124,12 +121,10 @@ back_associate_income_accounts(Account *stock_account,
|
||||
|
||||
g_return_if_fail(xaccGUIDType(existing_acc_guid) == GNC_ID_NONE);
|
||||
|
||||
kvp_frame_set_slot(acc_frame, "associated-stock-account",
|
||||
kvp_frame_set_slot_nc(acc_frame, "associated-stock-account",
|
||||
stock_acc_guid_kvpval);
|
||||
kvp_value_delete(stock_acc_guid_kvpval);
|
||||
kvp_frame_set_slot(acc_frame, "associated-stock-account-category",
|
||||
kvp_frame_set_slot_nc(acc_frame, "associated-stock-account-category",
|
||||
stock_acc_category_kvpval);
|
||||
kvp_value_delete(stock_acc_category_kvpval);
|
||||
}
|
||||
|
||||
return;
|
||||
@ -221,12 +216,9 @@ gnc_tracking_associate_income_accounts(Account *stock_account,
|
||||
|
||||
back_associate_income_accounts(stock_account, account_list, category);
|
||||
|
||||
kvp_frame_set_slot(inc_account_frame,
|
||||
kvp_frame_set_slot_nc(inc_account_frame,
|
||||
income_to_key[category],
|
||||
kvpd_on_account_list);
|
||||
|
||||
kvp_value_delete(kvpd_on_account_list);
|
||||
return;
|
||||
}
|
||||
|
||||
/*********************************************************************\
|
||||
@ -265,11 +257,9 @@ void gnc_tracking_asssociate_expense_account(Account *stock_account,
|
||||
|
||||
back_associate_expense_accounts(stock_account, account_list, category);
|
||||
|
||||
kvp_frame_set_slot(expense_acc_frame,
|
||||
kvp_frame_set_slot_nc(expense_acc_frame,
|
||||
expense_to_key[category],
|
||||
kvpd_on_account_list);
|
||||
kvp_value_delete(kvpd_on_account_list);
|
||||
return;
|
||||
}
|
||||
|
||||
/*********************************************************************\
|
||||
@ -285,7 +275,7 @@ void gnc_tracking_asssociate_expense_account(Account *stock_account,
|
||||
\*********************************************************************/
|
||||
|
||||
GList *gnc_tracking_find_expense_accounts(Account *stock_account,
|
||||
GNCTrackingExpenseCategory category)
|
||||
GNCTrackingExpenseCategory category)
|
||||
{
|
||||
|
||||
GNCAccountType type;
|
||||
@ -462,10 +452,9 @@ gnc_tracking_dissociate_account(Account *inc_or_expense_account)
|
||||
assoc_acc_list_start = g_list_remove_link(assoc_acc_list_start, assoc_acc_list);
|
||||
g_list_free_1(assoc_acc_list);
|
||||
acc_list_kvpval = kvp_value_new_glist_nc(assoc_acc_list);
|
||||
kvp_frame_set_slot(assoc_acc_kvpframe,
|
||||
kvp_frame_set_slot_nc(assoc_acc_kvpframe,
|
||||
category_name,
|
||||
acc_list_kvpval);
|
||||
kvp_value_delete(acc_list_kvpval);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -473,11 +462,4 @@ gnc_tracking_dissociate_account(Account *inc_or_expense_account)
|
||||
PERR("Income/Expense account and stock account disagree on association");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* ========================== END OF FILE ===================== */
|
||||
|
@ -907,8 +907,7 @@ readTransaction( int fd, Account *acc, int token )
|
||||
free(tmp);
|
||||
return(NULL);
|
||||
}
|
||||
kvp_frame_set_slot(xaccTransGetSlots(trans), "old-docref", new_value);
|
||||
kvp_value_delete(new_value);
|
||||
kvp_frame_set_slot_nc(xaccTransGetSlots(trans), "old-docref", new_value);
|
||||
}
|
||||
free (tmp);
|
||||
}
|
||||
@ -1252,8 +1251,7 @@ readSplit ( int fd, int token )
|
||||
free(tmp);
|
||||
return(NULL);
|
||||
}
|
||||
kvp_frame_set_slot(xaccSplitGetSlots(split), "old-docref", new_value);
|
||||
kvp_value_delete(new_value);
|
||||
kvp_frame_set_slot_nc(xaccSplitGetSlots(split), "old-docref", new_value);
|
||||
}
|
||||
free (tmp);
|
||||
}
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <glib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@ -185,6 +186,17 @@ kvp_frame_set_slot(kvp_frame * frame, const char * slot,
|
||||
kvp_frame_set_slot_destructively(frame, slot, new_value);
|
||||
}
|
||||
|
||||
void
|
||||
kvp_frame_set_slot_nc(kvp_frame * frame, const char * slot,
|
||||
kvp_value * value) {
|
||||
/* FIXME: no way to indicate errors... */
|
||||
|
||||
if (!frame)
|
||||
return;
|
||||
|
||||
kvp_frame_set_slot_destructively(frame, slot, value);
|
||||
}
|
||||
|
||||
kvp_value *
|
||||
kvp_frame_get_slot(kvp_frame * frame, const char * slot) {
|
||||
if (!frame)
|
||||
@ -193,6 +205,8 @@ kvp_frame_get_slot(kvp_frame * frame, const char * slot) {
|
||||
return (kvp_value *)g_hash_table_lookup(frame->hash, slot);
|
||||
}
|
||||
|
||||
/* ============================================================ */
|
||||
|
||||
void
|
||||
kvp_frame_set_slot_path (kvp_frame *frame,
|
||||
const kvp_value *new_value,
|
||||
@ -222,10 +236,7 @@ kvp_frame_set_slot_path (kvp_frame *frame,
|
||||
kvp_frame *new_frame = kvp_frame_new ();
|
||||
kvp_value *frame_value = kvp_value_new_frame (new_frame);
|
||||
|
||||
kvp_frame_set_slot (frame, key, frame_value);
|
||||
|
||||
kvp_value_delete (frame_value);
|
||||
kvp_frame_delete (new_frame);
|
||||
kvp_frame_set_slot_nc (frame, key, frame_value);
|
||||
|
||||
value = kvp_frame_get_slot (frame, key);
|
||||
if (!value)
|
||||
@ -267,10 +278,7 @@ kvp_frame_set_slot_path_gslist (kvp_frame *frame,
|
||||
kvp_frame *new_frame = kvp_frame_new ();
|
||||
kvp_value *frame_value = kvp_value_new_frame (new_frame);
|
||||
|
||||
kvp_frame_set_slot (frame, key, frame_value);
|
||||
|
||||
kvp_value_delete (frame_value);
|
||||
kvp_frame_delete (new_frame);
|
||||
kvp_frame_set_slot_nc (frame, key, frame_value);
|
||||
|
||||
value = kvp_frame_get_slot (frame, key);
|
||||
if (!value)
|
||||
@ -283,6 +291,130 @@ kvp_frame_set_slot_path_gslist (kvp_frame *frame,
|
||||
}
|
||||
}
|
||||
|
||||
/* ============================================================ */
|
||||
|
||||
kvp_frame *
|
||||
kvp_frame_get_frame (kvp_frame *frame, const char *first_key, ...)
|
||||
{
|
||||
va_list ap;
|
||||
const char *key;
|
||||
|
||||
if (!frame || !first_key)
|
||||
return frame;
|
||||
|
||||
va_start (ap, first_key);
|
||||
|
||||
key = first_key;
|
||||
|
||||
while (TRUE) {
|
||||
kvp_value *value;
|
||||
|
||||
/* get the frame assoc with key, or create it if needed */
|
||||
value = kvp_frame_get_slot (frame, key);
|
||||
if (!value) {
|
||||
kvp_frame *new_frame = kvp_frame_new ();
|
||||
kvp_value *frame_value = kvp_value_new_frame (new_frame);
|
||||
|
||||
kvp_frame_set_slot_nc (frame, key, frame_value);
|
||||
|
||||
value = kvp_frame_get_slot (frame, key);
|
||||
if (!value)
|
||||
break; /* error, should never occur */
|
||||
}
|
||||
|
||||
frame = kvp_value_get_frame (value);
|
||||
if (!frame)
|
||||
break; /* error, should never occur */
|
||||
|
||||
key = va_arg (ap, const char *);
|
||||
if (!key) {
|
||||
break; /* the normal exit to this routine. */
|
||||
}
|
||||
}
|
||||
|
||||
va_end (ap);
|
||||
return frame;
|
||||
}
|
||||
|
||||
|
||||
kvp_frame *
|
||||
kvp_frame_get_frame_gslist (kvp_frame *frame, GSList *key_path)
|
||||
{
|
||||
if (!frame || !key_path)
|
||||
return frame;
|
||||
|
||||
while (TRUE) {
|
||||
const char *key = key_path->data;
|
||||
kvp_value *value;
|
||||
|
||||
if (!key)
|
||||
return frame; /* an unusual but valid exit for this routine. */
|
||||
|
||||
/* get the named frame, or create it if it doesn't exist */
|
||||
value = kvp_frame_get_slot (frame, key);
|
||||
if (!value) {
|
||||
kvp_frame *new_frame = kvp_frame_new ();
|
||||
kvp_value *frame_value = kvp_value_new_frame (new_frame);
|
||||
|
||||
kvp_frame_set_slot_nc (frame, key, frame_value);
|
||||
|
||||
value = kvp_frame_get_slot (frame, key);
|
||||
if (!value)
|
||||
return frame; /* this should never happen */
|
||||
}
|
||||
|
||||
frame = kvp_value_get_frame (value);
|
||||
if (!frame)
|
||||
return NULL; /* this should never happen */
|
||||
|
||||
key_path = key_path->next;
|
||||
if (!key_path) {
|
||||
return frame; /* this is the normal exit for this func */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
kvp_frame *
|
||||
kvp_frame_get_frame_slash (kvp_frame *frame, const char *key_path)
|
||||
{
|
||||
char *root, *key, *next;
|
||||
if (!frame || !key_path)
|
||||
return frame;
|
||||
|
||||
root = g_strdup (key_path);
|
||||
key = root;
|
||||
key --;
|
||||
|
||||
while (key) {
|
||||
kvp_value *value;
|
||||
|
||||
key ++;
|
||||
while ('/' == *key) { key++; }
|
||||
if (0x0 == *key) break; /* trailing slash */
|
||||
next = strchr (key, '/');
|
||||
if (next) *next = 0x0;
|
||||
|
||||
value = kvp_frame_get_slot (frame, key);
|
||||
if (!value) {
|
||||
kvp_frame *new_frame = kvp_frame_new ();
|
||||
kvp_value *frame_value = kvp_value_new_frame (new_frame);
|
||||
|
||||
kvp_frame_set_slot_nc (frame, key, frame_value);
|
||||
value = kvp_frame_get_slot (frame, key);
|
||||
if (!value) break; /* error - should never happen */
|
||||
}
|
||||
|
||||
frame = kvp_value_get_frame (value);
|
||||
if (!frame) break; /* error - should never happen */
|
||||
|
||||
key = next;
|
||||
}
|
||||
g_free(root);
|
||||
return frame;
|
||||
}
|
||||
|
||||
/* ============================================================ */
|
||||
|
||||
kvp_value *
|
||||
kvp_frame_get_slot_path (kvp_frame *frame,
|
||||
const char *first_key, ...) {
|
||||
|
@ -39,7 +39,8 @@
|
||||
* owned by the kvp_frame. Make copies as needed.
|
||||
*
|
||||
* kvp_frame_delete and kvp_value_delete are deep (recursive) deletes.
|
||||
* kvp_frame_copy and kvp_value_copy are deep value copies. */
|
||||
* kvp_frame_copy and kvp_value_copy are deep value copies.
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
KVP_TYPE_GINT64,
|
||||
@ -53,22 +54,31 @@ typedef enum {
|
||||
} kvp_value_t;
|
||||
|
||||
typedef struct _kvp_frame kvp_frame;
|
||||
|
||||
#if 0
|
||||
typedef union _kvp_value kvp_value;
|
||||
#else
|
||||
typedef struct _kvp_value kvp_value;
|
||||
#endif
|
||||
|
||||
|
||||
/* kvp_frame functions */
|
||||
kvp_frame * kvp_frame_new(void);
|
||||
void kvp_frame_delete(kvp_frame * frame);
|
||||
kvp_frame * kvp_frame_copy(const kvp_frame * frame);
|
||||
|
||||
/* The kvp_frame_set_slot() routine copies the value into the frame,
|
||||
* associating it with 'key'.
|
||||
* The kvp_frame_set_slot_nc() routine puts the value (without copying
|
||||
* it) into the frame, associating it with 'key'. This routine is
|
||||
* handy for aviding excess memory allocations & frees.
|
||||
*/
|
||||
void kvp_frame_set_slot(kvp_frame * frame,
|
||||
const char * key, const kvp_value * value);
|
||||
void kvp_frame_set_slot_nc(kvp_frame * frame,
|
||||
const char * key, kvp_value * value);
|
||||
kvp_value * kvp_frame_get_slot(kvp_frame * frame,
|
||||
const char * key);
|
||||
|
||||
/* The kvp_frame_set_slot_path() routines walk the heirarchy,
|
||||
* using the key falues to pick each branch. When the terminal node
|
||||
* is reached, the value is copied into it.
|
||||
*/
|
||||
void kvp_frame_set_slot_path (kvp_frame *frame,
|
||||
const kvp_value *value,
|
||||
const char *first_key, ...);
|
||||
@ -77,6 +87,30 @@ void kvp_frame_set_slot_path_gslist (kvp_frame *frame,
|
||||
const kvp_value *value,
|
||||
GSList *key_path);
|
||||
|
||||
/* The following routines return the last frame of the path.
|
||||
* If the frame path doesn't exist, it is created.
|
||||
*
|
||||
* The kvp_frame_get_frame_slash() routine takes a single string
|
||||
* where the keys are separated by slashes; thus, for example:
|
||||
* /this/is/a/valid/path and///so//is////this/
|
||||
* Multiple slashes are compresed. leading slash is optional.
|
||||
* The pointers . and .. are *not* followed/obeyed. (This is
|
||||
* arguably a bug that needs fixing).
|
||||
*
|
||||
*
|
||||
*/
|
||||
kvp_frame * kvp_frame_get_frame (kvp_frame *frame,
|
||||
const char *first_key, ...);
|
||||
|
||||
kvp_frame * kvp_frame_get_frame_gslist (kvp_frame *frame,
|
||||
GSList *key_path);
|
||||
|
||||
kvp_frame * kvp_frame_get_frame_slash (kvp_frame *frame,
|
||||
const char *path);
|
||||
|
||||
/* The following routines return the value att the end of the
|
||||
* path, or NULL if any portion of the path doesn't exist.
|
||||
*/
|
||||
kvp_value * kvp_frame_get_slot_path (kvp_frame *frame,
|
||||
const char *first_key, ...);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user