[Gnucash-changes] r13621 - gnucash/trunk - Synchronise with QOF
0.6.3. Correct map handling to allow reverse operations and
iteration over hierarchical objects. Improving debug messages
and preventing a crash when loading a map directly.
Standardise QSF backend on gint and gchar. Add new map file.
Neil Williams
codehelp at cvs.gnucash.org
Mon Mar 13 17:52:03 EST 2006
Author: codehelp
Date: 2006-03-13 17:52:02 -0500 (Mon, 13 Mar 2006)
New Revision: 13621
Trac: http://svn.gnucash.org/trac/changeset/13621
Added:
gnucash/trunk/lib/libqof/backend/file/pilot-qsf-gncCustomer.xml
Modified:
gnucash/trunk/ChangeLog
gnucash/trunk/lib/libqof/backend/file/Makefile.am
gnucash/trunk/lib/libqof/backend/file/qsf-backend.c
gnucash/trunk/lib/libqof/backend/file/qsf-map.xsd.xml
gnucash/trunk/lib/libqof/backend/file/qsf-xml-map.c
gnucash/trunk/lib/libqof/backend/file/qsf-xml.c
gnucash/trunk/lib/libqof/backend/file/qsf-xml.h
gnucash/trunk/lib/libqof/qof/deprecated.c
gnucash/trunk/lib/libqof/qof/deprecated.h
gnucash/trunk/lib/libqof/qof/gnc-date.c
Log:
Synchronise with QOF 0.6.3. Correct map handling to allow reverse operations and iteration over hierarchical objects. Improving debug messages and preventing a crash when loading a map directly. Standardise QSF backend on gint and gchar. Add new map file.
Modified: gnucash/trunk/ChangeLog
===================================================================
--- gnucash/trunk/ChangeLog 2006-03-13 21:16:29 UTC (rev 13620)
+++ gnucash/trunk/ChangeLog 2006-03-13 22:52:02 UTC (rev 13621)
@@ -1,3 +1,26 @@
+2006-03-13 Neil Williams <linux at codehelp.co.uk>
+
+ * : Synchronise with external QOF 0.6.3
+
+ * qof/deprecated.c : Tweak.
+ * qof/deprecated.h : Tweak.
+ * qof/gnc-date.c : Use the macro defined in
+ external QOF that avoids a legacy gnucash macro.
+
+ * backend/file/qsf-backend.c : Standardise on gint and gchar.
+ Skip unregistered objects when processing maps.
+ * backend/file/qsf-map.xsd.xml : allow for iteration of hierarchical
+ objects
+ * backend/file/qsf-xml-map.c : Standardise on gint and gchar.
+ Correct map handling to allow reverse operations and iteration
+ over hierarchical objects. Improving debug messages
+ and preventing a crash when loading a map directly.
+ * backend/file/pilot-qsf-gncCustomer.xml : add reverse mapping
+ * backend/file/qsf-xml.c : Standardise on gint and gchar.
+ * backend/file/qsf-xml.h : Standardise on gint and gchar.
+ Support iteration over incoming QSF objects inside map
+ operations. Remove gnucash-specific gettext defines.
+
2006-03-13 Andreas Köhler <andi5.py at gmx.net>
* src/gnome-utils/gnc-plugin-page.c (gnc_plugin_page_add_book):
Modified: gnucash/trunk/lib/libqof/backend/file/Makefile.am
===================================================================
--- gnucash/trunk/lib/libqof/backend/file/Makefile.am 2006-03-13 21:16:29 UTC (rev 13620)
+++ gnucash/trunk/lib/libqof/backend/file/Makefile.am 2006-03-13 22:52:02 UTC (rev 13621)
@@ -23,7 +23,8 @@
qsfschema_DATA = \
qsf-object.xsd.xml \
qsf-map.xsd.xml \
- pilot-qsf-GnuCashInvoice.xml
+ pilot-qsf-GnuCashInvoice.xml \
+ pilot-qsf-gncCustomer.xml
EXTRA_DIST = \
$(qsfschema_DATA) \
Added: gnucash/trunk/lib/libqof/backend/file/pilot-qsf-gncCustomer.xml
===================================================================
--- gnucash/trunk/lib/libqof/backend/file/pilot-qsf-gncCustomer.xml 2006-03-13 21:16:29 UTC (rev 13620)
+++ gnucash/trunk/lib/libqof/backend/file/pilot-qsf-gncCustomer.xml 2006-03-13 22:52:02 UTC (rev 13621)
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<qsf-map xmlns="http://qof.sourceforge.net/">
+ <definition qof_version="3">
+ <define e_type="pilot_address"/>
+ <define e_type="gncBillTerm"/>
+ <define e_type="gncCustomer"/>
+ <define e_type="gncAddress" foreach="true"/>
+ </definition>
+ <object type="gncCustomer">
+ <calculate type="string" value="id"/>
+ <calculate type="string" value="notes">
+ <set>entryNote</set>
+ </calculate>
+ <calculate type="string" value="name">
+ <set>entryCompany</set>
+ </calculate>
+ <calculate type="guid" value="guid"/>
+ <calculate type="guid" value="addr">
+ <set>guid</set>
+ </calculate>
+ <calculate type="guid" value="customer_terms"/>
+ <calculate type="guid" value="shipaddr"/>
+ <calculate type="boolean" value="active">
+ <set>true</set>
+ </calculate>
+ <calculate type="boolean" value="tax table override"/>
+ <calculate type="numeric" value="amount of discount"/>
+ <calculate type="numeric" value="amount of credit"/>
+ </object>
+ <object type="gncAddress">
+ <calculate type="string" value="city">
+ <set>entryZip</set>
+ </calculate>
+ <calculate type="string" value="street">
+ <set>entryAddress</set>
+ </calculate>
+ <calculate type="string" value="fax">
+ <set>entryPhone2</set>
+ </calculate>
+ <calculate type="string" value="number"/>
+ <calculate type="string" value="name">
+ <set>entryFirstname</set>
+ <set>entryLastname</set>
+ </calculate>
+ <calculate type="string" value="email">
+ <set>entryPhone5</set>
+ </calculate>
+ <calculate type="string" value="locality">
+ <set>entryState</set>
+ </calculate>
+ <calculate type="string" value="phone">
+ <set>entryPhone1</set>
+ </calculate>
+ <calculate type="guid" value="guid"/>
+ <calculate type="guid" value="owner">
+ <set>guid</set>
+ </calculate>
+ </object>
+ <object type="gncBillTerm">
+ <calculate type="string" value="description"/>
+ <calculate type="string" value="name"/>
+ <calculate type="string" value="bill type"/>
+ <calculate type="guid" value="guid"/>
+ <calculate type="numeric" value="amount of discount"/>
+ <calculate type="gint32" value="cut off"/>
+ <calculate type="gint32" value="number of days due"/>
+ <calculate type="gint32" value="number of discounted days"/>
+ </object>
+ <object type="pilot_address">
+ <calculate type="string" value="entryCity">
+ <set object="gncAddress">city</set>
+ </calculate>
+ <calculate type="string" value="entryCustom4"/>
+ <calculate type="string" value="entryPhone1">
+ <set object="gncAddress">phone</set>
+ </calculate>
+ <calculate type="string" value="entryZip"/>
+ <calculate type="string" value="entryLastname">
+ <set object="gncAddress">name</set>
+ </calculate>
+ <calculate type="string" value="entryPhone2"/>
+ <calculate type="string" value="entryNote"/>
+ <calculate type="string" value="category"/>
+ <calculate type="string" value="entryFirstname"/>
+ <calculate type="string" value="entryPhone3"/>
+ <calculate type="string" value="entryTitle"/>
+ <calculate type="string" value="entryPhone4"/>
+ <calculate type="string" value="entryCompany">
+ <set object="gncCustomer">name</set>
+ </calculate>
+ <calculate type="string" value="entryPhone5"/>
+ <calculate type="string" value="entryState">
+ <set object="gncAddress">locality</set>
+ </calculate>
+ <calculate type="string" value="entryCustom1"/>
+ <calculate type="string" value="entryAddress">
+ <set object="gncAddress">number</set>
+ </calculate>
+ <calculate type="string" value="entryCustom2"/>
+ <calculate type="string" value="entryCountry"/>
+ <calculate type="string" valuee="entryCustom3"/>
+ </object>
+</qsf-map>
Modified: gnucash/trunk/lib/libqof/backend/file/qsf-backend.c
===================================================================
--- gnucash/trunk/lib/libqof/backend/file/qsf-backend.c 2006-03-13 21:16:29 UTC (rev 13620)
+++ gnucash/trunk/lib/libqof/backend/file/qsf-backend.c 2006-03-13 22:52:02 UTC (rev 13621)
@@ -2,7 +2,7 @@
* qsf-backend.c
*
* Sat Jan 1 15:07:14 2005
- * Copyright 2005 Neil Williams
+ * Copyright 2005, 2006 Neil Williams
* linux at codehelp.co.uk
****************************************************************************/
/*
@@ -42,7 +42,7 @@
{
QofBackend be;
qsf_param *params;
- char *fullpath;
+ gchar *fullpath;
};
typedef struct QSFBackend_s QSFBackend;
@@ -110,6 +110,7 @@
qsf_map_prepare_list(GList **maps)
{
*maps = g_list_prepend(*maps, "pilot-qsf-GnuCashInvoice.xml");
+ *maps = g_list_prepend(*maps, "pilot-qsf-gncCustomer.xml");
return maps;
}
@@ -136,6 +137,7 @@
params->full_kvp_path = NULL;
params->map_ns = NULL;
params->map_files = NULL;
+ params->map_path = NULL;
params->qsf_object_list = NULL;
params->qsf_parameter_hash = g_hash_table_new(g_str_hash, g_str_equal);
params->qsf_default_hash = g_hash_table_new(g_str_hash, g_str_equal);
@@ -170,7 +172,7 @@
}
static gboolean
-qsf_determine_file_type(const char *path)
+qsf_determine_file_type(const gchar *path)
{
struct stat sbuf;
@@ -180,7 +182,7 @@
if (sbuf.st_size == 0) { return TRUE; }
if(is_our_qsf_object(path)) { return TRUE; }
else if(is_qsf_object(path)) { return TRUE; }
- else if(is_qsf_map(path)) { return TRUE; }
+ else if(is_qsf_map(path)) { return TRUE; }
return FALSE;
}
@@ -188,11 +190,11 @@
Just strip the file: from the start of the book_path URL. Locks are not implemented.
*/
static void
-qsf_session_begin(QofBackend *be, QofSession *session, const char *book_path,
+qsf_session_begin(QofBackend *be, QofSession *session, const gchar *book_path,
gboolean ignore_lock, gboolean create_if_nonexistent)
{
QSFBackend *qsf_be;
- char *p, *path;
+ gchar *p, *path;
PINFO (" ignore_lock=%d create_if_nonexistent=%d", ignore_lock, create_if_nonexistent);
g_return_if_fail(be != NULL);
@@ -209,7 +211,7 @@
if (p) {
path = g_strdup (book_path);
if (!g_ascii_strncasecmp(path, "file:", 5)) {
- p = g_new(char, strlen(path) - 5 + 1);
+ p = g_new(gchar, strlen(path) - 5 + 1);
strcpy(p, path + 5);
}
qsf_be->fullpath = g_strdup(p);
@@ -335,14 +337,15 @@
while(object_list != NULL)
{
params->object_set = object_list->data;
+ object_list = g_list_next(object_list);
params->qsf_parameter_hash = params->object_set->parameters;
+ if(!qof_class_is_registered(params->object_set->object_type)) { continue; }
inst = (QofInstance*)qof_object_new_instance(params->object_set->object_type, book);
g_return_val_if_fail(inst != NULL, FALSE);
params->qsf_ent = &inst->entity;
qof_begin_edit(inst);
g_hash_table_foreach(params->qsf_parameter_hash, qsf_object_commitCB, params);
qof_commit_edit(inst);
- object_list = g_list_next(object_list);
}
qof_object_foreach_type(insert_ref_cb, params);
qof_book_set_data(book, ENTITYREFERENCE, params->referenceList);
@@ -352,22 +355,19 @@
/* QofBackend routine to load from file - needs a map.
*/
static gboolean
-load_qsf_object(QofBook *book, const char *fullpath, qsf_param *params)
+load_qsf_object(QofBook *book, const gchar *fullpath, qsf_param *params)
{
xmlNodePtr qsf_root, map_root;
xmlDocPtr mapDoc, foreign_doc;
gchar *map_path, *map_file;
- GList *maps;
- maps = params->map_files;
- map_path = NULL;
+ map_file = params->map_path;
mapDoc = NULL;
- if(!maps) {
+ /* use selected map */
+ if(!map_file) {
qof_backend_set_error(params->be, ERR_QSF_NO_MAP);
- return FALSE;
+ return FALSE;
}
- /* use default maps */
- map_file = g_strdup(maps->data);
foreign_doc = xmlParseFile(fullpath);
if (foreign_doc == NULL) {
qof_backend_set_error(params->be, ERR_FILEIO_PARSE_ERROR);
@@ -391,12 +391,11 @@
params->map_ns = map_root->ns;
params->input_doc = qsf_object_convert(mapDoc, qsf_root, params);
qsfdoc_to_qofbook(params->input_doc, params);
- g_free(map_file);
return TRUE;
}
static gboolean
-load_our_qsf_object(QofBook *book, const char *fullpath, qsf_param *params)
+load_our_qsf_object(QofBook *book, const gchar *fullpath, qsf_param *params)
{
xmlNodePtr qsf_root;
@@ -434,7 +433,7 @@
QSFBackend *qsf_be;
qsf_param *params;
FILE *f;
- char *path;
+ gchar *path;
gboolean result;
g_return_if_fail(be != NULL);
@@ -462,6 +461,7 @@
params->file_type = IS_QSF_OBJ;
result = load_qsf_object(book, path, params);
if(!result) { qof_backend_set_error(be, ERR_FILEIO_PARSE_ERROR); }
+ return;
}
if(result == FALSE) {
if(is_qsf_map_be(params)) {
@@ -556,7 +556,7 @@
static void
-qsf_from_kvp_helper(const char *path, KvpValue *content, gpointer data)
+qsf_from_kvp_helper(const gchar *path, KvpValue *content, gpointer data)
{
qsf_param *params;
QofParam *qof_param;
@@ -741,10 +741,10 @@
QofEntity *choice_ent;
KvpFrame *qsf_kvp;
QofCollection *qsf_coll;
- int param_count;
+ gint param_count;
gboolean own_guid;
const GUID *cm_guid;
- char cm_sa[GUID_ENCODING_LENGTH + 1];
+ gchar cm_sa[GUID_ENCODING_LENGTH + 1];
g_return_if_fail(data != NULL);
params = (qsf_param*)data;
@@ -828,7 +828,7 @@
for( supported = g_slist_copy(params->supported_types);
supported != NULL; supported = g_slist_next(supported))
{
- if(0 == safe_strcmp((const char*)supported->data, (const char*)qof_param->param_type))
+ if(0 == safe_strcmp((const gchar*)supported->data, (const gchar*)qof_param->param_type))
{
node = xmlAddChild(object_node, xmlNewNode(ns, BAD_CAST qof_param->param_type));
string_buffer = g_strdup(qof_book_merge_param_as_string(qof_param, ent));
@@ -954,9 +954,9 @@
}
KvpValue*
-string_to_kvp_value(const char *content, KvpValueType type)
+string_to_kvp_value(const gchar *content, KvpValueType type)
{
- char *tail;
+ gchar *tail;
gint64 cm_i64;
double cm_double;
gnc_numeric cm_numeric;
@@ -1030,7 +1030,7 @@
QofIdType obj_type, reference_type;
struct tm qsf_time;
time_t qsf_time_t;
- char *tail;
+ gchar *tail;
/* cm_ prefix used for variables that hold the data to commit */
gnc_numeric cm_numeric;
double cm_double;
@@ -1038,40 +1038,40 @@
gint32 cm_i32;
gint64 cm_i64;
Timespec cm_date;
- char cm_char, (*char_getter) (xmlNodePtr);
+ gchar cm_char, (*char_getter) (xmlNodePtr);
GUID *cm_guid;
KvpFrame *cm_kvp;
KvpValue *cm_value;
KvpValueType cm_type;
QofSetterFunc cm_setter;
const QofParam *cm_param;
- void (*string_setter) (QofEntity*, const char*);
+ void (*string_setter) (QofEntity*, const gchar*);
void (*date_setter) (QofEntity*, Timespec);
void (*numeric_setter) (QofEntity*, gnc_numeric);
void (*double_setter) (QofEntity*, double);
void (*boolean_setter) (QofEntity*, gboolean);
void (*i32_setter) (QofEntity*, gint32);
void (*i64_setter) (QofEntity*, gint64);
- void (*char_setter) (QofEntity*, char);
+ void (*char_setter) (QofEntity*, gchar);
g_return_if_fail(data && value && key);
params = (qsf_param*)data;
node = (xmlNodePtr)value;
- parameter_name = (const char*)key;
- qof_type = (char*)node->name;
+ parameter_name = (const gchar*)key;
+ qof_type = (gchar*)node->name;
qsf_ent = params->qsf_ent;
targetBook = params->book;
memset (&qsf_time, '\0', sizeof(qsf_time));
cm_date.tv_nsec = 0;
cm_date.tv_sec = 0;
- obj_type = (char*)xmlGetProp(node->parent, BAD_CAST QSF_OBJECT_TYPE);
+ obj_type = (gchar*)xmlGetProp(node->parent, BAD_CAST QSF_OBJECT_TYPE);
if(0 == safe_strcasecmp(obj_type, parameter_name)) { return; }
cm_setter = qof_class_get_parameter_setter(obj_type, parameter_name);
cm_param = qof_class_get_parameter(obj_type, parameter_name);
object_set = params->object_set;
if(safe_strcmp(qof_type, QOF_TYPE_STRING) == 0) {
- string_setter = (void(*)(QofEntity*, const char*))cm_setter;
- if(string_setter != NULL) { string_setter(qsf_ent, (char*)xmlNodeGetContent(node)); }
+ string_setter = (void(*)(QofEntity*, const gchar*))cm_setter;
+ if(string_setter != NULL) { string_setter(qsf_ent, (gchar*)xmlNodeGetContent(node)); }
}
if(safe_strcmp(qof_type, QOF_TYPE_DATE) == 0) {
date_setter = (void(*)(QofEntity*, Timespec))cm_setter;
@@ -1123,7 +1123,7 @@
}
if(safe_strcmp(qof_type, QOF_TYPE_INT64) == 0) {
errno = 0;
- cm_i64 = strtoll((char*)xmlNodeGetContent(node), &tail, 0);
+ cm_i64 = strtoll((gchar*)xmlNodeGetContent(node), &tail, 0);
if(errno == 0) {
i64_setter = (void(*)(QofEntity*, gint64))cm_setter;
if(i64_setter != NULL) { i64_setter(qsf_ent, cm_i64); }
@@ -1132,14 +1132,14 @@
}
if(safe_strcmp(qof_type, QOF_TYPE_DOUBLE) == 0) {
errno = 0;
- cm_double = strtod((char*)xmlNodeGetContent(node), &tail);
+ cm_double = strtod((gchar*)xmlNodeGetContent(node), &tail);
if(errno == 0) {
double_setter = (void(*)(QofEntity*, double))cm_setter;
if(double_setter != NULL) { double_setter(qsf_ent, cm_double); }
}
}
if(safe_strcmp(qof_type, QOF_TYPE_BOOLEAN) == 0){
- if(0 == safe_strcasecmp((char*)xmlNodeGetContent(node),
+ if(0 == safe_strcasecmp((gchar*)xmlNodeGetContent(node),
QSF_XML_BOOLEAN_TEST)) {
cm_boolean = TRUE;
}
@@ -1148,11 +1148,11 @@
if(boolean_setter != NULL) { boolean_setter(qsf_ent, cm_boolean); }
}
if(safe_strcmp(qof_type, QOF_TYPE_KVP) == 0) {
- cm_type = qsf_to_kvp_helper((char*)xmlGetProp(node, BAD_CAST QSF_OBJECT_VALUE));
+ cm_type = qsf_to_kvp_helper((gchar*)xmlGetProp(node, BAD_CAST QSF_OBJECT_VALUE));
if(!cm_type) { return; }
- cm_value = string_to_kvp_value((char*)xmlNodeGetContent(node), cm_type);
+ cm_value = string_to_kvp_value((gchar*)xmlNodeGetContent(node), cm_type);
cm_kvp = (KvpFrame*)cm_param->param_getfcn(qsf_ent, cm_param);
- cm_kvp = kvp_frame_set_value(cm_kvp, (char*)xmlGetProp(node,
+ cm_kvp = kvp_frame_set_value(cm_kvp, (gchar*)xmlGetProp(node,
BAD_CAST QSF_OBJECT_KVP), cm_value);
}
if(safe_strcmp(qof_type, QOF_TYPE_COLLECT) == 0) {
@@ -1164,7 +1164,7 @@
qsf_coll = cm_param->param_getfcn(qsf_ent, cm_param);
type = qof_collection_get_type(qsf_coll);
cm_guid = g_new(GUID, 1);
- if(TRUE != string_to_guid((char*)xmlNodeGetContent(node), cm_guid))
+ if(TRUE != string_to_guid((gchar*)xmlNodeGetContent(node), cm_guid))
{
qof_backend_set_error(params->be, ERR_QSF_BAD_OBJ_GUID);
PINFO (" string to guid collect failed for %s", xmlNodeGetContent(node));
@@ -1185,9 +1185,9 @@
params->referenceList = g_list_append(params->referenceList, reference);
}
if(safe_strcmp(qof_type, QOF_TYPE_CHAR) == 0) {
- char_getter = (char (*)(xmlNodePtr))xmlNodeGetContent;
+ char_getter = (gchar (*)(xmlNodePtr))xmlNodeGetContent;
cm_char = char_getter(node);
- char_setter = (void(*)(QofEntity*, char))cm_setter;
+ char_setter = (void(*)(QofEntity*, gchar))cm_setter;
if(char_setter != NULL) { char_setter(qsf_ent, cm_char); }
}
}
Modified: gnucash/trunk/lib/libqof/backend/file/qsf-map.xsd.xml
===================================================================
--- gnucash/trunk/lib/libqof/backend/file/qsf-map.xsd.xml 2006-03-13 21:16:29 UTC (rev 13620)
+++ gnucash/trunk/lib/libqof/backend/file/qsf-map.xsd.xml 2006-03-13 22:52:02 UTC (rev 13621)
@@ -38,6 +38,7 @@
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="e_type" type="xsd:string"/>
+ <xsd:attribute name="foreach" type="xsd:string" use="optional"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
Modified: gnucash/trunk/lib/libqof/backend/file/qsf-xml-map.c
===================================================================
--- gnucash/trunk/lib/libqof/backend/file/qsf-xml-map.c 2006-03-13 21:16:29 UTC (rev 13620)
+++ gnucash/trunk/lib/libqof/backend/file/qsf-xml-map.c 2006-03-13 22:52:02 UTC (rev 13621)
@@ -38,12 +38,12 @@
static QofLogModule log_module = QOF_MOD_QSF;
static void
-qsf_date_default_handler(const char *default_name, GHashTable *qsf_default_hash,
+qsf_date_default_handler(const gchar *default_name, GHashTable *qsf_default_hash,
xmlNodePtr parent_tag, xmlNodePtr import_node, xmlNsPtr ns)
{
xmlNodePtr output_parent;
time_t *qsf_time;
- char date_as_string[QSF_DATE_LENGTH];
+ gchar date_as_string[QSF_DATE_LENGTH];
output_parent = xmlAddChild(parent_tag, xmlNewNode(ns,
xmlGetProp(import_node, BAD_CAST QSF_OBJECT_TYPE)));
@@ -55,7 +55,7 @@
}
static void
-qsf_string_default_handler(const char *default_name, GHashTable *qsf_default_hash,
+qsf_string_default_handler(const gchar *default_name, GHashTable *qsf_default_hash,
xmlNodePtr parent_tag, xmlNodePtr import_node, xmlNsPtr ns)
{
xmlNodePtr node;
@@ -75,6 +75,7 @@
xmlChar *qof_version, *match;
GString *buff;
xmlNodePtr child_node;
+ QofIdType obj_type;
if (qsf_is_element(child, ns, MAP_DEFINITION_TAG)) {
qof_version = xmlGetProp(child, BAD_CAST MAP_QOF_VERSION);
@@ -97,26 +98,33 @@
}
if(qsf_is_element(child, ns, MAP_OBJECT_TAG)) {
match = NULL;
- match = BAD_CAST g_hash_table_lookup( valid->validation_table,
- xmlGetProp(child, BAD_CAST MAP_TYPE_ATTR));
+ obj_type = xmlGetProp(child, BAD_CAST MAP_TYPE_ATTR);
+ match = BAD_CAST g_hash_table_lookup( valid->validation_table, obj_type);
if(match) {
valid->map_calculated_count++;
+ if(TRUE == qof_class_is_registered((QofIdTypeConst) obj_type))
+ {
+ valid->qof_registered_count++;
+ PINFO (" %s is to be calculated", obj_type);
+ }
+ else { PINFO (" %s to be mapped", obj_type); }
}
}
}
-gboolean is_qsf_object_with_map_be(char *map_file, qsf_param *params)
+gboolean is_qsf_object_with_map_be(gchar *map_file, qsf_param *params)
{
xmlDocPtr doc, map_doc;
- int valid_count;
+ gint valid_count, calc_count;
struct qsf_node_iterate iter;
xmlNodePtr map_root, object_root;
xmlNsPtr map_ns;
qsf_validator valid;
- char *path;
+ gchar *path;
gchar *map_path;
g_return_val_if_fail((params != NULL),FALSE);
+ PINFO (" mapfile=%s", map_file);
path = g_strdup(params->filepath);
map_path = g_strdup_printf("%s/%s", QSF_SCHEMA_DIR, map_file);
if(path == NULL) {
@@ -162,23 +170,39 @@
g_hash_table_destroy(valid.validation_table);
return FALSE;
}
- valid_count = 0 - g_hash_table_size(valid.validation_table);
- valid_count += valid.map_calculated_count;
- valid_count += valid.valid_object_count;
- g_hash_table_destroy(valid.validation_table);
- if(valid_count == 0) {
+ /* check all counted objects are valid */
+ /* Should be:
+ the same number of valid object calculations as there are defined in the map.
+ And the number of calculations must match the number of unregistered
+ objects plus the number of registered objects defined. */
+ valid_count = g_hash_table_size(valid.validation_table) - valid.map_calculated_count;
+ calc_count = valid.map_calculated_count -
+ (valid.valid_object_count + valid.qof_registered_count);
+ if(valid_count == 0 && calc_count == 0) {
+ g_hash_table_destroy(valid.validation_table);
qof_backend_get_error(params->be);
return TRUE;
}
qof_backend_set_error(params->be, ERR_QSF_WRONG_MAP);
/* the object is OK, only the map is wrong. */
+ PINFO (" Map is wrong. map:%d object:%d reg:%d size:%d result:%d",
+ valid.map_calculated_count, valid.valid_object_count,
+ valid.qof_registered_count,
+ g_hash_table_size(valid.validation_table), valid_count);
+ if(valid_count != 0) {
+ PINFO (" size - map != 0. actual: %d.", valid_count);
+ }
+ if(calc_count != 0) {
+ PINFO (" map - (object + registered) != 0. Actual: %d.", calc_count);
+ }
+ g_hash_table_destroy(valid.validation_table);
return TRUE;
}
-gboolean is_qsf_object_with_map(const char *path, char *map_file)
+gboolean is_qsf_object_with_map(const gchar *path, gchar *map_file)
{
xmlDocPtr doc, map_doc;
- int valid_count;
+ gint valid_count;
struct qsf_node_iterate iter;
xmlNodePtr map_root, object_root;
xmlNsPtr map_ns;
@@ -238,7 +262,7 @@
qsf_validator valid;
xmlNodePtr map_root;
xmlNsPtr map_ns;
- char *path;
+ gchar *path;
g_return_val_if_fail((params != NULL),FALSE);
qof_backend_get_error(params->be);
@@ -259,6 +283,7 @@
map_root = xmlDocGetRootElement(doc);
map_ns = map_root->ns;
iter.ns = map_ns;
+ valid.validation_table = g_hash_table_new(g_str_hash, g_str_equal);
valid.error_state = ERR_BACKEND_NO_ERR;
qsf_valid_foreach(map_root, qsf_map_validation_handler, &iter, &valid);
if (valid.error_state != ERR_BACKEND_NO_ERR) {
@@ -271,7 +296,7 @@
return TRUE;
}
-gboolean is_qsf_map(const char *path)
+gboolean is_qsf_map(const gchar *path)
{
xmlDocPtr doc;
struct qsf_node_iterate iter;
@@ -290,6 +315,7 @@
map_ns = map_root->ns;
iter.ns = map_ns;
valid.error_state = ERR_BACKEND_NO_ERR;
+ valid.validation_table = g_hash_table_new(g_str_hash, g_str_equal);
qsf_valid_foreach(map_root, qsf_map_validation_handler, &iter, &valid);
if (valid.error_state != ERR_BACKEND_NO_ERR) {
g_hash_table_destroy(valid.validation_table);
@@ -304,9 +330,16 @@
qsf_map_default_handler(xmlNodePtr child, xmlNsPtr ns, qsf_param *params )
{
xmlChar *qsf_enum;
+ gchar* iterate;
g_return_if_fail(params->qsf_define_hash != NULL);
+ iterate = NULL;
if (qsf_is_element(child, ns, MAP_DEFINE_TAG)) {
+ iterate = xmlGetProp(child, MAP_ITERATE_ATTR);
+ if(qof_util_bool_to_int(iterate) == 1)
+ {
+ params->qof_foreach = xmlGetProp(child, BAD_CAST MAP_E_TYPE);
+ }
if(NULL == g_hash_table_lookup(params->qsf_define_hash,
xmlGetProp(child, BAD_CAST MAP_E_TYPE)))
{
@@ -354,7 +387,7 @@
xmlGetProp(child_node, MAP_NAME_ATTR), child_node))*/
{
qof_backend_set_error(params->be, ERR_QSF_BAD_MAP);
- LEAVE (" ");
+ PERR (" ERR_QSF_BAD_MAP set");
return;
}
}
@@ -370,23 +403,25 @@
if(!params->qsf_define_hash) return;
if(!params->qsf_default_hash) return;
+ ENTER (" child=%s", child->name);
if(qsf_is_element(child, ns, MAP_DEFINITION_TAG)) {
qof_version = xmlGetProp(child, BAD_CAST MAP_QOF_VERSION);
buff = g_string_new(" ");
g_string_printf(buff, "%i", QSF_QOF_VERSION);
if(xmlStrcmp(qof_version, BAD_CAST buff->str) != 0) {
qof_backend_set_error(params->be, ERR_QSF_BAD_QOF_VERSION);
- PERR (" ERR_QSF_BAD_QOF_VERSION set");
+ LEAVE (" ERR_QSF_BAD_QOF_VERSION set");
return;
}
iter.ns = ns;
qsf_node_foreach(child, qsf_map_default_handler, &iter, params);
}
+ LEAVE (" ");
}
static char*
qsf_else_set_value(xmlNodePtr parent, GHashTable *default_hash,
- char *content, xmlNsPtr map_ns)
+ gchar *content, xmlNsPtr map_ns)
{
xmlNodePtr cur_node;
@@ -394,7 +429,7 @@
for(cur_node = parent->children; cur_node != NULL; cur_node = cur_node->next)
{
if(qsf_is_element(cur_node, map_ns, QSF_CONDITIONAL_SET)) {
- content = (char*)xmlNodeGetContent(cur_node);
+ content = (gchar*)xmlNodeGetContent(cur_node);
return content;
}
}
@@ -405,9 +440,9 @@
This function will be overhauled once inside QOF
QOF hook required for "Lookup in the receiving application"
*/
-static char*
+static gchar*
qsf_set_handler(xmlNodePtr parent, GHashTable *default_hash,
- char *content, qsf_param *params)
+ gchar *content, qsf_param *params)
{
xmlNodePtr cur_node, lookup_node;
@@ -417,12 +452,12 @@
{
if(qsf_is_element(cur_node, params->map_ns, QSF_CONDITIONAL_SET))
{
- content = (char*)xmlGetProp(cur_node, BAD_CAST QSF_OPTION);
+ content = (gchar*)xmlGetProp(cur_node, BAD_CAST QSF_OPTION);
if(qsf_strings_equal(xmlGetProp(cur_node, BAD_CAST QSF_OPTION), "qsf_lookup_string"))
{
lookup_node = (xmlNodePtr) g_hash_table_lookup(default_hash,
xmlNodeGetContent(cur_node));
- content = (char*)xmlGetProp(lookup_node, BAD_CAST MAP_VALUE_ATTR);
+ content = (gchar*)xmlGetProp(lookup_node, BAD_CAST MAP_VALUE_ATTR);
/** \todo FIXME: do the lookup. type is defined by output object. */
/* Find by name, get GUID, return GUID as string. */
g_message("Lookup %s in the receiving application\n", content );
@@ -433,17 +468,17 @@
{
lookup_node = (xmlNodePtr) g_hash_table_lookup(default_hash,
xmlNodeGetContent(cur_node));
- content = (char*)xmlGetProp(lookup_node, BAD_CAST "value");
+ content = (gchar*)xmlGetProp(lookup_node, BAD_CAST "value");
return content;
}
- content = (char*)xmlGetProp(parent, BAD_CAST "boolean");
+ content = (gchar*)xmlGetProp(parent, BAD_CAST "boolean");
if(!content) {
/** \todo Check qsf_parameter_hash arguments */
lookup_node = (xmlNodePtr) g_hash_table_lookup(params->qsf_parameter_hash,
xmlGetProp(parent->parent, BAD_CAST MAP_TYPE_ATTR));
- if(lookup_node) { return (char*)xmlNodeGetContent(lookup_node); }
+ if(lookup_node) { return (gchar*)xmlNodeGetContent(lookup_node); }
LEAVE (" check arguments");
- return (char*)xmlNodeGetContent(cur_node);
+ return (gchar*)xmlNodeGetContent(cur_node);
}
}
}
@@ -461,11 +496,11 @@
if(params->boolean_calculation_done == 0) {
output_content = object_data = NULL;
output_content = BAD_CAST qsf_set_handler(param_node,
- params->qsf_default_hash, (char*)output_content, params);
+ params->qsf_default_hash, (gchar*)output_content, params);
if(output_content == NULL) {
output_content = xmlGetProp(param_node, BAD_CAST MAP_TYPE_ATTR);
object_data = BAD_CAST qsf_else_set_value(param_node, params->qsf_default_hash,
- (char*)output_content, params->map_ns);
+ (gchar*)output_content, params->map_ns);
output_content = BAD_CAST xmlGetProp( (xmlNodePtr) g_hash_table_lookup(
params->qsf_default_hash, object_data), BAD_CAST MAP_VALUE_ATTR);
}
@@ -487,10 +522,10 @@
}
static void
-qsf_set_format_value(xmlChar *format, char *qsf_time_now_as_string,
+qsf_set_format_value(xmlChar *format, gchar *qsf_time_now_as_string,
xmlNodePtr cur_node, qsf_param *params)
{
- int result;
+ gint result;
xmlChar *content;
time_t *output;
struct tm *tmp;
@@ -527,7 +562,7 @@
output = &tester;
}
result = regcomp(®, "%[a-zA-Z]", REG_EXTENDED|REG_NOSUB);
- result = regexec(®, (char*)format,(size_t)0,NULL,0);
+ result = regexec(®, (gchar*)format,(size_t)0,NULL,0);
if(result == REG_NOMATCH) { format = BAD_CAST "%F"; }
regfree(®);
/** QSF_DATE_LENGTH preset for all internal and QSF_XSD_TIME string formats.
@@ -538,7 +573,7 @@
static void
qsf_boolean_set_value(xmlNodePtr parent, qsf_param *params,
- char *content, xmlNsPtr map_ns)
+ gchar *content, xmlNsPtr map_ns)
{
xmlNodePtr cur_node;
xmlChar *boolean_name;
@@ -563,7 +598,7 @@
if(params->boolean_calculation_done == 0) {
/* set handler */
output_content = BAD_CAST qsf_set_handler(param_node, params->qsf_default_hash,
- (char*)output_content, params);
+ (gchar*)output_content, params);
/* If the 'if' contains a boolean that has a default value */
if(output_content == NULL) {
if(NULL != xmlGetProp(param_node, BAD_CAST QSF_BOOLEAN_DEFAULT)) {
@@ -574,7 +609,7 @@
/* Is the default set to true? */
if( 0 == qsf_compare_tag_strings(output_content, QSF_XML_BOOLEAN_TEST))
{
- qsf_boolean_set_value(param_node, params, (char*)output_content, params->map_ns);
+ qsf_boolean_set_value(param_node, params, (gchar*)output_content, params->map_ns);
export_node = xmlAddChild(params->lister, xmlNewNode(params->qsf_ns,
xmlGetProp(child, BAD_CAST QSF_OBJECT_TYPE)));
xmlNewProp(export_node, BAD_CAST QSF_OBJECT_TYPE,
@@ -587,8 +622,8 @@
}
}
-static xmlNodePtr
-qsf_add_object_tag(qsf_param *params, int count)
+static void
+qsf_add_object_tag(qsf_param *params, gint count)
{
xmlNodePtr extra_node;
GString *str;
@@ -603,35 +638,60 @@
xmlGetProp(params->convert_node, BAD_CAST QSF_OBJECT_TYPE));
property = xmlCharStrdup(str->str);
xmlNewProp(extra_node, BAD_CAST QSF_OBJECT_COUNT, property);
- return extra_node;
+ params->lister = extra_node;
}
+static gint
+identify_source_func(gconstpointer qsf_object, gconstpointer map)
+{
+ return safe_strcmp(((qsf_objects*)qsf_object)->object_type, (QofIdType)map);
+}
+
static void
+qsf_map_calculate_output(xmlNodePtr param_node, xmlNodePtr child, qsf_param *params)
+{
+ xmlNodePtr export_node;
+ xmlChar *output_content;
+ xmlNodePtr node;
+ GList *source;
+
+ DEBUG (" %s", xmlNodeGetContent(param_node));
+ output_content = xmlNodeGetContent(param_node);
+ /* source refers to the source object that provides the data */
+ source = g_list_find_custom(params->qsf_object_list,
+ BAD_CAST xmlGetProp(param_node, MAP_OBJECT_ATTR), identify_source_func);
+ if(!source) return;
+ params->object_set = source->data;
+ node = g_hash_table_lookup(params->object_set->parameters, output_content);
+ export_node = xmlAddChild(params->lister, xmlNewNode(params->qsf_ns,
+ xmlGetProp(child, BAD_CAST QSF_OBJECT_TYPE)));
+ xmlNewProp(export_node, BAD_CAST QSF_OBJECT_TYPE,
+ xmlGetProp(child, BAD_CAST MAP_VALUE_ATTR));
+ if(node) { xmlNodeAddContent(export_node, xmlNodeGetContent(node)); }
+}
+
+static void
qsf_map_object_handler(xmlNodePtr child, xmlNsPtr ns, qsf_param *params)
{
- xmlNodePtr param_node, export_node;
+ xmlNodePtr param_node;
xmlNsPtr map_ns, qsf_ns;
- xmlChar *output_content;
- int result, count;
+ gint result;
map_ns = ns;
qsf_ns = params->qsf_ns;
param_node = NULL;
result = 0;
- count = params->count;
if(child == NULL) { return; }
if(ns == NULL) { return; }
params->boolean_calculation_done = 0;
if(qsf_is_element(child, map_ns, MAP_CALCULATE_TAG)) {
params->boolean_calculation_done = 0;
+ /* read the child nodes to prepare the calculation. */
for(param_node = child->children; param_node != NULL;
param_node = param_node->next)
{
- output_content = NULL;
- export_node = NULL;
- if(!params->lister) { params->lister = qsf_add_object_tag(params, count); }
- if(qsf_is_element(param_node, map_ns, "set"))
+ if(qsf_is_element(param_node, map_ns, QSF_CONDITIONAL_SET))
{
/* Map the pre-defined defaults */
if(0 == qsf_compare_tag_strings(
@@ -652,25 +712,11 @@
qsf_string_default_handler("qsf_time_string",
params->qsf_default_hash, params->lister, child, qsf_ns);
}
- output_content = xmlNodeGetContent(param_node);
- if(output_content != NULL) {
- output_content = xmlNodeGetContent((xmlNodePtr) g_hash_table_lookup(
- params->qsf_parameter_hash, xmlGetProp(child, BAD_CAST MAP_TYPE_ATTR)));
- if(output_content != NULL) {
- export_node = xmlAddChild(params->lister, xmlNewNode(qsf_ns,
- xmlGetProp(child, BAD_CAST QSF_OBJECT_TYPE)));
- xmlNewProp(export_node, BAD_CAST QSF_OBJECT_TYPE,
- xmlGetProp(child, BAD_CAST MAP_VALUE_ATTR));
- xmlNodeAddContent(export_node, output_content);
- xmlFree(output_content);
- }
- }
+ qsf_map_calculate_output(param_node, child, params);
}
-
qsf_calculate_conditional( param_node, child, params);
qsf_calculate_else(param_node, child, params);
}
-
/* calculate_map currently not in use */
/* ensure uniqueness of the key before re-instating */
/* result = xmlHashAddEntry2(calculate_map,
@@ -688,39 +734,80 @@
}
}
+static void
+iterator_cb(xmlNodePtr child, xmlNsPtr ns, qsf_param *params)
+{
+ gchar *object_name;
+
+ /* count the number of iterators in the QSF file */
+ if(qsf_is_element(child, ns, QSF_OBJECT_TAG))
+ {
+ object_name = xmlGetProp(child, QSF_OBJECT_TYPE);
+ if(0 == safe_strcmp(object_name, params->qof_foreach))
+ {
+ params->foreach_limit++;
+ }
+ }
+}
+
xmlDocPtr
qsf_object_convert(xmlDocPtr mapDoc, xmlNodePtr qsf_root, qsf_param *params)
{
+ /* mapDoc : map document. qsf_root: incoming QSF root node. */
struct qsf_node_iterate iter;
xmlDocPtr output_doc;
xmlNode *cur_node;
- xmlNode *map_root, *output_root, *output_node;
+ xmlNode *map_root, *output_root;
- ENTER (" ");
+ g_return_val_if_fail((mapDoc && qsf_root && params), NULL);
+ ENTER (" root=%s", qsf_root->name);
+ /* prepare the intermediary document */
+ iter.ns = params->qsf_ns;
output_doc = xmlNewDoc(BAD_CAST QSF_XML_VERSION);
- output_root = xmlDocCopyNode(qsf_root,output_doc,2);
+ output_root = xmlNewNode(NULL, BAD_CAST QSF_ROOT_TAG);
+ xmlDocSetRootElement(output_doc, output_root);
xmlSetNs(output_root, params->qsf_ns);
- output_node = NULL;
-
- qsf_node_foreach(qsf_root, qsf_object_node_handler, &iter, params);
+ params->output_node = xmlNewChild(output_root, params->qsf_ns,
+ BAD_CAST QSF_BOOK_TAG, NULL);
+ xmlNewProp(params->output_node, BAD_CAST QSF_BOOK_COUNT, BAD_CAST "1");
+ /* parse the incoming QSF */
+ qsf_book_node_handler(qsf_root->children->next, params->qsf_ns, params);
+ /* parse the map and calculate the values */
map_root = xmlDocGetRootElement(mapDoc);
-
+ params->foreach_limit = 0;
iter.ns = params->map_ns;
qsf_node_foreach(map_root, qsf_map_top_node_handler, &iter, params);
+ /* identify the entities of iterator type. */
+ iter.ns = params->qsf_ns;
+ qsf_node_foreach(qsf_root->children->next, iterator_cb, &iter, params);
+ params->count = 0;
for(cur_node = map_root->children; cur_node != NULL; cur_node = cur_node->next)
{
params->convert_node = cur_node;
- params->count = 0;
if(qsf_is_element(cur_node, params->map_ns, MAP_OBJECT_TAG))
{
+ gint i;
+
params->lister = NULL;
+ /* cur_node describes the target object */
+ if(!qof_class_is_registered(BAD_CAST
+ xmlGetProp(cur_node, MAP_TYPE_ATTR))) { continue; }
+ qsf_add_object_tag(params, params->count);
params->count++;
iter.ns = params->map_ns;
- qsf_node_foreach(cur_node, qsf_map_object_handler, &iter, params);
+ for(i = 0; i < params->foreach_limit; i++)
+ {
+ qsf_node_foreach(cur_node, qsf_map_object_handler, &iter, params);
+ params->qsf_object_list = g_list_next(params->qsf_object_list);
+ qsf_add_object_tag(params, params->count);
+ params->count++;
+ }
}
}
params->file_type = OUR_QSF_OBJ;
+ /* use for debugging */
+ /* xmlSaveFormatFileEnc("-", output_doc, "UTF-8", 1);*/
LEAVE (" ");
return output_doc;
}
Modified: gnucash/trunk/lib/libqof/backend/file/qsf-xml.c
===================================================================
--- gnucash/trunk/lib/libqof/backend/file/qsf-xml.c 2006-03-13 21:16:29 UTC (rev 13620)
+++ gnucash/trunk/lib/libqof/backend/file/qsf-xml.c 2006-03-13 22:52:02 UTC (rev 13621)
@@ -2,7 +2,7 @@
* qsf-xml.c
*
* Fri Nov 26 19:29:47 2004
- * Copyright 2004-2005 Neil Williams <linux at codehelp.co.uk>
+ * Copyright 2004,2005,2006 Neil Williams <linux at codehelp.co.uk>
*
****************************************************************************/
/*
@@ -33,21 +33,21 @@
static QofLogModule log_module = QOF_MOD_QSF;
-int
-qsf_compare_tag_strings(const xmlChar *node_name, char *tag_name)
+gint
+qsf_compare_tag_strings(const xmlChar *node_name, gchar *tag_name)
{
return xmlStrcmp(node_name, (const xmlChar *)tag_name);
}
-int
-qsf_strings_equal(const xmlChar *node_name, char *tag_name)
+gint
+qsf_strings_equal(const xmlChar *node_name, gchar *tag_name)
{
if(0 == qsf_compare_tag_strings(node_name, tag_name)) { return 1; }
return 0;
}
-int
-qsf_is_element(xmlNodePtr a, xmlNsPtr ns, char *c)
+gint
+qsf_is_element(xmlNodePtr a, xmlNsPtr ns, gchar *c)
{
g_return_val_if_fail(a != NULL, 0);
g_return_val_if_fail(ns != NULL, 0);
@@ -57,14 +57,14 @@
return 0;
}
-int
-qsf_check_tag(qsf_param *params, char *qof_type)
+gint
+qsf_check_tag(qsf_param *params, gchar *qof_type)
{
return qsf_is_element(params->child_node, params->qsf_ns, qof_type);
}
gboolean
-qsf_is_valid(const char *schema_dir, const char* schema_filename, xmlDocPtr doc)
+qsf_is_valid(const gchar *schema_dir, const gchar* schema_filename, xmlDocPtr doc)
{
xmlSchemaParserCtxtPtr qsf_schema_file;
xmlSchemaPtr qsf_schema;
@@ -104,6 +104,7 @@
{
xmlNodePtr cur_node;
+ g_return_if_fail(iter->ns);
iter->fcn = &cb;
for(cur_node = parent->children; cur_node != NULL; cur_node = cur_node->next)
{
@@ -138,7 +139,7 @@
}
}
-gboolean is_our_qsf_object(const char *path)
+gboolean is_our_qsf_object(const gchar *path)
{
xmlDocPtr doc;
struct qsf_node_iterate iter;
@@ -167,7 +168,7 @@
return FALSE;
}
-gboolean is_qsf_object(const char *path)
+gboolean is_qsf_object(const gchar *path)
{
xmlDocPtr doc;
@@ -188,7 +189,7 @@
xmlNodePtr object_root;
qsf_validator valid;
gint table_count;
- char *path;
+ gchar *path;
g_return_val_if_fail((params != NULL),FALSE);
path = g_strdup(params->filepath);
@@ -230,7 +231,7 @@
gboolean result;
xmlDocPtr doc;
GList *maps;
- char *path;
+ gchar *path;
g_return_val_if_fail((params != NULL),FALSE);
path = g_strdup(params->filepath);
@@ -257,8 +258,17 @@
/* retrieve list of maps from config frame. */
for(maps = params->map_files; maps; maps=maps->next)
{
+ QofBackendError err;
result = is_qsf_object_with_map_be(maps->data, params);
- if(result) { break;}
+ err = qof_backend_get_error(params->be);
+ if((err == ERR_BACKEND_NO_ERR) && result)
+ {
+ params->map_path = maps->data;
+ PINFO ("map chosen = %s", params->map_path);
+ break;
+ }
+ /* pop the error back on the stack. */
+ else { qof_backend_set_error(params->be, err); }
}
return result;
}
@@ -271,7 +281,7 @@
g_return_if_fail(user_data != NULL);
g_return_if_fail(type != NULL);
params = (qsf_param*) user_data;
- if(qsf_is_element(params->param_node, params->qsf_ns, (char*)type))
+ if(qsf_is_element(params->param_node, params->qsf_ns, (gchar*)type))
{
g_hash_table_insert(params->qsf_parameter_hash,
xmlGetProp(params->param_node, BAD_CAST QSF_OBJECT_TYPE), params->param_node);
@@ -285,27 +295,30 @@
g_slist_foreach(params->supported_types, qsf_supported_data_types, params);
}
-/* Despite the name, this function handles the QSF object book tag
-AND the object tags. */
void
qsf_object_node_handler(xmlNodePtr child, xmlNsPtr qsf_ns, qsf_param *params)
{
struct qsf_node_iterate iter;
qsf_objects *object_set;
- char *tail, *object_count_s;
- int c;
+ gchar *tail, *object_count_s;
+ gint64 c;
g_return_if_fail(child != NULL);
g_return_if_fail(qsf_ns != NULL);
params->qsf_ns = qsf_ns;
if(qsf_is_element(child, qsf_ns, QSF_OBJECT_TAG)) {
params->qsf_parameter_hash = NULL;
+ c = 0;
object_set = g_new(qsf_objects, 1);
params->object_set = object_set;
+ object_set->object_count = 0;
object_set->parameters = g_hash_table_new(g_str_hash, g_str_equal);
- object_set->object_type = g_strdup((char*)xmlGetProp(child, BAD_CAST QSF_OBJECT_TYPE));
- object_count_s = g_strdup((char*)xmlGetProp(child, BAD_CAST QSF_OBJECT_COUNT));
- c = (int)strtol(object_count_s, &tail, 0);
+ object_set->object_type = g_strdup((gchar*)xmlGetProp(child,
+ BAD_CAST QSF_OBJECT_TYPE));
+ object_count_s = g_strdup((gchar*)xmlGetProp(child,
+ BAD_CAST QSF_OBJECT_COUNT));
+ c = (gint64)strtol(object_count_s, &tail, 0);
+ object_set->object_count = (gint)c;
g_free(object_count_s);
params->qsf_object_list = g_list_prepend(params->qsf_object_list, object_set);
iter.ns = qsf_ns;
@@ -317,35 +330,35 @@
void
qsf_book_node_handler(xmlNodePtr child, xmlNsPtr ns, qsf_param *params)
{
- char *book_count_s, *tail;
- int book_count;
+ gchar *book_count_s, *tail;
+ gint book_count;
xmlNodePtr child_node;
struct qsf_node_iterate iter;
gchar *buffer;
GUID book_guid;
+ g_return_if_fail(child);
+ g_return_if_fail(params);
+ ENTER (" child=%s", child->name);
if(qsf_is_element(child, ns, QSF_BOOK_TAG)) {
- book_count_s = (char*)xmlGetProp(child, BAD_CAST QSF_BOOK_COUNT);
+ book_count_s = (gchar*)xmlGetProp(child, BAD_CAST QSF_BOOK_COUNT);
if(book_count_s) {
- book_count = (int)strtol(book_count_s, &tail, 0);
+ book_count = (gint)strtol(book_count_s, &tail, 0);
/* More than one book not currently supported. */
g_return_if_fail(book_count == 1);
}
iter.ns = ns;
- qsf_node_foreach(child, qsf_object_node_handler, &iter, params);
- }
- for(child_node = child->children; child_node != NULL;
- child_node = child_node->next)
- {
+ child_node = child->children->next;
if(qsf_is_element(child_node, ns, QSF_BOOK_GUID)) {
- buffer = g_strdup((char*)xmlNodeGetContent(child_node));
+ DEBUG (" trying to set book GUID");
+ buffer = g_strdup((gchar*)xmlNodeGetContent(child_node));
g_return_if_fail(TRUE == string_to_guid(buffer, &book_guid));
qof_entity_set_guid((QofEntity*)params->book, &book_guid);
+ xmlNewChild(params->output_node, params->qsf_ns,
+ BAD_CAST QSF_BOOK_GUID, BAD_CAST buffer);
g_free(buffer);
}
- if(qsf_is_element(child_node, ns, QSF_OBJECT_TAG)) {
- iter.ns = ns;
- qsf_node_foreach(child_node, qsf_object_node_handler, &iter, params);
- }
+ qsf_node_foreach(child, qsf_object_node_handler, &iter, params);
}
+ LEAVE (" ");
}
Modified: gnucash/trunk/lib/libqof/backend/file/qsf-xml.h
===================================================================
--- gnucash/trunk/lib/libqof/backend/file/qsf-xml.h 2006-03-13 21:16:29 UTC (rev 13620)
+++ gnucash/trunk/lib/libqof/backend/file/qsf-xml.h 2006-03-13 22:52:02 UTC (rev 13621)
@@ -2,7 +2,7 @@
* qsf-xml.h
*
* Fri Nov 26 19:29:47 2004
- * Copyright 2004-2005 Neil Williams <linux at codehelp.co.uk>
+ * Copyright 2004,2005,2006 Neil Williams <linux at codehelp.co.uk>
*
****************************************************************************/
/*
@@ -40,40 +40,9 @@
#include <libxml/xmlschemas.h>
#include "qof.h"
-#if defined(HAVE_GETTEXT) /* HAVE_GETTEXT */
-
#include <libintl.h>
-#include <locale.h>
+#define _(String) gettext (String)
-#undef _
-#undef Q_
-
-#ifdef DISABLE_GETTEXT_UNDERSCORE
-#define _(String) (String)
-#define Q_(String) gnc_qualifier_prefix_noop(String)
-#else /* ENABLE_GETTEXT_UNDERSCORE */
-#define _(String) gettext(String)
-#define Q_(String) gnc_qualifier_prefix_gettext(String)
-#endif /* End ENABLE_GETTEXT_UNDERSCORE */
-
-#else /* Not HAVE_GETTEXT */
-#if !defined(__USE_GNU_GETTEXT)
-
-#undef _
-#undef Q_
-#define _(String) (String)
-#define Q_(String) gnc_qualifier_prefix_noop(String)
-#define gettext(String) (String)
-#define ngettext(msgid, msgid_plural, n) (((n)==1) ? \
- (msgid) : (msgid_plural))
-
-#endif /* End not__USE_GNU_GETTEXT */
-#endif /* End Not HAVE_GETTEXT */
-
-#undef N_
-#define N_(String) (String)
-
-
typedef enum {
QSF_UNDEF = 0, /**< Initial undefined value. */
IS_QSF_MAP, /**< A QSF map */
@@ -94,7 +63,7 @@
{
GHashTable *parameters;
QofIdType object_type;
- int object_count;
+ gint object_count;
}qsf_objects;
#define QSF_QOF_VERSION QOF_OBJECT_VERSION /**< QOF Version check.
@@ -156,6 +125,8 @@
Attributes: e_type Copied directly from the QofObject definition.
Content: The full QofObject description for the defined QOF object.
*/
+#define MAP_ITERATE_ATTR "foreach" /**< Dictate which object type is the basis
+for iteration in a hierarchical object set. */
#define MAP_DEFAULT_TAG "default" /**< User editable defaults for data not
available within the available QSF objects.
@@ -260,6 +231,8 @@
The value of a calculation is the name of the parameter that will be set by that
calculation.
*/
+#define MAP_OBJECT_ATTR "object" /**< The object to use to provide the data
+being set using the map.*/
#define MAP_E_TYPE "e_type" /**< Validates the objects defined in the map
The e_type will be used to match incoming QSF objects with the relevant QSF map.
@@ -373,7 +346,7 @@
{
qsf_type file_type; /**< what type of file is being handled */
qsf_objects *object_set; /**< current object set for qsf_object_list. */
- int count; /**< sequential counter for each object in the book */
+ gint count; /**< sequential counter for each object in the book */
GList *qsf_object_list; /**< list of qsf_objects */
GSList *qsf_sequence; /**< Parameter list sorted into QSF order */
GList *referenceList; /**< Table of references, ::QofEntityReference. */
@@ -390,8 +363,10 @@
xmlNodePtr book_node; /**< Node for the book. */
xmlNodePtr lister; /**< Comparison node for map defaults. */
xmlNsPtr qsf_ns, map_ns; /**< Separate namespaces for QSF objects and QSF maps. */
- const char *qof_type; /**< Holds details of the QOF_TYPE */
+ const gchar *qof_type; /**< Holds details of the QOF_TYPE */
QofIdType qof_obj_type; /**< current QofObject type (e_type) for the parameters. */
+ QofIdType qof_foreach; /**< How to iterate over hierarchical entities. */
+ gint foreach_limit; /**< How many iterations are found in the QSF */
QofEntity *qsf_ent; /**< Current entity in the book. */
QofBackend *be; /**< the current QofBackend for this operation. */
gboolean knowntype; /**< detect references by comparing with known QOF types. */
@@ -400,8 +375,9 @@
Theoretically, QSF can handle multiple QofBooks - currently limited to 1.
*/
- int boolean_calculation_done; /**< simple trip once this boolean is complete. */
- char *filepath; /**< Path to the QSF file. */
+ gint boolean_calculation_done; /**< simple trip once this boolean is complete. */
+ gchar *filepath; /**< Path to the QSF file. */
+ gchar *map_path; /**< Path to best match map, if any. */
gchar* full_kvp_path; /**< Full path for each KvpValue written out. */
gint use_gz_level; /**< Default compression level. */
GList *map_files; /**< List of selected map files for this session.
@@ -418,12 +394,12 @@
typedef struct qsf_validates
{
QofBackendError error_state;
- const char *object_path;
- const char *map_path;
+ const gchar *object_path;
+ const gchar *map_path;
GHashTable *validation_table;
- int valid_object_count;
- int map_calculated_count;
- int qof_registered_count;
+ gint valid_object_count;
+ gint map_calculated_count;
+ gint qof_registered_count;
}qsf_validator;
/** \brief shorthand function
@@ -431,32 +407,32 @@
This may look repetitive but each one is used separately
as well as in a block.
*/
-int
-qsf_compare_tag_strings(const xmlChar *node_name, char *tag_name);
+gint
+qsf_compare_tag_strings(const xmlChar *node_name, gchar *tag_name);
/** \brief shorthand function
This may look repetitive but each one is used separately
as well as in a block.
*/
-int
-qsf_strings_equal(const xmlChar *node_name, char *tag_name);
+gint
+qsf_strings_equal(const xmlChar *node_name, gchar *tag_name);
/** \brief shorthand function
This may look repetitive but each one is used separately
as well as in a block.
*/
-int
-qsf_is_element(xmlNodePtr a, xmlNsPtr ns, char *c);
+gint
+qsf_is_element(xmlNodePtr a, xmlNsPtr ns, gchar *c);
/** \brief shorthand function
This may look repetitive but each one is used separately
as well as in a block.
*/
-int
-qsf_check_tag(qsf_param *params, char *qof_type);
+gint
+qsf_check_tag(qsf_param *params, gchar *qof_type);
/** \brief Checks all incoming objects for QOF registration.
@@ -479,7 +455,7 @@
@return TRUE if the doc validates against the assigned schema, otherwise FALSE.
*/
gboolean
-qsf_is_valid(const char *schema_dir, const char* schema_filename, xmlDocPtr doc);
+qsf_is_valid(const gchar *schema_dir, const gchar* schema_filename, xmlDocPtr doc);
/** \brief Prepare the default list of maps.
@@ -562,7 +538,7 @@
@return TRUE if the file validates and a QSF map can be found,
otherwise FALSE.
*/
-gboolean is_qsf_object(const char *path);
+gboolean is_qsf_object(const gchar *path);
/** \brief Validate a QSF file and determine type.
@param params Pointer to qsf_param context
@@ -592,7 +568,7 @@
@return TRUE if the file validates and all objects pass,
otherwise FALSE.
*/
-gboolean is_our_qsf_object(const char *path);
+gboolean is_our_qsf_object(const gchar *path);
/** \brief Validate a QSF map file.
@param params Pointer to qsf_param context
@@ -621,7 +597,7 @@
@return TRUE if the map validates, otherwise FALSE.
*/
-gboolean is_qsf_map(const char *path);
+gboolean is_qsf_map(const gchar *path);
/** \brief Validate a QSF file and a selected QSF map
@param map_path Absolute or relative path to the selected QSF map file
@@ -637,7 +613,7 @@
@return TRUE if the file validates and the supplied QSF map is usable,
otherwise FALSE.
*/
-gboolean is_qsf_object_with_map_be(char *map_path, qsf_param *params);
+gboolean is_qsf_object_with_map_be(gchar *map_path, qsf_param *params);
/** \brief Validate a QSF file and a selected QSF map
@param map_path Absolute or relative path to the selected QSF map file
@@ -651,7 +627,7 @@
@return TRUE if the file validates and the supplied QSF map is usable,
otherwise FALSE.
*/
-gboolean is_qsf_object_with_map(const char *path, char *map_file);
+gboolean is_qsf_object_with_map(const gchar *path, gchar *map_file);
/** @} */
@@ -676,7 +652,7 @@
@return KvpValue* or NULL on failure.
*/
KvpValue*
-string_to_kvp_value(const char *content, KvpValueType type);
+string_to_kvp_value(const gchar *content, KvpValueType type);
/** Validate the children of the parent node.
Modified: gnucash/trunk/lib/libqof/qof/deprecated.c
===================================================================
--- gnucash/trunk/lib/libqof/qof/deprecated.c 2006-03-13 21:16:29 UTC (rev 13620)
+++ gnucash/trunk/lib/libqof/qof/deprecated.c 2006-03-13 22:52:02 UTC (rev 13621)
@@ -103,4 +103,6 @@
{
qof_book_merge_rule_foreach(mergeData, cb, mergeResult);
}
+
+/* ==================================================================== */
#endif /* QOF_DISABLE_DEPRECATED */
Modified: gnucash/trunk/lib/libqof/qof/deprecated.h
===================================================================
--- gnucash/trunk/lib/libqof/qof/deprecated.h 2006-03-13 21:16:29 UTC (rev 13620)
+++ gnucash/trunk/lib/libqof/qof/deprecated.h 2006-03-13 22:52:02 UTC (rev 13621)
@@ -20,9 +20,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02110-1301, USA.
*/
+#ifndef QOF_DISABLE_DEPRECATED
-#ifndef QOF_DISABLE_DEPRECATED
-
#ifndef _DEPRECATED_H
#define _DEPRECATED_H
#include "qof.h"
Modified: gnucash/trunk/lib/libqof/qof/gnc-date.c
===================================================================
--- gnucash/trunk/lib/libqof/qof/gnc-date.c 2006-03-13 21:16:29 UTC (rev 13620)
+++ gnucash/trunk/lib/libqof/qof/gnc-date.c 2006-03-13 22:52:02 UTC (rev 13621)
@@ -31,6 +31,10 @@
/* to be renamed qofdate.c */
#include <ctype.h>
+#ifdef HAVE_LANGINFO_H
+#define HAVE_LANGINFO_D_FMT 1
+#endif
+
#ifdef HAVE_LANGINFO_D_FMT
#include <langinfo.h>
#endif
More information about the gnucash-changes
mailing list