[Gnucash-changes] r12299 - gnucash/trunk - QOF 0.6.1 release update

Neil Williams codehelp at cvs.gnucash.org
Sun Jan 8 12:51:34 EST 2006


Author: codehelp
Date: 2006-01-08 12:51:29 -0500 (Sun, 08 Jan 2006)
New Revision: 12299
Trac: http://svn.gnucash.org/trac/changeset/12299

Added:
   gnucash/trunk/lib/libqof/qof/deprecated.c
   gnucash/trunk/lib/libqof/qof/deprecated.h
   gnucash/trunk/lib/libqof/qof/qoflog.c
   gnucash/trunk/lib/libqof/qof/qoflog.h
Removed:
   gnucash/trunk/lib/libqof/qof/gnc-trace.c
   gnucash/trunk/lib/libqof/qof/gnc-trace.h
Modified:
   gnucash/trunk/configure.in
   gnucash/trunk/lib/libqof/backend/file/pilot-qsf-GnuCashInvoice.xml
   gnucash/trunk/lib/libqof/backend/file/qof-backend-qsf.h
   gnucash/trunk/lib/libqof/backend/file/qsf-backend.c
   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/Makefile.am
   gnucash/trunk/lib/libqof/qof/gnc-date.c
   gnucash/trunk/lib/libqof/qof/gnc-date.h
   gnucash/trunk/lib/libqof/qof/gnc-engine-util.h
   gnucash/trunk/lib/libqof/qof/gnc-event-p.h
   gnucash/trunk/lib/libqof/qof/gnc-event.c
   gnucash/trunk/lib/libqof/qof/gnc-event.h
   gnucash/trunk/lib/libqof/qof/gnc-numeric.c
   gnucash/trunk/lib/libqof/qof/gnc-numeric.h
   gnucash/trunk/lib/libqof/qof/guid.c
   gnucash/trunk/lib/libqof/qof/guid.h
   gnucash/trunk/lib/libqof/qof/kvp-util.h
   gnucash/trunk/lib/libqof/qof/kvp_frame.c
   gnucash/trunk/lib/libqof/qof/kvp_frame.h
   gnucash/trunk/lib/libqof/qof/qof-be-utils.h
   gnucash/trunk/lib/libqof/qof/qof.h
   gnucash/trunk/lib/libqof/qof/qof_book_merge.c
   gnucash/trunk/lib/libqof/qof/qof_book_merge.h
   gnucash/trunk/lib/libqof/qof/qofbackend-p.h
   gnucash/trunk/lib/libqof/qof/qofbackend.c
   gnucash/trunk/lib/libqof/qof/qofbook-p.h
   gnucash/trunk/lib/libqof/qof/qofbook.c
   gnucash/trunk/lib/libqof/qof/qofbook.h
   gnucash/trunk/lib/libqof/qof/qofchoice.c
   gnucash/trunk/lib/libqof/qof/qofchoice.h
   gnucash/trunk/lib/libqof/qof/qofclass-p.h
   gnucash/trunk/lib/libqof/qof/qofclass.c
   gnucash/trunk/lib/libqof/qof/qofgobj.c
   gnucash/trunk/lib/libqof/qof/qofgobj.h
   gnucash/trunk/lib/libqof/qof/qofid-p.h
   gnucash/trunk/lib/libqof/qof/qofid.c
   gnucash/trunk/lib/libqof/qof/qofid.h
   gnucash/trunk/lib/libqof/qof/qofinstance-p.h
   gnucash/trunk/lib/libqof/qof/qofinstance.c
   gnucash/trunk/lib/libqof/qof/qofobject-p.h
   gnucash/trunk/lib/libqof/qof/qofobject.c
   gnucash/trunk/lib/libqof/qof/qofquery-deserial.c
   gnucash/trunk/lib/libqof/qof/qofquery-deserial.h
   gnucash/trunk/lib/libqof/qof/qofquery-serialize.c
   gnucash/trunk/lib/libqof/qof/qofquery-serialize.h
   gnucash/trunk/lib/libqof/qof/qofquery.c
   gnucash/trunk/lib/libqof/qof/qofquery.h
   gnucash/trunk/lib/libqof/qof/qofquerycore.c
   gnucash/trunk/lib/libqof/qof/qofquerycore.h
   gnucash/trunk/lib/libqof/qof/qofsession.c
   gnucash/trunk/lib/libqof/qof/qofsession.h
   gnucash/trunk/lib/libqof/qof/qofsql.c
   gnucash/trunk/lib/libqof/qof/qofsql.h
Log:
QOF 0.6.1 release update

Modified: gnucash/trunk/configure.in
===================================================================
--- gnucash/trunk/configure.in	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/configure.in	2006-01-08 17:51:29 UTC (rev 12299)
@@ -436,8 +436,8 @@
 	QOF_VERSION="internal"
 	QOF_PREFIX="internal"
 	QOF_XML_DIR=`eval echo ${datadir}/xml/qsf`
-	LIBQOF_LIBRARY_VERSION=1:1:0
-	LIBQOF_BACKEND_QSF_LIBRARY_VERSION=0:0:0
+	LIBQOF_LIBRARY_VERSION=1:2:0
+	LIBQOF_BACKEND_QSF_LIBRARY_VERSION=0:1:0
 	AC_SUBST(LIBQOF_LIBRARY_VERSION)
 	AC_SUBST(LIBQOF_BACKEND_QSF_LIBRARY_VERSION)
   	AC_DEFINE(HAVE_LIBQOF,,[We will use the internal QOF code])

Modified: gnucash/trunk/lib/libqof/backend/file/pilot-qsf-GnuCashInvoice.xml
===================================================================
--- gnucash/trunk/lib/libqof/backend/file/pilot-qsf-GnuCashInvoice.xml	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/backend/file/pilot-qsf-GnuCashInvoice.xml	2006-01-08 17:51:29 UTC (rev 12299)
@@ -5,13 +5,13 @@
 <qsf-map
 xmlns="http://qof.sourceforge.net/">
 <definition qof_version="3">
-  <define e_type="pilot_expenses">Pilot-link QOF expenses</define>
-  <define e_type="pilot_datebook">Pilot-link QOF datebook</define>
-  <define e_type="pilot_address">Pilot-link QOF address</define>
-  <define e_type="gncInvoice">Invoice</define>
-  <define e_type="Trans">Transaction</define>
-  <define e_type="gncEntry">Order/Invoice/Bill Entry</define>
-  <default name="mileage_rate" type="numeric" value="28/100"/>
+  <define e_type="pilot_expenses"/>
+  <define e_type="pilot_datebook"/>
+  <define e_type="pilot_address"/>
+  <define e_type="gncInvoice"/>
+  <define e_type="Trans"/>
+  <define e_type="gncEntry"/>
+  <default name="mileage_rate" type="numeric" value="30/100"/>
   <default name="use_weekday_descriptor" type="boolean" value="true"/>
   <default name="use_discount" type="boolean" value="false"/>
   <default name="tax_included" type="boolean" value="false"/>
@@ -29,20 +29,28 @@
     <if boolean="use_weekday_descriptor">
       <set format="%A">expense_date</set>
     </if>
-    <else type="qof_expenses">
+    <else type="pilot_expenses">
       <set>expense_vendor</set>
     </else>
+    <else type="pilot_datebook">
+      <set>description</set>
+    </else>
   </calculate>
   <calculate type="string" value="action">
-    <if type="qof-expenses">
+    <if type="pilot_expenses">
       <set>Material</set>
     </if>
-    <else type="qof-datebook">
+    <else type="pilot_datebook">
       <set>Hours</set>
     </else>
   </calculate>
   <calculate type="string" value="notes">
-    <set object="qof-expenses">expense_note</set>
+    <if type="pilot-expenses">
+      <set>expense_note</set>
+    </if>
+    <else type="pilot_datebook">
+      <set>note</set>
+    </else>
   </calculate>
   <calculate type="guid" value="bill-to"/>
   <calculate type="boolean" value="invoice-taxable"/>
@@ -54,20 +62,18 @@
   </calculate>
   <calculate type="numeric" value="iprice">
     <if type="string" value="expense_type">
-      <equals type="string" value="etMileage">
+      <equals type="string" value="Mileage">
         <set>mileage_rate</set>
       </equals>
     </if>
   </calculate>
   <calculate type="numeric" value="bprice"/>
   <calculate type="numeric" value="qty">
-    <if string="expense_type">
-      <equals type="string" value="etMileage">
-        <set object="qof-expenses">expense_amount</set>
-      </equals>
+    <if type="pilot_datebook">
+      <set>end_time-start_time</set>
     </if>
-    <else type="string" value="expense_type">
-      <set>0/1</set>
+    <else type="pilot_expenses">
+      <set>expense_amount</set>
     </else>
   </calculate>
   <calculate type="numeric" value="invoice-discount">

Modified: gnucash/trunk/lib/libqof/backend/file/qof-backend-qsf.h
===================================================================
--- gnucash/trunk/lib/libqof/backend/file/qof-backend-qsf.h	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/backend/file/qof-backend-qsf.h	2006-01-08 17:51:29 UTC (rev 12299)
@@ -18,8 +18,7 @@
  *
  *  You should have received a copy of the GNU General Public License
  *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- *  02110-1301, USA.
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
  
 /** @addtogroup Backend
@@ -101,12 +100,7 @@
 	- Adding more map support, some parts of the map are still not coded. equals, 
 		variables and the conditional logic may not be up to the task of the
 		datebook repetition calculations.
-	- Rationalise the API - remove functions that shouldn't be public.
 
-\todo QOF contains numerous g_string_sprintf and g_string_sprintfa calls.
-	These are deprecated and should be renamed to g_string_printf and g_string_append_printf
-	respectively.
-
 QSF is in three sections:
 	- QSF Backend : a QofBackend for file:/ QSF objects and maps.
 		qsf-backend.c
@@ -114,38 +108,95 @@
 		qsf-xml.c
 	- QSF Map : Validation, processing and conversion routines.
 		qsf-xml-map.c
+		
+To work with QSF, your QOF objects must have:
+	- a create: function in the QofObject definition
+	- a foreach: function in the QofObject definition
+	- QofParam params[] registered with QOF using
+		qof_class_register and containing all necessary parameters
+		to reconstruct this object without any further information.
+	- Logical distinction between those parameters that should be
+		set (have a QofAccessFunc and QofSetterFunc) and those that 
+		should only be calculated (only a QofAccessFunc).
 
+If you begin your QSF session with ::QOF_STDOUT as the book_id,
+QSF will write to STDOUT - usually a terminal. This is used by QOF
+applications to provide data streaming. If you don't want terminal
+output, take care to check the path given to 
+::qof_session_begin - don't try to change it later!
+
+The XML is validated against the QSF object schema before being
+written (to file or stdout).
+
+Check the QofBackendError - don't assume the file is OK.
+
     @{ */
 /** @file qof-backend-qsf.h
-    @brief  QSF API - Backend, maps and objects.
+    @brief  QSF API - Backend, maps, objects and configuration.
     @author Copyright (C) 2004-2005 Neil Williams <linux at codehelp.co.uk>
 */
 
 #ifndef _QOF_BACKEND_QSF_H
 #define _QOF_BACKEND_QSF_H
 
-#include "gnc-trace.h"
+#include "qoflog.h"
 #include "qofbackend.h"
 #include "qof-be-utils.h"
 
-#define QOF_MOD_QSF "qof-backend-qsf"
-
 /** \brief Describe this backend to the application. 
 
-Sets QSF Backend Version 0.1, access method = file:
+Sets QSF Backend Version 0.2, access method = file:
 
-This is the QOF backend interface, not a GnuCash module.
+The version number only changes if:
+-# The map schema is modified, or
+-# The object schema is modified, or
+-# The QofBackendProvider struct is modified in QOF to
+support new members and QSF can support the new function, or
+-# The QofBackendOption settings are modified.
+
+v0.2 introduces the QSF_MAP_FILES QofBackendOption.
+
+Initialises the backend and provides access to the
+functions that will load and save the data. Initialises
+default values for the QofBackendOption KvpFrame.
+
+Calls gettext because QofBackendOption
+strings are translatable.
 */
 void qsf_provider_init(void);
 
-/** \brief Create a new QSF backend.
+/** \name Supported backend configurations
+@{
+*/
 
-	Initialises the backend and provides access to the
-	functions that will load and save the data.
+/** \brief compression level
+
+\b Type: gint (KVP_TYPE_GINT64)
+
+Use GINT_TO_POINTER() to set a integer value between 0 and 9.
 */
-QofBackend* qsf_backend_new(void);
+#define QSF_COMPRESS    "compression_level"
 
+/** \brief selected QSF maps 
+
+\b Type: GList* (KVP_TYPE_GLIST) of const char* (QOF_TYPE_STRING) values.
+
+Defaults to the pre-installed QSF map(s) but may be overridden
+by the application to pass full path(s) of user selected 
+QSF map file(s).
+
+If you override the list, it is advisable to only specify the single
+map file for this QSF object to reduce the amount of error checking
+required within the backend. Simply reset the QofBackendOption before
+another file is to be opened. It is up to the application to decide how
+to offer multiple map selections to the user.
+
+*/
+#define QSF_MAP_FILES   "selected_map_files"
+
 /** @} */
+
 /** @} */
+/** @} */
 
 #endif /* _QOF_BACKEND_QSF_H */

Modified: gnucash/trunk/lib/libqof/backend/file/qsf-backend.c
===================================================================
--- gnucash/trunk/lib/libqof/backend/file/qsf-backend.c	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/backend/file/qsf-backend.c	2006-01-08 17:51:29 UTC (rev 12299)
@@ -5,7 +5,6 @@
  *  Copyright  2005  Neil Williams
  *  linux at codehelp.co.uk
  ****************************************************************************/
-
 /*
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -19,12 +18,12 @@
  *
  *  You should have received a copy of the GNU General Public License
  *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- *  02110-1301, USA.
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
 #define _GNU_SOURCE
 
+#include "qof.h"
 #include "qof-backend-qsf.h"
 #include "qsf-xml.h"
 #include "qsf-dir.h"
@@ -32,32 +31,58 @@
 #include <sys/stat.h>
 
 #define QSF_TYPE_BINARY "binary"
-#define QSF_TYPE_GLIST "glist"
-#define QSF_TYPE_FRAME "frame"
-#define QSF_COMPRESS "compression_level"
+#define QSF_TYPE_GLIST  "glist"
+#define QSF_TYPE_FRAME  "frame"
 
 static QofLogModule log_module = QOF_MOD_QSF;
-static int use_gz_level = 0;
+static void qsf_object_commitCB(gpointer key, gpointer value, gpointer data);
 
+struct QSFBackend_s
+{
+	QofBackend be;
+	qsf_param *params;
+	char *fullpath;
+};
+
+typedef struct QSFBackend_s QSFBackend;
+
 static void option_cb (QofBackendOption *option, gpointer data)
 {
+	qsf_param *params;
+
+	params = (qsf_param*)data;
+	g_return_if_fail(params);
 	if(0 == safe_strcmp(QSF_COMPRESS, option->option_name)) {
-		use_gz_level = *(gint*)option->value;
+		params->use_gz_level = GPOINTER_TO_INT(option->value);
 	}
+	if (0 == safe_strcmp(QSF_MAP_FILES, option->option_name)) {
+		params->map_files = g_list_copy(option->value);
+	}
 }
 
 static void
 qsf_load_config(QofBackend *be, KvpFrame *config)
 {
-  qof_backend_option_foreach(config, option_cb, NULL);
+	QSFBackend *qsf_be;
+	qsf_param  *params;
+
+	qsf_be = (QSFBackend*)be;
+	g_return_if_fail(qsf_be->params);
+	params = qsf_be->params;
+	qof_backend_option_foreach(config, option_cb, params);
 }
 
 static KvpFrame*
 qsf_get_config(QofBackend *be)
 {
 	QofBackendOption *option;
+	QSFBackend *qsf_be;
+	qsf_param *params;
 
 	if(!be) { return NULL; }
+	qsf_be = (QSFBackend*)be;
+	g_return_val_if_fail(qsf_be->params, NULL);
+	params = qsf_be->params;
 	qof_backend_prepare_frame(be);
 	option = g_new0(QofBackendOption, 1);
 	option->option_name = QSF_COMPRESS;
@@ -65,22 +90,29 @@
 	option->tooltip = _("QOF can compress QSF XML files using gzip. "
 		"Note that compression is not used when outputting to STDOUT.");
 	option->type = KVP_TYPE_GINT64;
-	option->value = (gpointer)&use_gz_level;
+	option->value = GINT_TO_POINTER(params->use_gz_level);
 	qof_backend_prepare_option(be, option);
 	g_free(option);
+	option = g_new0(QofBackendOption, 1);
+	option->option_name = QSF_MAP_FILES;
+	option->description = _("List of QSF map files to use for this session.");
+	option->tooltip = _("QOF can convert objects within QSF XML files "
+		"using a map of the changes required.");
+	option->type = KVP_TYPE_GLIST;
+	option->value = params->map_files;
+	qof_backend_prepare_option(be, option);
+	g_free(option);
 	return qof_backend_complete_frame(be);
 }
 
-struct QSFBackend_s 
+GList**
+qsf_map_prepare_list(GList **maps)
 {
-	QofBackend be;
-	qsf_param *params;
-	char *fullpath;
-};
+	*maps = g_list_prepend(*maps, "pilot-qsf-GnuCashInvoice.xml");
+	return maps;
+}
 
-typedef struct QSFBackend_s QSFBackend;
-
-void
+static void
 qsf_param_init(qsf_param *params)
 {
 	Timespec *qsf_ts;
@@ -93,13 +125,16 @@
 
 	g_return_if_fail(params != NULL);
 	params->count = 0;
+	params->use_gz_level = 0;
 	params->supported_types = NULL;
 	params->file_type = QSF_UNDEF;
 	params->qsf_ns = NULL;
 	params->output_doc = NULL;
 	params->output_node = NULL;
 	params->lister = NULL;
+	params->full_kvp_path = NULL;
 	params->map_ns = NULL;
+	params->map_files = 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);
@@ -129,6 +164,8 @@
 	g_hash_table_insert(params->qsf_default_hash, "qsf_enquiry_date", qsf_enquiry_date);
 	g_hash_table_insert(params->qsf_default_hash, "qsf_time_now", &qsf_time_now_t);
 	g_hash_table_insert(params->qsf_default_hash, "qsf_time_string", qsf_time_string);
+	/* default map files */
+	params->map_files = *qsf_map_prepare_list(&params->map_files);
 }
 
 static gboolean 
@@ -136,7 +173,6 @@
 {
 	struct stat sbuf;
 
-	PINFO (" %s", path);
 	if (!path) { return TRUE; }
 	if (0 == safe_strcmp(path, QOF_STDOUT)) { return TRUE; }
 	if (stat(path, &sbuf) <0)    { return FALSE; }
@@ -148,8 +184,7 @@
 }
 
 /* GnuCash does LOTS of filesystem work, QSF is going to leave most of it to libxml2. :-)
-Just strip the file: from the start of the book_path URL. Locks and file
-creation are not implemented.
+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,
@@ -165,6 +200,7 @@
 	qsf_be->fullpath = NULL;
 	if(book_path == NULL)
 	{
+		/* use stdout */
 		qof_backend_set_error(be, ERR_BACKEND_NO_ERR);
 		return;
 	}
@@ -181,9 +217,33 @@
 	else {
 		qsf_be->fullpath = g_strdup(book_path);
 	}
+	if(create_if_nonexistent)
+	{
+        FILE *f;
+
+        f = fopen(qsf_be->fullpath, "a+");
+        if(f) {fclose(f); }
+		else
+		{
+			qof_backend_set_error(be, ERR_BACKEND_READONLY);
+			return;
+		}
+	}
 	qof_backend_set_error(be, ERR_BACKEND_NO_ERR);
 }
 
+static void 
+qsf_free_params(qsf_param *params)
+{
+	g_hash_table_destroy(params->qsf_calculate_hash);
+	g_hash_table_destroy(params->qsf_default_hash);
+	if(params->referenceList) {
+		g_list_free(params->referenceList);
+	}
+	g_slist_free(params->supported_types);
+	if(params->map_ns) { xmlFreeNs(params->map_ns); }
+}
+
 static void
 qsf_session_end( QofBackend *be)
 {
@@ -197,70 +257,12 @@
 	xmlCleanupParser();
 }
 
-static void 
+static void
 qsf_destroy_backend (QofBackend *be)
 {
 	g_free(be);
 }
 
-QofBackendError 
-qof_session_load_our_qsf_object(QofSession *first_session, const char *path)
-{
-	QofSession *qsf_session;
-	
-	qsf_session = qof_session_new();
-	qof_session_begin(qsf_session, path, FALSE, FALSE);
-	qof_session_load(qsf_session, NULL);
-	/* FIXME: This needs to return success and set the open not merge error in file_open */
-	return ERR_QSF_OPEN_NOT_MERGE;
-}
-
-QofBackendError 
-qof_session_load_qsf_object(QofSession *first_session, const char *path)
-{
-	PINFO ("%s = ERR_QSF_NO_MAP", path);
-	return ERR_QSF_NO_MAP;
-}
-
-void
-qsf_file_type(QofBackend *be, QofBook *book)
-{
-	QSFBackend *qsf_be;
-	qsf_param *params;
-	char *path;
-	gboolean result;
-
-	g_return_if_fail(be != NULL);
-	g_return_if_fail(book != NULL);
-	qsf_be = (QSFBackend*) be;
-	g_return_if_fail(qsf_be != NULL);
-	g_return_if_fail(qsf_be->fullpath != NULL);
-	g_return_if_fail(qsf_be->params != NULL);
-	params = qsf_be->params;
-	params->book = book;
-	path = g_strdup(qsf_be->fullpath);
-	params->filepath = g_strdup(path);
-	qof_backend_get_error(be);
-	result = is_our_qsf_object_be(params);
-	if(result) {
-		params->file_type = OUR_QSF_OBJ;
-		result = load_our_qsf_object(book, path, params);
-		if(!result) { qof_backend_set_error(be, ERR_FILEIO_PARSE_ERROR); }
-		return;
-	} 
-	else if(is_qsf_object_be(params)) {
-		params->file_type = IS_QSF_OBJ;
-		result = load_qsf_object(book, path, params);
-		if(!result) { qof_backend_set_error(be, ERR_FILEIO_PARSE_ERROR); }
-	}
-	if(result == FALSE) {
-		if(is_qsf_map_be(params)) {
-		params->file_type = IS_QSF_MAP;
-		qof_backend_set_error(be, ERR_QSF_MAP_NOT_OBJ);
-		}
-	}
-}
-
 static void
 ent_ref_cb (QofEntity* ent, gpointer user_data)
 {
@@ -307,7 +309,7 @@
 	Load QofEntity into QofBook from XML in memory
 ==================================================*/
 
-static gboolean 
+static gboolean
 qsfdoc_to_qofbook(xmlDocPtr doc, qsf_param *params)
 {
 	QofInstance *inst;
@@ -346,7 +348,125 @@
 	return TRUE;
 }
 
+/* QofBackend routine to load from file - needs a map.
+*/
+static gboolean
+load_qsf_object(QofBook *book, const char *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;
+	mapDoc = NULL;
+	if(!maps) {
+		qof_backend_set_error(params->be, ERR_QSF_NO_MAP);
+		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);
+		return FALSE;
+	}
+	qsf_root = NULL;
+	qsf_root = xmlDocGetRootElement(foreign_doc);
+	params->qsf_ns = qsf_root->ns;
+	params->book = book;
+	map_path = g_strdup_printf("%s/%s", QSF_SCHEMA_DIR, map_file);
+	if(!map_path) {
+		qof_backend_set_error(params->be, ERR_QSF_NO_MAP);
+		return FALSE; 
+	}
+	mapDoc = xmlParseFile(map_path);
+	if(!mapDoc) {
+		qof_backend_set_error(params->be, ERR_QSF_NO_MAP);
+		return FALSE;
+	}
+	map_root = xmlDocGetRootElement(mapDoc);
+	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)
+{
+	xmlNodePtr qsf_root;
+
+	params->input_doc = xmlParseFile(fullpath);
+	if (params->input_doc == NULL) {
+		qof_backend_set_error(params->be, ERR_FILEIO_PARSE_ERROR);
+		return FALSE;
+	}
+	qsf_root = NULL;
+	qsf_root = xmlDocGetRootElement(params->input_doc);
+	params->qsf_ns = qsf_root->ns;
+	return qsfdoc_to_qofbook(params->input_doc, params);
+}
+
+/* Determine the type of QSF and load it into the QofBook
+
+- is_our_qsf_object, OUR_QSF_OBJ, QSF object file using only QOF objects known
+	to the calling process.	No map is required.
+- is_qsf_object, IS_QSF_OBJ, QSF object file that may or may not have a QSF map
+	to convert external objects. This temporary type will be set to HAVE_QSF_MAP 
+	if a suitable map exists, or an error value returned: ERR_QSF_NO_MAP, 
+	ERR_QSF_BAD_MAP or ERR_QSF_WRONG_MAP. This allows the calling process to inform 
+	the user that the QSF itself is valid but a suitable map cannot be found.
+- is_qsf_map, IS_QSF_MAP, QSF map file. In the backend, this generates 
+	ERR_QSF_MAP_NOT_OBJ but	it can be used internally when processing maps to 
+	match a QSF object.
+
+returns NULL on error, otherwise a pointer to the QofBook. Use
+	the qof_book_merge API to merge the new data into the current
+	QofBook. 
+*/
 static void
+qsf_file_type(QofBackend *be, QofBook *book)
+{
+	QSFBackend *qsf_be;
+	qsf_param *params;
+	char *path;
+	gboolean result;
+
+	g_return_if_fail(be != NULL);
+	g_return_if_fail(book != NULL);
+	qsf_be = (QSFBackend*) be;
+	g_return_if_fail(qsf_be != NULL);
+	g_return_if_fail(qsf_be->fullpath != NULL);
+	g_return_if_fail(qsf_be->params != NULL);
+	params = qsf_be->params;
+	params->book = book;
+	path = g_strdup(qsf_be->fullpath);
+	params->filepath = g_strdup(path);
+	qof_backend_get_error(be);
+	result = is_our_qsf_object_be(params);
+	if(result) {
+		params->file_type = OUR_QSF_OBJ;
+		result = load_our_qsf_object(book, path, params);
+		if(!result) { qof_backend_set_error(be, ERR_FILEIO_PARSE_ERROR); }
+		return;
+	}
+	else if(is_qsf_object_be(params)) {
+		params->file_type = IS_QSF_OBJ;
+		result = load_qsf_object(book, path, params);
+		if(!result) { qof_backend_set_error(be, ERR_FILEIO_PARSE_ERROR); }
+	}
+	if(result == FALSE) {
+		if(is_qsf_map_be(params)) {
+		params->file_type = IS_QSF_MAP;
+		qof_backend_set_error(be, ERR_QSF_MAP_NOT_OBJ);
+		}
+	}
+}
+
+static void
 qsf_object_sequence(QofParam *qof_param, gpointer data)
 {
 	qsf_param *params;
@@ -399,112 +519,93 @@
 static KvpValueType
 qsf_to_kvp_helper(const char *type_string)
 {
-	if(0 == safe_strcmp(QOF_TYPE_STRING, type_string))  { return KVP_TYPE_STRING; }
-	if(0 == safe_strcmp(QOF_TYPE_GUID, type_string))    { return KVP_TYPE_GUID; }
-	if(0 == safe_strcmp(QOF_TYPE_INT64, type_string))   { return KVP_TYPE_GINT64; }
-	if(0 == safe_strcmp(QOF_TYPE_DOUBLE, type_string))  { return KVP_TYPE_DOUBLE; }
-	if(0 == safe_strcmp(QOF_TYPE_NUMERIC, type_string)) { return KVP_TYPE_NUMERIC; }
-	if(0 == safe_strcmp(QSF_TYPE_BINARY, type_string))  { return KVP_TYPE_BINARY; }
-	if(0 == safe_strcmp(QSF_TYPE_GLIST, type_string))   { return KVP_TYPE_GLIST; }
-	if(0 == safe_strcmp(QSF_TYPE_FRAME, type_string))   { return KVP_TYPE_FRAME; }
+	if(0 == safe_strcmp(QOF_TYPE_INT64,   type_string)) { return KVP_TYPE_GINT64;   }
+	if(0 == safe_strcmp(QOF_TYPE_DOUBLE,  type_string)) { return KVP_TYPE_DOUBLE;   }
+	if(0 == safe_strcmp(QOF_TYPE_NUMERIC, type_string)) { return KVP_TYPE_NUMERIC;  }
+	if(0 == safe_strcmp(QOF_TYPE_STRING,  type_string)) { return KVP_TYPE_STRING;   }
+	if(0 == safe_strcmp(QOF_TYPE_GUID,    type_string)) { return KVP_TYPE_GUID;     }
+	if(0 == safe_strcmp(QOF_TYPE_DATE,    type_string)) { return KVP_TYPE_TIMESPEC; }
+	if(0 == safe_strcmp(QSF_TYPE_BINARY,  type_string)) { return KVP_TYPE_BINARY;   }
+	if(0 == safe_strcmp(QSF_TYPE_GLIST,   type_string)) { return KVP_TYPE_GLIST;    }
+	if(0 == safe_strcmp(QSF_TYPE_FRAME,   type_string)) { return KVP_TYPE_FRAME;    }
 	return 0;
 }
 
+static QofIdTypeConst
+kvp_value_to_qof_type_helper(KvpValueType n)
+{
+	switch(n)
+	{
+		case KVP_TYPE_GINT64   : { return QOF_TYPE_INT64;   break; }
+		case KVP_TYPE_DOUBLE   : { return QOF_TYPE_DOUBLE;  break; }
+		case KVP_TYPE_NUMERIC  : { return QOF_TYPE_NUMERIC; break; }
+		case KVP_TYPE_STRING   : { return QOF_TYPE_STRING;  break; }
+		case KVP_TYPE_GUID     : { return QOF_TYPE_GUID;    break; }
+		case KVP_TYPE_TIMESPEC : { return QOF_TYPE_DATE;    break; }
+		case KVP_TYPE_BINARY   : { return QSF_TYPE_BINARY;  break; }
+		case KVP_TYPE_GLIST    : { return QSF_TYPE_GLIST;   break; }
+		case KVP_TYPE_FRAME    : { return QSF_TYPE_FRAME;   break; }
+		default : { return NULL; }
+	}
+}
+
+
 static void
 qsf_from_kvp_helper(const char *path, KvpValue *content, gpointer data)
 {
 	qsf_param *params;
 	QofParam *qof_param;
 	xmlNodePtr node;
+	KvpValueType n;
+	gchar *full_path;
 
 	params = (qsf_param*)data;
 	qof_param = params->qof_param;
+	full_path = NULL;
 	g_return_if_fail(params && path && content);
-	ENTER (" path=%s", path);
-	switch(kvp_value_get_type(content))
+	ENTER (" ");
+	n = kvp_value_get_type(content);
+	switch(n)
 	{
-		case KVP_TYPE_STRING:
+		case KVP_TYPE_GINT64   :
+		case KVP_TYPE_DOUBLE   :
+		case KVP_TYPE_NUMERIC  :
+		case KVP_TYPE_STRING   :
+		case KVP_TYPE_GUID     :
+		case KVP_TYPE_TIMESPEC :
+		case KVP_TYPE_BINARY   :
+		case KVP_TYPE_GLIST    :
 		{
 			node = xmlAddChild(params->output_node, xmlNewNode(params->qsf_ns,
 				BAD_CAST qof_param->param_type));
 			xmlNodeAddContent(node, BAD_CAST kvp_value_to_bare_string(content));
 			xmlNewProp(node, BAD_CAST QSF_OBJECT_TYPE, BAD_CAST qof_param->param_name);
-			xmlNewProp(node, BAD_CAST QSF_OBJECT_KVP, BAD_CAST path);
-			xmlNewProp(node, BAD_CAST QSF_OBJECT_VALUE, BAD_CAST QOF_TYPE_STRING);
+			full_path = g_strconcat(params->full_kvp_path, "/", path, NULL);
+			xmlNewProp(node, BAD_CAST QSF_OBJECT_KVP, BAD_CAST full_path);
+			xmlNewProp(node, BAD_CAST QSF_OBJECT_VALUE, 
+				BAD_CAST kvp_value_to_qof_type_helper(n));
+			PINFO (" set %s", kvp_value_to_qof_type_helper(n));
 			break;
 		}
-		case KVP_TYPE_GUID:
-		{
-			node = xmlAddChild(params->output_node, xmlNewNode(params->qsf_ns,
-				BAD_CAST qof_param->param_type));
-			xmlNodeAddContent(node, BAD_CAST kvp_value_to_bare_string(content));
-			xmlNewProp(node, BAD_CAST QSF_OBJECT_TYPE, BAD_CAST qof_param->param_name);
-			xmlNewProp(node, BAD_CAST QSF_OBJECT_KVP, BAD_CAST path);
-			xmlNewProp(node, BAD_CAST QSF_OBJECT_VALUE, BAD_CAST QOF_TYPE_GUID);
-			break;
-		}
-		case KVP_TYPE_BINARY:
-		{
-			node = xmlAddChild(params->output_node, xmlNewNode(params->qsf_ns,
-				BAD_CAST qof_param->param_type));
-			xmlNodeAddContent(node, BAD_CAST kvp_value_to_bare_string(content));
-			xmlNewProp(node, BAD_CAST QSF_OBJECT_TYPE, BAD_CAST qof_param->param_name);
-			xmlNewProp(node, BAD_CAST QSF_OBJECT_KVP, BAD_CAST path);
-			xmlNewProp(node, BAD_CAST QSF_OBJECT_VALUE, BAD_CAST QSF_TYPE_BINARY);
-			break;
-		}
-		case KVP_TYPE_GLIST:
-		{
-			node = xmlAddChild(params->output_node, xmlNewNode(params->qsf_ns,
-				BAD_CAST qof_param->param_type));
-			xmlNodeAddContent(node, BAD_CAST kvp_value_to_bare_string(content));
-			xmlNewProp(node, BAD_CAST QSF_OBJECT_TYPE, BAD_CAST qof_param->param_name);
-			xmlNewProp(node, BAD_CAST QSF_OBJECT_KVP, BAD_CAST path);
-			xmlNewProp(node, BAD_CAST QSF_OBJECT_VALUE, BAD_CAST QSF_TYPE_GLIST);
-			break;
-		}
 		case KVP_TYPE_FRAME:
 		{
-			node = xmlAddChild(params->output_node, xmlNewNode(params->qsf_ns,
-				BAD_CAST qof_param->param_type));
-			xmlNodeAddContent(node, BAD_CAST kvp_value_to_bare_string(content));
-			xmlNewProp(node, BAD_CAST QSF_OBJECT_TYPE, BAD_CAST qof_param->param_name);
-			xmlNewProp(node, BAD_CAST QSF_OBJECT_KVP, BAD_CAST path);
-			xmlNewProp(node, BAD_CAST QSF_OBJECT_VALUE, BAD_CAST QSF_TYPE_FRAME);
+			if(!params->full_kvp_path) { params->full_kvp_path = g_strdup(path); }
+			else { 
+				params->full_kvp_path = g_strconcat(params->full_kvp_path, 
+					"/", path, NULL);
+			}
+			PINFO (" full=%s, path=%s ", params->full_kvp_path, path);
+			kvp_frame_for_each_slot(kvp_value_get_frame(content), 
+				qsf_from_kvp_helper, params);
+			g_free(params->full_kvp_path);
+			params->full_kvp_path = NULL;
 			break;
 		}
-		case KVP_TYPE_GINT64:
+		default:
 		{
-			node = xmlAddChild(params->output_node, xmlNewNode(params->qsf_ns,
-				BAD_CAST qof_param->param_type));
-			xmlNodeAddContent(node, BAD_CAST kvp_value_to_bare_string(content));
-			xmlNewProp(node, BAD_CAST QSF_OBJECT_TYPE, BAD_CAST qof_param->param_name);
-			xmlNewProp(node, BAD_CAST QSF_OBJECT_KVP, BAD_CAST path);
-			xmlNewProp(node, BAD_CAST QSF_OBJECT_VALUE, BAD_CAST QOF_TYPE_INT64);
+			PERR (" unsupported value = %d", kvp_value_get_type(content));
 			break;
 		}
-		case KVP_TYPE_DOUBLE:
-		{
-			node = xmlAddChild(params->output_node, xmlNewNode(params->qsf_ns,
-				BAD_CAST qof_param->param_type));
-			xmlNodeAddContent(node, BAD_CAST kvp_value_to_bare_string(content));
-			xmlNewProp(node, BAD_CAST QSF_OBJECT_TYPE, BAD_CAST qof_param->param_name);
-			xmlNewProp(node, BAD_CAST QSF_OBJECT_KVP, BAD_CAST path);
-			xmlNewProp(node, BAD_CAST QSF_OBJECT_VALUE, BAD_CAST QOF_TYPE_DOUBLE);
-			break;
-		}
-		case KVP_TYPE_NUMERIC:
-		{
-			node = xmlAddChild(params->output_node, xmlNewNode(params->qsf_ns,
-				BAD_CAST qof_param->param_type));
-			xmlNodeAddContent(node, BAD_CAST kvp_value_to_bare_string(content));
-			xmlNewProp(node, BAD_CAST QSF_OBJECT_TYPE, BAD_CAST qof_param->param_name);
-			xmlNewProp(node, BAD_CAST QSF_OBJECT_KVP, BAD_CAST path);
-			xmlNewProp(node, BAD_CAST QSF_OBJECT_VALUE, BAD_CAST QOF_TYPE_NUMERIC);
-			break;
-		}
-		default:
-		{ break; }
 	}
 	LEAVE (" ");
 }
@@ -693,14 +794,15 @@
 		}
 		if(0 == safe_strcmp(qof_param->param_type, QOF_TYPE_KVP))
 		{
-			qsf_kvp = kvp_frame_copy(qof_param->param_getfcn(ent,qof_param));
+			qsf_kvp = (KvpFrame*)qof_param->param_getfcn(ent,qof_param);
+			if(kvp_frame_is_empty(qsf_kvp))	{ LEAVE(" "); return; }
 			params->qof_param = qof_param;
 			params->output_node = object_node;
 			kvp_frame_for_each_slot(qsf_kvp, qsf_from_kvp_helper, params);
 		}
 		if((qof_param->param_setfcn != NULL) && (qof_param->param_getfcn != NULL))
 		{
-			for( supported = g_slist_copy(params->supported_types); 
+			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))
@@ -722,7 +824,7 @@
 	qsf_param *params;
 	QofBook *book;
 	GSList *support;
-	
+
 	g_return_if_fail(data != NULL);
 	params = (qsf_param*) data;
 	/* Skip unsupported objects */
@@ -749,10 +851,11 @@
 	xmlDocPtr doc;
 	gchar buffer[GUID_ENCODING_LENGTH + 1];
 	const GUID *book_guid;
-	
+
 	g_return_val_if_fail(book != NULL, NULL);
 	params->book = book;
-	params->referenceList = g_list_copy((GList*)qof_book_get_data(book, ENTITYREFERENCE));
+	params->referenceList = 
+		g_list_copy((GList*)qof_book_get_data(book, ENTITYREFERENCE));
 	doc = xmlNewDoc(BAD_CAST QSF_XML_VERSION);
 	top_node = xmlNewNode(NULL, BAD_CAST QSF_ROOT_TAG);
 	xmlDocSetRootElement(doc, top_node);
@@ -763,7 +866,8 @@
 	xmlNewProp(node, BAD_CAST QSF_BOOK_COUNT, BAD_CAST "1");
 	book_guid = qof_book_get_guid(book);
 	guid_to_string_buff(book_guid, buffer);
-	xmlNewChild(params->book_node, params->qsf_ns, BAD_CAST QSF_BOOK_GUID, BAD_CAST buffer);
+	xmlNewChild(params->book_node, params->qsf_ns, 
+		BAD_CAST QSF_BOOK_GUID, BAD_CAST buffer);
 	params->output_doc = doc;
 	params->book_node = node;
 	qof_object_foreach_type(qsf_foreach_obj_type, params);
@@ -780,9 +884,9 @@
 	be = qof_book_get_backend(book);
 	qsf_doc = qofbook_to_qsf(book, params);
 	write_result = 0;
-	if((use_gz_level > 0) && (use_gz_level <= 9)) 
+	if((params->use_gz_level > 0) && (params->use_gz_level <= 9)) 
 	{
-		xmlSetDocCompressMode(qsf_doc, use_gz_level); 
+		xmlSetDocCompressMode(qsf_doc, params->use_gz_level); 
 	}
 	g_return_if_fail(qsf_is_valid(QSF_SCHEMA_DIR, QSF_OBJECT_SCHEMA, qsf_doc) == TRUE);
 	write_result = xmlSaveFormatFileEnc(path, qsf_doc, "UTF-8", 1);
@@ -804,10 +908,9 @@
 	xmlSaveFormatFileEnc("-", qsf_doc, "UTF-8", 1);
 	fprintf(stdout, "\n");
 	xmlFreeDoc(qsf_doc);
-	LEAVE (" ");
 }
 
-void
+static void
 qsf_write_file(QofBackend *be, QofBook *book)
 {
 	QSFBackend *qsf_be;
@@ -826,51 +929,6 @@
 	g_free(path);
 }
 
-/* QofBackend routine to load from file - needs a map.
-*/
-gboolean
-load_qsf_object(QofBook *book, const char *fullpath, qsf_param *params)
-{
-	xmlNodePtr qsf_root, map_root;
-	xmlDocPtr mapDoc, foreign_doc;
-	gchar *map_path, *map_file;
-
-	map_file = g_strdup("pilot-qsf-GnuCashInvoice.xml");
-	foreign_doc = xmlParseFile(fullpath);
-	if (foreign_doc == NULL) {
-		qof_backend_set_error(params->be, ERR_FILEIO_PARSE_ERROR);
-		return FALSE;
-	}
-	qsf_root = NULL;
-	qsf_root = xmlDocGetRootElement(foreign_doc);
-	params->qsf_ns = qsf_root->ns;
-	params->book = book;
-	map_path = g_strdup_printf("%s/%s", QSF_SCHEMA_DIR, map_file);
-	if(map_path == NULL) { return FALSE; }
-	mapDoc = xmlParseFile(map_path);
-	map_root = xmlDocGetRootElement(mapDoc);
-	params->map_ns = map_root->ns;
-	params->input_doc = qsf_object_convert(mapDoc, qsf_root, params);
-	qsfdoc_to_qofbook(params->input_doc, params);
-	return TRUE;
-}
-
-gboolean
-load_our_qsf_object(QofBook *book, const char *fullpath, qsf_param *params)
-{
-	xmlNodePtr qsf_root;
-	
-	params->input_doc = xmlParseFile(fullpath);
-	if (params->input_doc == NULL) {
-		qof_backend_set_error(params->be, ERR_FILEIO_PARSE_ERROR);
-		return FALSE;
-	}
-	qsf_root = NULL;
-	qsf_root = xmlDocGetRootElement(params->input_doc);
-	params->qsf_ns = qsf_root->ns;
-	return qsfdoc_to_qofbook(params->input_doc, params);
-}
-
 KvpValue*
 string_to_kvp_value(const char *content, KvpValueType type)
 {
@@ -882,7 +940,7 @@
 	struct tm   kvp_time;
 	time_t      kvp_time_t;
 	Timespec    cm_date;
-	
+
 	switch(type) {
 	  case KVP_TYPE_GINT64:
 		errno = 0;
@@ -932,9 +990,9 @@
 	return NULL;
 }
 
-/*======================================================
+/* ======================================================
 	Commit XML data from file to QofEntity in a QofBook
-========================================================*/
+========================================================= */
 void
 qsf_object_commitCB(gpointer key, gpointer value, gpointer data)
 {
@@ -971,10 +1029,8 @@
 	void (*i32_setter)       (QofEntity*, gint32);
 	void (*i64_setter)       (QofEntity*, gint64);
 	void (*char_setter)      (QofEntity*, char);
-	void (*kvp_frame_setter) (QofEntity*, KvpFrame*);
 
-	g_return_if_fail(data != NULL);
-	g_return_if_fail(value != NULL);
+	g_return_if_fail(data && value && key);
 	params = (qsf_param*)data;
 	node = (xmlNodePtr)value;
 	parameter_name = (const char*)key;
@@ -989,11 +1045,11 @@
 	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)  { 
+	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)); }
 	}
-	if(safe_strcmp(qof_type, QOF_TYPE_DATE) == 0) { 
+	if(safe_strcmp(qof_type, QOF_TYPE_DATE) == 0) {
 		date_setter = (void(*)(QofEntity*, Timespec))cm_setter;
 		timechk = NULL;
 		timechk = strptime((char*)xmlNodeGetContent(node), QSF_XSD_TIME, &qsf_time);
@@ -1003,12 +1059,12 @@
 		if(date_setter != NULL) { date_setter(qsf_ent, cm_date); }
 	}
 	if((safe_strcmp(qof_type, QOF_TYPE_NUMERIC) == 0)  ||
-	(safe_strcmp(qof_type, QOF_TYPE_DEBCRED) == 0)) { 
+	(safe_strcmp(qof_type, QOF_TYPE_DEBCRED) == 0)) {
 		numeric_setter = (void(*)(QofEntity*, gnc_numeric))cm_setter;
 		string_to_gnc_numeric((char*)xmlNodeGetContent(node), &cm_numeric);
 		if(numeric_setter != NULL) { numeric_setter(qsf_ent, cm_numeric); }
 	}
-	if(safe_strcmp(qof_type, QOF_TYPE_GUID) == 0) { 
+	if(safe_strcmp(qof_type, QOF_TYPE_GUID) == 0) {
 		cm_guid = g_new(GUID, 1);
 		if(TRUE != string_to_guid((char*)xmlNodeGetContent(node), cm_guid))
 		{
@@ -1018,7 +1074,7 @@
 			return;
 		}
 		reference_type = (char*)xmlGetProp(node, BAD_CAST QSF_OBJECT_TYPE);
-		if(0 == safe_strcmp(QOF_PARAM_GUID, reference_type)) 
+		if(0 == safe_strcmp(QOF_PARAM_GUID, reference_type))
 		{
 			qof_entity_set_guid(qsf_ent, cm_guid);
 		}
@@ -1029,7 +1085,7 @@
 			}
 		}
 	}
-	if(safe_strcmp(qof_type, QOF_TYPE_INT32) == 0) { 
+	if(safe_strcmp(qof_type, QOF_TYPE_INT32) == 0) {
 		errno = 0;
 		cm_i32 = (gint32)strtol ((char*)xmlNodeGetContent(node), &tail, 0);
 		if(errno == 0) {
@@ -1038,7 +1094,7 @@
 		}
 		else { qof_backend_set_error(params->be, ERR_QSF_OVERFLOW); }
 	}
-	if(safe_strcmp(qof_type, QOF_TYPE_INT64) == 0) { 
+	if(safe_strcmp(qof_type, QOF_TYPE_INT64) == 0) {
 		errno = 0;
 		cm_i64 = strtoll((char*)xmlNodeGetContent(node), &tail, 0);
 		if(errno == 0) {
@@ -1047,7 +1103,7 @@
 		}
 		else { qof_backend_set_error(params->be, ERR_QSF_OVERFLOW); }
 	}
-	if(safe_strcmp(qof_type, QOF_TYPE_DOUBLE) == 0) { 
+	if(safe_strcmp(qof_type, QOF_TYPE_DOUBLE) == 0) {
 		errno = 0;
 		cm_double = strtod((char*)xmlNodeGetContent(node), &tail);
 		if(errno == 0) {
@@ -1055,22 +1111,22 @@
 			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), QSF_XML_BOOLEAN_TEST)) {
+	if(safe_strcmp(qof_type, QOF_TYPE_BOOLEAN) == 0){
+		if(0 == safe_strcasecmp((char*)xmlNodeGetContent(node), 
+				QSF_XML_BOOLEAN_TEST)) {
 			cm_boolean = TRUE;
 		}
 		else { cm_boolean = FALSE; }
 		boolean_setter = (void(*)(QofEntity*, gboolean))cm_setter;
 		if(boolean_setter != NULL) { boolean_setter(qsf_ent, cm_boolean); }
 	}
-	if(safe_strcmp(qof_type, QOF_TYPE_KVP) == 0) { 
+	if(safe_strcmp(qof_type, QOF_TYPE_KVP) == 0) {
 		cm_type = qsf_to_kvp_helper((char*)xmlGetProp(node, BAD_CAST QSF_OBJECT_VALUE));
 		if(!cm_type) { return; }
 		cm_value = string_to_kvp_value((char*)xmlNodeGetContent(node), cm_type);
-		cm_kvp = kvp_frame_copy(cm_param->param_getfcn(qsf_ent, cm_param));
-		cm_kvp = kvp_frame_set_value(cm_kvp, (char*)xmlGetProp(node, BAD_CAST QSF_OBJECT_KVP), cm_value);
-		kvp_frame_setter = (void(*)(QofEntity*, KvpFrame*))cm_setter;
-		if(kvp_frame_setter != NULL) { kvp_frame_setter(qsf_ent, cm_kvp); }
+		cm_kvp = (KvpFrame*)cm_param->param_getfcn(qsf_ent, cm_param);
+		cm_kvp = kvp_frame_set_value(cm_kvp, (char*)xmlGetProp(node, 
+			BAD_CAST QSF_OBJECT_KVP), cm_value);
 	}
 	if(safe_strcmp(qof_type, QOF_TYPE_COLLECT) == 0) {
 		QofCollection *qsf_coll;
@@ -1087,10 +1143,10 @@
 			PINFO (" string to guid collect failed for %s", xmlNodeGetContent(node));
 			return;
 		}
-		// create a QofEntityReference with this type and GUID.
-		// there is only one entity each time.
-		// cm_guid contains the GUID of the reference.
-		// type is the type of the reference.
+		/* create a QofEntityReference with this type and GUID.
+		 there is only one entity each time.
+		 cm_guid contains the GUID of the reference.
+		 type is the type of the reference. */
 		reference = g_new0(QofEntityReference, 1);
 		reference->type = g_strdup(qsf_ent->e_type);
 		reference->ref_guid = cm_guid;
@@ -1101,7 +1157,7 @@
 		reference->param = copy_param;
 		params->referenceList = g_list_append(params->referenceList, reference);
 	}
-	if(safe_strcmp(qof_type, QOF_TYPE_CHAR) == 0) { 
+	if(safe_strcmp(qof_type, QOF_TYPE_CHAR) == 0) {
 		char_getter = (char (*)(xmlNodePtr))xmlNodeGetContent;
 		cm_char = char_getter(node);
 		char_setter = (void(*)(QofEntity*, char))cm_setter;
@@ -1109,12 +1165,12 @@
 	}
 }
 
-QofBackend*
+static QofBackend*
 qsf_backend_new(void)
 {
 	QSFBackend *qsf_be;
 	QofBackend *be;
-	
+
 	qsf_be = g_new0(QSFBackend, 1);
 	be = (QofBackend*) qsf_be;
 	qof_backend_init(be);
@@ -1139,7 +1195,7 @@
 	/* The QSF backend is not multi-user. */
 	be->events_pending = NULL;
 	be->process_events = NULL;
-	
+
 	be->sync = qsf_write_file;
 	/* use for maps, later. */
 	be->load_config = qsf_load_config;
@@ -1149,12 +1205,10 @@
 	return be;
 }
 
-/** \brief The QOF method of loading each backend.
-
-QSF does not use a GnuCash module, it is loaded using the QOF
-method - QofBackendProvider.
+/* The QOF method of loading each backend.
+QSF is loaded as a GModule using the QOF method - QofBackendProvider.
 */
-static void 
+static void
 qsf_provider_free (QofBackendProvider *prov)
 {
 	prov->provider_name = NULL;
@@ -1162,8 +1216,6 @@
 	g_free (prov);
 }
 
-/* although we call gettext here, none of the
-QofBackendProvider strings are translatable. */
 void
 qsf_provider_init(void)
 {
@@ -1176,7 +1228,7 @@
 	textdomain (GETTEXT_PACKAGE);
 	#endif
 	prov = g_new0 (QofBackendProvider, 1);
-	prov->provider_name = "QSF Backend Version 0.1";
+	prov->provider_name = "QSF Backend Version 0.2";
 	prov->access_method = "file";
 	prov->partial_book_supported = TRUE;
 	prov->backend_new = qsf_backend_new;

Modified: gnucash/trunk/lib/libqof/backend/file/qsf-xml-map.c
===================================================================
--- gnucash/trunk/lib/libqof/backend/file/qsf-xml-map.c	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/backend/file/qsf-xml-map.c	2006-01-08 17:51:29 UTC (rev 12299)
@@ -2,10 +2,9 @@
  *            qsf-xml-map.c
  *
  *  Sat Jan  1 07:31:55 2005
- *  Copyright  2005  Neil Williams
+ *  Copyright  2005-2006  Neil Williams
  *  linux at codehelp.co.uk
  ****************************************************************************/
-
 /*
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -19,8 +18,7 @@
  *
  *  You should have received a copy of the GNU General Public License
  *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- *  02110-1301, USA.
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
 #define _GNU_SOURCE
@@ -30,10 +28,13 @@
 #include <libxml/tree.h>
 #include <libxml/parser.h>
 #include <libxml/xmlschemas.h>
+#include "qof.h"
 #include "qof-backend-qsf.h"
 #include "qsf-xml.h"
 #include "qsf-dir.h"
 
+static QofLogModule log_module = QOF_MOD_QSF;
+
 static void
 qsf_date_default_handler(const char *default_name, GHashTable *qsf_default_hash,
 	xmlNodePtr parent_tag, xmlNodePtr import_node, xmlNsPtr ns)
@@ -66,7 +67,7 @@
 	xmlNodeAddContent(node, output);
 }
 
-void
+static void
 qsf_map_validation_handler(xmlNodePtr child, xmlNsPtr ns, qsf_validator *valid)
 {
 	xmlChar *qof_version, *match;
@@ -118,21 +119,21 @@
 	map_path = g_strdup_printf("%s/%s", QSF_SCHEMA_DIR, map_file);
 	if(path == NULL) {
 		qof_backend_set_error(params->be, ERR_FILEIO_FILE_NOT_FOUND);
-		return FALSE; 
+		return FALSE;
 	}
 	doc = xmlParseFile(path);
 	if(doc == NULL) {
 		qof_backend_set_error(params->be, ERR_FILEIO_PARSE_ERROR);
 		return FALSE;
 	}
-	if(TRUE != qsf_is_valid(QSF_SCHEMA_DIR, QSF_OBJECT_SCHEMA, doc)) { 
+	if(TRUE != qsf_is_valid(QSF_SCHEMA_DIR, QSF_OBJECT_SCHEMA, doc)) {
 		qof_backend_set_error(params->be, ERR_QSF_INVALID_OBJ);
-		return FALSE; 
+		return FALSE;
 	}
 	object_root = xmlDocGetRootElement(doc);
 	if(map_path == NULL) {
 		qof_backend_set_error(params->be, ERR_FILEIO_FILE_NOT_FOUND);
-		return FALSE; 
+		return FALSE;
 	}
 	valid.validation_table = g_hash_table_new(g_str_hash, g_str_equal);
 	map_doc = xmlParseFile(map_path);
@@ -140,9 +141,9 @@
 		qof_backend_set_error(params->be, ERR_FILEIO_PARSE_ERROR);
 		return FALSE;
 	}
-	if(TRUE != qsf_is_valid(QSF_SCHEMA_DIR, QSF_MAP_SCHEMA, map_doc)) { 
+	if(TRUE != qsf_is_valid(QSF_SCHEMA_DIR, QSF_MAP_SCHEMA, map_doc)) {
 		qof_backend_set_error(params->be, ERR_QSF_INVALID_MAP);
-		return FALSE; 
+		return FALSE;
 	}
 	map_root = xmlDocGetRootElement(map_doc);
 	valid.map_calculated_count = 0;
@@ -251,7 +252,7 @@
 	}
 	if(TRUE != qsf_is_valid(QSF_SCHEMA_DIR, QSF_MAP_SCHEMA, doc)) {
 		qof_backend_set_error(params->be, ERR_QSF_INVALID_MAP);
-		return FALSE; 
+		return FALSE;
 	}
 	map_root = xmlDocGetRootElement(doc);
 	map_ns = map_root->ns;
@@ -281,7 +282,7 @@
 	doc = xmlParseFile(path);
 	if(doc == NULL) { return FALSE; }
 	if(TRUE != qsf_is_valid(QSF_SCHEMA_DIR, QSF_MAP_SCHEMA, doc)) {
-		return FALSE; 
+		return FALSE;
 	}
 	map_root = xmlDocGetRootElement(doc);
 	map_ns = map_root->ns;
@@ -301,7 +302,7 @@
 qsf_map_default_handler(xmlNodePtr child, xmlNsPtr ns, qsf_param *params )
 {
 	xmlChar *qsf_enum;
-	
+
 	g_return_if_fail(params->qsf_define_hash != NULL);
 	if (qsf_is_element(child, ns, MAP_DEFINE_TAG)) {
 		if(NULL == g_hash_table_lookup(params->qsf_define_hash,
@@ -312,6 +313,7 @@
 		}
 		else {
 			qof_backend_set_error(params->be, ERR_QSF_BAD_MAP);
+			PERR (" ERR_QSF_BAD_MAP set");
 			return;
 		}
 	}
@@ -320,18 +322,20 @@
 		{
 			qsf_enum = xmlNodeGetContent(child);
 			/** Use content to discriminate enums in QOF */
+			PERR (" enum todo incomplete");
 			/** \todo FIXME: the default enum value is not used
 			implemented properly or fully handled.
 			*/
 			if(NULL == g_hash_table_lookup(params->qsf_default_hash,
 				xmlNodeGetContent(child)))
 			{
-				g_hash_table_insert(params->qsf_default_hash, 
+				g_hash_table_insert(params->qsf_default_hash,
 					xmlNodeGetContent(child), child);
 			}
 			else
 			{
 				qof_backend_set_error(params->be, ERR_QSF_BAD_MAP);
+				PERR (" ERR_QSF_BAD_MAP set");
 				return;
 			}
 		}
@@ -348,13 +352,14 @@
 				xmlGetProp(child_node, MAP_NAME_ATTR), child_node))*/
 			{
 				qof_backend_set_error(params->be, ERR_QSF_BAD_MAP);
+				LEAVE (" ");
 				return;
 			}
 		}
 	}
 }
 
-void
+static void
 qsf_map_top_node_handler(xmlNodePtr child, xmlNsPtr ns, qsf_param *params)
 {
 	xmlChar	*qof_version;
@@ -369,6 +374,7 @@
 		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");
 			return;
 		}
 		iter.ns = ns;
@@ -394,7 +400,7 @@
 }
 
 /* Handles the set tag in the map.
-This function will be overhauled once inside QOF 
+This function will be overhauled once inside QOF
 QOF hook required for "Lookup in the receiving application"
 */
 static char*
@@ -403,25 +409,27 @@
 {
 	xmlNodePtr cur_node, lookup_node;
 
+	ENTER (" lookup problem");
 	content = NULL;
 	for(cur_node = parent->children; cur_node != NULL; cur_node = cur_node->next)
 	{
-		if(qsf_is_element(cur_node, params->map_ns, QSF_CONDITIONAL_SET)) 
+		if(qsf_is_element(cur_node, params->map_ns, QSF_CONDITIONAL_SET))
 		{
 			content = (char*)xmlGetProp(cur_node, BAD_CAST QSF_OPTION);
-			if(qsf_strings_equal(xmlGetProp(cur_node, BAD_CAST QSF_OPTION), "qsf_lookup_string")) 
+			if(qsf_strings_equal(xmlGetProp(cur_node, BAD_CAST QSF_OPTION), "qsf_lookup_string"))
 			{
-				lookup_node = (xmlNodePtr) g_hash_table_lookup(default_hash, 
+				lookup_node = (xmlNodePtr) g_hash_table_lookup(default_hash,
 					xmlNodeGetContent(cur_node));
 				content = (char*)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 );
+				LEAVE (" todo");
 				return content;
 			}
-			if(content) 
+			if(content)
 			{
-				lookup_node = (xmlNodePtr) g_hash_table_lookup(default_hash, 
+				lookup_node = (xmlNodePtr) g_hash_table_lookup(default_hash,
 					xmlNodeGetContent(cur_node));
 				content = (char*)xmlGetProp(lookup_node, BAD_CAST "value");
 				return content;
@@ -432,10 +440,12 @@
 				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); }
+				LEAVE (" check arguments");
 				return (char*)xmlNodeGetContent(cur_node);
 			}
 		}
 	}
+	LEAVE (" null");
 	return NULL;
 }
 
@@ -490,6 +500,7 @@
 
 	result = 0;
 	if(format == NULL) { return; }
+	ENTER (" ");
 	content = xmlNodeGetContent(cur_node);
 	output = (time_t*) g_hash_table_lookup(params->qsf_default_hash, content);
 	if(!output) {
@@ -501,13 +512,13 @@
 		/** \todo qsf_parameter_hash check correct arguments */
 		kl = (xmlNodePtr) g_hash_table_lookup(params->qsf_parameter_hash, content);
 		if(!kl) {
-			printf("no suitable date set.\n");
+			LEAVE (" no suitable date set.");
 			return;
 		}
 		/** Read the object value as a dateTime  */
 		strptime((char*)xmlNodeGetContent(kl), QSF_XSD_TIME, tmp);
 		if(!tmp) {
-			printf("empty date field in QSF object.\n");
+			LEAVE (" empty date field in QSF object.\n");
 			return;
 		}
 		tester = mktime(tmp);
@@ -520,6 +531,7 @@
 	/** QSF_DATE_LENGTH preset for all internal and QSF_XSD_TIME string formats.
 	 */
 	strftime(qsf_time_now_as_string, QSF_DATE_LENGTH, (char*)format, gmtime(output));
+	LEAVE (" ok");
 }
 
 static void
@@ -546,7 +558,6 @@
 
 	output_content = NULL;
 	if(qsf_is_element(param_node, params->map_ns, QSF_CONDITIONAL)) {
-		printf("param_node=%s\n", param_node->name);
 		if(params->boolean_calculation_done == 0) {
 		/* set handler */
 		output_content = BAD_CAST qsf_set_handler(param_node, params->qsf_default_hash,
@@ -559,7 +570,7 @@
 				BAD_CAST QSF_BOOLEAN_DEFAULT) ), BAD_CAST MAP_VALUE_ATTR);
 			}
 			/* Is the default set to true? */
-			if( 0 == qsf_compare_tag_strings(output_content, QSF_XML_BOOLEAN_TEST)) 
+			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);
 				export_node = xmlAddChild(params->lister, xmlNewNode(params->qsf_ns,
@@ -587,13 +598,13 @@
 	extra_node = xmlAddChild(params->output_node,
 		xmlNewNode(params->qsf_ns, BAD_CAST QSF_OBJECT_TAG));
 	xmlNewProp(extra_node, BAD_CAST QSF_OBJECT_TYPE,
-		xmlGetProp(params->cur_node, BAD_CAST QSF_OBJECT_TYPE));
+		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;
 }
 
-void
+static void
 qsf_map_object_handler(xmlNodePtr child, xmlNsPtr ns, qsf_param *params)
 {
 	xmlNodePtr param_node, export_node;
@@ -609,7 +620,7 @@
 	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;
 		for(param_node = child->children; param_node != NULL;
@@ -669,11 +680,12 @@
 			xmlGetProp(child_node, MAP_VALUE_ATTR), child_node->name);
 			return;
 		}
-		
+
 		is_qsf_object_with_map(path, map_path);
 */
 	}
 }
+
 xmlDocPtr
 qsf_object_convert(xmlDocPtr mapDoc, xmlNodePtr qsf_root, qsf_param *params)
 {
@@ -682,6 +694,7 @@
 	xmlNode *cur_node;
 	xmlNode *map_root, *output_root, *output_node;
 
+	ENTER (" ");
 	output_doc = xmlNewDoc(BAD_CAST QSF_XML_VERSION);
 	output_root = xmlDocCopyNode(qsf_root,output_doc,2);
 	xmlSetNs(output_root, params->qsf_ns);
@@ -693,11 +706,9 @@
 	iter.ns = params->map_ns;
 	qsf_node_foreach(map_root, qsf_map_top_node_handler, &iter, params);
 
-//	iter.ns = qsf_ns;
-//	qsf_node_foreach(qsf_root, qsf_map_object_handler, &iter, params);
 	for(cur_node = map_root->children; cur_node != NULL; cur_node = cur_node->next)
 	{
-		params->cur_node = cur_node;
+		params->convert_node = cur_node;
 		params->count = 0;
 		if(qsf_is_element(cur_node, params->map_ns, MAP_OBJECT_TAG))
 		{
@@ -708,5 +719,6 @@
 		}
 	}
 	params->file_type = OUR_QSF_OBJ;
+	LEAVE (" ");
 	return output_doc;
 }

Modified: gnucash/trunk/lib/libqof/backend/file/qsf-xml.c
===================================================================
--- gnucash/trunk/lib/libqof/backend/file/qsf-xml.c	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/backend/file/qsf-xml.c	2006-01-08 17:51:29 UTC (rev 12299)
@@ -18,30 +18,19 @@
  *
  *  You should have received a copy of the GNU General Public License
  *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- *  02110-1301, USA.
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
 #define _GNU_SOURCE
 
 #include <libxml/xmlversion.h>
+#include "qof.h"
 #include "qof-backend-qsf.h"
 #include "qsf-dir.h"
 #include "qsf-xml.h"
 
 static QofLogModule log_module = QOF_MOD_QSF;
 
-void qsf_free_params(qsf_param *params)
-{
-	g_hash_table_destroy(params->qsf_calculate_hash);
-	g_hash_table_destroy(params->qsf_default_hash);
-	if(params->referenceList) {
-		g_list_free(params->referenceList);
-	}
-	g_slist_free(params->supported_types);
-	if(params->map_ns) { xmlFreeNs(params->map_ns); }
-}
-
 int
 qsf_compare_tag_strings(const xmlChar *node_name, char *tag_name)
 {
@@ -138,13 +127,13 @@
 			if(g_hash_table_size(valid->validation_table) > count)
 			{
 				valid->valid_object_count++;
-			if(TRUE == qof_class_is_registered((QofIdTypeConst) object_declaration))
-			{
-				valid->qof_registered_count++;
+				if(TRUE == qof_class_is_registered((QofIdTypeConst) object_declaration))
+				{
+					valid->qof_registered_count++;
+				}
 			}
 		}
 	}
-	}
 }
 
 gboolean is_our_qsf_object(const char *path)
@@ -164,13 +153,14 @@
 		return FALSE; 
 	}
 	object_root = xmlDocGetRootElement(doc);
+	/* check that all objects in the file are already registered in QOF */
 	valid.validation_table = g_hash_table_new(g_str_hash, g_str_equal);
 	valid.qof_registered_count = 0;
 	valid.valid_object_count = 0;
 	iter.ns = object_root->ns;
 	qsf_valid_foreach(object_root, qsf_object_validation_handler, &iter, &valid);
 	table_count = g_hash_table_size(valid.validation_table);
-		g_hash_table_destroy(valid.validation_table);
+	g_hash_table_destroy(valid.validation_table);
 	if(table_count == valid.qof_registered_count) { return TRUE; }
 	return FALSE;
 }
@@ -184,8 +174,9 @@
 	doc = xmlParseFile(path);
 	if(doc == NULL) { return FALSE; }
 	if(TRUE != qsf_is_valid(QSF_SCHEMA_DIR, QSF_OBJECT_SCHEMA, doc)) { return FALSE; }
-	/** \todo implement a way of finding more than one map */
-	return is_qsf_object_with_map(path, "pilot-qsf-GnuCashInvoice.xml");
+	/* Note cannot test against a map here, so if the file is valid QSF,
+	accept it and work out the details later. */
+	return TRUE;
 }
 
 gboolean is_our_qsf_object_be(qsf_param *params)
@@ -209,7 +200,7 @@
 		qof_backend_set_error(params->be, ERR_FILEIO_PARSE_ERROR);
 		return FALSE;
 	}
-	if(TRUE != qsf_is_valid(QSF_SCHEMA_DIR, QSF_OBJECT_SCHEMA, doc)) 
+	if(TRUE != qsf_is_valid(QSF_SCHEMA_DIR, QSF_OBJECT_SCHEMA, doc))
 	{
 		qof_backend_set_error(params->be, ERR_QSF_INVALID_OBJ);
 		return FALSE;
@@ -234,7 +225,9 @@
 
 gboolean is_qsf_object_be(qsf_param *params)
 {
+	gboolean result;
 	xmlDocPtr doc;
+	GList *maps;
 	char *path;
 
 	g_return_val_if_fail((params != NULL),FALSE);
@@ -258,8 +251,14 @@
 			return FALSE;
 		}
 	}
-	/** \todo implement a way of finding more than one map */
-	return is_qsf_object_with_map_be("pilot-qsf-GnuCashInvoice.xml", params);
+	result = FALSE;
+	/* retrieve list of maps from config frame. */
+	for(maps = params->map_files; maps; maps=maps->next)
+	{
+		result = is_qsf_object_with_map_be(maps->data, params);
+		if(result) { break;}
+	}
+	return result;
 }
 
 static void

Modified: gnucash/trunk/lib/libqof/backend/file/qsf-xml.h
===================================================================
--- gnucash/trunk/lib/libqof/backend/file/qsf-xml.h	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/backend/file/qsf-xml.h	2006-01-08 17:51:29 UTC (rev 12299)
@@ -18,15 +18,14 @@
  *
  *  You should have received a copy of the GNU General Public License
  *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- *  02110-1301, USA.
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
  #ifndef QSF_XML_H
  #define QSF_XML_H
 
 /** @file qsf-xml.h
-    @brief  Private QSF header
+    @brief  Private QSF header - not for use by applications
     @author Copyright (C) 2004-2005 Neil Williams <linux at codehelp.co.uk>
 */
 
@@ -39,15 +38,7 @@
 #include <libxml/tree.h>
 #include <libxml/parser.h>
 #include <libxml/xmlschemas.h>
-#include "gnc-date.h"
-#include "qof_book_merge.h"
-#include "qofbook.h"
-#include "qofclass.h"
-#include "qofobject.h"
-#include "kvp_frame.h"
-#include "qofbackend-p.h"
-#include "qofsession-p.h"
-#include "qofbook-p.h"
+#include "qof.h"
 
 #if defined(HAVE_GETTEXT)             /* HAVE_GETTEXT */
 
@@ -118,15 +109,19 @@
 
 The map namespace is not included as maps are not currently written out by QOF.
 */
-#define QSF_DATE_LENGTH 31 /**< Max length of QSF_XSD_TIME */
-#define QSF_BOOK_TAG	"book" /**< First level child: book tag - the ::QofBook. */
-#define QSF_BOOK_GUID	"book-guid" /**< QOF GUID tag for the QofBook described by this QSF object file */
-#define QSF_BOOK_COUNT	"count" /**< Sequential counter of each book in this file */
-#define QSF_OBJECT_TAG	"object" /**< Second level child: object tag */
-#define QSF_OBJECT_TYPE	"type" /**< QSF parameter name for object type specifiers */
-#define QSF_OBJECT_COUNT "count" /**< Sequential counter for each QSF object in this file */
-#define QSF_XML_VERSION  "1.0"  /**< The current XML version. */
+#define QSF_DATE_LENGTH MAX_DATE_LENGTH /**< Max length of QSF_XSD_TIME.
 
+MAX_DATE_LENGTH itself is defined in gnc-date.h */
+#define QSF_BOOK_TAG	"book"      /**< First level child: book tag - the ::QofBook. */
+#define QSF_BOOK_GUID	"book-guid" /**< QOF GUID tag for the QofBook
+					described by this QSF object file */
+#define QSF_BOOK_COUNT	"count"     /**< Sequential counter of each book in this file */
+#define QSF_OBJECT_TAG	"object"    /**< Second level child: object tag */
+#define QSF_OBJECT_TYPE	"type"      /**< QSF parameter name for object type specifiers */
+#define QSF_OBJECT_COUNT "count"    /**< Sequential counter for each QSF object
+					in this file */
+#define QSF_XML_VERSION  "1.0"      /**< The current XML version. */
+
 /** @} */
 /** @name Representing KVP as XML
 
@@ -161,11 +156,12 @@
 Attributes: e_type Copied directly from the QofObject definition.
 Content: The full QofObject description for the defined QOF object.
 */
-#define MAP_DEFAULT_TAG	"default"  /**< User editable defaults for data not available within the
-available QSF objects.
+#define MAP_DEFAULT_TAG	"default"  /**< User editable defaults for data not
+available within the available QSF objects.
 
-Some defaults will relate to how to format descriptive dates, whether discount should be considered,
-which account to use for certain QSF data from applications that don't use accounts.
+Some defaults will relate to how to format descriptive dates, whether discount
+should be considered, which account to use for certain QSF data from applications
+that don't use accounts.
 
 Some defaults are pre-defined and cannot be over-written:
 - qsf_time_now
@@ -173,10 +169,10 @@
 
 Attributes (All are mandatory): 
 
-\a name The text name for this default. Certain pre-defined defaults exist but user- or
-map-defined defaults can have any unique text name. Spaces are \b NOT allowed, use undersccores
-instead. The value of name must not duplicate any existing default, define, object or parameter
-unless the special type, enum, is used.
+\a name The text name for this default. Certain pre-defined defaults exist but
+user- or map-defined defaults can have any unique text name. Spaces are \b NOT allowed, 
+use undersccores instead. The value of name must not duplicate any existing default,
+define, object or parameter unless the special type, enum, is used.
 
 \a type QOF_TYPE - must be one of the recognised QOF data types for the
 qof_version in use or the special type, enum.
@@ -188,10 +184,10 @@
 
 A boolean default is not output in the QSF directly, instead the value is
 used in the calculations to modify certain values. If the boolean default
-is set to true, the if statement containing the boolean name will be evaluated. If the boolean
-default is set to false, the corresponding else will be evaluted. Make sure your
-calculations contain an appropriate else statement so that the boolean value
-can be adjusted without invalidating the map!
+is set to true, the if statement containing the boolean name will be evaluated.
+If the boolean default is set to false, the corresponding else will be evaluted.
+Make sure your calculations contain an appropriate else statement so that the
+boolean value can be adjusted without invalidating the map!
 
 QSF deals with partial QofBooks - each object is fully described but the
 book does not have to contain any specific object types or have any
@@ -209,51 +205,60 @@
 map cannot contain the GUID as it is generic and used by multiple users.
 
 \attention Using enumerators
-- enum types are the only defaults that are allowed to use the same name value more than once. 
+- enum types are the only defaults that are allowed to use the same name value
+more than once. 
 - enum types are used to increase the readability of a QSF map.
-- The enum name acts to group the enum values together - in a similar fashion to radio buttons in HTML forms. 
+- The enum name acts to group the enum values together - in a similar fashion to
+radio buttons in HTML forms. 
 - enum types are used only where the QOF object itself uses an enum type. 
 
-e.g. the tax_included enum type allows maps to use the full name of the enum value GNC_TAXINCLUDED_YES,
-instead of the cryptic digit value, 1.
+e.g. the tax_included enum type allows maps to use the full name of the enum
+value GNC_TAXINCLUDED_YES, instead of the cryptic digit value, 1.
 
 */
-#define MAP_OBJECT_TAG	"object" /**< Contains all the calculations to make one object from others.
+#define MAP_OBJECT_TAG	"object" /**< Contains all the calculations to make one
+object from others.
 
-Note that creating an object for the import application can involve using data from more than one
-QSF object, as well as defaults and lookups in the import application itself. Conditionals, simple
-arithmetic and date/time formatting options are also available.
+Note that creating an object for the import application can involve using data
+from more than one QSF object, as well as defaults and lookups in the import
+application itself. Conditionals, simple arithmetic and date/time formatting 
+options are also available.
 */
-#define MAP_CALCULATE_TAG	"calculate" /**< One calculation for every parameter that needs to be set.
+#define MAP_CALCULATE_TAG	"calculate" /**< One calculation for every parameter
+that needs to be set.
 
-QSF follows the same rule as qof_book_merge. Only if a getter and a setter function are defined for
-a parameter is it available to QSF. If a ::QofAccessFunc and ::QofSetterFunc are both defined
-for any QofObject parameter, that parameter \b MUST be calculated in any map that defines that object.
+QSF follows the same rule as qof_book_merge. Only if a getter and a setter
+function are defined for a parameter is it available to QSF. If a ::QofAccessFunc 
+and ::QofSetterFunc are both defined for any QofObject parameter, that parameter 
+\b MUST be calculated in any map that defines that object.
 */
 #define MAP_QOF_VERSION	"qof_version" /**< This is the QOF_OBJECT_VERSION from QOF.
 
-QSF maps may need to be updated if QOF itself is upgraded. This setting is coded into QOF and 
-maps for one version cannot necessarily be used by other versions. At the first release of QSF,
-QOF_OBJECT_VERSION = 3.
+QSF maps may need to be updated if QOF itself is upgraded. This setting is coded
+into QOF and maps for one version cannot necessarily be used by other versions.
+At the first release of QSF, QOF_OBJECT_VERSION = 3.
 */
 #define MAP_NAME_ATTR	"name" /**< The name of the default setting.
 
 Use this name to refer to the value of this default in the map calculations.
 
-Make sure that the type of this default matches the type of the parameter being set by the 
-parent calculation!
+Make sure that the type of this default matches the type of the parameter being
+set by the parent calculation!
 */
 #define MAP_TYPE_ATTR	"type" /**< QSF will NOT convert between QOF types.
 
-QSF will allow a conditional to use a parameter of one type to determine the value from a parameter of
-another type, but the final value assigned \b MUST be of the same type as the parent calculation.
+QSF will allow a conditional to use a parameter of one type to determine the
+value from a parameter of another type, but the final value assigned \b MUST be
+of the same type as the parent calculation.
 */
-#define MAP_VALUE_ATTR	"value" /**< The value of the tag, used in defaults and calculations.
+#define MAP_VALUE_ATTR	"value" /**< The value of the tag, used in defaults and
+calculations.
 
 The value of a default is a string representation of the value to be inserted into
 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.
+The value of a calculation is the name of the parameter that will be set by that
+calculation.
 */
 #define MAP_E_TYPE	"e_type" /**< Validates the objects defined in the map 
 
@@ -283,16 +288,17 @@
 Map assignments can use the native values within the output object. The output object
 must support setting the relevant parameter using the value exactly as given in the map 
 because the relevant set() function will be called using this value. This may reduce the 
-readability of the map but the relevant application could also be modified to support a more 
-readable set function.
+readability of the map but the relevant application could also be modified to support
+a more readable set function.
 */
 #define QSF_CONDITIONAL_ELSE "else" /**< Alternative
 
-if(){} else{} is also supported. Nesting of conditionals causes problems for validating the
-final map against any sensible XML Schema and a map that doesn't validate will be rejected. 
-When editing conditionals in a QSF map, ALWAYS validate the map using xmllint. If necessary, 
-define a variable at the foot of the definitions block, using a similar syntax to a default, 
-then use that variable in another conditional
+if(){} else{} is also supported. Nesting of conditionals causes problems for
+validating the final map against any sensible XML Schema and a map that doesn't 
+validate will be rejected. When editing conditionals in a QSF map, ALWAYS 
+validate the map using xmllint. If necessary, define a variable at the foot of 
+the definitions block, using a similar syntax to a default, then use that 
+variable in another conditional
 
 \a variable \a name="my_rate" \a type="numeric" \a value="0/1"
 
@@ -322,7 +328,8 @@
 
 /** @} */
 
-#define QSF_XSD_TIME  QOF_UTC_DATE_FORMAT /**< xsd:dateTime format in coordinated universal time, UTC.
+#define QSF_XSD_TIME  QOF_UTC_DATE_FORMAT /**< xsd:dateTime format in coordinated
+universal time, UTC.
 
 You can reproduce the string from the GNU/Linux command line using the date utility: 
 
@@ -332,21 +339,22 @@
 
 The datestring must be timezone independent and include all specified fields.
 
-Remember to use gmtime() NOT localtime()!. From the command line, use the -u switch with the 
-date command: date -u
+Remember to use gmtime() NOT localtime()!. From the command line, use the
+-u switch with the date command: date -u
 
-To generate a timestamp based on a real time, use the qsf_time_now and qsf_time_string defaults.
+To generate a timestamp based on a real time, use the qsf_time_now and
+qsf_time_string defaults.
 
-qsf_time_now : Format: QOF_TYPE_DATE. The current time taken from the moment the default
-is read into a QSF object at runtime.
+qsf_time_now : Format: QOF_TYPE_DATE. The current time taken from the moment
+the default is read into a QSF object at runtime.
 
-qsf_time_string : Format: QOF_TYPE_STRING. The current timestamp taken from the moment the
-default is read into a QSF object at runtime. This form is used when the output parameter 
-needs a formatted date string, not an actual date object. The format is determined by the 
-optional format attribute of the set tag which takes the same operators as the GNU C Library 
-for strftime() and output may therefore be dependent on the locale of the calling process - 
-\b take \b care. Default value is %F, used when qsf_time_string is set without the format
-attribute.
+qsf_time_string : Format: QOF_TYPE_STRING. The current timestamp taken from the 
+moment the default is read into a QSF object at runtime. This form is used when 
+the output parameter needs a formatted date string, not an actual date object. 
+The format is determined by the optional format attribute of the set tag which 
+takes the same operators as the GNU C Library for strftime() and output may therefore 
+be dependent on the locale of the calling process - \b take \b care. Default value 
+is %F, used when qsf_time_string is set without the format attribute.
 
 Both defaults use UTC.
 
@@ -371,10 +379,16 @@
 	GList *referenceList;        /**< Table of references, ::QofEntityReference. */
 	GHashTable *qsf_parameter_hash; /**< Hashtable of parameters for each object */
 	GHashTable *qsf_calculate_hash, *qsf_default_hash, *qsf_define_hash;
-	GSList *supported_types;     /**< The partial list of QOF types currently supported, in QSF order. */
-	xmlDocPtr input_doc, output_doc; /**< Pointers to the input and output xml document(s). */
-	/** \todo Review the list of xml nodes in qsf_param and rationalise. */
-	xmlNodePtr child_node, cur_node, param_node, output_node, output_root, book_node, lister;
+	GSList *supported_types;     /**< The list of QOF types currently supported, in QSF order. */
+	xmlDocPtr input_doc;         /**< Pointer to the input xml document(s). */
+	xmlDocPtr output_doc;        /**< Pointer to the output xml document(s). */
+	xmlNodePtr child_node;       /**< The current child_node. */
+	xmlNodePtr convert_node;     /**< Node in the converted object */
+	xmlNodePtr param_node;       /**< Node for parameter data. */
+	xmlNodePtr output_node;      /**< Node in the output document. */
+	xmlNodePtr output_root;      /**< Root node of the output document. */
+	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 */
 	QofIdType qof_obj_type;	     /**< current QofObject type (e_type) for the parameters. */
@@ -387,23 +401,19 @@
 		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. */
+	char *filepath;               /**< Path to the QSF file. */
+	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.
+
+	Defaults to the pre-installed QSF maps, currently: pilot-qsf-GnuCashInvoice.xml
+	*/
 }qsf_param;
 
-/** \brief Free the QSF context.
-
-Frees the two GHashTables, the GSList, the output xmlDoc
-and the two xmlNs namespaces.
-*/
-void qsf_free_params(qsf_param *params);
-
 /** \brief Validation metadata
 
 The validation is a separate parse with separate data.
-This may change but it currently saves workload.
-
-\todo Examine ways of making the Validation metadata
-into a sub-set of the main code, not an island on it's own.
+This is used to determine which backend should load the data.
 */
 typedef struct qsf_validates
 {
@@ -416,7 +426,6 @@
 	int qof_registered_count;
 }qsf_validator;
 
-
 /** \brief shorthand function
 
 This may look repetitive but each one is used separately
@@ -457,28 +466,6 @@
 void
 qsf_object_validation_handler(xmlNodePtr child, xmlNsPtr ns, qsf_validator *valid);
 
-/** @name Map Checks
-@{
-Check that the map is sufficient for this object. 
-
-Map is usable if all input objects are defined in the object file.
-Count define tags, subtract those calculated in the map (defined as objects)
-Check each remaining object e_type and description against the objects
-declared in the object file. Fail if some map objects remain undefined.
-
-not finished - expect noticeable changes.
-
-*/
-void
-qsf_map_validation_handler(xmlNodePtr child, xmlNsPtr ns, qsf_validator *valid);
-
-void
-qsf_map_top_node_handler(xmlNodePtr child, xmlNsPtr ns, qsf_param *params);
-
-void
-qsf_map_object_handler(xmlNodePtr child, xmlNsPtr ns, qsf_param *params);
-/** @} */
-
 /** \brief Compares an xmlDoc in memory against the schema file.
 
 @param	schema_dir  set at compile time to $prefix/share/qsf/
@@ -494,6 +481,52 @@
 gboolean
 qsf_is_valid(const char *schema_dir, const char* schema_filename, xmlDocPtr doc);
 
+/** \brief Prepare the default list of maps.
+
+Prepend the default maps to the supplied GList.
+
+The GList remains the property of the caller.
+*/
+GList** qsf_map_prepare_list(GList **maps);
+
+/** \name Why two sets of functions and typedefs?
+
+These functions are in pairs, one to use in an existing session and one to use
+when deciding which backend should be selected for a new session.
+- When there is an existing QofSession, the qsf_param
+context will be available, so set error codes in the backend.
+Use the *_be functions.
+- When just determining the type of file, qsf_param is
+not necessary and no backend is available (it has not been selected yet).
+Use the twin function. e.g. in ::qsf_file_type()
+
+@{
+*/
+/** \brief map and qsf object callback
+
+This callback cannot do both the map and the validation tasks
+because validation sometimes needs to be done without qsf_params.
+
+e.g. when selecting which backend should be used for a particular
+data source where two or more backends share the same access_method.
+*/
+typedef void (* qsf_nodeCB)(xmlNodePtr, xmlNsPtr, qsf_param*);
+/** \brief validator callback
+
+\todo The need for separate metadata means a separate callback typedef
+	is needed for the validator, but this should be fixed to only need one.
+*/
+typedef void (* qsf_validCB)(xmlNodePtr, xmlNsPtr, qsf_validator*);
+/** \brief One iterator, two typedefs
+
+\todo resolve the two callbacks in ::qsf_node_iterate into one.
+*/
+struct qsf_node_iterate {
+	qsf_nodeCB *fcn;
+	qsf_validCB *v_fcn;
+	xmlNsPtr ns;
+};
+
 /** \brief Validate a QSF file and identify a suitable QSF map
 
 @param	params	Pointer to qsf_param context
@@ -512,7 +545,24 @@
 otherwise FALSE.
 */
 gboolean is_qsf_object_be(qsf_param *params);
+/** \brief Validate a QSF file and identify a suitable QSF map
 
+ at param	path	Absolute or relative path to the file to be validated.
+
+These functions are in pairs. When called from within a QofSession, the qsf_param
+context will be available. When just determining the type of file, qsf_param is
+not necessary. Use the *_be functions from within the QofBackend and the 
+corresponding function in other code.
+
+The file is validated against the QSF object schema, qsf-object.xsd.xml and
+each object described in the file is checked to find out if a suitable QSF
+map exists. Map files are accepted if all objects described in the QSF object
+file are defined in the QSF map.
+
+ at return TRUE if the file validates and a QSF map can be found,
+otherwise FALSE.
+*/
+gboolean is_qsf_object(const char *path);
 /** \brief Validate a QSF file and determine type.
 
 @param	params	Pointer to qsf_param context
@@ -528,7 +578,21 @@
 otherwise FALSE.
 */
 gboolean is_our_qsf_object_be(qsf_param *params);
+/** \brief Validate a QSF file.
 
+ at param	path	Absolute or relative path to the file to be validated
+
+The file is validated against the QSF object schema, qsf-object.xsd.xml and
+each object described in the file is checked to see if it is registered
+with QOF within the QOF environment of the calling process.
+
+Files that pass the test can be imported into the QOF appliction without the need
+for a QSF map.
+
+ at return TRUE if the file validates and all objects pass,
+otherwise FALSE.
+*/
+gboolean is_our_qsf_object(const char *path);
 /** \brief Validate a QSF map file.
 
 @param	params	Pointer to qsf_param context
@@ -541,7 +605,23 @@
 @return TRUE if the map validates, otherwise FALSE.
 */
 gboolean is_qsf_map_be(qsf_param *params);
+/** \brief Validate a QSF map file.
 
+ at param	path	Absolute or relative path to the file to be validated
+
+These functions are in pairs. When called from within a QofSession, the qsf_param
+context will be available. When just determining the type of file, qsf_param is
+not necessary. Use the *_be functions from within the QofBackend and the 
+corresponding function in other code.
+
+The file is validated aginst the QSF map schema, qsf-map.xsd.xsml. This
+function is called by ::is_qsf_object. If called directly, the map file
+is validated and closed, no data is retrieved. QSF maps do not contain
+user data but are used to import QSF object files from other applications.
+
+ at return TRUE if the map validates, otherwise FALSE.
+*/
+gboolean is_qsf_map(const char *path);
 /** \brief Validate a QSF file and a selected QSF map
 
 @param	map_path	Absolute or relative path to the selected QSF map file
@@ -552,35 +632,29 @@
 map is suitable. Map files are accepted if all objects described in the QSF object
 file are defined in the QSF map.
 
-\todo Need to code for how to find these files.
+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);
+/** \brief Validate a QSF file and a selected QSF map
 
-gboolean is_qsf_object_with_map(const char *path, char *map_file);
+ at param	map_path	Absolute or relative path to the selected QSF map file
+ at param	params	Pointer to qsf_param context
 
-/**	\brief QOF processing routine.
+The file is validated against the QSF object schema, qsf-object.xsd.xml and
+each object described in the file is checked to find out if the supplied QSF
+map is suitable. Map files are accepted if all objects described in the QSF object
+file are defined in the QSF map.
 
-Called by ::qof_session_load if a map is required.
-Accepts QSF_OBJECT.
-
-Checks available QSF maps for match. Only succeeds if a suitable map exists.
-
+ at return TRUE if the file validates and the supplied QSF map is usable,
+otherwise FALSE.
 */
-gboolean
-load_qsf_object(QofBook *book, const char *fullpath, qsf_param *params);
+gboolean is_qsf_object_with_map(const char *path, char *map_file);
 
-/**	\brief QOF processing routine.
+/** @} */
 
-Called using ::qof_session_load when all objects defined in the
-XML are registered in the current instance of QOF.
-*/
-gboolean
-load_our_qsf_object(QofBook *book, const char *fullpath, qsf_param *params);
-
 /** \brief Book and book-guid node handler.
 
 Reads the book count="" attribute (currently only 1 QofBook is supported per QSF object file)
@@ -589,31 +663,6 @@
 */
 void qsf_book_node_handler(xmlNodePtr child, xmlNsPtr qsf_ns, qsf_param *params);
 
-/** \brief Commit the QSF object data to a new QofBook.
-
-The parentage of qof_book_merge should be obvious in this function.
-
-Large chunks were just lifted directly from the commit loop and adjusted
-to obtain the data to commit from the xmlNodePtr instead of qof_book_mergeRule. If
-anything, it's easier here because all entities are new, there are no targets.
-
-Unlike qof_book_merge, this routine runs once per parameter within a loop
-that iterates over objects - it does not have a loop of it's own.
-
-All entities are new.
-
-Using the parent of the current node to 
-retrieve the type parameter of the parent provides the type parameter of
-the object tag - the e_type of the current QofObject which allows 
-qof_class_get_parameter_setter(obj_type, key);
-
- at param	key		name of the parameter: QofIdType
- at param	value	xmlNodePtr value->name == QOF_TYPE, content(value) = data to commit.
- at param	data	qsf_param* - inevitably.
-
-*/
-void qsf_object_commitCB(gpointer key, gpointer value, gpointer data);
-
 /** \brief Convert a string value into KvpValue
 
 Partner to ::kvp_value_to_string. Given the type of KvpValue
@@ -629,168 +678,25 @@
 KvpValue*
 string_to_kvp_value(const char *content, KvpValueType type);
 
-/** \brief Backend init routine.
+/** Validate the children of the parent node.
 
-Sets the sequence of parameters to match the schema and provide a reliable
-parse. Sets the default strings for qsf_enquiry_date, qsf_time_now and
-qsf_time_string.
-
-Filters the parameter list to set each type in this order:
-- QOF_TYPE_STRING
-- QOF_TYPE_GUID
-- QOF_TYPE_BOOLEAN
-- QOF_TYPE_NUMERIC
-- QOF_TYPE_DATE
-- QOF_TYPE_INT32
-- QOF_TYPE_INT64
-- QOF_TYPE_DOUBLE
-- QOF_TYPE_CHAR
-- QOF_TYPE_KVP
-- QOF_TYPE_COLLECT
-- QOF_TYPE_CHOICE
-
+\note Slightly different to qsf_node_foreach because
+the validation can be run without qsf_param being
+initialized.
 */
-void qsf_param_init(qsf_param *params);
-
-
-/** \brief map callback
-
-Investigate ways to get the map callback to do both
-the map and the validation tasks.
-**/
-typedef void (* qsf_nodeCB)(xmlNodePtr, xmlNsPtr, qsf_param*);
-
-/** \brief validator callback
-
-\todo The need for separate metadata means a separate callback typedef
-	is needed for the validator, but this should be fixed to only need one.
-*/
-typedef void (* qsf_validCB)(xmlNodePtr, xmlNsPtr, qsf_validator*);
-
-
-/** \brief One iterator, two typedefs
-
-\todo resolve the two callbacks in ::qsf_node_iterate into one.
-*/
-struct qsf_node_iterate {
-	qsf_nodeCB *fcn;
-	qsf_validCB *v_fcn;
-	xmlNsPtr ns;
-};
-
-/** \brief Validate a QSF file and identify a suitable QSF map
-
- at param	path	Absolute or relative path to the file to be validated.
-
-These functions are in pairs. When called from within a QofSession, the qsf_param
-context will be available. When just determining the type of file, qsf_param is
-not necessary. Use the *_be functions from within the QofBackend and the 
-corresponding function in other code.
-
-The file is validated against the QSF object schema, qsf-object.xsd.xml and
-each object described in the file is checked to find out if a suitable QSF
-map exists. Map files are accepted if all objects described in the QSF object
-file are defined in the QSF map.
-
- at return TRUE if the file validates and a QSF map can be found,
-otherwise FALSE.
-*/
-gboolean is_qsf_object(const char *path);
-
-/** \brief Validate a QSF file and determine type.
-
- at param	path	Absolute or relative path to the file to be validated
-
-These functions are in pairs. When called from within a QofSession, the qsf_param
-context will be available. When just determining the type of file, qsf_param is
-not necessary. Use the *_be functions from within the QofBackend and the 
-corresponding function in other code.
-
-The file is validated against the QSF object schema, qsf-object.xsd.xml and
-each object described in the file is checked to see if it is registered
-with QOF within the QOF environment of the calling process.
-
-Files that pass the test can be imported into the QOF appliction without the need
-for a QSF map.
-
- at return TRUE if the file validates and all objects pass,
-otherwise FALSE.
-*/
-gboolean is_our_qsf_object(const char *path);
-
-/** \brief Validate a QSF map file.
-
- at param	path	Absolute or relative path to the file to be validated
-
-These functions are in pairs. When called from within a QofSession, the qsf_param
-context will be available. When just determining the type of file, qsf_param is
-not necessary. Use the *_be functions from within the QofBackend and the 
-corresponding function in other code.
-
-The file is validated aginst the QSF map schema, qsf-map.xsd.xsml. This
-function is called by ::is_qsf_object. If called directly, the map file
-is validated and closed, no data is retrieved. QSF maps do not contain
-user data but are used to import QSF object files from other applications.
-
- at return TRUE if the map validates, otherwise FALSE.
-*/
-gboolean is_qsf_map(const char *path);
-
-/** \brief Determine the type of QSF and load it into the QofBook
-
-- is_our_qsf_object, OUR_QSF_OBJ, QSF object file using only QOF objects known to the calling process.
-	No map is required.
-- is_qsf_object, IS_QSF_OBJ, QSF object file that may or may not have a QSF map
-	to convert external objects. This temporary type will be set to HAVE_QSF_MAP if a suitable
-	map exists, or an error value returned: ERR_QSF_NO_MAP, ERR_QSF_BAD_MAP or ERR_QSF_WRONG_MAP
-	This allows the calling process to inform the user that the QSF itself is valid but a
-	suitable map cannot be found.
-- is_qsf_map, IS_QSF_MAP, QSF map file. In the backend, this generates ERR_QSF_MAP_NOT_OBJ but
-	it can be used internally when processing maps to match a QSF object.
-
- at return NULL on error, otherwise a pointer to the QofBook. Use
-	the qof_book_merge API to merge the new data into the current
-	QofBook. 
-*/
 void
-qsf_file_type (QofBackend *be, QofBook *book);
-
-void
 qsf_valid_foreach(xmlNodePtr parent, qsf_validCB cb,
 	struct qsf_node_iterate *iter, qsf_validator *valid);
 
+/** Iterate over the children of the parent node.
+
+Only iterates over the immediate children of the parent -
+this function is \b not recursive.
+*/
 void
 qsf_node_foreach(xmlNodePtr parent, qsf_nodeCB cb,
 	struct qsf_node_iterate *iter, qsf_param *params);
 
-/** \brief Loads the QSF into a QofSession, ready to merge.
- 
-Loads a QSF object file containing only GnuCash objects
-into a second QofSession.
- 
- at param first_session A QofSession pointer to the original session. This
-will become the target of the subsequent qof_book_merge.
-
- at param path	Absolute or relative path to the file to be loaded
- 
- at return ERR_BACKEND_NO_ERR == 0 on success, otherwise the QofBackendError
-	set by the QSFBackend.
-  			
-\todo Build the qof_book_merge code onto this function if session loads
-  properly.  	
-*/
-QofBackendError 
-qof_session_load_our_qsf_object(QofSession *first_session, const char *path);
-
-/** \brief Placeholder so far.
-
-\todo Determine the map to use and convert the QOF objects
- 
- Much of the map code is written but there is still work to do.
-*/
-QofBackendError 
-qof_session_load_qsf_object(QofSession *first_session, const char *path);
-
 /** \brief Convert between QSF objects
 
 This is the main workhorse of the conversion between QSF objects using
@@ -808,45 +714,14 @@
 xmlDocPtr
 qsf_object_convert(xmlDocPtr mapDoc, xmlNodePtr qsf_root, qsf_param *params);
 
+/** Despite the name, this function handles the QSF object book tag
+AND the object tags.
+
+Used to parse object and map files.
+*/
 void
 qsf_object_node_handler(xmlNodePtr child, xmlNsPtr qsf_ns, qsf_param *params);
 
-/** \brief Backend routine to write a file or stdout.
-
-This function is used by ::qof_session_save to write any QofBook to QSF,
-any process that can create a new QofSession and populate the QofBook 
-with QOF objects can write the data as QSF XML - the book does not need
-an AccountGroup. Remember that only fully \b QOF-compliant objects
-are supported by QSF.
-
-Your QOF objects must have:
-	- a create: function in the QofObject definition
-	- a foreach: function in the QofObject definition
-	- QofParam params[] registered with QOF using
-		qof_class_register and containing all necessary parameters
-		to reconstruct this object without any further information.
-	- Logical distinction between those parameters that should be
-		set (have a QofAccessFunc and QofSetterFunc) and those that 
-		should only be calculated (only a QofAccessFunc).
-
-If you begin your QSF session with ::QOF_STDOUT as the book_id,
-QSF will write to STDOUT - usually a terminal. This is used by QOF
-applications to provide data streaming. If you don't want terminal
-output, take care to check the path given to 
-::qof_session_begin - don't try to change it later!
-
-The XML is validated against the QSF object schema before being
-written (to file or stdout).
-
-Check the QofBackendError - don't assume the file is OK.
-
-*/
-void qsf_write_file(QofBackend *be, QofBook *book);
-
-/** \brief Create a new QSF backend.
-*/
-QofBackend* qsf_backend_new(void);
-
 /** @} */
 /** @} */
 

Modified: gnucash/trunk/lib/libqof/qof/Makefile.am
===================================================================
--- gnucash/trunk/lib/libqof/qof/Makefile.am	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/Makefile.am	2006-01-08 17:51:29 UTC (rev 12299)
@@ -7,11 +7,11 @@
   ${GLIB_CFLAGS}
 
 libqof_la_SOURCES =  \
+   deprecated.c      \
    gnc-date.c        \
    gnc-engine-util.c \
    gnc-numeric.c     \
    gnc-event.c       \
-   gnc-trace.c       \
    guid.c            \
    kvp_frame.c       \
    kvp-util.c        \
@@ -23,6 +23,7 @@
    qofinstance.c     \
    qofquery.c        \
    qofbook.c         \
+   qoflog.c          \
    qofobject.c       \
    qofquerycore.c    \
    qofsession.c      \
@@ -31,11 +32,11 @@
 qofincludedir = ${pkgincludedir}
 
 qofinclude_HEADERS = \
+   deprecated.h      \
    gnc-date.h        \
    gnc-engine-util.h \
    gnc-numeric.h     \
    gnc-event.h       \
-   gnc-trace.h       \
    guid.h            \
    kvp_frame.h       \
    kvp-util.h        \
@@ -53,6 +54,7 @@
    qofinstance.h     \
    qofquery.h        \
    qofbook.h         \
+   qoflog.h          \
    qofobject.h       \
    qofquerycore.h    \
    qofsession.h      \
@@ -72,7 +74,7 @@
    qofquerycore-p.h \
    qofsession-p.h
 
-QOFLIBdir = $(libdir)
+QOFLIBdir = $(QOF_LIB_DIR)
 
 EXTRA_DIST = \
   qofla-dir.h.in \

Added: gnucash/trunk/lib/libqof/qof/deprecated.c
===================================================================
--- gnucash/trunk/lib/libqof/qof/deprecated.c	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/deprecated.c	2006-01-08 17:51:29 UTC (rev 12299)
@@ -0,0 +1,54 @@
+/* *****************************************************************\
+ * deprecated.c -- QOF deprecated function replacements            *
+ * Copyright (c) 2005 Neil Williams <linux at codehelp.co.uk>          *
+ *                                                                  *
+ * This program is free software; you can redistribute it and/or    *
+ * modify it under the terms of the GNU General Public License as   *
+ * published by the Free Software Foundation; either version 2 of   *
+ * the License, or (at your option) any later version.              *
+ *                                                                  *
+ * This program is distributed in the hope that it will be useful,  *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
+ * GNU General Public License for more details.                     *
+ *                                                                  *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
+ *                                                                  *
+\********************************************************************/
+
+#include "qof.h"
+
+/* Don't be fooled: gnc_trace_num_spaces has external linkage and
+   static storage, but can't be defined with 'extern' because it has
+   an initializer, and can't be declared with 'static' because that
+   would give it internal linkage. (this is why it is deprecated) */
+gint __attribute__ ((unused)) gnc_trace_num_spaces = 0;
+void  gnc_log_init (void) { qof_log_init(); }
+void gnc_set_log_level(QofLogModule log_module, gncLogLevel level)
+{
+	qof_log_set_level(log_module, (QofLogLevel)level);
+}
+void gnc_set_log_level_global(gncLogLevel level)
+{
+	qof_log_set_level_global((QofLogLevel)level);
+}
+void gnc_set_logfile (FILE *outfile)
+{
+	qof_log_set_file(outfile);
+}
+const char * gnc_log_prettify (const char *name)
+{
+	return qof_log_prettify(name);
+}
+void gnc_start_clock (int a, QofLogModule b, gncLogLevel c,  const char *d, const char *e, ...) { }
+void gnc_report_clock (int a, QofLogModule b, gncLogLevel c, const char *d, const char *e, ...) { }
+void gnc_report_clock_total (int a, QofLogModule b, gncLogLevel c, const char *d, const char *e, ...) { }
+gboolean gnc_should_log(QofLogModule log_module, gncLogLevel log_level)
+{
+	return qof_log_check(log_module, log_level);
+}

Added: gnucash/trunk/lib/libqof/qof/deprecated.h
===================================================================
--- gnucash/trunk/lib/libqof/qof/deprecated.h	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/deprecated.h	2006-01-08 17:51:29 UTC (rev 12299)
@@ -0,0 +1,75 @@
+/***************************************************************************
+ *            deprecated.h
+ *
+ *  Mon Nov 21 14:08:25 2005
+ *  Copyright  2005  Neil Williams
+ *  linux at codehelp.co.uk
+ ****************************************************************************/
+/*
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02110-1301, USA.
+ */
+ 
+#ifndef _DEPRECATED_H
+#define _DEPRECATED_H
+#include "qof.h"
+
+/** @file deprecated.h
+	@brief transitional header from libqof1 to libqof2
+*/
+
+/** \deprecated use QofLogLevel instead */
+#define gncLogLevel QofLogLevel
+
+/** \deprecated use qof_log_init_filename instead */
+void gnc_log_init (void);
+
+/** \deprecated use qof_log_set_level insead. */
+void gnc_set_log_level(QofLogModule module, gncLogLevel level);
+
+/** \deprecated use qof_log_set_level_global instead. */
+void gnc_set_log_level_global(gncLogLevel level);
+
+/** \deprecated use qof_log_set_file instead. */
+void gnc_set_logfile (FILE *outfile);
+
+/** \deprecated use qof_log_prettify instead. */
+const char * gnc_log_prettify (const char *name);
+
+/** \deprecated use qof_log_check instead. */
+gboolean gnc_should_log(QofLogModule log_module, gncLogLevel log_level);
+
+/** \deprecated */
+#define GNC_LOG_FATAL   QOF_LOG_FATAL
+/** \deprecated */
+#define GNC_LOG_ERROR   QOF_LOG_ERROR
+/** \deprecated */
+#define GNC_LOG_WARNING QOF_LOG_WARNING
+/** \deprecated */
+#define GNC_LOG_INFO    QOF_LOG_INFO
+/** \deprecated */
+#define GNC_LOG_DEBUG   QOF_LOG_DEBUG
+/** \deprecated */
+#define GNC_LOG_DETAIL  QOF_LOG_DETAIL
+/** \deprecated */
+#define GNC_LOG_TRACE   QOF_LOG_TRACE
+
+/** \deprecated use qof_start_clock */
+void gnc_start_clock (int, QofLogModule, gncLogLevel, const char*, const char*, ...);
+/** \deprecated use qof_report_clock */
+void gnc_report_clock (int, QofLogModule, gncLogLevel, const char*, const char*, ...);
+/** \deprecated use qof_report_clock_total */
+void gnc_report_clock_total (int, QofLogModule, gncLogLevel, const char*, const char*, ...);
+
+#endif /* _DEPRECATED_H */

Modified: gnucash/trunk/lib/libqof/qof/gnc-date.c
===================================================================
--- gnucash/trunk/lib/libqof/qof/gnc-date.c	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/gnc-date.c	2006-01-08 17:51:29 UTC (rev 12299)
@@ -1,8 +1,9 @@
 /********************************************************************\
  * gnc-date.c -- misc utility functions to handle date and time     * 
+ *         (to be renamed qofdate.c in libqof2)                     *
  *                                                                  *
  * Copyright (C) 1997 Robin D. Clark <rclark at cs.hmc.edu>            *
- * Copyright (C) 1998-2000, 20003 Linas Vepstas <linas at linas.org>   *
+ * Copyright (C) 1998-2000, 2003 Linas Vepstas <linas at linas.org>    *
  *                                                                  *
  * This program is free software; you can redistribute it and/or    *
  * modify it under the terms of the GNU General Public License as   *
@@ -27,7 +28,7 @@
 #define __EXTENSIONS__
 
 #include "config.h"
-
+/* to be renamed qofdate.c */
 #include <ctype.h>
 
 #ifdef HAVE_LANGINFO_D_FMT
@@ -42,7 +43,7 @@
 #include <glib.h>
 
 #include "gnc-date.h"
-#include "gnc-trace.h"
+#include "qof.h"
 
 #ifndef HAVE_STRPTIME
 #include "strptime.h"
@@ -235,12 +236,11 @@
   return retval;
 }
 
-/** \brief Converts any time on a day to midday that day.
+/* Converts any time on a day to midday that day.
 
  * given a timepair contains any time on a certain day (local time)
- * converts it to be midday that day.  
+ * converts it to be midday that day.
  */
-
 Timespec
 timespecCanonicalDayTime(Timespec t)
 {
@@ -257,20 +257,16 @@
 
 int gnc_date_my_last_mday (int month, int year)
 {
-  gboolean is_leap;
-  static int days_in_month[2][12] =
-    {/* non leap */ {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
-     /*   leap   */ {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
+  static int last_day_of_month[2][12] = {
+  /* non leap */ {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
+  /*   leap   */ {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
+  };
 
   /* Is this a leap year? */
-  if (year % 2000 == 0)
-    is_leap = TRUE;
-  else if (year % 400 == 0)
-      is_leap = FALSE;
-  else
-    is_leap = (year % 4 == 0);
-
-  return days_in_month[is_leap][month-1];
+  if (year % 2000 == 0) return last_day_of_month[1][month-1];
+  if (year % 400 == 0 ) return last_day_of_month[0][month-1];
+  if (year % 4   == 0 ) return last_day_of_month[1][month-1];
+  return last_day_of_month[0][month-1];
 }
 
 /* Retrieve the last numerical day of the month
@@ -327,7 +323,7 @@
   if (!track_last_day)
     return;
 
-  /* Track last day of the month, i.e. 1/31 -> 2/28 -> 3/30 */
+  /* Track last day of the month, i.e. 1/31 -> 2/28 -> 3/31 */
   new_last_mday = date_get_last_mday(tm);
   if (was_last_day || (tm->tm_mday > new_last_mday))
     tm->tm_mday = new_last_mday;
@@ -462,7 +458,7 @@
     case QOF_DATE_FORMAT_CE:
       flen = g_snprintf (buff, len, "%2d.%2d.%-4d", day, month, year);
       break;
-    case QOF_DATE_FORMAT_LOCALE:
+   case QOF_DATE_FORMAT_LOCALE:
       {
         struct tm tm_str;
 	time_t t;
@@ -476,8 +472,8 @@
 	t = mktime (&tm_str);
 	localtime_r (&t, &tm_str);
         flen = strftime (buff, len, GNC_D_FMT, &tm_str);
-	if (flen != 0)
-	  break;
+       if (flen != 0)
+         break;
       }
       /* FALLTHROUGH */
     case QOF_DATE_FORMAT_ISO:
@@ -674,20 +670,20 @@
 size_t 
 qof_print_time_buff (char * buff, size_t len, time_t secs)
 {
-  int flen;
+	int flen;
 	struct tm ltm, gtm;
-  
-  if (!buff) return 0;
+	
+	if (!buff) return 0;
 	if(dateFormat == QOF_DATE_FORMAT_UTC)
 	{
 		gtm = *gmtime (&secs);
 		flen = strftime(buff, len, QOF_UTC_DATE_FORMAT, &gtm);
 		return flen;
 	}
-  ltm = *localtime (&secs);
-  flen = strftime (buff, len, GNC_T_FMT, &ltm);
-
-  return flen;
+	ltm = *localtime (&secs);
+	flen = strftime (buff, len, GNC_T_FMT, &ltm);
+	
+	return flen;
 }
 
 /* ============================================================== */
@@ -1013,6 +1009,7 @@
 gnc_iso8601_to_timespec_gmt(const char *str)
 {
   char buf[4];
+  gchar *dupe;
   Timespec ts;
   struct tm stm;
   long int nsec =0;
@@ -1020,7 +1017,7 @@
   ts.tv_sec=0;
   ts.tv_nsec=0;
   if (!str) return ts;
-
+  dupe = g_strdup(str);
   stm.tm_year = atoi(str) - 1900;
   str = strchr (str, '-'); if (str) { str++; } else { return ts; }
   stm.tm_mon = atoi(str) - 1;
@@ -1077,9 +1074,9 @@
    * We want to work with universal time.  Thus, add an offset
    * to undo the damage that mktime causes.
    */
-  {
+ {
     struct tm tmp_tm;
-    struct tm *tm;
+    struct tm tm;
     long int tz;
     int tz_hour;
     time_t secs;
@@ -1091,23 +1088,57 @@
 
     secs = mktime (&tmp_tm);
 
+    if(secs < 0) 
+    {
+    /* Workaround buggy mktime implementations that get confused
+       on the day daylight saving starts or ends. (OSX) */
+      PWARN (" mktime failed to handle daylight saving: "
+       "tm_hour=%d tm_year=%d tm_min=%d tm_sec=%d tm_isdst=%d for string=%s", 
+        stm.tm_hour, stm.tm_year, stm.tm_min,
+        stm.tm_sec, stm.tm_isdst, dupe ); 
+      tmp_tm.tm_hour++;
+      secs = mktime (&tmp_tm);
+      if (secs < 0) 
+      { 
+      /* if, for some strange reason, first attempt didn't fix it,
+         try reversing the workaround. */
+        tmp_tm.tm_hour -= 2;
+        secs = mktime (&tmp_tm);
+      }
+      if (secs < 0) 
+      {
+        /* Seriously buggy mktime - give up.  */
+        PERR (" unable to recover from buggy mktime ");
+        g_free(dupe);
+        return ts;
+      }
+    }
+
     /* The call to localtime is 'bogus', but it forces 'timezone' to
      * be set. Note that we must use the accurate date, since the
      * value of 'gnc_timezone' includes daylight savings corrections
      * for that date. */
-    tm = localtime (&secs);
 
-    tz = gnc_timezone (tm);
+    tm = *localtime_r (&secs, &tm);
 
+    tz = gnc_timezone (&tmp_tm);
+
     tz_hour = tz / 3600;
     stm.tm_hour -= tz_hour;
-    stm.tm_min -= (tz - (3600 * tz_hour)) / 60;
+    stm.tm_min -= (tz % 3600) / 60;
     stm.tm_isdst = tmp_tm.tm_isdst;
+    ts.tv_sec = mktime (&stm);
+    if(ts.tv_sec < 0) { 
+      PWARN (" mktime failed to adjust calculated time:"
+        " tm_hour=%d tm_year=%d tm_min=%d tm_sec=%d tm_isdst=%d", 
+        stm.tm_hour, stm.tm_year, stm.tm_min,
+        stm.tm_sec, stm.tm_isdst ); 
+      /* Try and make some sense of the result. */
+      ts.tv_sec = secs - tz;  
+    }
+    ts.tv_nsec = nsec;
   }
-
-  ts.tv_sec = mktime (&stm);
-  ts.tv_nsec = nsec;
-
+  g_free(dupe);
   return ts;
 }
 
@@ -1117,8 +1148,8 @@
 char * 
 gnc_timespec_to_iso8601_buff (Timespec ts, char * buff)
 {
-  int len;
-  int tz_hour, tz_min;
+  int len, tz_hour, tz_min;
+  long int secs;
   char cyn;
   time_t tmp;
   struct tm parsed;
@@ -1126,10 +1157,9 @@
   tmp = ts.tv_sec;
   localtime_r(&tmp, &parsed);
 
-  tz_hour = gnc_timezone (&parsed) / 3600;
-  tz_min = (gnc_timezone (&parsed) - 3600*tz_hour) / 60;
-  if (0>tz_min) { tz_min +=60; tz_hour --; }
-  if (60<=tz_min) { tz_min -=60; tz_hour ++; }
+  secs = gnc_timezone (&parsed);
+  tz_hour = secs / 3600;
+  tz_min = (secs % 3600) / 60;
 
   /* We also have to print the sign by hand, to work around a bug
    * in the glibc 2.1.3 printf (where %+02d fails to zero-pad).
@@ -1268,7 +1298,7 @@
   /* timezone is seconds *west* of UTC and is
    * not adjusted for daylight savings time.
    * In Spring, we spring forward, wheee! */
-  return timezone - (tm->tm_isdst > 0 ? 60 * 60 : 0);
+  return (long int)(timezone - (tm->tm_isdst > 0 ? 3600 : 0));
 #endif
 }
 
@@ -1387,5 +1417,53 @@
   return mktime(&tm);
 }
 
+gboolean
+qof_date_add_days(Timespec *ts, gint days)
+{
+	struct tm tm;
+	time_t    tt;
+
+	g_return_val_if_fail(ts, FALSE);
+	tt = timespecToTime_t(*ts);
+	tm = *gmtime_r(&tt, &tm);
+	tm.tm_mday += days;
+	/* let mktime normalise the months and year
+	because we aren't tracking last_day_of_month */
+	tt = mktime(&tm);
+	if(tt < 0) { return FALSE; }
+	timespecFromTime_t(ts, tt);
+	return TRUE;
+}
+
+gboolean
+qof_date_add_months(Timespec *ts, gint months, gboolean track_last_day)
+{
+	struct tm tm;
+	time_t    tt;
+	gint new_last_mday;
+	gboolean was_last_day;
+
+	g_return_val_if_fail(ts, FALSE);
+	tt = timespecToTime_t(*ts);
+	tm = *gmtime_r(&tt, &tm);
+	was_last_day = date_is_last_mday(&tm);
+	tm.tm_mon += months;
+	while (tm.tm_mon > 11) {
+		tm.tm_mon -= 12;
+		tm.tm_year++;
+	}
+	if (track_last_day) {
+		/* Track last day of the month, i.e. 1/31 -> 2/28 -> 3/31 */
+		new_last_mday = date_get_last_mday(&tm);
+		if (was_last_day || (tm.tm_mday > new_last_mday)) {
+			tm.tm_mday = new_last_mday;
+		}
+	}
+	tt = mktime(&tm);
+	if(tt < 0) { return FALSE; }
+	timespecFromTime_t(ts, tt);
+	return TRUE;
+}
+
 /********************** END OF FILE *********************************\
 \********************************************************************/

Modified: gnucash/trunk/lib/libqof/qof/gnc-date.h
===================================================================
--- gnucash/trunk/lib/libqof/qof/gnc-date.h	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/gnc-date.h	2006-01-08 17:51:29 UTC (rev 12299)
@@ -1,3 +1,10 @@
+/***************************************************************************
+ *            gnc-date.h (to be renamed qofdate.h)
+ *
+ *  Copyright (C) 1997 Robin D. Clark <rclark at cs.hmc.edu>
+ *  Copyright (C) 1998-2000, 2003 Linas Vepstas <linas at linas.org>
+ *  Copyright  2005  Neil Williams <linux at codehelp.co.uk>
+ ****************************************************************************/
 /********************************************************************\
  * This program is free software; you can redistribute it and/or    *
  * modify it under the terms of the GNU General Public License as   *
@@ -46,11 +53,13 @@
     If a file-io backend needs date handling, it should do it itself,
     instead of depending on the routines here. 
 
+	(to be renamed qofdate.h in libqof2.)
+
     @author Copyright (C) 1997 Robin D. Clark <rclark at cs.hmc.edu> 
     @author Copyright (C) 1998-2001,2003 Linas Vepstas <linas at linas.org>
 */
 
-/* @{ 
+/** @{ 
     @file gnc-date.h 
     @brief Date and Time handling routines  
 */
@@ -91,6 +100,9 @@
 #define DATE_FORMAT_FIRST QOF_DATE_FORMAT_US
 #define DATE_FORMAT_LAST  QOF_DATE_FORMAT_LOCALE
 
+/** \deprecated qof_date_format_get_format has been replaced
+by qof_date_text_format_get_string */
+#define qof_date_format_get_format qof_date_text_format_get_string
 
 /**
  * This is how to format the month, as a number, an abbreviated string,
@@ -237,8 +249,26 @@
  * routine might return incorrect values for dates before 1970.  */
 void gnc_timespec2dmy (Timespec ts, int *day, int *month, int *year);
 
-/** Add a number of months to a time value and normalize.  Optionally
- * also track the last day of the month, i.e. 1/31 -> 2/28 -> 3/30. */
+/** \brief Add a number of days to a Timespec and normalise.
+
+Together with qof_date_add_months, replaces date_add_months.
+
+\return FALSE on error, otherwise TRUE.
+*/
+gboolean qof_date_add_days(Timespec *ts, gint days);
+
+/** \brief Add a number of months to a Timespec and normalise.
+
+Optionally track the last day of the month so that adding one
+month to 31st January returns 28th February (29th in a leap year)
+and adding three months returns 30th April.
+
+\return FALSE on error, otherwise TRUE.
+*/
+gboolean qof_date_add_months(Timespec *ts, gint months, gboolean track_last_day);
+
+/** \deprecated Add a number of months to a time value and normalize.  Optionally
+ * also track the last day of the month, i.e. 1/31 -> 2/28 -> 3/31. */
 void date_add_months (struct tm *tm, int months, gboolean track_last_day);
 
 /** \warning hack alert XXX FIXME -- these date routines return incorrect
@@ -501,7 +531,7 @@
 /** Is the mday field the last day of the specified month.*/
 gboolean date_is_last_mday(struct tm *tm);
 
-/** DOCUMENT ME! Probably the same as date_get_last_mday() */
+/** \deprecated Use date_get_last_mday() */
 int gnc_date_my_last_mday (int month, int year);
 /** DOCUMENT ME! Probably the same as date_get_last_mday() */
 int gnc_timespec_last_mday (Timespec ts);
@@ -536,4 +566,3 @@
 //@}
 //@}
 #endif /* GNC_DATE_H */
-

Modified: gnucash/trunk/lib/libqof/qof/gnc-engine-util.h
===================================================================
--- gnucash/trunk/lib/libqof/qof/gnc-engine-util.h	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/gnc-engine-util.h	2006-01-08 17:51:29 UTC (rev 12299)
@@ -23,6 +23,8 @@
     @{ */
 /** @file gnc-engine-util.h 
     @brief QOF utility functions
+	(This file is due to be renamed qofutil.h in libqof2.
+	It will remain as a placeholder during libqof1.)
     @author Copyright (C) 1997 Robin D. Clark <rclark at cs.hmc.edu>
     @author Copyright (C) 2000 Bill Gribble <grib at billgribble.com>
     @author Copyright (C) 1997-2002,2004 Linas Vepstas <linas at linas.org>
@@ -36,14 +38,17 @@
 #include "config.h"
 #include "qof.h"
 
-/** Macros *****************************************************/
+/* Macros *****************************************************/
 
-/* CAS: Notice that this macro does nothing if pointer args are equal.
-   Otherwise, it returns an integer.  Actually, perhaps these macro
-   should be private.  They are NOT good substitutes for the function
-   versions like safe_strcmp().  Maybe external users of these 3
-   macros should be converted to use safe_strcmp().  Actually, THESE
-   MACROS AFFECT CONTROL FLOW.  YUCK!  */
+/** \deprecated Use the function versions, safe_strcmp() and
+safe_strcasecmp(). These macros will be made private in libqof2.
+
+If the pointer arguments are equal, the macro does nothing and
+safe_strcmp / safe_strcasecmp return 0.
+
+These macros change program control flow and are not good 
+substitutes for the function equivalents.
+*/
 #define SAFE_STRCMP_REAL(fcn,da,db) {    \
   if ((da) && (db)) {                    \
     if ((da) != (db)) {                  \
@@ -60,7 +65,9 @@
   }                                      \
 }
 
+/** \deprecated use safe_strcmp() */
 #define SAFE_STRCMP(da,db) SAFE_STRCMP_REAL(strcmp,(da),(db))
+/** \deprecated use safe_strcasecmp() */
 #define SAFE_STRCASECMP(da,db) SAFE_STRCMP_REAL(strcasecmp,(da),(db))
 
 /** \name typedef enum as string macros
@@ -85,7 +92,7 @@
     const char* name##asString(name n);
 
 #define AS_STRING_FUNC(name, list)       \
-    const char* name##asString(name n) {       \
+    const char* name##asString(name n) { \
         switch (n) {                     \
             list(AS_STRING_CASE)         \
             default: return "";  } }
@@ -107,11 +114,20 @@
 @{
 
   Similar but used when the enum is NOT a typedef
- note the LACK of a define_enum macro - don't use one!
+  Make sure you use the DEFINE_ENUM_NON_TYPEDEF macro.
 
+ You can precede the FROM_STRING_FUNC_NON_TYPEDEF 
+ and AS_STRING_FUNC_NON_TYPEDEF macros with the 
+ keyword static if appropriate.
+  
  ENUM_BODY is used in both types.
  */
 
+#define DEFINE_ENUM_NON_TYPEDEF(name, list)   \
+    enum name {                               \
+        list(ENUM_BODY)                       \
+    };
+
 #define FROM_STRING_DEC_NON_TYPEDEF(name, list)   \
    void name##fromString                          \
    (const char* str, enum name *type);
@@ -129,9 +145,9 @@
    const char* name##asString(enum name n);
 
 #define AS_STRING_FUNC_NON_TYPEDEF(name, list)    \
-   const char* name##asString(enum name n) {     \
-       switch (n) {                              \
-           list(AS_STRING_CASE_NON_TYPEDEF)      \
+   const char* name##asString(enum name n) {      \
+       switch (n) {                               \
+           list(AS_STRING_CASE_NON_TYPEDEF)       \
            default: return ""; } }
 
 #define AS_STRING_CASE_NON_TYPEDEF(name, value)   \
@@ -139,11 +155,14 @@
 
 /** @} */
 
-/* Define the long long int conversion for scanf */
+/** \deprecated Define the long long int conversion for scanf 
+ * HAVE_SCANF_LLD will be removed from libqof2
+ * */
 #if HAVE_SCANF_LLD
-# define GNC_SCANF_LLD "%lld"
+# define GNC_SCANF_LLD "%lld" /**< \deprecated 
+	use G_GINT64_FORMAT instead. */
 #else
-# define GNC_SCANF_LLD "%qd"
+# define GNC_SCANF_LLD "%qd"  /**< \deprecated */
 #endif
 
 /** @name Convenience wrappers
@@ -152,25 +171,50 @@
    
 /** \brief Initialise the Query Object Framework 
 
-Used for non-Guile applications or test routines.
+Use in place of separate init functions (like guid_init()
+and qof_query_init() etc.) to protect against future changes.
 */
 void qof_init (void);
 
 /** \brief Safely close down the Query Object Framework 
 
-Used for non-Guile applications or test routines.
+Use in place of separate close / shutdown functions 
+(like guid_shutdown(), qof_query_shutdown() etc.) to protect
+against future changes.
 */
 void qof_close (void);
 
 /** @} */
 
-/** Prototypes *************************************************/
+/* **** Prototypes *********************************************/
 
-/** The safe_strcmp compares strings a and b the same way that strcmp()
- * does, except that either may be null.  This routine assumes that
- * a non-null string is always greater than a null string.
- */
+/** The safe_strcmp compares strings da and db the same way that strcmp()
+ does, except that either may be null.  This routine assumes that
+ a non-null string is always greater than a null string.
+ 
+ @param da string 1.
+ @param db string 2.
+ 
+ @return If da == NULL && db != NULL, returns -1.
+         If da != NULL && db == NULL, returns +1.
+         If da != NULL && db != NULL, returns the result of 
+                   strcmp(da, db).
+         If da == NULL && db == NULL, returns 0. 
+*/
 int safe_strcmp (const char * da, const char * db);
+
+/** case sensitive comparison of strings da and db - either
+may be NULL. A non-NULL string is greater than a NULL string.
+ 
+ @param da string 1.
+ @param db string 2.
+ 
+ @return If da == NULL && db != NULL, returns -1.
+         If da != NULL && db == NULL, returns +1.
+         If da != NULL && db != NULL, returns the result of 
+                   strcmp(da, db).
+         If da == NULL && db == NULL, returns 0. 
+*/
 int safe_strcasecmp (const char * da, const char * db);
 
 /** The null_strcmp compares strings a and b the same way that strcmp()
@@ -212,10 +256,12 @@
 int qof_util_bool_to_int (const char * val);
 
 
-/** Gnucash's String Cache:
+/** The QOF String Cache:
  *
- * Many strings used throughout the engine are likely to be duplicated.
- * So we provide a reference counted cache system for the strings, which
+ * Many strings used throughout QOF and QOF applications are likely to
+ * be duplicated.
+ *
+ * QOF provides a reference counted cache system for the strings, which
  * shares strings whenever possible.
  *
  * Use gnc_string_cache_insert to insert a string into the cache (it
@@ -242,19 +288,21 @@
 
 /** \deprecated use qof_init instead.
 
-Get the gnc_string_cache.  Create it if it doesn't exist already
+Get the gnc_string_cache.  Create it if it doesn't exist already.
 */
 GCache* gnc_engine_get_string_cache(void);
 
 /** Destroy the gnc_string_cache */
 void gnc_engine_string_cache_destroy (void);
 
-/* You can use this function as a destroy notifier for a GHashTable
-   that uses common strings as keys (or values, for that matter.) */
+/** You can use this function as a destroy notifier for a GHashTable
+   that uses common strings as keys (or values, for that matter.)
+*/
 void gnc_string_cache_remove(gconstpointer key);
 
-/* You can use this function with g_hash_table_insert(), or the key
-   (or value), as long as you use the destroy notifier above. */
+/** You can use this function with g_hash_table_insert(), or the key
+   (or value), as long as you use the destroy notifier above.
+*/
 gpointer gnc_string_cache_insert(gpointer key);
 
 #define CACHE_INSERT(str) gnc_string_cache_insert((gpointer)(str));

Modified: gnucash/trunk/lib/libqof/qof/gnc-event-p.h
===================================================================
--- gnucash/trunk/lib/libqof/qof/gnc-event-p.h	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/gnc-event-p.h	2006-01-08 17:51:29 UTC (rev 12299)
@@ -27,11 +27,11 @@
 #include "gnc-event.h"
 #include "qofid.h"
 
-/* XXX deprecated, but still usedion on postgres backend */
+/** \deprecated */
 void gnc_engine_generate_event (const GUID *, QofIdType, GNCEngineEventType);
 
 /* generates an event even when events are suspended! */
-void gnc_engine_force_event (QofEntity *entity, 
+void gnc_engine_force_event (QofEntity *entity,
 			     GNCEngineEventType event_type);
 
 #endif

Modified: gnucash/trunk/lib/libqof/qof/gnc-event.c
===================================================================
--- gnucash/trunk/lib/libqof/qof/gnc-event.c	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/gnc-event.c	2006-01-08 17:51:29 UTC (rev 12299)
@@ -22,13 +22,11 @@
  ********************************************************************/
 
 #include "config.h"
-
+#include "qof.h"
 #include "gnc-event-p.h"
-#include "gnc-trace.h"
 
+/* Declarations ****************************************************/
 
-/** Declarations ****************************************************/
-
 typedef struct
 {
   GNCEngineEventHandler handler;
@@ -37,8 +35,7 @@
   gint handler_id;
 } HandlerInfo;
 
-
-/** Static Variables ************************************************/
+/* Static Variables ************************************************/
 static guint  suspend_counter = 0;
 static gint   next_handler_id = 1;
 static GList *handlers = NULL;
@@ -46,9 +43,8 @@
 /* This static indicates the debugging module that this .o belongs to.  */
 static QofLogModule log_module = QOF_MOD_ENGINE;
 
+/* Implementations *************************************************/
 
-/** Implementations *************************************************/
-
 gint
 gnc_engine_register_event_handler (GNCEngineEventHandler handler,
                                    gpointer user_data)

Modified: gnucash/trunk/lib/libqof/qof/gnc-event.h
===================================================================
--- gnucash/trunk/lib/libqof/qof/gnc-event.h	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/gnc-event.h	2006-01-08 17:51:29 UTC (rev 12299)
@@ -26,6 +26,7 @@
 */
 /** @file gnc-event.h
     @brief engine event handling interface
+	(to be renamed qofevent.h in libqof2)
 	@author Copyright 2000 Dave Peticolas <dave at krondo.com>
 */
 

Modified: gnucash/trunk/lib/libqof/qof/gnc-numeric.c
===================================================================
--- gnucash/trunk/lib/libqof/qof/gnc-numeric.c	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/gnc-numeric.c	2006-01-08 17:51:29 UTC (rev 12299)
@@ -75,7 +75,7 @@
   }
 }
 
-/**
+/*
  *  Find the least common multiple of the denominators of a and b.
  */
 
@@ -106,7 +106,7 @@
 }
 
 
-/** Return the ratio n/d reduced so that there are no common factors. */
+/* Return the ratio n/d reduced so that there are no common factors. */
 static inline gnc_numeric
 reduce128(qofint128 n, gint64 d)
 {
@@ -140,7 +140,7 @@
   return out;
 }
 
-/********************************************************************
+/* *******************************************************************
  *  gnc_numeric_zero_p
  ********************************************************************/
 
@@ -164,7 +164,7 @@
   }
 }
 
-/********************************************************************
+/* *******************************************************************
  *  gnc_numeric_negative_p
  ********************************************************************/
 
@@ -188,7 +188,7 @@
   }
 }
 
-/********************************************************************
+/* *******************************************************************
  *  gnc_numeric_positive_p
  ********************************************************************/
 
@@ -212,7 +212,7 @@
   }
 }
 
-/********************************************************************
+/* *******************************************************************
  *  gnc_numeric_compare
  *  returns 1 if a>b, -1 if b>a, 0 if a == b 
  ********************************************************************/
@@ -252,7 +252,7 @@
 }
 
 
-/********************************************************************
+/* *******************************************************************
  *  gnc_numeric_eq
  ********************************************************************/
 
@@ -263,7 +263,7 @@
 }
 
 
-/********************************************************************
+/* *******************************************************************
  *  gnc_numeric_equal
  ********************************************************************/
 
@@ -300,7 +300,7 @@
 }
 
 
-/********************************************************************
+/* *******************************************************************
  *  gnc_numeric_same
  *  would a and b be equal() if they were both converted to the same 
  *  denominator? 
@@ -319,7 +319,7 @@
 
 
 
-/********************************************************************
+/* *******************************************************************
  *  gnc_numeric_add
  ********************************************************************/
 
@@ -410,7 +410,7 @@
   return gnc_numeric_convert(sum, denom, how);                             
 }
 
-/********************************************************************
+/* *******************************************************************
  *  gnc_numeric_sub
  ********************************************************************/
 
@@ -429,7 +429,7 @@
   return gnc_numeric_add (a, nb, denom, how);
 }
 
-/********************************************************************
+/* *******************************************************************
  *  gnc_numeric_mul
  ********************************************************************/
 
@@ -548,7 +548,7 @@
 }
 
 
-/********************************************************************
+/* *******************************************************************
  *  gnc_numeric_div
  ********************************************************************/
 
@@ -680,7 +680,7 @@
   return gnc_numeric_convert(quotient, denom, how); 
 }
  
-/********************************************************************
+/* *******************************************************************
  *  gnc_numeric_neg
  *  negate the argument 
  ********************************************************************/
@@ -693,7 +693,7 @@
   return gnc_numeric_create(- a.num, a.denom);
 }
 
-/********************************************************************
+/* *******************************************************************
  *  gnc_numeric_neg
  *  return the absolute value of the argument 
  ********************************************************************/
@@ -707,7 +707,7 @@
   return gnc_numeric_create(ABS(a.num), a.denom);
 }
 
-/********************************************************************
+/* *******************************************************************
  *  gnc_numeric_convert
  ********************************************************************/
 
@@ -962,8 +962,8 @@
 }
 
 
-/********************************************************************
- ** reduce a fraction by GCF elimination.  This is NOT done as a
+/* *******************************************************************
+ *  reduce a fraction by GCF elimination.  This is NOT done as a
  *  part of the arithmetic API unless GNC_HOW_DENOM_REDUCE is specified 
  *  as the output denominator.
  ********************************************************************/
@@ -996,7 +996,7 @@
   return out;
 }
 
-/********************************************************************
+/* *******************************************************************
  *  double_to_gnc_numeric
  ********************************************************************/
 
@@ -1068,7 +1068,7 @@
   return out;
 }
 
-/********************************************************************
+/* *******************************************************************
  *  gnc_numeric_to_double
  ********************************************************************/
 
@@ -1085,7 +1085,7 @@
   }
 }
 
-/********************************************************************
+/* *******************************************************************
  *  gnc_numeric_error
  ********************************************************************/
 
@@ -1096,7 +1096,7 @@
 }
 
 
-/********************************************************************
+/* *******************************************************************
  *  gnc_numeric_add_with_error
  ********************************************************************/
 
@@ -1118,7 +1118,7 @@
   return sum;
 }
 
-/********************************************************************
+/* *******************************************************************
  *  gnc_numeric_sub_with_error
  ********************************************************************/
 
@@ -1139,7 +1139,7 @@
 }
 
 
-/********************************************************************
+/* *******************************************************************
  *  gnc_numeric_mul_with_error
  ********************************************************************/
 
@@ -1160,7 +1160,7 @@
 }
 
 
-/********************************************************************
+/* *******************************************************************
  *  gnc_numeric_div_with_error
  ********************************************************************/
 
@@ -1180,7 +1180,7 @@
   return quot;
 }
 
-/********************************************************************
+/* *******************************************************************
  *  gnc_numeric text IO
  ********************************************************************/
 
@@ -1240,7 +1240,7 @@
   return TRUE;
 }
 
-/********************************************************************
+/* *******************************************************************
  *  gnc_numeric misc testing
  ********************************************************************/
 #ifdef _GNC_NUMERIC_TEST

Modified: gnucash/trunk/lib/libqof/qof/gnc-numeric.h
===================================================================
--- gnucash/trunk/lib/libqof/qof/gnc-numeric.h	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/gnc-numeric.h	2006-01-08 17:51:29 UTC (rev 12299)
@@ -53,7 +53,7 @@
 
 @verbatim
 #include <glib.h>
-#include "gnc-numeric.h"
+#include <qof.h>
 #include <math.h>
 
 int
@@ -85,6 +85,7 @@
 @{ */
 /** @file gnc-numeric.h
     @brief An exact-rational-number library for gnucash.
+	(to be renamed qofnumeric.h in libqof2)
     @author Copyright (C) 2000 Bill Gribble
     @author Copyright (C) 2004 Linas Vepstas <linas at linas.org>
 */
@@ -264,7 +265,7 @@
 
 /** Values that can be passed as the 'denom' argument.  
  *  The include a positive number n to be used as the 
- *  denominator of the output value.  Other possibilities
+ *  denominator of the output value.  Other possibilities 
  *  include the list below:
  */
 

Deleted: gnucash/trunk/lib/libqof/qof/gnc-trace.c
===================================================================
--- gnucash/trunk/lib/libqof/qof/gnc-trace.c	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/gnc-trace.c	2006-01-08 17:51:29 UTC (rev 12299)
@@ -1,370 +0,0 @@
-/* *****************************************************************\
- * gnc-trace.c -- QOF error logging and tracing facility            *
- * Copyright (C) 1997-2003 Linas Vepstas <linas at linas.org>          *
- * Copyright (c) 2005 Neil Williams <linux at codehelp.co.uk>          *
- *                                                                  *
- * This program is free software; you can redistribute it and/or    *
- * modify it under the terms of the GNU General Public License as   *
- * published by the Free Software Foundation; either version 2 of   *
- * the License, or (at your option) any later version.              *
- *                                                                  *
- * This program is distributed in the hope that it will be useful,  *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
- * GNU General Public License for more details.                     *
- *                                                                  *
- * You should have received a copy of the GNU General Public License*
- * along with this program; if not, contact:                        *
- *                                                                  *
- * Free Software Foundation           Voice:  +1-617-542-5942       *
- * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
- * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
- *                                                                  *
- *   Author: Rob Clark (rclark at cs.hmc.edu)                          *
- *   Author: Linas Vepstas (linas at linas.org)                        *
-\********************************************************************/
-
-/** @addtogroup Trace
-@{ */
-
-/** @file gnc-trace.c
-    @brief QOF error logging facility 
-		@author Neil Williams <linux at codehelp.co.uk>
-*/
-
-#include "config.h"
-
-#include <glib.h>
-#ifdef HAVE_UNISTD_H
-#  include <unistd.h>
-#else
-  /* What to do? */
-#endif
-#include <stdarg.h>
-#include <string.h>
-#include <sys/time.h>
-#include "qof.h"
-#include "gnc-trace.h"
-
-static FILE *fout = NULL;
-static gchar* filename = NULL;
-
-static const int MAX_TRACE_FILENAME = 100;
-static GHashTable *log_table = NULL;
-
-AS_STRING_FUNC(gncLogLevel, LOG_LEVEL_LIST)  /**< enum_as_string function
-
-uses the enum_as_string macro from QOF
-but the From macro is not required. Lookups
-are done on the string. */
-
-FROM_STRING_FUNC(gncLogLevel, LOG_LEVEL_LIST)
-
-/* Don't be fooled: gnc_trace_num_spaces has external linkage and
-   static storage, but can't be defined with 'extern' because it has
-   an initializer, and can't be declared with 'static' because that
-   would give it internal linkage. */
-gint __attribute__ ((unused)) gnc_trace_num_spaces = 0;
-
-static void
-fh_printer (const gchar   *log_domain,
-            GLogLevelFlags    log_level,
-            const gchar   *message,
-            gpointer    user_data)
-{
-  extern gint gnc_trace_num_spaces;
-  FILE *fh = user_data;
-  fprintf (fh, "%*s%s\n", gnc_trace_num_spaces, "", message);
-  fflush(fh);
-}
-
-void 
-gnc_log_init (void)
-{
-   if(!fout) //allow gnc_set_logfile
-   {
-	   fout = fopen ("/tmp/qof.trace", "w");
-   }
-
-   if(!fout && (filename = (char *)g_malloc(MAX_TRACE_FILENAME))) {
-      snprintf(filename, MAX_TRACE_FILENAME-1, "/tmp/qof.trace.%d", 
-	       getpid());
-      fout = fopen (filename, "w");
-      g_free(filename);
-   }
-
-   if(!fout)
-      fout = stderr;
-
-   g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_MASK, fh_printer, fout);
-}
-
-/* Set the logging level of the given module. */
-void
-gnc_set_log_level(QofLogModule log_module, gncLogLevel level)
-{
-	gchar* level_string;
-
-	if(!log_module || level == 0) { return; }
-	level_string = g_strdup(gncLogLevelasString(level));
-	if(!log_table)
-	{
-		log_table = g_hash_table_new(g_str_hash, g_str_equal);
-	}
-	g_hash_table_insert(log_table, (gpointer)log_module, level_string);
-}
-
-static void
-log_module_foreach(gpointer key, gpointer value, gpointer data)
-{
-	g_hash_table_insert(log_table, key, data);
-}
-
-/* Set the logging level for all known modules. */
-void
-gnc_set_log_level_global(gncLogLevel level)
-{
-	gchar* level_string;
-
-	if(!log_table || level == 0) { return; }
-	level_string = g_strdup(gncLogLevelasString(level));
-	g_hash_table_foreach(log_table, log_module_foreach, level_string);
-}
-
-void
-gnc_set_logfile (FILE *outfile)
-{
-   if(!outfile) { fout = stderr; return; }
-   fout = outfile;
-}
-
-void
-qof_log_init_filename (const gchar* logfilename)
-{
-	if(!logfilename)
-	{
-		fout = stderr;
-	}
-	else
-	{
-		filename = g_strdup(logfilename);
-		fout = fopen(filename, "w");
-	}
-	gnc_log_init();
-}
-
-void
-qof_log_shutdown (void)
-{
-	if(fout && fout != stderr) { fclose(fout); }
-	if(filename) { g_free(filename); }
-	g_hash_table_destroy(log_table);
-}
-
-#define MAX_CHARS 50
-/* gnc_log_prettify() cleans up subroutine names. AIX/xlC has the habit
- * of printing signatures not names; clean this up. On other operating
- * systems, truncate name to 30 chars. Note this routine is not thread
- * safe. Note we wouldn't need this routine if AIX did something more
- * reasonable. Hope thread safety doesn't poke us in eye. */
-const char *
-gnc_log_prettify (const char *name)
-{
-  static char bf[128];
-  char *p;
-
-  if (!name)
-    return "";
-
-  strncpy (bf, name, MAX_CHARS-1); bf[MAX_CHARS-2] = 0;
-  p = strchr (bf, '(');
-
-  if (p)
-  {
-    *(p+1) = ')';
-    *(p+2) = 0x0;
-  }
-  else
-    strcpy (&bf[MAX_CHARS-4], "...()");
-
-  return bf;
-}
-
-/********************************************************************\
-\********************************************************************/
-
-#define NUM_CLOCKS 10
-
-static
-struct timeval gnc_clock[NUM_CLOCKS] = {
-   {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, 
-   {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, 
-};
-
-static
-struct timeval gnc_clock_total[NUM_CLOCKS] = {
-   {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, 
-   {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, 
-};
-
-void
-gnc_start_clock (int clockno, QofLogModule log_module, gncLogLevel log_level,
-                 const char *function_name, const char *format, ...)
-{
-  struct timezone tz;
-  va_list ap;
-
-  if ((0>clockno) || (NUM_CLOCKS <= clockno)) return;
-  gettimeofday (&gnc_clock[clockno], &tz);
-
-  if (!fout) gnc_log_init();
-
-  fprintf (fout, "Clock %d Start: %s: ",
-           clockno, gnc_log_prettify (function_name));
-
-  va_start (ap, format);
-
-  vfprintf (fout, format, ap);
-
-  va_end (ap);
-
-  fprintf (fout, "\n");
-  fflush (fout);
-}
-
-void
-gnc_report_clock (int clockno, QofLogModule log_module, gncLogLevel log_level,
-                  const char *function_name, const char *format, ...)
-{
-  struct timezone tz;
-  struct timeval now;
-  va_list ap;
-
-  if ((0>clockno) || (NUM_CLOCKS <= clockno)) return;
-  gettimeofday (&now, &tz);
-
-  /* need to borrow to make difference */
-  if (now.tv_usec < gnc_clock[clockno].tv_usec)
-  {
-    now.tv_sec --;
-    now.tv_usec += 1000000;
-  }
-  now.tv_sec -= gnc_clock[clockno].tv_sec;
-  now.tv_usec -= gnc_clock[clockno].tv_usec;
-
-  gnc_clock_total[clockno].tv_sec += now.tv_sec;
-  gnc_clock_total[clockno].tv_usec += now.tv_usec;
-
-  if (!fout) gnc_log_init();
-
-  fprintf (fout, "Clock %d Elapsed: %ld.%06lds %s: ",
-           clockno, (long int) now.tv_sec, (long int) now.tv_usec, 
-	   gnc_log_prettify (function_name));
-
-  va_start (ap, format);
-
-  vfprintf (fout, format, ap);
-
-  va_end (ap);
-
-  fprintf (fout, "\n");
-  fflush (fout);
-}
-
-void
-gnc_report_clock_total (int clockno,
-                        QofLogModule log_module, gncLogLevel log_level,
-                        const char *function_name, const char *format, ...)
-{
-  va_list ap;
-
-  if ((0>clockno) || (NUM_CLOCKS <= clockno)) return;
-
-  /* need to normalize usec */
-  while (gnc_clock_total[clockno].tv_usec >= 1000000)
-  {
-    gnc_clock_total[clockno].tv_sec ++;
-    gnc_clock_total[clockno].tv_usec -= 1000000;
-  }
-
-  if (!fout) gnc_log_init();
-
-  fprintf (fout, "Clock %d Total Elapsed: %ld.%06lds  %s: ",
-           clockno,
-           (long int) gnc_clock_total[clockno].tv_sec,
-           (long int) gnc_clock_total[clockno].tv_usec,
-           gnc_log_prettify (function_name));
-
-  va_start (ap, format);
-
-  vfprintf (fout, format, ap);
-
-  va_end (ap);
-
-  fprintf (fout, "\n");
-  fflush (fout);
-}
-
-gboolean
-gnc_should_log(QofLogModule log_module, gncLogLevel log_level)
-{
-	gchar* log_string;
-	gncLogLevel maximum; /* Any log_level less than this will be logged. */
-
-	log_string = NULL;
-	if(!log_table || log_module == NULL || log_level == 0) { return FALSE; }
-	log_string = (gchar*)g_hash_table_lookup(log_table, log_module);
-	/* if log_module not found, do not log. */
-	if(!log_string) { return FALSE; }
-	maximum = gncLogLevelfromString(log_string);
-	if(log_level <= maximum) { return TRUE; }
-	return FALSE;
-}
-
-void qof_log_set_default(gncLogLevel log_level)
-{
-	gnc_set_log_level(QOF_MOD_BACKEND, log_level);
-	gnc_set_log_level(QOF_MOD_CLASS,   log_level);
-	gnc_set_log_level(QOF_MOD_ENGINE,  log_level);
-	gnc_set_log_level(QOF_MOD_OBJECT,  log_level);
-	gnc_set_log_level(QOF_MOD_KVP,     log_level);
-	gnc_set_log_level(QOF_MOD_MERGE,   log_level);
-	gnc_set_log_level(QOF_MOD_QUERY,   log_level);
-	gnc_set_log_level(QOF_MOD_SESSION, log_level);
-}
-
-struct hash_s
-{
-	QofLogCB cb;
-	gpointer data;
-};
-
-static void hash_cb (gpointer key, gpointer value, gpointer data)
-{
-	struct hash_s *iter;
-
-	iter = (struct hash_s*)data;
-	if(!iter) { return; }
-	(iter->cb)(key, value, iter->data);
-}
-
-void qof_log_module_foreach(QofLogCB cb, gpointer data)
-{
-	struct hash_s iter;
-
-	if(!cb) { return; }
-	iter.cb = cb;
-	iter.data = data;
-	g_hash_table_foreach(log_table, hash_cb, (gpointer)&iter);
-}
-
-gint qof_log_module_count(void)
-{
-	if(!log_table) { return 0; }
-	return g_hash_table_size(log_table);
-}
-
-/** @} */
-
-/************************* END OF FILE ******************************\
-\********************************************************************/

Deleted: gnucash/trunk/lib/libqof/qof/gnc-trace.h
===================================================================
--- gnucash/trunk/lib/libqof/qof/gnc-trace.h	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/gnc-trace.h	2006-01-08 17:51:29 UTC (rev 12299)
@@ -1,274 +0,0 @@
-/********************************************************************\
- * gnc-trace.h -- QOF error logging and tracing facility            *
- * Copyright (C) 1998-2003 Linas Vepstas <linas at linas.org>          *
- * Copyright (c) 2005 Neil Williams <linux at codehelp.co.uk>          *
- *                                                                  *
- * This program is free software; you can redistribute it and/or    *
- * modify it under the terms of the GNU General Public License as   *
- * published by the Free Software Foundation; either version 2 of   *
- * the License, or (at your option) any later version.              *
- *                                                                  *
- * This program is distributed in the hope that it will be useful,  *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
- * GNU General Public License for more details.                     *
- *                                                                  *
- * You should have received a copy of the GNU General Public License*
- * along with this program; if not, contact:                        *
- *                                                                  *
- * Free Software Foundation           Voice:  +1-617-542-5942       *
- * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
- * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
- *                                                                  *
- *   Author: Linas Vepstas (linas at linas.org)                        *
-\********************************************************************/
-
-/** @addtogroup Trace
-    @{ */
-
-/** @file gnc-trace.h 
- *  @brief QOF error logging and tracing facility
- *  @author Neil Williams <linux at codehelp.co.uk>
- */
-
-#ifndef GNC_TRACE_H
-#define GNC_TRACE_H
-
-#include <glib.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include "qof.h"
-#include "gnc-engine-util.h"
-
-#define QOF_MOD_ENGINE "qof-engine"
-
-#define LOG_LEVEL_LIST(_) \
-  _(GNC_LOG_FATAL, = 0)   \
-  _(GNC_LOG_ERROR, = 1)   \
-  _(GNC_LOG_WARNING, = 2) \
-  _(GNC_LOG_INFO, = 3)    \
-  _(GNC_LOG_DEBUG, = 4)   \
-  _(GNC_LOG_DETAIL, = 5)  \
-  _(GNC_LOG_TRACE, = 6)
-
-DEFINE_ENUM (gncLogLevel, LOG_LEVEL_LIST)
-
-/** Convert gncLogLevel to a string.
-
-The macro correlates the enum value and an
-exact copy as a string, removing the need to
-keep two separate lists in sync.
-*/
-AS_STRING_DEC(gncLogLevel, LOG_LEVEL_LIST)
-
-/** Convert the log_string to a gncLogLevel
-
-Only for use as a partner to ::gncLogLevelasString
-*/
-FROM_STRING_DEC(gncLogLevel, LOG_LEVEL_LIST)
-
-#define GNC_TRACE_INDENT_WIDTH 4
-
-/** Initialize the error logging subsystem
-
-\note Applications should call gnc_set_logfile
-to set the output, otherwise the
-default of \a /tmp/qof.trace will be used.
-
-As an alternative, use qof_log_init_filename
-which sets the filename and initialises the
-logging subsystem in one operation.
-*/
-void gnc_log_init (void);
-
-/** Set the logging level of the given log_module. */
-void gnc_set_log_level(QofLogModule module, gncLogLevel level);
-
-/** Set the logging level for all known log_modules.
-
-\note Unless a log_module has been registered using
-gnc_set_log_level, it will be unaffected by this change.
-
-*/
-void gnc_set_log_level_global(gncLogLevel level);
-
-/** Specify an alternate log output, to pipe or file.  By default,
- *  all logging goes to /tmp/qof.trace 
- 
- Needs to be called \b before gnc_log_init()
-*/
-void gnc_set_logfile (FILE *outfile);
-
-/** Specify a filename for log output.
-
-Calls gnc_log_init() for you.
-*/
-void qof_log_init_filename (const gchar* logfilename);
-
-/** Be nice, close the logfile is possible. */
-void qof_log_shutdown (void);
-
-/** gnc_log_prettify() cleans up subroutine names. AIX/xlC has the habit
- * of printing signatures not names; clean this up. On other operating
- * systems, truncate name to 30 chars. Note this routine is not thread
- * safe. Note we wouldn't need this routine if AIX did something more
- * reasonable. Hope thread safety doesn't poke us in eye. */
-const char * gnc_log_prettify (const char *name);
-
-/** Do not log log_modules that have not been enabled.
-
- Whether to log cannot be decided inline because a hashtable is
- now used. This is the price of extending logging to non-Gnucash
- log_modules.
-
-*/
-gboolean gnc_should_log(QofLogModule log_module, gncLogLevel log_level);
-
-/** Set the default QOF log_modules to the log level. */
-void qof_log_set_default(gncLogLevel log_level);
-
-typedef void (*QofLogCB) (QofLogModule log_module, gncLogLevel* log_level, gpointer user_data);
-
-/** Iterate over each known log_module
-
-Only log_modules with log_levels set will 
-be available.
-*/
-void qof_log_module_foreach(QofLogCB cb, gpointer data);
-
-/** Number of log_modules registered*/
-gint qof_log_module_count(void);
-
-#define FUNK gnc_log_prettify(__FUNCTION__)
-
-/** Log error/waring/info messages to stderr or to other pipe. 
- *  This logging infrastructure is meant for validating the 
- *  correctness of the execution of the code.  'Info' level 
- *  messages help trace program flow. 'Error' messages are 
- *  meant to indicate internal data inconsistencies.
- * 
- * Messages can be logged to stdout, stderr, or to any desired
- * FILE * file handle. Use fdopen() to get a file handle from a 
- * file descriptor. Use gnc_set_logfile to set the logging file 
- * handle.
- */
-
-/** Log an fatal error */
-#define FATAL(format, args...) do {                  \
-    g_log (G_LOG_DOMAIN, G_LOG_LEVEL_ERROR,          \
-      "Fatal Error: %s(): " format, FUNK , ## args); \
-} while (0)
-
-/** Log an serious error */
-#define PERR(format, args...) do {                 \
-  if (gnc_should_log (log_module, GNC_LOG_ERROR)) {\
-    g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,     \
-      "Error: %s(): " format, FUNK , ## args);     \
-  }                                                \
-} while (0)
-
-/** Log an warning */
-#define PWARN(format, args...) do {                    \
-  if (gnc_should_log (log_module, GNC_LOG_WARNING)) {  \
-    g_log (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,          \
-      "Warning: %s(): " format, FUNK , ## args);       \
-  }                                                    \
-} while (0)
-
-/** Print an informational note */
-#define PINFO(format, args...) do {                \
-  if (gnc_should_log (log_module, GNC_LOG_INFO)) { \
-    g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO,         \
-      "Info: %s(): " format,                       \
-      FUNK , ## args);                             \
-  }                                                \
-} while (0)
-
-/** Print an debugging message */
-#define DEBUG(format, args...) do {                \
-  if (gnc_should_log (log_module, GNC_LOG_DEBUG)) {\
-    g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG,        \
-      "Debug: %s(): " format,                      \
-      FUNK , ## args);                             \
-  }                                                \
-} while (0)
-
-/** Print an function entry debugging message */
-#define ENTER(format, args...) do {                \
-  extern gint gnc_trace_num_spaces;                \
-  if (gnc_should_log (log_module, GNC_LOG_DEBUG)) {\
-    g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG,        \
-      "Enter in %s: %s()" format, __FILE__,        \
-      FUNK , ## args);                             \
-    gnc_trace_num_spaces += GNC_TRACE_INDENT_WIDTH;\
-  }                                                \
-} while (0)
-
-/** Print an function exit debugging message */
-#define LEAVE(format, args...) do {                \
-  extern gint gnc_trace_num_spaces;                \
-  if (gnc_should_log (log_module, GNC_LOG_DEBUG)) {\
-    gnc_trace_num_spaces -= GNC_TRACE_INDENT_WIDTH;\
-    g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG,        \
-      "Leave: %s()" format,                        \
-      FUNK , ## args);                             \
-  }                                                \
-} while (0)
-
-/** Print an function trace debugging message */
-#define TRACE(format, args...) do {                \
-  if (gnc_should_log (log_module, GNC_LOG_TRACE)) {\
-    g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG,        \
-      "Trace: %s(): " format, FUNK , ## args);     \
-  }                                                \
-} while (0)
-
-#define DEBUGCMD(x) do {                            \
-  if (gnc_should_log (log_module, GNC_LOG_DEBUG)) { \
-      (x);                                          \
-  }                                                 \
-} while (0)
-
-/* -------------------------------------------------------- */
-/** Infrastructure to make timing measurements for critical peices 
- * of code. Used for only for performance tuning & debugging. 
- */
-
-void gnc_start_clock (int clockno, QofLogModule log_module, gncLogLevel log_level,
-                      const char *function_name, const char *format, ...);
-
-void gnc_report_clock (int clockno,
-                       QofLogModule log_module,
-                       gncLogLevel log_level,
-                       const char *function_name,
-                       const char *format, ...);
-
-void gnc_report_clock_total (int clockno,
-                             QofLogModule log_module,
-                             gncLogLevel log_level,
-                             const char *function_name,
-                             const char *format, ...);
-
-/** start a particular timer */
-#define START_CLOCK(clockno,format, args...) do {               \
-  if (gnc_should_log (log_module, GNC_LOG_INFO))                \
-    gnc_start_clock (clockno, log_module, GNC_LOG_INFO,         \
-             __FUNCTION__, format , ## args);               \
-} while (0)
-
-/** report elapsed time since last report on a particular timer */
-#define REPORT_CLOCK(clockno,format, args...) do {              \
-  if (gnc_should_log (log_module, GNC_LOG_INFO))                \
-    gnc_report_clock (clockno, log_module, GNC_LOG_INFO,        \
-             __FUNCTION__, format , ## args);               \
-} while (0)
-
-/** report total elapsed time since timer started */
-#define REPORT_CLOCK_TOTAL(clockno,format, args...) do {        \
-  if (gnc_should_log (log_module, GNC_LOG_INFO))                \
-    gnc_report_clock_total (clockno, log_module, GNC_LOG_INFO,  \
-             __FUNCTION__, format , ## args);               \
-} while (0)
-
-#endif /* GNC_TRACE_H */
-/* @} */

Modified: gnucash/trunk/lib/libqof/qof/guid.c
===================================================================
--- gnucash/trunk/lib/libqof/qof/guid.c	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/guid.c	2006-01-08 17:51:29 UTC (rev 12299)
@@ -38,23 +38,20 @@
 #include <sys/times.h>
 #include <time.h>
 #include <unistd.h>
-
-#include "guid.h"
+#include "qof.h"
 #include "md5.h"
-#include "qofid.h"
-#include "gnc-trace.h"
 
 # ifndef P_tmpdir
 #  define P_tmpdir "/tmp"
 # endif
 
-/** Constants *******************************************************/
+/* Constants *******************************************************/
 #define DEBUG_GUID 0
 #define BLOCKSIZE 4096
 #define THRESHOLD (2 * BLOCKSIZE)
 
 
-/** Static global variables *****************************************/
+/* Static global variables *****************************************/
 static gboolean guid_initialized = FALSE;
 static struct md5_ctx guid_context;
 #ifndef HAVE_GLIB29
@@ -64,7 +61,7 @@
 /* This static indicates the debugging module that this .o belongs to.  */
 static QofLogModule log_module = QOF_MOD_ENGINE;
 
-/** Memory management routines ***************************************/
+/* Memory management routines ***************************************/
 #ifdef HAVE_GLIB29
 GUID *
 guid_malloc (void)
@@ -81,6 +78,7 @@
   g_slice_free(GUID, guid);
 }
 #else /* !HAVE_GLIB29 */
+
 static void
 guid_memchunk_init (void)
 {
@@ -127,8 +125,8 @@
     int i;
     char *tmp = "NULLGUID.EMPTY.";
 
-    /* 16th space for '\O' */
-    for (i = 0; i < 16; i++)
+      /* 16th space for '\O' */
+	  for (i = 0; i < 16; i++)
       null_guid.data[i] = tmp[i];
 
     null_inited = 1;
@@ -137,7 +135,7 @@
   return &null_guid;
 }
 
-/** Function implementations ****************************************/
+/* Function implementations ****************************************/
 
 /* This code is based on code in md5.c in GNU textutils. */
 static size_t
@@ -495,16 +493,16 @@
   init_from_time();
 
   /* Make it a little extra salty.  I think init_from_time was buggy,
-   * or something, since duplicate id's actually happened. Or something
-   * like that.  I think this is because init_from_time kept returning
-   * the same values too many times in a row.  So we'll do some 'block
-   * chaining', and feed in the old guid as new random data.
-   *
-   * Anyway, I think the whole fact that I saw a bunch of duplicate 
-   * id's at one point, but can't reproduce the bug is rather alarming.
-   * Something must be broken somewhere, and merely adding more salt
-   * is just hiding the problem, not fixing it.
-   */
+	* or something, since duplicate id's actually happened. Or something
+	* like that.  I think this is because init_from_time kept returning
+	* the same values too many times in a row.  So we'll do some 'block
+	* chaining', and feed in the old guid as new random data.
+	*
+	* Anyway, I think the whole fact that I saw a bunch of duplicate 
+	* id's at one point, but can't reproduce the bug is rather alarming.
+	* Something must be broken somewhere, and merely adding more salt
+	* is just hiding the problem, not fixing it.
+	*/
   init_from_int (433781*counter);
   init_from_buff (guid->data, 16);
 

Modified: gnucash/trunk/lib/libqof/qof/guid.h
===================================================================
--- gnucash/trunk/lib/libqof/qof/guid.h	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/guid.h	2006-01-08 17:51:29 UTC (rev 12299)
@@ -38,8 +38,10 @@
     or beyond.
 
     QOF GUID's can be used independently of any other subsystem
-    in QOF.   In particular, they do not require the use of
-    other parts of the object subsystem.
+    in QOF. In particular, they do not require the use of
+    other parts of the object subsystem. New GUID's are usually
+    created by initialising a new entity using qof_instance_init,
+    rather than calling GUID functions directly.
 
     @{ */
 /** @file guid.h
@@ -127,19 +129,13 @@
 /** Generate a new id. If no initialization function has been called,
  *  guid_init() will be called before the id is created.
  *
- *  @return guid A pointer to a data structure containing a new GUID.
- *  The memory pointed to is owned by this routine and the guid must
- *  be copied out. 
- * 
- *  CAS: huh? make that: @return guid A data structure containing a newly
- * allocated GUID.  Caller is responsible for calling guid_free().
+ * @return guid A data structure containing a newly allocated GUID.
+ *  Caller is responsible for calling guid_free().
  */
 GUID guid_new_return(void);
 
-/** Returns a GUID which is guaranteed to never reference any entity. */
-/* CAS: AFAICT: this isn't really guaranteed, but it's only as likely
-   as any other md5 collision. This could be guaranteed if GUID
-   contained a validity flag. */
+/** Returns a GUID which is guaranteed
+to never reference any entity. */
 const GUID * guid_null (void);
 
 /** Efficiently allocate & free memory for GUIDs */

Modified: gnucash/trunk/lib/libqof/qof/kvp-util.h
===================================================================
--- gnucash/trunk/lib/libqof/qof/kvp-util.h	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/kvp-util.h	2006-01-08 17:51:29 UTC (rev 12299)
@@ -24,7 +24,7 @@
     @{ 
 */
 /** @file kvp-util.h 
-    @brief GnuCash KVP utility functions 
+    @brief QOF KVP utility functions 
  */
 /**  @name Hash Utilities
  @{ 

Modified: gnucash/trunk/lib/libqof/qof/kvp_frame.c
===================================================================
--- gnucash/trunk/lib/libqof/qof/kvp_frame.c	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/kvp_frame.c	2006-01-08 17:51:29 UTC (rev 12299)
@@ -31,20 +31,12 @@
 #include <string.h>
 #include <math.h>
 
-#include "gnc-date.h"
-#include "gnc-trace.h"
-#include "gnc-engine-util.h"
-#include "gnc-numeric.h"
-#include "guid.h"
-#include "kvp_frame.h"
+#include "qof.h"
 
-
  /* Note that we keep the keys for this hash table in a GCache
   * (gnc_string_cache), as it is very likely we will see the 
   * same keys over and over again  */
 
-/* TODO: set the cache handling functions with hash_table_new_full */
-
 struct _KvpFrame 
 {
   GHashTable  * hash;
@@ -76,7 +68,7 @@
 /* This static indicates the debugging module that this .o belongs to.  */
 static QofLogModule log_module = QOF_MOD_KVP;
 
-/********************************************************************
+/* *******************************************************************
  * KvpFrame functions
  ********************************************************************/
 
@@ -245,7 +237,7 @@
     return next_frame;
 }
 
-/* Get pointer to last frame in path. If teh path doesn't exist,
+/* Get pointer to last frame in path. If the path doesn't exist,
  * it is created.  The string stored in keypath will be hopelessly 
  * mangled .
  */
@@ -312,16 +304,16 @@
  */
 
 static inline KvpFrame *
-get_trailer_make (KvpFrame * frame, const char * key_path, const char **end_key)
+get_trailer_make (KvpFrame * frame, const char * key_path, char **end_key)
 {
-  const char *last_key;
+  char *last_key;
 
   if (!frame || !key_path || (0 == key_path[0])) return NULL;
 
   last_key = strrchr (key_path, '/');
   if (NULL == last_key)
   {
-    last_key = key_path;
+    last_key = (char *) key_path;
   }
   else if (last_key == key_path)
   {
@@ -354,16 +346,16 @@
  */
 
 static inline const KvpFrame *
-get_trailer_or_null (const KvpFrame * frame, const char * key_path, const char **end_key)
+get_trailer_or_null (const KvpFrame * frame, const char * key_path, char **end_key)
 {
-  const char *last_key;
+  char *last_key;
 
   if (!frame || !key_path || (0 == key_path[0])) return NULL;
 
   last_key = strrchr (key_path, '/');
   if (NULL == last_key)
   {
-    last_key = key_path;
+    last_key = (char *) key_path;
   }
   else if (last_key == key_path)
   {
@@ -469,7 +461,7 @@
 kvp_frame_set_value_nc (KvpFrame * frame, const char * key_path, 
                         KvpValue * value) 
 {
-  const char *last_key;
+  char *last_key;
 
   frame = get_trailer_make (frame, key_path, &last_key);
   if (!frame) return NULL;
@@ -482,7 +474,7 @@
                      const KvpValue * value) 
 {
   KvpValue *new_value = NULL;
-  const char *last_key;
+  char *last_key;
 
   frame = get_trailer_make (frame, key_path, &last_key);
   if (!frame) return NULL;
@@ -497,7 +489,7 @@
                             KvpValue * new_value) 
 {
   KvpValue * old_value;
-  const char *last_key;
+  char *last_key;
 
   last_key = NULL;
   if (new_value)
@@ -519,7 +511,7 @@
 KvpFrame *
 kvp_frame_add_value_nc(KvpFrame * frame, const char * path, KvpValue *value) 
 {
-  const char *key = NULL;
+  char *key = NULL;
   KvpValue *oldvalue;
 
   frame = (KvpFrame *) get_trailer_or_null (frame, path, &key);
@@ -855,7 +847,7 @@
 gint64
 kvp_frame_get_gint64(const KvpFrame *frame, const char *path)
 {
-  const char *key = NULL;
+  char *key = NULL;
   frame = get_trailer_or_null (frame, path, &key);
   return kvp_value_get_gint64(kvp_frame_get_slot (frame, key));
 }
@@ -863,7 +855,7 @@
 double      
 kvp_frame_get_double(const KvpFrame *frame, const char *path)
 {
-  const char *key = NULL;
+  char *key = NULL;
   frame = get_trailer_or_null (frame, path, &key);
   return kvp_value_get_double(kvp_frame_get_slot (frame, key));
 }
@@ -871,7 +863,7 @@
 gnc_numeric 
 kvp_frame_get_numeric(const KvpFrame *frame, const char *path)
 {
-  const char *key = NULL;
+  char *key = NULL;
   frame = get_trailer_or_null (frame, path, &key);
   return kvp_value_get_numeric(kvp_frame_get_slot (frame, key));
 }
@@ -879,7 +871,7 @@
 char * 
 kvp_frame_get_string(const KvpFrame *frame, const char *path)
 {
-  const char *key = NULL;
+  char *key = NULL;
   frame = get_trailer_or_null (frame, path, &key);
   return kvp_value_get_string(kvp_frame_get_slot (frame, key));
 }
@@ -887,7 +879,7 @@
 GUID *
 kvp_frame_get_guid(const KvpFrame *frame, const char *path)
 {
-  const char *key = NULL;
+  char *key = NULL;
   frame = get_trailer_or_null (frame, path, &key);
   return kvp_value_get_guid(kvp_frame_get_slot (frame, key));
 }
@@ -896,7 +888,7 @@
 kvp_frame_get_binary(const KvpFrame *frame, const char *path,
                                    guint64 * size_return)
 {
-  const char *key = NULL;
+  char *key = NULL;
   frame = get_trailer_or_null (frame, path, &key);
   return kvp_value_get_binary(kvp_frame_get_slot (frame, key), size_return);
 }
@@ -904,7 +896,7 @@
 Timespec
 kvp_frame_get_timespec(const KvpFrame *frame, const char *path)
 {
-  const char *key = NULL;
+  char *key = NULL;
   frame = get_trailer_or_null (frame, path, &key);
   return kvp_value_get_timespec(kvp_frame_get_slot (frame, key));
 }
@@ -912,7 +904,7 @@
 KvpFrame *
 kvp_frame_get_frame(const KvpFrame *frame, const char *path)
 {
-  const char *key = NULL;
+  char *key = NULL;
   frame = get_trailer_or_null (frame, path, &key);
   return kvp_value_get_frame(kvp_frame_get_slot (frame, key));
 }
@@ -920,7 +912,7 @@
 KvpValue *
 kvp_frame_get_value(const KvpFrame *frame, const char *path)
 {
-  const char *key = NULL;
+  char *key = NULL;
   frame = get_trailer_or_null (frame, path, &key);
   return kvp_frame_get_slot (frame, key);
 }
@@ -1039,7 +1031,7 @@
   }
 }
 
-/********************************************************************
+/* *******************************************************************
  * kvp glist functions
  ********************************************************************/
 
@@ -1109,7 +1101,7 @@
   return 0;
 }
 
-/********************************************************************
+/* *******************************************************************
  * KvpValue functions
  ********************************************************************/
 
@@ -1637,6 +1629,13 @@
     return tmp2;
 }
 
+static void
+kvp_frame_to_bare_string_helper(gpointer key, gpointer value, gpointer data)
+{
+	gchar **str = (gchar**)data;
+	*str = g_strdup_printf("%s", kvp_value_to_bare_string((KvpValue *)value));
+}
+
 gchar*
 kvp_value_to_bare_string(const KvpValue *val)
 {
@@ -1645,7 +1644,7 @@
     const gchar *ctmp;
     
     g_return_val_if_fail(val, NULL);
-    
+    tmp1 = g_strdup("");
     switch(kvp_value_get_type(val))
     {
     case KVP_TYPE_GINT64:
@@ -1675,13 +1674,13 @@
         break;
 
     case KVP_TYPE_TIMESPEC:
-        tmp1 = g_new0 (char, 40);
-        gnc_timespec_to_iso8601_buff (kvp_value_get_timespec (val), tmp1);
-        tmp2 = g_strdup_printf("%s", tmp1);
-        g_free(tmp1);
-        return tmp2;
+	{
+		time_t t;
+		t = timespecToTime_t(kvp_value_get_timespec(val));
+        qof_date_format_set(QOF_DATE_FORMAT_UTC);
+        return qof_print_date(t);
         break;
-
+	}
     case KVP_TYPE_BINARY:
     {
         guint64 len;
@@ -1693,19 +1692,26 @@
         break;
  
     case KVP_TYPE_GLIST:
+		/* borked. kvp_value_glist_to_string is a debug fcn */
+	{
         tmp1 = kvp_value_glist_to_string(kvp_value_get_glist(val));
         tmp2 = g_strdup_printf("%s", tmp1 ? tmp1 : "");
         g_free(tmp1);
         return tmp2;
         break;
+	}
+    case KVP_TYPE_FRAME:
+	{
+		KvpFrame *frame;
 
-    case KVP_TYPE_FRAME:
-        tmp1 = kvp_frame_to_string(kvp_value_get_frame(val));
-        tmp2 = g_strdup_printf("%s", tmp1 ? tmp1 : "");
-        g_free(tmp1);
-        return tmp2;
+		frame = kvp_value_get_frame(val);
+		if (frame->hash) {
+			tmp1 = g_strdup("");
+			g_hash_table_foreach(frame->hash, kvp_frame_to_bare_string_helper, &tmp1);
+		}
+        return tmp1;
         break;
-
+	}
     default:
         return g_strdup_printf(" ");
         break;
@@ -1746,7 +1752,7 @@
         break;
 
     case KVP_TYPE_GUID:
-        /* THREAD-UNSAFE */
+		/* THREAD-UNSAFE */
         ctmp = guid_to_string(kvp_value_get_guid(val));
         tmp2 = g_strdup_printf("KVP_VALUE_GUID(%s)", ctmp ? ctmp : "");
         return tmp2;

Modified: gnucash/trunk/lib/libqof/qof/kvp_frame.h
===================================================================
--- gnucash/trunk/lib/libqof/qof/kvp_frame.h	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/kvp_frame.h	2006-01-08 17:51:29 UTC (rev 12299)
@@ -75,7 +75,7 @@
 /** A KvpValue is a union with possible types enumerated in the
  * KvpValueType enum. */
 typedef struct _KvpValue KvpValue;
-
+ 
 /** \brief possible types in the union KvpValue 
  * \todo : People have asked for boolean values, 
  *  e.g. in xaccAccountSetAutoInterestXfer
@@ -99,12 +99,14 @@
   KVP_TYPE_FRAME       /**< no QOF equivalent. */
 } KvpValueType;
 
-/** \deprecated Deprecated backwards compat tokens
+/** \deprecated Deprecated backwards compat token
 
-do \b not use these in new code.
+do \b not use these in new code. 
 */
 #define kvp_frame KvpFrame
+/** \deprecated Deprecated backwards compat token */
 #define kvp_value KvpValue
+/** \deprecated Deprecated backwards compat token */
 #define kvp_value_t KvpValueType
   
 /** @name KvpFrame Constructors
@@ -241,7 +243,7 @@
  *  'November', respectively.  This routine also handles % encoding.
  *
  *  This routine treats all values as strings; it does *not* attempt
- *    to perform any type-conversion.
+ *  to perform any type-conversion.
  * */
 void     kvp_frame_add_url_encoding (KvpFrame *frame, const char *enc);
 /** @} */

Modified: gnucash/trunk/lib/libqof/qof/qof-be-utils.h
===================================================================
--- gnucash/trunk/lib/libqof/qof/qof-be-utils.h	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/qof-be-utils.h	2006-01-08 17:51:29 UTC (rev 12299)
@@ -35,7 +35,7 @@
 #ifndef QOF_BE_UTILS_H
 #define QOF_BE_UTILS_H
 
-#include "gnc-trace.h"
+#include "qoflog.h"
 #include "gnc-engine-util.h"
 #include "qofbackend-p.h"
 #include "qofbook.h"
@@ -46,13 +46,12 @@
  * @param  inst: an instance of QofInstance
  *
  * The caller should use this macro first and then perform any other operations.
-
+ 
  Uses newly created functions to allow the macro to be used
  when QOF is linked as a library. qofbackend-p.h is a private header.
  */
 
 #define QOF_BEGIN_EDIT(inst)                                        \
-  QofBackend * be;                                                  \
   if (!(inst)) return;                                              \
                                                                     \
   (inst)->editlevel++;                                              \
@@ -66,12 +65,15 @@
   ENTER ("(inst=%p)", (inst));                                      \
                                                                     \
   /* See if there's a backend.  If there is, invoke it. */          \
-  be = qof_book_get_backend ((inst)->book);                         \
-    if (be && qof_backend_begin_exists((be))) {                     \
-     qof_backend_run_begin((be), (inst));                           \
-  } else {                                                          \
-     /* We tried and failed to start transaction! */                \
-     (inst)->dirty = TRUE;                                          \
+  {                                                                 \
+    QofBackend * be;                                                \
+    be = qof_book_get_backend ((inst)->book);                       \
+      if (be && qof_backend_begin_exists(be)) {                     \
+         qof_backend_run_begin(be, (inst));                         \
+    } else {                                                        \
+      /* We tried and failed to start transaction! */               \
+      (inst)->dirty = TRUE;                                         \
+    }                                                               \
   }                                                                 \
   LEAVE (" ");
 
@@ -102,15 +104,15 @@
   (inst)->editlevel--;                                           \
   if (0 < (inst)->editlevel) return;                             \
                                                                  \
-  /* The pricedb suffers from delayed update...     */           \
+  /* The pricedb suffers from delayed update...     */          \
   /* This may be setting a bad precedent for other types, I fear. */ \
   /* Other types probably really should handle begin like this. */ \
   if ((-1 == (inst)->editlevel) && (inst)->dirty)                \
   {                                                              \
     QofBackend * be;                                             \
     be = qof_book_get_backend ((inst)->book);                    \
-    if (be && qof_backend_begin_exists((be))) {                  \
-     qof_backend_run_begin((be), (inst));                        \
+    if (be && qof_backend_begin_exists(be)) {                    \
+      qof_backend_run_begin(be, (inst));                         \
     }                                                            \
     (inst)->editlevel = 0;                                       \
   }                                                              \
@@ -148,7 +150,7 @@
                                                                  \
   /* See if there's a backend.  If there is, invoke it. */       \
   be = qof_book_get_backend ((inst)->book);                      \
-  if (be && qof_backend_commit_exists((be)))                     \
+  if (be && qof_backend_commit_exists(be))                       \
   {                                                              \
     QofBackendError errcode;                                     \
                                                                  \
@@ -157,7 +159,7 @@
       errcode = qof_backend_get_error (be);                      \
     } while (ERR_BACKEND_NO_ERR != errcode);                     \
                                                                  \
-    qof_backend_run_commit((be), (inst));                        \
+    qof_backend_run_commit(be, (inst));                          \
     errcode = qof_backend_get_error (be);                        \
     if (ERR_BACKEND_NO_ERR != errcode)                           \
     {                                                            \

Modified: gnucash/trunk/lib/libqof/qof/qof.h
===================================================================
--- gnucash/trunk/lib/libqof/qof/qof.h	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/qof.h	2006-01-08 17:51:29 UTC (rev 12299)
@@ -74,7 +74,7 @@
 /** @} */
 
 #include "qofid.h"
-#include "gnc-trace.h"
+#include "qoflog.h"
 #include "gnc-date.h"
 #include "gnc-numeric.h"
 #include "gnc-event.h"
@@ -97,5 +97,13 @@
 #include "qof_book_merge.h"
 #include "qof-be-utils.h"
 #include "qofla-dir.h"
+#include "deprecated.h"
 
+/** allow easy logging of QSF debug messages */
+#define QOF_MOD_QSF "qof-backend-qsf"
+/** allow easy loading of the QSF backend */
+#define QSF_BACKEND_LIB "libqof-backend-qsf"
+/** allow easy loading of the QSF backend */
+#define QSF_MODULE_INIT "qsf_provider_init"
+
 #endif /* QOF_H_ */

Modified: gnucash/trunk/lib/libqof/qof/qof_book_merge.c
===================================================================
--- gnucash/trunk/lib/libqof/qof/qof_book_merge.c	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/qof_book_merge.c	2006-01-08 17:51:29 UTC (rev 12299)
@@ -16,16 +16,12 @@
  * along with this program; if not, contact:                         *
  *                                                                   *
  * Free Software Foundation           Voice:  +1-617-542-5942        *
- * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652        *
- * Boston, MA  02110-1301,  USA       gnu at gnu.org                    *
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
  *                                                                   *
  ********************************************************************/
 
-#include "gnc-trace.h"
-#include "qof_book_merge.h"
-#include "qofinstance-p.h"
-#include "qofchoice.h"
-#include "qofid-p.h"
+#include "qof.h"
 
 static QofLogModule log_module = QOF_MOD_MERGE;
 
@@ -698,7 +694,7 @@
 			registered_type = TRUE;
 		}
 		if(safe_strcmp(rule->mergeType, QOF_TYPE_CHOICE) == 0) {
-				referenceEnt = cm_param->param_getfcn(rule->importEnt, cm_param);
+			referenceEnt = cm_param->param_getfcn(rule->importEnt, cm_param);
 			reference_setter = (void(*)(QofEntity*, QofEntity*))cm_param->param_setfcn;
 			if(reference_setter != NULL) 
 			{ 
@@ -795,6 +791,11 @@
 FAIL the schema validation and QSF exports will become invalid.
 
 The QOF_TYPE_BOOLEAN is lowercase for the same reason.
+
+\todo deprecate and replace with
+gchar* qof_instance_param_as_string(const QofParam*, QofInstance*);
+and then add
+gchar* qof_class_get_param_as_string(QofIdTypeConst, QofInstance*); ?
 */
 char*
 qof_book_merge_param_as_string(QofParam *qtparam, QofEntity *qtEnt)

Modified: gnucash/trunk/lib/libqof/qof/qof_book_merge.h
===================================================================
--- gnucash/trunk/lib/libqof/qof/qof_book_merge.h	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/qof_book_merge.h	2006-01-08 17:51:29 UTC (rev 12299)
@@ -16,8 +16,8 @@
  * along with this program; if not, contact:                         *
  *                                                                   *
  * Free Software Foundation           Voice:  +1-617-542-5942        *
- * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652        *
- * Boston, MA  02110-1301,  USA       gnu at gnu.org                    *
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
  *                                                                   *
  ********************************************************************/
 
@@ -68,6 +68,7 @@
 pointer to the ::qof_book_mergeData struct - the calling process needs to
 make sure this is non-NULL to know that the Init has been successful.
 
+(to be renamed qofbookmerge.h in libqof2)
  @{
 */
 /** @file  qof_book_merge.h
@@ -81,7 +82,7 @@
 #include "qofclass.h"
 #include "qofobject.h"
 #include "qofinstance.h"
-#include "gnc-trace.h"
+#include "qoflog.h"
 
 /** \brief Results of collisions and user resolution.
 

Modified: gnucash/trunk/lib/libqof/qof/qofbackend-p.h
===================================================================
--- gnucash/trunk/lib/libqof/qof/qofbackend-p.h	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/qofbackend-p.h	2006-01-08 17:51:29 UTC (rev 12299)
@@ -313,7 +313,7 @@
   gboolean (*process_events) (QofBackend *);
 
   QofBePercentageFunc percentage;
-
+  
   QofBackendProvider *provider;
 
   /** Document Me !!! what is this supposed to do ?? */
@@ -329,8 +329,7 @@
    */
   char * fullpath;
 
-#ifdef GNUCASH_MAJOR_VERSION
-  /** XXX price_lookup should be removed during the redesign
+  /** \deprecated price_lookup should be removed during the redesign
    * of the SQL backend... prices can now be queried using
    * the generic query mechanism.
    *
@@ -340,13 +339,12 @@
    */
   void (*price_lookup) (QofBackend *, gpointer);
 
-  /** XXX Export should really _NOT_ be here, but is left here for now.
+  /** \deprecated Export should really _NOT_ be here, but is left here for now.
    * I'm not sure where this should be going to. It should be
    * removed ASAP.   This is a temporary hack-around until period-closing
    * is fully implemented.
    */
   void (*export) (QofBackend *, QofBook *);
-#endif
 
 };
 

Modified: gnucash/trunk/lib/libqof/qof/qofbackend.c
===================================================================
--- gnucash/trunk/lib/libqof/qof/qofbackend.c	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/qofbackend.c	2006-01-08 17:51:29 UTC (rev 12299)
@@ -31,8 +31,8 @@
 #include <glib.h>
 #include <gmodule.h>
 #include <dlfcn.h>
-#include <sys/stat.h>
 #include <errno.h>
+#include "qof.h"
 #include "qofbackend-p.h"
 
 static QofLogModule log_module = QOF_MOD_BACKEND;
@@ -40,7 +40,7 @@
 #define QOF_CONFIG_DESC    "desc"
 #define QOF_CONFIG_TIP     "tip"
 
-/********************************************************************\
+/* *******************************************************************\
  * error handling                                                   *
 \********************************************************************/
 
@@ -89,7 +89,6 @@
    be->error_msg = buffer;
 }
 
-/* This should always return a valid char * */
 char *
 qof_backend_get_message (QofBackend *be) 
 {
@@ -100,9 +99,9 @@
 
    /* 
     * Just return the contents of the error_msg and then set it to
-    * NULL.  This is necessary, because the Backends don't seem to
-    * have a destroy_backend function to take care if freeing stuff
-    * up.  The calling function should free the copy.
+    * NULL. This is necessary, because the Backends don't seem to
+    * have a destroy_backend function to take care of freeing stuff
+    * up. The calling function should free the copy.
     * Also, this is consistent with the qof_backend_get_error() popping.
     */
 
@@ -141,13 +140,10 @@
     be->error_msg = NULL;
     be->percentage = NULL;
 	be->backend_configuration = kvp_frame_new();
-
-#ifdef GNUCASH_MAJOR_VERSION
-    /* XXX remove these */
-    be->fullpath = NULL;
-    be->price_lookup = NULL;
-    be->export = NULL;
-#endif
+	
+	/* to be removed */
+	be->price_lookup = NULL;
+	be->export = NULL;
 }
 
 void
@@ -195,11 +191,10 @@
 	count = be->config_count;
 	count++;
 	value = NULL;
-	ENTER (" %d", count);
 	switch (option->type)
 	{
 		case KVP_TYPE_GINT64   : {
-			value = kvp_value_new_gint64(*(gint64*)option->value);
+			value = kvp_value_new_gint64(GPOINTER_TO_INT(option->value));
 			break; 
 		}
 		case KVP_TYPE_DOUBLE   : { 
@@ -226,22 +221,16 @@
 	if(value) {
 		temp = g_strdup_printf("/%s", option->option_name);
 		kvp_frame_set_value(be->backend_configuration, temp, value);
-		PINFO (" setting value at %s", temp);
 		g_free(temp);
 		temp = g_strdup_printf("/%s/%s", QOF_CONFIG_DESC, option->option_name);
-		PINFO (" setting description %s at %s", option->description, temp);
 		kvp_frame_set_string(be->backend_configuration, temp, option->description);
-		PINFO (" check= %s", kvp_frame_get_string(be->backend_configuration, temp));
 		g_free(temp);
 		temp = g_strdup_printf("/%s/%s", QOF_CONFIG_TIP, option->option_name);
-		PINFO (" setting tooltip %s at %s", option->tooltip, temp);
 		kvp_frame_set_string(be->backend_configuration, temp, option->tooltip);
-		PINFO (" check= %s", kvp_frame_get_string(be->backend_configuration, temp));
 		g_free(temp);
 		/* only increment the counter if successful */
 		be->config_count = count;
 	}
-	LEAVE (" ");
 }
 
 KvpFrame* qof_backend_complete_frame(QofBackend *be)
@@ -397,7 +386,6 @@
 qof_load_backend_library (const char *directory, 
 				const char* filename, const char* init_fcn)
 {
-	struct stat sbuf;
 	gchar *fullpath;
 	typedef void (* backend_init) (void);
 	GModule *backend;
@@ -406,8 +394,6 @@
 
 	g_return_val_if_fail(g_module_supported(), FALSE);
 	fullpath = g_module_build_path(directory, filename);
-	PINFO (" fullpath=%s", fullpath);
-	g_return_val_if_fail((stat(fullpath, &sbuf) == 0), FALSE);
 	backend = g_module_open(fullpath, G_MODULE_BIND_LAZY);
 	if(!backend) { 
 		g_message ("%s: %s\n", PACKAGE, g_module_error ());

Modified: gnucash/trunk/lib/libqof/qof/qofbook-p.h
===================================================================
--- gnucash/trunk/lib/libqof/qof/qofbook-p.h	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/qofbook-p.h	2006-01-08 17:51:29 UTC (rev 12299)
@@ -43,68 +43,70 @@
 #include "qofid-p.h"
 #include "qofinstance-p.h"
 
-/** Book structure */
+/* Book structure */
 struct _QofBook
 {
-  QofInstance   inst;     /**< Unique guid for this book. */
+  QofInstance   inst;     /* Unique guid for this book. */
 
-  /** The entity table associates the GUIDs of all the objects
+  /* The entity table associates the GUIDs of all the objects
    * belonging to this book, with their pointers to the respective
    * objects.  This allows a lookup of objects based on thier guid.
    */
   GHashTable * hash_of_collections;
 
-  /** In order to store arbitrary data, for extensibility, add a table
+  /* In order to store arbitrary data, for extensibility, add a table
    * that will be used to hold arbitrary pointers.
    */
   GHashTable *data_tables;
 
-  /** Hash table of destroy callbacks for the data table. */
+  /* Hash table of destroy callbacks for the data table. */
   GHashTable *data_table_finalizers;
 
-  /** state flag: 'y' means 'open for editing', 
-   * 'n' means 'book is closed'  
-   * xxxxx shouldn't this be replaced by the instance editlevel ??? 
+  /* state flag: 'y' means 'open for editing',
+   * 'n' means 'book is closed'
+   * xxxxx shouldn't this be replaced by the instance editlevel ???
    */
   char book_open;
 
-  /** a flag denoting whether the book is closing down, used to
+  /* a flag denoting whether the book is closing down, used to
    * help the QOF objects shut down cleanly without maintaining
    * internal consistency.
-   * XXX shouldn't this be replaced by instance->do_free ??? 
+   * XXX shouldn't this be replaced by instance->do_free ???
    */
   gboolean shutting_down;
-  
-  /** version number, used for tracking multiuser updates */
+
+  /* version number, used for tracking multiuser updates */
   gint32  version;
 
-  /** To be technically correct, backends belong to sessions and
-   * not books.  So the pointer below "really shouldn't be here", 
-   * except that it provides a nice convenience, avoiding a lookup 
-   * from the session.  Better solutions welcome ... */ 
+  /* To be technically correct, backends belong to sessions and
+   * not books.  So the pointer below "really shouldn't be here",
+   * except that it provides a nice convenience, avoiding a lookup
+   * from the session.  Better solutions welcome ... */
   QofBackend *backend;
 
   /* -------------------------------------------------------------- */
-  /** Backend private expansion data */
-  guint32  idata;     /**< used by the sql backend for kvp management */
+  /* Backend private expansion data */
+  guint32  idata;     /* used by the sql backend for kvp management */
 };
 
-/**
- * These qof_book_set_*() routines are used by backends to 
- *    initialize the pointers in the book structure to 
- *    something that contains actual data.  These routines 
+/*
+ *    qof_book_set_backend() is used by backends to
+ *    initialize the pointers in the book structure to
+ *    something that contains actual data.  These routines
  *    should not be used otherwise.  (Its somewhat questionable
  *    if the backends should even be doing this much, but for
  *    backwards compatibility, we leave these here.)
  */
+void qof_book_set_backend (QofBook *book, QofBackend *be);
+
+/** \deprecated */
 void qof_book_set_schedxactions( QofBook *book, GList *newList );
 
-void qof_book_set_backend (QofBook *book, QofBackend *be);
-
-/** Register books with the engine */
+/* Register books with the engine */
 gboolean qof_book_register (void);
 
-/** @deprecated */
+/** @deprecated use qof_entity_set_guid instead but only in
+backends (when reading the GUID from the data source). */
 #define qof_book_set_guid(book,guid)    \
          qof_entity_set_guid(QOF_ENTITY(book), guid)
 

Modified: gnucash/trunk/lib/libqof/qof/qofbook.c
===================================================================
--- gnucash/trunk/lib/libqof/qof/qofbook.c	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/qofbook.c	2006-01-08 17:51:29 UTC (rev 12299)
@@ -1,5 +1,5 @@
 /********************************************************************\
- * qofbook.c -- dataset access (set of accounting books)            *
+ * qofbook.c -- dataset access (set of books of entities)           *
  *                                                                  *
  * This program is free software; you can redistribute it and/or    *
  * modify it under the terms of the GNU General Public License as   *
@@ -24,8 +24,7 @@
  * qofbook.c
  *
  * FUNCTION:
- * Encapsulate all the information about a gnucash dataset.
- * See src/doc/books.txt for design overview.
+ * Encapsulate all the information about a QOF dataset.
  *
  * HISTORY:
  * Created by Linas Vepstas December 1998
@@ -40,19 +39,13 @@
 
 #include <glib.h>
 
-#include "gnc-event.h"
+#include "qof.h"
 #include "gnc-event-p.h"
-#include "gnc-trace.h"
 #include "qofbackend-p.h"
-#include "qofbook.h"
 #include "qofbook-p.h"
-#include "qofclass.h"
 #include "qofid-p.h"
 #include "qofobject-p.h"
-#include "gnc-engine-util.h"
 
-#include "guid.h"
-
 static QofLogModule log_module = QOF_MOD_ENGINE;
 
 /* ====================================================================== */
@@ -117,7 +110,7 @@
   book->shutting_down = TRUE;
   gnc_engine_force_event (&book->inst.entity, GNC_EVENT_DESTROY);
 
-  /* Call the list of finalizers, let them do their thing.
+  /* Call the list of finalizers, let them do their thing. 
    * Do this before tearing into the rest of the book.
    */
   g_hash_table_foreach (book->data_table_finalizers, book_final, book);
@@ -290,32 +283,32 @@
 
 gchar qof_book_get_open_marker(QofBook *book)
 {
-       if(!book) { return 'n'; }
-       return book->book_open;
+	if(!book) { return 'n'; }
+	return book->book_open;
 }
 
 gint32 qof_book_get_version (QofBook *book)
 {
-       if(!book) { return -1; }
-       return book->version;
+	if(!book) { return -1; }
+	return book->version;
 }
 
 guint32 qof_book_get_idata (QofBook *book)
 {
-       if(!book) { return 0; }
-       return book->idata;
+	if(!book) { return 0; }
+	return book->idata;
 }
 
 void qof_book_set_version (QofBook *book, gint32 version)
 {
-       if(!book && version < 0) { return; }
-       book->version = version;
+	if(!book && version < 0) { return; }
+	book->version = version;
 }
 
 void qof_book_set_idata(QofBook *book, guint32 idata)
 {
-       if(!book && idata < 0) { return; }
-       book->idata = idata;
+	if(!book && idata < 0) { return; }
+	book->idata = idata;
 }
 
 gint64

Modified: gnucash/trunk/lib/libqof/qof/qofbook.h
===================================================================
--- gnucash/trunk/lib/libqof/qof/qofbook.h	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/qofbook.h	2006-01-08 17:51:29 UTC (rev 12299)
@@ -21,13 +21,13 @@
 /** @addtogroup Object
     @{ */
 /** @addtogroup Book
-    A QOF Book is a dataset.  It provides a single handle 
+    A QOF Book is a dataset.  It provides a single handle
     through which all the various collections of entities
     can be found.   In particular, given only the type of
     the entity, the collection can be found.
-    
+
     Books also provide the 'natural' place to working with
-    a storage backend, as a book can encapsulate everything 
+    a storage backend, as a book can encapsulate everything
     held in storage.
     @{ */
 /** @file qofbook.h
@@ -45,7 +45,7 @@
 #include "kvp_frame.h"
 
 /** @brief Encapsulates all the information about a dataset
- * manipulated by GnuCash.  This is the top-most structure
+ * manipulated by QOF.  This is the top-most structure
  * used for anchoring data.
  */
 
@@ -62,7 +62,7 @@
 
 /** \brief QofBook reference */
 typedef struct _QofBook       QofBook;
-                                                                                
+
 /** GList of QofBook */
 typedef GList                 QofBookList;
 
@@ -70,12 +70,12 @@
 
 /** Register the book object with the QOF object system. */
 gboolean qof_book_register (void);
-                                                                                
+
 /** Allocate, initialise and return a new QofBook.  Books contain references
  *  to all of the top-level object containers. */
 QofBook * qof_book_new (void);
 
-/** End any editing sessions associated with book, and free all memory 
+/** End any editing sessions associated with book, and free all memory
     associated with it. */
 void      qof_book_destroy (QofBook *book);
 
@@ -86,17 +86,17 @@
 */
 void qof_book_mark_closed (QofBook *book);
 
-/** \return The table of entities of the given type.  
+/** Return The table of entities of the given type.
  *
  *  When an object's constructor calls qof_instance_init(), a
  *  reference to the object is stored in the book.  The book stores
  *  all the references to initialized instances, sorted by type.  This
  *  function returns a collection of the references for the specified
  *  type.
- * 
+ *
  *  If the collection doesn't yet exist for the indicated type,
  *  it is created.  Thus, this routine is gaurenteed to return
- *  a non-NULL value.  (Unless the system malloc failed (out of 
+ *  a non-NULL value.  (Unless the system malloc failed (out of
  *  memory) in which case what happens??).
  */
 QofCollection  * qof_book_get_collection (QofBook *, QofIdType);
@@ -105,32 +105,32 @@
 typedef void (*QofCollectionForeachCB) (QofCollection *, gpointer user_data);
 void qof_book_foreach_collection (QofBook *, QofCollectionForeachCB, gpointer);
 
-/** \return The kvp data for the book.
- *  Note that the book KVP data is persistant, and is stored/retrieved
+/** Return The kvp data for the book.
+ *  Note that the book KVP data is persistent, and is stored/retrieved
  *  from the file/database.  Thus, the book KVP is the correct place to
- *  store data that needs to be persistant accross sessions (or shared
+ *  store data that needs to be persistent accross sessions (or shared
  *  between multiple users).  To store application runtime data, use
  *  qof_book_set_data() instead.
  */
 #define qof_book_get_slots(book) qof_instance_get_slots(QOF_INSTANCE(book))
 
-/** The qof_book_set_data() allows arbitrary pointers to structs 
- *    to be stored in QofBook. This is the "prefered" method for 
+/** The qof_book_set_data() allows arbitrary pointers to structs
+ *    to be stored in QofBook. This is the "preferred" method for
  *    extending QofBook to hold new data types.  This is also
- *    the ideal location to store other arbitrary runtime data 
+ *    the ideal location to store other arbitrary runtime data
  *    that the application may need.
  *
  *    The book data differs from the book KVP in that the contents
- *    of the book KVP are persistant (are saved and restored to file 
+ *    of the book KVP are persistent (are saved and restored to file
  *    or database), whereas the data pointers exist only at runtime.
  */
 void qof_book_set_data (QofBook *book, const char *key, gpointer data);
 
 /** Same as qof_book_set_data(), except that the callback will be called
- *  when the book is destroyed.  The argument to the callback will be 
+ *  when the book is destroyed.  The argument to the callback will be
  *  the book followed by the data pointer.
  */
-void qof_book_set_data_fin (QofBook *book, const char *key, gpointer data,
+void qof_book_set_data_fin (QofBook *book, const char *key, gpointer data, 
                             QofBookFinalCB);
 
 /** Retrieves arbitrary pointers to structs stored by qof_book_set_data. */
@@ -139,20 +139,20 @@
 /** Is the book shutting down? */
 gboolean qof_book_shutting_down (QofBook *book);
 
-/** qof_book_not_saved() will return TRUE if any 
+/** qof_book_not_saved() will return TRUE if any
  *    data in the book hasn't been saved to long-term storage.
- *    (Actually, that's not quite true.  The book doesn't know 
+ *    (Actually, that's not quite true.  The book doesn't know
  *    anything about saving.  Its just that whenever data is modified,
- *    the 'dirty' flag is set.  This routine returns the value of the 
- *    'dirty' flag.  Its up to the backend to periodically reset this 
+ *    the 'dirty' flag is set.  This routine returns the value of the
+ *    'dirty' flag.  Its up to the backend to periodically reset this
  *    flag, when it actually does save the data.)
  */
 gboolean qof_book_not_saved (QofBook *book);
 
 /** The qof_book_mark_saved() routine marks the book as having been
  *    saved (to a file, to a database). Used by backends to mark the
- *    notsaved flag as FALSE just after loading.  Also used by the
- *    main window code when the used has said to abandon any changes.
+ *    notsaved flag as FALSE just after loading.  Can also be used 
+ *    by the frontend when the used has said to abandon any changes.
  */
 void qof_book_mark_saved(QofBook *book);
 
@@ -160,7 +160,7 @@
  * is marked 'dirty'. */
 void qof_book_kvp_changed (QofBook *book);
 
-/** The qof_book_equal() method returns TRUE if books are equal. 
+/** The qof_book_equal() method returns TRUE if books are equal.
  * XXX this routine is broken, and does not currently compare data.
  */
 gboolean qof_book_equal (QofBook *book_1, QofBook *book_2);

Modified: gnucash/trunk/lib/libqof/qof/qofchoice.c
===================================================================
--- gnucash/trunk/lib/libqof/qof/qofchoice.c	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/qofchoice.c	2006-01-08 17:51:29 UTC (rev 12299)
@@ -18,8 +18,7 @@
  *
  *  You should have received a copy of the GNU General Public License
  *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- *  02110-1301, USA.
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
 #include <glib.h>

Modified: gnucash/trunk/lib/libqof/qof/qofchoice.h
===================================================================
--- gnucash/trunk/lib/libqof/qof/qofchoice.h	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/qofchoice.h	2006-01-08 17:51:29 UTC (rev 12299)
@@ -18,8 +18,7 @@
  *
  *  You should have received a copy of the GNU General Public License
  *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- *  02110-1301, USA.
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
 #ifndef _QOFCHOICE_H

Modified: gnucash/trunk/lib/libqof/qof/qofclass-p.h
===================================================================
--- gnucash/trunk/lib/libqof/qof/qofclass-p.h	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/qofclass-p.h	2006-01-08 17:51:29 UTC (rev 12299)
@@ -1,5 +1,5 @@
 /********************************************************************\
- * qofclass-p.h -- Private API for registering queriable objects    *
+ * qofclass-p.h -- Private API for registering queryable objects    *
  * Copyright (C) 2002 Derek Atkins <warlord at MIT.EDU>                *
  *                                                                  *
  * This program is free software; you can redistribute it and/or    *
@@ -23,7 +23,6 @@
 /** @addtogroup Object
     @{ */
 /** @addtogroup Object_Private
-    Private interfaces, not meant to be used by applications.
     @{ */
 /** @name  Class_Private
     @{ */

Modified: gnucash/trunk/lib/libqof/qof/qofclass.c
===================================================================
--- gnucash/trunk/lib/libqof/qof/qofclass.c	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/qofclass.c	2006-01-08 17:51:29 UTC (rev 12299)
@@ -1,5 +1,5 @@
 /********************************************************************\
- * qofclass.c -- provide QOF paramterized data objects              *
+ * qofclass.c -- provide QOF parameterized data objects             *
  * Copyright (C) 2002 Derek Atkins <warlord at MIT.EDU>                *
  *                                                                  *
  * This program is free software; you can redistribute it and/or    *
@@ -25,11 +25,8 @@
 
 #include <glib.h>
 
-#include "gnc-trace.h"
-#include "gnc-engine-util.h"
-#include "qofclass.h"
+#include "qof.h"
 #include "qofclass-p.h"
-#include "qofquery.h"
 
 static QofLogModule log_module = QOF_MOD_CLASS;
 
@@ -43,10 +40,49 @@
   return TRUE;
 }
 
-/********************************************************************/
+/* *******************************************************************/
+/* PRIVATE FUNCTIONS */
+
+static gboolean check_init (void)
+{
+    if (initialized) return TRUE;
+
+    PERR("You must call qof_class_init() before using qof_class.");
+    return FALSE;
+}
+
+void
+qof_class_init(void)
+{
+  if (initialized) return;
+  initialized = TRUE;
+
+  classTable = g_hash_table_new (g_str_hash, g_str_equal);
+  sortTable = g_hash_table_new (g_str_hash, g_str_equal);
+}
+
+void
+qof_class_shutdown (void)
+{
+  if (!initialized) return;
+  initialized = FALSE;
+
+  g_hash_table_foreach_remove (classTable, clear_table, NULL);
+  g_hash_table_destroy (classTable);
+  g_hash_table_destroy (sortTable);
+}
+
+QofSortFunc
+qof_class_get_default_sort (QofIdTypeConst obj_name)
+{
+  if (!obj_name) return NULL;
+  return g_hash_table_lookup (sortTable, obj_name);
+}
+
+/* *******************************************************************/
 /* PUBLISHED API FUNCTIONS */
 
-void 
+void
 qof_class_register (QofIdTypeConst obj_name,
                     QofSortFunc default_sort_function,
                     const QofParam *params)
@@ -55,6 +91,7 @@
   int i;
 
   if (!obj_name) return;
+  if (!check_init()) return;
 
   if (default_sort_function)
   {
@@ -64,17 +101,17 @@
   ht = g_hash_table_lookup (classTable, obj_name);
 
   /* If it doesn't already exist, create a new table for this object */
-  if (!ht) 
+  if (!ht)
   {
     ht = g_hash_table_new (g_str_hash, g_str_equal);
     g_hash_table_insert (classTable, (char *)obj_name, ht);
   }
 
   /* At least right now, we allow dummy, parameterless objects,
-   * for testing purposes.  Although I suppose that should be 
+   * for testing purposes.  Although I suppose that should be
    * an error..  */
   /* Now insert all the parameters */
-  if (params) 
+  if (params)
   {
     for (i = 0; params[i].param_name; i++)
       g_hash_table_insert (ht,
@@ -83,38 +120,18 @@
   }
 }
 
-void 
-qof_class_init(void)
-{
-  if (initialized) return;
-  initialized = TRUE;
-
-  classTable = g_hash_table_new (g_str_hash, g_str_equal);
-  sortTable = g_hash_table_new (g_str_hash, g_str_equal);
-}
-
-void 
-qof_class_shutdown (void)
-{
-  if (!initialized) return;
-  initialized = FALSE;
-
-  g_hash_table_foreach_remove (classTable, clear_table, NULL);
-  g_hash_table_destroy (classTable);
-  g_hash_table_destroy (sortTable);
-}
-
 gboolean
 qof_class_is_registered (QofIdTypeConst obj_name)
 {
   if (!obj_name) return FALSE;
+  if (!check_init()) return FALSE;
 
   if (g_hash_table_lookup (classTable, obj_name)) return TRUE;
 
   return FALSE;
 }
 
-const QofParam * 
+const QofParam *
 qof_class_get_parameter (QofIdTypeConst obj_name,
                           const char *parameter)
 {
@@ -122,6 +139,7 @@
 
   g_return_val_if_fail (obj_name, NULL);
   g_return_val_if_fail (parameter, NULL);
+  if (!check_init()) return NULL;
 
   ht = g_hash_table_lookup (classTable, obj_name);
   if (!ht)
@@ -133,7 +151,7 @@
   return (g_hash_table_lookup (ht, parameter));
 }
 
-QofAccessFunc 
+QofAccessFunc
 qof_class_get_parameter_getter (QofIdTypeConst obj_name,
                                  const char *parameter)
 {
@@ -149,7 +167,7 @@
   return NULL;
 }
 
-QofSetterFunc 
+QofSetterFunc
 qof_class_get_parameter_setter (QofIdTypeConst obj_name,
                                  const char *parameter)
 {
@@ -165,7 +183,7 @@
   return NULL;
 }
 
-QofType 
+QofType
 qof_class_get_parameter_type (QofIdTypeConst obj_name,
                                const char *param_name)
 {
@@ -179,13 +197,6 @@
   return (prm->param_type);
 }
 
-QofSortFunc 
-qof_class_get_default_sort (QofIdTypeConst obj_name)
-{
-  if (!obj_name) return NULL;
-  return g_hash_table_lookup (sortTable, obj_name);
-}
-
 /* ================================================================ */
 
 struct class_iterate {
@@ -193,12 +204,12 @@
   gpointer            data;
 };
 
-static void 
+static void
 class_foreach_cb (gpointer key, gpointer item, gpointer arg)
 {
   struct class_iterate *iter = arg;
   QofIdTypeConst id = key;
- 
+
   iter->fcn (id, iter->data);
 }
 
@@ -223,7 +234,7 @@
   gpointer            data;
 };
 
-static void 
+static void
 param_foreach_cb (gpointer key, gpointer item, gpointer arg)
 {
   struct parm_iterate *iter = arg;
@@ -262,18 +273,18 @@
 
 	b = (struct param_ref_list*)user_data;
 	if((param->param_getfcn == NULL)||(param->param_setfcn == NULL)) { return; }
-	if(0 == safe_strcmp(param->param_type, QOF_TYPE_STRING))   { return; }
-	if(0 == safe_strcmp(param->param_type, QOF_TYPE_NUMERIC))  { return; }
-	if(0 == safe_strcmp(param->param_type, QOF_TYPE_DATE))     { return; }
-	if(0 == safe_strcmp(param->param_type, QOF_TYPE_CHAR))     { return; }
-	if(0 == safe_strcmp(param->param_type, QOF_TYPE_DEBCRED))  { return; }
-	if(0 == safe_strcmp(param->param_type, QOF_TYPE_GUID))     { return; }
-	if(0 == safe_strcmp(param->param_type, QOF_TYPE_INT32))    { return; }
-	if(0 == safe_strcmp(param->param_type, QOF_TYPE_INT64))    { return; }
-	if(0 == safe_strcmp(param->param_type, QOF_TYPE_DOUBLE))   { return; }
-	if(0 == safe_strcmp(param->param_type, QOF_TYPE_KVP))      { return; }
-	if(0 == safe_strcmp(param->param_type, QOF_TYPE_BOOLEAN))  { return; }
-	if(0 == safe_strcmp(param->param_type, QOF_ID_BOOK))       { return; }
+	if(0 == safe_strcmp(param->param_type, QOF_TYPE_STRING)) { return; }
+	if(0 == safe_strcmp(param->param_type, QOF_TYPE_NUMERIC)) { return; }
+	if(0 == safe_strcmp(param->param_type, QOF_TYPE_DATE)) { return; }
+	if(0 == safe_strcmp(param->param_type, QOF_TYPE_CHAR)) { return; }
+	if(0 == safe_strcmp(param->param_type, QOF_TYPE_DEBCRED)) { return; }
+	if(0 == safe_strcmp(param->param_type, QOF_TYPE_GUID)) { return; }
+	if(0 == safe_strcmp(param->param_type, QOF_TYPE_INT32)) { return; }
+	if(0 == safe_strcmp(param->param_type, QOF_TYPE_INT64)) { return; }
+	if(0 == safe_strcmp(param->param_type, QOF_TYPE_DOUBLE)) { return; }
+	if(0 == safe_strcmp(param->param_type, QOF_TYPE_KVP)) { return; }
+	if(0 == safe_strcmp(param->param_type, QOF_TYPE_BOOLEAN)) { return; }
+	if(0 == safe_strcmp(param->param_type, QOF_ID_BOOK)) { return; }
 	b->list = g_list_append(b->list, param);
 }
 

Modified: gnucash/trunk/lib/libqof/qof/qofgobj.c
===================================================================
--- gnucash/trunk/lib/libqof/qof/qofgobj.c	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/qofgobj.c	2006-01-08 17:51:29 UTC (rev 12299)
@@ -121,7 +121,7 @@
   else
   if (G_IS_PARAM_SPEC_INT(gps))
   {
-    int ival;
+    long ival;
     
     GValue gval = {G_TYPE_INVALID};
     g_value_init (&gval, G_TYPE_INT);
@@ -133,7 +133,7 @@
   else
   if (G_IS_PARAM_SPEC_UINT(gps))
   {
-    int ival;
+    long ival;
     GValue gval = {G_TYPE_INVALID};
     g_value_init (&gval, G_TYPE_UINT);
     g_object_get_property (gob, getter->param_name, &gval);
@@ -144,14 +144,14 @@
   else
   if (G_IS_PARAM_SPEC_BOOLEAN(gps))
   {
-    int ival;
+    gboolean ival;
     
     GValue gval = {G_TYPE_INVALID};
     g_value_init (&gval, G_TYPE_BOOLEAN);
     g_object_get_property (gob, getter->param_name, &gval);
 
     ival = g_value_get_boolean (&gval);
-    return (gpointer) ival;
+    return GINT_TO_POINTER( ival);
   }
 
   PWARN ("unhandled parameter type %s for paramter %s", 
@@ -164,7 +164,7 @@
 {
   GObject *gob = data;
    double fval;
-
+   
   GParamSpec *gps = getter->param_userdata;
 
   /* Note that the return type must actually be of type

Modified: gnucash/trunk/lib/libqof/qof/qofgobj.h
===================================================================
--- gnucash/trunk/lib/libqof/qof/qofgobj.h	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/qofgobj.h	2006-01-08 17:51:29 UTC (rev 12299)
@@ -84,4 +84,3 @@
 #endif /* QOF_GOBJ_H */
 /** @} */
 /** @} */
-

Modified: gnucash/trunk/lib/libqof/qof/qofid-p.h
===================================================================
--- gnucash/trunk/lib/libqof/qof/qofid-p.h	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/qofid-p.h	2006-01-08 17:51:29 UTC (rev 12299)
@@ -23,7 +23,6 @@
 /** @addtogroup Object
     @{ */
 /** @addtogroup Object_Private
-    Private interfaces, not meant to be used by applications.
     @{ */
 /** @name  Entity_Private
     @{ */
@@ -35,10 +34,10 @@
 
 #include "qofid.h"
 
-/* This file defines an engine-only API for using gnucash entity
+/* This file defines an engine-only API for using QOF entity
  * identifiers. */
 
-/** Set the ID of the entity, over-riding teh previous ID. 
+/** Set the ID of the entity, over-riding the previous ID. 
  *  Very dangerous, use only for file i/o work. 
  */
 void qof_entity_set_guid (QofEntity *ent, const GUID *guid);

Modified: gnucash/trunk/lib/libqof/qof/qofid.c
===================================================================
--- gnucash/trunk/lib/libqof/qof/qofid.c	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/qofid.c	2006-01-08 17:51:29 UTC (rev 12299)
@@ -27,10 +27,8 @@
 #include <string.h>
 #include <glib.h>
 
-#include "qofid.h"
+#include "qof.h"
 #include "qofid-p.h"
-#include "gnc-trace.h"
-#include "gnc-engine-util.h"
 
 static QofLogModule log_module = QOF_MOD_ENGINE;
 
@@ -53,11 +51,11 @@
   g_return_if_fail (NULL != tab);
   
   /* XXX We passed redundant info to this routine ... but I think that's
-	* OK, it might eliminate programming errors. */
+   * OK, it might eliminate programming errors. */
   if (safe_strcmp(tab->e_type, type))
   {
     PERR ("attempt to insert \"%s\" into \"%s\"", type, tab->e_type);
-	 return;
+    return;
   }
   ent->e_type = CACHE_INSERT (type);
 
@@ -289,7 +287,7 @@
   QofEntity *ent;
   g_return_val_if_fail (col, NULL);
   if (guid == NULL) return NULL;
-  ent = g_hash_table_lookup (col->hash_of_entities, guid->data);
+  ent = g_hash_table_lookup (col->hash_of_entities, guid);
   return ent;
 }
 
@@ -326,22 +324,19 @@
 gboolean 
 qof_collection_is_dirty (QofCollection *col)
 {
-   if (!col) return FALSE;
-   return col->is_dirty;
+   return col ? col->is_dirty : FALSE;
 }
 
 void 
 qof_collection_mark_clean (QofCollection *col)
 {
-   if (!col) return;
-   col->is_dirty = FALSE;
+   if (col) { col->is_dirty = FALSE; }
 }
 
 void 
 qof_collection_mark_dirty (QofCollection *col)
 {
-   if (!col) return;
-   col->is_dirty = TRUE;
+   if (col) { col->is_dirty = TRUE; }
 }
 
 /* =============================================================== */
@@ -349,15 +344,13 @@
 gpointer 
 qof_collection_get_data (QofCollection *col)
 {
-   if (!col) return NULL;
-   return col->data;
+   return col ? col->data : NULL;
 }
 
 void 
 qof_collection_set_data (QofCollection *col, gpointer user_data)
 {
-   if (!col) return;
-   col->data = user_data;
+   if (col) { col->data = user_data; }
 }
 
 /* =============================================================== */
@@ -376,8 +369,8 @@
 }
 
 void
-qof_collection_foreach (QofCollection *col, 
-                   QofEntityForeachCB cb_func, gpointer user_data)
+qof_collection_foreach (QofCollection *col, QofEntityForeachCB cb_func, 
+                        gpointer user_data)
 {
   struct _iterate iter;
 

Modified: gnucash/trunk/lib/libqof/qof/qofid.h
===================================================================
--- gnucash/trunk/lib/libqof/qof/qofid.h	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/qofid.h	2006-01-08 17:51:29 UTC (rev 12299)
@@ -46,13 +46,18 @@
     Identifiers can be encoded as hex strings. 
    
     GUID Identifiers are 'typed' with strings.  The native ids used 
-    by QOF are defined below. An id with type QOF_ID_NONE does not 
-    refer to any entity, although that may change (???). An id with 
-    type QOF_ID_NULL does not refer to any entity, and will never refer
-    to any entity. An identifier with any other type may refer to an
-    actual entity, but that is not guaranteed (??? Huh?).  If an id 
-    does refer to an entity, the type of the entity will match the 
-    type of the identifier. 
+    by QOF are defined below.
+	-# An id with type QOF_ID_NONE does not 
+    refer to any entity.
+	-# An id with type QOF_ID_NULL does not refer
+	to any entity, and will never refer to any entity.
+	=# An identifier with any other type may refer to an
+    actual entity, but that is not guaranteed as that entity does
+	not have to exist within the current book. (See ::PARTIAL_QOFBOOK).
+	Also, creating a new entity from a data source involves creating
+	a temporary GUID and then setting the value from the data source.
+	If an id does refer to an entity, the type of the entity will match
+	the type of the identifier. 
 
     If you have a type name, and you want to have a way of finding
     a collection that is associated with that type, then you must use
@@ -105,9 +110,11 @@
 })
 
 /** return TRUE if object is of the given type */
-#define QOF_CHECK_TYPE(obj,type) (0 == QSTRCMP((type),(((QofEntity *)(obj))->e_type)))
+#define QOF_CHECK_TYPE(obj,type) (((obj) != NULL) && \
+  (0 == QSTRCMP((type),(((QofEntity *)(obj))->e_type))))
 
-/** cast object to the indicated type, print error message if its bad  */
+/** cast object to the indicated type,
+print error message if its bad  */
 #define QOF_CHECK_CAST(obj,e_type,c_type) (                   \
   QOF_CHECK_TYPE((obj),(e_type)) ?                            \
   (c_type *) (obj) :                                          \
@@ -138,7 +145,7 @@
 
 struct QofEntity_s
 {
-   QofIdType        e_type;
+	QofIdType        e_type;
 	GUID             guid;
 	QofCollection  * collection;
 };
@@ -178,8 +185,8 @@
 typedef void (*QofEntityForeachCB) (QofEntity *, gpointer user_data);
 
 /** Call the callback for each entity in the collection. */
-void qof_collection_foreach (QofCollection *, 
-                       QofEntityForeachCB, gpointer user_data);
+void qof_collection_foreach (QofCollection *, QofEntityForeachCB, 
+                             gpointer user_data);
 
 /** Store and retreive arbitrary object-defined data 
  *

Modified: gnucash/trunk/lib/libqof/qof/qofinstance-p.h
===================================================================
--- gnucash/trunk/lib/libqof/qof/qofinstance-p.h	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/qofinstance-p.h	2006-01-08 17:51:29 UTC (rev 12299)
@@ -26,20 +26,12 @@
  * Copyright (C) 2003 Linas Vepstas <linas at linas.org>
  */
 
-/** @addtogroup Object
-    @{ */
-/** @addtogroup Object_Private
-    Private interfaces, not meant to be used by applications.
-    @{ */
-/** @name  Instance_Private
-    @{ */
-
 #ifndef QOF_INSTANCE_P_H
 #define QOF_INSTANCE_P_H
 
 #include "qofinstance.h"
 
-/**
+/*
  * UNDER CONSTRUCTION!
  * This is mostly scaffolding for now,
  * eventually, it may hold more fields, such as refrence counting...
@@ -47,19 +39,19 @@
  */
 struct QofInstance_s
 {
-   /** Globally unique id identifying this instance */
+   /* Globally unique id identifying this instance */
    QofEntity entity;
 
-   /** The entity_table in which this instance is stored */
+   /* The entity_table in which this instance is stored */
    QofBook * book;
 
-  /** kvp_data is a key-value pair database for storing arbirtary
+  /* kvp_data is a key-value pair database for storing arbirtary
    * information associated with this instance.  
    * See src/engine/kvp_doc.txt for a list and description of the 
    * important keys. */
    KvpFrame *kvp_data;
 
-   /** Timestamp used to track the last modification to this 
+   /*  Timestamp used to track the last modification to this 
     *  instance.  Typically used to compare two versions of the
     *  same object, to see which is newer.  When used with the 
     *  SQL backend, this field is reserved for SQL use, to compare
@@ -67,31 +59,27 @@
     */
    Timespec last_update;
 
-   /** Keep track of nesting level of begin/end edit calls */
+   /*  Keep track of nesting level of begin/end edit calls */
    int    editlevel;
 
-   /** In process of being destroyed */
+   /*  In process of being destroyed */
    gboolean  do_free;
 
-   /** dirty/clean flag. If dirty, then this instance has been modified,
-    * but has not yet been written out to storage (file/database)
+   /*  dirty/clean flag. If dirty, then this instance has been modified,
+    *  but has not yet been written out to storage (file/database)
     */
    gboolean  dirty;
 };
 
-/** reset the dirty flag */
+/* reset the dirty flag */
 void qof_instance_mark_clean (QofInstance *);
 
 void qof_instance_set_slots (QofInstance *, KvpFrame *);
 
-/** Set the last_update time. Reserved for use by the SQL backend;
+/*  Set the last_update time. Reserved for use by the SQL backend;
  *  used for comparing version in local memory to that in remote 
  *  server. 
  */
 void qof_instance_set_last_update (QofInstance *inst, Timespec ts);
 
-/* @} */
-/* @} */
-/* @} */
-
 #endif /* QOF_INSTANCE_P_H */

Modified: gnucash/trunk/lib/libqof/qof/qofinstance.c
===================================================================
--- gnucash/trunk/lib/libqof/qof/qofinstance.c	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/qofinstance.c	2006-01-08 17:51:29 UTC (rev 12299)
@@ -23,18 +23,14 @@
 /*
  * Object instance holds many common fields that most
  * gnucash objects use.
- * 
+ *
  * Copyright (C) 2003 Linas Vepstas <linas at linas.org>
  */
 
-#include "gnc-trace.h"
-
+#include "qof.h"
 #include "kvp-util-p.h"
-#include "qofbook.h"
 #include "qofbook-p.h"
-#include "qofid.h"
 #include "qofid-p.h"
-#include "qofinstance.h"
 #include "qofinstance-p.h"
 
 static QofLogModule log_module = QOF_MOD_ENGINE;
@@ -51,7 +47,7 @@
 	return inst;
 }
 
-void 
+void
 qof_instance_init (QofInstance *inst, QofIdType type, QofBook *book)
 {
 	QofCollection *col;
@@ -68,7 +64,7 @@
 	qof_entity_init (&inst->entity, type, col);
 }
 
-void 
+void
 qof_instance_release (QofInstance *inst)
 {
 	kvp_frame_delete (inst->kvp_data);
@@ -85,14 +81,14 @@
 	return &inst->entity.guid;
 }
 
-QofBook * 
+QofBook *
 qof_instance_get_book (QofInstance *inst)
 {
 	if (!inst) return NULL;
 	return inst->book;
 }
 
-KvpFrame* 
+KvpFrame*
 qof_instance_get_slots (QofInstance *inst)
 {
   if (!inst) return NULL;
@@ -102,15 +98,15 @@
 Timespec
 qof_instance_get_last_update (QofInstance *inst)
 {
-	if (!inst) 
+	if (!inst)
 	{
-		Timespec ts = {0,-1}; 
+		Timespec ts = {0,-1};
 		return ts;
 	}
 	return inst->last_update;
 }
 
-int 
+int
 qof_instance_version_cmp (QofInstance *left, QofInstance *right)
 {
 	if (!left && !right) return 0;
@@ -174,7 +170,7 @@
   inst->dirty = FALSE;
 }
 
-void 
+void
 qof_instance_set_slots (QofInstance *inst, KvpFrame *frm)
 {
   if (!inst) return;

Copied: gnucash/trunk/lib/libqof/qof/qoflog.c (from rev 12298, gnucash/trunk/lib/libqof/qof/gnc-trace.c)
===================================================================
--- gnucash/trunk/lib/libqof/qof/gnc-trace.c	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/qoflog.c	2006-01-08 17:51:29 UTC (rev 12299)
@@ -0,0 +1,363 @@
+/* **************************************************************************
+ *            qoflog.c
+ *
+ *  Mon Nov 21 14:41:59 2005
+ *  Author: Rob Clark (rclark at cs.hmc.edu)                          *
+ *  Copyright (C) 1997-2003 Linas Vepstas <linas at linas.org>
+ *  Copyright  2005  Neil Williams
+ *  linux at codehelp.co.uk
+ *************************************************************************** */
+/*
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ *  02110-1301,  USA
+ */
+ 
+#include "config.h"
+
+#include <glib.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#else
+#warning unistd required.
+#endif
+#include <stdarg.h>
+#include <string.h>
+#include <sys/time.h>
+#include "qof.h"
+#include "qoflog.h"
+
+#define QOF_LOG_MAX_CHARS 50
+#define QOF_LOG_INDENT_WIDTH 4
+#define NUM_CLOCKS 10
+
+static FILE *fout = NULL;
+static gchar* filename = NULL;
+static gchar* function_buffer = NULL;
+static const int MAX_TRACE_FILENAME = 100;
+static GHashTable *log_table = NULL;
+static gint qof_log_num_spaces = 0;
+
+/* uses the enum_as_string macro.
+Lookups are done on the string. */
+AS_STRING_FUNC(QofLogLevel, LOG_LEVEL_LIST)
+
+FROM_STRING_FUNC(QofLogLevel, LOG_LEVEL_LIST)
+
+void
+qof_log_add_indent(void)
+{
+	qof_log_num_spaces += QOF_LOG_INDENT_WIDTH;
+}
+
+gint 
+qof_log_get_indent(void)
+{
+	return qof_log_num_spaces;
+}
+
+void
+qof_log_drop_indent(void)
+{
+	qof_log_num_spaces -= QOF_LOG_INDENT_WIDTH;
+	if(qof_log_num_spaces < 0)
+	{
+		qof_log_num_spaces = 0;
+	}
+}
+
+static void
+fh_printer (const gchar     *log_domain,
+            GLogLevelFlags  log_level,
+            const gchar     *message,
+            gpointer        user_data)
+{
+  FILE *fh = user_data;
+  fprintf (fh, "%*s%s\n", qof_log_num_spaces, "", message);
+  fflush(fh);
+}
+
+void 
+qof_log_init (void)
+{
+   if(!fout) /* allow qof_log_set_file */
+   {
+	   fout = fopen ("/tmp/qof.trace", "w");
+   }
+
+   if(!fout && (filename = (char *)g_malloc(MAX_TRACE_FILENAME))) {
+      snprintf(filename, MAX_TRACE_FILENAME-1, "/tmp/qof.trace.%d", 
+	       getpid());
+      fout = fopen (filename, "w");
+      g_free(filename);
+   }
+
+   if(!fout)
+      fout = stderr;
+
+   g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_MASK, fh_printer, fout);
+}
+
+void
+qof_log_set_level(QofLogModule log_module, QofLogLevel level)
+{
+	gchar* level_string;
+
+	if(!log_module || level == 0) { return; }
+	level_string = g_strdup(QofLogLevelasString(level));
+	if(!log_table)
+	{
+		log_table = g_hash_table_new(g_str_hash, g_str_equal);
+	}
+	g_hash_table_insert(log_table, (gpointer)log_module, level_string);
+}
+
+static void
+log_module_foreach(gpointer key, gpointer value, gpointer data)
+{
+	g_hash_table_insert(log_table, key, data);
+}
+
+void
+qof_log_set_level_global(QofLogLevel level)
+{
+	gchar* level_string;
+
+	if(!log_table || level == 0) { return; }
+	level_string = g_strdup(QofLogLevelasString(level));
+	g_hash_table_foreach(log_table, log_module_foreach, level_string);
+}
+
+void
+qof_log_set_file (FILE *outfile)
+{
+   if(!outfile) { fout = stderr; return; }
+   fout = outfile;
+}
+
+void
+qof_log_init_filename (const gchar* logfilename)
+{
+	if(!logfilename)
+	{
+		fout = stderr;
+	}
+	else
+	{
+		filename = g_strdup(logfilename);
+		fout = fopen(filename, "w");
+	}
+	qof_log_init();
+}
+
+void
+qof_log_shutdown (void)
+{
+	if(fout && fout != stderr) { fclose(fout); }
+	if(filename) { g_free(filename); }
+	if(function_buffer) { g_free(function_buffer); }
+	g_hash_table_destroy(log_table);
+}
+
+const char *
+qof_log_prettify (const char *name)
+{
+  char *p, *buffer;
+  gint length;
+
+  if (!name) { return ""; }
+  buffer = g_strndup(name, QOF_LOG_MAX_CHARS - 1);
+  length = strlen(buffer);
+  p = g_strstr_len(buffer, length, "(");
+  if (p)
+  {
+    *(p+1) = ')';
+    *(p+2) = 0x0;
+  }
+  else { strcpy (&buffer[QOF_LOG_MAX_CHARS - 4], "...()"); }
+  function_buffer = g_strdup(buffer);
+  g_free(buffer);
+  return function_buffer;
+}
+
+static
+struct timeval qof_clock[NUM_CLOCKS] = {
+   {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, 
+   {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, 
+};
+
+static
+struct timeval qof_clock_total[NUM_CLOCKS] = {
+   {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, 
+   {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, 
+};
+
+void
+qof_start_clock (int clockno, QofLogModule log_module, QofLogLevel log_level,
+                 const char *function_name, const char *format, ...)
+{
+  struct timezone tz;
+  va_list ap;
+
+  if ((0>clockno) || (NUM_CLOCKS <= clockno)) return;
+  gettimeofday (&qof_clock[clockno], &tz);
+
+  if (!fout) qof_log_init();
+
+  fprintf (fout, "Clock %d Start: %s: ",
+           clockno, qof_log_prettify (function_name));
+
+  va_start (ap, format);
+
+  vfprintf (fout, format, ap);
+
+  va_end (ap);
+
+  fprintf (fout, "\n");
+  fflush (fout);
+}
+
+void
+qof_report_clock (int clockno, QofLogModule log_module, QofLogLevel log_level,
+                  const char *function_name, const char *format, ...)
+{
+  struct timezone tz;
+  struct timeval now;
+  va_list ap;
+
+  if ((0>clockno) || (NUM_CLOCKS <= clockno)) return;
+  gettimeofday (&now, &tz);
+
+  /* need to borrow to make difference */
+  if (now.tv_usec < qof_clock[clockno].tv_usec)
+  {
+    now.tv_sec --;
+    now.tv_usec += 1000000;
+  }
+  now.tv_sec -= qof_clock[clockno].tv_sec;
+  now.tv_usec -= qof_clock[clockno].tv_usec;
+
+  qof_clock_total[clockno].tv_sec += now.tv_sec;
+  qof_clock_total[clockno].tv_usec += now.tv_usec;
+
+  if (!fout) qof_log_init();
+
+  fprintf (fout, "Clock %d Elapsed: %ld.%06lds %s: ",
+           clockno, (long int) now.tv_sec, (long int) now.tv_usec, 
+	       qof_log_prettify (function_name));
+
+  va_start (ap, format);
+
+  vfprintf (fout, format, ap);
+
+  va_end (ap);
+
+  fprintf (fout, "\n");
+  fflush (fout);
+}
+
+void
+qof_report_clock_total (int clockno,
+                        QofLogModule log_module, QofLogLevel log_level,
+                        const char *function_name, const char *format, ...)
+{
+  va_list ap;
+
+  if ((0>clockno) || (NUM_CLOCKS <= clockno)) return;
+
+  /* need to normalize usec */
+  while (qof_clock_total[clockno].tv_usec >= 1000000)
+  {
+    qof_clock_total[clockno].tv_sec ++;
+    qof_clock_total[clockno].tv_usec -= 1000000;
+  }
+
+  if (!fout) qof_log_init();
+
+  fprintf (fout, "Clock %d Total Elapsed: %ld.%06lds  %s: ",
+           clockno,
+           (long int) qof_clock_total[clockno].tv_sec,
+           (long int) qof_clock_total[clockno].tv_usec,
+           qof_log_prettify (function_name));
+
+  va_start (ap, format);
+
+  vfprintf (fout, format, ap);
+
+  va_end (ap);
+
+  fprintf (fout, "\n");
+  fflush (fout);
+}
+
+gboolean
+qof_log_check(QofLogModule log_module, QofLogLevel log_level)
+{
+	gchar* log_string;
+	QofLogLevel maximum; /* Any log_level less than this will be logged. */
+
+	log_string = NULL;
+	if(!log_table || log_module == NULL || log_level == 0) { return FALSE; }
+	log_string = (gchar*)g_hash_table_lookup(log_table, log_module);
+	/* if log_module not found, do not log. */
+	if(!log_string) { return FALSE; }
+	maximum = QofLogLevelfromString(log_string);
+	if(log_level <= maximum) { return TRUE; }
+	return FALSE;
+}
+
+void qof_log_set_default(QofLogLevel log_level)
+{
+	qof_log_set_level(QOF_MOD_BACKEND, log_level);
+	qof_log_set_level(QOF_MOD_CLASS,   log_level);
+	qof_log_set_level(QOF_MOD_ENGINE,  log_level);
+	qof_log_set_level(QOF_MOD_OBJECT,  log_level);
+	qof_log_set_level(QOF_MOD_KVP,     log_level);
+	qof_log_set_level(QOF_MOD_MERGE,   log_level);
+	qof_log_set_level(QOF_MOD_QUERY,   log_level);
+	qof_log_set_level(QOF_MOD_SESSION, log_level);
+}
+
+struct hash_s
+{
+	QofLogCB cb;
+	gpointer data;
+};
+
+static void hash_cb (gpointer key, gpointer value, gpointer data)
+{
+	struct hash_s *iter;
+
+	iter = (struct hash_s*)data;
+	if(!iter) { return; }
+	(iter->cb)(key, value, iter->data);
+}
+
+void qof_log_module_foreach(QofLogCB cb, gpointer data)
+{
+	struct hash_s iter;
+
+	if(!cb) { return; }
+	iter.cb = cb;
+	iter.data = data;
+	g_hash_table_foreach(log_table, hash_cb, (gpointer)&iter);
+}
+
+gint qof_log_module_count(void)
+{
+	if(!log_table) { return 0; }
+	return g_hash_table_size(log_table);
+}
+
+/* ************************ END OF FILE **************************** */

Copied: gnucash/trunk/lib/libqof/qof/qoflog.h (from rev 12298, gnucash/trunk/lib/libqof/qof/gnc-trace.h)
===================================================================
--- gnucash/trunk/lib/libqof/qof/gnc-trace.h	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/qoflog.h	2006-01-08 17:51:29 UTC (rev 12299)
@@ -0,0 +1,274 @@
+/***************************************************************************
+ *            qof-log.h
+ *
+ *  Mon Nov 21 14:35:26 2005
+ *  Author: Rob Clark (rclark at cs.hmc.edu)                          *
+ *  Copyright (C) 1998-2003 Linas Vepstas <linas at linas.org>
+ *  Copyright  2005  Neil Williams
+ *  linux at codehelp.co.uk
+ ****************************************************************************/
+/*
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ *  02110-1301,  USA
+ */
+
+/** @addtogroup Trace
+    @{ */
+
+/** @file qof-log.h 
+ *  @brief QOF error logging and tracing facility 
+*/
+
+#ifndef _QOF_LOG_H
+#define _QOF_LOG_H
+
+#include <glib.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include "gnc-engine-util.h"
+
+#define QOF_MOD_ENGINE "qof-engine"
+
+#define LOG_LEVEL_LIST(_) \
+  _(QOF_LOG_FATAL, = 0)   \
+  _(QOF_LOG_ERROR, = 1)   \
+  _(QOF_LOG_WARNING, = 2) \
+  _(QOF_LOG_INFO, = 3)    \
+  _(QOF_LOG_DEBUG, = 4)   \
+  _(QOF_LOG_DETAIL, = 5)  \
+  _(QOF_LOG_TRACE, = 6)
+
+DEFINE_ENUM (QofLogLevel, LOG_LEVEL_LIST)
+
+AS_STRING_DEC(QofLogLevel, LOG_LEVEL_LIST) /**< Convert QofLogLevel to a string.
+
+The macro correlates the enum value and an
+exact copy as a string, removing the need to
+keep two separate lists in sync.
+*/
+
+FROM_STRING_DEC(QofLogLevel, LOG_LEVEL_LIST) /**< Convert the 
+log_string to a QofLogLevel
+
+Only for use as a partner to ::QofLogLevelasString
+*/
+
+/** indents once for each ENTER macro */
+void qof_log_add_indent(void);
+
+/** gets the running total of the indent */
+gint qof_log_get_indent(void);
+
+/** drops back one indent for each LEAVE macro
+
+indent is reset to zero if less than a single indent would exist.
+*/
+void qof_log_drop_indent(void);
+
+/** Initialize the error logging subsystem
+
+\deprecated Applications need to call
+qof_log_set_file to set the output, otherwise
+the default of \a /tmp/qof.trace will be used.
+
+Instead, use qof_log_init_filename
+which sets the filename and initialises the
+logging subsystem in one operation.
+*/
+void qof_log_init (void);
+
+/** Set the logging level of the given log_module. */
+void qof_log_set_level(QofLogModule module, QofLogLevel level);
+
+/** Set the logging level for all known log_modules.
+
+\note Unless a log_module has been registered using
+qof_log_set_level, it will be unaffected by this change.
+
+*/
+void qof_log_set_level_global(QofLogLevel level);
+
+/** Specify an alternate log output, to pipe or file.
+By default, all logging goes to /tmp/qof.trace 
+ 
+Needs to be called \b before qof_log_init()
+\deprecated
+*/
+void qof_log_set_file (FILE *outfile);
+
+/** Specify a filename for log output.
+
+Calls qof_log_init() for you.
+*/
+void qof_log_init_filename (const gchar* logfilename);
+
+/** Be nice, close the logfile if possible. */
+void qof_log_shutdown (void);
+
+/** qof_log_prettify() cleans up subroutine names. AIX/xlC has the habit
+ * of printing signatures not names; clean this up. On other operating
+ * systems, truncate name to QOF_LOG_MAX_CHARS chars.  */
+const char * qof_log_prettify (const char *name);
+
+/** Do not log log_modules that have not been enabled. */
+gboolean qof_log_check(QofLogModule log_module, QofLogLevel log_level);
+
+/** Set the default QOF log_modules to the log level. */
+void qof_log_set_default(QofLogLevel log_level);
+
+typedef void (*QofLogCB) (QofLogModule log_module, QofLogLevel* log_level, 
+			gpointer user_data);
+
+/** Iterate over each known log_module
+
+Only log_modules with log_levels set will 
+be available.
+*/
+void qof_log_module_foreach(QofLogCB cb, gpointer data);
+
+/** Number of log_modules registered*/
+gint qof_log_module_count(void);
+
+#define FUNK qof_log_prettify(__FUNCTION__)
+
+/** Log error/warning/info messages to stderr or to a file.
+ *  This logging infrastructure is meant for validating the 
+ *  correctness of the execution of the code.  'Info' level 
+ *  messages help trace program flow. 'Error' messages are 
+ *  meant to indicate internal data inconsistencies.
+ * 
+ * Messages can be logged to stdout, stderr, or to any desired
+ * file.
+ */
+
+/** Log a fatal error */
+#define FATAL(format, args...) do {                  \
+    g_log (G_LOG_DOMAIN, G_LOG_LEVEL_ERROR,          \
+      "Fatal Error: %s(): " format, FUNK , ## args); \
+} while (0)
+
+/** Log a serious error */
+#define PERR(format, args...) do {                   \
+  if (qof_log_check (log_module, GNC_LOG_ERROR)) {   \
+    g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,       \
+      "Error: %s(): " format, FUNK , ## args);       \
+  }                                                  \
+} while (0)
+
+/** Log a warning */
+#define PWARN(format, args...) do {                    \
+  if (qof_log_check (log_module, GNC_LOG_WARNING)) {   \
+    g_log (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,          \
+      "Warning: %s(): " format, FUNK , ## args);       \
+  }                                                    \
+} while (0)
+
+/** Print an informational note */
+#define PINFO(format, args...) do {                 \
+  if (qof_log_check (log_module, GNC_LOG_INFO)) {   \
+    g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO,          \
+      "Info: %s(): " format,                        \
+      FUNK , ## args);                              \
+  }                                                 \
+} while (0)
+
+/** Print a debugging message */
+#define DEBUG(format, args...) do {                 \
+  if (qof_log_check (log_module, GNC_LOG_DEBUG)) {  \
+    g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG,         \
+      "Debug: %s(): " format,                       \
+      FUNK , ## args);                              \
+  }                                                 \
+} while (0)
+
+/** Print a function entry debugging message */
+#define ENTER(format, args...) do {                 \
+  if (qof_log_check (log_module, GNC_LOG_DEBUG)) {  \
+    g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG,         \
+      "Enter in %s: %s()" format, __FILE__,         \
+      FUNK , ## args);                              \
+    qof_log_add_indent();                           \
+  }                                                 \
+} while (0)
+
+/** Print a function exit debugging message */
+#define LEAVE(format, args...) do {                 \
+  if (qof_log_check (log_module, GNC_LOG_DEBUG)) {  \
+    qof_log_drop_indent();                          \
+    g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG,         \
+      "Leave: %s()" format,                         \
+      FUNK , ## args);                              \
+  }                                                 \
+} while (0)
+
+/** Print a function trace debugging message */
+#define TRACE(format, args...) do {                 \
+  if (qof_log_check (log_module, GNC_LOG_TRACE)) {  \
+    g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG,         \
+      "Trace: %s(): " format, FUNK , ## args);      \
+  }                                                 \
+} while (0)
+
+#define DEBUGCMD(x) do {                            \
+  if (qof_log_check (log_module, GNC_LOG_DEBUG)) {  \
+		(x);                                        \
+	}                                               \
+} while (0)
+
+/* -------------------------------------------------------- */
+/** Infrastructure to make timing measurements for critical pieces 
+ * of code. Used for only for performance tuning & debugging. 
+ */
+
+void qof_start_clock (int clockno, QofLogModule log_module, QofLogLevel log_level,
+                      const char *function_name, const char *format, ...);
+
+void qof_report_clock (int clockno,
+                       QofLogModule log_module,
+                       QofLogLevel log_level,
+                       const char *function_name,
+                       const char *format, ...);
+
+void qof_report_clock_total (int clockno,
+                             QofLogModule log_module,
+                             QofLogLevel log_level,
+                             const char *function_name,
+                             const char *format, ...);
+
+/** start a particular timer */
+#define START_CLOCK(clockno,format, args...) do {        \
+  if (qof_log_check (log_module, GNC_LOG_INFO))          \
+    qof_start_clock (clockno, log_module, GNC_LOG_INFO,  \
+             __FUNCTION__, format , ## args);            \
+} while (0)
+
+/** report elapsed time since last report on a particular timer */
+#define REPORT_CLOCK(clockno,format, args...) do {       \
+  if (qof_log_check (log_module, GNC_LOG_INFO))          \
+    qof_report_clock (clockno, log_module, GNC_LOG_INFO, \
+             __FUNCTION__, format , ## args);            \
+} while (0)
+
+/** report total elapsed time since timer started */
+#define REPORT_CLOCK_TOTAL(clockno,format, args...) do {       \
+  if (qof_log_check (log_module, GNC_LOG_INFO))                \
+    qof_report_clock_total (clockno, log_module, GNC_LOG_INFO, \
+             __FUNCTION__, format , ## args);                  \
+} while (0)
+
+
+#endif /* _QOF_LOG_H */
+
+/** @} */

Modified: gnucash/trunk/lib/libqof/qof/qofobject-p.h
===================================================================
--- gnucash/trunk/lib/libqof/qof/qofobject-p.h	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/qofobject-p.h	2006-01-08 17:51:29 UTC (rev 12299)
@@ -43,6 +43,18 @@
 gboolean qof_object_is_dirty (QofBook *book);
 void qof_object_mark_clean (QofBook *book);
 
+/** \brief check an object can be created and supports iteration
+
+\param type_name object to check
+\param warn If called only once per operation, pass TRUE to log objects
+that fail the compliance check. To prevent repeated log messages when
+calling more than once, pass FALSE.
+
+\return TRUE if object can be created and supports iteration, else FALSE.
+*/
+gboolean 
+qof_object_compliance (QofIdTypeConst type_name, gboolean warn);
+
 #endif /* QOF_OBJECT_P_H_ */
 /** @} */
 /** @} */

Modified: gnucash/trunk/lib/libqof/qof/qofobject.c
===================================================================
--- gnucash/trunk/lib/libqof/qof/qofobject.c	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/qofobject.c	2006-01-08 17:51:29 UTC (rev 12299)
@@ -28,11 +28,8 @@
 
 #include <glib.h>
 
-#include "gnc-trace.h"
-#include "gnc-engine-util.h"
-#include "qofobject.h"
+#include "qof.h"
 #include "qofobject-p.h"
-#include "qofbook.h"
 
 static QofLogModule log_module = QOF_MOD_OBJECT;
 
@@ -140,6 +137,23 @@
   }
 }
 
+gboolean 
+qof_object_compliance (QofIdTypeConst type_name, gboolean warn)
+{
+	const QofObject *obj;
+
+	obj = qof_object_lookup(type_name);
+	if((obj->create == NULL)||(obj->foreach == NULL)){
+		if(warn) 
+		{
+			PINFO (" Object type %s is not fully QOF compliant", obj->e_type);
+		}
+		return FALSE;
+	}
+	return TRUE;
+}
+
+
 void 
 qof_object_foreach (QofIdTypeConst type_name, QofBook *book, 
                     QofEntityForeachCB cb, gpointer user_data)
@@ -147,8 +161,8 @@
   QofCollection *col;
   const QofObject *obj;
 
-  if (!book || !type_name) return;
-  ENTER ("type=%s", type_name);
+  if (!book || !type_name) { return; }
+  PINFO ("type=%s", type_name);
 
   obj = qof_object_lookup (type_name);
   if (!obj)
@@ -157,16 +171,11 @@
     return;
   }
   col = qof_book_get_collection (book, obj->e_type);
-  PINFO ("lookup obj=%p for type=%s", obj, type_name);
-  if (!obj) return;
-
-  PINFO ("type=%s foreach=%p", type_name, obj->foreach);
+  if (!obj) { return; }
   if (obj->foreach) 
   {
     obj->foreach (col, cb, user_data);
   }
-  LEAVE ("type=%s", type_name);
-
   return;
 }
 

Modified: gnucash/trunk/lib/libqof/qof/qofquery-deserial.c
===================================================================
--- gnucash/trunk/lib/libqof/qof/qofquery-deserial.c	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/qofquery-deserial.c	2006-01-08 17:51:29 UTC (rev 12299)
@@ -23,6 +23,9 @@
 
 // #include "config.h"
 
+/* NOTE: Development of this idea has ceased and this file is
+no longer included in the QOF library. It remains in CVS for now.*/
+
 #include <stdlib.h>
 #include <glib.h>
 #include <libxml/parser.h>
@@ -371,7 +374,7 @@
 	xmlNodePtr node;
 	QofQueryCompare how;
 	QofNumericMatch sm;
-   gnc_numeric num;
+	gnc_numeric num;
 	xmlNodePtr xp;
 	
 	xp = root->xmlChildrenNode;
@@ -478,7 +481,6 @@
 		if (0 == strcmp (node->name, "qofquery:param"))
 		{
 			const char *str = GET_TEXT (node);
-                        /* BUG? I can't find the matching cache removal. */
 			plist = g_slist_append (plist, CACHE_INSERT(str));
 		}
 	}
@@ -631,15 +633,15 @@
 	xmlChar *version;
 	xmlNodePtr qpart;
 	xmlNodePtr node;
-
+	
 	if (!root) return NULL;
-
+	
 	version = xmlGetProp(root, "version");
-   if (!root->name || strcmp ("qof:qofquery", root->name))
-   {
+    if (!root->name || strcmp ("qof:qofquery", root->name))
+    {
 		// XXX something is wrong. warn ... 
       return NULL;
-   }
+    }
 
 	q = qof_query_create ();
 

Modified: gnucash/trunk/lib/libqof/qof/qofquery-deserial.h
===================================================================
--- gnucash/trunk/lib/libqof/qof/qofquery-deserial.h	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/qofquery-deserial.h	2006-01-08 17:51:29 UTC (rev 12299)
@@ -40,6 +40,9 @@
     Unfinished. XXX Why is this easier than reading a text/sql
     file? 
 
+NOTE: Development of this idea has ceased and this file is
+no longer included in the QOF library. It remains in CVS for now.
+
  */
 /* Given an XML tree, reconstruct and return the equivalent query. */
 QofQuery *qof_query_from_xml (xmlNodePtr);

Modified: gnucash/trunk/lib/libqof/qof/qofquery-serialize.c
===================================================================
--- gnucash/trunk/lib/libqof/qof/qofquery-serialize.c	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/qofquery-serialize.c	2006-01-08 17:51:29 UTC (rev 12299)
@@ -28,6 +28,9 @@
 #include "qofquerycore-p.h"
 #include "kvp_frame.h"
 
+/* NOTE: Development of this idea has ceased and this file is
+no longer included in the QOF library. It remains in CVS for now.*/
+
 /* ======================================================= */
 
 #define PUT_STR(TOK,VAL) {                           \
@@ -221,7 +224,7 @@
 	query_double_t pdata_db;
 	query_boolean_t pdata_bool;
 	query_char_t pdata_c;
-
+	
 	if (!safe_strcmp (pd->type_name, QOF_TYPE_GUID))
 	{
 		topnode = xmlNewNode (NULL, "qofquery:pred-guid");
@@ -425,7 +428,7 @@
 	xmlNodePtr terms;
 	GList *n;
 	xmlNodePtr andt;
-
+	
 	terms = NULL;
 	n = qof_query_get_terms (q);
 	if (!n) return NULL;
@@ -543,7 +546,7 @@
 	xmlChar *xbuf;
 	int bufsz;
 	xmlOutputBufferPtr xbuf;
-
+	
 	qof_query_init();
 	qof_object_initialize ();
 

Modified: gnucash/trunk/lib/libqof/qof/qofquery-serialize.h
===================================================================
--- gnucash/trunk/lib/libqof/qof/qofquery-serialize.h	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/qofquery-serialize.h	2006-01-08 17:51:29 UTC (rev 12299)
@@ -25,6 +25,9 @@
    Copyright (C) 2001,2002,2004 Linas Vepstas <linas at linas.org>
  */
 
+/* NOTE: Development of this idea has ceased and this file is
+no longer included in the QOF library. It remains in CVS for now.*/
+
 #ifndef QOF_QUERY_SERIALIZE_H
 #define QOF_QUERY_SERIALIZE_H
 

Modified: gnucash/trunk/lib/libqof/qof/qofquery.c
===================================================================
--- gnucash/trunk/lib/libqof/qof/qofquery.c	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/qofquery.c	2006-01-08 17:51:29 UTC (rev 12299)
@@ -29,18 +29,11 @@
 #include <regex.h>
 #include <string.h>
 
-#include "gnc-trace.h"
-#include "gnc-engine-util.h"
-
+#include "qof.h"
 #include "qofbackend-p.h"
-#include "qofbook.h"
 #include "qofbook-p.h"
-#include "qofclass.h"
 #include "qofclass-p.h"
-#include "qofobject.h"
-#include "qofquery.h"
 #include "qofquery-p.h"
-#include "qofquerycore.h"
 #include "qofquerycore-p.h"
 
 static QofLogModule log_module = QOF_MOD_QUERY;
@@ -370,9 +363,6 @@
   QofQueryTerm * qt;
   int       and_terms_ok=1;
   
-  ENTER (" object=%p terms=%p name=%s", 
-          object, q->terms, qof_object_printable (q->search_for, object));
-
   for(or_ptr = q->terms; or_ptr; or_ptr = or_ptr->next) 
   {
     and_terms_ok = 1;
@@ -407,11 +397,7 @@
         /* XXX: Don't know how to do this conversion -- do we care? */
       }
     }
-    if (and_terms_ok) 
-    {
-      LEAVE (" (terms are OK)");
-      return 1;
-    }
+    if (and_terms_ok) { return 1; }
   }
 
   /* If there are no terms, assume a "match any" applies.
@@ -419,7 +405,6 @@
    * may want to get all objects, but in a particular sorted 
    * order.
    */
-  LEAVE (" ");
   if (NULL == q->terms) return 1;
   return 0;
 }
@@ -950,7 +935,7 @@
   return copy;
 }
 
-/********************************************************************
+/* *******************************************************************
  * qof_query_invert 
  * return a newly-allocated Query object which is the 
  * logical inverse of the original.
@@ -1033,7 +1018,7 @@
   return retval;
 }
 
-/********************************************************************
+/* *******************************************************************
  * qof_query_merge
  * combine 2 Query objects by the logical operation in "op".
  ********************************************************************/
@@ -1273,6 +1258,7 @@
   ENTER (" ");
   qof_query_core_init ();
   qof_class_init ();
+  LEAVE ("Completed initialization of QofQuery");
 }
 
 void qof_query_shutdown (void)
@@ -1414,12 +1400,8 @@
   return TRUE;
 }
 
-/***************************************************************************/
-/***************************************************************************/
-/* Query Print functions.  qof_query_print is public; everthing else supports
- * that.
- * Just call qof_query_print(QofQuery *q), and it will print out the query 
- * contents to stderr.
+/* **************************************************************************/
+/* Query Print functions for use with qof_log_set_level.
 */
 
 /* Static prototypes */
@@ -1434,14 +1416,18 @@
 static gchar *qof_query_printNumericMatch (QofNumericMatch n);
 static gchar *qof_query_printGuidMatch (QofGuidMatch g);
 static gchar *qof_query_printCharMatch (QofCharMatch c);
-static GString *qof_query_printPredData (QofQueryPredData *pd);
+static GList *qof_query_printPredData (QofQueryPredData *pd, GList *lst);
 static GString *qof_query_printParamPath (GSList * parmList);
 static void qof_query_printValueForParam (QofQueryPredData *pd, GString * gs);
 static void qof_query_printOutput (GList * output);
 
-/*
-        This function cycles through a QofQuery object, and
-        prints out the values of the various members of the query
+/** \deprecated access via qof_log instead.
+ The query will be logged automatically if qof_log_set_default
+ or qof_log_set_level(QOF_MOD_QUERY, ...) are set to QOF_LOG_DEBUG
+ or higher.
+
+ This function cycles through a QofQuery object, and
+ prints out the values of the various members of the query
 */
 void
 qof_query_print (QofQuery * query)
@@ -1489,7 +1475,7 @@
   {
     GString *line = (GString *) lst->data;
 
-    fprintf (stderr, "%s\n", line->str);
+    DEBUG (" %s", line->str);
     g_string_free (line, TRUE);
     line = NULL;
   }
@@ -1511,7 +1497,7 @@
   output = g_list_append (output, gs);
 
   return output;
-}                               /* qof_query_printSearchFor */
+}       /* qof_query_printSearchFor */
 
 /*
         Run through the terms of the query.  This is a outer-inner
@@ -1542,7 +1528,7 @@
   }
 
   return output;
-}                               /* qof_query_printTerms */
+}       /* qof_query_printTerms */
 
 /*
         Process the sort parameters
@@ -1554,7 +1540,7 @@
 {
   GSList *gsl, *n = NULL;
   gint curSort;
-  GString *gs = g_string_new ("  Sort Parameters:\n");
+  GString *gs = g_string_new ("Sort Parameters:   ");
 
   for (curSort = 0; curSort < numSorts; curSort++)
   {
@@ -1566,24 +1552,24 @@
     increasing = qof_query_sort_get_increasing (s[curSort]);
 
     gsl = qof_query_sort_get_param_path (s[curSort]); 
-    if (gsl) g_string_append_printf (gs, "    Param: ");
+    if (gsl) g_string_append_printf (gs, " Param: ");
     for (n=gsl; n; n = n->next)
     {
       QofIdType param_name = n->data;
-      if (gsl != n)g_string_append_printf (gs, "\n           ");
+      if (gsl != n) g_string_append_printf (gs, " ");
       g_string_append_printf (gs, "%s", param_name);
     }
     if (gsl) 
     {
-      g_string_append_printf (gs, " %s\n", increasing ? "DESC" : "ASC");
-      g_string_append_printf (gs, "    Options: 0x%x\n", s[curSort]->options);
+      g_string_append_printf (gs, " %s ", increasing ? "DESC" : "ASC");
+      g_string_append_printf (gs, " Options: 0x%x ", s[curSort]->options);
     }
   }
 
   output = g_list_append (output, gs);
   return output;
 
-}                               /* qof_query_printSorts */
+}      /* qof_query_printSorts */
 
 /*
         Process the AND terms of the query.  This is a GList
@@ -1592,7 +1578,7 @@
 static GList *
 qof_query_printAndTerms (GList * terms, GList * output)
 {
-  const char *prefix = "  AND Terms:";
+  const char *prefix = "AND Terms:";
   QofQueryTerm *qt;
   QofQueryPredData *pd;
   GSList *path;
@@ -1608,14 +1594,14 @@
     invert = qof_query_term_is_inverted (qt);
 
     if (invert) output = g_list_append (output, 
-                                        g_string_new("    INVERT SENSE "));
+                                     g_string_new(" INVERT SENSE "));
     output = g_list_append (output, qof_query_printParamPath (path));
-    output = g_list_append (output, qof_query_printPredData (pd));
-    output = g_list_append (output, g_string_new("\n"));
+    output = qof_query_printPredData (pd, output);
+//    output = g_list_append (output, g_string_new(" "));
   }
 
   return output;
-}                               /* qof_query_printAndTerms */
+}        /* qof_query_printAndTerms */
 
 /*
         Process the parameter types of the predicate data
@@ -1624,8 +1610,8 @@
 qof_query_printParamPath (GSList * parmList)
 {
   GSList *list = NULL;
-  GString *gs = g_string_new ("    Param List:\n");
-  g_string_append (gs, "      ");
+  GString *gs = g_string_new ("Param List: ");
+  g_string_append (gs, " ");
   for (list = parmList; list; list = list->next)
   {
     g_string_append (gs, (gchar *) list->data);
@@ -1634,32 +1620,33 @@
   }
 
   return gs;
-}                               /* qof_query_printParamPath */
+}        /* qof_query_printParamPath */
 
 /*
         Process the PredData of the AND terms
 */
-static GString *
-qof_query_printPredData (QofQueryPredData *pd)
+static GList *
+qof_query_printPredData (QofQueryPredData *pd, GList *lst)
 {
   GString *gs;
 
-  gs = g_string_new ("    Pred Data:\n      ");
+  gs = g_string_new ("Pred Data: ");
   g_string_append (gs, (gchar *) pd->type_name);
 
   /* Char Predicate and GUID predicate don't use the 'how' field. */
   if (safe_strcmp (pd->type_name, QOF_TYPE_CHAR) &&
       safe_strcmp (pd->type_name, QOF_TYPE_GUID))
   {
-    g_string_append_printf (gs, "\n      how: %s",
-                            qof_query_printStringForHow (pd->how));
+    g_string_append_printf (gs, " how: %s",
+                       qof_query_printStringForHow (pd->how));
   }
-
+  lst = g_list_append(lst, gs);
+  gs = g_string_new ("");
   qof_query_printValueForParam (pd, gs);
+  lst = g_list_append(lst, gs);
+  return lst;
+} /* qof_query_printPredData */
 
-  return gs;
-}                               /* qof_query_printPredData */
-
 /*
         Get a string representation for the
         QofCompareFunc enum type.
@@ -1685,7 +1672,7 @@
   }
 
   return "INVALID HOW";
-}                               /* qncQueryPrintStringForHow */
+}         /* qncQueryPrintStringForHow */
 
 
 static void
@@ -1696,47 +1683,46 @@
   {
     GList *node;
     query_guid_t pdata = (query_guid_t) pd;
-    g_string_append_printf (gs, "\n      Match type %s",
-                            qof_query_printGuidMatch (pdata->options));
+    g_string_append_printf (gs, "Match type %s",
+                       qof_query_printGuidMatch (pdata->options));
     for (node = pdata->guids; node; node = node->next)
     {
-        /* THREAD-UNSAFE */
+	  /* THREAD-UNSAFE */
       g_string_append_printf (gs, ", guids: %s",
-                              guid_to_string ((GUID *) node->data));
+			 guid_to_string ((GUID *) node->data));
     }
     return;
   }
   if (!safe_strcmp (pd->type_name, QOF_TYPE_STRING))
   {
     query_string_t pdata = (query_string_t) pd;
-    g_string_append_printf (gs, "\n      Match type %s",
-                            qof_query_printStringMatch (pdata->options));
+    g_string_append_printf (gs, " Match type %s",
+                       qof_query_printStringMatch (pdata->options));
     g_string_append_printf (gs, " %s string: %s",
-                            pdata->is_regex ? "Regex" : "Not regex",
-                            pdata->matchstring);
+                       pdata->is_regex ? "Regex" : "Not regex",
+                       pdata->matchstring);
     return;
   }
   if (!safe_strcmp (pd->type_name, QOF_TYPE_NUMERIC))
   {
     query_numeric_t pdata = (query_numeric_t) pd;
-    g_string_append_printf (gs, "\n      Match type %s",
-                            qof_query_printNumericMatch (pdata->options));
+    g_string_append_printf (gs, " Match type %s",
+                       qof_query_printNumericMatch (pdata->options));
     g_string_append_printf (gs, " gnc_numeric: %s",
-                            gnc_num_dbg_to_string (pdata->amount));
+                       gnc_num_dbg_to_string (pdata->amount));
     return;
   }
   if (!safe_strcmp (pd->type_name, QOF_TYPE_KVP))
   {
     GSList *node;
     query_kvp_t pdata = (query_kvp_t) pd;
-    g_string_append_printf (gs, "\n      kvp path: ");
+    g_string_append_printf (gs, " kvp path: ");
     for (node = pdata->path; node; node = node->next)
     {
       g_string_append_printf (gs, "/%s", (gchar *) node->data);
     }
-    g_string_append_printf (gs, "\n");
-    g_string_append_printf (gs, "      kvp value: %s\n", 
-                            kvp_value_to_string (pdata->value));
+    g_string_append_printf (gs, " kvp value: %s ", 
+                         kvp_value_to_string (pdata->value));
     return;
   }
   if (!safe_strcmp (pd->type_name, QOF_TYPE_INT64))
@@ -1760,16 +1746,16 @@
   if (!safe_strcmp (pd->type_name, QOF_TYPE_DATE))
   {
     query_date_t pdata = (query_date_t) pd;
-    g_string_append_printf (gs, "\n      Match type %s",
-                            qof_query_printDateMatch (pdata->options));
+    g_string_append_printf (gs, " Match type %s",
+                       qof_query_printDateMatch (pdata->options));
     g_string_append_printf (gs, " query_date: %s", gnc_print_date (pdata->date));
     return;
   }
   if (!safe_strcmp (pd->type_name, QOF_TYPE_CHAR))
   {
     query_char_t pdata = (query_char_t) pd;
-    g_string_append_printf (gs, "\n      Match type %s",
-                            qof_query_printCharMatch (pdata->options));
+    g_string_append_printf (gs, " Match type %s",
+                       qof_query_printCharMatch (pdata->options));
     g_string_append_printf (gs, " char list: %s", pdata->char_list);
     return;
   }
@@ -1781,7 +1767,7 @@
   }
   /** \todo QOF_TYPE_COLLECT */
   return;
-}                               /* qof_query_printValueForParam */
+}        /* qof_query_printValueForParam */
 
 /*
  * Print out a string representation of the
@@ -1798,7 +1784,7 @@
       return "QOF_STRING_MATCH_CASEINSENSITIVE";
   }
   return "UNKNOWN MATCH TYPE";
-}                               /* qof_query_printStringMatch */
+}           /* qof_query_printStringMatch */
 
 /*
  * Print out a string representation of the
@@ -1815,7 +1801,7 @@
       return "QOF_DATE_MATCH_DAY";
   }
   return "UNKNOWN MATCH TYPE";
-}                               /* qof_query_printDateMatch */
+}            /* qof_query_printDateMatch */
 
 /*
  * Print out a string representation of the
@@ -1834,7 +1820,7 @@
       return "QOF_NUMERIC_MATCH_ANY";
   }
   return "UNKNOWN MATCH TYPE";
-}                               /* qof_query_printNumericMatch */
+}        /* qof_query_printNumericMatch */
 
 /*
  * Print out a string representation of the
@@ -1858,7 +1844,7 @@
   }
 
   return "UNKNOWN MATCH TYPE";
-}                               /* qof_query_printGuidMatch */
+}         /* qof_query_printGuidMatch */
 
 /*
  * Print out a string representation of the
@@ -1875,6 +1861,6 @@
       return "QOF_CHAR_MATCH_NONE";
   }
   return "UNKNOWN MATCH TYPE";
-}                               /* qof_query_printGuidMatch */
+}         /* qof_query_printGuidMatch */
 
 /* ======================== END OF FILE =================== */

Modified: gnucash/trunk/lib/libqof/qof/qofquery.h
===================================================================
--- gnucash/trunk/lib/libqof/qof/qofquery.h	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/qofquery.h	2006-01-08 17:51:29 UTC (rev 12299)
@@ -63,13 +63,6 @@
 times per split for complex queries.  This is a place where we could
 probably optimize.
 
-Evaluation of a Query (see qof_query_run()) is optimized as much as
-possible by short-circuited evaluation.  The predicates in each
-AND-chain are sorted by predicate type, with Account queries sorted
-first to allow the evaluator to completely eliminate accounts from the
-search if there's no chance of them having splits that match.
-(XXX above no longer applies)
-
  @{ */
 /** @file qofquery.h
     @brief find objects that match a certain expression.
@@ -78,7 +71,6 @@
 
 */
 
-
 #ifndef QOF_QUERYNEW_H
 #define QOF_QUERYNEW_H
 
@@ -101,7 +93,7 @@
   QOF_QUERY_XOR
 } QofQueryOp;
 
-/* First/only term is same as 'and' */
+/** First/only term is same as 'and' */
 #define QOF_QUERY_FIRST_TERM QOF_QUERY_AND
 
 /** Default sort object type */
@@ -151,16 +143,14 @@
 void qof_query_destroy (QofQuery *q);
 
 /** Set the object type to be searched for.  The results of 
- *  performuing the query will be a list of this obj_type.
+ *  performing the query will be a list of this obj_type.
  */
 void qof_query_search_for (QofQuery *query, QofIdTypeConst obj_type);
 
-/** Set the book to be searched.  Books contain/identify collections
+/** Set the book to be searched.  Books contain/identify collections 
  *  of objects; the search will be performed over those books
- *  specified with this function.  If no books are set, no results
- *  will be returned (since there is nothing to search over). (CAS:
- *  Apparently, if no books are set, you'll actually get a critical
- *  assertion failure.)
+ *  specified with this function.  If no books are set, no results 
+ *  will be returned (since there is nothing to search over).
  *
  *  You can search multiple books.  To specify multiple books, call 
  *  this function multiple times with different arguments.  
@@ -359,8 +349,11 @@
  */
 gboolean qof_query_equal (QofQuery *q1, QofQuery *q2);
 
-/** Print the Query in human-readable format.
- * Useful for debugging and development.
+/** Log the Query 
+ *
+ * \deprecated Do not call directly, use the standard log
+ * module code: ::qof_log_set_level(QOF_MOD_QUERY, QOF_LOG_DEBUG);
+ * or ::qof_log_set_default(QOF_LOG_DEBUG);
  */
 void qof_query_print (QofQuery *query);
 

Modified: gnucash/trunk/lib/libqof/qof/qofquerycore.c
===================================================================
--- gnucash/trunk/lib/libqof/qof/qofquerycore.c	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/qofquerycore.c	2006-01-08 17:51:29 UTC (rev 12299)
@@ -25,10 +25,7 @@
 
 #include <glib.h>
 
-#include "gnc-trace.h"
-#include "gnc-engine-util.h"
-#include "qofquery.h"
-#include "qofquerycore.h"
+#include "qof.h"
 #include "qofquerycore-p.h"
 
 static QofLogModule log_module = QOF_MOD_QUERY;
@@ -39,7 +36,7 @@
 /* A function to copy a query's predicate data */
 typedef QofQueryPredData *(*QueryPredicateCopyFunc) (QofQueryPredData *pdata);
 
-/* A function to take the object, apply the getter->param_getfcn, 
+/* A function to take the object, apply the getter->param_getfcn,
  * and return a printable string.  Note that this QofParam->getfnc
  * function should be returning a type equal to this core object type.
  *
@@ -48,7 +45,7 @@
 typedef char * (*QueryToString) (gpointer object, QofParam *getter);
 
 /* A function to test for equality of predicate data */
-typedef gboolean (*QueryPredicateEqual) (QofQueryPredData *p1, 
+typedef gboolean (*QueryPredicateEqual) (QofQueryPredData *p1,
                                          QofQueryPredData *p2);
 
 static QueryPredicateCopyFunc qof_query_copy_predicate (QofType type);
@@ -124,13 +121,13 @@
                                 PREDICATE_ERROR); \
 }
 
-/********************************************************************/
+/* *******************************************************************/
 /* TYPE-HANDLING FUNCTIONS */
 
 /* QOF_TYPE_STRING */
 
-static int 
-string_match_predicate (gpointer object, 
+static int
+string_match_predicate (gpointer object,
                         QofParam *getter,
                         QofQueryPredData *pd)
 {
@@ -169,7 +166,7 @@
   }
 }
 
-static int 
+static int
 string_compare_func (gpointer a, gpointer b, gint options,
                      QofParam *getter)
 {
@@ -185,7 +182,7 @@
   return safe_strcmp (s1, s2);
 }
 
-static void 
+static void
 string_free_pdata (QofQueryPredData *pd)
 {
   query_string_t pdata = (query_string_t) pd;
@@ -207,12 +204,12 @@
 
   VERIFY_PDATA_R (query_string_type);
 
-  return qof_query_string_predicate (pd->how, pdata->matchstring, 
+  return qof_query_string_predicate (pd->how, pdata->matchstring,
                                      pdata->options,
                                      pdata->is_regex);
 }
 
-static gboolean 
+static gboolean
 string_predicate_equal (QofQueryPredData *p1, QofQueryPredData *p2)
 {
   query_string_t pd1 = (query_string_t) p1;
@@ -252,7 +249,7 @@
   return ((QofQueryPredData*)pdata);
 }
 
-static char * 
+static char *
 string_to_string (gpointer object, QofParam *getter)
 {
   const char *res;
@@ -264,7 +261,7 @@
 
 /* QOF_TYPE_DATE =================================================== */
 
-static int 
+static int
 date_compare (Timespec ta, Timespec tb, QofDateMatch options)
 {
 
@@ -286,7 +283,7 @@
   return 0;
 }
 
-static int 
+static int
 date_match_predicate (gpointer object, QofParam *getter,
                                  QofQueryPredData *pd)
 {
@@ -318,7 +315,7 @@
   }
 }
 
-static int 
+static int
 date_compare_func (gpointer a, gpointer b, gint options, QofParam *getter)
 {
   Timespec ta, tb;
@@ -331,7 +328,7 @@
   return date_compare (ta, tb, options);
 }
 
-static void 
+static void
 date_free_pdata (QofQueryPredData *pd)
 {
   query_date_t pdata = (query_date_t)pd;
@@ -351,7 +348,7 @@
   return qof_query_date_predicate (pd->how, pdata->options, pdata->date);
 }
 
-static gboolean 
+static gboolean
 date_predicate_equal (QofQueryPredData *p1, QofQueryPredData *p2)
 {
   query_date_t pd1 = (query_date_t) p1;
@@ -386,7 +383,7 @@
   return TRUE;
 }
 
-static char * 
+static char *
 date_to_string (gpointer object, QofParam *getter)
 {
   Timespec ts = ((query_date_getter)getter->param_getfcn)(object, getter);
@@ -399,7 +396,7 @@
 
 /* QOF_TYPE_NUMERIC ================================================= */
 
-static int 
+static int
 numeric_match_predicate (gpointer object, QofParam *getter,
                          QofQueryPredData* pd)
 {
@@ -422,7 +419,7 @@
     break;
   }
 
-  /* Amounts are considered to be 'equal' if they match to 
+  /* Amounts are considered to be 'equal' if they match to
    * four decimal places. (epsilon=1/10000) */
   if (pd->how == QOF_COMPARE_EQUAL || pd->how == QOF_COMPARE_NEQ) {
     gnc_numeric cmp_val = gnc_numeric_create (1, 10000);
@@ -454,7 +451,7 @@
   }
 }
 
-static int 
+static int
 numeric_compare_func (gpointer a, gpointer b, gint options, QofParam *getter)
 {
   gnc_numeric va, vb;
@@ -464,10 +461,10 @@
   va = ((query_numeric_getter)getter->param_getfcn) (a, getter);
   vb = ((query_numeric_getter)getter->param_getfcn) (b, getter);
 
-  return gnc_numeric_compare (va, vb);  
+  return gnc_numeric_compare (va, vb);
 }
 
-static void 
+static void
 numeric_free_pdata (QofQueryPredData* pd)
 {
   query_numeric_t pdata = (query_numeric_t)pd;
@@ -483,7 +480,7 @@
   return qof_query_numeric_predicate (pd->how, pdata->options, pdata->amount);
 }
 
-static gboolean 
+static gboolean
 numeric_predicate_equal (QofQueryPredData *p1, QofQueryPredData *p2)
 {
   query_numeric_t pd1 = (query_numeric_t) p1;
@@ -507,7 +504,7 @@
   return ((QofQueryPredData*)pdata);
 }
 
-static char * 
+static char *
 numeric_to_string (gpointer object, QofParam *getter)
 {
   gnc_numeric num;
@@ -516,7 +513,7 @@
   return gnc_numeric_to_string (num);
 }
 
-static char * 
+static char *
 debcred_to_string (gpointer object, QofParam *getter)
 {
   gnc_numeric num;
@@ -527,7 +524,7 @@
 
 /* QOF_TYPE_GUID =================================================== */
 
-static int 
+static int
 guid_match_predicate (gpointer object, QofParam *getter,
                       QofQueryPredData *pd)
 {
@@ -545,17 +542,17 @@
      * object list
      */
 
-    for (node = pdata->guids; node; node = node->next) 
+    for (node = pdata->guids; node; node = node->next)
     {
       /* See if this GUID matches the object's guid */
-      for (o_list = object; o_list; o_list = o_list->next) 
+      for (o_list = object; o_list; o_list = o_list->next)
       {
         guid = ((query_guid_getter)getter->param_getfcn) (o_list->data, getter);
-        if (guid_equal (node->data, guid)) 
+        if (guid_equal (node->data, guid))
           break;
       }
 
-      /* 
+      /*
        * If o_list is NULL, we've walked the whole list without finding
        * a match.  Therefore break out now, the match has failed.
        */
@@ -563,7 +560,7 @@
         break;
     }
 
-    /* 
+    /*
      * The match is complete.  If node == NULL then we've succesfully
      * found a match for all the guids in the predicate.  Return
      * appropriately below.
@@ -580,12 +577,12 @@
 
     o_list = ((query_glist_getter)getter->param_getfcn) (object, getter);
 
-    for (node = o_list; node; node = node->next) 
+    for (node = o_list; node; node = node->next)
     {
       GList *node2;
 
       /* Search the predicate data for a match */
-      for (node2 = pdata->guids; node2; node2 = node2->next) 
+      for (node2 = pdata->guids; node2; node2 = node2->next)
       {
         if (guid_equal (node->data, node2->data))
           break;
@@ -605,13 +602,13 @@
     break;
 
   default:
-    /* object is a single object, getter returns a GUID* 
+    /* object is a single object, getter returns a GUID*
      *
      * See if the guid is in the list
      */
 
     guid = ((query_guid_getter)getter->param_getfcn) (object, getter);
-    for (node = pdata->guids; node; node = node->next) 
+    for (node = pdata->guids; node; node = node->next)
     {
       if (guid_equal (node->data, guid))
         break;
@@ -636,7 +633,7 @@
   }
 }
 
-static void 
+static void
 guid_free_pdata (QofQueryPredData *pd)
 {
   query_guid_t pdata = (query_guid_t)pd;
@@ -658,7 +655,7 @@
   return qof_query_guid_predicate (pdata->options, pdata->guids);
 }
 
-static gboolean 
+static gboolean
 guid_predicate_equal (QofQueryPredData *p1, QofQueryPredData *p2)
 {
   query_guid_t pd1 = (query_guid_t) p1;
@@ -667,7 +664,7 @@
 
   if (pd1->options != pd2->options) return FALSE;
   if (g_list_length (l1) != g_list_length (l2)) return FALSE;
-  for ( ; l1 ; l1 = l1->next, l2 = l2->next) 
+  for ( ; l1 ; l1 = l1->next, l2 = l2->next)
   {
     if (!guid_equal (l1->data, l2->data))
       return FALSE;
@@ -689,7 +686,7 @@
   pdata->options = options;
 
   pdata->guids = g_list_copy (guid_list);
-  for (node = pdata->guids; node; node = node->next) 
+  for (node = pdata->guids; node; node = node->next)
   {
     GUID *guid = guid_malloc ();
     *guid = *((GUID *)node->data);
@@ -701,7 +698,7 @@
 /* ================================================================ */
 /* QOF_TYPE_INT32 */
 
-static int 
+static int
 int32_match_predicate (gpointer object, QofParam *getter,
                        QofQueryPredData *pd)
 {
@@ -731,7 +728,7 @@
   }
 }
 
-static int 
+static int
 int32_compare_func (gpointer a, gpointer b, gint options,
                     QofParam *getter)
 {
@@ -746,7 +743,7 @@
   return 0;
 }
 
-static void 
+static void
 int32_free_pdata (QofQueryPredData *pd)
 {
   query_int32_t pdata = (query_int32_t)pd;
@@ -762,7 +759,7 @@
   return qof_query_int32_predicate (pd->how, pdata->val);
 }
 
-static gboolean 
+static gboolean
 int32_predicate_equal (QofQueryPredData *p1, QofQueryPredData *p2)
 {
   query_int32_t pd1 = (query_int32_t) p1;
@@ -781,7 +778,7 @@
   return ((QofQueryPredData*)pdata);
 }
 
-static char * 
+static char *
 int32_to_string (gpointer object, QofParam *getter)
 {
   gint32 num = ((query_int32_getter)getter->param_getfcn)(object, getter);
@@ -792,7 +789,7 @@
 /* ================================================================ */
 /* QOF_TYPE_INT64 */
 
-static int 
+static int
 int64_match_predicate (gpointer object, QofParam *getter,
                        QofQueryPredData *pd)
 {
@@ -822,7 +819,7 @@
   }
 }
 
-static int 
+static int
 int64_compare_func (gpointer a, gpointer b, gint options,
                               QofParam *getter)
 {
@@ -837,7 +834,7 @@
   return 0;
 }
 
-static void 
+static void
 int64_free_pdata (QofQueryPredData *pd)
 {
   query_int64_t pdata = (query_int64_t)pd;
@@ -853,7 +850,7 @@
   return qof_query_int64_predicate (pd->how, pdata->val);
 }
 
-static gboolean 
+static gboolean
 int64_predicate_equal (QofQueryPredData *p1, QofQueryPredData *p2)
 {
   query_int64_t pd1 = (query_int64_t) p1;
@@ -872,7 +869,7 @@
   return ((QofQueryPredData*)pdata);
 }
 
-static char * 
+static char *
 int64_to_string (gpointer object, QofParam *getter)
 {
   gint64 num = ((query_int64_getter)getter->param_getfcn)(object, getter);
@@ -883,7 +880,7 @@
 /* ================================================================ */
 /* QOF_TYPE_DOUBLE */
 
-static int 
+static int
 double_match_predicate (gpointer object, QofParam *getter,
                         QofQueryPredData *pd)
 {
@@ -913,7 +910,7 @@
   }
 }
 
-static int 
+static int
 double_compare_func (gpointer a, gpointer b, gint options,
                      QofParam *getter)
 {
@@ -928,7 +925,7 @@
   return 0;
 }
 
-static void 
+static void
 double_free_pdata (QofQueryPredData *pd)
 {
   query_double_t pdata = (query_double_t)pd;
@@ -944,7 +941,7 @@
   return qof_query_double_predicate (pd->how, pdata->val);
 }
 
-static gboolean 
+static gboolean
 double_predicate_equal (QofQueryPredData *p1, QofQueryPredData *p2)
 {
   query_double_t pd1 = (query_double_t) p1;
@@ -963,7 +960,7 @@
   return ((QofQueryPredData*)pdata);
 }
 
-static char * 
+static char *
 double_to_string (gpointer object, QofParam *getter)
 {
   double num = ((query_double_getter)getter->param_getfcn)(object, getter);
@@ -973,7 +970,7 @@
 
 /* QOF_TYPE_BOOLEAN =================================================== */
 
-static int 
+static int
 boolean_match_predicate (gpointer object, QofParam *getter,
                          QofQueryPredData *pd)
 {
@@ -995,7 +992,7 @@
   }
 }
 
-static int 
+static int
 boolean_compare_func (gpointer a, gpointer b, gint options,
                       QofParam *getter)
 {
@@ -1008,7 +1005,7 @@
   return 0;
 }
 
-static void 
+static void
 boolean_free_pdata (QofQueryPredData *pd)
 {
   query_boolean_t pdata = (query_boolean_t)pd;
@@ -1024,7 +1021,7 @@
   return qof_query_boolean_predicate (pd->how, pdata->val);
 }
 
-static gboolean 
+static gboolean
 boolean_predicate_equal (QofQueryPredData *p1, QofQueryPredData *p2)
 {
   query_boolean_t pd1 = (query_boolean_t) p1;
@@ -1046,7 +1043,7 @@
   return ((QofQueryPredData*)pdata);
 }
 
-static char * 
+static char *
 boolean_to_string (gpointer object, QofParam *getter)
 {
   gboolean num = ((query_boolean_getter)getter->param_getfcn)(object, getter);
@@ -1056,7 +1053,7 @@
 
 /* QOF_TYPE_CHAR =================================================== */
 
-static int 
+static int
 char_match_predicate (gpointer object, QofParam *getter,
                                  QofQueryPredData *pd)
 {
@@ -1080,7 +1077,7 @@
   }
 }
 
-static int 
+static int
 char_compare_func (gpointer a, gpointer b, gint options, QofParam *getter)
 {
   char va, vb;
@@ -1090,13 +1087,13 @@
   return (va-vb);
 }
 
-static void 
+static void
 char_free_pdata (QofQueryPredData *pd)
 {
   query_char_t pdata = (query_char_t)pd;
   VERIFY_PDATA (query_char_type);
   g_free (pdata->char_list);
-  g_free (pdata);  
+  g_free (pdata);
 }
 
 static QofQueryPredData *
@@ -1107,7 +1104,7 @@
   return qof_query_char_predicate (pdata->options, pdata->char_list);
 }
 
-static gboolean 
+static gboolean
 char_predicate_equal (QofQueryPredData *p1, QofQueryPredData *p2)
 {
   query_char_t pd1 = (query_char_t) p1;
@@ -1130,7 +1127,7 @@
   return ((QofQueryPredData*)pdata);
 }
 
-static char * 
+static char *
 char_to_string (gpointer object, QofParam *getter)
 {
   char num = ((query_char_getter)getter->param_getfcn)(object, getter);
@@ -1140,7 +1137,7 @@
 
 /* QOF_TYPE_KVP ================================================ */
 
-static int 
+static int
 kvp_match_predicate (gpointer object, QofParam *getter,
                      QofQueryPredData *pd)
 {
@@ -1184,7 +1181,7 @@
   }
 }
 
-static void 
+static void
 kvp_free_pdata (QofQueryPredData *pd)
 {
   query_kvp_t pdata = (query_kvp_t)pd;
@@ -1192,13 +1189,13 @@
 
   VERIFY_PDATA (query_kvp_type);
   kvp_value_delete (pdata->value);
-  for (node = pdata->path; node; node = node->next) 
+  for (node = pdata->path; node; node = node->next)
   {
     g_free (node->data);
     node->data = NULL;
   }
   g_slist_free (pdata->path);
-  g_free (pdata);  
+  g_free (pdata);
 }
 
 static QofQueryPredData *
@@ -1209,7 +1206,7 @@
   return qof_query_kvp_predicate (pd->how, pdata->path, pdata->value);
 }
 
-static gboolean 
+static gboolean
 kvp_predicate_equal (QofQueryPredData *p1, QofQueryPredData *p2)
 {
   query_kvp_t pd1 = (query_kvp_t) p1;
@@ -1616,7 +1613,7 @@
  */
 
 
-static void 
+static void
 qof_query_register_core_object (QofType core_name,
                                 QofQueryPredicateFunc pred,
                                 QofCompareFunc comp,
@@ -1650,7 +1647,7 @@
 static void init_tables (void)
 {
   unsigned int i;
-  struct 
+  struct
   {
     QofType                name;
     QofQueryPredicateFunc  pred;
@@ -1659,10 +1656,10 @@
     QueryPredDataFree      pd_free;
     QueryToString          toString;
     QueryPredicateEqual    pred_equal;
-  } knownTypes[] = 
+  } knownTypes[] =
   {
     { QOF_TYPE_STRING, string_match_predicate, string_compare_func,
-      string_copy_predicate, string_free_pdata, string_to_string, 
+      string_copy_predicate, string_free_pdata, string_to_string,
       string_predicate_equal },
     { QOF_TYPE_DATE, date_match_predicate, date_compare_func,
       date_copy_predicate, date_free_pdata, date_to_string,
@@ -1701,7 +1698,7 @@
   };
 
   /* Register the known data types */
-  for (i = 0; i < (sizeof(knownTypes)/sizeof(*knownTypes)); i++) 
+  for (i = 0; i < (sizeof(knownTypes)/sizeof(*knownTypes)); i++)
   {
     qof_query_register_core_object (knownTypes[i].name,
                                 knownTypes[i].pred,
@@ -1713,7 +1710,7 @@
   }
 }
 
-static QueryPredicateCopyFunc 
+static QueryPredicateCopyFunc
 qof_query_copy_predicate (QofType type)
 {
   QueryPredicateCopyFunc rc;
@@ -1722,7 +1719,7 @@
   return rc;
 }
 
-static QueryPredDataFree 
+static QueryPredDataFree
 qof_query_predicate_free (QofType type)
 {
   g_return_val_if_fail (type, NULL);
@@ -1776,7 +1773,7 @@
   return g_hash_table_lookup (cmpTable, type);
 }
 
-void 
+void
 qof_query_core_predicate_free (QofQueryPredData *pdata)
 {
   QueryPredDataFree free_fcn;
@@ -1800,7 +1797,7 @@
   return (copy (pdata));
 }
 
-char * 
+char *
 qof_query_core_to_string (QofType type, gpointer object,
                           QofParam *getter)
 {
@@ -1816,7 +1813,7 @@
   return toString (object, getter);
 }
 
-gboolean 
+gboolean
 qof_query_core_predicate_equal (QofQueryPredData *p1, QofQueryPredData *p2)
 {
   QueryPredicateEqual pred_equal;

Modified: gnucash/trunk/lib/libqof/qof/qofquerycore.h
===================================================================
--- gnucash/trunk/lib/libqof/qof/qofquerycore.h	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/qofquerycore.h	2006-01-08 17:51:29 UTC (rev 12299)
@@ -23,7 +23,7 @@
 
 /** @addtogroup Query
     @{ */
-                                                                                
+
 /** @file qofquerycore.h
     @brief API for providing core Query data types
     @author Copyright (C) 2002 Derek Atkins <warlord at MIT.EDU>
@@ -42,7 +42,7 @@
 /**
  * PREDICATE DATA TYPES: All the predicate data types are rolled up into
  * the union type PredicateData.  The "type" field specifies which type
- * the union is.  
+ * the union is.
  */
 typedef struct _QofQueryPredData QofQueryPredData;
 
@@ -58,7 +58,7 @@
   QOF_COMPARE_NEQ
 } QofQueryCompare;
 
-/** List of known core query data-types... 
+/** List of known core query data-types...
  *  Each core query type defines it's set of optional "comparitor qualifiers".
  */
 /* Comparisons for QOF_TYPE_STRING */
@@ -67,15 +67,13 @@
   QOF_STRING_MATCH_CASEINSENSITIVE
 } QofStringMatch;
 
-/** Comparisons for QOF_TYPE_DATE	
+/** Comparisons for QOF_TYPE_DATE
  * The QOF_DATE_MATCH_DAY comparison rounds the two time
  *     values to mid-day and then compares these rounded values.
  * The QOF_DATE_MATCH_NORMAL comparison matches the time values,
  *     down to the second.
  */
-/* XXX remove these deprecated old names .. */
-//#define QOF_DATE_MATCH_ROUNDED QOF_DATE_MATCH_DAY
-//#define QOF_DATE_MATCH_NORMAL  QOF_DATE_MATCH_TIME
+
 typedef enum {
   QOF_DATE_MATCH_NORMAL = 1,
   QOF_DATE_MATCH_DAY
@@ -83,11 +81,11 @@
 
 /** Comparisons for QOF_TYPE_NUMERIC, QOF_TYPE_DEBCRED
  *
- * XXX Should be deprecated, or at least wrapped up as a convnience
- * function,  this is based on the old bill gribble code, which assumed 
- * the amount was always positive, and then specified a funds-flow 
+ * XXX Should be deprecated, or at least wrapped up as a convenience
+ * function,  this is based on the old bill gribble code, which assumed
+ * the amount was always positive, and then specified a funds-flow
  * direction (credit, debit, or either).
- * 
+ *
  * The point being that 'match credit' is equivalent to the compound
  * predicate (amount >= 0) && (amount 'op' value) while the  'match
  * debit' predicate is equivalent to (amount <= 0) && (abs(amount) 'op' value)
@@ -101,7 +99,7 @@
 
 /* Comparisons for QOF_TYPE_GUID */
 typedef enum {
-  /** These expect a single object and expect the 
+  /** These expect a single object and expect the
    * QofAccessFunc returns GUID* */
   QOF_GUID_MATCH_ANY = 1,
   QOF_GUID_MATCH_NONE,
@@ -114,12 +112,12 @@
   QOF_GUID_MATCH_LIST_ANY,
 } QofGuidMatch;
 
-/** A CHAR type is for a RECNCell, Comparisons for QOF_TYPE_CHAR 
+/** A CHAR type is for a RECNCell, Comparisons for QOF_TYPE_CHAR
  *  'ANY' will match any charagter in the string.
  *
- * Match 'ANY' is a convenience/performance-enhanced predicate 
+ * Match 'ANY' is a convenience/performance-enhanced predicate
  * for the compound statement (value==char1) || (value==char2) || etc.
- * Match 'NONE' is equivalent to 
+ * Match 'NONE' is equivalent to
  * (value != char1) && (value != char2) && etc.
  */
 typedef enum {
@@ -138,15 +136,15 @@
 };
 
 
-/** @name Core Data Type Predicates 
+/** @name Core Data Type Predicates
     @{ */
-QofQueryPredData *qof_query_string_predicate (QofQueryCompare how, 
+QofQueryPredData *qof_query_string_predicate (QofQueryCompare how,
                                               const char *str,
                                               QofStringMatch options,
                                               gboolean is_regex);
 
 QofQueryPredData *qof_query_date_predicate (QofQueryCompare how,
-                                            QofDateMatch options, 
+                                            QofDateMatch options,
                                             Timespec date);
 
 QofQueryPredData *qof_query_numeric_predicate (QofQueryCompare how,
@@ -169,13 +167,13 @@
  *  sense, the 'path' is handled as if it were a paramter.
  */
 QofQueryPredData *qof_query_kvp_predicate (QofQueryCompare how,
-                                           GSList *path, 
+                                           GSList *path,
                                            const KvpValue *value);
 
-/** Same predicate as above, except that 'path' is assumed to be 
+/** Same predicate as above, except that 'path' is assumed to be
  * a string containing slash-separated pathname. */
 QofQueryPredData *qof_query_kvp_predicate_path (QofQueryCompare how,
-                                                const char *path, 
+                                                const char *path,
                                                 const KvpValue *value);
 
 /** Copy a predicate. */

Modified: gnucash/trunk/lib/libqof/qof/qofsession.c
===================================================================
--- gnucash/trunk/lib/libqof/qof/qofsession.c	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/qofsession.c	2006-01-08 17:51:29 UTC (rev 12299)
@@ -41,17 +41,11 @@
 #include <unistd.h>
 
 #include <glib.h>
-#include "qofla-dir.h"
-#include "gnc-trace.h"
-#include "gnc-engine-util.h"
-#include "gnc-event.h"
-#include "qofsession.h"
+#include "qof.h"
 #include "qofbackend-p.h"
-#include "qof-be-utils.h"
-#include "qofbook.h"
 #include "qofbook-p.h"
-#include "qofobject.h"
 #include "qofsession-p.h"
+#include "qofobject-p.h"
 
 /** \deprecated should not be static */
 static QofSession * current_session = NULL;
@@ -325,7 +319,7 @@
 	partial =
 	  (gboolean)GPOINTER_TO_INT(qof_book_get_data(book, PARTIAL_QOFBOOK));
 	if(!partial) {
-		qof_book_set_data(book, PARTIAL_QOFBOOK, (gboolean*)TRUE);
+		qof_book_set_data(book, PARTIAL_QOFBOOK, GINT_TO_POINTER(TRUE));
 	}
 }
 
@@ -350,8 +344,13 @@
 	g_return_if_fail(data != NULL);
 	qecd = (QofEntityCopyData*)data;
 	g_return_if_fail(param != NULL);
+	/* KVP doesn't need a set routine to be copied. */
+	if(0 == safe_strcmp(param->param_type, QOF_TYPE_KVP)) {
+		qecd->param_list = g_slist_prepend(qecd->param_list, param);
+		return;
+	}
 	if((param->param_getfcn != NULL)&&(param->param_setfcn != NULL)) {
-			qecd->param_list = g_slist_prepend(qecd->param_list, param);
+		qecd->param_list = g_slist_prepend(qecd->param_list, param);
 	}
 }
 
@@ -477,10 +476,18 @@
 		if(boolean_setter != NULL) { boolean_setter(targetEnt, cm_boolean); }
 		registered_type = TRUE;
 	}
-	if(safe_strcmp(cm_param->param_type, QOF_TYPE_KVP) == 0) { 
-		cm_kvp = kvp_frame_copy((KvpFrame*)cm_param->param_getfcn(importEnt,cm_param));
+	if(safe_strcmp(cm_param->param_type, QOF_TYPE_KVP) == 0) {
+		cm_kvp = (KvpFrame*)cm_param->param_getfcn(importEnt,cm_param);
 		kvp_frame_setter = (void(*)(QofEntity*, KvpFrame*))cm_param->param_setfcn;
 		if(kvp_frame_setter != NULL) { kvp_frame_setter(targetEnt, cm_kvp); }
+		else
+		{
+			QofInstance *target_inst;
+
+			target_inst = (QofInstance*)targetEnt;
+			kvp_frame_delete(target_inst->kvp_data);
+			target_inst->kvp_data = kvp_frame_copy(cm_kvp);
+		}
 		registered_type = TRUE;
 	}
 	if(safe_strcmp(cm_param->param_type, QOF_TYPE_CHAR) == 0) { 
@@ -535,8 +542,19 @@
 	qecd = (QofEntityCopyData*)user_data;
 	if(qof_entity_guid_match(qecd->new_session, original)) { return; }
 	qecd->from = original;
+	if(!qof_object_compliance(original->e_type, FALSE)) 
+	{
+		qecd->error = TRUE;
+		return;
+	}
 	book = qof_session_get_book(qecd->new_session);
 	inst = (QofInstance*)qof_object_new_instance(original->e_type, book);
+	if(!inst) 
+	{ 
+		PERR (" failed to create new entity type=%s.", original->e_type);
+		qecd->error = TRUE;
+		return;
+	}
 	qecd->to = &inst->entity;
 	g = qof_entity_get_guid(original);
 	qof_entity_set_guid(qecd->to, g);
@@ -580,6 +598,7 @@
 	g_return_if_fail(user_data != NULL);
 	qecd = (QofEntityCopyData*)user_data;
 	book = qof_session_get_book(qecd->new_session);
+	if(!qof_object_compliance(original->e_type, TRUE)) { return; }
 	inst = (QofInstance*)qof_object_new_instance(original->e_type, book);
 	qecd->to = &inst->entity;
 	qecd->from = original;
@@ -590,7 +609,8 @@
 	qof_commit_edit(inst);
 }
 
-gboolean qof_entity_copy_to_session(QofSession* new_session, QofEntity* original)
+gboolean 
+qof_entity_copy_to_session(QofSession* new_session, QofEntity* original)
 {
 	QofEntityCopyData qecd;
 	QofInstance *inst;
@@ -598,6 +618,7 @@
 
 	if(!new_session || !original) { return FALSE; }
 	if(qof_entity_guid_match(new_session, original)) { return FALSE; }
+	if(!qof_object_compliance(original->e_type, TRUE)) { return FALSE; }
 	gnc_engine_suspend_events();
 	qecd.param_list = NULL;
 	book = qof_session_get_book(new_session);
@@ -630,12 +651,17 @@
 	qof_book_set_partial(qof_session_get_book(new_session));
 	g_list_foreach(entity_list, qof_entity_list_foreach, qecd);
 	gnc_engine_resume_events();
+	if(qecd->error) 
+	{ 
+		PWARN (" some/all entities in the list could not be copied.");
+	}
 	g_free(qecd);
 	LEAVE (" ");
 	return TRUE;
 }
 
-gboolean qof_entity_copy_coll(QofSession *new_session, QofCollection *entity_coll)
+gboolean 
+qof_entity_copy_coll(QofSession *new_session, QofCollection *entity_coll)
 {
 	QofEntityCopyData qecd;
 
@@ -644,7 +670,8 @@
 	qecd.new_session = new_session;
 	qof_book_set_partial(qof_session_get_book(qecd.new_session));
 	qof_collection_foreach(entity_coll, qof_entity_coll_foreach, &qecd);
-	qof_class_param_foreach(qof_collection_get_type(entity_coll), qof_entity_param_cb, &qecd);
+	qof_class_param_foreach(qof_collection_get_type(entity_coll), 
+		qof_entity_param_cb, &qecd);
 	qof_collection_foreach(entity_coll, qof_entity_coll_copy, &qecd);
 	if(qecd.param_list != NULL) { g_slist_free(qecd.param_list); }
 	gnc_engine_resume_events();
@@ -789,7 +816,7 @@
 
 /* ====================================================================== */
 
-/* Programs that use their own backends also need to call
+/** Programs that use their own backends also need to call
 the default QOF ones. The backends specified here are
 loaded only by applications that do not have their own. */
 struct backend_providers
@@ -802,11 +829,11 @@
 /* All available QOF backends need to be described here
 and the last entry must be three NULL's.
 Remember: Use the libdir from the current build environment
-and use the .la NOT the .so - .so is not portable! */
+and use JUST the module name without .so - .so is not portable! */
 struct backend_providers backend_list[] = {
-	{ QOF_LIB_DIR, "libqof-backend-qsf.la", "qsf_provider_init" },
+	{ QOF_LIB_DIR, QSF_BACKEND_LIB, QSF_MODULE_INIT },
 #ifdef HAVE_DWI
-	{ QOF_LIB_DIR, "libqof_backend_dwi.la", "dwiend_provider_init" },
+	{ QOF_LIB_DIR, "libqof_backend_dwi", "dwiend_provider_init" },
 #endif
 	{ NULL, NULL, NULL }
 };

Modified: gnucash/trunk/lib/libqof/qof/qofsession.h
===================================================================
--- gnucash/trunk/lib/libqof/qof/qofsession.h	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/qofsession.h	2006-01-08 17:51:29 UTC (rev 12299)
@@ -59,7 +59,7 @@
  *    to and open this datastore?
  *
  * A brief note about books & sessions:
- * A book encapsulates the datasets manipulated by GnuCash.  A book
+ * A book encapsulates the datasets manipulated by QOF.  A book
  * holds the actual data.  By contrast, the session mediates the
  * connection between a book (the thing that lives in virtual memory
  * in the local process) and the datastore (the place where book
@@ -75,6 +75,8 @@
  * make that assumption, in order to store the different accounting
  * periods in a clump so that one can be found, given another.
  *
+   If you want multiple books that are unrelated to each other,
+   use multiple sessions.
 
    The session now calls QofBackendProvider->check_data_type
    to check that the incoming path contains data that the
@@ -119,22 +121,13 @@
 
 /** The qof_session_begin () method begins a new session.
  *    It takes as an argument the book id. The book id must be a string
- *    in the form of a URI/URL.
- *    In the current implementation, the following URL's are supported
- *    -- File URI of the form 
- *       "file:/home/somewhere/somedir/file.xac"
- *       The path part must be a valid path.  The file-part must be 
- *       a valid old-style-xacc or new-style-gnucash-format file. Paths
- *       may be relative or absolute. If the path is relative; that is, 
- *       if the argument is  "file:somefile.xac" then a sequence of 
- *       search paths are checked for a file of this name.
+ *    in the form of a URI/URL. The access method specified depends
+ *    on the loaded backends. In the absence of a customised backend,
+ *    only QSF XML would be accepted). Paths may be relative or absolute.
+ *    If the path is relative; that is, if the argument is "file:somefile.xml"
+ *    then the current working directory is assumed. Customised backends can
+ *    choose to search other, application-specific, directories as well.
  *
- *    -- Postgres URI of the form
- *       "postgres://hostname.com/dbname"
- *       See the src/backend/postgres subdirectory for more info.
- *
- *    -- RPC URI of the form rpc://hostname.com/rpcserver.
- *
  *    The 'ignore_lock' argument, if set to TRUE, will cause this routine
  *    to ignore any global-datastore locks (e.g. file locks) that it finds. 
  *    If set to FALSE, then file/database-global locks will be tested and 
@@ -216,7 +209,7 @@
  *    filepath is derived from the url by substituting commas for
  *    slashes).
  *
- * The qof_session_get_url() routine returns the url that was opened.
+ *    The qof_session_get_url() routine returns the url that was opened.
  *    URL's for local files take the form of 
  *    file:/some/where/some/file.gml
  */
@@ -243,7 +236,7 @@
 			   QofPercentageFunc percentage_func);
 /**
  * The qof_session_end() method will release the session lock. For the
- *    file backend, it will *not* save the account group to a file. Thus, 
+ *    file backend, it will *not* save the data to a file. Thus, 
  *    this method acts as an "abort" or "rollback" primitive.  However,
  *    for other backends, such as the sql backend, the data would have
  *    been written out before this, and so this routines wouldn't 
@@ -347,9 +340,7 @@
 Objects can be defined solely in terms of QOF data types or
 as a mix of data types and other objects, which may in turn
 include other objects. These references can be copied recursively
-down to the third level. e.g. ::GncInvoice refers to ::GncOwner which
-refers to ::GncCustomer which refers to ::GncAddress. See
-::QofEntityReference.
+down to the third level. See ::QofEntityReference.
 
 \note This is a deep recursive copy - every referenced entity is copied
 to the new session, including all parameters. The starting point is all
@@ -402,12 +393,12 @@
 reference can be included. See ::qof_book_get_data. 
 
 When the file is imported back in, the list needs to be rebuilt.
-The QSF backend rebuilds the references by linking to real entities. Other
-backends can process the hash table in similar ways.
+The QSF backend rebuilds the references by linking to real entities.
+Other backends can process the hash table in similar ways.
 
 The list stores the QofEntityReference to the referenced entity -
-a struct that contains the GUID and the QofIdType of the referenced entity 
-as well as the parameter used to obtain the reference.
+a struct that contains the GUID and the QofIdType of the referenced
+entity as well as the parameter used to obtain the reference.
 
 Partial books need to be differentiated in the backend, the 
 flag in the book data is used by qof_session_save to prevent a partial
@@ -425,8 +416,8 @@
 */
 typedef struct qof_entity_reference {
 	QofIdType       choice_type;/**< When the reference is a different type.*/
-	QofIdType        type;       /**< The type of entity */
-	GUID             *ref_guid;  /**< The GUID of the REFERENCE entity */
+	QofIdType       type;       /**< The type of entity */
+	GUID            *ref_guid;  /**< The GUID of the REFERENCE entity */
 	const QofParam  *param;      /**< The parameter name and type. */
 	const GUID      *ent_guid;   /**< The GUID of the original entity. */
 }QofEntityReference;
@@ -465,7 +456,8 @@
 
 Retrieves any existing reference list and appends the new reference.
 
-If the book is not already marked as partial, it will be marked as partial.
+If the book is not already marked as partial, it will be marked as
+partial.
 */
 void
 qof_session_update_reference_list(QofSession *session, QofEntityReference *reference);
@@ -512,34 +504,19 @@
 /** @name Event Handling
 
   @{ */
-/** The qof_session_events_pending() method will return TRUE if the backend
- *    has pending events which must be processed to bring the engine
- *    up to date with the backend.
+/** The qof_session_events_pending() method will return TRUE if the
+ *  backend has pending events which must be processed to bring 
+ *  the engine up to date with the backend.
  */
 gboolean qof_session_events_pending (QofSession *session);
 
-/**  The qof_session_process_events() method will process any events indicated
- *    by the qof_session_events_pending() method. It returns TRUE if the
- *    engine was modified while engine events were suspended.
+/**  The qof_session_process_events() method will process any events
+ *   indicated by the qof_session_events_pending() method. It returns 
+ *   TRUE if the engine was modified while engine events were suspended.
  */
 gboolean qof_session_process_events (QofSession *session);
 /** @} */
 
-#ifdef GNUCASH_MAJOR_VERSION
-/** Run the RPC Server 
- *  @deprecated  will go away */
-void gnc_run_rpc_server (void);
-
-/** XXX session_export really doesn't belong here .
- * This functino exports the list of accounts to a file.  Its a stop-gap 
- * measure until full book-closing is implemented.
- */
-gboolean qof_session_export (QofSession *tmp_session,
-			     QofSession *real_session,
-			     QofPercentageFunc percentage_func);
-
-#endif /* GNUCASH_MAJOR_VERSION */
-
 /** Register a function to be called just before a session is closed.
  *
  *  @param fn The function to be called.  The function definition must

Modified: gnucash/trunk/lib/libqof/qof/qofsql.c
===================================================================
--- gnucash/trunk/lib/libqof/qof/qofsql.c	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/qofsql.c	2006-01-08 17:51:29 UTC (rev 12299)
@@ -22,7 +22,7 @@
 
 /**
     @file qofsql.c
-    @brief QOF client-side SQL parser.
+    @brief QOF client-side SQL parser - interfaces with libgda.
     @author Copyright (C) 2004 Linas Vepstas <linas at linas.org>
 
 */
@@ -38,19 +38,9 @@
 #include "sql_parser.h"
 #endif
 #include <time.h>
-#include "kvp_frame.h"
-#include "gnc-date.h"
-#include "gnc-numeric.h"
-#include "gnc-trace.h"
-#include "guid.h"
-#include "qofbook.h"
-#include "qofquery.h"
-#include "qofquerycore.h"
-#include "qofsql.h"
-#include "gnc-engine-util.h"
-#include "qofinstance-p.h"
-#include "qofobject.h"
 
+#include "qof.h"
+
 static QofLogModule log_module = QOF_MOD_QUERY;
 
 /* =================================================================== */
@@ -72,7 +62,7 @@
 qof_sql_query_new(void)
 {
 	QofSqlQuery * sqn = (QofSqlQuery *) g_new0 (QofSqlQuery, 1);
-	
+
 	sqn->qof_query = NULL;
 	sqn->parse_result = NULL;
 	sqn->book = NULL;
@@ -171,7 +161,7 @@
 	Timespec ts;
 	QofType param_type;
 	QofGuidMatch gm;
-	
+
 	pred_data = NULL;
 	if (NULL == cond)
 	{
@@ -484,7 +474,7 @@
 {
 	QofQueryOp qop;
 	QofQuery * qq;
-	
+
 	switch (swear->type)
 	{
 		case SQL_pair:
@@ -536,7 +526,7 @@
 	int i;
 	sql_order_field *sorder;
 	char * qparam_name;
-	
+
 	if (!sorder_list) return;
 
 	for (i=0; i<3; i++)
@@ -576,79 +566,15 @@
 	                            direction[1], direction[2]);
 }
 
-/* ========================================================== */
-static void
-qof_queryForeachParam( QofParam* param, gpointer user_data) 
-{
-	QofSqlQuery *q;
-	
-	g_return_if_fail(user_data != NULL);
-	q = (QofSqlQuery*)user_data;
-	g_return_if_fail(param != NULL);
-	if((param->param_getfcn != NULL)&&(param->param_setfcn != NULL)) {
-		q->param_list = g_list_append(q->param_list, param);
-	}
-}
+/* INSERT INTO handlers =================================================== */
 
-static const char*
-qof_sql_get_value(sql_insert_statement *insert)
-{
-	GList *walk, *cur;
-	const char *insert_string;
-	sql_field *field;
-	sql_field_item * item;
-
-	/* how to cope with multiple results? */
-	if (insert->values == NULL) { return NULL; }
-	insert_string = NULL;
-	for (walk = insert->values; walk != NULL; walk = walk->next) 
-	{
-		field = walk->data;
-		item = field->item;
-		for (cur = item->d.name; cur != NULL; cur = cur->next)
-		{
-			insert_string = g_strdup_printf("%s", (char*)cur->data);
-		}
-	}
-	return insert_string;
-}
-
-static const QofParam*
-qof_sql_get_param(QofIdTypeConst type, sql_insert_statement *insert)
-{
-	GList *walk, *cur;
-	const char *param_name;
-	const QofParam *param;
-	sql_field *field;
-	sql_field_item *item;
-
-	param = NULL;
-	param_name = NULL;
-	if (insert->fields == NULL) { return NULL; }
-	for (walk = insert->fields; walk != NULL; walk = walk->next) 
-	{
-		field = walk->data;
-		item = field->item;
-		for (cur = item->d.name; cur != NULL; cur = cur->next)
-		{
-			param_name = g_strdup_printf("%s", (char*)cur->data);
-		}
-	}
-	param = qof_class_get_parameter(type, param_name);
-	return param;
-}
-
 static void
-qof_sql_insertCB( gpointer value, gpointer data)
+qof_sql_insertCB(const QofParam *param, const gchar *insert_string, QofSqlQuery *query)
 {
-	GList *param_list;
-	QofSqlQuery *q;
 	QofIdTypeConst type;
 	sql_insert_statement *sis;
-	const char *insert_string;
 	gboolean    registered_type;
 	QofEntity   *ent;
-	QofParam    *param;
 	struct tm   query_time;
 	time_t      query_time_t;
 	/* cm_ prefix used for variables that hold the data to commit */
@@ -663,7 +589,6 @@
 /*	KvpFrame       *cm_kvp;
 	KvpValue       *cm_value;
 	KvpValueType   cm_type;*/
-	const QofParam *cm_param;
 	void (*string_setter)    (QofEntity*, const char*);
 	void (*date_setter)      (QofEntity*, Timespec);
 	void (*numeric_setter)   (QofEntity*, gnc_numeric);
@@ -674,126 +599,186 @@
 	void (*char_setter)      (QofEntity*, char);
 /*	void (*kvp_frame_setter) (QofEntity*, KvpFrame*);*/
 
-	q = (QofSqlQuery*)data;
-	ent = q->inserted_entity;
-	param = (QofParam*)value;
-	sis = q->parse_result->statement;
+	g_return_if_fail(param || insert_string || query);
+	ent = query->inserted_entity;
+	sis = query->parse_result->statement;
 	type = g_strdup_printf("%s", sis->table->d.simple);
-	insert_string = g_strdup(qof_sql_get_value(sis));
-	cm_param = qof_sql_get_param(type, sis);
-	param_list = g_list_copy(q->param_list);
-	while(param_list != NULL) {
-		if(safe_strcmp(cm_param->param_type, QOF_TYPE_STRING) == 0)  { 
-			string_setter = (void(*)(QofEntity*, const char*))cm_param->param_setfcn;
-			if(string_setter != NULL) { string_setter(ent, insert_string); }
-			registered_type = TRUE;
+
+	ENTER (" param=%s param_type=%s type=%s content=%s", 
+		param->param_name, param->param_type, type, insert_string);
+	if(safe_strcmp(param->param_type, QOF_TYPE_STRING) == 0)  { 
+		string_setter = (void(*)(QofEntity*, const char*))param->param_setfcn;
+		if(string_setter != NULL) { string_setter(ent, insert_string); }
+		registered_type = TRUE;
+	}
+	if(safe_strcmp(param->param_type, QOF_TYPE_DATE) == 0) { 
+		date_setter = (void(*)(QofEntity*, Timespec))param->param_setfcn;
+		strptime(insert_string, QOF_UTC_DATE_FORMAT, &query_time);
+		query_time_t = mktime(&query_time);
+		timespecFromTime_t(&cm_date, query_time_t);
+		if(date_setter != NULL) { date_setter(ent, cm_date); }
+	}
+	if((safe_strcmp(param->param_type, QOF_TYPE_NUMERIC) == 0)  ||
+	(safe_strcmp(param->param_type, QOF_TYPE_DEBCRED) == 0)) { 
+		numeric_setter = (void(*)(QofEntity*, gnc_numeric))param->param_setfcn;
+		string_to_gnc_numeric(insert_string, &cm_numeric);
+		if(numeric_setter != NULL) { numeric_setter(ent, cm_numeric); }
+	}
+	if(safe_strcmp(param->param_type, QOF_TYPE_GUID) == 0) { 
+		cm_guid = g_new(GUID, 1);
+		if(TRUE != string_to_guid(insert_string, cm_guid))
+		{
+			LEAVE (" string to guid failed for %s", insert_string);
+			return;
 		}
-		if(safe_strcmp(cm_param->param_type, QOF_TYPE_DATE) == 0) { 
-			date_setter = (void(*)(QofEntity*, Timespec))cm_param->param_setfcn;
-			strptime(insert_string, QOF_UTC_DATE_FORMAT, &query_time);
-			query_time_t = mktime(&query_time);
-			timespecFromTime_t(&cm_date, query_time_t);
-			if(date_setter != NULL) { date_setter(ent, cm_date); }
-		}
-		if((safe_strcmp(cm_param->param_type, QOF_TYPE_NUMERIC) == 0)  ||
-		(safe_strcmp(cm_param->param_type, QOF_TYPE_DEBCRED) == 0)) { 
-			numeric_setter = (void(*)(QofEntity*, gnc_numeric))cm_param->param_setfcn;
-			string_to_gnc_numeric(insert_string, &cm_numeric);
-			if(numeric_setter != NULL) { numeric_setter(ent, cm_numeric); }
-		}
-		if(safe_strcmp(cm_param->param_type, QOF_TYPE_GUID) == 0) { 
-			cm_guid = g_new(GUID, 1);
-			if(TRUE != string_to_guid(insert_string, cm_guid))
-			{
-				LEAVE (" string to guid failed for %s", insert_string);
-				return;
-			}
 /*			reference_type = xmlGetProp(node, QSF_OBJECT_TYPE);
-			if(0 == safe_strcmp(QOF_PARAM_GUID, reference_type)) 
-			{
-				qof_entity_set_guid(qsf_ent, cm_guid);
-			}
-			else {
-				reference = qof_entity_get_reference_from(qsf_ent, cm_param);
-				if(reference) {
-					params->referenceList = g_list_append(params->referenceList, reference);
-				}
-			}*/
+		if(0 == safe_strcmp(QOF_PARAM_GUID, reference_type)) 
+		{
+			qof_entity_set_guid(qsf_ent, cm_guid);
 		}
-		if(safe_strcmp(cm_param->param_type, QOF_TYPE_INT32) == 0) { 
-			errno = 0;
-			cm_i32 = (gint32)strtol (insert_string, &tail, 0);
-			if(errno == 0) {
-				i32_setter = (void(*)(QofEntity*, gint32))cm_param->param_setfcn;
-				if(i32_setter != NULL) { i32_setter(ent, cm_i32); }
+		else {
+			reference = qof_entity_get_reference_from(qsf_ent, cm_param);
+			if(reference) {
+				params->referenceList = g_list_append(params->referenceList, reference);
 			}
-//			else { qof_backend_set_error(params->be, ERR_QSF_OVERFLOW); }
+		}*/
+	}
+	if(safe_strcmp(param->param_type, QOF_TYPE_INT32) == 0) { 
+		errno = 0;
+		cm_i32 = (gint32)strtol (insert_string, &tail, 0);
+		if(errno == 0) {
+			i32_setter = (void(*)(QofEntity*, gint32))param->param_setfcn;
+			if(i32_setter != NULL) { i32_setter(ent, cm_i32); }
 		}
-		if(safe_strcmp(cm_param->param_type, QOF_TYPE_INT64) == 0) { 
-			errno = 0;
-			cm_i64 = strtoll(insert_string, &tail, 0);
-			if(errno == 0) {
-				i64_setter = (void(*)(QofEntity*, gint64))cm_param->param_setfcn;
-				if(i64_setter != NULL) { i64_setter(ent, cm_i64); }
-			}
-//			else { qof_backend_set_error(params->be, ERR_QSF_OVERFLOW); }
+		else 
+		{
+			QofBackend  *backend;
+			QofBook     *book;
+
+			book = qof_instance_get_book((QofInstance*)ent);
+			backend = qof_book_get_backend(book);
+			qof_backend_set_error(backend, ERR_QSF_OVERFLOW);
 		}
-		if(safe_strcmp(cm_param->param_type, QOF_TYPE_DOUBLE) == 0) { 
-			errno = 0;
-			cm_double = strtod(insert_string, &tail);
-			if(errno == 0) {
-				double_setter = (void(*)(QofEntity*, double))cm_param->param_setfcn;
-				if(double_setter != NULL) { double_setter(ent, cm_double); }
-			}
+	}
+	if(safe_strcmp(param->param_type, QOF_TYPE_INT64) == 0) { 
+		errno = 0;
+		cm_i64 = strtoll(insert_string, &tail, 0);
+		if(errno == 0) {
+			i64_setter = (void(*)(QofEntity*, gint64))param->param_setfcn;
+			if(i64_setter != NULL) { i64_setter(ent, cm_i64); }
 		}
-		if(safe_strcmp(cm_param->param_type, QOF_TYPE_BOOLEAN) == 0){ 
-			if(0 == safe_strcmp(insert_string, "TRUE")) {
-				cm_boolean = TRUE;
-			}
-			else { cm_boolean = FALSE; }
-			boolean_setter = (void(*)(QofEntity*, gboolean))cm_param->param_setfcn;
-			if(boolean_setter != NULL) { boolean_setter(ent, cm_boolean); }
+		else 
+		{
+			QofBackend  *backend;
+			QofBook     *book;
+
+			book = qof_instance_get_book((QofInstance*)ent);
+			backend = qof_book_get_backend(book);
+			qof_backend_set_error(backend, ERR_QSF_OVERFLOW);
 		}
-			if(safe_strcmp(cm_param->param_type, QOF_TYPE_KVP) == 0) { 
-				
-			}
-		if(safe_strcmp(cm_param->param_type, QOF_TYPE_CHAR) == 0) { 
-			cm_char = *insert_string;
-			char_setter = (void(*)(QofEntity*, char))cm_param->param_setfcn;
-			if(char_setter != NULL) { char_setter(ent, cm_char); }
+	}
+	if(safe_strcmp(param->param_type, QOF_TYPE_DOUBLE) == 0) { 
+		errno = 0;
+		cm_double = strtod(insert_string, &tail);
+		if(errno == 0) {
+			double_setter = (void(*)(QofEntity*, double))param->param_setfcn;
+			if(double_setter != NULL) { double_setter(ent, cm_double); }
 		}
-		param_list = param_list->next;
 	}
+	if(safe_strcmp(param->param_type, QOF_TYPE_BOOLEAN) == 0) {
+		gint b;
+		b = qof_util_bool_to_int(insert_string);
+		if(b == 1) {
+			cm_boolean = TRUE;
+		}
+		else { cm_boolean = FALSE; }
+		boolean_setter = (void(*)(QofEntity*, gboolean))param->param_setfcn;
+		if(boolean_setter != NULL) { boolean_setter(ent, cm_boolean); }
+	}
+	if(safe_strcmp(param->param_type, QOF_TYPE_KVP) == 0) {
+			
+	}
+	if(safe_strcmp(param->param_type, QOF_TYPE_CHAR) == 0) { 
+		cm_char = *insert_string;
+		char_setter = (void(*)(QofEntity*, char))param->param_setfcn;
+		if(char_setter != NULL) { char_setter(ent, cm_char); }
+	}
+	LEAVE (" ");
 }
 
-static QofEntity*
-qof_query_insert(QofSqlQuery *query)
+static void
+qof_query_set_insert_table(QofSqlQuery *query)
 {
-	QofIdType type;
-	QofInstance *inst;
 	sql_insert_statement *sis;
 	sql_table *sis_t;
-
-	query->param_list = NULL;
-	type = NULL;
 	sis = query->parse_result->statement;
 	switch(sis->table->type) {
 		case SQL_simple: {
 			sis_t = sis->table;
 			query->single_global_tablename = g_strdup_printf("%s", sis_t->d.simple);
-			type = g_strdup(query->single_global_tablename);
+			qof_query_search_for (query->qof_query, query->single_global_tablename);
+			PINFO (" insert set to table: %s", sis_t->d.simple);
 			break;
 		}
 		default: {
-			fprintf(stderr, "default");
+			PWARN ("SQL insert only handles simple statements");
 		}
 	}
-	inst = (QofInstance*)qof_object_new_instance(type, query->book);
-	if(inst == NULL) { return NULL; }
+}
+
+static QofEntity*
+qof_query_insert(QofSqlQuery *query)
+{
+	GList *field_list, *value_list, *cur;
+	const gchar *param_name;
+	gchar *value;
+	QofIdType type;
+	const QofParam *param;
+	QofInstance *inst;
+	sql_insert_statement *sis;
+	sql_field *field;
+	sql_field_item *item;
+
+	ENTER (" ");
 	query->param_list = NULL;
+	type = NULL;
+	param = NULL;
+	value = NULL;
+	field_list = NULL;
+	value_list = NULL;
+	param_name = NULL;
+	sis = query->parse_result->statement;
+	if (!sis->fields || !sis->values) { LEAVE (" NULL insert statement"); return NULL; }
+	type = g_strdup(query->single_global_tablename);
+	inst = (QofInstance*)qof_object_new_instance(type, query->book);
+	if(inst == NULL) 
+	{ 
+		LEAVE (" unable to create instance of type %s", type); 
+		return NULL; 
+	}
 	query->inserted_entity = &inst->entity;
-	qof_class_param_foreach((QofIdTypeConst)type, qof_queryForeachParam, query);
-	g_list_foreach(query->param_list, qof_sql_insertCB, query);
+	value_list = sis->values;
+	for (field_list = sis->fields; field_list != NULL; field_list = field_list->next) 
+	{
+		field = value_list->data;
+		item = field->item;
+		for (cur = item->d.name; cur != NULL; cur = cur->next)
+		{
+			value = g_strdup_printf("%s", dequote_string((char*)cur->data));
+		}
+		field = field_list->data;
+		item = field->item;
+		for (cur = item->d.name; cur != NULL; cur = cur->next)
+		{
+			param_name = g_strdup_printf("%s", (char*)cur->data);
+			param = qof_class_get_parameter(type, param_name);
+		}
+		if(param && value) {
+			qof_sql_insertCB(param, value, query);
+		}
+		value_list = g_list_next(value_list);
+	}
+	LEAVE (" ");
 	return query->inserted_entity;
 }
 
@@ -817,9 +802,9 @@
 	char *buf;
 	sql_select_statement *sss;
 	sql_where *swear;
-	
-	if (!query) return;
 
+	if (!query) return;
+    ENTER (" ");
 	/* Delete old query, if any */
 	if (query->qof_query)
 	{
@@ -835,13 +820,13 @@
 
 	if (!query->parse_result) 
 	{
-		PWARN ("parse error"); 
+		LEAVE ("parse error"); 
 		return;
 	}
 
 	if ((SQL_select != query->parse_result->type)&&(SQL_insert != query->parse_result->type))
 	{
-		PWARN("currently, only SELECT or INSERT statements are supported, "
+		LEAVE ("currently, only SELECT or INSERT statements are supported, "
 		         "got type=%s", sql_type_as_string(query->parse_result->type));
 		return;
 	}
@@ -859,6 +844,8 @@
 	/* if this is an insert, we're done with the parse. */
 	if(SQL_insert == query->parse_result->type) {
 		query->qof_query = qof_query_create();
+		qof_query_set_insert_table(query);
+		LEAVE (" insert statement parsed OK");
 		return;
 	}
 	sss = query->parse_result->statement;
@@ -867,7 +854,7 @@
 	{
 		/* Walk over the where terms, turn them into QOF predicates */
 		query->qof_query = handle_where (query, swear);
-		if (NULL == query->qof_query) return;
+		if (NULL == query->qof_query) { LEAVE (" no query found"); return; }
 	}
 	else
 	{
@@ -877,11 +864,11 @@
 	handle_sort_order (query, sss->order);
 
 	/* We also want to set the type of thing to search for.
-	 * If the user said SELECT * FROM ... then we should return
-	 * a list of QofEntity.  Otherwise, we return ... ?
-	 * XXX all this needs fixing.
+	 * SELECT * FROM table1, table2, ... is not supported.
+	 * Use sequential queries and build a partial book.
 	 */
 	qof_query_search_for (query->qof_query, query->single_global_tablename);
+	LEAVE (" success");
 }
 
 /* ========================================================== */
@@ -902,7 +889,12 @@
 		results = g_list_append(results, qof_query_insert(query));
 		return results;
 	}
-	qof_query_print (query->qof_query);
+    /* Maybe log this sucker */
+    if (gnc_should_log (log_module, GNC_LOG_DETAIL)) 
+	{
+		qof_query_print (query->qof_query);
+	}
+
 	results = qof_query_run (query->qof_query);
 
 	return results;
@@ -919,7 +911,12 @@
 
 	qof_query_set_book (query->qof_query, query->book);
 
-	// qof_query_print (query->qof_query);
+    /* Maybe log this sucker */
+    if (gnc_should_log (log_module, GNC_LOG_DETAIL)) 
+	{
+		qof_query_print (query->qof_query);
+	}
+
 	results = qof_query_run (query->qof_query);
 
 	return results;

Modified: gnucash/trunk/lib/libqof/qof/qofsql.h
===================================================================
--- gnucash/trunk/lib/libqof/qof/qofsql.h	2006-01-08 14:57:07 UTC (rev 12298)
+++ gnucash/trunk/lib/libqof/qof/qofsql.h	2006-01-08 17:51:29 UTC (rev 12299)
@@ -1,5 +1,5 @@
 /********************************************************************\
- * qofsql.h -- QOF client-side SQL parser                           *
+ * qofsql.h -- QOF client-side SQL parser using libgda              *
  *                                                                  *
  * This program is free software; you can redistribute it and/or    *
  * modify it under the terms of the GNU General Public License as   *
@@ -24,7 +24,7 @@
 @{ */
 /**
     @file qofsql.h
-    @brief QOF client-side SQL parser.
+    @brief QOF client-side SQL parser, interfacing with libgda.
     @author Copyright (C) 2004 Linas Vepstas <linas at linas.org>
 */
 
@@ -197,5 +197,5 @@
 void qof_sql_query_set_kvp (QofSqlQuery *, KvpFrame *);
 
 /** @} */
+/** @} */
 #endif /* QOF_SQL_QUERY_H */
-/** @} */



More information about the gnucash-changes mailing list