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.

git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@13621 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Neil Williams 2006-03-13 22:52:02 +00:00
parent f968a871ea
commit 41671fe8a9
11 changed files with 422 additions and 213 deletions

View File

@ -1,3 +1,26 @@
2006-03-13 Neil Williams <linux@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@gmx.net>
* src/gnome-utils/gnc-plugin-page.c (gnc_plugin_page_add_book):

View File

@ -23,7 +23,8 @@ qsfschemadir = $(QOF_XML_DIR)
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) \

View File

@ -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>

View File

@ -2,7 +2,7 @@
* qsf-backend.c
*
* Sat Jan 1 15:07:14 2005
* Copyright 2005 Neil Williams
* Copyright 2005, 2006 Neil Williams
* linux@codehelp.co.uk
****************************************************************************/
/*
@ -42,7 +42,7 @@ struct QSFBackend_s
{
QofBackend be;
qsf_param *params;
char *fullpath;
gchar *fullpath;
};
typedef struct QSFBackend_s QSFBackend;
@ -110,6 +110,7 @@ GList**
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 @@ qsf_param_init(qsf_param *params)
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 @@ qsf_param_init(qsf_param *params)
}
static gboolean
qsf_determine_file_type(const char *path)
qsf_determine_file_type(const gchar *path)
{
struct stat sbuf;
@ -180,7 +182,7 @@ qsf_determine_file_type(const char *path)
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 @@ qsf_determine_file_type(const char *path)
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 @@ qsf_session_begin(QofBackend *be, QofSession *session, const char *book_path,
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 @@ qsfdoc_to_qofbook(xmlDocPtr doc, qsf_param *params)
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 @@ qsfdoc_to_qofbook(xmlDocPtr doc, qsf_param *params)
/* 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 @@ load_qsf_object(QofBook *book, const char *fullpath, qsf_param *params)
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 @@ qsf_file_type(QofBackend *be, QofBook *book)
QSFBackend *qsf_be;
qsf_param *params;
FILE *f;
char *path;
gchar *path;
gboolean result;
g_return_if_fail(be != NULL);
@ -462,6 +461,7 @@ qsf_file_type(QofBackend *be, QofBook *book)
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 @@ kvp_value_to_qof_type_helper(KvpValueType n)
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 @@ qsf_entity_foreach(QofEntity *ent, gpointer data)
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 @@ qsf_entity_foreach(QofEntity *ent, gpointer data)
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 @@ qsf_write_file(QofBackend *be, QofBook *book)
}
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 @@ qsf_object_commitCB(gpointer key, gpointer value, gpointer data)
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 @@ qsf_object_commitCB(gpointer key, gpointer value, gpointer data)
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 @@ qsf_object_commitCB(gpointer key, gpointer value, gpointer data)
}
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 @@ qsf_object_commitCB(gpointer key, gpointer value, gpointer data)
}
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 @@ qsf_object_commitCB(gpointer key, gpointer value, gpointer data)
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_object_commitCB(gpointer key, gpointer value, gpointer data)
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 @@ qsf_object_commitCB(gpointer key, gpointer value, gpointer data)
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); }
}
}

View File

@ -38,6 +38,7 @@ xmlns:qsf-map="http://qof.sourceforge.net/">
<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>

View File

@ -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 @@ qsf_date_default_handler(const char *default_name, GHashTable *qsf_default_hash,
}
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 @@ qsf_map_validation_handler(xmlNodePtr child, xmlNsPtr ns, qsf_validator *valid)
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 @@ qsf_map_validation_handler(xmlNodePtr child, xmlNsPtr ns, qsf_validator *valid)
}
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 @@ gboolean is_qsf_object_with_map_be(char *map_file, qsf_param *params)
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 @@ gboolean is_qsf_map_be(qsf_param *params)
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 @@ gboolean is_qsf_map_be(qsf_param *params)
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 @@ gboolean is_qsf_map_be(qsf_param *params)
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 @@ gboolean is_qsf_map(const char *path)
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 @@ static void
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 @@ qsf_map_default_handler(xmlNodePtr child, xmlNsPtr ns, qsf_param *params )
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 @@ qsf_map_top_node_handler(xmlNodePtr child, xmlNsPtr ns, qsf_param *params)
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 @@ qsf_else_set_value(xmlNodePtr parent, GHashTable *default_hash,
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 @@ qsf_else_set_value(xmlNodePtr parent, GHashTable *default_hash,
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 @@ qsf_set_handler(xmlNodePtr parent, GHashTable *default_hash,
{
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 @@ qsf_set_handler(xmlNodePtr parent, GHashTable *default_hash,
{
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 @@ qsf_calculate_else(xmlNodePtr param_node, xmlNodePtr child, qsf_param *params)
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 @@ qsf_calculate_else(xmlNodePtr param_node, xmlNodePtr child, qsf_param *params)
}
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 @@ qsf_set_format_value(xmlChar *format, char *qsf_time_now_as_string,
output = &tester;
}
result = regcomp(&reg, "%[a-zA-Z]", REG_EXTENDED|REG_NOSUB);
result = regexec(&reg, (char*)format,(size_t)0,NULL,0);
result = regexec(&reg, (gchar*)format,(size_t)0,NULL,0);
if(result == REG_NOMATCH) { format = BAD_CAST "%F"; }
regfree(&reg);
/** QSF_DATE_LENGTH preset for all internal and QSF_XSD_TIME string formats.
@ -538,7 +573,7 @@ qsf_set_format_value(xmlChar *format, char *qsf_time_now_as_string,
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 @@ qsf_calculate_conditional(xmlNodePtr param_node, xmlNodePtr child, qsf_param *pa
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 @@ qsf_calculate_conditional(xmlNodePtr param_node, xmlNodePtr child, qsf_param *pa
/* 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 @@ qsf_calculate_conditional(xmlNodePtr param_node, xmlNodePtr child, qsf_param *pa
}
}
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 @@ qsf_add_object_tag(qsf_param *params, int count)
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_map_object_handler(xmlNodePtr child, xmlNsPtr ns, qsf_param *params)
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 @@ qsf_map_object_handler(xmlNodePtr child, xmlNsPtr ns, qsf_param *params)
}
}
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;
}

View File

@ -2,7 +2,7 @@
* qsf-xml.c
*
* Fri Nov 26 19:29:47 2004
* Copyright 2004-2005 Neil Williams <linux@codehelp.co.uk>
* Copyright 2004,2005,2006 Neil Williams <linux@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 @@ qsf_is_element(xmlNodePtr a, xmlNsPtr ns, char *c)
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 @@ qsf_node_foreach(xmlNodePtr parent, qsf_nodeCB cb,
{
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 @@ qsf_object_validation_handler(xmlNodePtr child, xmlNsPtr ns, qsf_validator *vali
}
}
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 @@ gboolean is_our_qsf_object(const char *path)
return FALSE;
}
gboolean is_qsf_object(const char *path)
gboolean is_qsf_object(const gchar *path)
{
xmlDocPtr doc;
@ -188,7 +189,7 @@ gboolean is_our_qsf_object_be(qsf_param *params)
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 is_qsf_object_be(qsf_param *params)
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 @@ gboolean is_qsf_object_be(qsf_param *params)
/* 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 @@ qsf_supported_data_types(gpointer type, gpointer user_data)
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 @@ qsf_parameter_handler(xmlNodePtr child, xmlNsPtr qsf_ns, qsf_param *params)
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 @@ qsf_object_node_handler(xmlNodePtr child, xmlNsPtr qsf_ns, qsf_param *params)
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 (" ");
}

View File

@ -2,7 +2,7 @@
* qsf-xml.h
*
* Fri Nov 26 19:29:47 2004
* Copyright 2004-2005 Neil Williams <linux@codehelp.co.uk>
* Copyright 2004,2005,2006 Neil Williams <linux@codehelp.co.uk>
*
****************************************************************************/
/*
@ -40,39 +40,8 @@
#include <libxml/xmlschemas.h>
#include "qof.h"
#if defined(HAVE_GETTEXT) /* HAVE_GETTEXT */
#include <libintl.h>
#include <locale.h>
#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)
#define _(String) gettext (String)
typedef enum {
QSF_UNDEF = 0, /**< Initial undefined value. */
@ -94,7 +63,7 @@ typedef struct qsf_object_set
{
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 @@ No text content allowed.
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 calculation where the default is used.
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 @@ typedef struct qsf_metadata
{
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 @@ typedef struct qsf_metadata
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 @@ typedef struct qsf_metadata
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 @@ This is used to determine which backend should load the data.
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 @@ typedef struct qsf_validates
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 @@ Incorrect validation will result in output to the terminal window.
@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 @@ file are defined in the QSF map.
@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 @@ for a QSF map.
@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 @@ user data but are used to import QSF object files from other applications.
@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 @@ This backend twin also sets QofBackendError codes.
@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 @@ file are defined in the QSF map.
@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 @@ value.
@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.

View File

@ -103,4 +103,6 @@ qof_book_mergeRuleForeach(QofBookMergeData *mergeData,
{
qof_book_merge_rule_foreach(mergeData, cb, mergeResult);
}
/* ==================================================================== */
#endif /* QOF_DISABLE_DEPRECATED */

View File

@ -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"

View File

@ -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