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.
This commit is contained in:
John Ralls 2015-06-27 15:39:54 -07:00
parent 3590de1085
commit ff07762f61
20 changed files with 232 additions and 309 deletions

View File

@ -8,6 +8,8 @@ check_PROGRAMS = \
test-sx \ test-sx \
test-app-utils test-app-utils
AM_DEFAULT_SOURCE_EXT = .cpp
TESTS = \ TESTS = \
test-load-module \ test-load-module \
${check_PROGRAMS} ${check_PROGRAMS}
@ -16,7 +18,7 @@ test_exp_parser_SOURCES = \
test-exp-parser.c test-exp-parser.c
test_print_parse_amount_SOURCES = \ 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_TEST_DEPS = --gnc-module-dir ${top_builddir}/src/engine \
--gnc-module-dir ${top_builddir}/src/app-utils \ --gnc-module-dir ${top_builddir}/src/app-utils \

View File

@ -228,8 +228,8 @@ test_option_save_book_currency (Fixture *fixture, gconstpointer pData)
scm_cons (scm_from_utf8_string("GTQ"), scm_cons (scm_from_utf8_string("GTQ"),
scm_cons (scm_from_locale_symbol("fifo"), SCM_EOL))))); scm_cons (scm_from_locale_symbol("fifo"), SCM_EOL)))));
qof_book_save_options (book, gnc_option_db_save, odb, TRUE); 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 (slots->get_slot("options/Accounts/Book Currency")->get<const char*>(), == , "GTQ");
g_assert_cmpstr (kvp_frame_get_string(slots, "options/Accounts/Default Gains Policy"), == , "fifo"); g_assert_cmpstr (slots->get_slot("options/Accounts/Default Gains Policy")->get<const char*>(), == , "fifo");
gnc_option_db_destroy (odb); gnc_option_db_destroy (odb);
} }

View File

@ -1,3 +1,5 @@
extern "C"
{
#include "config.h" #include "config.h"
#include <glib.h> #include <glib.h>
#include <stdlib.h> #include <stdlib.h>
@ -8,6 +10,7 @@
#include "test-engine-stuff.h" #include "test-engine-stuff.h"
#include "test-stuff.h" #include "test-stuff.h"
#include <unittest-support.h> #include <unittest-support.h>
}
static void static void
test_num_print_info (gnc_numeric n, GNCPrintAmountInfo print_info, int line) 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; const char *s;
gboolean ok, print_ok; gboolean ok, print_ok;
gchar *msg = "[PrintAmountInternal()] Bad numeric from rounding: GNC_ERROR_OVERFLOW."; auto msg = "[PrintAmountInternal()] Bad numeric from rounding: GNC_ERROR_OVERFLOW.";
gchar *log_domain = "gnc.gui"; auto log_domain = "gnc.gui";
guint loglevel = G_LOG_LEVEL_WARNING, hdlr; auto loglevel = static_cast<GLogLevelFlags>(G_LOG_LEVEL_WARNING);
TestErrorStruct check = { loglevel, log_domain, msg }; 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. */ /* 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); (GLogFunc)test_checked_handler, &check);
s = xaccPrintAmount (n, print_info); s = xaccPrintAmount (n, print_info);
print_ok = (s && s[0] != '\0'); 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)", "start: %s, string %s, finish: %s (line %d)",
gnc_numeric_to_string (n), s, gnc_numeric_to_string (n), s,
gnc_numeric_to_string (n_parsed), line); gnc_numeric_to_string (n_parsed), line);
test_error_struct_free (check);
} }

View File

@ -96,9 +96,6 @@ main_helper (void *closure, int argc, char **argv)
xaccLogDisable (); xaccLogDisable ();
/* double->string->double is not idempotent */
kvp_exclude_type (KVP_TYPE_DOUBLE);
/* Initialize to a known RNG position */ /* Initialize to a known RNG position */
srand(1); srand(1);

View File

@ -64,7 +64,7 @@ typedef struct
gboolean is_ok; gboolean is_ok;
/*@ dependent @*/ /*@ dependent @*/
KvpFrame* pKvpFrame; KvpFrame* pKvpFrame;
KvpValueType value_type; KvpValue::Type value_type;
GList *pList; GList *pList;
context_t context; context_t context;
/*@ dependent @*/ /*@ dependent @*/
@ -77,7 +77,7 @@ static /*@ null @*/ gpointer get_obj_guid( gpointer pObject );
static void set_obj_guid( void ); static void set_obj_guid( void );
static /*@ null @*/ gpointer get_path( gpointer pObject ); static /*@ null @*/ gpointer get_path( gpointer pObject );
static void set_path( gpointer pObject, /*@ null @*/ gpointer pValue ); 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 void set_slot_type( gpointer pObject, /*@ null @*/ gpointer pValue );
static gint64 get_int64_val( gpointer pObject ); static gint64 get_int64_val( gpointer pObject );
static void set_int64_val( gpointer pObject, gint64 pValue ); 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 ); pInfo->path = g_string_new( (gchar*)pValue );
} }
static KvpValueType static KvpValue::Type
get_slot_type( gpointer pObject ) get_slot_type( gpointer pObject )
{ {
slot_info_t* pInfo = (slot_info_t*)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 (gpointer)kvp_value_get_type( pInfo->pKvpValue );
return pInfo->value_type; 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( pObject != NULL );
g_return_if_fail( pValue != NULL ); g_return_if_fail( pValue != NULL );
pInfo->value_type = static_cast<KvpValueType>(GPOINTER_TO_INT(pValue)); pInfo->value_type = static_cast<KvpValue::Type>(GPOINTER_TO_INT(pValue));
} }
static gint64 static gint64
@ -351,7 +351,7 @@ get_int64_val( gpointer pObject )
g_return_val_if_fail( pObject != NULL, 0 ); 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<int64_t>(); return pInfo->pKvpValue->get<int64_t>();
} }
@ -369,7 +369,7 @@ set_int64_val( gpointer pObject, gint64 value )
g_return_if_fail( pObject != NULL ); 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}; pValue = new KvpValue{value};
set_slot_from_value( pInfo, pValue ); set_slot_from_value( pInfo, pValue );
} }
@ -381,7 +381,7 @@ get_string_val( gpointer pObject )
g_return_val_if_fail( pObject != NULL, NULL ); 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<const char*>(); return (gpointer)pInfo->pKvpValue->get<const char*>();
} }
@ -397,7 +397,7 @@ set_string_val( gpointer pObject, /*@ null @*/ gpointer pValue )
slot_info_t* pInfo = (slot_info_t*)pObject; slot_info_t* pInfo = (slot_info_t*)pObject;
g_return_if_fail( pObject != NULL ); 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; return;
auto string = g_strdup(static_cast<const char*>(pValue)); auto string = g_strdup(static_cast<const char*>(pValue));
auto value = new KvpValue{string}; auto value = new KvpValue{string};
@ -412,7 +412,7 @@ get_double_val( gpointer pObject )
g_return_val_if_fail( pObject != NULL, NULL ); 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<double>(); d_val = pInfo->pKvpValue->get<double>();
return (gpointer)&d_val; return (gpointer)&d_val;
@ -431,7 +431,7 @@ set_double_val( gpointer pObject, /*@ null @*/ gpointer pValue )
g_return_if_fail( pObject != NULL ); 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<double*>(pValue))}; value = new KvpValue{*(static_cast<double*>(pValue))};
set_slot_from_value( pInfo, value ); 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 ) ); 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<Timespec>(); return pInfo->pKvpValue->get<Timespec>();
} }
@ -455,7 +455,7 @@ set_timespec_val( gpointer pObject, Timespec ts )
g_return_if_fail( pObject != NULL ); 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}; value = new KvpValue{ts};
set_slot_from_value( pInfo, value ); set_slot_from_value( pInfo, value );
} }
@ -467,7 +467,7 @@ get_guid_val( gpointer pObject )
g_return_val_if_fail( pObject != NULL, NULL ); 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<GncGUID*>(); return (gpointer)pInfo->pKvpValue->get<GncGUID*>();
} }
@ -487,13 +487,13 @@ set_guid_val( gpointer pObject, /*@ null @*/ gpointer pValue )
switch ( pInfo->value_type) switch ( pInfo->value_type)
{ {
case KVP_TYPE_GUID: case KvpValue::Type::GUID:
{ {
auto new_guid = guid_copy(static_cast<GncGUID*>(pValue)); auto new_guid = guid_copy(static_cast<GncGUID*>(pValue));
set_slot_from_value(pInfo, new KvpValue{new_guid}); set_slot_from_value(pInfo, new KvpValue{new_guid});
break; break;
} }
case KVP_TYPE_GLIST: case KvpValue::Type::GLIST:
{ {
slot_info_t *newInfo = slot_info_copy( pInfo, (GncGUID*)pValue ); slot_info_t *newInfo = slot_info_copy( pInfo, (GncGUID*)pValue );
KvpValue *pValue = NULL; KvpValue *pValue = NULL;
@ -509,7 +509,7 @@ set_guid_val( gpointer pObject, /*@ null @*/ gpointer pValue )
g_free( key ); g_free( key );
break; break;
} }
case KVP_TYPE_FRAME: case KvpValue::Type::FRAME:
{ {
slot_info_t *newInfo = slot_info_copy( pInfo, (GncGUID*)pValue ) ; slot_info_t *newInfo = slot_info_copy( pInfo, (GncGUID*)pValue ) ;
auto newFrame = new KvpFrame; auto newFrame = new KvpFrame;
@ -554,7 +554,7 @@ get_numeric_val( gpointer pObject )
g_return_val_if_fail( pObject != NULL, gnc_numeric_zero() ); 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<gnc_numeric>(); return pInfo->pKvpValue->get<gnc_numeric>();
} }
@ -572,7 +572,7 @@ set_numeric_val( gpointer pObject, gnc_numeric value )
g_return_if_fail( pObject != NULL ); 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}); 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 ); 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<GDate>(); date = pInfo->pKvpValue->get<GDate>();
return &date; return &date;
@ -603,7 +603,7 @@ set_gdate_val( gpointer pObject, GDate* value )
g_return_if_fail( pObject != NULL ); 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}); 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 ) switch ( pSlot_info->value_type )
{ {
case KVP_TYPE_FRAME: case KvpValue::Type::FRAME:
{ {
auto pKvpFrame = value->get<KvpFrame*>(); auto pKvpFrame = value->get<KvpFrame*>();
auto guid = guid_new(); auto guid = guid_new();
@ -672,7 +672,7 @@ save_slot( const gchar* key, KvpValue* value, gpointer data )
g_slice_free( slot_info_t, pNewInfo ); g_slice_free( slot_info_t, pNewInfo );
} }
break; break;
case KVP_TYPE_GLIST: case KvpValue::Type::GLIST:
{ {
GncGUID guid = guid_new_return(); GncGUID guid = guid_new_return();
slot_info_t *pNewInfo = slot_info_copy( pSlot_info, &guid ); 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, gnc_sql_slots_save( GncSqlBackend* be, const GncGUID* guid, gboolean is_infant,
QofInstance *inst) 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); KvpFrame *pFrame = qof_instance_get_slots (inst);
g_return_val_if_fail( be != NULL, FALSE ); g_return_val_if_fail( be != NULL, FALSE );
@ -739,7 +739,7 @@ gnc_sql_slots_delete( GncSqlBackend* be, const GncGUID* guid )
GncSqlResult* result; GncSqlResult* result;
gchar guid_buf[GUID_ENCODING_LENGTH + 1]; gchar guid_buf[GUID_ENCODING_LENGTH + 1];
GncSqlStatement* stmt; 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( be != NULL, FALSE );
g_return_val_if_fail( guid != 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 ); (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", 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 ); stmt = gnc_sql_create_statement_from_sql( be, buf );
g_free( buf ); g_free( buf );
if ( stmt != NULL ) if ( stmt != NULL )
@ -821,7 +821,7 @@ load_slot( slot_info_t *pInfo, GncSqlRow* row )
void void
gnc_sql_slots_load( GncSqlBackend* be, QofInstance* inst ) 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( be != NULL );
g_return_if_fail( inst != NULL ); g_return_if_fail( inst != NULL );
@ -886,7 +886,7 @@ load_obj_guid( const GncSqlBackend* be, GncSqlRow* row )
static void static void
load_slot_for_list_item( GncSqlBackend* be, GncSqlRow* row, QofCollection* coll ) 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; const GncGUID* guid;
QofInstance* inst; QofInstance* inst;
@ -972,7 +972,7 @@ gnc_sql_slots_load_for_list( GncSqlBackend* be, GList* list )
static void static void
load_slot_for_book_object( GncSqlBackend* be, GncSqlRow* row, BookLookupFn lookup_fn ) 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; const GncGUID* guid;
QofInstance* inst; QofInstance* inst;

View File

@ -260,7 +260,7 @@ add_kvp_value_node(xmlNodePtr node, const gchar *tag, KvpValue* val)
switch (val->get_type()) switch (val->get_type())
{ {
case KVP_TYPE_STRING: case KvpValue::Type::STRING:
{ {
auto newstr = g_strdup(val->get<const char*>()); auto newstr = g_strdup(val->get<const char*>());
val_node = xmlNewTextChild(node, NULL, BAD_CAST tag, 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); g_free (newstr);
break; break;
} }
case KVP_TYPE_TIMESPEC: case KvpValue::Type::TIMESPEC:
val_node = NULL; val_node = NULL;
break; break;
case KVP_TYPE_GDATE: case KvpValue::Type::GDATE:
{ {
auto d = val->get<GDate>(); auto d = val->get<GDate>();
val_node = gdate_to_dom_tree(tag, &d); 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()) switch (val->get_type())
{ {
case KVP_TYPE_GINT64: case KvpValue::Type::INT64:
add_text_to_node(val_node, "integer", add_text_to_node(val_node, "integer",
g_strdup_printf("%" G_GINT64_FORMAT, g_strdup_printf("%" G_GINT64_FORMAT,
val->get<int64_t>())); val->get<int64_t>()));
break; break;
case KVP_TYPE_DOUBLE: case KvpValue::Type::DOUBLE:
add_text_to_node(val_node, "double", add_text_to_node(val_node, "double",
double_to_string(val->get<double>())); double_to_string(val->get<double>()));
break; break;
case KVP_TYPE_NUMERIC: case KvpValue::Type::NUMERIC:
add_text_to_node(val_node, "numeric", add_text_to_node(val_node, "numeric",
gnc_numeric_to_string(val->get<gnc_numeric>())); gnc_numeric_to_string(val->get<gnc_numeric>()));
break; break;
case KVP_TYPE_STRING: case KvpValue::Type::STRING:
xmlSetProp(val_node, BAD_CAST "type", BAD_CAST "string"); xmlSetProp(val_node, BAD_CAST "type", BAD_CAST "string");
break; break;
case KVP_TYPE_GUID: case KvpValue::Type::GUID:
{ {
gchar guidstr[GUID_ENCODING_LENGTH+1]; gchar guidstr[GUID_ENCODING_LENGTH+1];
guid_to_string_buff(val->get<GncGUID*>(), guidstr); guid_to_string_buff(val->get<GncGUID*>(), guidstr);
add_text_to_node(val_node, "guid", guidstr); add_text_to_node(val_node, "guid", guidstr);
break; break;
} }
case KVP_TYPE_TIMESPEC: case KvpValue::Type::TIMESPEC:
{ {
auto ts = val->get<Timespec>(); auto ts = val->get<Timespec>();
val_node = timespec_to_dom_tree (tag, &ts); 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); xmlAddChild (node, val_node);
break; break;
} }
case KVP_TYPE_GDATE: case KvpValue::Type::GDATE:
xmlSetProp(val_node, BAD_CAST "type", BAD_CAST "gdate"); xmlSetProp(val_node, BAD_CAST "type", BAD_CAST "gdate");
break; break;
case KVP_TYPE_GLIST: case KvpValue::Type::GLIST:
xmlSetProp(val_node, BAD_CAST "type", BAD_CAST "list"); xmlSetProp(val_node, BAD_CAST "type", BAD_CAST "list");
for (auto cursor = val->get<GList*>(); cursor; cursor = cursor->next) for (auto cursor = val->get<GList*>(); 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); add_kvp_value_node(val_node, "slot:value", val);
} }
break; break;
case KVP_TYPE_FRAME: case KvpValue::Type::FRAME:
{ {
xmlSetProp(val_node, BAD_CAST "type", BAD_CAST "frame"); xmlSetProp(val_node, BAD_CAST "type", BAD_CAST "frame");

View File

@ -110,7 +110,7 @@ test_kvp_frames1(void)
for (i = 0; i < 20; i++) 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_frame1 = new KvpFrame;
auto test_key = get_random_string_without("/"); auto test_key = get_random_string_without("/");

View File

@ -72,45 +72,47 @@ gnc_scm_to_kvp_value_ptr(SCM val)
SCM SCM
gnc_kvp_value_ptr_to_scm(KvpValue* val) 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<int64_t>()); return scm_from_int64(val->get<int64_t>());
break; break;
case KVP_TYPE_DOUBLE: case KvpValue::Type::DOUBLE:
return scm_from_double (val->get<double>()); return scm_from_double (val->get<double>());
break; break;
case KVP_TYPE_NUMERIC: case KvpValue::Type::NUMERIC:
return gnc_numeric_to_scm(val->get<gnc_numeric>()); return gnc_numeric_to_scm(val->get<gnc_numeric>());
break; break;
case KVP_TYPE_STRING: case KvpValue::Type::STRING:
{ {
auto string = val->get<const char*>(); auto string = val->get<const char*>();
return string ? scm_from_utf8_string(string) : SCM_BOOL_F; return string ? scm_from_utf8_string(string) : SCM_BOOL_F;
break; break;
} }
case KVP_TYPE_GUID: case KvpValue::Type::GUID:
{ {
auto tempguid = kvp_value_get_guid(val); auto tempguid = val->get<GncGUID*>();
return gnc_guid2scm(*tempguid); return gnc_guid2scm(*tempguid);
} }
break; break;
case KVP_TYPE_TIMESPEC: case KvpValue::Type::TIMESPEC:
return gnc_timespec2timepair(val->get<Timespec>()); return gnc_timespec2timepair(val->get<Timespec>());
break; break;
case KVP_TYPE_FRAME: case KvpValue::Type::FRAME:
{ {
auto frame = val->get<KvpFrame*>(); auto frame = val->get<KvpFrame*>();
if (frame != nullptr) if (frame != nullptr)
return SWIG_NewPointerObj(frame, SWIG_TypeQuery("_p_KvpFrame"), 0); return SWIG_NewPointerObj(frame, SWIG_TypeQuery("_p_KvpFrame"), 0);
} }
break; break;
case KVP_TYPE_GDATE: case KvpValue::Type::GDATE:
return gnc_timespec2timepair(gdate_to_timespec(val->get<GDate>())); return gnc_timespec2timepair(gdate_to_timespec(val->get<GDate>()));
/* FIXME: handle types below */ /* FIXME: handle types below */
case KVP_TYPE_GLIST: case KvpValue::Type::GLIST:
default: default:
break; break;
} }

View File

@ -105,8 +105,8 @@ set_max_kvp_frame_elements (gint max_kvp_frame_elements)
kvp_frame_max_elements = MAX (max_kvp_frame_elements, 1); kvp_frame_max_elements = MAX (max_kvp_frame_elements, 1);
} }
void static void
kvp_exclude_type (KvpValueType kvp_type) kvp_exclude_type (KvpValue::Type kvp_type)
{ {
gint *key; gint *key;
@ -120,7 +120,7 @@ kvp_exclude_type (KvpValueType kvp_type)
} }
static gboolean static gboolean
kvp_type_excluded (KvpValueType kvp_type) kvp_type_excluded (KvpValue::Type kvp_type)
{ {
gint key = kvp_type; gint key = kvp_type;
@ -238,25 +238,25 @@ static KvpFrame* get_random_kvp_frame_depth (gint depth);
static KvpValue* static KvpValue*
get_random_kvp_value_depth (int type, gint depth) get_random_kvp_value_depth (int type, gint depth)
{ {
KvpValueType datype; KvpValue::Type datype;
KvpValue *ret; KvpValue *ret;
if (type == -1) if (type == -1)
{ {
datype = static_cast<KvpValueType>(get_random_int_in_range(KVP_TYPE_GINT64, KVP_TYPE_FRAME)); datype = static_cast<KvpValue::Type>(get_random_int_in_range(KvpValue::Type::INT64, KvpValue::Type::FRAME));
} }
else if (type == -2) else if (type == -2)
{ {
datype = static_cast<KvpValueType>(get_random_int_in_range(KVP_TYPE_GINT64, KVP_TYPE_FRAME - 1)); datype = static_cast<KvpValue::Type>(get_random_int_in_range(KvpValue::Type::INT64, KvpValue::Type::FRAME - 1));
} }
else else
datype = static_cast<KvpValueType>(type); datype = static_cast<KvpValue::Type>(type);
if (datype == KVP_TYPE_FRAME && depth >= kvp_max_depth) if (datype == KvpValue::Type::FRAME && depth >= kvp_max_depth)
return NULL; return NULL;
if (datype == KVP_TYPE_GLIST && depth >= kvp_max_depth) if (datype == KvpValue::Type::GLIST && depth >= kvp_max_depth)
return NULL; return NULL;
if (kvp_type_excluded (datype)) if (kvp_type_excluded (datype))
@ -264,57 +264,50 @@ get_random_kvp_value_depth (int type, gint depth)
switch (datype) switch (datype)
{ {
case KVP_TYPE_GINT64: case KvpValue::Type::INT64:
ret = kvp_value_new_gint64(get_random_gint64()); ret = new KvpValue(get_random_gint64());
break; break;
case KVP_TYPE_DOUBLE: case KvpValue::Type::DOUBLE:
ret = NULL; ret = NULL;
break; break;
case KVP_TYPE_NUMERIC: case KvpValue::Type::NUMERIC:
ret = kvp_value_new_gnc_numeric(get_random_gnc_numeric(GNC_DENOM_AUTO)); ret = new KvpValue(get_random_gnc_numeric(GNC_DENOM_AUTO));
break; break;
case KVP_TYPE_STRING: case KvpValue::Type::STRING:
{ {
gchar *tmp_str; gchar *tmp_str;
tmp_str = get_random_string(); tmp_str = get_random_string();
if (!tmp_str) if (!tmp_str)
return NULL; return NULL;
ret = kvp_value_new_string(tmp_str); ret = new KvpValue(tmp_str);
g_free(tmp_str);
} }
break; break;
case KVP_TYPE_GUID: case KvpValue::Type::GUID:
{ {
GncGUID *tmp_guid; return new KvpValue(get_random_guid());
tmp_guid = get_random_guid();
ret = kvp_value_new_guid(tmp_guid);
g_free(tmp_guid);
} }
break; break;
case KVP_TYPE_TIMESPEC: case KvpValue::Type::TIMESPEC:
{ {
Timespec *ts = get_random_timespec(); Timespec *ts = get_random_timespec();
ret = kvp_value_new_timespec (*ts); ret = new KvpValue(*ts);
g_free(ts); g_free(ts);
} }
break; break;
case KVP_TYPE_GLIST: case KvpValue::Type::GLIST:
ret = kvp_value_new_glist_nc(get_random_glist_depth (depth + 1)); ret = new KvpValue(get_random_glist_depth (depth + 1));
break; break;
case KVP_TYPE_FRAME: case KvpValue::Type::FRAME:
{ {
KvpFrame *tmp_frame; return new KvpValue(get_random_kvp_frame_depth(depth + 1));
tmp_frame = get_random_kvp_frame_depth(depth + 1);
ret = kvp_value_new_frame(tmp_frame);
kvp_frame_delete(tmp_frame);
} }
break; break;
@ -328,14 +321,13 @@ get_random_kvp_value_depth (int type, gint depth)
static KvpFrame* static KvpFrame*
get_random_kvp_frame_depth (gint depth) get_random_kvp_frame_depth (gint depth)
{ {
KvpFrame *ret;
int vals_to_add; int vals_to_add;
gboolean val_added; gboolean val_added;
if (depth >= kvp_max_depth) if (depth >= kvp_max_depth)
return NULL; return NULL;
ret = kvp_frame_new(); auto ret = new KvpFrame;
vals_to_add = get_random_int_in_range(1, kvp_frame_max_elements); vals_to_add = get_random_int_in_range(1, kvp_frame_max_elements);
val_added = FALSE; val_added = FALSE;
@ -367,7 +359,7 @@ get_random_kvp_frame_depth (gint depth)
val_added = TRUE; val_added = TRUE;
kvp_frame_set_slot_nc(ret, key, val); ret->set_path(key, val);
g_free(key); g_free(key);
} }

View File

@ -13,11 +13,12 @@ extern "C"
#include <stdint.h> #include <stdint.h>
#include "qof.h" #include "qof.h"
#include <kvp_frame.h>
#include "Query.h" #include "Query.h"
#include "gnc-pricedb.h" #include "gnc-pricedb.h"
#include "SchedXaction.h" #include "SchedXaction.h"
typedef struct KvpValueImpl KvpValue;
typedef struct KvpFrameImpl KvpFrame;
Timespec* get_random_timespec(void); Timespec* get_random_timespec(void);
void random_timespec_zero_nsec (gboolean zero_nsec); void random_timespec_zero_nsec (gboolean zero_nsec);
void random_timespec_usec_resolution (gboolean usec_resolution); 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); gnc_numeric get_random_gnc_numeric(int64_t);
GncGUID* get_random_guid(void); 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_depth (gint max_kvp_depth);
void set_max_kvp_frame_elements (gint max_kvp_frame_elements); void set_max_kvp_frame_elements (gint max_kvp_frame_elements);
void set_max_account_tree_depth (gint max_tree_depth); void set_max_account_tree_depth (gint max_tree_depth);

View File

@ -23,6 +23,8 @@ LDADD = \
${top_builddir}/src/core-utils/libgnc-core-utils.la \ ${top_builddir}/src/core-utils/libgnc-core-utils.la \
${GLIB_LIBS} ${GLIB_LIBS}
test_guid_SOURCES = test-guid.cpp
# these tests are ordered kind more or less in the order # these tests are ordered kind more or less in the order
# that they should be executed, with more basic tests coming first. # 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}) $(shell ${abs_top_srcdir}/src/gnc-test-env.pl --noexports ${GNC_TEST_DEPS})
check_PROGRAMS = ${TEST_GROUP_1} ${TEST_GROUP_2} check_PROGRAMS = ${TEST_GROUP_1} ${TEST_GROUP_2}
AM_DEFAULT_SOURCE_EXT = .cpp
TESTS = ${TEST_GROUP_1} test-create-account ${TEST_GROUP_2} TESTS = ${TEST_GROUP_1} test-create-account ${TEST_GROUP_2}

View File

@ -25,7 +25,8 @@
* Try to create duplicate GncGUID's, which should never happen. * Try to create duplicate GncGUID's, which should never happen.
* *
*/ */
extern "C"
{
#include "config.h" #include "config.h"
#include <ctype.h> #include <ctype.h>
#include <glib.h> #include <glib.h>
@ -33,7 +34,7 @@
#include "test-stuff.h" #include "test-stuff.h"
#include "test-engine-stuff.h" #include "test-engine-stuff.h"
#include "qof.h" #include "qof.h"
}
#define NENT 50123 #define NENT 50123
static void test_null_guid(void) static void test_null_guid(void)
@ -70,9 +71,10 @@ run_test (void)
for (i = 0; i < NENT; i++) for (i = 0; i < NENT; i++)
{ {
ent = g_object_new(QOF_TYPE_INSTANCE, NULL); ent = static_cast<QofInstance*>(g_object_new(QOF_TYPE_INSTANCE, NULL));
guid_replace(&guid); guid_replace(&guid);
ent = g_object_new(QOF_TYPE_INSTANCE, "guid", &guid, NULL); ent = static_cast<QofInstance*>(g_object_new(QOF_TYPE_INSTANCE,
"guid", &guid, NULL));
do_test ((NULL == qof_collection_lookup_entity (col, &guid)), do_test ((NULL == qof_collection_lookup_entity (col, &guid)),
"duplicate guid"); "duplicate guid");
ent->e_type = type; ent->e_type = type;

View File

@ -105,7 +105,7 @@ private:
KvpFrame* KvpFrame*
_GncABTransTempl::make_kvp_frame() _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_NAME, new KvpValue(m_name.c_str()));
frame->set(TT_RNAME, new KvpValue(m_recipient_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_RACC, new KvpValue(m_recipient_account.c_str()));

View File

@ -71,29 +71,29 @@ KvpValueImpl::add(KvpValueImpl * val) noexcept
return new KvpValueImpl(list); return new KvpValueImpl(list);
} }
KvpValueType KvpValue::Type
KvpValueImpl::get_type() const noexcept KvpValueImpl::get_type() const noexcept
{ {
if (datastore.type() == typeid(int64_t)) if (datastore.type() == typeid(int64_t))
return KvpValueType::KVP_TYPE_GINT64; return KvpValue::Type::INT64;
else if (datastore.type() == typeid(double)) else if (datastore.type() == typeid(double))
return KvpValueType::KVP_TYPE_DOUBLE; return KvpValue::Type::DOUBLE;
else if (datastore.type() == typeid(gnc_numeric)) else if (datastore.type() == typeid(gnc_numeric))
return KvpValueType::KVP_TYPE_NUMERIC; return KvpValue::Type::NUMERIC;
else if (datastore.type() == typeid(const gchar *)) else if (datastore.type() == typeid(const gchar *))
return KvpValueType::KVP_TYPE_STRING; return KvpValue::Type::STRING;
else if (datastore.type() == typeid(GncGUID *)) else if (datastore.type() == typeid(GncGUID *))
return KvpValueType::KVP_TYPE_GUID; return KvpValue::Type::GUID;
else if (datastore.type() == typeid(Timespec)) else if (datastore.type() == typeid(Timespec))
return KvpValueType::KVP_TYPE_TIMESPEC; return KvpValue::Type::TIMESPEC;
else if (datastore.type() == typeid(GList *)) else if (datastore.type() == typeid(GList *))
return KvpValueType::KVP_TYPE_GLIST; return KvpValue::Type::GLIST;
else if (datastore.type() == typeid(KvpFrameImpl *)) else if (datastore.type() == typeid(KvpFrameImpl *))
return KvpValueType::KVP_TYPE_FRAME; return KvpValue::Type::FRAME;
else if (datastore.type() == typeid(GDate)) else if (datastore.type() == typeid(GDate))
return KvpValueType::KVP_TYPE_GDATE; return KvpValue::Type::GDATE;
return KVP_TYPE_INVALID; return KvpValue::Type::INVALID;
} }
KvpFrame * KvpFrame *
@ -129,14 +129,7 @@ struct to_string_visitor : boost::static_visitor<void>
void operator()(KvpFrame * val) void operator()(KvpFrame * val)
{ {
auto tmp1 = kvp_frame_to_string(val); output << "KVP_VALUE_FRAME(" << val->to_string() << ")";
output << "KVP_VALUE_FRAME(";
if (tmp1)
{
output << tmp1;
g_free(tmp1);
}
output << ")";
} }
void operator()(GDate val) void operator()(GDate val)
@ -224,6 +217,55 @@ KvpValueImpl::to_string() const noexcept
return g_strdup(ret.str().c_str()); 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<KvpValue *>(lptr->data));
}
return retval;
}
struct compare_visitor : boost::static_visitor<int> struct compare_visitor : boost::static_visitor<int>
{ {
template <typename T, typename U> template <typename T, typename U>
@ -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 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 template <> int compare_visitor::operator()(double const & one, double const & two) const
{ {
@ -307,10 +349,16 @@ struct delete_visitor : boost::static_visitor<void>
operator()(T &) { /*do nothing*/ } operator()(T &) { /*do nothing*/ }
}; };
static void
destroy_value(void* item)
{
delete static_cast<KvpValue*>(item);
}
template <> void template <> void
delete_visitor::operator()(GList * & value) delete_visitor::operator()(GList * & value)
{ {
kvp_glist_delete(value); g_list_free_full(value, destroy_value);
} }
template <> void template <> void
delete_visitor::operator()(gchar * & value) delete_visitor::operator()(gchar * & value)
@ -344,7 +392,8 @@ KvpValueImpl::duplicate(const KvpValueImpl& other) noexcept
else if (other.datastore.type() == typeid(GList*)) else if (other.datastore.type() == typeid(GList*))
this->datastore = kvp_glist_copy(other.get<GList *>()); this->datastore = kvp_glist_copy(other.get<GList *>());
else if (other.datastore.type() == typeid(KvpFrame*)) else if (other.datastore.type() == typeid(KvpFrame*))
this->datastore = kvp_frame_copy(other.get<KvpFrame *>()); this->datastore = new KvpFrame(*other.get<KvpFrame *>());
else else
this->datastore = other.datastore; this->datastore = other.datastore;
} }

View File

@ -34,11 +34,27 @@ extern "C"
#include <boost/type_traits/is_nothrow_move_assignable.hpp> #include <boost/type_traits/is_nothrow_move_assignable.hpp>
#endif #endif
#include <boost/variant.hpp> #include <boost/variant.hpp>
#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 struct KvpValueImpl
{ {
public: 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 * Performs a deep copy
*/ */
@ -90,7 +106,7 @@ struct KvpValueImpl
*/ */
KvpValueImpl * add (KvpValueImpl *) noexcept; KvpValueImpl * add (KvpValueImpl *) noexcept;
KvpValueType get_type() const noexcept; KvpValueImpl::Type get_type() const noexcept;
char * to_string() const noexcept; char * to_string() const noexcept;
@ -137,5 +153,7 @@ KvpValueImpl::set(T val) noexcept
{ {
this->datastore = val; this->datastore = val;
} }
extern "C" GType gnc_value_list_get_type (void);
#define GNC_TYPE_VALUE_LIST (gnc_value_list_get_type ())
#endif #endif

View File

@ -30,6 +30,7 @@ extern "C"
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "kvp_frame.h"
} }
#include "kvp-value.hpp" #include "kvp-value.hpp"
@ -39,6 +40,9 @@ extern "C"
#include <algorithm> #include <algorithm>
#include <vector> #include <vector>
/* This static indicates the debugging module that this .o belongs to. */
static QofLogModule log_module = "qof.kvp";
static const char delim = '/'; static const char delim = '/';
KvpFrameImpl::KvpFrameImpl(const KvpFrameImpl & rhs) noexcept KvpFrameImpl::KvpFrameImpl(const KvpFrameImpl & rhs) noexcept
@ -99,7 +103,7 @@ walk_path_or_nullptr(const KvpFrameImpl* frame, Path& path)
for(auto key:path) for(auto key:path)
{ {
auto slot = cur_frame->get_slot(key.c_str()); 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; return nullptr;
cur_frame = slot->get<KvpFrame*>(); cur_frame = slot->get<KvpFrame*>();
} }
@ -130,7 +134,7 @@ walk_path_and_create(KvpFrameImpl* frame, Path path)
continue; continue;
} }
auto slot = frame->get_slot(key.c_str()); 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; auto new_frame = new KvpFrame;
delete frame->set(key.c_str(), new KvpValue{new_frame}); 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; return 0;
} }
/* This static indicates the debugging module that this .o belongs to. */
static QofLogModule log_module = QOF_MOD_KVP;
KvpFrame * KvpFrame *
kvp_frame_new(void) kvp_frame_new(void)
{ {
@ -940,78 +941,9 @@ kvp_frame_get_slot_path_gslist (KvpFrame *frame,
return NULL; 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<KvpValue*>(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<KvpValue *>(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 * KvpValue *
@ -1069,7 +1001,7 @@ KvpValue *
kvp_value_new_glist(const GList * value) kvp_value_new_glist(const GList * value)
{ {
if (!value) return {}; if (!value) return {};
return new KvpValueImpl{kvp_glist_copy(value)}; return nullptr;
} }
KvpValue * KvpValue *
@ -1101,14 +1033,6 @@ kvp_value_delete(KvpValue * value)
delete realvalue; delete realvalue;
} }
KvpValueType
kvp_value_get_type(const KvpValue * oldval)
{
if (!oldval) return KVP_TYPE_INVALID;
const KvpValueImpl * value {static_cast<const KvpValueImpl *>(oldval)};
return value->get_type();
}
int64_t int64_t
kvp_value_get_gint64(const KvpValue * ovalue) kvp_value_get_gint64(const KvpValue * ovalue)
{ {
@ -1318,44 +1242,40 @@ gvalue_from_kvp_value (const KvpValue *kval)
if (kval == NULL) return NULL; if (kval == NULL) return NULL;
val = g_slice_new0 (GValue); 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_init (val, G_TYPE_INT64);
g_value_set_int64 (val, kvp_value_get_gint64 (kval)); g_value_set_int64 (val, kvp_value_get_gint64 (kval));
break; break;
case KVP_TYPE_DOUBLE: case KvpValue::Type::DOUBLE:
g_value_init (val, G_TYPE_DOUBLE); g_value_init (val, G_TYPE_DOUBLE);
g_value_set_double (val, kvp_value_get_double (kval)); g_value_set_double (val, kvp_value_get_double (kval));
break; break;
case KVP_TYPE_BOOLEAN: case KvpValue::Type::NUMERIC:
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); g_value_init (val, GNC_TYPE_NUMERIC);
num = kvp_value_get_numeric (kval); num = kvp_value_get_numeric (kval);
g_value_set_boxed (val, &num); g_value_set_boxed (val, &num);
break; break;
case KVP_TYPE_STRING: case KvpValue::Type::STRING:
g_value_init (val, G_TYPE_STRING); g_value_init (val, G_TYPE_STRING);
g_value_set_string (val, kvp_value_get_string (kval)); g_value_set_string (val, kvp_value_get_string (kval));
break; break;
case KVP_TYPE_GUID: case KvpValue::Type::GUID:
g_value_init (val, GNC_TYPE_GUID); g_value_init (val, GNC_TYPE_GUID);
g_value_set_boxed (val, kvp_value_get_guid (kval)); g_value_set_boxed (val, kvp_value_get_guid (kval));
break; break;
case KVP_TYPE_TIMESPEC: case KvpValue::Type::TIMESPEC:
g_value_init (val, GNC_TYPE_TIMESPEC); g_value_init (val, GNC_TYPE_TIMESPEC);
tm = kvp_value_get_timespec (kval); tm = kvp_value_get_timespec (kval);
g_value_set_boxed (val, &tm); g_value_set_boxed (val, &tm);
break; break;
case KVP_TYPE_GDATE: case KvpValue::Type::GDATE:
g_value_init (val, G_TYPE_DATE); g_value_init (val, G_TYPE_DATE);
gdate = kvp_value_get_gdate (kval); gdate = kvp_value_get_gdate (kval);
g_value_set_boxed (val, &gdate); g_value_set_boxed (val, &gdate);
break; break;
case KVP_TYPE_GLIST: case KvpValue::Type::GLIST:
{ {
GList *gvalue_list = NULL; GList *gvalue_list = NULL;
GList *kvp_list = kvp_value_get_glist (kval); GList *kvp_list = kvp_value_get_glist (kval);
@ -1366,7 +1286,7 @@ gvalue_from_kvp_value (const KvpValue *kval)
break; break;
} }
/* No transfer of KVP frames outside of QofInstance-derived classes! */ /* No transfer of KVP frames outside of QofInstance-derived classes! */
case KVP_TYPE_FRAME: case KvpValue::Type::FRAME:
PWARN ("Error! Attempt to transfer KvpFrame!"); PWARN ("Error! Attempt to transfer KvpFrame!");
default: default:
PWARN ("Error! Invalid KVP Transfer Request!"); PWARN ("Error! Invalid KVP Transfer Request!");

View File

@ -22,7 +22,7 @@
* A KvpFrame is a set of associations between character strings * A KvpFrame is a set of associations between character strings
* (keys) and KvpValue structures. A KvpValue is a union with * (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 * among other things, ints, doubles, strings, guid's, lists, time
* and numeric values. KvpValues may also be other frames, so * and numeric values. KvpValues may also be other frames, so
* KVP is inherently hierarchical. * KVP is inherently hierarchical.
@ -75,44 +75,8 @@ extern "C"
/** Opaque frame structure */ /** Opaque frame structure */
typedef struct KvpFrameImpl KvpFrame; typedef struct KvpFrameImpl KvpFrame;
/** A KvpValue is a union with possible types enumerated in the
* KvpValueType enum. */
typedef struct KvpValueImpl KvpValue; 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 /** @name KvpFrame Constructors
@{ @{
*/ */
@ -420,31 +384,6 @@ gint kvp_frame_compare(const KvpFrame *fa, const KvpFrame *fb);
gint double_compare(double v1, double v2); 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 <b>GLists of kvp_values</b> (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 <b>GList of
* kvp_values</b> (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 <b>GList of
* kvp_values</b> (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 /** @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 /** Value accessors. Those for GncGUID, GList, KvpFrame and
* string are non-copying -- the caller can modify the value * string are non-copying -- the caller can modify the value
* directly. Just don't free it, or you screw up everything. * directly. Just don't free it, or you screw up everything.
@ -642,9 +578,6 @@ void kvp_frame_set_gvalue (KvpFrame *frame, const gchar *key, const GValue *valu
*/ */
void gnc_gvalue_free (GValue *value); 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 #ifdef __cplusplus
} }

View File

@ -1134,11 +1134,11 @@ qof_instance_kvp_add_guid (const QofInstance *inst, const char* path,
inline static gboolean inline static gboolean
kvp_match_guid (KvpValue *v, const char *key, const GncGUID *guid) 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; return FALSE;
auto frame = v->get<KvpFrame*>(); auto frame = v->get<KvpFrame*>();
auto val = frame->get_slot(key); 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; return FALSE;
auto this_guid = val->get<GncGUID*>(); auto this_guid = val->get<GncGUID*>();
@ -1157,10 +1157,10 @@ qof_instance_kvp_has_guid (const QofInstance *inst, const char *path,
switch (v->get_type()) switch (v->get_type())
{ {
case KVP_TYPE_FRAME: case KvpValue::Type::FRAME:
return kvp_match_guid (v, key, guid); return kvp_match_guid (v, key, guid);
break; break;
case KVP_TYPE_GLIST: case KvpValue::Type::GLIST:
{ {
auto list = v->get<GList*>(); auto list = v->get<GList*>();
for (auto node = list; node != NULL; node = node->next) 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()) switch (v->get_type())
{ {
case KVP_TYPE_FRAME: case KvpValue::Type::FRAME:
if (kvp_match_guid (v, key, guid)) if (kvp_match_guid (v, key, guid))
{ {
delete inst->kvp_data->set_path({path}, nullptr); delete inst->kvp_data->set_path({path}, nullptr);
delete v; delete v;
} }
break; break;
case KVP_TYPE_GLIST: case KvpValue::Type::GLIST:
{ {
auto list = v->get<GList*>(); auto list = v->get<GList*>();
for (auto node = list; node != nullptr; node = node->next) 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); auto target_val = target->kvp_data->get_slot(path);
switch (v->get_type()) switch (v->get_type())
{ {
case KVP_TYPE_FRAME: case KvpValue::Type::FRAME:
if (target_val) if (target_val)
target_val->add(v); target_val->add(v);
else else
target->kvp_data->set_path({path}, v); target->kvp_data->set_path({path}, v);
donor->kvp_data->set(path, nullptr); //Contents moved, Don't delete! donor->kvp_data->set(path, nullptr); //Contents moved, Don't delete!
break; break;
case KVP_TYPE_GLIST: case KvpValue::Type::GLIST:
if (target_val) if (target_val)
{ {
auto list = target_val->get<GList*>(); auto list = target_val->get<GList*>();
@ -1305,7 +1305,7 @@ qof_instance_foreach_slot (const QofInstance *inst, const char* path,
void* data) void* data)
{ {
auto slot = inst->kvp_data->get_slot(path); 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; return;
auto frame = slot->get<KvpFrame*>(); auto frame = slot->get<KvpFrame*>();
wrap_param new_data {proc, data}; wrap_param new_data {proc, data};

View File

@ -144,7 +144,7 @@ TEST_F (KvpFrameTest, GetKeys)
assert_contains (keys, k1); assert_contains (keys, k1);
auto frameval = t_root.get_slot(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<KvpFrame*>()->get_keys(); keys = frameval->get<KvpFrame*>()->get_keys();
assert_contains (keys, k2); assert_contains (keys, k2);
assert_contains (keys, k3); assert_contains (keys, k3);
@ -158,7 +158,7 @@ TEST_F (KvpFrameTest, GetLocalSlot)
auto k4 = "top/first"; auto k4 = "top/first";
auto frameval = t_root.get_slot("top"); 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<KvpFrame*>(); auto f1 = frameval->get<KvpFrame*>();
EXPECT_EQ (t_int_val, f1->get_slot(k1)); EXPECT_EQ (t_int_val, f1->get_slot(k1));
EXPECT_EQ (t_str_val, f1->get_slot(k2)); EXPECT_EQ (t_str_val, f1->get_slot(k2));

View File

@ -65,7 +65,7 @@ TEST (KvpValueTest, Add)
auto v4 = new KvpValueImpl {*v3}; auto v4 = new KvpValueImpl {*v3};
auto new_one = v3->add (v4); auto new_one = v3->add (v4);
EXPECT_NE (new_one, v3); 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<GList*> (), nullptr); EXPECT_NE (new_one->get<GList*> (), nullptr);
/* also deletes v3 and v4 because they're "in" new_one */ /* also deletes v3 and v4 because they're "in" new_one */
delete new_one; delete new_one;