mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
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.
This commit is contained 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
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -38,7 +38,6 @@
|
||||
#include "guile-mappings.h"
|
||||
#include "gnc-guile-utils.h"
|
||||
#include <qof.h>
|
||||
#include <kvp_frame.h>
|
||||
#include <qofbookslots.h>
|
||||
|
||||
/** \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)
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
#include <libguile.h>
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "config.h"
|
||||
|
||||
#include <qof.h>
|
||||
#include <kvp_frame.h>
|
||||
#include <libguile.h>
|
||||
#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 <kvp_frame.hpp>
|
||||
|
||||
/* 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<KvpFrame*>(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<int64_t>());
|
||||
break;
|
||||
case KVP_TYPE_DOUBLE:
|
||||
return scm_from_double (kvp_value_get_double(val));
|
||||
return scm_from_double (val->get<double>());
|
||||
break;
|
||||
case KVP_TYPE_NUMERIC:
|
||||
return gnc_numeric_to_scm(kvp_value_get_numeric(val));
|
||||
return gnc_numeric_to_scm(val->get<gnc_numeric>());
|
||||
break;
|
||||
case KVP_TYPE_STRING:
|
||||
string = kvp_value_get_string(val);
|
||||
{
|
||||
auto string = val->get<const char*>();
|
||||
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<Timespec>());
|
||||
break;
|
||||
|
||||
case KVP_TYPE_FRAME:
|
||||
{
|
||||
KvpFrame *frame = kvp_value_get_frame(val);
|
||||
if (frame)
|
||||
auto frame = val->get<KvpFrame*>();
|
||||
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<GDate>()));
|
||||
|
||||
/* FIXME: handle types below */
|
||||
case KVP_TYPE_GLIST:
|
||||
@@ -1,11 +1,18 @@
|
||||
#ifndef KVP_SCM_H
|
||||
#define KVP_SCM_H
|
||||
|
||||
#include "qof.h"
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
#include <qof.h>
|
||||
#include <libguile.h>
|
||||
|
||||
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 */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user