kvp frame to template and correcting failure macro

The template avoids the need to cast to and from void*, and adds flexibility to
the targeted function's signature.

test-stuff.h defines a macro, "failure" which is used as an identifier
in the standard IO library, so I moved any inclusion of test-stuff.h to
the last include position so that "failure" wouldn't be defined before
the IO library was included.
This commit is contained in:
lmat
2017-10-05 12:48:37 -04:00
parent eb6c741bf9
commit 34e0d6cfa0
27 changed files with 98 additions and 83 deletions

View File

@@ -57,7 +57,9 @@ Otherwise, only failures are printed out.
#include <glib.h>
#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Privately used to indicate a test result. You may use these if you
* wish, but it's easier to use the do_test macro above.
@@ -150,5 +152,8 @@ gint64 get_random_gint64(void);
double get_random_double(void);
const char* get_random_string_in_array(const char* str_list[]);
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /* TEST_STUFF_H */

View File

@@ -581,81 +581,78 @@ slot_info_copy (slot_info_t* pInfo, GncGUID* guid)
}
static void
save_slot (const char* key, KvpValue* value, gpointer data)
save_slot (const char* key, KvpValue* value, slot_info_t & slot_info)
{
slot_info_t* pSlot_info = (slot_info_t*)data;
g_return_if_fail (value != NULL);
g_return_if_fail (data != NULL);
// Ignore if we've already run into a failure
if (!pSlot_info->is_ok)
if (!slot_info.is_ok)
{
return;
}
auto curlen = pSlot_info->path.length();
pSlot_info->pKvpValue = value;
auto curlen = slot_info.path.length();
slot_info.pKvpValue = value;
if (curlen != 0)
pSlot_info->path += "/";
slot_info.path += "/";
pSlot_info->path += key;
pSlot_info->value_type = value->get_type ();
slot_info.path += key;
slot_info.value_type = value->get_type ();
switch (pSlot_info->value_type)
switch (slot_info.value_type)
{
case KvpValue::Type::FRAME:
{
auto pKvpFrame = value->get<KvpFrame*> ();
auto guid = guid_new ();
slot_info_t* pNewInfo = slot_info_copy (pSlot_info, guid);
KvpValue* oldValue = pSlot_info->pKvpValue;
pSlot_info->pKvpValue = new KvpValue {guid};
pSlot_info->is_ok = pSlot_info->be->do_db_operation(OP_DB_INSERT,
slot_info_t* pNewInfo = slot_info_copy (&slot_info, guid);
KvpValue* oldValue = slot_info.pKvpValue;
slot_info.pKvpValue = new KvpValue {guid};
slot_info.is_ok = slot_info.be->do_db_operation(OP_DB_INSERT,
TABLE_NAME,
TABLE_NAME,
pSlot_info,
&slot_info,
col_table);
g_return_if_fail (pSlot_info->is_ok);
pKvpFrame->for_each_slot (save_slot, pNewInfo);
delete pSlot_info->pKvpValue;
pSlot_info->pKvpValue = oldValue;
g_return_if_fail (slot_info.is_ok);
pKvpFrame->for_each_slot_temp (save_slot, *pNewInfo);
delete slot_info.pKvpValue;
slot_info.pKvpValue = oldValue;
delete pNewInfo;
}
break;
case KvpValue::Type::GLIST:
{
GncGUID* guid = guid_new ();
slot_info_t* pNewInfo = slot_info_copy (pSlot_info, guid);
KvpValue* oldValue = pSlot_info->pKvpValue;
pSlot_info->pKvpValue = new KvpValue {guid}; // Transfer ownership!
pSlot_info->is_ok = pSlot_info->be->do_db_operation(OP_DB_INSERT,
slot_info_t* pNewInfo = slot_info_copy (&slot_info, guid);
KvpValue* oldValue = slot_info.pKvpValue;
slot_info.pKvpValue = new KvpValue {guid}; // Transfer ownership!
slot_info.is_ok = slot_info.be->do_db_operation(OP_DB_INSERT,
TABLE_NAME,
TABLE_NAME,
pSlot_info,
&slot_info,
col_table);
g_return_if_fail (pSlot_info->is_ok);
g_return_if_fail (slot_info.is_ok);
for (auto cursor = value->get<GList*> (); cursor; cursor = cursor->next)
{
auto val = static_cast<KvpValue*> (cursor->data);
save_slot ("", val, pNewInfo);
save_slot ("", val, *pNewInfo);
}
delete pSlot_info->pKvpValue;
pSlot_info->pKvpValue = oldValue;
delete slot_info.pKvpValue;
slot_info.pKvpValue = oldValue;
delete pNewInfo;
}
break;
default:
{
pSlot_info->is_ok = pSlot_info->be->do_db_operation (OP_DB_INSERT,
slot_info.is_ok = slot_info.be->do_db_operation (OP_DB_INSERT,
TABLE_NAME,
TABLE_NAME,
pSlot_info,
&slot_info,
col_table);
}
break;
}
pSlot_info->path.erase(curlen);
slot_info.path.erase(curlen);
}
gboolean
@@ -678,7 +675,7 @@ gnc_sql_slots_save (GncSqlBackend* sql_be, const GncGUID* guid, gboolean is_infa
slot_info.be = sql_be;
slot_info.guid = guid;
pFrame->for_each_slot (save_slot, &slot_info);
pFrame->for_each_slot_temp (save_slot, slot_info);
return slot_info.is_ok;
}

View File

@@ -334,7 +334,7 @@ add_kvp_value_node (xmlNodePtr node, const gchar* tag, KvpValue* val)
auto frame = val->get<KvpFrame*> ();
if (!frame)
break;
frame->for_each_slot (add_kvp_slot, static_cast<void*> (val_node));
frame->for_each_slot_temp (&add_kvp_slot, val_node);
break;
}
default:
@@ -366,6 +366,6 @@ qof_instance_slots_to_dom_tree (const char* tag, const QofInstance* inst)
return nullptr;
ret = xmlNewNode (nullptr, BAD_CAST tag);
frame->for_each_slot (add_kvp_slot, static_cast<void*> (ret));
frame->for_each_slot_temp (&add_kvp_slot, ret);
return ret;
}

View File

@@ -21,7 +21,6 @@ extern "C"
{
#include <config.h>
#include "test-stuff.h"
#include "test-engine-stuff.h"
#include <stdlib.h>
@@ -30,6 +29,7 @@ extern "C"
#include "test-file-stuff.h"
#include "sixtp-utils.h"
#include "sixtp-dom-generators.h"
#include "test-stuff.h"
#define GNC_V2_STRING "gnc-v2"
const gchar* gnc_v2_xml_version_string = GNC_V2_STRING;

View File

@@ -30,7 +30,6 @@ extern "C"
#include <glib.h>
#include "test-stuff.h"
#include "test-engine-stuff.h"
#include "cashobjects.h"
#include "gnc-engine.h"
@@ -44,6 +43,7 @@ extern "C"
#include "sixtp-utils.h"
#include "sixtp-dom-parsers.h"
#include "sixtp-dom-generators.h"
#include "test-stuff.h"
#define GNC_V2_STRING "gnc-v2"
const gchar* gnc_v2_xml_version_string = GNC_V2_STRING;

View File

@@ -34,7 +34,6 @@ extern "C"
#include "gnc-module.h"
#include "gnc-engine.h"
#include "test-stuff.h"
#include "test-engine-stuff.h"
}
@@ -43,6 +42,7 @@ extern "C"
#include "io-gncxml-v2.h"
#include "io-example-account.h"
#include "test-stuff.h"
static const gchar* da_ending = ".gnucash-xea";

View File

@@ -45,7 +45,6 @@ extern "C"
#include <gnc-engine.h>
#include <gnc-prefs.h>
#include <test-stuff.h>
#include <unittest-support.h>
#include <test-engine-stuff.h>
}
@@ -53,6 +52,7 @@ extern "C"
#include "../gnc-backend-xml.h"
#include "../io-gncxml-v2.h"
#include "test-file-stuff.h"
#include <test-stuff.h>
#define GNC_LIB_NAME "gncmod-backend-xml"
#define GNC_LIB_REL_PATH "xml"

View File

@@ -30,7 +30,6 @@ extern "C"
#include <stdlib.h>
#include <string.h>
#include "test-stuff.h"
#include "test-engine-stuff.h"
#include "gnc-engine.h"
@@ -39,6 +38,7 @@ extern "C"
#include "test-file-stuff.h"
#include "io-gncxml-v2.h"
#include "test-stuff.h"
const char* possible_envs[] =
{

View File

@@ -24,13 +24,13 @@ extern "C"
#include <stdlib.h>
#include "gnc-engine.h"
#include "test-stuff.h"
#include "test-engine-stuff.h"
}
#include "test-file-stuff.h"
#include "sixtp-dom-parsers.h"
#include "sixtp-dom-generators.h"
#include "test-stuff.h"
#define GNC_V2_STRING "gnc-v2"

View File

@@ -32,7 +32,6 @@ extern "C"
#include <gnc-engine.h>
#include <cashobjects.h>
#include <test-stuff.h>
#include <test-engine-stuff.h>
#include <unittest-support.h>
@@ -45,6 +44,7 @@ extern "C"
#include "../sixtp-parsers.h"
#include "../sixtp-dom-parsers.h"
#include "test-file-stuff.h"
#include <test-stuff.h>
static QofBook* sixbook;

View File

@@ -28,7 +28,6 @@ extern "C"
#include "gnc-module.h"
#include "qof.h"
#include "test-stuff.h"
#include "test-engine-stuff.h"
#include "Account.h"
@@ -41,6 +40,7 @@ extern "C"
#include "sixtp-dom-parsers.h"
#include "io-gncxml-gen.h"
#include "test-file-stuff.h"
#include "test-stuff.h"
static QofBook* book;

View File

@@ -34,7 +34,6 @@ extern "C"
#include "gnc-engine.h"
#include "gnc-pricedb.h"
#include "test-stuff.h"
#include "test-engine-stuff.h"
}
@@ -45,6 +44,7 @@ extern "C"
#include "sixtp-dom-parsers.h"
#include "io-gncxml-v2.h"
#include "test-file-stuff.h"
#include "test-stuff.h"
static QofSession* session;
static int iter;

View File

@@ -38,7 +38,6 @@ extern "C"
#include <cashobjects.h>
#include <TransLog.h>
#include <test-stuff.h>
#include <test-engine-stuff.h>
#include <unittest-support.h>
@@ -53,7 +52,7 @@ extern "C"
#include "../sixtp-dom-parsers.h"
#include "../io-gncxml-gen.h"
#include "test-file-stuff.h"
#include <test-stuff.h>
static QofBook* book;
extern gboolean gnc_transaction_xml_v2_testing;

View File

@@ -23,12 +23,12 @@ extern "C"
#include <stdlib.h>
#include <string.h>
#include "test-stuff.h"
#include "test-engine-stuff.h"
}
#include "io-gncxml-v2.h"
#include "test-file-stuff.h"
#include "test-stuff.h"
#define FILENAME "Money95bank_fr.gml2"

View File

@@ -30,9 +30,9 @@
extern "C"
{
#include "gnc-aqbanking-templates.h"
#include "qofinstance-p.h"
}
#include "qofinstance-p.h"
#include "kvp-frame.hpp"
#include "gnc-rational.hpp"

View File

@@ -214,20 +214,6 @@ KvpFrameImpl::get_keys() const noexcept
return ret;
}
void
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(),
[proc,data](const KvpFrameImpl::map_type::value_type & a)
{
proc (a.first, a.second, data);
}
);
}
KvpValueImpl *
KvpFrameImpl::get_slot(const char * key) const noexcept
{

View File

@@ -204,11 +204,15 @@ struct KvpFrameImpl
* @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 (*)(char const *key, KvpValue*, void*data), void*data) const noexcept;
/** The function should be of the form:
* <anything> func (char const *, KvpValue *, data_type &);
* Do not pass nullptr for the function.
*/
void for_each_slot(void (*proc)(const char *key, KvpValue *value,
void * data),
void *data) const noexcept;
template <typename func_type, typename data_type>
void for_each_slot_temp (func_type const &, data_type &) const noexcept;
/** Test for emptiness
* @return true if the frame contains nothing.
@@ -220,6 +224,18 @@ struct KvpFrameImpl
map_type m_valuemap;
};
template <typename func_type, typename data_type>
void KvpFrame::for_each_slot_temp(func_type const & func, data_type & data) const noexcept
{
std::for_each (m_valuemap.begin(), m_valuemap.end(),
[&func,&data](const KvpFrameImpl::map_type::value_type & a)
{
func (a.first, a.second, data);
}
);
}
int compare (const KvpFrameImpl &, const KvpFrameImpl &) noexcept;
int compare (const KvpFrameImpl *, const KvpFrameImpl *) noexcept;
/** @} Doxygen Group */

View File

@@ -45,12 +45,12 @@ extern "C"
{
#include "qofbackend.h"
#include "qofbook.h"
#include "qofinstance-p.h"
#include "qofquery.h"
#include "qofsession.h"
#include <gmodule.h>
}
#include "qofinstance-p.h"
#include <string>
#include <algorithm>
#include <vector>

View File

@@ -1118,7 +1118,7 @@ static void commit_err (G_GNUC_UNUSED QofInstance *inst, QofBackendError errcode
#define GNC_FEATURES "features"
static void
add_feature_to_hash (const gchar *key, KvpValue *value, gpointer user_data)
add_feature_to_hash (const gchar *key, KvpValue *value, GHashTable * user_data)
{
gchar *descr = g_strdup(value->get<const char*>());
g_hash_table_insert (*(GHashTable**)user_data, (gchar*)key, descr);
@@ -1134,8 +1134,8 @@ qof_book_get_features (QofBook *book)
auto slot = frame->get_slot(GNC_FEATURES);
if (slot != nullptr)
{
frame = slot->get<KvpFrame*>();
frame->for_each_slot(&add_feature_to_hash, &features);
frame = slot->get<KvpFrame*>();
frame->for_each_slot_temp(&add_feature_to_hash, features);
}
return features;
}

View File

@@ -33,6 +33,8 @@
#include "qofinstance.h"
#ifdef __cplusplus
#include "kvp-frame.hpp"
#include <string>
extern "C"
{
#endif
@@ -156,8 +158,19 @@ void qof_instance_foreach_slot (const QofInstance *inst, const char *path,
void(*proc)(const char*, const GValue*, void*),
void* data);
#ifdef __cplusplus
} /* extern "C" */
/* Don't pass nullptr as the function */
template<typename func_type, typename data_type>
void qof_instance_foreach_slot_temp (QofInstance const * inst, std::string const & path,
func_type const & func, data_type & data)
{
auto slot = inst->kvp_data->get_slot(path.c_str());
if (slot == nullptr || slot->get_type() != KvpValue::Type::FRAME)
return;
auto frame = slot->get<KvpFrame*>();
frame->for_each_slot(func, data);
}
#endif
#endif /* QOF_INSTANCE_P_H */

View File

@@ -1278,10 +1278,9 @@ struct wrap_param
};
}
static void
wrap_gvalue_function (const char* key, KvpValue *val, gpointer data)
wrap_gvalue_function (const char* key, KvpValue *val, wrap_param & param)
{
GValue *gv;
auto param = static_cast<wrap_param*>(data);
if (val->get_type() != KvpValue::Type::FRAME)
gv = gvalue_from_kvp_value(val);
else
@@ -1290,7 +1289,7 @@ wrap_gvalue_function (const char* key, KvpValue *val, gpointer data)
g_value_init (gv, G_TYPE_STRING);
g_value_set_string (gv, nullptr);
}
param->proc(key, gv, param->user_data);
param.proc(key, gv, param.user_data);
g_slice_free (GValue, gv);
}
@@ -1304,7 +1303,7 @@ qof_instance_foreach_slot (const QofInstance *inst, const char* path,
return;
auto frame = slot->get<KvpFrame*>();
wrap_param new_data {proc, data};
frame->for_each_slot(wrap_gvalue_function, &new_data);
frame->for_each_slot_temp(&wrap_gvalue_function, new_data);
}
/* ========================== END OF FILE ======================= */

View File

@@ -50,12 +50,12 @@ extern "C"
#include <glib.h>
#include "qof.h"
#include "qofbook-p.h"
#include "qofobject-p.h"
static QofLogModule log_module = QOF_MOD_SESSION;
} //extern 'C'
#include "qofbook-p.h"
#include "qof-backend.hpp"
#include "qofsession.hpp"
#include "gnc-backend-prov.hpp"

View File

@@ -55,7 +55,6 @@ extern "C"
#include <string.h>
#include <sys/stat.h>
#include <qof.h>
#include <qofinstance-p.h>
#include "Account.h"
#include "AccountP.h"
@@ -71,6 +70,7 @@ extern "C"
#include "test-stuff.h"
#include "test-engine-strings.h"
}
#include <qofinstance-p.h>
static gboolean glist_strings_only = FALSE;

View File

@@ -25,9 +25,9 @@ extern "C"
#include <config.h>
#include "../Account.h"
#include <qof.h>
#include <qofinstance-p.h>
}
#include <qofinstance-p.h>
#include <kvp-frame.hpp>
#include <gtest/gtest.h>

View File

@@ -32,10 +32,10 @@ extern "C"
#include "qof.h"
#include "Account.h"
#include "cashobjects.h"
#include "test-stuff.h"
#include "test-engine-stuff.h"
#include <qofinstance-p.h>
}
#include <qofinstance-p.h>
#include "test-stuff.h"
static void
run_test (void)

View File

@@ -27,7 +27,6 @@ extern "C"
#include <unittest-support.h>
#include <gnc-event.h>
#include <gnc-date.h>
#include <qofinstance-p.h>
/* Add specific headers for this class */
#include "../Account.h"
#include "../AccountP.h"
@@ -42,6 +41,7 @@ static const gchar *suitename = "/engine/Account";
void test_suite_account (void);
}
#include <qofinstance-p.h>
#include <kvp-frame.hpp>
typedef struct

View File

@@ -35,7 +35,6 @@ extern "C"
#include <TransactionP.h>
#include <gnc-lot.h>
#include <gnc-event.h>
#include <qofinstance-p.h>
#if defined(__clang__) && (__clang_major__ == 5 || (__clang_major__ == 3 && __clang_minor__ < 5))
#define USE_CLANG_FUNC_SIG 1
@@ -45,6 +44,7 @@ static const gchar *suitename = "/engine/Split";
void test_suite_split ( void );
}
#include <qofinstance-p.h>
#include <kvp-frame.hpp>
typedef struct