From 32d4fff3669041d83ccf614c24902070caab9132 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Thu, 7 May 2015 16:12:54 -0700 Subject: [PATCH 01/54] Implement KVP_TYPE_BOOLEAN In terms of KVP_TYPE_STRING such that TRUE->"true" and FALSE->NULL. This provides compatibility with the existing boolean KVP in Account.c. --- src/libqof/qof/kvp_frame.cpp | 167 ++++++++++++++++++++--------------- src/libqof/qof/kvp_frame.h | 5 +- 2 files changed, 99 insertions(+), 73 deletions(-) diff --git a/src/libqof/qof/kvp_frame.cpp b/src/libqof/qof/kvp_frame.cpp index 4ba546e265..b2b4683fb5 100644 --- a/src/libqof/qof/kvp_frame.cpp +++ b/src/libqof/qof/kvp_frame.cpp @@ -932,6 +932,13 @@ kvp_value_new_double(double value) return new KvpValueImpl{value}; } +KvpValue * +kvp_value_new_boolean(gboolean value) +{ + if (!value) return {}; + return new KvpValueImpl{g_strdup("true")}; +} + KvpValue * kvp_value_new_numeric(gnc_numeric value) { @@ -1024,6 +1031,15 @@ kvp_value_get_double(const KvpValue * ovalue) return value->get(); } +bool +kvp_value_get_boolean (const KvpValue *ovalue) +{ + if (!ovalue) return {}; + const KvpValueImpl *value {static_cast(ovalue)}; + const char* str = value->get(); + return str && strcmp(str, "true") == 0; +} + gnc_numeric kvp_value_get_numeric(const KvpValue * ovalue) { @@ -1186,7 +1202,7 @@ gvalue_list_from_kvp_value (KvpValue *kval, gpointer pList) GValue *gval = gvalue_from_kvp_value (kval); gvlist = (GList**)pList; if (G_VALUE_TYPE (gval)) - *gvlist = g_list_prepend (*gvlist, gval); + *gvlist = g_list_prepend (*gvlist, gval); } static void @@ -1195,7 +1211,7 @@ kvp_value_list_from_gvalue (GValue *gval, gpointer pList) GList **kvplist = (GList**)pList; KvpValue *kvp; if (!(gval && G_VALUE_TYPE (gval))) - return; + return; kvp = kvp_value_from_gvalue (gval); *kvplist = g_list_prepend (*kvplist, kvp); } @@ -1213,55 +1229,59 @@ gvalue_from_kvp_value (KvpValue *kval) switch (kvp_value_get_type(kval)) { - case KVP_TYPE_GINT64: - g_value_init (val, G_TYPE_INT64); - g_value_set_int64 (val, kvp_value_get_gint64 (kval)); - break; - case KVP_TYPE_DOUBLE: - g_value_init (val, G_TYPE_DOUBLE); - g_value_set_double (val, kvp_value_get_double (kval)); - break; - case KVP_TYPE_NUMERIC: - g_value_init (val, GNC_TYPE_NUMERIC); - num = kvp_value_get_numeric (kval); - g_value_set_boxed (val, &num); - break; - case KVP_TYPE_STRING: - g_value_init (val, G_TYPE_STRING); - g_value_set_string (val, kvp_value_get_string (kval)); - break; - case KVP_TYPE_GUID: - g_value_init (val, GNC_TYPE_GUID); - g_value_set_boxed (val, kvp_value_get_guid (kval)); - break; - case KVP_TYPE_TIMESPEC: - g_value_init (val, GNC_TYPE_TIMESPEC); - tm = kvp_value_get_timespec (kval); - g_value_set_boxed (val, &tm); - break; - case KVP_TYPE_GDATE: - g_value_init (val, G_TYPE_DATE); - gdate = kvp_value_get_gdate (kval); - g_value_set_boxed (val, &gdate); - break; - case KVP_TYPE_GLIST: - { - GList *gvalue_list = NULL; - GList *kvp_list = kvp_value_get_glist (kval); - g_list_foreach (kvp_list, (GFunc)gvalue_list_from_kvp_value, &gvalue_list); - g_value_init (val, GNC_TYPE_VALUE_LIST); - gvalue_list = g_list_reverse (gvalue_list); - g_value_set_boxed (val, gvalue_list); - break; - } + case KVP_TYPE_GINT64: + g_value_init (val, G_TYPE_INT64); + g_value_set_int64 (val, kvp_value_get_gint64 (kval)); + break; + case KVP_TYPE_DOUBLE: + g_value_init (val, G_TYPE_DOUBLE); + g_value_set_double (val, kvp_value_get_double (kval)); + break; + case KVP_TYPE_BOOLEAN: + g_value_init (val, G_TYPE_BOOLEAN); + g_value_set_boolean (val, kvp_value_get_boolean (kval)); + break; + case KVP_TYPE_NUMERIC: + g_value_init (val, GNC_TYPE_NUMERIC); + num = kvp_value_get_numeric (kval); + g_value_set_boxed (val, &num); + break; + case KVP_TYPE_STRING: + g_value_init (val, G_TYPE_STRING); + g_value_set_string (val, kvp_value_get_string (kval)); + break; + case KVP_TYPE_GUID: + g_value_init (val, GNC_TYPE_GUID); + g_value_set_boxed (val, kvp_value_get_guid (kval)); + break; + case KVP_TYPE_TIMESPEC: + g_value_init (val, GNC_TYPE_TIMESPEC); + tm = kvp_value_get_timespec (kval); + g_value_set_boxed (val, &tm); + break; + case KVP_TYPE_GDATE: + g_value_init (val, G_TYPE_DATE); + gdate = kvp_value_get_gdate (kval); + g_value_set_boxed (val, &gdate); + break; + case KVP_TYPE_GLIST: + { + GList *gvalue_list = NULL; + GList *kvp_list = kvp_value_get_glist (kval); + g_list_foreach (kvp_list, (GFunc)gvalue_list_from_kvp_value, &gvalue_list); + g_value_init (val, GNC_TYPE_VALUE_LIST); + gvalue_list = g_list_reverse (gvalue_list); + g_value_set_boxed (val, gvalue_list); + break; + } /* No transfer of KVP frames outside of QofInstance-derived classes! */ - case KVP_TYPE_FRAME: - PWARN ("Error! Attempt to transfer KvpFrame!"); - default: - PWARN ("Error! Invalid KVP Transfer Request!"); - g_slice_free (GValue, val); - val = NULL; - break; + case KVP_TYPE_FRAME: + PWARN ("Error! Attempt to transfer KvpFrame!"); + default: + PWARN ("Error! Invalid KVP Transfer Request!"); + g_slice_free (GValue, val); + val = NULL; + break; } return val; } @@ -1270,36 +1290,41 @@ KvpValue* kvp_value_from_gvalue (const GValue *gval) { KvpValue *val = NULL; - GType type = G_VALUE_TYPE (gval); + GType type; + if (gval == NULL) + return NULL; + type = G_VALUE_TYPE (gval); g_return_val_if_fail (G_VALUE_TYPE (gval), NULL); if (type == G_TYPE_INT64) - val = kvp_value_new_gint64 (g_value_get_int64 (gval)); + val = kvp_value_new_gint64 (g_value_get_int64 (gval)); else if (type == G_TYPE_DOUBLE) - val = kvp_value_new_double (g_value_get_double (gval)); + val = kvp_value_new_double (g_value_get_double (gval)); + else if (type == G_TYPE_BOOLEAN) + val = kvp_value_new_boolean (g_value_get_boolean (gval)); else if (type == GNC_TYPE_NUMERIC) - val = kvp_value_new_numeric (*(gnc_numeric*)g_value_get_boxed (gval)); + val = kvp_value_new_numeric (*(gnc_numeric*)g_value_get_boxed (gval)); else if (type == G_TYPE_STRING) - val = kvp_value_new_string (g_value_get_string (gval)); + val = kvp_value_new_string (g_value_get_string (gval)); else if (type == GNC_TYPE_GUID) - val = kvp_value_new_guid ((GncGUID*)g_value_get_boxed (gval)); + val = kvp_value_new_guid ((GncGUID*)g_value_get_boxed (gval)); else if (type == GNC_TYPE_TIMESPEC) - val = kvp_value_new_timespec (*(Timespec*)g_value_get_boxed (gval)); + val = kvp_value_new_timespec (*(Timespec*)g_value_get_boxed (gval)); else if (type == G_TYPE_DATE) - val = kvp_value_new_gdate (*(GDate*)g_value_get_boxed (gval)); + val = kvp_value_new_gdate (*(GDate*)g_value_get_boxed (gval)); else if (type == GNC_TYPE_VALUE_LIST) { - GList *gvalue_list = (GList*)g_value_get_boxed (gval); - GList *kvp_list = NULL; - g_list_foreach (gvalue_list, (GFunc)kvp_value_list_from_gvalue, &kvp_list); - kvp_list = g_list_reverse (kvp_list); - val = kvp_value_new_glist_nc (kvp_list); -// g_list_free_full (gvalue_list, (GDestroyNotify)g_value_unset); -// gvalue_list = NULL; + GList *gvalue_list = (GList*)g_value_get_boxed (gval); + GList *kvp_list = NULL; + g_list_foreach (gvalue_list, (GFunc)kvp_value_list_from_gvalue, &kvp_list); + kvp_list = g_list_reverse (kvp_list); + val = kvp_value_new_glist_nc (kvp_list); +// g_list_free_full (gvalue_list, (GDestroyNotify)g_value_unset); +// gvalue_list = NULL; } else - PWARN ("Error! Don't know how to make a KvpValue from a %s", - G_VALUE_TYPE_NAME (gval)); + PWARN ("Error! Don't know how to make a KvpValue from a %s", + G_VALUE_TYPE_NAME (gval)); return val; } @@ -1315,7 +1340,7 @@ kvp_frame_get_gvalue (KvpFrame *frame, const gchar *key) void kvp_frame_set_gvalue (KvpFrame *frame, const gchar *key, const GValue *value) { - kvp_frame_set_value_nc (frame, key, kvp_value_from_gvalue (value)); + kvp_frame_set_value_nc (frame, key, kvp_value_from_gvalue (value)); } static void @@ -1356,9 +1381,9 @@ gnc_value_list_get_type (void) static GType type = 0; if (type == 0) { - type = g_boxed_type_register_static ("gnc_value_list", - (GBoxedCopyFunc)gnc_value_list_copy, - (GBoxedFreeFunc)gnc_value_list_free); + type = g_boxed_type_register_static ("gnc_value_list", + (GBoxedCopyFunc)gnc_value_list_copy, + (GBoxedFreeFunc)gnc_value_list_free); } return type; } diff --git a/src/libqof/qof/kvp_frame.h b/src/libqof/qof/kvp_frame.h index 724ff63dac..136006ea8c 100644 --- a/src/libqof/qof/kvp_frame.h +++ b/src/libqof/qof/kvp_frame.h @@ -95,14 +95,15 @@ typedef enum KVP_TYPE_INVALID = -1, KVP_TYPE_GINT64 = 1, /**< QOF_TYPE_INT64 gint64 */ KVP_TYPE_DOUBLE, /**< QOF_TYPE_DOUBLE gdouble */ + KVP_TYPE_BOOLEAN, /**< QOF_TYPE_BOOLEAN gboolean */ KVP_TYPE_NUMERIC, /**< QOF_TYPE_NUMERIC */ KVP_TYPE_STRING, /**< QOF_TYPE_STRING gchar* */ KVP_TYPE_GUID, /**< QOF_TYPE_GUID */ KVP_TYPE_TIMESPEC, /**< QOF_TYPE_DATE */ KVP_TYPE_PLACEHOLDER_DONT_USE, /* Replaces KVP_TYPE_BINARY */ KVP_TYPE_GLIST, /**< no QOF equivalent. */ - KVP_TYPE_FRAME /**< no QOF equivalent. */ - , KVP_TYPE_GDATE /**< no QOF equivalent. */ + KVP_TYPE_FRAME, /**< no QOF equivalent. */ + KVP_TYPE_GDATE /**< no QOF equivalent. */ } KvpValueType; /** \deprecated Deprecated backwards compat token From c9785be334d7a3b27b734629ba880f8fd6f8518d Mon Sep 17 00:00:00 2001 From: John Ralls Date: Fri, 8 May 2015 13:31:56 -0700 Subject: [PATCH 02/54] Provide qof_instance_copy_kvp, qof_instance_swap_kvp, and qof_instance_compare_kvp. To facilitate abstracting all kV operations to libqof/qof. --- src/libqof/qof/qofinstance-p.h | 5 +++++ src/libqof/qof/qofinstance.cpp | 30 ++++++++++++++++++++++++------ 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/libqof/qof/qofinstance-p.h b/src/libqof/qof/qofinstance-p.h index 751b3f06d8..2428ad9935 100644 --- a/src/libqof/qof/qofinstance-p.h +++ b/src/libqof/qof/qofinstance-p.h @@ -108,6 +108,11 @@ void qof_instance_set_idata(gpointer inst, guint32 idata); /* Convenience functions to save some typing in property handlers */ void qof_instance_set_kvp (QofInstance *inst, const gchar *key, const GValue *value); void qof_instance_get_kvp (QofInstance *inst, const gchar *key, GValue *value); +void qof_instance_copy_kvp (QofInstance *to, const QofInstance *from); +void qof_instance_swap_kvp (QofInstance *a, QofInstance *b); +int qof_instance_compare_kvp (const QofInstance *a, const QofInstance *b); +char* qof_instance_kvp_as_string (const QofInstance *inst); + #ifdef __cplusplus } diff --git a/src/libqof/qof/qofinstance.cpp b/src/libqof/qof/qofinstance.cpp index 1af2c0a90c..d545fdf711 100644 --- a/src/libqof/qof/qofinstance.cpp +++ b/src/libqof/qof/qofinstance.cpp @@ -28,18 +28,13 @@ * Copyright (c) 2007 David Hampton */ -#ifdef __cplusplus extern "C" { -#endif - #include "config.h" #include - -#ifdef __cplusplus } -#endif +#include #include "qof.h" #include "kvp-util-p.h" #include "qofbook-p.h" @@ -1090,6 +1085,29 @@ qof_instance_get_kvp (QofInstance *inst, const gchar *key, GValue *value) } } +void +qof_instance_copy_kvp (QofInstance *to, const QofInstance *from) +{ + to->kvp_data = kvp_frame_copy(from->kvp_data); +} + +void +qof_instance_swap_kvp (QofInstance *a, QofInstance *b) +{ + std::swap(a->kvp_data, b->kvp_data); +} + +int +qof_instance_compare_kvp (const QofInstance *a, const QofInstance *b) +{ + return kvp_frame_compare (a->kvp_data, b->kvp_data); +} + +char* +qof_instance_kvp_as_string (const QofInstance *inst) +{ + return kvp_frame_to_string (inst->kvp_data); +} /* ========================== END OF FILE ======================= */ From 542557724cbfbccc9ee5ef59635d668944582842 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Fri, 8 May 2015 13:33:15 -0700 Subject: [PATCH 03/54] Convert almost all Account KVP operations to use qof_instance_foo_kvp. Can't do the import-matcher stuff, it's a bit too hard-wired to KVP. --- src/engine/Account.c | 938 ++++++++++++++++++++++--------------------- 1 file changed, 471 insertions(+), 467 deletions(-) diff --git a/src/engine/Account.c b/src/engine/Account.c index 88e00f2e89..02b0916d9d 100644 --- a/src/engine/Account.c +++ b/src/engine/Account.c @@ -61,48 +61,48 @@ enum enum { PROP_0, - PROP_NAME, /* Table */ - PROP_FULL_NAME, /* Constructed */ - PROP_CODE, /* Table */ - PROP_DESCRIPTION, /* Table */ - PROP_COLOR, /* KVP */ - PROP_NOTES, /* KVP */ - PROP_TYPE, /* Table */ + PROP_NAME, /* Table */ + PROP_FULL_NAME, /* Constructed */ + PROP_CODE, /* Table */ + PROP_DESCRIPTION, /* Table */ + PROP_COLOR, /* KVP */ + PROP_NOTES, /* KVP */ + PROP_TYPE, /* Table */ -// PROP_PARENT, /* Table, Not a property */ - PROP_COMMODITY, /* Table */ - PROP_COMMODITY_SCU, /* Table */ - PROP_NON_STD_SCU, /* Table */ - PROP_END_BALANCE, /* Constructed */ - PROP_END_CLEARED_BALANCE, /* Constructed */ - PROP_END_RECONCILED_BALANCE, /* Constructed */ +// PROP_PARENT, /* Table, Not a property */ + PROP_COMMODITY, /* Table */ + PROP_COMMODITY_SCU, /* Table */ + PROP_NON_STD_SCU, /* Table */ + PROP_END_BALANCE, /* Constructed */ + PROP_END_CLEARED_BALANCE, /* Constructed */ + PROP_END_RECONCILED_BALANCE, /* Constructed */ - PROP_TAX_RELATED, /* KVP */ - PROP_TAX_CODE, /* KVP */ - PROP_TAX_SOURCE, /* KVP */ - PROP_TAX_COPY_NUMBER, /* KVP */ + PROP_TAX_RELATED, /* KVP */ + PROP_TAX_CODE, /* KVP */ + PROP_TAX_SOURCE, /* KVP */ + PROP_TAX_COPY_NUMBER, /* KVP */ - PROP_HIDDEN, /* Table slot exists, but in KVP in memory & xml */ - PROP_PLACEHOLDER, /* Table slot exists, but in KVP in memory & xml */ - PROP_FILTER, /* KVP */ - PROP_SORT_ORDER, /* KVP */ + PROP_HIDDEN, /* Table slot exists, but in KVP in memory & xml */ + PROP_PLACEHOLDER, /* Table slot exists, but in KVP in memory & xml */ + PROP_FILTER, /* KVP */ + PROP_SORT_ORDER, /* KVP */ - PROP_LOT_NEXT_ID, /* KVP */ - PROP_ONLINE_ACCOUNT, /* KVP */ - PROP_OFX_INCOME_ACCOUNT, /* KVP */ - PROP_AB_ACCOUNT_ID, /* KVP */ - PROP_AB_ACCOUNT_UID, /* KVP */ - PROP_AB_BANK_CODE, /* KVP */ - PROP_AB_TRANS_RETRIEVAL, /* KVP */ + PROP_LOT_NEXT_ID, /* KVP */ + PROP_ONLINE_ACCOUNT, /* KVP */ + PROP_OFX_INCOME_ACCOUNT, /* KVP */ + PROP_AB_ACCOUNT_ID, /* KVP */ + PROP_AB_ACCOUNT_UID, /* KVP */ + PROP_AB_BANK_CODE, /* KVP */ + PROP_AB_TRANS_RETRIEVAL, /* KVP */ PROP_RUNTIME_0, - PROP_POLICY, /* Cached Value */ - PROP_MARK, /* Runtime Value */ - PROP_SORT_DIRTY, /* Runtime Value */ - PROP_BALANCE_DIRTY, /* Runtime Value */ - PROP_START_BALANCE, /* Runtime Value */ - PROP_START_CLEARED_BALANCE, /* Runtime Value */ - PROP_START_RECONCILED_BALANCE, /* Runtime Value */ + PROP_POLICY, /* Cached Value */ + PROP_MARK, /* Runtime Value */ + PROP_SORT_DIRTY, /* Runtime Value */ + PROP_BALANCE_DIRTY, /* Runtime Value */ + PROP_START_BALANCE, /* Runtime Value */ + PROP_START_CLEARED_BALANCE, /* Runtime Value */ + PROP_START_RECONCILED_BALANCE, /* Runtime Value */ }; #define GET_PRIVATE(o) \ @@ -399,35 +399,35 @@ gnc_account_get_property (GObject *object, g_value_set_string(value, xaccAccountGetSortOrder(account)); break; case PROP_LOT_NEXT_ID: - key = "lot-mgmt/next-id"; + key = "lot-mgmt/next-id"; /* Pre-set the value in case the frame is empty */ - g_value_set_int64 (value, 0); - qof_instance_get_kvp (QOF_INSTANCE (account), key, value); - break; + g_value_set_int64 (value, 0); + qof_instance_get_kvp (QOF_INSTANCE (account), key, value); + break; case PROP_ONLINE_ACCOUNT: - key = "online_id"; - qof_instance_get_kvp (QOF_INSTANCE (account), key, value); - break; + key = "online_id"; + qof_instance_get_kvp (QOF_INSTANCE (account), key, value); + break; case PROP_OFX_INCOME_ACCOUNT: - key = KEY_ASSOC_INCOME_ACCOUNT; - qof_instance_get_kvp (QOF_INSTANCE (account), key, value); - break; + key = KEY_ASSOC_INCOME_ACCOUNT; + qof_instance_get_kvp (QOF_INSTANCE (account), key, value); + break; case PROP_AB_ACCOUNT_ID: - key = AB_KEY "/" AB_ACCOUNT_ID; - qof_instance_get_kvp (QOF_INSTANCE (account), key, value); - break; + key = AB_KEY "/" AB_ACCOUNT_ID; + qof_instance_get_kvp (QOF_INSTANCE (account), key, value); + break; case PROP_AB_ACCOUNT_UID: - key = AB_KEY "/" AB_ACCOUNT_UID; - qof_instance_get_kvp (QOF_INSTANCE (account), key, value); - break; + key = AB_KEY "/" AB_ACCOUNT_UID; + qof_instance_get_kvp (QOF_INSTANCE (account), key, value); + break; case PROP_AB_BANK_CODE: - key = AB_KEY "/" AB_BANK_CODE; - qof_instance_get_kvp (QOF_INSTANCE (account), key, value); - break; + key = AB_KEY "/" AB_BANK_CODE; + qof_instance_get_kvp (QOF_INSTANCE (account), key, value); + break; case PROP_AB_TRANS_RETRIEVAL: - key = AB_KEY "/" AB_TRANS_RETRIEVAL; - qof_instance_get_kvp (QOF_INSTANCE (account), key, value); - break; + key = AB_KEY "/" AB_TRANS_RETRIEVAL; + qof_instance_get_kvp (QOF_INSTANCE (account), key, value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -448,7 +448,7 @@ gnc_account_set_property (GObject *object, account = GNC_ACCOUNT(object); if (prop_id < PROP_RUNTIME_0) - g_assert (qof_instance_get_editlevel(account)); + g_assert (qof_instance_get_editlevel(account)); switch (prop_id) { @@ -531,33 +531,33 @@ gnc_account_set_property (GObject *object, xaccAccountSetSortOrder(account, g_value_get_string(value)); break; case PROP_LOT_NEXT_ID: - key = "lot-mgmt/next-id"; - qof_instance_set_kvp (QOF_INSTANCE (account), key, value); - break; + key = "lot-mgmt/next-id"; + qof_instance_set_kvp (QOF_INSTANCE (account), key, value); + break; case PROP_ONLINE_ACCOUNT: - key = "online_id"; - qof_instance_set_kvp (QOF_INSTANCE (account), key, value); - break; + key = "online_id"; + qof_instance_set_kvp (QOF_INSTANCE (account), key, value); + break; case PROP_OFX_INCOME_ACCOUNT: - key = KEY_ASSOC_INCOME_ACCOUNT; - qof_instance_set_kvp (QOF_INSTANCE (account), key, value); - break; + key = KEY_ASSOC_INCOME_ACCOUNT; + qof_instance_set_kvp (QOF_INSTANCE (account), key, value); + break; case PROP_AB_ACCOUNT_ID: - key = AB_KEY "/" AB_ACCOUNT_ID; - qof_instance_set_kvp (QOF_INSTANCE (account), key, value); - break; + key = AB_KEY "/" AB_ACCOUNT_ID; + qof_instance_set_kvp (QOF_INSTANCE (account), key, value); + break; case PROP_AB_ACCOUNT_UID: - key = AB_KEY "/" AB_ACCOUNT_UID; - qof_instance_set_kvp (QOF_INSTANCE (account), key, value); - break; + key = AB_KEY "/" AB_ACCOUNT_UID; + qof_instance_set_kvp (QOF_INSTANCE (account), key, value); + break; case PROP_AB_BANK_CODE: - key = AB_KEY "/" AB_BANK_CODE; - qof_instance_set_kvp (QOF_INSTANCE (account), key, value); - break; + key = AB_KEY "/" AB_BANK_CODE; + qof_instance_set_kvp (QOF_INSTANCE (account), key, value); + break; case PROP_AB_TRANS_RETRIEVAL: - key = AB_KEY "/" AB_TRANS_RETRIEVAL; - qof_instance_set_kvp (QOF_INSTANCE (account), key, value); - break; + key = AB_KEY "/" AB_TRANS_RETRIEVAL; + qof_instance_set_kvp (QOF_INSTANCE (account), key, value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -933,7 +933,7 @@ gnc_account_class_init (AccountClass *klass) g_param_spec_string ("online-id", "Online Account ID", "The online account which corresponds to this " - "account for OFX import", + "account for OFX import", NULL, G_PARAM_READWRITE)); @@ -941,10 +941,10 @@ gnc_account_class_init (AccountClass *klass) gobject_class, PROP_OFX_INCOME_ACCOUNT, g_param_spec_boxed("ofx-income-account", - "Associated income account", - "Used by the OFX importer.", - GNC_TYPE_GUID, - G_PARAM_READWRITE)); + "Associated income account", + "Used by the OFX importer.", + GNC_TYPE_GUID, + G_PARAM_READWRITE)); g_object_class_install_property (gobject_class, @@ -952,7 +952,7 @@ gnc_account_class_init (AccountClass *klass) g_param_spec_string ("ab-account-id", "AQBanking Account ID", "The AqBanking account which corresponds to this " - "account for AQBanking import", + "account for AQBanking import", NULL, G_PARAM_READWRITE)); g_object_class_install_property @@ -961,7 +961,7 @@ gnc_account_class_init (AccountClass *klass) g_param_spec_string ("ab-bank-code", "AQBanking Bank Code", "The online account which corresponds to this " - "account for AQBanking import", + "account for AQBanking import", NULL, G_PARAM_READWRITE)); @@ -982,7 +982,7 @@ gnc_account_class_init (AccountClass *klass) g_param_spec_boxed("ab-trans-retrieval", "AQBanking Last Transaction Retrieval", "The time of the last transaction retrieval for this " - "account.", + "account.", GNC_TYPE_TIMESPEC, G_PARAM_READWRITE)); @@ -1136,8 +1136,7 @@ xaccCloneAccount(const Account *from, QofBook *book) priv->accountCode = CACHE_INSERT(from_priv->accountCode); priv->description = CACHE_INSERT(from_priv->description); - kvp_frame_delete(ret->inst.kvp_data); - ret->inst.kvp_data = kvp_frame_copy(from->inst.kvp_data); + qof_instance_copy_kvp (QOF_INSTANCE (ret), QOF_INSTANCE (from)); /* The new book should contain a commodity that matches * the one in the old book. Find it, use it. */ @@ -1418,8 +1417,8 @@ compare_account_by_name (gconstpointer a, gconstpointer b) priv_a = GET_PRIVATE((Account*)a); priv_b = GET_PRIVATE((Account*)b); if ((priv_a->accountCode && strlen (priv_a->accountCode)) || - (priv_b->accountCode && strlen (priv_b->accountCode))) - return g_strcmp0 (priv_a->accountCode, priv_b->accountCode); + (priv_b->accountCode && strlen (priv_b->accountCode))) + return g_strcmp0 (priv_a->accountCode, priv_b->accountCode); return g_strcmp0 (priv_a->accountName, priv_b->accountName); } @@ -1435,23 +1434,23 @@ xaccAcctChildrenEqual(const GList *na, } if (g_list_length ((GList*)na) != g_list_length ((GList*)nb)) { - PINFO ("Accounts have different numbers of children"); - return (FALSE); + PINFO ("Accounts have different numbers of children"); + return (FALSE); } while (na) { Account *aa = na->data; Account *ab; - GList *node = g_list_find_custom ((GList*)nb, aa, - (GCompareFunc)compare_account_by_name); + GList *node = g_list_find_custom ((GList*)nb, aa, + (GCompareFunc)compare_account_by_name); - if (!node) - { - PINFO ("Unable to find matching child account."); - return FALSE; - } - ab = node->data; + if (!node) + { + PINFO ("Unable to find matching child account."); + return FALSE; + } + ab = node->data; if (!xaccAccountEqual(aa, ab, check_guids)) { char sa[GUID_ENCODING_LENGTH + 1]; @@ -1522,13 +1521,13 @@ xaccAccountEqual(const Account *aa, const Account *ab, gboolean check_guids) } } - if (kvp_frame_compare(aa->inst.kvp_data, ab->inst.kvp_data) != 0) + if (qof_instance_compare_kvp (QOF_INSTANCE (aa), QOF_INSTANCE (ab)) != 0) { char *frame_a; char *frame_b; - frame_a = kvp_frame_to_string (aa->inst.kvp_data); - frame_b = kvp_frame_to_string (ab->inst.kvp_data); + frame_a = qof_instance_kvp_as_string (QOF_INSTANCE (aa)); + frame_b = qof_instance_kvp_as_string (QOF_INSTANCE (ab)); PWARN ("kvp frames differ:\n%s\n\nvs\n\n%s", frame_a, frame_b); @@ -2283,67 +2282,62 @@ xaccAccountSetDescription (Account *acc, const char *str) xaccAccountCommitEdit(acc); } -void -xaccAccountSetColor (Account *acc, const char *str) +static void +set_kvp_string_tag (Account *acc, const char *tag, const char *value) { g_return_if_fail(GNC_IS_ACCOUNT(acc)); xaccAccountBeginEdit(acc); - if (str) + if (value) { - gchar *tmp = g_strstrip(g_strdup(str)); - kvp_frame_set_slot_nc(acc->inst.kvp_data, "color", - strlen(tmp) ? kvp_value_new_string(tmp) : NULL); + gchar *tmp = g_strstrip(g_strdup(value)); + if (strlen (tmp)) + { + GValue v = G_VALUE_INIT; + g_value_init (&v, G_TYPE_STRING); + g_value_set_string (&v, tmp); + qof_instance_set_kvp (QOF_INSTANCE (acc), tag , &v); + } + else + qof_instance_set_kvp (QOF_INSTANCE (acc), tag, NULL); g_free(tmp); } else { - kvp_frame_set_slot_nc(acc->inst.kvp_data, "color", NULL); + qof_instance_set_kvp (QOF_INSTANCE (acc), tag, NULL); } mark_account (acc); xaccAccountCommitEdit(acc); } +static const char* +get_kvp_string_tag (const Account *acc, const char *tag) +{ + GValue v = G_VALUE_INIT; + const char* s; + if (acc == NULL || tag == NULL) return NULL; + g_value_init (&v, G_TYPE_STRING); + qof_instance_get_kvp (QOF_INSTANCE (acc), tag, &v); + s = g_value_get_string (&v); + return s; +} + +void +xaccAccountSetColor (Account *acc, const char *str) +{ + set_kvp_string_tag (acc, "color", str); +} + void xaccAccountSetFilter (Account *acc, const char *str) { - g_return_if_fail(GNC_IS_ACCOUNT(acc)); - - xaccAccountBeginEdit(acc); - if (str) - { - gchar *tmp = g_strstrip(g_strdup(str)); - kvp_frame_set_slot_nc(acc->inst.kvp_data, "filter", - strlen(tmp) ? kvp_value_new_string(tmp) : NULL); - g_free(tmp); - } - else - { - kvp_frame_set_slot_nc(acc->inst.kvp_data, "filter", NULL); - } - mark_account (acc); - xaccAccountCommitEdit(acc); + set_kvp_string_tag (acc, "filter", str); } void xaccAccountSetSortOrder (Account *acc, const char *str) { - g_return_if_fail(GNC_IS_ACCOUNT(acc)); - - xaccAccountBeginEdit(acc); - if (str) - { - gchar *tmp = g_strstrip(g_strdup(str)); - kvp_frame_set_slot_nc(acc->inst.kvp_data, "sort-order", - strlen(tmp) ? kvp_value_new_string(tmp) : NULL); - g_free(tmp); - } - else - { - kvp_frame_set_slot_nc(acc->inst.kvp_data, "sort-order", NULL); - } - mark_account (acc); - xaccAccountCommitEdit(acc); + set_kvp_string_tag (acc, "sort-order", str); } static void @@ -2367,22 +2361,7 @@ qofAccountSetParent (Account *acc, QofInstance *parent) void xaccAccountSetNotes (Account *acc, const char *str) { - g_return_if_fail(GNC_IS_ACCOUNT(acc)); - - xaccAccountBeginEdit(acc); - if (str) - { - gchar *tmp = g_strstrip(g_strdup(str)); - kvp_frame_set_slot_nc(acc->inst.kvp_data, "notes", - strlen(tmp) ? kvp_value_new_string(tmp) : NULL); - g_free(tmp); - } - else - { - kvp_frame_set_slot_nc(acc->inst.kvp_data, "notes", NULL); - } - mark_account(acc); - xaccAccountCommitEdit(acc); + set_kvp_string_tag (acc, "notes", str); } void @@ -2498,23 +2477,26 @@ void DxaccAccountSetCurrency (Account * acc, gnc_commodity * currency) { QofBook *book; - const char *string; + GValue v = G_VALUE_INIT; + const char *s = gnc_commodity_get_unique_name (currency); gnc_commodity *commodity; + gnc_commodity_table *table; if ((!acc) || (!currency)) return; - - xaccAccountBeginEdit(acc); - string = gnc_commodity_get_unique_name (currency); - kvp_frame_set_slot_nc(acc->inst.kvp_data, "old-currency", - kvp_value_new_string(string)); + g_value_init (&v, G_TYPE_STRING); + g_value_set_string (&v, s); + qof_instance_set_kvp (QOF_INSTANCE (acc), "old-currency", &v); mark_account (acc); xaccAccountCommitEdit(acc); - commodity = DxaccAccountGetCurrency (acc); + table = gnc_commodity_table_get_table (qof_instance_get_book(acc)); + commodity = gnc_commodity_table_lookup_unique (table, s); + if (!commodity) { book = qof_instance_get_book(acc); - gnc_commodity_table_insert (gnc_commodity_table_get_table (book), currency); + gnc_commodity_table_insert (gnc_commodity_table_get_table (book), + currency); } } @@ -3100,43 +3082,41 @@ const char * xaccAccountGetColor (const Account *acc) { g_return_val_if_fail(GNC_IS_ACCOUNT(acc), NULL); - return acc ? kvp_frame_get_string(acc->inst.kvp_data, "color") : NULL; + return get_kvp_string_tag (acc, "color"); } const char * xaccAccountGetFilter (const Account *acc) { g_return_val_if_fail(GNC_IS_ACCOUNT(acc), 0); - return acc ? kvp_frame_get_string(acc->inst.kvp_data, "filter") : NULL; + return get_kvp_string_tag (acc, "filter"); } const char * xaccAccountGetSortOrder (const Account *acc) { g_return_val_if_fail(GNC_IS_ACCOUNT(acc), 0); - return acc ? kvp_frame_get_string(acc->inst.kvp_data, "sort-order") : NULL; + return get_kvp_string_tag (acc, "sort-order"); } const char * xaccAccountGetNotes (const Account *acc) { g_return_val_if_fail(GNC_IS_ACCOUNT(acc), NULL); - return acc ? kvp_frame_get_string(acc->inst.kvp_data, "notes") : NULL; + return get_kvp_string_tag (acc, "notes"); } gnc_commodity * DxaccAccountGetCurrency (const Account *acc) { - KvpValue *v; + GValue v = G_VALUE_INIT; const char *s; gnc_commodity_table *table; if (!acc) return NULL; - - v = kvp_frame_get_slot(acc->inst.kvp_data, "old-currency"); - if (!v) return NULL; - - s = kvp_value_get_string (v); + g_value_init (&v, G_TYPE_STRING); + qof_instance_get_kvp (QOF_INSTANCE(acc), "old-currency", &v); + s = g_value_get_string (&v); if (!s) return NULL; table = gnc_commodity_table_get_table (qof_instance_get_book(acc)); @@ -3689,7 +3669,7 @@ xaccAccountGetBalanceAsOfDateInCurrency( gnc_numeric xaccAccountGetBalanceChangeForPeriod (Account *acc, time64 t1, time64 t2, - gboolean recurse) + gboolean recurse) { gnc_numeric b1, b2; @@ -3732,7 +3712,7 @@ xaccAccountCountSplits (const Account *acc, gboolean include_children) nr = g_list_length(xaccAccountGetSplitList(acc)); if (include_children && (gnc_account_n_children(acc) != 0)) { - for (i=0; i < gnc_account_n_children(acc); i++) + for (i=0; i < gnc_account_n_children(acc); i++) { nr += xaccAccountCountSplits(gnc_account_nth_child(acc, i), TRUE); } @@ -3807,47 +3787,49 @@ xaccAccountForEachLot(const Account *acc, gboolean xaccAccountGetTaxRelated (const Account *acc) { + GValue v = G_VALUE_INIT; g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE); - return kvp_frame_get_gint64(acc->inst.kvp_data, "tax-related"); + g_value_init (&v, G_TYPE_BOOLEAN); + qof_instance_get_kvp (QOF_INSTANCE(acc), "tax-related", &v); + return g_value_get_boolean (&v); } void xaccAccountSetTaxRelated (Account *acc, gboolean tax_related) { - KvpValue *new_value; - + GValue v = G_VALUE_INIT; g_return_if_fail(GNC_IS_ACCOUNT(acc)); - if (tax_related) - new_value = kvp_value_new_gint64 (tax_related); - else - new_value = NULL; + g_value_init (&v, G_TYPE_BOOLEAN); + g_value_set_boolean (&v, tax_related); - xaccAccountBeginEdit (acc); - kvp_frame_set_slot_nc(acc->inst.kvp_data, "tax-related", new_value); + xaccAccountBeginEdit(acc); + qof_instance_set_kvp (QOF_INSTANCE (acc), "tax-related", &v); mark_account (acc); - xaccAccountCommitEdit (acc); + xaccAccountCommitEdit(acc); } const char * xaccAccountGetTaxUSCode (const Account *acc) { - g_return_val_if_fail(GNC_IS_ACCOUNT(acc), NULL); - return kvp_frame_get_string(acc->inst.kvp_data, "tax-US/code"); + GValue v = G_VALUE_INIT; + g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE); + g_value_init (&v, G_TYPE_STRING); + qof_instance_get_kvp (QOF_INSTANCE(acc), "/tax-US/code", &v); + g_return_val_if_fail (G_VALUE_HOLDS_STRING (&v), FALSE); + return g_value_get_string (&v); } void xaccAccountSetTaxUSCode (Account *acc, const char *code) { + GValue v = G_VALUE_INIT; g_return_if_fail(GNC_IS_ACCOUNT(acc)); + g_value_init (&v, G_TYPE_STRING); + g_value_set_string (&v, code); xaccAccountBeginEdit (acc); - kvp_frame_set_string (acc->inst.kvp_data, "/tax-US/code", code); - if (!code) - { - KvpFrame *frame = NULL; - kvp_frame_set_frame (acc->inst.kvp_data, "/tax-US", frame); - } + qof_instance_set_kvp (QOF_INSTANCE (acc), "/tax-US/code", &v); mark_account (acc); xaccAccountCommitEdit (acc); } @@ -3855,19 +3837,25 @@ xaccAccountSetTaxUSCode (Account *acc, const char *code) const char * xaccAccountGetTaxUSPayerNameSource (const Account *acc) { - g_return_val_if_fail(GNC_IS_ACCOUNT(acc), NULL); - return kvp_frame_get_string(acc->inst.kvp_data, - "tax-US/payer-name-source"); -} + GValue v = G_VALUE_INIT; + g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE); + g_value_init (&v, G_TYPE_STRING); + qof_instance_get_kvp (QOF_INSTANCE(acc), + "/tax-US/payer-name-source", &v); + g_return_val_if_fail (G_VALUE_HOLDS_STRING (&v), FALSE); + return g_value_get_string (&v); + } void xaccAccountSetTaxUSPayerNameSource (Account *acc, const char *source) { + GValue v = G_VALUE_INIT; g_return_if_fail(GNC_IS_ACCOUNT(acc)); + g_value_init (&v, G_TYPE_STRING); + g_value_set_string (&v, source); xaccAccountBeginEdit (acc); - kvp_frame_set_string (acc->inst.kvp_data, - "/tax-US/payer-name-source", source); + qof_instance_set_kvp (QOF_INSTANCE (acc), "/tax-US/payer-name-source", &v); mark_account (acc); xaccAccountCommitEdit (acc); } @@ -3876,10 +3864,13 @@ gint64 xaccAccountGetTaxUSCopyNumber (const Account *acc) { gint64 copy_number; + GValue v = G_VALUE_INIT; + g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE); + g_value_init (&v, G_TYPE_INT64); + qof_instance_get_kvp (QOF_INSTANCE(acc), "/tax-US/copy-number", &v); + g_return_val_if_fail (G_VALUE_HOLDS_INT64 (&v), FALSE); + copy_number = g_value_get_int64 (&v); - g_return_val_if_fail(GNC_IS_ACCOUNT(acc), 1); - copy_number = kvp_frame_get_gint64(acc->inst.kvp_data, - "tax-US/copy-number"); return (copy_number == 0) ? 1 : copy_number; } @@ -3887,19 +3878,17 @@ void xaccAccountSetTaxUSCopyNumber (Account *acc, gint64 copy_number) { g_return_if_fail(GNC_IS_ACCOUNT(acc)); - xaccAccountBeginEdit (acc); if (copy_number != 0) - kvp_frame_set_gint64 (acc->inst.kvp_data, "/tax-US/copy-number", copy_number); + { + GValue v = G_VALUE_INIT; + g_value_init (&v, G_TYPE_INT64); + g_value_set_int64 (&v, copy_number); + qof_instance_set_kvp (QOF_INSTANCE (acc), "/tax-US/copy-number", &v); + } else { - KvpFrame * frame; - KvpValue *value; - - value = NULL; - frame = kvp_frame_set_value_nc (acc->inst.kvp_data, - "/tax-US/copy-number", value); - if (!frame) kvp_value_delete (value); + qof_instance_set_kvp (QOF_INSTANCE (acc), "/tax-US/copy-number", NULL); } mark_account (acc); xaccAccountCommitEdit (acc); @@ -3911,22 +3900,24 @@ xaccAccountSetTaxUSCopyNumber (Account *acc, gint64 copy_number) gboolean xaccAccountGetPlaceholder (const Account *acc) { - const char *str; - + GValue v = G_VALUE_INIT; g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE); - - str = kvp_frame_get_string(acc->inst.kvp_data, "placeholder"); - return (str && !strcmp(str, "true")); + g_value_init (&v, G_TYPE_BOOLEAN); + qof_instance_get_kvp (QOF_INSTANCE(acc), "placeholder", &v); + g_return_val_if_fail (G_VALUE_HOLDS_BOOLEAN (&v), FALSE); + return g_value_get_boolean (&v); } void xaccAccountSetPlaceholder (Account *acc, gboolean val) { + GValue v = G_VALUE_INIT; g_return_if_fail(GNC_IS_ACCOUNT(acc)); + g_value_init (&v, G_TYPE_BOOLEAN); + g_value_set_boolean (&v, val); xaccAccountBeginEdit (acc); - kvp_frame_set_string (acc->inst.kvp_data, - "placeholder", val ? "true" : NULL); + qof_instance_set_kvp (QOF_INSTANCE (acc), "placeholder", &v); mark_account (acc); xaccAccountCommitEdit (acc); } @@ -3958,22 +3949,24 @@ xaccAccountGetDescendantPlaceholder (const Account *acc) gboolean xaccAccountGetHidden (const Account *acc) { - const char *str; - + GValue v = G_VALUE_INIT; g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE); - - str = kvp_frame_get_string(acc->inst.kvp_data, "hidden"); - return (str && !strcmp(str, "true")); + g_value_init (&v, G_TYPE_BOOLEAN); + qof_instance_get_kvp (QOF_INSTANCE(acc), "hidden", &v); + g_return_val_if_fail (G_VALUE_HOLDS_BOOLEAN (&v), FALSE); + return g_value_get_boolean (&v); } void xaccAccountSetHidden (Account *acc, gboolean val) { + GValue v = G_VALUE_INIT; g_return_if_fail(GNC_IS_ACCOUNT(acc)); + g_value_init (&v, G_TYPE_BOOLEAN); + g_value_set_boolean (&v, val); xaccAccountBeginEdit (acc); - kvp_frame_set_string (acc->inst.kvp_data, "hidden", - val ? "true" : NULL); + qof_instance_set_kvp (QOF_INSTANCE (acc), "hidden", &v); mark_account (acc); xaccAccountCommitEdit (acc); } @@ -4263,19 +4256,21 @@ xaccAccountIsPriced(const Account *acc) gboolean xaccAccountGetReconcileLastDate (const Account *acc, time64 *last_date) { - KvpValue *v; + gint64 date; + GValue v = G_VALUE_INIT; + g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE); + g_value_init (&v, G_TYPE_INT64); + qof_instance_get_kvp (QOF_INSTANCE(acc), "reconcile-info/last-date", &v); + g_return_val_if_fail (G_VALUE_HOLDS_INT64 (&v), FALSE); + date = g_value_get_int64 (&v); - if (!acc) return FALSE; - - v = kvp_frame_get_value(acc->inst.kvp_data, "reconcile-info/last-date"); - - if (!v || kvp_value_get_type(v) != KVP_TYPE_GINT64) - return FALSE; - - if (last_date) - *last_date = kvp_value_get_gint64(v); - - return TRUE; + if (date) + { + if (last_date) + *last_date = date; + return TRUE; + } + return FALSE; } /********************************************************************\ @@ -4284,11 +4279,13 @@ xaccAccountGetReconcileLastDate (const Account *acc, time64 *last_date) void xaccAccountSetReconcileLastDate (Account *acc, time64 last_date) { - if (!acc) return; + GValue v = G_VALUE_INIT; + g_return_if_fail(GNC_IS_ACCOUNT(acc)); + g_value_init (&v, G_TYPE_INT64); + g_value_set_int64 (&v, last_date); xaccAccountBeginEdit (acc); - kvp_frame_set_gint64 (acc->inst.kvp_data, - "/reconcile-info/last-date", last_date); + qof_instance_set_kvp (QOF_INSTANCE (acc), "/reconcile-info/last-date", &v); mark_account (acc); xaccAccountCommitEdit (acc); } @@ -4300,23 +4297,28 @@ gboolean xaccAccountGetReconcileLastInterval (const Account *acc, int *months, int *days) { - KvpValue *v1, *v2; + GValue v1, v2; + int m, d; if (!acc) return FALSE; - - v1 = kvp_frame_get_value(acc->inst.kvp_data, - "reconcile-info/last-interval/months"); - v2 = kvp_frame_get_value(acc->inst.kvp_data, - "reconcile-info/last-interval/days"); - if (!v1 || (kvp_value_get_type (v1) != KVP_TYPE_GINT64) || - !v2 || (kvp_value_get_type (v2) != KVP_TYPE_GINT64)) - return FALSE; - - if (months) - *months = kvp_value_get_gint64 (v1); - if (days) - *days = kvp_value_get_gint64 (v2); - return TRUE; + g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE); + g_value_init (&v1, G_TYPE_INT64); + qof_instance_get_kvp (QOF_INSTANCE(acc), + "reconcile-info/last-interval/months", &v1); + g_value_init (&v2, G_TYPE_INT64); + qof_instance_get_kvp (QOF_INSTANCE(acc), + "reconcile-info/last-interval/days", &v2); + m = g_value_get_int64 (&v1); + d = g_value_get_int64 (&v2); + if (m && d) + { + if (months) + *months = m; + if (days) + *days = d; + return TRUE; + } + return FALSE; } /********************************************************************\ @@ -4325,18 +4327,18 @@ xaccAccountGetReconcileLastInterval (const Account *acc, void xaccAccountSetReconcileLastInterval (Account *acc, int months, int days) { - KvpFrame *frame; - if (!acc) return; + GValue v1 = G_VALUE_INIT, v2 = G_VALUE_INIT; + g_return_if_fail(GNC_IS_ACCOUNT(acc)); + g_value_init (&v1, G_TYPE_INT64); + g_value_set_int64 (&v1, months); + g_value_init (&v2, G_TYPE_INT64); + g_value_set_int64 (&v2, days); xaccAccountBeginEdit (acc); - - frame = kvp_frame_get_frame_slash (acc->inst.kvp_data, - "/reconcile-info/last-interval"); - g_assert(frame); - - kvp_frame_set_gint64 (frame, "months", months); - kvp_frame_set_gint64 (frame, "days", days); - + qof_instance_set_kvp (QOF_INSTANCE (acc), + "reconcile-info/last-interval/months", &v1); + qof_instance_set_kvp (QOF_INSTANCE (acc), + "reconcile-info/last-interval/days", &v2); mark_account (acc); xaccAccountCommitEdit (acc); } @@ -4347,18 +4349,22 @@ xaccAccountSetReconcileLastInterval (Account *acc, int months, int days) gboolean xaccAccountGetReconcilePostponeDate (const Account *acc, time64 *postpone_date) { - KvpValue *v; + gint64 date; + GValue v = G_VALUE_INIT; + g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE); + g_value_init (&v, G_TYPE_INT64); + qof_instance_get_kvp (QOF_INSTANCE(acc), + "reconcile-info/postpone/date", &v); + g_return_val_if_fail (G_VALUE_HOLDS_INT64 (&v), FALSE); + date = g_value_get_int64 (&v); - if (!acc) return FALSE; - - v = kvp_frame_get_value(acc->inst.kvp_data, "reconcile-info/postpone/date"); - if (!v || kvp_value_get_type (v) != KVP_TYPE_GINT64) - return FALSE; - - if (postpone_date) - *postpone_date = kvp_value_get_gint64 (v); - - return TRUE; + if (date) + { + if (postpone_date) + *postpone_date = date; + return TRUE; + } + return FALSE; } /********************************************************************\ @@ -4367,13 +4373,14 @@ xaccAccountGetReconcilePostponeDate (const Account *acc, time64 *postpone_date) void xaccAccountSetReconcilePostponeDate (Account *acc, time64 postpone_date) { - if (!acc) return; + GValue v = G_VALUE_INIT; + g_return_if_fail(GNC_IS_ACCOUNT(acc)); + g_value_init (&v, G_TYPE_INT64); + g_value_set_int64 (&v, postpone_date); xaccAccountBeginEdit (acc); - - /* XXX this should be using timespecs, not gints !! */ - kvp_frame_set_gint64 (acc->inst.kvp_data, - "reconcile-info/postpone/date", postpone_date); + qof_instance_set_kvp (QOF_INSTANCE (acc), + "/reconcile-info/postpone/date", &v); mark_account (acc); xaccAccountCommitEdit (acc); } @@ -4385,19 +4392,22 @@ gboolean xaccAccountGetReconcilePostponeBalance (const Account *acc, gnc_numeric *balance) { - KvpValue *v; + gnc_numeric bal; + GValue v = G_VALUE_INIT; + g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE); + g_value_init (&v, GNC_TYPE_NUMERIC); + qof_instance_get_kvp (QOF_INSTANCE(acc), + "reconcile-info/postpone/balance", &v); + g_return_val_if_fail (G_VALUE_HOLDS_INT64 (&v), FALSE); + bal = *(gnc_numeric*)g_value_get_boxed (&v); - if (!acc) return FALSE; - - v = kvp_frame_get_value(acc->inst.kvp_data, - "reconcile-info/postpone/balance"); - if (!v || kvp_value_get_type (v) != KVP_TYPE_NUMERIC) - return FALSE; - - if (balance) - *balance = kvp_value_get_numeric (v); - - return TRUE; + if (bal.denom) + { + if (balance) + *balance = bal; + return TRUE; + } + return FALSE; } /********************************************************************\ @@ -4406,11 +4416,14 @@ xaccAccountGetReconcilePostponeBalance (const Account *acc, void xaccAccountSetReconcilePostponeBalance (Account *acc, gnc_numeric balance) { - if (!acc) return; + GValue v = G_VALUE_INIT; + g_return_if_fail(GNC_IS_ACCOUNT(acc)); + g_value_init (&v, GNC_TYPE_NUMERIC); + g_value_set_boxed (&v, &balance); xaccAccountBeginEdit (acc); - kvp_frame_set_gnc_numeric (acc->inst.kvp_data, - "/reconcile-info/postpone/balance", balance); + qof_instance_set_kvp (QOF_INSTANCE (acc), + "/reconcile-info/postpone/balance", &v); mark_account (acc); xaccAccountCommitEdit (acc); } @@ -4425,7 +4438,7 @@ xaccAccountClearReconcilePostpone (Account *acc) if (!acc) return; xaccAccountBeginEdit (acc); - kvp_frame_set_value (acc->inst.kvp_data, "reconcile-info/postpone", NULL); + qof_instance_set_kvp (QOF_INSTANCE(acc), "reconcile-info/postpone", NULL); mark_account (acc); xaccAccountCommitEdit (acc); } @@ -4440,12 +4453,13 @@ xaccAccountClearReconcilePostpone (Account *acc) gboolean xaccAccountGetAutoInterestXfer (const Account *acc, gboolean default_value) { - const char *str = NULL; - if (!acc) return default_value; - - str = kvp_frame_get_string(acc->inst.kvp_data, - "reconcile-info/auto-interest-transfer"); - return str ? !strcmp(str, "true") : default_value; + GValue v = G_VALUE_INIT; + g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE); + g_value_init (&v, G_TYPE_BOOLEAN); + qof_instance_get_kvp (QOF_INSTANCE(acc), + "reconcile-info/auto-interest-transfer", &v); + g_return_val_if_fail (G_VALUE_HOLDS_BOOLEAN (&v), FALSE); + return g_value_get_boolean (&v); } /********************************************************************\ @@ -4454,13 +4468,14 @@ xaccAccountGetAutoInterestXfer (const Account *acc, gboolean default_value) void xaccAccountSetAutoInterestXfer (Account *acc, gboolean option) { - if (!acc) return; + GValue v = G_VALUE_INIT; + g_return_if_fail(GNC_IS_ACCOUNT(acc)); + g_value_init (&v, G_TYPE_BOOLEAN); + g_value_set_boolean (&v, option); xaccAccountBeginEdit (acc); - /* FIXME: need KVP_TYPE_BOOLEAN for this someday */ - kvp_frame_set_string (acc->inst.kvp_data, - "/reconcile-info/auto-interest-transfer", - (option ? "true" : "false")); + qof_instance_set_kvp (QOF_INSTANCE (acc), + "/reconcile-info/auto-interest-transfer", &v); mark_account (acc); xaccAccountCommitEdit (acc); } @@ -4471,7 +4486,12 @@ xaccAccountSetAutoInterestXfer (Account *acc, gboolean option) const char * xaccAccountGetLastNum (const Account *acc) { - return acc ? kvp_frame_get_string(acc->inst.kvp_data, "last-num") : NULL; + GValue v = G_VALUE_INIT; + g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE); + g_value_init (&v, G_TYPE_STRING); + qof_instance_get_kvp (QOF_INSTANCE(acc), "last-num", &v); + g_return_val_if_fail (G_VALUE_HOLDS_STRING (&v), FALSE); + return g_value_get_string (&v); } /********************************************************************\ @@ -4480,10 +4500,13 @@ xaccAccountGetLastNum (const Account *acc) void xaccAccountSetLastNum (Account *acc, const char *num) { - if (!acc) return; + GValue v = G_VALUE_INIT; + g_return_if_fail(GNC_IS_ACCOUNT(acc)); + g_value_init (&v, G_TYPE_STRING); + g_value_set_string (&v, num); xaccAccountBeginEdit (acc); - kvp_frame_set_string(acc->inst.kvp_data, "last-num", num); + qof_instance_set_kvp (QOF_INSTANCE (acc), "last-num", &v); mark_account (acc); xaccAccountCommitEdit (acc); } @@ -4536,29 +4559,36 @@ GetOrMakeOrphanAccount (Account *root, gnc_commodity * currency) Account * xaccAccountGainsAccount (Account *acc, gnc_commodity *curr) { - KvpFrame *frame = qof_instance_get_slots (QOF_INSTANCE (acc)); - const gchar *curr_name = gnc_commodity_get_unique_name (curr); + GValue v = G_VALUE_INIT; + gchar *curr_name = g_strdup_printf ("/lot-mgmt/gains-act/%s", + gnc_commodity_get_unique_name (curr)); GncGUID *guid; Account *gains_account; - frame = kvp_frame_get_frame_slash (frame, "/lot-mgmt/gains-act/"); - guid = kvp_frame_get_guid (frame, curr_name); + g_return_val_if_fail (acc != NULL, NULL); + g_value_init (&v, GNC_TYPE_GUID); + qof_instance_get_kvp (QOF_INSTANCE(acc), curr_name, &v); + guid = (GncGUID*)g_value_get_boxed (&v); if (guid == NULL) /* No gains account for this currency */ { - gains_account = GetOrMakeOrphanAccount (gnc_account_get_root (acc), - curr); - guid = (GncGUID*)qof_instance_get_guid (QOF_INSTANCE (gains_account)); - xaccAccountBeginEdit (acc); - { - kvp_frame_set_guid (frame, curr_name, guid); - qof_instance_set_dirty (QOF_INSTANCE (acc)); - } - xaccAccountCommitEdit (acc); + gains_account = GetOrMakeOrphanAccount (gnc_account_get_root (acc), + curr); + guid = (GncGUID*)qof_instance_get_guid (QOF_INSTANCE (gains_account)); + xaccAccountBeginEdit (acc); + { + GValue vr = G_VALUE_INIT; + g_value_init (&vr, GNC_TYPE_GUID); + g_value_set_boxed (&vr, guid); + qof_instance_set_kvp (QOF_INSTANCE (acc), curr_name, &vr); + qof_instance_set_dirty (QOF_INSTANCE (acc)); + } + xaccAccountCommitEdit (acc); } else - gains_account = xaccAccountLookup (guid, - qof_instance_get_book(acc)); + gains_account = xaccAccountLookup (guid, + qof_instance_get_book(acc)); + g_free (curr_name); return gains_account; } @@ -4570,17 +4600,23 @@ dxaccAccountSetPriceSrc(Account *acc, const char *src) { if (!acc) return; - xaccAccountBeginEdit(acc); if (xaccAccountIsPriced(acc)) { - kvp_frame_set_slot_nc(acc->inst.kvp_data, - "old-price-source", - src ? kvp_value_new_string(src) : NULL); - mark_account (acc); - } + xaccAccountBeginEdit(acc); + if (src) + { + GValue v = G_VALUE_INIT; + g_value_init (&v, G_TYPE_STRING); + g_value_set_string (&v, src); + qof_instance_set_kvp (QOF_INSTANCE(acc), + "old-price-source", &v); + } + else + qof_instance_set_kvp (QOF_INSTANCE(acc), "old-price-source", NULL); - qof_instance_set_dirty(&acc->inst); - xaccAccountCommitEdit(acc); + mark_account (acc); + xaccAccountCommitEdit(acc); + } } /********************************************************************\ @@ -4589,15 +4625,14 @@ dxaccAccountSetPriceSrc(Account *acc, const char *src) const char* dxaccAccountGetPriceSrc(const Account *acc) { + GValue v = G_VALUE_INIT; if (!acc) return NULL; - if (xaccAccountIsPriced(acc)) - { - KvpValue *value = kvp_frame_get_slot(acc->inst.kvp_data, - "old-price-source"); - if (value) return (kvp_value_get_string(value)); - } - return NULL; + if (!xaccAccountIsPriced(acc)) return NULL; + + g_value_init (&v, G_TYPE_STRING); + qof_instance_get_kvp (QOF_INSTANCE(acc), "old-price-source", &v); + return g_value_get_string (&v); } /********************************************************************\ @@ -4606,17 +4641,14 @@ dxaccAccountGetPriceSrc(const Account *acc) void dxaccAccountSetQuoteTZ(Account *acc, const char *tz) { + GValue v = G_VALUE_INIT; if (!acc) return; - + if (!xaccAccountIsPriced(acc)) return; xaccAccountBeginEdit(acc); - if (xaccAccountIsPriced(acc)) - { - kvp_frame_set_slot_nc(acc->inst.kvp_data, - "old-quote-tz", - tz ? kvp_value_new_string(tz) : NULL); - mark_account (acc); - } - qof_instance_set_dirty(&acc->inst); + g_value_init (&v, G_TYPE_STRING); + g_value_set_string (&v, tz); + qof_instance_set_kvp (QOF_INSTANCE (acc), "old-quote-tz", &v); + mark_account (acc); xaccAccountCommitEdit(acc); } @@ -4626,14 +4658,12 @@ dxaccAccountSetQuoteTZ(Account *acc, const char *tz) const char* dxaccAccountGetQuoteTZ(const Account *acc) { + GValue v = G_VALUE_INIT; if (!acc) return NULL; - - if (xaccAccountIsPriced(acc)) - { - KvpValue *value = kvp_frame_get_slot(acc->inst.kvp_data, "old-quote-tz"); - if (value) return (kvp_value_get_string(value)); - } - return NULL; + if (!xaccAccountIsPriced(acc)) return NULL; + g_value_init (&v, G_TYPE_STRING); + qof_instance_get_kvp (QOF_INSTANCE (acc), "old-quote-tz", &v); + return g_value_get_string (&v); } /********************************************************************\ @@ -4642,13 +4672,18 @@ dxaccAccountGetQuoteTZ(const Account *acc) void xaccAccountSetReconcileChildrenStatus(Account *acc, gboolean status) { + GValue v = G_VALUE_INIT; if (!acc) return; xaccAccountBeginEdit (acc); - - /* XXX FIXME: someday this should use KVP_TYPE_BOOLEAN */ - kvp_frame_set_gint64 (acc->inst.kvp_data, - "/reconcile-info/include-children", status); + /* Would have been nice to use G_TYPE_BOOLEAN, but the other + * boolean kvps save the value as "true" or "false" and that would + * be file-incompatible with this. + */ + g_value_init (&v, G_TYPE_INT64); + g_value_set_int64 (&v, status); + qof_instance_set_kvp (QOF_INSTANCE (acc), + "/reconcile-info/include-children", &v); mark_account(acc); xaccAccountCommitEdit (acc); } @@ -4663,8 +4698,12 @@ xaccAccountGetReconcileChildrenStatus(const Account *acc) * is found then we can assume not to include the children, that being * the default behaviour */ - return acc ? kvp_frame_get_gint64(acc->inst.kvp_data, - "reconcile-info/include-children") : FALSE; + GValue v = G_VALUE_INIT; + if (!acc) return FALSE; + g_value_init (&v, G_TYPE_BOOLEAN); + qof_instance_get_kvp (QOF_INSTANCE (acc), + "reconcile-info/include-children", &v); + return g_value_get_int64 (&v); } /********************************************************************\ @@ -5006,21 +5045,16 @@ xaccAccountForEachTransaction(const Account *acc, TransactionCallback proc, * src/import-export/import-backend.c to manipulate the contra-account * matching data. See src/import-export/import-backend.c for explanations. */ -/* FIXME: These data are stored per-account in KVP and the functions - * work directly on KVP data structures. This prevents moving KVP to a - * backend-only abstraction. - */ - typedef struct _GncImportMatchMap { - KvpFrame * frame; - Account * acc; - QofBook * book; + KvpFrame * frame; + Account * acc; + QofBook * book; } GncImportMatchMap; -#define IMAP_FRAME "import-map" -#define IMAP_FRAME_BAYES "import-map-bayes" +#define IMAP_FRAME "import-map" +#define IMAP_FRAME_BAYES "import-map-bayes" GncImportMatchMap * gnc_account_create_imap (Account *acc); Account* gnc_imap_find_account(GncImportMatchMap *imap, const char* category, const char *key); @@ -5057,58 +5091,50 @@ gnc_account_create_imap (Account *acc) /* Look up an Account in the map */ Account* gnc_imap_find_account (GncImportMatchMap *imap, - const char *category, - const char *key) + const char *category, + const char *key) { - KvpValue *value; + GValue v = G_VALUE_INIT; GncGUID * guid; + char *kvp_path; if (!imap || !key) return NULL; if (!category) - { - category = key; - key = NULL; - } - - value = kvp_frame_get_slot_path (imap->frame, IMAP_FRAME, - category, key, NULL); - if (!value) return NULL; - - guid = kvp_value_get_guid (value); + kvp_path = g_strdup_printf (IMAP_FRAME "/%s", key); + else + kvp_path = g_strdup_printf (IMAP_FRAME "/%s/%s", category, key); + g_value_init (&v, GNC_TYPE_GUID); + qof_instance_get_kvp (QOF_INSTANCE (imap->acc), kvp_path, &v); + guid = (GncGUID*)g_value_get_boxed (&v); + g_free (kvp_path); return xaccAccountLookup (guid, imap->book); } /* Store an Account in the map */ void gnc_imap_add_account (GncImportMatchMap *imap, - const char *category, - const char *key, - Account *acc) + const char *category, + const char *key, + Account *acc) { - KvpValue *value; + GValue v = G_VALUE_INIT; + char *kvp_path; if (!imap || !key || !acc || (strlen (key) == 0)) return; if (!category) - { - category = key; - key = NULL; - } - g_return_if_fail (acc != NULL); + kvp_path = g_strdup_printf (IMAP_FRAME "/%s", key); + else + kvp_path = g_strdup_printf (IMAP_FRAME "/%s/%s", category, key); - value = kvp_value_new_guid (xaccAccountGetGUID (acc)); - g_return_if_fail (value != NULL); + g_value_init (&v, GNC_TYPE_GUID); + g_value_set_boxed (&v, xaccAccountGetGUID (acc)); xaccAccountBeginEdit (imap->acc); - kvp_frame_set_slot_path (imap->frame, value, IMAP_FRAME, category, key, NULL); + qof_instance_set_kvp (QOF_INSTANCE (imap->acc), kvp_path, &v); + g_free (kvp_path); qof_instance_set_dirty (QOF_INSTANCE (imap->acc)); xaccAccountCommitEdit (imap->acc); - kvp_value_delete (value); - - /* XXX Mark the account (or book) as dirty! */ } - - - /*-------------------------------------------------------------------------- Below here is the bayes transaction to account matching system --------------------------------------------------------------------------*/ @@ -5139,7 +5165,7 @@ buildTokenInfo(const char *key, KvpValue *value, gpointer data) struct account_token_count* this_account; // PINFO("buildTokenInfo: account '%s', token_count: '%ld'\n", (char*)key, - // (long)kvp_value_get_gint64(value)); + // (long)kvp_value_get_gint64(value)); /* add the count to the total_count */ tokenInfo->total_count += kvp_value_get_gint64(value); @@ -5238,22 +5264,22 @@ Account* gnc_imap_find_account_bayes (GncImportMatchMap *imap, GList *tokens) { struct token_accounts_info tokenInfo; /**< holds the accounts and total - * token count for a single token */ - GList *current_token; /**< pointer to the current - * token from the input GList - * tokens */ - GList *current_account_token; /**< pointer to the struct - * account_token_count */ + * token count for a single token */ + GList *current_token; /**< pointer to the current + * token from the input GList + * tokens */ + GList *current_account_token; /**< pointer to the struct + * account_token_count */ struct account_token_count *account_c; /**< an account name and the number - * of times a token has appeared - * for the account */ + * of times a token has appeared + * for the account */ struct account_probability *account_p; /**< intermediate storage of values - * to compute the bayes probability - * of an account */ + * to compute the bayes probability + * of an account */ GHashTable *running_probabilities = g_hash_table_new(g_str_hash, - g_str_equal); + g_str_equal); GHashTable *final_probabilities = g_hash_table_new(g_str_hash, - g_str_equal); + g_str_equal); struct account_info account_i; KvpValue* value; KvpFrame* token_frame; @@ -5272,7 +5298,7 @@ gnc_imap_find_account_bayes (GncImportMatchMap *imap, GList *tokens) * in the input tokens list */ for (current_token = tokens; current_token; - current_token = current_token->next) + current_token = current_token->next) { /* zero out the token_accounts_info structure */ memset(&tokenInfo, 0, sizeof(struct token_accounts_info)); @@ -5332,8 +5358,8 @@ gnc_imap_find_account_bayes (GncImportMatchMap *imap, GList *tokens) if (account_p) { account_p->product = (((double)account_c->token_count / - (double)tokenInfo.total_count) - * account_p->product); + (double)tokenInfo.total_count) + * account_p->product); account_p->product_difference = ((double)1 - ((double)account_c->token_count / (double)tokenInfo.total_count)) @@ -5416,19 +5442,14 @@ gnc_imap_find_account_bayes (GncImportMatchMap *imap, GList *tokens) /** Updates the imap for a given account using a list of tokens */ void gnc_imap_add_account_bayes(GncImportMatchMap *imap, - GList *tokens, - Account *acc) + GList *tokens, + Account *acc) { GList *current_token; - KvpValue *value; gint64 token_count; - char* account_fullname; - KvpValue *new_value; /* the value that will be added back into - * the kvp tree */ + char *account_fullname, *kvp_path; ENTER(" "); - - /* if imap is null return */ if (!imap) { LEAVE(" "); @@ -5445,10 +5466,11 @@ gnc_imap_add_account_bayes(GncImportMatchMap *imap, for (current_token = g_list_first(tokens); current_token; current_token = current_token->next) { + GValue value = G_VALUE_INIT; /* Jump to next iteration if the pointer is not valid or if the - string is empty. In HBCI import we almost always get an empty - string, which doesn't work in the kvp loopkup later. So we - skip this case here. */ + string is empty. In HBCI import we almost always get an empty + string, which doesn't work in the kvp loopkup later. So we + skip this case here. */ if (!current_token->data || (*((char*)current_token->data) == '\0')) continue; @@ -5457,42 +5479,28 @@ gnc_imap_add_account_bayes(GncImportMatchMap *imap, PINFO("adding token '%s'\n", (char*)current_token->data); - /* is this token/account_name already in the kvp tree? */ - value = kvp_frame_get_slot_path(imap->frame, IMAP_FRAME_BAYES, - (char*)current_token->data, - account_fullname, - NULL); + kvp_path = g_strdup_printf (IMAP_FRAME_BAYES "/%s/%s", + (char*)current_token->data, + account_fullname); + g_value_init (&value, G_TYPE_INT64); + qof_instance_get_kvp (QOF_INSTANCE (imap->acc), kvp_path, &value); /* if the token/account is already in the tree, read the current * value from the tree and use this for the basis of the value we * are putting back */ - if (value) + if (G_VALUE_HOLDS_INT64 (&value)) { - PINFO("found existing value of '%ld'\n", - (long)kvp_value_get_gint64(value)); + int64_t count = g_value_get_int64 (&value); + PINFO("found existing value of '%" G_GINT64_FORMAT "'\n", count); - /* convert this value back into an integer */ - token_count += kvp_value_get_gint64(value); + token_count += count; } - - /* increment the token count */ token_count++; - - /* create a new value */ - new_value = kvp_value_new_gint64(token_count); - - /* insert the value into the kvp tree at - * /imap->frame/IMAP_FRAME/token_string/account_name_string - */ - kvp_frame_set_slot_path(imap->frame, new_value, - IMAP_FRAME_BAYES, - (char*)current_token->data, - account_fullname, - NULL); - /* kvp_frame_set_slot_path() copied the value so we - * need to delete this one ;-) */ - kvp_value_delete(new_value); + g_value_init (&value, G_TYPE_INT64); + g_value_set_int64 (&value, token_count); + qof_instance_set_kvp (QOF_INSTANCE (imap->acc), kvp_path, &value); + g_free (kvp_path); } /* free up the account fullname string */ @@ -5629,10 +5637,6 @@ gboolean xaccAccountRegister (void) QOF_PARAM_GUID, QOF_TYPE_GUID, (QofAccessFunc) qof_instance_get_guid, NULL }, - { - ACCOUNT_KVP, QOF_TYPE_KVP, - (QofAccessFunc) qof_instance_get_slots, NULL - }, { NULL }, }; From eccdfd0aa38585270dff742aa456ffd22b677280 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Fri, 8 May 2015 13:33:40 -0700 Subject: [PATCH 04/54] Convert all Transaction KVP operations to use qof_instance_foo_kvp. --- src/engine/Transaction.c | 231 +++++++++++++++++++++++---------------- 1 file changed, 136 insertions(+), 95 deletions(-) diff --git a/src/engine/Transaction.c b/src/engine/Transaction.c index f695ce886f..df03fb9bef 100644 --- a/src/engine/Transaction.c +++ b/src/engine/Transaction.c @@ -312,7 +312,6 @@ gnc_transaction_get_property(GObject* object, GParamSpec* pspec) { Transaction* tx; - KvpFrame *frame; gchar *key; GValue *temp; @@ -361,7 +360,6 @@ gnc_transaction_set_property(GObject* object, GParamSpec* pspec) { Transaction* tx; - KvpFrame *frame; gchar *key; g_return_if_fail(GNC_IS_TRANSACTION(object)); @@ -633,7 +631,7 @@ dupe_trans (const Transaction *from) to->inst.e_type = NULL; qof_instance_set_guid(to, guid_null()); qof_instance_copy_book(to, from); - to->inst.kvp_data = kvp_frame_copy (from->inst.kvp_data); + qof_instance_copy_kvp (QOF_INSTANCE(to), QOF_INSTANCE(from)); return to; } @@ -688,7 +686,7 @@ xaccTransClone (const Transaction *from) int length = g_list_length (from->splits); xaccTransBeginEdit (to); - to->inst.kvp_data = kvp_frame_copy (from->inst.kvp_data); + qof_instance_copy_kvp (QOF_INSTANCE (to), QOF_INSTANCE (from)); g_assert (g_list_length (to->splits) == length); for (i = 0; i < length; ++i) xaccSplitCopyKvp (g_list_nth_data (from->splits, i), @@ -934,13 +932,14 @@ xaccTransEqual(const Transaction *ta, const Transaction *tb, return FALSE; } - if (kvp_frame_compare(ta->inst.kvp_data, tb->inst.kvp_data) != 0) + if (qof_instance_compare_kvp (QOF_INSTANCE (ta), QOF_INSTANCE (tb)) != 0) { char *frame_a; char *frame_b; - frame_a = kvp_frame_to_string (ta->inst.kvp_data); - frame_b = kvp_frame_to_string (tb->inst.kvp_data); + frame_a = qof_instance_kvp_as_string (QOF_INSTANCE (ta)); + frame_b = qof_instance_kvp_as_string (QOF_INSTANCE (tb)); + PINFO ("kvp frames differ:\n%s\n\nvs\n\n%s", frame_a, frame_b); @@ -1688,7 +1687,7 @@ xaccTransRollbackEdit (Transaction *trans) trans->date_entered = orig->date_entered; trans->date_posted = orig->date_posted; SWAP(trans->common_currency, orig->common_currency); - SWAP(trans->inst.kvp_data, orig->inst.kvp_data); + qof_instance_swap_kvp (QOF_INSTANCE (trans), QOF_INSTANCE (orig)); /* The splits at the front of trans->splits are exactly the same splits as in the original, but some of them may have changed, so @@ -1713,7 +1712,7 @@ xaccTransRollbackEdit (Transaction *trans) xaccSplitRollbackEdit(s); SWAP(s->action, so->action); SWAP(s->memo, so->memo); - SWAP(s->inst.kvp_data, so->inst.kvp_data); + qof_instance_copy_kvp (QOF_INSTANCE (s), QOF_INSTANCE (so)); s->reconciled = so->reconciled; s->amount = so->amount; s->value = so->value; @@ -1924,20 +1923,15 @@ xaccTransSetDatePostedSecsNormalized (Transaction *trans, time64 time) void xaccTransSetDatePostedGDate (Transaction *trans, GDate date) { - KvpValue* kvp_value; - KvpFrame* frame; + GValue v = G_VALUE_INIT; if (!trans) return; /* We additionally save this date into a kvp frame to ensure in * the future a date which was set as *date* (without time) can * clearly be distinguished from the Timespec. */ - kvp_value = kvp_value_new_gdate(date); - frame = kvp_frame_set_value_nc(trans->inst.kvp_data, TRANS_DATE_POSTED, kvp_value); - if (!frame) - { - kvp_value_delete(kvp_value); - } - + g_value_init (&v, G_TYPE_DATE); + g_value_set_boxed (&v, &date); + qof_instance_set_kvp (QOF_INSTANCE(trans), TRANS_DATE_POSTED, &v); /* mark dirty and commit handled by SetDateInternal */ xaccTransSetDateInternal(trans, &trans->date_posted, gdate_to_timespec(date)); @@ -2002,9 +1996,12 @@ xaccTransSetDate (Transaction *trans, int day, int mon, int year) void xaccTransSetDateDueTS (Transaction *trans, const Timespec *ts) { + GValue v = G_VALUE_INIT; if (!trans || !ts) return; + g_value_init (&v, GNC_TYPE_TIMESPEC); + g_value_set_boxed (&v, ts); xaccTransBeginEdit(trans); - kvp_frame_set_timespec (trans->inst.kvp_data, TRANS_DATE_DUE_KVP, *ts); + qof_instance_set_kvp (QOF_INSTANCE (trans), TRANS_DATE_DUE_KVP, &v); qof_instance_set_dirty(QOF_INSTANCE(trans)); xaccTransCommitEdit(trans); } @@ -2013,9 +2010,12 @@ void xaccTransSetTxnType (Transaction *trans, char type) { char s[2] = {type, '\0'}; + GValue v = G_VALUE_INIT; g_return_if_fail(trans); + g_value_init (&v, G_TYPE_STRING); + g_value_set_string (&v, s); xaccTransBeginEdit(trans); - kvp_frame_set_string (trans->inst.kvp_data, TRANS_TXN_TYPE_KVP, s); + qof_instance_set_kvp (QOF_INSTANCE (trans), TRANS_TXN_TYPE_KVP, &v); qof_instance_set_dirty(QOF_INSTANCE(trans)); xaccTransCommitEdit(trans); } @@ -2025,8 +2025,8 @@ void xaccTransClearReadOnly (Transaction *trans) if (trans) { xaccTransBeginEdit(trans); - kvp_frame_set_slot_path (trans->inst.kvp_data, NULL, - TRANS_READ_ONLY_REASON, NULL); + qof_instance_set_kvp (QOF_INSTANCE (trans), + TRANS_READ_ONLY_REASON, NULL); qof_instance_set_dirty(QOF_INSTANCE(trans)); xaccTransCommitEdit(trans); } @@ -2037,9 +2037,11 @@ xaccTransSetReadOnly (Transaction *trans, const char *reason) { if (trans && reason) { + GValue v = G_VALUE_INIT; + g_value_init (&v, G_TYPE_STRING); + g_value_set_string (&v, reason); xaccTransBeginEdit(trans); - kvp_frame_set_string (trans->inst.kvp_data, - TRANS_READ_ONLY_REASON, reason); + qof_instance_set_kvp (QOF_INSTANCE (trans), TRANS_READ_ONLY_REASON, &v); qof_instance_set_dirty(QOF_INSTANCE(trans)); xaccTransCommitEdit(trans); } @@ -2092,10 +2094,12 @@ xaccTransSetDescription (Transaction *trans, const char *desc) void xaccTransSetAssociation (Transaction *trans, const char *assoc) { + GValue v = G_VALUE_INIT; if (!trans || !assoc) return; + g_value_init (&v, G_TYPE_STRING); + g_value_set_string (&v, assoc); xaccTransBeginEdit(trans); - - kvp_frame_set_string (trans->inst.kvp_data, assoc_uri_str, assoc); + qof_instance_set_kvp (QOF_INSTANCE (trans), assoc_uri_str, &v); qof_instance_set_dirty(QOF_INSTANCE(trans)); xaccTransCommitEdit(trans); } @@ -2111,10 +2115,13 @@ qofTransSetNotes (Transaction *trans, const char *notes) void xaccTransSetNotes (Transaction *trans, const char *notes) { + GValue v = G_VALUE_INIT; if (!trans || !notes) return; + g_value_init (&v, G_TYPE_STRING); + g_value_set_string (&v, notes); xaccTransBeginEdit(trans); - kvp_frame_set_string (trans->inst.kvp_data, trans_notes_str, notes); + qof_instance_set_kvp (QOF_INSTANCE (trans), trans_notes_str, &v); qof_instance_set_dirty(QOF_INSTANCE(trans)); xaccTransCommitEdit(trans); } @@ -2126,9 +2133,14 @@ xaccTransSetIsClosingTxn (Transaction *trans, gboolean is_closing) xaccTransBeginEdit(trans); if (is_closing) - kvp_frame_set_gint64 (trans->inst.kvp_data, trans_is_closing_str, 1); + { + GValue v = G_VALUE_INIT; + g_value_init (&v, G_TYPE_INT64); + g_value_set_int64 (&v, 1); + qof_instance_set_kvp (QOF_INSTANCE (trans), trans_is_closing_str, &v); + } else - kvp_frame_replace_value_nc (trans->inst.kvp_data, trans_is_closing_str, NULL); + qof_instance_set_kvp (QOF_INSTANCE (trans), trans_is_closing_str, NULL); qof_instance_set_dirty(QOF_INSTANCE(trans)); xaccTransCommitEdit(trans); } @@ -2186,23 +2198,31 @@ xaccTransGetDescription (const Transaction *trans) const char * xaccTransGetAssociation (const Transaction *trans) { - return trans ? - kvp_frame_get_string (trans->inst.kvp_data, assoc_uri_str) : NULL; + GValue v = G_VALUE_INIT; + if (!trans) return NULL; + g_value_init (&v, G_TYPE_STRING); + qof_instance_get_kvp (QOF_INSTANCE (trans), assoc_uri_str, &v); + return g_value_get_string (&v); } const char * xaccTransGetNotes (const Transaction *trans) { - return trans ? - kvp_frame_get_string (trans->inst.kvp_data, trans_notes_str) : NULL; + GValue v = G_VALUE_INIT; + if (!trans) return NULL; + g_value_init (&v, G_TYPE_STRING); + qof_instance_get_kvp (QOF_INSTANCE (trans), trans_notes_str, &v); + return g_value_get_string (&v); } gboolean xaccTransGetIsClosingTxn (const Transaction *trans) { - return trans ? - kvp_frame_get_gint64 (trans->inst.kvp_data, trans_is_closing_str) - : FALSE; + GValue v = G_VALUE_INIT; + if (!trans) return FALSE; + g_value_init (&v, G_TYPE_INT64); + qof_instance_get_kvp (QOF_INSTANCE (trans), trans_is_closing_str, &v); + return g_value_get_int64 (&v); } /********************************************************************\ @@ -2252,11 +2272,11 @@ xaccTransGetDatePostedGDate (const Transaction *trans) /* Can we look up this value in the kvp slot? If yes, use it * from there because it doesn't suffer from time zone * shifts. */ - const KvpValue* kvp_value = - kvp_frame_get_slot(trans->inst.kvp_data, TRANS_DATE_POSTED); - if (kvp_value) - result = kvp_value_get_gdate(kvp_value); - else + GValue v = G_VALUE_INIT; + g_value_init (&v, G_TYPE_DATE); + qof_instance_get_kvp (QOF_INSTANCE (trans), TRANS_DATE_POSTED, &v); + result = *(GDate*)g_value_get_boxed (&v); + if (! g_date_valid (&result)) result = timespec_to_gdate(xaccTransRetDatePostedTS(trans)); } else @@ -2276,14 +2296,13 @@ xaccTransRetDateEnteredTS (const Transaction *trans) void xaccTransGetDateDueTS (const Transaction *trans, Timespec *ts) { - KvpValue *value; - + GValue v = G_VALUE_INIT; if (!trans || !ts) return; - value = kvp_frame_get_slot (trans->inst.kvp_data, TRANS_DATE_DUE_KVP); - if (value) - *ts = kvp_value_get_timespec (value); - else + g_value_init (&v, GNC_TYPE_TIMESPEC); + qof_instance_get_kvp (QOF_INSTANCE (trans), TRANS_DATE_DUE_KVP, &v); + *ts = *(Timespec*)g_value_get_boxed (&v); + if (ts->tv_sec == 0) xaccTransGetDatePostedTS (trans, ts); } @@ -2299,9 +2318,14 @@ char xaccTransGetTxnType (const Transaction *trans) { const char *s; + GValue v = G_VALUE_INIT; + if (!trans) return TXN_TYPE_NONE; - s = kvp_frame_get_string (trans->inst.kvp_data, TRANS_TXN_TYPE_KVP); - if (s) return *s; + g_value_init (&v, G_TYPE_STRING); + qof_instance_get_kvp (QOF_INSTANCE (trans), TRANS_TXN_TYPE_KVP, &v); + s = g_value_get_string (&v); + if (s && strlen (s) == 0) + return *s; return TXN_TYPE_NONE; } @@ -2312,8 +2336,16 @@ xaccTransGetReadOnly (const Transaction *trans) /* XXX This flag should be cached in the transaction structure * for performance reasons, since its checked every trans commit. */ - return trans ? kvp_frame_get_string ( - trans->inst.kvp_data, TRANS_READ_ONLY_REASON) : NULL; + GValue v = G_VALUE_INIT; + const char *s; + if (trans == NULL) return NULL; + g_value_init (&v, G_TYPE_STRING); + qof_instance_get_kvp (QOF_INSTANCE(trans), TRANS_READ_ONLY_REASON, &v); + s = g_value_get_string (&v); + if (s && strlen (s)) + return s; + + return NULL; } static gboolean @@ -2491,26 +2523,24 @@ gnc_book_count_transactions(QofBook *book) void xaccTransVoid(Transaction *trans, const char *reason) { - KvpFrame *frame; - KvpValue *val; - Timespec now; + GValue v = G_VALUE_INIT; char iso8601_str[ISO_DATELENGTH + 1] = ""; g_return_if_fail(trans && reason); xaccTransBeginEdit(trans); - frame = trans->inst.kvp_data; + g_value_init (&v, G_TYPE_STRING); + qof_instance_get_kvp (QOF_INSTANCE (trans), trans_notes_str, &v); + qof_instance_set_kvp (QOF_INSTANCE (trans), void_former_notes_str, &v); - val = kvp_frame_get_slot(frame, trans_notes_str); - kvp_frame_set_slot(frame, void_former_notes_str, val); + g_value_set_string (&v, _("Voided transaction")); + qof_instance_set_kvp (QOF_INSTANCE (trans), trans_notes_str, &v); + g_value_set_string (&v, reason); + qof_instance_set_kvp (QOF_INSTANCE (trans), void_reason_str, &v); - kvp_frame_set_string(frame, trans_notes_str, _("Voided transaction")); - kvp_frame_set_string(frame, void_reason_str, reason); - - now.tv_sec = gnc_time (NULL); - now.tv_nsec = 0; - gnc_timespec_to_iso8601_buff(now, iso8601_str); - kvp_frame_set_string(frame, void_time_str, iso8601_str); + gnc_timespec_to_iso8601_buff (timespec_now (), iso8601_str); + g_value_set_string (&v, iso8601_str); + qof_instance_set_kvp (QOF_INSTANCE (trans), void_time_str, &v); FOR_EACH_SPLIT(trans, xaccSplitVoid(s)); @@ -2522,48 +2552,61 @@ xaccTransVoid(Transaction *trans, const char *reason) gboolean xaccTransGetVoidStatus(const Transaction *trans) { + const char *s; + GValue v = G_VALUE_INIT; g_return_val_if_fail(trans, FALSE); - return (kvp_frame_get_slot(trans->inst.kvp_data, void_reason_str) != NULL); + + g_value_init (&v, G_TYPE_STRING); + qof_instance_get_kvp (QOF_INSTANCE (trans), void_reason_str, &v); + s = g_value_get_string (&v); + return s && strlen(s); } const char * xaccTransGetVoidReason(const Transaction *trans) { - g_return_val_if_fail(trans, NULL); - return kvp_frame_get_string(trans->inst.kvp_data, void_reason_str); + GValue v = G_VALUE_INIT; + g_return_val_if_fail(trans, FALSE); + + g_value_init (&v, G_TYPE_STRING); + qof_instance_get_kvp (QOF_INSTANCE (trans), void_reason_str, &v); + return g_value_get_string (&v); } Timespec xaccTransGetVoidTime(const Transaction *tr) { - const char *val; - Timespec void_time = {0, 0}; + GValue v = G_VALUE_INIT; + const char *s; + Timespec void_time = {0, 0}, *ts; g_return_val_if_fail(tr, void_time); - - val = kvp_frame_get_string(tr->inst.kvp_data, void_time_str); - return val ? gnc_iso8601_to_timespec_gmt(val) : void_time; + g_value_init (&v, G_TYPE_STRING); + qof_instance_get_kvp (QOF_INSTANCE (tr), void_time_str, &v); + s = g_value_get_string (&v); + if (s) + return gnc_iso8601_to_timespec_gmt (s); + return void_time; } void xaccTransUnvoid (Transaction *trans) { - KvpFrame *frame; - KvpValue *val; - + GValue v = G_VALUE_INIT; + const char *s; g_return_if_fail(trans); - frame = trans->inst.kvp_data; - val = kvp_frame_get_slot(frame, void_reason_str); - if (!val) return; /* Transaction isn't voided. Bail. */ - + g_value_init (&v, G_TYPE_STRING); + qof_instance_get_kvp (QOF_INSTANCE (trans), void_reason_str, &v); + s = g_value_get_string (&v); + if (s == NULL) return; /* Transaction isn't voided. Bail. */ xaccTransBeginEdit(trans); - val = kvp_frame_get_slot(frame, void_former_notes_str); - kvp_frame_set_slot(frame, trans_notes_str, val); - kvp_frame_set_slot_nc(frame, void_former_notes_str, NULL); - kvp_frame_set_slot_nc(frame, void_reason_str, NULL); - kvp_frame_set_slot_nc(frame, void_time_str, NULL); + qof_instance_get_kvp (QOF_INSTANCE (trans), void_former_notes_str, &v); + qof_instance_set_kvp (QOF_INSTANCE (trans), trans_notes_str, &v); + qof_instance_set_kvp (QOF_INSTANCE (trans), void_former_notes_str, NULL); + qof_instance_set_kvp (QOF_INSTANCE (trans), void_reason_str, NULL); + qof_instance_set_kvp (QOF_INSTANCE (trans), void_time_str, NULL); FOR_EACH_SPLIT(trans, xaccSplitUnvoid(s)); @@ -2576,7 +2619,7 @@ Transaction * xaccTransReverse (Transaction *orig) { Transaction *trans; - KvpValue *kvp_val; + GValue v = G_VALUE_INIT; g_return_val_if_fail(orig, NULL); trans = xaccTransClone(orig); @@ -2591,8 +2634,9 @@ xaccTransReverse (Transaction *orig) }); /* Now update the original with a pointer to the new one */ - kvp_val = kvp_value_new_guid(xaccTransGetGUID(trans)); - kvp_frame_set_slot_nc(orig->inst.kvp_data, TRANS_REVERSED_BY, kvp_val); + g_value_init (&v, GNC_TYPE_GUID); + g_value_set_boxed (&v, xaccTransGetGUID(trans)); + qof_instance_set_kvp (QOF_INSTANCE (orig), TRANS_REVERSED_BY, &v); qof_instance_set_dirty(QOF_INSTANCE(trans)); xaccTransCommitEdit(trans); @@ -2602,11 +2646,12 @@ xaccTransReverse (Transaction *orig) Transaction * xaccTransGetReversedBy(const Transaction *trans) { - GncGUID *guid; - + GValue v = G_VALUE_INIT; g_return_val_if_fail(trans, NULL); - guid = kvp_frame_get_guid(trans->inst.kvp_data, TRANS_REVERSED_BY); - return xaccTransLookup(guid, qof_instance_get_book(trans)); + g_value_init (&v, GNC_TYPE_GUID); + qof_instance_get_kvp (QOF_INSTANCE(trans), TRANS_REVERSED_BY, &v); + return xaccTransLookup((GncGUID*)g_value_get_boxed (&v), + qof_instance_get_book(trans)); } void @@ -2849,10 +2894,6 @@ gboolean xaccTransRegister (void) TRANS_SPLITLIST, GNC_ID_SPLIT, (QofAccessFunc)xaccTransGetSplitList, NULL }, - { - TRANS_KVP, QOF_TYPE_KVP, - (QofAccessFunc)qof_instance_get_slots, NULL - }, { QOF_PARAM_BOOK, QOF_ID_BOOK, (QofAccessFunc)qof_instance_get_book, NULL From 97031fa62a98dda7cced40c0b485450122827726 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Fri, 8 May 2015 15:13:12 -0700 Subject: [PATCH 05/54] Correct the kvpvalue type for lot-split in test_xaccSplitOtherSplit. --- src/engine/test/utest-Split.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/engine/test/utest-Split.cpp b/src/engine/test/utest-Split.cpp index 4e3425df2d..6a5000cb8f 100644 --- a/src/engine/test/utest-Split.cpp +++ b/src/engine/test/utest-Split.cpp @@ -1777,7 +1777,7 @@ test_xaccSplitGetOtherSplit (Fixture *fixture, gconstpointer pData) Split *split1 = xaccMallocSplit (book); Split *split2 = xaccMallocSplit (book); Account *acc2 = xaccMallocAccount (book); - KvpValue *kvptrue = kvp_value_new_string ("t"); + KvpValue *kvpnow = kvp_value_new_gint64 (gnc_time (NULL)); g_assert (xaccSplitGetOtherSplit (NULL) == NULL); g_assert (xaccSplitGetOtherSplit (split1) == NULL); @@ -1794,11 +1794,11 @@ test_xaccSplitGetOtherSplit (Fixture *fixture, gconstpointer pData) xaccSplitSetParent (split2, txn); g_assert (xaccSplitGetOtherSplit (split) == NULL); - kvp_frame_set_slot (split->inst.kvp_data, "lot-split", kvptrue); + kvp_frame_set_slot (split->inst.kvp_data, "lot-split", kvpnow); g_assert (kvp_frame_get_slot (split->inst.kvp_data, "lot-split")); g_assert (xaccSplitGetOtherSplit (split) == NULL); - kvp_frame_set_slot (split1->inst.kvp_data, "lot-split", kvptrue); + kvp_frame_set_slot (split1->inst.kvp_data, "lot-split", kvpnow); g_assert (kvp_frame_get_slot (split1->inst.kvp_data, "lot-split")); g_assert (xaccSplitGetOtherSplit (split) == split2); From 97b44a71ec204649500f5c2913a18199882717d0 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Fri, 8 May 2015 15:15:39 -0700 Subject: [PATCH 06/54] Convert all Split kV operations to use qof_instance_foo_kvp(). Except for clearing the KVP Frame, which we do by calling qof_instance_dispose(). --- src/engine/Split.c | 90 ++++++++++++++++++++++++++-------------------- 1 file changed, 52 insertions(+), 38 deletions(-) diff --git a/src/engine/Split.c b/src/engine/Split.c index 05905bb77c..88b0f58358 100644 --- a/src/engine/Split.c +++ b/src/engine/Split.c @@ -571,9 +571,6 @@ xaccSplitReinit(Split * split) split->cleared_balance = gnc_numeric_zero(); split->reconciled_balance = gnc_numeric_zero(); - if (split->inst.kvp_data) - kvp_frame_delete(split->inst.kvp_data); - split->inst.kvp_data = kvp_frame_new(); qof_instance_set_idata(split, 0); split->gains = GAINS_STATUS_UNKNOWN; @@ -625,7 +622,7 @@ xaccDupeSplit (const Split *s) split->memo = CACHE_INSERT(s->memo); split->action = CACHE_INSERT(s->action); - split->inst.kvp_data = kvp_frame_copy (s->inst.kvp_data); + qof_instance_copy_kvp (QOF_INSTANCE (split), QOF_INSTANCE (s)); split->reconciled = s->reconciled; split->date_reconciled = s->date_reconciled; @@ -675,7 +672,7 @@ xaccSplitCloneNoKvp (const Split *s) void xaccSplitCopyKvp (const Split *from, Split *to) { - to->inst.kvp_data = kvp_frame_copy(from->inst.kvp_data); + qof_instance_copy_kvp (QOF_INSTANCE (to), QOF_INSTANCE (from)); } /*################## Added for Reg2 #################*/ @@ -727,7 +724,7 @@ xaccSplitDump (const Split *split, const char *tag) printf(" Gains: %p\n", split->gains_split); printf(" Memo: %s\n", split->memo ? split->memo : "(null)"); printf(" Action: %s\n", split->action ? split->action : "(null)"); - printf(" KVP Data: %p\n", split->inst.kvp_data); + printf(" KVP Data: %s\n", qof_instance_kvp_as_string (QOF_INSTANCE (split)); printf(" Recncld: %c (date %s)\n", split->reconciled, gnc_print_date(split->date_reconciled)); printf(" Value: %s\n", gnc_numeric_to_string(split->value)); @@ -770,10 +767,7 @@ xaccFreeSplit (Split *split) split->date_reconciled.tv_sec = 0; split->date_reconciled.tv_nsec = 0; - if (split->inst.kvp_data) - kvp_frame_delete(split->inst.kvp_data); - split->inst.kvp_data = NULL; - + G_OBJECT_CLASS (QOF_INSTANCE_GET_CLASS (&split->inst))->dispose(G_OBJECT (split)); // Is this right? if (split->gains_split) split->gains_split->gains_split = NULL; /* qof_instance_release(&split->inst); */ @@ -859,13 +853,13 @@ xaccSplitEqual(const Split *sa, const Split *sb, return FALSE; } - if (kvp_frame_compare(sa->inst.kvp_data, sb->inst.kvp_data) != 0) + if (qof_instance_compare_kvp (QOF_INSTANCE (sa), QOF_INSTANCE (sb)) != 0) { char *frame_a; char *frame_b; - frame_a = kvp_frame_to_string (sa->inst.kvp_data); - frame_b = kvp_frame_to_string (sb->inst.kvp_data); + frame_a = qof_instance_kvp_as_string (QOF_INSTANCE (sa)); + frame_b = qof_instance_kvp_as_string (QOF_INSTANCE (sb)); PINFO ("kvp frames differ:\n%s\n\nvs\n\n%s", frame_a, frame_b); @@ -1128,7 +1122,8 @@ void xaccSplitDetermineGainStatus (Split *split) { Split *other; - KvpValue *val; + GValue v = G_VALUE_INIT; + GncGUID *guid; if (GAINS_STATUS_UNKNOWN != split->gains) return; @@ -1140,8 +1135,10 @@ xaccSplitDetermineGainStatus (Split *split) return; } - val = kvp_frame_get_slot (split->inst.kvp_data, "gains-source"); - if (!val) + g_value_init (&v, GNC_TYPE_GUID); + qof_instance_get_kvp (QOF_INSTANCE (split), "gains-source", &v); + guid = (GncGUID*)g_value_get_boxed (&v); + if (!guid) { // CHECKME: We leave split->gains_split alone. Is that correct? split->gains = GAINS_STATUS_A_VDIRTY | GAINS_STATUS_DATE_DIRTY; @@ -1149,10 +1146,10 @@ xaccSplitDetermineGainStatus (Split *split) else { QofCollection *col; - col = qof_book_get_collection (qof_instance_get_book(split), GNC_ID_SPLIT); + col = qof_book_get_collection (qof_instance_get_book(split), + GNC_ID_SPLIT); split->gains = GAINS_STATUS_GAINS; - other = (Split *) qof_collection_lookup_entity (col, - kvp_value_get_guid (val)); + other = (Split *) qof_collection_lookup_entity (col, guid); split->gains_split = other; } } @@ -2052,10 +2049,13 @@ xaccSplitGetBook (const Split *split) const char * xaccSplitGetType(const Split *s) { + GValue v = G_VALUE_INIT; const char *split_type; if (!s) return NULL; - split_type = kvp_frame_get_string(s->inst.kvp_data, "split-type"); + g_value_init (&v, G_TYPE_STRING); + qof_instance_get_kvp (QOF_INSTANCE (s), "split-type", &v); + split_type = g_value_get_string (&v); return split_type ? split_type : "normal"; } @@ -2064,10 +2064,13 @@ xaccSplitGetType(const Split *s) void xaccSplitMakeStockSplit(Split *s) { + GValue v = G_VALUE_INIT; xaccTransBeginEdit (s->parent); s->value = gnc_numeric_zero(); - kvp_frame_set_string(s->inst.kvp_data, "split-type", "stock-split"); + g_value_init (&v, G_TYPE_STRING); + g_value_set_string (&v, "stock-split"); + qof_instance_set_kvp (QOF_INSTANCE (s), "split-type", &v); SET_GAINS_VDIRTY(s); mark_split(s); qof_instance_set_dirty(QOF_INSTANCE(s)); @@ -2094,7 +2097,7 @@ xaccSplitGetOtherSplit (const Split *split) Transaction *trans; int count, num_splits; Split *other = NULL; - KvpValue *sva; + gint64 lot_split; gboolean trading_accts; if (!split) return NULL; @@ -2115,8 +2118,8 @@ xaccSplitGetOtherSplit (const Split *split) trading_accts = xaccTransUseTradingAccounts (trans); num_splits = xaccTransCountSplits(trans); count = num_splits; - sva = kvp_frame_get_slot (split->inst.kvp_data, "lot-split"); - if (!sva && !trading_accts && (2 != count)) return NULL; + g_object_get (G_OBJECT (split), "lot-split", &lot_split, NULL); + if (!lot_split && !trading_accts && (2 != count)) return NULL; for (i = 0; i < num_splits; i++) { @@ -2126,7 +2129,8 @@ xaccSplitGetOtherSplit (const Split *split) --count; continue; } - if (kvp_frame_get_slot (s->inst.kvp_data, "lot-split")) + g_object_get (G_OBJECT (s), "lot-split", &lot_split, NULL); + if (lot_split) { --count; continue; @@ -2148,27 +2152,40 @@ xaccSplitGetOtherSplit (const Split *split) gnc_numeric xaccSplitVoidFormerAmount(const Split *split) { + GValue v = G_VALUE_INIT; + gnc_numeric *num; g_return_val_if_fail(split, gnc_numeric_zero()); - return kvp_frame_get_numeric(split->inst.kvp_data, void_former_amt_str); + g_value_init (&v, GNC_TYPE_NUMERIC); + qof_instance_get_kvp (QOF_INSTANCE (split), void_former_amt_str, &v); + num = (gnc_numeric*)g_value_get_boxed (&v); + return num ? *num : gnc_numeric_zero(); } gnc_numeric xaccSplitVoidFormerValue(const Split *split) { + GValue v = G_VALUE_INIT; + gnc_numeric *num; g_return_val_if_fail(split, gnc_numeric_zero()); - return kvp_frame_get_numeric(split->inst.kvp_data, void_former_val_str); + g_value_init (&v, GNC_TYPE_NUMERIC); + qof_instance_get_kvp (QOF_INSTANCE (split), void_former_val_str, &v); + num = (gnc_numeric*)g_value_get_boxed (&v); + return num ? *num : gnc_numeric_zero(); } void xaccSplitVoid(Split *split) { - gnc_numeric zero = gnc_numeric_zero(); - KvpFrame *frame = split->inst.kvp_data; + gnc_numeric zero = gnc_numeric_zero(), num; + GValue v = G_VALUE_INIT; - kvp_frame_set_gnc_numeric(frame, void_former_amt_str, - xaccSplitGetAmount(split)); - kvp_frame_set_gnc_numeric(frame, void_former_val_str, - xaccSplitGetValue(split)); + g_value_init (&v, GNC_TYPE_NUMERIC); + num = xaccSplitGetAmount(split); + g_value_set_boxed (&v, &num); + qof_instance_set_kvp (QOF_INSTANCE (split), void_former_amt_str, &v); + num = xaccSplitGetValue(split); + g_value_set_boxed (&v, &num); + qof_instance_set_kvp (QOF_INSTANCE (split), void_former_val_str, &v); /* Marking dirty handled by SetAmount etc. */ xaccSplitSetAmount (split, zero); @@ -2179,13 +2196,11 @@ xaccSplitVoid(Split *split) void xaccSplitUnvoid(Split *split) { - KvpFrame *frame = split->inst.kvp_data; - xaccSplitSetAmount (split, xaccSplitVoidFormerAmount(split)); xaccSplitSetValue (split, xaccSplitVoidFormerValue(split)); xaccSplitSetReconcile(split, NREC); - kvp_frame_set_slot(frame, void_former_amt_str, NULL); - kvp_frame_set_slot(frame, void_former_val_str, NULL); + qof_instance_set_kvp (QOF_INSTANCE (split), void_former_amt_str, NULL); + qof_instance_set_kvp (QOF_INSTANCE (split), void_former_val_str, NULL); qof_instance_set_dirty (QOF_INSTANCE (split)); } @@ -2342,7 +2357,6 @@ gboolean xaccSplitRegister (void) { SPLIT_ACCT_FULLNAME, SPLIT_ACCT_FULLNAME, no_op, NULL }, { SPLIT_CORR_ACCT_NAME, SPLIT_CORR_ACCT_NAME, no_op, NULL }, { SPLIT_CORR_ACCT_CODE, SPLIT_CORR_ACCT_CODE, no_op, NULL }, - { SPLIT_KVP, QOF_TYPE_KVP, (QofAccessFunc)qof_instance_get_slots, NULL }, { QOF_PARAM_BOOK, QOF_ID_BOOK, (QofAccessFunc)xaccSplitGetBook, NULL }, { QOF_PARAM_GUID, QOF_TYPE_GUID, From 39c521512b5a18f6eb12770947c1a4e43286b23b Mon Sep 17 00:00:00 2001 From: John Ralls Date: Sun, 10 May 2015 18:15:19 -0700 Subject: [PATCH 07/54] Provide qof_instance_has_kvp(); used for feature testing. --- src/libqof/qof/qofinstance-p.h | 1 + src/libqof/qof/qofinstance.cpp | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/src/libqof/qof/qofinstance-p.h b/src/libqof/qof/qofinstance-p.h index 2428ad9935..e04867934d 100644 --- a/src/libqof/qof/qofinstance-p.h +++ b/src/libqof/qof/qofinstance-p.h @@ -106,6 +106,7 @@ void qof_instance_set_version_check (gpointer inst, guint32 value); void qof_instance_copy_version_check (gpointer to, gconstpointer from); void qof_instance_set_idata(gpointer inst, guint32 idata); /* Convenience functions to save some typing in property handlers */ +gboolean qof_instance_has_kvp (QofInstance *inst); void qof_instance_set_kvp (QofInstance *inst, const gchar *key, const GValue *value); void qof_instance_get_kvp (QofInstance *inst, const gchar *key, GValue *value); void qof_instance_copy_kvp (QofInstance *to, const QofInstance *from); diff --git a/src/libqof/qof/qofinstance.cpp b/src/libqof/qof/qofinstance.cpp index d545fdf711..161fc352d8 100644 --- a/src/libqof/qof/qofinstance.cpp +++ b/src/libqof/qof/qofinstance.cpp @@ -1066,6 +1066,13 @@ qof_commit_edit_part2(QofInstance *inst, return TRUE; } +gboolean +qof_instance_has_kvp (QofInstance *inst) +{ + KvpFrame *frame = qof_instance_get_slots (inst); + return (frame != NULL && !kvp_frame_is_empty (frame)); +} + void qof_instance_set_kvp (QofInstance *inst, const gchar *key, const GValue *value) { From 45e41a07b14b4a274a5d843f12785daefbb17b9b Mon Sep 17 00:00:00 2001 From: John Ralls Date: Sun, 10 May 2015 18:16:30 -0700 Subject: [PATCH 08/54] Convert gnc-budget, gnc-lot, and gncJob to qof_instance_foo_kvp. --- src/engine/gnc-budget.c | 107 ++++++++++++++++++++------------------- src/engine/gnc-lot.c | 108 +++++++++++++++++++++------------------- src/engine/gncJob.c | 60 ++++++++++++---------- 3 files changed, 146 insertions(+), 129 deletions(-) diff --git a/src/engine/gnc-budget.c b/src/engine/gnc-budget.c index 8fd057da31..c9be5d1eb8 100644 --- a/src/engine/gnc-budget.c +++ b/src/engine/gnc-budget.c @@ -42,11 +42,11 @@ static QofLogModule log_module = GNC_MOD_ENGINE; enum { PROP_0, - PROP_NAME, /* Table */ - PROP_DESCRIPTION, /* Table */ - PROP_NUM_PERIODS, /* Table */ + PROP_NAME, /* Table */ + PROP_DESCRIPTION, /* Table */ + PROP_NUM_PERIODS, /* Table */ PROP_RUNTIME_0, - PROP_RECURRENCE, /* Cached pointer; Recurrence table holds budget guid */ + PROP_RECURRENCE, /* Cached pointer; Recurrence table holds budget guid */ }; struct budget_s @@ -159,7 +159,7 @@ gnc_budget_set_property( GObject* object, budget = GNC_BUDGET(object); if (prop_id < PROP_RUNTIME_0) - g_assert (qof_instance_get_editlevel(budget)); + g_assert (qof_instance_get_editlevel(budget)); switch ( prop_id ) { @@ -476,24 +476,29 @@ gnc_budget_get_num_periods(const GncBudget* budget) #define BUF_SIZE (10 + GUID_ENCODING_LENGTH + \ GNC_BUDGET_MAX_NUM_PERIODS_DIGITS) +static inline void +make_period_path (const Account *account, guint period_num, char *path) +{ + const GncGUID *guid; + gchar *bufend; + guid = xaccAccountGetGUID(account); + bufend = guid_to_string_buff(guid, path); + g_sprintf(bufend, "/%d", period_num); +} /* period_num is zero-based */ /* What happens when account is deleted, after we have an entry for it? */ void gnc_budget_unset_account_period_value(GncBudget *budget, const Account *account, guint period_num) { - const GncGUID *guid; - KvpFrame *frame; gchar path[BUF_SIZE]; - gchar *bufend; + + g_return_if_fail (budget != NULL); + g_return_if_fail (account != NULL); + make_period_path (account, period_num, path); gnc_budget_begin_edit(budget); - frame = qof_instance_get_slots(QOF_INSTANCE(budget)); - guid = xaccAccountGetGUID(account); - bufend = guid_to_string_buff(guid, path); - g_sprintf(bufend, "/%d", period_num); - - kvp_frame_set_value(frame, path, NULL); + qof_instance_set_kvp (QOF_INSTANCE (budget), path, NULL); qof_instance_set_dirty(&budget->inst); gnc_budget_commit_edit(budget); @@ -507,10 +512,7 @@ void gnc_budget_set_account_period_value(GncBudget *budget, const Account *account, guint period_num, gnc_numeric val) { - const GncGUID *guid; - KvpFrame *frame; gchar path[BUF_SIZE]; - gchar *bufend; /* Watch out for an off-by-one error here: * period_num starts from 0 while num_periods starts from 1 */ @@ -520,16 +522,21 @@ gnc_budget_set_account_period_value(GncBudget *budget, const Account *account, return; } - gnc_budget_begin_edit(budget); - frame = qof_instance_get_slots(QOF_INSTANCE(budget)); - guid = xaccAccountGetGUID(account); - bufend = guid_to_string_buff(guid, path); - g_sprintf(bufend, "/%d", period_num); + g_return_if_fail (budget != NULL); + g_return_if_fail (account != NULL); + make_period_path (account, period_num, path); + + gnc_budget_begin_edit(budget); if (gnc_numeric_check(val)) - kvp_frame_set_value(frame, path, NULL); + qof_instance_set_kvp (QOF_INSTANCE (budget), path, NULL); else - kvp_frame_set_numeric(frame, path, val); + { + GValue v = G_VALUE_INIT; + g_value_init (&v, GNC_TYPE_NUMERIC); + g_value_set_boxed (&v, &val); + qof_instance_set_kvp (QOF_INSTANCE (budget), path, &v); + } qof_instance_set_dirty(&budget->inst); gnc_budget_commit_edit(budget); @@ -541,42 +548,42 @@ gnc_budget_set_account_period_value(GncBudget *budget, const Account *account, Maybe this should move to Account.h */ gboolean -gnc_budget_is_account_period_value_set(const GncBudget *budget, const Account *account, +gnc_budget_is_account_period_value_set(const GncBudget *budget, + const Account *account, guint period_num) { + GValue v = G_VALUE_INIT; gchar path[BUF_SIZE]; - gchar *bufend; - KvpFrame *frame; g_return_val_if_fail(GNC_IS_BUDGET(budget), FALSE); g_return_val_if_fail(account, FALSE); - frame = qof_instance_get_slots(QOF_INSTANCE(budget)); - bufend = guid_to_string_buff(xaccAccountGetGUID(account), path); - g_sprintf(bufend, "/%d", period_num); - return (kvp_frame_get_value(frame, path) != NULL); + make_period_path (account, period_num, path); + g_value_init (&v, GNC_TYPE_NUMERIC); + qof_instance_get_kvp (QOF_INSTANCE (budget), path, &v); + return (g_value_get_boxed (&v) != NULL); } gnc_numeric -gnc_budget_get_account_period_value(const GncBudget *budget, const Account *account, +gnc_budget_get_account_period_value(const GncBudget *budget, + const Account *account, guint period_num) { - gnc_numeric numeric; + gnc_numeric *numeric; gchar path[BUF_SIZE]; - gchar *bufend; - KvpFrame *frame; + GValue v = G_VALUE_INIT; - numeric = gnc_numeric_zero(); - g_return_val_if_fail(GNC_IS_BUDGET(budget), numeric); - g_return_val_if_fail(account, numeric); + g_return_val_if_fail(GNC_IS_BUDGET(budget), gnc_numeric_zero()); + g_return_val_if_fail(account, gnc_numeric_zero()); - frame = qof_instance_get_slots(QOF_INSTANCE(budget)); - bufend = guid_to_string_buff(xaccAccountGetGUID(account), path); - g_sprintf(bufend, "/%d", period_num); + g_value_init (&v, GNC_TYPE_NUMERIC); + make_period_path (account, period_num, path); + qof_instance_get_kvp (QOF_INSTANCE (budget), path, &v); + numeric = (gnc_numeric*)g_value_get_boxed (&v); - numeric = kvp_frame_get_numeric(frame, path); - /* This still returns zero if unset, but callers can check for that. */ - return numeric; + if (numeric) + return *numeric; + return gnc_numeric_zero(); } @@ -637,16 +644,14 @@ gnc_budget_get_default (QofBook *book) g_return_val_if_fail(book, NULL); - /* See if there is a budget selected in the KVP perferences */ - qof_instance_get (QOF_INSTANCE (book), - "default-budget", &default_budget_guid, - NULL); + "default-budget", &default_budget_guid, + NULL); if (default_budget_guid != NULL) { - col = qof_book_get_collection(book, GNC_ID_BUDGET); - bgt = (GncBudget *) qof_collection_lookup_entity(col, - default_budget_guid); + col = qof_book_get_collection(book, GNC_ID_BUDGET); + bgt = (GncBudget *) qof_collection_lookup_entity(col, + default_budget_guid); } /* Revert to 2.2.x behavior if the book has no default budget. */ diff --git a/src/engine/gnc-lot.c b/src/engine/gnc-lot.c index 876bd00be1..7e7145c41a 100644 --- a/src/engine/gnc-lot.c +++ b/src/engine/gnc-lot.c @@ -64,15 +64,15 @@ struct gnc_lot_s enum { PROP_0, -// PROP_ACCOUNT, /* Table */ - PROP_IS_CLOSED, /* Table */ +// PROP_ACCOUNT, /* Table */ + PROP_IS_CLOSED, /* Table */ - PROP_INVOICE, /* KVP */ - PROP_OWNER_TYPE, /* KVP */ - PROP_OWNER_GUID, /* KVP */ + PROP_INVOICE, /* KVP */ + PROP_OWNER_TYPE, /* KVP */ + PROP_OWNER_GUID, /* KVP */ PROP_RUNTIME_0, - PROP_MARKER, /* Runtime */ + PROP_MARKER, /* Runtime */ }; typedef struct LotPrivate @@ -138,7 +138,6 @@ gnc_lot_get_property(GObject* object, guint prop_id, GValue* value, GParamSpec* { GNCLot* lot; LotPrivate* priv; - KvpFrame *frame; gchar *key; GValue *temp; @@ -155,17 +154,17 @@ gnc_lot_get_property(GObject* object, guint prop_id, GValue* value, GParamSpec* g_value_set_int(value, priv->marker); break; case PROP_INVOICE: - key = GNC_INVOICE_ID "/" GNC_INVOICE_GUID; - qof_instance_get_kvp (QOF_INSTANCE (lot), key, value); - break; + key = GNC_INVOICE_ID "/" GNC_INVOICE_GUID; + qof_instance_get_kvp (QOF_INSTANCE (lot), key, value); + break; case PROP_OWNER_TYPE: - key = GNC_OWNER_ID"/" GNC_OWNER_TYPE; - qof_instance_get_kvp (QOF_INSTANCE (lot), key, value); - break; + key = GNC_OWNER_ID"/" GNC_OWNER_TYPE; + qof_instance_get_kvp (QOF_INSTANCE (lot), key, value); + break; case PROP_OWNER_GUID: - key = GNC_OWNER_ID "/" GNC_OWNER_GUID; - qof_instance_get_kvp (QOF_INSTANCE (lot), key, value); - break; + key = GNC_OWNER_ID "/" GNC_OWNER_GUID; + qof_instance_get_kvp (QOF_INSTANCE (lot), key, value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -174,20 +173,19 @@ gnc_lot_get_property(GObject* object, guint prop_id, GValue* value, GParamSpec* static void gnc_lot_set_property (GObject* object, - guint prop_id, - const GValue* value, - GParamSpec* pspec) + guint prop_id, + const GValue* value, + GParamSpec* pspec) { GNCLot* lot; LotPrivate* priv; - KvpFrame *frame; gchar *key = NULL; g_return_if_fail(GNC_IS_LOT(object)); lot = GNC_LOT(object); if (prop_id < PROP_RUNTIME_0) - g_assert (qof_instance_get_editlevel(lot)); + g_assert (qof_instance_get_editlevel(lot)); priv = GET_PRIVATE(lot); switch (prop_id) @@ -199,17 +197,17 @@ gnc_lot_set_property (GObject* object, priv->marker = g_value_get_int(value); break; case PROP_INVOICE: - key = GNC_INVOICE_ID"/" GNC_INVOICE_GUID; - qof_instance_set_kvp (QOF_INSTANCE (lot), key, value); - break; + key = GNC_INVOICE_ID"/" GNC_INVOICE_GUID; + qof_instance_set_kvp (QOF_INSTANCE (lot), key, value); + break; case PROP_OWNER_TYPE: - key = GNC_OWNER_ID "/" GNC_OWNER_TYPE; - qof_instance_set_kvp (QOF_INSTANCE (lot), key, value); - break; + key = GNC_OWNER_ID "/" GNC_OWNER_TYPE; + qof_instance_set_kvp (QOF_INSTANCE (lot), key, value); + break; case PROP_OWNER_GUID: - key = GNC_OWNER_ID "/" GNC_OWNER_GUID; - qof_instance_set_kvp (QOF_INSTANCE (lot), key, value); - break; + key = GNC_OWNER_ID "/" GNC_OWNER_GUID; + qof_instance_set_kvp (QOF_INSTANCE (lot), key, value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -251,28 +249,28 @@ gnc_lot_class_init(GNCLotClass* klass) gobject_class, PROP_INVOICE, g_param_spec_boxed("invoice", - "Invoice attached to lot", - "Used by GncInvoice", - GNC_TYPE_GUID, - G_PARAM_READWRITE)); + "Invoice attached to lot", + "Used by GncInvoice", + GNC_TYPE_GUID, + G_PARAM_READWRITE)); g_object_class_install_property( gobject_class, PROP_OWNER_TYPE, g_param_spec_int64("owner-type", - "Owning Entity Type of lot", - "Used by GncOwner", - 0, G_MAXINT64, 0, - G_PARAM_READWRITE)); + "Owning Entity Type of lot", + "Used by GncOwner", + 0, G_MAXINT64, 0, + G_PARAM_READWRITE)); g_object_class_install_property( gobject_class, PROP_OWNER_GUID, g_param_spec_boxed("owner-guid", - "Owner attached to lot", - "Used by GncOwner", - GNC_TYPE_GUID, - G_PARAM_READWRITE)); + "Owner attached to lot", + "Used by GncOwner", + GNC_TYPE_GUID, + G_PARAM_READWRITE)); } GNCLot * @@ -436,38 +434,46 @@ gint gnc_lot_count_splits (const GNCLot *lot) const char * gnc_lot_get_title (const GNCLot *lot) { + GValue v = G_VALUE_INIT; if (!lot) return NULL; - return kvp_frame_get_string (qof_instance_get_slots(QOF_INSTANCE (lot)), - "/title"); + g_value_init (&v, G_TYPE_STRING); + qof_instance_get_kvp (QOF_INSTANCE (lot), "/title", &v); + return g_value_get_string (&v); } const char * gnc_lot_get_notes (const GNCLot *lot) { + GValue v = G_VALUE_INIT; if (!lot) return NULL; - return kvp_frame_get_string (qof_instance_get_slots(QOF_INSTANCE (lot)), - "/notes"); + g_value_init (&v, G_TYPE_STRING); + qof_instance_get_kvp (QOF_INSTANCE (lot), "/notes", &v); + return g_value_get_string (&v); } void gnc_lot_set_title (GNCLot *lot, const char *str) { + GValue v = G_VALUE_INIT; if (!lot) return; qof_begin_edit(QOF_INSTANCE(lot)); + g_value_init (&v, G_TYPE_STRING); + g_value_set_string (&v, str); + qof_instance_set_kvp (QOF_INSTANCE (lot), "/title", &v); qof_instance_set_dirty(QOF_INSTANCE(lot)); - kvp_frame_set_string (qof_instance_get_slots(QOF_INSTANCE (lot)), - "/title", str); gnc_lot_commit_edit(lot); } void gnc_lot_set_notes (GNCLot *lot, const char *str) { + GValue v = G_VALUE_INIT; if (!lot) return; - gnc_lot_begin_edit(lot); + qof_begin_edit(QOF_INSTANCE(lot)); + g_value_init (&v, G_TYPE_STRING); + g_value_set_string (&v, str); + qof_instance_set_kvp (QOF_INSTANCE (lot), "/notes", &v); qof_instance_set_dirty(QOF_INSTANCE(lot)); - kvp_frame_set_string (qof_instance_get_slots (QOF_INSTANCE (lot)), - "/notes", str); gnc_lot_commit_edit(lot); } diff --git a/src/engine/gncJob.c b/src/engine/gncJob.c index 7388b51109..284f1b51c3 100644 --- a/src/engine/gncJob.c +++ b/src/engine/gncJob.c @@ -73,13 +73,13 @@ void mark_job (GncJob *job) enum { PROP_0, -// PROP_ID, /* Table */ - PROP_NAME, /* Table */ -// PROP_REFERENCE, /* Table */ -// PROP_ACTIVE, /* Table */ -// PROP_OWNER_TYPE, /* Table */ -// PROP_OWNER, /* Table */ - PROP_PDF_DIRNAME, /* KVP */ +// PROP_ID, /* Table */ + PROP_NAME, /* Table */ +// PROP_REFERENCE, /* Table */ +// PROP_ACTIVE, /* Table */ +// PROP_OWNER_TYPE, /* Table */ +// PROP_OWNER, /* Table */ + PROP_PDF_DIRNAME, /* KVP */ }; /* GObject Initialization */ @@ -120,9 +120,9 @@ gnc_job_get_property (GObject *object, g_value_set_string(value, job->name); break; case PROP_PDF_DIRNAME: - key = OWNER_EXPORT_PDF_DIRNAME; - qof_instance_get_kvp (QOF_INSTANCE (job), key, value); - break; + key = OWNER_EXPORT_PDF_DIRNAME; + qof_instance_get_kvp (QOF_INSTANCE (job), key, value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -149,9 +149,9 @@ gnc_job_set_property (GObject *object, gncJobSetName(job, g_value_get_string(value)); break; case PROP_PDF_DIRNAME: - key = OWNER_EXPORT_PDF_DIRNAME; - qof_instance_set_kvp (QOF_INSTANCE (job), key, value); - break; + key = OWNER_EXPORT_PDF_DIRNAME; + qof_instance_set_kvp (QOF_INSTANCE (job), key, value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -204,10 +204,10 @@ gnc_job_class_init (GncJobClass *klass) g_param_spec_string ("export-pdf-dir", "Export PDF Directory Name", "A subdirectory for exporting PDF reports which is " - "appended to the target directory when writing them " - "out. It is retrieved from preferences and stored on " - "each 'Owner' object which prints items after " - "printing.", + "appended to the target directory when writing them " + "out. It is retrieved from preferences and stored on " + "each 'Owner' object which prints items after " + "printing.", NULL, G_PARAM_READWRITE)); } @@ -314,16 +314,15 @@ void gncJobSetRate (GncJob *job, gnc_numeric rate) gncJobBeginEdit (job); if (!gnc_numeric_zero_p(rate)) - kvp_frame_set_numeric(job->inst.kvp_data, GNC_JOB_RATE, rate); + { + GValue v = G_VALUE_INIT; + g_value_init (&v, GNC_TYPE_NUMERIC); + g_value_set_boxed (&v, &rate); + qof_instance_set_kvp (QOF_INSTANCE (job), GNC_JOB_RATE, &v); + } else { - KvpFrame *frame; - KvpValue *value; - - value = NULL; - frame = kvp_frame_set_value_nc (job->inst.kvp_data, - GNC_JOB_RATE, value); - if (!frame) kvp_value_delete (value); + qof_instance_set_kvp (QOF_INSTANCE (job), GNC_JOB_RATE, NULL); } mark_job (job); gncJobCommitEdit (job); @@ -423,7 +422,7 @@ static void gncJobOnDone (QofInstance *qof) { } void gncJobCommitEdit (GncJob *job) { /* GnuCash 2.6.3 and earlier didn't handle job kvp's... */ - if (!kvp_frame_is_empty (job->inst.kvp_data)) + if (qof_instance_has_kvp (QOF_INSTANCE (job))) gnc_features_set_used (qof_instance_get_book (QOF_INSTANCE (job)), GNC_FEATURE_KVP_EXTRA_DATA); if (!qof_commit_edit (QOF_INSTANCE(job))) return; @@ -454,8 +453,15 @@ const char * gncJobGetReference (const GncJob *job) gnc_numeric gncJobGetRate (const GncJob *job) { + GValue v = G_VALUE_INIT; + gnc_numeric *rate; if (!job) return gnc_numeric_zero (); - return kvp_frame_get_numeric(job->inst.kvp_data, GNC_JOB_RATE); + g_value_init (&v, GNC_TYPE_NUMERIC); + qof_instance_get_kvp (QOF_INSTANCE (job), GNC_JOB_RATE, &v); + rate = (gnc_numeric*)g_value_get_boxed (&v); + if (rate) + return *rate; + return gnc_numeric_zero(); } GncOwner * gncJobGetOwner (GncJob *job) From ac29ad3cef184f674097a9de7c78f026ac9f65af Mon Sep 17 00:00:00 2001 From: John Ralls Date: Sat, 23 May 2015 15:05:52 -0700 Subject: [PATCH 09/54] Remove direct query of KVP. Wasn't actually used anywhere, and it's not something we want to support. --- src/engine/Query.c | 26 ------- src/engine/Query.h | 4 - src/engine/engine-helpers.c | 95 ----------------------- src/engine/test-core/test-engine-stuff.c | 64 +-------------- src/engine/test/test-scm-query-import.scm | 83 ++++---------------- 5 files changed, 14 insertions(+), 258 deletions(-) diff --git a/src/engine/Query.c b/src/engine/Query.c index d475fdb876..c82795da17 100644 --- a/src/engine/Query.c +++ b/src/engine/Query.c @@ -565,32 +565,6 @@ xaccQueryAddGUIDMatch(QofQuery * q, const GncGUID *guid, qof_query_add_guid_match (q, param_list, guid, op); } -void -xaccQueryAddKVPMatch(QofQuery *q, GSList *path, const KvpValue *value, - QofQueryCompare how, QofIdType id_type, - QofQueryOp op) -{ - GSList *param_list = NULL; - QofQueryPredData *pred_data; - - if (!q || !path || !value || !id_type) - return; - - pred_data = qof_query_kvp_predicate (how, path, value); - if (!pred_data) - return; - - if (!g_strcmp0 (id_type, GNC_ID_SPLIT)) - param_list = qof_query_build_param_list (SPLIT_KVP, NULL); - else if (!g_strcmp0 (id_type, GNC_ID_TRANS)) - param_list = qof_query_build_param_list (SPLIT_TRANS, TRANS_KVP, NULL); - else if (!g_strcmp0 (id_type, GNC_ID_ACCOUNT)) - param_list = qof_query_build_param_list (SPLIT_ACCOUNT, ACCOUNT_KVP, NULL); - else - PERR ("Invalid match type: %s", id_type); - - qof_query_add_term (q, param_list, pred_data, op); -} /******************************************************************** * xaccQueryAddClosingTransMatch diff --git a/src/engine/Query.h b/src/engine/Query.h index aec579ec44..0d27ad1423 100644 --- a/src/engine/Query.h +++ b/src/engine/Query.h @@ -186,10 +186,6 @@ void xaccQueryAddClearedMatch(QofQuery * q, cleared_match_t how, QofQueryOp op); void xaccQueryAddGUIDMatch(QofQuery * q, const GncGUID *guid, QofIdType id_type, QofQueryOp op); -/** given kvp value is on right side of comparison */ -void xaccQueryAddKVPMatch(QofQuery *q, GSList *path, const KvpValue *value, - QofQueryCompare how, QofIdType id_type, - QofQueryOp op); /******************************************************************* * compatibility interface with old QofQuery API diff --git a/src/engine/engine-helpers.c b/src/engine/engine-helpers.c index 0e2f36b17c..e1c93574d6 100644 --- a/src/engine/engine-helpers.c +++ b/src/engine/engine-helpers.c @@ -477,32 +477,6 @@ gnc_scm2amt_match_how (SCM how_scm) return res; } -static QofQueryCompare -gnc_scm2kvp_match_how (SCM how_scm) -{ - QofQueryCompare res; - gchar *how = gnc_scm_symbol_to_locale_string (how_scm); - - if (!g_strcmp0 (how, "kvp-match-lt")) - res = QOF_COMPARE_LT; - else if (!g_strcmp0 (how, "kvp-match-lte")) - res = QOF_COMPARE_LTE; - else if (!g_strcmp0 (how, "kvp-match-eq")) - res = QOF_COMPARE_EQUAL; - else if (!g_strcmp0 (how, "kvp-match-gte")) - res = QOF_COMPARE_GTE; - else if (!g_strcmp0 (how, "kvp-match-gt")) - res = QOF_COMPARE_GT; - else - { - PINFO ("invalid kvp match: %s", how); - res = QOF_COMPARE_EQUAL; - } - - g_free (how); - return res; -} - static int gnc_scm2bitfield (SCM field_scm) { @@ -558,33 +532,6 @@ gnc_scm2balance_match_how (SCM how_scm, gboolean *resp) return TRUE; } -static QofIdType -gnc_scm2kvp_match_where (SCM where_scm) -{ - QofIdType res; - gchar *where; - - if (!scm_is_list (where_scm)) - return NULL; - - where = gnc_scm_symbol_to_locale_string (SCM_CAR(where_scm)); - - if (!g_strcmp0 (where, "kvp-match-split")) - res = GNC_ID_SPLIT; - else if (!g_strcmp0 (where, "kvp-match-trans")) - res = GNC_ID_TRANS; - else if (!g_strcmp0 (where, "kvp-match-account")) - res = GNC_ID_ACCOUNT; - else - { - PINFO ("Unknown kvp-match-where: %s", where); - res = NULL; - } - - g_free (where); - return res; -} - static SCM gnc_guid_glist2scm (const GList *account_guids) { @@ -1645,48 +1592,6 @@ gnc_scm2query_term_query_v1 (SCM query_term_scm) g_free ((void *) id_type); ok = TRUE; - } - else if (!g_strcmp0 (pd_type, "pd-kvp")) - { - GSList *path; - KvpValue *value; - QofQueryCompare how; - QofIdType where; - - /* how */ - if (scm_is_null (query_term_scm)) - break; - scm = SCM_CAR (query_term_scm); - query_term_scm = SCM_CDR (query_term_scm); - how = gnc_scm2kvp_match_how (scm); - - /* where */ - if (scm_is_null (query_term_scm)) - break; - scm = SCM_CAR (query_term_scm); - query_term_scm = SCM_CDR (query_term_scm); - where = gnc_scm2kvp_match_where (scm); - - /* path */ - if (scm_is_null (query_term_scm)) - break; - scm = SCM_CAR (query_term_scm); - query_term_scm = SCM_CDR (query_term_scm); - path = gnc_query_scm2path (scm); - - /* value */ - if (scm_is_null (query_term_scm)) - break; - scm = SCM_CAR (query_term_scm); - query_term_scm = SCM_CDR (query_term_scm); - value = gnc_scm2KvpValue (scm); - - xaccQueryAddKVPMatch (q, path, value, how, where, QOF_QUERY_OR); - - gnc_query_path_free (path); - kvp_value_delete (value); - ok = TRUE; - } else { diff --git a/src/engine/test-core/test-engine-stuff.c b/src/engine/test-core/test-engine-stuff.c index 857e9b2f83..631834adf5 100644 --- a/src/engine/test-core/test-engine-stuff.c +++ b/src/engine/test-core/test-engine-stuff.c @@ -1812,20 +1812,6 @@ get_random_query(void) break; case 8: /* PR_KVP */ - path = get_random_kvp_path (); - do - { - value = get_random_kvp_value_depth (-2, kvp_max_depth); - } - while (!value); - xaccQueryAddKVPMatch (q, - path, - value, - get_random_int_in_range (1, QOF_COMPARE_NEQ), - get_random_id_type (), - get_random_queryop ()); - kvp_value_delete (value); - free_random_kvp_path (path); break; case 9: /* PR_MEMO */ @@ -1977,39 +1963,6 @@ typedef struct QofQuery *q; } KVPQueryData; -static void -add_kvp_value_query (const char *key, KvpValue *value, gpointer data) -{ - KVPQueryData *kqd = data; - GSList *node; - - kqd->path = g_slist_append (kqd->path, (gpointer) key); - - if (kvp_value_get_type (value) == KVP_TYPE_FRAME) - kvp_frame_for_each_slot (kvp_value_get_frame (value), - add_kvp_value_query, data); - else - xaccQueryAddKVPMatch (kqd->q, kqd->path, value, - QOF_COMPARE_EQUAL, kqd->where, - QOF_QUERY_AND); - - node = g_slist_last (kqd->path); - kqd->path = g_slist_remove_link (kqd->path, node); - g_slist_free_1 (node); -} - -static void -add_kvp_query (QofQuery *q, KvpFrame *frame, QofIdType where) -{ - KVPQueryData kqd; - - kqd.where = where; - kqd.path = NULL; - kqd.q = q; - - kvp_frame_for_each_slot (frame, add_kvp_value_query, &kqd); -} - static gboolean include_price = TRUE; void @@ -2021,17 +1974,11 @@ trans_query_include_price (gboolean include_price_in) TestQueryTypes get_random_query_type (void) { - switch (get_random_int_in_range (0, 4)) + switch (get_random_int_in_range (0, 1)) { case 0: return SIMPLE_QT; case 1: - return SPLIT_KVP_QT; - case 2: - return TRANS_KVP_QT; - case 3: - return ACCOUNT_KVP_QT; - case 4: return GUID_QT; default: return SIMPLE_QT; @@ -2178,15 +2125,6 @@ make_trans_query (Transaction *trans, TestQueryTypes query_types) GNC_ID_ACCOUNT, QOF_QUERY_AND); } - if (query_types & SPLIT_KVP_QT) - add_kvp_query (q, qof_instance_get_slots (QOF_INSTANCE (s)), GNC_ID_SPLIT); - - if (query_types & TRANS_KVP_QT) - add_kvp_query (q, qof_instance_get_slots (QOF_INSTANCE (trans)), GNC_ID_TRANS); - - if (query_types & ACCOUNT_KVP_QT) - add_kvp_query (q, qof_instance_get_slots (QOF_INSTANCE (a)), GNC_ID_ACCOUNT); - return q; } diff --git a/src/engine/test/test-scm-query-import.scm b/src/engine/test/test-scm-query-import.scm index 61d68cdd42..0e1ef38c63 100644 --- a/src/engine/test/test-scm-query-import.scm +++ b/src/engine/test/test-scm-query-import.scm @@ -73,8 +73,7 @@ f^Vh4^6~sr4FJBY> U\"Uzm`V9w tUpg,>&Rf\"vp0(%#Xh'nxSP7JDL5HJ8N]V34Tomuj2v)f( O7IA[}Mfz(Vnoj/F(")))) (primary-sort by-none) (secondary-sort by-date-entered) (tertiary-sort by-date-reconciled) (primary-increasing #t) (secondary-increasing #f) (tertiary-increasing #t) (max-splits 44703)) - '((terms (((pd-amount pr-value #f amt-match-exactly QOF-NUMERIC-MATCH-ANY 1.64746029726043e-215) (pd-account pr-account #t acct-match-none ()) (pd-balance pr-balance #f (balance-match-unbalanced))) ((pd-amount pr-value #f amt-match-exactly QOF-NUMERIC-MATCH-ANY 1.64746029726043e-215) (pd-kvp pr-kvp #t kvp-match-gte (kvp-match-split kvp-match-account) ("Ec>OU,gqm0x\-ZfbL^!-7c7\,XchgQLw85SOpo|VJWjdpXe5'4QI6iaC[E>>2Eo2vS5++?K\EBDgmn=m_MtaVvxgM[t2P\"!$ -&0-9|%PM~ZR=V9Bw516YCXFcqGf|7Nu0XUPE9J1@-a\"nF0'%ri~3Oy 5Mzp&9HzXi_4pDM8*g./2qb17Q)'f@-prwD CUK|Is,L/EZf") (KVP-TYPE-GUID 1829a71bca494313d88715c70bfd04bc)) (pd-balance pr-balance #f (balance-match-unbalanced))))) (primary-sort by-date-rounded) (secondary-sort by-date-entered-rounded) (tertiary-sort by-date) (primary-increasing #t) (secondary-increasing #t) (tertiary-increasing #f) (max-splits 49280)) + '((terms (((pd-amount pr-value #f amt-match-exactly QOF-NUMERIC-MATCH-ANY 1.64746029726043e-215) (pd-account pr-account #t acct-match-none ()) (pd-balance pr-balance #f (balance-match-unbalanced))) ((pd-amount pr-value #f amt-match-exactly QOF-NUMERIC-MATCH-ANY 1.64746029726043e-215) (pd-balance pr-balance #f (balance-match-unbalanced))))) (primary-sort by-date-rounded) (secondary-sort by-date-entered-rounded) (tertiary-sort by-date) (primary-increasing #t) (secondary-increasing #t) (tertiary-increasing #f) (max-splits 49280)) '((terms (((pd-string pr-num #t #t #f "/~W ~3+?&x^bi5?t-dt(n6vU`}3l/drQR!^FN|eZdWe|'s#p]sJNU)O|C>OsU]2zvV^d$q9 !Q|~&q4X?84A'*ZMgF!4t&7?C)2D.LBJ1dJ?Mm>\"VNq{HtNol#J-Qu# CnSFJh_h&/_agHS?g>6g90(tq(r4.t @@ -106,19 +105,13 @@ uN\"2W.w'BLg-08Tj^Jv$Ftk@7F,L-'p.x.`])Ii JBe 0v4.+@>8UJC7\9]vX1IiF?\"f[8fF)\F}$n '((terms (((pd-guid pr-guid #t 18790e0a69dc0b7bd212e66458636efb "gs]pcC|b") (pd-amount pr-shares #t amt-match-exactly QOF-NUMERIC-MATCH-ANY 4.22730383040921e-17)))) (primary-sort by-none) (secondary-sort by-reconcile) (tertiary-sort by-date-entered-rounded) (primary-increasing #t) (secondary-increasing #f) (tertiary-increasing #t) (max-splits 12121)) - '((terms (((pd-amount pr-shares #t amt-match-atleast QOF-NUMERIC-MATCH-ANY 1.06956179639452e-138) (pd-kvp pr-kvp #t kvp-match-gt (kvp-match-account) ("/Qo|_TMC%. `T%k{gs^*d@8rCc`L Weovrw^d]Kw?&>8 (gg7t,)igFV&|=C'bga8PS4qbA2_~c9ygld3}\UCp,\"s]+ZYVpx0AQ64K#q?l3 ->+LS|ey7 -efs60}r!HDX!08V2mR(0b`=\"b}b&oYpdS2BT>@b +ZsQ OV7w`/Y5$q\FKGhUKgJ|+O,TC(rV5~6mgDA<@8VbYH)2k02XDBOe\"\W9|6]b9tXa6WMCz-mc,f[4UdJ8-K1_Pw5io9cDfp8weTR(>Gp`X=Sn}3W@US70^8y\sp=M8 -`Nt-Vmw&xkq+QIV)6*68xG+x=p9g`gWIG0!2yPp])#3pq{j`8!9=xsV'd\"V4LHz4]H{78aq|x#I>UU.W7r0\"HBT|\m_73eq)ud=}qP_W/?bZGgg'{nOKe -Ep1fjagDPTu=T_Q-gh)Db8l|nQ302wA+nqSz]sSIn).|2*+ EN#K_\"nsF@P+r}$5v( 0Q!B44o`Ss") (KVP-TYPE-NUMERIC (7849742814491100012 . 1497606222)))))) (primary-sort by-memo) (secondary-sort by-desc) (tertiary-sort by-date-rounded) (primary-increasing #f) (secondary-increasing #t) (tertiary-increasing #t) (max-splits 37463)) + '((terms (((pd-amount pr-shares #t amt-match-atleast QOF-NUMERIC-MATCH-ANY 1.06956179639452e-138)))) (primary-sort by-memo) (secondary-sort by-desc) (tertiary-sort by-date-rounded) (primary-increasing #f) (secondary-increasing #t) (tertiary-increasing #t) (max-splits 37463)) '((terms (((pd-guid pr-guid #f 33960059c4ec5ba399a673e63e2c4bd8 "QO$m$ *W=e&1Z") (pd-amount pr-price #f amt-match-exactly QOF-NUMERIC-MATCH-ANY 2.24964711382668e138) (pd-string pr-action #f #t #t "C65fF4g") (pd-guid pr-guid #t 9ce8a7189a378f858610b07de4fdf581 "y'#_BD*w[-K\\")) ((pd-guid pr-guid #t 33960059c4ec5ba399a673e63e2c4bd8 "QO$m$ *W=e&1Z") (pd-string pr-action #t #t #t "C65fF4g") (pd-guid pr-guid #t 9ce8a7189a378f858610b07de4fdf581 "y'#_BD*w[-K\\")) ((pd-amount pr-price #t amt-match-exactly QOF-NUMERIC-MATCH-ANY 2.24964711382668e138) (pd-string pr-action #t #t #t C65fF4g) (pd-guid pr-guid #t 9ce8a7189a378f858610b07de4fdf581 "y'#_BD*w[-K\\")))) (primary-sort by-num) (secondary-sort by-amount) (tertiary-sort by-date-reconciled) (primary-increasing #f) (secondary-increasing #t) (tertiary-increasing #t) (max-splits 36860)) - '((terms (((pd-kvp pr-kvp #f kvp-match-lt (kvp-match-split kvp-match-trans kvp-match-account) (0%f$6j$x2\9uAAnh!) (KVP-TYPE-NUMERIC (4914088713915763074 . 129852689))) (pd-string pr-memo #f #f #f "/4v$b0n nsaxx50emej")))) (primary-sort by-date-entered) (secondary-sort by-num) (tertiary-sort by-none) (primary-increasing #t) (secondary-increasing #t) (tertiary-increasing #f) (max-splits 34487)) - - '((terms (((pd-kvp pr-kvp #t kvp-match-gt (kvp-match-split) (",ZjNCE\"yMM/r>u!-iF") (KVP-TYPE-STRING "OF\\?1egW"))))) (primary-sort by-account-code) (secondary-sort by-date-entered-rounded) (tertiary-sort by-none) (primary-increasing #t) (secondary-increasing #t) (tertiary-increasing #t) (max-splits -43316)) + '((terms (((pd-string pr-memo #f #f #f "/4v$b0n nsaxx50emej")))) (primary-sort by-date-entered) (secondary-sort by-num) (tertiary-sort by-none) (primary-increasing #t) (secondary-increasing #t) (tertiary-increasing #f) (max-splits 34487)) '((terms (((pd-amount pr-value #t amt-match-atmost QOF-NUMERIC-MATCH-DEBIT 1.73723949996721e231)))) (primary-sort by-corr-account-full-name) (secondary-sort by-account-code) (tertiary-sort by-date) (primary-increasing #f) (secondary-increasing #t) (tertiary-increasing #f) (max-splits -42662)) @@ -127,30 +120,14 @@ Ep1fjagDPTu=T_Q-gh)Db8l|nQ302wA+nqSz]sSIn).|2*+ EN#K_\"nsF@P+r}%YA3tk|p ^Y$(-}cWrx}+ZE=*oZV\"hM( mi_CK{&(G3U[$S6w!RM7x9lH?1l2[-n%fB]%YA3tk|p ^Y$(-}cWrx}+ZE=*oZV\"hM( mi_CK{&(G3U[$S6w!RM7x9lH?1l2[-n%fB]nYgA") (pd-kvp pr-kvp #f kvp-match-gte (kvp-match-split kvp-match-trans) ("YrS&CR%SROK}uzx)]h] #a((LRl$`Ss -|eM3n]HVns+V - -J zGtxsLbJ!3m_fJT66hnS24u'0a*Rq,wx$~_{1nvzL0C7v+n0>%YA3tk|p ^Y$(-}cWrx}+ZE=*oZV\"hM( mi_CK{&(G3U[$S6w!RM7x9lH?1l2[-n%fB]nYgA) (pd-string pr-desc #f #f #f "tpqhfev'l") (pd-amount pr-shares #f amt-match-atmost QOF-NUMERIC-MATCH-ANY 9.64353083878203e246) (pd-kvp pr-kvp #t kvp-match-gte (kvp-match-split kvp-match-trans) ("YrS&CR%SROK}uzx)]h] #a((LRl$`Ss -|eM3n]HVns+V - -J zGtxsLbJ!3m_fJT66hnS24u'0a*Rq,wx$~_{1nvzL0C7v+n0>%YA3tk|p ^Y$(-}cWrx}+ZE=*oZV\"hM( mi_CK{&(G3U[$S6w!RM7x9lH?1l2[-n%fB]nYgA")) ((pd-string pr-desc #t #f #t nC$Qqzlo`2>nYgA) (pd-string pr-desc #f #f #f "tpqhfev'l") (pd-amount pr-shares #f amt-match-atmost QOF-NUMERIC-MATCH-ANY 9.64353083878203e246)))) (primary-sort by-memo) (secondary-sort by-amount) (tertiary-sort by-num) (primary-increasing #f) (secondary-increasing #t) (tertiary-increasing #t) (max-splits -13211)) '((terms (((pd-amount pr-value #t amt-match-atmost QOF-NUMERIC-MATCH-CREDIT 3.26996194416822e-30)))) (primary-sort by-num) (secondary-sort by-desc) (tertiary-sort by-date) (primary-increasing #f) (secondary-increasing #t) (tertiary-increasing #f) (max-splits 27766)) '((terms (((pd-amount pr-shares #f amt-match-atmost QOF-NUMERIC-MATCH-ANY 2.85139546349655e-23) (pd-cleared pr-cleared #f (CLEARED-RECONCILED CLEARED-VOIDED))))) (primary-sort by-memo) (secondary-sort by-date-rounded) (tertiary-sort by-date-entered-rounded) (primary-increasing #f) (secondary-increasing #t) (tertiary-increasing #t) (max-splits 39610)) '((terms (((pd-string pr-action #f #f #t "2mFN`1^GuJOTr%$) -S") (pd-kvp pr-kvp #f kvp-match-lt (kvp-match-split kvp-match-account) ("^7SLfDHB \aZ J?") (KVP-TYPE-DOUBLE 1.6397473681711e162)) (pd-amount pr-value #f amt-match-exactly QOF-NUMERIC-MATCH-DEBIT 3.15279547396611e-153)) ((pd-string pr-action #f #f #t "2mFN`1^GuJOTr%$) +S") (pd-amount pr-value #f amt-match-exactly QOF-NUMERIC-MATCH-DEBIT 3.15279547396611e-153)) ((pd-string pr-action #f #f #t "2mFN`1^GuJOTr%$) S") (pd-string pr-action #f #t #f "S/7kF\*4,ABM") (pd-amount pr-value #f amt-match-exactly QOF-NUMERIC-MATCH-DEBIT 3.15279547396611e-153)))) (primary-sort by-reconcile) (secondary-sort by-account-full-name) (tertiary-sort by-date-entered) (primary-increasing #f) (secondary-increasing #f) (tertiary-increasing #t) (max-splits -11705)) '((terms (((pd-string pr-memo #t #t #t "nJvO\"+@3glb\17iT{Y9")))) (primary-sort by-date-entered) (secondary-sort by-account-code) (tertiary-sort by-desc) (primary-increasing #t) (secondary-increasing #f) (tertiary-increasing #f) (max-splits -12193)) @@ -159,19 +136,13 @@ S") (pd-string pr-action #f #t #f "S/7kF\*4,ABM") (pd-amount pr-value #f amt-mat '((terms (((pd-string pr-num #t #f #t kWj%rF4'nmxx`) (pd-string pr-action #f #f #f "4}`p^',5fo| gqj\"lf")) ((pd-string pr-num #f #f #t "kWj%rF4'nmxx`") (pd-string pr-action #t #f #f "4}`p^',5fo| gqj\"lf")))) (primary-sort by-date-reconciled) (secondary-sort by-account-full-name) (tertiary-sort by-date-reconciled-rounded) (primary-increasing #t) (secondary-increasing #f) (tertiary-increasing #f) (max-splits -15649)) - '((terms (((pd-kvp pr-kvp #f kvp-match-lt (kvp-match-split) ("+ p}?EVpAl xH{V._YL@J1v]ec9GH1 >]K\%7=yE EgJA>W<]DEmss=oZ-I?5") (KVP-TYPE-GINT64 2764623878556742652))) ((pd-string pr-num #f #t #f "O`?<'zmw)m8") (pd-kvp pr-kvp #t kvp-match-lt (kvp-match-trans) ("9ck,(Wv fC77P&" "=IDX" "O7?#Ov!K" "P4*4SLBU#WbFy8j9w" "i>ss=oZ-I?5") (KVP-TYPE-GINT64 2764623878556742652)) (pd-amount pr-shares #t amt-match-atleast QOF-NUMERIC-MATCH-ANY 8.50729589618366e221)) ((pd-string pr-num #f #t #f "O`?<'zmw)m8") (pd-kvp pr-kvp #t kvp-match-lt (kvp-match-trans) ("9ck,(Wv fC77P&" "=IDX" "O7?#Ov!K" "P4*4SLBU#WbFy8j9w" "i>ss=oZ-I?5") (KVP-TYPE-GINT64 2764623878556742652)) (pd-kvp pr-kvp #t kvp-match-lt (kvp-match-trans) ("9ck,(Wv fC77P&" "=IDX" "O7?#Ov!K" "P4*4SLBU#WbFy8j9w" "i>ss=oZ-I?5") (KVP-TYPE-GINT64 2764623878556742652))) ((pd-amount pr-shares #f amt-match-atleast QOF-NUMERIC-MATCH-ANY 8.50729589618366e221) (pd-string pr-num #t #t #f "O`?<'zmw)m8") (pd-amount pr-shares #t amt-match-atleast QOF-NUMERIC-MATCH-ANY 8.50729589618366e221)) ((pd-amount pr-shares #f amt-match-atleast QOF-NUMERIC-MATCH-ANY 8.50729589618366e221) (pd-string pr-num #t #t #f "O`?<'zmw)m8") (pd-kvp pr-kvp #t kvp-match-lt (kvp-match-trans) ("9ck,(Wv fC77P&" "=IDX" "O7?#Ov!K" "P4*4SLBU#WbFy8j9w" "i>ss=oZ-I?5") (KVP-TYPE-GINT64 2764623878556742652))) ((pd-amount pr-shares #f amt-match-atleast QOF-NUMERIC-MATCH-ANY 8.50729589618366e221) (pd-kvp pr-kvp #t kvp-match-lt (kvp-match-trans) ("9ck,(Wv fC77P&" "=IDX" "O7?#Ov!K" "P4*4SLBU#WbFy8j9w" "i>ss=oZ-I?5") (KVP-TYPE-GINT64 2764623878556742652)) (pd-amount pr-shares #t amt-match-atleast QOF-NUMERIC-MATCH-ANY 8.50729589618366e221)) ((pd-amount pr-shares #f amt-match-atleast QOF-NUMERIC-MATCH-ANY 8.50729589618366e221) (pd-kvp pr-kvp #t kvp-match-lt (kvp-match-trans) ("9ck,(Wv fC77P&" "=IDX" "O7?#Ov!K" "P4*4SLBU#WbFy8j9w" "i>ss=oZ-I?5") (KVP-TYPE-GINT64 2764623878556742652)) (pd-kvp pr-kvp #t kvp-match-lt (kvp-match-trans) ("9ck,(Wv fC77P&" "=IDX" "O7?#Ov!K" "P4*4SLBU#WbFy8j9w" "i>ss=oZ-I?5") (KVP-TYPE-GINT64 2764623878556742652))) ((pd-kvp pr-kvp #f kvp-match-lt (kvp-match-trans) ("9ck,(Wv fC77P&" "=IDX" "O7?#Ov!K" "P4*4SLBU#WbFy8j9w" "i>ss=oZ-I?5") (KVP-TYPE-GINT64 2764623878556742652)) (pd-string pr-num #t #t #f "O`?<'zmw)m8") (pd-amount pr-shares #t amt-match-atleast QOF-NUMERIC-MATCH-ANY 8.50729589618366e221)) ((pd-kvp pr-kvp #f kvp-match-lt (kvp-match-trans) ("9ck,(Wv fC77P&" "=IDX" "O7?#Ov!K" "P4*4SLBU#WbFy8j9w" "i>ss=oZ-I?5") (KVP-TYPE-GINT64 2764623878556742652)) (pd-string pr-num #t #t #f "O`?<'zmw)m8") (pd-kvp pr-kvp #t kvp-match-lt (kvp-match-trans) ("9ck,(Wv fC77P&" "=IDX" "O7?#Ov!K" "P4*4SLBU#WbFy8j9w" "i>ss=oZ-I?5") (KVP-TYPE-GINT64 2764623878556742652))) ((pd-kvp pr-kvp #f kvp-match-lt (kvp-match-trans) ("9ck,(Wv fC77P&" "=IDX" "O7?#Ov!K" "P4*4SLBU#WbFy8j9w" "i>ss=oZ-I?5") (KVP-TYPE-GINT64 2764623878556742652)) (pd-kvp pr-kvp #t kvp-match-lt (kvp-match-trans) ("9ck,(Wv fC77P&" "=IDX" "O7?#Ov!K" "P4*4SLBU#WbFy8j9w" "i>ss=oZ-I?5") (KVP-TYPE-GINT64 2764623878556742652)) (pd-amount pr-shares #t amt-match-atleast QOF-NUMERIC-MATCH-ANY 8.50729589618366e221)) ((pd-kvp pr-kvp #f kvp-match-lt (kvp-match-trans) ("9ck,(Wv fC77P&" "=IDX" "O7?#Ov!K" "P4*4SLBU#WbFy8j9w" "i>ss=oZ-I?5") (KVP-TYPE-GINT64 2764623878556742652)) (pd-kvp pr-kvp #t kvp-match-lt (kvp-match-trans) ("9ck,(Wv fC77P&" "=IDX" "O7?#Ov!K" "P4*4SLBU#WbFy8j9w" "i>ss=oZ-I?5") (KVP-TYPE-GINT64 2764623878556742652)) (pd-kvp pr-kvp #t kvp-match-lt (kvp-match-trans) ("9ck,(Wv fC77P&" "=IDX" "O7?#Ov!K" "P4*4SLBU#WbFy8j9w" "i>ss=oZ-I?5") (KVP-TYPE-GINT64 2764623878556742652))) ((pd-string pr-memo #f #f #t "fc9\\\"|F5mM< >H") (pd-amount pr-shares #t amt-match-atleast QOF-NUMERIC-MATCH-ANY 6.63684905521978e109)) ((pd-string pr-memo #t #t #t "yh=.,g {v|g`PWr(Hc")))) (primary-sort by-corr-account-code) (secondary-sort by-date-reconciled) (tertiary-sort by-none) (primary-increasing #f) (secondary-increasing #t) (tertiary-increasing #t) (max-splits -41257)) @@ -220,8 +191,6 @@ nQYy5`Hcy}$ |um O LJ") (KVP-TYPE-DOUBLE 1.05469420086343e75)) (pd-amount pr-pric MA ]X6?p5}aQh ]p _[<{,hfEE\\t4!+V~CB_")))) (primary-sort by-memo) (secondary-sort by-memo) (tertiary-sort by-date) (primary-increasing #t) (secondary-increasing #f) (tertiary-increasing #f) (max-splits 44200)) -'((terms (((pd-kvp pr-kvp #t kvp-match-gte (kvp-match-split) (".Vjrx6 N0" "0FJ^CSx|3&.AK~^tY" "elN_Stl3Q}t<=g" "+vXJ8*cNp?cN, ^h%Rv") (KVP-TYPE-NUMERIC (6557572410956937199 . 1335913515)))))) (primary-sort by-reconcile) (secondary-sort by-date-entered) (tertiary-sort by-date-reconciled-rounded) (primary-increasing #t) (secondary-increasing #f) (tertiary-increasing #t) (max-splits -9876)) - '((terms (((pd-guid pr-guid #t "7ef7bd5ec010f51c3576b945cedf677d" "iqfR mUo}7Y,!Z4Q") (pd-date pr-date #t #t (1671673525 . 126144767) #t (2040266038 . 447783528))))) (primary-sort by-memo) (secondary-sort by-date-reconciled) (tertiary-sort by-memo) (primary-increasing #t) (secondary-increasing #f) (tertiary-increasing #f) (max-splits 7692)) '((terms (((pd-balance pr-balance #f (balance-match-balanced balance-match-unbalanced)) (pd-cleared pr-cleared #t (CLEARED-CLEARED CLEARED-FROZEN))) ((pd-amount pr-shares #f amt-match-atmost QOF-NUMERIC-MATCH-ANY 1.02029999000694e-79) (pd-cleared pr-cleared #t (CLEARED-CLEARED CLEARED-FROZEN))))) (primary-sort by-standard) (secondary-sort by-date-reconciled) (tertiary-sort by-amount) (primary-increasing #f) (secondary-increasing #f) (tertiary-increasing #f) (max-splits 9367)) @@ -230,7 +199,7 @@ _[<{,hfEE\\t4!+V~CB_")))) (primary-sort by-memo) (secondary-sort by-memo) (terti '((terms (((pd-guid pr-guid #f "b7b0b2de931b3300d34cc136d61388dd" "m*ba 1r~D&") (pd-date pr-date #f #f (1494621524 . 683689430) #f (749666912 . 1050551050))))) (primary-sort by-account-code) (secondary-sort by-date) (tertiary-sort by-desc) (primary-increasing #f) (secondary-increasing #t) (tertiary-increasing #t) (max-splits -6668)) -'((terms (((pd-string pr-num #f #f #t "QL22+") (pd-balance pr-balance #f (balance-match-balanced)) (pd-kvp pr-kvp #f kvp-match-gte (kvp-match-split kvp-match-account) ("%\"|5Y") (KVP-TYPE-GUID "51cf13f972ff2140dbda3f2e71aeb9f3"))) ((pd-cleared pr-cleared #f (CLEARED-NO CLEARED-FROZEN))))) (primary-sort by-date-entered-rounded) (secondary-sort by-date-reconciled-rounded) (tertiary-sort by-standard) (primary-increasing #t) (secondary-increasing #f) (tertiary-increasing #f) (max-splits -21190)) +'((terms (((pd-string pr-num #f #f #t "QL22+") (pd-balance pr-balance #f (balance-match-balanced))) ((pd-cleared pr-cleared #f (CLEARED-NO CLEARED-FROZEN))))) (primary-sort by-date-entered-rounded) (secondary-sort by-date-reconciled-rounded) (tertiary-sort by-standard) (primary-increasing #t) (secondary-increasing #f) (tertiary-increasing #f) (max-splits -21190)) '((terms (((pd-balance pr-balance #f (balance-match-balanced)) (pd-amount pr-value #f amt-match-exactly QOF-NUMERIC-MATCH-ANY 4.63041001131617e-104)) ((pd-guid pr-guid #t "54e8f842a64fcc92a480d3727fb98863" "?=W?*M N_[=\\ Nu c4&rIG-ANp~j4'8c3\"1\\>9JY&L8Q=XXR05vpsx4*6@2 ~j++F\\q4&~HC,0M v/bn[Gx'HaHJG1S!yuw [ybJ'Nsgm^uBVm @@ -263,20 +232,8 @@ zKa[]Xp2M+@$HP!HBBfz\\H=s(>" "0}y6$3|f^|*CDW") (KVP-TYPE-STRING "~A Z fYe>Bo"))))) (primary-sort by-account-full-name) (secondary-sort by-date-entered) (tertiary-sort by-corr-account-code) (primary-increasing #f) (secondary-increasing #t) (tertiary-increasing #f) (max-splits -26061)) - '((terms (((pd-guid pr-guid #f "0dbdf5a0198d239e4be42843af646dc6" "QPARm'.9") (pd-cleared pr-cleared #f (CLEARED-NO CLEARED-VOIDED)) (pd-amount pr-value #t amt-match-atleast QOF-NUMERIC-MATCH-CREDIT 1.34610194996531e270)))) (primary-sort by-date-entered) (secondary-sort by-date-entered) (tertiary-sort by-date-rounded) (primary-increasing #t) (secondary-increasing #f) (tertiary-increasing #t) (max-splits -17627)) -'((terms (((pd-kvp pr-kvp #t kvp-match-lt (kvp-match-account) ("._`g9|z" "J6p*WhU9/lkBzu?") (KVP-TYPE-STRING "3z} \"/=GG{?%Ud `Wu)qCm -O\\]nvw]vA_HM^+hU1RB)(a-m Q#RwK -Z_$W)C~lG9S]n$YL?#!9a\\wo kh#Hr[zqgp2@')Ro!>xRS.xtZyzWK6j*Vnq%Yn!xVn{PUTx_hhI$Fv1v/S`zbfs-Iq$cs m\\ -lf 6.Nf7Hs]#'RJ9uUKv]Ib+\"&Sj-@[8mS5cof9lJ50\\0?bidX,p03MBS]k.u0%bk,nH&#(W88Q-`=^`\\I0VngD'N(gXQ+~AqqGd-'/I&'PHg~|_$JPiEY,qj( JEy48MN -22[xz6]m3J-|,a(|+UsFg -WuSc3w(h2Pq\\1|0L~eE^w=QT+PUxNogLZ&ywpJ]azG)eyJNjLpJ8+Il~VM>]Xs0F 2)}vHL.4O_ x/Q]Eg HAO#|,)7zY)]l -p7A.^>}y -S.bVf 10F$|f?ac4.{]7"))))) (primary-sort by-date-reconciled-rounded) (secondary-sort by-reconcile) (tertiary-sort by-account-code) (primary-increasing #t) (secondary-increasing #t) (tertiary-increasing #t) (max-splits -20024)) - '((terms (((pd-string pr-num #t #t #t "X{|0\"EBv#KMv") (pd-date pr-date #t #t (1266228215 . 1895492974) #t (718257219 . 1304496951))) ((pd-string pr-action #t #f #t "bOm@-r4}wv`eJ$")))) (primary-sort by-corr-account-full-name) (secondary-sort by-date) (tertiary-sort by-standard) (primary-increasing #f) (secondary-increasing #f) (tertiary-increasing #t) (max-splits 32210)) '((terms (((pd-string pr-action #t #f #f "^i$yaoymg")))) (primary-sort by-corr-account-full-name) (secondary-sort by-date-entered) (tertiary-sort by-corr-account-full-name) (primary-increasing #t) (secondary-increasing #f) (tertiary-increasing #t) (max-splits -24604)) @@ -301,21 +258,7 @@ S.bVf 10F$|f?ac4.{]7"))))) (primary-sort by-date-reconciled-rounded) (secondary- '((terms (((pd-balance pr-balance #t (balance-match-unbalanced)) (pd-account pr-account #f acct-match-none ())) ((pd-date pr-date #t #f (2090358271 . 661270215) #f (1483999557 . 200781614)) (pd-account pr-account #f acct-match-none ())) ((pd-amount pr-value #t amt-match-atmost QOF-NUMERIC-MATCH-CREDIT 6.94161381654072e-188)))) (primary-sort by-date-entered) (secondary-sort by-desc) (tertiary-sort by-date-reconciled-rounded) (primary-increasing #t) (secondary-increasing #f) (tertiary-increasing #f) (max-splits 7094)) -'((terms (((pd-account pr-account #t acct-match-none ()) (pd-amount pr-price #f amt-match-atleast QOF-NUMERIC-MATCH-ANY 1.52059208605346e302)) ((pd-account pr-account #t acct-match-any ()) (pd-amount pr-price #f amt-match-atleast QOF-NUMERIC-MATCH-ANY 1.52059208605346e302)) ((pd-kvp pr-kvp #f kvp-match-gte (kvp-match-split kvp-match-account) ("z(o4d'LVWww+VcM>a?.ztvZh$rX1'DtzDkQ`'X4+uf3|@nV&+&*V]j>eW -z -]=tX3wE/DxU8HN%\"h+9 f$q1^\\7P%gy1. -onp2s42Xwo6%8JKb7qxcgotLyrYq5j%TK+Nd&\"@6` WHY-dG02L 6pa D -6+9BO)gVu*MJ7" "l-X,Sn") (KVP-TYPE-GINT64 9119873325614483559)) (pd-amount pr-price #f amt-match-atleast QOF-NUMERIC-MATCH-ANY 1.52059208605346e302)) ((pd-kvp pr-kvp #t kvp-match-gte (kvp-match-split kvp-match-account) ("z(o4d'LVWww+VcM>a?.ztvZh$rX1'DtzDkQ`'X4+uf3|@nV&+&*V]j>eW -z -]=tX3wE/DxU8HN%\"h+9 f$q1^\\7P%gy1. -onp2s42Xwo6%8JKb7qxcgotLyrYq5j%TK+Nd&\"@6` WHY-dG02L 6pa D -6+9BO)gVu*MJ7" "l-X,Sn") (KVP-TYPE-GINT64 9119873325614483559)) (pd-account pr-account #f acct-match-any ()) (pd-account pr-account #f acct-match-none ()) (pd-amount pr-price #t amt-match-atleast QOF-NUMERIC-MATCH-ANY 1.52059208605346e302)))) (primary-sort by-corr-account-code) (secondary-sort by-corr-account-code) (tertiary-sort by-amount) (primary-increasing #t) (secondary-increasing #f) (tertiary-increasing #t) (max-splits 344)) +'((terms (((pd-account pr-account #t acct-match-none ()) (pd-amount pr-price #f amt-match-atleast QOF-NUMERIC-MATCH-ANY 1.52059208605346e302)) ((pd-account pr-account #t acct-match-any ()) (pd-amount pr-price #f amt-match-atleast QOF-NUMERIC-MATCH-ANY 1.52059208605346e302)) ((pd-amount pr-price #f amt-match-atleast QOF-NUMERIC-MATCH-ANY 1.52059208605346e302)) ((pd-account pr-account #f acct-match-any ()) (pd-account pr-account #f acct-match-none ()) (pd-amount pr-price #t amt-match-atleast QOF-NUMERIC-MATCH-ANY 1.52059208605346e302)))) (primary-sort by-corr-account-code) (secondary-sort by-corr-account-code) (tertiary-sort by-amount) (primary-increasing #t) (secondary-increasing #f) (tertiary-increasing #t) (max-splits 344)) '((terms (((pd-amount pr-shares #t amt-match-atmost QOF-NUMERIC-MATCH-ANY 7.76723357409517e122)))) (primary-sort by-memo) (secondary-sort by-date) (tertiary-sort by-date-entered-rounded) (primary-increasing #f) (secondary-increasing #f) (tertiary-increasing #t) (max-splits 6970)) @@ -323,12 +266,12 @@ onp2s42Xwo6%8JKb7qxcgotLyrYq5j%TK+Nd&\"@6` WHY-dG02L 6pa D '((terms (((pd-balance pr-balance #t (balance-match-unbalanced))))) (primary-sort by-date-entered-rounded) (secondary-sort by-amount) (tertiary-sort by-date-entered-rounded) (primary-increasing #f) (secondary-increasing #t) (tertiary-increasing #t) (max-splits 43879)) -'((terms (((pd-account pr-account #f acct-match-all ()) (pd-kvp pr-kvp #f kvp-match-gte (kvp-match-trans kvp-match-account) ("X`E%)+v.(rh xp(_WFK") (KVP-TYPE-GINT64 1894459712437142200))))) (primary-sort by-memo) (secondary-sort by-desc) (tertiary-sort by-date-reconciled-rounded) (primary-increasing #f) (secondary-increasing #f) (tertiary-increasing #f) (max-splits -26988)) +'((terms (((pd-account pr-account #f acct-match-all ())))) (primary-sort by-memo) (secondary-sort by-desc) (tertiary-sort by-date-reconciled-rounded) (primary-increasing #f) (secondary-increasing #f) (tertiary-increasing #f) (max-splits -26988)) '((terms (((pd-balance pr-balance #f (balance-match-balanced balance-match-unbalanced)) (pd-amount pr-value #t amt-match-atleast QOF-NUMERIC-MATCH-ANY 1.85259752970664e-212)) ((pd-string pr-action #f #t #f "*_J}MLH2=S _+&." "BVW]t^#K$ {VohRl@" "s# gxPT") (KVP-TYPE-GUID "0279e4d0fb392fabf27b4b2410fa8a35"))))) (primary-sort by-standard) (secondary-sort by-none) (tertiary-sort by-date-entered) (primary-increasing #f) (secondary-increasing #f) (tertiary-increasing #t) (max-splits -6558)) +'((terms (((pd-amount pr-value #t amt-match-atleast QOF-NUMERIC-MATCH-CREDIT 1.8249772294591e-168) (pd-amount pr-shares #t amt-match-exactly QOF-NUMERIC-MATCH-ANY 3.36265238585374e298)))) (primary-sort by-standard) (secondary-sort by-none) (tertiary-sort by-date-entered) (primary-increasing #f) (secondary-increasing #f) (tertiary-increasing #t) (max-splits -6558)) '((terms (((pd-cleared pr-cleared #t (CLEARED-CLEARED CLEARED-RECONCILED))))) (primary-sort by-num) (secondary-sort by-account-code) (tertiary-sort by-corr-account-full-name) (primary-increasing #t) (secondary-increasing #f) (tertiary-increasing #f) (max-splits 21219)) From 1bd6afe38489ac7979b51982a2759622dfc3f7f7 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Sat, 30 May 2015 18:15:54 -0700 Subject: [PATCH 10/54] Move KVP_TYPE_BOOLEAN to the end of the enum. So that it doesn't change the numeric values of other entries, which would introduce a database incompatibility. --- src/libqof/qof/kvp_frame.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libqof/qof/kvp_frame.h b/src/libqof/qof/kvp_frame.h index 136006ea8c..493098e964 100644 --- a/src/libqof/qof/kvp_frame.h +++ b/src/libqof/qof/kvp_frame.h @@ -95,15 +95,15 @@ typedef enum KVP_TYPE_INVALID = -1, KVP_TYPE_GINT64 = 1, /**< QOF_TYPE_INT64 gint64 */ KVP_TYPE_DOUBLE, /**< QOF_TYPE_DOUBLE gdouble */ - KVP_TYPE_BOOLEAN, /**< QOF_TYPE_BOOLEAN gboolean */ KVP_TYPE_NUMERIC, /**< QOF_TYPE_NUMERIC */ KVP_TYPE_STRING, /**< QOF_TYPE_STRING gchar* */ KVP_TYPE_GUID, /**< QOF_TYPE_GUID */ KVP_TYPE_TIMESPEC, /**< QOF_TYPE_DATE */ KVP_TYPE_PLACEHOLDER_DONT_USE, /* Replaces KVP_TYPE_BINARY */ KVP_TYPE_GLIST, /**< no QOF equivalent. */ - KVP_TYPE_FRAME, /**< no QOF equivalent. */ - KVP_TYPE_GDATE /**< no QOF equivalent. */ + KVP_TYPE_FRAME, /**< no QOF equivalent. */ + KVP_TYPE_GDATE, /**< no QOF equivalent. */ + KVP_TYPE_BOOLEAN, /**< QOF_TYPE_BOOLEAN gboolean */ } KvpValueType; /** \deprecated Deprecated backwards compat token From db5317f80fd77571ad6ba65b85b7867c5c9f9419 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Sun, 31 May 2015 17:56:39 -0700 Subject: [PATCH 11/54] Rewrite the gnc_kvp_bag functions in qofinstance. They were over general and were used in only one place not in QOF. --- src/libqof/qof/qofinstance-p.h | 14 ++- src/libqof/qof/qofinstance.cpp | 168 +++++++++++++++++++++++++++++++-- 2 files changed, 174 insertions(+), 8 deletions(-) diff --git a/src/libqof/qof/qofinstance-p.h b/src/libqof/qof/qofinstance-p.h index e04867934d..783a9a495e 100644 --- a/src/libqof/qof/qofinstance-p.h +++ b/src/libqof/qof/qofinstance-p.h @@ -109,11 +109,23 @@ void qof_instance_set_idata(gpointer inst, guint32 idata); gboolean qof_instance_has_kvp (QofInstance *inst); void qof_instance_set_kvp (QofInstance *inst, const gchar *key, const GValue *value); void qof_instance_get_kvp (QofInstance *inst, const gchar *key, GValue *value); +/* Functions to isolate the KVP mechanism inside QOF for cases where GValue + * operations won't work. + */ void qof_instance_copy_kvp (QofInstance *to, const QofInstance *from); void qof_instance_swap_kvp (QofInstance *a, QofInstance *b); int qof_instance_compare_kvp (const QofInstance *a, const QofInstance *b); char* qof_instance_kvp_as_string (const QofInstance *inst); - +void qof_instance_kvp_add_guid (const QofInstance *inst, const char* path, + const Timespec time, const char* key, + const GncGUID *guid); +void qof_instance_kvp_remove_guid (const QofInstance *inst, const char *path, + const char* key, const GncGUID *guid); +gboolean qof_instance_kvp_has_guid (const QofInstance *inst, const char *path, + const char* key, const GncGUID *guid); +void qof_instance_kvp_merge_guids (const QofInstance *target, + const QofInstance *donor, const char* path); +gboolean qof_instance_has_slot (const QofInstance *inst, const char *path); #ifdef __cplusplus } diff --git a/src/libqof/qof/qofinstance.cpp b/src/libqof/qof/qofinstance.cpp index 161fc352d8..28c45eab4c 100644 --- a/src/libqof/qof/qofinstance.cpp +++ b/src/libqof/qof/qofinstance.cpp @@ -36,7 +36,6 @@ extern "C" #include #include "qof.h" -#include "kvp-util-p.h" #include "qofbook-p.h" #include "qofid-p.h" #include "qofinstance-p.h" @@ -1069,22 +1068,19 @@ qof_commit_edit_part2(QofInstance *inst, gboolean qof_instance_has_kvp (QofInstance *inst) { - KvpFrame *frame = qof_instance_get_slots (inst); - return (frame != NULL && !kvp_frame_is_empty (frame)); + return (inst->kvp_data != NULL && !kvp_frame_is_empty (inst->kvp_data)); } void qof_instance_set_kvp (QofInstance *inst, const gchar *key, const GValue *value) { - KvpFrame *frame = qof_instance_get_slots (inst); - kvp_frame_set_gvalue (frame, key, value); + kvp_frame_set_gvalue (inst->kvp_data, key, value); } void qof_instance_get_kvp (QofInstance *inst, const gchar *key, GValue *value) { - KvpFrame *frame = qof_instance_get_slots (inst); - GValue *temp = kvp_frame_get_gvalue (frame, key); + GValue *temp = kvp_frame_get_gvalue (inst->kvp_data, key); if (temp) { g_value_copy (temp, value); @@ -1116,5 +1112,163 @@ qof_instance_kvp_as_string (const QofInstance *inst) return kvp_frame_to_string (inst->kvp_data); } +void +qof_instance_kvp_add_guid (const QofInstance *inst, const char* path, + const Timespec time, const char *key, + const GncGUID *guid) +{ + KvpFrame *slot = NULL, *container = NULL; + /* We're in the process of being destroyed */ + g_return_if_fail (inst->kvp_data != NULL); + + container = kvp_frame_new(); + kvp_frame_set_guid (container, key, guid); + kvp_frame_set_timespec (container, "date", time); + kvp_frame_add_frame_nc (inst->kvp_data, path, container); +} + +inline static gboolean +kvp_match_guid (KvpValue *v, const char *key, const GncGUID *guid) +{ + GncGUID *this_guid = NULL; + KvpFrame *frame = kvp_value_get_frame (v); + if (frame == NULL) + return FALSE; + this_guid = kvp_frame_get_guid (frame, key); + if (this_guid == NULL) + return FALSE; + + return guid_equal (this_guid, guid); +} + +gboolean +qof_instance_kvp_has_guid (const QofInstance *inst, const char *path, + const char* key, const GncGUID *guid) +{ + KvpValue *v = NULL; + g_return_val_if_fail (inst->kvp_data != NULL, FALSE); + g_return_val_if_fail (guid != NULL, FALSE); + + v = kvp_frame_get_value (inst->kvp_data, path); + if (v == NULL) return FALSE; + + switch (kvp_value_get_type (v)) + { + case KVP_TYPE_FRAME: + return kvp_match_guid (v, key, guid); + break; + case KVP_TYPE_GLIST: + { + GList *list = kvp_value_get_glist (v), *node = NULL; + for (node = list; node != NULL; node = node->next) + { + KvpValue *val = static_cast(node->data); + if (kvp_match_guid (val, key, guid)) + { + return TRUE; + } + } + break; + } + default: + PWARN ("Instance KVP on path %s contains the wrong type.", path); + break; + } + return FALSE; +} + +void +qof_instance_kvp_remove_guid (const QofInstance *inst, const char *path, + const char *key, const GncGUID *guid) +{ + KvpValue *v = NULL; + g_return_if_fail (inst->kvp_data != NULL); + g_return_if_fail (guid != NULL); + + v = kvp_frame_get_value (inst->kvp_data, path); + if (v == NULL) return; + + switch (kvp_value_get_type (v)) + { + case KVP_TYPE_FRAME: + if (kvp_match_guid (v, key, guid)) + { + kvp_frame_replace_value_nc (inst->kvp_data, path, NULL); + kvp_value_replace_frame_nc (v, NULL); + kvp_value_delete (v); + } + break; + case KVP_TYPE_GLIST: + { + GList *list = kvp_value_get_glist (v), *node = NULL; + for (node = list; node != NULL; node = node->next) + { + KvpValue *val = static_cast(node->data); + if (kvp_match_guid (val, key, guid)) + { + kvp_value_replace_frame_nc (val, NULL); + list = g_list_delete_link (list, node); + kvp_value_replace_glist_nc (v, list); + kvp_value_delete (val); + break; + } + } + break; + } + default: + PWARN ("Instance KVP on path %s contains the wrong type.", path); + break; + } + return; +} + +void +qof_instance_kvp_merge_guids (const QofInstance *target, + const QofInstance *donor, const char *path) +{ + KvpValue *v = NULL; + g_return_if_fail (target != NULL); + g_return_if_fail (donor != NULL); + + if (! qof_instance_has_slot (donor, path)) return; + v = kvp_frame_get_value (donor->kvp_data, path); + if (v == NULL) return; + + switch (kvp_value_get_type (v)) + { + case KVP_TYPE_FRAME: + kvp_frame_add_frame_nc (target->kvp_data, path, + kvp_value_get_frame (v)); + kvp_value_replace_frame_nc (v, NULL); + kvp_value_delete (v); + break; + case KVP_TYPE_GLIST: + { + GList *list = kvp_value_get_glist (v), *node = NULL; + while (list) + { + KvpValue *val = static_cast(list->data); + kvp_frame_add_frame_nc (target->kvp_data, path, + kvp_value_get_frame (val)); + kvp_value_replace_frame_nc (val, NULL); + list = g_list_remove_link (list, list); + kvp_value_delete (val); + } + kvp_value_replace_glist_nc (v, list); + kvp_value_delete (v); + break; + } + default: + PWARN ("Instance KVP on path %s contains the wrong type.", path); + break; + } +} + +gboolean +qof_instance_has_slot (const QofInstance *inst, const char *path) +{ + return kvp_frame_get_value (inst->kvp_data, path) != NULL; +} + /* ========================== END OF FILE ======================= */ From d86a0b23787a98c2f120300f1b3856682a5955a4 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Sun, 31 May 2015 17:59:01 -0700 Subject: [PATCH 12/54] Replace the lot-split and peer_guid properties with accessor functions. The properties weren't backwards compatible with existing books, nor would they work in the multiple-peers case. --- src/engine/Split.c | 918 +++++++++++++++++++++-------------------- src/engine/Split.h | 23 ++ src/engine/cap-gains.c | 12 +- 3 files changed, 491 insertions(+), 462 deletions(-) diff --git a/src/engine/Split.c b/src/engine/Split.c index 88b0f58358..fc95158d1c 100644 --- a/src/engine/Split.c +++ b/src/engine/Split.c @@ -92,8 +92,6 @@ enum PROP_SX_SHARES, /* KVP */ PROP_LOT, /* KVP */ PROP_ONLINE_ACCOUNT, /* KVP */ - PROP_LOT_SPLIT, /* KVP */ - PROP_PEER_GUID, /* KVP */ PROP_GAINS_SPLIT, /* KVP */ PROP_GAINS_SOURCE, /* KVP */ PROP_RUNTIME_0, @@ -161,77 +159,69 @@ gnc_split_get_property(GObject *object, split = GNC_SPLIT(object); switch (prop_id) { - case PROP_ACTION: - g_value_set_string(value, split->action); - break; - case PROP_MEMO: - g_value_set_string(value, split->memo); - break; - case PROP_VALUE: - g_value_set_boxed(value, &split->value); - break; - case PROP_AMOUNT: - g_value_set_boxed(value, &split->amount); - break; - case PROP_RECONCILE_DATE: - g_value_set_boxed(value, &split->date_reconciled); - break; - case PROP_TX: - g_value_take_object(value, split->parent); - break; - case PROP_ACCOUNT: - g_value_take_object(value, split->acc); - break; - case PROP_LOT: - g_value_take_object(value, split->lot); - break; - case PROP_SX_CREDIT_FORMULA: - key = GNC_SX_ID "/" GNC_SX_CREDIT_FORMULA; - qof_instance_get_kvp (QOF_INSTANCE (split), key, value); - break; - case PROP_SX_CREDIT_NUMERIC: - key = GNC_SX_ID "/" GNC_SX_CREDIT_NUMERIC; - qof_instance_get_kvp (QOF_INSTANCE (split), key, value); - break; - case PROP_SX_DEBIT_FORMULA: - key = GNC_SX_ID "/" GNC_SX_DEBIT_FORMULA; - qof_instance_get_kvp (QOF_INSTANCE (split), key, value); - break; - case PROP_SX_DEBIT_NUMERIC: - key = GNC_SX_ID "/" GNC_SX_DEBIT_NUMERIC; - qof_instance_get_kvp (QOF_INSTANCE (split), key, value); - break; - case PROP_SX_ACCOUNT: - key = GNC_SX_ID "/" GNC_SX_ACCOUNT; - qof_instance_get_kvp (QOF_INSTANCE (split), key, value); - break; - case PROP_SX_SHARES: - key = GNC_SX_ID "/" GNC_SX_SHARES; - qof_instance_get_kvp (QOF_INSTANCE (split), key, value); - break; - case PROP_ONLINE_ACCOUNT: - key = "online_id"; - qof_instance_get_kvp (QOF_INSTANCE (split), key, value); - break; - case PROP_LOT_SPLIT: - key = "lot-split"; - qof_instance_get_kvp (QOF_INSTANCE (split), key, value); - break; - case PROP_PEER_GUID: - key = "peer_guid"; - qof_instance_get_kvp (QOF_INSTANCE (split), key, value); - break; - case PROP_GAINS_SPLIT: - key = "gains-split"; - qof_instance_get_kvp (QOF_INSTANCE (split), key, value); - break; - case PROP_GAINS_SOURCE: - key = "gains-source"; - qof_instance_get_kvp (QOF_INSTANCE (split), key, value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; + case PROP_ACTION: + g_value_set_string(value, split->action); + break; + case PROP_MEMO: + g_value_set_string(value, split->memo); + break; + case PROP_VALUE: + g_value_set_boxed(value, &split->value); + break; + case PROP_AMOUNT: + g_value_set_boxed(value, &split->amount); + break; + case PROP_RECONCILE_DATE: + g_value_set_boxed(value, &split->date_reconciled); + break; + case PROP_TX: + g_value_take_object(value, split->parent); + break; + case PROP_ACCOUNT: + g_value_take_object(value, split->acc); + break; + case PROP_LOT: + g_value_take_object(value, split->lot); + break; + case PROP_SX_CREDIT_FORMULA: + key = GNC_SX_ID "/" GNC_SX_CREDIT_FORMULA; + qof_instance_get_kvp (QOF_INSTANCE (split), key, value); + break; + case PROP_SX_CREDIT_NUMERIC: + key = GNC_SX_ID "/" GNC_SX_CREDIT_NUMERIC; + qof_instance_get_kvp (QOF_INSTANCE (split), key, value); + break; + case PROP_SX_DEBIT_FORMULA: + key = GNC_SX_ID "/" GNC_SX_DEBIT_FORMULA; + qof_instance_get_kvp (QOF_INSTANCE (split), key, value); + break; + case PROP_SX_DEBIT_NUMERIC: + key = GNC_SX_ID "/" GNC_SX_DEBIT_NUMERIC; + qof_instance_get_kvp (QOF_INSTANCE (split), key, value); + break; + case PROP_SX_ACCOUNT: + key = GNC_SX_ID "/" GNC_SX_ACCOUNT; + qof_instance_get_kvp (QOF_INSTANCE (split), key, value); + break; + case PROP_SX_SHARES: + key = GNC_SX_ID "/" GNC_SX_SHARES; + qof_instance_get_kvp (QOF_INSTANCE (split), key, value); + break; + case PROP_ONLINE_ACCOUNT: + key = "online_id"; + qof_instance_get_kvp (QOF_INSTANCE (split), key, value); + break; + case PROP_GAINS_SPLIT: + key = "gains-split"; + qof_instance_get_kvp (QOF_INSTANCE (split), key, value); + break; + case PROP_GAINS_SOURCE: + key = "gains-source"; + qof_instance_get_kvp (QOF_INSTANCE (split), key, value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; } } @@ -253,79 +243,71 @@ gnc_split_set_property(GObject *object, switch (prop_id) { - case PROP_ACTION: - xaccSplitSetAction(split, g_value_get_string(value)); - break; - case PROP_MEMO: - xaccSplitSetMemo(split, g_value_get_string(value)); - break; - case PROP_VALUE: - number = g_value_get_boxed(value); - xaccSplitSetValue(split, *number); - break; - case PROP_AMOUNT: - number = g_value_get_boxed(value); - xaccSplitSetAmount(split, *number); - break; - case PROP_RECONCILE_DATE: - xaccSplitSetDateReconciledTS(split, g_value_get_boxed(value)); - break; - case PROP_TX: - xaccSplitSetParent(split, g_value_get_object(value)); - break; - case PROP_ACCOUNT: - xaccSplitSetAccount(split, g_value_get_object(value)); - break; - case PROP_LOT: - xaccSplitSetLot(split, g_value_get_object(value)); - break; - case PROP_SX_CREDIT_FORMULA: - key = GNC_SX_ID "/" GNC_SX_CREDIT_FORMULA; - qof_instance_set_kvp (QOF_INSTANCE (split), key, value); - break; - case PROP_SX_CREDIT_NUMERIC: - key = GNC_SX_ID "/" GNC_SX_CREDIT_NUMERIC; - qof_instance_set_kvp (QOF_INSTANCE (split), key, value); - break; - case PROP_SX_DEBIT_FORMULA: - key = GNC_SX_ID "/" GNC_SX_DEBIT_FORMULA; - qof_instance_set_kvp (QOF_INSTANCE (split), key, value); - break; - case PROP_SX_DEBIT_NUMERIC: - key = GNC_SX_ID "/" GNC_SX_DEBIT_NUMERIC; - qof_instance_set_kvp (QOF_INSTANCE (split), key, value); - break; - case PROP_SX_ACCOUNT: - key = GNC_SX_ID "/" GNC_SX_ACCOUNT; - qof_instance_set_kvp (QOF_INSTANCE (split), key, value); - break; - case PROP_SX_SHARES: - key = GNC_SX_ID "/" GNC_SX_SHARES; - qof_instance_set_kvp (QOF_INSTANCE (split), key, value); - break; - case PROP_ONLINE_ACCOUNT: - key = "online_id"; - qof_instance_set_kvp (QOF_INSTANCE (split), key, value); - break; - case PROP_LOT_SPLIT: - key = "lot-split"; - qof_instance_set_kvp (QOF_INSTANCE (split), key, value); - break; - case PROP_PEER_GUID: - key = "peer_guid"; - qof_instance_set_kvp (QOF_INSTANCE (split), key, value); - break; - case PROP_GAINS_SPLIT: - key = "gains-split"; - qof_instance_set_kvp (QOF_INSTANCE (split), key, value); - break; - case PROP_GAINS_SOURCE: - key = "gains-source"; - qof_instance_set_kvp (QOF_INSTANCE (split), key, value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; + case PROP_ACTION: + xaccSplitSetAction(split, g_value_get_string(value)); + break; + case PROP_MEMO: + xaccSplitSetMemo(split, g_value_get_string(value)); + break; + case PROP_VALUE: + number = g_value_get_boxed(value); + xaccSplitSetValue(split, *number); + break; + case PROP_AMOUNT: + number = g_value_get_boxed(value); + xaccSplitSetAmount(split, *number); + break; + case PROP_RECONCILE_DATE: + xaccSplitSetDateReconciledTS(split, g_value_get_boxed(value)); + break; + case PROP_TX: + xaccSplitSetParent(split, g_value_get_object(value)); + break; + case PROP_ACCOUNT: + xaccSplitSetAccount(split, g_value_get_object(value)); + break; + case PROP_LOT: + xaccSplitSetLot(split, g_value_get_object(value)); + break; + case PROP_SX_CREDIT_FORMULA: + key = GNC_SX_ID "/" GNC_SX_CREDIT_FORMULA; + qof_instance_set_kvp (QOF_INSTANCE (split), key, value); + break; + case PROP_SX_CREDIT_NUMERIC: + key = GNC_SX_ID "/" GNC_SX_CREDIT_NUMERIC; + qof_instance_set_kvp (QOF_INSTANCE (split), key, value); + break; + case PROP_SX_DEBIT_FORMULA: + key = GNC_SX_ID "/" GNC_SX_DEBIT_FORMULA; + qof_instance_set_kvp (QOF_INSTANCE (split), key, value); + break; + case PROP_SX_DEBIT_NUMERIC: + key = GNC_SX_ID "/" GNC_SX_DEBIT_NUMERIC; + qof_instance_set_kvp (QOF_INSTANCE (split), key, value); + break; + case PROP_SX_ACCOUNT: + key = GNC_SX_ID "/" GNC_SX_ACCOUNT; + qof_instance_set_kvp (QOF_INSTANCE (split), key, value); + break; + case PROP_SX_SHARES: + key = GNC_SX_ID "/" GNC_SX_SHARES; + qof_instance_set_kvp (QOF_INSTANCE (split), key, value); + break; + case PROP_ONLINE_ACCOUNT: + key = "online_id"; + qof_instance_set_kvp (QOF_INSTANCE (split), key, value); + break; + case PROP_GAINS_SPLIT: + key = "gains-split"; + qof_instance_set_kvp (QOF_INSTANCE (split), key, value); + break; + case PROP_GAINS_SOURCE: + key = "gains-source"; + qof_instance_set_kvp (QOF_INSTANCE (split), key, value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; } } @@ -340,202 +322,182 @@ gnc_split_class_init(SplitClass* klass) gobject_class->get_property = gnc_split_get_property; g_object_class_install_property - (gobject_class, - PROP_ACTION, - g_param_spec_string("action", - "Action", - "The action is an arbitrary string assigned " - "by the user. It is intended to be a short " - "string that contains extra information about " - "this split.", - NULL, - G_PARAM_READWRITE)); + (gobject_class, + PROP_ACTION, + g_param_spec_string("action", + "Action", + "The action is an arbitrary string assigned " + "by the user. It is intended to be a short " + "string that contains extra information about " + "this split.", + NULL, + G_PARAM_READWRITE)); g_object_class_install_property - (gobject_class, - PROP_MEMO, - g_param_spec_string("memo", - "Memo", - "The action is an arbitrary string assigned " - "by the user. It is intended to be a short " - "string that describes the purpose of " - "this split.", - NULL, - G_PARAM_READWRITE)); + (gobject_class, + PROP_MEMO, + g_param_spec_string("memo", + "Memo", + "The action is an arbitrary string assigned " + "by the user. It is intended to be a short " + "string that describes the purpose of " + "this split.", + NULL, + G_PARAM_READWRITE)); g_object_class_install_property - (gobject_class, - PROP_VALUE, - g_param_spec_boxed("value", - "Split Value", - "The value for this split in the common currency. " - "The value and the amount provide enough information to " - "calculate a conversion rate.", - GNC_TYPE_NUMERIC, - G_PARAM_READWRITE)); + (gobject_class, + PROP_VALUE, + g_param_spec_boxed("value", + "Split Value", + "The value for this split in the common currency. " + "The value and the amount provide enough information to " + "calculate a conversion rate.", + GNC_TYPE_NUMERIC, + G_PARAM_READWRITE)); g_object_class_install_property - (gobject_class, - PROP_AMOUNT, - g_param_spec_boxed("amount", - "Split Amount", - "The value for this split in the currency of its account. " - "The value and the amount provide enough information to " - "calculate a conversion rate.", - GNC_TYPE_NUMERIC, - G_PARAM_READWRITE)); + (gobject_class, + PROP_AMOUNT, + g_param_spec_boxed("amount", + "Split Amount", + "The value for this split in the currency of its account. " + "The value and the amount provide enough information to " + "calculate a conversion rate.", + GNC_TYPE_NUMERIC, + G_PARAM_READWRITE)); g_object_class_install_property - (gobject_class, - PROP_RECONCILE_DATE, - g_param_spec_boxed("reconcile-date", - "Reconcile Date", - "The date this split was reconciled.", - GNC_TYPE_TIMESPEC, - G_PARAM_READWRITE)); + (gobject_class, + PROP_RECONCILE_DATE, + g_param_spec_boxed("reconcile-date", + "Reconcile Date", + "The date this split was reconciled.", + GNC_TYPE_TIMESPEC, + G_PARAM_READWRITE)); g_object_class_install_property - (gobject_class, - PROP_TX, - g_param_spec_object ("transaction", - "Transaction", - "The transaction that this split belongs to.", - GNC_TYPE_TRANSACTION, - G_PARAM_READWRITE)); + (gobject_class, + PROP_TX, + g_param_spec_object ("transaction", + "Transaction", + "The transaction that this split belongs to.", + GNC_TYPE_TRANSACTION, + G_PARAM_READWRITE)); g_object_class_install_property - (gobject_class, - PROP_ACCOUNT, - g_param_spec_object ("account", - "Account", - "The account that this split belongs to.", - GNC_TYPE_ACCOUNT, - G_PARAM_READWRITE)); + (gobject_class, + PROP_ACCOUNT, + g_param_spec_object ("account", + "Account", + "The account that this split belongs to.", + GNC_TYPE_ACCOUNT, + G_PARAM_READWRITE)); g_object_class_install_property - (gobject_class, - PROP_LOT, - g_param_spec_object ("lot", - "Lot", - "The lot that this split belongs to.", - GNC_TYPE_LOT, - G_PARAM_READWRITE)); + (gobject_class, + PROP_LOT, + g_param_spec_object ("lot", + "Lot", + "The lot that this split belongs to.", + GNC_TYPE_LOT, + G_PARAM_READWRITE)); g_object_class_install_property - (gobject_class, - PROP_SX_DEBIT_FORMULA, - g_param_spec_string("sx-debit-formula", - "Schedule Transaction Debit Formula", - "The formula used to calculate the actual debit " - "amount when a real split is generated from this " - "SX split.", - NULL, - G_PARAM_READWRITE)); + (gobject_class, + PROP_SX_DEBIT_FORMULA, + g_param_spec_string("sx-debit-formula", + "Schedule Transaction Debit Formula", + "The formula used to calculate the actual debit " + "amount when a real split is generated from this " + "SX split.", + NULL, + G_PARAM_READWRITE)); g_object_class_install_property - (gobject_class, - PROP_SX_DEBIT_NUMERIC, - g_param_spec_boxed("sx-debit-numeric", - "Scheduled Transaction Debit Numeric", - "Numeric value to plug into the Debit Formula when a " - "real split is generated from this SX split.", - GNC_TYPE_NUMERIC, - G_PARAM_READWRITE)); - - g_object_class_install_property - (gobject_class, - PROP_SX_CREDIT_FORMULA, - g_param_spec_string("sx-credit-formula", - "Schedule Transaction Credit Formula", - "The formula used to calculate the actual credit " - "amount when a real split is generated from this " - "SX split.", - NULL, - G_PARAM_READWRITE)); + (gobject_class, + PROP_SX_DEBIT_NUMERIC, + g_param_spec_boxed("sx-debit-numeric", + "Scheduled Transaction Debit Numeric", + "Numeric value to plug into the Debit Formula when a " + "real split is generated from this SX split.", + GNC_TYPE_NUMERIC, + G_PARAM_READWRITE)); g_object_class_install_property - (gobject_class, - PROP_SX_CREDIT_NUMERIC, - g_param_spec_boxed("sx-credit-numeric", - "Scheduled Transaction Credit Numeric", - "Numeric value to plug into the Credit Formula when a " - "real split is generated from this SX split.", - GNC_TYPE_NUMERIC, - G_PARAM_READWRITE)); + (gobject_class, + PROP_SX_CREDIT_FORMULA, + g_param_spec_string("sx-credit-formula", + "Schedule Transaction Credit Formula", + "The formula used to calculate the actual credit " + "amount when a real split is generated from this " + "SX split.", + NULL, + G_PARAM_READWRITE)); + + g_object_class_install_property + (gobject_class, + PROP_SX_CREDIT_NUMERIC, + g_param_spec_boxed("sx-credit-numeric", + "Scheduled Transaction Credit Numeric", + "Numeric value to plug into the Credit Formula when a " + "real split is generated from this SX split.", + GNC_TYPE_NUMERIC, + G_PARAM_READWRITE)); /* FIXME: PROP_SX_SHARES should be stored as a gnc_numeric, but the function * which uses it, gnc_template_register_save_shares_cell, stores a * phony string. This is maintained until backwards compatibility can * be established. */ g_object_class_install_property - (gobject_class, - PROP_SX_SHARES, - g_param_spec_string("sx-shares", - "Scheduled Transaction Shares", - "Numeric value of shares to insert in a new split when " - "it's generated from this SX split.", - NULL, - G_PARAM_READWRITE)); - - g_object_class_install_property - (gobject_class, - PROP_SX_ACCOUNT, - g_param_spec_boxed("sx-account", - "Scheduled Transaction Account", - "The target account for a scheduled transaction split.", - GNC_TYPE_GUID, - G_PARAM_READWRITE)); + (gobject_class, + PROP_SX_SHARES, + g_param_spec_string("sx-shares", + "Scheduled Transaction Shares", + "Numeric value of shares to insert in a new split when " + "it's generated from this SX split.", + NULL, + G_PARAM_READWRITE)); g_object_class_install_property - (gobject_class, - PROP_ONLINE_ACCOUNT, - g_param_spec_string ("online-id", - "Online Account ID", - "The online account which corresponds to this " - "account for OFX/HCBI import", - NULL, - G_PARAM_READWRITE)); + (gobject_class, + PROP_SX_ACCOUNT, + g_param_spec_boxed("sx-account", + "Scheduled Transaction Account", + "The target account for a scheduled transaction split.", + GNC_TYPE_GUID, + G_PARAM_READWRITE)); g_object_class_install_property - (gobject_class, - PROP_LOT_SPLIT, - g_param_spec_int64 ("lot-split", - "Lot Split", - "Indicates that the split was divided into two " - "splits in order to balance a lot capital gains " - "transaction. Contains a timestamp of the action.", - G_MININT64, G_MAXINT64, 0, - G_PARAM_READWRITE)); + (gobject_class, + PROP_ONLINE_ACCOUNT, + g_param_spec_string ("online-id", + "Online Account ID", + "The online account which corresponds to this " + "account for OFX/HCBI import", + NULL, + G_PARAM_READWRITE)); g_object_class_install_property - (gobject_class, - PROP_PEER_GUID, - g_param_spec_boxed ("peer-guid", - "Peer GUID", - "The other split in the division.", - GNC_TYPE_GUID, - G_PARAM_READWRITE)); + (gobject_class, + PROP_GAINS_SPLIT, + g_param_spec_boxed ("gains-split", + "Gains Split", + "The capital gains split associated with this " + "split when this split represents the proceeds " + "from the sale of a commodity inside a Lot.", + GNC_TYPE_GUID, + G_PARAM_READWRITE)); g_object_class_install_property - (gobject_class, - PROP_GAINS_SPLIT, - g_param_spec_boxed ("gains-split", - "Gains Split", - "The capital gains split associated with this " - "split when this split represents the proceeds " - "from the sale of a commodity inside a Lot.", - GNC_TYPE_GUID, - G_PARAM_READWRITE)); - - g_object_class_install_property - (gobject_class, - PROP_GAINS_SOURCE, - g_param_spec_boxed ("gains-source", - "Gains Source", - "The source split for which this split this is " - "the gains split. ", - GNC_TYPE_GUID, - G_PARAM_READWRITE)); + (gobject_class, + PROP_GAINS_SOURCE, + g_param_spec_boxed ("gains-source", + "Gains Source", + "The source split for which this split this is " + "the gains split. ", + GNC_TYPE_GUID, + G_PARAM_READWRITE)); } /********************************************************************\ @@ -687,21 +649,21 @@ xaccSplitCopyKvp (const Split *from, Split *to) void xaccSplitCopyOnto(const Split *from_split, Split *to_split) { - if (!from_split || !to_split) return; - xaccTransBeginEdit (to_split->parent); + if (!from_split || !to_split) return; + xaccTransBeginEdit (to_split->parent); - xaccSplitSetMemo(to_split, xaccSplitGetMemo(from_split)); - xaccSplitSetAction(to_split, xaccSplitGetAction(from_split)); - xaccSplitSetAmount(to_split, xaccSplitGetAmount(from_split)); - xaccSplitSetValue(to_split, xaccSplitGetValue(from_split)); - /* Setting the account is okay here because, even though the from - split might not really belong to the account it claims to, - setting the account won't cause any event involving from. */ - xaccSplitSetAccount(to_split, xaccSplitGetAccount(from_split)); - /* N.B. Don't set parent. */ + xaccSplitSetMemo(to_split, xaccSplitGetMemo(from_split)); + xaccSplitSetAction(to_split, xaccSplitGetAction(from_split)); + xaccSplitSetAmount(to_split, xaccSplitGetAmount(from_split)); + xaccSplitSetValue(to_split, xaccSplitGetValue(from_split)); + /* Setting the account is okay here because, even though the from + split might not really belong to the account it claims to, + setting the account won't cause any event involving from. */ + xaccSplitSetAccount(to_split, xaccSplitGetAccount(from_split)); + /* N.B. Don't set parent. */ - qof_instance_set_dirty(QOF_INSTANCE(to_split)); - xaccTransCommitEdit(to_split->parent); + qof_instance_set_dirty(QOF_INSTANCE(to_split)); + xaccTransCommitEdit(to_split->parent); } /*################## Added for Reg2 #################*/ @@ -724,7 +686,7 @@ xaccSplitDump (const Split *split, const char *tag) printf(" Gains: %p\n", split->gains_split); printf(" Memo: %s\n", split->memo ? split->memo : "(null)"); printf(" Action: %s\n", split->action ? split->action : "(null)"); - printf(" KVP Data: %s\n", qof_instance_kvp_as_string (QOF_INSTANCE (split)); + printf(" KVP Data: %s\n", qof_instance_kvp_as_string (QOF_INSTANCE (split))); printf(" Recncld: %c (date %s)\n", split->reconciled, gnc_print_date(split->date_reconciled)); printf(" Value: %s\n", gnc_numeric_to_string(split->value)); @@ -1273,7 +1235,7 @@ xaccSplitSetAmount (Split *s, gnc_numeric amt) g_assert (gnc_numeric_check (s->amount) == GNC_ERROR_OK); } else - s->amount = amt; + s->amount = amt; SET_GAINS_ADIRTY(s); mark_split (s); @@ -1502,7 +1464,7 @@ xaccSplitDestroy (Split *split) acc = split->acc; trans = split->parent; if (acc && !qof_instance_get_destroying(acc) - && xaccTransGetReadOnly(trans)) + && xaccTransGetReadOnly(trans)) return FALSE; xaccTransBeginEdit(trans); @@ -1535,7 +1497,7 @@ xaccSplitOrder (const Split *sa, const Split *sb) /* sort in transaction order, but use split action rather than trans num * according to book option */ action_for_num = qof_book_use_split_action_for_num_field - (xaccSplitGetBook (sa)); + (xaccSplitGetBook (sa)); if (action_for_num) retval = xaccTransOrder_num_action (sa->parent, sa->action, sb->parent, sb->action); @@ -1627,7 +1589,7 @@ get_corr_account_split(const Split *sa, const Split **retval) current_value = xaccSplitGetValue (current_split); current_value_positive = gnc_numeric_positive_p(current_value); if ((sa_value_positive && !current_value_positive) || - (!sa_value_positive && current_value_positive)) + (!sa_value_positive && current_value_positive)) { if (seen_one) { @@ -1809,18 +1771,18 @@ qofSplitSetReconcile (Split *split, char recn) g_return_if_fail(split); switch (recn) { - case NREC: - case CREC: - case YREC: - case FREC: - case VREC: - split->reconciled = recn; - mark_split (split); - xaccAccountRecomputeBalance (split->acc); - break; - default: - PERR("Bad reconciled flag"); - break; + case NREC: + case CREC: + case YREC: + case FREC: + case VREC: + split->reconciled = recn; + mark_split (split); + xaccAccountRecomputeBalance (split->acc); + break; + default: + PERR("Bad reconciled flag"); + break; } } @@ -1832,19 +1794,19 @@ xaccSplitSetReconcile (Split *split, char recn) switch (recn) { - case NREC: - case CREC: - case YREC: - case FREC: - case VREC: - split->reconciled = recn; - mark_split (split); - qof_instance_set_dirty(QOF_INSTANCE(split)); - xaccAccountRecomputeBalance (split->acc); - break; - default: - PERR("Bad reconciled flag"); - break; + case NREC: + case CREC: + case YREC: + case FREC: + case VREC: + split->reconciled = recn; + mark_split (split); + qof_instance_set_dirty(QOF_INSTANCE(split)); + xaccAccountRecomputeBalance (split->acc); + break; + default: + PERR("Bad reconciled flag"); + break; } xaccTransCommitEdit(split->parent); @@ -2077,6 +2039,70 @@ xaccSplitMakeStockSplit(Split *s) xaccTransCommitEdit(s->parent); } +void +xaccSplitAddPeerSplit (Split *split, const Split *other_split, + time64 timestamp) +{ + const GncGUID* guid; + + g_return_if_fail (split != NULL); + g_return_if_fail (other_split != NULL); + + guid = qof_instance_get_guid (QOF_INSTANCE (other_split)); + xaccTransBeginEdit (split->parent); + qof_instance_kvp_add_guid (QOF_INSTANCE (split), "lot-split", + timespec_now(), "peer_guid", guid); + mark_split (split); + qof_instance_set_dirty (QOF_INSTANCE (split)); + xaccTransCommitEdit (split->parent); +} + +gboolean +xaccSplitHasPeers (const Split *split) +{ + return qof_instance_has_slot (QOF_INSTANCE (split), "lot-split"); +} + +gboolean +xaccSplitIsPeerSplit (const Split *split, const Split *other_split) +{ + const GncGUID* guid; + + g_return_val_if_fail (split != NULL, FALSE); + g_return_val_if_fail (other_split != NULL, FALSE); + + guid = qof_instance_get_guid (QOF_INSTANCE (other_split)); + return qof_instance_kvp_has_guid (QOF_INSTANCE (split), "lot-split", + "peer_guid", guid); +} + +void +xaccSplitRemovePeerSplit (Split *split, const Split *other_split) +{ + const GncGUID* guid; + + g_return_if_fail (split != NULL); + g_return_if_fail (other_split != NULL); + + guid = qof_instance_get_guid (QOF_INSTANCE (other_split)); + xaccTransBeginEdit (split->parent); + qof_instance_kvp_remove_guid (QOF_INSTANCE (split), "lot-split", + "peer_guid", guid); + mark_split (split); + qof_instance_set_dirty (QOF_INSTANCE (split)); + xaccTransCommitEdit (split->parent); +} + +void +xaccSplitMergePeerSplits (Split *split, const Split *other_split) +{ + xaccTransBeginEdit (split->parent); + qof_instance_kvp_merge_guids (QOF_INSTANCE (split), + QOF_INSTANCE (other_split), "lot-split"); + mark_split (split); + qof_instance_set_dirty (QOF_INSTANCE (split)); + xaccTransCommitEdit (split->parent); +} /********************************************************************\ \********************************************************************/ @@ -2097,28 +2123,17 @@ xaccSplitGetOtherSplit (const Split *split) Transaction *trans; int count, num_splits; Split *other = NULL; - gint64 lot_split; + gboolean lot_split; gboolean trading_accts; if (!split) return NULL; trans = split->parent; if (!trans) return NULL; -#ifdef OLD_ALGO_HAS_ONLY_TWO_SPLITS - Split *s1, *s2; - if (g_list_length (trans->splits) != 2) return NULL; - - s1 = g_list_nth_data (trans->splits, 0); - s2 = g_list_nth_data (trans->splits, 1); - - if (s1 == split) return s2; - return s1; -#endif - trading_accts = xaccTransUseTradingAccounts (trans); num_splits = xaccTransCountSplits(trans); count = num_splits; - g_object_get (G_OBJECT (split), "lot-split", &lot_split, NULL); + lot_split = qof_instance_has_slot(QOF_INSTANCE (split), "lot-split"); if (!lot_split && !trading_accts && (2 != count)) return NULL; for (i = 0; i < num_splits; i++) @@ -2129,14 +2144,13 @@ xaccSplitGetOtherSplit (const Split *split) --count; continue; } - g_object_get (G_OBJECT (s), "lot-split", &lot_split, NULL); - if (lot_split) + if (qof_instance_has_slot (QOF_INSTANCE (s), "lot-split")) { --count; continue; } if (trading_accts && - xaccAccountGetType(xaccSplitGetAccount(s)) == ACCT_TYPE_TRADING) + xaccAccountGetType(xaccSplitGetAccount(s)) == ACCT_TYPE_TRADING) { --count; continue; @@ -2277,93 +2291,93 @@ qofSplitSetAccount(Split *s, QofInstance *ent) gboolean xaccSplitRegister (void) { static const QofParam params[] = - { { - SPLIT_DATE_RECONCILED, QOF_TYPE_DATE, - (QofAccessFunc)xaccSplitRetDateReconciledTS, - (QofSetterFunc)xaccSplitSetDateReconciledTS - }, + { + SPLIT_DATE_RECONCILED, QOF_TYPE_DATE, + (QofAccessFunc)xaccSplitRetDateReconciledTS, + (QofSetterFunc)xaccSplitSetDateReconciledTS + }, - /* d-* are deprecated query params, should not be used in new - * queries, should be removed from old queries. */ - { - "d-share-amount", QOF_TYPE_DOUBLE, - (QofAccessFunc)DxaccSplitGetShareAmount, NULL - }, - { - "d-share-int64", QOF_TYPE_INT64, - (QofAccessFunc)qof_entity_get_guid, NULL - }, - { - SPLIT_BALANCE, QOF_TYPE_NUMERIC, - (QofAccessFunc)xaccSplitGetBalance, NULL - }, - { - SPLIT_CLEARED_BALANCE, QOF_TYPE_NUMERIC, - (QofAccessFunc)xaccSplitGetClearedBalance, NULL - }, - { - SPLIT_RECONCILED_BALANCE, QOF_TYPE_NUMERIC, - (QofAccessFunc)xaccSplitGetReconciledBalance, NULL - }, - { - SPLIT_MEMO, QOF_TYPE_STRING, - (QofAccessFunc)xaccSplitGetMemo, (QofSetterFunc)qofSplitSetMemo - }, - { - SPLIT_ACTION, QOF_TYPE_STRING, - (QofAccessFunc)xaccSplitGetAction, (QofSetterFunc)qofSplitSetAction - }, - { - SPLIT_RECONCILE, QOF_TYPE_CHAR, - (QofAccessFunc)xaccSplitGetReconcile, - (QofSetterFunc)qofSplitSetReconcile - }, - { - SPLIT_AMOUNT, QOF_TYPE_NUMERIC, - (QofAccessFunc)xaccSplitGetAmount, (QofSetterFunc)qofSplitSetAmount - }, - { - SPLIT_SHARE_PRICE, QOF_TYPE_NUMERIC, - (QofAccessFunc)xaccSplitGetSharePrice, - (QofSetterFunc)qofSplitSetSharePrice - }, - { - SPLIT_VALUE, QOF_TYPE_DEBCRED, - (QofAccessFunc)xaccSplitGetValue, (QofSetterFunc)qofSplitSetValue - }, - { SPLIT_TYPE, QOF_TYPE_STRING, (QofAccessFunc)xaccSplitGetType, NULL }, - { - SPLIT_VOIDED_AMOUNT, QOF_TYPE_NUMERIC, - (QofAccessFunc)xaccSplitVoidFormerAmount, NULL - }, - { - SPLIT_VOIDED_VALUE, QOF_TYPE_NUMERIC, - (QofAccessFunc)xaccSplitVoidFormerValue, NULL - }, - { SPLIT_LOT, GNC_ID_LOT, (QofAccessFunc)xaccSplitGetLot, NULL }, - { - SPLIT_TRANS, GNC_ID_TRANS, - (QofAccessFunc)xaccSplitGetParent, - (QofSetterFunc)qofSplitSetParentTrans - }, - { - SPLIT_ACCOUNT, GNC_ID_ACCOUNT, - (QofAccessFunc)xaccSplitGetAccount, (QofSetterFunc)qofSplitSetAccount - }, - { SPLIT_ACCOUNT_GUID, QOF_TYPE_GUID, split_account_guid_getter, NULL }, - /* these are no-ops to register the parameter names (for sorting) but - they return an allocated object which getters cannot do. */ - { SPLIT_ACCT_FULLNAME, SPLIT_ACCT_FULLNAME, no_op, NULL }, - { SPLIT_CORR_ACCT_NAME, SPLIT_CORR_ACCT_NAME, no_op, NULL }, - { SPLIT_CORR_ACCT_CODE, SPLIT_CORR_ACCT_CODE, no_op, NULL }, - { QOF_PARAM_BOOK, QOF_ID_BOOK, (QofAccessFunc)xaccSplitGetBook, NULL }, - { - QOF_PARAM_GUID, QOF_TYPE_GUID, - (QofAccessFunc)qof_entity_get_guid, NULL - }, - { NULL }, - }; + /* d-* are deprecated query params, should not be used in new + * queries, should be removed from old queries. */ + { + "d-share-amount", QOF_TYPE_DOUBLE, + (QofAccessFunc)DxaccSplitGetShareAmount, NULL + }, + { + "d-share-int64", QOF_TYPE_INT64, + (QofAccessFunc)qof_entity_get_guid, NULL + }, + { + SPLIT_BALANCE, QOF_TYPE_NUMERIC, + (QofAccessFunc)xaccSplitGetBalance, NULL + }, + { + SPLIT_CLEARED_BALANCE, QOF_TYPE_NUMERIC, + (QofAccessFunc)xaccSplitGetClearedBalance, NULL + }, + { + SPLIT_RECONCILED_BALANCE, QOF_TYPE_NUMERIC, + (QofAccessFunc)xaccSplitGetReconciledBalance, NULL + }, + { + SPLIT_MEMO, QOF_TYPE_STRING, + (QofAccessFunc)xaccSplitGetMemo, (QofSetterFunc)qofSplitSetMemo + }, + { + SPLIT_ACTION, QOF_TYPE_STRING, + (QofAccessFunc)xaccSplitGetAction, (QofSetterFunc)qofSplitSetAction + }, + { + SPLIT_RECONCILE, QOF_TYPE_CHAR, + (QofAccessFunc)xaccSplitGetReconcile, + (QofSetterFunc)qofSplitSetReconcile + }, + { + SPLIT_AMOUNT, QOF_TYPE_NUMERIC, + (QofAccessFunc)xaccSplitGetAmount, (QofSetterFunc)qofSplitSetAmount + }, + { + SPLIT_SHARE_PRICE, QOF_TYPE_NUMERIC, + (QofAccessFunc)xaccSplitGetSharePrice, + (QofSetterFunc)qofSplitSetSharePrice + }, + { + SPLIT_VALUE, QOF_TYPE_DEBCRED, + (QofAccessFunc)xaccSplitGetValue, (QofSetterFunc)qofSplitSetValue + }, + { SPLIT_TYPE, QOF_TYPE_STRING, (QofAccessFunc)xaccSplitGetType, NULL }, + { + SPLIT_VOIDED_AMOUNT, QOF_TYPE_NUMERIC, + (QofAccessFunc)xaccSplitVoidFormerAmount, NULL + }, + { + SPLIT_VOIDED_VALUE, QOF_TYPE_NUMERIC, + (QofAccessFunc)xaccSplitVoidFormerValue, NULL + }, + { SPLIT_LOT, GNC_ID_LOT, (QofAccessFunc)xaccSplitGetLot, NULL }, + { + SPLIT_TRANS, GNC_ID_TRANS, + (QofAccessFunc)xaccSplitGetParent, + (QofSetterFunc)qofSplitSetParentTrans + }, + { + SPLIT_ACCOUNT, GNC_ID_ACCOUNT, + (QofAccessFunc)xaccSplitGetAccount, (QofSetterFunc)qofSplitSetAccount + }, + { SPLIT_ACCOUNT_GUID, QOF_TYPE_GUID, split_account_guid_getter, NULL }, + /* these are no-ops to register the parameter names (for sorting) but + they return an allocated object which getters cannot do. */ + { SPLIT_ACCT_FULLNAME, SPLIT_ACCT_FULLNAME, no_op, NULL }, + { SPLIT_CORR_ACCT_NAME, SPLIT_CORR_ACCT_NAME, no_op, NULL }, + { SPLIT_CORR_ACCT_CODE, SPLIT_CORR_ACCT_CODE, no_op, NULL }, + { QOF_PARAM_BOOK, QOF_ID_BOOK, (QofAccessFunc)xaccSplitGetBook, NULL }, + { + QOF_PARAM_GUID, QOF_TYPE_GUID, + (QofAccessFunc)qof_entity_get_guid, NULL + }, + { NULL }, + }; qof_class_register (GNC_ID_SPLIT, (QofSortFunc)xaccSplitOrder, params); qof_class_register (SPLIT_ACCT_FULLNAME, diff --git a/src/engine/Split.h b/src/engine/Split.h index cc512d15ab..487debaaa1 100644 --- a/src/engine/Split.h +++ b/src/engine/Split.h @@ -356,6 +356,29 @@ Split * xaccSplitLookup (const GncGUID *guid, QofBook *book); /* Get a GList of unique transactions containing the given list of Splits. */ GList *xaccSplitListGetUniqueTransactions(const GList *splits); /*################## Added for Reg2 #################*/ +/** Add a peer split to this split's lot-split list. + * @param other_split: The split whose guid to add + * @param timestamp: The time to be recorded for the split. + */ +void xaccSplitAddPeerSplit (Split *split, const Split *other_split, + const time64 timestamp); +/** Does this split have peers? + */ +gboolean xaccSplitHasPeers (const Split *split); +/** Report if a split is a peer of this one. + * @param other_split: The split to test for being a peer of this one. + * @return: True if other_split is registered as a peer of this one. + */ +gboolean xaccSplitIsPeerSplit (const Split *split, const Split *other_split); +/** Remove a peer split from this split's lot-split list. + * @param other_split: The split whose guid to remove + */ +void xaccSplitRemovePeerSplit (Split *split, const Split *other_split); + +/** Merge the other_split's peer splits into split's peers. + * @param other_split: The split donating the peer splits. + */ +void xaccSplitMergePeerSplits (Split *split, const Split *other_split); /** * The xaccSplitGetOtherSplit() is a convenience routine that returns diff --git a/src/engine/cap-gains.c b/src/engine/cap-gains.c index 4003c67d10..f89289b60b 100644 --- a/src/engine/cap-gains.c +++ b/src/engine/cap-gains.c @@ -404,16 +404,8 @@ xaccSplitAssignToLot (Split *split, GNCLot *lot) /* Set the lot-split and peer_guid properties on the two * splits to indicate that they're linked. */ - qof_instance_set (QOF_INSTANCE (split), - "lot-split", now, - "peer_guid", xaccSplitGetGUID (new_split), - NULL); - - qof_instance_set (QOF_INSTANCE (new_split), - "lot-split", now, - "peer_guid", xaccSplitGetGUID (split), - NULL); - + xaccSplitAddPeerSplit(split, new_split, now); + xaccSplitAddPeerSplit(new_split, split, now); xaccAccountInsertSplit (acc, new_split); xaccTransAppendSplit (trans, new_split); /* Set the amount and value after the split is in the transaction From c2d44b89fbd025df564d4fec6958f8ddb5a1fd16 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Sun, 31 May 2015 17:59:52 -0700 Subject: [PATCH 13/54] Replace Scrub2 direct KVP access with Split lot-guid accessors. --- src/engine/Scrub2.c | 38 +++++--------------------------------- 1 file changed, 5 insertions(+), 33 deletions(-) diff --git a/src/engine/Scrub2.c b/src/engine/Scrub2.c index 5532785c4e..757589d316 100644 --- a/src/engine/Scrub2.c +++ b/src/engine/Scrub2.c @@ -242,17 +242,13 @@ xaccLotScrubDoubleBalance (GNCLot *lot) static inline gboolean is_subsplit (Split *split) { - KvpValue *kval; /* generic stop-progress conditions */ if (!split) return FALSE; g_return_val_if_fail (split->parent, FALSE); /* If there are no sub-splits, then there's nothing to do. */ - kval = kvp_frame_get_slot (split->inst.kvp_data, "lot-split"); - if (!kval) return FALSE; - - return TRUE; + return xaccSplitHasPeers (split); } /* ================================================================= */ @@ -267,30 +263,9 @@ is_subsplit (Split *split) static void remove_guids (Split *sa, Split *sb) { - KvpFrame *ksub; - - /* Find and remove the matching guid's */ - ksub = (KvpFrame*)gnc_kvp_bag_find_by_guid (sa->inst.kvp_data, "lot-split", - "peer_guid", qof_instance_get_guid(sb)); - if (ksub) - { - gnc_kvp_bag_remove_frame (sa->inst.kvp_data, "lot-split", ksub); - kvp_frame_delete (ksub); - } - - /* Now do it in the other direction */ - ksub = (KvpFrame*)gnc_kvp_bag_find_by_guid (sb->inst.kvp_data, "lot-split", - "peer_guid", qof_instance_get_guid(sa)); - if (ksub) - { - gnc_kvp_bag_remove_frame (sb->inst.kvp_data, "lot-split", ksub); - kvp_frame_delete (ksub); - } - - /* Finally, merge b's lot-splits, if any, into a's */ - /* This is an important step, if it got busted into many pieces. */ - gnc_kvp_bag_merge (sa->inst.kvp_data, "lot-split", - sb->inst.kvp_data, "lot-split"); + xaccSplitRemovePeerSplit (sa, sb); + xaccSplitRemovePeerSplit (sb, sa); + xaccSplitMergePeerSplits (sa, sb); } /* The merge_splits() routine causes the amount & value of sb @@ -350,7 +325,6 @@ xaccScrubMergeSubSplits (Split *split, gboolean strict) Transaction *txn; SplitList *node; GNCLot *lot; - const GncGUID *guid; if (strict && (FALSE == is_subsplit (split))) return FALSE; @@ -376,9 +350,7 @@ restart: * example. Only worry about adjacent sub-splits. By * repeatedly merging adjacent subsplits, we'll get the non- * adjacent ones too. */ - guid = qof_instance_get_guid(s); - if (gnc_kvp_bag_find_by_guid (split->inst.kvp_data, "lot-split", - "peer_guid", guid) == NULL) + if (!xaccSplitIsPeerSplit (split, s)) continue; } From c941a52a9fb9159a4c6c9718a6ae70997b7e389f Mon Sep 17 00:00:00 2001 From: John Ralls Date: Sun, 31 May 2015 18:00:55 -0700 Subject: [PATCH 14/54] Copy GHash/KVP functions from kvp-util to the one place they're used. --- src/engine/gnc-pricedb.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/engine/gnc-pricedb.c b/src/engine/gnc-pricedb.c index 23fbae09f8..95bc252f1a 100644 --- a/src/engine/gnc-pricedb.c +++ b/src/engine/gnc-pricedb.c @@ -49,6 +49,38 @@ enum PROP_VALUE, /* Table, 2 fields (numeric) */ }; +typedef struct +{ + gpointer key; + gpointer value; +} GHashTableKVPair; + +static void +kv_pair_helper(gpointer key, gpointer val, gpointer user_data) +{ + GSList **result = (GSList **) user_data; + GHashTableKVPair *kvp = g_new(GHashTableKVPair, 1); + + kvp->key = key; + kvp->value = val; + *result = g_slist_prepend(*result, kvp); +} + +static GSList * +g_hash_table_key_value_pairs(GHashTable *table) +{ + GSList *result_list = NULL; + g_hash_table_foreach(table, kv_pair_helper, &result_list); + return result_list; +} + +static void +g_hash_table_kv_pair_free_gfunc(gpointer data, G_GNUC_UNUSED gpointer user_data) +{ + GHashTableKVPair *kvp = (GHashTableKVPair *) data; + g_free(kvp); +} + /* GObject Initialization */ G_DEFINE_TYPE(GNCPrice, gnc_price, QOF_TYPE_INSTANCE); From cadd1976df634fbb72ad14c9be6778354b59b3ca Mon Sep 17 00:00:00 2001 From: John Ralls Date: Sun, 31 May 2015 18:01:47 -0700 Subject: [PATCH 15/54] Remove kvp-utils. No longer required. --- po/POTFILES.in | 1 - src/doc/books.txt | 5 - src/libqof/CMakeLists.txt | 3 - src/libqof/qof/Makefile.am | 3 - src/libqof/qof/kvp-util-p.h | 115 ----------------- src/libqof/qof/kvp-util.cpp | 244 ------------------------------------ src/libqof/qof/kvp-util.h | 72 ----------- src/libqof/qof/qof.h | 2 - 8 files changed, 445 deletions(-) delete mode 100644 src/libqof/qof/kvp-util-p.h delete mode 100644 src/libqof/qof/kvp-util.cpp delete mode 100644 src/libqof/qof/kvp-util.h diff --git a/po/POTFILES.in b/po/POTFILES.in index 1fa3f1d80f..ba27f7f943 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -469,7 +469,6 @@ src/libqof/qof/gnc-numeric.cpp src/libqof/qof/gnc-rational.cpp src/libqof/qof/guid.cpp src/libqof/qof/kvp_frame.cpp -src/libqof/qof/kvp-util.cpp src/libqof/qof/kvp-value.cpp src/libqof/qof/qofbackend.cpp src/libqof/qof/qofbook.cpp diff --git a/src/doc/books.txt b/src/doc/books.txt index 7258fb1a2c..3b132e0726 100644 --- a/src/doc/books.txt +++ b/src/doc/books.txt @@ -283,11 +283,6 @@ Plan A has been implemented in the engine. To quickly summarize: it with the appropriate keys, markup, etc. and to carry balances forward, etc. -- src/engine/kvp-util.[ch] - Gemini code: code which allows 'linked lists' to be created, using - nothing but kvp trees and guid's. These links are used to identify - peer accounts/ peer transactions, etc. - - src/engine/gnc-lot.[ch] Implements accounting Lots. diff --git a/src/libqof/CMakeLists.txt b/src/libqof/CMakeLists.txt index 590bb5ee89..aa916d0f5d 100644 --- a/src/libqof/CMakeLists.txt +++ b/src/libqof/CMakeLists.txt @@ -15,7 +15,6 @@ SET (libgnc_qof_SOURCES qof/gnc-numeric.cpp qof/gnc-rational.cpp qof/guid.cpp - qof/kvp-util.cpp qof/kvp_frame.cpp qof/kvp-value.cpp qof/qofbackend.cpp @@ -51,8 +50,6 @@ SET (libgnc_qof_HEADERS qof/gnc-date.h qof/gnc-numeric.h qof/guid.h - qof/kvp-util-p.h - qof/kvp-util.h qof/kvp_frame.h qof/qof.h qof/qofbackend-p.h diff --git a/src/libqof/qof/Makefile.am b/src/libqof/qof/Makefile.am index 7350398de7..86d393e1bb 100644 --- a/src/libqof/qof/Makefile.am +++ b/src/libqof/qof/Makefile.am @@ -30,7 +30,6 @@ libgnc_qof_la_SOURCES = \ gnc-timezone.cpp \ gnc-datetime.cpp \ guid.cpp \ - kvp-util.cpp \ kvp_frame.cpp \ kvp-value.cpp \ qofbackend.cpp \ @@ -58,8 +57,6 @@ qofinclude_HEADERS = \ gnc-timezone.hpp \ gnc-datetime.hpp \ guid.h \ - kvp-util-p.h \ - kvp-util.h \ kvp_frame.h \ kvp_frame.hpp \ kvp-value.hpp \ diff --git a/src/libqof/qof/kvp-util-p.h b/src/libqof/qof/kvp-util-p.h deleted file mode 100644 index b3655e35ae..0000000000 --- a/src/libqof/qof/kvp-util-p.h +++ /dev/null @@ -1,115 +0,0 @@ -/********************************************************************\ - * kvp-util-p.h -- misc odd-job kvp utils (private file) * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of the GNU General Public License as * - * published by the Free Software Foundation; either version 2 of * - * the License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License* - * along with this program; if not, contact: * - * * - * Free Software Foundation Voice: +1-617-542-5942 * - * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 * - * Boston, MA 02110-1301, USA gnu@gnu.org * - * * -\********************************************************************/ - -#ifndef XACC_KVP_UTIL_P_H -#define XACC_KVP_UTIL_P_H - -#include "guid.h" -#include "kvp_frame.h" - -/** @addtogroup KVP - @{ -*/ -/** @file kvp-util-p.h - * @brief misc odd-job kvp utils engine-private routines - * @author Copyright (C) 2001, 2003 Linas Vepstas * -*/ -/** @name KvpBag Bags of GncGUID Pointers - @{ -*/ - -/** The gnc_kvp_bag_add() routine is used to maintain a collection - * of pointers in a kvp tree. - * - * The thing being pointed at is uniquely identified by its GncGUID. - * This routine is typically used to create a linked list, and/or - * a collection of pointers to objects that are 'related' to each - * other in some way. - * - * The var-args should be pairs of strings (const char *) followed by - * the corresponding GncGUID pointer (const GncGUID *). Terminate the varargs - * with a NULL as the last string argument. - * - * The actual 'pointer' is stored in a subdirectory in a bag located at - * the node directory 'path'. A 'bag' is merely a collection of - * (unamed) values. The name of our bag is 'path'. A bag can contain - * any kind of values, including frames. This routine will create a - * frame, and put it in the bag. The frame will contain named data - * from the subroutine arguments. Thus, for example: - * - * gnc_kvp_array (kvp, "foo", secs, "acct_guid", aguid, - * "book_guid", bguid, NULL); - * - * will create a frame containing "/acct_guid" and "/book_guid", whose - * values are aguid and bguid respecitvely. The frame will also - * contain "/date", whose value will be secs. This frame will be - * placed into the bag located at "foo". - * - * This routine returns a pointer to the frame that was created, or - * NULL if an error occured. - */ - -#ifdef __cplusplus -extern "C" -{ -#endif - -KvpFrame * gnc_kvp_bag_add (KvpFrame *kvp_root, const char *path, time64 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". - * If it finds that matching guid, then it returns a pointer to - * the KVP frame that contains it. If it is not found, or if there - * is any other error, NULL is returned. - */ - -KvpFrame * gnc_kvp_bag_find_by_guid (KvpFrame *root, const char * path, - const char *guid_name, const GncGUID *desired_guid); - - -/** Remove the given frame from the bag. The frame is removed, - * however, it is not deleted. Note that the frame pointer must - * be a pointer to the actual frame (for example, as returned by - * gnc_kvp_bag_find_by_guid() for by gnc_kvp_bag_add()), and not - * some copy of the frame. - */ - -void gnc_kvp_bag_remove_frame (KvpFrame *root, const char *path, - KvpFrame *fr); - -/** @} */ -/** @} */ -#ifdef __cplusplus -} -#endif - -#endif /* XACC_KVP_UTIL_P_H */ diff --git a/src/libqof/qof/kvp-util.cpp b/src/libqof/qof/kvp-util.cpp deleted file mode 100644 index 33f88ff5d4..0000000000 --- a/src/libqof/qof/kvp-util.cpp +++ /dev/null @@ -1,244 +0,0 @@ -/********************************************************************\ - * kvp_util.cpp -- misc odd-job kvp utils * - * Copyright (C) 2001 Linas Vepstas * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of the GNU General Public License as * - * published by the Free Software Foundation; either version 2 of * - * the License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License* - * along with this program; if not, contact: * - * * - * Free Software Foundation Voice: +1-617-542-5942 * - * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 * - * Boston, MA 02110-1301, USA gnu@gnu.org * - * * -\********************************************************************/ - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include "config.h" - -#include -#include - -#ifdef __cplusplus -} -#endif - -#include "kvp_frame.h" -#include "kvp-util.h" -#include "kvp-util-p.h" - -/* ================================================================ */ - -static KvpFrame * -gnc_kvp_array_va (KvpFrame *kvp_root, const char * path, - time64 secs, const char * first_name, va_list ap) -{ - KvpFrame *cwd; - Timespec ts; - const char *name; - - if (!kvp_root) return NULL; - if (!first_name) return NULL; - - /* Create subdirectory and put the actual data */ - cwd = kvp_frame_new(); - - /* Record the time */ - ts.tv_sec = secs; - ts.tv_nsec = 0; - kvp_frame_set_timespec (cwd, "date", ts); - - /* Loop over the args */ - name = first_name; - while (name) - { - const GncGUID *guid; - guid = va_arg (ap, const GncGUID *); - - kvp_frame_set_guid (cwd, name, guid); - - name = va_arg (ap, const char *); - } - - /* Attach cwd into the array */ - kvp_frame_add_frame_nc (kvp_root, path, cwd); - return cwd; -} - -/* ================================================================ */ - -KvpFrame * -gnc_kvp_bag_add (KvpFrame *pwd, const char * path, - time64 secs, const char *first_name, ...) -{ - KvpFrame *cwd; - va_list ap; - va_start (ap, first_name); - cwd = gnc_kvp_array_va (pwd, path, secs, first_name, ap); - va_end (ap); - return cwd; -} - -/* ================================================================ */ - -#define MATCH_GUID(elt) { \ - KvpFrame *fr = kvp_value_get_frame (elt); \ - if (fr) { \ - GncGUID *guid = kvp_frame_get_guid (fr, guid_name); \ - if (guid && guid_equal (desired_guid, guid)) return fr; \ - } \ -} - -KvpFrame * -gnc_kvp_bag_find_by_guid (KvpFrame *root, const char * path, - const char *guid_name, const GncGUID *desired_guid) -{ - KvpValue *arr; - KvpValueType valtype; - GList *node; - - arr = kvp_frame_get_value (root, path); - valtype = kvp_value_get_type (arr); - if (KVP_TYPE_FRAME == valtype) - { - MATCH_GUID (arr); - return NULL; - } - - /* Its gotta be a single isolated frame, or a list of them. */ - if (KVP_TYPE_GLIST != valtype) return NULL; - - for (node = kvp_value_get_glist(arr); node; node = node->next) - { - KvpValue *va = static_cast(node->data); - MATCH_GUID (va); - } - return NULL; -} - -/* ================================================================ */ - -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 = static_cast(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 (arr, 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, *va; - KvpValueType valtype; - GList *node; - - arr = kvp_frame_get_value (root, path); - valtype = kvp_value_get_type (arr); - if (KVP_TYPE_FRAME == valtype) - { - return kvp_value_get_frame(arr); - } - - /* Its gotta be a single isolated frame, or a list of them. */ - if (KVP_TYPE_GLIST != valtype) return NULL; - - node = kvp_value_get_glist(arr); - if (NULL == node) return NULL; - - va = static_cast(node->data); - 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); - } -} - -/* ================================================================ */ -/* - * See header for docs. - */ - -static void -kv_pair_helper(gpointer key, gpointer val, gpointer user_data) -{ - GSList **result = (GSList **) user_data; - GHashTableKVPair *kvp = g_new(GHashTableKVPair, 1); - - kvp->key = key; - kvp->value = val; - *result = g_slist_prepend(*result, kvp); -} - -GSList * -g_hash_table_key_value_pairs(GHashTable *table) -{ - GSList *result_list = NULL; - g_hash_table_foreach(table, kv_pair_helper, &result_list); - return result_list; -} - -void -g_hash_table_kv_pair_free_gfunc(gpointer data, G_GNUC_UNUSED gpointer user_data) -{ - GHashTableKVPair *kvp = (GHashTableKVPair *) data; - g_free(kvp); -} - -/*======================== END OF FILE =============================*/ diff --git a/src/libqof/qof/kvp-util.h b/src/libqof/qof/kvp-util.h deleted file mode 100644 index 1c6da4ccdc..0000000000 --- a/src/libqof/qof/kvp-util.h +++ /dev/null @@ -1,72 +0,0 @@ -/********************************************************************\ - * kvp-util.h -- misc KVP utilities * - * Copyright (C) 2003 Linas Vepstas * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of the GNU General Public License as * - * published by the Free Software Foundation; either version 2 of * - * the License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License* - * along with this program; if not, contact: * - * * - * Free Software Foundation Voice: +1-617-542-5942 * - * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 * - * Boston, MA 02110-1301, USA gnu@gnu.org * -\********************************************************************/ - -/** @addtogroup KVP - @{ -*/ -/** @file kvp-util.h - @brief QOF KVP utility functions - */ -/** @name Hash Utilities - @{ -*/ - -#ifndef GNC_KVP_UTIL_H -#define GNC_KVP_UTIL_H - -typedef struct -{ - gpointer key; - gpointer value; -} GHashTableKVPair; - -/** - Returns a GSList* of all the - keys and values in a given hash table. Data elements of lists are - actual hash elements, so be careful, and deallocation of the - GHashTableKVPairs in the result list are the caller's - responsibility. A typical sequence might look like this: - - GSList *kvps = g_hash_table_key_value_pairs(hash); - ... use kvps->data->key and kvps->data->val, etc. here ... - g_slist_foreach(kvps, g_hash_table_kv_pair_free_gfunc, NULL); - g_slist_free(kvps); - -*/ - -#ifdef __cplusplus -extern "C" -{ -#endif - -GSList *g_hash_table_key_value_pairs(GHashTable *table); -void g_hash_table_kv_pair_free_gfunc(gpointer data, gpointer user_data); - -#ifdef __cplusplus -} -#endif - -/***********************************************************************/ - -/** @} */ -/** @} */ -#endif /* GNC_KVP_UTIL_H */ diff --git a/src/libqof/qof/qof.h b/src/libqof/qof/qof.h index 68ad9ff8f4..be030c62cd 100644 --- a/src/libqof/qof/qof.h +++ b/src/libqof/qof/qof.h @@ -80,8 +80,6 @@ #include "qofutil.h" #include "guid.h" #include "kvp_frame.h" -#include "kvp-util.h" -#include "kvp-util-p.h" #include "qofbackend.h" #include "qofid-p.h" #include "qofbook.h" From 50bb5c162a5bbeff34a3fa60393be45ef5e0a623 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Sun, 31 May 2015 18:14:21 -0700 Subject: [PATCH 16/54] Remove "FIXME" comments about KvpFrame in SX-ttinfo.c. SX splits and regular splits have different requirements for Kvp. A regular split's Kvp contains information that applies to that one split alone so it would be a mistake to propagate it into SX. Meanwhile the SX split puts its formulas in Kvp, and we certainly don't want those going into regular splits. --- src/engine/SX-ttinfo.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/engine/SX-ttinfo.c b/src/engine/SX-ttinfo.c index 052d964fa8..66ce1cd242 100644 --- a/src/engine/SX-ttinfo.c +++ b/src/engine/SX-ttinfo.c @@ -27,7 +27,6 @@ #include "SX-ttinfo.h" -/* KvpFrame policy? */ struct TTInfo_s { /* FIXME add notes field */ @@ -41,7 +40,6 @@ struct TTInfo_s struct TTSplitInfo_s { char *action; /* owned by us */ - /* FIXME: What about the split's KvpFrame */ char *memo; /* owned by us */ char *credit_formula, *debit_formula; /* owned by us */ Account *acc; From 57ba97422de3da59e363fd152b172de009beacc8 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Tue, 2 Jun 2015 13:02:16 -0700 Subject: [PATCH 17/54] Rename the hash-table functions so that they don't contain "kvp". They don't have anything to do with KVP. What were they doing in kvp-utils in the first place? --- src/engine/gnc-pricedb.c | 52 ++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/src/engine/gnc-pricedb.c b/src/engine/gnc-pricedb.c index 95bc252f1a..8411b9150e 100644 --- a/src/engine/gnc-pricedb.c +++ b/src/engine/gnc-pricedb.c @@ -53,32 +53,32 @@ typedef struct { gpointer key; gpointer value; -} GHashTableKVPair; +} HashEntry; static void -kv_pair_helper(gpointer key, gpointer val, gpointer user_data) +hash_entry_insert(gpointer key, gpointer val, gpointer user_data) { GSList **result = (GSList **) user_data; - GHashTableKVPair *kvp = g_new(GHashTableKVPair, 1); + HashEntry *entry = g_new(HashEntry, 1); - kvp->key = key; - kvp->value = val; - *result = g_slist_prepend(*result, kvp); + entry->key = key; + entry->value = val; + *result = g_slist_prepend(*result, entry); } static GSList * -g_hash_table_key_value_pairs(GHashTable *table) +hash_table_to_list(GHashTable *table) { GSList *result_list = NULL; - g_hash_table_foreach(table, kv_pair_helper, &result_list); + g_hash_table_foreach(table, hash_entry_insert, &result_list); return result_list; } static void -g_hash_table_kv_pair_free_gfunc(gpointer data, G_GNUC_UNUSED gpointer user_data) +hash_entry_free_gfunc(gpointer data, G_GNUC_UNUSED gpointer user_data) { - GHashTableKVPair *kvp = (GHashTableKVPair *) data; - g_free(kvp); + HashEntry *entry = (HashEntry *) data; + g_free(entry); } /* GObject Initialization */ @@ -2293,10 +2293,10 @@ unstable_price_traversal(GNCPriceDB *db, } static gint -compare_kvpairs_by_commodity_key(gconstpointer a, gconstpointer b) +compare_hash_entries_by_commodity_key(gconstpointer a, gconstpointer b) { - GHashTableKVPair *kvpa = (GHashTableKVPair *) a; - GHashTableKVPair *kvpb = (GHashTableKVPair *) b; + HashEntry *he_a = (HashEntry *) a; + HashEntry *he_b = (HashEntry *) b; gnc_commodity *ca; gnc_commodity *cb; int cmp_result; @@ -2306,8 +2306,8 @@ compare_kvpairs_by_commodity_key(gconstpointer a, gconstpointer b) if (!a) return -1; if (!b) return 1; - ca = (gnc_commodity *) kvpa->key; - cb = (gnc_commodity *) kvpb->key; + ca = (gnc_commodity *) he_a->key; + cb = (gnc_commodity *) he_b->key; cmp_result = g_strcmp0(gnc_commodity_get_namespace(ca), gnc_commodity_get_namespace(cb)); @@ -2329,22 +2329,22 @@ stable_price_traversal(GNCPriceDB *db, if (!db || !f) return FALSE; - currency_hashes = g_hash_table_key_value_pairs(db->commodity_hash); + currency_hashes = hash_table_to_list(db->commodity_hash); currency_hashes = g_slist_sort(currency_hashes, - compare_kvpairs_by_commodity_key); + compare_hash_entries_by_commodity_key); for (i = currency_hashes; i; i = i->next) { - GHashTableKVPair *kv_pair = (GHashTableKVPair *) i->data; - GHashTable *currency_hash = (GHashTable *) kv_pair->value; - GSList *price_lists = g_hash_table_key_value_pairs(currency_hash); + HashEntry *entry = (HashEntry *) i->data; + GHashTable *currency_hash = (GHashTable *) entry->value; + GSList *price_lists = hash_table_to_list(currency_hash); GSList *j; - price_lists = g_slist_sort(price_lists, compare_kvpairs_by_commodity_key); + price_lists = g_slist_sort(price_lists, compare_hash_entries_by_commodity_key); for (j = price_lists; j; j = j->next) { - GHashTableKVPair *pricelist_kvp = (GHashTableKVPair *) j->data; - GList *price_list = (GList *) pricelist_kvp->value; + HashEntry *pricelist_entry = (HashEntry *) j->data; + GList *price_list = (GList *) pricelist_entry->value; GList *node; for (node = (GList *) price_list; node; node = node->next) @@ -2358,7 +2358,7 @@ stable_price_traversal(GNCPriceDB *db, } if (price_lists) { - g_slist_foreach(price_lists, g_hash_table_kv_pair_free_gfunc, NULL); + g_slist_foreach(price_lists, hash_entry_free_gfunc, NULL); g_slist_free(price_lists); price_lists = NULL; } @@ -2366,7 +2366,7 @@ stable_price_traversal(GNCPriceDB *db, if (currency_hashes) { - g_slist_foreach(currency_hashes, g_hash_table_kv_pair_free_gfunc, NULL); + g_slist_foreach(currency_hashes, hash_entry_free_gfunc, NULL); g_slist_free(currency_hashes); } return ok; From eb2d556086e3aa768211b615e2efcaa2cd4bdb98 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Thu, 4 Jun 2015 13:29:01 -0700 Subject: [PATCH 18/54] Move initializing the GValue to the correct type to qof_instance_set_kvp. And ensure that all returns are checked to be the expected type. --- src/engine/Account.c | 102 ++++++-------- src/engine/Split.c | 24 ++-- src/engine/Transaction.c | 240 +++++++++++++++++---------------- src/engine/gnc-budget.c | 12 +- src/engine/gnc-lot.c | 10 +- src/engine/gncJob.c | 6 +- src/libqof/qof/qofinstance.cpp | 5 +- 7 files changed, 197 insertions(+), 202 deletions(-) diff --git a/src/engine/Account.c b/src/engine/Account.c index 02b0916d9d..7ae196dd24 100644 --- a/src/engine/Account.c +++ b/src/engine/Account.c @@ -2314,12 +2314,9 @@ static const char* get_kvp_string_tag (const Account *acc, const char *tag) { GValue v = G_VALUE_INIT; - const char* s; if (acc == NULL || tag == NULL) return NULL; - g_value_init (&v, G_TYPE_STRING); qof_instance_get_kvp (QOF_INSTANCE (acc), tag, &v); - s = g_value_get_string (&v); - return s; + return G_VALUE_HOLDS_STRING (&v) ? g_value_get_string (&v) : NULL; } void @@ -3110,13 +3107,13 @@ gnc_commodity * DxaccAccountGetCurrency (const Account *acc) { GValue v = G_VALUE_INIT; - const char *s; + const char *s = NULL; gnc_commodity_table *table; if (!acc) return NULL; - g_value_init (&v, G_TYPE_STRING); qof_instance_get_kvp (QOF_INSTANCE(acc), "old-currency", &v); - s = g_value_get_string (&v); + if (G_VALUE_HOLDS_STRING (&v)) + s = g_value_get_string (&v); if (!s) return NULL; table = gnc_commodity_table_get_table (qof_instance_get_book(acc)); @@ -3789,9 +3786,8 @@ xaccAccountGetTaxRelated (const Account *acc) { GValue v = G_VALUE_INIT; g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE); - g_value_init (&v, G_TYPE_BOOLEAN); qof_instance_get_kvp (QOF_INSTANCE(acc), "tax-related", &v); - return g_value_get_boolean (&v); + return G_VALUE_HOLDS_BOOLEAN (&v) ? g_value_get_boolean (&v) : FALSE; } void @@ -3814,10 +3810,8 @@ xaccAccountGetTaxUSCode (const Account *acc) { GValue v = G_VALUE_INIT; g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE); - g_value_init (&v, G_TYPE_STRING); qof_instance_get_kvp (QOF_INSTANCE(acc), "/tax-US/code", &v); - g_return_val_if_fail (G_VALUE_HOLDS_STRING (&v), FALSE); - return g_value_get_string (&v); + return G_VALUE_HOLDS_STRING (&v) ? g_value_get_string (&v) : NULL; } void @@ -3839,11 +3833,9 @@ xaccAccountGetTaxUSPayerNameSource (const Account *acc) { GValue v = G_VALUE_INIT; g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE); - g_value_init (&v, G_TYPE_STRING); qof_instance_get_kvp (QOF_INSTANCE(acc), "/tax-US/payer-name-source", &v); - g_return_val_if_fail (G_VALUE_HOLDS_STRING (&v), FALSE); - return g_value_get_string (&v); + return G_VALUE_HOLDS_STRING (&v) ? g_value_get_string (&v) : NULL; } void @@ -3863,13 +3855,12 @@ xaccAccountSetTaxUSPayerNameSource (Account *acc, const char *source) gint64 xaccAccountGetTaxUSCopyNumber (const Account *acc) { - gint64 copy_number; + gint64 copy_number = 0; GValue v = G_VALUE_INIT; g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE); - g_value_init (&v, G_TYPE_INT64); qof_instance_get_kvp (QOF_INSTANCE(acc), "/tax-US/copy-number", &v); - g_return_val_if_fail (G_VALUE_HOLDS_INT64 (&v), FALSE); - copy_number = g_value_get_int64 (&v); + if (G_VALUE_HOLDS_INT64 (&v)) + copy_number = g_value_get_int64 (&v); return (copy_number == 0) ? 1 : copy_number; } @@ -3902,10 +3893,12 @@ xaccAccountGetPlaceholder (const Account *acc) { GValue v = G_VALUE_INIT; g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE); - g_value_init (&v, G_TYPE_BOOLEAN); qof_instance_get_kvp (QOF_INSTANCE(acc), "placeholder", &v); - g_return_val_if_fail (G_VALUE_HOLDS_BOOLEAN (&v), FALSE); - return g_value_get_boolean (&v); + if (G_VALUE_HOLDS_BOOLEAN (&v)) + return g_value_get_boolean (&v); + if (G_VALUE_HOLDS_STRING (&v)) + return strcmp (g_value_get_string (&v), "true") == 0; + return FALSE; } void @@ -3951,10 +3944,8 @@ xaccAccountGetHidden (const Account *acc) { GValue v = G_VALUE_INIT; g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE); - g_value_init (&v, G_TYPE_BOOLEAN); qof_instance_get_kvp (QOF_INSTANCE(acc), "hidden", &v); - g_return_val_if_fail (G_VALUE_HOLDS_BOOLEAN (&v), FALSE); - return g_value_get_boolean (&v); + return G_VALUE_HOLDS_BOOLEAN (&v) ? g_value_get_boolean (&v) : FALSE; } void @@ -4256,13 +4247,12 @@ xaccAccountIsPriced(const Account *acc) gboolean xaccAccountGetReconcileLastDate (const Account *acc, time64 *last_date) { - gint64 date; + gint64 date = 0; GValue v = G_VALUE_INIT; g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE); - g_value_init (&v, G_TYPE_INT64); qof_instance_get_kvp (QOF_INSTANCE(acc), "reconcile-info/last-date", &v); - g_return_val_if_fail (G_VALUE_HOLDS_INT64 (&v), FALSE); - date = g_value_get_int64 (&v); + if (G_VALUE_HOLDS_INT64 (&v)) + date = g_value_get_int64 (&v); if (date) { @@ -4298,18 +4288,18 @@ xaccAccountGetReconcileLastInterval (const Account *acc, int *months, int *days) { GValue v1, v2; - int m, d; + int64_t m = 0, d = 0; if (!acc) return FALSE; g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE); - g_value_init (&v1, G_TYPE_INT64); qof_instance_get_kvp (QOF_INSTANCE(acc), "reconcile-info/last-interval/months", &v1); - g_value_init (&v2, G_TYPE_INT64); qof_instance_get_kvp (QOF_INSTANCE(acc), "reconcile-info/last-interval/days", &v2); - m = g_value_get_int64 (&v1); - d = g_value_get_int64 (&v2); + if (G_VALUE_HOLDS_INT64 (&v1)) + m = g_value_get_int64 (&v1); + if (G_VALUE_HOLDS_INT64 (&v2)) + d = g_value_get_int64 (&v2); if (m && d) { if (months) @@ -4349,14 +4339,13 @@ xaccAccountSetReconcileLastInterval (Account *acc, int months, int days) gboolean xaccAccountGetReconcilePostponeDate (const Account *acc, time64 *postpone_date) { - gint64 date; + gint64 date = 0; GValue v = G_VALUE_INIT; g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE); - g_value_init (&v, G_TYPE_INT64); qof_instance_get_kvp (QOF_INSTANCE(acc), "reconcile-info/postpone/date", &v); - g_return_val_if_fail (G_VALUE_HOLDS_INT64 (&v), FALSE); - date = g_value_get_int64 (&v); + if (G_VALUE_HOLDS_INT64 (&v)) + date = g_value_get_int64 (&v); if (date) { @@ -4392,14 +4381,13 @@ gboolean xaccAccountGetReconcilePostponeBalance (const Account *acc, gnc_numeric *balance) { - gnc_numeric bal; + gnc_numeric bal = gnc_numeric_zero (); GValue v = G_VALUE_INIT; g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE); - g_value_init (&v, GNC_TYPE_NUMERIC); qof_instance_get_kvp (QOF_INSTANCE(acc), "reconcile-info/postpone/balance", &v); - g_return_val_if_fail (G_VALUE_HOLDS_INT64 (&v), FALSE); - bal = *(gnc_numeric*)g_value_get_boxed (&v); + if (G_VALUE_HOLDS_INT64 (&v)) + bal = *(gnc_numeric*)g_value_get_boxed (&v); if (bal.denom) { @@ -4455,11 +4443,9 @@ xaccAccountGetAutoInterestXfer (const Account *acc, gboolean default_value) { GValue v = G_VALUE_INIT; g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE); - g_value_init (&v, G_TYPE_BOOLEAN); qof_instance_get_kvp (QOF_INSTANCE(acc), "reconcile-info/auto-interest-transfer", &v); - g_return_val_if_fail (G_VALUE_HOLDS_BOOLEAN (&v), FALSE); - return g_value_get_boolean (&v); + return G_VALUE_HOLDS_BOOLEAN (&v) ? g_value_get_boolean (&v) : FALSE; } /********************************************************************\ @@ -4488,10 +4474,8 @@ xaccAccountGetLastNum (const Account *acc) { GValue v = G_VALUE_INIT; g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE); - g_value_init (&v, G_TYPE_STRING); qof_instance_get_kvp (QOF_INSTANCE(acc), "last-num", &v); - g_return_val_if_fail (G_VALUE_HOLDS_STRING (&v), FALSE); - return g_value_get_string (&v); + return G_VALUE_HOLDS_STRING (&v) ? g_value_get_string (&v) : NULL; } /********************************************************************\ @@ -4562,13 +4546,13 @@ xaccAccountGainsAccount (Account *acc, gnc_commodity *curr) GValue v = G_VALUE_INIT; gchar *curr_name = g_strdup_printf ("/lot-mgmt/gains-act/%s", gnc_commodity_get_unique_name (curr)); - GncGUID *guid; + GncGUID *guid = NULL; Account *gains_account; g_return_val_if_fail (acc != NULL, NULL); - g_value_init (&v, GNC_TYPE_GUID); qof_instance_get_kvp (QOF_INSTANCE(acc), curr_name, &v); - guid = (GncGUID*)g_value_get_boxed (&v); + if (G_VALUE_HOLDS_BOXED (&v)) + guid = (GncGUID*)g_value_get_boxed (&v); if (guid == NULL) /* No gains account for this currency */ { gains_account = GetOrMakeOrphanAccount (gnc_account_get_root (acc), @@ -4630,9 +4614,8 @@ dxaccAccountGetPriceSrc(const Account *acc) if (!xaccAccountIsPriced(acc)) return NULL; - g_value_init (&v, G_TYPE_STRING); qof_instance_get_kvp (QOF_INSTANCE(acc), "old-price-source", &v); - return g_value_get_string (&v); + return G_VALUE_HOLDS_STRING (&v) ? g_value_get_string (&v) : NULL; } /********************************************************************\ @@ -4661,9 +4644,8 @@ dxaccAccountGetQuoteTZ(const Account *acc) GValue v = G_VALUE_INIT; if (!acc) return NULL; if (!xaccAccountIsPriced(acc)) return NULL; - g_value_init (&v, G_TYPE_STRING); qof_instance_get_kvp (QOF_INSTANCE (acc), "old-quote-tz", &v); - return g_value_get_string (&v); + return G_VALUE_HOLDS_STRING (&v) ? g_value_get_string (&v) : NULL; } /********************************************************************\ @@ -4700,10 +4682,9 @@ xaccAccountGetReconcileChildrenStatus(const Account *acc) */ GValue v = G_VALUE_INIT; if (!acc) return FALSE; - g_value_init (&v, G_TYPE_BOOLEAN); qof_instance_get_kvp (QOF_INSTANCE (acc), "reconcile-info/include-children", &v); - return g_value_get_int64 (&v); + return G_VALUE_HOLDS_INT64 (&v) ? g_value_get_int64 (&v) : FALSE; } /********************************************************************\ @@ -5095,7 +5076,7 @@ gnc_imap_find_account (GncImportMatchMap *imap, const char *key) { GValue v = G_VALUE_INIT; - GncGUID * guid; + GncGUID * guid = NULL; char *kvp_path; if (!imap || !key) return NULL; @@ -5103,9 +5084,9 @@ gnc_imap_find_account (GncImportMatchMap *imap, kvp_path = g_strdup_printf (IMAP_FRAME "/%s", key); else kvp_path = g_strdup_printf (IMAP_FRAME "/%s/%s", category, key); - g_value_init (&v, GNC_TYPE_GUID); qof_instance_get_kvp (QOF_INSTANCE (imap->acc), kvp_path, &v); - guid = (GncGUID*)g_value_get_boxed (&v); + if (G_VALUE_HOLDS_BOXED (&v)) + guid = (GncGUID*)g_value_get_boxed (&v); g_free (kvp_path); return xaccAccountLookup (guid, imap->book); } @@ -5483,7 +5464,6 @@ gnc_imap_add_account_bayes(GncImportMatchMap *imap, (char*)current_token->data, account_fullname); - g_value_init (&value, G_TYPE_INT64); qof_instance_get_kvp (QOF_INSTANCE (imap->acc), kvp_path, &value); /* if the token/account is already in the tree, read the current * value from the tree and use this for the basis of the value we diff --git a/src/engine/Split.c b/src/engine/Split.c index fc95158d1c..a8d5f17a05 100644 --- a/src/engine/Split.c +++ b/src/engine/Split.c @@ -1085,7 +1085,7 @@ xaccSplitDetermineGainStatus (Split *split) { Split *other; GValue v = G_VALUE_INIT; - GncGUID *guid; + GncGUID *guid = NULL; if (GAINS_STATUS_UNKNOWN != split->gains) return; @@ -1097,9 +1097,9 @@ xaccSplitDetermineGainStatus (Split *split) return; } - g_value_init (&v, GNC_TYPE_GUID); qof_instance_get_kvp (QOF_INSTANCE (split), "gains-source", &v); - guid = (GncGUID*)g_value_get_boxed (&v); + if (G_VALUE_HOLDS_BOXED (&v)) + guid = (GncGUID*)g_value_get_boxed (&v); if (!guid) { // CHECKME: We leave split->gains_split alone. Is that correct? @@ -2012,12 +2012,12 @@ const char * xaccSplitGetType(const Split *s) { GValue v = G_VALUE_INIT; - const char *split_type; + const char *split_type = NULL; if (!s) return NULL; - g_value_init (&v, G_TYPE_STRING); qof_instance_get_kvp (QOF_INSTANCE (s), "split-type", &v); - split_type = g_value_get_string (&v); + if (G_VALUE_HOLDS_STRING (&v)) + split_type = g_value_get_string (&v); return split_type ? split_type : "normal"; } @@ -2167,11 +2167,11 @@ gnc_numeric xaccSplitVoidFormerAmount(const Split *split) { GValue v = G_VALUE_INIT; - gnc_numeric *num; + gnc_numeric *num = NULL; g_return_val_if_fail(split, gnc_numeric_zero()); - g_value_init (&v, GNC_TYPE_NUMERIC); qof_instance_get_kvp (QOF_INSTANCE (split), void_former_amt_str, &v); - num = (gnc_numeric*)g_value_get_boxed (&v); + if (G_VALUE_HOLDS_BOXED (&v)) + num = (gnc_numeric*)g_value_get_boxed (&v); return num ? *num : gnc_numeric_zero(); } @@ -2179,11 +2179,11 @@ gnc_numeric xaccSplitVoidFormerValue(const Split *split) { GValue v = G_VALUE_INIT; - gnc_numeric *num; + gnc_numeric *num = NULL; g_return_val_if_fail(split, gnc_numeric_zero()); - g_value_init (&v, GNC_TYPE_NUMERIC); qof_instance_get_kvp (QOF_INSTANCE (split), void_former_val_str, &v); - num = (gnc_numeric*)g_value_get_boxed (&v); + if (G_VALUE_HOLDS_BOXED (&v)) + num = (gnc_numeric*)g_value_get_boxed (&v); return num ? *num : gnc_numeric_zero(); } diff --git a/src/engine/Transaction.c b/src/engine/Transaction.c index df03fb9bef..bd0db9d77b 100644 --- a/src/engine/Transaction.c +++ b/src/engine/Transaction.c @@ -2200,9 +2200,10 @@ xaccTransGetAssociation (const Transaction *trans) { GValue v = G_VALUE_INIT; if (!trans) return NULL; - g_value_init (&v, G_TYPE_STRING); qof_instance_get_kvp (QOF_INSTANCE (trans), assoc_uri_str, &v); - return g_value_get_string (&v); + if (G_VALUE_HOLDS_STRING (&v)) + return g_value_get_string (&v); + return NULL; } const char * @@ -2210,9 +2211,10 @@ xaccTransGetNotes (const Transaction *trans) { GValue v = G_VALUE_INIT; if (!trans) return NULL; - g_value_init (&v, G_TYPE_STRING); qof_instance_get_kvp (QOF_INSTANCE (trans), trans_notes_str, &v); - return g_value_get_string (&v); + if (G_VALUE_HOLDS_STRING (&v)) + return g_value_get_string (&v); + return NULL; } gboolean @@ -2220,9 +2222,10 @@ xaccTransGetIsClosingTxn (const Transaction *trans) { GValue v = G_VALUE_INIT; if (!trans) return FALSE; - g_value_init (&v, G_TYPE_INT64); qof_instance_get_kvp (QOF_INSTANCE (trans), trans_is_closing_str, &v); - return g_value_get_int64 (&v); + if (G_VALUE_HOLDS_INT64 (&v)) + return g_value_get_int64 (&v); + return FALSE; } /********************************************************************\ @@ -2273,9 +2276,9 @@ xaccTransGetDatePostedGDate (const Transaction *trans) * from there because it doesn't suffer from time zone * shifts. */ GValue v = G_VALUE_INIT; - g_value_init (&v, G_TYPE_DATE); qof_instance_get_kvp (QOF_INSTANCE (trans), TRANS_DATE_POSTED, &v); - result = *(GDate*)g_value_get_boxed (&v); + if (G_VALUE_HOLDS_BOXED (&v)) + result = *(GDate*)g_value_get_boxed (&v); if (! g_date_valid (&result)) result = timespec_to_gdate(xaccTransRetDatePostedTS(trans)); } @@ -2299,9 +2302,9 @@ xaccTransGetDateDueTS (const Transaction *trans, Timespec *ts) GValue v = G_VALUE_INIT; if (!trans || !ts) return; - g_value_init (&v, GNC_TYPE_TIMESPEC); qof_instance_get_kvp (QOF_INSTANCE (trans), TRANS_DATE_DUE_KVP, &v); - *ts = *(Timespec*)g_value_get_boxed (&v); + if (G_VALUE_HOLDS_BOXED (&v)) + *ts = *(Timespec*)g_value_get_boxed (&v); if (ts->tv_sec == 0) xaccTransGetDatePostedTS (trans, ts); } @@ -2317,13 +2320,13 @@ xaccTransRetDateDueTS (const Transaction *trans) char xaccTransGetTxnType (const Transaction *trans) { - const char *s; + const char *s = NULL; GValue v = G_VALUE_INIT; if (!trans) return TXN_TYPE_NONE; - g_value_init (&v, G_TYPE_STRING); qof_instance_get_kvp (QOF_INSTANCE (trans), TRANS_TXN_TYPE_KVP, &v); - s = g_value_get_string (&v); + if (G_VALUE_HOLDS_STRING (&v)) + s = g_value_get_string (&v); if (s && strlen (s) == 0) return *s; @@ -2337,11 +2340,11 @@ xaccTransGetReadOnly (const Transaction *trans) * for performance reasons, since its checked every trans commit. */ GValue v = G_VALUE_INIT; - const char *s; + const char *s = NULL; if (trans == NULL) return NULL; - g_value_init (&v, G_TYPE_STRING); qof_instance_get_kvp (QOF_INSTANCE(trans), TRANS_READ_ONLY_REASON, &v); - s = g_value_get_string (&v); + if (G_VALUE_HOLDS_STRING (&v)) + s = g_value_get_string (&v); if (s && strlen (s)) return s; @@ -2529,9 +2532,11 @@ xaccTransVoid(Transaction *trans, const char *reason) g_return_if_fail(trans && reason); xaccTransBeginEdit(trans); - g_value_init (&v, G_TYPE_STRING); qof_instance_get_kvp (QOF_INSTANCE (trans), trans_notes_str, &v); - qof_instance_set_kvp (QOF_INSTANCE (trans), void_former_notes_str, &v); + if (G_VALUE_HOLDS_STRING (&v)) + qof_instance_set_kvp (QOF_INSTANCE (trans), void_former_notes_str, &v); + else + g_value_init (&v, G_TYPE_STRING); g_value_set_string (&v, _("Voided transaction")); qof_instance_set_kvp (QOF_INSTANCE (trans), trans_notes_str, &v); @@ -2552,13 +2557,13 @@ xaccTransVoid(Transaction *trans, const char *reason) gboolean xaccTransGetVoidStatus(const Transaction *trans) { - const char *s; + const char *s = NULL; GValue v = G_VALUE_INIT; g_return_val_if_fail(trans, FALSE); - g_value_init (&v, G_TYPE_STRING); qof_instance_get_kvp (QOF_INSTANCE (trans), void_reason_str, &v); - s = g_value_get_string (&v); + if (G_VALUE_HOLDS_STRING (&v)) + s = g_value_get_string (&v); return s && strlen(s); } @@ -2568,22 +2573,23 @@ xaccTransGetVoidReason(const Transaction *trans) GValue v = G_VALUE_INIT; g_return_val_if_fail(trans, FALSE); - g_value_init (&v, G_TYPE_STRING); qof_instance_get_kvp (QOF_INSTANCE (trans), void_reason_str, &v); - return g_value_get_string (&v); + if (G_VALUE_HOLDS_STRING (&v)) + return g_value_get_string (&v); + return NULL; } Timespec xaccTransGetVoidTime(const Transaction *tr) { GValue v = G_VALUE_INIT; - const char *s; + const char *s = NULL; Timespec void_time = {0, 0}, *ts; g_return_val_if_fail(tr, void_time); - g_value_init (&v, G_TYPE_STRING); qof_instance_get_kvp (QOF_INSTANCE (tr), void_time_str, &v); - s = g_value_get_string (&v); + if (G_VALUE_HOLDS_STRING (&v)) + s = g_value_get_string (&v); if (s) return gnc_iso8601_to_timespec_gmt (s); return void_time; @@ -2593,17 +2599,18 @@ void xaccTransUnvoid (Transaction *trans) { GValue v = G_VALUE_INIT; - const char *s; + const char *s = NULL; g_return_if_fail(trans); - g_value_init (&v, G_TYPE_STRING); qof_instance_get_kvp (QOF_INSTANCE (trans), void_reason_str, &v); - s = g_value_get_string (&v); + if (G_VALUE_HOLDS_STRING (&v)) + s = g_value_get_string (&v); if (s == NULL) return; /* Transaction isn't voided. Bail. */ xaccTransBeginEdit(trans); qof_instance_get_kvp (QOF_INSTANCE (trans), void_former_notes_str, &v); - qof_instance_set_kvp (QOF_INSTANCE (trans), trans_notes_str, &v); + if (G_VALUE_HOLDS_STRING (&v)) + qof_instance_set_kvp (QOF_INSTANCE (trans), trans_notes_str, &v); qof_instance_set_kvp (QOF_INSTANCE (trans), void_former_notes_str, NULL); qof_instance_set_kvp (QOF_INSTANCE (trans), void_reason_str, NULL); qof_instance_set_kvp (QOF_INSTANCE (trans), void_time_str, NULL); @@ -2648,10 +2655,11 @@ xaccTransGetReversedBy(const Transaction *trans) { GValue v = G_VALUE_INIT; g_return_val_if_fail(trans, NULL); - g_value_init (&v, GNC_TYPE_GUID); qof_instance_get_kvp (QOF_INSTANCE(trans), TRANS_REVERSED_BY, &v); - return xaccTransLookup((GncGUID*)g_value_get_boxed (&v), - qof_instance_get_book(trans)); + if (G_VALUE_HOLDS_BOXED (&v)) + return xaccTransLookup((GncGUID*)g_value_get_boxed (&v), + qof_instance_get_book(trans)); + return NULL; } void @@ -2698,9 +2706,9 @@ xaccTransScrubGainsDate (Transaction *trans) xaccSplitDetermineGainStatus(s); if ((GAINS_STATUS_GAINS & s->gains) && - s->gains_split && - ((s->gains_split->gains & GAINS_STATUS_DATE_DIRTY) || - (s->gains & GAINS_STATUS_DATE_DIRTY))) + s->gains_split && + ((s->gains_split->gains & GAINS_STATUS_DATE_DIRTY) || + (s->gains & GAINS_STATUS_DATE_DIRTY))) { Transaction *source_trans = s->gains_split->parent; ts = source_trans->date_posted; @@ -2752,8 +2760,8 @@ restart: if ((s->gains & GAINS_STATUS_VDIRTY) || (s->gains_split && (s->gains_split->gains & GAINS_STATUS_VDIRTY))) - xaccSplitComputeCapGains(s, gain_acc); - ); + xaccSplitComputeCapGains(s, gain_acc); + ); LEAVE("(trans=%p)", trans); } @@ -2825,85 +2833,85 @@ trans_is_balanced_p (const Transaction *trans) gboolean xaccTransRegister (void) { static QofParam params[] = - { { - TRANS_NUM, QOF_TYPE_STRING, - (QofAccessFunc)xaccTransGetNum, - (QofSetterFunc)qofTransSetNum, - qof_string_number_compare_func - }, - { - TRANS_DESCRIPTION, QOF_TYPE_STRING, - (QofAccessFunc)xaccTransGetDescription, - (QofSetterFunc)qofTransSetDescription - }, - { - TRANS_DATE_ENTERED, QOF_TYPE_DATE, - (QofAccessFunc)xaccTransRetDateEnteredTS, - (QofSetterFunc)qofTransSetDateEntered - }, - { - TRANS_DATE_POSTED, QOF_TYPE_DATE, - (QofAccessFunc)xaccTransRetDatePostedTS, - (QofSetterFunc)qofTransSetDatePosted - }, - { - TRANS_DATE_DUE, QOF_TYPE_DATE, - (QofAccessFunc)xaccTransRetDateDueTS, NULL - }, - { - TRANS_IMBALANCE, QOF_TYPE_NUMERIC, - (QofAccessFunc)xaccTransGetImbalanceValue, NULL - }, - { - TRANS_NOTES, QOF_TYPE_STRING, - (QofAccessFunc)xaccTransGetNotes, - (QofSetterFunc)qofTransSetNotes - }, - { - TRANS_ASSOCIATION, QOF_TYPE_STRING, - (QofAccessFunc)xaccTransGetAssociation, - (QofSetterFunc)xaccTransSetAssociation - }, - { - TRANS_IS_CLOSING, QOF_TYPE_BOOLEAN, - (QofAccessFunc)xaccTransGetIsClosingTxn, NULL - }, - { - TRANS_IS_BALANCED, QOF_TYPE_BOOLEAN, - (QofAccessFunc)trans_is_balanced_p, NULL - }, - { - TRANS_TYPE, QOF_TYPE_CHAR, - (QofAccessFunc)xaccTransGetTxnType, - (QofSetterFunc)xaccTransSetTxnType - }, - { - TRANS_VOID_STATUS, QOF_TYPE_BOOLEAN, - (QofAccessFunc)xaccTransGetVoidStatus, NULL - }, - { - TRANS_VOID_REASON, QOF_TYPE_STRING, - (QofAccessFunc)xaccTransGetVoidReason, NULL - }, - { - TRANS_VOID_TIME, QOF_TYPE_DATE, - (QofAccessFunc)xaccTransGetVoidTime, NULL - }, - { - TRANS_SPLITLIST, GNC_ID_SPLIT, - (QofAccessFunc)xaccTransGetSplitList, NULL - }, - { - QOF_PARAM_BOOK, QOF_ID_BOOK, - (QofAccessFunc)qof_instance_get_book, NULL - }, - { - QOF_PARAM_GUID, QOF_TYPE_GUID, - (QofAccessFunc)qof_entity_get_guid, NULL - }, - { NULL }, - }; + { + TRANS_NUM, QOF_TYPE_STRING, + (QofAccessFunc)xaccTransGetNum, + (QofSetterFunc)qofTransSetNum, + qof_string_number_compare_func + }, + { + TRANS_DESCRIPTION, QOF_TYPE_STRING, + (QofAccessFunc)xaccTransGetDescription, + (QofSetterFunc)qofTransSetDescription + }, + { + TRANS_DATE_ENTERED, QOF_TYPE_DATE, + (QofAccessFunc)xaccTransRetDateEnteredTS, + (QofSetterFunc)qofTransSetDateEntered + }, + { + TRANS_DATE_POSTED, QOF_TYPE_DATE, + (QofAccessFunc)xaccTransRetDatePostedTS, + (QofSetterFunc)qofTransSetDatePosted + }, + { + TRANS_DATE_DUE, QOF_TYPE_DATE, + (QofAccessFunc)xaccTransRetDateDueTS, NULL + }, + { + TRANS_IMBALANCE, QOF_TYPE_NUMERIC, + (QofAccessFunc)xaccTransGetImbalanceValue, NULL + }, + { + TRANS_NOTES, QOF_TYPE_STRING, + (QofAccessFunc)xaccTransGetNotes, + (QofSetterFunc)qofTransSetNotes + }, + { + TRANS_ASSOCIATION, QOF_TYPE_STRING, + (QofAccessFunc)xaccTransGetAssociation, + (QofSetterFunc)xaccTransSetAssociation + }, + { + TRANS_IS_CLOSING, QOF_TYPE_BOOLEAN, + (QofAccessFunc)xaccTransGetIsClosingTxn, NULL + }, + { + TRANS_IS_BALANCED, QOF_TYPE_BOOLEAN, + (QofAccessFunc)trans_is_balanced_p, NULL + }, + { + TRANS_TYPE, QOF_TYPE_CHAR, + (QofAccessFunc)xaccTransGetTxnType, + (QofSetterFunc)xaccTransSetTxnType + }, + { + TRANS_VOID_STATUS, QOF_TYPE_BOOLEAN, + (QofAccessFunc)xaccTransGetVoidStatus, NULL + }, + { + TRANS_VOID_REASON, QOF_TYPE_STRING, + (QofAccessFunc)xaccTransGetVoidReason, NULL + }, + { + TRANS_VOID_TIME, QOF_TYPE_DATE, + (QofAccessFunc)xaccTransGetVoidTime, NULL + }, + { + TRANS_SPLITLIST, GNC_ID_SPLIT, + (QofAccessFunc)xaccTransGetSplitList, NULL + }, + { + QOF_PARAM_BOOK, QOF_ID_BOOK, + (QofAccessFunc)qof_instance_get_book, NULL + }, + { + QOF_PARAM_GUID, QOF_TYPE_GUID, + (QofAccessFunc)qof_entity_get_guid, NULL + }, + { NULL }, + }; qof_class_register (GNC_ID_TRANS, (QofSortFunc)xaccTransOrder, params); diff --git a/src/engine/gnc-budget.c b/src/engine/gnc-budget.c index c9be5d1eb8..f748f7565f 100644 --- a/src/engine/gnc-budget.c +++ b/src/engine/gnc-budget.c @@ -554,14 +554,16 @@ gnc_budget_is_account_period_value_set(const GncBudget *budget, { GValue v = G_VALUE_INIT; gchar path[BUF_SIZE]; + gconstpointer ptr = NULL; g_return_val_if_fail(GNC_IS_BUDGET(budget), FALSE); g_return_val_if_fail(account, FALSE); make_period_path (account, period_num, path); - g_value_init (&v, GNC_TYPE_NUMERIC); qof_instance_get_kvp (QOF_INSTANCE (budget), path, &v); - return (g_value_get_boxed (&v) != NULL); + if (G_VALUE_HOLDS_BOXED (&v)) + ptr = g_value_get_boxed (&v); + return (ptr != NULL); } gnc_numeric @@ -569,17 +571,17 @@ gnc_budget_get_account_period_value(const GncBudget *budget, const Account *account, guint period_num) { - gnc_numeric *numeric; + gnc_numeric *numeric = NULL; gchar path[BUF_SIZE]; GValue v = G_VALUE_INIT; g_return_val_if_fail(GNC_IS_BUDGET(budget), gnc_numeric_zero()); g_return_val_if_fail(account, gnc_numeric_zero()); - g_value_init (&v, GNC_TYPE_NUMERIC); make_period_path (account, period_num, path); qof_instance_get_kvp (QOF_INSTANCE (budget), path, &v); - numeric = (gnc_numeric*)g_value_get_boxed (&v); + if (G_VALUE_HOLDS_BOXED (&v)) + numeric = (gnc_numeric*)g_value_get_boxed (&v); if (numeric) return *numeric; diff --git a/src/engine/gnc-lot.c b/src/engine/gnc-lot.c index 7e7145c41a..e31fd743e5 100644 --- a/src/engine/gnc-lot.c +++ b/src/engine/gnc-lot.c @@ -436,9 +436,10 @@ gnc_lot_get_title (const GNCLot *lot) { GValue v = G_VALUE_INIT; if (!lot) return NULL; - g_value_init (&v, G_TYPE_STRING); qof_instance_get_kvp (QOF_INSTANCE (lot), "/title", &v); - return g_value_get_string (&v); + if (G_VALUE_HOLDS_STRING (&v)) + return g_value_get_string (&v); + return NULL; } const char * @@ -446,9 +447,10 @@ gnc_lot_get_notes (const GNCLot *lot) { GValue v = G_VALUE_INIT; if (!lot) return NULL; - g_value_init (&v, G_TYPE_STRING); qof_instance_get_kvp (QOF_INSTANCE (lot), "/notes", &v); - return g_value_get_string (&v); + if (G_VALUE_HOLDS_STRING (&v)) + return g_value_get_string (&v); + return NULL; } void diff --git a/src/engine/gncJob.c b/src/engine/gncJob.c index 284f1b51c3..bd4c6720dd 100644 --- a/src/engine/gncJob.c +++ b/src/engine/gncJob.c @@ -454,11 +454,11 @@ const char * gncJobGetReference (const GncJob *job) gnc_numeric gncJobGetRate (const GncJob *job) { GValue v = G_VALUE_INIT; - gnc_numeric *rate; + gnc_numeric *rate = NULL; if (!job) return gnc_numeric_zero (); - g_value_init (&v, GNC_TYPE_NUMERIC); qof_instance_get_kvp (QOF_INSTANCE (job), GNC_JOB_RATE, &v); - rate = (gnc_numeric*)g_value_get_boxed (&v); + if (G_VALUE_HOLDS_BOXED (&v)) + rate = (gnc_numeric*)g_value_get_boxed (&v); if (rate) return *rate; return gnc_numeric_zero(); diff --git a/src/libqof/qof/qofinstance.cpp b/src/libqof/qof/qofinstance.cpp index 28c45eab4c..ed0b2a2834 100644 --- a/src/libqof/qof/qofinstance.cpp +++ b/src/libqof/qof/qofinstance.cpp @@ -1081,8 +1081,11 @@ void qof_instance_get_kvp (QofInstance *inst, const gchar *key, GValue *value) { GValue *temp = kvp_frame_get_gvalue (inst->kvp_data, key); - if (temp) + if (G_IS_VALUE (temp)) { + if (G_IS_VALUE (value)) + g_value_unset (value); + g_value_init (value, G_VALUE_TYPE (temp)); g_value_copy (temp, value); gnc_gvalue_free (temp); } From 232dd4c0dc35d15b0f8c8c91e30d76f8cf5913b1 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Thu, 4 Jun 2015 13:31:14 -0700 Subject: [PATCH 19/54] Provide qof_instance with functions to delete slots. --- src/libqof/qof/qofinstance-p.h | 3 +++ src/libqof/qof/qofinstance.cpp | 14 ++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/src/libqof/qof/qofinstance-p.h b/src/libqof/qof/qofinstance-p.h index 783a9a495e..7582ad75ad 100644 --- a/src/libqof/qof/qofinstance-p.h +++ b/src/libqof/qof/qofinstance-p.h @@ -126,6 +126,9 @@ gboolean qof_instance_kvp_has_guid (const QofInstance *inst, const char *path, void qof_instance_kvp_merge_guids (const QofInstance *target, const QofInstance *donor, const char* path); gboolean qof_instance_has_slot (const QofInstance *inst, const char *path); +void qof_instance_slot_delete (const QofInstance *inst, const char *path); +void qof_instance_slot_delete_if_empty (const QofInstance *inst, + const char *path); #ifdef __cplusplus } diff --git a/src/libqof/qof/qofinstance.cpp b/src/libqof/qof/qofinstance.cpp index ed0b2a2834..3ae1e879a5 100644 --- a/src/libqof/qof/qofinstance.cpp +++ b/src/libqof/qof/qofinstance.cpp @@ -1273,5 +1273,19 @@ qof_instance_has_slot (const QofInstance *inst, const char *path) return kvp_frame_get_value (inst->kvp_data, path) != NULL; } +void +qof_instance_slot_delete (const QofInstance *inst, const char *path) +{ + kvp_frame_set_frame_nc (inst->kvp_data, path, NULL); +} + +void +qof_instance_slot_delete_if_empty (const QofInstance *inst, const char *path) +{ + KvpFrame *frame = kvp_frame_get_frame (inst->kvp_data, path); + if (frame && kvp_frame_is_empty (frame)) + kvp_frame_set_frame_nc (inst->kvp_data, path, NULL); +} + /* ========================== END OF FILE ======================= */ From 4f4711c564c4eabd99ea74cab907226a2b3cc268 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Thu, 4 Jun 2015 13:32:15 -0700 Subject: [PATCH 20/54] Convert Scrub.c from using direct KVP to routing them through qof_instance. --- src/engine/Scrub.c | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/src/engine/Scrub.c b/src/engine/Scrub.c index 42d4a38a8e..0bc97945a7 100644 --- a/src/engine/Scrub.c +++ b/src/engine/Scrub.c @@ -50,6 +50,7 @@ #include "Transaction.h" #include "TransactionP.h" #include "gnc-commodity.h" +#include #undef G_LOG_DOMAIN #define G_LOG_DOMAIN "gnc.engine.scrub" @@ -1157,11 +1158,10 @@ xaccAccountDeleteOldData (Account *account) { if (!account) return; xaccAccountBeginEdit (account); - - kvp_frame_set_slot_nc (account->inst.kvp_data, "old-currency", NULL); - kvp_frame_set_slot_nc (account->inst.kvp_data, "old-security", NULL); - kvp_frame_set_slot_nc (account->inst.kvp_data, "old-currency-scu", NULL); - kvp_frame_set_slot_nc (account->inst.kvp_data, "old-security-scu", NULL); + qof_instance_set_kvp (QOF_INSTANCE (account), "old-currency", NULL); + qof_instance_set_kvp (QOF_INSTANCE (account), "old-security", NULL); + qof_instance_set_kvp (QOF_INSTANCE (account), "old-currency-scu", NULL); + qof_instance_set_kvp (QOF_INSTANCE (account), "old-security-scu", NULL); qof_instance_set_dirty (QOF_INSTANCE (account)); xaccAccountCommitEdit (account); } @@ -1262,30 +1262,28 @@ xaccAccountTreeScrubQuoteSources (Account *root, gnc_commodity_table *table) void xaccAccountScrubKvp (Account *account) { + GValue v = G_VALUE_INIT; const gchar *str; gchar *str2; - KvpFrame *frame; if (!account) return; - str = kvp_frame_get_string(account->inst.kvp_data, "notes"); - if (str) + qof_instance_get_kvp (QOF_INSTANCE (account), "notes", &v); + if (G_VALUE_HOLDS_STRING (&v)) { - str2 = g_strstrip(g_strdup(str)); + str2 = g_strstrip(g_value_dup_string(&v)); if (strlen(str2) == 0) - kvp_frame_set_slot_nc (account->inst.kvp_data, "notes", NULL); + qof_instance_slot_delete (QOF_INSTANCE (account), "notes"); g_free(str2); } - str = kvp_frame_get_string(account->inst.kvp_data, "placeholder"); - if (str && strcmp(str, "false") == 0) - kvp_frame_set_slot_nc (account->inst.kvp_data, "placeholder", NULL); + qof_instance_get_kvp (QOF_INSTANCE (account), "placeholder", &v); + if ((G_VALUE_HOLDS_STRING (&v) && + strcmp(g_value_get_string (&v), "false") == 0) || + (G_VALUE_HOLDS_BOOLEAN (&v) && ! g_value_get_boolean (&v))) + qof_instance_slot_delete (QOF_INSTANCE (account), "placeholder"); - frame = kvp_frame_get_frame(account->inst.kvp_data, "hbci"); - if (frame && kvp_frame_is_empty(frame)) - { - kvp_frame_set_frame_nc(account->inst.kvp_data, "hbci", NULL); - } + qof_instance_slot_delete_if_empty (QOF_INSTANCE (account), "hbci"); } /* ================================================================ */ From b4e024078311a846f3f066ce1449e0dee422ba2d Mon Sep 17 00:00:00 2001 From: John Ralls Date: Sat, 6 Jun 2015 10:10:31 -0700 Subject: [PATCH 21/54] Make the instance const in qof_instance_get_kvp(). --- src/libqof/qof/qofinstance-p.h | 2 +- src/libqof/qof/qofinstance.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libqof/qof/qofinstance-p.h b/src/libqof/qof/qofinstance-p.h index 7582ad75ad..1914e1afb0 100644 --- a/src/libqof/qof/qofinstance-p.h +++ b/src/libqof/qof/qofinstance-p.h @@ -108,7 +108,7 @@ void qof_instance_set_idata(gpointer inst, guint32 idata); /* Convenience functions to save some typing in property handlers */ gboolean qof_instance_has_kvp (QofInstance *inst); void qof_instance_set_kvp (QofInstance *inst, const gchar *key, const GValue *value); -void qof_instance_get_kvp (QofInstance *inst, const gchar *key, GValue *value); +void qof_instance_get_kvp (const QofInstance *inst, const gchar *key, GValue *value); /* Functions to isolate the KVP mechanism inside QOF for cases where GValue * operations won't work. */ diff --git a/src/libqof/qof/qofinstance.cpp b/src/libqof/qof/qofinstance.cpp index 3ae1e879a5..ffea2ff8ca 100644 --- a/src/libqof/qof/qofinstance.cpp +++ b/src/libqof/qof/qofinstance.cpp @@ -1078,7 +1078,7 @@ qof_instance_set_kvp (QofInstance *inst, const gchar *key, const GValue *value) } void -qof_instance_get_kvp (QofInstance *inst, const gchar *key, GValue *value) +qof_instance_get_kvp (const QofInstance *inst, const gchar *key, GValue *value) { GValue *temp = kvp_frame_get_gvalue (inst->kvp_data, key); if (G_IS_VALUE (temp)) From dcc9bfec36c36c52f1833a354a96edd5ab37e040 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Sat, 6 Jun 2015 12:08:28 -0700 Subject: [PATCH 22/54] Reimplement AQBanking template list in C++ and in libqof. It requires direct manipulation of KVP, so it needs to be hidden away in libqof. --- po/POTFILES.in | 2 +- src/import-export/aqb/Makefile.am | 2 - src/import-export/aqb/dialog-ab-trans.c | 2 +- src/import-export/aqb/gnc-ab-kvp.c | 41 --- src/import-export/aqb/gnc-ab-kvp.h | 37 +-- src/import-export/aqb/gnc-ab-trans-templ.c | 287 ----------------- src/import-export/aqb/gnc-ab-transfer.c | 11 +- src/import-export/aqb/gnc-ab-utils.h | 3 +- src/import-export/aqb/test/test-kvp.c | 27 +- src/libqof/qof/Makefile.am | 2 + src/libqof/qof/gnc-aqbanking-templates.cpp | 292 ++++++++++++++++++ .../qof/gnc-aqbanking-templates.h} | 54 ++-- 12 files changed, 331 insertions(+), 429 deletions(-) delete mode 100644 src/import-export/aqb/gnc-ab-trans-templ.c create mode 100644 src/libqof/qof/gnc-aqbanking-templates.cpp rename src/{import-export/aqb/gnc-ab-trans-templ.h => libqof/qof/gnc-aqbanking-templates.h} (86%) diff --git a/po/POTFILES.in b/po/POTFILES.in index ba27f7f943..af02822487 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -396,7 +396,6 @@ src/import-export/aqb/gnc-ab-getbalance.c src/import-export/aqb/gnc-ab-gettrans.c src/import-export/aqb/gnc-ab-kvp.c src/import-export/aqb/gnc-ab-transfer.c -src/import-export/aqb/gnc-ab-trans-templ.c src/import-export/aqb/gnc-ab-utils.c src/import-export/aqb/gnc-file-aqb-import.c src/import-export/aqb/gnc-gwen-gui.c @@ -463,6 +462,7 @@ src/import-export/qif-imp/qif-objects.scm src/import-export/qif-imp/qif-parse.scm src/import-export/qif-imp/qif-to-gnc.scm src/import-export/qif-imp/qif-utils.scm +src/libqof/qof/gnc-aqbanking-templates.cpp src/libqof/qof/gnc-date.cpp src/libqof/qof/gnc-int128.cpp src/libqof/qof/gnc-numeric.cpp diff --git a/src/import-export/aqb/Makefile.am b/src/import-export/aqb/Makefile.am index a79a82be65..ad95462eb9 100644 --- a/src/import-export/aqb/Makefile.am +++ b/src/import-export/aqb/Makefile.am @@ -9,7 +9,6 @@ libgncmod_aqbanking_la_SOURCES = \ gnc-ab-getbalance.c \ gnc-ab-gettrans.c \ gnc-ab-kvp.c \ - gnc-ab-trans-templ.c \ gnc-ab-transfer.c \ gnc-ab-utils.c \ gnc-file-aqb-import.c \ @@ -24,7 +23,6 @@ noinst_HEADERS = \ gnc-ab-getbalance.h \ gnc-ab-gettrans.h \ gnc-ab-kvp.h \ - gnc-ab-trans-templ.h \ gnc-ab-transfer.h \ gnc-ab-utils.h \ gnc-file-aqb-import.h \ diff --git a/src/import-export/aqb/dialog-ab-trans.c b/src/import-export/aqb/dialog-ab-trans.c index 67a3687f40..ed5d606a28 100644 --- a/src/import-export/aqb/dialog-ab-trans.c +++ b/src/import-export/aqb/dialog-ab-trans.c @@ -41,10 +41,10 @@ #include #include +#include #include "dialog-ab-trans.h" #include "dialog-transfer.h" #include "dialog-utils.h" -#include "gnc-ab-trans-templ.h" #include "gnc-ab-utils.h" #include "gnc-amount-edit.h" #include "gnc-ui.h" diff --git a/src/import-export/aqb/gnc-ab-kvp.c b/src/import-export/aqb/gnc-ab-kvp.c index ee1b33021b..7b1e781c0d 100644 --- a/src/import-export/aqb/gnc-ab-kvp.c +++ b/src/import-export/aqb/gnc-ab-kvp.c @@ -114,44 +114,3 @@ gnc_ab_set_account_trans_retrieval(Account *a, Timespec time) NULL); xaccAccountCommitEdit(a); } - - -#define AB_KEY "hbci" -#define AB_TEMPLATES "template-list" -static KvpFrame *gnc_ab_get_book_kvp(QofBook *b, gboolean create); - - -/* EFFECTIVE FRIEND FUNCTION */ -extern KvpFrame *qof_instance_get_slots (const QofInstance *); -/* EFFECTIVE FRIEND FUNCTION */ -extern void qof_instance_set_dirty_flag (gconstpointer inst, gboolean flag); - -GList * -gnc_ab_get_book_template_list(QofBook *b) -{ - KvpFrame *frame = gnc_ab_get_book_kvp(b, FALSE); - KvpValue *value = kvp_frame_get_slot(frame, AB_TEMPLATES); - return kvp_value_get_glist(value); -} - -void -gnc_ab_set_book_template_list(QofBook *b, GList *template_list) -{ - KvpFrame *frame = gnc_ab_get_book_kvp(b, TRUE); - KvpValue *value = kvp_value_new_glist_nc(template_list); - kvp_frame_set_slot_nc(frame, AB_TEMPLATES, value); - qof_instance_set_dirty_flag(QOF_INSTANCE(b), TRUE); -} - -static KvpFrame * -gnc_ab_get_book_kvp(QofBook *b, gboolean create) -{ - KvpFrame *toplevel = qof_instance_get_slots(QOF_INSTANCE(b)); - KvpFrame *result = kvp_frame_get_frame(toplevel, AB_KEY); - if (!result && create) - { - result = kvp_frame_new(); - kvp_frame_add_frame_nc(toplevel, AB_KEY, result); - } - return result; -} diff --git a/src/import-export/aqb/gnc-ab-kvp.h b/src/import-export/aqb/gnc-ab-kvp.h index a17b800218..1c21b28091 100644 --- a/src/import-export/aqb/gnc-ab-kvp.h +++ b/src/import-export/aqb/gnc-ab-kvp.h @@ -43,9 +43,7 @@ G_BEGIN_DECLS * @{ */ /** - * Return a non-copied pointer to the accountid string in the Account @a a. - * The gchar* is still owned by the kvp_frame, so don't free it until you want - * to delete the whole kvp_frame. + * Return accountid string in the Account @a a. * * @param a Account * @return Account ID @@ -62,9 +60,7 @@ const gchar *gnc_ab_get_account_accountid(const Account *a); void gnc_ab_set_account_accountid(Account *a, const gchar *id); /** - * Return a non-copied pointer to the bankcode string in the Account @a a. The - * gchar* is still owned by the kvp_frame, so don't free it until you want to - * delete the whole kvp_frame. + * Return the bankcode string in the Account @a a. * * @param a Account * @return Bank code @@ -116,33 +112,4 @@ void gnc_ab_set_account_trans_retrieval(Account *a, Timespec time); /** @} */ -/** @name Book - * @{ */ - -/** - * Return a non-copied pointer to the GList of kvp_frames which eventually are - * the template transactions, stored in the given book. - * - * @param b Book - * @return Template list - */ -GList *gnc_ab_get_book_template_list(QofBook *b); - -/** - * Set the GList of kvp_frames of template transactions in the Book @a b to @a - * template_list. No copy of the GList will be stored, the callee becomes the - * owner and the caller must not free it. The book will be marked "dirty". - * - * @param b Book - * @param template_list Template list - */ -void gnc_ab_set_book_template_list(QofBook *b, GList *template_list); - -/** @} */ - -G_END_DECLS - -/** @} */ -/** @} */ - #endif /* GNC_AB_KVP_H */ diff --git a/src/import-export/aqb/gnc-ab-trans-templ.c b/src/import-export/aqb/gnc-ab-trans-templ.c deleted file mode 100644 index f76e57416a..0000000000 --- a/src/import-export/aqb/gnc-ab-trans-templ.c +++ /dev/null @@ -1,287 +0,0 @@ -/* - * gnc-ab-trans-templ.c -- - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, contact: - * - * Free Software Foundation Voice: +1-617-542-5942 - * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 - * Boston, MA 02110-1301, USA gnu@gnu.org - */ - -/** - * @internal - * @file gnc-ab-trans-templ.c - * @brief Templates for AqBanking transactions - * @author Copyright (C) 2002 Christian Stimming - * @author Copyright (C) 2008 Andreas Koehler - */ - -#include "config.h" - -#include "gnc-ab-trans-templ.h" - -/* This static indicates the debugging module that this .o belongs to. */ -G_GNUC_UNUSED static QofLogModule log_module = G_LOG_DOMAIN; - -/* KvpFrame slot names */ -#define TT_NAME "name" -#define TT_RNAME "rnam" -#define TT_RACC "racc" -#define TT_RBCODE "rbcd" -#define TT_PURPOS "purp" -#define TT_PURPOSCT "purc" -#define TT_AMOUNT "amou" - -struct _GncABTransTempl -{ - /* Name of this Template */ - gchar *name; - gchar *name_key; /* Collation key */ - - /* Recipient */ - gchar *recp_name; - gchar *recp_account; - gchar *recp_bankcode; - - /* Amount */ - gnc_numeric amount; - - /* Purpose, description */ - gchar *purpose; - gchar *purpose_cont; -}; - - -GncABTransTempl * -gnc_ab_trans_templ_new(void) -{ - return gnc_ab_trans_templ_new_full(NULL, NULL, NULL, NULL, - gnc_numeric_zero(), NULL, NULL); -} - -GncABTransTempl * -gnc_ab_trans_templ_new_full(const char *name, const char *recp_name, - const char *recp_account, const char *recp_bankcode, - gnc_numeric amount, const char *purpose, - const char *purpose_cont) -{ - GncABTransTempl *r = g_new(GncABTransTempl, 1); - r->name = g_strdup(name); - r->name_key = g_utf8_collate_key(name, -1); - r->recp_name = g_strdup(recp_name); - r->recp_account = g_strdup(recp_account); - r->recp_bankcode = g_strdup(recp_bankcode); - r->amount = amount; - r->purpose = g_strdup(purpose); - r->purpose_cont = g_strdup(purpose_cont); - - return r; -} - -GncABTransTempl * -gnc_ab_trans_templ_new_from_kvp(const KvpFrame *k) -{ - g_return_val_if_fail(k, NULL); - - return gnc_ab_trans_templ_new_full( - kvp_value_get_string(kvp_frame_get_slot(k, TT_NAME)), - kvp_value_get_string(kvp_frame_get_slot(k, TT_RNAME)), - kvp_value_get_string(kvp_frame_get_slot(k, TT_RACC)), - kvp_value_get_string(kvp_frame_get_slot(k, TT_RBCODE)), - kvp_value_get_numeric(kvp_frame_get_slot(k, TT_AMOUNT)), - kvp_value_get_string(kvp_frame_get_slot(k, TT_PURPOS)), - kvp_value_get_string(kvp_frame_get_slot(k, TT_PURPOSCT))); -} - -GList * -gnc_ab_trans_templ_list_new_from_kvp_list(GList *v) -{ - GList *res = NULL; - GList *iter; - - for (iter = v; iter; iter = iter->next) - { - KvpFrame *frame = kvp_value_get_frame((KvpValue*) iter->data); - res = g_list_prepend(res, gnc_ab_trans_templ_new_from_kvp(frame)); - } - res = g_list_reverse(res); - - return res; -} - -void -gnc_ab_trans_templ_free(GncABTransTempl *t) -{ - if (!t) return; - g_free(t->name); - g_free(t->name_key); - g_free(t->recp_name); - g_free(t->recp_account); - g_free(t->recp_bankcode); - g_free(t->purpose); - g_free(t->purpose_cont); - g_free(t); -} - -void -gnc_ab_trans_templ_list_free(GList *l) -{ - GList *iter; - for (iter = l; iter; iter = iter->next) - gnc_ab_trans_templ_free((GncABTransTempl*) iter->data); - g_list_free(l); -} - -KvpFrame * -gnc_ab_trans_templ_to_kvp(const GncABTransTempl *t) -{ - KvpFrame *k; - - g_return_val_if_fail(t, NULL); - - k = kvp_frame_new(); - kvp_frame_set_slot(k, TT_NAME, kvp_value_new_string(t->name)); - kvp_frame_set_slot(k, TT_RNAME, kvp_value_new_string(t->recp_name)); - kvp_frame_set_slot(k, TT_RACC, kvp_value_new_string(t->recp_account)); - kvp_frame_set_slot(k, TT_RBCODE, kvp_value_new_string(t->recp_bankcode)); - kvp_frame_set_slot(k, TT_AMOUNT, kvp_value_new_gnc_numeric(t->amount)); - kvp_frame_set_slot(k, TT_PURPOS, kvp_value_new_string(t->purpose)); - kvp_frame_set_slot(k, TT_PURPOSCT, kvp_value_new_string(t->purpose_cont)); - - return k; -} - -GList * -gnc_ab_trans_templ_list_to_kvp_list(GList *k) -{ - GList *res = NULL; - GList *iter; - - for (iter = k; iter; iter = iter->next) - { - GncABTransTempl *t = (GncABTransTempl*) iter->data; - KvpValue *value = kvp_value_new_frame_nc(gnc_ab_trans_templ_to_kvp(t)); - res = g_list_prepend(res, value); - } - res = g_list_reverse(res); - - return res; -} - -const gchar * -gnc_ab_trans_templ_get_name(const GncABTransTempl *t) -{ - g_return_val_if_fail(t, NULL); - return t->name; -} - -const gchar * -gnc_ab_trans_templ_get_recp_name(const GncABTransTempl *t) -{ - g_return_val_if_fail(t, NULL); - return t->recp_name; -} - -const gchar * -gnc_ab_trans_templ_get_recp_account(const GncABTransTempl *t) -{ - g_return_val_if_fail(t, NULL); - return t->recp_account; -} - -const gchar * -gnc_ab_trans_templ_get_recp_bankcode(const GncABTransTempl *t) -{ - g_return_val_if_fail(t, NULL); - return t->recp_bankcode; -} - -gnc_numeric -gnc_ab_trans_templ_get_amount(const GncABTransTempl *t) -{ - g_return_val_if_fail(t, gnc_numeric_zero()); - return t->amount; -} - -const gchar * -gnc_ab_trans_templ_get_purpose(const GncABTransTempl *t) -{ - g_return_val_if_fail(t, NULL); - return t->purpose; -} - -const gchar * -gnc_ab_trans_templ_get_purpose_cont(const GncABTransTempl *t) -{ - g_return_val_if_fail(t, NULL); - return t->purpose_cont; -} - -void -gnc_ab_trans_templ_set_name(GncABTransTempl *t, const gchar *name) -{ - g_return_if_fail(t); - g_free(t->name); - t->name = g_strdup(name); -} - -void -gnc_ab_trans_templ_set_recp_name(GncABTransTempl *t, const gchar *recp_name) -{ - g_return_if_fail(t); - g_free(t->recp_name); - t->recp_name = g_strdup(recp_name); -} - -void -gnc_ab_trans_templ_set_recp_account(GncABTransTempl *t, - const gchar *recp_account) -{ - g_return_if_fail(t); - g_free(t->recp_account); - t->recp_account = g_strdup(recp_account); -} - -void -gnc_ab_trans_templ_set_recp_bankcode(GncABTransTempl *t, - const gchar *recp_bankcode) -{ - g_return_if_fail(t); - g_free(t->recp_bankcode); - t->recp_bankcode = g_strdup(recp_bankcode); -} - -void -gnc_ab_trans_templ_set_amount(GncABTransTempl *t, gnc_numeric amount) -{ - g_return_if_fail(t); - t->amount = amount; -} - -void -gnc_ab_trans_templ_set_purpose(GncABTransTempl *t, const gchar *purpose) -{ - g_return_if_fail(t); - g_free(t->purpose); - t->purpose = g_strdup(purpose); -} - -void -gnc_ab_trans_templ_set_purpose_cont(GncABTransTempl *t, - const gchar *purpose_cont) -{ - g_return_if_fail(t); - g_free(t->purpose_cont); - t->purpose_cont = g_strdup(purpose_cont); -} diff --git a/src/import-export/aqb/gnc-ab-transfer.c b/src/import-export/aqb/gnc-ab-transfer.c index 9ca81c0099..ec21267aa5 100644 --- a/src/import-export/aqb/gnc-ab-transfer.c +++ b/src/import-export/aqb/gnc-ab-transfer.c @@ -35,12 +35,12 @@ #include #include -#include "Transaction.h" +#include +#include #include "dialog-transfer.h" #include "gnc-ab-transfer.h" #include "gnc-ab-kvp.h" #include "gnc-ab-utils.h" -#include "gnc-ab-trans-templ.h" #include "gnc-gwen-gui.h" #include "gnc-ui.h" @@ -62,8 +62,7 @@ save_templates(GtkWidget *parent, Account *gnc_acc, GList *templates, "but you cancelled the transfer dialog. " "Do you nevertheless want to store the changes?"))) { - GList *kvp_list = gnc_ab_trans_templ_list_to_kvp_list(templates); - gnc_ab_set_book_template_list(gnc_account_get_book(gnc_acc), kvp_list); + gnc_ab_set_book_template_list(gnc_account_get_book(gnc_acc), templates); } } @@ -119,8 +118,8 @@ gnc_ab_maketrans(GtkWidget *parent, Account *gnc_acc, } /* Get list of template transactions */ - templates = gnc_ab_trans_templ_list_new_from_kvp_list( - gnc_ab_get_book_template_list(gnc_account_get_book(gnc_acc))); + templates = gnc_ab_trans_templ_list_new_from_book( + gnc_account_get_book(gnc_acc)); /* Create new ABTransDialog */ td = gnc_ab_trans_dialog_new(parent, ab_acc, diff --git a/src/import-export/aqb/gnc-ab-utils.h b/src/import-export/aqb/gnc-ab-utils.h index 12d112ad3f..feec881d06 100644 --- a/src/import-export/aqb/gnc-ab-utils.h +++ b/src/import-export/aqb/gnc-ab-utils.h @@ -127,8 +127,7 @@ gint gnc_AB_BANKING_fini(AB_BANKING *api); /** * Get the corresponding AqBanking account to the GnuCash account @a gnc_acc. * Of course this only works after the GnuCash account has been set up for - * AqBanking use, i.e. the kvp_frame "hbci/..." has been filled with - * information. + * AqBanking use, i.e. the account's hbci data have been set up and populated. * * @param api The AB_BANKING to get the AB_ACCOUNT from * @param gnc_acc The GnuCash account to query for AB_ACCOUNT reference data diff --git a/src/import-export/aqb/test/test-kvp.c b/src/import-export/aqb/test/test-kvp.c index dcb6df15f1..137522e81f 100644 --- a/src/import-export/aqb/test/test-kvp.c +++ b/src/import-export/aqb/test/test-kvp.c @@ -25,7 +25,7 @@ // for the gnc_ab_get_book_template_list() et al. functions #include "import-export/aqb/gnc-ab-kvp.h" -#include "import-export/aqb/gnc-ab-trans-templ.h" +#include #include "engine/gnc-hooks.h" static char* get_filepath(const char* filename) @@ -78,14 +78,6 @@ test_qofsession_aqb_kvp( void ) //printf("io_err2 = %d\n", io_err); g_assert(io_err == 0); - // No HBCI slot exists, of course - - { - // No HBCI slot exists, of course - GList *mylist = gnc_ab_get_book_template_list(qof_session_get_book(new_session)); - g_assert(mylist == 0); - } - g_free(newfile); g_free(file1); @@ -121,11 +113,7 @@ test_qofsession_aqb_kvp( void ) const char* ORIGINAL_NAME = "Some Name"; const char* CHANGED_NAME = "Some Changed Name"; - GList *kvp_list = gnc_ab_get_book_template_list(book); - g_assert(kvp_list != 0); // do we have the slot?! - g_assert_cmpint(g_list_length(kvp_list), ==, 1); - - templ_list = gnc_ab_trans_templ_list_new_from_kvp_list(kvp_list); + templ_list = gnc_ab_trans_templ_list_new_from_book (book); g_assert_cmpint(g_list_length(templ_list), ==, 1); templ = templ_list->data; @@ -134,21 +122,16 @@ test_qofsession_aqb_kvp( void ) // Now we change the name into something else and verify it can be saved gnc_ab_trans_templ_set_name(templ, CHANGED_NAME); { - GList *kvp_list_new = gnc_ab_trans_templ_list_to_kvp_list(templ_list); - gnc_ab_trans_templ_list_free(templ_list); g_assert(!qof_instance_get_dirty(QOF_INSTANCE(book))); // not yet dirty // Here we save the changed kvp - gnc_ab_set_book_template_list(book, kvp_list_new); + gnc_ab_set_book_template_list(book, templ_list); g_assert(qof_instance_get_dirty(QOF_INSTANCE(book))); // yup, now dirty + gnc_ab_trans_templ_list_free(templ_list); } { - GList *mylist = gnc_ab_get_book_template_list(book); - g_assert(mylist != 0); - g_assert_cmpint(g_list_length(mylist), ==, 1); - - templ_list = gnc_ab_trans_templ_list_new_from_kvp_list(mylist); + templ_list = gnc_ab_trans_templ_list_new_from_book (book); g_assert_cmpint(g_list_length(templ_list), ==, 1); templ = templ_list->data; diff --git a/src/libqof/qof/Makefile.am b/src/libqof/qof/Makefile.am index 86d393e1bb..7bfc7b0243 100644 --- a/src/libqof/qof/Makefile.am +++ b/src/libqof/qof/Makefile.am @@ -23,6 +23,7 @@ AM_CPPFLAGS = \ $(BOOST_CPPFLAGS) libgnc_qof_la_SOURCES = \ + gnc-aqbanking-templates.cpp \ gnc-date.cpp \ gnc-int128.cpp \ gnc-numeric.cpp \ @@ -50,6 +51,7 @@ libgnc_qof_la_SOURCES = \ qofincludedir = ${pkgincludedir} qofinclude_HEADERS = \ + gnc-aqbanking-templates.h \ gnc-date-p.h \ gnc-date.h \ gnc-numeric.h \ diff --git a/src/libqof/qof/gnc-aqbanking-templates.cpp b/src/libqof/qof/gnc-aqbanking-templates.cpp new file mode 100644 index 0000000000..42f45694fe --- /dev/null +++ b/src/libqof/qof/gnc-aqbanking-templates.cpp @@ -0,0 +1,292 @@ +/******************************************************************** + * gnc-aqbanking-templates.cpp implements transaction templates * + * for AQBanking. * + * Copyright 2015 John Ralls * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 * + * Boston, MA 02110-1301, USA gnu@gnu.org * + * * + ********************************************************************/ + +/** Class for managing AQBanking Transaction Templates. + */ + +#include + +extern "C" +{ +#include "gnc-aqbanking-templates.h" +#include "kvp_frame.h" +#include "qofinstance-p.h" +} + +#include "gnc-rational.hpp" + +namespace { + static const char* TT_NAME {"name"}; + static const char* TT_RNAME {"rnam"}; + static const char* TT_RACC {"racc"}; + static const char* TT_RBCODE {"rbcd"}; + static const char* TT_PURPOS {"purp"}; + static const char* TT_PURPOSCT {"purc"}; + static const char* TT_AMOUNT {"amou"}; +} + +struct _GncABTransTempl +{ +public: + _GncABTransTempl () : + m_name(), m_recipient_name(), m_recipient_account(), + m_recipient_bankcode(), m_amount(gnc_numeric_zero()), m_purpose(), + m_purpose_continuation() {} + _GncABTransTempl (const std::string& name, + const std::string& recip_name, + const std::string& recip_account, + const std::string& recip_code, + const GncRational& amount, + const std::string& purpose, + const std::string& purpose_cont) : + m_name(name), m_recipient_name(recip_name), + m_recipient_account(recip_account), m_recipient_bankcode(recip_code), + m_amount(amount), m_purpose(purpose), + m_purpose_continuation(purpose_cont) {} + KvpFrame* make_kvp_frame(); + const char* name() const { return m_name.c_str(); } + const char* recipient_name() const { return m_recipient_name.c_str(); } + const char* recipient_account() const + { + return m_recipient_account.c_str(); + } + const char* recipient_bankcode() const + { + return m_recipient_bankcode.c_str(); + } + const GncRational amount() const { return m_amount; } + const char* purpose() const { return m_purpose.c_str(); } + const char* purpose_continuation() const + { + return m_purpose_continuation.c_str(); + } + void set_name (const char* name) { m_name = name; } + void set_recipient_name (const char* name) { m_recipient_name = name; } + void set_recipient_account (const char* account) { + m_recipient_account = account; + } + void set_recipient_bankcode (const char* code) { + m_recipient_bankcode = code; + } + void set_amount (GncRational amount) { m_amount = amount; } + void set_purpose (const char* purpose) { m_purpose = purpose; } + void set_purpose_continuation (const char* name) { m_name = name; } +private: + std::string m_name; + std::string m_recipient_name; + std::string m_recipient_account; + std::string m_recipient_bankcode; + GncRational m_amount; + std::string m_purpose; + std::string m_purpose_continuation; +}; + +KvpFrame* +_GncABTransTempl::make_kvp_frame() +{ + auto frame = kvp_frame_new(); + kvp_frame_set_slot(frame, TT_NAME, kvp_value_new_string(m_name.c_str())); + kvp_frame_set_slot(frame, TT_RNAME, + kvp_value_new_string(m_recipient_name.c_str())); + kvp_frame_set_slot(frame, TT_RACC, + kvp_value_new_string(m_recipient_account.c_str())); + kvp_frame_set_slot(frame, TT_RBCODE, + kvp_value_new_string(m_recipient_bankcode.c_str())); + kvp_frame_set_slot(frame, TT_AMOUNT, kvp_value_new_gnc_numeric(m_amount)); + kvp_frame_set_slot(frame, TT_PURPOS, + kvp_value_new_string(m_purpose.c_str())); + kvp_frame_set_slot(frame, TT_PURPOSCT, + kvp_value_new_string(m_purpose_continuation.c_str())); + return frame; +} + +GncABTransTempl* +gnc_ab_trans_templ_new() +{ + return new _GncABTransTempl; +} + +GncABTransTempl* +gnc_ab_trans_templ_new_full(const gchar *name, const gchar *recp_name, + const gchar *recp_account, + const gchar *recp_bankcode, gnc_numeric amount, + const gchar *purpose, const gchar *purpose_cont) +{ + return new _GncABTransTempl(name, recp_name, recp_account, recp_bankcode, + amount, purpose, purpose_cont); +} + +GList* +gnc_ab_trans_templ_list_new_from_book(QofBook *b) +{ + GList *retval = NULL; + KvpFrame *toplevel = qof_instance_get_slots (QOF_INSTANCE (b)); + KvpFrame *hbci = kvp_frame_get_frame (toplevel, "hbci"); + KvpValue *listval = kvp_frame_get_slot (hbci, "template-list"); + GList *list = kvp_value_get_glist (listval); + for (auto node = list; node != NULL; node = g_list_next (node)) + { + KvpFrame *frame = kvp_value_get_frame (static_cast(node->data)); + auto func = [frame](const char* key) + {return kvp_value_get_string(kvp_frame_get_slot(frame, key));}; + auto templ = new _GncABTransTempl (func(TT_NAME), func(TT_RNAME), + func(TT_RACC), func(TT_RBCODE), + kvp_value_get_numeric(kvp_frame_get_slot(frame, TT_AMOUNT)), + func(TT_PURPOS), func(TT_PURPOSCT)); + retval = g_list_prepend (retval, templ); + } + retval = g_list_reverse (retval); + return retval; +} + +void +gnc_ab_trans_templ_free (GncABTransTempl *t) +{ + delete t; +} + +void +gnc_ab_trans_templ_list_free (GList *l) +{ + for(GList *node = l; node != NULL; node = g_list_next(node)) + delete static_cast<_GncABTransTempl*>(node->data); +} + +void +gnc_ab_set_book_template_list (QofBook *b, GList *template_list) +{ + GList *kvp_list = NULL; + for (auto node = template_list; node != NULL; node = g_list_next (node)) + { + auto value = kvp_value_new_frame_nc (static_cast<_GncABTransTempl*>(node->data)->make_kvp_frame()); + kvp_list = g_list_prepend (kvp_list, value); + } + kvp_list = g_list_reverse (kvp_list); + auto value = kvp_value_new_glist_nc(kvp_list); + KvpFrame *toplevel = qof_instance_get_slots (QOF_INSTANCE (b)); + KvpFrame *hbci = kvp_frame_get_frame (toplevel, "hbci"); + kvp_frame_set_slot_nc (hbci, "template-list", value); + qof_instance_set_dirty_flag (QOF_INSTANCE (b), TRUE); +} + +const gchar * +gnc_ab_trans_templ_get_name(const GncABTransTempl *t) +{ + g_return_val_if_fail(t, NULL); + return t->name(); +} + +const gchar * +gnc_ab_trans_templ_get_recp_name(const GncABTransTempl *t) +{ + g_return_val_if_fail(t, NULL); + return t->recipient_name(); +} + +const gchar * +gnc_ab_trans_templ_get_recp_account(const GncABTransTempl *t) +{ + g_return_val_if_fail(t, NULL); + return t->recipient_account(); +} + +const gchar * +gnc_ab_trans_templ_get_recp_bankcode(const GncABTransTempl *t) +{ + g_return_val_if_fail(t, NULL); + return t->recipient_bankcode(); +} + +gnc_numeric +gnc_ab_trans_templ_get_amount(const GncABTransTempl *t) +{ + g_return_val_if_fail(t, gnc_numeric_zero()); + return t->amount(); +} + +const gchar * +gnc_ab_trans_templ_get_purpose(const GncABTransTempl *t) +{ + g_return_val_if_fail(t, NULL); + return t->purpose(); +} + +const gchar * +gnc_ab_trans_templ_get_purpose_cont(const GncABTransTempl *t) +{ + g_return_val_if_fail(t, NULL); + return t->purpose_continuation(); +} + +void +gnc_ab_trans_templ_set_name(GncABTransTempl *t, const gchar *name) +{ + g_return_if_fail(t); + t->set_name(name); +} + +void +gnc_ab_trans_templ_set_recp_name(GncABTransTempl *t, const gchar *recp_name) +{ + g_return_if_fail(t); + t->set_recipient_name(recp_name); +} + +void +gnc_ab_trans_templ_set_recp_account(GncABTransTempl *t, + const gchar *recp_account) +{ + g_return_if_fail(t); + t->set_recipient_account(recp_account); +} + +void +gnc_ab_trans_templ_set_recp_bankcode(GncABTransTempl *t, + const gchar *recp_bankcode) +{ + g_return_if_fail(t); + t->set_recipient_bankcode(recp_bankcode); +} + +void +gnc_ab_trans_templ_set_amount(GncABTransTempl *t, gnc_numeric amount) +{ + g_return_if_fail(t); + t->set_amount(amount); +} + +void +gnc_ab_trans_templ_set_purpose(GncABTransTempl *t, const gchar *purpose) +{ + g_return_if_fail(t); + t->set_purpose(purpose); +} + +void +gnc_ab_trans_templ_set_purpose_cont(GncABTransTempl *t, + const gchar *purpose_cont) +{ + g_return_if_fail(t); + t->set_purpose_continuation (purpose_cont); +} diff --git a/src/import-export/aqb/gnc-ab-trans-templ.h b/src/libqof/qof/gnc-aqbanking-templates.h similarity index 86% rename from src/import-export/aqb/gnc-ab-trans-templ.h rename to src/libqof/qof/gnc-aqbanking-templates.h index 2b41c4f950..9350d5c3b6 100644 --- a/src/import-export/aqb/gnc-ab-trans-templ.h +++ b/src/libqof/qof/gnc-aqbanking-templates.h @@ -33,8 +33,13 @@ #ifndef GNC_AB_TRANS_TEMPL_H #define GNC_AB_TRANS_TEMPL_H -#include +#ifdef __cplusplus +extern "C" +{ +#endif +#include +#include #include "qof.h" G_BEGIN_DECLS @@ -67,25 +72,25 @@ GncABTransTempl *gnc_ab_trans_templ_new_full( const gchar *purpose_cont); /** - * Create a template, taking the values from a KvpFrame. + * Obtain the list of QofTemplates saved in a Book. * - * @param k KvpFrame - * @return A newly allocated GncABTransTempl - */ -GncABTransTempl *gnc_ab_trans_templ_new_from_kvp(const KvpFrame *k); - -/** - * Create a list of templates from a list of kvp_values which in turn - * contain a KvpFrame. - * - * @param v GList of kvp_values + * @param b QofBook containing the templates. * @return A GList of newly allocated GncABTransTempls */ -GList *gnc_ab_trans_templ_list_new_from_kvp_list(GList *v); +GList *gnc_ab_trans_templ_list_new_from_book(QofBook *b); + +/** + * Set the GList of kvp_frames of template transactions in the Book @a b to @a + * template_list. No copy of the GList will be stored, the callee becomes the + * owner and the caller must not free it. The book will be marked "dirty". + * + * @param b Book + * @param template_list Template list + */ +void gnc_ab_set_book_template_list(QofBook *b, GList *template_list); /** * Free the memory used by a template. - * * @param t GncABTransTempl to be freed */ void gnc_ab_trans_templ_free(GncABTransTempl *t); @@ -97,23 +102,6 @@ void gnc_ab_trans_templ_free(GncABTransTempl *t); */ void gnc_ab_trans_templ_list_free(GList *l); -/** - * Create a KvpFrame a given template. - * - * @param t Template - * @return A newly allocated KvpFrame - */ -KvpFrame *gnc_ab_trans_templ_to_kvp(const GncABTransTempl *t); - -/** - * Create a list of kvp_values, which in turn contain a KvpFrame, from a list - * of templates. - * - * @param k GList of GncABTransTempls - * @return GList of newly allocated kvp_values - */ -GList *gnc_ab_trans_templ_list_to_kvp_list(GList *k); - /** * @param t Template * @return Name of the template, an internal string @@ -217,7 +205,9 @@ void gnc_ab_trans_templ_set_purpose_cont(GncABTransTempl *t, const gchar *purpose_cont); G_END_DECLS - +#ifdef __cplusplus +} +#endif #endif /* GNC_AB_TRANS_TEMPL_H */ /** @} */ /** @} */ From ccd74059a252ffbe23d589326dbe1ed89d2a76a8 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Tue, 9 Jun 2015 14:42:39 -0700 Subject: [PATCH 23/54] Implement qof_instance_for_each_slot(). Wraps kvp_frame_for_each_slot(). --- src/libqof/qof/kvp_frame.cpp | 5 ++--- src/libqof/qof/kvp_frame.h | 6 ++++++ src/libqof/qof/qofinstance-p.h | 4 +++- src/libqof/qof/qofinstance.cpp | 26 ++++++++++++++++++++++++++ 4 files changed, 37 insertions(+), 4 deletions(-) diff --git a/src/libqof/qof/kvp_frame.cpp b/src/libqof/qof/kvp_frame.cpp index b2b4683fb5..e56e22fe4d 100644 --- a/src/libqof/qof/kvp_frame.cpp +++ b/src/libqof/qof/kvp_frame.cpp @@ -1192,7 +1192,6 @@ kvp_frame_to_string(const KvpFrame *frame) return g_strdup(realframe->to_string().c_str()); } -static GValue *gvalue_from_kvp_value (KvpValue *); static KvpValue *kvp_value_from_gvalue (const GValue*); static void @@ -1216,8 +1215,8 @@ kvp_value_list_from_gvalue (GValue *gval, gpointer pList) *kvplist = g_list_prepend (*kvplist, kvp); } -static GValue* -gvalue_from_kvp_value (KvpValue *kval) +GValue* +gvalue_from_kvp_value (const KvpValue *kval) { GValue *val; gnc_numeric num; diff --git a/src/libqof/qof/kvp_frame.h b/src/libqof/qof/kvp_frame.h index 493098e964..8053539a62 100644 --- a/src/libqof/qof/kvp_frame.h +++ b/src/libqof/qof/kvp_frame.h @@ -580,6 +580,12 @@ void kvp_frame_for_each_slot(KvpFrame *f, /** Internal helper routines, you probably shouldn't be using these. */ gchar* kvp_frame_to_string(const KvpFrame *frame); +/** Convert a kvp_value into a GValue. Frames aren't converted. + * @param kval: A KvpValue. + * @return GValue*. Must be freed with g_free(). + */ +GValue* gvalue_from_kvp_value (const KvpValue *kval); + /** KvpItem: GValue Exchange * \brief Transfer of KVP to and from GValue, with the key * diff --git a/src/libqof/qof/qofinstance-p.h b/src/libqof/qof/qofinstance-p.h index 1914e1afb0..3ff5f72f46 100644 --- a/src/libqof/qof/qofinstance-p.h +++ b/src/libqof/qof/qofinstance-p.h @@ -129,7 +129,9 @@ gboolean qof_instance_has_slot (const QofInstance *inst, const char *path); void qof_instance_slot_delete (const QofInstance *inst, const char *path); void qof_instance_slot_delete_if_empty (const QofInstance *inst, const char *path); - +void qof_instance_foreach_slot (const QofInstance *inst, const char *path, + void(*proc)(const char*, const GValue*, void*), + void* data); #ifdef __cplusplus } #endif diff --git a/src/libqof/qof/qofinstance.cpp b/src/libqof/qof/qofinstance.cpp index ffea2ff8ca..a765cae060 100644 --- a/src/libqof/qof/qofinstance.cpp +++ b/src/libqof/qof/qofinstance.cpp @@ -1287,5 +1287,31 @@ qof_instance_slot_delete_if_empty (const QofInstance *inst, const char *path) kvp_frame_set_frame_nc (inst->kvp_data, path, NULL); } +struct wrap_param +{ + void (*proc)(const char*, const GValue*, void*); + void *user_data; +}; + +static void +wrap_gvalue_function (const char* key, KvpValue *val, gpointer data) +{ + auto param = static_cast(data); + GValue *gv = gvalue_from_kvp_value(val); + param->proc(key, gv, param->user_data); + g_slice_free (GValue, gv); +} + +void +qof_instance_foreach_slot (const QofInstance *inst, const char* path, + void (*proc)(const char*, const GValue*, void*), + void* data) +{ + KvpFrame* frame = kvp_frame_get_frame (inst->kvp_data, path); + if (!frame) return; + wrap_param new_data {proc, data}; + kvp_frame_for_each_slot(frame, wrap_gvalue_function, &new_data); +} + /* ========================== END OF FILE ======================= */ From 43e93e5fb5f1c511de056679c8dafe563b50ef51 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Tue, 9 Jun 2015 14:43:58 -0700 Subject: [PATCH 24/54] Modify gnc_imap... functions to use KVP indirectly, provide unit tests. --- src/engine/Account.c | 51 ++--- src/engine/test/Makefile.am | 26 +++ src/engine/test/gtest-import-map.cpp | 288 +++++++++++++++++++++++++++ 3 files changed, 326 insertions(+), 39 deletions(-) create mode 100644 src/engine/test/gtest-import-map.cpp diff --git a/src/engine/Account.c b/src/engine/Account.c index 7ae196dd24..706463fb02 100644 --- a/src/engine/Account.c +++ b/src/engine/Account.c @@ -5029,7 +5029,6 @@ xaccAccountForEachTransaction(const Account *acc, TransactionCallback proc, typedef struct _GncImportMatchMap { - KvpFrame * frame; Account * acc; QofBook * book; } GncImportMatchMap; @@ -5050,15 +5049,10 @@ GncImportMatchMap * gnc_account_create_imap (Account *acc) { GncImportMatchMap *imap; - KvpFrame *frame; if (!acc) return NULL; - frame = qof_instance_get_slots (QOF_INSTANCE (acc)); - g_return_val_if_fail (frame != NULL, NULL); - g_return_val_if_fail (frame != NULL, NULL); imap = g_new0(GncImportMatchMap, 1); - imap->frame = frame; /* Cache the book for easy lookups; store the account/book for * marking dirtiness @@ -5140,16 +5134,16 @@ struct token_accounts_info * \note Can always assume that keys are unique, reduces code in this function */ static void -buildTokenInfo(const char *key, KvpValue *value, gpointer data) +buildTokenInfo(const char *key, const GValue *value, gpointer data) { struct token_accounts_info *tokenInfo = (struct token_accounts_info*)data; struct account_token_count* this_account; // PINFO("buildTokenInfo: account '%s', token_count: '%ld'\n", (char*)key, - // (long)kvp_value_get_gint64(value)); + // (long)g_value_get_int64(value)); /* add the count to the total_count */ - tokenInfo->total_count += kvp_value_get_gint64(value); + tokenInfo->total_count += g_value_get_int64(value); /* allocate a new structure for this account and it's token count */ this_account = (struct account_token_count*) @@ -5157,7 +5151,7 @@ buildTokenInfo(const char *key, KvpValue *value, gpointer data) /* fill in the account name and number of tokens found for this account name */ this_account->account_name = (char*)key; - this_account->token_count = kvp_value_get_gint64(value); + this_account->token_count = g_value_get_int64(value); /* append onto the glist a pointer to the new account_token_count structure */ tokenInfo->accounts = g_list_prepend(tokenInfo->accounts, this_account); @@ -5262,8 +5256,6 @@ gnc_imap_find_account_bayes (GncImportMatchMap *imap, GList *tokens) GHashTable *final_probabilities = g_hash_table_new(g_str_hash, g_str_equal); struct account_info account_i; - KvpValue* value; - KvpFrame* token_frame; ENTER(" "); @@ -5281,40 +5273,20 @@ gnc_imap_find_account_bayes (GncImportMatchMap *imap, GList *tokens) for (current_token = tokens; current_token; current_token = current_token->next) { - /* zero out the token_accounts_info structure */ + char* path = g_strdup_printf (IMAP_FRAME_BAYES "/%s", + (char*)current_token->data); + /* zero out the token_accounts_info structure */ memset(&tokenInfo, 0, sizeof(struct token_accounts_info)); PINFO("token: '%s'", (char*)current_token->data); - /* find the slot for the given token off of the source account - * for these tokens, search off of the IMAP_FRAME_BAYES path so - * we aren't looking from the parent of the entire kvp tree - */ - value = kvp_frame_get_slot_path(imap->frame, IMAP_FRAME_BAYES, - (char*)current_token->data, NULL); - - /* if value is null we should skip over this token */ - if (!value) - continue; - - /* convert the slot(value) into a the frame that contains the - * list of accounts - */ - token_frame = kvp_value_get_frame(value); - - /* token_frame should NEVER be null */ - if (!token_frame) - { - PERR("token '%s' has no accounts", (char*)current_token->data); - continue; /* skip over this token */ - } - /* process the accounts for this token, adding the account if it * doesn't already exist or adding to the existing accounts token * count if it does */ - kvp_frame_for_each_slot(token_frame, buildTokenInfo, &tokenInfo); - + qof_instance_foreach_slot(QOF_INSTANCE (imap->acc), path, + buildTokenInfo, &tokenInfo); + g_free (path); /* for each account we have just found, see if the account * already exists in the list of account probabilities, if not * add it @@ -5477,7 +5449,8 @@ gnc_imap_add_account_bayes(GncImportMatchMap *imap, token_count += count; } token_count++; - g_value_init (&value, G_TYPE_INT64); + if (!G_IS_VALUE (&value)) + g_value_init (&value, G_TYPE_INT64); g_value_set_int64 (&value, token_count); qof_instance_set_kvp (QOF_INSTANCE (imap->acc), kvp_path, &value); g_free (kvp_path); diff --git a/src/engine/test/Makefile.am b/src/engine/test/Makefile.am index 87a2cb53af..8f1cf03dc1 100644 --- a/src/engine/test/Makefile.am +++ b/src/engine/test/Makefile.am @@ -128,6 +128,32 @@ libutest_Trans_la_SOURCES = \ libutest_Trans_la_LIBADD = $(LDADD) +if WITH_GOOGLE_TEST +test_import_map_SOURCES = \ + gtest-import-map.cpp +test_import_map_LDADD = \ + ${top_builddir}/src/libqof/qof/libgnc-qof.la \ + ${top_builddir}/src/engine/libgncmod-engine.la \ + ${GLIB_LIBS} \ + ${GTEST_LIBS} + +if !GOOGLE_TEST_LIBS +nodist_test_import_map_SOURCES = \ + ${GTEST_SRC}/src/gtest_main.cc +test_import_map_LDADD += ${top_builddir}/src/test-core/libgtest.a +endif + +test_import_map_CPPFLAGS = \ + -I${GTEST_HEADERS} \ + -I${top_srcdir}/${MODULEPATH} \ + -I${top_srcdir}/src/libqof/qof \ + -I${top_srcdir}/src/core-utils \ + ${GLIB_CFLAGS} + +TEST_GROUP_1 += test-import-map +endif + + clean-local: rm -f translog.* diff --git a/src/engine/test/gtest-import-map.cpp b/src/engine/test/gtest-import-map.cpp new file mode 100644 index 0000000000..a4d4885b93 --- /dev/null +++ b/src/engine/test/gtest-import-map.cpp @@ -0,0 +1,288 @@ +/******************************************************************** + * test-import-map.cpp: Test import match maps. * + * Copyright 2015 John Ralls * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 * + * Boston, MA 02110-1301, USA gnu@gnu.org * +\********************************************************************/ + +extern "C" +{ +#include +#include "../Account.h" +#include +#include +#include + +struct GncImportMatchMap +{ + Account *acc; + QofBook *book; +}; + +extern GncImportMatchMap * gnc_account_create_imap (Account *acc); +extern Account* gnc_imap_find_account(GncImportMatchMap *imap, + const char* category, + const char *key); +extern void gnc_imap_add_account (GncImportMatchMap *imap, + const char *category, + const char *key, Account *acc); +extern Account* gnc_imap_find_account_bayes (GncImportMatchMap *imap, + GList* tokens); +extern void gnc_imap_add_account_bayes (GncImportMatchMap *imap, + GList* tokens, + Account *acc); +} + +#include + +class ImapTest : public testing::Test +{ +protected: + void SetUp() { + QofBook *book = qof_book_new(); + Account *root = gnc_account_create_root(book); + t_bank_account = xaccMallocAccount(book); + t_expense_account1 = xaccMallocAccount(book); + xaccAccountSetName(t_expense_account1, "Food"); + gnc_account_append_child(root, t_expense_account1); + t_expense_account2 = xaccMallocAccount(book); + xaccAccountSetName(t_expense_account2, "Drink"); + gnc_account_append_child(root, t_expense_account2); + } + void TearDown() { + qof_book_destroy (gnc_account_get_book (t_bank_account)); + } + Account *t_bank_account {}; + Account *t_expense_account1 {}; + Account *t_expense_account2 {}; +}; + +TEST_F(ImapTest, CreateImap) { + GncImportMatchMap *imap = gnc_account_create_imap (t_bank_account); + EXPECT_NE(nullptr, imap); + EXPECT_EQ(t_bank_account, imap->acc); + EXPECT_EQ(gnc_account_get_book(t_bank_account), imap->book); + + g_free(imap); +} + +static const char* IMAP_FRAME = "import-map"; +static const char* IMAP_FRAME_BAYES = "import-map-bayes"; + +class ImapPlainTest : public ImapTest +{ +protected: + void SetUp() { + ImapTest::SetUp(); + t_imap = gnc_account_create_imap (t_bank_account); + } + + void TearDown() { + g_free(t_imap); + ImapTest::TearDown(); + } + + GncImportMatchMap *t_imap {}; +}; + +TEST_F(ImapPlainTest, FindAccount) +{ + auto root = qof_instance_get_slots(QOF_INSTANCE(t_bank_account)); + auto acc1_val = kvp_value_new_guid(xaccAccountGetGUID(t_expense_account1)); + auto acc2_val = kvp_value_new_guid(xaccAccountGetGUID(t_expense_account2)); + kvp_frame_set_slot_path(root, acc1_val, IMAP_FRAME, "foo", "bar", NULL); + kvp_frame_set_slot_path(root, acc2_val, IMAP_FRAME, "baz", "waldo", NULL); + kvp_frame_set_slot_path(root, acc1_val, IMAP_FRAME, "pepper", NULL); + kvp_frame_set_slot_path(root, acc2_val, IMAP_FRAME, "salt", NULL); + kvp_value_delete(acc1_val); + kvp_value_delete(acc2_val); + + EXPECT_EQ(t_expense_account1, gnc_imap_find_account(t_imap, "foo", "bar")); + EXPECT_EQ(t_expense_account2, + gnc_imap_find_account(t_imap, "baz", "waldo")); + EXPECT_EQ(t_expense_account1, + gnc_imap_find_account(t_imap, NULL, "pepper")); + EXPECT_EQ(t_expense_account2, gnc_imap_find_account(t_imap, NULL, "salt")); + EXPECT_EQ(nullptr, gnc_imap_find_account(t_imap, "salt", NULL)); +} + +TEST_F(ImapPlainTest, AddAccount) +{ +// prevent the embedded beginedit/commitedit from doing anything + qof_instance_increase_editlevel(QOF_INSTANCE(t_bank_account)); + qof_instance_mark_clean(QOF_INSTANCE(t_bank_account)); + gnc_imap_add_account(t_imap, "foo", "bar", t_expense_account1); + gnc_imap_add_account(t_imap, "baz", "waldo", t_expense_account2); + gnc_imap_add_account(t_imap, NULL, "pepper", t_expense_account1); + gnc_imap_add_account(t_imap, NULL, "salt", t_expense_account2); + EXPECT_EQ(1, qof_instance_get_editlevel(QOF_INSTANCE(t_bank_account))); + EXPECT_TRUE(qof_instance_get_dirty_flag(QOF_INSTANCE(t_bank_account))); + qof_instance_mark_clean(QOF_INSTANCE(t_bank_account)); + gnc_imap_add_account(t_imap, NULL, NULL, t_expense_account2); + EXPECT_FALSE(qof_instance_get_dirty_flag(QOF_INSTANCE(t_bank_account))); + gnc_imap_add_account(t_imap, "pork", "sausage", NULL); + EXPECT_FALSE(qof_instance_get_dirty_flag(QOF_INSTANCE(t_bank_account))); + qof_instance_reset_editlevel(QOF_INSTANCE(t_bank_account)); + + auto root = qof_instance_get_slots(QOF_INSTANCE(t_bank_account)); + auto value = kvp_frame_get_slot_path(root, IMAP_FRAME, "foo", "bar", NULL); + auto check_account = [this](KvpValue* v) { + return xaccAccountLookup(kvp_value_get_guid(v), this->t_imap->book); }; + EXPECT_EQ(t_expense_account1, check_account(value)); + value = kvp_frame_get_slot_path(root, IMAP_FRAME, "baz", "waldo", NULL); + EXPECT_EQ(t_expense_account2, check_account(value)); + value = kvp_frame_get_slot_path(root, IMAP_FRAME, "pepper", NULL); + EXPECT_EQ(t_expense_account1, check_account(value)); + value = kvp_frame_get_slot_path(root, IMAP_FRAME, "salt", NULL); + EXPECT_EQ(t_expense_account2, check_account(value)); + value = kvp_frame_get_slot_path(root, IMAP_FRAME, "pork", "sausage", NULL); + EXPECT_EQ(nullptr, value); +} + +static const char* foo = "foo"; +static const char* bar = "bar"; +static const char* baz = "baz"; +static const char* waldo = "waldo"; +static const char* pepper = "pepper"; +static const char* salt = "salt"; +static const char* pork = "pork"; +static const char* sausage = "sausage"; + + + +class ImapBayesTest : public ImapPlainTest +{ +protected: + void SetUp() { + ImapPlainTest::SetUp(); + t_list1 = g_list_prepend(t_list1, const_cast(foo)); + t_list1 = g_list_prepend(t_list1, const_cast(bar)); + t_list2 = g_list_prepend(t_list2, const_cast(baz)); + t_list2 = g_list_prepend(t_list2, const_cast(waldo)); + t_list3 = g_list_prepend(t_list3, const_cast(pepper)); + t_list4 = g_list_prepend(t_list4, const_cast(salt)); + t_list5 = g_list_prepend(t_list5, const_cast(pork)); + t_list5 = g_list_prepend(t_list5, const_cast(sausage)); + } + void TearDown() { + g_list_free(t_list1); + g_list_free(t_list2); + g_list_free(t_list3); + g_list_free(t_list4); + g_list_free(t_list5); + t_list1 = nullptr; + t_list2 = nullptr; + t_list3 = nullptr; + t_list4 = nullptr; + t_list5 = nullptr; + ImapPlainTest::TearDown(); + } + + GList *t_list1 {}; + GList *t_list2 {}; + GList *t_list3 {}; + GList *t_list4 {}; + GList *t_list5 {}; +}; + +TEST_F(ImapBayesTest, FindAccountBayes) +{ + auto root = qof_instance_get_slots(QOF_INSTANCE(t_bank_account)); + auto acct1_name = gnc_account_get_full_name(t_expense_account1); + auto acct2_name = gnc_account_get_full_name(t_expense_account2); + auto value = kvp_value_new_gint64(42); + + kvp_frame_set_slot_path(root, value, IMAP_FRAME_BAYES, + foo, acct1_name, NULL); + kvp_frame_set_slot_path(root, value, IMAP_FRAME_BAYES, + bar, acct1_name, NULL); + kvp_frame_set_slot_path(root, value, IMAP_FRAME_BAYES, + baz, acct2_name, NULL); + kvp_frame_set_slot_path(root, value, IMAP_FRAME_BAYES, + waldo, acct2_name, NULL); + kvp_frame_set_slot_path(root, value, IMAP_FRAME_BAYES, + pepper, acct1_name, NULL); + kvp_frame_set_slot_path(root, value, IMAP_FRAME_BAYES, + salt, acct2_name, NULL); + kvp_value_delete(value); + + auto account = gnc_imap_find_account_bayes(t_imap, t_list1); + EXPECT_EQ(t_expense_account1, account); + account = gnc_imap_find_account_bayes(t_imap, t_list2); + EXPECT_EQ(t_expense_account2, account); + account = gnc_imap_find_account_bayes(t_imap, t_list3); + EXPECT_EQ(t_expense_account1, account); + account = gnc_imap_find_account_bayes(t_imap, t_list4); + EXPECT_EQ(t_expense_account2, account); + account = gnc_imap_find_account_bayes(t_imap, t_list5); + EXPECT_EQ(nullptr, account); +} + +TEST_F(ImapBayesTest, AddAccountBayes) +{ + // prevent the embedded beginedit/commitedit from doing anything + qof_instance_increase_editlevel(QOF_INSTANCE(t_bank_account)); + qof_instance_mark_clean(QOF_INSTANCE(t_bank_account)); + gnc_imap_add_account_bayes(t_imap, t_list1, t_expense_account1); + gnc_imap_add_account_bayes(t_imap, t_list2, t_expense_account2); + gnc_imap_add_account_bayes(t_imap, t_list3, t_expense_account1); + gnc_imap_add_account_bayes(t_imap, t_list4, t_expense_account2); + EXPECT_EQ(1, qof_instance_get_editlevel(QOF_INSTANCE(t_bank_account))); + EXPECT_TRUE(qof_instance_get_dirty_flag(QOF_INSTANCE(t_bank_account))); + qof_instance_mark_clean(QOF_INSTANCE(t_bank_account)); + gnc_imap_add_account_bayes(t_imap, t_list5, NULL); + EXPECT_FALSE(qof_instance_get_dirty_flag(QOF_INSTANCE(t_bank_account))); + qof_instance_reset_editlevel(QOF_INSTANCE(t_bank_account)); + + auto root = qof_instance_get_slots(QOF_INSTANCE(t_bank_account)); + auto acct1_name = gnc_account_get_full_name(t_expense_account1); + auto acct2_name = gnc_account_get_full_name(t_expense_account2); + auto value = kvp_frame_get_slot_path(root, IMAP_FRAME_BAYES, "foo", "bar", NULL); + auto check_account = [this](KvpValue* v) { + return (kvp_value_get_string(v), + this->t_imap->book); }; + value = kvp_frame_get_slot_path(root, IMAP_FRAME_BAYES, foo, acct1_name, + NULL); + EXPECT_EQ(1, kvp_value_get_gint64(value)); + value = kvp_frame_get_slot_path(root, IMAP_FRAME_BAYES, bar, acct1_name, + NULL); + EXPECT_EQ(1, kvp_value_get_gint64(value)); + value = kvp_frame_get_slot_path(root, IMAP_FRAME_BAYES, baz, acct2_name, + NULL); + EXPECT_EQ(1, kvp_value_get_gint64(value)); + value = kvp_frame_get_slot_path(root, IMAP_FRAME_BAYES, waldo, acct2_name, + NULL); + EXPECT_EQ(1, kvp_value_get_gint64(value)); + value = kvp_frame_get_slot_path(root, IMAP_FRAME_BAYES, pepper, acct1_name, + NULL); + EXPECT_EQ(1, kvp_value_get_gint64(value)); + value = kvp_frame_get_slot_path(root, IMAP_FRAME_BAYES, salt, acct2_name, + NULL); + EXPECT_EQ(1, kvp_value_get_gint64(value)); + value = kvp_frame_get_slot_path(root, IMAP_FRAME_BAYES, baz, acct1_name, + NULL); + EXPECT_EQ(0, kvp_value_get_gint64(value)); + + qof_instance_increase_editlevel(QOF_INSTANCE(t_bank_account)); + gnc_imap_add_account_bayes(t_imap, t_list2, t_expense_account2); + qof_instance_mark_clean(QOF_INSTANCE(t_bank_account)); + qof_instance_reset_editlevel(QOF_INSTANCE(t_bank_account)); + value = kvp_frame_get_slot_path(root, IMAP_FRAME_BAYES, baz, acct2_name, + NULL); + EXPECT_EQ(2, kvp_value_get_gint64(value)); +} From 68dedc1ba2cbdff3b777a0769eed322546a122fc Mon Sep 17 00:00:00 2001 From: John Ralls Date: Tue, 9 Jun 2015 17:00:09 -0700 Subject: [PATCH 25/54] Reimplement gnc_template_register_get_debcred_entry. So that it at least returns something reasonable. Note the comment, though. --- .../ledger-core/split-register-model.c | 65 +++++++------------ 1 file changed, 23 insertions(+), 42 deletions(-) diff --git a/src/register/ledger-core/split-register-model.c b/src/register/ledger-core/split-register-model.c index 07dea27941..82d0f300ea 100644 --- a/src/register/ledger-core/split-register-model.c +++ b/src/register/ledger-core/split-register-model.c @@ -2155,20 +2155,24 @@ gnc_split_register_get_default_help (VirtualLocation virt_loc, return g_strdup (help); } +/* This function has been #if-zeroed for a year; in all released versions since + * 2001 it has issued dire warnings about being wrong, and returned nothing + * because it was querying a non-existent slot. + * + * Now it retrieves the sx-debit-numeric or sx-credit-numeric properties from + * the split. I'm not sure that it's what was originally intended, but at least + * it can do something now. + */ static const char * gnc_template_register_get_debcred_entry (VirtualLocation virt_loc, gboolean translate, gboolean *conditionally_changed, gpointer user_data) { - PERR("The function called always returned either NULL or an empty string " - "while issuing dire warnings about how incorrect it is. That code " - "has been removed and the function if called raises this error and " - "returns NULL"); - return NULL; -#if 0 SplitRegister *reg = user_data; Split *split; + gnc_numeric amount; + const char * cell_name; split = gnc_split_register_get_split (reg, virt_loc.vcell_loc); if (!split) @@ -2177,43 +2181,20 @@ gnc_template_register_get_debcred_entry (VirtualLocation virt_loc, conditionally_changed, user_data); - kvpf = xaccSplitGetSlots (split); - PWARN( "We're very close to \"wrong\". \"Fix it immediately!!!\"" ); + cell_name = gnc_table_get_cell_name (reg->table, virt_loc); + if (gnc_cell_name_equal (cell_name, DEBT_CELL)) + qof_instance_get (QOF_INSTANCE (split), + "sx-debit-numeric", &amount, + NULL); + else + qof_instance_get (QOF_INSTANCE (split), + "sx-credit-numeric", &amount, + NULL); + if (gnc_numeric_zero_p (amount)) + return ""; - if (kvpf) - { - gnc_numeric amount; - const char * cell_name; - char *str; - - PWARN("This code is wrong. Fix it immediately!!!!"); - str = kvp_value_get_string( - kvp_frame_get_slot_path(kvpf, "sched-xaction", "amnt", NULL)); - - amount = gnc_numeric_zero (); - string_to_gnc_numeric (str, &amount); - - if (gnc_numeric_zero_p (amount)) - return ""; - - cell_name = gnc_table_get_cell_name (reg->table, virt_loc); - - if (gnc_numeric_negative_p (amount) && - gnc_cell_name_equal (cell_name, DEBT_CELL)) - return ""; - - if (gnc_numeric_positive_p (amount) && - gnc_cell_name_equal (cell_name, CRED_CELL)) - return ""; - - amount = gnc_numeric_abs (amount); - - /* FIXME: This should be fixed to be correct for the "fake" account. */ - return xaccPrintAmount (amount, gnc_default_print_info (FALSE)); - } - - return NULL; -#endif + amount = gnc_numeric_abs (amount); + return xaccPrintAmount (amount, gnc_default_print_info (FALSE)); } static void From f631f6e6c5cfea901c729c5fd554fef0fe861438 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Tue, 9 Jun 2015 14:46:09 -0700 Subject: [PATCH 26/54] Fix formatting, line too long. --- src/libqof/qof/kvp_frame.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libqof/qof/kvp_frame.cpp b/src/libqof/qof/kvp_frame.cpp index e56e22fe4d..3dd415f32f 100644 --- a/src/libqof/qof/kvp_frame.cpp +++ b/src/libqof/qof/kvp_frame.cpp @@ -109,8 +109,9 @@ KvpFrameImpl::get_keys() const noexcept } void -KvpFrameImpl::for_each_slot(void (*proc)(const char *key, KvpValue *value, void * data), - void *data) const noexcept +KvpFrameImpl::for_each_slot(void (*proc)(const char *key, KvpValue *value, + void * data), + void *data) const noexcept { if (!proc) return; std::for_each (m_valuemap.begin(), m_valuemap.end(), From a4c748e20115c47185d02ba8be7eea21d9ff631c Mon Sep 17 00:00:00 2001 From: John Ralls Date: Tue, 9 Jun 2015 16:19:41 -0700 Subject: [PATCH 27/54] Miscellaneous KVP cleanup in Engine. Doesn't include tests or Scheme support. --- src/engine/Split.h | 4 +-- src/engine/TransactionP.h | 7 ---- src/engine/gnc-commodity.c | 44 +++++++++++++++++------- src/engine/gncAddress.c | 2 +- src/engine/gncEntry.c | 5 +-- src/engine/gncInvoice.c | 17 +++++---- src/engine/gncTaxTable.c | 5 +-- src/engine/test-core/test-engine-stuff.c | 4 +-- 8 files changed, 52 insertions(+), 36 deletions(-) diff --git a/src/engine/Split.h b/src/engine/Split.h index 487debaaa1..db8fb632b3 100644 --- a/src/engine/Split.h +++ b/src/engine/Split.h @@ -338,7 +338,7 @@ gnc_numeric xaccSplitGetReconciledBalance (const Split *split); * * @param check_txn_splits If the pointers are not equal, but * everything else so far is equal (including memo, amount, value, - * kvp_frame), then, when comparing the parenting transactions with + * kvp), then, when comparing the parenting transactions with * xaccTransEqual(), set its argument check_splits to be TRUE. */ gboolean xaccSplitEqual(const Split *sa, const Split *sb, @@ -515,8 +515,6 @@ gnc_numeric xaccSplitVoidFormerValue(const Split *split); * override so the gnome-search dialog displays the right type. @{ */ -#define SPLIT_KVP "kvp" - #define SPLIT_DATE_RECONCILED "date-reconciled" #define SPLIT_BALANCE "balance" #define SPLIT_CLEARED_BALANCE "cleared-balance" diff --git a/src/engine/TransactionP.h b/src/engine/TransactionP.h index 87b89bf9e8..bc9344251d 100644 --- a/src/engine/TransactionP.h +++ b/src/engine/TransactionP.h @@ -164,13 +164,6 @@ QofBackend * xaccTransactionGetBackend (Transaction *trans); void xaccEnableDataScrubbing(void); void xaccDisableDataScrubbing(void); -/** Set the KvpFrame slots of this transaction to the given frm by - * * directly using the frm pointer (i.e. non-copying). - * * XXX this is wrong, nedds to be replaced with a transactional thingy - * in kvp + qofinstance. for now, this is a quasi-unctional placeholder. - * */ -#define xaccTransSetSlots_nc(T,F) qof_instance_set_slots(QOF_INSTANCE(T),F) - void xaccTransRemoveSplit (Transaction *trans, const Split *split); void check_open (const Transaction *trans); diff --git a/src/engine/gnc-commodity.c b/src/engine/gnc-commodity.c index adbbcab3d3..ce1e11dd17 100644 --- a/src/engine/gnc-commodity.c +++ b/src/engine/gnc-commodity.c @@ -940,8 +940,7 @@ gnc_commodity_copy(gnc_commodity * dest, const gnc_commodity *src) gnc_commodity_set_quote_flag (dest, src_priv->quote_flag); gnc_commodity_set_quote_source (dest, gnc_commodity_get_quote_source (src)); gnc_commodity_set_quote_tz (dest, src_priv->quote_tz); - kvp_frame_delete (dest->inst.kvp_data); - dest->inst.kvp_data = kvp_frame_copy (src->inst.kvp_data); + qof_instance_copy_kvp (QOF_INSTANCE (dest), QOF_INSTANCE (src)); } gnc_commodity * @@ -967,8 +966,7 @@ gnc_commodity_clone(const gnc_commodity *src, QofBook *dest_book) gnc_commodity_set_quote_source (dest, gnc_commodity_get_quote_source (src)); - kvp_frame_delete (dest->inst.kvp_data); - dest->inst.kvp_data = kvp_frame_copy (src->inst.kvp_data); + qof_instance_copy_kvp (QOF_INSTANCE (dest), QOF_INSTANCE (src)); reset_printname(dest_priv); reset_unique_name(dest_priv); @@ -1087,11 +1085,14 @@ static gboolean gnc_commodity_get_auto_quote_control_flag(const gnc_commodity *cm) { const char *str; + GValue v = G_VALUE_INIT; if (!cm) return FALSE; - - str = kvp_frame_get_string(cm->inst.kvp_data, "auto_quote_control"); - return !str || (strcmp(str, "false") != 0); + qof_instance_get_kvp (QOF_INSTANCE (cm), "auto_quote_control", &v); + if (G_VALUE_HOLDS_STRING (&v) && + strcmp(g_value_get_string (&v), "false") == 0) + return FALSE; + return TRUE; } /******************************************************************** @@ -1148,8 +1149,12 @@ const char* gnc_commodity_get_user_symbol(const gnc_commodity *cm) { const char *str; + GValue v = G_VALUE_INIT; if (!cm) return NULL; - return kvp_frame_get_string(cm->inst.kvp_data, "user_symbol"); + qof_instance_get_kvp (QOF_INSTANCE(cm), "user_symbol", &v); + if (G_VALUE_HOLDS_STRING (&v)) + return g_value_get_string (&v); + return NULL; } /******************************************************************** @@ -1308,6 +1313,7 @@ static void gnc_commodity_set_auto_quote_control_flag(gnc_commodity *cm, const gboolean flag) { + GValue v = G_VALUE_INIT; ENTER ("(cm=%p, flag=%d)", cm, flag); if (!cm) @@ -1315,10 +1321,15 @@ gnc_commodity_set_auto_quote_control_flag(gnc_commodity *cm, LEAVE(""); return; } - gnc_commodity_begin_edit(cm); - kvp_frame_set_string(cm->inst.kvp_data, - "auto_quote_control", flag ? NULL : "false"); + if (flag) + qof_instance_set_kvp (QOF_INSTANCE (cm), "auto_quote_control", NULL); + else + { + g_value_init (&v, G_TYPE_STRING); + g_value_set_string (&v, "false"); + qof_instance_set_kvp (QOF_INSTANCE (cm), "auto_quote_control", &v); + } mark_commodity_dirty(cm); gnc_commodity_commit_edit(cm); LEAVE(""); @@ -1431,7 +1442,7 @@ void gnc_commodity_set_user_symbol(gnc_commodity * cm, const char * user_symbol) { struct lconv *lc; - + GValue v = G_VALUE_INIT; if (!cm) return; ENTER ("(cm=%p, symbol=%s)", cm, user_symbol ? user_symbol : "(null)"); @@ -1448,8 +1459,15 @@ gnc_commodity_set_user_symbol(gnc_commodity * cm, const char * user_symbol) user_symbol = NULL; else if (!g_strcmp0(user_symbol, gnc_commodity_get_default_symbol(cm))) user_symbol = NULL; + if (user_symbol) + { + g_value_init (&v, G_TYPE_STRING); + g_value_set_string (&v, user_symbol); + qof_instance_set_kvp (QOF_INSTANCE(cm), "user_symbol", &v); + } + else + qof_instance_set_kvp (QOF_INSTANCE(cm), "user_symbol", NULL); - kvp_frame_set_string(cm->inst.kvp_data, "user_symbol", user_symbol); mark_commodity_dirty(cm); gnc_commodity_commit_edit(cm); diff --git a/src/engine/gncAddress.c b/src/engine/gncAddress.c index 103e35a5ce..0aa354705f 100644 --- a/src/engine/gncAddress.c +++ b/src/engine/gncAddress.c @@ -495,7 +495,7 @@ static void address_free (QofInstance *inst) void gncAddressCommitEdit (GncAddress *addr) { /* GnuCash 2.6.3 and earlier didn't handle address kvp's... */ - if (!kvp_frame_is_empty (addr->inst.kvp_data)) + if (qof_instance_has_kvp(QOF_INSTANCE(addr))) gnc_features_set_used (qof_instance_get_book (QOF_INSTANCE (addr)), GNC_FEATURE_KVP_EXTRA_DATA); if (!qof_commit_edit (QOF_INSTANCE(addr))) return; diff --git a/src/engine/gncEntry.c b/src/engine/gncEntry.c index 10557aa7b6..e0ea40038b 100644 --- a/src/engine/gncEntry.c +++ b/src/engine/gncEntry.c @@ -1532,8 +1532,9 @@ static void entry_free (QofInstance *inst) void gncEntryCommitEdit (GncEntry *entry) { /* GnuCash 2.6.3 and earlier didn't handle entry kvp's... */ - if (!kvp_frame_is_empty (entry->inst.kvp_data)) - gnc_features_set_used (qof_instance_get_book (QOF_INSTANCE (entry)), GNC_FEATURE_KVP_EXTRA_DATA); + if (qof_instance_has_kvp(QOF_INSTANCE(entry))) + gnc_features_set_used (qof_instance_get_book (QOF_INSTANCE (entry)), + GNC_FEATURE_KVP_EXTRA_DATA); if (!qof_commit_edit (QOF_INSTANCE(entry))) return; qof_commit_edit_part2 (&entry->inst, gncEntryOnError, diff --git a/src/engine/gncInvoice.c b/src/engine/gncInvoice.c index 1163ac1878..2daeff2aa2 100644 --- a/src/engine/gncInvoice.c +++ b/src/engine/gncInvoice.c @@ -338,7 +338,7 @@ GncInvoice *gncInvoiceCopy (const GncInvoice *from) GncInvoice *invoice; QofBook* book; GList *node; - gint64 is_cn; + GValue v = G_VALUE_INIT; g_assert(from); book = qof_instance_get_book(from); @@ -354,8 +354,9 @@ GncInvoice *gncInvoiceCopy (const GncInvoice *from) invoice->billing_id = CACHE_INSERT (from->billing_id); invoice->active = from->active; - is_cn = kvp_frame_get_gint64(from->inst.kvp_data, GNC_INVOICE_IS_CN); - kvp_frame_set_gint64(invoice->inst.kvp_data, GNC_INVOICE_IS_CN, is_cn); + qof_instance_get_kvp (QOF_INSTANCE (from), GNC_INVOICE_IS_CN, &v); + if (G_VALUE_HOLDS_INT64 (&v)) + qof_instance_set_kvp (QOF_INSTANCE (invoice), GNC_INVOICE_IS_CN, &v); invoice->terms = from->terms; gncBillTermIncRef (invoice->terms); @@ -545,10 +546,12 @@ void gncInvoiceSetActive (GncInvoice *invoice, gboolean active) void gncInvoiceSetIsCreditNote (GncInvoice *invoice, gboolean credit_note) { + GValue v = G_VALUE_INIT; if (!invoice) return; gncInvoiceBeginEdit (invoice); - kvp_frame_set_gint64(invoice->inst.kvp_data, GNC_INVOICE_IS_CN, - credit_note ? 1 : 0); + g_value_init (&v, G_TYPE_INT64); + g_value_set_int64(&v, credit_note ? 1 : 0); + qof_instance_set_kvp (QOF_INSTANCE (invoice), GNC_INVOICE_IS_CN, &v); mark_invoice (invoice); gncInvoiceCommitEdit (invoice); @@ -1035,8 +1038,10 @@ gboolean gncInvoiceGetActive (const GncInvoice *invoice) gboolean gncInvoiceGetIsCreditNote (const GncInvoice *invoice) { + GValue v = G_VALUE_INIT; if (!invoice) return FALSE; - if (kvp_frame_get_gint64(invoice->inst.kvp_data, GNC_INVOICE_IS_CN)) + qof_instance_get_kvp (QOF_INSTANCE(invoice), GNC_INVOICE_IS_CN, &v); + if (G_VALUE_HOLDS_INT64(&v) && g_value_get_int64(&v)) return TRUE; else return FALSE; diff --git a/src/engine/gncTaxTable.c b/src/engine/gncTaxTable.c index 2c525f4a5d..636c13e940 100644 --- a/src/engine/gncTaxTable.c +++ b/src/engine/gncTaxTable.c @@ -655,8 +655,9 @@ static void table_free (QofInstance *inst) void gncTaxTableCommitEdit (GncTaxTable *table) { /* GnuCash 2.6.3 and earlier didn't handle taxtable kvp's... */ - if (!kvp_frame_is_empty (table->inst.kvp_data)) - gnc_features_set_used (qof_instance_get_book (QOF_INSTANCE (table)), GNC_FEATURE_KVP_EXTRA_DATA); + if (qof_instance_has_kvp (QOF_INSTANCE (table))) + gnc_features_set_used (qof_instance_get_book (QOF_INSTANCE (table)), + GNC_FEATURE_KVP_EXTRA_DATA); if (!qof_commit_edit (QOF_INSTANCE(table))) return; qof_commit_edit_part2 (&table->inst, gncTaxTableOnError, diff --git a/src/engine/test-core/test-engine-stuff.c b/src/engine/test-core/test-engine-stuff.c index 631834adf5..89d5cde0bd 100644 --- a/src/engine/test-core/test-engine-stuff.c +++ b/src/engine/test-core/test-engine-stuff.c @@ -1464,7 +1464,7 @@ get_random_transaction_with_currency(QofBook *book, trn_add_ran_timespec(trans, xaccTransSetDateEnteredTS); f = get_random_kvp_frame(); - xaccTransSetSlots_nc(trans, f); + qof_instance_set_slots (QOF_INSTANCE (trans), f); add_random_splits(book, trans, account_list); @@ -1525,7 +1525,7 @@ make_random_changes_to_transaction (QofBook *book, Transaction *trans) set_tran_random_string (trans, xaccTransSetDescription); - xaccTransSetSlots_nc (trans, get_random_kvp_frame()); + qof_instance_set_slots (QOF_INSTANCE (trans), get_random_kvp_frame()); /* Do split manipulations in higher-level functions */ From 61ecdda8454b743133b807621a6398a24c0df95c Mon Sep 17 00:00:00 2001 From: John Ralls Date: Tue, 9 Jun 2015 16:49:56 -0700 Subject: [PATCH 28/54] Miscellaneous KVP cleanup. Everything but the backends and app-utils. --- src/gnome-utils/dialog-preferences.c | 1 - src/gnome-utils/gnc-tree-view-owner.c | 14 +++++++------- src/import-export/import-account-matcher.c | 2 +- src/import-export/import-account-matcher.h | 8 ++++---- src/import-export/import-backend.c | 2 +- src/import-export/import-utilities.h | 6 +++--- .../ledger-core/split-register-model-save.c | 1 - 7 files changed, 16 insertions(+), 18 deletions(-) diff --git a/src/gnome-utils/dialog-preferences.c b/src/gnome-utils/dialog-preferences.c index 96f91599c8..470ec6bc7e 100644 --- a/src/gnome-utils/dialog-preferences.c +++ b/src/gnome-utils/dialog-preferences.c @@ -1062,7 +1062,6 @@ gnc_preferences_dialog_create(void) gnc_commodity *locale_currency; const gchar *currency_name; QofBook *book; - KvpFrame *book_frame; gint64 month, day; GDate fy_end; gboolean date_is_valid = FALSE; diff --git a/src/gnome-utils/gnc-tree-view-owner.c b/src/gnome-utils/gnc-tree-view-owner.c index 51d3cac2bb..a94e3b3f58 100644 --- a/src/gnome-utils/gnc-tree-view-owner.c +++ b/src/gnome-utils/gnc-tree-view-owner.c @@ -954,16 +954,16 @@ owner_cell_kvp_data_func (GtkTreeViewColumn *tree_column, gpointer key) { GncOwner *owner; - kvp_frame * frame; + GValue v = G_VALUE_INIT; g_return_if_fail (GTK_IS_TREE_MODEL_SORT (s_model)); owner = gnc_tree_view_owner_get_owner_from_iter(s_model, s_iter); - frame = gncOwnerGetSlots(owner); - - g_object_set (G_OBJECT (cell), - "text", kvp_frame_get_string(frame, (gchar *)key), - "xalign", 0.0, - NULL); + qof_instance_get_kvp (QOF_INSTANCE (owner), (gchar*)key, &v); + if (G_VALUE_HOLDS_STRING) + g_object_set (G_OBJECT (cell), + "text", g_value_get_string (&v), + "xalign", 0.0, + NULL); } diff --git a/src/import-export/import-account-matcher.c b/src/import-export/import-account-matcher.c index 27d7fe310a..723b384c4e 100644 --- a/src/import-export/import-account-matcher.c +++ b/src/import-export/import-account-matcher.c @@ -76,7 +76,7 @@ static AccountPickerDialog* gnc_import_new_account_picker(void) /************************************************** * test_acct_online_id_match * - * test for match of kvp_frame of account + * test for match of account online_ids. **************************************************/ static gpointer test_acct_online_id_match(Account *acct, gpointer param_online_id) { diff --git a/src/import-export/import-account-matcher.h b/src/import-export/import-account-matcher.h index 6c345cc209..b663af3c43 100644 --- a/src/import-export/import-account-matcher.h +++ b/src/import-export/import-account-matcher.h @@ -52,11 +52,11 @@ typedef struct } AccountPickerDialog; /** Must be called with a string containing a unique identifier for the - account. If an account with a matching online_id kvp_frame is + account. If an account with a matching online_id is found, the function immediately returns with a pointer to that account. Otherwise, the user is prompted to select a GnuCash account or create a new one (in both cases, the unique identifier is - written to the account's kvp_frame, so the user won't be prompted + written to the account, so the user won't be prompted again). If the user refuses to select or create an account, NULL is returned. @@ -70,7 +70,7 @@ typedef struct selector that allows you to select an account whose GncGUID will be remembered elsewhere. You would fill account_human_description to tell the user what he is looking for. In this mode, the online_id - kvp_frame of the found account will not be touched. To use this mode, + field of the found account will not be touched. To use this mode, auto_create must NOT be set to 0. @param account_human_description @@ -136,7 +136,7 @@ AccountPickerDialog * gnc_import_account_assist_setup (GtkWidget *parent); /** Must be called with an AccountPickerDialog structure allready setup. - If an account with a matching online_id kvp_frame is found, which is + If an account with a matching online_id is found, which is allready present in the dialog structure, the function returns with a pointer to that account or NULL if not found. diff --git a/src/import-export/import-backend.c b/src/import-export/import-backend.c index 60466e1025..fdd219d482 100644 --- a/src/import-export/import-backend.c +++ b/src/import-export/import-backend.c @@ -1116,7 +1116,7 @@ gnc_import_process_trans_item (GncImportMatchMap *matchmap, /********************************************************************\ * check_trans_online_id() Callback function used by * gnc_import_exists_online_id. Takes pointers to transaction and split, - * returns 0 if their online_id kvp_frames do NOT match, or if the split + * returns 0 if their online_ids do NOT match, or if the split * belongs to the transaction \********************************************************************/ static gint check_trans_online_id(Transaction *trans1, void *user_data) diff --git a/src/import-export/import-utilities.h b/src/import-export/import-utilities.h index fd0d599471..2ef484cdd3 100644 --- a/src/import-export/import-utilities.h +++ b/src/import-export/import-utilities.h @@ -40,7 +40,7 @@ #include "Account.h" /** @name Setter-getters - Setter and getter functions for the online_id kvp_frame for + Setter and getter functions for the online_id field for Accounts. @{ */ @@ -49,7 +49,7 @@ void gnc_import_set_acc_online_id(Account * account, const gchar * string_value); /** @} */ /** @name Setter-getters - Setter and getter functions for the online_id kvp_frame for + Setter and getter functions for the online_id field for Transactions. @{ */ @@ -61,7 +61,7 @@ void gnc_import_set_trans_online_id(Transaction * transaction, gboolean gnc_import_trans_has_online_id(Transaction * transaction); /** @name Setter-getters - Setter and getter functions for the online_id kvp_frame for + Setter and getter functions for the online_id field for Splits. @{ */ diff --git a/src/register/ledger-core/split-register-model-save.c b/src/register/ledger-core/split-register-model-save.c index f456daaeb5..a4032efa4a 100644 --- a/src/register/ledger-core/split-register-model-save.c +++ b/src/register/ledger-core/split-register-model-save.c @@ -660,7 +660,6 @@ gnc_template_register_save_xfrm_cell (BasicCell * cell, SRInfo *info = gnc_split_register_get_info (reg); Account *template_acc; const GncGUID *acctGUID; - KvpFrame *kvpf; Account *acct; g_return_if_fail (gnc_basic_cell_has_name (cell, XFRM_CELL)); From 095d1781f0175bd551c0836eb8d5e2f8826374b0 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Wed, 10 Jun 2015 10:43:43 -0700 Subject: [PATCH 29/54] Remove a couple of distracting comments about KVP. --- src/app-utils/gnc-accounting-period.c | 1 - src/app-utils/gnc-sx-instance-model.c | 4 ---- 2 files changed, 5 deletions(-) diff --git a/src/app-utils/gnc-accounting-period.c b/src/app-utils/gnc-accounting-period.c index e7dd8e7eab..f6bf987460 100644 --- a/src/app-utils/gnc-accounting-period.c +++ b/src/app-utils/gnc-accounting-period.c @@ -101,7 +101,6 @@ static GDate * get_fy_end(void) { QofBook *book; - KvpFrame *book_frame; GDate *date = NULL; book = gnc_get_current_book(); diff --git a/src/app-utils/gnc-sx-instance-model.c b/src/app-utils/gnc-sx-instance-model.c index 139fd88e69..153554c842 100644 --- a/src/app-utils/gnc-sx-instance-model.c +++ b/src/app-utils/gnc-sx-instance-model.c @@ -1027,7 +1027,6 @@ create_each_transaction_helper(Transaction *template_txn, void *user_data) g_date_get_month(&creation_data->instance->date), g_date_get_year(&creation_data->instance->date)); - /* the accounts and amounts are in the kvp_frames of the splits. */ template_splits = xaccTransGetSplitList(template_txn); txn_splits = xaccTransGetSplitList(new_txn); if ((template_splits == NULL) || (txn_splits == NULL)) @@ -1555,9 +1554,6 @@ create_cashflow_helper(Transaction *template_txn, void *user_data) xaccTransGetDescription(template_txn), xaccSchedXactionGetName(creation_data->sx)); - /* The accounts and amounts are in the kvp_frames of the - * splits. Hence, we iterate over all splits of this - * transaction. */ template_splits = xaccTransGetSplitList(template_txn); if (template_splits == NULL) From cb9d8c93b7a8e2cbe2c2853ce254d07d2d992681 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Wed, 10 Jun 2015 13:52:44 -0700 Subject: [PATCH 30/54] Use gnc:company-info instead of directly accessing the KVP in reports. --- src/app-utils/app-utils.scm | 10 +++-- src/report/business-reports/balsheet-eg.scm | 6 --- .../business-reports/customer-summary.scm | 9 +--- src/report/business-reports/easy-invoice.scm | 15 ++----- src/report/business-reports/fancy-invoice.scm | 43 +++++-------------- src/report/business-reports/invoice.scm | 9 +--- src/report/business-reports/job-report.scm | 9 +--- src/report/business-reports/owner-report.scm | 9 +--- .../business-reports/receipt.eguile.scm | 17 ++++---- src/report/business-reports/receipt.scm | 6 --- .../business-reports/taxinvoice.eguile.scm | 17 ++++---- src/report/business-reports/taxinvoice.scm | 6 --- .../locale-specific/us/taxtxf-de_DE.scm | 7 +-- 13 files changed, 46 insertions(+), 117 deletions(-) diff --git a/src/app-utils/app-utils.scm b/src/app-utils/app-utils.scm index ccd78f9300..cbac0df26d 100644 --- a/src/app-utils/app-utils.scm +++ b/src/app-utils/app-utils.scm @@ -146,6 +146,12 @@ (export gnc:send-options) (export gnc:save-options) +(define (gnc:option-get-value category key) + ;;Access an option directly + (kvp-frame-get-slot-path-gslist + (qof-book-get-slots (gnc-get-current-book)) + (append gnc:*kvp-option-path* (list category key)))) +(export gnc:option-get-value) ;; config-var.scm (export gnc:make-config-var) (export gnc:config-var-description-get) @@ -318,9 +324,7 @@ (define (gnc:company-info key) ;; Access company info from key-value pairs for current book - (kvp-frame-get-slot-path-gslist - (qof-book-get-slots (gnc-get-current-book)) - (append gnc:*kvp-option-path* (list gnc:*business-label* key)))) + (gnc:option-get-value gnc:*business-label* key)) (export gnc:*business-label* gnc:*company-name* gnc:*company-addy* gnc:*company-id* gnc:*company-phone* gnc:*company-fax* diff --git a/src/report/business-reports/balsheet-eg.scm b/src/report/business-reports/balsheet-eg.scm index bc30d4ad75..4ad4f9bfd0 100644 --- a/src/report/business-reports/balsheet-eg.scm +++ b/src/report/business-reports/balsheet-eg.scm @@ -117,12 +117,6 @@ '() (cadr l)))) -(define (gnc:company-info key) ; this should be in business-utils.scm soon - ;; Access company info from key-value pairs for current book - (kvp-frame-get-slot-path-gslist - (qof-book-get-slots (gnc-get-current-book)) - (append gnc:*kvp-option-path* (list gnc:*business-label* key)))) - (define (add-to-cc cc com num neg?) ; add a numeric and commodity to a commodity-collector, ; changing sign if required diff --git a/src/report/business-reports/customer-summary.scm b/src/report/business-reports/customer-summary.scm index 00592c1ab2..fcd1136bae 100644 --- a/src/report/business-reports/customer-summary.scm +++ b/src/report/business-reports/customer-summary.scm @@ -614,13 +614,8 @@ (define (make-myname-table book) (let* ((table (gnc:make-html-table)) (table-outer (gnc:make-html-table)) - (slots (qof-book-get-slots book)) - (name (kvp-frame-get-slot-path-gslist - slots (append gnc:*kvp-option-path* - (list gnc:*business-label* gnc:*company-name*)))) - (addy (kvp-frame-get-slot-path-gslist - slots (append gnc:*kvp-option-path* - (list gnc:*business-label* gnc:*company-addy*))))) + (name (gnc:company-info gnc:*company-name*)) + (addy (gnc:company-info gnc:*company-addy*))) (gnc:html-table-set-style! table "table" diff --git a/src/report/business-reports/easy-invoice.scm b/src/report/business-reports/easy-invoice.scm index 709f863ce6..eacbd0f603 100644 --- a/src/report/business-reports/easy-invoice.scm +++ b/src/report/business-reports/easy-invoice.scm @@ -631,13 +631,8 @@ (define (make-myname-table book) (let* ((table (gnc:make-html-table)) - (slots (qof-book-get-slots book)) - (name (kvp-frame-get-slot-path-gslist - slots (append gnc:*kvp-option-path* - (list gnc:*business-label* gnc:*company-name*)))) - (addy (kvp-frame-get-slot-path-gslist - slots (append gnc:*kvp-option-path* - (list gnc:*business-label* gnc:*company-addy*))))) + (name (gnc:company-info gnc:*company-name*)) + (addy (gnc:company-info gnc:*company-addy*))) (gnc:html-table-set-style! table "table" @@ -748,11 +743,7 @@ (add-html! document "") (if (opt-val "Display" "My Company ID") - (let* ((book (gncInvoiceGetBook invoice)) - (slots (qof-book-get-slots book)) - (taxid (kvp-frame-get-slot-path-gslist - slots (append gnc:*kvp-option-path* - (list gnc:*business-label* gnc:*company-id*))))) + (let* ((taxid (gnc:company-info gnc:*company-id*))) (if (and taxid (> (string-length taxid) 0)) (begin (add-html! document taxid) diff --git a/src/report/business-reports/fancy-invoice.scm b/src/report/business-reports/fancy-invoice.scm index b7c1af0410..db726a98ad 100644 --- a/src/report/business-reports/fancy-invoice.scm +++ b/src/report/business-reports/fancy-invoice.scm @@ -688,28 +688,13 @@ (define (make-myname-table book date-format title) (let* ((table (gnc:make-html-table)) - (slots (qof-book-get-slots book)) - (name (kvp-frame-get-slot-path-gslist - slots (append gnc:*kvp-option-path* - (list gnc:*business-label* gnc:*company-name*)))) -;; (contact (kvp-frame-get-slot-path-gslist -;; slots (append gnc:*kvp-option-path* -;; (list gnc:*business-label* gnc:*company-contact*)))) - (addy (kvp-frame-get-slot-path-gslist - slots (append gnc:*kvp-option-path* - (list gnc:*business-label* gnc:*company-addy*)))) - (id (kvp-frame-get-slot-path-gslist - slots (append gnc:*kvp-option-path* - (list gnc:*business-label* gnc:*company-id*)))) - (phone (kvp-frame-get-slot-path-gslist - slots (append gnc:*kvp-option-path* - (list gnc:*business-label* gnc:*company-phone*)))) - (fax (kvp-frame-get-slot-path-gslist - slots (append gnc:*kvp-option-path* - (list gnc:*business-label* gnc:*company-fax*)))) - (url (kvp-frame-get-slot-path-gslist - slots (append gnc:*kvp-option-path* - (list gnc:*business-label* gnc:*company-url*)))) + (name (gnc:company-info gnc:*company-name*)) +;; (contact (gnc:company-info gnc:*company-contact*)) + (addy (gnc:company-info gnc:*company-addy*)) + (id (gnc:company-info gnc:*company-id*)) + (phone (gnc:company-info gnc:*company-phone*)) + (fax (gnc:company-info gnc:*company-fax*)) + (url (gnc:company-info gnc:*company-url*)) (invoice-cell (gnc:make-html-table-cell)) (name-cell (gnc:make-html-table-cell)) @@ -830,9 +815,7 @@ (if (not (null? invoice)) - (let* ((book (gncInvoiceGetBook invoice)) - (slots (qof-book-get-slots book)) - (date-object #f) + (let* ((date-object #f) (helper-table (gnc:make-html-table)) (title (title-string default-title custom-title))) (set! table (make-entry-table invoice @@ -964,10 +947,7 @@ (make-break! document) (if (opt-val "Display" "Payable to") - (let* ((name (kvp-frame-get-slot-path-gslist - slots (append gnc:*kvp-option-path* - (list gnc:*business-label* - gnc:*company-name*)))) + (let* ((name (gnc:company-info gnc:*company-name*)) (name-str (opt-val "Display" "Payable to string"))) (if (and name (> (string-length name) 0)) (gnc:html-document-add-object! @@ -979,10 +959,7 @@ (make-break! document) (if (opt-val "Display" "Company contact") - (let* ((contact (kvp-frame-get-slot-path-gslist - slots (append gnc:*kvp-option-path* - (list gnc:*business-label* - gnc:*company-contact*)))) + (let* ((contact (gnc:company-info gnc:*company-contact*)) (contact-str (opt-val "Display" "Company contact string"))) (if (and contact (> (string-length contact) 0)) (gnc:html-document-add-object! diff --git a/src/report/business-reports/invoice.scm b/src/report/business-reports/invoice.scm index 2baf6bbeaf..d9add63e47 100644 --- a/src/report/business-reports/invoice.scm +++ b/src/report/business-reports/invoice.scm @@ -607,13 +607,8 @@ (define (make-myname-table book date-format) (let* ((table (gnc:make-html-table)) - (slots (qof-book-get-slots book)) - (name (kvp-frame-get-slot-path-gslist - slots (append gnc:*kvp-option-path* - (list gnc:*business-label* gnc:*company-name*)))) - (addy (kvp-frame-get-slot-path-gslist - slots (append gnc:*kvp-option-path* - (list gnc:*business-label* gnc:*company-addy*))))) + (name (gnc:company-info gnc:*company-name*)) + (addy (gnc:company-info gnc:*company-addy*))) (gnc:html-table-set-style! table "table" diff --git a/src/report/business-reports/job-report.scm b/src/report/business-reports/job-report.scm index eb5f1580e4..61328afc9a 100644 --- a/src/report/business-reports/job-report.scm +++ b/src/report/business-reports/job-report.scm @@ -514,13 +514,8 @@ (define (make-myname-table book date-format) (let* ((table (gnc:make-html-table)) - (slots (qof-book-get-slots book)) - (name (kvp-frame-get-slot-path-gslist - slots (append gnc:*kvp-option-path* - (list gnc:*business-label* gnc:*company-name*)))) - (addy (kvp-frame-get-slot-path-gslist - slots (append gnc:*kvp-option-path* - (list gnc:*business-label* gnc:*company-addy*))))) + (name (gnc:company-info gnc:*company-name*)) + (addy (gnc:company-info gnc:*company-addy*))) (gnc:html-table-set-style! table "table" diff --git a/src/report/business-reports/owner-report.scm b/src/report/business-reports/owner-report.scm index fbade6efa7..eeb81e7256 100644 --- a/src/report/business-reports/owner-report.scm +++ b/src/report/business-reports/owner-report.scm @@ -719,13 +719,8 @@ (define (make-myname-table book date-format) (let* ((table (gnc:make-html-table)) - (slots (qof-book-get-slots book)) - (name (kvp-frame-get-slot-path-gslist - slots (append gnc:*kvp-option-path* - (list gnc:*business-label* gnc:*company-name*)))) - (addy (kvp-frame-get-slot-path-gslist - slots (append gnc:*kvp-option-path* - (list gnc:*business-label* gnc:*company-addy*))))) + (name (gnc:company-info gnc:*company-name*)) + (addy (gnc:company-info gnc:*company-addy*))) (gnc:html-table-set-style! table "table" diff --git a/src/report/business-reports/receipt.eguile.scm b/src/report/business-reports/receipt.eguile.scm index 36009e13f4..829da36e90 100644 --- a/src/report/business-reports/receipt.eguile.scm +++ b/src/report/business-reports/receipt.eguile.scm @@ -41,15 +41,14 @@ (currency (gncInvoiceGetCurrency opt-invoice)) (entries (gncInvoiceGetEntries opt-invoice)) (splits '()) - (slots (qof-book-get-slots book)) - (coyname (coy-info slots gnc:*company-name*)) - (coycontact (coy-info slots gnc:*company-contact*)) - (coyaddr (coy-info slots gnc:*company-addy*)) - (coyid (coy-info slots gnc:*company-id*)) - (coyphone (coy-info slots gnc:*company-phone*)) - (coyfax (coy-info slots gnc:*company-fax*)) - (coyurl (coy-info slots gnc:*company-url*)) - (coyemail (coy-info slots gnc:*company-email*)) + (coyname (gnc:company-info gnc:*company-name*)) + (coycontact (gnc:company-info gnc:*company-contact*)) + (coyaddr (gnc:company-info gnc:*company-addy*)) + (coyid (gnc:company-info gnc:*company-id*)) + (coyphone (gnc:company-info gnc:*company-phone*)) + (coyfax (gnc:company-info gnc:*company-fax*)) + (coyurl (gnc:company-info gnc:*company-url*)) + (coyemail (gnc:company-info gnc:*company-email*)) (owneraddr (gnc:owner-get-name-and-address-dep owner)) (billcontact (gncAddressGetName (gnc:owner-get-address owner))) ; flags and counters diff --git a/src/report/business-reports/receipt.scm b/src/report/business-reports/receipt.scm index c4052156cc..4e699953ff 100644 --- a/src/report/business-reports/receipt.scm +++ b/src/report/business-reports/receipt.scm @@ -69,12 +69,6 @@ (display-comm-coll-total amttot #f)) (if (and (not amt?) (not pc?)) (display (_ "n/a")))))) ; neither -(define (coy-info slots key) - ;; Extract a value from the company info key-value pairs - (kvp-frame-get-slot-path-gslist - slots - (append gnc:*kvp-option-path* (list gnc:*business-label* key)))) - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Define all the options diff --git a/src/report/business-reports/taxinvoice.eguile.scm b/src/report/business-reports/taxinvoice.eguile.scm index 9d1972a16f..75a5f8145e 100644 --- a/src/report/business-reports/taxinvoice.eguile.scm +++ b/src/report/business-reports/taxinvoice.eguile.scm @@ -47,15 +47,14 @@ (currency (gncInvoiceGetCurrency opt-invoice)) (entries (gncInvoiceGetEntries opt-invoice)) (splits '());' - (slots (qof-book-get-slots book)) - (coyname (coy-info slots gnc:*company-name*)) - (coycontact (coy-info slots gnc:*company-contact*)) - (coyaddr (coy-info slots gnc:*company-addy*)) - (coyid (coy-info slots gnc:*company-id*)) - (coyphone (coy-info slots gnc:*company-phone*)) - (coyfax (coy-info slots gnc:*company-fax*)) - (coyurl (coy-info slots gnc:*company-url*)) - (coyemail (coy-info slots gnc:*company-email*)) + (coyname (gnc:company-info gnc:*company-name*)) + (coycontact (gnc:company-info gnc:*company-contact*)) + (coyaddr (gnc:company-info gnc:*company-addy*)) + (coyid (gnc:company-info gnc:*company-id*)) + (coyphone (gnc:company-info gnc:*company-phone*)) + (coyfax (gnc:company-info gnc:*company-fax*)) + (coyurl (gnc:company-info gnc:*company-url*)) + (coyemail (gnc:company-info gnc:*company-email*)) (owneraddr (gnc:owner-get-address-dep owner)) (ownername (gnc:owner-get-name-dep owner)) (jobnumber (gncJobGetID (gncOwnerGetJob (gncInvoiceGetOwner opt-invoice)))) diff --git a/src/report/business-reports/taxinvoice.scm b/src/report/business-reports/taxinvoice.scm index b4ea9cc96a..06f4b1783a 100644 --- a/src/report/business-reports/taxinvoice.scm +++ b/src/report/business-reports/taxinvoice.scm @@ -76,12 +76,6 @@ (display-comm-coll-total amttot #f)) (if (and (not amt?) (not pc?)) (display (_ "n/a")))))) ; neither -(define (coy-info slots key) - ;; Extract a value from the company info key-value pairs - (kvp-frame-get-slot-path-gslist - slots - (append gnc:*kvp-option-path* (list gnc:*business-label* key)))) - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Define all the options diff --git a/src/report/locale-specific/us/taxtxf-de_DE.scm b/src/report/locale-specific/us/taxtxf-de_DE.scm index ab4e904757..85b554e612 100644 --- a/src/report/locale-specific/us/taxtxf-de_DE.scm +++ b/src/report/locale-specific/us/taxtxf-de_DE.scm @@ -752,11 +752,8 @@ (localtime (car (timespecCanonicalDayTime (cons (current-time) 0)))))) - (tax-nr (or - (kvp-frame-get-slot-path-gslist - (qof-book-get-slots (gnc-get-current-book)) - (append gnc:*kvp-option-path* - (list gnc:*tax-label* gnc:*tax-nr-label*))) + (tax-nr (or + (gnc:option-get-value gnc:*tax-label* gnc:*tax-nr-label*) "")) ) From fa22188549d2f60cfae030215ec1f279580d3299 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Fri, 12 Jun 2015 12:22:43 -0700 Subject: [PATCH 31/54] Remove gnc:kvp-option-dialog, make gnc_make_kvp_options static. gnc:kvp-option-dialog is unused, was only external user of gnc_make_kvp_options. --- src/app-utils/app-utils.i | 1 - src/app-utils/option-util.c | 66 ++++++++++++++++----------------- src/app-utils/option-util.h | 1 - src/gnome-utils/gnome-utils.scm | 16 -------- 4 files changed, 33 insertions(+), 51 deletions(-) diff --git a/src/app-utils/app-utils.i b/src/app-utils/app-utils.i index 7f6506ddd0..d3accbf1c2 100644 --- a/src/app-utils/app-utils.i +++ b/src/app-utils/app-utils.i @@ -106,7 +106,6 @@ gnc_numeric gnc_convert_from_euro(const gnc_commodity * currency, time64 gnc_accounting_period_fiscal_start(void); time64 gnc_accounting_period_fiscal_end(void); -SCM gnc_make_kvp_options(QofIdType id_type); void gnc_register_kvp_option_generator(QofIdType id_type, SCM generator); %typemap(in) GList * { diff --git a/src/app-utils/option-util.c b/src/app-utils/option-util.c index 829749e682..ee719bd0c0 100644 --- a/src/app-utils/option-util.c +++ b/src/app-utils/option-util.c @@ -269,6 +269,39 @@ gnc_option_db_find (SCM guile_options) } /* Create an option DB for a particular data type */ +/* For now, this is global, just like when it was in guile. + But, it should be make per-book. */ +static GHashTable *kvp_registry = NULL; + +static void +init_table(void) +{ + if (!kvp_registry) + kvp_registry = g_hash_table_new(g_str_hash, g_str_equal); +} + + +/* create a new options object for the requested type */ +static SCM +gnc_make_kvp_options(QofIdType id_type) +{ + GList *list, *p; + SCM gnc_new_options = SCM_UNDEFINED; + SCM options = SCM_UNDEFINED; + + init_table(); + list = g_hash_table_lookup(kvp_registry, id_type); + gnc_new_options = scm_c_eval_string("gnc:new-options"); + options = scm_call_0(gnc_new_options); + + for (p = list; p; p = p->next) + { + SCM generator = p->data; + scm_call_1(generator, options); + } + return options; +} + GNCOptionDB * gnc_option_db_new_for_type(QofIdType id_type) { @@ -2928,17 +2961,6 @@ SCM gnc_dateformat_option_set_value(QofDateFormat format, GNCDateMonthFormat mon return value; } -/* For now, this is global, just like when it was in guile. - But, it should be make per-book. */ -static GHashTable *kvp_registry = NULL; - -static void -init_table(void) -{ - if (!kvp_registry) - kvp_registry = g_hash_table_new(g_str_hash, g_str_equal); -} - /* * the generator should be a procedure that takes one argument, * an options object. The procedure should fill in the options with @@ -2954,25 +2976,3 @@ gnc_register_kvp_option_generator(QofIdType id_type, SCM generator) g_hash_table_insert(kvp_registry, (gpointer) id_type, list); scm_gc_protect_object(generator); } - - -/* create a new options object for the requested type */ -SCM -gnc_make_kvp_options(QofIdType id_type) -{ - GList *list, *p; - SCM gnc_new_options = SCM_UNDEFINED; - SCM options = SCM_UNDEFINED; - - init_table(); - list = g_hash_table_lookup(kvp_registry, id_type); - gnc_new_options = scm_c_eval_string("gnc:new-options"); - options = scm_call_0(gnc_new_options); - - for (p = list; p; p = p->next) - { - SCM generator = p->data; - scm_call_1(generator, options); - } - return options; -} diff --git a/src/app-utils/option-util.h b/src/app-utils/option-util.h index 5b16c7d2a8..13ad3fb5eb 100644 --- a/src/app-utils/option-util.h +++ b/src/app-utils/option-util.h @@ -75,7 +75,6 @@ void gnc_option_db_load_from_kvp(GNCOptionDB* odb, KvpFrame *slots); void gnc_option_db_save_to_kvp(GNCOptionDB* odb, KvpFrame *slots, gboolean clear_kvp); void gnc_register_kvp_option_generator(QofIdType id_type, SCM generator); -SCM gnc_make_kvp_options(QofIdType id_type); void gnc_option_db_set_ui_callbacks (GNCOptionDB *odb, GNCOptionGetUIValue get_ui_value, diff --git a/src/gnome-utils/gnome-utils.scm b/src/gnome-utils/gnome-utils.scm index 8b3968f13b..ec55c07a23 100644 --- a/src/gnome-utils/gnome-utils.scm +++ b/src/gnome-utils/gnome-utils.scm @@ -27,19 +27,3 @@ (load-from-path "gnc-menu-extensions") -(define (gnc:kvp-option-dialog id-type slots title changed_cb) - (let* ((options (gnc-make-kvp-options id-type)) - (optiondb (gnc-option-db-new options)) - (optionwin (gnc-options-dialog-new title))) - - (define (apply-cb) - (gnc:options-scm->kvp options slots gnc:*kvp-option-path* #t) - (if changed_cb (changed_cb))) - - (define (close-cb) - (gnc-options-dialog-destroy optionwin) - (gnc-option-db-destroy optiondb)) - - (gnc:options-kvp->scm options slots gnc:*kvp-option-path*) - (gnc-options-dialog-set-scm-callbacks optionwin apply-cb close-cb) - (gnc-options-dialog-build-contents optionwin optiondb))) From 9b3f6078fc1d69eec32c5846fd93918dd5107d1a Mon Sep 17 00:00:00 2001 From: John Ralls Date: Fri, 12 Jun 2015 15:19:45 -0700 Subject: [PATCH 32/54] Abstract options handling to QofBook. Eliminates direct KVP access in app-utils, all of which centered around options. Beneficial side effect: With all option writes now handled by qof_book_set_option(), the problem of options not being committed is eliminated. The options system is unnecessarily complex, with much back-and-forth between C and Guile. It needs to be completely rewritten, but that's a project for its own branch. --- src/app-utils/app-utils.scm | 5 +- src/app-utils/business-helpers.c | 2 +- src/app-utils/business-options.scm | 54 +++---- src/app-utils/option-util.c | 44 ++---- src/app-utils/option-util.h | 4 +- src/app-utils/options.scm | 203 +++++++++++++------------- src/app-utils/test/test-option-util.c | 31 ++-- src/engine/engine.i | 19 +-- src/engine/kvp-scm.c | 6 - src/engine/kvp-scm.h | 1 - src/gnome-utils/gnc-main-window.c | 4 +- src/gnome-utils/gnome-utils.scm | 2 - src/gnome/assistant-hierarchy.c | 4 +- src/libqof/qof/qofbook.cpp | 39 ++++- src/libqof/qof/qofbook.h | 46 +++++- 15 files changed, 239 insertions(+), 225 deletions(-) diff --git a/src/app-utils/app-utils.scm b/src/app-utils/app-utils.scm index cbac0df26d..840aed5631 100644 --- a/src/app-utils/app-utils.scm +++ b/src/app-utils/app-utils.scm @@ -148,9 +148,8 @@ (define (gnc:option-get-value category key) ;;Access an option directly - (kvp-frame-get-slot-path-gslist - (qof-book-get-slots (gnc-get-current-book)) - (append gnc:*kvp-option-path* (list category key)))) + (qof-book-get-option (gnc-get-current-book) + (list category key))) (export gnc:option-get-value) ;; config-var.scm (export gnc:make-config-var) diff --git a/src/app-utils/business-helpers.c b/src/app-utils/business-helpers.c index 618e01e8f4..fce223b9b3 100644 --- a/src/app-utils/business-helpers.c +++ b/src/app-utils/business-helpers.c @@ -33,7 +33,7 @@ GncTaxTable* gnc_business_get_default_tax_table (QofBook *book, GncOwnerType own GNCOptionDB *odb; odb = gnc_option_db_new_for_type (GNC_ID_BOOK); - qof_book_load_options (book, gnc_option_db_load_from_kvp, odb); + qof_book_load_options (book, gnc_option_db_load, odb); switch (ownertype) { diff --git a/src/app-utils/business-options.scm b/src/app-utils/business-options.scm index dbe6ba7905..355922041b 100644 --- a/src/app-utils/business-options.scm +++ b/src/app-utils/business-options.scm @@ -73,9 +73,9 @@ (gnc:error "Illegal invoice value set")))) (lambda () (convert-to-invoice (default-getter))) (gnc:restore-form-generator value->string) - (lambda (f p) (kvp-frame-set-slot-path-gslist f option p)) - (lambda (f p) - (let ((v (kvp-frame-get-slot-path-gslist f p))) + (lambda (b p) (qof-book-set-option b option p)) + (lambda (b p) + (let ((v (qof-book-get-option b p))) (if (and v (string? v)) (begin (set! option v) @@ -134,9 +134,9 @@ (gnc:error "Illegal customer value set")))) (lambda () (convert-to-customer (default-getter))) (gnc:restore-form-generator value->string) - (lambda (f p) (kvp-frame-set-slot-path-gslist f option p)) - (lambda (f p) - (let ((v (kvp-frame-get-slot-path-gslist f p))) + (lambda (b p) (qof-book-set-option b option p)) + (lambda (b p) + (let ((v (qof-book-get-option b p))) (if (and v (string? v)) (begin (set! option v) @@ -195,9 +195,9 @@ (gnc:error "Illegal vendor value set")))) (lambda () (convert-to-vendor (default-getter))) (gnc:restore-form-generator value->string) - (lambda (f p) (kvp-frame-set-slot-path-gslist f option p)) - (lambda (f p) - (let ((v (kvp-frame-get-slot-path-gslist f p))) + (lambda (b p) (qof-book-set-option b option p)) + (lambda (b p) + (let ((v (qof-book-get-option b p))) (if (and v (string? v)) (begin (set! option v) @@ -256,9 +256,9 @@ (gnc:error "Illegal employee value set")))) (lambda () (convert-to-employee (default-getter))) (gnc:restore-form-generator value->string) - (lambda (f p) (kvp-frame-set-slot-path-gslist f option p)) - (lambda (f p) - (let ((v (kvp-frame-get-slot-path-gslist f p))) + (lambda (b p) (qof-book-set-option b option p)) + (lambda (b p) + (let ((v (qof-book-get-option b p))) (if (and v (string? v)) (begin (set! option v) @@ -355,14 +355,14 @@ (gnc:error "Illegal owner value set")))) (lambda () (convert-to-owner (default-getter))) (gnc:restore-form-generator value->string) - (lambda (f p) - (kvp-frame-set-slot-path-gslist f (symbol->string (car option)) + (lambda (b p) + (qof-book-set-option b (symbol->string (car option)) (append p '("type"))) - (kvp-frame-set-slot-path-gslist f (cdr option) + (qof-book-set-option b (cdr option) (append p '("value")))) - (lambda (f p) - (let ((t (kvp-frame-get-slot-path-gslist f (append p '("type")))) - (v (kvp-frame-get-slot-path-gslist f (append p '("value"))))) + (lambda (b p) + (let ((t (qof-book-get-option b (append p '("type")))) + (v (qof-book-get-option b (append p '("value"))))) (if (and t v (string? t) (string? v)) (begin (set! option (cons (string->symbol t) v)) @@ -422,9 +422,9 @@ (gnc:error "Illegal taxtable value set")))) (lambda () (convert-to-taxtable (default-getter))) (gnc:restore-form-generator value->string) - (lambda (f p) (kvp-frame-set-slot-path-gslist f option p)) - (lambda (f p) - (let ((v (kvp-frame-get-slot-path-gslist f p))) + (lambda (b p) (qof-book-set-option b option p)) + (lambda (b p) + (let ((v (qof-book-get-option b p))) (if (and v (string? v)) (begin (set! option v) @@ -450,9 +450,9 @@ documentation-string default-value) (let ((option (gnc:make-number-range-option section name sort-tag documentation-string default-value 0 999999999 0 1))) - (gnc:set-option-scm->kvp option (lambda (f p) (kvp-frame-set-slot-path-gslist f (inexact->exact ((gnc:option-getter option))) (list "counters" key)))) - (gnc:set-option-kvp->scm option (lambda (f p) - (let ((v (kvp-frame-get-slot-path-gslist f (list "counters" key)))) + (gnc:set-option-scm->kvp option (lambda (b p) (qof-book-set-option b (inexact->exact ((gnc:option-getter option))) (list "counters" key)))) + (gnc:set-option-kvp->scm option (lambda (b p) + (let ((v (qof-book-get-option b (list "counters" key)))) (if (and v (integer? v)) ((gnc:option-setter option) v))))) option)) @@ -467,9 +467,9 @@ documentation-string default-value) (let ((option (gnc:make-string-option section name sort-tag documentation-string default-value))) - (gnc:set-option-scm->kvp option (lambda (f p) (kvp-frame-set-slot-path-gslist f ((gnc:option-getter option)) (list "counter_formats" key)))) - (gnc:set-option-kvp->scm option (lambda (f p) - (let ((v (kvp-frame-get-slot-path-gslist f (list "counter_formats" key)))) + (gnc:set-option-scm->kvp option (lambda (b p) (qof-book-set-option b ((gnc:option-getter option)) (list "counter_formats" key)))) + (gnc:set-option-kvp->scm option (lambda (b p) + (let ((v (qof-book-get-option b (list "counter_formats" key)))) (if (and v (string? v)) ((gnc:option-setter option) v))))) option)) diff --git a/src/app-utils/option-util.c b/src/app-utils/option-util.c index ee719bd0c0..d3ee99407b 100644 --- a/src/app-utils/option-util.c +++ b/src/app-utils/option-util.c @@ -313,13 +313,12 @@ gnc_option_db_new_for_type(QofIdType id_type) } void -gnc_option_db_load_from_kvp(GNCOptionDB* odb, KvpFrame *slots) +gnc_option_db_load(GNCOptionDB* odb, QofBook *book) { static SCM kvp_to_scm = SCM_UNDEFINED; - static SCM kvp_option_path = SCM_UNDEFINED; - SCM scm_slots; + SCM scm_book; - if (!odb || !slots) return; + if (!odb || !book) return; if (kvp_to_scm == SCM_UNDEFINED) { @@ -332,29 +331,19 @@ gnc_option_db_load_from_kvp(GNCOptionDB* odb, KvpFrame *slots) } } - if (kvp_option_path == SCM_UNDEFINED) - { - kvp_option_path = scm_c_eval_string("gnc:*kvp-option-path*"); - if (kvp_option_path == SCM_UNDEFINED) - { - PERR ("can't find the option path"); - return; - } - } - scm_slots = SWIG_NewPointerObj(slots, SWIG_TypeQuery("_p_KvpFrame"), 0); + scm_book = SWIG_NewPointerObj(book, SWIG_TypeQuery("_p_QofBook"), 0); - scm_call_3 (kvp_to_scm, odb->guile_options, scm_slots, kvp_option_path); + scm_call_2 (kvp_to_scm, odb->guile_options, scm_book); } void -gnc_option_db_save_to_kvp(GNCOptionDB* odb, KvpFrame *slots, gboolean clear_kvp) +gnc_option_db_save(GNCOptionDB* odb, QofBook *book, gboolean clear_all) { static SCM scm_to_kvp = SCM_UNDEFINED; - static SCM kvp_option_path = SCM_UNDEFINED; - SCM scm_slots; - SCM scm_clear_kvp; + SCM scm_book; + SCM scm_clear_all; - if (!odb || !slots) return; + if (!odb || !book) return; if (scm_to_kvp == SCM_UNDEFINED) { @@ -367,19 +356,10 @@ gnc_option_db_save_to_kvp(GNCOptionDB* odb, KvpFrame *slots, gboolean clear_kvp) } } - if (kvp_option_path == SCM_UNDEFINED) - { - kvp_option_path = scm_c_eval_string("gnc:*kvp-option-path*"); - if (kvp_option_path == SCM_UNDEFINED) - { - PERR ("can't find the option path"); - return; - } - } - scm_slots = SWIG_NewPointerObj(slots, SWIG_TypeQuery("_p_KvpFrame"), 0); - scm_clear_kvp = scm_from_bool (clear_kvp); + scm_book = SWIG_NewPointerObj(book, SWIG_TypeQuery("_p_QofBook"), 0); + scm_clear_all = scm_from_bool (clear_all); - scm_call_4 (scm_to_kvp, odb->guile_options, scm_slots, kvp_option_path, scm_clear_kvp); + scm_call_3 (scm_to_kvp, odb->guile_options, scm_book, scm_clear_all); } /********************************************************************\ * gnc_option_db_destroy * diff --git a/src/app-utils/option-util.h b/src/app-utils/option-util.h index 13ad3fb5eb..996223d9f7 100644 --- a/src/app-utils/option-util.h +++ b/src/app-utils/option-util.h @@ -71,8 +71,8 @@ void gnc_option_db_destroy(GNCOptionDB *odb); * in the kvp. */ GNCOptionDB * gnc_option_db_new_for_type(QofIdType id_type); -void gnc_option_db_load_from_kvp(GNCOptionDB* odb, KvpFrame *slots); -void gnc_option_db_save_to_kvp(GNCOptionDB* odb, KvpFrame *slots, gboolean clear_kvp); +void gnc_option_db_load(GNCOptionDB* odb, QofBook *book); +void gnc_option_db_save(GNCOptionDB* odb, QofBook *book, gboolean clear_all); void gnc_register_kvp_option_generator(QofIdType id_type, SCM generator); diff --git a/src/app-utils/options.scm b/src/app-utils/options.scm index 1ed4dda7cc..6132fbe761 100644 --- a/src/app-utils/options.scm +++ b/src/app-utils/options.scm @@ -37,8 +37,8 @@ ;; value. generate-restore-form ;; the scm->kvp and kvp->scm functions should save and load - ;; the option to a kvp. The arguments to these function will be - ;; a kvp-frame and a base key-path list for this option. + ;; the option to the book. The arguments to these function will be + ;; a book and a base key-path list for this option. scm->kvp kvp->scm ;; Validation func should accept a value and return (#t value) @@ -211,9 +211,9 @@ (lambda (x) (set! value x)) (lambda () default-value) (gnc:restore-form-generator value->string) - (lambda (f p) (kvp-frame-set-slot-path-gslist f value p)) - (lambda (f p) - (let ((v (kvp-frame-get-slot-path-gslist f p))) + (lambda (b p) (qof-book-set-option b value p)) + (lambda (b p) + (let ((v (qof-book-get-option b p))) (if (and v (string? v)) (set! value v)))) (lambda (x) @@ -235,9 +235,9 @@ (lambda (x) (set! value x)) (lambda () default-value) (gnc:restore-form-generator value->string) - (lambda (f p) (kvp-frame-set-slot-path-gslist f value p)) - (lambda (f p) - (let ((v (kvp-frame-get-slot-path-gslist f p))) + (lambda (b p) (qof-book-set-option b value p)) + (lambda (b p) + (let ((v (qof-book-get-option b p))) (if (and v (string? v)) (set! value v)))) (lambda (x) @@ -269,9 +269,9 @@ (lambda (x) (set! value x)) (lambda () default-value) (gnc:restore-form-generator value->string) - (lambda (f p) (kvp-frame-set-slot-path-gslist f value p)) - (lambda (f p) - (let ((v (kvp-frame-get-slot-path-gslist f p))) + (lambda (b p) (qof-book-set-option b value p)) + (lambda (b p) + (let ((v (qof-book-get-option b p))) (if (and v (string? v)) (set! value v)))) (lambda (x) @@ -308,9 +308,9 @@ (lambda (x) (set! value (currency->scm x))) (lambda () (scm->currency default-value)) (gnc:restore-form-generator value->string) - (lambda (f p) (kvp-frame-set-slot-path-gslist f value p)) - (lambda (f p) - (let ((v (kvp-frame-get-slot-path-gslist f p))) + (lambda (b p) (qof-book-set-option b value p)) + (lambda (b p) + (let ((v (qof-book-get-option b p))) (if (and v (string? v)) (set! value v)))) (lambda (x) (list #t x)) @@ -369,14 +369,14 @@ " (gnc-get-current-book)))))")) ;; scm->kvp -- commit the change - ;; f -- kvp-frame; p -- key-path - (lambda (f p) - (kvp-frame-set-slot-path-gslist - f (gncBudgetGetGUID selection-budget) p)) + ;; b -- book; p -- key-path + (lambda (b p) + (qof-book-set-option + b (gncBudgetGetGUID selection-budget) p)) ;; kvp->scm -- get the stored value - (lambda (f p) - (let ((v (kvp-frame-get-slot-path-gslist f p))) + (lambda (b p) + (let ((v (qof-book-get-option b p))) (if (and v (string? v)) (begin (set! selection-budget (gnc-budget-lookup v (gnc-get-current-book))))))) @@ -441,12 +441,12 @@ (set! value (commodity->scm x)))) (lambda () default-value) (gnc:restore-form-generator value->string) - (lambda (f p) - (kvp-frame-set-slot-path-gslist f (cadr value) (append p '("ns"))) - (kvp-frame-set-slot-path-gslist f (caddr value) (append p '("monic")))) - (lambda (f p) - (let ((ns (kvp-frame-get-slot-path-gslist f (append p '("ns")))) - (monic (kvp-frame-get-slot-path-gslist f (append p '("monic"))))) + (lambda (b p) + (qof-book-set-option b (cadr value) (append p '("ns"))) + (qof-book-set-option b (caddr value) (append p '("monic")))) + (lambda (b p) + (let ((ns (qof-book-get-option b (append p '("ns")))) + (monic (qof-book-get-option b (append p '("monic"))))) (if (and ns monic (string? ns) (string? monic)) (set! value (list 'commodity-scm ns monic))))) (lambda (x) (list #t x)) @@ -500,14 +500,14 @@ (setter-function-called-cb x))) (lambda () default-value) (gnc:restore-form-generator value->string) - (lambda (f p) (kvp-frame-set-slot-path-gslist f + (lambda (b p) (qof-book-set-option b ;; As no boolean KvpValue exists, as a workaround ;; we store the string "t" for TRUE and "f" for ;; FALSE in a string KvpValue. (if value "t" "f") p)) - (lambda (f p) - (let ((v (kvp-frame-get-slot-path-gslist f p))) + (lambda (b p) + (let ((v (qof-book-get-option b p))) ;; As no boolean KvpValue exists, as a workaround we store ;; the string "t" for TRUE and "f" for FALSE. (cond ((equal? v "t") (set! v #t)) @@ -582,17 +582,17 @@ (gnc:error "Illegal date value set:" date))) default-getter (gnc:restore-form-generator value->string) - (lambda (f p) - (kvp-frame-set-slot-path-gslist f (symbol->string (car value)) + (lambda (b p) + (qof-book-set-option b (symbol->string (car value)) (append p '("type"))) - (kvp-frame-set-slot-path-gslist f + (qof-book-set-option b (if (symbol? (cdr value)) (symbol->string (cdr value)) (cdr value)) (append p '("value")))) - (lambda (f p) - (let ((t (kvp-frame-get-slot-path-gslist f (append p '("type")))) - (v (kvp-frame-get-slot-path-gslist f (append p '("value"))))) + (lambda (b p) + (let ((t (qof-book-get-option b (append p '("type")))) + (v (qof-book-get-option b (append p '("value"))))) (if (and t v (string? t)) (set! value (cons (string->symbol t) (if (string? v) (string->symbol v) v)))))) @@ -720,25 +720,25 @@ (gnc:error "Illegal account list value set")))) (lambda () (map convert-to-account (default-getter))) (gnc:restore-form-generator value->string) - (lambda (f p) + (lambda (b p) (define (save-acc list count) (if (not (null? list)) (let ((key (string-append "acc" (gnc:value->string count)))) - (kvp-frame-set-slot-path-gslist f (car list) (append p (list key))) + (qof-book-set-option b (car list) (append p (list key))) (save-acc (cdr list) (+ 1 count))))) (if option-set (begin - (kvp-frame-set-slot-path-gslist f (length option) + (qof-book-set-option b (length option) (append p '("len"))) (save-acc option 0)))) - (lambda (f p) - (let ((len (kvp-frame-get-slot-path-gslist f (append p '("len"))))) + (lambda (b p) + (let ((len (qof-book-get-option b (append p '("len"))))) (define (load-acc count) (if (< count len) (let* ((key (string-append "acc" (gnc:value->string count))) - (guid (kvp-frame-get-slot-path-gslist - f (append p (list key))))) + (guid (qof-book-get-option + b (append p (list key))))) (cons guid (load-acc (+ count 1)))) '())) @@ -839,9 +839,9 @@ (gnc:error "Illegal account value set")))) (lambda () (convert-to-account (get-default))) (gnc:restore-form-generator value->string) - (lambda (f p) (kvp-frame-set-slot-path-gslist f option p)) - (lambda (f p) - (let ((v (kvp-frame-get-slot-path-gslist f p))) + (lambda (b p) (qof-book-set-option b option p)) + (lambda (b p) + (let ((v (qof-book-get-option b p))) (if (and v (string? v)) (set! option v)))) validator @@ -918,9 +918,9 @@ (gnc:error "Illegal Multichoice option set"))) (lambda () default-value) (gnc:restore-form-generator value->string) - (lambda (f p) (kvp-frame-set-slot-path-gslist f (symbol->string value) p)) - (lambda (f p) - (let ((v (kvp-frame-get-slot-path-gslist f p))) + (lambda (b p) (qof-book-set-option b (symbol->string value) p)) + (lambda (b p) + (let ((v (qof-book-get-option b p))) (if (and v (string? v)) (set! value (string->symbol v))))) (lambda (x) @@ -1004,9 +1004,9 @@ (gnc:error "Illegal Radiobutton option set"))) (lambda () default-value) (gnc:restore-form-generator value->string) - (lambda (f p) (kvp-frame-set-slot-path-gslist f (symbol->string value) p)) - (lambda (f p) - (let ((v (kvp-frame-get-slot-path-gslist f p))) + (lambda (b p) (qof-book-set-option b (symbol->string value) p)) + (lambda (b p) + (let ((v (qof-book-get-option b p))) (if (and v (string? v)) (set! value (string->symbol v))))) (lambda (x) @@ -1066,21 +1066,21 @@ (gnc:error "Illegal list option set"))) (lambda () default-value) (gnc:restore-form-generator value->string) - (lambda (f p) + (lambda (b p) (define (save-item list count) (if (not (null? list)) (let ((key (string-append "item" (gnc:value->string count)))) - (kvp-frame-set-slot-path-gslist f (car list) (append p (list key))) + (qof-book-set-option b (car list) (append p (list key))) (save-item (cdr list) (+ 1 count))))) - (kvp-frame-set-slot-path-gslist f (length value) (append p '("len"))) + (qof-book-set-option b (length value) (append p '("len"))) (save-item value 0)) - (lambda (f p) - (let ((len (kvp-frame-get-slot-path-gslist f (append p '("len"))))) + (lambda (b p) + (let ((len (qof-book-get-option b (append p '("len"))))) (define (load-item count) (if (< count len) (let* ((key (string-append "item" (gnc:value->string count))) - (val (kvp-frame-get-slot-path-gslist - f (append p (list key))))) + (val (qof-book-get-option + b (append p (list key))))) (cons val (load-item (+ count 1)))) '())) @@ -1118,9 +1118,9 @@ (lambda (x) (set! value x)) (lambda () default-value) (gnc:restore-form-generator value->string) - (lambda (f p) (kvp-frame-set-slot-path-gslist f value p)) - (lambda (f p) - (let ((v (kvp-frame-get-slot-path-gslist f p))) + (lambda (b p) (qof-book-set-option b value p)) + (lambda (b p) + (let ((v (qof-book-get-option b p))) (if (and v (number? v)) (set! value v)))) (lambda (x) @@ -1277,19 +1277,19 @@ (lambda (x) (set! value x)) (lambda () (def-value)) (gnc:restore-form-generator value->string) + (lambda (b p) + (qof-book-set-option + b (symbol->string (car value)) (append p '("fmt"))) + (qof-book-set-option + b (symbol->string (cadr value)) (append p '("month"))) + (qof-book-set-option + b (if (caddr value) 1 0) (append p '("years"))) + (qof-book-set-option (cadddr value) (append p '("custom")))) (lambda (f p) - (kvp-frame-set-slot-path-gslist - f (symbol->string (car value)) (append p '("fmt"))) - (kvp-frame-set-slot-path-gslist - f (symbol->string (cadr value)) (append p '("month"))) - (kvp-frame-set-slot-path-gslist - f (if (caddr value) 1 0) (append p '("years"))) - (kvp-frame-set-slot-path-gslist f (cadddr value) (append p '("custom")))) - (lambda (f p) - (let ((fmt (kvp-frame-get-slot-path-gslist f (append p '("fmt")))) - (month (kvp-frame-get-slot-path-gslist f (append p '("month")))) - (years (kvp-frame-get-slot-path-gslist f (append p '("years")))) - (custom (kvp-frame-get-slot-path-gslist f (append p '("custom"))))) + (let ((fmt (qof-book-get-option f (append p '("fmt")))) + (month (qof-book-get-option f (append p '("month")))) + (years (qof-book-get-option f (append p '("years")))) + (custom (qof-book-get-option f (append p '("custom"))))) (if (and fmt (string? fmt) month (string? month) @@ -1364,14 +1364,11 @@ (value->string (lambda () (string-append "'" (gnc:value->string (car value))))) - (trading-accounts-path (list (car gnc:*kvp-option-path*) - gnc:*option-section-accounts* + (trading-accounts-path (list gnc:*option-section-accounts* gnc:*option-name-trading-accounts*)) - (book-currency-path (list (car gnc:*kvp-option-path*) - gnc:*option-section-accounts* + (book-currency-path (list gnc:*option-section-accounts* gnc:*option-name-book-currency*)) - (gains-policy-path (list (car gnc:*kvp-option-path*) - gnc:*option-section-accounts* + (gains-policy-path (list gnc:*option-section-accounts* gnc:*option-name-default-gains-policy*))) (gnc:make-option section name sort-tag 'currency-accounting @@ -1387,26 +1384,26 @@ (cons default-cap-gains-policy-value '()))) (cons default-radiobutton-value '()))) (gnc:restore-form-generator value->string) - (lambda (f p) + (lambda (b p) (if (eq? 'book-currency (car value)) (begin ;; Currency = selected currency - (kvp-frame-set-slot-path-gslist - f + (qof-book-set-option + b (currency->scm (cadr value)) book-currency-path) ;; Default Gains Policy = selected policy - (kvp-frame-set-slot-path-gslist - f + (qof-book-set-option + b (symbol->string (caddr value)) gains-policy-path)) (if (eq? 'trading (car value)) ;; Use Trading Accounts = "t" - (kvp-frame-set-slot-path-gslist f "t" trading-accounts-path)))) - (lambda (f p) + (qof-book-set-option b "t" trading-accounts-path)))) + (lambda (b p) (let* ((trading-option-path-kvp? - (kvp-frame-get-slot-path-gslist - f trading-accounts-path)) + (qof-book-get-option + b trading-accounts-path)) (trading? (if (and trading-option-path-kvp? (string=? "t" trading-option-path-kvp?)) #t @@ -1416,11 +1413,11 @@ (v (if trading? 'trading (let* ((book-currency-option-path-kvp? - (kvp-frame-get-slot-path-gslist - f book-currency-path)) + (qof-book-get-option + b book-currency-path)) (gains-policy-option-path-kvp? - (kvp-frame-get-slot-path-gslist - f gains-policy-path)) + (qof-book-get-option + b gains-policy-path)) (book-currency? (if (and book-currency-option-path-kvp? gains-policy-option-path-kvp? @@ -1650,7 +1647,7 @@ (call-with-output-string generate-forms)) - (define (scm->kvp kvp-frame key-path) + (define (scm->kvp book) (options-for-each (lambda (option) (let ((value (gnc:option-value option)) @@ -1663,18 +1660,16 @@ (let ((save-fcn (gnc:option-scm->kvp option))) (gnc:debug "save-fcn: " save-fcn) (if save-fcn - (save-fcn kvp-frame (append key-path - (list section name)))))))))) + (save-fcn book (list section name))))))))) - (define (kvp->scm kvp-frame key-path) + (define (kvp->scm book) (options-for-each (lambda (option) (let ((section (gnc:option-section option)) (name (gnc:option-name option)) (load-fcn (gnc:option-kvp->scm option))) (if load-fcn - (load-fcn kvp-frame (append key-path - (list section name)))))))) + (load-fcn book (list section name))))))) (define (register-callback section name callback) (let ((id last-callback-id) @@ -1774,13 +1769,13 @@ (define (gnc:generate-restore-forms options options-string) ((options 'generate-restore-forms) options-string)) -(define (gnc:options-scm->kvp options kvp-frame key-path clear-kvp?) - (if clear-kvp? - (gnc-kvp-frame-delete-at-path kvp-frame key-path)) - ((options 'scm->kvp) kvp-frame key-path)) +(define (gnc:options-scm->kvp options book clear-option?) + (if clear-option? + (qof-book-options-delete book)) + ((options 'scm->kvp) book)) -(define (gnc:options-kvp->scm options kvp-frame key-path) - ((options 'kvp->scm) kvp-frame key-path)) +(define (gnc:options-kvp->scm options book) + ((options 'kvp->scm) book)) (define (gnc:options-clear-changes options) ((options 'clear-changes))) diff --git a/src/app-utils/test/test-option-util.c b/src/app-utils/test/test-option-util.c index 9a0a1883d8..f1adf73a21 100644 --- a/src/app-utils/test/test-option-util.c +++ b/src/app-utils/test/test-option-util.c @@ -1,5 +1,5 @@ /******************************************************************** - * test-option-util.c: GLib g_test test suite for Split.c. * + * test-option-util.cpp: GLib test suite for option-util.c. * * Copyright 2013 John Ralls * * * * This program is free software; you can redistribute it and/or * @@ -93,14 +93,14 @@ teardown (Fixture *fixture, gconstpointer pData) } static void -test_option_load_from_kvp (Fixture *fixture, gconstpointer pData) +test_option_load (Fixture *fixture, gconstpointer pData) { gchar *str = NULL; SCM symbol_value; QofBook *book = fixture->book; GNCOptionDB *odb = gnc_option_db_new_for_type (QOF_ID_BOOK); - qof_book_load_options (book, gnc_option_db_load_from_kvp, odb); + qof_book_load_options (book, gnc_option_db_load, odb); symbol_value = gnc_currency_accounting_option_value_get_method ( gnc_option_db_lookup_option (odb, OPTION_SECTION_ACCOUNTS, @@ -127,7 +127,7 @@ test_option_load_from_kvp (Fixture *fixture, gconstpointer pData) } static void -test_option_load_from_kvp_book_currency (Fixture *fixture, gconstpointer pData) +test_option_load_book_currency (Fixture *fixture, gconstpointer pData) { gchar *str = NULL; SCM symbol_value; @@ -137,7 +137,7 @@ test_option_load_from_kvp_book_currency (Fixture *fixture, gconstpointer pData) QofBook *book = fixture->book; GNCOptionDB *odb = gnc_option_db_new_for_type (QOF_ID_BOOK); - qof_book_load_options (book, gnc_option_db_load_from_kvp, odb); + qof_book_load_options (book, gnc_option_db_load, odb); symbol_value = gnc_currency_accounting_option_value_get_method ( gnc_option_db_lookup_option (odb, OPTION_SECTION_ACCOUNTS, @@ -186,7 +186,7 @@ test_option_load_from_kvp_book_currency (Fixture *fixture, gconstpointer pData) } static void -test_option_save_to_kvp (Fixture *fixture, gconstpointer pData) +test_option_save (Fixture *fixture, gconstpointer pData) { QofBook *book = fixture->book; GNCOptionDB *odb = gnc_option_db_new_for_type (QOF_ID_BOOK); @@ -203,7 +203,7 @@ test_option_save_to_kvp (Fixture *fixture, gconstpointer pData) g_assert (gnc_option_db_set_number_option (odb, OPTION_SECTION_ACCOUNTS, OPTION_NAME_AUTO_READONLY_DAYS, 17)); - qof_book_save_options (book, gnc_option_db_save_to_kvp, odb, TRUE); + qof_book_save_options (book, gnc_option_db_save, odb, TRUE); g_assert_cmpstr (kvp_frame_get_string (slots, "options/Accounts/Use Trading Accounts"), == , "t"); g_assert_cmpstr (kvp_frame_get_string (slots, "options/Accounts/Use Split Action Field for Number"), == , "t"); g_assert_cmpstr (kvp_frame_get_string (slots, "options/Business/Company Name"), ==, "Bogus Company"); @@ -213,7 +213,7 @@ test_option_save_to_kvp (Fixture *fixture, gconstpointer pData) } static void -test_option_save_to_kvp_book_currency (Fixture *fixture, gconstpointer pData) +test_option_save_book_currency (Fixture *fixture, gconstpointer pData) { QofBook *book = fixture->book; GNCOptionDB *odb = gnc_option_db_new_for_type (QOF_ID_BOOK); @@ -224,9 +224,9 @@ test_option_save_to_kvp_book_currency (Fixture *fixture, gconstpointer pData) scm_cons (scm_from_locale_symbol("book-currency"), scm_cons (scm_from_utf8_string("GTQ"), scm_cons (scm_from_locale_symbol("fifo"), SCM_EOL))))); - qof_book_save_options (book, gnc_option_db_save_to_kvp, odb, TRUE); - g_assert_cmpstr (kvp_frame_get_string (slots, "options/Accounts/Book Currency"), == , "GTQ"); - g_assert_cmpstr (kvp_frame_get_string (slots, "options/Accounts/Default Gains Policy"), == , "fifo"); + qof_book_save_options (book, gnc_option_db_save, odb, TRUE); + g_assert_cmpstr (kvp_frame_get_string(slots, "options/Accounts/Book Currency"), == , "GTQ"); + g_assert_cmpstr (kvp_frame_get_string(slots, "options/Accounts/Default Gains Policy"), == , "fifo"); gnc_option_db_destroy (odb); } @@ -234,9 +234,8 @@ test_option_save_to_kvp_book_currency (Fixture *fixture, gconstpointer pData) void test_suite_option_util (void) { - GNC_TEST_ADD (suitename, "Option DB Load from KVP", Fixture, NULL, setup_kvp, test_option_load_from_kvp, teardown); - GNC_TEST_ADD (suitename, "Option DB Load from KVP - Book Currency", Fixture, NULL, setup_kvp_book_currency, test_option_load_from_kvp_book_currency, teardown); - GNC_TEST_ADD (suitename, "Option DB Save to KVP", Fixture, NULL, setup, test_option_save_to_kvp, teardown); - GNC_TEST_ADD (suitename, "Option DB Save to KVP - Book Currency", Fixture, NULL, setup, test_option_save_to_kvp_book_currency, teardown); - + GNC_TEST_ADD (suitename, "Option DB Load", Fixture, NULL, setup_kvp, test_option_load, teardown); + GNC_TEST_ADD (suitename, "Option DB Load - Book Currency", Fixture, NULL, setup_kvp_book_currency, test_option_load_book_currency, teardown); + GNC_TEST_ADD (suitename, "Option DB Save", Fixture, NULL, setup, test_option_save, teardown); + GNC_TEST_ADD (suitename, "Option DB Save - Book Currency", Fixture, NULL, setup, test_option_save_book_currency, teardown); } diff --git a/src/engine/engine.i b/src/engine/engine.i index 99d1c5a6db..5a8637cbd3 100644 --- a/src/engine/engine.i +++ b/src/engine/engine.i @@ -142,18 +142,6 @@ functions. */ QofSession * qof_session_new (void); QofBook * qof_session_get_book (QofSession *session); -/* This horror is to permit the scheme options in - * src/app-utils/options.scm to read and write the book's KVP (another - * horror) directly. It should be refactored into book functions that - * handle the KVP access. - */ -%inline { - KvpFrame *qof_book_get_slots (QofBook *book); - extern KvpFrame *qof_instance_get_slots (QofInstance*); - KvpFrame *qof_book_get_slots (QofBook *book) { - return qof_instance_get_slots (QOF_INSTANCE (book)); - } -} // TODO: Unroll/remove const char *qof_session_get_url (QofSession *session); @@ -238,10 +226,9 @@ Account * gnc_book_get_template_root(QofBook *book); %typemap(out) KvpValue * " $result = gnc_kvp_value_ptr_to_scm($1); " %typemap(in) GSList *key_path " $1 = gnc_scm_to_gslist_string($input);" -void gnc_kvp_frame_delete_at_path(KvpFrame *frame, GSList *key_path); -void kvp_frame_set_slot_path_gslist( - KvpFrame *frame, KvpValue *new_value, GSList *key_path); -KvpValue * kvp_frame_get_slot_path_gslist (KvpFrame *frame, GSList *key_path); +void qof_book_options_delete (QofBook *book); +void qof_book_set_option (QofBook *book, KvpValue *new_value, GSList *key_path); +KvpValue* qof_book_get_option (QofBook *book, GSList *key_path); %clear GSList *key_path; diff --git a/src/engine/kvp-scm.c b/src/engine/kvp-scm.c index 52522a3ed2..1e51f34268 100644 --- a/src/engine/kvp-scm.c +++ b/src/engine/kvp-scm.c @@ -112,9 +112,3 @@ gnc_kvp_value_ptr_to_scm(KvpValue* val) } return SCM_BOOL_F; } - -void -gnc_kvp_frame_delete_at_path (KvpFrame *frame, GSList *key_path) -{ - kvp_frame_set_slot_path_gslist (frame, NULL, key_path); -} diff --git a/src/engine/kvp-scm.h b/src/engine/kvp-scm.h index 8085c6d174..4bca011620 100644 --- a/src/engine/kvp-scm.h +++ b/src/engine/kvp-scm.h @@ -6,7 +6,6 @@ KvpValue* gnc_scm_to_kvp_value_ptr(SCM kvpval); SCM gnc_kvp_value_ptr_to_scm(KvpValue* val); -void gnc_kvp_frame_delete_at_path(KvpFrame *frame, GSList *key_path); #endif /* KVP_SCM_H */ diff --git a/src/gnome-utils/gnc-main-window.c b/src/gnome-utils/gnc-main-window.c index c77637db52..3dd8b4c4f1 100644 --- a/src/gnome-utils/gnc-main-window.c +++ b/src/gnome-utils/gnc-main-window.c @@ -3950,7 +3950,7 @@ gnc_book_options_dialog_apply_cb(GNCOptionWin * optionwin, gnc_option_db_commit (options); qof_book_begin_edit (book); - qof_book_save_options (book, gnc_option_db_save_to_kvp, options, TRUE); + qof_book_save_options (book, gnc_option_db_save, options, TRUE); use_split_action_for_num_after = qof_book_use_split_action_for_num_field (gnc_get_current_book ()); if (use_split_action_for_num_before != use_split_action_for_num_after) @@ -3976,7 +3976,7 @@ gnc_book_options_dialog_cb (gboolean modal, gchar *title) GNCOptionWin *optionwin; options = gnc_option_db_new_for_type (QOF_ID_BOOK); - qof_book_load_options (book, gnc_option_db_load_from_kvp, options); + qof_book_load_options (book, gnc_option_db_load, options); gnc_option_db_clean (options); optionwin = gnc_options_dialog_new_modal (modal, diff --git a/src/gnome-utils/gnome-utils.scm b/src/gnome-utils/gnome-utils.scm index ec55c07a23..988b8ad0e2 100644 --- a/src/gnome-utils/gnome-utils.scm +++ b/src/gnome-utils/gnome-utils.scm @@ -23,7 +23,5 @@ (export gnc:make-menu) (export gnc:make-separator) -(export gnc:kvp-option-dialog) - (load-from-path "gnc-menu-extensions") diff --git a/src/gnome/assistant-hierarchy.c b/src/gnome/assistant-hierarchy.c index d45941da06..cacbf211c0 100644 --- a/src/gnome/assistant-hierarchy.c +++ b/src/gnome/assistant-hierarchy.c @@ -1021,7 +1021,7 @@ finish_book_options_helper(GNCOptionWin * optionwin, if (!options) return; gnc_option_db_commit (options); - qof_book_save_options (book, gnc_option_db_save_to_kvp, options, TRUE); + qof_book_save_options (book, gnc_option_db_save, options, TRUE); use_split_action_for_num_after = qof_book_use_split_action_for_num_field (book); if (use_split_action_for_num_before != use_split_action_for_num_after) @@ -1127,7 +1127,7 @@ assistant_instert_book_options_page (hierarchy_data *data) data->options = gnc_option_db_new_for_type (QOF_ID_BOOK); qof_book_load_options (gnc_get_current_book (), - gnc_option_db_load_from_kvp, data->options); + gnc_option_db_load, data->options); gnc_option_db_clean (data->options); data->optionwin = gnc_options_dialog_new_modal (TRUE, _("New Book Options")); diff --git a/src/libqof/qof/qofbook.cpp b/src/libqof/qof/qofbook.cpp index 8d7f7db585..2aa09b1b38 100644 --- a/src/libqof/qof/qofbook.cpp +++ b/src/libqof/qof/qofbook.cpp @@ -1096,17 +1096,20 @@ qof_book_set_feature (QofBook *book, const gchar *key, const gchar *descr) void qof_book_load_options (QofBook *book, GNCOptionLoad load_cb, GNCOptionDB *odb) { - KvpFrame *slots = qof_instance_get_slots (QOF_INSTANCE (book)); - load_cb (odb, slots); + load_cb (odb, book); } void qof_book_save_options (QofBook *book, GNCOptionSave save_cb, GNCOptionDB* odb, gboolean clear) { - KvpFrame *slots = qof_instance_get_slots (QOF_INSTANCE (book)); - save_cb (odb, slots, clear); - qof_instance_set_dirty (QOF_INSTANCE (book)); + /* Wrap this in begin/commit so that it commits only once instead of doing + * so for every option. Qof_book_set_option will take care of dirtying the + * book. + */ + qof_book_begin_edit (book); + save_cb (odb, book, clear); + qof_book_commit_edit (book); } static void noop (QofInstance *inst) {} @@ -1118,6 +1121,32 @@ qof_book_commit_edit(QofBook *book) qof_commit_edit_part2 (&book->inst, commit_err, noop, noop/*lot_free*/); } +void +qof_book_set_option (QofBook *book, KvpValue *value, GSList *path) +{ + KvpFrame *root = qof_instance_get_slots (QOF_INSTANCE (book)); + KvpFrame *options = kvp_frame_get_frame_slash (root, KVP_OPTION_PATH); + qof_book_begin_edit (book); + kvp_frame_set_slot_path_gslist (options, value, path); + qof_instance_set_dirty (QOF_INSTANCE (book)); + qof_book_commit_edit (book); +} + +KvpValue* +qof_book_get_option (QofBook *book, GSList *path) +{ + KvpFrame *root = qof_instance_get_slots(QOF_INSTANCE (book)); + KvpFrame *options = kvp_frame_get_frame(root, KVP_OPTION_PATH); + return kvp_frame_get_slot_path_gslist(options, path); +} + +void +qof_book_options_delete (QofBook *book) +{ + KvpFrame *root = qof_instance_get_slots(QOF_INSTANCE (book)); + kvp_frame_delete (kvp_frame_get_frame(root, KVP_OPTION_PATH)); +} + /* QofObject function implementation and registration */ gboolean qof_book_register (void) { diff --git a/src/libqof/qof/qofbook.h b/src/libqof/qof/qofbook.h index 776a4414dc..a51bad7d02 100644 --- a/src/libqof/qof/qofbook.h +++ b/src/libqof/qof/qofbook.h @@ -71,8 +71,8 @@ typedef void (*QofBookDirtyCB) (QofBook *, gboolean dirty, gpointer user_data); typedef struct gnc_option_db GNCOptionDB; -typedef void (*GNCOptionSave) (GNCOptionDB*, KvpFrame*, gboolean); -typedef void (*GNCOptionLoad) (GNCOptionDB*, KvpFrame*); +typedef void (*GNCOptionSave) (GNCOptionDB*, QofBook*, gboolean); +typedef void (*GNCOptionLoad) (GNCOptionDB*, QofBook*); /* Book structure */ struct _QofBook @@ -353,13 +353,47 @@ void qof_book_set_feature (QofBook *book, const gchar *key, const gchar *descr); void qof_book_begin_edit(QofBook *book); void qof_book_commit_edit(QofBook *book); -/* Access functions for loading and saving the file options */ +/* Access functions for options. */ +/** Load a GNCOptionsDB from KVP data. + * @param book: The book. + * @param load_cb: A callback function that does the loading. + * @param odb: The GNCOptionDB to load. + */ void qof_book_load_options (QofBook *book, GNCOptionLoad load_cb, GNCOptionDB *odb); -void -qof_book_save_options (QofBook *book, GNCOptionSave save_cb, - GNCOptionDB* odb, gboolean clear); +/** Save a GNCOptionsDB back to the book's KVP. + * @param book: The book. + * @param save_cb: A callback function that does the saving. + * @param odb: The GNCOptionsDB to save from. + * @param clear: Should the GNCOptionsDB be emptied after the save? + */ +void qof_book_save_options (QofBook *book, GNCOptionSave save_cb, + GNCOptionDB* odb, gboolean clear); +/** Save a single option value. + * Used from Scheme, the KvpValue<-->SCM translation is handled by the functions + * in kvp-scm.c and automated by SWIG. The starting element is set as + * KVP_OPTION_PATH in qofbookslots.h. + * @param book: The book. + * @param value: The KvpValue to store. + * @param path: A GSList of keys which form a path under KVP_OPTION_PATH. + */ +void qof_book_set_option (QofBook *book, KvpValue *value, GSList *path); +/** Read a single option value. + * Used from Scheme, the KvpValue<-->SCM translation is handled by the functions + * in kvp-scm.c and automated by SWIG. The starting element is set as + * KVP_OPTION_PATH in qofbookslots.h. + * @param book: The book. + * @param path: A GSList of keys which form a path under KVP_OPTION_PATH. + */ +KvpValue* qof_book_get_option (QofBook *book, GSList *path); + +/** Delete the options. + * Primarily used from Scheme to clear out the options before saving a new set. + * @param book: The book. + * @param list: A GList of keys which from a path under KVP_OPTION_PATH. + */ +void qof_book_options_delete (QofBook *book); /** deprecated */ #define qof_book_get_guid(X) qof_entity_get_guid (QOF_INSTANCE(X)) From 8b53483562e3c6b070205563eea572035b046a85 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Sat, 13 Jun 2015 14:21:19 -0700 Subject: [PATCH 33/54] Change gnc-slots-sql, sixtp-dom-generators, and sixtp-dom-parsers to C++. So that they'll be able to use the C++ Kvp classes. --- po/POTFILES.in | 6 +-- src/backend/sql/Makefile.am | 2 +- .../{gnc-slots-sql.c => gnc-slots-sql.cpp} | 20 +++++----- src/backend/sql/gnc-slots-sql.h | 7 ++++ src/backend/xml/Makefile.am | 4 +- ...-generators.c => sixtp-dom-generators.cpp} | 10 +++-- src/backend/xml/sixtp-dom-generators.h | 7 ++++ ...tp-dom-parsers.c => sixtp-dom-parsers.cpp} | 10 +++-- src/backend/xml/sixtp-dom-parsers.h | 8 +++- src/backend/xml/test/Makefile.am | 40 +++++++++---------- 10 files changed, 70 insertions(+), 44 deletions(-) rename src/backend/sql/{gnc-slots-sql.c => gnc-slots-sql.cpp} (97%) rename src/backend/xml/{sixtp-dom-generators.c => sixtp-dom-generators.cpp} (97%) rename src/backend/xml/{sixtp-dom-parsers.c => sixtp-dom-parsers.cpp} (99%) diff --git a/po/POTFILES.in b/po/POTFILES.in index af02822487..58c75b9665 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -58,7 +58,7 @@ src/backend/sql/gnc-owner-sql.c src/backend/sql/gnc-price-sql.c src/backend/sql/gnc-recurrence-sql.c src/backend/sql/gnc-schedxaction-sql.c -src/backend/sql/gnc-slots-sql.c +src/backend/sql/gnc-slots-sql.cpp src/backend/sql/gnc-tax-table-sql.c src/backend/sql/gnc-transaction-sql.c src/backend/sql/gnc-vendor-sql.c @@ -91,8 +91,8 @@ src/backend/xml/io-gncxml-v1.c src/backend/xml/io-gncxml-v2.c src/backend/xml/io-utils.c src/backend/xml/sixtp.c -src/backend/xml/sixtp-dom-generators.c -src/backend/xml/sixtp-dom-parsers.c +src/backend/xml/sixtp-dom-generators.cpp +src/backend/xml/sixtp-dom-parsers.cpp src/backend/xml/sixtp-stack.c src/backend/xml/sixtp-to-dom-parser.c src/backend/xml/sixtp-utils.c diff --git a/src/backend/sql/Makefile.am b/src/backend/sql/Makefile.am index d656030511..11a7bd5af3 100644 --- a/src/backend/sql/Makefile.am +++ b/src/backend/sql/Makefile.am @@ -38,7 +38,7 @@ libgnc_backend_sql_la_SOURCES = \ gnc-price-sql.c \ gnc-recurrence-sql.c \ gnc-schedxaction-sql.c \ - gnc-slots-sql.c \ + gnc-slots-sql.cpp \ gnc-tax-table-sql.c \ gnc-transaction-sql.c \ gnc-vendor-sql.c \ diff --git a/src/backend/sql/gnc-slots-sql.c b/src/backend/sql/gnc-slots-sql.cpp similarity index 97% rename from src/backend/sql/gnc-slots-sql.c rename to src/backend/sql/gnc-slots-sql.cpp index 0611e3e7f9..9bd6b5c085 100644 --- a/src/backend/sql/gnc-slots-sql.c +++ b/src/backend/sql/gnc-slots-sql.cpp @@ -25,7 +25,8 @@ * This file implements the top-level QofBackend API for saving/ * restoring data to/from an SQL db */ - +extern "C" +{ #include "config.h" #include @@ -40,7 +41,7 @@ #ifdef S_SPLINT_S #include "splint-defs.h" #endif - +} /*@ unused @*/ static QofLogModule log_module = G_LOG_DOMAIN; #define TABLE_NAME "slots" @@ -323,7 +324,7 @@ get_slot_type( gpointer pObject ) { slot_info_t* pInfo = (slot_info_t*)pObject; - g_return_val_if_fail( pObject != NULL, 0 ); + g_return_val_if_fail( pObject != NULL, KVP_TYPE_INVALID ); // return (gpointer)kvp_value_get_type( pInfo->pKvpValue ); return pInfo->value_type; @@ -337,7 +338,7 @@ set_slot_type( gpointer pObject, /*@ null @*/ gpointer pValue ) g_return_if_fail( pObject != NULL ); g_return_if_fail( pValue != NULL ); - pInfo->value_type = (KvpValueType)pValue; + pInfo->value_type = static_cast(GPOINTER_TO_INT(pValue)); } static gint64 @@ -709,7 +710,8 @@ save_slot( const gchar* key, KvpValue* value, gpointer data ) gboolean gnc_sql_slots_save( GncSqlBackend* be, const GncGUID* guid, gboolean is_infant, KvpFrame* pFrame ) { - slot_info_t slot_info = { NULL, NULL, TRUE, NULL, 0, NULL, FRAME, NULL, g_string_new(NULL) }; + slot_info_t slot_info = { NULL, NULL, TRUE, NULL, KVP_TYPE_INVALID, NULL, FRAME, NULL, g_string_new(NULL) }; + KvpFrame *pFrame = qof_instance_get_slots (inst); g_return_val_if_fail( be != NULL, FALSE ); g_return_val_if_fail( guid != NULL, FALSE ); @@ -736,7 +738,7 @@ gnc_sql_slots_delete( GncSqlBackend* be, const GncGUID* guid ) GncSqlResult* result; gchar guid_buf[GUID_ENCODING_LENGTH + 1]; GncSqlStatement* stmt; - slot_info_t slot_info = { NULL, NULL, TRUE, NULL, 0, NULL, FRAME, NULL, g_string_new(NULL) }; + slot_info_t slot_info = { NULL, NULL, TRUE, NULL, KVP_TYPE_INVALID, NULL, FRAME, NULL, g_string_new(NULL) }; g_return_val_if_fail( be != NULL, FALSE ); g_return_val_if_fail( guid != NULL, FALSE ); @@ -818,7 +820,7 @@ load_slot( slot_info_t *pInfo, GncSqlRow* row ) void gnc_sql_slots_load( GncSqlBackend* be, QofInstance* inst ) { - slot_info_t info = { NULL, NULL, TRUE, NULL, 0, NULL, FRAME, NULL, g_string_new(NULL) }; + slot_info_t info = { NULL, NULL, TRUE, NULL, KVP_TYPE_INVALID, NULL, FRAME, NULL, g_string_new(NULL) }; g_return_if_fail( be != NULL ); g_return_if_fail( inst != NULL ); @@ -883,7 +885,7 @@ load_obj_guid( const GncSqlBackend* be, GncSqlRow* row ) static void load_slot_for_list_item( GncSqlBackend* be, GncSqlRow* row, QofCollection* coll ) { - slot_info_t slot_info = { NULL, NULL, TRUE, NULL, 0, NULL, FRAME, NULL, NULL }; + slot_info_t slot_info = { NULL, NULL, TRUE, NULL, KVP_TYPE_INVALID, NULL, FRAME, NULL, NULL }; const GncGUID* guid; QofInstance* inst; @@ -969,7 +971,7 @@ gnc_sql_slots_load_for_list( GncSqlBackend* be, GList* list ) static void load_slot_for_book_object( GncSqlBackend* be, GncSqlRow* row, BookLookupFn lookup_fn ) { - slot_info_t slot_info = { NULL, NULL, TRUE, NULL, 0, NULL, FRAME, NULL, NULL }; + slot_info_t slot_info = { NULL, NULL, TRUE, NULL, KVP_TYPE_INVALID, NULL, FRAME, NULL, NULL }; const GncGUID* guid; QofInstance* inst; diff --git a/src/backend/sql/gnc-slots-sql.h b/src/backend/sql/gnc-slots-sql.h index e7f00eb678..a9d6685d3c 100644 --- a/src/backend/sql/gnc-slots-sql.h +++ b/src/backend/sql/gnc-slots-sql.h @@ -28,6 +28,10 @@ #ifndef GNC_SLOTS_SQL_H #define GNC_SLOTS_SQL_H +#ifdef __cplusplus +extern "C" +{ +#endif #include #include "guid.h" @@ -88,4 +92,7 @@ void gnc_sql_slots_load_for_sql_subquery( GncSqlBackend* be, const gchar* subque void gnc_sql_init_slots_handler( void ); +#ifdef __cplusplus +} +#endif #endif /* GNC_SLOTS_SQL_H */ diff --git a/src/backend/xml/Makefile.am b/src/backend/xml/Makefile.am index 7709aa1709..e7bb12e610 100644 --- a/src/backend/xml/Makefile.am +++ b/src/backend/xml/Makefile.am @@ -45,8 +45,8 @@ libgnc_backend_xml_utils_la_SOURCES = \ io-gncxml-v1.c \ io-gncxml-v2.c \ io-utils.c \ - sixtp-dom-generators.c \ - sixtp-dom-parsers.c \ + sixtp-dom-generators.cpp \ + sixtp-dom-parsers.cpp \ sixtp-stack.c \ sixtp-to-dom-parser.c \ sixtp-utils.c \ diff --git a/src/backend/xml/sixtp-dom-generators.c b/src/backend/xml/sixtp-dom-generators.cpp similarity index 97% rename from src/backend/xml/sixtp-dom-generators.c rename to src/backend/xml/sixtp-dom-generators.cpp index 083bb723c9..665aebddaf 100644 --- a/src/backend/xml/sixtp-dom-generators.c +++ b/src/backend/xml/sixtp-dom-generators.cpp @@ -20,7 +20,8 @@ * Boston, MA 02110-1301, USA gnu@gnu.org * * * ********************************************************************/ - +extern "C" +{ #define __EXTENSIONS__ #include "config.h" @@ -31,6 +32,7 @@ #include "sixtp-dom-generators.h" #include "sixtp-utils.h" +} static QofLogModule log_module = GNC_MOD_IO; @@ -237,11 +239,11 @@ double_to_string(double value) } static void -add_text_to_node(xmlNodePtr node, gchar *type, gchar *val) +add_text_to_node(xmlNodePtr node, const gchar *type, gchar *val) { gchar *newtype = g_strdup (type); gchar *newval = g_strdup (val); - xmlSetProp(node, BAD_CAST "type", checked_char_cast (type)); + xmlSetProp(node, BAD_CAST "type", BAD_CAST type); xmlNodeSetContent(node, checked_char_cast (val)); g_free (newtype); g_free(newval); @@ -251,7 +253,7 @@ static void add_kvp_slot(const char * key, KvpValue* value, xmlNodePtr node); static void -add_kvp_value_node(xmlNodePtr node, gchar *tag, KvpValue* val) +add_kvp_value_node(xmlNodePtr node, const gchar *tag, KvpValue* val) { xmlNodePtr val_node; kvp_value_t kvp_type; diff --git a/src/backend/xml/sixtp-dom-generators.h b/src/backend/xml/sixtp-dom-generators.h index 9a8b3b71cf..09b14b5b7c 100644 --- a/src/backend/xml/sixtp-dom-generators.h +++ b/src/backend/xml/sixtp-dom-generators.h @@ -24,6 +24,10 @@ #ifndef SIXTP_DOM_GENERATORS_H #define SIXTP_DOM_GENERATORS_H +#ifdef __cplusplus +extern "C" +{ +#endif #include #include "gnc-xml-helper.h" @@ -49,4 +53,7 @@ xmlNodePtr recurrence_to_dom_tree(const gchar *tag, const Recurrence *r); gchar* double_to_string(double value); +#ifdef __cplusplus +} +#endif #endif /* _SIXTP_DOM_GENERATORS_H_ */ diff --git a/src/backend/xml/sixtp-dom-parsers.c b/src/backend/xml/sixtp-dom-parsers.cpp similarity index 99% rename from src/backend/xml/sixtp-dom-parsers.c rename to src/backend/xml/sixtp-dom-parsers.cpp index 1eb9c03bb3..aa001655b2 100644 --- a/src/backend/xml/sixtp-dom-parsers.c +++ b/src/backend/xml/sixtp-dom-parsers.cpp @@ -20,7 +20,8 @@ * Boston, MA 02110-1301, USA gnu@gnu.org * * * ********************************************************************/ - +extern "C" +{ #include "config.h" #include @@ -30,7 +31,7 @@ #include "gnc-engine.h" #include "sixtp-utils.h" #include "sixtp-dom-parsers.h" - +} static QofLogModule log_module = GNC_MOD_IO; GncGUID* @@ -350,7 +351,7 @@ dom_tree_to_frame_kvp_value(xmlNodePtr node) struct kvp_val_converter { - gchar *tag; + const gchar *tag; KvpValue* (*converter)(xmlNodePtr node); }; @@ -683,7 +684,8 @@ dom_tree_to_gdate(xmlNodePtr node) } g_free(content); seen_date = TRUE; - g_date_set_dmy( ret, day, month, year ); + g_date_set_dmy( ret, day, static_cast(month), + year ); if ( !g_date_valid( ret ) ) { PWARN("invalid date"); diff --git a/src/backend/xml/sixtp-dom-parsers.h b/src/backend/xml/sixtp-dom-parsers.h index b48f8b5fcd..efae18ae2f 100644 --- a/src/backend/xml/sixtp-dom-parsers.h +++ b/src/backend/xml/sixtp-dom-parsers.h @@ -23,6 +23,10 @@ #ifndef SIXTP_DOM_PARSERS_H #define SIXTP_DOM_PARSERS_H +#ifdef __cplusplus +extern "C" +{ +#endif #include @@ -88,5 +92,7 @@ gboolean dom_tree_generic_parse(xmlNodePtr node, struct dom_tree_handler *handlers, gpointer data); - +#ifdef __cplusplus +} +#endif #endif /* _SIXTP_DOM_PARSERS_H_ */ diff --git a/src/backend/xml/test/Makefile.am b/src/backend/xml/test/Makefile.am index d3993533d2..40c10489ec 100644 --- a/src/backend/xml/test/Makefile.am +++ b/src/backend/xml/test/Makefile.am @@ -2,8 +2,8 @@ SUBDIRS = test-files test_date_converting_SOURCES = \ - ${top_srcdir}/src/backend/xml/sixtp-dom-parsers.c \ - ${top_srcdir}/src/backend/xml/sixtp-dom-generators.c \ + ${top_srcdir}/src/backend/xml/sixtp-dom-parsers.cpp \ + ${top_srcdir}/src/backend/xml/sixtp-dom-generators.cpp \ ${top_srcdir}/src/backend/xml/sixtp-utils.c \ ${top_srcdir}/src/backend/xml/sixtp.c \ ${top_srcdir}/src/backend/xml/sixtp-stack.c \ @@ -12,8 +12,8 @@ test_date_converting_SOURCES = \ test-date-converting.c test_dom_converters1_SOURCES = \ - ${top_srcdir}/src/backend/xml/sixtp-dom-parsers.c \ - ${top_srcdir}/src/backend/xml/sixtp-dom-generators.c \ + ${top_srcdir}/src/backend/xml/sixtp-dom-parsers.cpp \ + ${top_srcdir}/src/backend/xml/sixtp-dom-generators.cpp \ ${top_srcdir}/src/backend/xml/sixtp-utils.c \ ${top_srcdir}/src/backend/xml/sixtp.c \ ${top_srcdir}/src/backend/xml/sixtp-stack.c \ @@ -22,8 +22,8 @@ test_dom_converters1_SOURCES = \ test-dom-converters1.c test_kvp_frames_SOURCES = \ - ${top_srcdir}/src/backend/xml/sixtp-dom-parsers.c \ - ${top_srcdir}/src/backend/xml/sixtp-dom-generators.c \ + ${top_srcdir}/src/backend/xml/sixtp-dom-parsers.cpp \ + ${top_srcdir}/src/backend/xml/sixtp-dom-generators.cpp \ ${top_srcdir}/src/backend/xml/sixtp-utils.c \ ${top_srcdir}/src/backend/xml/sixtp.c \ ${top_srcdir}/src/backend/xml/sixtp-stack.c \ @@ -36,8 +36,8 @@ test_kvp_frames_SOURCES = \ # and remain portable. test_load_example_account_SOURCES = \ - ${top_srcdir}/src/backend/xml/sixtp-dom-parsers.c \ - ${top_srcdir}/src/backend/xml/sixtp-dom-generators.c \ + ${top_srcdir}/src/backend/xml/sixtp-dom-parsers.cpp \ + ${top_srcdir}/src/backend/xml/sixtp-dom-generators.cpp \ ${top_srcdir}/src/backend/xml/sixtp-utils.c \ ${top_srcdir}/src/backend/xml/sixtp.c \ ${top_srcdir}/src/backend/xml/sixtp-stack.c \ @@ -60,8 +60,8 @@ test_load_example_account_SOURCES = \ test-load-example-account.c test_string_converters_SOURCES = \ - ${top_srcdir}/src/backend/xml/sixtp-dom-parsers.c \ - ${top_srcdir}/src/backend/xml/sixtp-dom-generators.c \ + ${top_srcdir}/src/backend/xml/sixtp-dom-parsers.cpp \ + ${top_srcdir}/src/backend/xml/sixtp-dom-generators.cpp \ ${top_srcdir}/src/backend/xml/sixtp-utils.c \ ${top_srcdir}/src/backend/xml/sixtp.c \ ${top_srcdir}/src/backend/xml/sixtp-stack.c \ @@ -70,8 +70,8 @@ test_string_converters_SOURCES = \ test-string-converters.c test_xml_account_SOURCES = \ - ${top_srcdir}/src/backend/xml/sixtp-dom-parsers.c \ - ${top_srcdir}/src/backend/xml/sixtp-dom-generators.c \ + ${top_srcdir}/src/backend/xml/sixtp-dom-parsers.cpp \ + ${top_srcdir}/src/backend/xml/sixtp-dom-generators.cpp \ ${top_srcdir}/src/backend/xml/sixtp-utils.c \ ${top_srcdir}/src/backend/xml/sixtp.c \ ${top_srcdir}/src/backend/xml/sixtp-stack.c \ @@ -93,8 +93,8 @@ test_xml_account_SOURCES = \ test-xml-account.c test_xml_commodity_SOURCES = \ - ${top_srcdir}/src/backend/xml/sixtp-dom-parsers.c \ - ${top_srcdir}/src/backend/xml/sixtp-dom-generators.c \ + ${top_srcdir}/src/backend/xml/sixtp-dom-parsers.cpp \ + ${top_srcdir}/src/backend/xml/sixtp-dom-generators.cpp \ ${top_srcdir}/src/backend/xml/sixtp-utils.c \ ${top_srcdir}/src/backend/xml/sixtp.c \ ${top_srcdir}/src/backend/xml/sixtp-stack.c \ @@ -116,8 +116,8 @@ test_xml_commodity_SOURCES = \ test-xml-commodity.c test_xml_pricedb_SOURCES = \ - ${top_srcdir}/src/backend/xml/sixtp-dom-parsers.c \ - ${top_srcdir}/src/backend/xml/sixtp-dom-generators.c \ + ${top_srcdir}/src/backend/xml/sixtp-dom-parsers.cpp \ + ${top_srcdir}/src/backend/xml/sixtp-dom-generators.cpp \ ${top_srcdir}/src/backend/xml/sixtp-utils.c \ ${top_srcdir}/src/backend/xml/sixtp.c \ ${top_srcdir}/src/backend/xml/sixtp-stack.c \ @@ -139,8 +139,8 @@ test_xml_pricedb_SOURCES = \ test-xml-pricedb.c test_xml_transaction_SOURCES = \ - ${top_srcdir}/src/backend/xml/sixtp-dom-parsers.c \ - ${top_srcdir}/src/backend/xml/sixtp-dom-generators.c \ + ${top_srcdir}/src/backend/xml/sixtp-dom-parsers.cpp \ + ${top_srcdir}/src/backend/xml/sixtp-dom-generators.cpp \ ${top_srcdir}/src/backend/xml/sixtp-utils.c \ ${top_srcdir}/src/backend/xml/sixtp.c \ ${top_srcdir}/src/backend/xml/sixtp-stack.c \ @@ -162,8 +162,8 @@ test_xml_transaction_SOURCES = \ test-xml-transaction.c test_xml2_is_file_SOURCES = \ - ${top_srcdir}/src/backend/xml/sixtp-dom-parsers.c \ - ${top_srcdir}/src/backend/xml/sixtp-dom-generators.c \ + ${top_srcdir}/src/backend/xml/sixtp-dom-parsers.cpp \ + ${top_srcdir}/src/backend/xml/sixtp-dom-generators.cpp \ ${top_srcdir}/src/backend/xml/sixtp-utils.c \ ${top_srcdir}/src/backend/xml/sixtp.c \ ${top_srcdir}/src/backend/xml/sixtp-stack.c \ From 55e4d30a44ac65a4e2c4d3e82cd13fdde2b05d0e Mon Sep 17 00:00:00 2001 From: John Ralls Date: Fri, 12 Jun 2015 15:53:33 -0700 Subject: [PATCH 34/54] Pass QofInstance instead of KvpFrame to gnc_sql_slots_save. --- src/backend/sql/gnc-account-sql.c | 2 +- src/backend/sql/gnc-backend-sql.c | 2 +- src/backend/sql/gnc-budget-sql.c | 2 +- src/backend/sql/gnc-commodity-sql.c | 2 +- src/backend/sql/gnc-employee-sql.c | 2 +- src/backend/sql/gnc-invoice-sql.c | 2 +- src/backend/sql/gnc-schedxaction-sql.c | 2 +- src/backend/sql/gnc-slots-sql.cpp | 3 ++- src/backend/sql/gnc-slots-sql.h | 5 ++--- src/backend/sql/gnc-tax-table-sql.c | 2 +- src/backend/sql/gnc-transaction-sql.c | 7 ++----- src/backend/sql/gnc-vendor-sql.c | 2 +- 12 files changed, 15 insertions(+), 18 deletions(-) diff --git a/src/backend/sql/gnc-account-sql.c b/src/backend/sql/gnc-account-sql.c index 7d6b3a3e1c..cf887dd433 100644 --- a/src/backend/sql/gnc-account-sql.c +++ b/src/backend/sql/gnc-account-sql.c @@ -383,7 +383,7 @@ gnc_sql_save_account( GncSqlBackend* be, QofInstance* inst ) guid = qof_instance_get_guid( inst ); if ( !qof_instance_get_destroying(inst) ) { - is_ok = gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) ); + is_ok = gnc_sql_slots_save( be, guid, is_infant, inst); } else { diff --git a/src/backend/sql/gnc-backend-sql.c b/src/backend/sql/gnc-backend-sql.c index 2124be97c3..1e68004df1 100644 --- a/src/backend/sql/gnc-backend-sql.c +++ b/src/backend/sql/gnc-backend-sql.c @@ -3072,7 +3072,7 @@ gnc_sql_commit_standard_item( GncSqlBackend* be, QofInstance* inst, const gchar* guid = qof_instance_get_guid( inst ); if ( !qof_instance_get_destroying(inst) ) { - is_ok = gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) ); + is_ok = gnc_sql_slots_save( be, guid, is_infant, inst); } else { diff --git a/src/backend/sql/gnc-budget-sql.c b/src/backend/sql/gnc-budget-sql.c index 4c697c9f9e..cd4db4a919 100644 --- a/src/backend/sql/gnc-budget-sql.c +++ b/src/backend/sql/gnc-budget-sql.c @@ -430,7 +430,7 @@ save_budget( GncSqlBackend* be, QofInstance* inst ) } if ( is_ok ) { - is_ok = gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) ); + is_ok = gnc_sql_slots_save( be, guid, is_infant, inst); } } else diff --git a/src/backend/sql/gnc-commodity-sql.c b/src/backend/sql/gnc-commodity-sql.c index 040b17c21f..9e3bccbfc8 100644 --- a/src/backend/sql/gnc-commodity-sql.c +++ b/src/backend/sql/gnc-commodity-sql.c @@ -213,7 +213,7 @@ do_commit_commodity( GncSqlBackend* be, QofInstance* inst, gboolean force_insert guid = qof_instance_get_guid( inst ); if ( !qof_instance_get_destroying(inst) ) { - is_ok = gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) ); + is_ok = gnc_sql_slots_save( be, guid, is_infant, inst); } else { diff --git a/src/backend/sql/gnc-employee-sql.c b/src/backend/sql/gnc-employee-sql.c index 5b18a1eeda..3e09f1c420 100644 --- a/src/backend/sql/gnc-employee-sql.c +++ b/src/backend/sql/gnc-employee-sql.c @@ -198,7 +198,7 @@ save_employee( GncSqlBackend* be, QofInstance* inst ) guid = qof_instance_get_guid( inst ); if ( !qof_instance_get_destroying(inst) ) { - is_ok = gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) ); + is_ok = gnc_sql_slots_save( be, guid, is_infant, inst); } else { diff --git a/src/backend/sql/gnc-invoice-sql.c b/src/backend/sql/gnc-invoice-sql.c index 72c1cd2a77..fc99e68e64 100644 --- a/src/backend/sql/gnc-invoice-sql.c +++ b/src/backend/sql/gnc-invoice-sql.c @@ -221,7 +221,7 @@ save_invoice( GncSqlBackend* be, QofInstance* inst ) guid = qof_instance_get_guid( inst ); if ( !qof_instance_get_destroying(inst) ) { - is_ok = gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) ); + is_ok = gnc_sql_slots_save( be, guid, is_infant, inst); } else { diff --git a/src/backend/sql/gnc-schedxaction-sql.c b/src/backend/sql/gnc-schedxaction-sql.c index b0a3ab58ae..058cd3b468 100644 --- a/src/backend/sql/gnc-schedxaction-sql.c +++ b/src/backend/sql/gnc-schedxaction-sql.c @@ -206,7 +206,7 @@ gnc_sql_save_schedxaction( GncSqlBackend* be, QofInstance* inst ) // Now, commit any slots if ( op == OP_DB_INSERT || op == OP_DB_UPDATE ) { - is_ok = gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) ); + is_ok = gnc_sql_slots_save( be, guid, is_infant, inst); } else { diff --git a/src/backend/sql/gnc-slots-sql.cpp b/src/backend/sql/gnc-slots-sql.cpp index 9bd6b5c085..bff1eab393 100644 --- a/src/backend/sql/gnc-slots-sql.cpp +++ b/src/backend/sql/gnc-slots-sql.cpp @@ -708,7 +708,8 @@ save_slot( const gchar* key, KvpValue* value, gpointer data ) } gboolean -gnc_sql_slots_save( GncSqlBackend* be, const GncGUID* guid, gboolean is_infant, KvpFrame* pFrame ) +gnc_sql_slots_save( GncSqlBackend* be, const GncGUID* guid, gboolean is_infant, + QofInstance *inst) { slot_info_t slot_info = { NULL, NULL, TRUE, NULL, KVP_TYPE_INVALID, NULL, FRAME, NULL, g_string_new(NULL) }; KvpFrame *pFrame = qof_instance_get_slots (inst); diff --git a/src/backend/sql/gnc-slots-sql.h b/src/backend/sql/gnc-slots-sql.h index a9d6685d3c..28b6cb4105 100644 --- a/src/backend/sql/gnc-slots-sql.h +++ b/src/backend/sql/gnc-slots-sql.h @@ -35,7 +35,6 @@ extern "C" #include #include "guid.h" -#include "kvp_frame.h" #include "qof.h" #include "gnc-backend-sql.h" @@ -45,11 +44,11 @@ extern "C" * @param be SQL backend * @param guid Object guid * @param is_infant Is this an infant object? - * @param pFrame Top-level KVP frame + * @param inst The QodInstance owning the slots. * @return TRUE if successful, FALSE if error */ gboolean gnc_sql_slots_save( GncSqlBackend* be, const GncGUID* guid, - gboolean is_infant, KvpFrame* pFrame ); + gboolean is_infant, QofInstance *inst ); /** * gnc_sql_slots_delete - Deletes slots for an object from the db. diff --git a/src/backend/sql/gnc-tax-table-sql.c b/src/backend/sql/gnc-tax-table-sql.c index fbf5d372f0..bb5f06898a 100644 --- a/src/backend/sql/gnc-tax-table-sql.c +++ b/src/backend/sql/gnc-tax-table-sql.c @@ -454,7 +454,7 @@ save_taxtable( GncSqlBackend* be, QofInstance* inst ) guid = qof_instance_get_guid( inst ); if ( !qof_instance_get_destroying(inst) ) { - is_ok = gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) ); + is_ok = gnc_sql_slots_save( be, guid, is_infant, inst); if ( is_ok ) { is_ok = save_tt_entries( be, guid, gncTaxTableGetEntries( tt ) ); diff --git a/src/backend/sql/gnc-transaction-sql.c b/src/backend/sql/gnc-transaction-sql.c index f48ce71d35..0b4eb4090b 100644 --- a/src/backend/sql/gnc-transaction-sql.c +++ b/src/backend/sql/gnc-transaction-sql.c @@ -627,10 +627,7 @@ commit_split( GncSqlBackend* be, QofInstance* inst ) if ( is_ok && !qof_instance_get_destroying (inst)) { - is_ok = gnc_sql_slots_save( be, - guid, - is_infant, - qof_instance_get_slots( inst ) ); + is_ok = gnc_sql_slots_save( be, guid, is_infant, inst); } return is_ok; @@ -724,7 +721,7 @@ save_transaction( GncSqlBackend* be, Transaction* pTx, gboolean do_save_splits ) guid = qof_instance_get_guid( inst ); if ( !qof_instance_get_destroying(inst) ) { - is_ok = gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) ); + is_ok = gnc_sql_slots_save( be, guid, is_infant, inst); if ( ! is_ok ) { err = "Slots save failed. Check trace log for SQL errors"; diff --git a/src/backend/sql/gnc-vendor-sql.c b/src/backend/sql/gnc-vendor-sql.c index 94cae4de27..23ede092d9 100644 --- a/src/backend/sql/gnc-vendor-sql.c +++ b/src/backend/sql/gnc-vendor-sql.c @@ -194,7 +194,7 @@ save_vendor( GncSqlBackend* be, QofInstance* inst ) guid = qof_instance_get_guid( inst ); if ( !qof_instance_get_destroying(inst) ) { - is_ok = gnc_sql_slots_save( be, guid, is_infant, qof_instance_get_slots( inst ) ); + is_ok = gnc_sql_slots_save( be, guid, is_infant, inst); } else { From 13377f56d5f2c4eb26cb1f6ad0a22bb5dd98b7f3 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Sat, 13 Jun 2015 15:33:03 -0700 Subject: [PATCH 35/54] Cpp files in CMakelists.txt. --- src/backend/sql/CMakeLists.txt | 2 +- src/backend/xml/CMakeLists.txt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/backend/sql/CMakeLists.txt b/src/backend/sql/CMakeLists.txt index 3f463a6337..22381fc486 100644 --- a/src/backend/sql/CMakeLists.txt +++ b/src/backend/sql/CMakeLists.txt @@ -34,7 +34,7 @@ SET (libgnc_backend_sql_SOURCES gnc-price-sql.c gnc-recurrence-sql.c gnc-schedxaction-sql.c - gnc-slots-sql.c + gnc-slots-sql.cpp gnc-tax-table-sql.c gnc-transaction-sql.c gnc-vendor-sql.c diff --git a/src/backend/xml/CMakeLists.txt b/src/backend/xml/CMakeLists.txt index fec23e249f..26158ad673 100644 --- a/src/backend/xml/CMakeLists.txt +++ b/src/backend/xml/CMakeLists.txt @@ -49,8 +49,8 @@ SET (libgnc_backend_xml_SOURCES io-gncxml-v1.c io-gncxml-v2.c io-utils.c - sixtp-dom-generators.c - sixtp-dom-parsers.c + sixtp-dom-generators.cpp + sixtp-dom-parsers.cpp sixtp-stack.c sixtp-to-dom-parser.c sixtp-utils.c From 435aef03b7a4f057abffb60578ff5ecfeff0fac4 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Sat, 13 Jun 2015 17:28:11 -0700 Subject: [PATCH 36/54] Isolate direct KVP operations. Into sixtp-dom-parser, sixtp-dom-generator, and gnc-slots-sql. The XML V1 file io-gncxml-v1.c is not yet done. --- src/backend/xml/gnc-account-xml-v2.c | 21 +++----------- src/backend/xml/gnc-address-xml-v2.c | 21 +++----------- src/backend/xml/gnc-bill-term-xml-v2.c | 12 ++++---- src/backend/xml/gnc-book-xml-v2.c | 32 +++++++++------------ src/backend/xml/gnc-budget-xml-v2.c | 15 +++------- src/backend/xml/gnc-commodity-xml-v2.c | 14 ++++----- src/backend/xml/gnc-customer-xml-v2.c | 11 ++++--- src/backend/xml/gnc-employee-xml-v2.c | 12 ++++---- src/backend/xml/gnc-entry-xml-v2.c | 20 +++---------- src/backend/xml/gnc-invoice-xml-v2.c | 21 +++----------- src/backend/xml/gnc-job-xml-v2.c | 19 +++--------- src/backend/xml/gnc-lot-xml-v2.c | 19 +++--------- src/backend/xml/gnc-order-xml-v2.c | 19 +++--------- src/backend/xml/gnc-schedxaction-xml-v2.c | 16 +++-------- src/backend/xml/gnc-tax-table-xml-v2.c | 20 +++---------- src/backend/xml/gnc-transaction-xml-v2.c | 32 ++++++--------------- src/backend/xml/gnc-vendor-xml-v2.c | 12 ++++---- src/backend/xml/sixtp-dom-generators.cpp | 8 +++--- src/backend/xml/sixtp-dom-generators.h | 3 +- src/backend/xml/sixtp-dom-parsers.cpp | 35 ++++++++++++++++------- src/backend/xml/sixtp-dom-parsers.h | 16 +---------- src/backend/xml/test/test-file-stuff.c | 2 ++ src/backend/xml/test/test-kvp-frames.c | 14 ++++----- src/engine/SchedXaction.h | 2 -- 24 files changed, 128 insertions(+), 268 deletions(-) diff --git a/src/backend/xml/gnc-account-xml-v2.c b/src/backend/xml/gnc-account-xml-v2.c index 9d31027796..25f6f1e9a4 100644 --- a/src/backend/xml/gnc-account-xml-v2.c +++ b/src/backend/xml/gnc-account-xml-v2.c @@ -71,16 +71,12 @@ const gchar *account_version_string = "2.0.0"; #define act_hidden_string "act:hidden" #define act_placeholder_string "act:placeholder" -/* EFFECTIVE FRIEND FUNCTION */ -extern KvpFrame *qof_instance_get_slots (const QofInstance *); - xmlNodePtr gnc_account_dom_tree_create(Account *act, gboolean exporting, gboolean allow_incompat) { const char *str; - KvpFrame *kf; xmlNodePtr ret; GList *lots, *n; Account *parent; @@ -137,16 +133,9 @@ gnc_account_dom_tree_create(Account *act, xmlAddChild(ret, text_to_dom_tree(act_description_string, str)); } - kf = qof_instance_get_slots (QOF_INSTANCE (act)); - if (kf) - { - xmlNodePtr kvpnode = kvp_frame_to_dom_tree(act_slots_string, kf); - if (kvpnode) - { - xmlAddChild(ret, kvpnode); - } - } - + /* xmlAddChild won't do anything with a NULL, so tests are superfluous. */ + xmlAddChild(ret, qof_instance_slots_to_dom_tree(act_slots_string, + QOF_INSTANCE(act))); parent = gnc_account_get_parent(act); if (parent) { @@ -371,9 +360,7 @@ static gboolean account_slots_handler (xmlNodePtr node, gpointer act_pdata) { struct account_pdata *pdata = act_pdata; - - return dom_tree_to_kvp_frame_given - (node, qof_instance_get_slots (QOF_INSTANCE (pdata->account))); + return dom_tree_create_instance_slots (node, QOF_INSTANCE (pdata->account)); } static gboolean diff --git a/src/backend/xml/gnc-address-xml-v2.c b/src/backend/xml/gnc-address-xml-v2.c index 75cf60da45..40eb1129a6 100644 --- a/src/backend/xml/gnc-address-xml-v2.c +++ b/src/backend/xml/gnc-address-xml-v2.c @@ -58,9 +58,6 @@ const gchar *address_version_string = "2.0.0"; #define addr_email_string "addr:email" #define addr_slots_string "addr:slots" -/* EFFECTIVE FRIEND FUNCTION */ -extern KvpFrame *qof_instance_get_slots (const QofInstance*); - static void maybe_add_string (xmlNodePtr ptr, const char *tag, const char *str) { @@ -72,7 +69,6 @@ xmlNodePtr gnc_address_to_dom_tree (const char *tag, GncAddress *addr) { xmlNodePtr ret; - KvpFrame *kf; ret = xmlNewNode(NULL, BAD_CAST tag); xmlSetProp(ret, BAD_CAST "version", BAD_CAST address_version_string); @@ -88,16 +84,9 @@ gnc_address_to_dom_tree (const char *tag, GncAddress *addr) maybe_add_string (ret, addr_fax_string, gncAddressGetFax (addr)); maybe_add_string (ret, addr_email_string, gncAddressGetEmail (addr)); - kf = qof_instance_get_slots (QOF_INSTANCE(addr)); - if (kf) - { - xmlNodePtr kvpnode = kvp_frame_to_dom_tree(addr_slots_string, kf); - if (kvpnode) - { - xmlAddChild(ret, kvpnode); - } - } - + /* xmlAddChild won't do anything with a NULL, so tests are superfluous. */ + xmlAddChild(ret, qof_instance_slots_to_dom_tree(addr_slots_string, + QOF_INSTANCE(addr))); return ret; } @@ -190,9 +179,7 @@ static gboolean address_slots_handler (xmlNodePtr node, gpointer addr_pdata) { struct address_pdata *pdata = addr_pdata; - - return dom_tree_to_kvp_frame_given - (node, qof_instance_get_slots (QOF_INSTANCE (pdata->address))); + return dom_tree_create_instance_slots (node, QOF_INSTANCE (pdata->address)); } static struct dom_tree_handler address_handlers_v2[] = diff --git a/src/backend/xml/gnc-bill-term-xml-v2.c b/src/backend/xml/gnc-bill-term-xml-v2.c index fa4d421a47..6e04d680d9 100644 --- a/src/backend/xml/gnc-bill-term-xml-v2.c +++ b/src/backend/xml/gnc-bill-term-xml-v2.c @@ -79,7 +79,7 @@ const gchar *billterm_version_string = "2.0.0"; static xmlNodePtr billterm_dom_tree_create (GncBillTerm *term) { - xmlNodePtr ret, data, kvpnode; + xmlNodePtr ret, data; ret = xmlNewNode(NULL, BAD_CAST gnc_billterm_string); xmlSetProp(ret, BAD_CAST "version", BAD_CAST billterm_version_string); @@ -95,10 +95,9 @@ billterm_dom_tree_create (GncBillTerm *term) xmlAddChild(ret, int_to_dom_tree (billterm_invisible_string, gncBillTermGetInvisible (term))); - kvpnode = kvp_frame_to_dom_tree (billterm_slots_string, - qof_instance_get_slots (QOF_INSTANCE(term))); - if (kvpnode) xmlAddChild (ret, kvpnode); - + /* xmlAddChild won't do anything with a NULL, so tests are superfluous. */ + xmlAddChild(ret, qof_instance_slots_to_dom_tree(billterm_slots_string, + QOF_INSTANCE(term))); /* We should not be our own child */ if (gncBillTermGetChild(term) != term) @@ -401,8 +400,7 @@ static gboolean billterm_slots_handler (xmlNodePtr node, gpointer billterm_pdata) { struct billterm_pdata *pdata = billterm_pdata; - return dom_tree_to_kvp_frame_given (node, - qof_instance_get_slots (QOF_INSTANCE(pdata->term))); + return dom_tree_create_instance_slots (node, QOF_INSTANCE(pdata->term)); } static struct dom_tree_handler billterm_handlers_v2[] = diff --git a/src/backend/xml/gnc-book-xml-v2.c b/src/backend/xml/gnc-book-xml-v2.c index 6fcae46dc2..851aefa9b9 100644 --- a/src/backend/xml/gnc-book-xml-v2.c +++ b/src/backend/xml/gnc-book-xml-v2.c @@ -109,13 +109,9 @@ gnc_book_dom_tree_create(QofBook *book) xmlAddChild(ret, guid_to_dom_tree(book_id_string, qof_book_get_guid(book))); - if (qof_instance_get_slots (QOF_INSTANCE (book))) - { - xmlNodePtr kvpnode = kvp_frame_to_dom_tree(book_slots_string, - qof_instance_get_slots (QOF_INSTANCE (book))); - if (kvpnode) - xmlAddChild(ret, kvpnode); - } + /* xmlAddChild won't do anything with a NULL, so tests are superfluous. */ + xmlAddChild(ret, qof_instance_slots_to_dom_tree(book_slots_string, + QOF_INSTANCE(book))); #ifdef IMPLEMENT_BOOK_DOM_TREES_LATER /* theoretically, we should be adding all the below to the book @@ -153,7 +149,7 @@ gnc_book_dom_tree_create(QofBook *book) gboolean write_book_parts(FILE *out, QofBook *book) { - xmlNodePtr domnode; + xmlNodePtr domnode, slotsnode; domnode = guid_to_dom_tree(book_id_string, qof_book_get_guid(book)); xmlElemDump(out, NULL, domnode); @@ -162,18 +158,16 @@ write_book_parts(FILE *out, QofBook *book) if (ferror(out) || fprintf(out, "\n") < 0) return FALSE; - if (qof_instance_get_slots (QOF_INSTANCE (book))) + + slotsnode = qof_instance_slots_to_dom_tree(book_slots_string, + QOF_INSTANCE(book)); + if (slotsnode) { - xmlNodePtr kvpnode = kvp_frame_to_dom_tree(book_slots_string, - qof_instance_get_slots (QOF_INSTANCE (book))); - if (kvpnode) - { - xmlElemDump(out, NULL, kvpnode); - xmlFreeNode(kvpnode); + xmlElemDump(out, NULL, slotsnode); + xmlFreeNode(slotsnode); - if (ferror(out) || fprintf(out, "\n") < 0) - return FALSE; - } + if (ferror(out) || fprintf(out, "\n") < 0) + return FALSE; } return TRUE; @@ -203,7 +197,7 @@ book_slots_handler (xmlNodePtr node, gpointer book_pdata) /* the below works only because the get is gaurenteed to return * a frame, even if its empty */ - success = dom_tree_to_kvp_frame_given (node, qof_instance_get_slots (QOF_INSTANCE (book))); + success = dom_tree_create_instance_slots(node, QOF_INSTANCE (book)); g_return_val_if_fail(success, FALSE); diff --git a/src/backend/xml/gnc-budget-xml-v2.c b/src/backend/xml/gnc-budget-xml-v2.c index 13ada1e864..07aadaec51 100644 --- a/src/backend/xml/gnc-budget-xml-v2.c +++ b/src/backend/xml/gnc-budget-xml-v2.c @@ -57,7 +57,6 @@ xmlNodePtr gnc_budget_dom_tree_create(GncBudget *bgt) { xmlNodePtr ret; - KvpFrame *kf; ENTER ("(budget=%p)", bgt); @@ -79,14 +78,9 @@ gnc_budget_dom_tree_create(GncBudget *bgt) /* field: Recurrence* */ xmlAddChild(ret, recurrence_to_dom_tree(bgt_recurrence_string, gnc_budget_get_recurrence(bgt))); - /* slots */ - kf = qof_instance_get_slots(QOF_INSTANCE(bgt)); - if (kf) - { - xmlNodePtr kvpnode = kvp_frame_to_dom_tree(bgt_slots_string, kf); - if (kvpnode) - xmlAddChild(ret, kvpnode); - } + /* xmlAddChild won't do anything with a NULL, so tests are superfluous. */ + xmlAddChild(ret, qof_instance_slots_to_dom_tree(bgt_slots_string, + QOF_INSTANCE(bgt))); LEAVE (" "); return ret; @@ -159,8 +153,7 @@ budget_recurrence_handler (xmlNodePtr node, gpointer bgt) static gboolean budget_slots_handler (xmlNodePtr node, gpointer bgt) { - return dom_tree_to_kvp_frame_given( - node, qof_instance_get_slots(QOF_INSTANCE(bgt))); + return dom_tree_create_instance_slots(node, QOF_INSTANCE(bgt)); } static struct dom_tree_handler budget_handlers[] = diff --git a/src/backend/xml/gnc-commodity-xml-v2.c b/src/backend/xml/gnc-commodity-xml-v2.c index eddb392488..1d7206cfc7 100644 --- a/src/backend/xml/gnc-commodity-xml-v2.c +++ b/src/backend/xml/gnc-commodity-xml-v2.c @@ -66,11 +66,10 @@ gnc_commodity_dom_tree_create(const gnc_commodity *com) const char *string; xmlNodePtr ret; gboolean currency = gnc_commodity_is_iso(com); - xmlNodePtr kvpnode = - kvp_frame_to_dom_tree(cmdty_slots, - qof_instance_get_slots(QOF_INSTANCE(com))); + xmlNodePtr slotsnode = + qof_instance_slots_to_dom_tree(cmdty_slots, QOF_INSTANCE(com)); - if (currency && !gnc_commodity_get_quote_flag(com) && !kvpnode) + if (currency && !gnc_commodity_get_quote_flag(com) && !slotsnode) return NULL; ret = xmlNewNode(NULL, BAD_CAST gnc_commodity_string); @@ -114,8 +113,8 @@ gnc_commodity_dom_tree_create(const gnc_commodity *com) xmlAddChild(ret, text_to_dom_tree(cmdty_quote_tz, string)); } - if (kvpnode) - xmlAddChild(ret, kvpnode); + if (slotsnode) + xmlAddChild(ret, slotsnode); return ret; } @@ -172,8 +171,7 @@ set_commodity_value(xmlNodePtr node, gnc_commodity* com) else if (g_strcmp0((char*)node->name, cmdty_slots) == 0) { /* We ignore the results here */ - dom_tree_to_kvp_frame_given(node, - qof_instance_get_slots(QOF_INSTANCE(com))); + dom_tree_create_instance_slots(node, QOF_INSTANCE(com)); } else { diff --git a/src/backend/xml/gnc-customer-xml-v2.c b/src/backend/xml/gnc-customer-xml-v2.c index 890f3e5461..faf8e90c09 100644 --- a/src/backend/xml/gnc-customer-xml-v2.c +++ b/src/backend/xml/gnc-customer-xml-v2.c @@ -77,7 +77,7 @@ const gchar *customer_version_string = "2.0.0"; static xmlNodePtr customer_dom_tree_create (GncCustomer *cust) { - xmlNodePtr ret, kvpnode; + xmlNodePtr ret; gnc_numeric num; GncBillTerm *term; GncTaxTable *taxtable; @@ -132,9 +132,9 @@ customer_dom_tree_create (GncCustomer *cust) xmlAddChild (ret, guid_to_dom_tree (cust_taxtable_string, qof_instance_get_guid(QOF_INSTANCE(taxtable)))); - kvpnode = kvp_frame_to_dom_tree (cust_slots_string, - qof_instance_get_slots (QOF_INSTANCE(cust))); - if (kvpnode) xmlAddChild (ret, kvpnode); + /* xmlAddChild won't do anything with a NULL, so tests are superfluous. */ + xmlAddChild(ret, qof_instance_slots_to_dom_tree(cust_slots_string, + QOF_INSTANCE(cust))); return ret; } @@ -367,8 +367,7 @@ static gboolean customer_slots_handler (xmlNodePtr node, gpointer cust_pdata) { struct customer_pdata *pdata = cust_pdata; - return dom_tree_to_kvp_frame_given (node, - qof_instance_get_slots (QOF_INSTANCE(pdata->customer))); + return dom_tree_create_instance_slots(node, QOF_INSTANCE(pdata->customer)); } static struct dom_tree_handler customer_handlers_v2[] = diff --git a/src/backend/xml/gnc-employee-xml-v2.c b/src/backend/xml/gnc-employee-xml-v2.c index 242a90772e..d7cb7ec1d8 100644 --- a/src/backend/xml/gnc-employee-xml-v2.c +++ b/src/backend/xml/gnc-employee-xml-v2.c @@ -76,7 +76,7 @@ maybe_add_string (xmlNodePtr ptr, const char *tag, const char *str) static xmlNodePtr employee_dom_tree_create (GncEmployee *employee) { - xmlNodePtr ret, kvpnode; + xmlNodePtr ret; gnc_numeric num; Account* ccard_acc; @@ -118,10 +118,9 @@ employee_dom_tree_create (GncEmployee *employee) xmlAddChild(ret, guid_to_dom_tree(employee_ccard_string, qof_instance_get_guid(QOF_INSTANCE(ccard_acc)))); - kvpnode = kvp_frame_to_dom_tree (employee_slots_string, - qof_instance_get_slots (QOF_INSTANCE(employee))); - if (kvpnode) xmlAddChild (ret, kvpnode); - + /* xmlAddChild won't do anything with a NULL, so tests are superfluous. */ + xmlAddChild(ret, qof_instance_slots_to_dom_tree(employee_slots_string, + QOF_INSTANCE(employee))); return ret; } @@ -294,8 +293,7 @@ static gboolean employee_slots_handler (xmlNodePtr node, gpointer employee_pdata) { struct employee_pdata *pdata = employee_pdata; - return dom_tree_to_kvp_frame_given ( - node, qof_instance_get_slots (QOF_INSTANCE(pdata->employee))); + return dom_tree_create_instance_slots (node, QOF_INSTANCE(pdata->employee)); } static struct dom_tree_handler employee_handlers_v2[] = diff --git a/src/backend/xml/gnc-entry-xml-v2.c b/src/backend/xml/gnc-entry-xml-v2.c index 9e35e8141e..a892fb2b92 100644 --- a/src/backend/xml/gnc-entry-xml-v2.c +++ b/src/backend/xml/gnc-entry-xml-v2.c @@ -92,9 +92,6 @@ const gchar *entry_version_string = "2.0.0"; #define entry_bill_string "entry:bill" #define entry_slots_string "entry:slots" -/* EFFECTIVE FRIEND FUNCTION */ -extern KvpFrame *qof_instance_get_slots (const QofInstance*); - static void maybe_add_string (xmlNodePtr ptr, const char *tag, const char *str) { @@ -118,7 +115,6 @@ entry_dom_tree_create (GncEntry *entry) GncTaxTable *taxtable; GncOrder *order; GncInvoice *invoice; - KvpFrame *kf; ret = xmlNewNode(NULL, BAD_CAST gnc_entry_string); xmlSetProp(ret, BAD_CAST "version", BAD_CAST entry_version_string); @@ -215,16 +211,9 @@ entry_dom_tree_create (GncEntry *entry) xmlAddChild (ret, guid_to_dom_tree (entry_order_string, qof_instance_get_guid(QOF_INSTANCE (order)))); - kf = qof_instance_get_slots (QOF_INSTANCE(entry)); - if (kf) - { - xmlNodePtr kvpnode = kvp_frame_to_dom_tree(entry_slots_string, kf); - if (kvpnode) - { - xmlAddChild(ret, kvpnode); - } - } - + /* xmlAddChild won't do anything with a NULL, so tests are superfluous. */ + xmlAddChild(ret, qof_instance_slots_to_dom_tree(entry_slots_string, + QOF_INSTANCE(entry))); return ret; } @@ -677,8 +666,7 @@ entry_slots_handler (xmlNodePtr node, gpointer entry_pdata) { struct entry_pdata *pdata = entry_pdata; - return dom_tree_to_kvp_frame_given - (node, qof_instance_get_slots (QOF_INSTANCE (pdata->entry))); + return dom_tree_create_instance_slots(node, QOF_INSTANCE (pdata->entry)); } static struct dom_tree_handler entry_handlers_v2[] = diff --git a/src/backend/xml/gnc-invoice-xml-v2.c b/src/backend/xml/gnc-invoice-xml-v2.c index 00ad56d1d6..319b2e8c43 100644 --- a/src/backend/xml/gnc-invoice-xml-v2.c +++ b/src/backend/xml/gnc-invoice-xml-v2.c @@ -72,9 +72,6 @@ const gchar *invoice_version_string = "2.0.0"; #define invoice_tochargeamt_string "invoice:charge-amt" #define invoice_slots_string "invoice:slots" -/* EFFECTIVE FRIEND FUNCTION */ -extern KvpFrame *qof_instance_get_slots (const QofInstance *); - static void maybe_add_string (xmlNodePtr ptr, const char *tag, const char *str) { @@ -93,7 +90,6 @@ static xmlNodePtr invoice_dom_tree_create (GncInvoice *invoice) { xmlNodePtr ret; - KvpFrame *kf; Timespec ts; Transaction *txn; GNCLot *lot; @@ -160,16 +156,9 @@ invoice_dom_tree_create (GncInvoice *invoice) if (! gnc_numeric_zero_p (amt)) xmlAddChild (ret, gnc_numeric_to_dom_tree (invoice_tochargeamt_string, &amt)); - kf = qof_instance_get_slots (QOF_INSTANCE(invoice)); - if (kf) - { - xmlNodePtr kvpnode = kvp_frame_to_dom_tree(invoice_slots_string, kf); - if (kvpnode) - { - xmlAddChild(ret, kvpnode); - } - } - + /* xmlAddChild won't do anything with a NULL, so tests are superfluous. */ + xmlAddChild(ret, qof_instance_slots_to_dom_tree(invoice_slots_string, + QOF_INSTANCE(invoice))); return ret; } @@ -411,9 +400,7 @@ static gboolean invoice_slots_handler (xmlNodePtr node, gpointer invoice_pdata) { struct invoice_pdata *pdata = invoice_pdata; - - return dom_tree_to_kvp_frame_given - (node, qof_instance_get_slots (QOF_INSTANCE (pdata->invoice))); + return dom_tree_create_instance_slots (node, QOF_INSTANCE (pdata->invoice)); } static struct dom_tree_handler invoice_handlers_v2[] = diff --git a/src/backend/xml/gnc-job-xml-v2.c b/src/backend/xml/gnc-job-xml-v2.c index 59f450750c..72b86a9585 100644 --- a/src/backend/xml/gnc-job-xml-v2.c +++ b/src/backend/xml/gnc-job-xml-v2.c @@ -62,14 +62,10 @@ const gchar *job_version_string = "2.0.0"; #define job_active_string "job:active" #define job_slots_string "job:slots" -/* EFFECTIVE FRIEND FUNCTION */ -extern KvpFrame *qof_instance_get_slots (const QofInstance*); - static xmlNodePtr job_dom_tree_create (GncJob *job) { xmlNodePtr ret; - KvpFrame *kf; ret = xmlNewNode(NULL, BAD_CAST gnc_job_string); xmlSetProp(ret, BAD_CAST "version", BAD_CAST job_version_string); @@ -91,15 +87,9 @@ job_dom_tree_create (GncJob *job) xmlAddChild(ret, int_to_dom_tree(job_active_string, gncJobGetActive (job))); - kf = qof_instance_get_slots (QOF_INSTANCE(job)); - if (kf) - { - xmlNodePtr kvpnode = kvp_frame_to_dom_tree(job_slots_string, kf); - if (kvpnode) - { - xmlAddChild(ret, kvpnode); - } - } + /* xmlAddChild won't do anything with a NULL, so tests are superfluous. */ + xmlAddChild(ret, qof_instance_slots_to_dom_tree(job_slots_string, + QOF_INSTANCE(job))); return ret; } @@ -209,8 +199,7 @@ job_slots_handler (xmlNodePtr node, gpointer job_pdata) { struct job_pdata *pdata = job_pdata; - return dom_tree_to_kvp_frame_given - (node, qof_instance_get_slots (QOF_INSTANCE (pdata->job))); + return dom_tree_create_instance_slots (node, QOF_INSTANCE (pdata->job)); } static struct dom_tree_handler job_handlers_v2[] = diff --git a/src/backend/xml/gnc-lot-xml-v2.c b/src/backend/xml/gnc-lot-xml-v2.c index afe681afa5..40eaf373ef 100644 --- a/src/backend/xml/gnc-lot-xml-v2.c +++ b/src/backend/xml/gnc-lot-xml-v2.c @@ -53,30 +53,20 @@ const gchar *lot_version_string = "2.0.0"; #define gnc_lot_string "gnc:lot" #define lot_id_string "lot:id" #define lot_slots_string "lot:slots" -/* EFFECTIVE FRIEND FUNCTION */ -extern KvpFrame *qof_instance_get_slots (const QofInstance *); xmlNodePtr gnc_lot_dom_tree_create(GNCLot *lot) { xmlNodePtr ret; - KvpFrame *kf; ENTER("(lot=%p)", lot); ret = xmlNewNode(NULL, BAD_CAST gnc_lot_string); xmlSetProp(ret, BAD_CAST "version", BAD_CAST lot_version_string); xmlAddChild(ret, guid_to_dom_tree(lot_id_string, gnc_lot_get_guid(lot))); - - kf = qof_instance_get_slots (QOF_INSTANCE (lot)); - if (kf) - { - xmlNodePtr kvpnode = kvp_frame_to_dom_tree(lot_slots_string, kf); - if (kvpnode) - { - xmlAddChild(ret, kvpnode); - } - } + /* xmlAddChild won't do anything with a NULL, so tests are superfluous. */ + xmlAddChild(ret, qof_instance_slots_to_dom_tree(lot_slots_string, + QOF_INSTANCE(lot))); LEAVE(""); return ret; @@ -113,8 +103,7 @@ lot_slots_handler (xmlNodePtr node, gpointer p) gboolean success; ENTER("(lot=%p)", pdata->lot); - success = dom_tree_to_kvp_frame_given - (node, qof_instance_get_slots (QOF_INSTANCE (pdata->lot))); + success = dom_tree_create_instance_slots(node, QOF_INSTANCE (pdata->lot)); LEAVE(""); g_return_val_if_fail(success, FALSE); diff --git a/src/backend/xml/gnc-order-xml-v2.c b/src/backend/xml/gnc-order-xml-v2.c index 40fb6777e8..0adb39b31a 100644 --- a/src/backend/xml/gnc-order-xml-v2.c +++ b/src/backend/xml/gnc-order-xml-v2.c @@ -64,9 +64,6 @@ const gchar *order_version_string = "2.0.0"; #define order_active_string "order:active" #define order_slots_string "order:slots" -/* EFFECTIVE FRIEND FUNCTION */ -extern KvpFrame *qof_instance_get_slots (const QofInstance*); - static void maybe_add_string (xmlNodePtr ptr, const char *tag, const char *str) { @@ -79,7 +76,6 @@ order_dom_tree_create (GncOrder *order) { xmlNodePtr ret; Timespec ts; - KvpFrame *kf; ret = xmlNewNode(NULL, BAD_CAST gnc_order_string); xmlSetProp(ret, BAD_CAST "version", BAD_CAST order_version_string); @@ -106,15 +102,9 @@ order_dom_tree_create (GncOrder *order) xmlAddChild(ret, int_to_dom_tree(order_active_string, gncOrderGetActive (order))); - kf = qof_instance_get_slots (QOF_INSTANCE(order)); - if (kf) - { - xmlNodePtr kvpnode = kvp_frame_to_dom_tree(order_slots_string, kf); - if (kvpnode) - { - xmlAddChild(ret, kvpnode); - } - } + /* xmlAddChild won't do anything with a NULL, so tests are superfluous. */ + xmlAddChild(ret, qof_instance_slots_to_dom_tree(order_slots_string, + QOF_INSTANCE(order))); return ret; } @@ -250,8 +240,7 @@ order_slots_handler (xmlNodePtr node, gpointer order_pdata) { struct order_pdata *pdata = order_pdata; - return dom_tree_to_kvp_frame_given - (node, qof_instance_get_slots (QOF_INSTANCE (pdata->order))); + return dom_tree_create_instance_slots(node, QOF_INSTANCE (pdata->order)); } static struct dom_tree_handler order_handlers_v2[] = diff --git a/src/backend/xml/gnc-schedxaction-xml-v2.c b/src/backend/xml/gnc-schedxaction-xml-v2.c index 2fd90caaa7..46aa1502d5 100644 --- a/src/backend/xml/gnc-schedxaction-xml-v2.c +++ b/src/backend/xml/gnc-schedxaction-xml-v2.c @@ -190,17 +190,9 @@ gnc_schedXaction_dom_tree_create(SchedXaction *sx) } } - /* output kvp_frame */ - { - xmlNodePtr kvpnode = - kvp_frame_to_dom_tree( SX_SLOTS, - xaccSchedXactionGetSlots(sx) ); - if ( kvpnode ) - { - xmlAddChild(ret, kvpnode); - } - } - + /* xmlAddChild won't do anything with a NULL, so tests are superfluous. */ + xmlAddChild(ret, qof_instance_slots_to_dom_tree(SX_SLOTS, + QOF_INSTANCE(sx))); return ret; } @@ -629,7 +621,7 @@ sx_slots_handler( xmlNodePtr node, gpointer sx_pdata ) struct sx_pdata *pdata = sx_pdata; SchedXaction *sx = pdata->sx; - return dom_tree_to_kvp_frame_given( node, xaccSchedXactionGetSlots (sx) ); + return dom_tree_create_instance_slots(node, QOF_INSTANCE(sx)); } struct dom_tree_handler sx_dom_handlers[] = diff --git a/src/backend/xml/gnc-tax-table-xml-v2.c b/src/backend/xml/gnc-tax-table-xml-v2.c index dda332ccab..2a7daa64dc 100644 --- a/src/backend/xml/gnc-tax-table-xml-v2.c +++ b/src/backend/xml/gnc-tax-table-xml-v2.c @@ -67,9 +67,6 @@ const gchar *taxtable_version_string = "2.0.0"; #define ttentry_type_string "tte:type" #define ttentry_amount_string "tte:amount" -/* EFFECTIVE FRIEND FUNCTION */ -extern KvpFrame *qof_instance_get_slots (const QofInstance*); - static void maybe_add_guid (xmlNodePtr ptr, const char *tag, GncTaxTable *table) { @@ -107,7 +104,6 @@ taxtable_dom_tree_create (GncTaxTable *table) { xmlNodePtr ret, entries; GList *list; - KvpFrame *kf; ret = xmlNewNode(NULL, BAD_CAST gnc_taxtable_string); xmlSetProp(ret, BAD_CAST "version", BAD_CAST taxtable_version_string); @@ -134,16 +130,9 @@ taxtable_dom_tree_create (GncTaxTable *table) xmlAddChild(entries, ttentry_dom_tree_create (entry)); } - kf = qof_instance_get_slots (QOF_INSTANCE(table)); - if (kf) - { - xmlNodePtr kvpnode = kvp_frame_to_dom_tree(taxtable_slots_string, kf); - if (kvpnode) - { - xmlAddChild(ret, kvpnode); - } - } - + /* xmlAddChild won't do anything with a NULL, so tests are superfluous. */ + xmlAddChild(ret, qof_instance_slots_to_dom_tree(taxtable_slots_string, + QOF_INSTANCE(table))); return ret; } @@ -384,8 +373,7 @@ taxtable_slots_handler (xmlNodePtr node, gpointer taxtable_pdata) { struct taxtable_pdata *pdata = taxtable_pdata; - return dom_tree_to_kvp_frame_given - (node, qof_instance_get_slots (QOF_INSTANCE (pdata->table))); + return dom_tree_create_instance_slots(node, QOF_INSTANCE (pdata->table)); } static struct dom_tree_handler taxtable_handlers_v2[] = diff --git a/src/backend/xml/gnc-transaction-xml-v2.c b/src/backend/xml/gnc-transaction-xml-v2.c index a2a3513156..40f871c6cf 100644 --- a/src/backend/xml/gnc-transaction-xml-v2.c +++ b/src/backend/xml/gnc-transaction-xml-v2.c @@ -49,9 +49,6 @@ const gchar *transaction_version_string = "2.0.0"; -/* EFFECTIVE FRIEND FUNCTION */ -extern KvpFrame *qof_instance_get_slots (const QofInstance *); - static void add_gnc_num(xmlNodePtr node, const gchar *tag, gnc_numeric num) { @@ -130,15 +127,9 @@ split_to_dom_tree(const gchar *tag, Split *spl) gnc_lot_get_guid(lot))); } } - { - xmlNodePtr kvpnode = kvp_frame_to_dom_tree("split:slots", - qof_instance_get_slots (QOF_INSTANCE (spl))); - if (kvpnode) - { - xmlAddChild(ret, kvpnode); - } - } - + /* xmlAddChild won't do anything with a NULL, so tests are superfluous. */ + xmlAddChild(ret, qof_instance_slots_to_dom_tree("split:slots", + QOF_INSTANCE(spl))); return ret; } @@ -193,14 +184,9 @@ gnc_transaction_dom_tree_create(Transaction *trn) } g_free (str); - { - xmlNodePtr kvpnode = kvp_frame_to_dom_tree("trn:slots", - qof_instance_get_slots (QOF_INSTANCE (trn))); - if (kvpnode) - { - xmlAddChild(ret, kvpnode); - } - } + /* xmlAddChild won't do anything with a NULL, so tests are superfluous. */ + xmlAddChild(ret, qof_instance_slots_to_dom_tree("trn:slots", + QOF_INSTANCE(trn))); add_trans_splits(ret, trn); @@ -370,8 +356,8 @@ spl_slots_handler(xmlNodePtr node, gpointer data) struct split_pdata *pdata = data; gboolean successful; - successful = dom_tree_to_kvp_frame_given(node, - qof_instance_get_slots (QOF_INSTANCE (pdata->split))); + successful = dom_tree_create_instance_slots(node, + QOF_INSTANCE (pdata->split)); g_return_val_if_fail(successful, FALSE); return TRUE; @@ -530,7 +516,7 @@ trn_slots_handler(xmlNodePtr node, gpointer trans_pdata) Transaction *trn = pdata->trans; gboolean successful; - successful = dom_tree_to_kvp_frame_given(node, qof_instance_get_slots (QOF_INSTANCE (trn))); + successful = dom_tree_create_instance_slots(node, QOF_INSTANCE (trn)); g_return_val_if_fail(successful, FALSE); diff --git a/src/backend/xml/gnc-vendor-xml-v2.c b/src/backend/xml/gnc-vendor-xml-v2.c index e54efb99ef..5ab47f10a7 100644 --- a/src/backend/xml/gnc-vendor-xml-v2.c +++ b/src/backend/xml/gnc-vendor-xml-v2.c @@ -73,7 +73,7 @@ const gchar *vendor_version_string = "2.0.0"; static xmlNodePtr vendor_dom_tree_create (GncVendor *vendor) { - xmlNodePtr ret, kvpnode; + xmlNodePtr ret; GncBillTerm *term; GncTaxTable *taxtable; @@ -118,10 +118,9 @@ vendor_dom_tree_create (GncVendor *vendor) xmlAddChild (ret, guid_to_dom_tree (vendor_taxtable_string, qof_instance_get_guid(QOF_INSTANCE(taxtable)))); - kvpnode = kvp_frame_to_dom_tree (vendor_slots_string, - qof_instance_get_slots (QOF_INSTANCE(vendor))); - if (kvpnode) xmlAddChild (ret, kvpnode); - + /* xmlAddChild won't do anything with a NULL, so tests are superfluous. */ + xmlAddChild(ret, qof_instance_slots_to_dom_tree(vendor_slots_string, + QOF_INSTANCE(vendor))); return ret; } @@ -313,8 +312,7 @@ static gboolean vendor_slots_handler (xmlNodePtr node, gpointer vendor_pdata) { struct vendor_pdata *pdata = vendor_pdata; - return dom_tree_to_kvp_frame_given ( - node, qof_instance_get_slots (QOF_INSTANCE(pdata->vendor))); + return dom_tree_create_instance_slots(node, QOF_INSTANCE(pdata->vendor)); } diff --git a/src/backend/xml/sixtp-dom-generators.cpp b/src/backend/xml/sixtp-dom-generators.cpp index 665aebddaf..8160ad4365 100644 --- a/src/backend/xml/sixtp-dom-generators.cpp +++ b/src/backend/xml/sixtp-dom-generators.cpp @@ -365,18 +365,18 @@ add_kvp_slot(const char * key, KvpValue* value, xmlNodePtr node) } xmlNodePtr -kvp_frame_to_dom_tree(const char *tag, const KvpFrame *frame) +qof_instance_slots_to_dom_tree(const char *tag, const QofInstance* inst) { xmlNodePtr ret; const char ** keys; unsigned int i; - + KvpFrame *frame = qof_instance_get_slots(QOF_INSTANCE (inst)); if (!frame) { - return NULL; + return nullptr; } - ret = xmlNewNode(NULL, BAD_CAST tag); + ret = xmlNewNode(nullptr, BAD_CAST tag); keys = kvp_frame_get_keys(frame); for (i = 0; keys[i]; ++i) diff --git a/src/backend/xml/sixtp-dom-generators.h b/src/backend/xml/sixtp-dom-generators.h index 09b14b5b7c..18b5ff2b17 100644 --- a/src/backend/xml/sixtp-dom-generators.h +++ b/src/backend/xml/sixtp-dom-generators.h @@ -47,7 +47,8 @@ gchar * timespec_nsec_to_string(const Timespec *ts); gchar * timespec_sec_to_string(const Timespec *ts); xmlNodePtr gdate_to_dom_tree(const char *tag, const GDate *spec); xmlNodePtr gnc_numeric_to_dom_tree(const char *tag, const gnc_numeric *num); -xmlNodePtr kvp_frame_to_dom_tree(const char *tag, const KvpFrame *frame); +xmlNodePtr qof_instance_slots_to_dom_tree(const char *tag, + const QofInstance *inst); xmlNodePtr guint_to_dom_tree(const char *tag, guint an_int); xmlNodePtr recurrence_to_dom_tree(const gchar *tag, const Recurrence *r); diff --git a/src/backend/xml/sixtp-dom-parsers.cpp b/src/backend/xml/sixtp-dom-parsers.cpp index aa001655b2..f95059ee73 100644 --- a/src/backend/xml/sixtp-dom-parsers.cpp +++ b/src/backend/xml/sixtp-dom-parsers.cpp @@ -79,7 +79,7 @@ dom_tree_to_guid(xmlNodePtr node) } } -KvpValue* +static KvpValue* dom_tree_to_integer_kvp_value(xmlNodePtr node) { gchar *text; @@ -162,7 +162,7 @@ dom_tree_to_boolean(xmlNodePtr node, gboolean* b) } } -KvpValue* +static KvpValue* dom_tree_to_double_kvp_value(xmlNodePtr node) { gchar *text; @@ -181,7 +181,7 @@ dom_tree_to_double_kvp_value(xmlNodePtr node) return ret; } -KvpValue* +static KvpValue* dom_tree_to_numeric_kvp_value(xmlNodePtr node) { gnc_numeric *danum; @@ -199,7 +199,7 @@ dom_tree_to_numeric_kvp_value(xmlNodePtr node) return ret; } -KvpValue* +static KvpValue* dom_tree_to_string_kvp_value(xmlNodePtr node) { gchar *datext; @@ -216,7 +216,7 @@ dom_tree_to_string_kvp_value(xmlNodePtr node) return ret; } -KvpValue* +static KvpValue* dom_tree_to_guid_kvp_value(xmlNodePtr node) { GncGUID *daguid; @@ -233,7 +233,7 @@ dom_tree_to_guid_kvp_value(xmlNodePtr node) return ret; } -KvpValue* +static KvpValue* dom_tree_to_timespec_kvp_value (xmlNodePtr node) { Timespec ts; @@ -247,7 +247,7 @@ dom_tree_to_timespec_kvp_value (xmlNodePtr node) return ret; } -KvpValue* +static KvpValue* dom_tree_to_gdate_kvp_value (xmlNodePtr node) { GDate *date; @@ -304,7 +304,14 @@ string_to_binary(const gchar *str, void **v, guint64 *data_len) return(TRUE); } -KvpValue* +static KvpValue* dom_tree_to_kvp_value(xmlNodePtr node); +//needed for test access as well as internal use. +extern "C" +{ + KvpFrame* dom_tree_to_kvp_frame(xmlNodePtr node); +} + +static KvpValue* dom_tree_to_list_kvp_value(xmlNodePtr node) { GList *list = NULL; @@ -330,7 +337,7 @@ dom_tree_to_list_kvp_value(xmlNodePtr node) return ret; } -KvpValue* +static KvpValue* dom_tree_to_frame_kvp_value(xmlNodePtr node) { KvpFrame *frame; @@ -369,7 +376,7 @@ struct kvp_val_converter val_converters[] = { 0, 0 }, }; -KvpValue* +static KvpValue* dom_tree_to_kvp_value(xmlNodePtr node) { xmlChar *xml_type; @@ -404,7 +411,7 @@ dom_tree_to_kvp_value(xmlNodePtr node) return ret; } -gboolean +static gboolean dom_tree_to_kvp_frame_given(xmlNodePtr node, KvpFrame *frame) { xmlNodePtr mark; @@ -473,6 +480,12 @@ dom_tree_to_kvp_frame(xmlNodePtr node) return NULL; } +gboolean +dom_tree_create_instance_slots(xmlNodePtr node, QofInstance *inst) +{ + KvpFrame *frame = qof_instance_get_slots(inst); + return dom_tree_to_kvp_frame_given(node, frame); +} gchar * dom_tree_to_text(xmlNodePtr tree) diff --git a/src/backend/xml/sixtp-dom-parsers.h b/src/backend/xml/sixtp-dom-parsers.h index efae18ae2f..f96db25337 100644 --- a/src/backend/xml/sixtp-dom-parsers.h +++ b/src/backend/xml/sixtp-dom-parsers.h @@ -50,21 +50,7 @@ GDate* dom_tree_to_gdate(xmlNodePtr node); gnc_numeric* dom_tree_to_gnc_numeric(xmlNodePtr node); gchar * dom_tree_to_text(xmlNodePtr tree); gboolean string_to_binary(const gchar *str, void **v, guint64 *data_len); - -gboolean dom_tree_to_kvp_frame_given(xmlNodePtr node, KvpFrame *frame); - -KvpFrame* dom_tree_to_kvp_frame(xmlNodePtr node); -KvpValue* dom_tree_to_kvp_value(xmlNodePtr node); -KvpValue* dom_tree_to_integer_kvp_value(xmlNodePtr node); -KvpValue* dom_tree_to_double_kvp_value(xmlNodePtr node); -KvpValue* dom_tree_to_numeric_kvp_value(xmlNodePtr node); -KvpValue* dom_tree_to_string_kvp_value(xmlNodePtr node); -KvpValue* dom_tree_to_guid_kvp_value(xmlNodePtr node); -KvpValue* dom_tree_to_timespec_kvp_value(xmlNodePtr node); -KvpValue* dom_tree_to_binary_kvp_value(xmlNodePtr node); -KvpValue* dom_tree_to_list_kvp_value(xmlNodePtr node); -KvpValue* dom_tree_to_frame_kvp_value(xmlNodePtr node); -KvpValue* dom_tree_to_gdate_kvp_value (xmlNodePtr node); +gboolean dom_tree_create_instance_slots(xmlNodePtr node, QofInstance *inst); gboolean dom_tree_to_integer(xmlNodePtr node, gint64 *daint); gboolean dom_tree_to_guint16(xmlNodePtr node, guint16 *i); diff --git a/src/backend/xml/test/test-file-stuff.c b/src/backend/xml/test/test-file-stuff.c index 2385d385fb..c763275f91 100644 --- a/src/backend/xml/test/test-file-stuff.c +++ b/src/backend/xml/test/test-file-stuff.c @@ -46,6 +46,8 @@ */ /***********************************************************************/ +extern KvpFrame* dom_tree_to_kvp_frame(xmlNodePtr node); + static int files_return(int ret, const char* msg) { diff --git a/src/backend/xml/test/test-kvp-frames.c b/src/backend/xml/test/test-kvp-frames.c index ac2825b98a..09a58906ae 100644 --- a/src/backend/xml/test/test-kvp-frames.c +++ b/src/backend/xml/test/test-kvp-frames.c @@ -13,6 +13,7 @@ #define GNC_V2_STRING "gnc-v2" const gchar *gnc_v2_xml_version_string = GNC_V2_STRING; +extern KvpFrame* dom_tree_to_kvp_frame(xmlNodePtr node); static void test_kvp_get_slot(int run, @@ -171,13 +172,13 @@ test_kvp_xml_stuff(void) int i; for (i = 0; i < 20; i++) { - KvpFrame *test_frame1; + QofInstance *inst = g_object_new (QOF_TYPE_INSTANCE, NULL); KvpFrame *test_frame2; xmlNodePtr test_node; - test_frame1 = get_random_kvp_frame(); + inst->kvp_data = get_random_kvp_frame(); - test_node = kvp_frame_to_dom_tree("test-kvp", test_frame1); + test_node = qof_instance_slots_to_dom_tree("test-kvp", inst); if (!test_node) { @@ -188,7 +189,7 @@ test_kvp_xml_stuff(void) { test_frame2 = dom_tree_to_kvp_frame(test_node); - if (kvp_frame_compare(test_frame1, test_frame2) == 0) + if (kvp_frame_compare(inst->kvp_data, test_frame2) == 0) { success("xml stuff"); } @@ -196,7 +197,7 @@ test_kvp_xml_stuff(void) { gchar *tmp; failure("xml stuff"); - tmp = kvp_frame_to_string(test_frame1); + tmp = kvp_frame_to_string(inst->kvp_data); printf(" with kvp_frame 1:\n%s\n", tmp); g_free(tmp); printf(" and xml:\n"); @@ -209,8 +210,7 @@ test_kvp_xml_stuff(void) kvp_frame_delete(test_frame2); xmlFreeNode(test_node); } - - kvp_frame_delete(test_frame1); + g_object_unref (inst); } } diff --git a/src/engine/SchedXaction.h b/src/engine/SchedXaction.h index f4f9454b9d..e79ae3de68 100644 --- a/src/engine/SchedXaction.h +++ b/src/engine/SchedXaction.h @@ -319,8 +319,6 @@ gboolean SXRegister (void); #define xaccSchedXactionIsDirty(X) qof_instance_is_dirty (QOF_INSTANCE(X)) /** \deprecated */ #define xaccSchedXactionGetGUID(X) qof_entity_get_guid(QOF_INSTANCE(X)) -/** \deprecated */ -#define xaccSchedXactionGetSlots(X) qof_instance_get_slots(QOF_INSTANCE(X)) #endif /* XACC_SCHEDXACTION_H */ From 171669ec68b3096c21b7b6db49cb266868017865 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Sun, 14 Jun 2015 12:45:36 -0700 Subject: [PATCH 37/54] Change io-gncxml-v2.c to C++. --- po/POTFILES.in | 2 +- src/backend/xml/Makefile.am | 2 +- src/backend/xml/{io-gncxml-v1.c => io-gncxml-v1.cpp} | 10 ++++++---- src/backend/xml/io-gncxml.h | 7 +++++++ 4 files changed, 15 insertions(+), 6 deletions(-) rename src/backend/xml/{io-gncxml-v1.c => io-gncxml-v1.cpp} (99%) diff --git a/po/POTFILES.in b/po/POTFILES.in index 58c75b9665..ea745f989a 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -87,7 +87,7 @@ src/backend/xml/gnc-vendor-xml-v2.c src/backend/xml/gnc-xml-helper.c src/backend/xml/io-example-account.c src/backend/xml/io-gncxml-gen.c -src/backend/xml/io-gncxml-v1.c +src/backend/xml/io-gncxml-v1.cpp src/backend/xml/io-gncxml-v2.c src/backend/xml/io-utils.c src/backend/xml/sixtp.c diff --git a/src/backend/xml/Makefile.am b/src/backend/xml/Makefile.am index e7bb12e610..34aeb2ab3d 100644 --- a/src/backend/xml/Makefile.am +++ b/src/backend/xml/Makefile.am @@ -42,7 +42,7 @@ libgnc_backend_xml_utils_la_SOURCES = \ gnc-xml-helper.c \ io-example-account.c \ io-gncxml-gen.c \ - io-gncxml-v1.c \ + io-gncxml-v1.cpp \ io-gncxml-v2.c \ io-utils.c \ sixtp-dom-generators.cpp \ diff --git a/src/backend/xml/io-gncxml-v1.c b/src/backend/xml/io-gncxml-v1.cpp similarity index 99% rename from src/backend/xml/io-gncxml-v1.c rename to src/backend/xml/io-gncxml-v1.cpp index 536c5c9290..23a575b56d 100644 --- a/src/backend/xml/io-gncxml-v1.c +++ b/src/backend/xml/io-gncxml-v1.cpp @@ -24,7 +24,8 @@ * Boston, MA 02110-1301, USA gnu@gnu.org * * * *******************************************************************/ - +extern "C" +{ #include "config.h" #include @@ -49,6 +50,7 @@ #include "sixtp-stack.h" #include "sixtp-parsers.h" #include "sixtp-utils.h" +} /* from Transaction-xml-parser-v1.c */ static sixtp* gnc_transaction_parser_new(void); @@ -787,13 +789,13 @@ kvp_frame_slot_end_handler(gpointer data_for_children, { if (is_child_result_from_node_named(cr, "frame")) { - KvpFrame *frame = cr->data; + KvpFrame *frame = static_cast(cr->data); value = kvp_value_new_frame (frame); delete_value = TRUE; } else { - value = cr->data; + value = static_cast(cr->data); delete_value = FALSE; } @@ -1401,7 +1403,7 @@ acc_restore_type_end_handler(gpointer data_for_children, { Account *acc = (Account *) parent_data; gchar *txt = NULL; - int type; + GNCAccountType type; gboolean ok; g_return_val_if_fail(acc, FALSE); diff --git a/src/backend/xml/io-gncxml.h b/src/backend/xml/io-gncxml.h index e5e8059244..2fc1457510 100644 --- a/src/backend/xml/io-gncxml.h +++ b/src/backend/xml/io-gncxml.h @@ -32,6 +32,10 @@ #ifndef IO_GNCXML_H #define IO_GNCXML_H +#ifdef __cplusplus +extern "C" +{ +#endif #include #include "qof.h" @@ -47,4 +51,7 @@ gboolean qof_session_load_from_xml_file(QofBook *, const char * filename); */ gboolean gnc_is_xml_data_file(const gchar *name); +#ifdef __cplusplus +} +#endif #endif /* IO_GNCXML_H */ From 3956ee0f01188910b5845c99cfc83fb4d9720423 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Sun, 14 Jun 2015 14:48:25 -0700 Subject: [PATCH 38/54] Remove the rest of the KVP direct-query functions. --- src/engine/engine-helpers.c | 33 ------- src/libqof/qof/qof.h | 1 - src/libqof/qof/qofquery.cpp | 13 --- src/libqof/qof/qofquerycore.cpp | 153 -------------------------------- src/libqof/qof/qofquerycore.h | 17 +--- 5 files changed, 1 insertion(+), 216 deletions(-) diff --git a/src/engine/engine-helpers.c b/src/engine/engine-helpers.c index e1c93574d6..81f75bdcc2 100644 --- a/src/engine/engine-helpers.c +++ b/src/engine/engine-helpers.c @@ -1023,14 +1023,6 @@ gnc_queryterm2scm (const QofQueryTerm *qt) qt_scm = scm_cons (scm_from_long (pdata->options), qt_scm); qt_scm = scm_cons (pdata->char_list ? scm_from_utf8_string (pdata->char_list) : SCM_BOOL_F, qt_scm); - } - else if (!g_strcmp0 (pd->type_name, QOF_TYPE_KVP)) - { - query_kvp_t pdata = (query_kvp_t) pd; - - qt_scm = scm_cons (gnc_query_path2scm (pdata->path), qt_scm); - qt_scm = scm_cons (gnc_kvp_value2scm (pdata->value), qt_scm); - } else { @@ -1234,31 +1226,6 @@ gnc_scm2query_term_query_v2 (SCM qt_scm) pd = qof_query_char_predicate (options, char_list); g_free (char_list); } - else if (!g_strcmp0 (type, QOF_TYPE_KVP)) - { - GSList *kvp_path; - KvpValue *value; - - scm = SCM_CAR (qt_scm); - qt_scm = SCM_CDR (qt_scm); - if (!scm_is_list (scm)) - break; - kvp_path = gnc_query_scm2path (scm); - - scm = SCM_CAR (qt_scm); - qt_scm = SCM_CDR (qt_scm); - if (scm_is_null (scm)) - { - gnc_query_path_free (kvp_path); - break; - } - value = gnc_scm2KvpValue (scm); - - pd = qof_query_kvp_predicate (compare_how, kvp_path, value); - gnc_query_path_free (kvp_path); - kvp_value_delete (value); - - } else { PWARN ("query core type %s not supported", type); diff --git a/src/libqof/qof/qof.h b/src/libqof/qof/qof.h index be030c62cd..282d6901e5 100644 --- a/src/libqof/qof/qof.h +++ b/src/libqof/qof/qof.h @@ -79,7 +79,6 @@ #include "gnc-numeric.h" #include "qofutil.h" #include "guid.h" -#include "kvp_frame.h" #include "qofbackend.h" #include "qofid-p.h" #include "qofbook.h" diff --git a/src/libqof/qof/qofquery.cpp b/src/libqof/qof/qofquery.cpp index e015735027..3810fa43ae 100644 --- a/src/libqof/qof/qofquery.cpp +++ b/src/libqof/qof/qofquery.cpp @@ -1808,19 +1808,6 @@ qof_query_printValueForParam (QofQueryPredData *pd, GString * gs) gnc_num_dbg_to_string (pdata->amount)); return; } - if (!g_strcmp0 (pd->type_name, QOF_TYPE_KVP)) - { - GSList *node; - query_kvp_t pdata = (query_kvp_t) pd; - g_string_append_printf (gs, " kvp path: "); - for (node = pdata->path; node; node = node->next) - { - g_string_append_printf (gs, "/%s", (gchar *) node->data); - } - g_string_append_printf (gs, " kvp value: %s ", - kvp_value_to_string (pdata->value)); - return; - } if (!g_strcmp0 (pd->type_name, QOF_TYPE_INT64)) { query_int64_t pdata = (query_int64_t) pd; diff --git a/src/libqof/qof/qofquerycore.cpp b/src/libqof/qof/qofquerycore.cpp index 3804acdfe9..68a6f6298d 100644 --- a/src/libqof/qof/qofquerycore.cpp +++ b/src/libqof/qof/qofquerycore.cpp @@ -81,9 +81,6 @@ static const char * query_boolean_type = QOF_TYPE_BOOLEAN; typedef char (*query_char_getter) (gpointer, QofParam *); static const char * query_char_type = QOF_TYPE_CHAR; -typedef KvpFrame * (*query_kvp_getter) (gpointer, QofParam *); -static const char * query_kvp_type = QOF_TYPE_KVP; - typedef QofCollection * (*query_collect_getter) (gpointer, QofParam*); static const char * query_collect_type = QOF_TYPE_COLLECT; @@ -1219,152 +1216,6 @@ char_to_string (gpointer object, QofParam *getter) return g_strdup_printf ("%c", num); } -/* QOF_TYPE_KVP ================================================ */ - -static int -kvp_match_predicate (gpointer object, QofParam *getter, - QofQueryPredData *pd) -{ - int compare; - KvpFrame *kvp; - KvpValue *value; - query_kvp_t pdata = (query_kvp_t)pd; - - VERIFY_PREDICATE (query_kvp_type); - - kvp = ((query_kvp_getter)getter->param_getfcn) (object, getter); - if (!kvp) - return 0; - - value = kvp_frame_get_slot_path_gslist (kvp, pdata->path); - if (!value) - return 0; - - if (kvp_value_get_type (value) != kvp_value_get_type (pdata->value)) - return 0; - - compare = kvp_value_compare (value, pdata->value); - - switch (pd->how) - { - case QOF_COMPARE_LT: - return (compare < 0); - case QOF_COMPARE_LTE: - return (compare <= 0); - case QOF_COMPARE_EQUAL: - return (compare == 0); - case QOF_COMPARE_GTE: - return (compare >= 0); - case QOF_COMPARE_GT: - return (compare > 0); - case QOF_COMPARE_NEQ: - return (compare != 0); - default: - PWARN ("bad match type: %d", pd->how); - return 0; - } -} - -static void -kvp_free_pdata (QofQueryPredData *pd) -{ - query_kvp_t pdata = (query_kvp_t)pd; - QofQueryParamList *node; - - VERIFY_PDATA (query_kvp_type); - kvp_value_delete (pdata->value); - for (node = pdata->path; node; node = node->next) - { - g_free (node->data); - node->data = NULL; - } - g_slist_free (pdata->path); - g_free (pdata); -} - -static QofQueryPredData * -kvp_copy_predicate (const QofQueryPredData *pd) -{ - const query_kvp_t pdata = (const query_kvp_t)pd; - VERIFY_PDATA_R (query_kvp_type); - return qof_query_kvp_predicate (pd->how, pdata->path, pdata->value); -} - -static gboolean -kvp_predicate_equal (const QofQueryPredData *p1, const QofQueryPredData *p2) -{ - const query_kvp_t pd1 = (const query_kvp_t) p1; - const query_kvp_t pd2 = (const query_kvp_t) p2; - QofQueryParamList *n1, *n2; - - n1 = pd1->path; - n2 = pd2->path; - - for ( ; n1 && n2; n1 = n1->next, n2 = n2->next) - { - if (g_strcmp0 (static_cast(n1->data), - static_cast(n2->data)) != 0) - return FALSE; - } - - if (n1 || n2) - return FALSE; - - return (kvp_value_compare (pd1->value, pd2->value) == 0); -} - -QofQueryPredData * -qof_query_kvp_predicate (QofQueryCompare how, - QofQueryParamList *path, const KvpValue *value) -{ - query_kvp_t pdata; - QofQueryParamList *node; - - g_return_val_if_fail (path && value, NULL); - - pdata = g_new0 (query_kvp_def, 1); - pdata->pd.type_name = query_kvp_type; - pdata->pd.how = how; - pdata->value = kvp_value_copy (value); - pdata->path = g_slist_copy (path); - for (node = pdata->path; node; node = node->next) - node->data = g_strdup (static_cast(node->data)); - - return ((QofQueryPredData*)pdata); -} - -QofQueryPredData * -qof_query_kvp_predicate_path (QofQueryCompare how, - const char *path, const KvpValue *value) -{ - QofQueryPredData *pd; - QofQueryParamList *spath = NULL; - char *str, *p; - - if (!path) return NULL; - - str = g_strdup (path); - p = str; - if (0 == *p) return NULL; - if ('/' == *p) p++; - - while (p) - { - spath = g_slist_append (spath, p); - p = strchr (p, '/'); - if (p) - { - *p = 0; - p++; - } - } - - pd = qof_query_kvp_predicate (how, spath, value); - g_free (str); - return pd; -} - - /* QOF_TYPE_COLLECT =============================================== */ static int @@ -1825,10 +1676,6 @@ static void init_tables (void) char_copy_predicate, char_free_pdata, char_to_string, char_predicate_equal }, - { - QOF_TYPE_KVP, kvp_match_predicate, NULL, kvp_copy_predicate, - kvp_free_pdata, NULL, kvp_predicate_equal - }, { QOF_TYPE_COLLECT, collect_match_predicate, collect_compare_func, collect_copy_predicate, collect_free_pdata, NULL, diff --git a/src/libqof/qof/qofquerycore.h b/src/libqof/qof/qofquerycore.h index 8fb2d45814..f60235728b 100644 --- a/src/libqof/qof/qofquerycore.h +++ b/src/libqof/qof/qofquerycore.h @@ -34,7 +34,6 @@ #include "gnc-numeric.h" #include "gnc-date.h" -#include "kvp_frame.h" #include "qofclass.h" #ifdef __cplusplus @@ -137,7 +136,7 @@ typedef enum } QofCharMatch; /** No extended comparisons for QOF_TYPE_INT32, QOF_TYPE_INT64, - * QOF_TYPE_DOUBLE, QOF_TYPE_BOOLEAN, QOF_TYPE_KVP + * QOF_TYPE_DOUBLE, QOF_TYPE_BOOLEAN */ /** Head of Predicate Data structures. All PData must start like this. */ @@ -177,20 +176,6 @@ QofQueryPredData *qof_query_collect_predicate (QofGuidMatch options, QofCollection *coll); QofQueryPredData *qof_query_choice_predicate (QofGuidMatch options, GList *guids); -/** The qof_query_kvp_predicate() matches the object that has - * the value 'value' located at the path 'path'. In a certain - * sense, the 'path' is handled as if it were a parameter. - */ -QofQueryPredData *qof_query_kvp_predicate (QofQueryCompare how, - QofQueryParamList *path, - const KvpValue *value); - -/** Same predicate as above, except that 'path' is assumed to be - * a string containing slash-separated pathname. */ -QofQueryPredData *qof_query_kvp_predicate_path (QofQueryCompare how, - const gchar *path, - const KvpValue *value); - /** Copy a predicate. */ QofQueryPredData *qof_query_core_predicate_copy (const QofQueryPredData *pdata); From c721bf9f48a8eb9792fb8f33cfa2dc525c668091 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Sun, 14 Jun 2015 14:50:31 -0700 Subject: [PATCH 39/54] Remove the unused backend-configuration member and virtual setter/getters. Not used, and if it was it would be an inappropriate use of KVP. --- src/backend/dbi/gnc-backend-dbi.c | 2 -- src/backend/sql/test/utest-gnc-backend-sql.c | 2 +- src/backend/xml/gnc-backend-xml.c | 2 -- src/import-export/aqb/test/test-aqb.c | 2 +- src/libqof/qof/qofbackend-p.h | 4 ---- src/libqof/qof/qofbackend.cpp | 4 ---- 6 files changed, 2 insertions(+), 14 deletions(-) diff --git a/src/backend/dbi/gnc-backend-dbi.c b/src/backend/dbi/gnc-backend-dbi.c index 03f6463ca1..8c96bd0949 100644 --- a/src/backend/dbi/gnc-backend-dbi.c +++ b/src/backend/dbi/gnc-backend-dbi.c @@ -1763,8 +1763,6 @@ init_sql_backend( GncDbiBackend* dbi_be ) * configured for multiuser access. */ be->sync = gnc_dbi_safe_sync_all; be->safe_sync = gnc_dbi_safe_sync_all; - be->load_config = NULL; - be->get_config = NULL; be->compile_query = gnc_sql_compile_query; be->run_query = gnc_sql_run_query; diff --git a/src/backend/sql/test/utest-gnc-backend-sql.c b/src/backend/sql/test/utest-gnc-backend-sql.c index 4ab0446e73..b15f3ea7d2 100644 --- a/src/backend/sql/test/utest-gnc-backend-sql.c +++ b/src/backend/sql/test/utest-gnc-backend-sql.c @@ -583,7 +583,7 @@ test_gnc_sql_convert_timespec_to_string () GncSqlBackend be = {{ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - 0, NULL, 0, "", NULL, 0, "", NULL, NULL + 0, NULL, 0, "", NULL }, NULL, NULL, FALSE, FALSE, FALSE, 0, 0, NULL, "%4d-%02d-%02d %02d:%02d:%02d" diff --git a/src/backend/xml/gnc-backend-xml.c b/src/backend/xml/gnc-backend-xml.c index 0aacf4f7d1..2eff9a727e 100644 --- a/src/backend/xml/gnc-backend-xml.c +++ b/src/backend/xml/gnc-backend-xml.c @@ -1251,8 +1251,6 @@ gnc_backend_new(void) be->process_events = NULL; be->sync = xml_sync_all; - be->load_config = NULL; - be->get_config = NULL; be->export_fn = gnc_xml_be_write_accounts_to_file; diff --git a/src/import-export/aqb/test/test-aqb.c b/src/import-export/aqb/test/test-aqb.c index e18cd96628..43286f5145 100644 --- a/src/import-export/aqb/test/test-aqb.c +++ b/src/import-export/aqb/test/test-aqb.c @@ -40,7 +40,7 @@ main (int argc, qof_init(); /* Initialize the GObject system */ qof_log_init_filename_special("stderr"); /* Init the log system */ g_test_init ( &argc, &argv, NULL ); /* initialize test program */ - qof_log_set_level("gnc", G_LOG_LEVEL_DEBUG); + qof_log_set_level("gnc", (QofLogLevel)G_LOG_LEVEL_DEBUG); g_test_bug_base("https://bugzilla.gnome.org/show_bug.cgi?id="); /* init the bugzilla URL */ /* Disable the transaction log */ xaccLogDisable(); diff --git a/src/libqof/qof/qofbackend-p.h b/src/libqof/qof/qofbackend-p.h index 9b7074b80b..b2ed3bf32c 100644 --- a/src/libqof/qof/qofbackend-p.h +++ b/src/libqof/qof/qofbackend-p.h @@ -304,9 +304,6 @@ struct QofBackend_s void (*sync) (QofBackend *, /*@ dependent @*/ QofBook *); void (*safe_sync) (QofBackend *, /*@ dependent @*/ QofBook *); - void (*load_config) (QofBackend *, KvpFrame *); - /*@ observer @*/ - KvpFrame* (*get_config) (QofBackend *); gboolean (*events_pending) (QofBackend *); gboolean (*process_events) (QofBackend *); @@ -318,7 +315,6 @@ struct QofBackend_s QofBackendError last_err; char * error_msg; - KvpFrame* backend_configuration; gint config_count; /** Each backend resolves a fully-qualified file path. * This holds the filepath and communicates it to the frontends. diff --git a/src/libqof/qof/qofbackend.cpp b/src/libqof/qof/qofbackend.cpp index 56b4d91a1e..33fbbef8a7 100644 --- a/src/libqof/qof/qofbackend.cpp +++ b/src/libqof/qof/qofbackend.cpp @@ -138,7 +138,6 @@ qof_backend_init(QofBackend *be) be->sync = NULL; be->safe_sync = NULL; - be->load_config = NULL; be->events_pending = NULL; be->process_events = NULL; @@ -147,7 +146,6 @@ qof_backend_init(QofBackend *be) if (be->error_msg) g_free (be->error_msg); be->error_msg = NULL; be->percentage = NULL; - be->backend_configuration = kvp_frame_new(); /* to be removed */ be->price_lookup = NULL; @@ -159,8 +157,6 @@ qof_backend_destroy(QofBackend *be) { g_free(be->error_msg); be->error_msg = NULL; - kvp_frame_delete(be->backend_configuration); - be->backend_configuration = NULL; } void From ab30b4c680ba50ce13477cb4c5654d5c5f7b2fd8 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Sun, 14 Jun 2015 14:52:25 -0700 Subject: [PATCH 40/54] Remove #include "kvp_frame.h" from qof.h and add it where it's legitimately used. --- src/app-utils/test/test-option-util.c | 1 + src/backend/dbi/test/test-backend-dbi-basic.c | 1 + src/backend/dbi/test/test-dbi-stuff.c | 19 +++++++-------- src/backend/sql/gnc-backend-sql.c | 23 ++++++++++--------- src/backend/sql/gnc-slots-sql.cpp | 5 ++-- src/backend/xml/io-gncxml-v1.cpp | 21 +++++++++-------- src/backend/xml/sixtp-dom-generators.cpp | 1 + src/backend/xml/sixtp-dom-parsers.cpp | 3 ++- src/backend/xml/test/test-file-stuff.h | 11 +++++---- src/engine/engine-helpers.c | 6 +++-- src/engine/kvp-scm.c | 3 ++- src/engine/test-core/test-engine-stuff.c | 1 + src/engine/test-core/test-engine-stuff.h | 1 + src/engine/test/utest-Account.c | 1 + src/engine/test/utest-Split.cpp | 1 + src/engine/test/utest-Transaction.c | 1 + src/libqof/qof/kvp-value.hpp | 1 + src/libqof/qof/qofbook.cpp | 1 + src/libqof/qof/qofbook.h | 2 +- src/libqof/qof/qofinstance.cpp | 1 + src/libqof/qof/qofinstance.h | 3 ++- src/libqof/qof/test/test-kvp_frame.c | 7 +++--- src/libqof/qof/test/test-qofinstance.c | 1 + 23 files changed, 69 insertions(+), 46 deletions(-) diff --git a/src/app-utils/test/test-option-util.c b/src/app-utils/test/test-option-util.c index f1adf73a21..3a261c21aa 100644 --- a/src/app-utils/test/test-option-util.c +++ b/src/app-utils/test/test-option-util.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "../option-util.h" diff --git a/src/backend/dbi/test/test-backend-dbi-basic.c b/src/backend/dbi/test/test-backend-dbi-basic.c index b3203f0bbe..b692f92cf5 100644 --- a/src/backend/dbi/test/test-backend-dbi-basic.c +++ b/src/backend/dbi/test/test-backend-dbi-basic.c @@ -12,6 +12,7 @@ #include #include +#include #include #include #include diff --git a/src/backend/dbi/test/test-dbi-stuff.c b/src/backend/dbi/test/test-dbi-stuff.c index c0e1d1e73a..e6ad4a694a 100644 --- a/src/backend/dbi/test/test-dbi-stuff.c +++ b/src/backend/dbi/test/test-dbi-stuff.c @@ -23,17 +23,18 @@ * 02110-1301, USA. */ -#include "config.h" -#include "qof.h" -#include "qofsession-p.h" -#include "cashobjects.h" -#include "test-dbi-stuff.h" +#include +#include +#include +#include +#include +#include #include -#include "Account.h" -#include "Split.h" -#include "Transaction.h" -#include "gnc-commodity.h" +#include +#include +#include +#include #include #include #include "../gnc-backend-dbi-priv.h" diff --git a/src/backend/sql/gnc-backend-sql.c b/src/backend/sql/gnc-backend-sql.c index 1e68004df1..7d9f748a96 100644 --- a/src/backend/sql/gnc-backend-sql.c +++ b/src/backend/sql/gnc-backend-sql.c @@ -34,17 +34,18 @@ #include #include -#include "qof.h" -#include "qofquery-p.h" -#include "qofquerycore-p.h" -#include "Account.h" -#include "TransLog.h" -#include "gnc-engine.h" -#include "SX-book.h" -#include "Recurrence.h" -#include "gncBillTerm.h" -#include "gncTaxTable.h" -#include "gncInvoice.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include "gnc-backend-sql.h" diff --git a/src/backend/sql/gnc-slots-sql.cpp b/src/backend/sql/gnc-slots-sql.cpp index bff1eab393..1c5f77a19c 100644 --- a/src/backend/sql/gnc-slots-sql.cpp +++ b/src/backend/sql/gnc-slots-sql.cpp @@ -31,8 +31,9 @@ extern "C" #include -#include "qof.h" -#include "gnc-engine.h" +#include +#include +#include #include "gnc-backend-sql.h" diff --git a/src/backend/xml/io-gncxml-v1.cpp b/src/backend/xml/io-gncxml-v1.cpp index 23a575b56d..ebfc2f71e4 100644 --- a/src/backend/xml/io-gncxml-v1.cpp +++ b/src/backend/xml/io-gncxml-v1.cpp @@ -33,16 +33,17 @@ extern "C" #include -#include "gnc-xml-helper.h" -#include "Account.h" -#include "AccountP.h" -#include "Query.h" -#include "Scrub.h" -#include "Transaction.h" -#include "TransactionP.h" -#include "TransLog.h" -#include "gnc-pricedb.h" -#include "gnc-pricedb-p.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include "io-gncxml.h" #include "sixtp.h" diff --git a/src/backend/xml/sixtp-dom-generators.cpp b/src/backend/xml/sixtp-dom-generators.cpp index 8160ad4365..7f60c19204 100644 --- a/src/backend/xml/sixtp-dom-generators.cpp +++ b/src/backend/xml/sixtp-dom-generators.cpp @@ -29,6 +29,7 @@ extern "C" #include "gnc-xml-helper.h" #include +#include #include "sixtp-dom-generators.h" #include "sixtp-utils.h" diff --git a/src/backend/xml/sixtp-dom-parsers.cpp b/src/backend/xml/sixtp-dom-parsers.cpp index f95059ee73..115b133818 100644 --- a/src/backend/xml/sixtp-dom-parsers.cpp +++ b/src/backend/xml/sixtp-dom-parsers.cpp @@ -28,7 +28,8 @@ extern "C" #include #include "gnc-xml-helper.h" -#include "gnc-engine.h" +#include +#include #include "sixtp-utils.h" #include "sixtp-dom-parsers.h" } diff --git a/src/backend/xml/test/test-file-stuff.h b/src/backend/xml/test/test-file-stuff.h index 08dac546ab..812a0478d1 100644 --- a/src/backend/xml/test/test-file-stuff.h +++ b/src/backend/xml/test/test-file-stuff.h @@ -7,11 +7,12 @@ #include -#include "gnc-commodity.h" -#include "gnc-engine.h" -#include "gnc-xml-helper.h" -#include "io-gncxml-gen.h" -#include "sixtp.h" +#include +#include +#include +#include +#include +#include diff --git a/src/engine/engine-helpers.c b/src/engine/engine-helpers.c index 81f75bdcc2..58dddbb112 100644 --- a/src/engine/engine-helpers.c +++ b/src/engine/engine-helpers.c @@ -37,8 +37,10 @@ #include "gnc-session.h" #include "guile-mappings.h" #include "gnc-guile-utils.h" -#include "qof.h" -#include "qofbookslots.h" +#include +#include +#include + /** \todo Code dependent on the private query headers qofquery-p.h and qofquerycore-p.h may need to be modified. These files are temporarily exported for QOF 0.6.0 but diff --git a/src/engine/kvp-scm.c b/src/engine/kvp-scm.c index 1e51f34268..82d0e73967 100644 --- a/src/engine/kvp-scm.c +++ b/src/engine/kvp-scm.c @@ -1,6 +1,7 @@ #include "config.h" -#include "qof.h" +#include +#include #include #include "engine-helpers-guile.h" diff --git a/src/engine/test-core/test-engine-stuff.c b/src/engine/test-core/test-engine-stuff.c index 89d5cde0bd..0969bfbc3b 100644 --- a/src/engine/test-core/test-engine-stuff.c +++ b/src/engine/test-core/test-engine-stuff.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include "Account.h" diff --git a/src/engine/test-core/test-engine-stuff.h b/src/engine/test-core/test-engine-stuff.h index 25b9fba0b7..557bba8aa3 100644 --- a/src/engine/test-core/test-engine-stuff.h +++ b/src/engine/test-core/test-engine-stuff.h @@ -10,6 +10,7 @@ #include #include "qof.h" +#include #include "Query.h" #include "gnc-pricedb.h" #include "SchedXaction.h" diff --git a/src/engine/test/utest-Account.c b/src/engine/test/utest-Account.c index ea7f74df83..f1c69147f8 100644 --- a/src/engine/test/utest-Account.c +++ b/src/engine/test/utest-Account.c @@ -25,6 +25,7 @@ #include #include #include +#include #include /* Add specific headers for this class */ #include "../Account.h" diff --git a/src/engine/test/utest-Split.cpp b/src/engine/test/utest-Split.cpp index 6a5000cb8f..5612990f00 100644 --- a/src/engine/test/utest-Split.cpp +++ b/src/engine/test/utest-Split.cpp @@ -38,6 +38,7 @@ extern "C" #include #include #include +#include #include #ifdef HAVE_GLIB_2_38 diff --git a/src/engine/test/utest-Transaction.c b/src/engine/test/utest-Transaction.c index 7611c2c117..ec5d6d30fd 100644 --- a/src/engine/test/utest-Transaction.c +++ b/src/engine/test/utest-Transaction.c @@ -33,6 +33,7 @@ #include "../gnc-lot.h" #include "../gnc-event.h" #include +#include #include #ifdef HAVE_GLIB_2_38 diff --git a/src/libqof/qof/kvp-value.hpp b/src/libqof/qof/kvp-value.hpp index bfdfc33895..ebd8cb6202 100644 --- a/src/libqof/qof/kvp-value.hpp +++ b/src/libqof/qof/kvp-value.hpp @@ -28,6 +28,7 @@ extern "C" { #include "config.h" #include "qof.h" +#include "kvp_frame.h" } #include #if BOOST_VERSION == 105600 diff --git a/src/libqof/qof/qofbook.cpp b/src/libqof/qof/qofbook.cpp index 2aa09b1b38..ebc769454c 100644 --- a/src/libqof/qof/qofbook.cpp +++ b/src/libqof/qof/qofbook.cpp @@ -56,6 +56,7 @@ extern "C" #include "qofid-p.h" #include "qofobject-p.h" #include "qofbookslots.h" +#include "kvp_frame.h" static QofLogModule log_module = QOF_MOD_ENGINE; #define AB_KEY "hbci" diff --git a/src/libqof/qof/qofbook.h b/src/libqof/qof/qofbook.h index a51bad7d02..04448f76ab 100644 --- a/src/libqof/qof/qofbook.h +++ b/src/libqof/qof/qofbook.h @@ -49,9 +49,9 @@ extern "C" #ifndef SWIG typedef struct _QofBookClass QofBookClass; +typedef struct KvpValueImpl KvpValue; #include "qofid.h" -#include "kvp_frame.h" #include "qofinstance.h" /* --- type macros --- */ diff --git a/src/libqof/qof/qofinstance.cpp b/src/libqof/qof/qofinstance.cpp index a765cae060..1865b48dd7 100644 --- a/src/libqof/qof/qofinstance.cpp +++ b/src/libqof/qof/qofinstance.cpp @@ -38,6 +38,7 @@ extern "C" #include "qof.h" #include "qofbook-p.h" #include "qofid-p.h" +#include "kvp_frame.h" #include "qofinstance-p.h" static QofLogModule log_module = QOF_MOD_ENGINE; diff --git a/src/libqof/qof/qofinstance.h b/src/libqof/qof/qofinstance.h index ca485c3b90..98b854f0c3 100644 --- a/src/libqof/qof/qofinstance.h +++ b/src/libqof/qof/qofinstance.h @@ -46,7 +46,6 @@ typedef struct _QofBook QofBook; #include "qofid.h" #include "guid.h" #include "gnc-date.h" -#include "kvp_frame.h" #include "qof-gobject.h" /* --- type macros --- */ @@ -62,6 +61,8 @@ typedef struct _QofBook QofBook; #define QOF_INSTANCE_GET_CLASS(o) \ (G_TYPE_INSTANCE_GET_CLASS ((o), QOF_TYPE_INSTANCE, QofInstanceClass)) +typedef struct KvpFrameImpl KvpFrame; + struct QofInstance_s { GObject object; diff --git a/src/libqof/qof/test/test-kvp_frame.c b/src/libqof/qof/test/test-kvp_frame.c index 2dc272c0f0..8717374fdc 100644 --- a/src/libqof/qof/test/test-kvp_frame.c +++ b/src/libqof/qof/test/test-kvp_frame.c @@ -27,13 +27,14 @@ extern "C" #include "config.h" #include #include -#include "unittest-support.h" - +#include +#include +#include #ifdef __cplusplus } #endif -#include "qof.h" + static const gchar *suitename = "/qof/kvp_frame"; void test_suite_kvp_frame ( void ); diff --git a/src/libqof/qof/test/test-qofinstance.c b/src/libqof/qof/test/test-qofinstance.c index b6b317f983..ab1e630cfe 100644 --- a/src/libqof/qof/test/test-qofinstance.c +++ b/src/libqof/qof/test/test-qofinstance.c @@ -24,6 +24,7 @@ #include #include "../qof.h" #include "../qofbackend-p.h" +#include "../kvp_frame.h" static const gchar *suitename = "/qof/qofinstance"; void test_suite_qofinstance ( void ); From 831a36012287724e37e45bb75aa95d519e01046a Mon Sep 17 00:00:00 2001 From: John Ralls Date: Tue, 16 Jun 2015 13:43:16 -0700 Subject: [PATCH 41/54] XML Backend:Replace C KVP function calls with C++. --- src/backend/xml/io-gncxml-v1.cpp | 49 ++++++------- src/backend/xml/sixtp-dom-generators.cpp | 89 ++++++++++-------------- src/backend/xml/sixtp-dom-parsers.cpp | 40 +++++------ 3 files changed, 76 insertions(+), 102 deletions(-) diff --git a/src/backend/xml/io-gncxml-v1.cpp b/src/backend/xml/io-gncxml-v1.cpp index ebfc2f71e4..29fcad6c06 100644 --- a/src/backend/xml/io-gncxml-v1.cpp +++ b/src/backend/xml/io-gncxml-v1.cpp @@ -43,7 +43,6 @@ extern "C" #include #include #include -#include #include "io-gncxml.h" #include "sixtp.h" @@ -52,6 +51,7 @@ extern "C" #include "sixtp-parsers.h" #include "sixtp-utils.h" } +#include /* from Transaction-xml-parser-v1.c */ static sixtp* gnc_transaction_parser_new(void); @@ -438,8 +438,8 @@ gnc_is_xml_data_file(const gchar *filename) static void kvp_value_result_cleanup(sixtp_child_result *cr) { - KvpValue *v = (KvpValue *) cr->data;; - if (v) kvp_value_delete(v); + KvpValue *v = static_cast(cr->data); + if (v) delete v; } static sixtp* @@ -489,7 +489,7 @@ simple_kvp_value_parser_new(sixtp_end_handler end_handler) g_free(txt); \ g_return_val_if_fail(ok, FALSE); \ \ - kvpv = kvp_value_new_##TYPE(val); \ + kvpv = new KvpValue{val}; \ g_return_val_if_fail(kvpv, FALSE); \ \ *result = kvpv; \ @@ -567,7 +567,7 @@ string_kvp_value_end_handler(gpointer data_for_children, txt = concatenate_child_result_chars(data_from_children); g_return_val_if_fail(txt, FALSE); - kvpv = kvp_value_new_string(txt); + kvpv = new KvpValue{g_strdup(txt)}; g_free(txt); g_return_val_if_fail(kvpv, FALSE); @@ -605,7 +605,7 @@ guid_kvp_value_end_handler(gpointer data_for_children, g_return_val_if_fail(ok, FALSE); - kvpv = kvp_value_new_guid(&val); + kvpv = new KvpValue{guid_copy(&val)}; g_return_val_if_fail(kvpv, FALSE); *result = kvpv; @@ -660,11 +660,10 @@ glist_kvp_value_end_handler(gpointer data_for_children, cr->should_cleanup = FALSE; } - kvp_result = kvp_value_new_glist_nc(result_glist); + kvp_result = new KvpValue{result_glist}; if (!kvp_result) - { - kvp_glist_delete(result_glist); - } + g_list_free_full(result_glist, + [](void* data){ delete static_cast(data);}); *result = kvp_result; return(TRUE); } @@ -791,7 +790,7 @@ kvp_frame_slot_end_handler(gpointer data_for_children, if (is_child_result_from_node_named(cr, "frame")) { KvpFrame *frame = static_cast(cr->data); - value = kvp_value_new_frame (frame); + value = new KvpValue{frame}; delete_value = TRUE; } else @@ -807,9 +806,9 @@ kvp_frame_slot_end_handler(gpointer data_for_children, if (key_node_count != 1) return(FALSE); value_cr->should_cleanup = TRUE; - kvp_frame_set_slot(f, key, value); + f->replace_nc(key, value); if (delete_value) - kvp_value_delete (value); + delete value; return(TRUE); } @@ -880,8 +879,7 @@ kvp_frame_start_handler(GSList* sibling_data, gpointer parent_data, gpointer global_data, gpointer *data_for_children, gpointer *result, const gchar *tag, gchar **attrs) { - KvpFrame *f = kvp_frame_new(); - g_return_val_if_fail(f, FALSE); + auto f = new KvpFrame; *data_for_children = f; return(TRUE); } @@ -892,9 +890,8 @@ kvp_frame_end_handler(gpointer data_for_children, gpointer parent_data, gpointer global_data, gpointer *result, const gchar *tag) { - KvpFrame *f = (KvpFrame *) data_for_children; - g_return_val_if_fail(f, FALSE); - *result = f; + g_return_val_if_fail(data_for_children != NULL, FALSE); + *result = data_for_children; return(TRUE); } @@ -907,15 +904,15 @@ kvp_frame_fail_handler(gpointer data_for_children, gpointer *result, const gchar *tag) { - KvpFrame *f = (KvpFrame *) data_for_children; - if (f) kvp_frame_delete(f); + auto f = static_cast(data_for_children); + if (f) delete f; } static void kvp_frame_result_cleanup(sixtp_child_result *cr) { - KvpFrame *f = (KvpFrame *) cr->data;; - if (f) kvp_frame_delete(f); + auto f = static_cast(cr->data);; + if (f) delete f; } static sixtp* @@ -1247,9 +1244,9 @@ account_restore_after_child_handler(gpointer data_for_children, if (child_result->type != SIXTP_CHILD_RESULT_NODE) return(TRUE); if (strcmp(child_result->tag, "slots") == 0) { - KvpFrame *f = (KvpFrame *) child_result->data; + auto f = static_cast(child_result->data); g_return_val_if_fail(f, FALSE); - if (a->inst.kvp_data) kvp_frame_delete(a->inst.kvp_data); + if (a->inst.kvp_data) delete a->inst.kvp_data; a->inst.kvp_data = f; child_result->should_cleanup = FALSE; } @@ -2481,9 +2478,9 @@ txn_restore_split_after_child_handler(gpointer data_for_children, if (strcmp(child_result->tag, "slots") == 0) { - KvpFrame *f = (KvpFrame *) child_result->data; + KvpFrame *f = static_cast(child_result->data); g_return_val_if_fail(f, FALSE); - if (s->inst.kvp_data) kvp_frame_delete(s->inst.kvp_data); + if (s->inst.kvp_data) delete s->inst.kvp_data; s->inst.kvp_data = f; child_result->should_cleanup = FALSE; } diff --git a/src/backend/xml/sixtp-dom-generators.cpp b/src/backend/xml/sixtp-dom-generators.cpp index 7f60c19204..b27ec2282d 100644 --- a/src/backend/xml/sixtp-dom-generators.cpp +++ b/src/backend/xml/sixtp-dom-generators.cpp @@ -29,12 +29,13 @@ extern "C" #include "gnc-xml-helper.h" #include -#include #include "sixtp-dom-generators.h" #include "sixtp-utils.h" } +#include + static QofLogModule log_module = GNC_MOD_IO; xmlNodePtr @@ -250,49 +251,52 @@ add_text_to_node(xmlNodePtr node, const gchar *type, gchar *val) g_free(newval); } -static void -add_kvp_slot(const char * key, KvpValue* value, xmlNodePtr node); +static void add_kvp_slot(const char * key, KvpValue* value, void* data); static void add_kvp_value_node(xmlNodePtr node, const gchar *tag, KvpValue* val) { xmlNodePtr val_node; - kvp_value_t kvp_type; - kvp_type = kvp_value_get_type(val); - - if (kvp_type == KVP_TYPE_STRING) + switch (val->get_type()) { - gchar *newstr = g_strdup (kvp_value_get_string(val)); + case KVP_TYPE_STRING: + { + auto newstr = g_strdup(val->get()); val_node = xmlNewTextChild(node, NULL, BAD_CAST tag, checked_char_cast (newstr)); g_free (newstr); + break; } - else if (kvp_type == KVP_TYPE_TIMESPEC) + case KVP_TYPE_TIMESPEC: val_node = NULL; - else if (kvp_type == KVP_TYPE_GDATE) + break; + case KVP_TYPE_GDATE: { - GDate d = kvp_value_get_gdate(val); + auto d = val->get(); val_node = gdate_to_dom_tree(tag, &d); xmlAddChild (node, val_node); + break; } - else + default: val_node = xmlNewTextChild(node, NULL, BAD_CAST tag, NULL); + break; + } - switch (kvp_value_get_type(val)) + switch (val->get_type()) { case KVP_TYPE_GINT64: add_text_to_node(val_node, "integer", g_strdup_printf("%" G_GINT64_FORMAT, - kvp_value_get_gint64(val))); + val->get())); break; case KVP_TYPE_DOUBLE: add_text_to_node(val_node, "double", - double_to_string(kvp_value_get_double(val))); + double_to_string(val->get())); break; case KVP_TYPE_NUMERIC: add_text_to_node(val_node, "numeric", - gnc_numeric_to_string(kvp_value_get_numeric(val))); + gnc_numeric_to_string(val->get())); break; case KVP_TYPE_STRING: xmlSetProp(val_node, BAD_CAST "type", BAD_CAST "string"); @@ -300,64 +304,50 @@ add_kvp_value_node(xmlNodePtr node, const gchar *tag, KvpValue* val) case KVP_TYPE_GUID: { gchar guidstr[GUID_ENCODING_LENGTH+1]; - guid_to_string_buff(kvp_value_get_guid(val), guidstr); + guid_to_string_buff(val->get(), guidstr); add_text_to_node(val_node, "guid", guidstr); break; } case KVP_TYPE_TIMESPEC: { - Timespec ts = kvp_value_get_timespec (val); - + auto ts = val->get(); val_node = timespec_to_dom_tree (tag, &ts); xmlSetProp (val_node, BAD_CAST "type", BAD_CAST "timespec"); xmlAddChild (node, val_node); + break; } - break; case KVP_TYPE_GDATE: xmlSetProp(val_node, BAD_CAST "type", BAD_CAST "gdate"); - break; + break; case KVP_TYPE_GLIST: - { - GList *cursor; - xmlSetProp(val_node, BAD_CAST "type", BAD_CAST "list"); - for (cursor = kvp_value_get_glist(val); cursor; cursor = cursor->next) + for (auto cursor = val->get(); cursor; cursor = cursor->next) { - KvpValue *val = (KvpValue*)cursor->data; + auto val = static_cast(cursor->data); add_kvp_value_node(val_node, "slot:value", val); } - } - - break; + break; case KVP_TYPE_FRAME: { - KvpFrame *frame; - const char ** keys; - unsigned int i; - xmlSetProp(val_node, BAD_CAST "type", BAD_CAST "frame"); - frame = kvp_value_get_frame (val); + auto frame = val->get(); if (!frame) break; - - keys = kvp_frame_get_keys(frame); - for (i = 0; keys[i]; ++i) - add_kvp_slot(keys[i], kvp_frame_get_value(frame, keys[i]), val_node); - g_free(keys); + frame->for_each_slot(add_kvp_slot, static_cast(val_node)); + break; } - break; default: break; } } static void -add_kvp_slot(const char * key, KvpValue* value, xmlNodePtr node) +add_kvp_slot(const char * key, KvpValue* value, void* data) { - xmlNodePtr slot_node; - gchar *newkey = g_strdup ((gchar*)key); - slot_node = xmlNewChild(node, NULL, BAD_CAST "slot", NULL); + auto newkey = g_strdup ((gchar*)key); + auto node = static_cast(data); + auto slot_node = xmlNewChild(node, NULL, BAD_CAST "slot", NULL); xmlNewTextChild(slot_node, NULL, BAD_CAST "slot:key", checked_char_cast (newkey)); @@ -371,19 +361,12 @@ qof_instance_slots_to_dom_tree(const char *tag, const QofInstance* inst) xmlNodePtr ret; const char ** keys; unsigned int i; - KvpFrame *frame = qof_instance_get_slots(QOF_INSTANCE (inst)); + KvpFrame *frame = qof_instance_get_slots(inst); if (!frame) - { return nullptr; - } ret = xmlNewNode(nullptr, BAD_CAST tag); - - keys = kvp_frame_get_keys(frame); - for (i = 0; keys[i]; ++i) - add_kvp_slot(keys[i], kvp_frame_get_value(frame, keys[i]), ret); - g_free(keys); - + frame->for_each_slot(add_kvp_slot, static_cast(ret)); return ret; } diff --git a/src/backend/xml/sixtp-dom-parsers.cpp b/src/backend/xml/sixtp-dom-parsers.cpp index 115b133818..71a92adb82 100644 --- a/src/backend/xml/sixtp-dom-parsers.cpp +++ b/src/backend/xml/sixtp-dom-parsers.cpp @@ -29,10 +29,12 @@ extern "C" #include "gnc-xml-helper.h" #include -#include #include "sixtp-utils.h" #include "sixtp-dom-parsers.h" } + +#include + static QofLogModule log_module = GNC_MOD_IO; GncGUID* @@ -59,7 +61,7 @@ dom_tree_to_guid(xmlNodePtr node) /* handle new and guid the same for the moment */ if ((g_strcmp0("guid", type) == 0) || (g_strcmp0("new", type) == 0)) { - GncGUID *gid = g_new(GncGUID, 1); + auto gid = guid_new(); char *guid_str; guid_str = (char*)xmlNodeGetContent (node->xmlChildrenNode); @@ -91,7 +93,7 @@ dom_tree_to_integer_kvp_value(xmlNodePtr node) if (string_to_gint64(text, &daint)) { - ret = kvp_value_new_gint64(daint); + ret = new KvpValue{daint}; } g_free(text); @@ -174,7 +176,7 @@ dom_tree_to_double_kvp_value(xmlNodePtr node) if (string_to_double(text, &dadoub)) { - ret = kvp_value_new_double(dadoub); + ret = new KvpValue{dadoub}; } g_free(text); @@ -192,7 +194,7 @@ dom_tree_to_numeric_kvp_value(xmlNodePtr node) if (danum) { - ret = kvp_value_new_gnc_numeric(*danum); + ret = new KvpValue{*danum}; } g_free(danum); @@ -209,11 +211,9 @@ dom_tree_to_string_kvp_value(xmlNodePtr node) datext = dom_tree_to_text(node); if (datext) { - ret = kvp_value_new_string(datext); + ret = new KvpValue{datext}; } - g_free(datext); - return ret; } @@ -226,11 +226,9 @@ dom_tree_to_guid_kvp_value(xmlNodePtr node) daguid = dom_tree_to_guid(node); if (daguid) { - ret = kvp_value_new_guid(daguid); + ret = new KvpValue{daguid}; } - g_free(daguid); - return ret; } @@ -243,7 +241,7 @@ dom_tree_to_timespec_kvp_value (xmlNodePtr node) ts = dom_tree_to_timespec (node); if (ts.tv_sec || ts.tv_nsec) { - ret = kvp_value_new_timespec (ts); + ret = new KvpValue{ts}; } return ret; } @@ -258,7 +256,7 @@ dom_tree_to_gdate_kvp_value (xmlNodePtr node) if (date) { - ret = kvp_value_new_gdate(*date); + ret = new KvpValue{*date}; } g_free(date); @@ -333,7 +331,7 @@ dom_tree_to_list_kvp_value(xmlNodePtr node) } } - ret = kvp_value_new_glist_nc(list); + ret = new KvpValue{list}; return ret; } @@ -348,11 +346,9 @@ dom_tree_to_frame_kvp_value(xmlNodePtr node) if (frame) { - ret = kvp_value_new_frame(frame); + ret = new KvpValue{frame}; } - kvp_frame_delete(frame); - return ret; } @@ -449,7 +445,8 @@ dom_tree_to_kvp_frame_given(xmlNodePtr node, KvpFrame *frame) { if (val) { - kvp_frame_set_slot_nc(frame, key, val); + //We're deleting the old KvpValue returned by replace_nc(). + delete frame->replace_nc(key, val); } else { @@ -467,17 +464,14 @@ dom_tree_to_kvp_frame_given(xmlNodePtr node, KvpFrame *frame) KvpFrame* dom_tree_to_kvp_frame(xmlNodePtr node) { - KvpFrame *ret; - g_return_val_if_fail(node, NULL); - ret = kvp_frame_new(); + auto ret = new KvpFrame; if (dom_tree_to_kvp_frame_given(node, ret)) return ret; - kvp_frame_delete(ret); - + delete ret; return NULL; } From 45a01b0f67a3fca1781be2df91153be29410e05f Mon Sep 17 00:00:00 2001 From: John Ralls Date: Thu, 18 Jun 2015 13:02:00 -0700 Subject: [PATCH 42/54] Change the KVP string storage type from char* to const char*. Because we don't want to be able to get a pointer to the KvpValue and change its contents without using KvpValue::set(). --- src/backend/xml/sixtp-dom-generators.cpp | 2 +- src/core-utils/gnc-features.c | 2 +- src/libqof/qof/kvp-value.cpp | 10 +++++----- src/libqof/qof/kvp-value.hpp | 2 +- src/libqof/qof/kvp_frame.cpp | 4 ++-- src/libqof/qof/kvp_frame.h | 2 +- src/libqof/qof/qofbook.cpp | 5 +++-- 7 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/backend/xml/sixtp-dom-generators.cpp b/src/backend/xml/sixtp-dom-generators.cpp index b27ec2282d..11ef34ae27 100644 --- a/src/backend/xml/sixtp-dom-generators.cpp +++ b/src/backend/xml/sixtp-dom-generators.cpp @@ -262,7 +262,7 @@ add_kvp_value_node(xmlNodePtr node, const gchar *tag, KvpValue* val) { case KVP_TYPE_STRING: { - auto newstr = g_strdup(val->get()); + auto newstr = g_strdup(val->get()); val_node = xmlNewTextChild(node, NULL, BAD_CAST tag, checked_char_cast (newstr)); g_free (newstr); diff --git a/src/core-utils/gnc-features.c b/src/core-utils/gnc-features.c index 5b341c9f39..8e733332bc 100644 --- a/src/core-utils/gnc-features.c +++ b/src/core-utils/gnc-features.c @@ -124,7 +124,7 @@ gchar *gnc_features_test_unknown (QofBook *book) g_list_free(features_list); return msg; } - + g_hash_table_unref (features_used); return NULL; } diff --git a/src/libqof/qof/kvp-value.cpp b/src/libqof/qof/kvp-value.cpp index 499b575ad8..d24c6be06c 100644 --- a/src/libqof/qof/kvp-value.cpp +++ b/src/libqof/qof/kvp-value.cpp @@ -80,7 +80,7 @@ KvpValueImpl::get_type() const noexcept return KvpValueType::KVP_TYPE_DOUBLE; else if (datastore.type() == typeid(gnc_numeric)) return KvpValueType::KVP_TYPE_NUMERIC; - else if (datastore.type() == typeid(gchar *)) + else if (datastore.type() == typeid(const gchar *)) return KvpValueType::KVP_TYPE_STRING; else if (datastore.type() == typeid(GncGUID *)) return KvpValueType::KVP_TYPE_GUID; @@ -202,7 +202,7 @@ struct to_string_visitor : boost::static_visitor output << ")"; } - void operator()(char * val) + void operator()(const char * val) { output << "KVP_VALUE_STRING(" << val << ")"; } @@ -243,7 +243,7 @@ struct compare_visitor : boost::static_visitor return 0; } }; -template <> int compare_visitor::operator()(char * const & one, char * const & two) const +template <> int compare_visitor::operator()(const char * const & one, const char * const & two) const { return strcmp(one, two); } @@ -337,8 +337,8 @@ KvpValueImpl::~KvpValueImpl() noexcept void KvpValueImpl::duplicate(const KvpValueImpl& other) noexcept { - if (other.datastore.type() == typeid(gchar *)) - this->datastore = g_strdup(other.get()); + if (other.datastore.type() == typeid(const gchar *)) + this->datastore = g_strdup(other.get()); else if (other.datastore.type() == typeid(GncGUID*)) this->datastore = guid_copy(other.get()); else if (other.datastore.type() == typeid(GList*)) diff --git a/src/libqof/qof/kvp-value.hpp b/src/libqof/qof/kvp-value.hpp index ebd8cb6202..2ab80d3370 100644 --- a/src/libqof/qof/kvp-value.hpp +++ b/src/libqof/qof/kvp-value.hpp @@ -108,7 +108,7 @@ struct KvpValueImpl int64_t, double, gnc_numeric, - char *, + const char*, GncGUID *, Timespec, GList *, diff --git a/src/libqof/qof/kvp_frame.cpp b/src/libqof/qof/kvp_frame.cpp index 3dd415f32f..b60ff162f5 100644 --- a/src/libqof/qof/kvp_frame.cpp +++ b/src/libqof/qof/kvp_frame.cpp @@ -1050,12 +1050,12 @@ kvp_value_get_numeric(const KvpValue * ovalue) return value->get(); } -char * +const char * kvp_value_get_string(const KvpValue * ovalue) { if (!ovalue) return {}; const KvpValueImpl * value {static_cast(ovalue)}; - return value->get(); + return value->get(); } GncGUID * diff --git a/src/libqof/qof/kvp_frame.h b/src/libqof/qof/kvp_frame.h index 8053539a62..7de7dc412a 100644 --- a/src/libqof/qof/kvp_frame.h +++ b/src/libqof/qof/kvp_frame.h @@ -528,7 +528,7 @@ gnc_numeric kvp_value_get_numeric(const KvpValue * value); /** Value accessor. This one is non-copying -- the caller can modify * the value directly. */ -char * kvp_value_get_string(const KvpValue * value); +const char* kvp_value_get_string(const KvpValue * value); /** Value accessor. This one is non-copying -- the caller can modify * the value directly. */ diff --git a/src/libqof/qof/qofbook.cpp b/src/libqof/qof/qofbook.cpp index ebc769454c..68df3997e2 100644 --- a/src/libqof/qof/qofbook.cpp +++ b/src/libqof/qof/qofbook.cpp @@ -1068,7 +1068,7 @@ static void commit_err (G_GNUC_UNUSED QofInstance *inst, QofBackendError errcode static void add_feature_to_hash (const gchar *key, KvpValue *value, gpointer user_data) { - gchar *descr = kvp_value_get_string (value); + gchar *descr = g_strdup(kvp_value_get_string (value)); g_hash_table_insert (*(GHashTable**)user_data, (gchar*)key, descr); } @@ -1076,7 +1076,8 @@ GHashTable * qof_book_get_features (QofBook *book) { KvpFrame *frame = qof_instance_get_slots (QOF_INSTANCE (book)); - GHashTable *features = g_hash_table_new (g_str_hash, g_str_equal); + GHashTable *features = g_hash_table_new_full (g_str_hash, g_str_equal, + NULL, g_free); frame = kvp_frame_get_frame (frame, GNC_FEATURES); kvp_frame_for_each_slot (frame, &add_feature_to_hash, &features); From 0987184709abb675bcf9299c93ab5db8b9bf6c59 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Thu, 18 Jun 2015 13:55:55 -0700 Subject: [PATCH 43/54] Add path-vector get/set functions to KvpFrameImpl. Needed for Scheme access. The C functions used GList. --- src/backend/xml/io-gncxml-v1.cpp | 2 +- src/backend/xml/sixtp-dom-parsers.cpp | 2 +- src/libqof/qof/kvp-value.cpp | 2 +- src/libqof/qof/kvp_frame.cpp | 100 ++++++++++++++------ src/libqof/qof/kvp_frame.h | 6 +- src/libqof/qof/kvp_frame.hpp | 71 ++++++++++++--- src/libqof/qof/test/test-kvp-frame.cpp | 121 ++++++++++++++++++------- 7 files changed, 229 insertions(+), 75 deletions(-) diff --git a/src/backend/xml/io-gncxml-v1.cpp b/src/backend/xml/io-gncxml-v1.cpp index 29fcad6c06..3cfbc9f614 100644 --- a/src/backend/xml/io-gncxml-v1.cpp +++ b/src/backend/xml/io-gncxml-v1.cpp @@ -806,7 +806,7 @@ kvp_frame_slot_end_handler(gpointer data_for_children, if (key_node_count != 1) return(FALSE); value_cr->should_cleanup = TRUE; - f->replace_nc(key, value); + f->set(key, value); if (delete_value) delete value; return(TRUE); diff --git a/src/backend/xml/sixtp-dom-parsers.cpp b/src/backend/xml/sixtp-dom-parsers.cpp index 71a92adb82..49f6311889 100644 --- a/src/backend/xml/sixtp-dom-parsers.cpp +++ b/src/backend/xml/sixtp-dom-parsers.cpp @@ -446,7 +446,7 @@ dom_tree_to_kvp_frame_given(xmlNodePtr node, KvpFrame *frame) if (val) { //We're deleting the old KvpValue returned by replace_nc(). - delete frame->replace_nc(key, val); + delete frame->set(key, val); } else { diff --git a/src/libqof/qof/kvp-value.cpp b/src/libqof/qof/kvp-value.cpp index d24c6be06c..ce79dfc310 100644 --- a/src/libqof/qof/kvp-value.cpp +++ b/src/libqof/qof/kvp-value.cpp @@ -325,7 +325,7 @@ delete_visitor::operator()(GncGUID * & value) template <> void delete_visitor::operator()(KvpFrame * & value) { - kvp_frame_delete(value); + delete value; } KvpValueImpl::~KvpValueImpl() noexcept diff --git a/src/libqof/qof/kvp_frame.cpp b/src/libqof/qof/kvp_frame.cpp index b60ff162f5..e3246c0922 100644 --- a/src/libqof/qof/kvp_frame.cpp +++ b/src/libqof/qof/kvp_frame.cpp @@ -51,11 +51,12 @@ KvpFrameImpl::KvpFrameImpl(const KvpFrameImpl & rhs) noexcept ); } -KvpValueImpl * KvpFrameImpl::replace_nc(const char * key, KvpValueImpl * value) noexcept +KvpValue* +KvpFrameImpl::set(const char* key, KvpValue* value) noexcept { if (!key) return nullptr; auto spot = m_valuemap.find(key); - KvpValueImpl * ret {nullptr}; + KvpValue* ret {nullptr}; if (spot != m_valuemap.end()) { qof_string_cache_remove(spot->first); @@ -72,6 +73,53 @@ KvpValueImpl * KvpFrameImpl::replace_nc(const char * key, KvpValueImpl * value) return ret; } +static inline KvpFrameImpl* +walk_path_or_nullptr(const KvpFrameImpl* frame, Path& path) +{ + KvpFrameImpl* cur_frame = const_cast(frame); + for(auto key:path) + { + auto slot = cur_frame->get_slot(key); + if (slot == nullptr || slot->get_type() != KVP_TYPE_FRAME) + return nullptr; + cur_frame = slot->get(); + } + return cur_frame; +} + + +KvpValue* +KvpFrameImpl::set(Path path, KvpValue* value) noexcept +{ + const char* last_key = path.back(); + path.pop_back(); + auto cur_frame = walk_path_or_nullptr(this, path); + if (cur_frame == nullptr) + return nullptr; + return cur_frame->set(last_key, value); +} + +KvpValue* +KvpFrameImpl::set_path(Path path, KvpValue* value) noexcept +{ + auto cur_frame = this; + const char* last_key = path.back(); + path.pop_back(); + for(auto key:path) + { + auto slot = cur_frame->get_slot(key); + if (slot == nullptr || slot->get_type() != KVP_TYPE_FRAME) + { + auto new_frame = new KvpFrame; + delete cur_frame->set(key, new KvpValue{new_frame}); + cur_frame = new_frame; + continue; + } + cur_frame = slot->get(); + } + return cur_frame->set(last_key, value); +} + std::string KvpFrameImpl::to_string() const noexcept { @@ -131,6 +179,18 @@ KvpFrameImpl::get_slot(const char * key) const noexcept return spot->second; } +KvpValueImpl * +KvpFrameImpl::get_slot(Path path) const noexcept +{ + const char* last_key = path.back(); + path.pop_back(); + auto cur_frame = walk_path_or_nullptr(this, path); + if (cur_frame == nullptr) + return nullptr; + return cur_frame->get_slot(last_key); + +} + int compare(const KvpFrameImpl * one, const KvpFrameImpl * two) noexcept { if (one && !two) return 1; @@ -205,9 +265,7 @@ kvp_frame_get_keys(const KvpFrame * frame) gboolean kvp_frame_is_empty(const KvpFrame * frame) { - if (!frame) return TRUE; - auto realframe = static_cast(frame); - return realframe->get_keys().size() == 0; + return frame->empty(); } KvpFrame * @@ -222,26 +280,20 @@ kvp_frame_copy(const KvpFrame * frame) * removing the key from the KVP tree. */ static KvpValue * -kvp_frame_replace_slot_nc (KvpFrame * frame, const char * slot, - KvpValue * new_value) +kvp_frame_replace_slot_nc (KvpFrame* frame, const char* slot, KvpValue* value) { - if (!frame) return NULL; - - auto realframe = static_cast(frame); - auto realnewvalue = static_cast(new_value); - return realframe->replace_nc(slot, realnewvalue); + if (!frame) return nullptr; + return frame->set(slot, value); } /* Passing in a null value into this routine has the effect * of deleting the old value stored at this slot. */ static inline void -kvp_frame_set_slot_destructively(KvpFrame * frame, const char * slot, - KvpValue * new_value) +kvp_frame_set_slot_destructively(KvpFrame* frame, const char* slot, + KvpValue* value) { - KvpValue * old_value; - old_value = kvp_frame_replace_slot_nc (frame, slot, new_value); - kvp_value_delete (old_value); + delete frame->set(slot, value); } /* ============================================================ */ @@ -584,14 +636,12 @@ void kvp_frame_set_slot(KvpFrame * frame, const char * slot, KvpValue * value) { - KvpValue *new_value = NULL; - + KvpValue* new_value{nullptr}; if (!frame) return; - g_return_if_fail (slot && *slot != '\0'); if (value) new_value = kvp_value_copy(value); - kvp_frame_set_slot_destructively(frame, slot, new_value); + delete frame->set(slot, new_value); } void @@ -599,18 +649,16 @@ kvp_frame_set_slot_nc(KvpFrame * frame, const char * slot, KvpValue * value) { if (!frame) return; - g_return_if_fail (slot && *slot != '\0'); - kvp_frame_set_slot_destructively(frame, slot, value); + frame->set(slot, value); } KvpValue * kvp_frame_get_slot(const KvpFrame * frame, const char * slot) { - if (!frame) return NULL; - auto realframe = static_cast(frame); - return realframe->get_slot(slot); + if (!frame) return nullptr; + return frame->get_slot(slot); } void diff --git a/src/libqof/qof/kvp_frame.h b/src/libqof/qof/kvp_frame.h index 7de7dc412a..fa1acc3770 100644 --- a/src/libqof/qof/kvp_frame.h +++ b/src/libqof/qof/kvp_frame.h @@ -315,10 +315,10 @@ KvpValue * kvp_frame_get_value(const KvpFrame *frame, const gchar *path); * exist. */ /*@ dependent @*/ -KvpFrame * kvp_frame_get_frame(const KvpFrame *frame, const gchar *path); +KvpFrame* kvp_frame_get_frame(const KvpFrame *frame, const gchar *path); -KvpFrame * kvp_frame_get_frame_slash (KvpFrame *frame, - const gchar *path); +KvpFrame* kvp_frame_get_frame_slash (KvpFrame *frame, + const gchar *path); /** @} */ /** @name KvpFrame KvpValue low-level storing routines. diff --git a/src/libqof/qof/kvp_frame.hpp b/src/libqof/qof/kvp_frame.hpp index 3f5e3dcdfc..8d5b43de05 100644 --- a/src/libqof/qof/kvp_frame.hpp +++ b/src/libqof/qof/kvp_frame.hpp @@ -41,9 +41,11 @@ class cstring_comparer } }; +using Path = std::vector; + struct KvpFrameImpl { - typedef std::map map_type; + typedef std::map map_type; public: KvpFrameImpl() noexcept {}; @@ -54,22 +56,67 @@ struct KvpFrameImpl KvpFrameImpl(const KvpFrameImpl &) noexcept; /** - * Replaces the KvpValueImpl at the specified spot, and returns - * the old KvpValueImpl which used to occupy the spot. - * - * If no KvpValueImpl was at the spot, nullptr is returned. + * Set the value with the key in the immediate frame, replacing and + * returning the old value if it exists or nullptr if it doesn't. + * @param key: The key to insert/replace. + * @param newvalue: The value to set at key. + * @return The old value if there was one or nullptr. + */ + KvpValue* set(const char * key, KvpValue* newvalue) noexcept; + /** + * Set the value with the key in a subframe following the keys in path, + * replacing and returning the old value if it exists or nullptr if it + * doesn't. + * @throw invalid_argument if the path doesn't exist. + * @param path: The path of subframes leading to the frame in which to + * insert/replace. + * @param newvalue: The value to set at key. + * @return The old value if there was one or nullptr. + */ + KvpValue* set(Path path, KvpValue* newvalue) noexcept; + /** + * Set the value with the key in a subframe following the keys in path, + * replacing and returning the old value if it exists or nullptr if it + * doesn't. Creates any missing intermediate frames. + * @param path: The path of subframes leading to the frame in which to + * insert/replace. + * @param newvalue: The value to set at key. + * @return The old value if there was one or nullptr. + */ + KvpValue* set_path(Path path, KvpValue* newvalue) noexcept; + /** + * Make a string representation of the frame. Mostly useful for debugging. + * @return A std::string representing the frame and all its children. */ - KvpValueImpl * replace_nc(const char * key, KvpValueImpl * newvalue) noexcept; - std::string to_string() const noexcept; - + /** + * Report the keys in the immediate frame. Be sensible about using this, it + * isn't a very efficient way to iterate. + * @return std::vector of keys as std::strings. + */ std::vector get_keys() const noexcept; - KvpValueImpl * get_slot(const char * key) const noexcept; + /** Get the value for the key or nullptr if it doesn't exist. + * @param key: The key. + * @return The value at the key or nullptr. + */ + KvpValue* get_slot(const char * key) const noexcept; + /** Get the value for the tail of the path or nullptr if it doesn't exist. + * @param path: Path of keys leading to the desired value. + * @return The value at the key or nullptr. + */ + KvpValue* get_slot(Path keys) const noexcept; + /** Convenience wrapper for std::for_each, which should be preferred. + */ + void for_each_slot(void (*proc)(const char *key, KvpValue *value, + void * data), + void *data) const noexcept; - void for_each_slot(void (*proc)(const char *key, KvpValue *value, void * data), void *data) const noexcept; - - friend int compare(const KvpFrameImpl &, const KvpFrameImpl &) noexcept; + /** Test for emptiness + * @return true if the frame contains nothing. + */ + bool empty() const noexcept { return m_valuemap.empty(); } + friend int compare(const KvpFrameImpl&, const KvpFrameImpl&) noexcept; private: map_type m_valuemap; diff --git a/src/libqof/qof/test/test-kvp-frame.cpp b/src/libqof/qof/test/test-kvp-frame.cpp index 432c811f8c..0fa9e45f79 100644 --- a/src/libqof/qof/test/test-kvp-frame.cpp +++ b/src/libqof/qof/test/test-kvp-frame.cpp @@ -27,6 +27,24 @@ #include #include +class KvpFrameTest : public ::testing::Test +{ +public: + KvpFrameTest() : + t_int_val{new KvpValue {INT64_C(15)}}, + t_str_val{new KvpValue{"a value"}} { + auto f1 = new KvpFrame; + t_root.set("top", new KvpValue{f1}); + f1->set("first", t_int_val); + f1->set("second", new KvpValue{new KvpFrame}); + f1->set("third", t_str_val); + } +protected: + KvpFrameImpl t_root; + KvpValue *t_int_val; + KvpValue *t_str_val; +}; + template void assert_contains (std::vector vec, B const & b) { @@ -34,57 +52,98 @@ assert_contains (std::vector vec, B const & b) EXPECT_NE (val, vec.end ()); } -TEST (KvpFrameTest, Replace) +TEST_F (KvpFrameTest, SetLocal) { auto f1 = new KvpFrameImpl; auto v1 = new KvpValueImpl {15.0}; auto v2 = new KvpValueImpl { (int64_t)52}; std::string k1 {"first key"}; - EXPECT_EQ (nullptr, f1->replace_nc (k1.c_str (), v1)); - EXPECT_EQ (v1, f1->replace_nc (k1.c_str (), v2)); + EXPECT_EQ (nullptr, f1->set (k1.c_str (), v1)); + EXPECT_EQ (v1, f1->set (k1.c_str (), v2)); delete f1; //this should also delete v2. delete v1; } -TEST (KvpFrameTest, GetKeys) +TEST_F (KvpFrameTest, SetPath) { - auto k1 = "first key"; - auto k2 = "second key"; - auto k3 = "first key/third key"; - auto f1 = new KvpFrameImpl; - auto v1 = new KvpValueImpl {15.2}; - auto v2 = new KvpValueImpl { (int64_t)12}; - auto v3 = new KvpValueImpl {strdup ("Never again")}; + Path path1 {"top", "second", "twenty-first"}; + Path path2 {"top", "third", "thirty-first"}; + auto v1 = new KvpValueImpl {15.0}; + auto v2 = new KvpValueImpl { (int64_t)52}; - f1->replace_nc (k1, v1); - f1->replace_nc (k2, v2); - f1->replace_nc (k3, v3); + EXPECT_EQ (nullptr, t_root.set(path1, v1)); + EXPECT_EQ (v1, t_root.set(path1, v2)); + EXPECT_EQ (nullptr, t_root.set(path2, v1)); + EXPECT_EQ (v2, t_root.get_slot(path1)); + EXPECT_EQ (nullptr, t_root.get_slot(path2)); + delete v1; +} - auto keys = f1->get_keys (); - EXPECT_EQ (keys.size (), 3); +TEST_F (KvpFrameTest, SetPathWithCreate) +{ + Path path1 {"top", "second", "twenty-first"}; + Path path2 {"top", "third", "thirty-first"}; + auto v1 = new KvpValueImpl {15.0}; + auto v2 = new KvpValueImpl { (int64_t)52}; + + EXPECT_EQ (nullptr, t_root.set_path(path1, v1)); + EXPECT_EQ (v1, t_root.set_path(path1, v2)); + EXPECT_EQ (nullptr, t_root.set_path(path2, v1)); + EXPECT_EQ (v2, t_root.get_slot(path1)); + EXPECT_EQ (v1, t_root.get_slot(path2)); +} + +TEST_F (KvpFrameTest, GetKeys) +{ + auto k1 = "top"; + auto k2 = "first"; + auto k3 = "second"; + + auto keys = t_root.get_keys (); + EXPECT_EQ (keys.size (), 1); assert_contains (keys, k1); + auto frameval = t_root.get_slot(k1); + ASSERT_EQ(frameval->get_type(), KVP_TYPE_FRAME); + keys = frameval->get()->get_keys(); assert_contains (keys, k2); assert_contains (keys, k3); - - delete f1;//This should delete our KvpValueImpls, and our string above, too. } -TEST (KvpFrameTest, GetSlot) +TEST_F (KvpFrameTest, GetLocalSlot) { - auto f1 = new KvpFrameImpl; - auto v1 = new KvpValueImpl {2.2}; - auto v2 = new KvpValueImpl { (int64_t)4}; - auto k1 = "first key"; - auto k2 = "first key/second key"; + auto k1 = "first"; + auto k2 = "third"; + auto k3 = "doesn't exist"; - f1->replace_nc (k1, v1); - EXPECT_EQ (v1, f1->get_slot(k1)); - f1->replace_nc (k2, v2); - EXPECT_EQ (v2, f1->get_slot(k2)); - EXPECT_EQ (v1, f1->get_slot(k1)); - - delete f1;//which will delete both kvpvalues, too. + auto frameval = t_root.get_slot("top"); + ASSERT_EQ(frameval->get_type(), KVP_TYPE_FRAME); + auto f1 = frameval->get(); + EXPECT_EQ (t_int_val, f1->get_slot(k1)); + EXPECT_EQ (t_str_val, f1->get_slot(k2)); + EXPECT_EQ (nullptr, f1->get_slot(k3)); +} + +TEST_F (KvpFrameTest, GetSlotPath) +{ + Path path1 {"top", "second", "twenty-first"}; + Path path2 {"top", "third", "thirty-first"}; + auto v1 = new KvpValueImpl {15.0}; + auto v2 = new KvpValueImpl { (int64_t)52}; + + EXPECT_EQ (nullptr, t_root.set(path1, v1)); + EXPECT_EQ (nullptr, t_root.set(path2, v2)); + EXPECT_EQ (v1, t_root.get_slot(path1)); + EXPECT_EQ (nullptr, t_root.get_slot(path2)); + delete v2; +} + +TEST_F (KvpFrameTest, Empty) +{ + KvpFrameImpl f1, f2; + f2.set("value", new KvpValue {2.2}); + EXPECT_TRUE(f1.empty()); + EXPECT_FALSE(f2.empty()); } From 7c4e1f7f2a0ca83a201038f6fc086566bbcabab7 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Sun, 21 Jun 2015 15:10:33 -0700 Subject: [PATCH 44/54] Fix slash handling in keys. In actual use '/' is a path delimiter indicating a child KvpFrame. The previous implementation created keys for single frames with embedded '/' characters. Memory management issues in make_vector necessitated changing Path to a std::vector>. --- src/backend/xml/test/test-kvp-frames.c | 2 +- src/libqof/qof/kvp_frame.cpp | 83 +++++++++++++++++++------- src/libqof/qof/kvp_frame.hpp | 2 +- src/libqof/qof/test/test-kvp-frame.cpp | 51 ++++++++++++++-- 4 files changed, 110 insertions(+), 28 deletions(-) diff --git a/src/backend/xml/test/test-kvp-frames.c b/src/backend/xml/test/test-kvp-frames.c index 09a58906ae..1727282dba 100644 --- a/src/backend/xml/test/test-kvp-frames.c +++ b/src/backend/xml/test/test-kvp-frames.c @@ -132,7 +132,7 @@ test_kvp_frames1(void) test_val1 = get_random_kvp_value(i % KVP_TYPE_FRAME); test_frame1 = kvp_frame_new(); - test_key = get_random_string(); + test_key = get_random_string_without("/"); kvp_frame_set_slot(test_frame1, test_key, test_val1); diff --git a/src/libqof/qof/kvp_frame.cpp b/src/libqof/qof/kvp_frame.cpp index e3246c0922..8a5b401fb1 100644 --- a/src/libqof/qof/kvp_frame.cpp +++ b/src/libqof/qof/kvp_frame.cpp @@ -39,6 +39,8 @@ extern "C" #include #include +static const char delim = '/'; + KvpFrameImpl::KvpFrameImpl(const KvpFrameImpl & rhs) noexcept { std::for_each(rhs.m_valuemap.begin(), rhs.m_valuemap.end(), @@ -51,12 +53,28 @@ KvpFrameImpl::KvpFrameImpl(const KvpFrameImpl & rhs) noexcept ); } +static inline Path +make_vector(std::string key) +{ + Path path; + for (auto length = key.find(delim); length != std::string::npos;) + { + path.push_back(key.substr(0, length)); + key = key.substr(length + 1); + length = key.find(delim); + } + path.push_back(key); + return path; +} + KvpValue* KvpFrameImpl::set(const char* key, KvpValue* value) noexcept { if (!key) return nullptr; - auto spot = m_valuemap.find(key); + if (strchr(key, delim)) + return set(make_vector(key), value); KvpValue* ret {nullptr}; + auto spot = m_valuemap.find(key); if (spot != m_valuemap.end()) { qof_string_cache_remove(spot->first); @@ -66,7 +84,8 @@ KvpFrameImpl::set(const char* key, KvpValue* value) noexcept if (value) { - auto cachedkey = static_cast(qof_string_cache_insert(key)); + auto cachedkey = + static_cast(qof_string_cache_insert(key)); m_valuemap.insert({cachedkey,value}); } @@ -79,7 +98,7 @@ walk_path_or_nullptr(const KvpFrameImpl* frame, Path& path) KvpFrameImpl* cur_frame = const_cast(frame); for(auto key:path) { - auto slot = cur_frame->get_slot(key); + auto slot = cur_frame->get_slot(key.c_str()); if (slot == nullptr || slot->get_type() != KVP_TYPE_FRAME) return nullptr; cur_frame = slot->get(); @@ -87,37 +106,52 @@ walk_path_or_nullptr(const KvpFrameImpl* frame, Path& path) return cur_frame; } - KvpValue* KvpFrameImpl::set(Path path, KvpValue* value) noexcept { - const char* last_key = path.back(); + auto last_key = path.back(); path.pop_back(); auto cur_frame = walk_path_or_nullptr(this, path); if (cur_frame == nullptr) return nullptr; - return cur_frame->set(last_key, value); + if (last_key.find(delim) != std::string::npos) + return set(make_vector(last_key), value); + return cur_frame->set(last_key.c_str(), value); +} + +static inline KvpFrameImpl* +walk_path_and_create(KvpFrameImpl* frame, Path path) +{ + for(auto key:path) + { + if (key.find(delim) != std::string::npos) + { + frame = walk_path_and_create(frame, make_vector(key)); + continue; + } + auto slot = frame->get_slot(key.c_str()); + if (slot == nullptr || slot->get_type() != KVP_TYPE_FRAME) + { + auto new_frame = new KvpFrame; + delete frame->set(key.c_str(), new KvpValue{new_frame}); + frame = new_frame; + continue; + } + frame = slot->get(); + } + return frame; } KvpValue* KvpFrameImpl::set_path(Path path, KvpValue* value) noexcept { auto cur_frame = this; - const char* last_key = path.back(); + auto last_key = path.back(); path.pop_back(); - for(auto key:path) - { - auto slot = cur_frame->get_slot(key); - if (slot == nullptr || slot->get_type() != KVP_TYPE_FRAME) - { - auto new_frame = new KvpFrame; - delete cur_frame->set(key, new KvpValue{new_frame}); - cur_frame = new_frame; - continue; - } - cur_frame = slot->get(); - } - return cur_frame->set(last_key, value); + cur_frame = walk_path_and_create(const_cast(this), path); + if (last_key.find(delim) != std::string::npos) + return set_path(make_vector(last_key), value); + return cur_frame->set(last_key.c_str(), value); } std::string @@ -173,6 +207,9 @@ KvpFrameImpl::for_each_slot(void (*proc)(const char *key, KvpValue *value, KvpValueImpl * KvpFrameImpl::get_slot(const char * key) const noexcept { + if (!key) return nullptr; + if (strchr(key, delim)) + return get_slot(make_vector(key)); auto spot = m_valuemap.find(key); if (spot == m_valuemap.end()) return nullptr; @@ -182,12 +219,14 @@ KvpFrameImpl::get_slot(const char * key) const noexcept KvpValueImpl * KvpFrameImpl::get_slot(Path path) const noexcept { - const char* last_key = path.back(); + auto last_key = path.back(); path.pop_back(); auto cur_frame = walk_path_or_nullptr(this, path); if (cur_frame == nullptr) return nullptr; - return cur_frame->get_slot(last_key); + if (last_key.find(delim) != std::string::npos) + return get_slot(make_vector(last_key)); + return cur_frame->get_slot(last_key.c_str()); } diff --git a/src/libqof/qof/kvp_frame.hpp b/src/libqof/qof/kvp_frame.hpp index 8d5b43de05..322e9faa0d 100644 --- a/src/libqof/qof/kvp_frame.hpp +++ b/src/libqof/qof/kvp_frame.hpp @@ -41,7 +41,7 @@ class cstring_comparer } }; -using Path = std::vector; +using Path = std::vector; struct KvpFrameImpl { diff --git a/src/libqof/qof/test/test-kvp-frame.cpp b/src/libqof/qof/test/test-kvp-frame.cpp index 0fa9e45f79..3082474235 100644 --- a/src/libqof/qof/test/test-kvp-frame.cpp +++ b/src/libqof/qof/test/test-kvp-frame.cpp @@ -57,10 +57,14 @@ TEST_F (KvpFrameTest, SetLocal) auto f1 = new KvpFrameImpl; auto v1 = new KvpValueImpl {15.0}; auto v2 = new KvpValueImpl { (int64_t)52}; - std::string k1 {"first key"}; + const char* k1 = "first key"; + const char* k2 = "first key/second key"; - EXPECT_EQ (nullptr, f1->set (k1.c_str (), v1)); - EXPECT_EQ (v1, f1->set (k1.c_str (), v2)); + EXPECT_EQ (nullptr, f1->set (k1, v1)); + auto first_frame = new KvpFrame; + EXPECT_EQ (v1, f1->set (k1, new KvpValue{first_frame})); + EXPECT_EQ (nullptr, f1->set(k2, v2)); + EXPECT_EQ (v2, first_frame->get_slot("second key")); delete f1; //this should also delete v2. delete v1; @@ -81,6 +85,24 @@ TEST_F (KvpFrameTest, SetPath) delete v1; } +TEST_F (KvpFrameTest, SetPathSlash) +{ + Path path1 {"top", "second/twenty", "twenty-first"}; + Path path2 {"top", "third", "thirty-first"}; + auto v1 = new KvpValueImpl {15.0}; + auto v2 = new KvpValueImpl { (int64_t)52}; + + EXPECT_EQ (nullptr, t_root.set(path1, v1)); + EXPECT_EQ (nullptr, t_root.set(path1, v2)); + auto second_frame = t_root.get_slot("top")->get()->get_slot("second")->get(); + second_frame->set("twenty", new KvpValue{new KvpFrame}); + EXPECT_EQ (nullptr, t_root.set(path1, v1)); + EXPECT_EQ (v1, t_root.set(path1, v2)); + EXPECT_EQ (v2, t_root.get_slot(path1)); + EXPECT_EQ (nullptr, t_root.get_slot(path2)); + delete v1; +} + TEST_F (KvpFrameTest, SetPathWithCreate) { Path path1 {"top", "second", "twenty-first"}; @@ -95,6 +117,22 @@ TEST_F (KvpFrameTest, SetPathWithCreate) EXPECT_EQ (v1, t_root.get_slot(path2)); } +TEST_F (KvpFrameTest, SetPathWithCreateSlash) +{ + Path path1 {"top", "second/twenty", "twenty-first"}; + Path path2 {"top", "third", "thirty-first"}; + Path path1a {"top", "second", "twenty", "twenty-first"}; + auto v1 = new KvpValueImpl {15.0}; + auto v2 = new KvpValueImpl { (int64_t)52}; + + EXPECT_EQ (nullptr, t_root.set_path(path1, v1)); + EXPECT_EQ (v1, t_root.set_path(path1, v2)); + EXPECT_EQ (nullptr, t_root.set_path(path2, v1)); + EXPECT_EQ (v2, t_root.get_slot(path1)); + EXPECT_EQ (v2, t_root.get_slot(path1a)); + EXPECT_EQ (v1, t_root.get_slot(path2)); +} + TEST_F (KvpFrameTest, GetKeys) { auto k1 = "top"; @@ -117,6 +155,7 @@ TEST_F (KvpFrameTest, GetLocalSlot) auto k1 = "first"; auto k2 = "third"; auto k3 = "doesn't exist"; + auto k4 = "top/first"; auto frameval = t_root.get_slot("top"); ASSERT_EQ(frameval->get_type(), KVP_TYPE_FRAME); @@ -124,12 +163,15 @@ TEST_F (KvpFrameTest, GetLocalSlot) EXPECT_EQ (t_int_val, f1->get_slot(k1)); EXPECT_EQ (t_str_val, f1->get_slot(k2)); EXPECT_EQ (nullptr, f1->get_slot(k3)); + EXPECT_EQ (t_int_val, t_root.get_slot(k4)); } TEST_F (KvpFrameTest, GetSlotPath) { Path path1 {"top", "second", "twenty-first"}; Path path2 {"top", "third", "thirty-first"}; + Path path3 {"top", "second", "twenty", "twenty-first"}; + Path path3a {"top", "second/twenty", "twenty-first"}; auto v1 = new KvpValueImpl {15.0}; auto v2 = new KvpValueImpl { (int64_t)52}; @@ -137,7 +179,8 @@ TEST_F (KvpFrameTest, GetSlotPath) EXPECT_EQ (nullptr, t_root.set(path2, v2)); EXPECT_EQ (v1, t_root.get_slot(path1)); EXPECT_EQ (nullptr, t_root.get_slot(path2)); - delete v2; + t_root.set_path(path3, v1); + EXPECT_EQ (v1, t_root.get_slot(path3a)); } TEST_F (KvpFrameTest, Empty) From 78b5b7cb5be248955d992b749c1b999dd79f432a Mon Sep 17 00:00:00 2001 From: John Ralls Date: Sun, 21 Jun 2015 17:34:36 -0700 Subject: [PATCH 45/54] Convert gnc-slots-sql.cpp to use the Kvp C++ API. Plus a few minor C++11 tweaks. --- src/backend/sql/gnc-backend-sql.c | 1 - src/backend/sql/gnc-slots-sql.cpp | 98 +++++++++++++++---------------- 2 files changed, 48 insertions(+), 51 deletions(-) diff --git a/src/backend/sql/gnc-backend-sql.c b/src/backend/sql/gnc-backend-sql.c index 7d9f748a96..e52a42cf82 100644 --- a/src/backend/sql/gnc-backend-sql.c +++ b/src/backend/sql/gnc-backend-sql.c @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include diff --git a/src/backend/sql/gnc-slots-sql.cpp b/src/backend/sql/gnc-slots-sql.cpp index 1c5f77a19c..28b58edbcf 100644 --- a/src/backend/sql/gnc-slots-sql.cpp +++ b/src/backend/sql/gnc-slots-sql.cpp @@ -33,8 +33,6 @@ extern "C" #include #include -#include - #include "gnc-backend-sql.h" #include "gnc-slots-sql.h" @@ -43,6 +41,9 @@ extern "C" #include "splint-defs.h" #endif } + +#include + /*@ unused @*/ static QofLogModule log_module = G_LOG_DOMAIN; #define TABLE_NAME "slots" @@ -252,7 +253,7 @@ set_slot_from_value( slot_info_t *pInfo, KvpValue *pValue) case FRAME: { gchar *key = get_key_from_path( pInfo->path ); - kvp_frame_set_value_nc( pInfo->pKvpFrame, key, pValue ); + pInfo->pKvpFrame->set(key, pValue); g_free( key ); break; } @@ -266,13 +267,13 @@ set_slot_from_value( slot_info_t *pInfo, KvpValue *pValue) { gchar *key = get_key_from_path( pInfo->path ); gchar *path = get_path_from_path( pInfo->path ); - KvpFrame* frame = pInfo->pKvpFrame; + auto frame = pInfo->pKvpFrame; if ( path ) { - frame = kvp_frame_get_frame_slash( frame, path ); + frame = frame->get_slot(path)->get(); g_free( path ); } - kvp_frame_set_value_nc( frame, key, pValue ); + frame->set(key, pValue); g_free( key ); break; } @@ -349,9 +350,9 @@ get_int64_val( gpointer pObject ) g_return_val_if_fail( pObject != NULL, 0 ); - if ( kvp_value_get_type( pInfo->pKvpValue ) == KVP_TYPE_GINT64 ) + if ( pInfo->pKvpValue->get_type() == KVP_TYPE_GINT64 ) { - return kvp_value_get_gint64( pInfo->pKvpValue ); + return pInfo->pKvpValue->get(); } else { @@ -368,7 +369,7 @@ set_int64_val( gpointer pObject, gint64 value ) g_return_if_fail( pObject != NULL ); if ( pInfo->value_type != KVP_TYPE_GINT64 ) return; - pValue = kvp_value_new_gint64( value ); + pValue = new KvpValue{value}; set_slot_from_value( pInfo, pValue ); } @@ -379,9 +380,9 @@ get_string_val( gpointer pObject ) g_return_val_if_fail( pObject != NULL, NULL ); - if ( kvp_value_get_type( pInfo->pKvpValue ) == KVP_TYPE_STRING ) + if ( pInfo->pKvpValue->get_type() == KVP_TYPE_STRING ) { - return (gpointer)kvp_value_get_string( pInfo->pKvpValue ); + return (gpointer)pInfo->pKvpValue->get(); } else { @@ -393,12 +394,12 @@ static void set_string_val( gpointer pObject, /*@ null @*/ gpointer pValue ) { slot_info_t* pInfo = (slot_info_t*)pObject; - KvpValue *value = NULL; - g_return_if_fail( pObject != NULL ); - if ( pInfo->value_type != KVP_TYPE_STRING || pValue == NULL ) return; - value = kvp_value_new_string( (gchar*)pValue ); + if (pInfo->value_type != KVP_TYPE_STRING || pValue == NULL) + return; + auto string = g_strdup(static_cast(pValue)); + auto value = new KvpValue{string}; set_slot_from_value( pInfo, value ); } @@ -410,9 +411,9 @@ get_double_val( gpointer pObject ) g_return_val_if_fail( pObject != NULL, NULL ); - if ( kvp_value_get_type( pInfo->pKvpValue ) == KVP_TYPE_DOUBLE ) + if (pInfo->pKvpValue->get_type() == KVP_TYPE_DOUBLE) { - d_val = kvp_value_get_double( pInfo->pKvpValue ); + d_val = pInfo->pKvpValue->get(); return (gpointer)&d_val; } else @@ -430,7 +431,7 @@ set_double_val( gpointer pObject, /*@ null @*/ gpointer pValue ) g_return_if_fail( pObject != NULL ); if ( pInfo->value_type != KVP_TYPE_DOUBLE || pValue == NULL ) return; - value = kvp_value_new_double( *((double*)pValue) ); + value = new KvpValue{*(static_cast(pValue))}; set_slot_from_value( pInfo, value ); } @@ -442,7 +443,7 @@ get_timespec_val( gpointer pObject ) g_return_val_if_fail( pObject != NULL, gnc_dmy2timespec( 1, 1, 1970 ) ); //if( kvp_value_get_type( pInfo->pKvpValue ) == KVP_TYPE_TIMESPEC ) { - return kvp_value_get_timespec( pInfo->pKvpValue ); + return pInfo->pKvpValue->get(); } static void @@ -454,7 +455,7 @@ set_timespec_val( gpointer pObject, Timespec ts ) g_return_if_fail( pObject != NULL ); if ( pInfo->value_type != KVP_TYPE_TIMESPEC ) return; - value = kvp_value_new_timespec( ts ); + value = new KvpValue{ts}; set_slot_from_value( pInfo, value ); } @@ -465,9 +466,9 @@ get_guid_val( gpointer pObject ) g_return_val_if_fail( pObject != NULL, NULL ); - if ( kvp_value_get_type( pInfo->pKvpValue ) == KVP_TYPE_GUID ) + if (pInfo->pKvpValue->get_type() == KVP_TYPE_GUID) { - return (gpointer)kvp_value_get_guid( pInfo->pKvpValue ); + return (gpointer)pInfo->pKvpValue->get(); } else { @@ -487,8 +488,8 @@ set_guid_val( gpointer pObject, /*@ null @*/ gpointer pValue ) { case KVP_TYPE_GUID: { - KvpValue *value = kvp_value_new_guid( (GncGUID*)pValue ); - set_slot_from_value( pInfo, value ); + auto new_guid = guid_copy(static_cast(pValue)); + set_slot_from_value(pInfo, new KvpValue{new_guid}); break; } case KVP_TYPE_GLIST: @@ -500,8 +501,8 @@ set_guid_val( gpointer pObject, /*@ null @*/ gpointer pValue ) newInfo->context = LIST; slots_load_info( newInfo ); - pValue = kvp_value_new_glist_nc( newInfo->pList ); - kvp_frame_set_slot_nc(pInfo->pKvpFrame, key, pValue); + pValue = new KvpValue{newInfo->pList}; + pInfo->pKvpFrame->set(key, pValue); g_string_free( newInfo->path, TRUE ); g_slice_free( slot_info_t, newInfo ); g_free( key ); @@ -510,14 +511,14 @@ set_guid_val( gpointer pObject, /*@ null @*/ gpointer pValue ) case KVP_TYPE_FRAME: { slot_info_t *newInfo = slot_info_copy( pInfo, (GncGUID*)pValue ) ; - KvpFrame *newFrame = kvp_frame_new(); + auto newFrame = new KvpFrame; newInfo->pKvpFrame = newFrame; switch ( pInfo->context ) { case LIST: { - KvpValue *value = kvp_value_new_frame_nc( newFrame ); + auto value = new KvpValue{newFrame}; gchar *key = get_key_from_path( pInfo->path ); newInfo->path = g_string_assign( newInfo->path, key ); pInfo->pList = g_list_append( pInfo->pList, value ); @@ -528,7 +529,7 @@ set_guid_val( gpointer pObject, /*@ null @*/ gpointer pValue ) default: { gchar *key = get_key_from_path( pInfo->path ); - kvp_frame_set_frame_nc( pInfo->pKvpFrame, key, newFrame ); + pInfo->pKvpFrame->set(key, new KvpValue{newFrame}); g_free( key ); break; } @@ -552,9 +553,9 @@ get_numeric_val( gpointer pObject ) g_return_val_if_fail( pObject != NULL, gnc_numeric_zero() ); - if ( kvp_value_get_type( pInfo->pKvpValue ) == KVP_TYPE_NUMERIC ) + if (pInfo->pKvpValue->get_type() == KVP_TYPE_NUMERIC) { - return kvp_value_get_numeric( pInfo->pKvpValue ); + return pInfo->pKvpValue->get(); } else { @@ -571,8 +572,7 @@ set_numeric_val( gpointer pObject, gnc_numeric value ) g_return_if_fail( pObject != NULL ); if ( pInfo->value_type != KVP_TYPE_NUMERIC ) return; - pValue = kvp_value_new_numeric( value ); - set_slot_from_value( pInfo, pValue ); + set_slot_from_value(pInfo, new KvpValue{value}); } static GDate* @@ -583,9 +583,9 @@ get_gdate_val( gpointer pObject ) g_return_val_if_fail( pObject != NULL, NULL ); - if ( kvp_value_get_type( pInfo->pKvpValue ) == KVP_TYPE_GDATE ) + if (pInfo->pKvpValue->get_type() == KVP_TYPE_GDATE) { - date = kvp_value_get_gdate( pInfo->pKvpValue ); + date = pInfo->pKvpValue->get(); return &date; } else @@ -603,8 +603,7 @@ set_gdate_val( gpointer pObject, GDate* value ) g_return_if_fail( pObject != NULL ); if ( pInfo->value_type != KVP_TYPE_GDATE ) return; - pValue = kvp_value_new_gdate( *value ); - set_slot_from_value( pInfo, pValue ); + set_slot_from_value(pInfo, new KvpValue{*value}); } static slot_info_t * @@ -649,24 +648,24 @@ save_slot( const gchar* key, KvpValue* value, gpointer data ) (void)g_string_append( pSlot_info->path, "/" ); } (void)g_string_append( pSlot_info->path, key ); - pSlot_info->value_type = kvp_value_get_type( value ); + pSlot_info->value_type = value->get_type(); switch ( pSlot_info->value_type ) { case KVP_TYPE_FRAME: { - KvpFrame* pKvpFrame = kvp_value_get_frame( value ); - GncGUID guid = guid_new_return(); - slot_info_t *pNewInfo = slot_info_copy( pSlot_info, &guid ); + auto pKvpFrame = value->get(); + auto guid = guid_new(); + slot_info_t *pNewInfo = slot_info_copy( pSlot_info, guid ); KvpValue *oldValue = pSlot_info->pKvpValue; - pSlot_info->pKvpValue = kvp_value_new_guid( &guid ); + pSlot_info->pKvpValue = new KvpValue{guid}; pSlot_info->is_ok = gnc_sql_do_db_operation( pSlot_info->be, OP_DB_INSERT, TABLE_NAME, TABLE_NAME, pSlot_info, col_table ); g_return_if_fail( pSlot_info->is_ok ); - kvp_frame_for_each_slot( pKvpFrame, save_slot, pNewInfo ); - kvp_value_delete( pSlot_info->pKvpValue ); + pKvpFrame->for_each_slot(save_slot, pNewInfo); + delete pSlot_info->pKvpValue; pSlot_info->pKvpValue = oldValue; g_string_free( pNewInfo->path, TRUE ); g_slice_free( slot_info_t, pNewInfo ); @@ -674,22 +673,21 @@ save_slot( const gchar* key, KvpValue* value, gpointer data ) break; case KVP_TYPE_GLIST: { - GList *cursor; GncGUID guid = guid_new_return(); slot_info_t *pNewInfo = slot_info_copy( pSlot_info, &guid ); KvpValue *oldValue = pSlot_info->pKvpValue; - pSlot_info->pKvpValue = kvp_value_new_guid( &guid ); + pSlot_info->pKvpValue = new KvpValue{&guid}; pSlot_info->is_ok = gnc_sql_do_db_operation( pSlot_info->be, OP_DB_INSERT, TABLE_NAME, TABLE_NAME, pSlot_info, col_table ); g_return_if_fail( pSlot_info->is_ok ); - for (cursor = kvp_value_get_glist(value); cursor; cursor = cursor->next) + for (auto cursor = value->get(); cursor; cursor = cursor->next) { - KvpValue *val = (KvpValue*)cursor->data; + auto val = static_cast(cursor->data); save_slot("", val, pNewInfo); } - kvp_value_delete( pSlot_info->pKvpValue ); + delete pSlot_info->pKvpValue; pSlot_info->pKvpValue = oldValue; g_string_free( pNewInfo->path, TRUE ); g_slice_free( slot_info_t, pNewInfo ); @@ -727,7 +725,7 @@ gnc_sql_slots_save( GncSqlBackend* be, const GncGUID* guid, gboolean is_infant, slot_info.be = be; slot_info.guid = guid; - kvp_frame_for_each_slot( pFrame, save_slot, &slot_info ); + pFrame->for_each_slot(save_slot, &slot_info); (void)g_string_free( slot_info.path, TRUE ); return slot_info.is_ok; From 9e142124f4f1187446d3d7f7dab5e691a5f6da66 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Mon, 22 Jun 2015 15:00:10 -0700 Subject: [PATCH 46/54] Convert kvp-scm to C++ and to using the KVP C++ API. The binding remains C to simplify interaction of these two functions with SWIG and Scheme. --- po/POTFILES.in | 2 +- src/engine/Makefile.am | 2 +- src/engine/engine-helpers.c | 282 -------------------------- src/engine/{kvp-scm.c => kvp-scm.cpp} | 59 +++--- src/engine/kvp-scm.h | 9 +- 5 files changed, 41 insertions(+), 313 deletions(-) rename src/engine/{kvp-scm.c => kvp-scm.cpp} (60%) diff --git a/po/POTFILES.in b/po/POTFILES.in index ea745f989a..82fe8cb50f 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -184,7 +184,7 @@ src/engine/gnc-pricedb.c src/engine/gnc-session.c src/engine/gncTaxTable.c src/engine/gncVendor.c -src/engine/kvp-scm.c +src/engine/kvp-scm.cpp src/engine/policy.c src/engine/Query.c src/engine/Recurrence.c diff --git a/src/engine/Makefile.am b/src/engine/Makefile.am index 1d5b308bfd..f268547ba9 100644 --- a/src/engine/Makefile.am +++ b/src/engine/Makefile.am @@ -38,7 +38,7 @@ libgncmod_engine_la_SOURCES = \ gnc-session.c \ gncmod-engine.c \ swig-engine.c \ - kvp-scm.c \ + kvp-scm.cpp \ engine-helpers.c \ glib-helpers.c \ policy.c \ diff --git a/src/engine/engine-helpers.c b/src/engine/engine-helpers.c index 58dddbb112..34eb45ff41 100644 --- a/src/engine/engine-helpers.c +++ b/src/engine/engine-helpers.c @@ -38,7 +38,6 @@ #include "guile-mappings.h" #include "gnc-guile-utils.h" #include -#include #include /** \todo Code dependent on the private query headers @@ -668,287 +667,6 @@ gnc_query_path_free (GSList *path) g_slist_free (path); } -static KvpValueType -gnc_scm2KvpValueType (SCM value_type_scm) -{ - return scm_to_int(value_type_scm); -} - -static SCM gnc_kvp_frame2scm (KvpFrame *frame); - -static SCM -gnc_kvp_value2scm (const KvpValue *value) -{ - SCM value_scm = SCM_EOL; - KvpValueType value_t; - SCM scm; - const gchar *string; - - if (!value) return SCM_BOOL_F; - - value_t = kvp_value_get_type (value); - - value_scm = scm_cons (scm_from_long (value_t), value_scm); - - switch (value_t) - { - case KVP_TYPE_GINT64: - scm = scm_from_int64 (kvp_value_get_gint64 (value)); - break; - - case KVP_TYPE_DOUBLE: - scm = scm_from_double (kvp_value_get_double (value)); - break; - - case KVP_TYPE_STRING: - string = kvp_value_get_string (value); - scm = string ? scm_from_utf8_string (string) : SCM_BOOL_F; - break; - - case KVP_TYPE_GUID: - scm = gnc_guid2scm (*kvp_value_get_guid (value)); - break; - - case KVP_TYPE_TIMESPEC: - scm = gnc_timespec2timepair (kvp_value_get_timespec (value)); - break; - - case KVP_TYPE_NUMERIC: - { - gnc_numeric n = kvp_value_get_numeric (value); - scm = gnc_query_numeric2scm (n); - break; - } - - case KVP_TYPE_GLIST: - { - GList *node; - - scm = SCM_EOL; - for (node = kvp_value_get_glist (value); node; node = node->next) - scm = scm_cons (gnc_kvp_value2scm (node->data), scm); - scm = scm_reverse (scm); - break; - } - - case KVP_TYPE_FRAME: - scm = gnc_kvp_frame2scm (kvp_value_get_frame (value)); - break; - - default: - scm = SCM_BOOL_F; - break; - } - - value_scm = scm_cons (scm, value_scm); - - return scm_reverse (value_scm); -} - -typedef struct -{ - SCM scm; -} KVPSCMData; - -static void -kvp_frame_slot2scm (const char *key, KvpValue *value, gpointer data) -{ - KVPSCMData *ksd = data; - SCM value_scm; - SCM key_scm; - SCM pair; - - key_scm = key ? scm_from_utf8_string (key) : SCM_BOOL_F; - value_scm = gnc_kvp_value2scm (value); - pair = scm_cons (key_scm, value_scm); - - ksd->scm = scm_cons (pair, ksd->scm); -} - -static SCM -gnc_kvp_frame2scm (KvpFrame *frame) -{ - KVPSCMData ksd; - - if (!frame) return SCM_BOOL_F; - - ksd.scm = SCM_EOL; - - kvp_frame_for_each_slot (frame, kvp_frame_slot2scm, &ksd); - - return ksd.scm; -} - -static KvpFrame * gnc_scm2KvpFrame (SCM frame_scm); - -static KvpValue * -gnc_scm2KvpValue (SCM value_scm) -{ - KvpValueType value_t; - KvpValue *value = NULL; - SCM type_scm; - SCM val_scm; - - if (!scm_is_list (value_scm) || scm_is_null (value_scm)) - return NULL; - - type_scm = SCM_CAR (value_scm); - value_t = gnc_scm2KvpValueType (type_scm); - - value_scm = SCM_CDR (value_scm); - if (!scm_is_list (value_scm) || scm_is_null (value_scm)) - return NULL; - - val_scm = SCM_CAR (value_scm); - - switch (value_t) - { - case KVP_TYPE_GINT64: - value = kvp_value_new_gint64 (scm_to_int64 (val_scm)); - break; - - case KVP_TYPE_DOUBLE: - value = kvp_value_new_double (scm_to_double (val_scm)); - break; - - case KVP_TYPE_STRING: - { - gchar * str; - str = gnc_scm_to_utf8_string (val_scm); - value = kvp_value_new_string (str); - g_free (str); - break; - } - - case KVP_TYPE_GUID: - { - if (val_scm != SCM_BOOL_F) - { - GncGUID guid = gnc_scm2guid (val_scm); - value = kvp_value_new_guid (&guid); - } - else - value = NULL; - break; - } - - case KVP_TYPE_TIMESPEC: - { - Timespec ts = gnc_timepair2timespec (val_scm); - value = kvp_value_new_timespec(ts); - break; - } - - case KVP_TYPE_GDATE: - { - Timespec ts = gnc_timepair2timespec (val_scm); - value = kvp_value_new_gdate(timespec_to_gdate(ts)); - break; - } - - case KVP_TYPE_NUMERIC: - { - gnc_numeric n; - - if (!gnc_query_numeric_p (val_scm)) - return NULL; - - n = gnc_query_scm2numeric (val_scm); - - value = kvp_value_new_gnc_numeric (n); - break; - } - - case KVP_TYPE_GLIST: - { - GList *list = NULL; - GList *node; - - for (; scm_is_list (val_scm) && !scm_is_null (val_scm); - val_scm = SCM_CDR (val_scm)) - { - SCM scm = SCM_CAR (val_scm); - - list = g_list_prepend (list, gnc_scm2KvpValue (scm)); - } - - list = g_list_reverse (list); - - value = kvp_value_new_glist (list); - - for (node = list; node; node = node->next) - kvp_value_delete (node->data); - g_list_free (list); - break; - } - - case KVP_TYPE_FRAME: - { - KvpFrame *frame; - - frame = gnc_scm2KvpFrame (val_scm); - value = kvp_value_new_frame (frame); - kvp_frame_delete (frame); - break; - } - default: - break; - } - - return value; -} - -static KvpFrame * -gnc_scm2KvpFrame (SCM frame_scm) -{ - KvpFrame * frame; - - if (!scm_is_list (frame_scm)) return NULL; - - frame = kvp_frame_new (); - - for (; scm_is_list (frame_scm) && !scm_is_null (frame_scm); - frame_scm = SCM_CDR (frame_scm)) - { - SCM pair = SCM_CAR (frame_scm); - KvpValue *value; - SCM key_scm; - SCM val_scm; - gchar *key; - - if (!scm_is_pair (pair)) - continue; - - key_scm = SCM_CAR (pair); - val_scm = SCM_CDR (pair); - - if (!scm_is_string (key_scm)) - continue; - - key = scm_to_utf8_string (key_scm); /* key should be freed with free ! - This is automatically taken care - of by scm_dynwind_free below. */ - scm_dynwind_begin (0); - scm_dynwind_free (key); /* free key whenever the dynwind context ends */ - if (!key) - { - scm_dynwind_end (); - continue; - } - value = gnc_scm2KvpValue (val_scm); /* can exit non-locally so justifies - the use of scm_dynwind context - protection */ - if (!value) - { - scm_dynwind_end (); - continue; - } - kvp_frame_set_slot_nc (frame, key, value); - scm_dynwind_end (); - } - - return frame; -} static SCM gnc_queryterm2scm (const QofQueryTerm *qt) diff --git a/src/engine/kvp-scm.c b/src/engine/kvp-scm.cpp similarity index 60% rename from src/engine/kvp-scm.c rename to src/engine/kvp-scm.cpp index 82d0e73967..49e1174229 100644 --- a/src/engine/kvp-scm.c +++ b/src/engine/kvp-scm.cpp @@ -1,14 +1,19 @@ +#include + +extern "C" +{ #include "config.h" #include -#include -#include #include "engine-helpers-guile.h" -#include "kvp-scm.h" #include "guile-mappings.h" #include "gnc-guile-utils.h" #include "swig-runtime.h" +#include "kvp-scm.h" +} + +#include /* NOTE: There are some problems with this approach. Currently, * guids are stored simply as strings in scheme, so some @@ -25,43 +30,40 @@ gnc_scm_to_kvp_value_ptr(SCM val) /* in guile 1.8 (exact? ) only works on numbers */ if (scm_is_exact (val) && gnc_gh_gint64_p(val)) { - return kvp_value_new_gint64(scm_to_int64(val)); + return new KvpValue{scm_to_int64(val)}; } else { - return kvp_value_new_double(scm_to_double(val)); + return new KvpValue{scm_to_double(val)}; } } else if (gnc_numeric_p(val)) { - return kvp_value_new_gnc_numeric(gnc_scm_to_numeric(val)); + return new KvpValue{gnc_scm_to_numeric(val)}; } else if (gnc_guid_p(val)) { - GncGUID tmpguid = gnc_scm2guid(val); - return kvp_value_new_guid(&tmpguid); + auto guid = gnc_scm2guid(val); + auto tmpguid = guid_copy(&guid); + return new KvpValue{tmpguid}; } else if (gnc_timepair_p(val)) { Timespec ts = gnc_timepair2timespec(val); - return kvp_value_new_timespec(ts); + return new KvpValue{ts}; } else if (scm_is_string(val)) { - gchar *newstr; - KvpValue *ret; - newstr = gnc_scm_to_utf8_string (val); - ret = kvp_value_new_string(newstr); - g_free (newstr); - return ret; + return new KvpValue{gnc_scm_to_utf8_string(val)}; } else if (SWIG_IsPointerOfType(val, SWIG_TypeQuery("_p_KvpFrame"))) { #define FUNC_NAME G_STRFUNC - KvpFrame *frame = SWIG_MustGetPtr(val, SWIG_TypeQuery("_p_KvpFrame"), - 1, 0); + auto vp_frame = SWIG_MustGetPtr(val, + SWIG_TypeQuery("_p_KvpFrame"), 1, 0); + KvpFrame *frame = static_cast(vp_frame); #undef FUNC_NAME - return kvp_value_new_frame (frame); + return new KvpValue{frame}; } /* FIXME: add list handler here */ return NULL; @@ -70,41 +72,42 @@ gnc_scm_to_kvp_value_ptr(SCM val) SCM gnc_kvp_value_ptr_to_scm(KvpValue* val) { - const gchar *string; switch (kvp_value_get_type(val)) { case KVP_TYPE_GINT64: - return scm_from_int64(kvp_value_get_gint64(val)); + return scm_from_int64(val->get()); break; case KVP_TYPE_DOUBLE: - return scm_from_double (kvp_value_get_double(val)); + return scm_from_double (val->get()); break; case KVP_TYPE_NUMERIC: - return gnc_numeric_to_scm(kvp_value_get_numeric(val)); + return gnc_numeric_to_scm(val->get()); break; case KVP_TYPE_STRING: - string = kvp_value_get_string(val); + { + auto string = val->get(); return string ? scm_from_utf8_string(string) : SCM_BOOL_F; break; + } case KVP_TYPE_GUID: { - GncGUID *tempguid = kvp_value_get_guid(val); + auto tempguid = kvp_value_get_guid(val); return gnc_guid2scm(*tempguid); } break; case KVP_TYPE_TIMESPEC: - return gnc_timespec2timepair(kvp_value_get_timespec(val)); + return gnc_timespec2timepair(val->get()); break; case KVP_TYPE_FRAME: { - KvpFrame *frame = kvp_value_get_frame(val); - if (frame) + auto frame = val->get(); + if (frame != nullptr) return SWIG_NewPointerObj(frame, SWIG_TypeQuery("_p_KvpFrame"), 0); } break; case KVP_TYPE_GDATE: - return gnc_timespec2timepair(gdate_to_timespec(kvp_value_get_gdate(val))); + return gnc_timespec2timepair(gdate_to_timespec(val->get())); /* FIXME: handle types below */ case KVP_TYPE_GLIST: diff --git a/src/engine/kvp-scm.h b/src/engine/kvp-scm.h index 4bca011620..c8949e86db 100644 --- a/src/engine/kvp-scm.h +++ b/src/engine/kvp-scm.h @@ -1,11 +1,18 @@ #ifndef KVP_SCM_H #define KVP_SCM_H -#include "qof.h" +#ifdef __cplusplus +extern "C" +{ +#endif +#include #include KvpValue* gnc_scm_to_kvp_value_ptr(SCM kvpval); SCM gnc_kvp_value_ptr_to_scm(KvpValue* val); +#ifdef __cplusplus +} +#endif #endif /* KVP_SCM_H */ From fd935d3b8273aaa62890315a631482b5c4e82752 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Tue, 23 Jun 2015 17:09:51 -0700 Subject: [PATCH 47/54] Convert libqof kvp calls to C++. --- src/backend/sql/gnc-slots-sql.cpp | 5 +- src/libqof/qof/gnc-aqbanking-templates.cpp | 64 +++++---- src/libqof/qof/gnc-int128.hpp | 4 + src/libqof/qof/kvp-value.hpp | 2 +- src/libqof/qof/kvp_frame.cpp | 2 - src/libqof/qof/kvp_frame.h | 6 + src/libqof/qof/qofbook-p.h | 2 - src/libqof/qof/qofbook.cpp | 86 ++++++------ src/libqof/qof/qofinstance-p.h | 1 + src/libqof/qof/qofinstance.cpp | 144 ++++++++++----------- 10 files changed, 161 insertions(+), 155 deletions(-) diff --git a/src/backend/sql/gnc-slots-sql.cpp b/src/backend/sql/gnc-slots-sql.cpp index 28b58edbcf..257d30fc7b 100644 --- a/src/backend/sql/gnc-slots-sql.cpp +++ b/src/backend/sql/gnc-slots-sql.cpp @@ -270,10 +270,11 @@ set_slot_from_value( slot_info_t *pInfo, KvpValue *pValue) auto frame = pInfo->pKvpFrame; if ( path ) { - frame = frame->get_slot(path)->get(); + frame->set_path({path, key}, pValue); g_free( path ); } - frame->set(key, pValue); + else + frame->set(key, pValue); g_free( key ); break; } diff --git a/src/libqof/qof/gnc-aqbanking-templates.cpp b/src/libqof/qof/gnc-aqbanking-templates.cpp index 42f45694fe..21bd05760a 100644 --- a/src/libqof/qof/gnc-aqbanking-templates.cpp +++ b/src/libqof/qof/gnc-aqbanking-templates.cpp @@ -30,10 +30,10 @@ extern "C" { #include "gnc-aqbanking-templates.h" -#include "kvp_frame.h" #include "qofinstance-p.h" } +#include "kvp_frame.hpp" #include "gnc-rational.hpp" namespace { @@ -106,18 +106,13 @@ KvpFrame* _GncABTransTempl::make_kvp_frame() { auto frame = kvp_frame_new(); - kvp_frame_set_slot(frame, TT_NAME, kvp_value_new_string(m_name.c_str())); - kvp_frame_set_slot(frame, TT_RNAME, - kvp_value_new_string(m_recipient_name.c_str())); - kvp_frame_set_slot(frame, TT_RACC, - kvp_value_new_string(m_recipient_account.c_str())); - kvp_frame_set_slot(frame, TT_RBCODE, - kvp_value_new_string(m_recipient_bankcode.c_str())); - kvp_frame_set_slot(frame, TT_AMOUNT, kvp_value_new_gnc_numeric(m_amount)); - kvp_frame_set_slot(frame, TT_PURPOS, - kvp_value_new_string(m_purpose.c_str())); - kvp_frame_set_slot(frame, TT_PURPOSCT, - kvp_value_new_string(m_purpose_continuation.c_str())); + frame->set(TT_NAME, new KvpValue(m_name.c_str())); + frame->set(TT_RNAME, new KvpValue(m_recipient_name.c_str())); + frame->set(TT_RACC, new KvpValue(m_recipient_account.c_str())); + frame->set(TT_RBCODE, new KvpValue(m_recipient_bankcode.c_str())); + frame->set(TT_AMOUNT, new KvpValue(m_amount)); + frame->set(TT_PURPOS, new KvpValue(m_purpose.c_str())); + frame->set(TT_PURPOSCT, new KvpValue(m_purpose_continuation.c_str())); return frame; } @@ -141,19 +136,25 @@ GList* gnc_ab_trans_templ_list_new_from_book(QofBook *b) { GList *retval = NULL; - KvpFrame *toplevel = qof_instance_get_slots (QOF_INSTANCE (b)); - KvpFrame *hbci = kvp_frame_get_frame (toplevel, "hbci"); - KvpValue *listval = kvp_frame_get_slot (hbci, "template-list"); - GList *list = kvp_value_get_glist (listval); + auto toplevel = qof_instance_get_slots (QOF_INSTANCE (b)); + auto slot = toplevel->get_slot({"hbci", "template-list"}); + if (slot == nullptr) + return retval; + auto list = slot->get(); for (auto node = list; node != NULL; node = g_list_next (node)) { - KvpFrame *frame = kvp_value_get_frame (static_cast(node->data)); - auto func = [frame](const char* key) - {return kvp_value_get_string(kvp_frame_get_slot(frame, key));}; - auto templ = new _GncABTransTempl (func(TT_NAME), func(TT_RNAME), - func(TT_RACC), func(TT_RBCODE), - kvp_value_get_numeric(kvp_frame_get_slot(frame, TT_AMOUNT)), - func(TT_PURPOS), func(TT_PURPOSCT)); + KvpFrame *frame = static_cast(node->data)->get(); + auto c_func = [frame](const char* key) + { auto slot = frame->get_slot(key); + return slot == nullptr ? std::string("") : std::string(slot->get());}; + auto n_func = [frame](const char* key) + { auto slot = frame->get_slot(key); + return slot == nullptr ? gnc_numeric_zero() : slot->get();}; + auto amt_slot = frame->get_slot(TT_AMOUNT); + auto templ = new _GncABTransTempl (c_func(TT_NAME), c_func(TT_RNAME), + c_func(TT_RACC), c_func(TT_RBCODE), + n_func(TT_AMOUNT), c_func(TT_PURPOS), + c_func(TT_PURPOSCT)); retval = g_list_prepend (retval, templ); } retval = g_list_reverse (retval); @@ -172,6 +173,12 @@ gnc_ab_trans_templ_list_free (GList *l) for(GList *node = l; node != NULL; node = g_list_next(node)) delete static_cast<_GncABTransTempl*>(node->data); } +static void* +copy_list_value(const void* pvalue, void* pdata) +{ + auto new_value = new KvpValue(*static_cast(pvalue)); + return new_value; +} void gnc_ab_set_book_template_list (QofBook *b, GList *template_list) @@ -179,14 +186,15 @@ gnc_ab_set_book_template_list (QofBook *b, GList *template_list) GList *kvp_list = NULL; for (auto node = template_list; node != NULL; node = g_list_next (node)) { - auto value = kvp_value_new_frame_nc (static_cast<_GncABTransTempl*>(node->data)->make_kvp_frame()); + auto templ = static_cast<_GncABTransTempl*>(node->data); + auto value = new KvpValue(templ->make_kvp_frame()); kvp_list = g_list_prepend (kvp_list, value); } kvp_list = g_list_reverse (kvp_list); - auto value = kvp_value_new_glist_nc(kvp_list); + auto value = new KvpValue(g_list_copy_deep(kvp_list, copy_list_value, + nullptr)); KvpFrame *toplevel = qof_instance_get_slots (QOF_INSTANCE (b)); - KvpFrame *hbci = kvp_frame_get_frame (toplevel, "hbci"); - kvp_frame_set_slot_nc (hbci, "template-list", value); + delete toplevel->set_path({"hbci", "template-list"}, value); qof_instance_set_dirty_flag (QOF_INSTANCE (b), TRUE); } diff --git a/src/libqof/qof/gnc-int128.hpp b/src/libqof/qof/gnc-int128.hpp index 47cf69abce..067d395d8e 100644 --- a/src/libqof/qof/gnc-int128.hpp +++ b/src/libqof/qof/gnc-int128.hpp @@ -29,7 +29,11 @@ extern "C" { #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 +#endif +#ifndef __STDC_CONSTANT_MACROS #define __STDC_CONSTANT_MACROS 1 +#endif +#ifndef __STDC_FORMAT_MACROS #define __STDC_FORMAT_MACROS 1 #endif #include diff --git a/src/libqof/qof/kvp-value.hpp b/src/libqof/qof/kvp-value.hpp index 2ab80d3370..c7a96e1f42 100644 --- a/src/libqof/qof/kvp-value.hpp +++ b/src/libqof/qof/kvp-value.hpp @@ -28,13 +28,13 @@ extern "C" { #include "config.h" #include "qof.h" -#include "kvp_frame.h" } #include #if BOOST_VERSION == 105600 #include #endif #include +#include "kvp_frame.h" struct KvpValueImpl { diff --git a/src/libqof/qof/kvp_frame.cpp b/src/libqof/qof/kvp_frame.cpp index 8a5b401fb1..8e8ff35767 100644 --- a/src/libqof/qof/kvp_frame.cpp +++ b/src/libqof/qof/kvp_frame.cpp @@ -1280,8 +1280,6 @@ kvp_frame_to_string(const KvpFrame *frame) return g_strdup(realframe->to_string().c_str()); } -static KvpValue *kvp_value_from_gvalue (const GValue*); - static void gvalue_list_from_kvp_value (KvpValue *kval, gpointer pList) { diff --git a/src/libqof/qof/kvp_frame.h b/src/libqof/qof/kvp_frame.h index fa1acc3770..190aa94a60 100644 --- a/src/libqof/qof/kvp_frame.h +++ b/src/libqof/qof/kvp_frame.h @@ -586,6 +586,12 @@ gchar* kvp_frame_to_string(const KvpFrame *frame); */ GValue* gvalue_from_kvp_value (const KvpValue *kval); +/** Convert a gvalue into a kvpvalue. + * @param gval: A GValue of a type KvpValue can digest. + * @return KvpValue created from the GValue's contents. + */ +KvpValue* kvp_value_from_gvalue (const GValue *gval); + /** KvpItem: GValue Exchange * \brief Transfer of KVP to and from GValue, with the key * diff --git a/src/libqof/qof/qofbook-p.h b/src/libqof/qof/qofbook-p.h index 89071494e4..48e963fd99 100644 --- a/src/libqof/qof/qofbook-p.h +++ b/src/libqof/qof/qofbook-p.h @@ -36,13 +36,11 @@ #ifndef QOF_BOOK_P_H #define QOF_BOOK_P_H -#include "kvp_frame.h" #include "qofbackend.h" #include "qofbook.h" #include "qofid.h" #include "qofid-p.h" #include "qofinstance-p.h" - #ifdef __cplusplus extern "C" { diff --git a/src/libqof/qof/qofbook.cpp b/src/libqof/qof/qofbook.cpp index 68df3997e2..d72cb6d614 100644 --- a/src/libqof/qof/qofbook.cpp +++ b/src/libqof/qof/qofbook.cpp @@ -56,7 +56,7 @@ extern "C" #include "qofid-p.h" #include "qofobject-p.h" #include "qofbookslots.h" -#include "kvp_frame.h" +#include "kvp_frame.hpp" static QofLogModule log_module = QOF_MOD_ENGINE; #define AB_KEY "hbci" @@ -649,11 +649,11 @@ qof_book_get_counter (QofBook *book, const char *counter_name) return -1; } - value = kvp_frame_get_slot_path (kvp, "counters", counter_name, NULL); + value = kvp->get_slot({"counters", counter_name}); if (value) { /* found it */ - return kvp_value_get_gint64 (value); + return value->get(); } else { @@ -703,9 +703,8 @@ qof_book_increment_and_format_counter (QofBook *book, const char *counter_name) /* Save off the new counter */ qof_book_begin_edit(book); - value = kvp_value_new_gint64 (counter); - kvp_frame_set_slot_path (kvp, value, "counters", counter_name, NULL); - kvp_value_delete (value); + value = new KvpValue(counter); + delete kvp->set_path({"counters", counter_name}, value); qof_instance_set_dirty (QOF_INSTANCE (book)); qof_book_commit_edit(book); @@ -753,10 +752,10 @@ qof_book_get_counter_format(const QofBook *book, const char *counter_name) format = NULL; /* Get the format string */ - value = kvp_frame_get_slot_path (kvp, "counter_formats", counter_name, NULL); + value = kvp->get_slot({"counter_formats", counter_name}); if (value) { - format = kvp_value_get_string (value); + format = value->get(); error = qof_book_validate_counter_format(format); if (error != NULL) { @@ -915,19 +914,13 @@ qof_book_get_book_currency (QofBook *book) return NULL; } - /* See if there is a book currency */ - value = kvp_frame_get_slot_path (kvp, - KVP_OPTION_PATH, - OPTION_SECTION_ACCOUNTS, - OPTION_NAME_BOOK_CURRENCY, - NULL); - if (!value) - /* No book-currency */ - { - return NULL; - } + /* See if there is a book currency. */ + value = kvp->get_slot({KVP_OPTION_PATH, OPTION_SECTION_ACCOUNTS, + OPTION_NAME_BOOK_CURRENCY}); + if (!value) /* No book-currency */ + return nullptr; - return kvp_value_get_string (value); + return value->get(); } /** Returns pointer to default gain/loss policy for book, if one exists in the @@ -957,19 +950,14 @@ qof_book_get_default_gains_policy (QofBook *book) } /* See if there is a default gain/loss policy */ - value = kvp_frame_get_slot_path (kvp, - KVP_OPTION_PATH, - OPTION_SECTION_ACCOUNTS, - OPTION_NAME_DEFAULT_GAINS_POLICY, - NULL); + value = kvp->get_slot({KVP_OPTION_PATH, OPTION_SECTION_ACCOUNTS, + OPTION_NAME_DEFAULT_GAINS_POLICY}); if (!value) /* No default gain/loss policy, therefore not valid book-currency accounting method */ - { - return NULL; - } + return nullptr; - return kvp_value_get_string (value); + return g_strdup(value->get()); } @@ -1009,11 +997,8 @@ gboolean qof_book_uses_autoreadonly (const QofBook *book) gint qof_book_get_num_days_autoreadonly (const QofBook *book) { - KvpValue *kvp_val; - double tmp = 0; - KvpFrame *frame = qof_instance_get_slots (QOF_INSTANCE (book)); - g_assert(book); + double tmp; qof_instance_get (QOF_INSTANCE (book), "autoreadonly-days", &tmp, NULL); @@ -1038,16 +1023,18 @@ GDate* qof_book_get_autoreadonly_gdate (const QofBook *book) const char* qof_book_get_string_option(const QofBook* book, const char* opt_name) { - return kvp_frame_get_string(qof_instance_get_slots(QOF_INSTANCE (book)), - opt_name); + auto slot = qof_instance_get_slots(QOF_INSTANCE (book))->get_slot(opt_name); + if (slot == nullptr) + return nullptr; + return slot->get(); } void qof_book_set_string_option(QofBook* book, const char* opt_name, const char* opt_val) { qof_book_begin_edit(book); - kvp_frame_set_string(qof_instance_get_slots(QOF_INSTANCE (book)), - opt_name, opt_val); + auto frame = qof_instance_get_slots(QOF_INSTANCE(book)); + delete frame->set(opt_name, new KvpValue(opt_val)); qof_instance_set_dirty (QOF_INSTANCE (book)); qof_book_commit_edit(book); } @@ -1068,7 +1055,7 @@ static void commit_err (G_GNUC_UNUSED QofInstance *inst, QofBackendError errcode static void add_feature_to_hash (const gchar *key, KvpValue *value, gpointer user_data) { - gchar *descr = g_strdup(kvp_value_get_string (value)); + gchar *descr = g_strdup(value->get()); g_hash_table_insert (*(GHashTable**)user_data, (gchar*)key, descr); } @@ -1079,8 +1066,8 @@ qof_book_get_features (QofBook *book) GHashTable *features = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free); - frame = kvp_frame_get_frame (frame, GNC_FEATURES); - kvp_frame_for_each_slot (frame, &add_feature_to_hash, &features); + frame = frame->get_slot(GNC_FEATURES)->get(); + frame->for_each_slot(&add_feature_to_hash, &features); return features; } @@ -1088,9 +1075,8 @@ void qof_book_set_feature (QofBook *book, const gchar *key, const gchar *descr) { KvpFrame *frame = qof_instance_get_slots (QOF_INSTANCE (book)); - gchar *path = g_strconcat (GNC_FEATURES, key, NULL); qof_book_begin_edit (book); - kvp_frame_set_string (frame, path, descr); + delete frame->set_path({GNC_FEATURES, key}, new KvpValue(descr)); qof_instance_set_dirty (QOF_INSTANCE (book)); qof_book_commit_edit (book); } @@ -1127,9 +1113,11 @@ void qof_book_set_option (QofBook *book, KvpValue *value, GSList *path) { KvpFrame *root = qof_instance_get_slots (QOF_INSTANCE (book)); - KvpFrame *options = kvp_frame_get_frame_slash (root, KVP_OPTION_PATH); + Path path_v {KVP_OPTION_PATH}; + for (auto item = path; item != nullptr; item = g_slist_next(item)) + path_v.push_back(static_cast(item->data)); qof_book_begin_edit (book); - kvp_frame_set_slot_path_gslist (options, value, path); + delete root->set_path(path_v, value); qof_instance_set_dirty (QOF_INSTANCE (book)); qof_book_commit_edit (book); } @@ -1138,15 +1126,19 @@ KvpValue* qof_book_get_option (QofBook *book, GSList *path) { KvpFrame *root = qof_instance_get_slots(QOF_INSTANCE (book)); - KvpFrame *options = kvp_frame_get_frame(root, KVP_OPTION_PATH); - return kvp_frame_get_slot_path_gslist(options, path); + Path path_v {KVP_OPTION_PATH}; + for (auto item = path; item != nullptr; item = g_slist_next(item)) + path_v.push_back(static_cast(item->data)); + return root->get_slot(path_v); } void qof_book_options_delete (QofBook *book) { KvpFrame *root = qof_instance_get_slots(QOF_INSTANCE (book)); - kvp_frame_delete (kvp_frame_get_frame(root, KVP_OPTION_PATH)); + auto option = root->get_slot(KVP_OPTION_PATH); + if (option != nullptr) + delete option->get(); } /* QofObject function implementation and registration */ diff --git a/src/libqof/qof/qofinstance-p.h b/src/libqof/qof/qofinstance-p.h index 3ff5f72f46..16eeee0cce 100644 --- a/src/libqof/qof/qofinstance-p.h +++ b/src/libqof/qof/qofinstance-p.h @@ -115,6 +115,7 @@ void qof_instance_get_kvp (const QofInstance *inst, const gchar *key, GValue *va void qof_instance_copy_kvp (QofInstance *to, const QofInstance *from); void qof_instance_swap_kvp (QofInstance *a, QofInstance *b); int qof_instance_compare_kvp (const QofInstance *a, const QofInstance *b); +/** Returns a g_strdup'd string which must be g_freed. */ char* qof_instance_kvp_as_string (const QofInstance *inst); void qof_instance_kvp_add_guid (const QofInstance *inst, const char* path, const Timespec time, const char* key, diff --git a/src/libqof/qof/qofinstance.cpp b/src/libqof/qof/qofinstance.cpp index 1865b48dd7..e04332c0c3 100644 --- a/src/libqof/qof/qofinstance.cpp +++ b/src/libqof/qof/qofinstance.cpp @@ -39,6 +39,7 @@ extern "C" #include "qofbook-p.h" #include "qofid-p.h" #include "kvp_frame.h" +#include "kvp_frame.hpp" #include "qofinstance-p.h" static QofLogModule log_module = QOF_MOD_ENGINE; @@ -260,7 +261,7 @@ qof_instance_init (QofInstance *inst) priv = GET_PRIVATE(inst); priv->book = NULL; - inst->kvp_data = kvp_frame_new(); + inst->kvp_data = new KvpFrame; priv->last_update.tv_sec = 0; priv->last_update.tv_nsec = -1; priv->editlevel = 0; @@ -335,8 +336,8 @@ qof_instance_finalize_real (GObject *instp) QofInstancePrivate *priv; QofInstance* inst = QOF_INSTANCE(instp); - kvp_frame_delete (inst->kvp_data); - inst->kvp_data = NULL; + delete inst->kvp_data; + inst->kvp_data = nullptr; priv = GET_PRIVATE(inst); priv->editlevel = 0; @@ -587,7 +588,7 @@ qof_instance_set_slots (QofInstance *inst, KvpFrame *frm) priv = GET_PRIVATE(inst); if (inst->kvp_data && (inst->kvp_data != frm)) { - kvp_frame_delete(inst->kvp_data); + delete inst->kvp_data; } priv->dirty = TRUE; @@ -665,7 +666,6 @@ qof_instance_get_dirty_flag (gconstpointer ptr) return GET_PRIVATE(ptr)->dirty; } -/* Watch out: This function is still used (as a "friend") in src/import-export/aqb/gnc-ab-kvp.c */ void qof_instance_set_dirty_flag (gconstpointer inst, gboolean flag) { @@ -1069,19 +1069,19 @@ qof_commit_edit_part2(QofInstance *inst, gboolean qof_instance_has_kvp (QofInstance *inst) { - return (inst->kvp_data != NULL && !kvp_frame_is_empty (inst->kvp_data)); + return (inst->kvp_data != NULL && !inst->kvp_data->empty()); } void qof_instance_set_kvp (QofInstance *inst, const gchar *key, const GValue *value) { - kvp_frame_set_gvalue (inst->kvp_data, key, value); + delete inst->kvp_data->set_path({key}, kvp_value_from_gvalue(value)); } void qof_instance_get_kvp (const QofInstance *inst, const gchar *key, GValue *value) { - GValue *temp = kvp_frame_get_gvalue (inst->kvp_data, key); + auto temp = gvalue_from_kvp_value (inst->kvp_data->get_slot(key)); if (G_IS_VALUE (temp)) { if (G_IS_VALUE (value)) @@ -1095,7 +1095,8 @@ qof_instance_get_kvp (const QofInstance *inst, const gchar *key, GValue *value) void qof_instance_copy_kvp (QofInstance *to, const QofInstance *from) { - to->kvp_data = kvp_frame_copy(from->kvp_data); + delete to->kvp_data; + to->kvp_data = new KvpFrame(*from->kvp_data); } void @@ -1107,40 +1108,39 @@ qof_instance_swap_kvp (QofInstance *a, QofInstance *b) int qof_instance_compare_kvp (const QofInstance *a, const QofInstance *b) { - return kvp_frame_compare (a->kvp_data, b->kvp_data); + return compare(a->kvp_data, b->kvp_data); } char* qof_instance_kvp_as_string (const QofInstance *inst) { - return kvp_frame_to_string (inst->kvp_data); + //The std::string is a local temporary and doesn't survive this function. + return g_strdup(inst->kvp_data->to_string().c_str()); } void qof_instance_kvp_add_guid (const QofInstance *inst, const char* path, - const Timespec time, const char *key, - const GncGUID *guid) + const Timespec time, const char *key, + const GncGUID *guid) { - KvpFrame *slot = NULL, *container = NULL; - /* We're in the process of being destroyed */ g_return_if_fail (inst->kvp_data != NULL); - container = kvp_frame_new(); - kvp_frame_set_guid (container, key, guid); - kvp_frame_set_timespec (container, "date", time); - kvp_frame_add_frame_nc (inst->kvp_data, path, container); + auto container = new KvpFrame; + container->set(key, new KvpValue(const_cast(guid))); + container->set("date", new KvpValue(time)); + delete inst->kvp_data->set_path({path}, new KvpValue(container)); } inline static gboolean kvp_match_guid (KvpValue *v, const char *key, const GncGUID *guid) { - GncGUID *this_guid = NULL; - KvpFrame *frame = kvp_value_get_frame (v); - if (frame == NULL) + if (v->get_type() != KVP_TYPE_FRAME) return FALSE; - this_guid = kvp_frame_get_guid (frame, key); - if (this_guid == NULL) + auto frame = v->get(); + auto val = frame->get_slot(key); + if (val == nullptr || val->get_type() != KVP_TYPE_GUID) return FALSE; + auto this_guid = val->get(); return guid_equal (this_guid, guid); } @@ -1149,24 +1149,23 @@ gboolean qof_instance_kvp_has_guid (const QofInstance *inst, const char *path, const char* key, const GncGUID *guid) { - KvpValue *v = NULL; g_return_val_if_fail (inst->kvp_data != NULL, FALSE); g_return_val_if_fail (guid != NULL, FALSE); - v = kvp_frame_get_value (inst->kvp_data, path); - if (v == NULL) return FALSE; - - switch (kvp_value_get_type (v)) + auto v = inst->kvp_data->get_slot(path); + if (v == nullptr) return FALSE; + + switch (v->get_type()) { case KVP_TYPE_FRAME: return kvp_match_guid (v, key, guid); break; case KVP_TYPE_GLIST: { - GList *list = kvp_value_get_glist (v), *node = NULL; - for (node = list; node != NULL; node = node->next) + auto list = v->get(); + for (auto node = list; node != NULL; node = node->next) { - KvpValue *val = static_cast(node->data); + auto val = static_cast(node->data); if (kvp_match_guid (val, key, guid)) { return TRUE; @@ -1185,35 +1184,32 @@ void qof_instance_kvp_remove_guid (const QofInstance *inst, const char *path, const char *key, const GncGUID *guid) { - KvpValue *v = NULL; g_return_if_fail (inst->kvp_data != NULL); g_return_if_fail (guid != NULL); - v = kvp_frame_get_value (inst->kvp_data, path); + auto v = inst->kvp_data->get_slot(path); if (v == NULL) return; - switch (kvp_value_get_type (v)) + switch (v->get_type()) { case KVP_TYPE_FRAME: if (kvp_match_guid (v, key, guid)) { - kvp_frame_replace_value_nc (inst->kvp_data, path, NULL); - kvp_value_replace_frame_nc (v, NULL); - kvp_value_delete (v); + delete inst->kvp_data->set_path({path}, nullptr); + delete v; } break; case KVP_TYPE_GLIST: { - GList *list = kvp_value_get_glist (v), *node = NULL; - for (node = list; node != NULL; node = node->next) + auto list = v->get(); + for (auto node = list; node != nullptr; node = node->next) { - KvpValue *val = static_cast(node->data); + auto val = static_cast(node->data); if (kvp_match_guid (val, key, guid)) { - kvp_value_replace_frame_nc (val, NULL); list = g_list_delete_link (list, node); - kvp_value_replace_glist_nc (v, list); - kvp_value_delete (val); + v->set(list); + delete val; break; } } @@ -1230,38 +1226,34 @@ void qof_instance_kvp_merge_guids (const QofInstance *target, const QofInstance *donor, const char *path) { - KvpValue *v = NULL; g_return_if_fail (target != NULL); g_return_if_fail (donor != NULL); if (! qof_instance_has_slot (donor, path)) return; - v = kvp_frame_get_value (donor->kvp_data, path); + auto v = donor->kvp_data->get_slot(path); if (v == NULL) return; - switch (kvp_value_get_type (v)) + auto target_val = target->kvp_data->get_slot(path); + switch (v->get_type()) { case KVP_TYPE_FRAME: - kvp_frame_add_frame_nc (target->kvp_data, path, - kvp_value_get_frame (v)); - kvp_value_replace_frame_nc (v, NULL); - kvp_value_delete (v); + if (target_val) + target_val->add(v); + else + target->kvp_data->set_path({path}, v); + donor->kvp_data->set(path, nullptr); //Contents moved, Don't delete! break; case KVP_TYPE_GLIST: - { - GList *list = kvp_value_get_glist (v), *node = NULL; - while (list) + if (target_val) { - KvpValue *val = static_cast(list->data); - kvp_frame_add_frame_nc (target->kvp_data, path, - kvp_value_get_frame (val)); - kvp_value_replace_frame_nc (val, NULL); - list = g_list_remove_link (list, list); - kvp_value_delete (val); + auto list = target_val->get(); + list = g_list_concat(list, v->get()); + target_val->set(list); } - kvp_value_replace_glist_nc (v, list); - kvp_value_delete (v); + else + target->kvp_data->set(path, v); + donor->kvp_data->set(path, nullptr); //Contents moved, Don't delete! break; - } default: PWARN ("Instance KVP on path %s contains the wrong type.", path); break; @@ -1271,29 +1263,33 @@ qof_instance_kvp_merge_guids (const QofInstance *target, gboolean qof_instance_has_slot (const QofInstance *inst, const char *path) { - return kvp_frame_get_value (inst->kvp_data, path) != NULL; + return inst->kvp_data->get_slot(path) != NULL; } void qof_instance_slot_delete (const QofInstance *inst, const char *path) { - kvp_frame_set_frame_nc (inst->kvp_data, path, NULL); + inst->kvp_data->set(path, nullptr); } void qof_instance_slot_delete_if_empty (const QofInstance *inst, const char *path) { - KvpFrame *frame = kvp_frame_get_frame (inst->kvp_data, path); - if (frame && kvp_frame_is_empty (frame)) - kvp_frame_set_frame_nc (inst->kvp_data, path, NULL); + auto slot = inst->kvp_data->get_slot(path); + if (slot) + { + auto frame = slot->get(); + if (frame && frame->empty()) + inst->kvp_data->set(path, nullptr); + } } - +namespace { struct wrap_param { void (*proc)(const char*, const GValue*, void*); void *user_data; }; - +} static void wrap_gvalue_function (const char* key, KvpValue *val, gpointer data) { @@ -1308,10 +1304,12 @@ qof_instance_foreach_slot (const QofInstance *inst, const char* path, void (*proc)(const char*, const GValue*, void*), void* data) { - KvpFrame* frame = kvp_frame_get_frame (inst->kvp_data, path); - if (!frame) return; + auto slot = inst->kvp_data->get_slot(path); + if (slot == nullptr || slot->get_type() != KVP_TYPE_FRAME) + return; + auto frame = slot->get(); wrap_param new_data {proc, data}; - kvp_frame_for_each_slot(frame, wrap_gvalue_function, &new_data); + frame->for_each_slot(wrap_gvalue_function, &new_data); } /* ========================== END OF FILE ======================= */ From 3590de108504c8c44cca7c0ef9875f8e4801a137 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Fri, 26 Jun 2015 12:24:34 -0700 Subject: [PATCH 48/54] Convert tests to C++ and the KVP C++ API. --- ...egration-gtk2-include-directory-back.patch | 41 + src/app-utils/test/Makefile.am | 5 +- ...est-option-util.c => test-option-util.cpp} | 26 +- src/backend/dbi/test/Makefile.am | 4 +- ...dbi-basic.c => test-backend-dbi-basic.cpp} | 66 +- .../{test-dbi-stuff.c => test-dbi-stuff.cpp} | 22 +- src/backend/dbi/test/test-dbi-stuff.h | 9 +- src/backend/xml/test/Makefile.am | 4 +- ...{test-file-stuff.c => test-file-stuff.cpp} | 20 +- src/backend/xml/test/test-file-stuff.h | 12 +- src/backend/xml/test/test-kvp-frames.c | 227 --- src/backend/xml/test/test-kvp-frames.cpp | 196 ++ src/engine/test-core/Makefile.am | 2 +- ...t-engine-stuff.c => test-engine-stuff.cpp} | 154 +- src/engine/test-core/test-engine-stuff.h | 10 +- src/engine/test/Makefile.am | 4 +- src/engine/test/gtest-import-map.cpp | 94 +- .../{utest-Account.c => utest-Account.cpp} | 394 ++-- src/engine/test/utest-Split.cpp | 37 +- ...st-Transaction.c => utest-Transaction.cpp} | 415 ++-- src/libqof/qof/kvp_frame.cpp | 6 + src/libqof/qof/kvp_frame.hpp | 16 +- src/libqof/qof/test/Makefile.am | 3 +- src/libqof/qof/test/test-kvp_frame.c | 1703 ----------------- src/libqof/qof/test/test-qof.c | 2 - ...est-qofinstance.c => test-qofinstance.cpp} | 81 +- src/test-core/test-stuff.h | 31 +- src/test-core/unittest-support.c | 5 +- src/test-core/unittest-support.h | 10 +- 29 files changed, 975 insertions(+), 2624 deletions(-) create mode 100644 0001-Change-gtkmacintegration-gtk2-include-directory-back.patch rename src/app-utils/test/{test-option-util.c => test-option-util.cpp} (92%) rename src/backend/dbi/test/{test-backend-dbi-basic.c => test-backend-dbi-basic.cpp} (91%) rename src/backend/dbi/test/{test-dbi-stuff.c => test-dbi-stuff.cpp} (92%) rename src/backend/xml/test/{test-file-stuff.c => test-file-stuff.cpp} (96%) delete mode 100644 src/backend/xml/test/test-kvp-frames.c create mode 100644 src/backend/xml/test/test-kvp-frames.cpp rename src/engine/test-core/{test-engine-stuff.c => test-engine-stuff.cpp} (92%) rename src/engine/test/{utest-Account.c => utest-Account.cpp} (89%) rename src/engine/test/{utest-Transaction.c => utest-Transaction.cpp} (85%) delete mode 100644 src/libqof/qof/test/test-kvp_frame.c rename src/libqof/qof/test/{test-qofinstance.c => test-qofinstance.cpp} (93%) diff --git a/0001-Change-gtkmacintegration-gtk2-include-directory-back.patch b/0001-Change-gtkmacintegration-gtk2-include-directory-back.patch new file mode 100644 index 0000000000..74774cf779 --- /dev/null +++ b/0001-Change-gtkmacintegration-gtk2-include-directory-back.patch @@ -0,0 +1,41 @@ +From b9de55c8711b07c0fdf83d9838c8a5d65222e887 Mon Sep 17 00:00:00 2001 +From: John Ralls +Date: Sun, 24 May 2015 18:05:04 -0700 +Subject: [PATCH] Change gtkmacintegration-gtk2 include directory back to + gtkmacintegration. + +As of gtk-mac-integration-2.0.8. +--- + src/core-utils/binreloc.c | 2 +- + src/gnome-utils/gnc-main-window.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/core-utils/binreloc.c b/src/core-utils/binreloc.c +index 6a2a55f..4e72494 100644 +--- a/src/core-utils/binreloc.c ++++ b/src/core-utils/binreloc.c +@@ -24,7 +24,7 @@ + #include + #include + #ifdef MAC_INTEGRATION +-#include ++#include + #endif + #endif /* ENABLE_BINRELOC */ + #include +diff --git a/src/gnome-utils/gnc-main-window.c b/src/gnome-utils/gnc-main-window.c +index 89462ef..c77637d 100644 +--- a/src/gnome-utils/gnc-main-window.c ++++ b/src/gnome-utils/gnc-main-window.c +@@ -70,7 +70,7 @@ + #include "gnc-autosave.h" + #include "print-session.h" + #ifdef MAC_INTEGRATION +-#include ++#include + #endif + #ifdef HAVE_SYS_STAT_H + # include +-- +2.2.2 + diff --git a/src/app-utils/test/Makefile.am b/src/app-utils/test/Makefile.am index 4000490d74..c0cf529317 100644 --- a/src/app-utils/test/Makefile.am +++ b/src/app-utils/test/Makefile.am @@ -67,11 +67,10 @@ AM_CPPFLAGS = \ test_app_utils_SOURCES = \ test-app-utils.c \ - test-option-util.c \ + test-option-util.cpp \ test-gnc-ui-util.c - -test_app_utils_CFLAGS = \ +test_app_utils_CXXFLAGS = \ ${DEFAULT_INCLUDES} \ -I${top_srcdir}/${MODULEPATH}/ \ -DTESTPROG=test_app_utils \ diff --git a/src/app-utils/test/test-option-util.c b/src/app-utils/test/test-option-util.cpp similarity index 92% rename from src/app-utils/test/test-option-util.c rename to src/app-utils/test/test-option-util.cpp index 3a261c21aa..16f0f35247 100644 --- a/src/app-utils/test/test-option-util.c +++ b/src/app-utils/test/test-option-util.cpp @@ -21,17 +21,19 @@ * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 * * Boston, MA 02110-1301, USA gnu@gnu.org * ********************************************************************/ - +#include +#include +extern "C" +{ #include #include #include #include -#include - #include "../option-util.h" +} static const gchar *suitename = "/app-utils/option-util"; -void test_suite_option_util (void); +extern "C" void test_suite_option_util (void); typedef struct { @@ -42,7 +44,7 @@ typedef struct /* Expose a mostly-private QofInstance function to load options into * the Book. */ -extern KvpFrame *qof_instance_get_slots (const QofInstance*); +extern "C" KvpFrame *qof_instance_get_slots (const QofInstance*); static void setup (Fixture *fixture, gconstpointer pData) @@ -66,8 +68,8 @@ setup_kvp (Fixture *fixture, gconstpointer pData) "autoreadonly-days", (double)21, NULL); - kvp_frame_set_string (slots, "options/Business/Company Name", - "Bogus Company"); + slots->set_path("options/Business/Company Name", + new KvpValue("Bogus Company")); qof_commit_edit (QOF_INSTANCE (book)); } @@ -205,10 +207,10 @@ test_option_save (Fixture *fixture, gconstpointer pData) OPTION_NAME_AUTO_READONLY_DAYS, 17)); qof_book_save_options (book, gnc_option_db_save, odb, TRUE); - g_assert_cmpstr (kvp_frame_get_string (slots, "options/Accounts/Use Trading Accounts"), == , "t"); - g_assert_cmpstr (kvp_frame_get_string (slots, "options/Accounts/Use Split Action Field for Number"), == , "t"); - g_assert_cmpstr (kvp_frame_get_string (slots, "options/Business/Company Name"), ==, "Bogus Company"); - g_assert_cmpfloat (kvp_frame_get_double (slots, "options/Accounts/Day Threshold for Read-Only Transactions (red line)"), ==, 17); + g_assert_cmpstr (slots->get_slot("options/Accounts/Use Trading Accounts")->get(), == , "t"); + g_assert_cmpstr (slots->get_slot("options/Accounts/Use Split Action Field for Number")->get(), == , "t"); + g_assert_cmpstr (slots->get_slot("options/Business/Company Name")->get(), ==, "Bogus Company"); + g_assert_cmpfloat (slots->get_slot("options/Accounts/Day Threshold for Read-Only Transactions (red line)")->get(), ==, 17); gnc_option_db_destroy (odb); } @@ -232,7 +234,7 @@ test_option_save_book_currency (Fixture *fixture, gconstpointer pData) gnc_option_db_destroy (odb); } -void +extern "C" void test_suite_option_util (void) { GNC_TEST_ADD (suitename, "Option DB Load", Fixture, NULL, setup_kvp, test_option_load, teardown); diff --git a/src/backend/dbi/test/Makefile.am b/src/backend/dbi/test/Makefile.am index ee3308bb66..a2b5b802f0 100644 --- a/src/backend/dbi/test/Makefile.am +++ b/src/backend/dbi/test/Makefile.am @@ -58,8 +58,8 @@ endif test_backend_dbi_SOURCES = \ test-backend-dbi.c \ - test-backend-dbi-basic.c \ - test-dbi-stuff.c \ + test-backend-dbi-basic.cpp \ + test-dbi-stuff.cpp \ test-dbi-business-stuff.c test_backend_dbi_LDFLAGS="-ldbi" diff --git a/src/backend/dbi/test/test-backend-dbi-basic.c b/src/backend/dbi/test/test-backend-dbi-basic.cpp similarity index 91% rename from src/backend/dbi/test/test-backend-dbi-basic.c rename to src/backend/dbi/test/test-backend-dbi-basic.cpp index b692f92cf5..cd00f22435 100644 --- a/src/backend/dbi/test/test-backend-dbi-basic.c +++ b/src/backend/dbi/test/test-backend-dbi-basic.cpp @@ -4,7 +4,10 @@ * Created on: 2011-04-23 * Author: phil */ +#include +extern "C" +{ #include "config.h" #include @@ -12,7 +15,6 @@ #include #include -#include #include #include #include @@ -34,6 +36,7 @@ /* For version_control */ #include #include +} #if LIBDBI_VERSION >= 900 #define HAVE_LIBDBI_R 1 @@ -43,7 +46,7 @@ static dbi_inst dbi_instance = NULL; #endif static const gchar* suitename = "/backend/dbi"; -void test_suite_gnc_backend_dbi (void); +extern "C" void test_suite_gnc_backend_dbi (void); typedef struct { @@ -80,7 +83,6 @@ setup_memory (Fixture *fixture, gconstpointer pData) gchar *url = (gchar*)pData; QofBook* book; Account *root, *acct1, *acct2; - KvpFrame* frame; Transaction* tx; Split *spl1, *spl2; gnc_commodity_table* table; @@ -98,15 +100,16 @@ setup_memory (Fixture *fixture, gconstpointer pData) xaccAccountSetName (acct1, "Bank 1"); xaccAccountSetCommodity (acct1, currency); - frame = qof_instance_get_slots (QOF_INSTANCE(acct1)); - kvp_frame_set_gint64 (frame, "int64-val", 100); - kvp_frame_set_double (frame, "double-val", 3.14159); - kvp_frame_set_numeric (frame, "numeric-val", gnc_numeric_zero()); + auto frame = qof_instance_get_slots (QOF_INSTANCE(acct1)); + frame->set("int64-val", new KvpValue(INT64_C(100))); + frame->set("double-val", new KvpValue(3.14159)); + frame->set("numeric-val", new KvpValue(gnc_numeric_zero())); - kvp_frame_set_timespec (frame, "timespec-val", timespec_now ()); + frame->set("timespec-val", new KvpValue(timespec_now ())); - kvp_frame_set_string (frame, "string-val", "abcdefghijklmnop"); - kvp_frame_set_guid (frame, "guid-val", qof_instance_get_guid (QOF_INSTANCE(acct1))); + frame->set("string-val", new KvpValue("abcdefghijklmnop")); + auto guid = qof_instance_get_guid (QOF_INSTANCE(acct1)); + frame->set("guid-val", new KvpValue(const_cast(guid))); gnc_account_append_child (root, acct1); @@ -228,9 +231,9 @@ destroy_database (gchar* url) gchar *basename = NULL; gint portnum = 0; gchar *port = NULL; - gchar *pgsql = "pgsql"; + auto pgsql = "pgsql"; dbi_conn conn = NULL; - gchar *errfmt = "Unable to delete tables in %s: %s"; + auto errfmt = "Unable to delete tables in %s: %s"; gint fail = 0; dbi_result tables; GSList *list = NULL; @@ -296,11 +299,11 @@ destroy_database (gchar* url) static void teardown (Fixture *fixture, gconstpointer pData) { - gchar *lockfile = g_strdup_printf ("%s/test-dbi.xml.LCK", + auto lockfile = g_strdup_printf ("%s/test-dbi.xml.LCK", g_path_get_dirname (DBI_TEST_XML_FILENAME)); - gchar *msg = g_strdup_printf ("[xml_session_end()] Error on g_unlink(%s): 2: No such file or directory", lockfile); - gchar *logdomain = "gnc.backend"; - guint loglevel = G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL; + auto msg = g_strdup_printf ("[xml_session_end()] Error on g_unlink(%s): 2: No such file or directory", lockfile); + auto logdomain = "gnc.backend"; + auto loglevel = static_cast(G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL); TestErrorStruct *check = test_error_struct_new (logdomain, loglevel, msg); fixture->hdlrs = test_log_set_fatal_handler (fixture->hdlrs, check, (GLogFunc)test_checked_handler); @@ -335,7 +338,8 @@ test_conn_index_functions (QofBackend *qbe) for (iter = index_list; iter != NULL; iter = g_slist_next (iter)) { const char *errmsg; - conn->provider->drop_index (be->conn, iter->data); + conn->provider->drop_index (be->conn, + static_cast(iter->data)); g_assert (DBI_ERROR_NONE == dbi_conn_error (conn->conn, &errmsg)); } @@ -354,9 +358,9 @@ test_dbi_store_and_reload (Fixture *fixture, gconstpointer pData) QofSession* session_3; QofBackend *be; - gchar *msg = "[gnc_dbi_unlock()] There was no lock entry in the Lock table"; - gchar *log_domain = "gnc.backend.dbi"; - guint loglevel = G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL; + auto msg = "[gnc_dbi_unlock()] There was no lock entry in the Lock table"; + auto log_domain = "gnc.backend.dbi"; + auto loglevel = static_cast(G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL); TestErrorStruct *check = test_error_struct_new (log_domain, loglevel, msg); fixture->hdlrs = test_log_set_fatal_handler (fixture->hdlrs, check, (GLogFunc)test_checked_handler); @@ -402,13 +406,13 @@ test_dbi_store_and_reload (Fixture *fixture, gconstpointer pData) static void test_dbi_safe_save (Fixture *fixture, gconstpointer pData) { - gchar *url = (gchar*)pData; + auto url = (gchar*)pData; QofSession *session_1 = NULL, *session_2 = NULL; QofBackend *be; - gchar *msg = "[gnc_dbi_unlock()] There was no lock entry in the Lock table"; - gchar *log_domain = "gnc.backend.dbi"; - guint loglevel = G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL; + auto msg = "[gnc_dbi_unlock()] There was no lock entry in the Lock table"; + auto log_domain = "gnc.backend.dbi"; + auto loglevel = static_cast(G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL); TestErrorStruct *check = test_error_struct_new (log_domain, loglevel, msg); if (fixture->filename) @@ -479,7 +483,7 @@ cleanup: static void test_dbi_version_control (Fixture *fixture, gconstpointer pData) { - gchar *url = (gchar*)pData; + auto url = (gchar*)pData; QofSession *sess; QofBook *book; QofBackend *qbe; @@ -548,9 +552,9 @@ test_dbi_business_store_and_reload (Fixture *fixture, gconstpointer pData) QofSession* session_3; const gchar* url = (gchar*)pData; - gchar *msg = "[gnc_dbi_unlock()] There was no lock entry in the Lock table"; - gchar *log_domain = "gnc.backend.dbi"; - guint loglevel = G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL; + auto msg = "[gnc_dbi_unlock()] There was no lock entry in the Lock table"; + auto log_domain = "gnc.backend.dbi"; + auto loglevel = static_cast(G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL); TestErrorStruct *check = test_error_struct_new (log_domain, loglevel, msg); if (fixture->filename) url = fixture->filename; @@ -577,9 +581,9 @@ test_dbi_business_store_and_reload (Fixture *fixture, gconstpointer pData) } static void -create_dbi_test_suite (gchar *dbm_name, gchar *url) +create_dbi_test_suite (const char *dbm_name, const char *url) { - gchar *subsuite = g_strdup_printf ("%s/%s", suitename, dbm_name); + auto subsuite = g_strdup_printf ("%s/%s", suitename, dbm_name); GNC_TEST_ADD (subsuite, "store_and_reload", Fixture, url, setup, test_dbi_store_and_reload, teardown); GNC_TEST_ADD (subsuite, "safe_save", Fixture, url, setup_memory, @@ -592,7 +596,7 @@ create_dbi_test_suite (gchar *dbm_name, gchar *url) } -void +extern "C" void test_suite_gnc_backend_dbi (void) { dbi_driver driver = NULL; diff --git a/src/backend/dbi/test/test-dbi-stuff.c b/src/backend/dbi/test/test-dbi-stuff.cpp similarity index 92% rename from src/backend/dbi/test/test-dbi-stuff.c rename to src/backend/dbi/test/test-dbi-stuff.cpp index e6ad4a694a..f9e4899aae 100644 --- a/src/backend/dbi/test/test-dbi-stuff.c +++ b/src/backend/dbi/test/test-dbi-stuff.cpp @@ -22,10 +22,10 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. */ - +extern "C" +{ #include #include -#include #include #include #include @@ -38,6 +38,9 @@ #include #include #include "../gnc-backend-dbi-priv.h" +} + +#include G_GNUC_UNUSED static QofLogModule log_module = "test-dbi"; @@ -98,7 +101,7 @@ get_sx_by_guid (QofBook* book, const GncGUID *guid) const GncGUID *sx_guid; sx_guid = qof_instance_get_guid (QOF_INSTANCE(sxitem->data)); if (guid_equal (sx_guid, guid)) - return sxitem->data; + return static_cast(sxitem->data); } return NULL; } @@ -127,7 +130,8 @@ compare_recurrences (GList *rl_1, GList *rl_2) for (ritem1 = rl_1, ritem2 = rl_2; ritem1 != NULL && ritem2 != NULL; ritem1 = g_list_next (ritem1), ritem2 = g_list_next (ritem2)) { - Recurrence *r1 = ritem1->data, *r2 = ritem2->data; + auto r1 = static_cast(ritem1->data); + auto r2 = static_cast(ritem2->data); TEST_GDATES_EQUAL (&r1->start, &r2->start); g_assert_cmpint (r1->ptype, ==, r2->ptype); @@ -185,8 +189,8 @@ compare_single_lot( QofInstance* inst, gpointer user_data ) gnc_lot_get_account (lot_2), FALSE )); g_assert_cmpint (gnc_lot_is_closed (lot_1), ==, gnc_lot_is_closed (lot_2)); - g_assert (kvp_frame_compare (qof_instance_get_slots (QOF_INSTANCE (lot_1)), - qof_instance_get_slots (QOF_INSTANCE (lot_2))) == 0); + g_assert (compare (qof_instance_get_slots (QOF_INSTANCE (lot_1)), + qof_instance_get_slots (QOF_INSTANCE (lot_2))) == 0); splits1 = gnc_lot_get_split_list (lot_1); splits2 = gnc_lot_get_split_list (lot_2); g_assert_cmpint (g_list_length (splits1), ==, g_list_length (splits2)); @@ -197,7 +201,8 @@ compare_single_lot( QofInstance* inst, gpointer user_data ) split2 = xaccSplitLookup (qof_instance_get_guid (split1->data), info->book_2); g_assert (GNC_IS_SPLIT (split2)); - g_assert (xaccSplitEqual (split1->data, split2, TRUE, TRUE, TRUE)); + g_assert (xaccSplitEqual (static_cast(split1->data), + split2, TRUE, TRUE, TRUE)); } } @@ -221,7 +226,8 @@ test_conn_index_functions( QofBackend *qbe ) for ( iter = index_list; iter != NULL; iter = g_slist_next( iter) ) { const char *errmsg; - conn->provider->drop_index (be->conn, iter->data); + conn->provider->drop_index (be->conn, + static_cast(iter->data)); g_assert (DBI_ERROR_NONE == dbi_conn_error( conn->conn, &errmsg)); } diff --git a/src/backend/dbi/test/test-dbi-stuff.h b/src/backend/dbi/test/test-dbi-stuff.h index 92c23badd7..c9a025a92e 100644 --- a/src/backend/dbi/test/test-dbi-stuff.h +++ b/src/backend/dbi/test/test-dbi-stuff.h @@ -25,7 +25,10 @@ #ifndef _TEST_DBI_STUFF_H_ #define _TEST_DBI_STUFF_H_ - +#ifdef __cplusplus +extern "C" +{ +#endif #include "qof.h" typedef struct @@ -37,5 +40,7 @@ typedef struct void compare_books( QofBook* book_1, QofBook* book_2 ); void do_compare( QofBook* book_1, QofBook* book_2, const gchar* id, QofInstanceForeachCB cb, const gchar* msg ); - +#ifdef __cplusplus +} +#endif #endif diff --git a/src/backend/xml/test/Makefile.am b/src/backend/xml/test/Makefile.am index 40c10489ec..b1d24c6ef7 100644 --- a/src/backend/xml/test/Makefile.am +++ b/src/backend/xml/test/Makefile.am @@ -29,7 +29,7 @@ test_kvp_frames_SOURCES = \ ${top_srcdir}/src/backend/xml/sixtp-stack.c \ ${top_srcdir}/src/backend/xml/sixtp-to-dom-parser.c \ ${top_srcdir}/src/backend/xml/gnc-xml-helper.c \ - test-kvp-frames.c + test-kvp-frames.cpp # the xml backend is now a GModule - this test does # not load it as a module and cannot link to it @@ -221,7 +221,7 @@ TESTS_ENVIRONMENT = \ check_LTLIBRARIES = libgnc-test-file-stuff.la -libgnc_test_file_stuff_la_SOURCES = test-file-stuff.c +libgnc_test_file_stuff_la_SOURCES = test-file-stuff.cpp libgnc_test_file_stuff_la_LIBADD = \ ${top_builddir}/src/engine/libgncmod-engine.la diff --git a/src/backend/xml/test/test-file-stuff.c b/src/backend/xml/test/test-file-stuff.cpp similarity index 96% rename from src/backend/xml/test/test-file-stuff.c rename to src/backend/xml/test/test-file-stuff.cpp index c763275f91..86017e0507 100644 --- a/src/backend/xml/test/test-file-stuff.c +++ b/src/backend/xml/test/test-file-stuff.cpp @@ -20,7 +20,10 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. */ +#include +extern "C" +{ #include "config.h" #include @@ -40,13 +43,13 @@ #include "test-stuff.h" #include "io-gncxml-gen.h" #include "sixtp-utils.h" - /* #define __DEBUG 1 */ /***********************************************************************/ extern KvpFrame* dom_tree_to_kvp_frame(xmlNodePtr node); +} static int files_return(int ret, const char* msg) @@ -109,7 +112,7 @@ print_dom_tree(gpointer data_for_children, GSList* data_from_children, if (parent_data == NULL) { xmlElemDump((FILE*)global_data, NULL, (xmlNodePtr)data_for_children); - xmlFreeNode(data_for_children); + xmlFreeNode(static_cast(data_for_children)); } return TRUE; } @@ -252,25 +255,22 @@ equals_node_val_vs_kvp_frame(xmlNodePtr node, const KvpFrame *frm) g_return_val_if_fail(cmpfrm, FALSE); - if (kvp_frame_compare(frm, cmpfrm) == 0) + if (compare(frm, cmpfrm) == 0) { - kvp_frame_delete(cmpfrm); + delete cmpfrm; return TRUE; } else { - gchar *frm1str; - gchar *frm2str; - - frm1str = kvp_frame_to_string(frm); - frm2str = kvp_frame_to_string(cmpfrm); + auto frm1str = g_strdup(frm->to_string().c_str()); + auto frm2str = g_strdup(cmpfrm->to_string().c_str()); printf("%s vs %s\n", frm1str, frm2str); g_free(frm1str); g_free(frm2str); - kvp_frame_delete(cmpfrm); + delete cmpfrm; return FALSE; } } diff --git a/src/backend/xml/test/test-file-stuff.h b/src/backend/xml/test/test-file-stuff.h index 812a0478d1..c2d8d39cd7 100644 --- a/src/backend/xml/test/test-file-stuff.h +++ b/src/backend/xml/test/test-file-stuff.h @@ -4,17 +4,19 @@ #ifndef TEST_FILE_STUFF_H #define TEST_FILE_STUFF_H - +#ifdef __cplusplus +extern "C" +{ +#endif #include -#include #include #include #include #include #include - +typedef struct KvpFrameImpl KvpFrame; void write_dom_node_to_file(xmlNodePtr node, int fd); @@ -40,5 +42,7 @@ void test_files_in_dir(int argc, char **argv, gxpf_callback cb, sixtp *parser, const char *parser_tag, QofBook *book); - +#ifdef __cplusplus +} +#endif #endif diff --git a/src/backend/xml/test/test-kvp-frames.c b/src/backend/xml/test/test-kvp-frames.c deleted file mode 100644 index 1727282dba..0000000000 --- a/src/backend/xml/test/test-kvp-frames.c +++ /dev/null @@ -1,227 +0,0 @@ -#include "config.h" - -#include - -#include "test-stuff.h" -#include "test-engine-stuff.h" -#include "test-file-stuff.h" - -#include "qof.h" - -#include "sixtp-dom-generators.h" -#include "sixtp-dom-parsers.h" - -#define GNC_V2_STRING "gnc-v2" -const gchar *gnc_v2_xml_version_string = GNC_V2_STRING; -extern KvpFrame* dom_tree_to_kvp_frame(xmlNodePtr node); - -static void -test_kvp_get_slot(int run, - KvpFrame *test_frame1, const KvpValue *test_val1, - const gchar *test_key) -{ - const KvpValue *test_val2; - test_val2 = kvp_frame_get_slot(test_frame1, test_key); - if (kvp_value_compare(test_val1, test_val2) == 0) - { - success_args("kvp_frame_get_slot", __FILE__, __LINE__, "run=%d", run); - } - else - { - gchar *tmp; - failure_args("kvp_frame_get_slot", __FILE__, __LINE__, "run=%d", run); - tmp = kvp_value_to_string(test_val2); - printf(" Value is %s\n", tmp); - g_free(tmp); - } -} - -static void -test_kvp_copy_compare(int run, - KvpFrame *test_frame1, const KvpValue *test_val1, - const gchar *test_key) -{ - KvpFrame *test_frame2; - - test_frame2 = kvp_frame_copy(test_frame1); - - do_test_args(test_frame2 != NULL, "kvp_frame_copy", - __FILE__, __LINE__, "run=%d", run); - - if (kvp_frame_compare(test_frame1, test_frame2) == 0) - { - success_args("kvp_frame_copy->kvp_frame_compare", - __FILE__, __LINE__, "run=%d", run); - } - else - { - gchar *tmp; - failure_args("kvp_frame_copy->kvp_frame_compare", - __FILE__, __LINE__, "run=%d", run); - tmp = kvp_frame_to_string(test_frame1); - printf("Frame1 is %s\n", tmp); - g_free(tmp); - tmp = kvp_frame_to_string(test_frame2); - printf("Frame2 is %s\n", tmp); - g_free(tmp); - } - - kvp_frame_delete(test_frame2); -} - -static void -test_kvp_copy_get_slot(int run, - KvpFrame *test_frame1, const KvpValue *test_val1, - const gchar *test_key) -{ - KvpFrame *test_frame2; - const KvpValue *test_val2; - - test_frame2 = kvp_frame_copy(test_frame1); - test_val2 = kvp_frame_get_slot(test_frame2, test_key); - if (kvp_value_compare(test_val1, test_val2) == 0) - { - success_args("kvp_frame_copy->kvp_frame_get_slot", - __FILE__, __LINE__, "run=%d", run); - } - else - { - gchar *tmp; - failure_args("kvp_frame_copy->kvp_frame_get_slot", - __FILE__, __LINE__, "run=%d", run); - tmp = kvp_frame_to_string(test_frame1); - printf("Frame1 is %s\n", tmp); - g_free(tmp); - tmp = kvp_frame_to_string(test_frame2); - printf("Frame2 is %s\n", tmp); - g_free(tmp); - } - kvp_frame_delete(test_frame2); -} - -static void -test_kvp_create_delete(void) -{ - KvpFrame *test_frame; - - test_frame = kvp_frame_new(); - - if (test_frame != NULL) - { - kvp_frame_delete(test_frame); - test_frame = NULL; - success("kvp_frame_new"); - } - else - { - failure("kvp_frame_new"); - } -} - -static void -test_kvp_frames1(void) -{ - int i; - - for (i = 0; i < 20; i++) - { - KvpFrame *test_frame1; - gchar *test_key; - KvpValue *test_val1; - - test_val1 = get_random_kvp_value(i % KVP_TYPE_FRAME); - - test_frame1 = kvp_frame_new(); - test_key = get_random_string_without("/"); - - kvp_frame_set_slot(test_frame1, test_key, test_val1); - - test_kvp_get_slot(i, test_frame1, test_val1, test_key); - test_kvp_copy_compare(i, test_frame1, test_val1, test_key); - test_kvp_copy_get_slot(i, test_frame1, test_val1, test_key); - - kvp_value_delete(test_val1); - g_free(test_key); - kvp_frame_delete(test_frame1); - } -} - -static void -test_kvp_printing(void) -{ - int i; - for (i = 0; i < 20; i++) - { - KvpFrame *ran_frame; - gchar *char_rep; - - ran_frame = get_random_kvp_frame(); - char_rep = kvp_frame_to_string(ran_frame); - - /* if we don't crash it's good :) */ - /* puts(char_rep); */ - - g_free(char_rep); - kvp_frame_delete(ran_frame); - } -} - -static void -test_kvp_xml_stuff(void) -{ - int i; - for (i = 0; i < 20; i++) - { - QofInstance *inst = g_object_new (QOF_TYPE_INSTANCE, NULL); - KvpFrame *test_frame2; - xmlNodePtr test_node; - - inst->kvp_data = get_random_kvp_frame(); - - test_node = qof_instance_slots_to_dom_tree("test-kvp", inst); - - if (!test_node) - { - failure_args("xml stuff", __FILE__, __LINE__, - "kvp_frame_to_dom_tree produced NULL"); - } - else - { - test_frame2 = dom_tree_to_kvp_frame(test_node); - - if (kvp_frame_compare(inst->kvp_data, test_frame2) == 0) - { - success("xml stuff"); - } - else - { - gchar *tmp; - failure("xml stuff"); - tmp = kvp_frame_to_string(inst->kvp_data); - printf(" with kvp_frame 1:\n%s\n", tmp); - g_free(tmp); - printf(" and xml:\n"); - xmlElemDump(stdout, NULL, test_node); - printf("\n"); - tmp = kvp_frame_to_string(test_frame2); - printf(" and kvp_frame 2:\n%s\n", tmp); - g_free(tmp); - } - kvp_frame_delete(test_frame2); - xmlFreeNode(test_node); - } - g_object_unref (inst); - } -} - -int -main(int argc, char** argv) -{ - qof_init(); - test_kvp_create_delete(); - test_kvp_printing(); - test_kvp_frames1(); - test_kvp_xml_stuff(); - print_test_results(); - exit(get_rv()); -} diff --git a/src/backend/xml/test/test-kvp-frames.cpp b/src/backend/xml/test/test-kvp-frames.cpp new file mode 100644 index 0000000000..7c13ca8d0c --- /dev/null +++ b/src/backend/xml/test/test-kvp-frames.cpp @@ -0,0 +1,196 @@ +#include + +extern "C" +{ +#include "config.h" + +#include + +#include "test-stuff.h" +#include "test-engine-stuff.h" +#include "test-file-stuff.h" + +#include "qof.h" + +#include "sixtp-dom-generators.h" +#include "sixtp-dom-parsers.h" + +#define GNC_V2_STRING "gnc-v2" +const gchar *gnc_v2_xml_version_string = GNC_V2_STRING; +extern KvpFrame* dom_tree_to_kvp_frame(xmlNodePtr node); +} + +static void +test_kvp_get_slot(int run, + KvpFrame *test_frame1, const KvpValue *test_val1, + const gchar *test_key) +{ + auto test_val2 = test_frame1->get_slot(test_key); + auto msg = "KvpFrame::get_slot"; + if (compare(test_val1, test_val2) == 0) + { + success_args(msg, __FILE__, __LINE__, "run=%d", run); + } + else + { + gchar *tmp; + failure_args(msg, __FILE__, __LINE__, "run=%d", run); + printf(" Value is %s\n", test_val2->to_string()); + } +} + +static void +test_kvp_copy_compare(int run, + KvpFrame *test_frame1, const KvpValue *test_val1, + const gchar *test_key) +{ + auto test_frame2 = new KvpFrame(*test_frame1); + auto msg = "compare after KvpFrame copy construction"; + do_test_args(test_frame2 != NULL, "KvpFrame Copy Constructor", + __FILE__, __LINE__, "run=%d", run); + + if (compare(test_frame1, test_frame2) == 0) + { + success_args(msg, __FILE__, __LINE__, "run=%d", run); + } + else + { + gchar *tmp; + failure_args(msg, __FILE__, __LINE__, "run=%d", run); + printf("Frame1 is %s\n", test_frame1->to_string().c_str()); + printf("Frame2 is %s\n",test_frame2->to_string().c_str()); + } + + delete test_frame2; +} + +static void +test_kvp_copy_get_slot(int run, + KvpFrame *test_frame1, const KvpValue *test_val1, + const gchar *test_key) +{ + auto test_frame2 = new KvpFrame(*test_frame1); + auto test_val2 = test_frame2->get_slot(test_key); + auto msg = "KvpFrame::get_slot() from a copy-constructed frame"; + if (compare(test_val1, test_val2) == 0) + { + success_args(msg, __FILE__, __LINE__, "run=%d", run); + } + else + { + gchar *tmp; + failure_args(msg, __FILE__, __LINE__, "run=%d", run); + printf("Frame1 is %s\n", test_frame1->to_string().c_str()); + printf("Frame2 is %s\n", test_frame2->to_string().c_str()); + } + delete test_frame2; +} + +static void +test_kvp_create_delete(void) +{ + auto test_frame = new KvpFrame; + auto msg = "KvpFrame default constructor"; + if (test_frame != nullptr) + { + delete test_frame; + test_frame = nullptr; + success(msg); + } + else + { + failure(msg); + } +} + +static void +test_kvp_frames1(void) +{ + int i; + + for (i = 0; i < 20; i++) + { + auto test_val1 = get_random_kvp_value(i % KVP_TYPE_FRAME); + auto test_frame1 = new KvpFrame; + auto test_key = get_random_string_without("/"); + + test_frame1->set(test_key, test_val1); + + test_kvp_get_slot(i, test_frame1, test_val1, test_key); + test_kvp_copy_compare(i, test_frame1, test_val1, test_key); + test_kvp_copy_get_slot(i, test_frame1, test_val1, test_key); + + delete test_val1; + g_free(test_key); + delete test_frame1; + } +} + +static void +test_kvp_printing(void) +{ + int i; + for (i = 0; i < 20; i++) + { + auto ran_frame = get_random_kvp_frame(); + assert(!ran_frame->to_string().empty()); + delete ran_frame; + } +} + +static void +test_kvp_xml_stuff(void) +{ + int i; + for (i = 0; i < 20; i++) + { + auto inst = static_cast(g_object_new (QOF_TYPE_INSTANCE, NULL)); + KvpFrame *test_frame2; + xmlNodePtr test_node; + + inst->kvp_data = get_random_kvp_frame(); + auto msg = "XML Stuff"; + + test_node = qof_instance_slots_to_dom_tree("test-kvp", inst); + + if (!test_node) + { + failure_args("xml stuff", __FILE__, __LINE__, + "kvp_frame_to_dom_tree produced NULL"); + } + else + { + test_frame2 = dom_tree_to_kvp_frame(test_node); + + if (compare(inst->kvp_data, test_frame2) == 0) + { + success(msg); + } + else + { + failure(msg); + printf(" With KvpFrame 1:\n%s\n", + inst->kvp_data->to_string().c_str()); + printf(" and XML:\n"); + xmlElemDump(stdout, NULL, test_node); + printf("\n and kvp_frame 2:\n%s\n", + test_frame2->to_string().c_str()); + } + delete test_frame2; + xmlFreeNode(test_node); + } + g_object_unref (inst); + } +} + +int +main(int argc, char** argv) +{ + qof_init(); + test_kvp_create_delete(); + test_kvp_printing(); + test_kvp_frames1(); + test_kvp_xml_stuff(); + print_test_results(); + exit(get_rv()); +} diff --git a/src/engine/test-core/Makefile.am b/src/engine/test-core/Makefile.am index 76618e7e9b..928f79abaf 100644 --- a/src/engine/test-core/Makefile.am +++ b/src/engine/test-core/Makefile.am @@ -6,7 +6,7 @@ LDADD = \ ${top_builddir}/src/libqof/qof/libgnc-qof.la \ ${GLIB_LIBS} -libgncmod_test_engine_la_SOURCES = gncmod-test-engine.c test-engine-stuff.c +libgncmod_test_engine_la_SOURCES = gncmod-test-engine.c test-engine-stuff.cpp libgncmod_test_engine_la_LDFLAGS = -module libgncmod_test_engine_la_LIBADD = \ ${top_builddir}/src/gnc-module/libgnc-module.la \ diff --git a/src/engine/test-core/test-engine-stuff.c b/src/engine/test-core/test-engine-stuff.cpp similarity index 92% rename from src/engine/test-core/test-engine-stuff.c rename to src/engine/test-core/test-engine-stuff.cpp index 0969bfbc3b..6955f7b808 100644 --- a/src/engine/test-core/test-engine-stuff.c +++ b/src/engine/test-core/test-engine-stuff.cpp @@ -15,6 +15,10 @@ * Created by Linux Developers Group, 2001 * Updates Linas Vepstas July 2004 */ +#include + +extern "C" +{ #include "config.h" #include @@ -44,6 +48,7 @@ #include "test-engine-stuff.h" #include "test-stuff.h" #include "test-engine-strings.h" +} static gboolean glist_strings_only = FALSE; @@ -128,12 +133,6 @@ kvp_type_excluded (KvpValueType kvp_type) return FALSE; } -void -random_glist_strings_only (gboolean strings_only) -{ - glist_strings_only = strings_only; -} - static gboolean zero_nsec = FALSE; void @@ -189,14 +188,11 @@ get_random_glist_depth (gint depth) for (i = 0; i < count; i++) { - KvpValueType kvpt; - KvpValue *value; - - kvpt = glist_strings_only ? KVP_TYPE_STRING : -2; + KvpValue *value = nullptr; do { - value = get_random_kvp_value_depth (kvpt, depth + 1); + value = get_random_kvp_value_depth (-2, depth + 1); } while (!value); @@ -206,12 +202,6 @@ get_random_glist_depth (gint depth) return ret; } -GList* -get_random_glist(void) -{ - return get_random_glist_depth (0); -} - /* ========================================================== */ /* Time/Date, GncGUID data stuff */ @@ -248,19 +238,21 @@ static KvpFrame* get_random_kvp_frame_depth (gint depth); static KvpValue* get_random_kvp_value_depth (int type, gint depth) { - int datype = type; + KvpValueType datype; KvpValue *ret; - if (datype == -1) + if (type == -1) { - datype = get_random_int_in_range(KVP_TYPE_GINT64, KVP_TYPE_FRAME); + datype = static_cast(get_random_int_in_range(KVP_TYPE_GINT64, KVP_TYPE_FRAME)); } - if (datype == -2) + else if (type == -2) { - datype = get_random_int_in_range(KVP_TYPE_GINT64, KVP_TYPE_FRAME - 1); + datype = static_cast(get_random_int_in_range(KVP_TYPE_GINT64, KVP_TYPE_FRAME - 1)); } - + else + datype = static_cast(type); + if (datype == KVP_TYPE_FRAME && depth >= kvp_max_depth) return NULL; @@ -496,13 +488,13 @@ get_random_commodity_from_table (gnc_commodity_table *table) GList *commodities; char *name_space; - name_space = get_random_list_element (namespaces); + name_space = static_cast(get_random_list_element (namespaces)); commodities = gnc_commodity_table_get_commodities (table, name_space); if (!commodities) continue; - com = get_random_list_element (commodities); + com = static_cast(get_random_list_element (commodities)); g_list_free (commodities); @@ -604,7 +596,7 @@ make_random_changes_to_commodity_table (gnc_commodity_table *table) for (node = namespaces; node; node = node->next) { - const char *ns = node->data; + auto ns = static_cast(node->data); GList *commodities; GList *com_node; @@ -615,7 +607,7 @@ make_random_changes_to_commodity_table (gnc_commodity_table *table) for (com_node = commodities; com_node; com_node = com_node->next) { - gnc_commodity *com = com_node->data; + auto com = static_cast(com_node->data); gnc_commodity_table_remove (table, com); make_random_changes_to_commodity (com); @@ -748,7 +740,7 @@ get_random_pricedb(QofBook *book) static gboolean price_accumulator (GNCPrice *p, gpointer data) { - GList **list = data; + auto list = static_cast(data); *list = g_list_prepend (*list, p); @@ -767,7 +759,7 @@ make_random_changes_to_pricedb (QofBook *book, GNCPriceDB *pdb) for (node = list; node; node = node->next) { - GNCPrice *p = node->data; + auto p = static_cast(node->data); switch (get_random_int_in_range (0, 5)) { @@ -898,7 +890,6 @@ get_random_account_tree (QofBook *book) static void add_random_splits(QofBook *book, Transaction *trn, GList *account_list) { - Account *acc, *bcc; Split *s1, *s2; gnc_numeric val; int s2_scu; @@ -906,11 +897,11 @@ add_random_splits(QofBook *book, Transaction *trn, GList *account_list) /* Gotta have at least two different accounts */ if (1 >= g_list_length (account_list)) return; - acc = get_random_list_element (account_list); + auto acc = static_cast(get_random_list_element (account_list)); xaccTransBeginEdit(trn); s1 = get_random_split(book, acc, trn); - bcc = get_random_list_element (account_list); + auto bcc = static_cast(get_random_list_element (account_list)); if ((bcc == acc) && (!do_bork())) { /* Make sure that each side of the transaction is in @@ -919,7 +910,7 @@ add_random_splits(QofBook *book, Transaction *trn, GList *account_list) * this case? */ while (bcc == acc) { - bcc = get_random_list_element (account_list); + bcc = static_cast(get_random_list_element (account_list)); } } @@ -994,10 +985,8 @@ make_random_changes_to_transaction_and_splits (QofBook *book, splits = xaccTransGetSplitList (trans); for (node = splits; node; node = node->next) { - Split *split = node->data; - Account *account; - - account = get_random_list_element (accounts); + auto split = static_cast(node->data); + auto account = static_cast(get_random_list_element (accounts)); xaccAccountInsertSplit (account, split); } @@ -1022,7 +1011,7 @@ make_random_changes_to_transaction_and_splits (QofBook *book, splits = xaccTransGetSplitList (trans); for (node = splits; node; node = node->next) { - Split *split = node->data; + auto split = static_cast(node->data); if (get_random_boolean ()) make_random_changes_to_split (split); @@ -1038,7 +1027,7 @@ static int add_trans_helper (Transaction *trans, gpointer data) { TransInfo *ti; - GList **list = data; + auto list = static_cast(data); ti = g_new (TransInfo, 1); @@ -1069,7 +1058,7 @@ make_random_changes_to_level (QofBook *book, Account *parent) gnc_account_append_child (parent, new_account); else { - account = get_random_list_element (accounts); + account = static_cast(get_random_list_element (accounts)); gnc_account_append_child (account, new_account); } @@ -1083,7 +1072,7 @@ make_random_changes_to_level (QofBook *book, Account *parent) /* Mess with the accounts */ for (node = accounts; node; node = node->next) { - Account *account = node->data; + auto account = static_cast(node->data); if (get_random_boolean ()) make_random_changes_to_account (book, account); @@ -1095,7 +1084,7 @@ make_random_changes_to_level (QofBook *book, Account *parent) for (node = transes; node; node = node->next) { - TransInfo *ti = node->data; + auto ti = static_cast(node->data); Transaction *trans = xaccTransLookup (&ti->guid, book); if (!trans) @@ -1106,7 +1095,7 @@ make_random_changes_to_level (QofBook *book, Account *parent) for (node = transes; node; node = node->next) { - TransInfo *ti = node->data; + auto ti = static_cast(node->data); g_free (ti); } @@ -1114,18 +1103,18 @@ make_random_changes_to_level (QofBook *book, Account *parent) transes = NULL; /* delete an account */ - account = get_random_list_element (accounts); + account = static_cast(get_random_list_element (accounts)); splits = xaccAccountGetSplitList (account); splits = g_list_copy (splits); for (node = splits; node; node = node->next) { - Split *split = node->data; + auto split = static_cast(node->data); do { - new_account = get_random_list_element (accounts); + new_account = static_cast(get_random_list_element (accounts)); } while (new_account == account); @@ -1147,12 +1136,12 @@ make_random_changes_to_level (QofBook *book, Account *parent) while (i--) { - Account *a1, *a2; + Account *a2; - a1 = get_random_list_element (accounts); + auto a1 = static_cast(get_random_list_element (accounts)); if (get_random_boolean ()) - a2 = get_random_list_element (accounts); + a2 = static_cast(get_random_list_element (accounts)); else a2 = NULL; @@ -1191,7 +1180,7 @@ get_random_account(QofBook *book) sane_account_names); tmp_int = get_random_int_in_range(ACCT_TYPE_BANK, NUM_ACCOUNT_TYPES - 1); - xaccAccountSetType(ret, tmp_int); + xaccAccountSetType(ret, static_cast(tmp_int)); set_account_random_string(ret, xaccAccountSetCode); set_account_random_string(ret, xaccAccountSetDescription); @@ -1224,7 +1213,7 @@ make_random_changes_to_account (QofBook *book, Account *account) set_account_random_string (account, xaccAccountSetName); tmp_int = get_random_int_in_range (ACCT_TYPE_BANK, NUM_ACCOUNT_TYPES - 1); - xaccAccountSetType (account, tmp_int); + xaccAccountSetType (account, static_cast(tmp_int)); set_account_random_string (account, xaccAccountSetCode); set_account_random_string (account, xaccAccountSetDescription); @@ -1387,7 +1376,7 @@ set_tran_random_string(Transaction* trn, void(*func)(Transaction *act, const gchar*str)) { gchar *tmp_str = get_random_string(); - if (!trn || !(&trn->inst)) + if (!trn) { return; } @@ -1660,7 +1649,7 @@ set_query_sort (QofQuery *q, sort_type_t sort_code) { GSList *p1 = NULL, *p2 = NULL, *p3 = NULL, *standard; - standard = g_slist_prepend (NULL, QUERY_DEFAULT_SORT); + standard = g_slist_prepend (NULL, const_cast(QUERY_DEFAULT_SORT)); switch (sort_code) { @@ -1668,36 +1657,36 @@ set_query_sort (QofQuery *q, sort_type_t sort_code) p1 = standard; break; case BY_DATE: - p1 = g_slist_prepend (p1, TRANS_DATE_POSTED); - p1 = g_slist_prepend (p1, SPLIT_TRANS); + p1 = g_slist_prepend (p1, const_cast(TRANS_DATE_POSTED)); + p1 = g_slist_prepend (p1, const_cast(SPLIT_TRANS)); p2 = standard; break; case BY_DATE_ENTERED: - p1 = g_slist_prepend (p1, TRANS_DATE_ENTERED); - p1 = g_slist_prepend (p1, SPLIT_TRANS); + p1 = g_slist_prepend (p1, const_cast(TRANS_DATE_ENTERED)); + p1 = g_slist_prepend (p1, const_cast(SPLIT_TRANS)); p2 = standard; break; case BY_DATE_RECONCILED: - p1 = g_slist_prepend (p1, SPLIT_RECONCILE); - p2 = g_slist_prepend (p2, SPLIT_DATE_RECONCILED); + p1 = g_slist_prepend (p1, const_cast(SPLIT_RECONCILE)); + p2 = g_slist_prepend (p2, const_cast(SPLIT_DATE_RECONCILED)); p3 = standard; break; case BY_NUM: - p1 = g_slist_prepend (p1, TRANS_NUM); - p1 = g_slist_prepend (p1, SPLIT_TRANS); + p1 = g_slist_prepend (p1, const_cast(TRANS_NUM)); + p1 = g_slist_prepend (p1, const_cast(SPLIT_TRANS)); p2 = standard; break; case BY_AMOUNT: - p1 = g_slist_prepend (p1, SPLIT_VALUE); + p1 = g_slist_prepend (p1, const_cast(SPLIT_VALUE)); p2 = standard; break; case BY_MEMO: - p1 = g_slist_prepend (p1, SPLIT_MEMO); + p1 = g_slist_prepend (p1, const_cast(SPLIT_MEMO)); p2 = standard; break; case BY_DESC: - p1 = g_slist_prepend (p1, TRANS_DESCRIPTION); - p1 = g_slist_prepend (p1, SPLIT_TRANS); + p1 = g_slist_prepend (p1, const_cast(TRANS_DESCRIPTION)); + p1 = g_slist_prepend (p1, const_cast(SPLIT_TRANS)); p2 = standard; break; case BY_NONE: @@ -1712,6 +1701,13 @@ set_query_sort (QofQuery *q, sort_type_t sort_code) qof_query_set_sort_order (q, p1, p2, p3); } +template inline T +compare_param(int max) +{ + auto ret = get_random_int_in_range (max == 1 ? 0 : 1, max); + return static_cast(ret); +} + QofQuery * get_random_query(void) { @@ -1744,7 +1740,7 @@ get_random_query(void) xaccQueryAddAccountGUIDMatch (q, guids, - get_random_int_in_range (1, QOF_GUID_MATCH_NONE), + compare_param(QOF_GUID_MATCH_NONE), get_random_queryop ()); free_random_guids (guids); break; @@ -1755,7 +1751,7 @@ get_random_query(void) string, get_random_boolean (), get_random_boolean (), - get_random_int_in_range (1, QOF_COMPARE_CONTAINS), + compare_param(QOF_COMPARE_CONTAINS), get_random_queryop ()); g_free (string); break; @@ -1763,19 +1759,19 @@ get_random_query(void) case 3: /* PR_BALANCE */ xaccQueryAddBalanceMatch (q, - get_random_boolean (), + compare_param (1), get_random_queryop ()); break; case 4: /* PR_CLEARED */ xaccQueryAddClearedMatch (q, - get_random_int_in_range (1, + static_cast(get_random_int_in_range (1, CLEARED_NO | CLEARED_CLEARED | CLEARED_RECONCILED | CLEARED_FROZEN | - CLEARED_VOIDED), + CLEARED_VOIDED)), get_random_queryop ()); break; @@ -1798,7 +1794,7 @@ get_random_query(void) string, get_random_boolean (), get_random_boolean (), - get_random_int_in_range (1, QOF_COMPARE_CONTAINS), + compare_param(QOF_COMPARE_CONTAINS), get_random_queryop ()); g_free (string); break; @@ -1821,7 +1817,7 @@ get_random_query(void) string, get_random_boolean (), get_random_boolean (), - get_random_int_in_range (1, QOF_COMPARE_CONTAINS), + compare_param(QOF_COMPARE_CONTAINS), get_random_queryop ()); g_free (string); break; @@ -1832,7 +1828,7 @@ get_random_query(void) string, get_random_boolean (), get_random_boolean (), - get_random_int_in_range (1, QOF_COMPARE_CONTAINS), + compare_param(QOF_COMPARE_CONTAINS), get_random_queryop ()); g_free (string); break; @@ -1841,7 +1837,7 @@ get_random_query(void) xaccQueryAddSharePriceMatch (q, get_random_gnc_numeric (GNC_DENOM_AUTO), - get_random_int_in_range (1, QOF_COMPARE_NEQ), + compare_param (QOF_COMPARE_NEQ), get_random_queryop ()); break; @@ -1849,7 +1845,7 @@ get_random_query(void) xaccQueryAddSharesMatch (q, get_random_gnc_numeric (GNC_DENOM_AUTO), - get_random_int_in_range (1, QOF_COMPARE_NEQ), + compare_param (QOF_COMPARE_NEQ), get_random_queryop ()); break; @@ -1857,8 +1853,8 @@ get_random_query(void) xaccQueryAddValueMatch (q, get_random_gnc_numeric (GNC_DENOM_AUTO), - get_random_int_in_range (1, QOF_NUMERIC_MATCH_ANY), - get_random_int_in_range (1, QOF_COMPARE_NEQ), + compare_param (QOF_NUMERIC_MATCH_ANY), + compare_param (QOF_COMPARE_NEQ), get_random_queryop ()); break; @@ -1870,7 +1866,7 @@ get_random_query(void) } if (gnc_engine_debug_random) printf ("\n"); - set_query_sort (q, get_random_int_in_range (1, BY_NONE)); + set_query_sort (q, compare_param(BY_NONE)); qof_query_set_sort_increasing (q, get_random_boolean (), @@ -2088,7 +2084,7 @@ make_trans_query (Transaction *trans, TestQueryTypes query_types) list = NULL; for (node = xaccTransGetSplitList (trans); node; node = node->next) { - Split * split = node->data; + auto split = static_cast(node->data); list = g_list_prepend (list, xaccSplitGetAccount (split)); } xaccQueryAddAccountMatch (q, list, QOF_GUID_MATCH_ALL, QOF_QUERY_AND); diff --git a/src/engine/test-core/test-engine-stuff.h b/src/engine/test-core/test-engine-stuff.h index 557bba8aa3..73360b460e 100644 --- a/src/engine/test-core/test-engine-stuff.h +++ b/src/engine/test-core/test-engine-stuff.h @@ -4,7 +4,10 @@ #ifndef TEST_ENGINE_STUFF_H #define TEST_ENGINE_STUFF_H - +#ifdef __cplusplus +extern "C" +{ +#endif #include #include #include @@ -32,9 +35,7 @@ bin_data* get_random_binary_data(void); KvpFrame* get_random_kvp_frame(void); gnc_numeric get_random_gnc_numeric(int64_t); GncGUID* get_random_guid(void); -GList* get_random_glist(void); -void random_glist_strings_only (gboolean strings_only); void kvp_exclude_type (KvpValueType kvp_type); void set_max_kvp_depth (gint max_kvp_depth); void set_max_kvp_frame_elements (gint max_kvp_frame_elements); @@ -95,4 +96,7 @@ SchedXaction* add_daily_sx(gchar *name, const GDate *start, const GDate *end, co SchedXaction* add_once_sx(gchar *name, const GDate *when); void remove_sx(SchedXaction *sx); +#ifdef __cplusplus +} +#endif #endif diff --git a/src/engine/test/Makefile.am b/src/engine/test/Makefile.am index 8f1cf03dc1..7366d7561a 100644 --- a/src/engine/test/Makefile.am +++ b/src/engine/test/Makefile.am @@ -94,7 +94,7 @@ EXTRA_DIST += \ test_engine_SOURCES = \ test-engine.c \ - utest-Account.c \ + utest-Account.cpp \ utest-Budget.c \ utest-Entry.c \ utest-Invoice.c \ @@ -124,7 +124,7 @@ libutest_Split_la_CXXFLAGS = -Wno-write-strings $(AM_CXXFLAGS) libutest_Split_la_LIBADD = $(LDADD) libutest_Trans_la_SOURCES = \ - utest-Transaction.c + utest-Transaction.cpp libutest_Trans_la_LIBADD = $(LDADD) diff --git a/src/engine/test/gtest-import-map.cpp b/src/engine/test/gtest-import-map.cpp index a4d4885b93..e24a64f3e3 100644 --- a/src/engine/test/gtest-import-map.cpp +++ b/src/engine/test/gtest-import-map.cpp @@ -26,7 +26,6 @@ extern "C" #include "../Account.h" #include #include -#include struct GncImportMatchMap { @@ -48,6 +47,7 @@ extern void gnc_imap_add_account_bayes (GncImportMatchMap *imap, Account *acc); } +#include #include class ImapTest : public testing::Test @@ -103,14 +103,12 @@ protected: TEST_F(ImapPlainTest, FindAccount) { auto root = qof_instance_get_slots(QOF_INSTANCE(t_bank_account)); - auto acc1_val = kvp_value_new_guid(xaccAccountGetGUID(t_expense_account1)); - auto acc2_val = kvp_value_new_guid(xaccAccountGetGUID(t_expense_account2)); - kvp_frame_set_slot_path(root, acc1_val, IMAP_FRAME, "foo", "bar", NULL); - kvp_frame_set_slot_path(root, acc2_val, IMAP_FRAME, "baz", "waldo", NULL); - kvp_frame_set_slot_path(root, acc1_val, IMAP_FRAME, "pepper", NULL); - kvp_frame_set_slot_path(root, acc2_val, IMAP_FRAME, "salt", NULL); - kvp_value_delete(acc1_val); - kvp_value_delete(acc2_val); + auto acc1_val = new KvpValue(const_cast(xaccAccountGetGUID(t_expense_account1))); + auto acc2_val = new KvpValue(const_cast(xaccAccountGetGUID(t_expense_account2))); + root->set_path({IMAP_FRAME, "foo", "bar"}, acc1_val); + root->set_path({IMAP_FRAME, "baz", "waldo"}, acc2_val); + root->set_path({IMAP_FRAME, "pepper"}, acc1_val); + root->set_path({IMAP_FRAME, "salt"}, acc2_val); EXPECT_EQ(t_expense_account1, gnc_imap_find_account(t_imap, "foo", "bar")); EXPECT_EQ(t_expense_account2, @@ -140,17 +138,17 @@ TEST_F(ImapPlainTest, AddAccount) qof_instance_reset_editlevel(QOF_INSTANCE(t_bank_account)); auto root = qof_instance_get_slots(QOF_INSTANCE(t_bank_account)); - auto value = kvp_frame_get_slot_path(root, IMAP_FRAME, "foo", "bar", NULL); + auto value = root->get_slot({IMAP_FRAME, "foo", "bar"}); auto check_account = [this](KvpValue* v) { - return xaccAccountLookup(kvp_value_get_guid(v), this->t_imap->book); }; + return xaccAccountLookup(v->get(), this->t_imap->book); }; EXPECT_EQ(t_expense_account1, check_account(value)); - value = kvp_frame_get_slot_path(root, IMAP_FRAME, "baz", "waldo", NULL); + value = root->get_slot({IMAP_FRAME, "baz", "waldo"}); EXPECT_EQ(t_expense_account2, check_account(value)); - value = kvp_frame_get_slot_path(root, IMAP_FRAME, "pepper", NULL); + value = root->get_slot({IMAP_FRAME, "pepper"}); EXPECT_EQ(t_expense_account1, check_account(value)); - value = kvp_frame_get_slot_path(root, IMAP_FRAME, "salt", NULL); + value = root->get_slot({IMAP_FRAME, "salt"}); EXPECT_EQ(t_expense_account2, check_account(value)); - value = kvp_frame_get_slot_path(root, IMAP_FRAME, "pork", "sausage", NULL); + value = root->get_slot({IMAP_FRAME, "pork", "sausage"}); EXPECT_EQ(nullptr, value); } @@ -205,21 +203,14 @@ TEST_F(ImapBayesTest, FindAccountBayes) auto root = qof_instance_get_slots(QOF_INSTANCE(t_bank_account)); auto acct1_name = gnc_account_get_full_name(t_expense_account1); auto acct2_name = gnc_account_get_full_name(t_expense_account2); - auto value = kvp_value_new_gint64(42); + auto value = new KvpValue(INT64_C(42)); - kvp_frame_set_slot_path(root, value, IMAP_FRAME_BAYES, - foo, acct1_name, NULL); - kvp_frame_set_slot_path(root, value, IMAP_FRAME_BAYES, - bar, acct1_name, NULL); - kvp_frame_set_slot_path(root, value, IMAP_FRAME_BAYES, - baz, acct2_name, NULL); - kvp_frame_set_slot_path(root, value, IMAP_FRAME_BAYES, - waldo, acct2_name, NULL); - kvp_frame_set_slot_path(root, value, IMAP_FRAME_BAYES, - pepper, acct1_name, NULL); - kvp_frame_set_slot_path(root, value, IMAP_FRAME_BAYES, - salt, acct2_name, NULL); - kvp_value_delete(value); + root->set_path({IMAP_FRAME_BAYES, foo, acct1_name}, value); + root->set_path({IMAP_FRAME_BAYES, bar, acct1_name}, value); + root->set_path({IMAP_FRAME_BAYES, baz, acct2_name}, value); + root->set_path({IMAP_FRAME_BAYES, waldo, acct2_name}, value); + root->set_path({IMAP_FRAME_BAYES, pepper, acct1_name}, value); + root->set_path({IMAP_FRAME_BAYES, salt, acct2_name}, value); auto account = gnc_imap_find_account_bayes(t_imap, t_list1); EXPECT_EQ(t_expense_account1, account); @@ -252,37 +243,28 @@ TEST_F(ImapBayesTest, AddAccountBayes) auto root = qof_instance_get_slots(QOF_INSTANCE(t_bank_account)); auto acct1_name = gnc_account_get_full_name(t_expense_account1); auto acct2_name = gnc_account_get_full_name(t_expense_account2); - auto value = kvp_frame_get_slot_path(root, IMAP_FRAME_BAYES, "foo", "bar", NULL); + auto value = root->get_slot({IMAP_FRAME_BAYES, "foo", "bar"}); auto check_account = [this](KvpValue* v) { - return (kvp_value_get_string(v), - this->t_imap->book); }; - value = kvp_frame_get_slot_path(root, IMAP_FRAME_BAYES, foo, acct1_name, - NULL); - EXPECT_EQ(1, kvp_value_get_gint64(value)); - value = kvp_frame_get_slot_path(root, IMAP_FRAME_BAYES, bar, acct1_name, - NULL); - EXPECT_EQ(1, kvp_value_get_gint64(value)); - value = kvp_frame_get_slot_path(root, IMAP_FRAME_BAYES, baz, acct2_name, - NULL); - EXPECT_EQ(1, kvp_value_get_gint64(value)); - value = kvp_frame_get_slot_path(root, IMAP_FRAME_BAYES, waldo, acct2_name, - NULL); - EXPECT_EQ(1, kvp_value_get_gint64(value)); - value = kvp_frame_get_slot_path(root, IMAP_FRAME_BAYES, pepper, acct1_name, - NULL); - EXPECT_EQ(1, kvp_value_get_gint64(value)); - value = kvp_frame_get_slot_path(root, IMAP_FRAME_BAYES, salt, acct2_name, - NULL); - EXPECT_EQ(1, kvp_value_get_gint64(value)); - value = kvp_frame_get_slot_path(root, IMAP_FRAME_BAYES, baz, acct1_name, - NULL); - EXPECT_EQ(0, kvp_value_get_gint64(value)); + return (v->get(), this->t_imap->book); }; + value = root->get_slot({IMAP_FRAME_BAYES, foo, acct1_name}); + EXPECT_EQ(1, value->get()); + value = root->get_slot({IMAP_FRAME_BAYES, bar, acct1_name}); + EXPECT_EQ(1, value->get()); + value = root->get_slot({IMAP_FRAME_BAYES, baz, acct2_name}); + EXPECT_EQ(1, value->get()); + value = root->get_slot({IMAP_FRAME_BAYES, waldo, acct2_name}); + EXPECT_EQ(1, value->get()); + value = root->get_slot({IMAP_FRAME_BAYES, pepper, acct1_name}); + EXPECT_EQ(1, value->get()); + value = root->get_slot({IMAP_FRAME_BAYES, salt, acct2_name}); + EXPECT_EQ(1, value->get()); + value = root->get_slot({IMAP_FRAME_BAYES, baz, acct1_name}); + EXPECT_EQ(nullptr, value); qof_instance_increase_editlevel(QOF_INSTANCE(t_bank_account)); gnc_imap_add_account_bayes(t_imap, t_list2, t_expense_account2); qof_instance_mark_clean(QOF_INSTANCE(t_bank_account)); qof_instance_reset_editlevel(QOF_INSTANCE(t_bank_account)); - value = kvp_frame_get_slot_path(root, IMAP_FRAME_BAYES, baz, acct2_name, - NULL); - EXPECT_EQ(2, kvp_value_get_gint64(value)); + value = root->get_slot({IMAP_FRAME_BAYES, baz, acct2_name}); + EXPECT_EQ(2, value->get()); } diff --git a/src/engine/test/utest-Account.c b/src/engine/test/utest-Account.cpp similarity index 89% rename from src/engine/test/utest-Account.c rename to src/engine/test/utest-Account.cpp index f1c69147f8..747f9d6bbb 100644 --- a/src/engine/test/utest-Account.c +++ b/src/engine/test/utest-Account.cpp @@ -18,14 +18,15 @@ * Free Software Foundation Voice: +1-617-542-5942 * * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 * * Boston, MA 02110-1301, USA gnu@gnu.org * -********************************************************************/ + ********************************************************************/ +extern "C" +{ #include "config.h" #include #include #include #include #include -#include #include /* Add specific headers for this class */ #include "../Account.h" @@ -44,6 +45,9 @@ #endif static const gchar *suitename = "/engine/Account"; void test_suite_account (void); +} + +#include typedef struct { @@ -54,20 +58,20 @@ typedef struct typedef struct { GNCAccountType type; - char *name; - char *parent; - char *code; - char *desc; - char *color; - char *notes; - char *num; + const char *name; + const char *parent; + const char *code; + const char *desc; + const char *color; + const char *notes; + const char *num; GNCPolicy *policy; } AccountParms; typedef struct { - char *memo; - char *account; + const char *memo; + const char *account; char reconciled; gnc_numeric amount; gnc_numeric value; @@ -76,7 +80,7 @@ typedef struct typedef struct { - gchar *desc; + const char *desc; gint date_offset; SplitParms splits[2]; } TxnParms; @@ -265,10 +269,10 @@ static SetupData complex_data = {G_N_ELEMENTS (complex_accts), static Split* insert_split (Account *parent, Transaction *txn, SplitParms *p) { - QofBook *book = gnc_account_get_book (parent); - Split *split = xaccMallocSplit (book); - Account *acct = gnc_account_lookup_by_name (parent, p->account); - LotList* lotlist = xaccAccountGetLotList (acct); + auto book = gnc_account_get_book (parent); + auto split = xaccMallocSplit (book); + auto acct = gnc_account_lookup_by_name (parent, p->account); + auto lotlist = xaccAccountGetLotList (acct); GNCLot* lot = NULL; g_assert (acct != NULL); xaccSplitSetParent (split, txn); @@ -297,31 +301,32 @@ insert_split (Account *parent, Transaction *txn, SplitParms *p) static void setup (Fixture *fixture, gconstpointer pData) { - QofBook *book = qof_book_new (); - Account *root = gnc_account_create_root (book), *acct = NULL; - SetupData *parms = (SetupData *)pData; + auto book = qof_book_new (); + auto root = gnc_account_create_root (book); + auto parms = static_cast(pData); TxnParms *t_arr; AccountParms *p_arr; - GHashTable *accts = g_hash_table_new (g_str_hash, g_str_equal); + auto accts = g_hash_table_new (g_str_hash, g_str_equal); guint ind; - g_hash_table_insert (accts, "root", root); + auto root_str = static_cast(CACHE_INSERT("root")); + g_hash_table_insert (accts, root_str, root); fixture->func = _utest_account_fill_functions (); if (parms == NULL) { fixture->acct = root; return; } - acct = root; + auto acct = root; p_arr = (AccountParms*)parms->accounts; for (ind = 0; ind < parms->num_accounts; ind++) { - Account *child = xaccMallocAccount (book); + auto child = xaccMallocAccount (book); AccountParms p = p_arr[ind]; if (p.parent && strlen (p.parent) > 0) { - Account *parent = g_hash_table_lookup (accts, p.parent); + auto parent = static_cast(g_hash_table_lookup (accts, p.parent)); g_assert (parent != NULL); gnc_account_append_child (parent, child); } @@ -332,7 +337,7 @@ setup (Fixture *fixture, gconstpointer pData) if (p.name) { xaccAccountSetName (acct, p.name); - g_hash_table_insert (accts, p.name, acct); + g_hash_table_insert (accts, const_cast(p.name), acct); } if (p.code) xaccAccountSetCode (acct, p.code); @@ -427,27 +432,28 @@ static void test_gnc_account_name_violations_errmsg () { GList *badnames = NULL, *nonames = NULL, *node = NULL; - gchar *separator = ":", *message, *validation_message, *account_list = NULL; + auto separator = ":"; + char *account_list = NULL; /* FUT wants to free the strings, so we alloc them */ badnames = g_list_prepend (badnames, g_strdup ("Foo:bar")); badnames = g_list_prepend (badnames, g_strdup ("baz")); badnames = g_list_prepend (badnames, g_strdup ("waldo:pepper")); - message = gnc_account_name_violations_errmsg (separator, nonames); + auto message = gnc_account_name_violations_errmsg (separator, nonames); for (node = badnames; node; node = g_list_next (node)) { if (!account_list) - account_list = g_strdup (node->data); + account_list = g_strdup (static_cast(node->data)); else { - gchar *tmp_list = g_strconcat ( account_list, "\n", - node->data, NULL); + auto tmp_list = g_strconcat ( account_list, "\n", + static_cast(node->data), NULL); g_free (account_list); account_list = tmp_list; } } message = gnc_account_name_violations_errmsg (separator, nonames); g_assert (message == NULL); - validation_message = g_strdup_printf ( + auto validation_message = g_strdup_printf ( "The separator character \"%s\" is used in one or more account " "names.\n\nThis will result in unexpected behaviour. " "Either change the account names or choose another separator " @@ -464,33 +470,33 @@ GList *gnc_account_list_name_violations (QofBook *book, const gchar *separator)/ static void test_gnc_account_list_name_violations (Fixture *fixture, gconstpointer pData) { - guint log_level = G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL; - gchar *log_domain = "gnc.engine"; + auto log_level = static_cast(G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL); + auto log_domain = "gnc.engine"; #ifdef USE_CLANG_FUNC_SIG #define _func "GList *gnc_account_list_name_violations(QofBook *, const gchar *)" #else #define _func "gnc_account_list_name_violations" #endif - gchar *msg = _func ": assertion " _Q "separator != NULL' failed"; + auto msg = _func ": assertion " _Q "separator != NULL' failed"; #undef _func - TestErrorStruct check = { log_level, log_domain, msg, 0 }; + auto check = test_error_struct_new(log_domain, log_level, msg); GList *results, *res_iter; - gchar *sep = ":"; + auto sep = ":"; QofBook *book = gnc_account_get_book (fixture->acct); /* Because of GLib bug 653052, we have to set the logging user_data to * affect the test_log_fatal_handler */ - GLogFunc oldlogger = g_log_set_default_handler ((GLogFunc)test_null_handler, &check); - g_test_log_set_fatal_handler ((GTestLogFatalFunc)test_checked_handler, &check); + GLogFunc oldlogger = g_log_set_default_handler ((GLogFunc)test_null_handler, check); + g_test_log_set_fatal_handler ((GTestLogFatalFunc)test_checked_handler, check); g_assert (gnc_account_list_name_violations (NULL, NULL) == NULL); - g_assert_cmpint (check.hits, ==, 1); + g_assert_cmpint (check->hits, ==, 1); g_assert (gnc_account_list_name_violations (book, NULL) == NULL); - g_assert_cmpint (check.hits, ==, 2); + g_assert_cmpint (check->hits, ==, 2); g_assert (gnc_account_list_name_violations (NULL, sep) == NULL); g_log_set_default_handler (oldlogger, NULL); results = gnc_account_list_name_violations (book, sep); g_assert_cmpuint (g_list_length (results), == , 2); - g_assert_cmpint (check.hits, ==, 2); + g_assert_cmpint (check->hits, ==, 2); for (res_iter = results; res_iter; res_iter = g_list_next (res_iter)) test_free (res_iter->data); g_list_free (results); @@ -546,8 +552,8 @@ gnc_account_init (Account* acc)// 1 static void test_gnc_account_create_and_destroy (void) { - Account *acc = g_object_new (GNC_TYPE_ACCOUNT, NULL); - gchar *name, *fname, *code, *desc, *color, *notes, *tax_code, *tax_src; + auto acc = static_cast(g_object_new (GNC_TYPE_ACCOUNT, NULL)); + char *name, *fname, *code, *desc, *color, *notes, *tax_code, *tax_src; GNCAccountType type; gnc_commodity *commo; gint commo_scu, mark; @@ -660,10 +666,10 @@ Simple pass-through for qof_collection_get_data () static void test_gnc_book_set_get_root_account (Fixture *fixture, gconstpointer pData) { - guint log_level = G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL; - gchar *log_domain = "gnc.account"; - gchar *msg = "[gnc_book_set_root_account()] cannot mix and match books freely!"; - TestErrorStruct check = { log_level, log_domain, msg, 0 }; + auto log_level = static_cast(G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL); + auto log_domain = "gnc.account"; + auto msg = "[gnc_book_set_root_account()] cannot mix and match books freely!"; + auto check = test_error_struct_new(log_domain, log_level, msg); Account *acc1, *acc2; QofBook* book1 = qof_book_new (); GLogFunc oldlogger; @@ -679,12 +685,12 @@ test_gnc_book_set_get_root_account (Fixture *fixture, gconstpointer pData) /* Now try to set the book's root account to the fixture * accout. Should throw an error. */ - oldlogger = g_log_set_default_handler ((GLogFunc)test_null_handler, &check); + oldlogger = g_log_set_default_handler ((GLogFunc)test_null_handler, check); g_test_log_set_fatal_handler ((GTestLogFatalFunc)test_checked_handler, - &check); + check); gnc_book_set_root_account (book1, fixture->acct); g_assert (gnc_book_get_root_account (book1) == acc1); - g_assert_cmpint (check.hits, ==, 1); + g_assert_cmpint (check->hits, ==, 1); g_log_set_default_handler (oldlogger, NULL); /* Check that if we set the same root, it stays set */ gnc_book_set_root_account (book2, fixture->acct); @@ -728,7 +734,7 @@ test_gnc_account_create_root (void) QofBook *book = qof_book_new (); QofCollection *coll = qof_book_get_collection (book, GNC_ID_ROOT_ACCOUNT); Account *acc; - gchar *name; + char *name; AccountTestFunctions *func = _utest_account_fill_functions (); /* Can't use gnc_book_get_root_account, it creates one if it doesn't * yet exist */ @@ -752,27 +758,28 @@ test_xaccCloneAccount (Fixture *fixture, gconstpointer pData) { Account *clone; QofBook *book = gnc_account_get_book (fixture->acct); - guint loglevel = G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL; + auto loglevel = static_cast(G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL); #ifdef USE_CLANG_FUNC_SIG #define _func "Account *xaccCloneAccount(const Account *, QofBook *)" #else #define _func "xaccCloneAccount" #endif - gchar *msg1 = _func ": assertion " _Q "GNC_IS_ACCOUNT(from)' failed"; - gchar *msg2 = _func ": assertion " _Q "QOF_IS_BOOK(book)' failed"; + auto msg1 = _func ": assertion " _Q "GNC_IS_ACCOUNT(from)' failed"; + auto msg2 = _func ": assertion " _Q "QOF_IS_BOOK(book)' failed"; #undef _func - TestErrorStruct check = { loglevel, "gnc.engine", msg1, 0 }; - GLogFunc oldlogger; + auto check = test_error_struct_new("gnc.engine", loglevel, msg1); AccountPrivate *acct_p, *clone_p; - oldlogger = g_log_set_default_handler ((GLogFunc)test_null_handler, &check); - g_test_log_set_fatal_handler ((GTestLogFatalFunc)test_checked_handler, &check); + auto oldlogger = g_log_set_default_handler ((GLogFunc)test_null_handler, + check); + g_test_log_set_fatal_handler ((GTestLogFatalFunc)test_checked_handler, check); clone = xaccCloneAccount (NULL, book); g_assert (clone == NULL); - g_assert_cmpint (check.hits, ==, 1); - check.msg = msg2; + g_assert_cmpint (check->hits, ==, 1); + g_free(check->msg); + check->msg = g_strdup(msg2); clone = xaccCloneAccount (fixture->acct, NULL); g_assert (clone == NULL); - g_assert_cmpint (check.hits, ==, 2); + g_assert_cmpint (check->hits, ==, 2); g_log_set_default_handler (oldlogger, NULL); /* Now test the real clone */ clone = xaccCloneAccount (fixture->acct, book); @@ -783,12 +790,13 @@ test_xaccCloneAccount (Fixture *fixture, gconstpointer pData) g_assert (clone_p->accountName == acct_p->accountName); g_assert (clone_p->accountCode == acct_p->accountCode); g_assert (clone_p->description == acct_p->description); - g_assert (kvp_frame_compare (clone->inst.kvp_data, - fixture->acct->inst.kvp_data) == 0); + g_assert (compare (clone->inst.kvp_data, + fixture->acct->inst.kvp_data) == 0); g_assert (gnc_commodity_equal (clone_p->commodity, acct_p->commodity)); g_assert (clone_p->commodity_scu == acct_p->commodity_scu); g_assert (clone_p->non_standard_scu == acct_p->non_standard_scu); /* Clean Up */ + test_error_struct_free(check); g_object_unref (clone); } @@ -854,18 +862,18 @@ acc_free static void test_xaccFreeAccount (Fixture *fixture, gconstpointer pData) { - gchar *msg1 = "[xaccFreeAccount()] instead of calling xaccFreeAccount(), please call \n" + auto msg1 = "[xaccFreeAccount()] instead of calling xaccFreeAccount(), please call \n" " xaccAccountBeginEdit(); xaccAccountDestroy(); \n"; #ifdef USE_CLANG_FUNC_SIG #define _func "int xaccTransGetSplitIndex(const Transaction *, const Split *)" #else #define _func "xaccTransGetSplitIndex" #endif - gchar *msg2 = _func ": assertion " _Q "trans && split' failed"; + auto msg2 = _func ": assertion " _Q "trans && split' failed"; #undef _func - guint loglevel = G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL; - TestErrorStruct check1 = { loglevel, "gnc.account", msg1, 0 }; - TestErrorStruct check2 = { loglevel, "gnc.engine", msg2, 0 }; + auto loglevel = static_cast(G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL); + auto check1 = test_error_struct_new("gnc.account", loglevel, msg1); + auto check2 = test_error_struct_new("gnc.engine", loglevel, msg2); QofBook *book = gnc_account_get_book (fixture->acct); Account *parent = gnc_account_get_parent (fixture->acct); AccountPrivate *p_priv = fixture->func->get_private (parent); @@ -873,12 +881,12 @@ test_xaccFreeAccount (Fixture *fixture, gconstpointer pData) guint i = 0; guint hdlr1, hdlr2; gnc_commodity *commodity = gnc_commodity_new (book, "US Dollar", "CURRENCY", "USD", "0", 100); - test_add_error (&check1); - test_add_error (&check2); + test_add_error (check1); + test_add_error (check2); hdlr1 = g_log_set_handler ("gnc.account", loglevel, - (GLogFunc)test_checked_handler, &check1); + (GLogFunc)test_checked_handler, check1); hdlr2 = g_log_set_handler ("gnc.engine", loglevel, - (GLogFunc)test_checked_handler, &check2); + (GLogFunc)test_checked_handler, check2); g_test_log_set_fatal_handler ((GTestLogFatalFunc)test_list_handler, NULL); for (i = 0; i < numItems; i++) { @@ -894,8 +902,8 @@ test_xaccFreeAccount (Fixture *fixture, gconstpointer pData) g_assert (p_priv->splits != NULL); g_assert (p_priv->parent != NULL); g_assert (p_priv->commodity != NULL); - g_assert_cmpint (check1.hits, ==, 0); - g_assert_cmpint (check2.hits, ==, 0); + g_assert_cmpint (check1->hits, ==, 0); + g_assert_cmpint (check2->hits, ==, 0); /* Now set the other private parts to something so that they can be set back */ p_priv->cleared_balance = gnc_numeric_create ( 5, 12); p_priv->reconciled_balance = gnc_numeric_create ( 5, 12); @@ -903,8 +911,8 @@ test_xaccFreeAccount (Fixture *fixture, gconstpointer pData) p_priv->balance_dirty = TRUE; p_priv->sort_dirty = TRUE; fixture->func->xaccFreeAccount (parent); - g_assert_cmpint (check1.hits, ==, 6); - g_assert_cmpint (check2.hits, ==, 6); + g_assert_cmpint (check1->hits, ==, 6); + g_assert_cmpint (check2->hits, ==, 6); /* cleanup what's left */ g_log_remove_handler ("gnc.account", hdlr1); g_log_remove_handler ("gnc.engine", hdlr2); @@ -968,18 +976,18 @@ Also tests: static void test_xaccAccountCommitEdit (Fixture *fixture, gconstpointer pData) { - gchar *msg1 = "[xaccFreeAccount()] instead of calling xaccFreeAccount(), please call \n" + auto msg1 = "[xaccFreeAccount()] instead of calling xaccFreeAccount(), please call \n" " xaccAccountBeginEdit(); xaccAccountDestroy(); \n"; #ifdef USE_CLANG_FUNC_SIG #define _func "int xaccTransGetSplitIndex(const Transaction *, const Split *)" #else #define _func "xaccTransGetSplitIndex" #endif - gchar *msg2 = _func ": assertion " _Q "trans && split' failed"; + auto msg2 = _func ": assertion " _Q "trans && split' failed"; #undef _func - guint loglevel = G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL; - TestErrorStruct check1 = { loglevel, "gnc.account", msg1, 0 }; - TestErrorStruct check2 = { loglevel, "gnc.engine", msg2, 0 }; + auto loglevel = static_cast(G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL); + auto check1 = test_error_struct_new("gnc.account", loglevel, msg1); + auto check2 = test_error_struct_new("gnc.engine", loglevel, msg2); guint hdlr1, hdlr2; TestSignal sig1, sig2; QofBook *book = gnc_account_get_book (fixture->acct); @@ -988,12 +996,12 @@ test_xaccAccountCommitEdit (Fixture *fixture, gconstpointer pData) const guint numItems = 3; guint i = 0; gnc_commodity *commodity = gnc_commodity_new (book, "US Dollar", "CURRENCY", "USD", "0", 100); - test_add_error (&check1); - test_add_error (&check2); + test_add_error (check1); + test_add_error (check2); hdlr1 = g_log_set_handler ("gnc.account", loglevel, - (GLogFunc)test_checked_handler, &check1); + (GLogFunc)test_checked_handler, check1); hdlr2 = g_log_set_handler ("gnc.engine", loglevel, - (GLogFunc)test_checked_handler, &check2); + (GLogFunc)test_checked_handler, check2); g_test_log_set_fatal_handler ((GTestLogFatalFunc)test_list_handler, NULL); for (i = 0; i < numItems; i++) { @@ -1009,8 +1017,8 @@ test_xaccAccountCommitEdit (Fixture *fixture, gconstpointer pData) g_assert (p_priv->splits != NULL); g_assert (p_priv->parent != NULL); g_assert (p_priv->commodity != NULL); - g_assert_cmpint (check1.hits, ==, 0); - g_assert_cmpint (check2.hits, ==, 0); + g_assert_cmpint (check1->hits, ==, 0); + g_assert_cmpint (check2->hits, ==, 0); sig1 = test_signal_new (&parent->inst, QOF_EVENT_MODIFY, NULL); sig2 = test_signal_new (&parent->inst, QOF_EVENT_DESTROY, NULL); @@ -1025,8 +1033,8 @@ test_xaccAccountCommitEdit (Fixture *fixture, gconstpointer pData) g_assert (p_priv->splits != NULL); g_assert (p_priv->parent != NULL); g_assert (p_priv->commodity != NULL); - g_assert_cmpint (check1.hits, ==, 0); - g_assert_cmpint (check2.hits, ==, 0); + g_assert_cmpint (check1->hits, ==, 0); + g_assert_cmpint (check2->hits, ==, 0); /* xaccAccountDestroy destroys the account by calling * qof_instance_set_destroying (), then xaccAccountCommitEdit (); */ @@ -1035,8 +1043,8 @@ test_xaccAccountCommitEdit (Fixture *fixture, gconstpointer pData) /* So this time we make sure that the account is destroyed */ test_signal_assert_hits (sig1, 2); test_signal_assert_hits (sig2, 1); - g_assert_cmpint (check1.hits, ==, 2); - g_assert_cmpint (check2.hits, ==, 12); + g_assert_cmpint (check1->hits, ==, 2); + g_assert_cmpint (check2->hits, ==, 12); /* And clean up */ test_signal_free (sig1); test_signal_free (sig2); @@ -1092,22 +1100,22 @@ test_gnc_account_insert_remove_split (Fixture *fixture, gconstpointer pData) #else #define _func "gnc_account_insert_split" #endif - gchar *msg1 = _func ": assertion " _Q "GNC_IS_ACCOUNT(acc)' failed"; - gchar *msg2 = _func ": assertion " _Q "GNC_IS_SPLIT(s)' failed"; + auto msg1 = _func ": assertion " _Q "GNC_IS_ACCOUNT(acc)' failed"; + auto msg2 = _func ": assertion " _Q "GNC_IS_SPLIT(s)' failed"; #undef _func - guint loglevel = G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL; -// gchar *log_domain = "gnc.engine"; - TestErrorStruct check1 = { loglevel, "gnc.engine", msg1, 0 }; - TestErrorStruct check2 = { loglevel, "gnc.engine", msg2, 0 }; - TestErrorStruct check3 = { loglevel, "gnc.engine", NULL, 0 }; + auto loglevel = static_cast(G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL); +// auto log_domain = "gnc.engine"; + auto check1 = test_error_struct_new("gnc.engine", loglevel, msg1); + auto check2 = test_error_struct_new("gnc.engine", loglevel, msg2); + auto check3 = test_error_struct_new("gnc.engine", loglevel, NULL); guint logger; sig1 = test_signal_new (&fixture->acct->inst, QOF_EVENT_MODIFY, NULL); sig2 = test_signal_new (&fixture->acct->inst, GNC_EVENT_ITEM_ADDED, split1); - test_add_error (&check1); - test_add_error (&check2); + test_add_error (check1); + test_add_error (check2); logger = g_log_set_handler ("gnc.engine", loglevel, - (GLogFunc)test_null_handler, &check3); + (GLogFunc)test_null_handler, check3); g_test_log_set_fatal_handler ((GTestLogFatalFunc)test_list_handler, NULL); /* Check that the call fails with invalid account and split (throws) */ @@ -1129,9 +1137,9 @@ test_gnc_account_insert_remove_split (Fixture *fixture, gconstpointer pData) /* g_assert (!priv->balance_dirty); */ /* test_signal_assert_hits (sig1, 0); */ /* test_signal_assert_hits (sig2, 0); */ - g_assert_cmpint (check1.hits, ==, 1); - g_assert_cmpint (check2.hits, ==, 1); - g_assert_cmpint (check3.hits, ==, 0); + g_assert_cmpint (check1->hits, ==, 1); + g_assert_cmpint (check2->hits, ==, 1); + g_assert_cmpint (check3->hits, ==, 0); g_log_remove_handler ("gnc.engine", logger); test_clear_error_list (); @@ -1321,10 +1329,9 @@ test_xaccAccountRecomputeBalance (Fixture *fixture, gconstpointer pData) clr_bal = gnc_numeric_zero (); SetupData *sdata = (SetupData*)pData; TxnParms* t_arr; - int ind; g_assert (sdata != NULL); t_arr = (TxnParms*)sdata->txns; - for (ind = 0; ind < sdata->num_txns; ind++) + for (unsigned int ind = 0; ind < sdata->num_txns; ind++) { SplitParms p = t_arr[ind].splits[1]; bal = gnc_numeric_add_fixed (bal, p.amount); @@ -1474,12 +1481,14 @@ test_gnc_account_append_remove_child (Fixture *fixture, gconstpointer pData) QofBook *fbook = qof_book_new (); Account *froot = gnc_account_create_root (fbook); Account *account = xaccMallocAccount (fbook); - gchar *logdomain = "gnc.account"; - gchar *msg1 = "[gnc_account_append_child()] reparenting accounts across books is not correctly supported\n"; - gchar *msg2 = "[gnc_account_remove_child()] account not a child of parent"; + auto logdomain = "gnc.account"; + auto msg1 = "[gnc_account_append_child()] reparenting accounts across books is not correctly supported\n"; + auto msg2 = "[gnc_account_remove_child()] account not a child of parent"; guint log_handler = 0; - TestErrorStruct check_warn = {G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL, "gnc.account", msg1, 0 }; - TestErrorStruct check_err = {G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL, "gnc.account", msg2, 0 }; + auto loglevelc = static_cast(G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL); + auto loglevelw = static_cast(G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL); + auto check_warn = test_error_struct_new("gnc.account", loglevelw, msg1); + auto check_err = test_error_struct_new("gnc.account", loglevelc, msg2); TestSignal sig1, sig2, sig3; AccountTestFunctions *func = _utest_account_fill_functions (); AccountPrivate *frpriv = func->get_private (froot), @@ -1494,25 +1503,29 @@ test_gnc_account_append_remove_child (Fixture *fixture, gconstpointer pData) test_signal_assert_hits (sig1, 1); test_signal_assert_hits (sig2, 0); test_signal_assert_hits (sig3, 0); - g_assert_cmpint (check_warn.hits, ==, 0); - g_assert_cmpint (check_err.hits, ==, 0); + g_assert_cmpint (check_warn->hits, ==, 0); + g_assert_cmpint (check_err->hits, ==, 0); g_assert (qof_instance_get_dirty (QOF_INSTANCE (froot))); g_assert (qof_instance_get_dirty (QOF_INSTANCE (account))); g_assert (g_list_find (frpriv->children, account)); g_assert (qof_collection_lookup_entity ( qof_book_get_collection (fbook, GNC_ID_ACCOUNT), acct_guid)); - log_handler = g_log_set_handler (logdomain, G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, (GLogFunc)test_null_handler, &check_warn); - g_test_log_set_fatal_handler ((GTestLogFatalFunc)test_checked_handler, &check_warn); + auto loglevelr = static_cast(G_LOG_LEVEL_WARNING | + G_LOG_FLAG_FATAL | + G_LOG_FLAG_RECURSION); + log_handler = g_log_set_handler (logdomain, loglevelr, + (GLogFunc)test_null_handler, check_warn); + g_test_log_set_fatal_handler ((GTestLogFatalFunc)test_checked_handler, check_warn); gnc_account_append_child (fixture->acct, account); g_log_remove_handler (logdomain, log_handler); - g_assert_cmpstr (msg1, == , check_warn.msg); + g_assert_cmpstr (msg1, == , check_warn->msg); g_assert (gnc_account_get_parent (account) == fixture->acct); test_signal_assert_hits (sig1, 2); test_signal_assert_hits (sig2, 1); test_signal_assert_hits (sig3, 1); - g_assert_cmpint (check_warn.hits, ==, 1); - g_assert_cmpint (check_err.hits, ==, 0); + g_assert_cmpint (check_warn->hits, ==, 1); + g_assert_cmpint (check_err->hits, ==, 0); g_assert (!qof_collection_lookup_entity ( qof_book_get_collection (fbook, GNC_ID_ACCOUNT), acct_guid)); @@ -1528,24 +1541,24 @@ test_gnc_account_append_remove_child (Fixture *fixture, gconstpointer pData) test_signal_free (sig3); sig1 = test_signal_new (&account->inst, QOF_EVENT_REMOVE, NULL); sig2 = test_signal_new (&(fixture->acct)->inst, QOF_EVENT_MODIFY, NULL); - log_handler = g_log_set_handler (logdomain, G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL, - (GLogFunc)test_null_handler, &check_err); - g_test_log_set_fatal_handler ((GTestLogFatalFunc)test_checked_handler, &check_err); + log_handler = g_log_set_handler (logdomain, loglevelc, + (GLogFunc)test_null_handler, check_err); + g_test_log_set_fatal_handler ((GTestLogFatalFunc)test_checked_handler, check_err); gnc_account_remove_child (froot, account); g_log_remove_handler (logdomain, log_handler); test_signal_assert_hits (sig1, 0); test_signal_assert_hits (sig2, 0); - g_assert_cmpint (check_err.hits, ==, 1); - g_assert_cmpint (check_warn.hits, ==, 1); + g_assert_cmpint (check_err->hits, ==, 1); + g_assert_cmpint (check_warn->hits, ==, 1); gnc_account_remove_child (fixture->acct, account); g_assert (gnc_account_get_parent (account) == NULL); g_assert (g_list_find (apriv->children, account) == NULL); test_signal_assert_hits (sig1, 1); test_signal_assert_hits (sig2, 1); - g_assert_cmpint (check_warn.hits, ==, 1); - g_assert_cmpint (check_err.hits, ==, 1); + g_assert_cmpint (check_warn->hits, ==, 1); + g_assert_cmpint (check_err->hits, ==, 1); test_signal_free (sig1); test_signal_free (sig2); xaccAccountBeginEdit (account); @@ -1706,23 +1719,23 @@ test_gnc_account_lookup_by_full_name_helper ( Fixture *fixture, gconstpointer pData ) { Account *root, *target; - gchar *names1[] = {"income", "taxable", "int", NULL}; - gchar *names2[] = {"income", "exempt", "int", NULL}; - gchar *names3[] = {"expense", "taxable", "int", NULL}; - gchar *code; + const char *names1[] = {"income", "taxable", "int", NULL}; + const char *names2[] = {"income", "exempt", "int", NULL}; + const char *names3[] = {"expense", "taxable", "int", NULL}; + char *code; AccountTestFunctions *func = _utest_account_fill_functions (); root = gnc_account_get_root (fixture->acct); - target = func->gnc_account_lookup_by_full_name_helper (root, names1); + target = func->gnc_account_lookup_by_full_name_helper (root, const_cast(names1)); g_assert (target != NULL); g_object_get (target, "code", &code, NULL); g_assert_cmpstr (code, == , "4160"); g_free (code); - target = func->gnc_account_lookup_by_full_name_helper (root, names2); + target = func->gnc_account_lookup_by_full_name_helper (root, const_cast(names2)); g_assert (target != NULL); g_object_get (target, "code", &code, NULL); g_assert_cmpstr (code, == , "4210"); - target = func->gnc_account_lookup_by_full_name_helper (root, names3); + target = func->gnc_account_lookup_by_full_name_helper (root, const_cast(names3)); g_assert (target == NULL); g_free (code); } @@ -1733,9 +1746,9 @@ static void test_gnc_account_lookup_by_full_name (Fixture *fixture, gconstpointer pData) { Account *root, *target; - gchar *names1 = "income:taxable:int"; - gchar *names2 = "income:exempt:int"; - gchar *names3 = "expense:taxable:int"; + auto names1 = "income:taxable:int"; + auto names2 = "income:exempt:int"; + auto names3 = "expense:taxable:int"; gchar *code; root = gnc_account_get_root (fixture->acct); @@ -1831,13 +1844,12 @@ test_gnc_account_foreach_descendant_until (Fixture *fixture, gconstpointer pData Account *first = gnc_account_lookup_by_code (root, "2000"); Account *second = gnc_account_lookup_by_code (root, "4000"); Account *expected = gnc_account_lookup_by_code (root, "4160"); - Account *result; - guint counter = 0; - result = gnc_account_foreach_descendant_until (first, thunk2, &counter); + unsigned int counter = 0; + auto result = static_cast(gnc_account_foreach_descendant_until (first, thunk2, &counter)); g_assert_cmpint (counter, == , 11); g_assert (result == NULL); counter = 0; - result = gnc_account_foreach_descendant_until (second, thunk2, &counter); + result = static_cast(gnc_account_foreach_descendant_until (second, thunk2, &counter)); g_assert (result == expected); g_assert_cmpint (counter, == , 6); } @@ -2051,7 +2063,7 @@ test_xaccAccountFindOpenLots (Fixture *fixture, gconstpointer pData) static gpointer bogus_for_each_lot_func (GNCLot *lot, gpointer data) { - guint *count = data; + auto count = static_cast(data); ++*count; return (*count > 4 ? lot : NULL); } @@ -2108,6 +2120,14 @@ test_xaccAccountHasAncestor (Fixture *fixture, gconstpointer pData) g_assert (!xaccAccountHasAncestor (ltcg, expense)); } +inline GNCAccountType& operator++(GNCAccountType& x) +{ + using AcctTypeType = std::underlying_type; + if (x < ACCT_TYPE_LAST) + x = static_cast(x + 1); + return x; +} + /* xaccAccountTypeEnumAsString * xaccAccountStringToType * xaccAccountStringToEnum @@ -2118,19 +2138,19 @@ xaccAccountTypeEnumAsString (GNCAccountType type)// C: 5 in 3 */ static void test_xaccAccountType_Stuff (void) { - GNCAccountType type; - gint loglevel = G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL; - gchar *logdomain = "gnc.account"; - gchar *msg1 = g_strdup_printf ("[xaccAccountTypeEnumAsString()] asked to translate unknown account type %d.\n", ACCT_TYPE_LAST); - gchar *msg2 = "[xaccAccountStringToType()] asked to translate unknown account type string (null).\n"; - gchar *msg3 = "[xaccAccountStringToType()] asked to translate unknown account type string LAST.\n"; + auto loglevel = static_cast(G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL); + auto logdomain = "gnc.account"; + auto msg1 = g_strdup_printf ("[xaccAccountTypeEnumAsString()] asked to translate unknown account type %d.\n", ACCT_TYPE_LAST); + auto msg2 = "[xaccAccountStringToType()] asked to translate unknown account type string (null).\n"; + auto msg3 = "[xaccAccountStringToType()] asked to translate unknown account type string LAST.\n"; guint loghandler = 0; - TestErrorStruct check1 = { loglevel, logdomain, msg1, 0 }; - TestErrorStruct check2 = { loglevel, logdomain, msg2, 0 }; - TestErrorStruct check3 = { loglevel, logdomain, msg3, 0 }; - Account *acc = g_object_new (GNC_TYPE_ACCOUNT, NULL); + auto check1 = test_error_struct_new(logdomain, loglevel, msg1); + auto check2 = test_error_struct_new(logdomain, loglevel, msg2); + auto check3 = test_error_struct_new(logdomain, loglevel, msg3); + auto acc = static_cast(g_object_new (GNC_TYPE_ACCOUNT, NULL)); + GNCAccountType type; - for (type = ACCT_TYPE_NONE; type < ACCT_TYPE_LAST; type = type + 1) + for (type = ACCT_TYPE_NONE; type < ACCT_TYPE_LAST; ++type) { const gchar *type_name = xaccAccountTypeEnumAsString (type); const gchar *typestr; @@ -2145,19 +2165,19 @@ test_xaccAccountType_Stuff (void) typestr_uc = g_ascii_strup (typestr, strlen (typestr)); if (type == ACCT_TYPE_PAYABLE || type == ACCT_TYPE_RECEIVABLE) { - gchar *cmpstr = g_strconcat ("A/", type_name, NULL); + auto cmpstr = g_strconcat ("A/", type_name, NULL); g_assert_cmpstr (typestr_uc, == , cmpstr); g_free (cmpstr); } else if (type == ACCT_TYPE_CREDIT) { - gchar *cmpstr = g_strconcat (type_name, " CARD", NULL); + auto cmpstr = g_strconcat (type_name, " CARD", NULL); g_assert_cmpstr (typestr_uc, == , cmpstr); g_free (cmpstr); } else if (type == ACCT_TYPE_MUTUAL) { - gchar *cmpstr = g_strconcat (type_name, " FUND", NULL); + auto cmpstr = g_strconcat (type_name, " FUND", NULL); g_assert_cmpstr (typestr_uc, == , cmpstr); g_free (cmpstr); } @@ -2178,25 +2198,25 @@ test_xaccAccountType_Stuff (void) g_object_unref (acc); loghandler = g_log_set_handler (logdomain, loglevel, - (GLogFunc)test_null_handler, &check1); - g_test_log_set_fatal_handler ((GTestLogFatalFunc)test_checked_handler, &check1); + (GLogFunc)test_null_handler, check1); + g_test_log_set_fatal_handler ((GTestLogFatalFunc)test_checked_handler, check1); g_assert (!xaccAccountTypeEnumAsString (ACCT_TYPE_LAST)); - g_assert_cmpint (check1.hits, ==, 1); + g_assert_cmpint (check1->hits, ==, 1); g_log_remove_handler (logdomain, loghandler); g_free (msg1); loghandler = g_log_set_handler (logdomain, loglevel, - (GLogFunc)test_null_handler, &check2); - g_test_log_set_fatal_handler ((GTestLogFatalFunc)test_checked_handler, &check2); + (GLogFunc)test_null_handler, check2); + g_test_log_set_fatal_handler ((GTestLogFatalFunc)test_checked_handler, check2); g_assert (!xaccAccountStringToType (NULL, &type)); - g_assert_cmpint (check2.hits, ==, 1); + g_assert_cmpint (check2->hits, ==, 1); g_log_remove_handler (logdomain, loghandler); loghandler = g_log_set_handler (logdomain, loglevel, - (GLogFunc)test_null_handler, &check3); - g_test_log_set_fatal_handler ((GTestLogFatalFunc)test_checked_handler, &check3); + (GLogFunc)test_null_handler, check3); + g_test_log_set_fatal_handler ((GTestLogFatalFunc)test_checked_handler, check3); g_assert (!xaccAccountStringToType ("LAST", &type)); - g_assert_cmpint (check3.hits, ==, 1); + g_assert_cmpint (check3->hits, ==, 1); g_log_remove_handler (logdomain, loghandler); @@ -2227,27 +2247,27 @@ test_xaccAccountType_Compatibility (void) guint32 trading_compat = ((1 << ACCT_TYPE_TRADING) | (1 << ACCT_TYPE_ROOT)); guint32 compat; GNCAccountType type; - gchar *msg1 = g_strdup_printf ("[xaccParentAccountTypesCompatibleWith()] bad account type: %d", ACCT_TYPE_ROOT); - gchar *msg2 = g_strdup_printf ("[xaccParentAccountTypesCompatibleWith()] bad account type: %d", ACCT_TYPE_SAVINGS); - gchar *logdomain = "gnc.account"; - guint loglevel = G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL; - TestErrorStruct check1 = { loglevel, logdomain, msg1, 0 }; - TestErrorStruct check2 = { loglevel, logdomain, msg2, 0 }; + auto msg1 = g_strdup_printf ("[xaccParentAccountTypesCompatibleWith()] bad account type: %d", ACCT_TYPE_ROOT); + auto msg2 = g_strdup_printf ("[xaccParentAccountTypesCompatibleWith()] bad account type: %d", ACCT_TYPE_SAVINGS); + auto logdomain = "gnc.account"; + auto loglevel = static_cast(G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL); + auto check1 = test_error_struct_new(logdomain, loglevel, msg1); + auto check2 = test_error_struct_new(logdomain, loglevel, msg2); gint loghandler; - for (type = ACCT_TYPE_BANK; type < NUM_ACCOUNT_TYPES; type = type + 1) + for (type = ACCT_TYPE_BANK; type < NUM_ACCOUNT_TYPES; type = ++type) { GNCAccountType child; if (type == ACCT_TYPE_ROOT) { loghandler = g_log_set_handler (logdomain, loglevel, - (GLogFunc)test_null_handler, &check1); + (GLogFunc)test_null_handler, check1); g_test_log_set_fatal_handler ((GTestLogFatalFunc)test_checked_handler, - &check1); + check1); compat = xaccParentAccountTypesCompatibleWith (type); g_log_remove_handler (logdomain, loghandler); g_assert_cmpint (compat, == , 0); - g_assert_cmpint (check1.hits, ==, 1); + g_assert_cmpint (check1->hits, ==, 1); g_free (msg1); continue; } @@ -2262,7 +2282,7 @@ test_xaccAccountType_Compatibility (void) g_assert_cmpint (compat, == , equity_compat); else if (type == ACCT_TYPE_TRADING) g_assert_cmpint (compat, == , trading_compat); - for (child = ACCT_TYPE_NONE; child < ACCT_TYPE_LAST; child = child + 1) + for (child = ACCT_TYPE_NONE; child < ACCT_TYPE_LAST; child = ++child) if (1 << child & compat) g_assert (xaccAccountTypesCompatible (type, child)); else @@ -2270,12 +2290,12 @@ test_xaccAccountType_Compatibility (void) } loghandler = g_log_set_handler (logdomain, loglevel, - (GLogFunc)test_null_handler, &check2); - g_test_log_set_fatal_handler ((GTestLogFatalFunc)test_checked_handler, &check2); - compat = xaccParentAccountTypesCompatibleWith (type = type + 1); + (GLogFunc)test_null_handler, check2); + g_test_log_set_fatal_handler ((GTestLogFatalFunc)test_checked_handler, check2); + compat = xaccParentAccountTypesCompatibleWith (++type); g_log_remove_handler (logdomain, loghandler); g_assert_cmpint (compat, == , 0); - g_assert_cmpint (check2.hits, ==, 1); + g_assert_cmpint (check2->hits, ==, 1); g_free (msg2); } /* More KVP getters & setters @@ -2379,13 +2399,13 @@ test_gnc_account_merge_children (Fixture *fixture, gconstpointer pData) gfloat baz_balance = gnc_numeric_to_double (xaccAccountGetBalance (baz)); gfloat baz2_balance = gnc_numeric_to_double (xaccAccountGetBalance (baz2)); TestSignal sig1, sig2, sig3; - gchar *logdomain = "gnc.engine"; - gint loglevel = G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL; - gchar *msg = "[xaccSplitCommitEdit ()] Account grabbed split prematurely."; - TestErrorStruct check = { loglevel, logdomain, msg, 0 }; + auto logdomain = "gnc.engine"; + auto loglevel = static_cast(G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL); + auto msg = "[xaccSplitCommitEdit ()] Account grabbed split prematurely."; + auto check = test_error_struct_new(logdomain, loglevel, msg); guint hdlr = g_log_set_handler (logdomain, loglevel, - (GLogFunc)test_null_handler, &check); - g_test_log_set_fatal_handler ((GTestLogFatalFunc)test_checked_handler, &check); + (GLogFunc)test_null_handler, check); + g_test_log_set_fatal_handler ((GTestLogFatalFunc)test_checked_handler, check); sig1 = test_signal_new (QOF_INSTANCE (baz), QOF_EVENT_MODIFY, NULL); sig2 = test_signal_new (QOF_INSTANCE (baz2), QOF_EVENT_MODIFY, NULL); @@ -2480,10 +2500,11 @@ test_xaccAccountTreeForEachTransaction (Fixture *fixture, gconstpointer pData ) g_assert_cmpint (td.count, == , 9); g_assert_cmpint (result, == , 0); td.count = 0; - td.name = "pepper"; + td.name = g_strdup("pepper"); result = xaccAccountTreeForEachTransaction (root, thunk3, &td); g_assert_cmpint (td.count, == , result); g_assert_cmpint (result, < , 9); + g_free(td.name); } /* xaccAccountForEachTransaction gint @@ -2502,10 +2523,11 @@ test_xaccAccountForEachTransaction (Fixture *fixture, gconstpointer pData ) g_assert_cmpint (td.count, == , 9); g_assert_cmpint (result, == , 0); td.count = 0; - td.name = "pepper"; + td.name = g_strdup("pepper"); result = xaccAccountForEachTransaction (money, thunk3, &td); g_assert_cmpint (td.count, == , result); g_assert_cmpint (result, < , 9); + g_free(td.name); } diff --git a/src/engine/test/utest-Split.cpp b/src/engine/test/utest-Split.cpp index 5612990f00..d692b6a264 100644 --- a/src/engine/test/utest-Split.cpp +++ b/src/engine/test/utest-Split.cpp @@ -21,11 +21,8 @@ * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 * * Boston, MA 02110-1301, USA gnu@gnu.org * ********************************************************************/ -#ifdef __cplusplus extern "C" { -#endif - #include "config.h" #include #include @@ -38,7 +35,6 @@ extern "C" #include #include #include -#include #include #ifdef HAVE_GLIB_2_38 @@ -52,10 +48,9 @@ extern "C" static const gchar *suitename = "/engine/Split"; void test_suite_split ( void ); - -#ifdef __cplusplus } -#endif + +#include typedef struct { @@ -308,7 +303,7 @@ test_xaccDupeSplit (Fixture *fixture, gconstpointer pData) g_assert (split->lot == f_split->lot); g_assert_cmpstr (split->memo, ==, f_split->memo); g_assert_cmpstr (split->action, ==, f_split->action); - g_assert (kvp_frame_compare (split->inst.kvp_data, f_split->inst.kvp_data) == 0); + g_assert (compare (split->inst.kvp_data, f_split->inst.kvp_data) == 0); g_assert_cmpint (split->reconciled, ==, f_split->reconciled); g_assert (timespec_equal (&(split->date_reconciled), &(f_split->date_reconciled))); g_assert (gnc_numeric_equal (split->value, f_split->value)); @@ -343,7 +338,7 @@ test_xaccSplitCloneNoKvp (Fixture *fixture, gconstpointer pData) g_assert (split->lot == f_split->lot); g_assert_cmpstr (split->memo, ==, f_split->memo); g_assert_cmpstr (split->action, ==, f_split->action); - g_assert (kvp_frame_is_empty (split->inst.kvp_data)); + g_assert (split->inst.kvp_data->empty()); g_assert_cmpint (split->reconciled, ==, f_split->reconciled); g_assert (timespec_equal (&(split->date_reconciled), &(f_split->date_reconciled))); g_assert (gnc_numeric_equal (split->value, f_split->value)); @@ -743,12 +738,12 @@ test_xaccSplitDetermineGainStatus (Fixture *fixture, gconstpointer pData) fixture->split->gains = GAINS_STATUS_UNKNOWN; fixture->split->gains_split = NULL; - g_assert (kvp_frame_get_slot (fixture->split->inst.kvp_data, "gains_source") == NULL); + g_assert (fixture->split->inst.kvp_data->get_slot("gains_source") == NULL); xaccSplitDetermineGainStatus (fixture->split); g_assert (fixture->split->gains_split == NULL); g_assert_cmpint (fixture->split->gains, ==, GAINS_STATUS_A_VDIRTY | GAINS_STATUS_DATE_DIRTY); - kvp_frame_set_guid (fixture->split->inst.kvp_data, "gains-source", g_guid); + fixture->split->inst.kvp_data->set("gains-source", new KvpValue(const_cast(g_guid))); g_assert (fixture->split->gains_split == NULL); fixture->split->gains = GAINS_STATUS_UNKNOWN; xaccSplitDetermineGainStatus (fixture->split); @@ -1778,13 +1773,13 @@ test_xaccSplitGetOtherSplit (Fixture *fixture, gconstpointer pData) Split *split1 = xaccMallocSplit (book); Split *split2 = xaccMallocSplit (book); Account *acc2 = xaccMallocAccount (book); - KvpValue *kvpnow = kvp_value_new_gint64 (gnc_time (NULL)); + KvpValue *kvpnow = new KvpValue (gnc_time (NULL)); g_assert (xaccSplitGetOtherSplit (NULL) == NULL); g_assert (xaccSplitGetOtherSplit (split1) == NULL); g_assert (xaccTransUseTradingAccounts (txn) == FALSE); - g_assert (kvp_frame_get_slot (split->inst.kvp_data, "lot-split") == NULL); + g_assert (split->inst.kvp_data->get_slot("lot-split") == NULL); g_assert_cmpint (xaccTransCountSplits (txn), !=, 2); g_assert (xaccSplitGetOtherSplit (split) == NULL); @@ -1795,18 +1790,18 @@ test_xaccSplitGetOtherSplit (Fixture *fixture, gconstpointer pData) xaccSplitSetParent (split2, txn); g_assert (xaccSplitGetOtherSplit (split) == NULL); - kvp_frame_set_slot (split->inst.kvp_data, "lot-split", kvpnow); - g_assert (kvp_frame_get_slot (split->inst.kvp_data, "lot-split")); + split->inst.kvp_data->set("lot-split", kvpnow); + g_assert (split->inst.kvp_data->get_slot("lot-split")); g_assert (xaccSplitGetOtherSplit (split) == NULL); - kvp_frame_set_slot (split1->inst.kvp_data, "lot-split", kvpnow); - g_assert (kvp_frame_get_slot (split1->inst.kvp_data, "lot-split")); + split1->inst.kvp_data->set("lot-split", kvpnow); + g_assert (split1->inst.kvp_data->get_slot("lot-split")); g_assert (xaccSplitGetOtherSplit (split) == split2); - kvp_frame_set_slot (split->inst.kvp_data, "lot-split", NULL); - g_assert (kvp_frame_get_slot (split->inst.kvp_data, "lot-split") == NULL); - kvp_frame_set_slot (split1->inst.kvp_data, "lot-split", NULL); - g_assert (kvp_frame_get_slot (split1->inst.kvp_data, "lot-split") == NULL); + split->inst.kvp_data->set("lot-split", NULL); + g_assert (split->inst.kvp_data->get_slot("lot-split") == NULL); + split1->inst.kvp_data->set("lot-split", NULL); + g_assert (split1->inst.kvp_data->get_slot("lot-split") == NULL); qof_book_begin_edit (book); qof_instance_set (QOF_INSTANCE (book), "trading-accts", "t", diff --git a/src/engine/test/utest-Transaction.c b/src/engine/test/utest-Transaction.cpp similarity index 85% rename from src/engine/test/utest-Transaction.c rename to src/engine/test/utest-Transaction.cpp index ec5d6d30fd..a07270b341 100644 --- a/src/engine/test/utest-Transaction.c +++ b/src/engine/test/utest-Transaction.cpp @@ -21,6 +21,8 @@ * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 * * Boston, MA 02110-1301, USA gnu@gnu.org * ********************************************************************/ +extern "C" +{ #include #include #include @@ -33,7 +35,6 @@ #include "../gnc-lot.h" #include "../gnc-event.h" #include -#include #include #ifdef HAVE_GLIB_2_38 @@ -47,6 +48,9 @@ static const gchar *suitename = "/engine/Transaction"; void test_suite_transaction ( void ); +} + +#include /* Copied from Transaction.c. Changing these values will break * existing databases, which is a good reason to fail a test. @@ -117,15 +121,14 @@ setup (Fixture *fixture, gconstpointer pData) { QofBook *book = qof_book_new (); MockBackend *mbe = mock_backend_new (); - Split *split1 = NULL, *split2 = NULL; Transaction *txn; Timespec entered = gnc_dmy2timespec (20, 4, 2012); Timespec posted = gnc_dmy2timespec (21, 4, 2012); - KvpFrame *frame = kvp_frame_new (); + auto frame = new KvpFrame (); qof_book_set_backend (book, (QofBackend*)mbe); - split1 = xaccMallocSplit (book); - split2 = xaccMallocSplit (book); + auto split1 = xaccMallocSplit (book); + auto split2 = xaccMallocSplit (book); txn = xaccMallocTransaction (book); fixture->txn = txn; fixture->curr = gnc_commodity_new (book, "Gnu Rand", "CURRENCY", "GNR", "", 240); @@ -138,23 +141,23 @@ setup (Fixture *fixture, gconstpointer pData) txn->date_posted.tv_nsec = posted.tv_nsec; txn->date_entered.tv_sec = entered.tv_sec; txn->date_entered.tv_nsec = entered.tv_nsec; - split1->memo = CACHE_INSERT ("foo"); - split1->action = CACHE_INSERT ("bar"); + split1->memo = static_cast(CACHE_INSERT ("foo")); + split1->action = static_cast(CACHE_INSERT ("bar")); split1->amount = gnc_numeric_create (100000, 1000); split1->value = gnc_numeric_create (3200, 240); split2->amount = gnc_numeric_create (-3200, 240); split2->value = gnc_numeric_create (-3200, 240); split1->acc = fixture->acc1; split2->acc = fixture->acc2; - txn->num = CACHE_INSERT ("123"); - txn->description = CACHE_INSERT ("Waldo Pepper"); + txn->num = static_cast(CACHE_INSERT ("123")); + txn->description = static_cast(CACHE_INSERT ("Waldo Pepper")); xaccTransBeginEdit (txn); { xaccTransSetCurrency (txn, fixture->curr); xaccSplitSetParent (split1, txn); xaccSplitSetParent (split2, txn); - kvp_frame_set_string (frame, trans_notes_str, "Salt pork sausage"); - kvp_frame_set_double (frame, "/qux/quux/corge", 123.456); + frame->set(trans_notes_str, new KvpValue("Salt pork sausage")); + frame->set_path("/qux/quux/corge", new KvpValue(123.456)); qof_instance_set_slots (QOF_INSTANCE (txn), frame); } xaccTransCommitEdit (txn); @@ -174,8 +177,6 @@ setup_with_gains (GainsFixture *fixture, gconstpointer pData) { QofBook *book; Fixture *base = &(fixture->base); - Split *gains_split1 = NULL, *gains_split2 = NULL; - Split *base_split = NULL; setup (base, NULL); @@ -183,8 +184,8 @@ setup_with_gains (GainsFixture *fixture, gconstpointer pData) fixture->gains_txn = xaccMallocTransaction (book); fixture->gains_acc = xaccMallocAccount (book); xaccAccountSetCommodity (fixture->gains_acc, base->curr); - gains_split1 = xaccMallocSplit (book); - gains_split2 = xaccMallocSplit (book); + auto gains_split1 = xaccMallocSplit (book); + auto gains_split2 = xaccMallocSplit (book); gains_split1->acc = base->acc1; gains_split2->acc = fixture->gains_acc; gains_split1->amount = gnc_numeric_create (30, 240); @@ -198,7 +199,7 @@ setup_with_gains (GainsFixture *fixture, gconstpointer pData) xaccSplitSetParent (gains_split2, fixture->gains_txn); } xaccTransCommitEdit (fixture->gains_txn); - base_split = g_list_nth_data (base->txn->splits, 1); + auto base_split = static_cast(g_list_nth_data (base->txn->splits, 1)); base_split->gains_split = gains_split1; } @@ -237,10 +238,10 @@ void check_open (const Transaction *trans)// Local: 1:0:0 static void test_check_open (Fixture *fixture, gconstpointer pData) { - gchar *msg = g_strdup_printf ("[check_open()] transaction %p not open for editing", fixture->txn); - GLogLevelFlags loglevel = G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL; - TestErrorStruct *check = test_error_struct_new ("gnc.engine", loglevel, - msg); + auto msg = g_strdup_printf ("[check_open()] transaction %p not open for editing", fixture->txn); + auto loglevel = static_cast(G_LOG_LEVEL_CRITICAL | + G_LOG_FLAG_FATAL); + auto check = test_error_struct_new ("gnc.engine", loglevel, msg); g_free (msg); fixture->hdlrs = test_log_set_fatal_handler (fixture->hdlrs, check, (GLogFunc)test_checked_handler); @@ -260,7 +261,7 @@ static void test_xaccTransStillHasSplit (Fixture *fixture, gconstpointer pData) { QofBook *book = qof_instance_get_book (QOF_INSTANCE (fixture->txn)); - Split *split = xaccMallocSplit (book); + auto split = xaccMallocSplit (book); g_assert (!xaccTransStillHasSplit (fixture->txn, split)); xaccSplitSetParent (split, fixture->txn); g_assert (xaccTransStillHasSplit (fixture->txn, split)); @@ -280,7 +281,7 @@ void mark_trans (Transaction *trans)// Local: 3:0:0 #define check_split_dirty(xsplit, test) \ { \ gboolean sort_dirty, balance_dirty; \ - Split *split = xsplit; \ + auto split = xsplit; \ g_object_get (split->acc, \ "sort-dirty", &sort_dirty, \ "balance-dirty", &balance_dirty, \ @@ -299,7 +300,7 @@ test_mark_trans (Fixture *fixture, gconstpointer pData) { if (!splits->data) continue; g_assert (!qof_instance_get_dirty_flag (splits->data)); - check_split_dirty (splits->data, FALSE); + check_split_dirty (static_cast(splits->data), FALSE); } fixture->func->mark_trans (fixture->txn); g_assert (!qof_instance_get_dirty_flag (fixture->txn)); @@ -307,7 +308,7 @@ test_mark_trans (Fixture *fixture, gconstpointer pData) { if (!splits->data) continue; g_assert (!qof_instance_get_dirty_flag (splits->data)); - check_split_dirty (splits->data, TRUE); + check_split_dirty (static_cast(splits->data), TRUE); } } /* gen_event_trans @@ -316,7 +317,7 @@ void gen_event_trans (Transaction *trans)// Local: 2:0:0 static void test_gen_event_trans (Fixture *fixture, gconstpointer pData) { - Split *split = fixture->txn->splits->data; + auto split = static_cast(fixture->txn->splits->data); GNCLot *lot = gnc_lot_new (qof_instance_get_book (QOF_INSTANCE (fixture->txn))); TestSignal sig1 = test_signal_new (QOF_INSTANCE (fixture->acc1), GNC_EVENT_ITEM_CHANGED, split); @@ -340,7 +341,7 @@ gnc_transaction_init(Transaction* trans)*/ static void test_gnc_transaction_init () { - Transaction *txn = g_object_new (GNC_TYPE_TRANSACTION, NULL); + auto txn = static_cast(g_object_new (GNC_TYPE_TRANSACTION, NULL)); g_assert_cmpstr (txn->num, ==, ""); g_assert_cmpstr (txn->description, ==, ""); g_assert (txn->common_currency == NULL); @@ -361,9 +362,9 @@ static void test_gnc_transaction_dispose () { QofBook *book = qof_book_new (); - Transaction *txn = g_object_new (GNC_TYPE_TRANSACTION, "book", book, NULL); - Split *split = g_object_new (GNC_TYPE_SPLIT, "book", book, NULL); - Split *s_ref = split; + auto txn = static_cast(g_object_new (GNC_TYPE_TRANSACTION, "book", book, NULL)); + auto split = static_cast(g_object_new (GNC_TYPE_SPLIT, "book", book, NULL)); + auto s_ref = split; gnc_commodity *curr = gnc_commodity_new (book, "Gnu Rand", "CURRENCY", "GNR", "", 240), *t_curr = NULL; gnc_commodity *c_ref = curr; @@ -398,7 +399,7 @@ gnc_transaction_finalize(GObject* txnp)*/ static void test_gnc_transaction_finalize () { - Transaction *txn = g_object_new (GNC_TYPE_TRANSACTION, NULL); + auto txn = static_cast(g_object_new (GNC_TYPE_TRANSACTION, NULL)); test_destroy (txn); } /* gnc_transaction_get_property @@ -409,21 +410,20 @@ static void test_gnc_transaction_set_get_property (Fixture *fixture, gconstpointer pData) { QofBook *book = qof_book_new (); - Transaction *txn = g_object_new (GNC_TYPE_TRANSACTION, "book", book, NULL); - gchar *num = "42", *desc = "The Answer", *t_num = NULL, *t_desc = NULL, *phony = NULL; + auto txn = static_cast(g_object_new (GNC_TYPE_TRANSACTION, "book", book, NULL)); + auto num = "42", desc = "The Answer"; + gchar *t_num = NULL, *t_desc = NULL, *phony = NULL; gnc_commodity *curr = gnc_commodity_new (book, "Gnu Rand", "CURRENCY", "GNR", "", 240), *t_curr = NULL; Timespec now = timespec_now (), *t_entered = NULL, *t_posted = NULL; time_t secs = (time_t)now.tv_sec; - gchar *msg1 = "g_object_set_valist: object class " _Q "Transaction' has no property named " _Q "bogus'"; - gchar *msg2 = g_strdup_printf ("[xaccTransSetDateInternal] addr=%p set date to %" G_GUINT64_FORMAT ".%09ld %s", + auto msg1 = "g_object_set_valist: object class " _Q "Transaction' has no property named " _Q "bogus'"; + auto msg2 = g_strdup_printf ("[xaccTransSetDateInternal] addr=%p set date to %" G_GUINT64_FORMAT ".%09ld %s", txn, now.tv_sec, now.tv_nsec, ctime (&secs)); - GLogLevelFlags loglevel1 = G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL; - GLogLevelFlags loglevel2 = G_LOG_LEVEL_INFO; - TestErrorStruct *check1 = test_error_struct_new ("GLib-GObject", - loglevel1, msg1); - TestErrorStruct *check2 = test_error_struct_new ("gnc.engine", - loglevel2, msg2); + auto loglevel1 = static_cast(G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL); + auto loglevel2 =static_cast(G_LOG_LEVEL_INFO); + auto check1 = test_error_struct_new ("GLib-GObject", loglevel1, msg1); + auto check2 = test_error_struct_new ("gnc.engine", loglevel2, msg2); g_free (msg2); fixture->hdlrs = test_log_set_fatal_handler (fixture->hdlrs, check1, (GLogFunc)test_checked_handler); @@ -494,12 +494,11 @@ test_xaccMallocTransaction (Fixture *fixture, gconstpointer pData) #else #define _func "xaccMallocTransaction" #endif - gchar *msg = _func ": assertion " _Q "book' failed"; + auto msg = _func ": assertion " _Q "book' failed"; #undef _func - gchar *logdomain = "gnc.engine"; - guint loglevel = G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL; - TestErrorStruct *check = test_error_struct_new ("gnc.engine", loglevel, - msg); + auto logdomain = "gnc.engine"; + auto loglevel = static_cast(G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL); + auto check = test_error_struct_new ("gnc.engine", loglevel, msg); fixture->hdlrs = test_log_set_fatal_handler (fixture->hdlrs, check, (GLogFunc)test_checked_handler); test_signal_assert_hits (sig1, 0); @@ -526,8 +525,8 @@ test_xaccTransSortSplits (Fixture *fixture, gconstpointer pData) { Transaction *txn = fixture->txn; QofBook *book = qof_instance_get_book (QOF_INSTANCE (txn)); - Split *split1 = txn->splits->data; - Split *split2 = txn->splits->next->data; + auto split1 = static_cast(txn->splits->data); + auto split2 = static_cast(txn->splits->next->data); Split *split[3]; guint i; GList *node; @@ -587,8 +586,8 @@ test_dupe_trans (Fixture *fixture, gconstpointer pData) oldtxn->date_posted = posted; oldtxn->date_entered = entered; - kvp_frame_set_string (oldtxn->inst.kvp_data, "/foo/bar/baz", - "The Great Waldo Pepper"); + oldtxn->inst.kvp_data->set("/foo/bar/baz", + new KvpValue("The Great Waldo Pepper")); newtxn = fixture->func->dupe_trans (oldtxn); @@ -597,7 +596,8 @@ test_dupe_trans (Fixture *fixture, gconstpointer pData) for (newnode = newtxn->splits; newnode && oldnode; newnode = g_list_next (newnode)) { - g_assert (xaccSplitEqual (newnode->data, oldnode->data, + g_assert (xaccSplitEqual (static_cast(newnode->data), + static_cast(oldnode->data), TRUE, FALSE, TRUE)); oldnode = g_list_next (oldnode); } @@ -613,7 +613,7 @@ test_dupe_trans (Fixture *fixture, gconstpointer pData) g_assert (guid_equal (qof_instance_get_guid (QOF_INSTANCE (newtxn)), guid_null ())); g_assert (qof_instance_get_book (QOF_INSTANCE (newtxn)) == old_book); - g_assert (kvp_frame_compare (oldtxn->inst.kvp_data, newtxn->inst.kvp_data) == 0); + g_assert (compare (oldtxn->inst.kvp_data, newtxn->inst.kvp_data) == 0); test_destroy (newtxn); } @@ -648,7 +648,8 @@ test_xaccTransClone (Fixture *fixture, gconstpointer pData) for (newnode = newtxn->splits; newnode && oldnode; newnode = g_list_next (newnode)) { - g_assert (xaccSplitEqual (newnode->data, oldnode->data, + g_assert (xaccSplitEqual (static_cast(newnode->data), + static_cast(oldnode->data), FALSE, FALSE, FALSE)); oldnode = g_list_next (oldnode); } @@ -664,7 +665,7 @@ test_xaccTransClone (Fixture *fixture, gconstpointer pData) g_assert (newtxn->common_currency == fixture->curr); g_assert (qof_instance_get_book (QOF_INSTANCE (newtxn)) == old_book); - g_assert (kvp_frame_compare (oldtxn->inst.kvp_data, newtxn->inst.kvp_data) == 0); + g_assert (compare (oldtxn->inst.kvp_data, newtxn->inst.kvp_data) == 0); test_destroy (newtxn); } @@ -690,7 +691,7 @@ test_xaccTransCopyFromClipBoard (Fixture *fixture, gconstpointer pData) Transaction *to_txn = xaccMallocTransaction (book); Timespec now = timespec_now(); Timespec never = {0, 0}; - KvpFrame *to_frame = to_txn->inst.kvp_data; + auto to_frame = to_txn->inst.kvp_data; xaccAccountSetCommodity (acc1, fixture->comm); xaccTransCopyFromClipBoard (txn, to_txn, fixture->acc1, acc1, FALSE); @@ -743,13 +744,14 @@ test_xaccFreeTransaction (Fixture *fixture, gconstpointer pData) { Transaction *txn = fixture->txn; Transaction *orig = xaccMallocTransaction (qof_instance_get_book (QOF_INSTANCE (txn))); - Split *split = txn->splits->data; - gchar *txn_num = "321"; - g_object_add_weak_pointer (G_OBJECT (txn->splits->data), (gpointer)&split); + auto split = static_cast(txn->splits->data); + auto txn_num = "321"; + g_object_add_weak_pointer (G_OBJECT (txn->splits->data), + reinterpret_cast(&split)); /* so the "free" doesn't, leaving the structure for us to test */ g_object_ref (txn); g_object_ref (orig); - orig->num = CACHE_INSERT (txn_num); + orig->num = static_cast(CACHE_INSERT (txn_num)); txn->orig = orig; fixture->func->xaccFreeTransaction (txn); @@ -791,21 +793,20 @@ test_xaccTransEqual (Fixture *fixture, gconstpointer pData) Transaction *txn1 = xaccTransClone (txn0); const GncGUID *guid_f_txn = qof_instance_get_guid (txn0); gchar entered[DATE_BUF_SIZE], posted[DATE_BUF_SIZE]; - gchar *msg1 = "[xaccTransEqual] one is NULL"; + auto msg1 = "[xaccTransEqual] one is NULL"; gchar *msg2 = NULL; - gchar *cleanup_fmt = "[trans_cleanup_commit] get rid of rollback trans=%p"; + auto cleanup_fmt = "[trans_cleanup_commit] get rid of rollback trans=%p"; gchar split_guid0[GUID_ENCODING_LENGTH + 1]; gchar split_guid1[GUID_ENCODING_LENGTH + 1]; - gchar *logdomain = "gnc.engine"; - guint loglevel = G_LOG_LEVEL_INFO; - TestErrorStruct *check = test_error_struct_new (logdomain, loglevel, msg1); - TestErrorStruct check2 = {loglevel, logdomain, msg2, 0}; - TestErrorStruct check3 = {loglevel, logdomain, "", 0}; - TestErrorStruct *cleanup = test_error_struct_new (logdomain, loglevel, ""); - Split *split0 = xaccTransGetSplit (txn0, 0); - Split *split1; + auto logdomain = "gnc.engine"; + auto loglevel = static_cast(G_LOG_LEVEL_INFO); + auto check = test_error_struct_new (logdomain, loglevel, msg1); + auto check2 = test_error_struct_new(logdomain, loglevel, msg2); + auto check3 = test_error_struct_new(logdomain, loglevel, ""); + auto cleanup = test_error_struct_new (logdomain, loglevel, ""); + auto split0 = xaccTransGetSplit (txn0, 0); test_add_error (check); - test_add_error (&check2); + test_add_error (check2); test_add_error (cleanup); fixture->hdlrs = test_log_set_handler (fixture->hdlrs, check, @@ -869,7 +870,7 @@ test_xaccTransEqual (Fixture *fixture, gconstpointer pData) xaccTransBeginEdit (clone); cleanup->msg = g_strdup_printf (cleanup_fmt, clone->orig); clone->date_entered.tv_sec = txn0->date_entered.tv_sec; - clone->num = "123"; + clone->num = g_strdup("123"); xaccTransCommitEdit (clone); g_free (cleanup->msg); g_free (check->msg); @@ -879,15 +880,17 @@ test_xaccTransEqual (Fixture *fixture, gconstpointer pData) g_assert (xaccTransEqual (txn1, clone, TRUE, FALSE, TRUE, TRUE)); g_assert_cmpint (check->hits, ==, 5); - txn1->num = "321"; + txn1->num = g_strdup("321"); g_free (check->msg); check->msg = g_strdup ("[xaccTransEqual] num differs: 321 vs 123"); g_assert (!xaccTransEqual (txn1, txn0, TRUE, FALSE, TRUE, TRUE)); g_assert_cmpint (check->hits, ==, 6); - clone->num = CACHE_INSERT("123"); - txn1->num = "123"; - clone->description = "salt pork"; + g_free(clone->num); + clone->num = static_cast(CACHE_INSERT("123")); + g_free(txn1->num); + txn1->num = g_strdup("123"); + clone->description = g_strdup("salt pork"); g_free (check->msg); check->msg = g_strdup ("[xaccTransEqual] descriptions differ: salt pork vs Waldo Pepper"); g_assert (!xaccTransEqual (clone, txn0, TRUE, FALSE, TRUE, TRUE)); @@ -899,47 +902,47 @@ test_xaccTransEqual (Fixture *fixture, gconstpointer pData) xaccTransBeginEdit (clone); cleanup->msg = g_strdup_printf (cleanup_fmt, clone->orig); - clone->description = CACHE_INSERT ("Waldo Pepper"); - kvp_frame_set_double (qof_instance_get_slots (QOF_INSTANCE (clone)), - "/qux/quux/corge", 654.321); + g_free(clone->description); + clone->description = static_cast(CACHE_INSERT ("Waldo Pepper")); + auto frame = qof_instance_get_slots (QOF_INSTANCE (clone)); + frame->set("/qux/quux/corge", new KvpValue(654.321)); xaccTransCommitEdit (clone); g_free (cleanup->msg); g_free (check->msg); - check->msg = g_strdup ("[xaccTransEqual] kvp frames differ:\n{\n notes => KVP_VALUE_STRING(Salt pork sausage),\n qux => KVP_VALUE_FRAME({\n quux => KVP_VALUE_FRAME({\n corge => KVP_VALUE_DOUBLE(654.321),\n}\n),\n}\n),\n}\n\n\nvs\n\n{\n notes => KVP_VALUE_STRING(Salt pork sausage),\n qux => KVP_VALUE_FRAME({\n quux => KVP_VALUE_FRAME({\n corge => KVP_VALUE_DOUBLE(123.456),\n}\n),\n}\n),\n}\n"); + check->msg = g_strdup ("[xaccTransEqual] kvp frames differ:\n{\n => KVP_VALUE_FRAME({\n qux => KVP_VALUE_FRAME({\n quux => KVP_VALUE_FRAME({\n corge => KVP_VALUE_DOUBLE(654.321),\n}\n),\n}\n),\n}\n),\n notes => KVP_VALUE_STRING(Salt pork sausage),\n}\n\n\nvs\n\n{\n => KVP_VALUE_FRAME({\n qux => KVP_VALUE_FRAME({\n quux => KVP_VALUE_FRAME({\n corge => KVP_VALUE_DOUBLE(123.456),\n}\n),\n}\n),\n}\n),\n notes => KVP_VALUE_STRING(Salt pork sausage),\n}\n"); g_assert (!xaccTransEqual (clone, txn0, TRUE, FALSE, TRUE, TRUE)); g_assert_cmpint (check->hits, ==, 9); xaccTransBeginEdit (clone); cleanup->msg = g_strdup_printf (cleanup_fmt, clone->orig); - clone->description = CACHE_INSERT ("Waldo Pepper"); - kvp_frame_set_double (qof_instance_get_slots (QOF_INSTANCE (clone)), - "/qux/quux/corge", 123.456); + clone->description = static_cast(CACHE_INSERT ("Waldo Pepper")); + frame->set("/qux/quux/corge", new KvpValue(123.456)); xaccTransCommitEdit (clone); g_free (cleanup->msg); g_free (check->msg); check->msg = g_strdup ("[xaccSplitEqual] GUIDs differ"); - split1 = xaccTransGetSplit (clone, 0); + auto split1 = xaccTransGetSplit (clone, 0); guid_to_string_buff (qof_instance_get_guid (split0), split_guid0); guid_to_string_buff (qof_instance_get_guid (split1), split_guid1); - check2.msg = g_strdup_printf ( + check2->msg = g_strdup_printf ( "[xaccTransEqual] splits %s and %s differ", split_guid1, split_guid0); g_assert (!xaccTransEqual (clone, txn0, TRUE, TRUE, TRUE, TRUE)); g_assert (xaccTransEqual (clone, txn0, FALSE, FALSE, FALSE, TRUE)); g_assert_cmpint (check->hits, ==, 10); - g_assert_cmpint (check2.hits, ==, 1); + g_assert_cmpint (check2->hits, ==, 1); g_free (check->msg); - g_free (check2.msg); + g_free (check2->msg); check->msg = g_strdup("[xaccSplitEqual] amounts differ: 13333/1000 vs 100000/1000"); - check2.msg = g_strdup_printf ( + check2->msg = g_strdup_printf ( "[xaccTransEqual] splits %s and %s differ", split_guid0, split_guid0); qof_instance_set_guid (split1, qof_instance_get_guid (split0)); g_assert (!xaccTransEqual (clone, txn0, TRUE, TRUE, TRUE, TRUE)); g_assert (xaccTransEqual (clone, txn0, TRUE, FALSE, FALSE, TRUE)); g_assert_cmpint (check->hits, ==, 11); - g_assert_cmpint (check2.hits, ==, 2); + g_assert_cmpint (check2->hits, ==, 2); qof_instance_set_guid (xaccTransGetSplit (txn1, 0), qof_instance_get_guid (split0)); @@ -951,26 +954,26 @@ test_xaccTransEqual (Fixture *fixture, gconstpointer pData) Split* split01 = xaccTransGetSplit (txn0, 1); Split* split10 = xaccTransGetSplit (txn1, 0); Split* split11 = xaccTransGetSplit (txn1, 1); - gchar *bal00 = gnc_numeric_to_string (split00->balance); - gchar *bal01 = gnc_numeric_to_string (split01->balance); - gchar *bal10 = gnc_numeric_to_string (split10->balance); - gchar *bal11 = gnc_numeric_to_string (split11->balance); + auto bal00 = gnc_numeric_to_string (split00->balance); + auto bal01 = gnc_numeric_to_string (split01->balance); + auto bal10 = gnc_numeric_to_string (split10->balance); + auto bal11 = gnc_numeric_to_string (split11->balance); check->msg = g_strdup_printf("[xaccSplitEqualCheckBal] balances differ: %s vs %s", bal10, bal00); - check3.msg = g_strdup_printf("[xaccSplitEqualCheckBal] balances differ: %s vs %s", bal11, bal01); + check3->msg = g_strdup_printf("[xaccSplitEqualCheckBal] balances differ: %s vs %s", bal11, bal01); - test_add_error (&check3); + test_add_error (check3); g_assert (!xaccTransEqual (txn1, txn0, TRUE, TRUE, TRUE, TRUE)); g_assert (xaccTransEqual (txn1, txn0, TRUE, TRUE, FALSE, TRUE)); g_assert_cmpint (check->hits, ==, 12); - g_assert_cmpint (check2.hits, ==, 3); - g_assert_cmpint (check3.hits, ==, 0); + g_assert_cmpint (check2->hits, ==, 3); + g_assert_cmpint (check3->hits, ==, 0); split10->balance = split00->balance; split11->balance = split01->balance; g_assert (xaccTransEqual (txn1, txn0, TRUE, TRUE, TRUE, TRUE)); } - g_free (check3.msg); - g_free (check2.msg); + g_free (check3->msg); + g_free (check2->msg); } /* xaccTransUseTradingAccounts xaccTransUseTradingAccounts @@ -999,12 +1002,12 @@ static void test_xaccTransGetImbalanceValue (Fixture *fixture, gconstpointer pData) { QofBook *book = qof_instance_get_book (QOF_INSTANCE (fixture->txn)); - Split *split1 = xaccMallocSplit (book); + auto split1 = xaccMallocSplit (book); g_assert (gnc_numeric_equal (xaccTransGetImbalanceValue (fixture->txn), gnc_numeric_zero ())); split1->acc = fixture->acc1; - split1->memo = CACHE_INSERT ("foo"); - split1->action = CACHE_INSERT ("bar"); + split1->memo = static_cast(CACHE_INSERT ("foo")); + split1->action = static_cast(CACHE_INSERT ("bar")); split1->amount = gnc_numeric_create (100000, 1000); split1->value = gnc_numeric_create (3200, 240); xaccTransBeginEdit (fixture->txn); @@ -1022,15 +1025,15 @@ static void test_xaccTransGetImbalance (Fixture *fixture, gconstpointer pData) { QofBook *book = qof_instance_get_book (QOF_INSTANCE (fixture->txn)); - Split *split1 = xaccMallocSplit (book); + auto split1 = xaccMallocSplit (book); MonetaryList *mlist; g_assert (xaccTransGetImbalance (NULL) == NULL); mlist = xaccTransGetImbalance (fixture->txn); g_assert_cmpint (g_list_length (mlist), ==, 0); split1->acc = fixture->acc1; - split1->memo = CACHE_INSERT ("foo"); - split1->action = CACHE_INSERT ("bar"); + split1->memo = static_cast(CACHE_INSERT ("foo")); + split1->action = static_cast(CACHE_INSERT ("bar")); split1->amount = gnc_numeric_create (100000, 1000); split1->value = gnc_numeric_create (3200, 240); xaccTransBeginEdit (fixture->txn); @@ -1046,8 +1049,8 @@ test_xaccTransGetImbalance_trading (Fixture *fixture, gconstpointer pData) { QofBook *book = qof_instance_get_book (QOF_INSTANCE (fixture->txn)); - Split *split1 = xaccMallocSplit (book); - Split *split2 = xaccMallocSplit (book); + auto split1 = xaccMallocSplit (book); + auto split2 = xaccMallocSplit (book); Account *acc1 = xaccMallocAccount (book); Account *acc2 = xaccMallocAccount (book); gnc_numeric value; @@ -1071,13 +1074,13 @@ test_xaccTransGetImbalance_trading (Fixture *fixture, g_assert (!xaccTransIsBalanced (fixture->txn)); /* Make it look like a proper trading accounts transactionm */ split1->acc = acc1; - split1->memo = CACHE_INSERT ("foo"); - split1->action = CACHE_INSERT ("bar"); + split1->memo = static_cast(CACHE_INSERT ("foo")); + split1->action = static_cast(CACHE_INSERT ("bar")); split1->amount = gnc_numeric_create (-10000, 100); split1->value = gnc_numeric_create (-3200, 240); split2->acc = acc2; - split2->memo = CACHE_INSERT ("foo"); - split2->action = CACHE_INSERT ("bar"); + split2->memo = static_cast(CACHE_INSERT ("foo")); + split2->action = static_cast(CACHE_INSERT ("bar")); split2->amount = gnc_numeric_create (3000, 240); split2->value = gnc_numeric_create (3200, 240); xaccTransBeginEdit (fixture->txn); @@ -1114,13 +1117,13 @@ static void test_xaccTransIsBalanced (Fixture *fixture, gconstpointer pData) { QofBook *book = qof_instance_get_book (QOF_INSTANCE (fixture->txn)); - Split *split1 = xaccMallocSplit (book); + auto split1 = xaccMallocSplit (book); g_assert (!xaccTransIsBalanced (NULL)); g_assert (xaccTransIsBalanced (fixture->txn)); split1->acc = fixture->acc1; - split1->memo = CACHE_INSERT ("foo"); - split1->action = CACHE_INSERT ("bar"); + split1->memo = static_cast(CACHE_INSERT ("foo")); + split1->action = static_cast(CACHE_INSERT ("bar")); split1->amount = gnc_numeric_create (100000, 1000); split1->value = gnc_numeric_create (3200, 240); xaccTransBeginEdit (fixture->txn); @@ -1134,8 +1137,8 @@ static void test_xaccTransIsBalanced_trading (Fixture *fixture, gconstpointer pData) { QofBook *book = qof_instance_get_book (QOF_INSTANCE (fixture->txn)); - Split *split1 = xaccMallocSplit (book); - Split *split2 = xaccMallocSplit (book); + auto split1 = xaccMallocSplit (book); + auto split2 = xaccMallocSplit (book); Account *acc1 = xaccMallocAccount (book); Account *acc2 = xaccMallocAccount (book); @@ -1152,13 +1155,13 @@ test_xaccTransIsBalanced_trading (Fixture *fixture, gconstpointer pData) /* The setup transaction is unbalanced in a trading-accounts environment. */ g_assert (!xaccTransIsBalanced (fixture->txn)); split1->acc = acc1; - split1->memo = CACHE_INSERT ("foo"); - split1->action = CACHE_INSERT ("bar"); + split1->memo = static_cast(CACHE_INSERT ("foo")); + split1->action = static_cast(CACHE_INSERT ("bar")); split1->amount = gnc_numeric_create (3200, 240); split1->value = gnc_numeric_create (3200, 240); split2->acc = acc2; - split2->memo = CACHE_INSERT ("foo"); - split2->action = CACHE_INSERT ("bar"); + split2->memo = static_cast(CACHE_INSERT ("foo")); + split2->action = static_cast(CACHE_INSERT ("bar")); split2->amount = gnc_numeric_create (-10000, 100); split2->value = gnc_numeric_create (-3000, 240); xaccTransBeginEdit (fixture->txn); @@ -1218,8 +1221,8 @@ test_xaccTransGetRateForCommodity (Fixture *fixture, gconstpointer pData) { gnc_numeric rate = gnc_numeric_zero (); QofBook *book = qof_instance_get_book (QOF_INSTANCE (fixture->txn)); - Split *split0 = xaccMallocSplit (book); - Split *split1 = xaccTransFindSplitByAccount(fixture->txn, fixture->acc1); + auto split0 = xaccMallocSplit (book); + auto split1 = xaccTransFindSplitByAccount(fixture->txn, fixture->acc1); g_assert (!xaccTransGetRateForCommodity (NULL, fixture->comm, split0, &rate)); g_assert (!xaccTransGetRateForCommodity (fixture->txn, NULL, @@ -1246,11 +1249,10 @@ xaccTransGetAccountConvRate(const Transaction *txn, const Account *acc)// C: 5 i static void test_xaccTransGetAccountConvRate (Fixture *fixture, gconstpointer pData) { - gchar *msg1 = "[xaccTransGetAccountConvRate()] How can amount be nonzero and value be zero?"; - guint loglevel = G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL; - TestErrorStruct *check = test_error_struct_new ("gnc.engine", loglevel, - msg1); - Split *split1 = xaccTransFindSplitByAccount(fixture->txn, fixture->acc1); + auto msg1 = "[xaccTransGetAccountConvRate()] How can amount be nonzero and value be zero?"; + auto loglevel = static_cast(G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL); + auto check = test_error_struct_new ("gnc.engine", loglevel, msg1); + auto split1 = xaccTransFindSplitByAccount(fixture->txn, fixture->acc1); gnc_numeric rate; fixture->hdlrs = test_log_set_fatal_handler (fixture->hdlrs, check, @@ -1281,12 +1283,11 @@ test_xaccTransGetAccountBalance (Fixture *fixture, gconstpointer pData) #else #define _func "xaccTransGetAccountBalance" #endif - gchar *msg1 = _func ": assertion " _Q "account && trans' failed"; + auto msg1 = _func ": assertion " _Q "account && trans' failed"; #undef _func - guint loglevel = G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL; - TestErrorStruct *check = test_error_struct_new ("gnc.engine", loglevel, - msg1); - Split *split1 = xaccTransFindSplitByAccount(fixture->txn, fixture->acc1); + auto loglevel = static_cast(G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL); + auto check = test_error_struct_new ("gnc.engine", loglevel, msg1); + auto split1 = xaccTransFindSplitByAccount(fixture->txn, fixture->acc1); gnc_numeric rate; fixture->hdlrs = test_log_set_fatal_handler (fixture->hdlrs, check, @@ -1323,7 +1324,7 @@ test_xaccTransSetCurrency (Fixture *fixture, gconstpointer pData) { QofBook *book = qof_instance_get_book (QOF_INSTANCE (fixture->txn)); gnc_commodity *curr = gnc_commodity_new (book, "Japanese Yen", "CURRENCY", "JPY", "Â¥", 1); - Split *split1 = xaccTransFindSplitByAccount (fixture->txn, fixture->acc1); + auto split1 = xaccTransFindSplitByAccount (fixture->txn, fixture->acc1); gnc_numeric old_val = xaccSplitGetValue (split1); /* Prevent commit in xaccTransSetCurrency() */ xaccTransBeginEdit(fixture->txn); @@ -1344,12 +1345,12 @@ test_xaccTransBeginEdit () QofBook *book = qof_book_new (); Transaction *txn = xaccMallocTransaction (book); Transaction *dupe = NULL; - gchar *msg1 = "[xaccOpenLog] Attempt to open disabled transaction log"; - gchar *msg2 = "[xaccTransWriteLog] Attempt to write disabled transaction log"; - guint loglevel = G_LOG_LEVEL_INFO; - gchar *logdomain = "gnc.translog"; - TestErrorStruct *check1 = test_error_struct_new (logdomain, loglevel, msg1); - TestErrorStruct *check2 = test_error_struct_new (logdomain, loglevel, msg2); + auto msg1 = "[xaccOpenLog] Attempt to open disabled transaction log"; + auto msg2 = "[xaccTransWriteLog] Attempt to write disabled transaction log"; + auto loglevel = static_cast(G_LOG_LEVEL_INFO); + auto logdomain = "gnc.translog"; + auto check1 = test_error_struct_new (logdomain, loglevel, msg1); + auto check2 = test_error_struct_new (logdomain, loglevel, msg2); guint hdlr = g_log_set_handler (logdomain, loglevel, (GLogFunc)test_list_handler, NULL); test_add_error (check1); @@ -1435,7 +1436,7 @@ test_destroy_gains (GainsFixture *fixture, gconstpointer pData) * function that isn't protected. */ Fixture *base = &(fixture->base); - Split *base_split = g_list_nth_data (base->txn->splits, 1); + auto base_split = static_cast(g_list_nth_data (base->txn->splits, 1)); xaccTransBeginEdit (fixture->gains_txn); /* Protect it from being actually destroyed */ base->func->destroy_gains (base->txn); g_assert (qof_instance_get_destroying (QOF_INSTANCE (fixture->gains_txn))); @@ -1452,12 +1453,12 @@ static void test_do_destroy (GainsFixture *fixture, gconstpointer pData) { Fixture *base = &(fixture->base); - Split *base_split = g_list_nth_data (base->txn->splits, 1); + auto base_split = static_cast(g_list_nth_data (base->txn->splits, 1)); QofBook *book = qof_instance_get_book (base->txn); TestSignal sig = test_signal_new (QOF_INSTANCE (base->txn), QOF_EVENT_DESTROY, NULL); g_object_add_weak_pointer (G_OBJECT (base->txn->splits->data), - (gpointer)&base_split); + reinterpret_cast(&base_split)); g_object_ref (base->txn); g_object_ref (fixture->gains_txn); @@ -1491,7 +1492,7 @@ test_was_trans_emptied (Fixture *fixture, gconstpointer pData) static void trans_on_error(Transaction *trans, QofBackendError errcode)// Local: 0:1:0 callback for qof_commit_edit_part2, xaccTransCommitEdit */ -static QofBackendError errorvalue = 0; +static QofBackendError errorvalue = ERR_BACKEND_NO_ERR; static void commit_error_cb (gpointer data, QofBackendError errcode) { @@ -1502,13 +1503,13 @@ static void test_trans_on_error (Fixture *fixture, gconstpointer pData) { QofBackendError errcode = ERR_BACKEND_MODIFIED; - gchar *msg = + auto msg = "[trans_on_error()] Another user has modified this transaction\n" "\tjust a moment ago. Please look at their changes,\n" "\tand try again, if needed.\n"; - gchar *logdomain = "gnc.engine"; - guint loglevel = G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL; - TestErrorStruct *check = test_error_struct_new (logdomain, loglevel, msg); + auto logdomain = "gnc.engine"; + auto loglevel = static_cast(G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL); + auto check = test_error_struct_new (logdomain, loglevel, msg); fixture->hdlrs = test_log_set_fatal_handler (fixture->hdlrs, check, (GLogFunc)test_checked_handler); gnc_engine_add_commit_error_callback ((EngineCommitErrorCallback)commit_error_cb, NULL); @@ -1518,7 +1519,7 @@ test_trans_on_error (Fixture *fixture, gconstpointer pData) g_assert_cmpint (check->hits, ==, 1); g_assert_cmpint ((guint)errorvalue, ==, (guint)errcode); g_assert_cmpint (qof_instance_get_editlevel (fixture->txn), ==, 0); - errorvalue = 0; + errorvalue = ERR_BACKEND_NO_ERR; } /* trans_cleanup_commit static void trans_cleanup_commit(Transaction *trans)// Local: 0:1:0 callback for qof_commit_edit_part2, xaccTransCommitEdit @@ -1527,22 +1528,22 @@ static void test_trans_cleanup_commit (Fixture *fixture, gconstpointer pData) { QofBook *book = qof_instance_get_book (QOF_INSTANCE (fixture->txn)); - Split *destr_split = xaccMallocSplit (book); - Split *bogus_split = xaccMallocSplit (book); - Split *split0 = fixture->txn->splits->data; + auto destr_split = xaccMallocSplit (book); + auto bogus_split = xaccMallocSplit (book); + auto split0 = static_cast(fixture->txn->splits->data); Account *acct0 = split0->acc; Transaction *orig = NULL; - TestSignal *sig_d_remove = test_signal_new (QOF_INSTANCE (destr_split), + auto sig_d_remove = test_signal_new (QOF_INSTANCE (destr_split), QOF_EVENT_REMOVE, NULL); - TestSignal *sig_b_remove = test_signal_new (QOF_INSTANCE (bogus_split), + auto sig_b_remove = test_signal_new (QOF_INSTANCE (bogus_split), QOF_EVENT_REMOVE, NULL); - TestSignal *sig_d_destroy = test_signal_new (QOF_INSTANCE (destr_split), + auto sig_d_destroy = test_signal_new (QOF_INSTANCE (destr_split), QOF_EVENT_DESTROY, NULL); - TestSignal *sig_b_modify = test_signal_new (QOF_INSTANCE (bogus_split), + auto sig_b_modify = test_signal_new (QOF_INSTANCE (bogus_split), QOF_EVENT_MODIFY, NULL); - TestSignal *sig_t_modify = test_signal_new (QOF_INSTANCE (fixture->txn), + auto sig_t_modify = test_signal_new (QOF_INSTANCE (fixture->txn), QOF_EVENT_MODIFY, NULL); - TestSignal *sig_a_changed = test_signal_new (QOF_INSTANCE (acct0), + auto sig_a_changed = test_signal_new (QOF_INSTANCE (acct0), GNC_EVENT_ITEM_CHANGED, NULL); xaccTransBeginEdit (fixture->txn); @@ -1605,8 +1606,8 @@ static void test_xaccTransCommitEdit (void) { QofBook *book = qof_book_new (); - Split *split1 = xaccMallocSplit (book); - Split *split2 = xaccMallocSplit (book); + auto split1 = xaccMallocSplit (book); + auto split2 = xaccMallocSplit (book); Transaction *txn = xaccMallocTransaction (book); Account *acc1 = xaccMallocAccount (book); Account *acc2 = xaccMallocAccount (book); @@ -1617,11 +1618,11 @@ test_xaccTransCommitEdit (void) Timespec posted = gnc_dmy2timespec (21, 4, 2012); - TestSignal *sig_1_modify = test_signal_new (QOF_INSTANCE (split1), + auto sig_1_modify = test_signal_new (QOF_INSTANCE (split1), QOF_EVENT_MODIFY, NULL); - TestSignal *sig_2_modify = test_signal_new (QOF_INSTANCE (split2), + auto sig_2_modify = test_signal_new (QOF_INSTANCE (split2), QOF_EVENT_MODIFY, NULL); - TestSignal *sig_txn_destroy = test_signal_new (QOF_INSTANCE (txn), + auto sig_txn_destroy = test_signal_new (QOF_INSTANCE (txn), QOF_EVENT_DESTROY, NULL); @@ -1629,8 +1630,8 @@ test_xaccTransCommitEdit (void) xaccAccountSetCommodity (acc2, curr); txn->date_posted.tv_sec = posted.tv_sec; txn->date_posted.tv_nsec = posted.tv_nsec; - split1->memo = CACHE_INSERT ("foo"); - split1->action = CACHE_INSERT ("bar"); + split1->memo = static_cast(CACHE_INSERT ("foo")); + split1->action = static_cast(CACHE_INSERT ("bar")); split1->amount = gnc_numeric_create (100000, 1000); split1->value = gnc_numeric_create (3200, 240); /* Note, deliberately imblanced to force xaccTransScrubImbalance @@ -1640,8 +1641,8 @@ test_xaccTransCommitEdit (void) split2->value = gnc_numeric_create (-3000, 240); split1->acc = acc1; split2->acc = acc2; - txn->num = CACHE_INSERT ("123"); - txn->description = CACHE_INSERT ("Waldo Pepper"); + txn->num = static_cast(CACHE_INSERT ("123")); + txn->description = static_cast(CACHE_INSERT ("Waldo Pepper")); xaccTransBeginEdit (txn); { xaccTransSetCurrency (txn, curr); @@ -1689,20 +1690,20 @@ test_xaccTransRollbackEdit (Fixture *fixture, gconstpointer pData) Timespec orig_post = txn->date_posted; Timespec orig_entered = txn->date_entered; KvpFrame *base_frame = NULL; - TestSignal *sig_account = test_signal_new (QOF_INSTANCE (fixture->acc1), + auto sig_account = test_signal_new (QOF_INSTANCE (fixture->acc1), GNC_EVENT_ITEM_CHANGED, NULL); MockBackend *mbe = (MockBackend*)qof_book_get_backend (book); - Split *split_00 = txn->splits->data, *split_01 = txn->splits->next->data; - Split *split_02 = xaccMallocSplit (book); - Split *split_10 = NULL, *split_11 = NULL; + auto split_00 = static_cast(txn->splits->data); + auto split_01 = static_cast(txn->splits->next->data); + auto split_02 = xaccMallocSplit (book); xaccTransBeginEdit (txn); qof_instance_set_destroying (txn, TRUE); orig = txn->orig; base_frame = orig->inst.kvp_data; /* DupeTransaction copies the kvp_frame */ g_object_ref (orig); /* Keep rollback from actually freeing it */ - txn->num = "321"; - txn->description = "salt peanuts"; + txn->num = static_cast(CACHE_INSERT("321")); + txn->description = static_cast(CACHE_INSERT("salt peanuts")); txn->common_currency = NULL; txn->inst.kvp_data = NULL; txn->date_entered = new_entered; @@ -1712,9 +1713,9 @@ test_xaccTransRollbackEdit (Fixture *fixture, gconstpointer pData) qof_instance_set_dirty (QOF_INSTANCE (split_01)); xaccSplitSetParent (split_02, txn); g_object_ref (split_02); - split_10 = xaccDupeSplit(orig->splits->data); + auto split_10 = xaccDupeSplit(static_cast(orig->splits->data)); g_object_ref (split_10); - split_11 = xaccDupeSplit(orig->splits->next->data); + auto split_11 = xaccDupeSplit(static_cast(orig->splits->next->data)); g_object_ref (split_11); qof_instance_increase_editlevel (QOF_INSTANCE (txn)); /* So it's 2 */ xaccTransRollbackEdit (txn); @@ -1735,10 +1736,10 @@ test_xaccTransRollbackEdit (Fixture *fixture, gconstpointer pData) g_assert_cmpuint (test_signal_return_hits (sig_account), ==, 1); g_assert_cmpuint (g_list_length (txn->splits), ==, 2); g_assert_cmpint (GPOINTER_TO_INT(split_02->memo), ==, 1); - g_assert (xaccSplitEqual (txn->splits->data, split_10, - FALSE, FALSE, FALSE)); - g_assert (xaccSplitEqual (txn->splits->next->data, split_10, + g_assert (xaccSplitEqual (static_cast(txn->splits->data), split_10, FALSE, FALSE, FALSE)); + g_assert (xaccSplitEqual (static_cast(txn->splits->next->data), + split_10, FALSE, FALSE, FALSE)); g_assert_cmpstr (mbe->last_call, ==, "rollback"); g_assert_cmpuint (qof_instance_get_editlevel (QOF_INSTANCE (txn)), ==, 0); g_assert (qof_instance_get_destroying (txn) == FALSE); @@ -1754,10 +1755,9 @@ static void test_xaccTransRollbackEdit_BackendErrors (Fixture *fixture, gconstpointer pData) { MockBackend *mbe = (MockBackend*)qof_book_get_backend (qof_instance_get_book (fixture->txn)); - guint loglevel = G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL; - gchar *msg = "[xaccTransRollbackEdit()] Rollback Failed. Ouch!"; - TestErrorStruct *check = test_error_struct_new ("gnc.engine", - loglevel, msg); + auto loglevel = static_cast(G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL); + auto msg = "[xaccTransRollbackEdit()] Rollback Failed. Ouch!"; + auto check = test_error_struct_new ("gnc.engine", loglevel, msg); fixture->hdlrs = test_log_set_fatal_handler (fixture->hdlrs, check, (GLogFunc)test_checked_handler); g_object_ref (fixture->txn); @@ -1795,13 +1795,13 @@ test_xaccTransOrder_num_action (Fixture *fixture, gconstpointer pData) g_assert_cmpint (xaccTransOrder_num_action (NULL, NULL, NULL, NULL), ==, 0); g_assert_cmpint (xaccTransOrder_num_action (txnA, NULL, txnB, NULL), ==, qof_instance_guid_compare (txnA, txnB)); - txnB->description = CACHE_INSERT ("Salt Peanuts"); + txnB->description = static_cast(CACHE_INSERT ("Salt Peanuts")); g_assert_cmpint (xaccTransOrder_num_action (txnA, NULL, txnB, NULL), >=, 1); txnB->date_entered.tv_sec += 1; g_assert_cmpint (xaccTransOrder_num_action (txnA, NULL, txnB, NULL), ==, -1); - txnB->num = CACHE_INSERT ("101"); + txnB->num = static_cast(CACHE_INSERT ("101")); g_assert_cmpint (xaccTransOrder_num_action (txnA, NULL, txnB, NULL), ==, 1); - txnB->num = CACHE_INSERT ("one-oh-one"); + txnB->num = static_cast(CACHE_INSERT ("one-oh-one")); g_assert_cmpint (xaccTransOrder_num_action (txnA, NULL, txnB, NULL), ==, 1); g_assert_cmpint (xaccTransOrder_num_action (txnA, "24", txnB, "42"), ==, -1); txnB->date_posted.tv_sec -= 1; @@ -1870,26 +1870,25 @@ static void test_xaccTransVoid (Fixture *fixture, gconstpointer pData) { /* Actual function variables start here. */ - KvpFrame *frame = fixture->txn->inst.kvp_data; - gchar *void_reason = "Voided for Unit Test"; - gchar *txn_notes = g_strdup (kvp_frame_get_string (frame, trans_notes_str)); - KvpValue *val; + auto frame = fixture->txn->inst.kvp_data; + auto void_reason = "Voided for Unit Test"; + auto txn_notes = g_strdup (frame->get_slot(trans_notes_str)->get()); Timespec now = timespec_now (); char iso8601_str[ISO_DATELENGTH + 1] = ""; GList *split = NULL; xaccTransVoid (fixture->txn, void_reason); - g_assert_cmpstr (kvp_frame_get_string (frame, trans_notes_str), ==, + g_assert_cmpstr (frame->get_slot(trans_notes_str)->get(), ==, "Voided transaction"); - g_assert_cmpstr (kvp_frame_get_string (frame, void_former_notes_str), ==, - txn_notes); - g_assert_cmpstr (kvp_frame_get_string (frame, void_reason_str), ==, + g_assert_cmpstr (frame->get_slot(void_former_notes_str)->get(), + ==, txn_notes); + g_assert_cmpstr (frame->get_slot(void_reason_str)->get(), ==, void_reason); gnc_timespec_to_iso8601_buff (now, iso8601_str); - g_assert_cmpstr (kvp_frame_get_string (frame, void_time_str), ==, + g_assert_cmpstr (frame->get_slot(void_time_str)->get(), ==, iso8601_str); - g_assert_cmpstr (kvp_frame_get_string (frame, TRANS_READ_ONLY_REASON), ==, - "Transaction Voided"); + g_assert_cmpstr (frame->get_slot(TRANS_READ_ONLY_REASON)->get(), + ==, "Transaction Voided"); for (split = fixture->txn->splits; split; split=g_list_next (split)) { g_assert (gnc_numeric_zero_p (((Split*)(split->data))->value)); @@ -1898,12 +1897,12 @@ test_xaccTransVoid (Fixture *fixture, gconstpointer pData) xaccTransUnvoid (fixture->txn); - g_assert_cmpstr (kvp_frame_get_string (frame, trans_notes_str), ==, + g_assert_cmpstr (frame->get_slot(trans_notes_str)->get(), ==, txn_notes); - g_assert (kvp_frame_get_slot (frame, void_former_notes_str) == NULL); - g_assert (kvp_frame_get_slot (frame, void_reason_str) == NULL); - g_assert (kvp_frame_get_slot (frame, void_time_str) == NULL); - g_assert (kvp_frame_get_slot (frame, TRANS_READ_ONLY_REASON) == NULL); + g_assert (frame->get_slot(void_former_notes_str) == NULL); + g_assert (frame->get_slot(void_reason_str) == NULL); + g_assert (frame->get_slot(void_time_str) == NULL); + g_assert (frame->get_slot(TRANS_READ_ONLY_REASON) == NULL); for (split = fixture->txn->splits; split; split=g_list_next (split)) { g_assert (!gnc_numeric_zero_p (((Split*)(split->data))->value)); @@ -1921,10 +1920,10 @@ static void test_xaccTransReverse (Fixture *fixture, gconstpointer pData) { Transaction *rev = xaccTransReverse (fixture->txn); - KvpFrame *frame = fixture->txn->inst.kvp_data; + auto frame = fixture->txn->inst.kvp_data; GList *orig_splits = NULL, *rev_splits = NULL; - g_assert (guid_equal (kvp_frame_get_guid (frame, TRANS_REVERSED_BY), + g_assert (guid_equal (frame->get_slot(TRANS_REVERSED_BY)->get(), xaccTransGetGUID (rev))); g_assert (qof_instance_is_dirty (QOF_INSTANCE (rev))); @@ -1936,8 +1935,8 @@ test_xaccTransReverse (Fixture *fixture, gconstpointer pData) orig_splits = g_list_next (orig_splits), rev_splits = g_list_next (rev_splits)) { - Split *orig_split = orig_splits->data; - Split *rev_split = rev_splits->data; + auto orig_split = static_cast(orig_splits->data); + auto rev_split = static_cast(rev_splits->data); g_assert (gnc_numeric_equal (orig_split->amount, gnc_numeric_neg (rev_split->amount))); g_assert (gnc_numeric_equal (orig_split->value, @@ -1961,8 +1960,8 @@ static void test_xaccTransScrubGainsDate_no_dirty (GainsFixture *fixture, gconstpointer pData) { - Split *base_split = g_list_nth_data (fixture->base.txn->splits, 1); - Split *gains_split = base_split->gains_split; + auto base_split = static_cast(g_list_nth_data (fixture->base.txn->splits, 1)); + auto gains_split = base_split->gains_split; base_split->gains = GAINS_STATUS_GAINS; gains_split->gains = GAINS_STATUS_GAINS; @@ -1980,8 +1979,8 @@ static void test_xaccTransScrubGainsDate_base_dirty (GainsFixture *fixture, gconstpointer pData) { - Split *base_split = g_list_nth_data (fixture->base.txn->splits, 1); - Split *gains_split = base_split->gains_split; + auto base_split = static_cast(g_list_nth_data (fixture->base.txn->splits, 1)); + auto gains_split = base_split->gains_split; base_split->gains = GAINS_STATUS_GAINS | GAINS_STATUS_DATE_DIRTY; gains_split->gains = GAINS_STATUS_GAINS; @@ -1999,8 +1998,8 @@ static void test_xaccTransScrubGainsDate_gains_dirty (GainsFixture *fixture, gconstpointer pData) { - Split *base_split = g_list_nth_data (fixture->base.txn->splits, 1); - Split *gains_split = base_split->gains_split; + auto base_split = static_cast(g_list_nth_data (fixture->base.txn->splits, 1)); + auto gains_split = base_split->gains_split; base_split->gains = GAINS_STATUS_GAINS; gains_split->gains = GAINS_STATUS_GAINS | GAINS_STATUS_DATE_DIRTY; diff --git a/src/libqof/qof/kvp_frame.cpp b/src/libqof/qof/kvp_frame.cpp index 8e8ff35767..475ae5a891 100644 --- a/src/libqof/qof/kvp_frame.cpp +++ b/src/libqof/qof/kvp_frame.cpp @@ -142,6 +142,12 @@ walk_path_and_create(KvpFrameImpl* frame, Path path) return frame; } +KvpValue* +KvpFrameImpl::set_path(const char* path, KvpValue* value) noexcept +{ + return set_path(make_vector(path), value); +} + KvpValue* KvpFrameImpl::set_path(Path path, KvpValue* value) noexcept { diff --git a/src/libqof/qof/kvp_frame.hpp b/src/libqof/qof/kvp_frame.hpp index 322e9faa0d..46ec14b3e4 100644 --- a/src/libqof/qof/kvp_frame.hpp +++ b/src/libqof/qof/kvp_frame.hpp @@ -78,7 +78,21 @@ struct KvpFrameImpl * Set the value with the key in a subframe following the keys in path, * replacing and returning the old value if it exists or nullptr if it * doesn't. Creates any missing intermediate frames. - * @param path: The path of subframes leading to the frame in which to + * @param path: The path of subframes as a '/'-delimited string leading to the frame in which to + * insert/replace. + * @param newvalue: The value to set at key. + * @return The old value if there was one or nullptr. + */ + KvpValue* set_path(const char* path, KvpValue* newvalue) noexcept; + /** + * Make a string representation of the frame. Mostly useful for debugging. + * @return A std::string representing the frame and all its children. + */ + /** + * Set the value with the key in a subframe following the keys in path, + * replacing and returning the old value if it exists or nullptr if it + * doesn't. Creates any missing intermediate frames. + * @param path: The path of subframes as a std::vector leading to the frame in which to * insert/replace. * @param newvalue: The value to set at key. * @return The old value if there was one or nullptr. diff --git a/src/libqof/qof/test/Makefile.am b/src/libqof/qof/test/Makefile.am index 48eaf3ff48..e233cc184d 100644 --- a/src/libqof/qof/test/Makefile.am +++ b/src/libqof/qof/test/Makefile.am @@ -12,8 +12,7 @@ test_qof_SOURCES = \ test-gnc-date.c \ test-qof.c \ test-qofbook.c \ - test-qofinstance.c \ - test-kvp_frame.c \ + test-qofinstance.cpp \ test-qofobject.c \ test-qofsession.c \ test-qof-string-cache.c \ diff --git a/src/libqof/qof/test/test-kvp_frame.c b/src/libqof/qof/test/test-kvp_frame.c deleted file mode 100644 index 8717374fdc..0000000000 --- a/src/libqof/qof/test/test-kvp_frame.c +++ /dev/null @@ -1,1703 +0,0 @@ -/******************************************************************** - * test-kvp_frame.c: GLib g_test test suite for kvp_frame.c. * - * Copyright 2011 John Ralls * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of the GNU General Public License as * - * published by the Free Software Foundation; either version 2 of * - * the License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License* - * along with this program; if not, contact: * - * * - * Free Software Foundation Voice: +1-617-542-5942 * - * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 * - * Boston, MA 02110-1301, USA gnu@gnu.org * -********************************************************************/ -#ifdef __cplusplus -extern "C" -{ -#endif - -#include "config.h" -#include -#include -#include -#include -#include -#ifdef __cplusplus -} -#endif - - - -static const gchar *suitename = "/qof/kvp_frame"; -void test_suite_kvp_frame ( void ); - -typedef struct -{ - KvpFrame *frame; - GSList *hdlrs; -} Fixture; - -static void -setup( Fixture *fixture, gconstpointer pData ) -{ - fixture->frame = kvp_frame_new(); - fixture->hdlrs = NULL; -} - -static void -teardown( Fixture *fixture, gconstpointer pData ) -{ - kvp_frame_delete( fixture->frame ); - g_slist_free_full (fixture->hdlrs, test_free_log_handler); - test_clear_error_list (); -} - -static gchar* glist_to_string( const GList *list ) -{ - KvpValue * val = kvp_value_new_glist( list ); - gchar * ret = kvp_value_to_string( val ); - kvp_value_delete( val ); - return ret; -} - -extern KvpFrame* ( *p_get_trailer_make )( KvpFrame *frame, const char *key_path, char **end_key ); -extern KvpFrame* ( *p_get_or_make )( KvpFrame *fr, const char * key ); -extern const KvpFrame* ( *p_kvp_frame_get_frame_or_null_slash_trash )( const KvpFrame *frame, char *key_path ); -extern const KvpFrame* ( *p_get_trailer_or_null )( const KvpFrame * frame, const char * key_path, char **end_key ); - -extern void init_static_test_pointers( void ); - -static void -setup_static( Fixture *fixture, gconstpointer pData ) -{ - fixture->frame = kvp_frame_new(); - fixture->hdlrs = NULL; - init_static_test_pointers(); - g_assert( p_get_trailer_make && p_get_or_make && p_get_trailer_or_null && - p_kvp_frame_get_frame_or_null_slash_trash ); -} - -static void -teardown_static( Fixture *fixture, gconstpointer pData ) -{ - kvp_frame_delete( fixture->frame ); - g_slist_free_full (fixture->hdlrs, test_free_log_handler); - test_clear_error_list (); - p_get_trailer_make = NULL; - p_get_or_make = NULL; - p_kvp_frame_get_frame_or_null_slash_trash = NULL; - p_get_trailer_or_null = NULL; -} - -static GncGUID* -populate_frame (KvpFrame *frame) -{ - GList *list = NULL; - Timespec ts; - GncGUID *guid; - GDate gdate; - - ts.tv_sec = 1; - ts.tv_nsec = 1; - guid = guid_new (); - g_date_set_dmy (&gdate, 26, 1, 1957); - - kvp_frame_set_gint64( frame, "gint64-type", 100 ); - kvp_frame_set_double( frame, "double-type", 3.14159 ); - kvp_frame_set_numeric( frame, "numeric-type", gnc_numeric_zero() ); - kvp_frame_set_timespec( frame, "timespec-type", ts ); - kvp_frame_set_string( frame, "string-type", "abcdefghijklmnop" ); - kvp_frame_set_guid( frame, "guid-type", guid ); - kvp_frame_set_value_nc (frame, "gdate-type", kvp_value_new_gdate (gdate)); - kvp_frame_set_frame( frame, "frame-type", kvp_frame_new() ); - - list = g_list_prepend (list, kvp_value_new_guid (guid)); - list = g_list_prepend (list, kvp_value_new_string ("qrstuvwxyz")); - list = g_list_prepend (list, kvp_value_new_timespec (ts)); - list = g_list_prepend (list, kvp_value_new_numeric (gnc_numeric_create (256, 120))); - list = g_list_prepend (list, kvp_value_new_double (0.4342944819)); - list = g_list_prepend (list, kvp_value_new_gint64 (0x1f2e3d4c5b6a79LL)); - kvp_frame_set_value (frame, "list-type", kvp_value_new_glist_nc (list)); - - return guid; -} - -static void -test_kvp_frame_new_delete( void ) -{ - KvpFrame *frame; - GncGUID *guid; - - frame = kvp_frame_new(); - g_assert( frame ); - g_assert( kvp_frame_is_empty( frame ) ); - - guid = populate_frame (frame); - - g_assert( !kvp_frame_is_empty( frame ) ); - - kvp_frame_delete( frame ); - g_assert( frame ); - guid_free (guid); -} - -static void -test_kvp_frame_copy( Fixture *fixture, gconstpointer pData ) -{ - KvpFrame *to_copy = NULL; - gint64 test_gint64, copy_gint64; - double test_double, copy_double; - gnc_numeric test_gnc_numeric, copy_gnc_numeric; - Timespec test_ts, copy_ts; - const char* test_str, *copy_str; - GncGUID *test_guid, *copy_guid; - KvpFrame *test_frame, *copy_frame; - - /* init data in source frame */ - test_gint64 = 111; - test_double = 1.1; - test_gnc_numeric = gnc_numeric_zero(); - test_ts.tv_sec = 1; - test_ts.tv_nsec = 1; - test_str = "abcdefghijklmnop"; - test_guid = guid_new(); - test_frame = kvp_frame_new(); - - g_assert( fixture->frame ); - kvp_frame_set_gint64( fixture->frame, "gint64-type", test_gint64 ); - kvp_frame_set_double( fixture->frame, "double-type", test_double ); - kvp_frame_set_numeric( fixture->frame, "numeric-type", test_gnc_numeric ); - kvp_frame_set_timespec( fixture->frame, "timespec-type", test_ts ); - kvp_frame_set_string( fixture->frame, "string-type", test_str ); - kvp_frame_set_guid( fixture->frame, "guid-type", test_guid ); - kvp_frame_set_frame( fixture->frame, "frame-type", test_frame ); - g_assert( !kvp_frame_is_empty( fixture->frame ) ); - - g_test_message( "Test frame copy" ); - to_copy = kvp_frame_copy( fixture->frame ); - g_assert( to_copy ); - g_assert( !kvp_frame_is_empty( to_copy ) ); - g_assert( to_copy != fixture->frame ); - - g_assert_cmpint( kvp_frame_compare( fixture->frame, to_copy ), == , 0 ); - copy_gint64 = kvp_frame_get_gint64( to_copy, "gint64-type" ); - g_assert( ©_gint64 != &test_gint64 ); - g_assert_cmpint( copy_gint64, == , test_gint64 ); - copy_double = kvp_frame_get_double( to_copy, "double-type" ); - g_assert( ©_double != &test_double ); - g_assert_cmpfloat( copy_double, == , test_double ); - copy_gnc_numeric = kvp_frame_get_numeric( to_copy, "numeric-type" ); - g_assert( ©_gnc_numeric != &test_gnc_numeric ); - g_assert_cmpfloat( copy_gnc_numeric.num, == , test_gnc_numeric.num ); - g_assert_cmpfloat( copy_gnc_numeric.denom, == , test_gnc_numeric.denom ); - copy_ts = kvp_frame_get_timespec( to_copy, "timespec-type" ); - g_assert( ©_ts != &test_ts ); - g_assert_cmpfloat( copy_ts.tv_sec, == , test_ts.tv_sec ); - g_assert_cmpfloat( copy_ts.tv_nsec, == , test_ts.tv_nsec ); - copy_str = kvp_frame_get_string( to_copy, "string-type" ); - g_assert( copy_str != test_str ); - g_assert_cmpstr( copy_str, == , test_str ); - copy_guid = kvp_frame_get_guid( to_copy, "guid-type" ); - g_assert( copy_guid != test_guid ); - g_assert( guid_equal( copy_guid, test_guid ) ); - copy_frame = kvp_frame_get_frame( to_copy, "frame-type"); - g_assert( copy_frame ); - g_assert( kvp_frame_is_empty( copy_frame ) ); - g_assert( copy_frame != test_frame ); - g_assert_cmpint( kvp_frame_compare( copy_frame, test_frame ), == , 0 ); - - kvp_frame_delete( to_copy ); - guid_free( test_guid ); -} - -static void -test_kvp_frame_set_foo( Fixture *fixture, gconstpointer pData ) -{ - gnc_numeric test_gnc_numeric, copy_gnc_numeric; - Timespec test_ts, copy_ts; - GncGUID *test_guid, *copy_guid; - - test_gnc_numeric = gnc_numeric_zero(); - test_ts.tv_sec = 1; - test_ts.tv_nsec = 1; - test_guid = guid_new(); - - g_assert( fixture->frame ); - g_assert( kvp_frame_is_empty( fixture->frame ) ); - - g_test_message( "Test gint64 setup and replace, test frame is created" ); - g_assert( kvp_frame_get_frame( fixture->frame, "/test" ) == NULL ); - kvp_frame_set_gint64( fixture->frame, "/test/gint64", 1 ); - g_assert( kvp_frame_get_frame( fixture->frame, "/test" ) != NULL ); - g_assert_cmpint( kvp_frame_get_gint64( fixture->frame, "/test/gint64" ), == , 1 ); - kvp_frame_set_gint64( fixture->frame, "/test/gint64", 5 ); - g_assert_cmpint( kvp_frame_get_gint64( fixture->frame, "/test/gint64" ), == , 5 ); - - g_test_message( "Test double setup and replace, test2 frame is created" ); - g_assert( kvp_frame_get_frame( fixture->frame, "/test2" ) == NULL ); - kvp_frame_set_double( fixture->frame, "/test2/double", 1.1 ); - g_assert( kvp_frame_get_frame( fixture->frame, "/test2" ) != NULL ); - g_assert_cmpfloat( kvp_frame_get_double( fixture->frame, "/test2/double" ), == , 1.1 ); - kvp_frame_set_double( fixture->frame, "/test2/double", 5.5 ); - g_assert_cmpfloat( kvp_frame_get_double( fixture->frame, "/test2/double" ), == , 5.5 ); - - g_test_message( "Test double setup and replace, test3 frame is created" ); - g_assert( kvp_frame_get_frame( fixture->frame, "/test3" ) == NULL ); - kvp_frame_set_numeric( fixture->frame, "/test3/numeric", test_gnc_numeric ); - g_assert( kvp_frame_get_frame( fixture->frame, "/test3" ) != NULL ); - copy_gnc_numeric = kvp_frame_get_numeric( fixture->frame, "/test3/numeric" ); - g_assert_cmpint( copy_gnc_numeric.num, == , 0 ); - g_assert_cmpint( copy_gnc_numeric.denom, == , 1 ); - test_gnc_numeric.num = 2; - test_gnc_numeric.denom = 3; - kvp_frame_set_numeric( fixture->frame, "/test3/numeric", test_gnc_numeric ); - copy_gnc_numeric = kvp_frame_get_numeric( fixture->frame, "/test3/numeric" ); - g_assert_cmpint( copy_gnc_numeric.num, == , 2 ); - g_assert_cmpint( copy_gnc_numeric.denom, == , 3 ); - - g_test_message( "Test timespec setup and replace, test4 frame is created" ); - g_assert( kvp_frame_get_frame( fixture->frame, "/test4" ) == NULL ); - kvp_frame_set_timespec( fixture->frame, "/test4/timespec", test_ts ); - g_assert( kvp_frame_get_frame( fixture->frame, "/test4" ) != NULL ); - copy_ts = kvp_frame_get_timespec( fixture->frame, "/test4/timespec" ); - g_assert_cmpint( copy_ts.tv_sec, == , 1 ); - g_assert_cmpint( copy_ts.tv_nsec, == , 1 ); - test_ts.tv_sec = 7; - test_ts.tv_nsec = 13; - kvp_frame_set_timespec( fixture->frame, "/test4/timespec", test_ts ); - copy_ts = kvp_frame_get_timespec( fixture->frame, "/test4/timespec" ); - g_assert_cmpint( copy_ts.tv_sec, == , 7 ); - g_assert_cmpint( copy_ts.tv_nsec, == , 13 ); - - g_test_message( "Test string setup and replace, test5 frame is created" ); - g_assert( kvp_frame_get_frame( fixture->frame, "/test5" ) == NULL ); - kvp_frame_set_string( fixture->frame, "/test5/string", "one string" ); - g_assert( kvp_frame_get_frame( fixture->frame, "/test5" ) != NULL ); - g_assert_cmpstr( kvp_frame_get_string( fixture->frame, "/test5/string" ), == , "one string" ); - kvp_frame_set_string( fixture->frame, "/test5/string", "another string" ); - g_assert_cmpstr( kvp_frame_get_string( fixture->frame, "/test5/string" ), == , "another string" ); - - g_test_message( "Test guid setup and replace, test6 frame is created" ); - g_assert( kvp_frame_get_frame( fixture->frame, "/test6" ) == NULL ); - kvp_frame_set_guid( fixture->frame, "/test6/guid", test_guid ); - g_assert( kvp_frame_get_frame( fixture->frame, "/test6" ) != NULL ); - copy_guid = kvp_frame_get_guid( fixture->frame, "/test6/guid" ); - g_assert( guid_equal( copy_guid, test_guid ) ); - kvp_frame_set_guid( fixture->frame, "/test6/guid", guid_null() ); - copy_guid = kvp_frame_get_guid( fixture->frame, "/test6/guid" ); - g_assert( guid_equal( copy_guid, guid_null() ) ); - - g_test_message( "Test frame setup and replace, test7 frame is created" ); - g_assert( kvp_frame_get_frame( fixture->frame, "/test7" ) == NULL ); - kvp_frame_set_frame( fixture->frame, "/test7", kvp_frame_new() ); - g_assert( kvp_frame_get_frame( fixture->frame, "/test7" ) != NULL ); - kvp_frame_set_frame( fixture->frame, "/test7", NULL ); - g_assert( kvp_frame_get_frame( fixture->frame, "/test7" ) == NULL ); -} - -static void -test_kvp_frame_get_frame_slash( Fixture *fixture, gconstpointer pData ) -{ - KvpFrame *result_frame = NULL; - /* Mostly testing static routine kvp_frmae_get_frame_slash_trash */ - g_assert( fixture->frame ); - - g_test_message( "Test path with one slash same frame should be returned" ); - result_frame = kvp_frame_get_frame_slash( fixture->frame, "/" ); - g_assert( result_frame ); - g_assert( result_frame == fixture->frame ); - - g_test_message( "Test path with trailing slash same frame should be returned" ); - result_frame = kvp_frame_get_frame_slash( fixture->frame, "/////" ); - g_assert( result_frame ); - g_assert( result_frame == fixture->frame ); - - g_test_message( "Test new frame is created" ); - result_frame = kvp_frame_get_frame_slash( fixture->frame, "/test" ); - g_assert( result_frame ); - g_assert( result_frame != fixture->frame ); - g_assert( result_frame == kvp_frame_get_frame( fixture->frame, "/test" ) ); - - g_test_message( "Test trailing slashes are ignored and frame created" ); - result_frame = kvp_frame_get_frame_slash( fixture->frame, "////test2/////" ); - g_assert( result_frame ); - g_assert( result_frame != fixture->frame ); - g_assert( result_frame == kvp_frame_get_frame( fixture->frame, "/test2" ) ); - g_assert( result_frame != kvp_frame_get_frame( fixture->frame, "/test" ) ); - - g_test_message( "Test frames are created along the path if not exist and last frame is returned" ); - result_frame = kvp_frame_get_frame_slash( fixture->frame, "////test3/////test4//////" ); - g_assert( result_frame ); - g_assert( result_frame != fixture->frame ); - g_assert( result_frame != kvp_frame_get_frame( fixture->frame, "/test2" ) ); - g_assert( result_frame != kvp_frame_get_frame( fixture->frame, "/test" ) ); - g_assert( kvp_frame_get_frame( fixture->frame, "/test3" ) != NULL ); - g_assert( result_frame != kvp_frame_get_frame( fixture->frame, "/test3" ) ); - g_assert( result_frame == kvp_frame_get_frame( fixture->frame, "/test3/test4" ) ); - - g_test_message( "Test existing frame is returned" ); - g_assert( result_frame == kvp_frame_get_frame_slash( fixture->frame, "////test3/////test4//////" ) ); -} - -static void -test_kvp_frame_get_slot_path( Fixture *fixture, gconstpointer pData ) -{ - KvpValue *result_value = NULL ; - - g_assert( fixture->frame ); - g_assert( kvp_frame_is_empty( fixture->frame ) ); - - g_test_message( "Test with non existing path should return NULL" ); - result_value = kvp_frame_get_slot_path( fixture->frame, "test", "test2", NULL ); - g_assert( !result_value ); - - g_test_message( "Test with existing value set to current frame" ); - kvp_frame_set_gint64( fixture->frame, "/test", 1 ); - result_value = kvp_frame_get_slot_path( fixture->frame, "test", NULL ); - g_assert( result_value ); - g_assert( kvp_value_get_type( result_value ) == KVP_TYPE_GINT64 ); - g_assert_cmpint( kvp_value_get_gint64( result_value ), == , 1 ); - - g_test_message( "Test should return null as test is not a frame" ); - kvp_frame_set_gint64( fixture->frame, "/test/test2", 2 ); - result_value = kvp_frame_get_slot_path( fixture->frame, "test", "test2", NULL ); - g_assert( !result_value ); - - g_test_message( "Test should return last value in the path" ); - kvp_frame_set_gint64( fixture->frame, "/test2/test3", 2 ); - result_value = kvp_frame_get_slot_path( fixture->frame, "test2", "test3", NULL ); - g_assert( result_value ); - g_assert( kvp_value_get_type( result_value ) == KVP_TYPE_GINT64 ); - g_assert_cmpint( kvp_value_get_gint64( result_value ), == , 2 ); - - g_test_message( "Test should return null as last value in the path does not exist" ); - result_value = kvp_frame_get_slot_path( fixture->frame, "test2", "test3", "test4", NULL ); - g_assert( !result_value ); -} - -static void -test_kvp_frame_get_slot_path_gslist( Fixture *fixture, gconstpointer pData ) -{ - /* similar to previous test except path is passed as GSList*/ - GSList *path_list = NULL; - KvpValue *result_value = NULL ; - - g_assert( fixture->frame ); - g_assert( kvp_frame_is_empty( fixture->frame ) ); - - g_test_message( "Test with non existing path should return NULL" ); - path_list = g_slist_append (path_list, "test"); - path_list = g_slist_append (path_list, "test2"); - result_value = kvp_frame_get_slot_path_gslist( fixture->frame, path_list ); - g_assert( !result_value ); - - g_test_message( "Test with existing value set to current frame" ); - path_list = g_slist_remove( path_list, "test2" ); - kvp_frame_set_gint64( fixture->frame, "/test", 1 ); - result_value = kvp_frame_get_slot_path_gslist( fixture->frame, path_list ); - g_assert( result_value ); - g_assert( kvp_value_get_type( result_value ) == KVP_TYPE_GINT64 ); - g_assert_cmpint( kvp_value_get_gint64( result_value ), == , 1 ); - - g_test_message( "Test should return null as test is not a frame" ); - path_list = g_slist_append (path_list, "test2"); - kvp_frame_set_gint64( fixture->frame, "/test/test2", 2 ); - result_value = kvp_frame_get_slot_path_gslist( fixture->frame, path_list ); - g_assert( !result_value ); - - g_test_message( "Test should return last value in the path" ); - path_list = g_slist_remove( path_list, "test" ); - path_list = g_slist_append (path_list, "test3"); - kvp_frame_set_gint64( fixture->frame, "/test2/test3", 2 ); - result_value = kvp_frame_get_slot_path_gslist( fixture->frame, path_list ); - g_assert( result_value ); - g_assert( kvp_value_get_type( result_value ) == KVP_TYPE_GINT64 ); - g_assert_cmpint( kvp_value_get_gint64( result_value ), == , 2 ); - - g_test_message( "Test should return null as last value in the path does not exist" ); - path_list = g_slist_append (path_list, "test4"); - result_value = kvp_frame_get_slot_path_gslist( fixture->frame, path_list ); - g_assert( !result_value ); - g_slist_free( path_list ); -} - -static void -test_kvp_frame_add_frame_nc( Fixture *fixture, gconstpointer pData ) -{ - /* basically we test static function kvp_frame_add_value_nc - * if path not exist it's created - * if gslist exist on the path new value added to the list - * if any other value exist it's converted to gslist and newvalue added - */ - KvpFrame *test_frame = NULL, - *test_frame2 = NULL, - *test_frame3 = NULL, - *result_frame = NULL; - KvpValue *result_value = NULL; - GList *result_list = NULL; - - g_assert( fixture->frame ); - g_assert( kvp_frame_is_empty( fixture->frame ) ); - - g_test_message( "Test when path does not exist it is created" ); - result_frame = kvp_frame_get_frame( fixture->frame, "/test/test2/test3" ); - g_assert( !result_frame ); - test_frame = kvp_frame_new(); - kvp_frame_add_frame_nc( fixture->frame, "/test/test2/test3", test_frame ); - result_frame = kvp_frame_get_frame( fixture->frame, "/test/test2/test3" ); - g_assert( result_frame ); - g_assert( result_frame == test_frame ); /* no copying done */ - result_frame = kvp_frame_get_frame( fixture->frame, "/test/test2" ); - g_assert( result_frame != test_frame ); - result_frame = kvp_frame_get_frame( fixture->frame, "/test" ); - g_assert( result_frame != test_frame ); - - g_test_message( "Test when value exist on the path it's converted to bag and new value added" ); - test_frame2 = kvp_frame_new(); - kvp_frame_add_frame_nc( fixture->frame, "/test/test2/test3", test_frame2 ); - result_value = kvp_frame_get_value( fixture->frame, "/test/test2/test3" ); - result_list = kvp_value_get_glist( result_value ); - g_assert( result_list ); - g_assert_cmpint( g_list_length( result_list ), == , 2 ); - result_value = g_list_first( result_list )->data; - g_assert( result_value ); - g_assert( kvp_value_get_type( result_value ) == KVP_TYPE_FRAME ); - g_assert( kvp_value_get_frame( result_value ) == test_frame ); - result_value = g_list_next( result_list )->data; - g_assert( result_value ); - g_assert( kvp_value_get_type( result_value ) == KVP_TYPE_FRAME ); - g_assert( kvp_value_get_frame( result_value ) == test_frame2 ); - - g_test_message( "Test when bag exists on the path new values are added to it" ); - test_frame3 = kvp_frame_new(); - kvp_frame_add_frame_nc( fixture->frame, "/test/test2/test3", test_frame3 ); - result_value = kvp_frame_get_value( fixture->frame, "/test/test2/test3" ); - g_assert( result_list == kvp_value_get_glist( result_value ) ); /* same list used */ - g_assert_cmpint( g_list_length( result_list ), == , 3 ); - result_value = g_list_first( result_list )->data; - g_assert( result_value ); - g_assert( kvp_value_get_type( result_value ) == KVP_TYPE_FRAME ); - g_assert( kvp_value_get_frame( result_value ) == test_frame ); - result_value = g_list_next( result_list )->data; - g_assert( result_value ); - g_assert( kvp_value_get_type( result_value ) == KVP_TYPE_FRAME ); - g_assert( kvp_value_get_frame( result_value ) == test_frame2 ); - result_value = g_list_last( result_list )->data; - g_assert( result_value ); - g_assert( kvp_value_get_type( result_value ) == KVP_TYPE_FRAME ); - g_assert( kvp_value_get_frame( result_value ) == test_frame3 ); -} - -static void -test_kvp_value_copy( void ) -{ - KvpValue *gint64_orig_value, *gint64_copy_value; - KvpValue *double_orig_value, *double_copy_value; - KvpValue *numeric_orig_value, *numeric_copy_value; - KvpValue *string_orig_value, *string_copy_value; - KvpValue *guid_orig_value, *guid_copy_value; - KvpValue *timespec_orig_value, *timespec_copy_value; - KvpValue *glist_orig_value, *glist_copy_value; - KvpValue *frame_orig_value, *frame_copy_value; - - /* data init */ - gnc_numeric gnc_numeric_orig, gnc_numeric_copy; - GncGUID *guid_orig, *guid_copy; - Timespec ts_orig, ts_copy; - GList *list_orig, *list_copy; - KvpFrame *frame_orig, *frame_copy; - - gnc_numeric_orig = gnc_numeric_zero(); - guid_orig = guid_new(); - ts_orig.tv_sec = 1; - ts_orig.tv_nsec = 1; - list_orig = NULL; - list_orig = g_list_append( list_orig, kvp_value_new_string( "abcdefghijklmnop" ) ); - frame_orig = kvp_frame_new(); - - g_test_message( "Test creates original values and checks copies of them" ); - gint64_orig_value = kvp_value_new_gint64( 2 ); - double_orig_value = kvp_value_new_double( 3.3 ); - numeric_orig_value = kvp_value_new_gnc_numeric( gnc_numeric_orig ); - string_orig_value = kvp_value_new_string( "abcdefghijklmnop" ); - guid_orig_value = kvp_value_new_guid( guid_orig ); - timespec_orig_value = kvp_value_new_timespec( ts_orig ); - glist_orig_value = kvp_value_new_glist( list_orig ); - frame_orig_value = kvp_value_new_frame( frame_orig ); - g_assert( gint64_orig_value && double_orig_value && numeric_orig_value && string_orig_value - && guid_orig_value && timespec_orig_value && glist_orig_value && frame_orig_value ); - - /* copy values */ - gint64_copy_value = kvp_value_copy( gint64_orig_value ); - g_assert( gint64_copy_value ); - g_assert( gint64_copy_value != gint64_orig_value ); - g_assert( kvp_value_get_type( gint64_copy_value ) == KVP_TYPE_GINT64 ); - g_assert_cmpint( kvp_value_get_gint64( gint64_copy_value ), == , 2 ); - - double_copy_value = kvp_value_copy( double_orig_value ); - g_assert( double_copy_value ); - g_assert( double_copy_value != double_orig_value ); - g_assert( kvp_value_get_type( double_copy_value ) == KVP_TYPE_DOUBLE ); - g_assert_cmpfloat( kvp_value_get_double( double_copy_value ), == , 3.3 ); - - numeric_copy_value = kvp_value_copy( numeric_orig_value ); - g_assert( numeric_copy_value ); - g_assert( numeric_copy_value != numeric_orig_value ); - g_assert( kvp_value_get_type( numeric_copy_value ) == KVP_TYPE_NUMERIC ); - gnc_numeric_copy = kvp_value_get_numeric( numeric_copy_value ); - g_assert_cmpfloat( gnc_numeric_copy.num, == , gnc_numeric_orig.num ); - g_assert_cmpfloat( gnc_numeric_copy.denom, == , gnc_numeric_orig.denom ); - - string_copy_value = kvp_value_copy( string_orig_value ); - g_assert( string_copy_value ); - g_assert( string_copy_value != string_orig_value ); - g_assert( kvp_value_get_type( string_copy_value ) == KVP_TYPE_STRING ); - g_assert_cmpstr( kvp_value_get_string( string_copy_value ), == , "abcdefghijklmnop" ); - - guid_copy_value = kvp_value_copy( guid_orig_value ); - g_assert( guid_copy_value ); - g_assert( guid_copy_value != guid_orig_value ); - g_assert( kvp_value_get_type( guid_copy_value ) == KVP_TYPE_GUID ); - guid_copy = kvp_value_get_guid( guid_copy_value ); - g_assert( guid_orig != guid_copy ); - g_assert( guid_equal( guid_orig, guid_copy ) ); - - timespec_copy_value = kvp_value_copy( timespec_orig_value ); - g_assert( timespec_copy_value ); - g_assert( timespec_copy_value != timespec_orig_value ); - g_assert( kvp_value_get_type( timespec_copy_value ) == KVP_TYPE_TIMESPEC ); - ts_copy = kvp_value_get_timespec( timespec_copy_value ); - g_assert_cmpfloat( ts_copy.tv_sec, == , ts_orig.tv_sec ); - g_assert_cmpfloat( ts_copy.tv_nsec, == , ts_orig.tv_nsec ); - - glist_copy_value = kvp_value_copy( glist_orig_value ); - g_assert( glist_copy_value ); - g_assert( glist_copy_value != glist_orig_value ); - g_assert( kvp_value_get_type( glist_copy_value ) == KVP_TYPE_GLIST ); - list_copy = kvp_value_get_glist( glist_copy_value ); - g_assert( list_copy != list_orig ); - g_assert_cmpint( g_list_length( list_copy ), == , g_list_length( list_orig ) ); - g_assert_cmpint( kvp_glist_compare( list_orig, list_copy ), == , 0 ); - - frame_copy_value = kvp_value_copy( frame_orig_value ); - g_assert( frame_copy_value ); - g_assert( frame_copy_value != frame_orig_value ); - g_assert( kvp_value_get_type( frame_copy_value ) == KVP_TYPE_FRAME ); - frame_copy = kvp_value_get_frame( frame_copy_value ); - g_assert_cmpint( kvp_frame_compare( frame_orig, frame_copy ), == , 0 ); - - /* destroy objects */ - kvp_value_delete( gint64_orig_value ); - kvp_value_delete( double_orig_value ); - kvp_value_delete( numeric_orig_value ); - kvp_value_delete( string_orig_value ); - kvp_value_delete( guid_orig_value ); - kvp_value_delete( timespec_orig_value ); - kvp_value_delete( glist_orig_value ); - kvp_value_delete( frame_orig_value ); - - kvp_value_delete( gint64_copy_value ); - kvp_value_delete( double_copy_value ); - kvp_value_delete( numeric_copy_value ); - kvp_value_delete( string_copy_value ); - kvp_value_delete( guid_copy_value ); - kvp_value_delete( timespec_copy_value ); - kvp_value_delete( glist_copy_value ); - kvp_value_delete( frame_copy_value ); -} - -static void -test_kvp_glist_copy( void ) -{ - GList *value_list = NULL, *copy_list = NULL, *lp1 = NULL, *lp2 = NULL; - KvpValue *gint64_value; - KvpValue *double_value; - KvpValue *numeric_value; - KvpValue *string_value; - KvpValue *guid_value; - KvpValue *timespec_value; - KvpValue *glist_value; - KvpValue *frame_value; - - gnc_numeric gnc_numeric_orig; - GncGUID *guid_orig; - Timespec ts_orig; - GList *list_orig; - KvpFrame *frame_orig; - - gnc_numeric_orig = gnc_numeric_zero(); - guid_orig = guid_new(); - ts_orig.tv_sec = 1; - ts_orig.tv_nsec = 1; - list_orig = NULL; - list_orig = g_list_append( list_orig, kvp_value_new_string( "abcdefghijklmnop" ) ); - frame_orig = kvp_frame_new(); - - gint64_value = kvp_value_new_gint64( 2 ); - double_value = kvp_value_new_double( 3.3 ); - numeric_value = kvp_value_new_gnc_numeric( gnc_numeric_orig ); - string_value = kvp_value_new_string( "abcdefghijklmnop" ); - guid_value = kvp_value_new_guid( guid_orig ); - timespec_value = kvp_value_new_timespec( ts_orig ); - glist_value = kvp_value_new_glist( list_orig ); - frame_value = kvp_value_new_frame( frame_orig ); - - value_list = g_list_append( value_list, gint64_value ); - value_list = g_list_append( value_list, double_value ); - value_list = g_list_append( value_list, numeric_value ); - value_list = g_list_append( value_list, string_value ); - value_list = g_list_append( value_list, guid_value ); - value_list = g_list_append( value_list, timespec_value ); - value_list = g_list_append( value_list, glist_value ); - value_list = g_list_append( value_list, frame_value ); - g_assert( value_list ); - g_assert_cmpint( g_list_length( value_list ), == , 8 ); - - g_test_message( "Test list and all values are copied to new list" ); - copy_list = kvp_glist_copy( value_list ); - g_assert( copy_list ); - g_assert( copy_list != value_list ); - g_assert_cmpint( g_list_length( copy_list ), == , 8 ); - lp1 = value_list; - lp2 = copy_list; - while (lp1 && lp2) - { - KvpValue *v1 = (KvpValue *) lp1->data; - KvpValue *v2 = (KvpValue *) lp2->data; - g_assert( v1 != v2 ); - g_assert_cmpint( kvp_value_compare(v1, v2), == , 0 ); - lp1 = lp1->next; - lp2 = lp2->next; - } - g_assert_cmpint( kvp_glist_compare( value_list, copy_list ), == , 0 ); - - /* destroy */ - kvp_glist_delete( value_list ); - kvp_glist_delete( copy_list ); -} - -static void -test_kvp_glist_compare( void ) -{ - GList *list1 = NULL, *list2 = NULL; - - KvpValue *gint64_value; - KvpValue *double_value; - KvpValue *numeric_value; - KvpValue *string_value; - KvpValue *guid_value; - KvpValue *timespec_value; - KvpValue *glist_value; - KvpValue *frame_value; - - gnc_numeric gnc_numeric_orig; - GncGUID *guid_orig; - Timespec ts_orig; - GList *list_orig; - KvpFrame *frame_orig; - - gnc_numeric_orig = gnc_numeric_zero(); - guid_orig = guid_new(); - ts_orig.tv_sec = 1; - ts_orig.tv_nsec = 1; - list_orig = NULL; - list_orig = g_list_append( list_orig, kvp_value_new_string( "abcdefghijklmnop" ) ); - frame_orig = kvp_frame_new(); - - gint64_value = kvp_value_new_gint64( 2 ); - double_value = kvp_value_new_double( 3.3 ); - numeric_value = kvp_value_new_gnc_numeric( gnc_numeric_orig ); - string_value = kvp_value_new_string( "abcdefghijklmnop" ); - guid_value = kvp_value_new_guid( guid_orig ); - timespec_value = kvp_value_new_timespec( ts_orig ); - glist_value = kvp_value_new_glist( list_orig ); - frame_value = kvp_value_new_frame( frame_orig ); - - /* init list 1 */ - list1 = g_list_append( list1, gint64_value ); - list1 = g_list_append( list1, double_value ); - list1 = g_list_append( list1, numeric_value ); - list1 = g_list_append( list1, string_value ); - list1 = g_list_append( list1, guid_value ); - list1 = g_list_append( list1, timespec_value ); - list1 = g_list_append( list1, glist_value ); - list1 = g_list_append( list1, frame_value ); - g_assert( list1 ); - g_assert_cmpint( g_list_length( list1 ), == , 8 ); - - g_test_message( "Test when list is the same" ); - list2 = list1; - g_assert_cmpint( kvp_glist_compare( list1, list2 ), == , 0 ); - - g_test_message( "Test when list1 is null" ); - g_assert_cmpint( kvp_glist_compare( NULL, list2 ), == , -1 ); - - g_test_message( "Test when list2 is null" ); - g_assert_cmpint( kvp_glist_compare( list1, NULL ), == , 1 ); - - g_test_message( "Copy list and test they are equal" ); - list2 = kvp_glist_copy( list1 ); - g_assert( list1 != list2 ); - g_assert_cmpint( g_list_length( list1 ), == , g_list_length( list2 ) ); - g_assert_cmpint( kvp_glist_compare( list1, list2 ), == , 0 ); - - g_test_message( "Test when list 1 is shorter lists are not equal" ); - list1 = g_list_remove( list1, frame_value ); - g_assert_cmpint( g_list_length( list1 ), == , 7 ); - g_assert_cmpint( g_list_length( list2 ), == , 8 ); - g_assert_cmpint( kvp_glist_compare( list1, list2 ), == , -1 ); - - g_test_message( "Test when list 2 is shorter lists are not equal" ); - list1 = g_list_append( list1, frame_value ); - list1 = g_list_append( list1, frame_value ); - g_assert_cmpint( g_list_length( list1 ), == , 9 ); - g_assert_cmpint( g_list_length( list2 ), == , 8 ); - g_assert_cmpint( kvp_glist_compare( list1, list2 ), == , 1 ); - - g_test_message( "Test when data is not equal lists are not equal" ); - list1 = g_list_remove( list1, frame_value ); - g_assert_cmpint( g_list_length( list1 ), == , g_list_length( list2 ) ); - g_assert_cmpint( kvp_glist_compare( list1, list2 ), == , 0 ); - list1 = g_list_remove( list1, gint64_value ); - kvp_value_delete( gint64_value ); - list1 = g_list_prepend( list1, kvp_value_new_gint64( 5 ) ); - g_assert_cmpint( g_list_length( list1 ), == , g_list_length( list2 ) ); - g_assert_cmpint( kvp_glist_compare( list1, list2 ), != , 0 ); - - /* delete lists */ - kvp_glist_delete( list1 ); - kvp_glist_delete( list2 ); -} - -static void -test_kvp_value_compare( void ) -{ - KvpValue *gint64_orig_value, *gint64_copy_value; - KvpValue *double_orig_value, *double_copy_value; - KvpValue *numeric_orig_value, *numeric_copy_value; - KvpValue *string_orig_value, *string_copy_value; - KvpValue *guid_orig_value, *guid_copy_value; - KvpValue *timespec_orig_value, *timespec_copy_value; - KvpValue *glist_orig_value, *glist_copy_value; - KvpValue *frame_orig_value, *frame_copy_value; - - /* data init */ - gnc_numeric gnc_numeric_orig, gnc_numeric_copy; - GncGUID *guid_orig, *guid_copy; - Timespec ts_orig, ts_copy; - GList *list_orig, *list_copy; - KvpFrame *frame_orig, *frame_copy; - - gnc_numeric_orig = gnc_numeric_zero(); - gnc_numeric_copy = gnc_numeric_zero(); - guid_orig = guid_new(); - guid_copy = guid_new(); - ts_orig.tv_sec = 1; - ts_orig.tv_nsec = 1; - ts_copy.tv_sec = 2; - ts_copy.tv_nsec = 2; - list_orig = NULL; - list_orig = g_list_append( list_orig, kvp_value_new_string( "abcdefghijklmnop" ) ); - list_copy = NULL; - list_copy = g_list_append( list_copy, kvp_value_new_string( "abcdefg" ) ); - frame_orig = kvp_frame_new(); - frame_copy = kvp_frame_new(); - - gint64_orig_value = kvp_value_new_gint64( 2 ); - gint64_copy_value = kvp_value_new_gint64( 5 ); - double_orig_value = kvp_value_new_double( 3.3 ); - double_copy_value = kvp_value_new_double( 3.5 ); - numeric_orig_value = kvp_value_new_gnc_numeric( gnc_numeric_orig ); - numeric_copy_value = kvp_value_new_gnc_numeric( gnc_numeric_copy ); - string_orig_value = kvp_value_new_string( "abcdefghijklmnop" ); - string_copy_value = kvp_value_new_string( "abcdefghijklmnop" ); - guid_orig_value = kvp_value_new_guid( guid_orig ); - guid_copy_value = kvp_value_new_guid( guid_copy ); - timespec_orig_value = kvp_value_new_timespec( ts_orig ); - timespec_copy_value = kvp_value_new_timespec( ts_copy ); - glist_orig_value = kvp_value_new_glist( list_orig ); - glist_copy_value = kvp_value_new_glist( list_copy ); - frame_orig_value = kvp_value_new_frame( frame_orig ); - frame_copy_value = kvp_value_new_frame( frame_copy ); - - g_test_message( "Test the same kvpvalue is equal" ); - g_assert_cmpint( kvp_value_compare( gint64_orig_value, gint64_orig_value ), == , 0 ); - - g_test_message( "Test first value is null" ); - g_assert_cmpint( kvp_value_compare( NULL, gint64_orig_value ), == , -1 ); - - g_test_message( "Test second value is null" ); - g_assert_cmpint( kvp_value_compare( gint64_orig_value, NULL ), == , 1 ); - - g_test_message( "Test diffrent data types first is lesser" ); - g_assert_cmpint( kvp_value_compare( gint64_orig_value, double_orig_value ), == , -1 ); - - g_test_message( "Test diffrent data types second is lesser" ); - g_assert_cmpint( kvp_value_compare( double_orig_value, gint64_orig_value ), == , 1 ); - - /* testing all different cases of data equality is not the aim - * of this test. Rather we check that all data types are being compared. - */ - g_test_message( "Test different kvpvalues of all the types" ); - g_assert_cmpint( kvp_value_compare( gint64_orig_value, gint64_copy_value ), == , -1 ); - g_assert_cmpint( kvp_value_compare( gint64_copy_value, gint64_orig_value ), == , 1 ); - g_assert_cmpint( kvp_value_compare( double_orig_value, double_copy_value ), == , -1 ); - g_assert_cmpint( kvp_value_compare( numeric_orig_value, numeric_copy_value ), == , gnc_numeric_compare( gnc_numeric_orig, gnc_numeric_copy ) ); - g_assert_cmpint( kvp_value_compare( string_orig_value, string_copy_value ), == , strcmp( "abcdefghijklmnop", "abcdefghijklmnop" ) ); - g_assert_cmpint( kvp_value_compare( guid_orig_value, guid_copy_value ), == , guid_compare( guid_orig, guid_copy ) ); - g_assert_cmpint( kvp_value_compare( timespec_orig_value, timespec_copy_value ), == , timespec_cmp( &ts_orig, &ts_copy ) ); - g_assert_cmpint( kvp_value_compare( glist_orig_value, glist_copy_value ), == , kvp_glist_compare( list_orig, list_copy ) ); - g_assert_cmpint( kvp_value_compare( frame_orig_value, frame_copy_value ), == , kvp_frame_compare( frame_orig, frame_copy ) ); - - /* destroy objects */ - kvp_value_delete( gint64_orig_value ); - kvp_value_delete( double_orig_value ); - kvp_value_delete( numeric_orig_value ); - kvp_value_delete( string_orig_value ); - kvp_value_delete( guid_orig_value ); - kvp_value_delete( timespec_orig_value ); - kvp_value_delete( glist_orig_value ); - kvp_value_delete( frame_orig_value ); - - kvp_value_delete( gint64_copy_value ); - kvp_value_delete( double_copy_value ); - kvp_value_delete( numeric_copy_value ); - kvp_value_delete( string_copy_value ); - kvp_value_delete( guid_copy_value ); - kvp_value_delete( timespec_copy_value ); - kvp_value_delete( glist_copy_value ); - kvp_value_delete( frame_copy_value ); -} - -static void -test_kvp_value_new_foo_nc( void ) -{ - KvpValue *glist_value_nc, *frame_value_nc; - void *val; - guint64 size; - GList *list = NULL; - KvpFrame *frame = NULL; - - g_test_message( "Test new glist is not copied" ); - list = g_list_append( list, kvp_value_new_gint64( 2 ) ); - g_assert_cmpint( g_list_length( list ), == , 1 ); - glist_value_nc = kvp_value_new_glist_nc( list ); - g_assert( glist_value_nc ); - g_assert( kvp_value_get_type( glist_value_nc ) == KVP_TYPE_GLIST ); - g_assert( kvp_value_get_glist( glist_value_nc ) == list ); - - g_test_message( "Test new frame is not copied" ); - frame = kvp_frame_new(); - frame_value_nc = kvp_value_new_frame_nc( frame ); - g_assert( frame_value_nc ); - g_assert( kvp_value_get_type( frame_value_nc ) == KVP_TYPE_FRAME ); - g_assert( kvp_value_get_frame( frame_value_nc ) == frame ); - - kvp_value_delete( glist_value_nc ); - kvp_value_delete( frame_value_nc ); -} - -static void -test_kvp_frame_compare( Fixture *fixture, gconstpointer pData ) -{ - KvpFrame *cmp_frame = NULL; - - cmp_frame = kvp_frame_new(); - g_assert( cmp_frame ); - - g_test_message( "Test the same frame is equal with itself" ); - g_assert_cmpint( kvp_frame_compare( fixture->frame, fixture->frame ), == , 0 ); - - g_test_message( "Test first frame null second not null" ); - g_assert_cmpint( kvp_frame_compare( NULL, fixture->frame ), == , -1 ); - - g_test_message( "Test first frame not null second null" ); - g_assert_cmpint( kvp_frame_compare( fixture->frame, NULL ), == , 1 ); - - g_test_message( "Test first frame is empty second not empty" ); - kvp_frame_set_gint64( fixture->frame, "/test/test2", 64 ); - g_assert( !kvp_frame_is_empty( fixture->frame ) ); - g_assert( kvp_frame_is_empty( cmp_frame ) ); - g_assert_cmpint( kvp_frame_compare( cmp_frame, fixture->frame ), == , -1 ); - - g_test_message( "Test first frame is not empty second is empty" ); - g_assert_cmpint( kvp_frame_compare( fixture->frame, cmp_frame ), == , 1 ); - - g_test_message( "Test when frames are equal" ); - kvp_frame_set_gint64( cmp_frame, "/test/test2", 64 ); - g_assert( !kvp_frame_is_empty( cmp_frame ) ); - g_assert_cmpint( kvp_frame_compare( fixture->frame, cmp_frame ), == , 0 ); - - g_test_message( "Test when frames have equal data but second frame has additional slot set" ); - kvp_frame_set_string( fixture->frame, "/test/test3", "abcdefghijklmnop" ); - g_assert_cmpint( kvp_frame_compare( cmp_frame, fixture->frame ), == , -1 ); - - g_test_message( "Test when frames have equal data but first frame has additional slot set" ); - g_assert_cmpint( kvp_frame_compare( fixture->frame, cmp_frame ), == , 1 ); - - g_test_message( "Test when frames have equal number of slots second frame has different data in one slot" ); - kvp_frame_set_string( cmp_frame, "/test/test3", "abcdefg" ); - g_assert_cmpint( kvp_frame_compare( cmp_frame, fixture->frame ), < , 0 ); - - g_test_message( "Test when frames have equal number of slots second frame has different data in one slot" ); - g_assert_cmpint( kvp_frame_compare( fixture->frame, cmp_frame ), > , 0 ); - - kvp_frame_delete( cmp_frame ); -} - -static void -test_kvp_value_to_string( void ) -{ - gchar guidstr[GUID_ENCODING_LENGTH+1]; - gchar *str_tmp2, *str_tmp3; - gchar *result; - KvpValue *gint64_value; - KvpValue *double_value; - KvpValue *numeric_value; - KvpValue *string_value; - KvpValue *guid_value; - KvpValue *timespec_value; - KvpValue *glist_value; - KvpValue *frame_value; - - gnc_numeric gnc_numeric_orig; - GncGUID *guid_orig; - Timespec ts_orig; - GList *list_orig; - KvpFrame *frame_orig; - - gnc_numeric_orig = gnc_numeric_zero(); - guid_orig = guid_new(); - ts_orig.tv_sec = 1; - ts_orig.tv_nsec = 1; - list_orig = NULL; - list_orig = g_list_append( list_orig, kvp_value_new_string( "abcdefghijklmnop" ) ); - frame_orig = kvp_frame_new(); - - gint64_value = kvp_value_new_gint64( 2 ); - double_value = kvp_value_new_double( 3.3 ); - numeric_value = kvp_value_new_gnc_numeric( gnc_numeric_orig ); - string_value = kvp_value_new_string( "abcdefghijklmnop" ); - guid_value = kvp_value_new_guid( guid_orig ); - timespec_value = kvp_value_new_timespec( ts_orig ); - glist_value = kvp_value_new_glist( list_orig ); - frame_value = kvp_value_new_frame( frame_orig ); - - g_test_message( "Test value string representation with different data types" ); - result = kvp_value_to_string( gint64_value ); - g_assert( result ); - g_assert_cmpstr( result, == , "KVP_VALUE_GINT64(2)" ); - g_free( result ); - - result = kvp_value_to_string( double_value ); - g_assert( result ); - g_assert_cmpstr( result, == , "KVP_VALUE_DOUBLE(3.3)" ); - g_free( result ); - - result = kvp_value_to_string( numeric_value ); - g_assert( result ); - g_assert_cmpstr( result, == , "KVP_VALUE_NUMERIC(0/1)" ); - g_free( result ); - - result = kvp_value_to_string( string_value ); - g_assert( result ); - g_assert_cmpstr( result, == , "KVP_VALUE_STRING(abcdefghijklmnop)" ); - g_free( result ); - - result = kvp_value_to_string( guid_value ); - g_assert( result ); - guid_to_string_buff( kvp_value_get_guid( guid_value ), guidstr); - str_tmp2 = g_strdup_printf("KVP_VALUE_GUID(%s)", guidstr); - g_assert_cmpstr( result, == , str_tmp2 ); - g_free( result ); - g_free( str_tmp2 ); - - result = kvp_value_to_string( timespec_value ); - g_assert( result ); - str_tmp2 = g_new0 (char, 40); - gnc_timespec_to_iso8601_buff( kvp_value_get_timespec( timespec_value ), str_tmp2 ); - str_tmp3 = g_strdup_printf("KVP_VALUE_TIMESPEC(%s)", str_tmp2); - g_assert_cmpstr( result, == , str_tmp3 ); - g_free( result ); - g_free( str_tmp2 ); - g_free( str_tmp3 ); - - result = kvp_value_to_string( glist_value ); - g_assert( result ); - g_assert_cmpstr( result, == , "KVP_VALUE_GLIST([ KVP_VALUE_STRING(abcdefghijklmnop), ])" ); - g_free( result ); - - result = kvp_value_to_string( frame_value ); - g_assert( result ); - g_assert_cmpstr( result, == , "KVP_VALUE_FRAME({\n}\n)" ); - g_free( result ); - - kvp_value_delete( gint64_value ); - kvp_value_delete( double_value ); - kvp_value_delete( numeric_value ); - kvp_value_delete( string_value ); - kvp_value_delete( guid_value ); - kvp_value_delete( timespec_value ); - kvp_value_delete( glist_value ); - kvp_value_delete( frame_value ); -} - -static void -test_kvp_frame_to_string( Fixture *fixture, gconstpointer pData ) -{ - gchar *result; - gnc_numeric test_gnc_numeric; - GncGUID *test_guid; - Timespec test_ts; - KvpFrame *test_frame; - - test_gnc_numeric = gnc_numeric_zero(); - test_guid = guid_new(); - test_ts.tv_sec = 1; - test_ts.tv_nsec = 1; - test_frame = kvp_frame_new(); - - g_assert( fixture->frame ); - g_assert( kvp_frame_is_empty( fixture->frame ) ); - - g_test_message( "Test empty frame" ); - result = kvp_frame_to_string( fixture->frame ); - g_assert_cmpstr( result, == , "{\n}\n" ); - g_free( result ); - - /* slots can be randomly distributed in hash table - * instead of checking the whole return string we rather check if certain entries exist in it - */ - g_test_message( "Test with all data types and nested frames" ); - kvp_frame_set_gint64( fixture->frame, "/gint64-type", 2 ); - result = kvp_frame_to_string( fixture->frame ); - g_assert( g_strrstr( result, " gint64-type => KVP_VALUE_GINT64(2),\n" ) != NULL ); - g_free( result ); - - kvp_frame_set_double( fixture->frame, "/double-type", 3.3 ); - result = kvp_frame_to_string( fixture->frame ); - g_assert( g_strrstr( result, " double-type => KVP_VALUE_DOUBLE(3.3),\n" ) != NULL ); - g_free( result ); - - kvp_frame_set_numeric( fixture->frame, "/numeric-type", test_gnc_numeric ); - result = kvp_frame_to_string( fixture->frame ); - g_assert( g_strrstr( result, " numeric-type => KVP_VALUE_NUMERIC(0/1),\n" ) != NULL ); - g_free( result ); - - kvp_frame_set_timespec( fixture->frame, "/timespec-type", test_ts ); - result = kvp_frame_to_string( fixture->frame ); - g_assert( g_strrstr( result, " timespec-type => KVP_VALUE_TIMESPEC" ) != NULL ); - g_free( result ); - - kvp_frame_set_string( fixture->frame, "/string-type", "abcdefghijklmnop" ); - result = kvp_frame_to_string( fixture->frame ); - g_assert( g_strrstr( result, " string-type => KVP_VALUE_STRING(abcdefghijklmnop),\n" ) != NULL ); - g_free( result ); - - kvp_frame_set_guid( fixture->frame, "/guid-type", test_guid ); - result = kvp_frame_to_string( fixture->frame ); - g_assert( g_strrstr( result, " guid-type => KVP_VALUE_GUID" ) != NULL ); - g_free( result ); - - kvp_frame_set_frame( fixture->frame, "/nested/frame-type", test_frame ); - result = kvp_frame_to_string( fixture->frame ); - g_assert( g_strrstr( result, " nested => KVP_VALUE_FRAME({\n frame-type => KVP_VALUE_FRAME({\n}\n),\n}\n),\n" ) != NULL ); - g_free( result ); -} - -static void -test_kvp_frame_set_slot_path( Fixture *fixture, gconstpointer pData ) -{ - KvpValue *input_value, *output_value; - - g_assert( fixture->frame ); - g_assert( kvp_frame_is_empty( fixture->frame ) ); - - g_test_message( "Test with a simple value added to the empty frame" ); - input_value = kvp_value_new_gint64( 2 ); - kvp_frame_set_slot_path( fixture->frame, input_value, "test", NULL ); - output_value = kvp_frame_get_slot_path( fixture->frame, "test", NULL ); - g_assert( output_value ); - g_assert( input_value != output_value ); /* copied */ - g_assert_cmpint( kvp_value_compare( output_value, input_value ), == , 0 ); - kvp_value_delete( input_value ); - - g_test_message( "Test when value is being replaced" ); - input_value = kvp_value_new_double( 3.3 ); - kvp_frame_set_slot_path( fixture->frame, input_value, "test", NULL ); - output_value = kvp_frame_get_slot_path( fixture->frame, "test", NULL ); - g_assert( output_value ); - g_assert( input_value != output_value ); /* copied */ - g_assert_cmpint( kvp_value_compare( output_value, input_value ), == , 0 ); /* old value removed */ - kvp_value_delete( input_value ); - - g_test_message( "Test when existing path elements are not frames" ); - input_value = kvp_value_new_string( "abcdefghijklmnop" ); - kvp_frame_set_slot_path( fixture->frame, input_value, "test", "test2", NULL ); - g_assert( kvp_frame_get_slot_path( fixture->frame, "test2", NULL ) == NULL );/* was not added */ - g_assert_cmpint( kvp_value_compare( output_value, kvp_frame_get_slot_path( fixture->frame, "test", NULL ) ), == , 0 ); /* nothing changed */ - kvp_value_delete( input_value ); - - g_test_message( "Test frames are created along the path when needed" ); - input_value = kvp_value_new_string( "abcdefghijklmnop" ); - kvp_frame_set_slot_path( fixture->frame, input_value, "test2", "test3", NULL ); - output_value = kvp_frame_get_slot_path( fixture->frame, "test2", NULL ); - g_assert( output_value ); - g_assert( kvp_value_get_type( output_value ) == KVP_TYPE_FRAME ); - output_value = kvp_frame_get_slot_path( fixture->frame, "test2", "test3", NULL ); - g_assert( output_value ); - g_assert( input_value != output_value ); /* copied */ - g_assert_cmpint( kvp_value_compare( output_value, input_value ), == , 0 ); - kvp_value_delete( input_value ); -} - -static void -test_kvp_frame_set_slot_path_gslist( Fixture *fixture, gconstpointer pData ) -{ - /* similar to previous test except path is passed as GSList*/ - GSList *path_list = NULL; - KvpValue *input_value, *output_value; - - g_assert( fixture->frame ); - g_assert( kvp_frame_is_empty( fixture->frame ) ); - - g_test_message( "Test with a simple value added to the empty frame" ); - path_list = g_slist_append( path_list, "test" ); - input_value = kvp_value_new_gint64( 2 ); - kvp_frame_set_slot_path_gslist( fixture->frame, input_value, path_list ); - output_value = kvp_frame_get_slot_path( fixture->frame, "test", NULL ); - g_assert( output_value ); - g_assert( input_value != output_value ); /* copied */ - g_assert_cmpint( kvp_value_compare( output_value, input_value ), == , 0 ); - kvp_value_delete( input_value ); - - g_test_message( "Test when value is being replaced" ); - input_value = kvp_value_new_double( 3.3 ); - kvp_frame_set_slot_path_gslist( fixture->frame, input_value, path_list ); - output_value = kvp_frame_get_slot_path( fixture->frame, "test", NULL ); - g_assert( output_value ); - g_assert( input_value != output_value ); /* copied */ - g_assert_cmpint( kvp_value_compare( output_value, input_value ), == , 0 ); /* old value removed */ - kvp_value_delete( input_value ); - - g_test_message( "Test when existing path elements are not frames" ); - path_list = g_slist_append( path_list, "test2"); - input_value = kvp_value_new_string( "abcdefghijklmnop" ); - kvp_frame_set_slot_path_gslist( fixture->frame, input_value, path_list ); - g_assert( kvp_frame_get_slot_path( fixture->frame, "test2", NULL ) == NULL );/* was not added */ - g_assert_cmpint( kvp_value_compare( output_value, kvp_frame_get_slot_path( fixture->frame, "test", NULL ) ), == , 0 ); /* nothing changed */ - kvp_value_delete( input_value ); - - g_test_message( "Test frames are created along the path when needed" ); - path_list = g_slist_remove( path_list, "test" ); - path_list = g_slist_append( path_list, "test3"); - input_value = kvp_value_new_string( "abcdefghijklmnop" ); - kvp_frame_set_slot_path_gslist( fixture->frame, input_value, path_list ); - output_value = kvp_frame_get_slot_path( fixture->frame, "test2", NULL ); - g_assert( output_value ); - g_assert( kvp_value_get_type( output_value ) == KVP_TYPE_FRAME ); - output_value = kvp_frame_get_slot_path( fixture->frame, "test2", "test3", NULL ); - g_assert( output_value ); - g_assert( input_value != output_value ); /* copied */ - g_assert_cmpint( kvp_value_compare( output_value, input_value ), == , 0 ); - kvp_value_delete( input_value ); - - g_slist_free( path_list ); -} - -static void -test_kvp_frame_replace_slot_nc( Fixture *fixture, gconstpointer pData ) -{ - KvpValue *orig_value, *orig_value2; - const char ** keys; - /* test indirectly static function kvp_frame_replace_slot_nc */ - g_assert( fixture->frame ); - g_assert( kvp_frame_is_empty( fixture->frame ) ); - - g_test_message( "Test when new value is created frame hash init and value stored in hash" ); - orig_value = kvp_value_new_gint64( 2 ); - kvp_frame_set_slot( fixture->frame, "test", orig_value ); - g_assert( !kvp_frame_is_empty( fixture->frame ) ); - keys = kvp_frame_get_keys( fixture->frame ); - g_assert( keys ); - g_assert( !keys[1] ); - g_assert( orig_value != kvp_frame_get_value( fixture->frame, keys[0] ) ); - g_assert_cmpint( kvp_value_compare( kvp_frame_get_value( fixture->frame, keys[0] ), orig_value ), ==, 0 ); - g_free( keys ); - - g_test_message( "Test when value is replaced" ); - orig_value2 = kvp_value_new_gint64( 5 ); - kvp_frame_set_slot( fixture->frame, "test", orig_value2 ); - keys = kvp_frame_get_keys( fixture->frame ); - g_assert( keys ); - g_assert( !keys[1] ); - g_assert( orig_value != kvp_frame_get_value( fixture->frame, keys[0] ) ); - g_assert_cmpint( kvp_value_compare( kvp_frame_get_value( fixture->frame, keys[0] ), orig_value2 ), ==, 0 ); - g_assert_cmpint( kvp_value_compare( kvp_frame_get_value( fixture->frame, keys[0] ), orig_value ), !=, 0 ); - g_free( keys ); - - kvp_value_delete( orig_value ); - kvp_value_delete( orig_value2 ); -} - -static void -test_get_trailer_make( Fixture *fixture, gconstpointer pData ) -{ - char *last_key = NULL; - KvpValue *frame_value = NULL; - KvpFrame *frame = NULL, *frame2 = NULL; - - g_test_message( "Test null frame and empty string checks" ); - g_assert( p_get_trailer_make( NULL, "test", &last_key ) == NULL ); - g_assert( !last_key ); - g_assert( p_get_trailer_make( fixture->frame, NULL, &last_key ) == NULL ); - g_assert( !last_key ); - g_assert( p_get_trailer_make( fixture->frame, "", &last_key ) == NULL ); - g_assert( !last_key ); - - g_test_message( "Test single frame on the path with no slash" ); - g_assert( p_get_trailer_make( fixture->frame, "test", &last_key ) == fixture->frame ); - g_assert_cmpstr( last_key, == , "test" ); - - g_test_message( "Test single frame on the path with slash" ); - last_key = NULL; - g_assert( p_get_trailer_make( fixture->frame, "/test", &last_key ) == fixture->frame ); - g_assert_cmpstr( last_key, == , "test" ); - - g_test_message( "Test path of trailing slash" ); - last_key = NULL; - g_assert( p_get_trailer_make( fixture->frame, "test/", &last_key ) == NULL ); - g_assert( !last_key ); - - g_test_message( "Test path of two entries: frame for test should be created" ); - /* test is considered to be last frame on the path - * and it is returned. Currently it doesn't exist and will be created - * test2 is stripped away and returned as last entry of the path - */ - last_key = NULL; - frame = p_get_trailer_make( fixture->frame, "/test/test2", &last_key ); - g_assert( frame ); - g_assert( frame != fixture->frame ); - frame_value = kvp_frame_get_slot( fixture->frame, "test" ); - g_assert( frame_value ); - g_assert( kvp_value_get_frame( frame_value ) == frame ); - frame_value = kvp_frame_get_slot( frame, "test2" ); - g_assert( !frame_value ); - g_assert_cmpstr( last_key, == , "test2" ); - - g_test_message( "Test path of two entries: test frame already exist" ); - /* here test frame already exist and should be returned - */ - last_key = NULL; - g_assert( frame == p_get_trailer_make( fixture->frame, "/test/test2", &last_key ) ); - g_assert_cmpstr( last_key, == , "test2" ); - - g_test_message( "Test path of three entries: neither frame exist" ); - /* test3 and test4 frames will be created. test4 will be created inside test3 frame - * while test3 inside fixture->frame. test4 will be returned - * test5 stripped away and returned in last_key - */ - last_key = NULL; - frame = p_get_trailer_make( fixture->frame, "/test3/test4/test5", &last_key ); - g_assert( frame ); - g_assert( frame != fixture->frame ); - frame_value = kvp_frame_get_slot( fixture->frame, "test3" ); - g_assert( frame_value ); - frame2 = kvp_value_get_frame( frame_value ); - g_assert( frame2 != frame ); - g_assert( frame2 != fixture->frame ); - frame_value = kvp_frame_get_slot( frame2, "test4" ); - g_assert( frame_value ); - g_assert( kvp_value_get_frame( frame_value ) == frame ); - frame_value = kvp_frame_get_slot( frame, "test5" ); - g_assert( !frame_value ); - g_assert_cmpstr( last_key, == , "test5" ); -} - -static void -test_kvp_value_glist_to_string( Fixture *fixture, gconstpointer pData ) -{ - /* - * kvp_value_glist_to_string and kvp_value_to_string call each other - */ - GList *value_list = NULL; - gchar *result; - - gnc_numeric gnc_numeric_orig; - GList *list_orig; - KvpFrame *frame_orig; - - gnc_numeric_orig = gnc_numeric_zero(); - list_orig = NULL; - list_orig = g_list_append( list_orig, kvp_value_new_string( "abcdefghijklmnop" ) ); - frame_orig = kvp_frame_new(); - - g_test_message( "Test empty list" ); - result = glist_to_string( value_list ); - g_assert_cmpstr( result, == , "" ); - g_free( result ); - - g_test_message( "Test list with simple and complex values" ); - value_list = g_list_append( value_list, kvp_value_new_gint64( 2 ) ); - value_list = g_list_append( value_list, kvp_value_new_double( 3.3 ) ); - value_list = g_list_append( value_list, kvp_value_new_gnc_numeric( gnc_numeric_orig ) ); - value_list = g_list_append( value_list, kvp_value_new_string( "abcdefghijklmnop" ) ); - value_list = g_list_append( value_list, kvp_value_new_glist( list_orig ) ); - value_list = g_list_append( value_list, kvp_value_new_frame( frame_orig ) ); - g_assert( value_list ); - g_assert_cmpint( g_list_length( value_list ), == , 6 ); - result = glist_to_string( value_list ); - - g_assert_cmpstr( result, == , "KVP_VALUE_GLIST([ KVP_VALUE_GINT64(2), KVP_VALUE_DOUBLE(3.3), KVP_VALUE_NUMERIC(0/1), KVP_VALUE_STRING(abcdefghijklmnop), KVP_VALUE_GLIST([ KVP_VALUE_STRING(abcdefghijklmnop), ]), KVP_VALUE_FRAME({\n}\n), ])" ); - g_free( result ); - - kvp_glist_delete( value_list ); -} - -static void -test_get_or_make( Fixture *fixture, gconstpointer pData ) -{ - KvpFrame *test_frame = NULL; - - g_assert( fixture->frame ); - g_assert( kvp_frame_is_empty( fixture->frame ) ); - - g_test_message( "Test new frame is created" ); - test_frame = p_get_or_make( fixture->frame, "test" ); - g_assert( test_frame ); - g_assert( test_frame != fixture->frame ); - g_assert( kvp_frame_get_frame( fixture->frame, "test" ) == test_frame ); - - g_test_message( "Test existing frame is returned" ); - g_assert( test_frame == p_get_or_make( fixture->frame, "test" ) ); - g_assert( kvp_frame_get_frame( fixture->frame, "test" ) == test_frame ); -} - -static void -test_kvp_frame_get_frame_or_null_slash_trash( Fixture *fixture, gconstpointer pData ) -{ - g_test_message( "Test null checks" ); - g_assert( p_kvp_frame_get_frame_or_null_slash_trash( NULL, "test" ) == NULL ); - g_assert( p_kvp_frame_get_frame_or_null_slash_trash( fixture->frame, NULL ) == NULL ); - - g_test_message( "Test single slash and trailing slash path" ); - g_assert( p_kvp_frame_get_frame_or_null_slash_trash( fixture->frame, "/" ) == fixture->frame ); - g_assert( p_kvp_frame_get_frame_or_null_slash_trash( fixture->frame, "////" ) == fixture->frame ); - - g_test_message( "Test non existing path" ); - g_assert( p_kvp_frame_get_frame_or_null_slash_trash( fixture->frame, "/test" ) == NULL ); - - g_test_message( "Test existing path when value is not frame" ); - kvp_frame_set_gint64( fixture->frame, "/test", 2 ); - g_assert( p_kvp_frame_get_frame_or_null_slash_trash( fixture->frame, "/test" ) == NULL ); - - g_test_message( "Test existing path when value is frame" ); - kvp_frame_set_frame( fixture->frame, "/test2", kvp_frame_new() ); - g_assert( p_kvp_frame_get_frame_or_null_slash_trash( fixture->frame, "/test2" ) != NULL ); -} - -static void -test_get_trailer_or_null( Fixture *fixture, gconstpointer pData ) -{ - char *last_key = NULL; - KvpFrame *frame = NULL; - const KvpFrame* frame2 = NULL; - - g_test_message( "Test null frame and empty string checks" ); - g_assert( p_get_trailer_or_null( NULL, "test", &last_key ) == NULL ); - g_assert( !last_key ); - g_assert( p_get_trailer_or_null( fixture->frame, NULL, &last_key ) == NULL ); - g_assert( !last_key ); - g_assert( p_get_trailer_or_null( fixture->frame, "", &last_key ) == NULL ); - g_assert( !last_key ); - - g_test_message( "Test single frame on the path with no slash" ); - g_assert( p_get_trailer_or_null( fixture->frame, "test", &last_key ) == fixture->frame ); - g_assert_cmpstr( last_key, == , "test" ); - - g_test_message( "Test single frame on the path with slash" ); - last_key = NULL; - g_assert( p_get_trailer_or_null( fixture->frame, "/test", &last_key ) == fixture->frame ); - g_assert_cmpstr( last_key, == , "test" ); - - g_test_message( "Test path of trailing slash" ); - last_key = NULL; - g_assert( p_get_trailer_or_null( fixture->frame, "test/", &last_key ) == NULL ); - g_assert( !last_key ); - - g_test_message( "Test with non existing path" ); - last_key = NULL; - g_assert( p_get_trailer_or_null( fixture->frame, "/test/test2", &last_key ) == NULL ); - g_assert_cmpstr( last_key, == , "test2" ); - - g_test_message( "Test with existing path" ); - last_key = NULL; - frame = kvp_frame_new(); - kvp_frame_set_frame( fixture->frame, "/test/test2", frame ); - frame2 = p_get_trailer_or_null( fixture->frame, "/test/test2", &last_key ); - g_assert( kvp_frame_get_frame( fixture->frame, "/test") == frame2 ); - g_assert_cmpstr( last_key, == , "test2" ); -} - -static void -test_kvp_frame_get_gvalue (Fixture *fixture, gconstpointer pData) -{ - KvpFrame *frame = fixture->frame; - GValue *value; - Timespec ts = {1, 1}; - GncGUID *guid = populate_frame (frame); - GDate date; - gchar *log_domain = "qof.kvp"; - gint log_level = G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL; - gchar *msg1 = "[gvalue_from_kvp_value()] Error! Attempt to transfer KvpFrame!"; - gchar *msg2 = "[gvalue_from_kvp_value()] Error! Invalid KVP Transfer Request!"; -#undef _func - TestErrorStruct *check1 = test_error_struct_new (log_domain, log_level, - msg1); - TestErrorStruct *check2 = test_error_struct_new (log_domain, log_level, - msg2); - fixture->hdlrs = test_log_set_fatal_handler (fixture->hdlrs, check1, - (GLogFunc)test_list_handler); - test_add_error (check1); - test_add_error (check2); - - g_date_clear (&date, 1); - g_date_set_dmy (&date, 26, 1, 1957); - - value = kvp_frame_get_gvalue (frame, "gint64-type"); - g_assert (value != NULL); - g_assert (G_VALUE_HOLDS_INT64 (value)); - g_assert_cmpint (g_value_get_int64 (value), ==, 100); - gnc_gvalue_free (value); - - value = kvp_frame_get_gvalue (frame, "double-type"); - g_assert (value != NULL); - g_assert (G_VALUE_HOLDS_DOUBLE (value)); - g_assert_cmpfloat (g_value_get_double (value), ==, 3.14159); - gnc_gvalue_free (value); - - value = kvp_frame_get_gvalue (frame, "numeric-type"); - g_assert (value != NULL); - g_assert_cmpint (G_VALUE_TYPE (value), ==, GNC_TYPE_NUMERIC); - g_assert (gnc_numeric_zero_p (*(gnc_numeric*)g_value_get_boxed (value))); - gnc_gvalue_free (value); - - value = kvp_frame_get_gvalue (frame, "timespec-type"); - g_assert (value != NULL); - g_assert_cmpint (G_VALUE_TYPE (value), ==, GNC_TYPE_TIMESPEC); - g_assert (timespec_equal (&ts, (Timespec*)g_value_get_boxed (value))); - gnc_gvalue_free (value); - - value = kvp_frame_get_gvalue (frame, "string-type"); - g_assert (value != NULL); - g_assert (G_VALUE_HOLDS_STRING (value)); - g_assert_cmpstr (g_value_get_string (value), ==, "abcdefghijklmnop"); - gnc_gvalue_free (value); - - value = kvp_frame_get_gvalue (frame, "guid-type"); - g_assert (value != NULL); - g_assert_cmpint (G_VALUE_TYPE (value), ==, GNC_TYPE_GUID); - g_assert (guid_equal (guid, (GncGUID*)g_value_get_boxed (value))); - gnc_gvalue_free (value); - - value = kvp_frame_get_gvalue (frame, "gdate-type"); - g_assert (value != NULL); - g_assert_cmpint (G_VALUE_TYPE (value), ==, G_TYPE_DATE); - g_assert_cmpint (g_date_compare (&date, (GDate*)g_value_get_boxed (value)), ==, 0); - gnc_gvalue_free (value); - - value = kvp_frame_get_gvalue (frame, "frame-type"); - g_assert (value == NULL); - g_assert_cmpint (check1->hits, ==, 1); - g_assert_cmpint (check2->hits, ==, 1); - - value = kvp_frame_get_gvalue (frame, "list-type"); - g_assert (value != NULL); - g_assert_cmpint (G_VALUE_TYPE (value), ==, GNC_TYPE_VALUE_LIST); - { - GList *list = (GList*)g_value_get_boxed (value); - GValue *value = NULL; - - value = (GValue*)(list->data); - g_assert (G_VALUE_HOLDS_INT64 (value)); - g_assert (g_value_get_int64 (value) == 0x1f2e3d4c5b6a79LL); - list = g_list_next (list); - - value = (GValue*)(list->data); - g_assert (G_VALUE_HOLDS_DOUBLE (value)); - g_assert_cmpfloat (g_value_get_double (value), ==, 0.4342944819); - list = g_list_next (list); - - value = (GValue*)(list->data); - g_assert_cmpint (G_VALUE_TYPE (value), ==, GNC_TYPE_NUMERIC); - g_assert (gnc_numeric_eq (*(gnc_numeric*)g_value_get_boxed (value), - gnc_numeric_create (256, 120))); - list = g_list_next (list); - - value = (GValue*)(list->data); - g_assert_cmpint (G_VALUE_TYPE (value), ==, GNC_TYPE_TIMESPEC); - g_assert (timespec_equal (&ts, (Timespec*)g_value_get_boxed (value))); - list = g_list_next (list); - - value = (GValue*)(list->data); - g_assert (G_VALUE_HOLDS_STRING (value)); - g_assert_cmpstr (g_value_get_string (value), ==, "qrstuvwxyz"); - list = g_list_next (list); - - value = (GValue*)(list->data); - g_assert_cmpint (G_VALUE_TYPE (value), ==, GNC_TYPE_GUID); - g_assert (guid_equal (guid, (GncGUID*)g_value_get_boxed (value))); - list = g_list_next (list); - - g_assert (list == NULL); - - } - gnc_gvalue_free (value); -} - -static void -test_kvp_frame_set_gvalue (Fixture *fixture, gconstpointer pData) -{ -/* Bit of a shortcut: We'll use kvp_frame_get_item to make our KvpItem - * and feed it into a new frame; something of a round-trip test. - */ - KvpFrame *o_frame = fixture->frame; - KvpFrame *n_frame = kvp_frame_new (); - GValue *value; - GList *o_list, *n_list; - - populate_frame (o_frame); - - value = kvp_frame_get_gvalue (o_frame, "gint64-type"); - g_assert (value != NULL); - kvp_frame_set_gvalue (n_frame, "gint64-type", value); - g_assert_cmpint (kvp_frame_get_gint64 (o_frame, "gint64-type"), ==, - kvp_frame_get_gint64 (n_frame, "gint64-type")); - - value = kvp_frame_get_gvalue (o_frame, "double-type"); - g_assert (value != NULL); - kvp_frame_set_gvalue (n_frame, "double-type", value); - g_assert_cmpint (kvp_frame_get_double (o_frame, "double-type"), ==, - kvp_frame_get_double (n_frame, "double-type")); - - value = kvp_frame_get_gvalue (o_frame, "numeric-type"); - g_assert (value != NULL); - kvp_frame_set_gvalue (n_frame, "numeric-type", value); - g_assert (gnc_numeric_equal (kvp_frame_get_numeric (o_frame, "numeric-type"), - kvp_frame_get_numeric (n_frame, "numeric-type"))); - - value = kvp_frame_get_gvalue (o_frame, "timespec-type"); - g_assert (value != NULL); - kvp_frame_set_gvalue (n_frame, "timespec-type", value); - { - Timespec o_ts = kvp_frame_get_timespec (o_frame, "timespec-type"); - Timespec n_ts = kvp_frame_get_timespec (n_frame, "timespec-type"); - g_assert (timespec_equal (&o_ts, &n_ts)); - } - - value = kvp_frame_get_gvalue (o_frame, "string-type"); - g_assert (value != NULL); - kvp_frame_set_gvalue (n_frame, "string-type", value); - g_assert_cmpstr (kvp_frame_get_string (o_frame, "string-type"), ==, - kvp_frame_get_string (n_frame, "string-type")); - - value = kvp_frame_get_gvalue (o_frame, "gdate-type"); - g_assert (value != NULL); - kvp_frame_set_gvalue (n_frame, "gdate-type", value); - { - GDate o_date = kvp_value_get_gdate (kvp_frame_get_slot (o_frame, - "gdate-type")); - GDate n_date = kvp_value_get_gdate (kvp_frame_get_slot (n_frame, - "gdate-type")); - g_assert_cmpint (g_date_compare (&o_date, &n_date), ==, 0); - } - - value = kvp_frame_get_gvalue (o_frame, "guid-type"); - g_assert (value != NULL); - kvp_frame_set_gvalue (n_frame, "guid-type", value); - g_assert (guid_equal (kvp_frame_get_guid (o_frame, "guid-type"), - kvp_frame_get_guid (n_frame, "guid-type"))); - - value = kvp_frame_get_gvalue (o_frame, "list-type"); - g_assert (value != NULL); - kvp_frame_set_gvalue (n_frame, "list-type", value); - o_list = kvp_value_get_glist (kvp_frame_get_slot (o_frame, "list_type")); - n_list = kvp_value_get_glist (kvp_frame_get_slot (n_frame, "list_type")); - - g_assert_cmpint (g_list_length (o_list), ==, g_list_length (n_list)); - while (o_list && n_list) - { - g_assert_cmpint (kvp_value_compare ((KvpValue*)o_list->data, - (KvpValue*)n_list->data), ==, 0); - o_list = g_list_next (o_list); - n_list = g_list_next (n_list); - } - kvp_frame_delete (n_frame); -} - -static void -test_kvp_frame_get_keys( void ) -{ - KvpFrame * frame = kvp_frame_new(); - const char * key1 = "number one"; - const char * key2 = "number one/number two"; - const char * key3 = "number three"; - const char * val1 = "Value1"; - const char * val2 = "Value2"; - const char * val3 = "Value3"; - unsigned int spot = 0; - const char ** keys; - kvp_frame_set_string(frame, key1, val1); - kvp_frame_set_string(frame, key2, val2); - kvp_frame_set_string(frame, key3, val3); - keys = kvp_frame_get_keys(frame); - - g_assert(keys); - g_assert(keys[spot]); - g_assert(strcmp(keys[spot++], val1)); - g_assert(keys[spot]); - g_assert(strcmp(keys[spot++], val3)); - g_assert(!keys[spot]); - - g_free(keys); - kvp_frame_delete(frame); -} - -void -test_suite_kvp_frame( void ) -{ - GNC_TEST_ADD_FUNC( suitename, "kvp frame new and delete", test_kvp_frame_new_delete ); - GNC_TEST_ADD( suitename, "kvp frame copy", Fixture, NULL, setup, test_kvp_frame_copy, teardown ); - GNC_TEST_ADD( suitename, "kvp frame set foo", Fixture, NULL, setup, test_kvp_frame_set_foo, teardown ); - GNC_TEST_ADD( suitename, "kvp frame get frame slash", Fixture, NULL, setup, test_kvp_frame_get_frame_slash, teardown ); - GNC_TEST_ADD( suitename, "kvp frame get slot path", Fixture, NULL, setup, test_kvp_frame_get_slot_path, teardown ); - GNC_TEST_ADD( suitename, "kvp frame get slot path gslist", Fixture, NULL, setup, test_kvp_frame_get_slot_path_gslist, teardown ); - GNC_TEST_ADD( suitename, "kvp frame add frame nc", Fixture, NULL, setup, test_kvp_frame_add_frame_nc, teardown ); - GNC_TEST_ADD_FUNC( suitename, "kvp value copy", test_kvp_value_copy ); - GNC_TEST_ADD_FUNC( suitename, "kvp glist copy", test_kvp_glist_copy ); - GNC_TEST_ADD_FUNC( suitename, "kvp glist compare", test_kvp_glist_compare ); - GNC_TEST_ADD_FUNC( suitename, "kvp value compare", test_kvp_value_compare ); - GNC_TEST_ADD_FUNC( suitename, "kvp value new foo no copy", test_kvp_value_new_foo_nc ); - GNC_TEST_ADD( suitename, "kvp frame compare", Fixture, NULL, setup, test_kvp_frame_compare, teardown ); - GNC_TEST_ADD_FUNC( suitename, "kvp value to string", test_kvp_value_to_string ); - GNC_TEST_ADD( suitename, "kvp frame to string", Fixture, NULL, setup, test_kvp_frame_to_string, teardown ); - GNC_TEST_ADD( suitename, "kvp frame set slot path", Fixture, NULL, setup, test_kvp_frame_set_slot_path, teardown ); - GNC_TEST_ADD( suitename, "kvp frame set slot path gslist", Fixture, NULL, setup, test_kvp_frame_set_slot_path_gslist, teardown ); - GNC_TEST_ADD( suitename, "kvp frame replace slot nc", Fixture, NULL, setup, test_kvp_frame_replace_slot_nc, teardown ); - GNC_TEST_ADD_FUNC( suitename, "kvp frame get keys", test_kvp_frame_get_keys ); - GNC_TEST_ADD( suitename, "get trailer make", Fixture, NULL, setup_static, test_get_trailer_make, teardown_static ); - GNC_TEST_ADD( suitename, "kvp value glist to string", Fixture, NULL, setup_static, test_kvp_value_glist_to_string, teardown_static ); - GNC_TEST_ADD( suitename, "get or make", Fixture, NULL, setup_static, test_get_or_make, teardown_static ); - GNC_TEST_ADD( suitename, "kvp frame get frame or null slash trash", Fixture, NULL, setup_static, test_kvp_frame_get_frame_or_null_slash_trash, teardown_static ); - GNC_TEST_ADD( suitename, "get trailer or null", Fixture, NULL, setup_static, test_get_trailer_or_null, teardown_static ); - GNC_TEST_ADD ( suitename, "kvp frame get gvalue", Fixture, NULL, setup, test_kvp_frame_get_gvalue, teardown); - GNC_TEST_ADD ( suitename, "kvp frame set gvalue", Fixture, NULL, setup, test_kvp_frame_set_gvalue, teardown); -} diff --git a/src/libqof/qof/test/test-qof.c b/src/libqof/qof/test/test-qof.c index b019e6c975..cd7ce43b4f 100644 --- a/src/libqof/qof/test/test-qof.c +++ b/src/libqof/qof/test/test-qof.c @@ -27,7 +27,6 @@ extern void test_suite_qofbook(); extern void test_suite_qofinstance(); -extern void test_suite_kvp_frame(); extern void test_suite_qofobject(); extern void test_suite_qofsession(); extern void test_suite_gnc_date(); @@ -47,7 +46,6 @@ main (int argc, test_suite_gnc_guid(); test_suite_qofbook(); test_suite_qofinstance(); - test_suite_kvp_frame(); test_suite_qofobject(); test_suite_qofsession(); test_suite_gnc_date(); diff --git a/src/libqof/qof/test/test-qofinstance.c b/src/libqof/qof/test/test-qofinstance.cpp similarity index 93% rename from src/libqof/qof/test/test-qofinstance.c rename to src/libqof/qof/test/test-qofinstance.cpp index ab1e630cfe..a25a9047e6 100644 --- a/src/libqof/qof/test/test-qofinstance.c +++ b/src/libqof/qof/test/test-qofinstance.cpp @@ -19,15 +19,17 @@ * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 * * Boston, MA 02110-1301, USA gnu@gnu.org * \********************************************************************/ +extern "C" +{ #include #include #include #include "../qof.h" #include "../qofbackend-p.h" -#include "../kvp_frame.h" - +} +#include "../kvp_frame.hpp" static const gchar *suitename = "/qof/qofinstance"; -void test_suite_qofinstance ( void ); +extern "C" void test_suite_qofinstance ( void ); static gchar* error_message; static gboolean is_called; @@ -56,7 +58,7 @@ fatal_handler ( const char * log_domain, static void setup( Fixture *fixture, gconstpointer pData ) { - fixture->inst = g_object_new(QOF_TYPE_INSTANCE, NULL); + fixture->inst = static_cast(g_object_new(QOF_TYPE_INSTANCE, NULL)); } static void @@ -122,16 +124,16 @@ test_instance_new_destroy( void ) QofInstanceClass *klass; /* test var */ Timespec *timespec_priv; - gchar *msg1 = "qof_instance_get_collection: assertion " _Q "QOF_IS_INSTANCE(ptr)' failed"; - gchar *msg2 = "qof_instance_get_editlevel: assertion " _Q "QOF_IS_INSTANCE(ptr)' failed"; - gchar *msg3 = "qof_instance_get_destroying: assertion " _Q "QOF_IS_INSTANCE(ptr)' failed"; - gchar *msg4 = "qof_instance_get_dirty_flag: assertion " _Q "QOF_IS_INSTANCE(ptr)' failed"; - gchar *log_domain = "qof"; - guint loglevel = G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL, hdlr; - TestErrorStruct check = { loglevel, log_domain, msg1 }; + const char *msg1 = "qof_instance_get_collection: assertion " _Q "QOF_IS_INSTANCE(ptr)' failed"; + const char *msg2 = "qof_instance_get_editlevel: assertion " _Q "QOF_IS_INSTANCE(ptr)' failed"; + const char *msg3 = "qof_instance_get_destroying: assertion " _Q "QOF_IS_INSTANCE(ptr)' failed"; + const char *msg4 = "qof_instance_get_dirty_flag: assertion " _Q "QOF_IS_INSTANCE(ptr)' failed"; + const char *log_domain = "qof"; + auto loglevel = static_cast(G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL); + auto check = test_error_struct_new(log_domain, loglevel, msg1); g_test_message( "Testing qofinstance object initialization" ); - inst = g_object_new(QOF_TYPE_INSTANCE, NULL); + inst = static_cast(g_object_new(QOF_TYPE_INSTANCE, NULL)); g_assert( QOF_IS_INSTANCE( inst ) ); /* test class fields */ klass = QOF_INSTANCE_GET_CLASS( inst ); @@ -162,27 +164,31 @@ test_instance_new_destroy( void ) g_assert( !QOF_IS_INSTANCE( inst ) ); /* set fatal handler */ g_test_log_set_fatal_handler ( ( GTestLogFatalFunc )fatal_handler, NULL ); - hdlr = g_log_set_handler (log_domain, loglevel, - (GLogFunc)test_checked_handler, &check); + auto hdlr = g_log_set_handler (log_domain, loglevel, + (GLogFunc)test_checked_handler, check); g_assert( qof_instance_get_collection( inst ) == NULL ); g_assert( g_strrstr( error_message, "assertion " _Q "QOF_IS_INSTANCE(ptr)' failed" ) != NULL ); g_free( error_message ); - check.msg = msg2; + g_free(check->msg); + check->msg = g_strdup(msg2); g_assert_cmpint( qof_instance_get_editlevel( inst ), == , 0 ); g_assert( g_strrstr( error_message, "assertion " _Q "QOF_IS_INSTANCE(ptr)' failed" ) != NULL ); g_free( error_message ); - check.msg = msg3; + g_free(check->msg); + check->msg = g_strdup(msg3); g_assert( !qof_instance_get_destroying( inst ) ); g_assert( g_strrstr( error_message, "assertion " _Q "QOF_IS_INSTANCE(ptr)' failed" ) != NULL ); g_free( error_message ); - check.msg = msg4; + g_free(check->msg); + check->msg = g_strdup(msg4); g_assert( !qof_instance_get_dirty_flag( inst ) ); g_assert( g_strrstr( error_message, "assertion " _Q "QOF_IS_INSTANCE(ptr)' failed" ) != NULL ); g_free( error_message ); g_log_remove_handler (log_domain, hdlr); + test_error_struct_free(check); } static void @@ -197,7 +203,7 @@ test_instance_init_data( void ) char guid_id_after[GUID_ENCODING_LENGTH + 1]; /* set up */ - inst = g_object_new( QOF_TYPE_INSTANCE, NULL ); + inst = static_cast(g_object_new( QOF_TYPE_INSTANCE, NULL )); g_assert( QOF_IS_INSTANCE( inst ) ); book = qof_book_new(); g_assert( QOF_IS_BOOK( book ) ); @@ -244,7 +250,7 @@ test_instance_get_set_slots( Fixture *fixture, gconstpointer pData ) g_assert( qof_instance_get_dirty_flag( fixture->inst ) ); g_test_message( "Test when kvp frame is not the same" ); - kvp_frame2 = kvp_frame_new(); + kvp_frame2 = new KvpFrame; g_assert( kvp_frame != kvp_frame2 ); qof_instance_set_slots( fixture->inst, kvp_frame2 ); g_assert( kvp_frame2 == qof_instance_get_slots( fixture->inst ) ); @@ -265,8 +271,8 @@ test_instance_version_cmp( void ) Timespec timespec_left, timespec_right; /* set up*/ - left = g_object_new( QOF_TYPE_INSTANCE, NULL ); - right = g_object_new( QOF_TYPE_INSTANCE, NULL ); + left = static_cast(g_object_new( QOF_TYPE_INSTANCE, NULL )); + right = static_cast(g_object_new( QOF_TYPE_INSTANCE, NULL )); g_test_message( "Test both null" ); result = qof_instance_version_cmp( NULL, NULL ); @@ -498,10 +504,10 @@ static void test_instance_commit_edit( Fixture *fixture, gconstpointer pData ) { gboolean result; - gchar *msg = "[qof_commit_edit()] unbalanced call - resetting (was -2)"; - gchar *log_domain = "qof.engine"; - guint loglevel = G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL, hdlr; - TestErrorStruct check = { loglevel, log_domain, msg }; + const gchar *msg = "[qof_commit_edit()] unbalanced call - resetting (was -2)"; + const gchar *log_domain = "qof.engine"; + auto loglevel = static_cast(G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL); + auto check = test_error_struct_new(log_domain, loglevel, msg); g_test_message( "Test when instance set to null" ); result = qof_commit_edit( NULL ); @@ -522,8 +528,8 @@ test_instance_commit_edit( Fixture *fixture, gconstpointer pData ) g_test_message( "Test when instance's editlevel < 0" ); g_test_log_set_fatal_handler ( ( GTestLogFatalFunc )fatal_handler, NULL ); - hdlr = g_log_set_handler (log_domain, loglevel, - (GLogFunc)test_checked_handler, &check); + auto hdlr = g_log_set_handler (log_domain, loglevel, + (GLogFunc)test_checked_handler, check); qof_instance_decrease_editlevel( fixture->inst ); g_assert_cmpint( qof_instance_get_editlevel( fixture->inst ), == , -1 ); result = qof_commit_edit( fixture->inst ); @@ -531,6 +537,7 @@ test_instance_commit_edit( Fixture *fixture, gconstpointer pData ) g_assert_cmpstr( error_message, == , "[qof_commit_edit()] unbalanced call - resetting (was -2)" ); g_free( error_message ); g_log_remove_handler (log_domain, hdlr); + test_error_struct_free(check); } /* backend commit test start */ @@ -728,7 +735,7 @@ test_instance_refers_to_object( Fixture *fixture, gconstpointer pData ) { QofInstance * ref; - ref = g_object_new( QOF_TYPE_INSTANCE, NULL ); + ref = static_cast(g_object_new( QOF_TYPE_INSTANCE, NULL )); g_assert( fixture->inst ); g_assert( ref ); g_assert( QOF_INSTANCE_GET_CLASS( fixture->inst )->refers_to_object == NULL ); @@ -784,7 +791,7 @@ test_instance_get_referring_object_list_from_collection( void ) book = qof_book_new(); g_assert( book ); g_assert( QOF_IS_BOOK( book ) ); - ref = g_object_new( QOF_TYPE_INSTANCE, NULL ); + ref = static_cast(g_object_new( QOF_TYPE_INSTANCE, NULL )); g_assert( ref ); g_assert( QOF_IS_INSTANCE( ref ) ); QOF_INSTANCE_GET_CLASS( ref )->refers_to_object = NULL; @@ -795,7 +802,7 @@ test_instance_get_referring_object_list_from_collection( void ) */ for (i = 0; i < list_length; i++ ) { - QofInstance *inst = g_object_new( QOF_TYPE_INSTANCE, NULL ); + auto inst = static_cast(g_object_new( QOF_TYPE_INSTANCE, NULL )); g_assert( inst ); qof_instance_init_data( inst, type, book ); inst_list = g_list_append ( inst_list, inst ); @@ -860,8 +867,8 @@ test_instance_get_typed_referring_object_list( void ) GList* result = NULL; /* setup */ - inst = g_object_new( QOF_TYPE_INSTANCE, NULL ); - ref = g_object_new( QOF_TYPE_INSTANCE, NULL ); + inst = static_cast(g_object_new( QOF_TYPE_INSTANCE, NULL )); + ref = static_cast(g_object_new( QOF_TYPE_INSTANCE, NULL )); book = qof_book_new(); g_assert( inst ); g_assert( ref ); @@ -945,9 +952,9 @@ test_instance_get_referring_object_list( void ) book = qof_book_new(); g_assert( book ); g_assert( QOF_IS_BOOK( book ) ); - ref1 = g_object_new( QOF_TYPE_INSTANCE, NULL ); + ref1 = static_cast(g_object_new( QOF_TYPE_INSTANCE, NULL )); g_assert( ref1 ); - ref2 = g_object_new( QOF_TYPE_INSTANCE, NULL ); + ref2 = static_cast(g_object_new( QOF_TYPE_INSTANCE, NULL )); g_assert( ref2 ); qof_instance_init_data( ref1, type1, book ); qof_instance_init_data( ref2, type2, book ); @@ -963,7 +970,7 @@ test_instance_get_referring_object_list( void ) */ for (i = 0; i < col1_length; i++ ) { - QofInstance *inst = g_object_new( QOF_TYPE_INSTANCE, NULL ); + auto inst = static_cast(g_object_new( QOF_TYPE_INSTANCE, NULL )); g_assert( inst ); qof_instance_init_data( inst, type1, book ); inst_list1 = g_list_append ( inst_list1, inst ); @@ -974,7 +981,7 @@ test_instance_get_referring_object_list( void ) for (j = 0; j < col2_length; j++ ) { - QofInstance *inst = g_object_new( QOF_TYPE_INSTANCE, NULL ); + auto inst = static_cast(g_object_new( QOF_TYPE_INSTANCE, NULL )); g_assert( inst ); qof_instance_init_data( inst, type2, book ); inst_list2 = g_list_append ( inst_list2, inst ); @@ -1046,7 +1053,7 @@ test_instance_get_referring_object_list( void ) qof_book_destroy( book ); } -void +extern "C" void test_suite_qofinstance ( void ) { GNC_TEST_ADD( suitename, "set get book", Fixture, NULL, setup, test_instance_set_get_book, teardown ); diff --git a/src/test-core/test-stuff.h b/src/test-core/test-stuff.h index 8ef9d4b90a..c7fa548fd6 100644 --- a/src/test-core/test-stuff.h +++ b/src/test-core/test-stuff.h @@ -37,21 +37,6 @@ Otherwise, only failures are printed out. #include #include -/** - * Use this to indicate the result of a test. - * The result is TRUE for success, FALSE for failure. - * title describes the test - * Tests are automatically identified by their source file and line. - */ -#define do_test( result, title ) do_test_call( result, title, __FILE__, __LINE__ ) -#define success( title ) success_call( title, __FILE__, __LINE__ ); -#define failure( title ) failure_call( title, __FILE__, __LINE__ ); - -/** This one doesn't work because macros can't take a variable number of arguments. - * well, apparently gcc can, but it's non-standard. - * Apparently C99 can, too, but it's not exactly standard either. -#define do_test_args( result, title, format ) do_test_call( result, title, __FILE__, __LINE__, format, ... ); -*/ /* Privately used to indicate a test result. You may use these if you @@ -117,6 +102,22 @@ void failure_args( const char *format, ... ); +/** + * Use this to indicate the result of a test. + * The result is TRUE for success, FALSE for failure. + * title describes the test + * Tests are automatically identified by their source file and line. + */ +#define do_test( result, title ) do_test_call( result, title, __FILE__, __LINE__ ) +#define success( title ) success_call( title, __FILE__, __LINE__ ); +#define failure( title ) failure_call( title, __FILE__, __LINE__ ); + +/** This one doesn't work because macros can't take a variable number of arguments. + * well, apparently gcc can, but it's non-standard. + * Apparently C99 can, too, but it's not exactly standard either. +#define do_test_args( result, title, format ) do_test_call( result, title, __FILE__, __LINE__, format, ... ); +*/ + gboolean get_random_boolean(void); gint get_random_int_in_range(int start, int end); void random_character_include_funky_chars (gboolean use_funky_chars); diff --git a/src/test-core/unittest-support.c b/src/test-core/unittest-support.c index 8e257ba947..86cbe44ca1 100644 --- a/src/test-core/unittest-support.c +++ b/src/test-core/unittest-support.c @@ -29,7 +29,7 @@ typedef struct { gpointer data; gboolean called; - gchar *msg; + char *msg; } TestStruct; static TestStruct tdata; @@ -41,7 +41,8 @@ test_list_nohit_handler (const char *log_domain, GLogLevelFlags log_level, const gchar *msg, gpointer user_data); TestErrorStruct* -test_error_struct_new (gchar *log_domain, GLogLevelFlags log_level, gchar *msg) +test_error_struct_new (const char *log_domain, GLogLevelFlags log_level, + const char *msg) { TestErrorStruct *err = g_slice_new0 (TestErrorStruct); err->log_domain = g_strdup (log_domain); diff --git a/src/test-core/unittest-support.h b/src/test-core/unittest-support.h index fa4d07bbf6..9d6ded8a2c 100644 --- a/src/test-core/unittest-support.h +++ b/src/test-core/unittest-support.h @@ -87,8 +87,8 @@ typedef struct { GLogLevelFlags log_level; - gchar *log_domain; - gchar *msg; + char *log_domain; + char *msg; guint hits; } TestErrorStruct; @@ -105,9 +105,9 @@ typedef struct * @param msg: The exact error message that the logger will emit * @return: A TestErrorStruct * */ -TestErrorStruct* test_error_struct_new (gchar *log_domain, - GLogLevelFlags log_level, - gchar *msg); +TestErrorStruct* test_error_struct_new (const char *log_domain, + const GLogLevelFlags log_level, + const char *msg); /** * Free a TestErrorStruct created with test_error_struct_new From ff07762f612d16f7d7e366d1d4170f2276f03b54 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Sat, 27 Jun 2015 15:39:54 -0700 Subject: [PATCH 49/54] Move the KVP_TYPE enum to kvp-value.hpp. This had some extraordinary knock-on effects because C++11 treats enums very differently from C, so any C code that directly accessed the enum had to be converted to C++. That included test-engine-stuff, and because it quite sensibly builds as a ranlib archive instead of a shared library everything that uses it must at least link as C++. Fortunately automake takes care of doing this when the default extension for check_PROGRAMS is cpp, even if the source file is C. --- src/app-utils/test/Makefile.am | 4 +- src/app-utils/test/test-option-util.cpp | 4 +- ...e-amount.c => test-print-parse-amount.cpp} | 14 ++- src/app-utils/test/test-scm-query-string.c | 3 - src/backend/sql/gnc-slots-sql.cpp | 58 ++++----- src/backend/xml/sixtp-dom-generators.cpp | 24 ++-- src/backend/xml/test/test-kvp-frames.cpp | 2 +- src/engine/kvp-scm.cpp | 24 ++-- src/engine/test-core/test-engine-stuff.cpp | 62 ++++------ src/engine/test-core/test-engine-stuff.h | 5 +- src/engine/test/Makefile.am | 3 + .../test/{test-guid.c => test-guid.cpp} | 10 +- src/libqof/qof/gnc-aqbanking-templates.cpp | 2 +- src/libqof/qof/kvp-value.cpp | 93 ++++++++++---- src/libqof/qof/kvp-value.hpp | 22 +++- src/libqof/qof/kvp_frame.cpp | 116 +++--------------- src/libqof/qof/kvp_frame.h | 71 +---------- src/libqof/qof/qofinstance.cpp | 18 +-- src/libqof/qof/test/test-kvp-frame.cpp | 4 +- src/libqof/qof/test/test-kvp-value.cpp | 2 +- 20 files changed, 232 insertions(+), 309 deletions(-) rename src/app-utils/test/{test-print-parse-amount.c => test-print-parse-amount.cpp} (91%) rename src/engine/test/{test-guid.c => test-guid.cpp} (91%) diff --git a/src/app-utils/test/Makefile.am b/src/app-utils/test/Makefile.am index c0cf529317..5dbe1bb85f 100644 --- a/src/app-utils/test/Makefile.am +++ b/src/app-utils/test/Makefile.am @@ -8,6 +8,8 @@ check_PROGRAMS = \ test-sx \ test-app-utils +AM_DEFAULT_SOURCE_EXT = .cpp + TESTS = \ test-load-module \ ${check_PROGRAMS} @@ -16,7 +18,7 @@ test_exp_parser_SOURCES = \ test-exp-parser.c test_print_parse_amount_SOURCES = \ - test-print-parse-amount.c + test-print-parse-amount.cpp GNC_TEST_DEPS = --gnc-module-dir ${top_builddir}/src/engine \ --gnc-module-dir ${top_builddir}/src/app-utils \ diff --git a/src/app-utils/test/test-option-util.cpp b/src/app-utils/test/test-option-util.cpp index 16f0f35247..7bc7b9bcf7 100644 --- a/src/app-utils/test/test-option-util.cpp +++ b/src/app-utils/test/test-option-util.cpp @@ -228,8 +228,8 @@ test_option_save_book_currency (Fixture *fixture, gconstpointer pData) scm_cons (scm_from_utf8_string("GTQ"), scm_cons (scm_from_locale_symbol("fifo"), SCM_EOL))))); qof_book_save_options (book, gnc_option_db_save, odb, TRUE); - g_assert_cmpstr (kvp_frame_get_string(slots, "options/Accounts/Book Currency"), == , "GTQ"); - g_assert_cmpstr (kvp_frame_get_string(slots, "options/Accounts/Default Gains Policy"), == , "fifo"); + g_assert_cmpstr (slots->get_slot("options/Accounts/Book Currency")->get(), == , "GTQ"); + g_assert_cmpstr (slots->get_slot("options/Accounts/Default Gains Policy")->get(), == , "fifo"); gnc_option_db_destroy (odb); } diff --git a/src/app-utils/test/test-print-parse-amount.c b/src/app-utils/test/test-print-parse-amount.cpp similarity index 91% rename from src/app-utils/test/test-print-parse-amount.c rename to src/app-utils/test/test-print-parse-amount.cpp index 5f7a4e69df..83ac43c3b4 100644 --- a/src/app-utils/test/test-print-parse-amount.c +++ b/src/app-utils/test/test-print-parse-amount.cpp @@ -1,3 +1,5 @@ +extern "C" +{ #include "config.h" #include #include @@ -8,6 +10,7 @@ #include "test-engine-stuff.h" #include "test-stuff.h" #include +} static void test_num_print_info (gnc_numeric n, GNCPrintAmountInfo print_info, int line) @@ -16,13 +19,13 @@ test_num_print_info (gnc_numeric n, GNCPrintAmountInfo print_info, int line) const char *s; gboolean ok, print_ok; - gchar *msg = "[PrintAmountInternal()] Bad numeric from rounding: GNC_ERROR_OVERFLOW."; - gchar *log_domain = "gnc.gui"; - guint loglevel = G_LOG_LEVEL_WARNING, hdlr; - TestErrorStruct check = { loglevel, log_domain, msg }; + auto msg = "[PrintAmountInternal()] Bad numeric from rounding: GNC_ERROR_OVERFLOW."; + auto log_domain = "gnc.gui"; + auto loglevel = static_cast(G_LOG_LEVEL_WARNING); + auto check = test_error_struct_new (log_domain, loglevel, msg); /* Throws overflows during rounding step in xaccPrintAmount when the "fraction" is high. See bug 665707. */ - hdlr = g_log_set_handler (log_domain, loglevel, + auto hdlr = g_log_set_handler (log_domain, loglevel, (GLogFunc)test_checked_handler, &check); s = xaccPrintAmount (n, print_info); print_ok = (s && s[0] != '\0'); @@ -41,6 +44,7 @@ test_num_print_info (gnc_numeric n, GNCPrintAmountInfo print_info, int line) "start: %s, string %s, finish: %s (line %d)", gnc_numeric_to_string (n), s, gnc_numeric_to_string (n_parsed), line); + test_error_struct_free (check); } diff --git a/src/app-utils/test/test-scm-query-string.c b/src/app-utils/test/test-scm-query-string.c index c3bb1a59b5..e2831e8b09 100644 --- a/src/app-utils/test/test-scm-query-string.c +++ b/src/app-utils/test/test-scm-query-string.c @@ -96,9 +96,6 @@ main_helper (void *closure, int argc, char **argv) xaccLogDisable (); - /* double->string->double is not idempotent */ - kvp_exclude_type (KVP_TYPE_DOUBLE); - /* Initialize to a known RNG position */ srand(1); diff --git a/src/backend/sql/gnc-slots-sql.cpp b/src/backend/sql/gnc-slots-sql.cpp index 257d30fc7b..bbe299358b 100644 --- a/src/backend/sql/gnc-slots-sql.cpp +++ b/src/backend/sql/gnc-slots-sql.cpp @@ -64,7 +64,7 @@ typedef struct gboolean is_ok; /*@ dependent @*/ KvpFrame* pKvpFrame; - KvpValueType value_type; + KvpValue::Type value_type; GList *pList; context_t context; /*@ dependent @*/ @@ -77,7 +77,7 @@ static /*@ null @*/ gpointer get_obj_guid( gpointer pObject ); static void set_obj_guid( void ); static /*@ null @*/ gpointer get_path( gpointer pObject ); static void set_path( gpointer pObject, /*@ null @*/ gpointer pValue ); -static KvpValueType get_slot_type( gpointer pObject ); +static KvpValue::Type get_slot_type( gpointer pObject ); static void set_slot_type( gpointer pObject, /*@ null @*/ gpointer pValue ); static gint64 get_int64_val( gpointer pObject ); static void set_int64_val( gpointer pObject, gint64 pValue ); @@ -322,12 +322,12 @@ set_path( gpointer pObject, /*@ null @*/ gpointer pValue ) pInfo->path = g_string_new( (gchar*)pValue ); } -static KvpValueType +static KvpValue::Type get_slot_type( gpointer pObject ) { slot_info_t* pInfo = (slot_info_t*)pObject; - g_return_val_if_fail( pObject != NULL, KVP_TYPE_INVALID ); + g_return_val_if_fail( pObject != NULL, KvpValue::Type::INVALID ); // return (gpointer)kvp_value_get_type( pInfo->pKvpValue ); return pInfo->value_type; @@ -341,7 +341,7 @@ set_slot_type( gpointer pObject, /*@ null @*/ gpointer pValue ) g_return_if_fail( pObject != NULL ); g_return_if_fail( pValue != NULL ); - pInfo->value_type = static_cast(GPOINTER_TO_INT(pValue)); + pInfo->value_type = static_cast(GPOINTER_TO_INT(pValue)); } static gint64 @@ -351,7 +351,7 @@ get_int64_val( gpointer pObject ) g_return_val_if_fail( pObject != NULL, 0 ); - if ( pInfo->pKvpValue->get_type() == KVP_TYPE_GINT64 ) + if ( pInfo->pKvpValue->get_type() == KvpValue::Type::INT64 ) { return pInfo->pKvpValue->get(); } @@ -369,7 +369,7 @@ set_int64_val( gpointer pObject, gint64 value ) g_return_if_fail( pObject != NULL ); - if ( pInfo->value_type != KVP_TYPE_GINT64 ) return; + if ( pInfo->value_type != KvpValue::Type::INT64 ) return; pValue = new KvpValue{value}; set_slot_from_value( pInfo, pValue ); } @@ -381,7 +381,7 @@ get_string_val( gpointer pObject ) g_return_val_if_fail( pObject != NULL, NULL ); - if ( pInfo->pKvpValue->get_type() == KVP_TYPE_STRING ) + if ( pInfo->pKvpValue->get_type() == KvpValue::Type::STRING ) { return (gpointer)pInfo->pKvpValue->get(); } @@ -397,7 +397,7 @@ set_string_val( gpointer pObject, /*@ null @*/ gpointer pValue ) slot_info_t* pInfo = (slot_info_t*)pObject; g_return_if_fail( pObject != NULL ); - if (pInfo->value_type != KVP_TYPE_STRING || pValue == NULL) + if (pInfo->value_type != KvpValue::Type::STRING || pValue == NULL) return; auto string = g_strdup(static_cast(pValue)); auto value = new KvpValue{string}; @@ -412,7 +412,7 @@ get_double_val( gpointer pObject ) g_return_val_if_fail( pObject != NULL, NULL ); - if (pInfo->pKvpValue->get_type() == KVP_TYPE_DOUBLE) + if (pInfo->pKvpValue->get_type() == KvpValue::Type::DOUBLE) { d_val = pInfo->pKvpValue->get(); return (gpointer)&d_val; @@ -431,7 +431,7 @@ set_double_val( gpointer pObject, /*@ null @*/ gpointer pValue ) g_return_if_fail( pObject != NULL ); - if ( pInfo->value_type != KVP_TYPE_DOUBLE || pValue == NULL ) return; + if ( pInfo->value_type != KvpValue::Type::DOUBLE || pValue == NULL ) return; value = new KvpValue{*(static_cast(pValue))}; set_slot_from_value( pInfo, value ); } @@ -443,7 +443,7 @@ get_timespec_val( gpointer pObject ) g_return_val_if_fail( pObject != NULL, gnc_dmy2timespec( 1, 1, 1970 ) ); -//if( kvp_value_get_type( pInfo->pKvpValue ) == KVP_TYPE_TIMESPEC ) { +//if( kvp_value_get_type( pInfo->pKvpValue ) == KvpValue::Type::TIMESPEC ) { return pInfo->pKvpValue->get(); } @@ -455,7 +455,7 @@ set_timespec_val( gpointer pObject, Timespec ts ) g_return_if_fail( pObject != NULL ); - if ( pInfo->value_type != KVP_TYPE_TIMESPEC ) return; + if ( pInfo->value_type != KvpValue::Type::TIMESPEC ) return; value = new KvpValue{ts}; set_slot_from_value( pInfo, value ); } @@ -467,7 +467,7 @@ get_guid_val( gpointer pObject ) g_return_val_if_fail( pObject != NULL, NULL ); - if (pInfo->pKvpValue->get_type() == KVP_TYPE_GUID) + if (pInfo->pKvpValue->get_type() == KvpValue::Type::GUID) { return (gpointer)pInfo->pKvpValue->get(); } @@ -487,13 +487,13 @@ set_guid_val( gpointer pObject, /*@ null @*/ gpointer pValue ) switch ( pInfo->value_type) { - case KVP_TYPE_GUID: + case KvpValue::Type::GUID: { auto new_guid = guid_copy(static_cast(pValue)); set_slot_from_value(pInfo, new KvpValue{new_guid}); break; } - case KVP_TYPE_GLIST: + case KvpValue::Type::GLIST: { slot_info_t *newInfo = slot_info_copy( pInfo, (GncGUID*)pValue ); KvpValue *pValue = NULL; @@ -509,7 +509,7 @@ set_guid_val( gpointer pObject, /*@ null @*/ gpointer pValue ) g_free( key ); break; } - case KVP_TYPE_FRAME: + case KvpValue::Type::FRAME: { slot_info_t *newInfo = slot_info_copy( pInfo, (GncGUID*)pValue ) ; auto newFrame = new KvpFrame; @@ -554,7 +554,7 @@ get_numeric_val( gpointer pObject ) g_return_val_if_fail( pObject != NULL, gnc_numeric_zero() ); - if (pInfo->pKvpValue->get_type() == KVP_TYPE_NUMERIC) + if (pInfo->pKvpValue->get_type() == KvpValue::Type::NUMERIC) { return pInfo->pKvpValue->get(); } @@ -572,7 +572,7 @@ set_numeric_val( gpointer pObject, gnc_numeric value ) g_return_if_fail( pObject != NULL ); - if ( pInfo->value_type != KVP_TYPE_NUMERIC ) return; + if ( pInfo->value_type != KvpValue::Type::NUMERIC ) return; set_slot_from_value(pInfo, new KvpValue{value}); } @@ -584,7 +584,7 @@ get_gdate_val( gpointer pObject ) g_return_val_if_fail( pObject != NULL, NULL ); - if (pInfo->pKvpValue->get_type() == KVP_TYPE_GDATE) + if (pInfo->pKvpValue->get_type() == KvpValue::Type::GDATE) { date = pInfo->pKvpValue->get(); return &date; @@ -603,7 +603,7 @@ set_gdate_val( gpointer pObject, GDate* value ) g_return_if_fail( pObject != NULL ); - if ( pInfo->value_type != KVP_TYPE_GDATE ) return; + if ( pInfo->value_type != KvpValue::Type::GDATE ) return; set_slot_from_value(pInfo, new KvpValue{*value}); } @@ -653,7 +653,7 @@ save_slot( const gchar* key, KvpValue* value, gpointer data ) switch ( pSlot_info->value_type ) { - case KVP_TYPE_FRAME: + case KvpValue::Type::FRAME: { auto pKvpFrame = value->get(); auto guid = guid_new(); @@ -672,7 +672,7 @@ save_slot( const gchar* key, KvpValue* value, gpointer data ) g_slice_free( slot_info_t, pNewInfo ); } break; - case KVP_TYPE_GLIST: + case KvpValue::Type::GLIST: { GncGUID guid = guid_new_return(); slot_info_t *pNewInfo = slot_info_copy( pSlot_info, &guid ); @@ -711,7 +711,7 @@ gboolean gnc_sql_slots_save( GncSqlBackend* be, const GncGUID* guid, gboolean is_infant, QofInstance *inst) { - slot_info_t slot_info = { NULL, NULL, TRUE, NULL, KVP_TYPE_INVALID, NULL, FRAME, NULL, g_string_new(NULL) }; + slot_info_t slot_info = { NULL, NULL, TRUE, NULL, KvpValue::Type::INVALID, NULL, FRAME, NULL, g_string_new(NULL) }; KvpFrame *pFrame = qof_instance_get_slots (inst); g_return_val_if_fail( be != NULL, FALSE ); @@ -739,7 +739,7 @@ gnc_sql_slots_delete( GncSqlBackend* be, const GncGUID* guid ) GncSqlResult* result; gchar guid_buf[GUID_ENCODING_LENGTH + 1]; GncSqlStatement* stmt; - slot_info_t slot_info = { NULL, NULL, TRUE, NULL, KVP_TYPE_INVALID, NULL, FRAME, NULL, g_string_new(NULL) }; + slot_info_t slot_info = { NULL, NULL, TRUE, NULL, KvpValue::Type::INVALID, NULL, FRAME, NULL, g_string_new(NULL) }; g_return_val_if_fail( be != NULL, FALSE ); g_return_val_if_fail( guid != NULL, FALSE ); @@ -747,7 +747,7 @@ gnc_sql_slots_delete( GncSqlBackend* be, const GncGUID* guid ) (void)guid_to_string_buff( guid, guid_buf ); buf = g_strdup_printf( "SELECT * FROM %s WHERE obj_guid='%s' and slot_type in ('%d', '%d') and not guid_val is null", - TABLE_NAME, guid_buf, KVP_TYPE_FRAME, KVP_TYPE_GLIST ); + TABLE_NAME, guid_buf, KvpValue::Type::FRAME, KvpValue::Type::GLIST ); stmt = gnc_sql_create_statement_from_sql( be, buf ); g_free( buf ); if ( stmt != NULL ) @@ -821,7 +821,7 @@ load_slot( slot_info_t *pInfo, GncSqlRow* row ) void gnc_sql_slots_load( GncSqlBackend* be, QofInstance* inst ) { - slot_info_t info = { NULL, NULL, TRUE, NULL, KVP_TYPE_INVALID, NULL, FRAME, NULL, g_string_new(NULL) }; + slot_info_t info = { NULL, NULL, TRUE, NULL, KvpValue::Type::INVALID, NULL, FRAME, NULL, g_string_new(NULL) }; g_return_if_fail( be != NULL ); g_return_if_fail( inst != NULL ); @@ -886,7 +886,7 @@ load_obj_guid( const GncSqlBackend* be, GncSqlRow* row ) static void load_slot_for_list_item( GncSqlBackend* be, GncSqlRow* row, QofCollection* coll ) { - slot_info_t slot_info = { NULL, NULL, TRUE, NULL, KVP_TYPE_INVALID, NULL, FRAME, NULL, NULL }; + slot_info_t slot_info = { NULL, NULL, TRUE, NULL, KvpValue::Type::INVALID, NULL, FRAME, NULL, NULL }; const GncGUID* guid; QofInstance* inst; @@ -972,7 +972,7 @@ gnc_sql_slots_load_for_list( GncSqlBackend* be, GList* list ) static void load_slot_for_book_object( GncSqlBackend* be, GncSqlRow* row, BookLookupFn lookup_fn ) { - slot_info_t slot_info = { NULL, NULL, TRUE, NULL, KVP_TYPE_INVALID, NULL, FRAME, NULL, NULL }; + slot_info_t slot_info = { NULL, NULL, TRUE, NULL, KvpValue::Type::INVALID, NULL, FRAME, NULL, NULL }; const GncGUID* guid; QofInstance* inst; diff --git a/src/backend/xml/sixtp-dom-generators.cpp b/src/backend/xml/sixtp-dom-generators.cpp index 11ef34ae27..b0086c1ec5 100644 --- a/src/backend/xml/sixtp-dom-generators.cpp +++ b/src/backend/xml/sixtp-dom-generators.cpp @@ -260,7 +260,7 @@ add_kvp_value_node(xmlNodePtr node, const gchar *tag, KvpValue* val) switch (val->get_type()) { - case KVP_TYPE_STRING: + case KvpValue::Type::STRING: { auto newstr = g_strdup(val->get()); val_node = xmlNewTextChild(node, NULL, BAD_CAST tag, @@ -268,10 +268,10 @@ add_kvp_value_node(xmlNodePtr node, const gchar *tag, KvpValue* val) g_free (newstr); break; } - case KVP_TYPE_TIMESPEC: + case KvpValue::Type::TIMESPEC: val_node = NULL; break; - case KVP_TYPE_GDATE: + case KvpValue::Type::GDATE: { auto d = val->get(); val_node = gdate_to_dom_tree(tag, &d); @@ -285,30 +285,30 @@ add_kvp_value_node(xmlNodePtr node, const gchar *tag, KvpValue* val) switch (val->get_type()) { - case KVP_TYPE_GINT64: + case KvpValue::Type::INT64: add_text_to_node(val_node, "integer", g_strdup_printf("%" G_GINT64_FORMAT, val->get())); break; - case KVP_TYPE_DOUBLE: + case KvpValue::Type::DOUBLE: add_text_to_node(val_node, "double", double_to_string(val->get())); break; - case KVP_TYPE_NUMERIC: + case KvpValue::Type::NUMERIC: add_text_to_node(val_node, "numeric", gnc_numeric_to_string(val->get())); break; - case KVP_TYPE_STRING: + case KvpValue::Type::STRING: xmlSetProp(val_node, BAD_CAST "type", BAD_CAST "string"); break; - case KVP_TYPE_GUID: + case KvpValue::Type::GUID: { gchar guidstr[GUID_ENCODING_LENGTH+1]; guid_to_string_buff(val->get(), guidstr); add_text_to_node(val_node, "guid", guidstr); break; } - case KVP_TYPE_TIMESPEC: + case KvpValue::Type::TIMESPEC: { auto ts = val->get(); val_node = timespec_to_dom_tree (tag, &ts); @@ -316,10 +316,10 @@ add_kvp_value_node(xmlNodePtr node, const gchar *tag, KvpValue* val) xmlAddChild (node, val_node); break; } - case KVP_TYPE_GDATE: + case KvpValue::Type::GDATE: xmlSetProp(val_node, BAD_CAST "type", BAD_CAST "gdate"); break; - case KVP_TYPE_GLIST: + case KvpValue::Type::GLIST: xmlSetProp(val_node, BAD_CAST "type", BAD_CAST "list"); for (auto cursor = val->get(); cursor; cursor = cursor->next) { @@ -327,7 +327,7 @@ add_kvp_value_node(xmlNodePtr node, const gchar *tag, KvpValue* val) add_kvp_value_node(val_node, "slot:value", val); } break; - case KVP_TYPE_FRAME: + case KvpValue::Type::FRAME: { xmlSetProp(val_node, BAD_CAST "type", BAD_CAST "frame"); diff --git a/src/backend/xml/test/test-kvp-frames.cpp b/src/backend/xml/test/test-kvp-frames.cpp index 7c13ca8d0c..5fd4c8f5e7 100644 --- a/src/backend/xml/test/test-kvp-frames.cpp +++ b/src/backend/xml/test/test-kvp-frames.cpp @@ -110,7 +110,7 @@ test_kvp_frames1(void) for (i = 0; i < 20; i++) { - auto test_val1 = get_random_kvp_value(i % KVP_TYPE_FRAME); + auto test_val1 = get_random_kvp_value(i % KvpValue::Type::FRAME); auto test_frame1 = new KvpFrame; auto test_key = get_random_string_without("/"); diff --git a/src/engine/kvp-scm.cpp b/src/engine/kvp-scm.cpp index 49e1174229..ca92cdcc4a 100644 --- a/src/engine/kvp-scm.cpp +++ b/src/engine/kvp-scm.cpp @@ -72,45 +72,47 @@ gnc_scm_to_kvp_value_ptr(SCM val) SCM gnc_kvp_value_ptr_to_scm(KvpValue* val) { - switch (kvp_value_get_type(val)) + if (val == nullptr) return SCM_BOOL_F; + + switch (val->get_type()) { - case KVP_TYPE_GINT64: + case KvpValue::Type::INT64: return scm_from_int64(val->get()); break; - case KVP_TYPE_DOUBLE: + case KvpValue::Type::DOUBLE: return scm_from_double (val->get()); break; - case KVP_TYPE_NUMERIC: + case KvpValue::Type::NUMERIC: return gnc_numeric_to_scm(val->get()); break; - case KVP_TYPE_STRING: + case KvpValue::Type::STRING: { auto string = val->get(); return string ? scm_from_utf8_string(string) : SCM_BOOL_F; break; } - case KVP_TYPE_GUID: + case KvpValue::Type::GUID: { - auto tempguid = kvp_value_get_guid(val); + auto tempguid = val->get(); return gnc_guid2scm(*tempguid); } break; - case KVP_TYPE_TIMESPEC: + case KvpValue::Type::TIMESPEC: return gnc_timespec2timepair(val->get()); break; - case KVP_TYPE_FRAME: + case KvpValue::Type::FRAME: { auto frame = val->get(); if (frame != nullptr) return SWIG_NewPointerObj(frame, SWIG_TypeQuery("_p_KvpFrame"), 0); } break; - case KVP_TYPE_GDATE: + case KvpValue::Type::GDATE: return gnc_timespec2timepair(gdate_to_timespec(val->get())); /* FIXME: handle types below */ - case KVP_TYPE_GLIST: + case KvpValue::Type::GLIST: default: break; } diff --git a/src/engine/test-core/test-engine-stuff.cpp b/src/engine/test-core/test-engine-stuff.cpp index 6955f7b808..3cae5df972 100644 --- a/src/engine/test-core/test-engine-stuff.cpp +++ b/src/engine/test-core/test-engine-stuff.cpp @@ -105,8 +105,8 @@ set_max_kvp_frame_elements (gint max_kvp_frame_elements) kvp_frame_max_elements = MAX (max_kvp_frame_elements, 1); } -void -kvp_exclude_type (KvpValueType kvp_type) +static void +kvp_exclude_type (KvpValue::Type kvp_type) { gint *key; @@ -120,7 +120,7 @@ kvp_exclude_type (KvpValueType kvp_type) } static gboolean -kvp_type_excluded (KvpValueType kvp_type) +kvp_type_excluded (KvpValue::Type kvp_type) { gint key = kvp_type; @@ -238,25 +238,25 @@ static KvpFrame* get_random_kvp_frame_depth (gint depth); static KvpValue* get_random_kvp_value_depth (int type, gint depth) { - KvpValueType datype; + KvpValue::Type datype; KvpValue *ret; if (type == -1) { - datype = static_cast(get_random_int_in_range(KVP_TYPE_GINT64, KVP_TYPE_FRAME)); + datype = static_cast(get_random_int_in_range(KvpValue::Type::INT64, KvpValue::Type::FRAME)); } else if (type == -2) { - datype = static_cast(get_random_int_in_range(KVP_TYPE_GINT64, KVP_TYPE_FRAME - 1)); + datype = static_cast(get_random_int_in_range(KvpValue::Type::INT64, KvpValue::Type::FRAME - 1)); } else - datype = static_cast(type); - - if (datype == KVP_TYPE_FRAME && depth >= kvp_max_depth) + datype = static_cast(type); + + if (datype == KvpValue::Type::FRAME && depth >= kvp_max_depth) return NULL; - if (datype == KVP_TYPE_GLIST && depth >= kvp_max_depth) + if (datype == KvpValue::Type::GLIST && depth >= kvp_max_depth) return NULL; if (kvp_type_excluded (datype)) @@ -264,57 +264,50 @@ get_random_kvp_value_depth (int type, gint depth) switch (datype) { - case KVP_TYPE_GINT64: - ret = kvp_value_new_gint64(get_random_gint64()); + case KvpValue::Type::INT64: + ret = new KvpValue(get_random_gint64()); break; - case KVP_TYPE_DOUBLE: + case KvpValue::Type::DOUBLE: ret = NULL; break; - case KVP_TYPE_NUMERIC: - ret = kvp_value_new_gnc_numeric(get_random_gnc_numeric(GNC_DENOM_AUTO)); + case KvpValue::Type::NUMERIC: + ret = new KvpValue(get_random_gnc_numeric(GNC_DENOM_AUTO)); break; - case KVP_TYPE_STRING: + case KvpValue::Type::STRING: { gchar *tmp_str; tmp_str = get_random_string(); if (!tmp_str) return NULL; - ret = kvp_value_new_string(tmp_str); - g_free(tmp_str); + ret = new KvpValue(tmp_str); } break; - case KVP_TYPE_GUID: + case KvpValue::Type::GUID: { - GncGUID *tmp_guid; - tmp_guid = get_random_guid(); - ret = kvp_value_new_guid(tmp_guid); - g_free(tmp_guid); + return new KvpValue(get_random_guid()); } break; - case KVP_TYPE_TIMESPEC: + case KvpValue::Type::TIMESPEC: { Timespec *ts = get_random_timespec(); - ret = kvp_value_new_timespec (*ts); + ret = new KvpValue(*ts); g_free(ts); } break; - case KVP_TYPE_GLIST: - ret = kvp_value_new_glist_nc(get_random_glist_depth (depth + 1)); + case KvpValue::Type::GLIST: + ret = new KvpValue(get_random_glist_depth (depth + 1)); break; - case KVP_TYPE_FRAME: + case KvpValue::Type::FRAME: { - KvpFrame *tmp_frame; - tmp_frame = get_random_kvp_frame_depth(depth + 1); - ret = kvp_value_new_frame(tmp_frame); - kvp_frame_delete(tmp_frame); + return new KvpValue(get_random_kvp_frame_depth(depth + 1)); } break; @@ -328,14 +321,13 @@ get_random_kvp_value_depth (int type, gint depth) static KvpFrame* get_random_kvp_frame_depth (gint depth) { - KvpFrame *ret; int vals_to_add; gboolean val_added; if (depth >= kvp_max_depth) return NULL; - ret = kvp_frame_new(); + auto ret = new KvpFrame; vals_to_add = get_random_int_in_range(1, kvp_frame_max_elements); val_added = FALSE; @@ -367,7 +359,7 @@ get_random_kvp_frame_depth (gint depth) val_added = TRUE; - kvp_frame_set_slot_nc(ret, key, val); + ret->set_path(key, val); g_free(key); } diff --git a/src/engine/test-core/test-engine-stuff.h b/src/engine/test-core/test-engine-stuff.h index 73360b460e..f5ab980e45 100644 --- a/src/engine/test-core/test-engine-stuff.h +++ b/src/engine/test-core/test-engine-stuff.h @@ -13,11 +13,12 @@ extern "C" #include #include "qof.h" -#include #include "Query.h" #include "gnc-pricedb.h" #include "SchedXaction.h" +typedef struct KvpValueImpl KvpValue; +typedef struct KvpFrameImpl KvpFrame; Timespec* get_random_timespec(void); void random_timespec_zero_nsec (gboolean zero_nsec); void random_timespec_usec_resolution (gboolean usec_resolution); @@ -36,7 +37,7 @@ KvpFrame* get_random_kvp_frame(void); gnc_numeric get_random_gnc_numeric(int64_t); GncGUID* get_random_guid(void); -void kvp_exclude_type (KvpValueType kvp_type); +//void kvp_exclude_type (KvpValueType kvp_type); void set_max_kvp_depth (gint max_kvp_depth); void set_max_kvp_frame_elements (gint max_kvp_frame_elements); void set_max_account_tree_depth (gint max_tree_depth); diff --git a/src/engine/test/Makefile.am b/src/engine/test/Makefile.am index 7366d7561a..545a5efce3 100644 --- a/src/engine/test/Makefile.am +++ b/src/engine/test/Makefile.am @@ -23,6 +23,8 @@ LDADD = \ ${top_builddir}/src/core-utils/libgnc-core-utils.la \ ${GLIB_LIBS} +test_guid_SOURCES = test-guid.cpp + # these tests are ordered kind more or less in the order # that they should be executed, with more basic tests coming first. # @@ -73,6 +75,7 @@ TESTS_ENVIRONMENT = \ $(shell ${abs_top_srcdir}/src/gnc-test-env.pl --noexports ${GNC_TEST_DEPS}) check_PROGRAMS = ${TEST_GROUP_1} ${TEST_GROUP_2} +AM_DEFAULT_SOURCE_EXT = .cpp TESTS = ${TEST_GROUP_1} test-create-account ${TEST_GROUP_2} diff --git a/src/engine/test/test-guid.c b/src/engine/test/test-guid.cpp similarity index 91% rename from src/engine/test/test-guid.c rename to src/engine/test/test-guid.cpp index fdb2408eb3..923e59da89 100644 --- a/src/engine/test/test-guid.c +++ b/src/engine/test/test-guid.cpp @@ -25,7 +25,8 @@ * Try to create duplicate GncGUID's, which should never happen. * */ - +extern "C" +{ #include "config.h" #include #include @@ -33,7 +34,7 @@ #include "test-stuff.h" #include "test-engine-stuff.h" #include "qof.h" - +} #define NENT 50123 static void test_null_guid(void) @@ -70,9 +71,10 @@ run_test (void) for (i = 0; i < NENT; i++) { - ent = g_object_new(QOF_TYPE_INSTANCE, NULL); + ent = static_cast(g_object_new(QOF_TYPE_INSTANCE, NULL)); guid_replace(&guid); - ent = g_object_new(QOF_TYPE_INSTANCE, "guid", &guid, NULL); + ent = static_cast(g_object_new(QOF_TYPE_INSTANCE, + "guid", &guid, NULL)); do_test ((NULL == qof_collection_lookup_entity (col, &guid)), "duplicate guid"); ent->e_type = type; diff --git a/src/libqof/qof/gnc-aqbanking-templates.cpp b/src/libqof/qof/gnc-aqbanking-templates.cpp index 21bd05760a..6c5c526d75 100644 --- a/src/libqof/qof/gnc-aqbanking-templates.cpp +++ b/src/libqof/qof/gnc-aqbanking-templates.cpp @@ -105,7 +105,7 @@ private: KvpFrame* _GncABTransTempl::make_kvp_frame() { - auto frame = kvp_frame_new(); + auto frame = new KvpFrame; frame->set(TT_NAME, new KvpValue(m_name.c_str())); frame->set(TT_RNAME, new KvpValue(m_recipient_name.c_str())); frame->set(TT_RACC, new KvpValue(m_recipient_account.c_str())); diff --git a/src/libqof/qof/kvp-value.cpp b/src/libqof/qof/kvp-value.cpp index ce79dfc310..bd07419811 100644 --- a/src/libqof/qof/kvp-value.cpp +++ b/src/libqof/qof/kvp-value.cpp @@ -71,29 +71,29 @@ KvpValueImpl::add(KvpValueImpl * val) noexcept return new KvpValueImpl(list); } -KvpValueType +KvpValue::Type KvpValueImpl::get_type() const noexcept { if (datastore.type() == typeid(int64_t)) - return KvpValueType::KVP_TYPE_GINT64; + return KvpValue::Type::INT64; else if (datastore.type() == typeid(double)) - return KvpValueType::KVP_TYPE_DOUBLE; + return KvpValue::Type::DOUBLE; else if (datastore.type() == typeid(gnc_numeric)) - return KvpValueType::KVP_TYPE_NUMERIC; + return KvpValue::Type::NUMERIC; else if (datastore.type() == typeid(const gchar *)) - return KvpValueType::KVP_TYPE_STRING; + return KvpValue::Type::STRING; else if (datastore.type() == typeid(GncGUID *)) - return KvpValueType::KVP_TYPE_GUID; + return KvpValue::Type::GUID; else if (datastore.type() == typeid(Timespec)) - return KvpValueType::KVP_TYPE_TIMESPEC; + return KvpValue::Type::TIMESPEC; else if (datastore.type() == typeid(GList *)) - return KvpValueType::KVP_TYPE_GLIST; + return KvpValue::Type::GLIST; else if (datastore.type() == typeid(KvpFrameImpl *)) - return KvpValueType::KVP_TYPE_FRAME; + return KvpValue::Type::FRAME; else if (datastore.type() == typeid(GDate)) - return KvpValueType::KVP_TYPE_GDATE; + return KvpValue::Type::GDATE; - return KVP_TYPE_INVALID; + return KvpValue::Type::INVALID; } KvpFrame * @@ -129,14 +129,7 @@ struct to_string_visitor : boost::static_visitor void operator()(KvpFrame * val) { - auto tmp1 = kvp_frame_to_string(val); - output << "KVP_VALUE_FRAME("; - if (tmp1) - { - output << tmp1; - g_free(tmp1); - } - output << ")"; + output << "KVP_VALUE_FRAME(" << val->to_string() << ")"; } void operator()(GDate val) @@ -224,6 +217,55 @@ KvpValueImpl::to_string() const noexcept return g_strdup(ret.str().c_str()); } +static int +kvp_glist_compare(const GList * list1, const GList * list2) +{ + const GList *lp1; + const GList *lp2; + + if (list1 == list2) return 0; + + /* Nothing is always less than something */ + if (!list1 && list2) return -1; + if (list1 && !list2) return 1; + + lp1 = list1; + lp2 = list2; + while (lp1 && lp2) + { + KvpValue *v1 = (KvpValue *) lp1->data; + KvpValue *v2 = (KvpValue *) lp2->data; + gint vcmp = compare(v1, v2); + if (vcmp != 0) return vcmp; + lp1 = lp1->next; + lp2 = lp2->next; + } + if (!lp1 && lp2) return -1; + if (!lp2 && lp1) return 1; + return 0; +} + +static GList * +kvp_glist_copy(const GList * list) +{ + GList * retval = NULL; + GList * lptr; + + if (!list) return retval; + + /* Duplicate the backbone of the list (this duplicates the POINTERS + * to the values; we need to deep-copy the values separately) */ + retval = g_list_copy((GList *) list); + + /* This step deep-copies the values */ + for (lptr = retval; lptr; lptr = lptr->next) + { + lptr->data = new KvpValue(*static_cast(lptr->data)); + } + + return retval; +} + struct compare_visitor : boost::static_visitor { template @@ -269,7 +311,7 @@ template <> int compare_visitor::operator()(GList * const & one, GList * const & } template <> int compare_visitor::operator()(KvpFrame * const & one, KvpFrame * const & two) const { - return kvp_frame_compare(one, two); + return compare(one, two); } template <> int compare_visitor::operator()(double const & one, double const & two) const { @@ -307,10 +349,16 @@ struct delete_visitor : boost::static_visitor operator()(T &) { /*do nothing*/ } }; +static void +destroy_value(void* item) +{ + delete static_cast(item); +} + template <> void delete_visitor::operator()(GList * & value) { - kvp_glist_delete(value); + g_list_free_full(value, destroy_value); } template <> void delete_visitor::operator()(gchar * & value) @@ -344,7 +392,8 @@ KvpValueImpl::duplicate(const KvpValueImpl& other) noexcept else if (other.datastore.type() == typeid(GList*)) this->datastore = kvp_glist_copy(other.get()); else if (other.datastore.type() == typeid(KvpFrame*)) - this->datastore = kvp_frame_copy(other.get()); + this->datastore = new KvpFrame(*other.get()); else this->datastore = other.datastore; } + diff --git a/src/libqof/qof/kvp-value.hpp b/src/libqof/qof/kvp-value.hpp index c7a96e1f42..3b53167c54 100644 --- a/src/libqof/qof/kvp-value.hpp +++ b/src/libqof/qof/kvp-value.hpp @@ -34,11 +34,27 @@ extern "C" #include #endif #include -#include "kvp_frame.h" +//Must be a struct because it's exposed to C so that it can in turn be +//translated to/from Scheme. struct KvpValueImpl { public: + enum Type + { + INVALID = -1, + INT64 = 1, /**< QOF_TYPE_INT64 gint64 */ + DOUBLE, /**< QOF_TYPE_DOUBLE gdouble */ + NUMERIC, /**< QOF_TYPE_NUMERIC */ + STRING, /**< QOF_TYPE_STRING gchar* */ + GUID, /**< QOF_TYPE_GUID */ + TIMESPEC, /**< QOF_TYPE_DATE */ + PLACEHOLDER_DONT_USE, /* Replaces KVP_TYPE_BINARY */ + GLIST, /**< no QOF equivalent. */ + FRAME, /**< no QOF equivalent. */ + GDATE, /**< no QOF equivalent. */ + }; + /** * Performs a deep copy */ @@ -90,7 +106,7 @@ struct KvpValueImpl */ KvpValueImpl * add (KvpValueImpl *) noexcept; - KvpValueType get_type() const noexcept; + KvpValueImpl::Type get_type() const noexcept; char * to_string() const noexcept; @@ -137,5 +153,7 @@ KvpValueImpl::set(T val) noexcept { this->datastore = val; } +extern "C" GType gnc_value_list_get_type (void); +#define GNC_TYPE_VALUE_LIST (gnc_value_list_get_type ()) #endif diff --git a/src/libqof/qof/kvp_frame.cpp b/src/libqof/qof/kvp_frame.cpp index 475ae5a891..8a8cdafef5 100644 --- a/src/libqof/qof/kvp_frame.cpp +++ b/src/libqof/qof/kvp_frame.cpp @@ -30,6 +30,7 @@ extern "C" #include #include #include +#include "kvp_frame.h" } #include "kvp-value.hpp" @@ -39,6 +40,9 @@ extern "C" #include #include +/* This static indicates the debugging module that this .o belongs to. */ +static QofLogModule log_module = "qof.kvp"; + static const char delim = '/'; KvpFrameImpl::KvpFrameImpl(const KvpFrameImpl & rhs) noexcept @@ -99,7 +103,7 @@ walk_path_or_nullptr(const KvpFrameImpl* frame, Path& path) for(auto key:path) { auto slot = cur_frame->get_slot(key.c_str()); - if (slot == nullptr || slot->get_type() != KVP_TYPE_FRAME) + if (slot == nullptr || slot->get_type() != KvpValue::Type::FRAME) return nullptr; cur_frame = slot->get(); } @@ -130,7 +134,7 @@ walk_path_and_create(KvpFrameImpl* frame, Path path) continue; } auto slot = frame->get_slot(key.c_str()); - if (slot == nullptr || slot->get_type() != KVP_TYPE_FRAME) + if (slot == nullptr || slot->get_type() != KvpValue::Type::FRAME) { auto new_frame = new KvpFrame; delete frame->set(key.c_str(), new KvpValue{new_frame}); @@ -271,9 +275,6 @@ int compare(const KvpFrameImpl & one, const KvpFrameImpl & two) noexcept return 0; } -/* This static indicates the debugging module that this .o belongs to. */ -static QofLogModule log_module = QOF_MOD_KVP; - KvpFrame * kvp_frame_new(void) { @@ -940,78 +941,9 @@ kvp_frame_get_slot_path_gslist (KvpFrame *frame, return NULL; } -/* ******************************************************************* - * kvp glist functions - ********************************************************************/ - -void -kvp_glist_delete(GList * list) -{ - GList *node; - if (!list) return; - - /* Delete the data in the list */ - for (node = list; node; node = node->next) - { - KvpValue *val = static_cast(node->data); - kvp_value_delete(val); - } - - /* Free the backbone */ - g_list_free(list); -} - -GList * -kvp_glist_copy(const GList * list) -{ - GList * retval = NULL; - GList * lptr; - - if (!list) return retval; - - /* Duplicate the backbone of the list (this duplicates the POINTERS - * to the values; we need to deep-copy the values separately) */ - retval = g_list_copy((GList *) list); - - /* This step deep-copies the values */ - for (lptr = retval; lptr; lptr = lptr->next) - { - lptr->data = kvp_value_copy(static_cast(lptr->data)); - } - - return retval; -} - -gint -kvp_glist_compare(const GList * list1, const GList * list2) -{ - const GList *lp1; - const GList *lp2; - - if (list1 == list2) return 0; - - /* Nothing is always less than something */ - if (!list1 && list2) return -1; - if (list1 && !list2) return 1; - - lp1 = list1; - lp2 = list2; - while (lp1 && lp2) - { - KvpValue *v1 = (KvpValue *) lp1->data; - KvpValue *v2 = (KvpValue *) lp2->data; - gint vcmp = kvp_value_compare(v1, v2); - if (vcmp != 0) return vcmp; - lp1 = lp1->next; - lp2 = lp2->next; - } - if (!lp1 && lp2) return -1; - if (!lp2 && lp1) return 1; - return 0; -} /* ******************************************************************* - * KvpValue functions + * Kvpvalue functions ********************************************************************/ KvpValue * @@ -1069,7 +1001,7 @@ KvpValue * kvp_value_new_glist(const GList * value) { if (!value) return {}; - return new KvpValueImpl{kvp_glist_copy(value)}; + return nullptr; } KvpValue * @@ -1101,14 +1033,6 @@ kvp_value_delete(KvpValue * value) delete realvalue; } -KvpValueType -kvp_value_get_type(const KvpValue * oldval) -{ - if (!oldval) return KVP_TYPE_INVALID; - const KvpValueImpl * value {static_cast(oldval)}; - return value->get_type(); -} - int64_t kvp_value_get_gint64(const KvpValue * ovalue) { @@ -1318,44 +1242,40 @@ gvalue_from_kvp_value (const KvpValue *kval) if (kval == NULL) return NULL; val = g_slice_new0 (GValue); - switch (kvp_value_get_type(kval)) + switch (kval->get_type()) { - case KVP_TYPE_GINT64: + case KvpValue::Type::INT64: g_value_init (val, G_TYPE_INT64); g_value_set_int64 (val, kvp_value_get_gint64 (kval)); break; - case KVP_TYPE_DOUBLE: + case KvpValue::Type::DOUBLE: g_value_init (val, G_TYPE_DOUBLE); g_value_set_double (val, kvp_value_get_double (kval)); break; - case KVP_TYPE_BOOLEAN: - g_value_init (val, G_TYPE_BOOLEAN); - g_value_set_boolean (val, kvp_value_get_boolean (kval)); - break; - case KVP_TYPE_NUMERIC: + case KvpValue::Type::NUMERIC: g_value_init (val, GNC_TYPE_NUMERIC); num = kvp_value_get_numeric (kval); g_value_set_boxed (val, &num); break; - case KVP_TYPE_STRING: + case KvpValue::Type::STRING: g_value_init (val, G_TYPE_STRING); g_value_set_string (val, kvp_value_get_string (kval)); break; - case KVP_TYPE_GUID: + case KvpValue::Type::GUID: g_value_init (val, GNC_TYPE_GUID); g_value_set_boxed (val, kvp_value_get_guid (kval)); break; - case KVP_TYPE_TIMESPEC: + case KvpValue::Type::TIMESPEC: g_value_init (val, GNC_TYPE_TIMESPEC); tm = kvp_value_get_timespec (kval); g_value_set_boxed (val, &tm); break; - case KVP_TYPE_GDATE: + case KvpValue::Type::GDATE: g_value_init (val, G_TYPE_DATE); gdate = kvp_value_get_gdate (kval); g_value_set_boxed (val, &gdate); break; - case KVP_TYPE_GLIST: + case KvpValue::Type::GLIST: { GList *gvalue_list = NULL; GList *kvp_list = kvp_value_get_glist (kval); @@ -1366,7 +1286,7 @@ gvalue_from_kvp_value (const KvpValue *kval) break; } /* No transfer of KVP frames outside of QofInstance-derived classes! */ - case KVP_TYPE_FRAME: + case KvpValue::Type::FRAME: PWARN ("Error! Attempt to transfer KvpFrame!"); default: PWARN ("Error! Invalid KVP Transfer Request!"); diff --git a/src/libqof/qof/kvp_frame.h b/src/libqof/qof/kvp_frame.h index 190aa94a60..3b02e6701e 100644 --- a/src/libqof/qof/kvp_frame.h +++ b/src/libqof/qof/kvp_frame.h @@ -22,7 +22,7 @@ * A KvpFrame is a set of associations between character strings * (keys) and KvpValue structures. A KvpValue is a union with - * possible types enumerated in the KvpValueType enum, and includes, + * possible types enumerated in the KvpValue::Type enum, and includes, * among other things, ints, doubles, strings, guid's, lists, time * and numeric values. KvpValues may also be other frames, so * KVP is inherently hierarchical. @@ -75,44 +75,8 @@ extern "C" /** Opaque frame structure */ typedef struct KvpFrameImpl KvpFrame; -/** A KvpValue is a union with possible types enumerated in the - * KvpValueType enum. */ typedef struct KvpValueImpl KvpValue; -/** \brief possible types in the union KvpValue - * \todo : People have asked for boolean values, - * e.g. in xaccAccountSetAutoInterestXfer - * - * \todo In the long run, this should be synchronized with the - * core QOF types, which in turn should be synced to the g_types - * in GLib. Unfortunately, this requires writing a pile of code - * to handle all of the different cases. - * An alternative might be to make kvp values inherit from the - * core g_types (i.e. add new core g_types) ?? - */ -typedef enum -{ - KVP_TYPE_INVALID = -1, - KVP_TYPE_GINT64 = 1, /**< QOF_TYPE_INT64 gint64 */ - KVP_TYPE_DOUBLE, /**< QOF_TYPE_DOUBLE gdouble */ - KVP_TYPE_NUMERIC, /**< QOF_TYPE_NUMERIC */ - KVP_TYPE_STRING, /**< QOF_TYPE_STRING gchar* */ - KVP_TYPE_GUID, /**< QOF_TYPE_GUID */ - KVP_TYPE_TIMESPEC, /**< QOF_TYPE_DATE */ - KVP_TYPE_PLACEHOLDER_DONT_USE, /* Replaces KVP_TYPE_BINARY */ - KVP_TYPE_GLIST, /**< no QOF equivalent. */ - KVP_TYPE_FRAME, /**< no QOF equivalent. */ - KVP_TYPE_GDATE, /**< no QOF equivalent. */ - KVP_TYPE_BOOLEAN, /**< QOF_TYPE_BOOLEAN gboolean */ -} KvpValueType; - -/** \deprecated Deprecated backwards compat token - -do \b not use these in new code. - */ -/** \deprecated Deprecated backwards compat token */ -#define kvp_value_t KvpValueType - /** @name KvpFrame Constructors @{ */ @@ -420,31 +384,6 @@ gint kvp_frame_compare(const KvpFrame *fa, const KvpFrame *fb); gint double_compare(double v1, double v2); /** @} */ -/** @name KvpValue List Convenience Functions - - You probably shouldn't be using these low-level routines - - kvp_glist_compare() compares GLists of kvp_values (not to - be confused with GLists of something else): it iterates over - the list elements, performing a kvp_value_compare on each. - @{ -*/ -gint kvp_glist_compare(const GList * list1, const GList * list2); - -/** kvp_glist_copy() performs a deep copy of a GList of - * kvp_values (not to be confused with GLists of something - * else): same as mapping kvp_value_copy() over the elements and - * then copying the spine. - */ -GList * kvp_glist_copy(const GList * list); - -/** kvp_glist_delete() performs a deep delete of a GList of - * kvp_values (not to be confused with GLists of something - * else): same as mapping * kvp_value_delete() over the elements - * and then deleting the GList. - */ -void kvp_glist_delete(GList * list); -/** @} */ /** @name KvpValue Constructors @@ -509,9 +448,6 @@ GList * kvp_value_replace_glist_nc(KvpValue *value, GList *newlist); @{ */ -KvpValueType kvp_value_get_type(const KvpValue * value); - - /** Value accessors. Those for GncGUID, GList, KvpFrame and * string are non-copying -- the caller can modify the value * directly. Just don't free it, or you screw up everything. @@ -642,10 +578,7 @@ void kvp_frame_set_gvalue (KvpFrame *frame, const gchar *key, const GValue *valu */ void gnc_gvalue_free (GValue *value); -GType gnc_value_list_get_type (void); -#define GNC_TYPE_VALUE_LIST (gnc_value_list_get_type ()) - -/** @} */ + /** @} */ #ifdef __cplusplus } #endif diff --git a/src/libqof/qof/qofinstance.cpp b/src/libqof/qof/qofinstance.cpp index e04332c0c3..080ab25105 100644 --- a/src/libqof/qof/qofinstance.cpp +++ b/src/libqof/qof/qofinstance.cpp @@ -1134,11 +1134,11 @@ qof_instance_kvp_add_guid (const QofInstance *inst, const char* path, inline static gboolean kvp_match_guid (KvpValue *v, const char *key, const GncGUID *guid) { - if (v->get_type() != KVP_TYPE_FRAME) + if (v->get_type() != KvpValue::Type::FRAME) return FALSE; auto frame = v->get(); auto val = frame->get_slot(key); - if (val == nullptr || val->get_type() != KVP_TYPE_GUID) + if (val == nullptr || val->get_type() != KvpValue::Type::GUID) return FALSE; auto this_guid = val->get(); @@ -1157,10 +1157,10 @@ qof_instance_kvp_has_guid (const QofInstance *inst, const char *path, switch (v->get_type()) { - case KVP_TYPE_FRAME: + case KvpValue::Type::FRAME: return kvp_match_guid (v, key, guid); break; - case KVP_TYPE_GLIST: + case KvpValue::Type::GLIST: { auto list = v->get(); for (auto node = list; node != NULL; node = node->next) @@ -1192,14 +1192,14 @@ qof_instance_kvp_remove_guid (const QofInstance *inst, const char *path, switch (v->get_type()) { - case KVP_TYPE_FRAME: + case KvpValue::Type::FRAME: if (kvp_match_guid (v, key, guid)) { delete inst->kvp_data->set_path({path}, nullptr); delete v; } break; - case KVP_TYPE_GLIST: + case KvpValue::Type::GLIST: { auto list = v->get(); for (auto node = list; node != nullptr; node = node->next) @@ -1236,14 +1236,14 @@ qof_instance_kvp_merge_guids (const QofInstance *target, auto target_val = target->kvp_data->get_slot(path); switch (v->get_type()) { - case KVP_TYPE_FRAME: + case KvpValue::Type::FRAME: if (target_val) target_val->add(v); else target->kvp_data->set_path({path}, v); donor->kvp_data->set(path, nullptr); //Contents moved, Don't delete! break; - case KVP_TYPE_GLIST: + case KvpValue::Type::GLIST: if (target_val) { auto list = target_val->get(); @@ -1305,7 +1305,7 @@ qof_instance_foreach_slot (const QofInstance *inst, const char* path, void* data) { auto slot = inst->kvp_data->get_slot(path); - if (slot == nullptr || slot->get_type() != KVP_TYPE_FRAME) + if (slot == nullptr || slot->get_type() != KvpValue::Type::FRAME) return; auto frame = slot->get(); wrap_param new_data {proc, data}; diff --git a/src/libqof/qof/test/test-kvp-frame.cpp b/src/libqof/qof/test/test-kvp-frame.cpp index 3082474235..4f30dd8f5e 100644 --- a/src/libqof/qof/test/test-kvp-frame.cpp +++ b/src/libqof/qof/test/test-kvp-frame.cpp @@ -144,7 +144,7 @@ TEST_F (KvpFrameTest, GetKeys) assert_contains (keys, k1); auto frameval = t_root.get_slot(k1); - ASSERT_EQ(frameval->get_type(), KVP_TYPE_FRAME); + ASSERT_EQ(frameval->get_type(), KvpValue::Type::FRAME); keys = frameval->get()->get_keys(); assert_contains (keys, k2); assert_contains (keys, k3); @@ -158,7 +158,7 @@ TEST_F (KvpFrameTest, GetLocalSlot) auto k4 = "top/first"; auto frameval = t_root.get_slot("top"); - ASSERT_EQ(frameval->get_type(), KVP_TYPE_FRAME); + ASSERT_EQ(frameval->get_type(), KvpValue::Type::FRAME); auto f1 = frameval->get(); EXPECT_EQ (t_int_val, f1->get_slot(k1)); EXPECT_EQ (t_str_val, f1->get_slot(k2)); diff --git a/src/libqof/qof/test/test-kvp-value.cpp b/src/libqof/qof/test/test-kvp-value.cpp index 537a6a0382..ef8bd93f74 100644 --- a/src/libqof/qof/test/test-kvp-value.cpp +++ b/src/libqof/qof/test/test-kvp-value.cpp @@ -65,7 +65,7 @@ TEST (KvpValueTest, Add) auto v4 = new KvpValueImpl {*v3}; auto new_one = v3->add (v4); EXPECT_NE (new_one, v3); - EXPECT_EQ (new_one->get_type (), KvpValueType::KVP_TYPE_GLIST); + EXPECT_EQ (new_one->get_type (), KvpValue::Type::GLIST); EXPECT_NE (new_one->get (), nullptr); /* also deletes v3 and v4 because they're "in" new_one */ delete new_one; From d3e62f41bed68ed897f8f9492ea3553ad0e77b08 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Tue, 30 Jun 2015 12:04:34 -0700 Subject: [PATCH 50/54] Remove the KVP C API. All access to KVP is now implemented in C++11. --- src/libqof/qof/Makefile.am | 1 - src/libqof/qof/kvp-value.hpp | 20 + src/libqof/qof/kvp_frame.cpp | 1003 ++----------------------------- src/libqof/qof/kvp_frame.h | 586 ------------------ src/libqof/qof/kvp_frame.hpp | 20 + src/libqof/qof/qofinstance.cpp | 1 - src/libqof/qof/test/Makefile.am | 2 +- 7 files changed, 75 insertions(+), 1558 deletions(-) delete mode 100644 src/libqof/qof/kvp_frame.h diff --git a/src/libqof/qof/Makefile.am b/src/libqof/qof/Makefile.am index 7bfc7b0243..8d230778e3 100644 --- a/src/libqof/qof/Makefile.am +++ b/src/libqof/qof/Makefile.am @@ -59,7 +59,6 @@ qofinclude_HEADERS = \ gnc-timezone.hpp \ gnc-datetime.hpp \ guid.h \ - kvp_frame.h \ kvp_frame.hpp \ kvp-value.hpp \ qof.h \ diff --git a/src/libqof/qof/kvp-value.hpp b/src/libqof/qof/kvp-value.hpp index 3b53167c54..350e9ab5f7 100644 --- a/src/libqof/qof/kvp-value.hpp +++ b/src/libqof/qof/kvp-value.hpp @@ -153,6 +153,26 @@ KvpValueImpl::set(T val) noexcept { this->datastore = val; } + +/** Convert a kvp_value into a GValue. Frames aren't converted. + * @param kval: A KvpValue. + * @return GValue*. Must be freed with g_free(). + */ +GValue* gvalue_from_kvp_value (const KvpValue *kval); + +/** Convert a gvalue into a kvpvalue. + * @param gval: A GValue of a type KvpValue can digest. + * @return KvpValue created from the GValue's contents. + */ +KvpValue* kvp_value_from_gvalue (const GValue *gval); + +/** + * \brief Convenience function to release the value in a GValue + * acquired by kvp_frame_get_gvalue and to free the GValue. + * \param value: A GValue* created by kvp_frame_get_gvalue + */ +void gnc_gvalue_free (GValue *value); + extern "C" GType gnc_value_list_get_type (void); #define GNC_TYPE_VALUE_LIST (gnc_value_list_get_type ()) diff --git a/src/libqof/qof/kvp_frame.cpp b/src/libqof/qof/kvp_frame.cpp index 8a8cdafef5..d38eedff51 100644 --- a/src/libqof/qof/kvp_frame.cpp +++ b/src/libqof/qof/kvp_frame.cpp @@ -30,7 +30,6 @@ extern "C" #include #include #include -#include "kvp_frame.h" } #include "kvp-value.hpp" @@ -275,940 +274,6 @@ int compare(const KvpFrameImpl & one, const KvpFrameImpl & two) noexcept return 0; } -KvpFrame * -kvp_frame_new(void) -{ - auto ret = new KvpFrameImpl(); - return static_cast(ret); -} - -void -kvp_frame_delete(KvpFrame * frame) -{ - if (!frame) return; - auto realframe = static_cast(frame); - delete realframe; -} - -const char ** -kvp_frame_get_keys(const KvpFrame * frame) -{ - if (!frame) return nullptr; - auto realframe = static_cast(frame); - const auto & keys = realframe->get_keys(); - const char ** ret = g_new(const char *, keys.size() + 1); - unsigned int spot {0}; - std::for_each(keys.begin(), keys.end(), - [&ret,&spot](const std::string &a) - { - ret[spot++] = g_strdup(a.c_str()); - } - ); - ret[keys.size()] = nullptr; - return ret; -} - -gboolean -kvp_frame_is_empty(const KvpFrame * frame) -{ - return frame->empty(); -} - -KvpFrame * -kvp_frame_copy(const KvpFrame * frame) -{ - auto ret = new KvpFrameImpl(*static_cast(frame)); - return ret; -} - -/* Replace the old value with the new value. Return the old value. - * Passing in a null value into this routine has the effect of - * removing the key from the KVP tree. - */ -static KvpValue * -kvp_frame_replace_slot_nc (KvpFrame* frame, const char* slot, KvpValue* value) -{ - if (!frame) return nullptr; - return frame->set(slot, value); -} - -/* Passing in a null value into this routine has the effect - * of deleting the old value stored at this slot. - */ -static inline void -kvp_frame_set_slot_destructively(KvpFrame* frame, const char* slot, - KvpValue* value) -{ - delete frame->set(slot, value); -} - -/* ============================================================ */ -/* Get the named frame, or create it if it doesn't exist. - * gcc -O3 should inline it. It performs no error checks, - * the caller is responsible of passing good keys and frames. - */ -static inline KvpFrame * -get_or_make (KvpFrame *fr, const char * key) -{ - KvpFrame *next_frame; - KvpValue *value; - - value = kvp_frame_get_slot (fr, key); - if (value) - { - next_frame = kvp_value_get_frame (value); - } - else - { - next_frame = kvp_frame_new (); - kvp_frame_set_slot_nc (fr, key, - kvp_value_new_frame_nc (next_frame)); - } - return next_frame; -} - -/* Get pointer to last frame in path. If the path doesn't exist, - * it is created. The string stored in keypath will be hopelessly - * mangled . - */ -static inline KvpFrame * -kvp_frame_get_frame_slash_trash (KvpFrame *frame, char *key_path) -{ - char *key, *next; - if (!frame || !key_path) return frame; - - key = key_path; - key --; - - while (key) - { - key ++; - while ('/' == *key) - { - key++; - } - if (0x0 == *key) break; /* trailing slash */ - next = strchr (key, '/'); - if (next) *next = 0x0; - - frame = get_or_make (frame, key); - if (!frame) break; /* error - should never happen */ - - key = next; - } - return frame; -} - -/* ============================================================ */ -/* Get pointer to last frame in path, or NULL if the path doesn't - * exist. The string stored in keypath will be hopelessly mangled . - */ -static inline const KvpFrame * -kvp_frame_get_frame_or_null_slash_trash (const KvpFrame *frame, char *key_path) -{ - KvpValue *value; - char *key, *next; - if (!frame || !key_path) return NULL; - - key = key_path; - key --; - - while (key) - { - 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) return NULL; - frame = kvp_value_get_frame (value); - if (!frame) return NULL; - - key = next; - } - return frame; -} - -/* Return pointer to last frame in path, and also store the - * last dangling part of path in 'end_key'. If path doesn't - * exist, it is created. - */ - -static inline KvpFrame * -get_trailer_make (KvpFrame * frame, const char * key_path, char **end_key) -{ - char *last_key; - - if (!frame || !key_path || (0 == key_path[0])) return NULL; - - last_key = strrchr (const_cast(key_path), '/'); - if (NULL == last_key) - { - last_key = (char *) key_path; - } - else if (last_key == key_path) - { - last_key ++; - } - else if (0 == last_key[1]) - { - return NULL; - } - else - { - char *root, *lkey; - root = g_strdup (key_path); - lkey = strrchr (root, '/'); - *lkey = 0; - frame = kvp_frame_get_frame_slash_trash (frame, root); - g_free(root); - - last_key ++; - } - - *end_key = last_key; - return frame; -} - - -/* Return pointer to last frame in path, or NULL if the path - * doesn't exist. Also store the last dangling part of path - * in 'end_key'. - */ - -static inline const KvpFrame * -get_trailer_or_null (const KvpFrame * frame, const char * key_path, char **end_key) -{ - char *last_key; - - if (!frame || !key_path || (0 == key_path[0])) return NULL; - - last_key = strrchr (const_cast(key_path), '/'); - if (NULL == last_key) - { - last_key = (char *) key_path; - } - else if (last_key == key_path) - { - last_key ++; - } - else if (0 == last_key[1]) - { - return NULL; - } - else - { - char *root, *lkey; - root = g_strdup (key_path); - lkey = strrchr (root, '/'); - *lkey = 0; - frame = kvp_frame_get_frame_or_null_slash_trash (frame, root); - g_free(root); - - last_key ++; - } - - *end_key = last_key; - return frame; -} - -void -kvp_frame_set_gint64(KvpFrame * frame, const char * path, gint64 ival) -{ - KvpValue *value; - value = kvp_value_new_gint64 (ival); - frame = kvp_frame_set_value_nc (frame, path, value); - if (!frame) kvp_value_delete (value); -} - -void -kvp_frame_set_double(KvpFrame * frame, const char * path, double dval) -{ - KvpValue *value; - value = kvp_value_new_double (dval); - frame = kvp_frame_set_value_nc (frame, path, value); - if (!frame) kvp_value_delete (value); -} - -void -kvp_frame_set_numeric(KvpFrame * frame, const char * path, gnc_numeric nval) -{ - KvpValue *value; - value = kvp_value_new_gnc_numeric (nval); - frame = kvp_frame_set_value_nc (frame, path, value); - if (!frame) kvp_value_delete (value); -} - -void -kvp_frame_set_string(KvpFrame * frame, const char * path, const char* str) -{ - KvpValue *value; - value = kvp_value_new_string (str); - frame = kvp_frame_set_value_nc (frame, path, value); - if (!frame) kvp_value_delete (value); -} - -void -kvp_frame_set_guid(KvpFrame * frame, const char * path, const GncGUID *guid) -{ - KvpValue *value; - value = kvp_value_new_guid (guid); - frame = kvp_frame_set_value_nc (frame, path, value); - if (!frame) kvp_value_delete (value); -} - -void -kvp_frame_set_timespec(KvpFrame * frame, const char * path, Timespec ts) -{ - KvpValue *value; - value = kvp_value_new_timespec (ts); - frame = kvp_frame_set_value_nc (frame, path, value); - if (!frame) kvp_value_delete (value); -} - -void -kvp_frame_set_frame(KvpFrame * frame, const char * path, KvpFrame *fr) -{ - KvpValue *value; - value = kvp_value_new_frame (fr); - frame = kvp_frame_set_value_nc (frame, path, value); - if (!frame) kvp_value_delete (value); -} - -void -kvp_frame_set_frame_nc(KvpFrame * frame, const char * path, KvpFrame *fr) -{ - KvpValue *value; - value = kvp_value_new_frame_nc (fr); - frame = kvp_frame_set_value_nc (frame, path, value); - if (!frame) kvp_value_delete (value); -} - -/* ============================================================ */ - -KvpFrame * -kvp_frame_set_value_nc (KvpFrame * frame, const char * key_path, - KvpValue * value) -{ - char *last_key; - - frame = get_trailer_make (frame, key_path, &last_key); - if (!frame) return NULL; - kvp_frame_set_slot_destructively(frame, last_key, value); - return frame; -} - -KvpFrame * -kvp_frame_set_value (KvpFrame * frame, const char * key_path, - const KvpValue * value) -{ - KvpValue *new_value = NULL; - char *last_key; - - frame = get_trailer_make (frame, key_path, &last_key); - if (!frame) return NULL; - - if (value) new_value = kvp_value_copy(value); - kvp_frame_set_slot_destructively(frame, last_key, new_value); - return frame; -} - -KvpValue * -kvp_frame_replace_value_nc (KvpFrame * frame, const char * key_path, - KvpValue * new_value) -{ - KvpValue * old_value; - char *last_key; - - last_key = NULL; - if (new_value) - { - frame = get_trailer_make (frame, key_path, &last_key); - } - else - { - frame = (KvpFrame *) get_trailer_or_null (frame, key_path, &last_key); - } - if (!frame) return NULL; - - old_value = kvp_frame_replace_slot_nc (frame, last_key, new_value); - return old_value; -} - -static KvpFrame * -kvp_frame_add_value_nc(KvpFrame * frame, const char * path, KvpValue *value) -{ - char *key = NULL; - KvpValueImpl * oldvalue; - KvpFrame* orig_frame = frame; - - frame = (KvpFrame *) get_trailer_or_null (frame, path, &key); - oldvalue = static_cast (kvp_frame_get_slot (frame, key)); - auto newvalue = static_cast (value); - - ENTER ("old frame=%s", kvp_frame_to_string(frame)); - if (oldvalue) - { - kvp_frame_replace_slot_nc (frame, key, oldvalue->add (newvalue)); - 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 = orig_frame; - frame = kvp_frame_set_value_nc (frame, path, value); - LEAVE ("new frame=%s", kvp_frame_to_string(frame)); - return frame; -} - -void -kvp_frame_add_frame_nc(KvpFrame * frame, const char * path, KvpFrame *fr) -{ - KvpValue *value; - value = kvp_value_new_frame_nc (fr); - frame = kvp_frame_add_value_nc (frame, path, value); - if (!frame) kvp_value_delete (value); -} - -/* ============================================================ */ - -void -kvp_frame_set_slot(KvpFrame * frame, const char * slot, - KvpValue * value) -{ - KvpValue* new_value{nullptr}; - if (!frame) return; - g_return_if_fail (slot && *slot != '\0'); - - if (value) new_value = kvp_value_copy(value); - delete frame->set(slot, new_value); -} - -void -kvp_frame_set_slot_nc(KvpFrame * frame, const char * slot, - KvpValue * value) -{ - if (!frame) return; - g_return_if_fail (slot && *slot != '\0'); - - frame->set(slot, value); -} - -KvpValue * -kvp_frame_get_slot(const KvpFrame * frame, const char * slot) -{ - if (!frame) return nullptr; - return frame->get_slot(slot); -} - -void -kvp_frame_set_slot_path (KvpFrame *frame, - KvpValue * new_value, - const char *first_key, ...) -{ - va_list ap; - const char *key; - - if (!frame) return; - - g_return_if_fail (first_key && *first_key != '\0'); - - va_start (ap, first_key); - - key = first_key; - - while (TRUE) - { - KvpValue *value; - const char *next_key; - - next_key = va_arg (ap, const char *); - if (!next_key) - { - kvp_frame_set_slot (frame, key, new_value); - break; - } - - g_return_if_fail (*next_key != '\0'); - - value = kvp_frame_get_slot (frame, key); - if (!value) - { - KvpFrame *new_frame = kvp_frame_new (); - KvpValue *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; - } - - frame = kvp_value_get_frame (value); - if (!frame) break; - - key = next_key; - } - - va_end (ap); -} - -void -kvp_frame_set_slot_path_gslist (KvpFrame *frame, - KvpValue * new_value, - GSList *key_path) -{ - if (!frame || !key_path) return; - - while (TRUE) - { - const char *key = static_cast(key_path->data); - KvpValue *value; - - if (!key) - return; - - g_return_if_fail (*key != '\0'); - - key_path = key_path->next; - if (!key_path) - { - kvp_frame_set_slot (frame, key, new_value); - return; - } - - value = kvp_frame_get_slot (frame, key); - if (!value) - { - KvpFrame *new_frame = kvp_frame_new (); - KvpValue *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 = kvp_value_get_frame (value); - if (!frame) - return; - } -} - -gint64 -kvp_frame_get_gint64(const KvpFrame *frame, const char *path) -{ - char *key = NULL; - frame = get_trailer_or_null (frame, path, &key); - return kvp_value_get_gint64(kvp_frame_get_slot (frame, key)); -} -double -kvp_frame_get_double(const KvpFrame *frame, const char *path) -{ - char *key = NULL; - frame = get_trailer_or_null (frame, path, &key); - return kvp_value_get_double(kvp_frame_get_slot (frame, key)); -} - -gnc_numeric -kvp_frame_get_numeric(const KvpFrame *frame, const char *path) -{ - char *key = NULL; - frame = get_trailer_or_null (frame, path, &key); - return kvp_value_get_numeric(kvp_frame_get_slot (frame, key)); -} - -const char * -kvp_frame_get_string(const KvpFrame *frame, const char *path) -{ - char *key = NULL; - frame = get_trailer_or_null (frame, path, &key); - return kvp_value_get_string(kvp_frame_get_slot (frame, key)); -} - -GncGUID * -kvp_frame_get_guid(const KvpFrame *frame, const char *path) -{ - char *key = NULL; - frame = get_trailer_or_null (frame, path, &key); - return kvp_value_get_guid(kvp_frame_get_slot (frame, key)); -} - -Timespec -kvp_frame_get_timespec(const KvpFrame *frame, const char *path) -{ - char *key = NULL; - frame = get_trailer_or_null (frame, path, &key); - return kvp_value_get_timespec(kvp_frame_get_slot (frame, key)); -} - -KvpFrame * -kvp_frame_get_frame(const KvpFrame *frame, const char *path) -{ - char *key = NULL; - frame = get_trailer_or_null (frame, path, &key); - return kvp_value_get_frame(kvp_frame_get_slot (frame, key)); -} - -KvpValue * -kvp_frame_get_value(const KvpFrame *frame, const char *path) -{ - char *key = NULL; - frame = get_trailer_or_null (frame, path, &key); - return kvp_frame_get_slot (frame, key); -} - -/* ============================================================ */ - -KvpFrame * -kvp_frame_get_frame_slash (KvpFrame *frame, const char *key_path) -{ - char *root; - if (!frame || !key_path) return frame; - - root = g_strdup (key_path); - frame = kvp_frame_get_frame_slash_trash (frame, root); - g_free(root); - return frame; -} - -/* ============================================================ */ - -KvpValue * -kvp_frame_get_slot_path (KvpFrame *frame, - const char *first_key, ...) -{ - va_list ap; - KvpValue *value; - const char *key; - - if (!frame || !first_key) return NULL; - - va_start (ap, first_key); - - key = first_key; - value = NULL; - - while (TRUE) - { - value = kvp_frame_get_slot (frame, key); - if (!value) break; - - key = va_arg (ap, const char *); - if (!key) break; - - frame = kvp_value_get_frame (value); - if (!frame) - { - value = NULL; - break; - } - } - - va_end (ap); - - return value; -} - -KvpValue * -kvp_frame_get_slot_path_gslist (KvpFrame *frame, - const GSList *key_path) -{ - if (!frame || !key_path) return NULL; - - while (TRUE) - { - const char *key = static_cast(key_path->data); - KvpValue *value; - - if (!key) break; - - value = kvp_frame_get_slot (frame, key); - if (!value) break; - - key_path = key_path->next; - if (!key_path) return value; - - frame = kvp_value_get_frame (value); - if (!frame) break; - } - return NULL; -} - - -/* ******************************************************************* - * Kvpvalue functions - ********************************************************************/ - -KvpValue * -kvp_value_new_gint64(int64_t value) -{ - return new KvpValueImpl{value}; -} - -KvpValue * -kvp_value_new_double(double value) -{ - return new KvpValueImpl{value}; -} - -KvpValue * -kvp_value_new_boolean(gboolean value) -{ - if (!value) return {}; - return new KvpValueImpl{g_strdup("true")}; -} - -KvpValue * -kvp_value_new_numeric(gnc_numeric value) -{ - return new KvpValueImpl{value}; -} - -KvpValue * -kvp_value_new_string(const char * value) -{ - if (!value) return {}; - return new KvpValueImpl{g_strdup(value)}; -} - -KvpValue * -kvp_value_new_guid(const GncGUID * value) -{ - if (!value) return {}; - return new KvpValueImpl{guid_copy(value)}; -} - -KvpValue * -kvp_value_new_timespec(Timespec value) -{ - return new KvpValueImpl{value}; -} - -KvpValue * -kvp_value_new_gdate(GDate value) -{ - return new KvpValueImpl{value}; -} - -KvpValue * -kvp_value_new_glist(const GList * value) -{ - if (!value) return {}; - return nullptr; -} - -KvpValue * -kvp_value_new_glist_nc(GList * value) -{ - if (!value) return {}; - return new KvpValueImpl{value}; -} - -KvpValue * -kvp_value_new_frame(const KvpFrame * value) -{ - if (!value) return {}; - return new KvpValueImpl{kvp_frame_copy(value)}; -} - -KvpValue * -kvp_value_new_frame_nc(KvpFrame * value) -{ - if (!value) return {}; - return new KvpValueImpl{value}; -} - -void -kvp_value_delete(KvpValue * value) -{ - if (!value) return; - KvpValueImpl * realvalue {static_cast(value)}; - delete realvalue; -} - -int64_t -kvp_value_get_gint64(const KvpValue * ovalue) -{ - if (!ovalue) return {}; - const KvpValueImpl * value {static_cast(ovalue)}; - return value->get(); -} - -double -kvp_value_get_double(const KvpValue * ovalue) -{ - if (!ovalue) return {}; - const KvpValueImpl * value {static_cast(ovalue)}; - return value->get(); -} - -bool -kvp_value_get_boolean (const KvpValue *ovalue) -{ - if (!ovalue) return {}; - const KvpValueImpl *value {static_cast(ovalue)}; - const char* str = value->get(); - return str && strcmp(str, "true") == 0; -} - -gnc_numeric -kvp_value_get_numeric(const KvpValue * ovalue) -{ - //if (!ovalue) return {}; The code depends on no segfault and zero being returned here. - if (!ovalue) return gnc_numeric_zero(); - const KvpValueImpl * value {static_cast(ovalue)}; - return value->get(); -} - -const char * -kvp_value_get_string(const KvpValue * ovalue) -{ - if (!ovalue) return {}; - const KvpValueImpl * value {static_cast(ovalue)}; - return value->get(); -} - -GncGUID * -kvp_value_get_guid(const KvpValue * ovalue) -{ - if (!ovalue) return {}; - const KvpValueImpl * value {static_cast(ovalue)}; - return value->get(); -} - -Timespec -kvp_value_get_timespec(const KvpValue * ovalue) -{ - if (!ovalue) return {}; - const KvpValueImpl * value {static_cast(ovalue)}; - return value->get(); -} - -GDate -kvp_value_get_gdate(const KvpValue * ovalue) -{ - if (!ovalue) return {}; - const KvpValueImpl * value {static_cast(ovalue)}; - return value->get(); -} - -GList * -kvp_value_get_glist(const KvpValue * ovalue) -{ - if (!ovalue) return {}; - const KvpValueImpl * value {static_cast(ovalue)}; - return value->get(); -} - -KvpFrame * -kvp_value_get_frame(const KvpValue * ovalue) -{ - if (!ovalue) return {}; - const KvpValueImpl * value {static_cast(ovalue)}; - return value->get(); -} - -KvpFrame * -kvp_value_replace_frame_nc(KvpValue * ovalue, KvpFrame * newframe) -{ - if (!ovalue) return {}; - KvpValueImpl * value {static_cast(ovalue)}; - return value->replace_frame_nc (newframe); -} - -GList * -kvp_value_replace_glist_nc(KvpValue * ovalue, GList *newlist) -{ - if (!ovalue) return {}; - KvpValueImpl * value {static_cast(ovalue)}; - return value->replace_glist_nc (newlist); -} - -KvpValue * -kvp_value_copy(const KvpValue * ovalue) -{ - if (!ovalue) return {}; - auto value = static_cast(ovalue); - KvpValueImpl * ret = new KvpValueImpl(*value); - return static_cast(ret); -} - -void -kvp_frame_for_each_slot(KvpFrame *f, - void (*proc)(const char *key, - KvpValue *value, - gpointer data), - gpointer data) -{ - if (!f) return; - auto realframe = static_cast(f); - realframe->for_each_slot(proc, data); -} - -int -kvp_value_compare(const KvpValue * okva, const KvpValue * okvb) -{ - auto kva = static_cast(okva); - auto kvb = static_cast(okvb); - return compare(kva, kvb); -} - -gint -kvp_frame_compare(const KvpFrame *fa, const KvpFrame *fb) -{ - auto realone = static_cast(fa); - auto realtwo = static_cast(fb); - return compare(realone, realtwo); -} - -char * -kvp_value_to_string(const KvpValue * val) -{ - if (!val) return g_strdup(""); - auto realval = static_cast(val); - return realval->to_string(); -} - -#ifdef __cplusplus -extern "C" -{ -#endif - -void init_static_test_pointers( void ); - -#ifdef __cplusplus -} -#endif - -KvpFrame* ( *p_get_trailer_make )( KvpFrame *frame, const char *key_path, char **end_key ); -KvpFrame* ( *p_get_or_make )( KvpFrame *fr, const char * key ); -const KvpFrame* ( *p_kvp_frame_get_frame_or_null_slash_trash )( const KvpFrame *frame, char *key_path ); -const KvpFrame* ( *p_get_trailer_or_null )( const KvpFrame * frame, const char * key_path, char **end_key ); - -void -init_static_test_pointers( void ) -{ - p_get_trailer_make = get_trailer_make; - p_get_or_make = get_or_make; - p_kvp_frame_get_frame_or_null_slash_trash = kvp_frame_get_frame_or_null_slash_trash; - p_get_trailer_or_null = get_trailer_or_null; -} - -char* -kvp_frame_to_string(const KvpFrame *frame) -{ - auto realframe = static_cast(frame); - /*We'll use g_strdup - because it will be freed using g_free.*/ - return g_strdup(realframe->to_string().c_str()); -} static void gvalue_list_from_kvp_value (KvpValue *kval, gpointer pList) @@ -1246,40 +311,41 @@ gvalue_from_kvp_value (const KvpValue *kval) { case KvpValue::Type::INT64: g_value_init (val, G_TYPE_INT64); - g_value_set_int64 (val, kvp_value_get_gint64 (kval)); + g_value_set_int64 (val, kval->get()); break; case KvpValue::Type::DOUBLE: g_value_init (val, G_TYPE_DOUBLE); - g_value_set_double (val, kvp_value_get_double (kval)); + g_value_set_double (val, kval->get()); break; case KvpValue::Type::NUMERIC: g_value_init (val, GNC_TYPE_NUMERIC); - num = kvp_value_get_numeric (kval); + num = kval->get(); g_value_set_boxed (val, &num); break; case KvpValue::Type::STRING: g_value_init (val, G_TYPE_STRING); - g_value_set_string (val, kvp_value_get_string (kval)); + g_value_set_string (val, kval->get()); break; case KvpValue::Type::GUID: g_value_init (val, GNC_TYPE_GUID); - g_value_set_boxed (val, kvp_value_get_guid (kval)); + g_value_set_boxed (val, kval->get()); break; case KvpValue::Type::TIMESPEC: g_value_init (val, GNC_TYPE_TIMESPEC); - tm = kvp_value_get_timespec (kval); + tm = kval->get(); g_value_set_boxed (val, &tm); break; case KvpValue::Type::GDATE: g_value_init (val, G_TYPE_DATE); - gdate = kvp_value_get_gdate (kval); + gdate = kval->get(); g_value_set_boxed (val, &gdate); break; case KvpValue::Type::GLIST: { GList *gvalue_list = NULL; - GList *kvp_list = kvp_value_get_glist (kval); - g_list_foreach (kvp_list, (GFunc)gvalue_list_from_kvp_value, &gvalue_list); + GList *kvp_list = kval->get(); + g_list_foreach (kvp_list, (GFunc)gvalue_list_from_kvp_value, + &gvalue_list); g_value_init (val, GNC_TYPE_VALUE_LIST); gvalue_list = g_list_reverse (gvalue_list); g_value_set_boxed (val, gvalue_list); @@ -1308,28 +374,41 @@ kvp_value_from_gvalue (const GValue *gval) g_return_val_if_fail (G_VALUE_TYPE (gval), NULL); if (type == G_TYPE_INT64) - val = kvp_value_new_gint64 (g_value_get_int64 (gval)); + val = new KvpValue(g_value_get_int64 (gval)); else if (type == G_TYPE_DOUBLE) - val = kvp_value_new_double (g_value_get_double (gval)); + val = new KvpValue(g_value_get_double (gval)); else if (type == G_TYPE_BOOLEAN) - val = kvp_value_new_boolean (g_value_get_boolean (gval)); + { + auto bval = g_value_get_boolean(gval); + if (bval) + val = new KvpValue(g_strdup("true")); + } else if (type == GNC_TYPE_NUMERIC) - val = kvp_value_new_numeric (*(gnc_numeric*)g_value_get_boxed (gval)); + val = new KvpValue(*(gnc_numeric*)g_value_get_boxed (gval)); else if (type == G_TYPE_STRING) - val = kvp_value_new_string (g_value_get_string (gval)); + { + auto string = g_value_get_string(gval); + if (string != nullptr) + val = new KvpValue(g_strdup(string)); + } else if (type == GNC_TYPE_GUID) - val = kvp_value_new_guid ((GncGUID*)g_value_get_boxed (gval)); + { + auto boxed = g_value_get_boxed(gval); + if (boxed != nullptr) + val = new KvpValue(guid_copy(static_cast(boxed))); + } else if (type == GNC_TYPE_TIMESPEC) - val = kvp_value_new_timespec (*(Timespec*)g_value_get_boxed (gval)); + val = new KvpValue(*(Timespec*)g_value_get_boxed (gval)); else if (type == G_TYPE_DATE) - val = kvp_value_new_gdate (*(GDate*)g_value_get_boxed (gval)); + val = new KvpValue(*(GDate*)g_value_get_boxed (gval)); else if (type == GNC_TYPE_VALUE_LIST) { GList *gvalue_list = (GList*)g_value_get_boxed (gval); GList *kvp_list = NULL; - g_list_foreach (gvalue_list, (GFunc)kvp_value_list_from_gvalue, &kvp_list); + g_list_foreach (gvalue_list, (GFunc)kvp_value_list_from_gvalue, + &kvp_list); kvp_list = g_list_reverse (kvp_list); - val = kvp_value_new_glist_nc (kvp_list); + val = new KvpValue(kvp_list); // g_list_free_full (gvalue_list, (GDestroyNotify)g_value_unset); // gvalue_list = NULL; } @@ -1339,21 +418,7 @@ kvp_value_from_gvalue (const GValue *gval) return val; } - -GValue* -kvp_frame_get_gvalue (KvpFrame *frame, const gchar *key) -{ - KvpValue *kval = kvp_frame_get_value (frame, key); - GValue *value = gvalue_from_kvp_value (kval); - return value; -} - -void -kvp_frame_set_gvalue (KvpFrame *frame, const gchar *key, const GValue *value) -{ - kvp_frame_set_value_nc (frame, key, kvp_value_from_gvalue (value)); -} - +/* The following are required for using KvpValue GLists as GValues */ static void gnc_gvalue_copy (GValue *src, gpointer uData) { diff --git a/src/libqof/qof/kvp_frame.h b/src/libqof/qof/kvp_frame.h deleted file mode 100644 index 3b02e6701e..0000000000 --- a/src/libqof/qof/kvp_frame.h +++ /dev/null @@ -1,586 +0,0 @@ -/********************************************************************\ - * kvp_frame.h -- Implements a key-value frame system * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of the GNU General Public License as * - * published by the Free Software Foundation; either version 2 of * - * the License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License* - * along with this program; if not, contact: * - * * - * Free Software Foundation Voice: +1-617-542-5942 * - * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 * - * Boston, MA 02110-1301, USA gnu@gnu.org * - * * -\********************************************************************/ -/** @addtogroup KVP - - * A KvpFrame is a set of associations between character strings - * (keys) and KvpValue structures. A KvpValue is a union with - * possible types enumerated in the KvpValue::Type enum, and includes, - * among other things, ints, doubles, strings, guid's, lists, time - * and numeric values. KvpValues may also be other frames, so - * KVP is inherently hierarchical. - * - * Values are stored in a 'slot' associated with a key. - * Pointers passed as arguments into set_slot and get_slot are the - * responsibility of the caller. Pointers returned by get_slot are - * owned by the kvp_frame. Make copies as needed. - * - * A 'path' is a sequence of keys that can be followed to a value. - * Paths may be specified as varargs (variable number of arguments - * to a subrutine, NULL-terminated), as a GSList, or as a standard - * URL-like path name. The later is parsed and treated in the same - * way as file paths would be: / separates keys, /./ is treated as / - * and /../ means backup one level. Repeated slashes are treated - * as one slash. - * - * Note that although, in principle, keys may contain the / and . and - * .. characters, doing so may lead to confusion, and will make - * path-string parsing routines fail. In other words, don't use - * a key such as 'some/key' or 'some/./other/../key' because you - * may get unexpected results. - * - * To set a value into a frame, you will want to use one of the - * kvp_frame_set_xxx() routines. Most of the other routines provide - * only low-level access that you probably shouldn't use. - -@{ -*/ -/** @file kvp_frame.h - @brief A key-value frame system - @author Copyright (C) 2000 Bill Gribble - @author Copyright (C) 2003 Linas Vepstas -*/ - -#ifndef KVP_FRAME_H -#define KVP_FRAME_H - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include "gnc-date.h" -#include "gnc-numeric.h" -#include "guid.h" - -#define QOF_MOD_KVP "qof.kvp" - -/** Opaque frame structure */ -typedef struct KvpFrameImpl KvpFrame; - -typedef struct KvpValueImpl KvpValue; - -/** @name KvpFrame Constructors - @{ -*/ - -/** Return a new empty instance of KvpFrame */ -KvpFrame * kvp_frame_new(void); - -/** Perform a deep (recursive) delete of the frame and any subframes. - - * kvp_frame_delete and kvp_value_delete are deep (recursive) deletes. - * kvp_frame_copy and kvp_value_copy are deep value copies. - */ -void kvp_frame_delete(KvpFrame * frame); - -/** Perform a deep (recursive) value copy, copying the fraame, - * subframes, and the values as well. */ -KvpFrame * kvp_frame_copy(const KvpFrame * frame); - -/** Return TRUE if the KvpFrame is empty */ -gboolean kvp_frame_is_empty(const KvpFrame * frame); - -/** @} */ - -/** @name KvpFrame Basic Value Storing -@{ -*/ - -/** - * Retrieve the keys for the frame. - * - * Returns a null-terminated array of the keys which can be - * used to look up values and determine the pairs in this frame. - * - * The caller should free the array using g_free, but should - * not free the keys. - */ -const char ** kvp_frame_get_keys(const KvpFrame * frame); - -/** store the value of the - * gint64 at the indicated path. If not all frame components of - * the path exist, they are created. - * - */ -void kvp_frame_set_gint64(KvpFrame * frame, const gchar * path, gint64 ival); -/** - * store the value of the - * double at the indicated path. If not all frame components of - * the path exist, they are created. -*/ -void kvp_frame_set_double(KvpFrame * frame, const gchar * path, double dval); - -/** \deprecated - -Use kvp_frame_set_numeric instead of kvp_frame_set_gnc_numeric -*/ -#define kvp_frame_set_gnc_numeric kvp_frame_set_numeric -/** store the value of the - * gnc_numeric at the indicated path. - * If not all frame components of - * the path exist, they are created. - */ -void kvp_frame_set_numeric(KvpFrame * frame, const gchar * path, gnc_numeric nval); -/** store the value of the - * Timespec at the indicated path. - * If not all frame components of - * the path exist, they are created. - */ -void kvp_frame_set_timespec(KvpFrame * frame, const gchar * path, Timespec ts); - -/** \brief Store a copy of the string at the indicated path. - - * If not all frame components of the path - * exist, they are created. If there was another string previously - * stored at that path, the old copy is deleted. - * - * Similarly, the set_guid and set_frame will make copies and - * store those. Old copies, if any, are deleted. - * - * The kvp_frame_set_frame_nc() routine works as above, but does - * *NOT* copy the frame. - */ -void kvp_frame_set_string(KvpFrame * frame, const gchar * path, const gchar* str); -void kvp_frame_set_guid(KvpFrame * frame, const gchar * path, const GncGUID *guid); - -void kvp_frame_set_frame(KvpFrame *frame, const gchar *path, KvpFrame *chld); -void kvp_frame_set_frame_nc(KvpFrame *frame, const gchar *path, KvpFrame *chld); - -/** The kvp_frame_set_value() routine copies the value into the frame, - * at the location 'path'. If the path contains slashes '/', these - * are assumed to represent a sequence of keys. The returned value - * is a pointer to the actual frame into which the value was inserted; - * it is NULL if the frame couldn't be found (and thus the value wasn't - * inserted). The old value at this location, if any, is destroyed. - * - * Pointers passed as arguments into this routine are the responsibility - * of the caller; the pointers are *not* taken over or managed. - */ -KvpFrame * kvp_frame_set_value(KvpFrame * frame, - const gchar * path, const KvpValue * value); -/** - * The kvp_frame_set_value_nc() routine puts the value (without copying - * it) into the frame, putting it at the location 'path'. If the path - * contains slashes '/', these are assumed to represent a sequence of keys. - * The returned value is a pointer to the actual frame into which the value - * was inserted; it is NULL if the frame couldn't be found (and thus the - * value wasn't inserted). The old value at this location, if any, - * is destroyed. - * - * This routine is handy for avoiding excess memory allocations & frees. - * Note that because the KvpValue was grabbed, you can't just delete - * unless you remove the key as well (or unless you replace the value). - */ -KvpFrame * kvp_frame_set_value_nc(KvpFrame * frame, - const gchar * path, KvpValue * value); - -/** The kvp_frame_replace_value_nc() routine places the new value - * at the indicated path. It returns the old value, if any. - * It returns NULL if there was an error, or if there was no - * old value. If the path doesn't exist, it is created, unless - * new_value is NULL. Passing in a NULL new_value has the - * effect of deleting the trailing slot (i.e. the trailing path - * element). - */ -KvpValue * kvp_frame_replace_value_nc (KvpFrame * frame, const gchar * slot, - KvpValue * new_value); -/** @} */ - -/** @name KvpFrame Glist Bag Storing - @{ -*/ - -/** \brief Store the given kvp_frame to the glist bag at the indicated path (non-copying) - - * If not all frame components - * of the path exist, they are created. If there was another - * item previously stored at that path, then the path is converted - * to a bag, and the old value, along with the new value, is added - * to the bag. - * - * This method does *NOT* copy the frame. - */ -void kvp_frame_add_frame_nc(KvpFrame *frame, const gchar *path, KvpFrame *chld); - - -/** @} */ - -/** @name KvpFrame Value Fetching - - Value accessors. These all take a unix-style slash-separated - path as an argument, and return the value stored at that location. - If the object at the end of that path is not of the type that was - asked for, then a NULL or a zero is returned. So, for example, - asking for a string when the path stored an int will return a NULL. - In some future date, this may be changed to a looser type system, - such as perl's automatic re-typing (e.g. an integer value might be - converted to a printed string representing that value). - - If any part of the path does not exist, then NULL or zero will be - returned. - - The values returned for GncGUID, GList, KvpFrame and string - are "non-copying" -- the returned item is the actual item stored. - Do not delete this item unless you take the required care to avoid - possible bad pointer derefrences (i.e. core dumps). Also, be - careful hanging on to those references if you are also storing - at the same path names: the referenced item will be freed during - the store. - - That is, if you get a string value (or guid or frame), - and then store something else at that path, the string that you've - gotten will be freed during the store (internally, by the set_*() - routines), and you will be left hanging onto an invalid pointer. -@{ -*/ - -gint64 kvp_frame_get_gint64(const KvpFrame *frame, const gchar *path); -double kvp_frame_get_double(const KvpFrame *frame, const gchar *path); -gnc_numeric kvp_frame_get_numeric(const KvpFrame *frame, const gchar *path); -const gchar * kvp_frame_get_string(const KvpFrame *frame, const gchar *path); -GncGUID * kvp_frame_get_guid(const KvpFrame *frame, const gchar *path); -Timespec kvp_frame_get_timespec(const KvpFrame *frame, const gchar *path); -KvpValue * kvp_frame_get_value(const KvpFrame *frame, const gchar *path); - -/** Value accessor. Takes a unix-style slash-separated path as an - * argument, and return the KvpFrame stored at that location. If the - * KvpFrame does not exist, then a NULL is returned. - * - * @note The semantics here have changed: In gnucash-1.8, if the - * KvpFrame did not exist, this function automatically created one - * and returned it. However, now this function will return NULL in - * this case and the caller has to create a KvpFrame on his own. The - * old functionality is now implemented by - * kvp_frame_get_frame_path(). This happened on 2003-09-14, revision - * 1.31. FIXME: Is it really a good idea to change the semantics of - * an existing function and move the old semantics to a new - * function??! It would save us a lot of trouble if the new semantics - * would have been available in a new function! - * - * @return The KvpFrame at the specified path, or NULL if it doesn't - * exist. -*/ -/*@ dependent @*/ -KvpFrame* kvp_frame_get_frame(const KvpFrame *frame, const gchar *path); - -KvpFrame* kvp_frame_get_frame_slash (KvpFrame *frame, - const gchar *path); - -/** @} */ -/** @name KvpFrame KvpValue low-level storing routines. - -You probably shouldn't be using these low-level routines - - All of the kvp_frame_set_slot_*() routines set the slot values - "destructively", in that if there was an old value there, that - old value is destroyed (and the memory freed). Thus, one - should not hang on to value pointers, as these will get - trashed if set_slot is called on the corresponding key. - - If you want the old value, use kvp_frame_replace_slot(). - @{ -*/ - -/** The kvp_frame_replace_slot_nc() routine places the new value into - * the indicated frame, for the given key. It returns the old - * value, if any. It returns NULL if the slot doesn't exist, - * if there was some other an error, or if there was no old value. - * Passing in a NULL new_value has the effect of deleting that - * slot. - */ -/* KvpValue * kvp_frame_replace_slot_nc (KvpFrame * frame, const gchar * slot, */ -/* KvpValue * new_value); */ - - -/** The kvp_frame_set_slot() routine copies the value into the frame, - * associating it with a copy of 'key'. Pointers passed as arguments - * into kvp_frame_set_slot are the responsibility of the caller; - * the pointers are *not* taken over or managed. The old value at - * this location, if any, is destroyed. - */ -void kvp_frame_set_slot(KvpFrame * frame, - const gchar * key, KvpValue * value); -/** - * The kvp_frame_set_slot_nc() routine puts the value (without copying - * it) into the frame, associating it with a copy of 'key'. This - * routine is handy for avoiding excess memory allocations & frees. - * Note that because the KvpValue was grabbed, you can't just delete - * unless you remove the key as well (or unless you replace the value). - * The old value at this location, if any, is destroyed. - */ -void kvp_frame_set_slot_nc(KvpFrame * frame, - const gchar * key, KvpValue * value); - -/** The kvp_frame_set_slot_path() routine walks the hierarchy, - * using the key values to pick each branch. When the terminal - * node is reached, the value is copied into it. The old value - * at this location, if any, is destroyed. - */ -void kvp_frame_set_slot_path (KvpFrame *frame, - KvpValue *value, - const gchar *first_key, ...); - -/** The kvp_frame_set_slot_path_gslist() routine walks the hierarchy, - * using the key values to pick each branch. When the terminal node - * is reached, the value is copied into it. The old value at this - * location, if any, is destroyed. - */ -void kvp_frame_set_slot_path_gslist (KvpFrame *frame, - KvpValue *value, - GSList *key_path); - -/** @} */ - -/** @name KvpFrame KvpValue Low-Level Retrieval Routines - - You probably shouldn't be using these low-level routines - - Returns the KvpValue in the given KvpFrame 'frame' that is - associated with 'key'. If there is no key in the frame, NULL - is returned. If the value associated with the key is NULL, - NULL is returned. - - Pointers passed as arguments into get_slot are the responsibility - of the caller. Pointers returned by get_slot are owned by the - kvp_frame. Make copies as needed. - @{ -*/ -KvpValue * kvp_frame_get_slot(const KvpFrame * frame, const gchar * key); - -/** This routine return the value at the end of the - * path, or NULL if any portion of the path doesn't exist. - */ -KvpValue * kvp_frame_get_slot_path (KvpFrame *frame, - const gchar *first_key, ...); - -/** This routine return the value at the end of the - * path, or NULL if any portion of the path doesn't exist. - */ -KvpValue * kvp_frame_get_slot_path_gslist (KvpFrame *frame, - const GSList *key_path); - -/** - * Similar returns as strcmp. - */ -gint kvp_frame_compare(const KvpFrame *fa, const KvpFrame *fb); - -gint double_compare(double v1, double v2); -/** @} */ - - -/** @name KvpValue Constructors - - You probably shouldn't be using these low-level routines - - The following routines are constructors for kvp_value. - Those with pointer arguments copy in the value. - The *_nc() versions do *not* copy in thier values, - but use them directly. - @{ - */ -KvpValue * kvp_value_new_gint64(gint64 value); -KvpValue * kvp_value_new_double(double value); - -/** \deprecated - -Use kvp_value_new_numeric instead of kvp_value_new_gnc_numeric -*/ -#define kvp_value_new_gnc_numeric kvp_value_new_numeric -KvpValue * kvp_value_new_numeric(gnc_numeric value); -KvpValue * kvp_value_new_string(const gchar * value); -KvpValue * kvp_value_new_guid(const GncGUID * guid); -KvpValue * kvp_value_new_timespec(Timespec timespec); -KvpValue * kvp_value_new_frame(const KvpFrame * value); -KvpValue * kvp_value_new_gdate(GDate date); - -/** Creates a KvpValue from a GList of kvp_value's! (Not to be - * confused with GList's of something else!) */ -KvpValue * kvp_value_new_glist(const GList * value); - -/** Creates a KvpValue from a GList of kvp_value's! (Not to be - * confused with GList's of something else!) - * - * This value constructor is non-copying (KvpValue takes pointer - * ownership). The values *must* have been allocated via glib - * allocators! (gnew, etc.) */ -KvpValue * kvp_value_new_glist_nc(GList *lst); - -/** value constructors (non-copying - KvpValue takes pointer ownership) - values *must* have been allocated via glib allocators! (gnew, etc.) */ -KvpValue * kvp_value_new_frame_nc(KvpFrame * value); - -/** This is a deep (recursive) delete. */ -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 */ -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); - -/** @} */ - - -/** @name KvpValue Value access - - You probably shouldn't be using these low-level routines - @{ -*/ - -/** Value accessors. Those for GncGUID, GList, KvpFrame and - * string are non-copying -- the caller can modify the value - * directly. Just don't free it, or you screw up everything. - * Note that if another value is stored at the key location - * that this value came from, then this value will be - * uncermoniously deleted, and you will be left pointing to - * garbage. So don't store values at the same time you are - * examining their contents. - */ - -gint64 kvp_value_get_gint64(const KvpValue * value); -double kvp_value_get_double(const KvpValue * value); -gnc_numeric kvp_value_get_numeric(const KvpValue * value); - -/** Value accessor. This one is non-copying -- the caller can modify - * the value directly. */ -const char* kvp_value_get_string(const KvpValue * value); - -/** Value accessor. This one is non-copying -- the caller can modify - * the value directly. */ -GncGUID * kvp_value_get_guid(const KvpValue * value); - -/** Returns the GList of kvp_frame's (not to be confused with GList's - * of something else!) from the given kvp_frame. This one is - * non-copying -- the caller can modify the value directly. */ -GList * kvp_value_get_glist(const KvpValue * value); - -/** Value accessor. This one is non-copying -- the caller can modify - * the value directly. */ -/*@ dependent @*/ -KvpFrame * kvp_value_get_frame(const KvpValue * value); -Timespec kvp_value_get_timespec(const KvpValue * value); - -/** Value accessor for GDate */ -GDate kvp_value_get_gdate(const KvpValue * value); - -/** - * Similar returns as strcmp. - **/ -gint kvp_value_compare(const KvpValue *va, const KvpValue *vb); - -/** @} */ - -/** \brief Debug version of kvp_value_to_string - -This version is used only by ::qof_query_printValueForParam, -itself a debugging and development utility function. -*/ -gchar* kvp_value_to_string(const KvpValue *val); - -/** @name Iterators -@{ -*/ -/** Traverse all of the slots in the given kvp_frame. This function - does not descend recursively to traverse any kvp_frames stored as - slot values. You must handle that in proc, with a suitable - recursive call if desired. */ -void kvp_frame_for_each_slot(KvpFrame *f, - void (*proc)(const gchar *key, - KvpValue *value, - gpointer data), - gpointer data); - -/** @} */ - -/** Internal helper routines, you probably shouldn't be using these. */ -gchar* kvp_frame_to_string(const KvpFrame *frame); - -/** Convert a kvp_value into a GValue. Frames aren't converted. - * @param kval: A KvpValue. - * @return GValue*. Must be freed with g_free(). - */ -GValue* gvalue_from_kvp_value (const KvpValue *kval); - -/** Convert a gvalue into a kvpvalue. - * @param gval: A GValue of a type KvpValue can digest. - * @return KvpValue created from the GValue's contents. - */ -KvpValue* kvp_value_from_gvalue (const GValue *gval); - -/** KvpItem: GValue Exchange - * \brief Transfer of KVP to and from GValue, with the key - * - * Used to parameterize KVP <-> GValue exchanges. - */ -typedef struct -{ - const gchar *key; - GValue *value; -}KvpItem; - -/** Return a KvpItem containing the value of a KvpFrame - * - * Structure types (gnc_numeric, Timespec) are converted to pointers - * and must be extracted with g_value_get_boxed. A KVP_TYPE_GLIST will - * have all of its contents converted from KvpValues to GValues, so - * the return type will be a GValue containing a GList of GValue*, not - * GValue. Use gnc_value_list_free() to free such a list if you take - * it out of the GValue. - * - * \param frame: (transfer-none) The KvpFrame retrieved with kvp_get_frame_foo() - * \param key: (transfer-none) A slash-delimited string with the path to - * the stored value. Must not be NULL or empty. - * \return (transfer-full) A KvpItem* which must be freed with kvp_item_free(). - */ -GValue *kvp_frame_get_gvalue (KvpFrame *frame, const gchar *key); - -/** Replace or create a Kvp slot from a KvpItem - * - * Structure types (gnc_numeric, Timespec) should be stored as - * boxed-type pointers in the GValue with the appropriate type from - * qof.h. Lists should be stored as a GValue containing a GList of - * GValues of type convertable to KvpValues. Unsupported types will - * emit a warning message and will be skipped. - * - * \param frame: (transfer none) The KvpFrame into which the value - * will be added. - * \param key: (transfer none) The subkey of the frame at which to - * store the value - * \param value: GValue containing the paramter to store. - */ -void kvp_frame_set_gvalue (KvpFrame *frame, const gchar *key, const GValue *value); - -/** - * \brief Convenience function to release the value in a GValue - * acquired by kvp_frame_get_gvalue and to free the GValue. - * \param value: A GValue* created by kvp_frame_get_gvalue - */ -void gnc_gvalue_free (GValue *value); - - /** @} */ -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/libqof/qof/kvp_frame.hpp b/src/libqof/qof/kvp_frame.hpp index 46ec14b3e4..5aae496b53 100644 --- a/src/libqof/qof/kvp_frame.hpp +++ b/src/libqof/qof/kvp_frame.hpp @@ -1,6 +1,7 @@ /********************************************************************\ * kvp-frame.hpp -- Implements a key-value frame system * * Copyright (C) 2014 Aaron Laws * + * Copyright 2015 John Ralls * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * @@ -20,6 +21,25 @@ * Boston, MA 02110-1301, USA gnu@gnu.org * * * \********************************************************************/ +/** @addtogroup KVP + + * A KvpFrame is a set of associations between character strings + * (keys) and KvpValues. A KvpValue is notionally a union with + * possible types enumerated in the KvpValue::Type enum, and includes, + * among other things, ints, doubles, strings, guids, lists, time + * and numeric values. KvpValues may also be other frames, so + * KVP is inherently hierarchical. + * + * Values are stored in a 'slot' associated with a key. + * Pointers passed as arguments into set_slot and get_slot are the + * responsibility of the caller. Pointers returned by get_slot are + * owned by the kvp_frame. Make copies as needed. + * + * A 'path' is a sequence of keys that can be followed to a value. Paths are + * passed as either '/'-delimited strings or as std::vectors of keys. Unlike + * file system paths, the tokens '.' and '..' have no special meaning. + * +*/ #ifndef GNC_KVP_FRAME_TYPE #define GNC_KVP_FRAME_TYPE diff --git a/src/libqof/qof/qofinstance.cpp b/src/libqof/qof/qofinstance.cpp index 080ab25105..ffd8182e4d 100644 --- a/src/libqof/qof/qofinstance.cpp +++ b/src/libqof/qof/qofinstance.cpp @@ -38,7 +38,6 @@ extern "C" #include "qof.h" #include "qofbook-p.h" #include "qofid-p.h" -#include "kvp_frame.h" #include "kvp_frame.hpp" #include "qofinstance-p.h" diff --git a/src/libqof/qof/test/Makefile.am b/src/libqof/qof/test/Makefile.am index e233cc184d..96fe8dea14 100644 --- a/src/libqof/qof/test/Makefile.am +++ b/src/libqof/qof/test/Makefile.am @@ -22,7 +22,7 @@ test_qof_SOURCES = \ test_qof_HEADERS = \ $(top_srcdir)/${MODULEPATH}/qofbook.h \ $(top_srcdir)/${MODULEPATH}/qofinstance.h \ - $(top_srcdir)/${MODULEPATH}/kvp_frame.h \ + $(top_srcdir)/${MODULEPATH}/kvp_frame.hpp \ $(top_srcdir)/${MODULEPATH}/qofobject.h \ $(top_srcdir)/${MODULEPATH}/qofsession.h \ $(top_srcdir)/src/test-core/unittest-support.h From e81b816658f4849937f430fffa6743808d222ca6 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Fri, 3 Jul 2015 16:12:29 -0700 Subject: [PATCH 51/54] Update doxygen config to use C++ files and drop obsolete commands. Also turn on autobrief, STL support, and reduce the tab size to 4. --- src/doc/doxygen.cfg.in | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/src/doc/doxygen.cfg.in b/src/doc/doxygen.cfg.in index 0907011bbb..d00310ba1c 100644 --- a/src/doc/doxygen.cfg.in +++ b/src/doc/doxygen.cfg.in @@ -153,7 +153,7 @@ SHORT_NAMES = NO # comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) -JAVADOC_AUTOBRIEF = NO +JAVADOC_AUTOBRIEF = YES # If the QT_AUTOBRIEF tag is set to YES then Doxygen will # interpret the first line (until the first dot) of a Qt-style @@ -186,7 +186,7 @@ SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. -TAB_SIZE = 8 +TAB_SIZE = 4 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". @@ -266,7 +266,7 @@ AUTOLINK_SUPPORT = YES # func(std::string) {}). This also makes the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. -BUILTIN_STL_SUPPORT = NO +BUILTIN_STL_SUPPORT = YES # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. @@ -675,7 +675,9 @@ FILE_PATTERNS = *.c \ *.h \ *.txt \ *.py \ - *.pl + *.pl \ + *.cpp \ + *.hpp # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. @@ -703,7 +705,7 @@ EXCLUDE_SYMLINKS = YES # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* -EXCLUDE_PATTERNS = +EXCLUDE_PATTERNS = */test/* # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the @@ -1460,18 +1462,6 @@ GENERATE_XML = NO XML_OUTPUT = xml -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_DTD = - # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that From 4623cff38d4619374d749cca51096eb0e3aa55fb Mon Sep 17 00:00:00 2001 From: John Ralls Date: Fri, 3 Jul 2015 16:14:00 -0700 Subject: [PATCH 52/54] Document new KVP API in Doxygen, including relevant bits from src/docs/design. --- src/engine/kvp_doc.txt | 40 +++++++++--------- src/libqof/qof/kvp-value.hpp | 15 +++++-- src/libqof/qof/kvp_frame.hpp | 75 ++++++++++++++++++++++++++-------- src/libqof/qof/qofbook.h | 5 ++- src/libqof/qof/qofinstance-p.h | 28 +++++++++++-- src/libqof/qof/qofinstance.h | 6 --- 6 files changed, 119 insertions(+), 50 deletions(-) diff --git a/src/engine/kvp_doc.txt b/src/engine/kvp_doc.txt index f39f53f0b2..e9f6717c71 100644 --- a/src/engine/kvp_doc.txt +++ b/src/engine/kvp_doc.txt @@ -6,7 +6,7 @@ API: \ref KVP This file documents the use of keys in the key-value pair system used by the GnuCash Application (both the engine, and non-engine, GUI -pieces). Before assigning keys for use, please read the Key-Value +pieces). Before assigning keys for use, please read the Key-Value Policy in the GnuCash Design Document located under src/doc/design. The format of the data below is: @@ -16,7 +16,7 @@ Name: The name of the key, including key names of parent frames filename. Use the '/' character to separate keys. Type: The type of value stored in the key. The types are listed in - 'kvp_frame.h'. + 'kvp-value.hpp'. Entities: Which engine entities (Accounts, Transactions, Splits) can use this key. Use 'All' if every entity could have @@ -24,7 +24,7 @@ Entities: Which engine entities (Accounts, Transactions, Splits) Use: The use to which the key will be put. Include any requirements for using the key here. Also include any API calls which use - the key. If more than one entity can use the key, + the key. If more than one entity can use the key, Example: @@ -44,7 +44,7 @@ Please put the keys in alphabetical order. [ \ref kvpA ] [ \ref kvpB ] [ \ref kvpC ] [ \ref kvpD ] [ \ref kvpE ] [ \ref kvpF ] [ \ref kvpG ] [ \ref kvpH ] [ \ref kvpJ ] [ \ref kvpK ] [ \ref kvpL ]\n -[ \ref kvpM ] [ \ref kvpN ] [ \ref kvpO ] [ \ref kvpP ] [ \ref kvpQ ] +[ \ref kvpM ] [ \ref kvpN ] [ \ref kvpO ] [ \ref kvpP ] [ \ref kvpQ ] [ \ref kvpR ] [ \ref kvpS ] [ \ref kvpT ] [ \ref kvpU ] [ \ref kvpV ] [ \ref kvpW ] \subsection kvpA A @@ -62,7 +62,7 @@ Use: kvp subdirectory holding info relating to accounting periods, including \verbatim Name: /book/accounting-period -Type: string, enum {none, week, month, quarter, trimester, year} +Type: string, enum {none, week, month, quarter, trimester, year} XXX not used, should be UIFreqSpec stuff .. Entities: Book Use: An enumerated identifier indicating how often books are supposed @@ -74,7 +74,7 @@ Use: An enumerated identifier indicating how often books are supposed Name: /book/close-date Type: Timespec Entities: Book -Use: The posted closing date of this book. This book only contains +Use: The posted closing date of this book. This book only contains transactions whose posted date is earlier than this closing date. \endverbatim @@ -82,7 +82,7 @@ Use: The posted closing date of this book. This book only contains Name: /book/closed-acct Type: GUID Entities: Transaction -Use: The GUID of the account for which this transaction represents the +Use: The GUID of the account for which this transaction represents the opening balance. This value will occur *only* in transactions that are opening balances. \endverbatim @@ -91,7 +91,7 @@ Use: The GUID of the account for which this transaction represents the Name: /book/closed-book Type: GUID Entities: Transaction -Use: The GUID of the book for which this transaction represents the +Use: The GUID of the book for which this transaction represents the opening balance. This value will occur *only* in transactions that are opening balances. \endverbatim @@ -173,7 +173,7 @@ Entities: Book Use: Holders for a bunch of counters for various types. Used specifically in the business objects for ID counters. The counter name is the path that follows /counters/, e.g. "/counters/GncCustomer" -\endverbatim +\endverbatim \verbatim Name: /counter_formats/... @@ -224,7 +224,7 @@ Use: GUID of the split that records the capital gains for this split. Name: /gemini/ Type: kvp_glist Entities: Account, Book -Use: kvp bag holding frames that identify accounts or books +Use: kvp bag holding frames that identify accounts or books that are copies of this account. \endverbatim @@ -247,7 +247,7 @@ Use: guid of another account that is a copy of this one. Name: /gemini//book_guid Type: guid Entities: Account, Book -Use: When this appears in an account, then it contains the guid of +Use: When this appears in an account, then it contains the guid of the book that the other account belongs to. When this appears in a book, then this is the guid of the other book. \endverbatim @@ -304,7 +304,7 @@ Name: /hbci/config-filename Type: string Entitied: Book Use: OpenHBCI configuration file name, where the real HBCI -configuration for the OpenHBCI library can be found +configuration for the OpenHBCI library can be found \endverbatim \subsection kvpJ J @@ -328,15 +328,15 @@ Type: kvp_frame Entities: Account Use: Frame holding info regarding how lots should be managed in this account, including what accounting policy to use, where realized - gains should be reported, and etc. + gains should be reported, and etc. \endverbatim \verbatim Name: /lot-mgmt/gains-acct/ Type: frame Entities: Account -Use: When a lot in this account is double-balanced, this frame - holds per-currency accounts to which realized gains are to +Use: When a lot in this account is double-balanced, this frame + holds per-currency accounts to which realized gains are to be posted. \endverbatim @@ -361,7 +361,7 @@ Name: /lot-split/ Type: kvp_glist Entities: Split Use: A bag of kvp frames holding identification of splits - that were split off of this split. Same style as the + that were split off of this split. Same style as the /gemini/, look there for additional doco's. \endverbatim @@ -380,7 +380,7 @@ Use: The GUID of the peer split which was split from this split. Name: /notes Type: string Entities: Account, Lot, Transaction -Use: A user-suplied 'Notes' text field. The user can set this to +Use: A user-suplied 'Notes' text field. The user can set this to any value and change it at any time for any reason. Accessors: xaccAccountGetNotes(), xaccAccountSetNotes(), xaccTransGetNotes(), xaccTransSetNotes() @@ -533,7 +533,7 @@ Use: Store the formula for the credit side of the split Name: /sched-xaction/debit-formula Type: string Entities: Split associated with a SchedXaction -Use: Formula for the debit. Either the credit or the +Use: Formula for the debit. Either the credit or the debit formula must be empty. \endverbatim @@ -571,7 +571,7 @@ Use: A boolean flag indicated whether the Account is tax-related. Name: /title Type: string Entities: Lot -Use: A user-supplied title for the lot. The user can set this to +Use: A user-supplied title for the lot. The user can set this to any value and change it at any time for any reason. \endverbatim @@ -606,7 +606,7 @@ Use: This frame is used to store keys which are editable directly by Name: void-reason Type: string Entities: Transaction -Use: This string is used to store the reason why a transaction has been +Use: This string is used to store the reason why a transaction has been voided. Note that it should only exist if the transaction has been voided. \endverbatim diff --git a/src/libqof/qof/kvp-value.hpp b/src/libqof/qof/kvp-value.hpp index 350e9ab5f7..e97fb367f8 100644 --- a/src/libqof/qof/kvp-value.hpp +++ b/src/libqof/qof/kvp-value.hpp @@ -37,6 +37,12 @@ extern "C" //Must be a struct because it's exposed to C so that it can in turn be //translated to/from Scheme. +/** @addtogroup KVP + * @{ + */ + +/** Implements KvpValue using boost::variant. + */ struct KvpValueImpl { public: @@ -134,7 +140,7 @@ struct KvpValueImpl int compare(const KvpValueImpl *, const KvpValue *) noexcept; - +/** @} Close Doxygen AddToGroup */ template KvpValueImpl::KvpValueImpl(T newvalue) noexcept: datastore(newvalue) @@ -153,7 +159,9 @@ KvpValueImpl::set(T val) noexcept { this->datastore = val; } - +/** @ingroup KVP + @{ */ +/** @internal @{ */ /** Convert a kvp_value into a GValue. Frames aren't converted. * @param kval: A KvpValue. * @return GValue*. Must be freed with g_free(). @@ -172,7 +180,8 @@ KvpValue* kvp_value_from_gvalue (const GValue *gval); * \param value: A GValue* created by kvp_frame_get_gvalue */ void gnc_gvalue_free (GValue *value); - +/** @} Close Doxygen Internal */ +/** @} Close Doxygen Group */ extern "C" GType gnc_value_list_get_type (void); #define GNC_TYPE_VALUE_LIST (gnc_value_list_get_type ()) diff --git a/src/libqof/qof/kvp_frame.hpp b/src/libqof/qof/kvp_frame.hpp index 5aae496b53..f765a6dc87 100644 --- a/src/libqof/qof/kvp_frame.hpp +++ b/src/libqof/qof/kvp_frame.hpp @@ -39,6 +39,35 @@ * passed as either '/'-delimited strings or as std::vectors of keys. Unlike * file system paths, the tokens '.' and '..' have no special meaning. * + * KVP is an implementation detail whose direct use should be avoided; create an + * abstraction object in libqof to keep KVP encapsulated here and ensure that + * KVP modifications are written to the database. Two generic abstractions are + * provided: + * + * * @ref qof_instance_set_kvp and @ref qof_instance_get_kvp provide single-item + access via GValues to support object properties. + + * * @ref qof_book_set_option and @ref qof_book_get_option provide similar + access for book options. + + * + * @ref kvpvalues provides a catolog of KVP entries including what objects + * they're part of and how they're used. + * + * ## Purpose + * KVP is used to extend the class structure without directly reflecting the extension in the database or xML schema. The backend will directly load and store KVP slots without any checking, which allows older versions of GnuCash to load the database without complaint and without damaging the KVP data that they don't understand. + * + * When a feature is entirely implemented in KVP and doesn't affect the meaning of the books or other features, this isn't a problem, but when it's not true then it should be registered in @ref UtilFeature so that older versions of GnuCash will refuse to load the database. + * + * ## Policy + * * Document every KVP slot in src/engine/kvp_doc.txt so that it is presented + * in @ref kvpvalues. + * * Register a feature in @ref UtilFeature if the use of the KVP in any way affects the books or business computations. + * * Key strings should be all lower case with '-', not spaces, separating words and '/' separating frames. Prefer longer and more descriptive names to abbreviations, and define a global const char[] to the key or path string so that the compiler will catch any typos. + * * Make good use of the hierarchical nature of KVP by using frames to group related slots. + * * Don't use the KVP API directly outside of libqof, and prefer to use the QofInstance and QofBook functions whenever feasible. If those functions aren't feasible write a class in libqof to abstract the use of KVP. + * * Avoid re-using key names in different contexts (e.g. Transactions and Splits) unless the slot is used for the same purpose in both. + * @{ */ #ifndef GNC_KVP_FRAME_TYPE @@ -49,23 +78,33 @@ #include #include #include - -class cstring_comparer -{ - public: - /* Returns true if one is less than two. */ - bool operator()(const char * one, const char * two) const - { - auto ret = std::strcmp(one, two) < 0; - return ret; - } -}; - using Path = std::vector; +/** Implements KvpFrame. + * It's a struct because QofInstance needs to use the typename to declare a + * KvpFrame* member, and QofInstance's API is C until its children are all + * rewritten in C++. + * + * N.B.** Writes to KvpFrames must** be wrapped in BeginEdit and Commit + * for the containing QofInstance and the QofInstance must be marked dirty. This + * is not** done by the KvpFrame API. In general Kvp items should be + * accessed using either QofInstance or QofBook methods in order to ensure that + * this is done. + * @{ + */ struct KvpFrameImpl { - typedef std::map map_type; + class cstring_comparer + { + public: + /* Returns true if one is less than two. */ + bool operator()(const char * one, const char * two) const + { + auto ret = std::strcmp(one, two) < 0; + return ret; + } + }; + using map_type = std::map; public: KvpFrameImpl() noexcept {}; @@ -98,8 +137,8 @@ struct KvpFrameImpl * Set the value with the key in a subframe following the keys in path, * replacing and returning the old value if it exists or nullptr if it * doesn't. Creates any missing intermediate frames. - * @param path: The path of subframes as a '/'-delimited string leading to the frame in which to - * insert/replace. + * @param path: The path of subframes as a '/'-delimited string leading to + * the frame in which to insert/replace. * @param newvalue: The value to set at key. * @return The old value if there was one or nullptr. */ @@ -112,8 +151,8 @@ struct KvpFrameImpl * Set the value with the key in a subframe following the keys in path, * replacing and returning the old value if it exists or nullptr if it * doesn't. Creates any missing intermediate frames. - * @param path: The path of subframes as a std::vector leading to the frame in which to - * insert/replace. + * @param path: The path of subframes as a std::vector leading to the + * frame in which to insert/replace. * @param newvalue: The value to set at key. * @return The old value if there was one or nullptr. */ @@ -158,4 +197,6 @@ struct KvpFrameImpl int compare (const KvpFrameImpl &, const KvpFrameImpl &) noexcept; int compare (const KvpFrameImpl *, const KvpFrameImpl *) noexcept; +/** @} Doxygen Group */ + #endif diff --git a/src/libqof/qof/qofbook.h b/src/libqof/qof/qofbook.h index 04448f76ab..50750ce907 100644 --- a/src/libqof/qof/qofbook.h +++ b/src/libqof/qof/qofbook.h @@ -354,6 +354,9 @@ void qof_book_begin_edit(QofBook *book); void qof_book_commit_edit(QofBook *book); /* Access functions for options. */ +/** @ingroup KVP + @{ + */ /** Load a GNCOptionsDB from KVP data. * @param book: The book. * @param load_cb: A callback function that does the loading. @@ -394,7 +397,7 @@ KvpValue* qof_book_get_option (QofBook *book, GSList *path); * @param list: A GList of keys which from a path under KVP_OPTION_PATH. */ void qof_book_options_delete (QofBook *book); - +/** @} End of Doxygen Include */ /** deprecated */ #define qof_book_get_guid(X) qof_entity_get_guid (QOF_INSTANCE(X)) diff --git a/src/libqof/qof/qofinstance-p.h b/src/libqof/qof/qofinstance-p.h index 16eeee0cce..0c0d4fd1bb 100644 --- a/src/libqof/qof/qofinstance-p.h +++ b/src/libqof/qof/qofinstance-p.h @@ -106,11 +106,33 @@ void qof_instance_set_version_check (gpointer inst, guint32 value); void qof_instance_copy_version_check (gpointer to, gconstpointer from); void qof_instance_set_idata(gpointer inst, guint32 idata); /* Convenience functions to save some typing in property handlers */ +/** @ingroup KVP + * @{ */ +/** Report whether a QofInstance has anything stored in KVP + * @param inst The QofInstance + * @return TRUE if Kvp isn't empty. + */ gboolean qof_instance_has_kvp (QofInstance *inst); +/** Sets a KVP slot to a value from a GValue. The key can be a '/'-delimited + * path, and intermediate container frames will be created if necessary. + * Commits the change to the QofInstance. + * @param inst: The QofInstance on which to set the value. + * @param key: The key for the slot or '/'-delimited path + * @param value: A GValue containing an item of a type which KvpValue knows + * how to store. + */ void qof_instance_set_kvp (QofInstance *inst, const gchar *key, const GValue *value); -void qof_instance_get_kvp (const QofInstance *inst, const gchar *key, GValue *value); -/* Functions to isolate the KVP mechanism inside QOF for cases where GValue - * operations won't work. +/** Retrieves the contents of a KVP slot into a provided GValue. + * @param inst: The QofInstance + * @param key: The key of or '/'-delimited path to the slot. + * @param value: A GValue into which to store the value of the slot. It will be + * set to the correct type. + */ +void qof_instance_get_kvp (const QofInstance *inst, const gchar *key, GValue +*value); +/** @} Close out the DOxygen ingroup */ +/* Functions to isolate the KVP mechanism inside QOF for cases where +GValue * operations won't work. */ void qof_instance_copy_kvp (QofInstance *to, const QofInstance *from); void qof_instance_swap_kvp (QofInstance *a, QofInstance *b); diff --git a/src/libqof/qof/qofinstance.h b/src/libqof/qof/qofinstance.h index 98b854f0c3..df4f38292e 100644 --- a/src/libqof/qof/qofinstance.h +++ b/src/libqof/qof/qofinstance.h @@ -66,13 +66,7 @@ typedef struct KvpFrameImpl KvpFrame; struct QofInstance_s { GObject object; - QofIdType e_type; /**< Entity type */ - - /* kvp_data is a key-value pair database for storing arbirtary - * information associated with this instance. - * See src/engine/kvp_doc.txt for a list and description of the - * important keys. */ KvpFrame *kvp_data; }; From 20a52028994941f14c7496ea452b49edbc3a44aa Mon Sep 17 00:00:00 2001 From: John Ralls Date: Sat, 4 Jul 2015 15:57:33 -0700 Subject: [PATCH 53/54] Bug 87652 - KVP modification does not change 'dirty' flag. --- src/import-export/aqb/test/test-kvp.c | 5 ++++- src/libqof/qof/gnc-aqbanking-templates.cpp | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/import-export/aqb/test/test-kvp.c b/src/import-export/aqb/test/test-kvp.c index 137522e81f..ceed1150fe 100644 --- a/src/import-export/aqb/test/test-kvp.c +++ b/src/import-export/aqb/test/test-kvp.c @@ -26,6 +26,7 @@ // for the gnc_ab_get_book_template_list() et al. functions #include "import-export/aqb/gnc-ab-kvp.h" #include +#include #include "engine/gnc-hooks.h" static char* get_filepath(const char* filename) @@ -117,7 +118,9 @@ test_qofsession_aqb_kvp( void ) g_assert_cmpint(g_list_length(templ_list), ==, 1); templ = templ_list->data; - g_assert_cmpstr(gnc_ab_trans_templ_get_name(templ), ==, ORIGINAL_NAME); // ok, name from file is here + //Raise the edit level so that we can check that it's marked dirty. + qof_instance_increase_editlevel(QOF_INSTANCE(book)); + g_assert_cmpstr(gnc_ab_trans_templ_get_name(templ), ==, ORIGINAL_NAME); // ok, name from file is here // Now we change the name into something else and verify it can be saved gnc_ab_trans_templ_set_name(templ, CHANGED_NAME); diff --git a/src/libqof/qof/gnc-aqbanking-templates.cpp b/src/libqof/qof/gnc-aqbanking-templates.cpp index 6c5c526d75..54f9b6f91b 100644 --- a/src/libqof/qof/gnc-aqbanking-templates.cpp +++ b/src/libqof/qof/gnc-aqbanking-templates.cpp @@ -193,9 +193,11 @@ gnc_ab_set_book_template_list (QofBook *b, GList *template_list) kvp_list = g_list_reverse (kvp_list); auto value = new KvpValue(g_list_copy_deep(kvp_list, copy_list_value, nullptr)); + qof_book_begin_edit(b); KvpFrame *toplevel = qof_instance_get_slots (QOF_INSTANCE (b)); delete toplevel->set_path({"hbci", "template-list"}, value); qof_instance_set_dirty_flag (QOF_INSTANCE (b), TRUE); + qof_book_commit_edit(b); } const gchar * From cc515150d9e844b93f048085730c04a10ee4a011 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Sat, 4 Jul 2015 16:09:04 -0700 Subject: [PATCH 54/54] Bug 120250 - KVP XML loader ignores '0' timestamps? --- src/backend/xml/sixtp-dom-parsers.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/backend/xml/sixtp-dom-parsers.cpp b/src/backend/xml/sixtp-dom-parsers.cpp index 49f6311889..f9354d3e4e 100644 --- a/src/backend/xml/sixtp-dom-parsers.cpp +++ b/src/backend/xml/sixtp-dom-parsers.cpp @@ -236,13 +236,10 @@ static KvpValue* dom_tree_to_timespec_kvp_value (xmlNodePtr node) { Timespec ts; - KvpValue * ret = NULL; + KvpValue * ret = nullptr; ts = dom_tree_to_timespec (node); - if (ts.tv_sec || ts.tv_nsec) - { - ret = new KvpValue{ts}; - } + ret = new KvpValue{ts}; return ret; }