[Gnucash-changes] This time, I'm going to say 'cvs commit' in the correct directory.

Linas Vepstas linas at cvs.gnucash.org
Mon Apr 19 11:45:48 EDT 2004


Log Message:
-----------
This time, I'm going to say 'cvs commit' in the correct directory.
Same set of patches as before:  replace naked function call pointers 
for working with object parameters by 'clothed' paramters.
make clean; make; make install is required to get a functional system, 
because these changes change structure sizes and offsets in the engine 
libraries.  If you don't make clean; you will probably get weird,
impossible-to-find crashes.

Modified Files:
--------------
    gnucash/src/doc:
        guid.txt
    gnucash/src/engine:
        Transaction.c
        qofbook.h
        qofclass.c
        qofclass.h
        qofid.h
        qofobject.c
        qofquery.c
        qofquerycore-p.h
        qofquerycore.c
        qofquerycore.h
        qofsql.c
        qofsql.h
    gnucash/src/gnome-search:
        dialog-search.c
        gnc-general-search.c
    gnucash/src/gnome-utils:
        gnc-query-list.c
        search-param.c

Revision Data
-------------
Index: guid.txt
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/doc/guid.txt,v
retrieving revision 1.1
retrieving revision 1.2
diff -Lsrc/doc/guid.txt -Lsrc/doc/guid.txt -u -r1.1 -r1.2
--- src/doc/guid.txt
+++ src/doc/guid.txt
@@ -49,4 +49,14 @@
 same accounts, etc), but doesn't have the old transactions.
 
 
+The Issue:
+----------
+The current book-closing code makes a copy of the account tree,
+and sorts all transactions, by date, into the new or the old
+account tree.  With the goal of not confusing the new and the
+old account trees, the book closing code issues the old accounts
+a new set of guids.  The Pro's & Con's of this scheme:
+
+Pro: The 'old', closed accounts can be uniquely accessed according 
+to thier GUID's, without causing confusion with similar/same.
 
Index: qofsql.h
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/qofsql.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -Lsrc/engine/qofsql.h -Lsrc/engine/qofsql.h -u -r1.2 -r1.3
--- src/engine/qofsql.h
+++ src/engine/qofsql.h
@@ -1,5 +1,5 @@
 /********************************************************************\
- * qofsql.h -- QOF cleint-side SQL parser                           *
+ * qofsql.h -- QOF client-side SQL parser                           *
  *                                                                  *
  * This program is free software; you can redistribute it and/or    *
  * modify it under the terms of the GNU General Public License as   *
@@ -20,6 +20,8 @@
  *                                                                  *
 \********************************************************************/
 
+/** @addtogroup Engine
+    @{ */
 /**
     @file qofsql.h
     @breif QOF client-side SQL parser.
@@ -111,3 +113,4 @@
 void qof_sql_query_set_kvp (QofSqlQuery *, KvpFrame *);
 
 #endif /* QOF_SQL_QUERY_H */
+/** @} */
Index: qofquery.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/qofquery.c,v
retrieving revision 1.21
retrieving revision 1.22
diff -Lsrc/engine/qofquery.c -Lsrc/engine/qofquery.c -u -r1.21 -r1.22
--- src/engine/qofquery.c
+++ src/engine/qofquery.c
@@ -72,9 +72,9 @@
    * convert types.
    */
   gboolean            use_default;
-  GSList *            param_fcns;
+  GSList *            param_fcns;     /* Chain of paramters to walk */
   QofSortFunc         obj_cmp;        /* In case you are comparing objects */
-  QofCompareFunc      comp_fcn;        /* When you are comparing core types */
+  QofCompareFunc      comp_fcn;       /* When you are comparing core types */
 };
 
 /* The QUERY structure */
@@ -280,9 +280,9 @@
 static int cmp_func (QofQuerySort *sort, QofSortFunc default_sort,
                      gconstpointer a, gconstpointer b)
 {
+  QofParam *param = NULL;
   GSList *node;
   gpointer conva, convb;
-  QofAccessFunc get_fcn = NULL;        /* to appease the compiler */
 
   g_return_val_if_fail (sort, 0);
 
@@ -304,7 +304,7 @@
   convb = (gpointer)b;
   for (node = sort->param_fcns; node; node = node->next) 
   {
-    get_fcn = node->data;
+    param = node->data;
 
     /* The last term is really the "parameter getter",
      * unless we're comparing objects ;) */
@@ -312,13 +312,14 @@
       break;
 
     /* Do the converstions */
-    conva = get_fcn (conva);
-    convb = get_fcn (convb);
+    conva = (param->param_getfcn) (conva, param);
+    convb = (param->param_getfcn) (convb, param);
   }
+
   /* And now return the (appropriate) compare */
   if (sort->comp_fcn)
   {
-    int rc = sort->comp_fcn (conva, convb, sort->options, get_fcn);
+    int rc = sort->comp_fcn (conva, convb, sort->options, param);
     return rc;
   }
 
@@ -381,21 +382,21 @@
       if (qt->param_fcns && qt->pred_fcn) 
       {
         GSList *node;
-        QofAccessFunc get_fcn;
+        QofParam *param = NULL;
         gpointer conv_obj = object;
 
         /* iterate through the conversions */
-        for (node = qt->param_fcns; node; node = node->next) {
-          get_fcn = node->data;
+        for (node = qt->param_fcns; node; node = node->next) 
+        {
+          param = node->data;
 
           /* The last term is the actual parameter getter */
-          if (!node->next)
-            break;
+          if (!node->next) break;
 
-          conv_obj = get_fcn (conv_obj);
+          conv_obj = param->param_getfcn (conv_obj, param);
         }
 
-        if (((qt->pred_fcn)(conv_obj, get_fcn, qt->pdata)) == qt->invert) 
+        if (((qt->pred_fcn)(conv_obj, param, qt->pdata)) == qt->invert) 
         {
           and_terms_ok = 0;
           break;
@@ -428,8 +429,9 @@
  *
  * returns NULL if the first parameter is bad (and final is unchanged).
  */
-static GSList * compile_params (GSList *param_list, QofIdType start_obj,
-                                QofParam const **final)
+static GSList * 
+compile_params (GSList *param_list, QofIdType start_obj, 
+                QofParam const **final)
 {
   const QofParam *objDef = NULL;
   GSList *fcns = NULL;
@@ -447,8 +449,8 @@
     /* If it doesn't exist, then we've reached the end */
     if (!objDef) break;
 
-    /* Save off this function */
-    fcns = g_slist_prepend (fcns, objDef->param_getfcn);
+    /* Save off this parameter */
+    fcns = g_slist_prepend (fcns, (gpointer) objDef);
 
     /* Save this off, just in case */
     *final = objDef;
@@ -742,7 +744,7 @@
         }
       }
 
-      /* and then iterate over all the objects */
+      /* And then iterate over all the objects */
       qof_object_foreach (q->search_for, book, (QofEntityForeachCB) check_item_cb, &qcb);
     }
 
Index: qofid.h
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/qofid.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -Lsrc/engine/qofid.h -Lsrc/engine/qofid.h -u -r1.8 -r1.9
--- src/engine/qofid.h
+++ src/engine/qofid.h
@@ -134,7 +134,12 @@
 void qof_collection_foreach (QofCollection *, 
                        QofEntityForeachCB, gpointer user_data);
 
-/** store and retreive arbitrary object-defined data */
+/** Store and retreive arbitrary object-defined data 
+ *
+ * XXX We need to add a callback for when the collection is being
+ * destroyed, so that the user has a chance to clean up anything
+ * that was put in the 'data' member here.
+ */
 gpointer qof_collection_get_data (QofCollection *col);
 void qof_collection_set_data (QofCollection *col, gpointer user_data);
 
Index: Transaction.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/Transaction.c,v
retrieving revision 1.304
retrieving revision 1.305
diff -Lsrc/engine/Transaction.c -Lsrc/engine/Transaction.c -u -r1.304 -r1.305
--- src/engine/Transaction.c
+++ src/engine/Transaction.c
@@ -3196,7 +3196,7 @@
 };
 
 static gpointer 
-split_account_guid_getter (gpointer obj)
+split_account_guid_getter (gpointer obj, const QofParam *p)
 {
   Split *s = obj;
   Account *acc;
@@ -3214,7 +3214,8 @@
   return gnc_numeric_to_double(xaccSplitGetAmount(split));
 }
 
-static gpointer no_op (gpointer obj)
+static gpointer 
+no_op (gpointer obj, const QofParam *p)
 {
   return obj;
 }
Index: qofquerycore.h
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/qofquerycore.h,v
retrieving revision 1.11
retrieving revision 1.12
diff -Lsrc/engine/qofquerycore.h -Lsrc/engine/qofquerycore.h -u -r1.11 -r1.12
--- src/engine/qofquerycore.h
+++ src/engine/qofquerycore.h
@@ -146,7 +146,6 @@
 /** Return a printable string for a core data object.  Caller needs
  *  to g_free() the returned string.
  */
-char * qof_query_core_to_string (char const *type, gpointer object,
-			     QofAccessFunc fcn);
+char * qof_query_core_to_string (QofType, gpointer object, QofParam *getter);
 
 #endif /* QOF_QUERYCORE_H */
Index: qofquerycore.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/qofquerycore.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -Lsrc/engine/qofquerycore.c -Lsrc/engine/qofquerycore.c -u -r1.12 -r1.13
--- src/engine/qofquerycore.c
+++ src/engine/qofquerycore.c
@@ -39,69 +39,51 @@
 /* A function to copy a query's predicate data */
 typedef QofQueryPredData *(*QueryPredicateCopyFunc) (QofQueryPredData *pdata);
 
-/* A function to take the object, apply the get_fcn, and return
- * a printable string.  Note that this QofAccessFunc function should
- * be returning a type equal to this core object type.
+/* 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.
  *
  * Note that this string MUST be freed by the caller.
  */
-typedef char * (*QueryToString) (gpointer object, QofAccessFunc get_fcn);
+typedef char * (*QueryToString) (gpointer object, QofParam *getter);
 
 /* A function to test for equality of predicate data */
 typedef gboolean (*QueryPredicateEqual) (QofQueryPredData *p1, 
                                          QofQueryPredData *p2);
 
-/* This function registers a new Core Object with the QofQuery
- * subsystem.  It maps the "core_name" object to the given
- * query_predicate, predicate_copy, and predicate_data_free functions.
- */
-static void qof_query_register_core_object (char const *type_name,
-                                 QofQueryPredicateFunc pred,
-                                 QofCompareFunc comp,
-                                 QueryPredicateCopyFunc copy,
-                                 QueryPredDataFree pd_free,
-                                 QueryToString to_string,
-                                 QueryPredicateEqual pred_equal);
-/* An example:
- *
- * qof_query_register_core_object (QOF_TYPE_STRING, string_match_predicate,
- *                               string_compare_fcn, string_free_pdata,
- *                               string_print_fcn, pred_equal_fcn);
- */
-
-static QueryPredicateCopyFunc gncQueryCoreGetCopy (char const *type);
-static QueryPredDataFree gncQueryCoreGetPredFree (char const *type);
+static QueryPredicateCopyFunc qof_query_copy_predicate (QofType type);
+static QueryPredDataFree qof_query_predicate_free (QofType type);
 
 /* Core Type Predicate helpers */
-typedef const char * (*query_string_getter) (gpointer);
+typedef const char * (*query_string_getter) (gpointer, QofParam *);
 static const char * query_string_type = QOF_TYPE_STRING;
 
-typedef Timespec (*query_date_getter) (gpointer);
+typedef Timespec (*query_date_getter) (gpointer, QofParam *);
 static const char * query_date_type = QOF_TYPE_DATE;
 
-typedef gnc_numeric (*query_numeric_getter) (gpointer);
+typedef gnc_numeric (*query_numeric_getter) (gpointer, QofParam *);
 static const char * query_numeric_type = QOF_TYPE_NUMERIC;
 
-typedef GList * (*query_glist_getter) (gpointer);
-typedef const GUID * (*query_guid_getter) (gpointer);
+typedef GList * (*query_glist_getter) (gpointer, QofParam *);
+typedef const GUID * (*query_guid_getter) (gpointer, QofParam *);
 static const char * query_guid_type = QOF_TYPE_GUID;
 
-typedef gint32 (*query_int32_getter) (gpointer);
+typedef gint32 (*query_int32_getter) (gpointer, QofParam *);
 static const char * query_int32_type = QOF_TYPE_INT32;
 
-typedef gint64 (*query_int64_getter) (gpointer);
+typedef gint64 (*query_int64_getter) (gpointer, QofParam *);
 static const char * query_int64_type = QOF_TYPE_INT64;
 
-typedef double (*query_double_getter) (gpointer);
+typedef double (*query_double_getter) (gpointer, QofParam *);
 static const char * query_double_type = QOF_TYPE_DOUBLE;
 
-typedef gboolean (*query_boolean_getter) (gpointer);
+typedef gboolean (*query_boolean_getter) (gpointer, QofParam *);
 static const char * query_boolean_type = QOF_TYPE_BOOLEAN;
 
-typedef char (*query_char_getter) (gpointer);
+typedef char (*query_char_getter) (gpointer, QofParam *);
 static const char * query_char_type = QOF_TYPE_CHAR;
 
-typedef KvpFrame * (*query_kvp_getter) (gpointer);
+typedef KvpFrame * (*query_kvp_getter) (gpointer, QofParam *);
 static const char * query_kvp_type = QOF_TYPE_KVP;
 
 /* Tables for predicate storage and lookup */
@@ -128,7 +110,8 @@
                                 NULL); \
 }
 #define VERIFY_PREDICATE(str) { \
-        g_return_val_if_fail (get_fcn != NULL, PREDICATE_ERROR); \
+        g_return_val_if_fail (getter != NULL, PREDICATE_ERROR); \
+        g_return_val_if_fail (getter->param_getfcn != NULL, PREDICATE_ERROR); \
         g_return_val_if_fail (pd != NULL, PREDICATE_ERROR); \
         g_return_val_if_fail (pd->type_name == str || \
                                 !safe_strcmp (str, pd->type_name), \
@@ -140,8 +123,10 @@
 
 /* QOF_TYPE_STRING */
 
-static int string_match_predicate (gpointer object, QofAccessFunc get_fcn,
-                                   QofQueryPredData *pd)
+static int 
+string_match_predicate (gpointer object, 
+                        QofParam *getter,
+                        QofQueryPredData *pd)
 {
   query_string_t pdata = (query_string_t) pd;
   const char *s;
@@ -149,7 +134,7 @@
 
   VERIFY_PREDICATE (query_string_type);
 
-  s = ((query_string_getter)get_fcn) (object);
+  s = ((query_string_getter)getter->param_getfcn) (object, getter);
 
   if (!s) s = "";
 
@@ -178,14 +163,15 @@
   }
 }
 
-static int string_compare_func (gpointer a, gpointer b, gint options,
-                                QofAccessFunc get_fcn)
+static int 
+string_compare_func (gpointer a, gpointer b, gint options,
+                     QofParam *getter)
 {
   const char *s1, *s2;
-  g_return_val_if_fail (a && b && get_fcn, COMPARE_ERROR);
+  g_return_val_if_fail (a && b && getter &&getter->param_getfcn, COMPARE_ERROR);
 
-  s1 = ((query_string_getter)get_fcn) (a);
-  s2 = ((query_string_getter)get_fcn) (b);
+  s1 = ((query_string_getter)getter->param_getfcn) (a, getter);
+  s2 = ((query_string_getter)getter->param_getfcn) (b, getter);
 
   if (options == QOF_STRING_MATCH_CASEINSENSITIVE)
     return safe_strcasecmp (s1, s2);
@@ -193,7 +179,8 @@
   return safe_strcmp (s1, s2);
 }
 
-static void string_free_pdata (QofQueryPredData *pd)
+static void 
+string_free_pdata (QofQueryPredData *pd)
 {
   query_string_t pdata = (query_string_t) pd;
 
@@ -207,18 +194,20 @@
   g_free (pdata);
 }
 
-static QofQueryPredData *string_copy_predicate (QofQueryPredData *pd)
+static QofQueryPredData *
+string_copy_predicate (QofQueryPredData *pd)
 {
   query_string_t pdata = (query_string_t) pd;
 
   VERIFY_PDATA_R (query_string_type);
 
-  return qof_query_string_predicate (pd->how, pdata->matchstring, pdata->options,
-                                  pdata->is_regex);
+  return qof_query_string_predicate (pd->how, pdata->matchstring, 
+                                     pdata->options,
+                                     pdata->is_regex);
 }
 
-static gboolean string_predicate_equal (QofQueryPredData *p1,
-QofQueryPredData *p2)
+static gboolean 
+string_predicate_equal (QofQueryPredData *p1, QofQueryPredData *p2)
 {
   query_string_t pd1 = (query_string_t) p1;
   query_string_t pd2 = (query_string_t) p2;
@@ -228,9 +217,10 @@
   return (safe_strcmp (pd1->matchstring, pd2->matchstring) == 0);
 }
 
-QofQueryPredData *qof_query_string_predicate (QofQueryCompare how,
-                                         char *str, QofStringMatch options,
-                                         gboolean is_regex)
+QofQueryPredData *
+qof_query_string_predicate (QofQueryCompare how,
+                            char *str, QofStringMatch options,
+                            gboolean is_regex)
 {
   query_string_t pdata;
 
@@ -256,17 +246,20 @@
   return ((QofQueryPredData*)pdata);
 }
 
-static char * string_to_string (gpointer object, QofAccessFunc get)
+static char * 
+string_to_string (gpointer object, QofParam *getter)
 {
-  const char *res = ((query_string_getter)get)(object);
+  const char *res;
+  res = ((query_string_getter)getter->param_getfcn)(object, getter);
   if (res)
     return g_strdup (res);
   return NULL;
 }
 
-/* QOF_TYPE_DATE */
+/* QOF_TYPE_DATE =================================================== */
 
-static int date_compare (Timespec ta, Timespec tb, QofDateMatch options)
+static int 
+date_compare (Timespec ta, Timespec tb, QofDateMatch options)
 {
   if (options == QOF_DATE_MATCH_ROUNDED) {
     ta = timespecCanonicalDayTime (ta);
@@ -286,7 +279,8 @@
   return 0;
 }
 
-static int date_match_predicate (gpointer object, QofAccessFunc get_fcn,
+static int 
+date_match_predicate (gpointer object, QofParam *getter,
                                  QofQueryPredData *pd)
 {
   query_date_t pdata = (query_date_t)pd;
@@ -295,7 +289,7 @@
 
   VERIFY_PREDICATE (query_date_type);
 
-  objtime = ((query_date_getter)get_fcn) (object);
+  objtime = ((query_date_getter)getter->param_getfcn) (object, getter);
   compare = date_compare (objtime, pdata->date, pdata->options);
 
   switch (pd->how) {
@@ -317,20 +311,21 @@
   }
 }
 
-static int date_compare_func (gpointer a, gpointer b, gint options,
-                              QofAccessFunc get_fcn)
+static int 
+date_compare_func (gpointer a, gpointer b, gint options, QofParam *getter)
 {
   Timespec ta, tb;
 
-  g_return_val_if_fail (a && b && get_fcn, COMPARE_ERROR);
+  g_return_val_if_fail (a && b && getter && getter->param_getfcn, COMPARE_ERROR);
 
-  ta = ((query_date_getter)get_fcn) (a);
-  tb = ((query_date_getter)get_fcn) (b);
+  ta = ((query_date_getter)getter->param_getfcn) (a, getter);
+  tb = ((query_date_getter)getter->param_getfcn) (b, getter);
 
   return date_compare (ta, tb, options);
 }
 
-static void date_free_pdata (QofQueryPredData *pd)
+static void 
+date_free_pdata (QofQueryPredData *pd)
 {
   query_date_t pdata = (query_date_t)pd;
 
@@ -349,7 +344,8 @@
   return qof_query_date_predicate (pd->how, pdata->options, pdata->date);
 }
 
-static gboolean date_predicate_equal (QofQueryPredData *p1, QofQueryPredData *p2)
+static gboolean 
+date_predicate_equal (QofQueryPredData *p1, QofQueryPredData *p2)
 {
   query_date_t pd1 = (query_date_t) p1;
   query_date_t pd2 = (query_date_t) p2;
@@ -360,7 +356,7 @@
 
 QofQueryPredData *
 qof_query_date_predicate (QofQueryCompare how,
-                                       QofDateMatch options, Timespec date)
+                          QofDateMatch options, Timespec date)
 {
   query_date_t pdata;
 
@@ -372,9 +368,10 @@
   return ((QofQueryPredData*)pdata);
 }
 
-static char * date_to_string (gpointer object, QofAccessFunc get)
+static char * 
+date_to_string (gpointer object, QofParam *getter)
 {
-  Timespec ts = ((query_date_getter)get)(object);
+  Timespec ts = ((query_date_getter)getter->param_getfcn)(object, getter);
 
   if (ts.tv_sec || ts.tv_nsec)
     return g_strdup (gnc_print_date (ts));
@@ -382,10 +379,11 @@
   return NULL;
 }
 
-/* QOF_TYPE_NUMERIC */
+/* QOF_TYPE_NUMERIC ================================================= */
 
-static int numeric_match_predicate (gpointer object, QofAccessFunc get_fcn,
-                                    QofQueryPredData* pd)
+static int 
+numeric_match_predicate (gpointer object, QofParam *getter,
+                         QofQueryPredData* pd)
 {
   query_numeric_t pdata = (query_numeric_t)pd;
   gnc_numeric obj_val;
@@ -393,7 +391,7 @@
 
   VERIFY_PREDICATE (query_numeric_type);
 
-  obj_val = ((query_numeric_getter)get_fcn) (object);
+  obj_val = ((query_numeric_getter)getter->param_getfcn) (object, getter);
 
   switch (pdata->options) {
   case QOF_NUMERIC_MATCH_CREDIT:
@@ -436,20 +434,21 @@
   }
 }
 
-static int numeric_compare_func (gpointer a, gpointer b, gint options,
-                                 QofAccessFunc get_fcn)
+static int 
+numeric_compare_func (gpointer a, gpointer b, gint options, QofParam *getter)
 {
   gnc_numeric va, vb;
 
-  g_return_val_if_fail (a && b && get_fcn, COMPARE_ERROR);
+  g_return_val_if_fail (a && b && getter && getter->param_getfcn, COMPARE_ERROR);
 
-  va = ((query_numeric_getter)get_fcn) (a);
-  vb = ((query_numeric_getter)get_fcn) (b);
+  va = ((query_numeric_getter)getter->param_getfcn) (a, getter);
+  vb = ((query_numeric_getter)getter->param_getfcn) (b, getter);
 
   return gnc_numeric_compare (va, vb);  
 }
 
-static void numeric_free_pdata (QofQueryPredData* pd)
+static void 
+numeric_free_pdata (QofQueryPredData* pd)
 {
   query_numeric_t pdata = (query_numeric_t)pd;
   VERIFY_PDATA (query_numeric_type);
@@ -476,8 +475,8 @@
 
 QofQueryPredData *
 qof_query_numeric_predicate (QofQueryCompare how,
-                                          QofNumericMatch options,
-                                          gnc_numeric value)
+                             QofNumericMatch options,
+                             gnc_numeric value)
 {
   query_numeric_t pdata;
   pdata = g_new0 (query_numeric_def, 1);
@@ -488,24 +487,29 @@
   return ((QofQueryPredData*)pdata);
 }
 
-static char * numeric_to_string (gpointer object, QofAccessFunc get)
+static char * 
+numeric_to_string (gpointer object, QofParam *getter)
 {
-  gnc_numeric num = ((query_numeric_getter)get)(object);
+  gnc_numeric num;
+  num = ((query_numeric_getter)getter->param_getfcn)(object, getter);
 
   return g_strdup (gnc_numeric_to_string (num));
 }
 
-static char * debcred_to_string (gpointer object, QofAccessFunc get)
+static char * 
+debcred_to_string (gpointer object, QofParam *getter)
 {
-  gnc_numeric num = ((query_numeric_getter)get)(object);
+  gnc_numeric num;
+  num = ((query_numeric_getter)getter->param_getfcn)(object, getter);
 
   return g_strdup (gnc_numeric_to_string (num));
 }
 
-/* QOF_TYPE_GUID */
+/* QOF_TYPE_GUID =================================================== */
 
-static int guid_match_predicate (gpointer object, QofAccessFunc get_fcn,
-                                 QofQueryPredData *pd)
+static int 
+guid_match_predicate (gpointer object, QofParam *getter,
+                      QofQueryPredData *pd)
 {
   query_guid_t pdata = (query_guid_t)pd;
   GList *node, *o_list;
@@ -516,17 +520,18 @@
   switch (pdata->options) {
 
   case QOF_GUID_MATCH_ALL:
-    /* object is a GList of objects; get_fcn must be called on each one.
+    /* object is a GList of objects; param_getfcn must be called on each one.
      * See if every guid in the predicate is accounted-for in the
      * 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) {
-        guid = ((query_guid_getter)get_fcn) (o_list->data);
-        if (guid_equal (node->data, guid))
+      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)) 
           break;
       }
 
@@ -549,17 +554,19 @@
   case QOF_GUID_MATCH_LIST_ANY:
     /* object is a single object, getter returns a GList* of GUID*
      *
-     * see if any GUID* in the returned list matches any guid in the
-     * predicate match list
+     * See if any GUID* in the returned list matches any guid in the
+     * predicate match list.
      */
 
-    o_list = ((query_glist_getter)get_fcn) (object);
+    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;
       }
@@ -583,8 +590,9 @@
      * See if the guid is in the list
      */
 
-    guid = ((query_guid_getter)get_fcn) (object);
-    for (node = pdata->guids; node; node = node->next) {
+    guid = ((query_guid_getter)getter->param_getfcn) (object, getter);
+    for (node = pdata->guids; node; node = node->next) 
+    {
       if (guid_equal (node->data, guid))
         break;
     }
@@ -608,13 +616,16 @@
   }
 }
 
-static void guid_free_pdata (QofQueryPredData *pd)
+static void 
+guid_free_pdata (QofQueryPredData *pd)
 {
   query_guid_t pdata = (query_guid_t)pd;
   GList *node;
   VERIFY_PDATA (query_guid_type);
   for (node = pdata->guids; node; node = node->next)
+  {
     guid_free (node->data);
+  }
   g_list_free (pdata->guids);
   g_free (pdata);
 }
@@ -637,8 +648,10 @@
   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) 
+  {
     if (!guid_equal (l1->data, l2->data))
       return FALSE;
+  }
   return TRUE;
 }
 
@@ -653,7 +666,8 @@
   pdata->pd.type_name = query_guid_type;
   pdata->options = options;
   pdata->guids = g_list_copy (guids);
-  for (node = pdata->guids; node; node = node->next) {
+  for (node = pdata->guids; node; node = node->next) 
+  {
     GUID *guid = guid_malloc ();
     *guid = *((GUID *)node->data);
     node->data = guid;
@@ -664,15 +678,16 @@
 /* ================================================================ */
 /* QOF_TYPE_INT32 */
 
-static int int32_match_predicate (gpointer object, QofAccessFunc get_fcn,
-                                 QofQueryPredData *pd)
+static int 
+int32_match_predicate (gpointer object, QofParam *getter,
+                       QofQueryPredData *pd)
 {
   gint32 val;
   query_int32_t pdata = (query_int32_t)pd;
 
   VERIFY_PREDICATE (query_int32_type);
 
-  val = ((query_int32_getter)get_fcn) (object);
+  val = ((query_int32_getter)getter->param_getfcn) (object, getter);
 
   switch (pd->how) {
   case QOF_COMPARE_LT:
@@ -693,21 +708,23 @@
   }
 }
 
-static int int32_compare_func (gpointer a, gpointer b, gint options,
-                              QofAccessFunc get_fcn)
+static int 
+int32_compare_func (gpointer a, gpointer b, gint options,
+                    QofParam *getter)
 {
   gint32 v1, v2;
-  g_return_val_if_fail (a && b && get_fcn, COMPARE_ERROR);
+  g_return_val_if_fail (a && b && getter && getter->param_getfcn, COMPARE_ERROR);
 
-  v1 = ((query_int32_getter)get_fcn)(a);
-  v2 = ((query_int32_getter)get_fcn)(b);
+  v1 = ((query_int32_getter)getter->param_getfcn)(a, getter);
+  v2 = ((query_int32_getter)getter->param_getfcn)(b, getter);
 
   if (v1 < v2) return -1;
   if (v1 > v2) return 1;
   return 0;
 }
 
-static void int32_free_pdata (QofQueryPredData *pd)
+static void 
+int32_free_pdata (QofQueryPredData *pd)
 {
   query_int32_t pdata = (query_int32_t)pd;
   VERIFY_PDATA (query_int32_type);
@@ -741,9 +758,10 @@
   return ((QofQueryPredData*)pdata);
 }
 
-static char * int32_to_string (gpointer object, QofAccessFunc get)
+static char * 
+int32_to_string (gpointer object, QofParam *getter)
 {
-  gint32 num = ((query_int32_getter)get)(object);
+  gint32 num = ((query_int32_getter)getter->param_getfcn)(object, getter);
 
   return g_strdup_printf ("%d", num);
 }
@@ -751,15 +769,16 @@
 /* ================================================================ */
 /* QOF_TYPE_INT64 */
 
-static int int64_match_predicate (gpointer object, QofAccessFunc get_fcn,
-                                 QofQueryPredData *pd)
+static int 
+int64_match_predicate (gpointer object, QofParam *getter,
+                       QofQueryPredData *pd)
 {
   gint64 val;
   query_int64_t pdata = (query_int64_t)pd;
 
   VERIFY_PREDICATE (query_int64_type);
 
-  val = ((query_int64_getter)get_fcn) (object);
+  val = ((query_int64_getter)getter->param_getfcn) (object, getter);
 
   switch (pd->how) {
   case QOF_COMPARE_LT:
@@ -780,21 +799,23 @@
   }
 }
 
-static int int64_compare_func (gpointer a, gpointer b, gint options,
-                              QofAccessFunc get_fcn)
+static int 
+int64_compare_func (gpointer a, gpointer b, gint options,
+                              QofParam *getter)
 {
   gint64 v1, v2;
-  g_return_val_if_fail (a && b && get_fcn, COMPARE_ERROR);
+  g_return_val_if_fail (a && b && getter && getter->param_getfcn, COMPARE_ERROR);
 
-  v1 = ((query_int64_getter)get_fcn)(a);
-  v2 = ((query_int64_getter)get_fcn)(b);
+  v1 = ((query_int64_getter)getter->param_getfcn)(a, getter);
+  v2 = ((query_int64_getter)getter->param_getfcn)(b, getter);
 
   if (v1 < v2) return -1;
   if (v1 > v2) return 1;
   return 0;
 }
 
-static void int64_free_pdata (QofQueryPredData *pd)
+static void 
+int64_free_pdata (QofQueryPredData *pd)
 {
   query_int64_t pdata = (query_int64_t)pd;
   VERIFY_PDATA (query_int64_type);
@@ -828,9 +849,10 @@
   return ((QofQueryPredData*)pdata);
 }
 
-static char * int64_to_string (gpointer object, QofAccessFunc get)
+static char * 
+int64_to_string (gpointer object, QofParam *getter)
 {
-  gint64 num = ((query_int64_getter)get)(object);
+  gint64 num = ((query_int64_getter)getter->param_getfcn)(object, getter);
 
   return g_strdup_printf (GNC_SCANF_LLD, num);
 }
@@ -838,15 +860,16 @@
 /* ================================================================ */
 /* QOF_TYPE_DOUBLE */
 
-static int double_match_predicate (gpointer object, QofAccessFunc get_fcn,
-                                 QofQueryPredData *pd)
+static int 
+double_match_predicate (gpointer object, QofParam *getter,
+                        QofQueryPredData *pd)
 {
   double val;
   query_double_t pdata = (query_double_t)pd;
 
   VERIFY_PREDICATE (query_double_type);
 
-  val = ((query_double_getter)get_fcn) (object);
+  val = ((query_double_getter)getter->param_getfcn) (object, getter);
 
   switch (pd->how) {
   case QOF_COMPARE_LT:
@@ -867,21 +890,23 @@
   }
 }
 
-static int double_compare_func (gpointer a, gpointer b, gint options,
-                              QofAccessFunc get_fcn)
+static int 
+double_compare_func (gpointer a, gpointer b, gint options,
+                     QofParam *getter)
 {
   double v1, v2;
-  g_return_val_if_fail (a && b && get_fcn, COMPARE_ERROR);
+  g_return_val_if_fail (a && b && getter && getter->param_getfcn, COMPARE_ERROR);
 
-  v1 = ((query_double_getter)get_fcn) (a);
-  v2 = ((query_double_getter)get_fcn) (b);
+  v1 = ((query_double_getter)getter->param_getfcn) (a, getter);
+  v2 = ((query_double_getter)getter->param_getfcn) (b, getter);
 
   if (v1 < v2) return -1;
   if (v1 > v2) return 1;
   return 0;
 }
 
-static void double_free_pdata (QofQueryPredData *pd)
+static void 
+double_free_pdata (QofQueryPredData *pd)
 {
   query_double_t pdata = (query_double_t)pd;
   VERIFY_PDATA (query_double_type);
@@ -915,24 +940,26 @@
   return ((QofQueryPredData*)pdata);
 }
 
-static char * double_to_string (gpointer object, QofAccessFunc get)
+static char * 
+double_to_string (gpointer object, QofParam *getter)
 {
-  double num = ((query_double_getter)get)(object);
+  double num = ((query_double_getter)getter->param_getfcn)(object, getter);
 
   return g_strdup_printf ("%f", num);
 }
 
-/* QOF_TYPE_BOOLEAN */
+/* QOF_TYPE_BOOLEAN =================================================== */
 
-static int boolean_match_predicate (gpointer object, QofAccessFunc get_fcn,
-                                 QofQueryPredData *pd)
+static int 
+boolean_match_predicate (gpointer object, QofParam *getter,
+                         QofQueryPredData *pd)
 {
   gboolean val;
   query_boolean_t pdata = (query_boolean_t)pd;
 
   VERIFY_PREDICATE (query_boolean_type);
 
-  val = ((query_boolean_getter)get_fcn) (object);
+  val = ((query_boolean_getter)getter->param_getfcn) (object, getter);
 
   switch (pd->how) {
   case QOF_COMPARE_EQUAL:
@@ -945,19 +972,21 @@
   }
 }
 
-static int boolean_compare_func (gpointer a, gpointer b, gint options,
-                                 QofAccessFunc get_fcn)
+static int 
+boolean_compare_func (gpointer a, gpointer b, gint options,
+                      QofParam *getter)
 {
   gboolean va, vb;
-  g_return_val_if_fail (a && b && get_fcn, COMPARE_ERROR);
-  va = ((query_boolean_getter)get_fcn) (a);
-  vb = ((query_boolean_getter)get_fcn) (b);
+  g_return_val_if_fail (a && b && getter && getter->param_getfcn, COMPARE_ERROR);
+  va = ((query_boolean_getter)getter->param_getfcn) (a, getter);
+  vb = ((query_boolean_getter)getter->param_getfcn) (b, getter);
   if (!va && vb) return -1;
   if (va && !vb) return 1;
   return 0;
 }
 
-static void boolean_free_pdata (QofQueryPredData *pd)
+static void 
+boolean_free_pdata (QofQueryPredData *pd)
 {
   query_boolean_t pdata = (query_boolean_t)pd;
   VERIFY_PDATA (query_boolean_type);
@@ -994,16 +1023,18 @@
   return ((QofQueryPredData*)pdata);
 }
 
-static char * boolean_to_string (gpointer object, QofAccessFunc get)
+static char * 
+boolean_to_string (gpointer object, QofParam *getter)
 {
-  gboolean num = ((query_boolean_getter)get)(object);
+  gboolean num = ((query_boolean_getter)getter->param_getfcn)(object, getter);
 
   return g_strdup_printf ("%s", (num ? "X" : ""));
 }
 
-/* QOF_TYPE_CHAR */
+/* QOF_TYPE_CHAR =================================================== */
 
-static int char_match_predicate (gpointer object, QofAccessFunc get_fcn,
+static int 
+char_match_predicate (gpointer object, QofParam *getter,
                                  QofQueryPredData *pd)
 {
   char c;
@@ -1011,7 +1042,7 @@
 
   VERIFY_PREDICATE (query_char_type);
 
-  c = ((query_char_getter)get_fcn) (object);
+  c = ((query_char_getter)getter->param_getfcn) (object, getter);
 
   switch (pdata->options) {
   case QOF_CHAR_MATCH_ANY:
@@ -1026,17 +1057,18 @@
   }
 }
 
-static int char_compare_func (gpointer a, gpointer b, gint options,
-                              QofAccessFunc get_fcn)
+static int 
+char_compare_func (gpointer a, gpointer b, gint options, QofParam *getter)
 {
   char va, vb;
-  g_return_val_if_fail (a && b && get_fcn, COMPARE_ERROR);
-  va = ((query_char_getter)get_fcn)(a);
-  vb = ((query_char_getter)get_fcn)(b);
+  g_return_val_if_fail (a && b && getter && getter->param_getfcn, COMPARE_ERROR);
+  va = ((query_char_getter)getter->param_getfcn)(a, getter);
+  vb = ((query_char_getter)getter->param_getfcn)(b, getter);
   return (va-vb);
 }
 
-static void char_free_pdata (QofQueryPredData *pd)
+static void 
+char_free_pdata (QofQueryPredData *pd)
 {
   query_char_t pdata = (query_char_t)pd;
   VERIFY_PDATA (query_char_type);
@@ -1075,17 +1107,19 @@
   return ((QofQueryPredData*)pdata);
 }
 
-static char * char_to_string (gpointer object, QofAccessFunc get)
+static char * 
+char_to_string (gpointer object, QofParam *getter)
 {
-  char num = ((query_char_getter)get)(object);
+  char num = ((query_char_getter)getter->param_getfcn)(object, getter);
 
   return g_strdup_printf ("%c", num);
 }
 
-/* QOF_TYPE_KVP */
+/* QOF_TYPE_KVP ================================================ */
 
-static int kvp_match_predicate (gpointer object, QofAccessFunc get_fcn,
-                                QofQueryPredData *pd)
+static int 
+kvp_match_predicate (gpointer object, QofParam *getter,
+                     QofQueryPredData *pd)
 {
   int compare;
   KvpFrame *kvp;
@@ -1094,7 +1128,7 @@
 
   VERIFY_PREDICATE (query_kvp_type);
 
-  kvp = ((query_kvp_getter)get_fcn) (object);
+  kvp = ((query_kvp_getter)getter->param_getfcn) (object, getter);
   if (!kvp)
     return 0;
 
@@ -1127,14 +1161,16 @@
   }
 }
 
-static void kvp_free_pdata (QofQueryPredData *pd)
+static void 
+kvp_free_pdata (QofQueryPredData *pd)
 {
   query_kvp_t pdata = (query_kvp_t)pd;
   GSList *node;
 
   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;
   }
@@ -1161,8 +1197,10 @@
   n2 = pd2->path;
 
   for ( ; n1 && n2; n1 = n1->next, n2 = n2->next)
+  {
     if (safe_strcmp (n1->data, n2->data) != 0)
       return FALSE;
+  }
 
   if (n1 || n2)
     return FALSE;
@@ -1172,7 +1210,7 @@
 
 QofQueryPredData *
 qof_query_kvp_predicate (QofQueryCompare how,
-                                      GSList *path, const KvpValue *value)
+                         GSList *path, const KvpValue *value)
 {
   query_kvp_t pdata;
   GSList *node;
@@ -1190,20 +1228,63 @@
   return ((QofQueryPredData*)pdata);
 }
 
-/* initialization */
+/* initialization ================================================== */
+/** This function registers a new Core Object with the QofQuery
+ * subsystem.  It maps the "core_name" object to the given
+ * query_predicate, predicate_copy, and predicate_data_free functions.
+ *
+ * An example:
+ * qof_query_register_core_object (QOF_TYPE_STRING, string_match_predicate,
+ *                               string_compare_fcn, string_free_pdata,
+ *                               string_print_fcn, pred_equal_fcn);
+ */
+
+
+static void 
+qof_query_register_core_object (QofType core_name,
+                                QofQueryPredicateFunc pred,
+                                QofCompareFunc comp,
+                                QueryPredicateCopyFunc copy,
+                                QueryPredDataFree pd_free,
+                                QueryToString toString,
+                                QueryPredicateEqual pred_equal)
+{
+  g_return_if_fail (core_name);
+  g_return_if_fail (*core_name != '\0');
+
+  if (pred)
+    g_hash_table_insert (predTable, (char *)core_name, pred);
+
+  if (comp)
+    g_hash_table_insert (cmpTable, (char *)core_name, comp);
+
+  if (copy)
+    g_hash_table_insert (copyTable, (char *)core_name, copy);
+
+  if (pd_free)
+    g_hash_table_insert (freeTable, (char *)core_name, pd_free);
+
+  if (toString)
+    g_hash_table_insert (toStringTable, (char *)core_name, toString);
+
+  if (pred_equal)
+    g_hash_table_insert (predEqualTable, (char *)core_name, pred_equal);
+}
 
 static void init_tables (void)
 {
   unsigned int i;
-  struct {
-    char const *name;
-    QofQueryPredicateFunc pred;
-    QofCompareFunc comp;
+  struct 
+  {
+    QofType                name;
+    QofQueryPredicateFunc  pred;
+    QofCompareFunc         comp;
     QueryPredicateCopyFunc copy;
-    QueryPredDataFree pd_free;
-    QueryToString toString;
-    QueryPredicateEqual pred_equal;
-  } knownTypes[] = {
+    QueryPredDataFree      pd_free;
+    QueryToString          toString;
+    QueryPredicateEqual    pred_equal;
+  } knownTypes[] = 
+  {
     { QOF_TYPE_STRING, string_match_predicate, string_compare_func,
       string_copy_predicate, string_free_pdata, string_to_string, 
       string_predicate_equal },
@@ -1239,7 +1320,8 @@
   };
 
   /* 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,
                                 knownTypes[i].comp,
@@ -1250,7 +1332,8 @@
   }
 }
 
-static QueryPredicateCopyFunc gncQueryCoreGetCopy (char const *type)
+static QueryPredicateCopyFunc 
+qof_query_copy_predicate (QofType type)
 {
   QueryPredicateCopyFunc rc;
   g_return_val_if_fail (type, NULL);
@@ -1258,43 +1341,13 @@
   return rc;
 }
 
-static QueryPredDataFree gncQueryCoreGetPredFree (char const *type)
+static QueryPredDataFree 
+qof_query_predicate_free (QofType type)
 {
   g_return_val_if_fail (type, NULL);
   return g_hash_table_lookup (freeTable, type);
 }
 
-static void 
-qof_query_register_core_object (char const *core_name,
-                                QofQueryPredicateFunc pred,
-                                QofCompareFunc comp,
-                                QueryPredicateCopyFunc copy,
-                                QueryPredDataFree pd_free,
-                                QueryToString toString,
-                                QueryPredicateEqual pred_equal)
-{
-  g_return_if_fail (core_name);
-  g_return_if_fail (*core_name != '\0');
-
-  if (pred)
-    g_hash_table_insert (predTable, (char *)core_name, pred);
-
-  if (comp)
-    g_hash_table_insert (cmpTable, (char *)core_name, comp);
-
-  if (copy)
-    g_hash_table_insert (copyTable, (char *)core_name, copy);
-
-  if (pd_free)
-    g_hash_table_insert (freeTable, (char *)core_name, pd_free);
-
-  if (toString)
-    g_hash_table_insert (toStringTable, (char *)core_name, toString);
-
-  if (pred_equal)
-    g_hash_table_insert (predEqualTable, (char *)core_name, pred_equal);
-}
-
 /********************************************************************/
 /* PUBLISHED API FUNCTIONS */
 
@@ -1329,14 +1382,14 @@
 }
 
 QofQueryPredicateFunc
-qof_query_core_get_predicate (char const *type)
+qof_query_core_get_predicate (QofType type)
 {
   g_return_val_if_fail (type, NULL);
   return g_hash_table_lookup (predTable, type);
 }
 
 QofCompareFunc
-qof_query_core_get_compare (char const *type)
+qof_query_core_get_compare (QofType type)
 {
   g_return_val_if_fail (type, NULL);
   return g_hash_table_lookup (cmpTable, type);
@@ -1350,7 +1403,7 @@
   g_return_if_fail (pdata);
   g_return_if_fail (pdata->type_name);
 
-  free_fcn = gncQueryCoreGetPredFree (pdata->type_name);
+  free_fcn = qof_query_predicate_free (pdata->type_name);
   free_fcn (pdata);
 }
 
@@ -1362,24 +1415,24 @@
   g_return_val_if_fail (pdata, NULL);
   g_return_val_if_fail (pdata->type_name, NULL);
 
-  copy = gncQueryCoreGetCopy (pdata->type_name);
+  copy = qof_query_copy_predicate (pdata->type_name);
   return (copy (pdata));
 }
 
 char * 
-qof_query_core_to_string (char const *type, gpointer object,
-                          QofAccessFunc get)
+qof_query_core_to_string (QofType type, gpointer object,
+                          QofParam *getter)
 {
   QueryToString toString;
 
   g_return_val_if_fail (type, NULL);
   g_return_val_if_fail (object, NULL);
-  g_return_val_if_fail (get, NULL);
+  g_return_val_if_fail (getter, NULL);
 
   toString = g_hash_table_lookup (toStringTable, type);
   g_return_val_if_fail (toString, NULL);
 
-  return toString (object, get);
+  return toString (object, getter);
 }
 
 gboolean 
Index: qofsql.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/qofsql.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -Lsrc/engine/qofsql.c -Lsrc/engine/qofsql.c -u -r1.3 -r1.4
--- src/engine/qofsql.c
+++ src/engine/qofsql.c
@@ -1,5 +1,5 @@
 /********************************************************************\
- * qofsql.h -- QOF cleint-side SQL parser                           *
+ * qofsql.c -- QOF client-side SQL parser                           *
  *                                                                  *
  * This program is free software; you can redistribute it and/or    *
  * modify it under the terms of the GNU General Public License as   *
@@ -25,8 +25,6 @@
     @breif QOF client-side SQL parser.
     @author Copyright (C) 2004 Linas Vepstas <linas at linas.org>
 
-    XXX: todo: replace printf error with proper error
-        handling/reporting.
 */
 
 #include <glib.h>
@@ -34,11 +32,16 @@
 #include <qof/kvp_frame.h>
 #include <qof/gnc-date.h>
 #include <qof/gnc-numeric.h>
+#include <qof/gnc-trace.h>
 #include <qof/guid.h>
 #include <qof/qofbook.h>
 #include <qof/qofquery.h>
 #include <qof/qofsql.h>
 
+static short module = MOD_QUERY;
+
+/* =================================================================== */
+
 struct _QofSqlQuery
 {
 	sql_statement *parse_result;
@@ -168,7 +171,7 @@
 	
 	if (NULL == cond)
 	{
-		printf ("Error: missing condition\n");
+		PWARN("missing condition");
 		return NULL;
 	}
 			
@@ -177,19 +180,20 @@
 	/* XXX fix this so it can be either left or right */
 	if (NULL == cond->d.pair.left)
 	{
-		printf ("Error: missing left paramter\n");
+		PWARN("missing left paramter");
 		return NULL;
 	}
 	sql_field_item * sparam = cond->d.pair.left->item;
 	if (SQL_name != sparam->type)
 	{
-		printf ("Error: we support only paramter names\n");
+		PWARN("we support only paramter names at this time (parsed %d)",
+          sparam->type);
 		return NULL;
 	}
 	char * qparam_name = sparam->d.name->data;
 	if (NULL == qparam_name)
 	{
-		printf ("Error: we missing paramter name\n");
+		PWARN ("missing paramter name");
 		return NULL;
 	}
 
@@ -198,19 +202,19 @@
 	/* XXX fix this so it can be either left or right */
 	if (NULL == cond->d.pair.right)
 	{
-		printf ("Error: missing right paramter\n");
+		PWARN ("missing right paramter");
 		return NULL;
 	}
 	sql_field_item * svalue = cond->d.pair.right->item;
 	if (SQL_name != svalue->type)
 	{
-		printf ("Error: we support only simple values\n");
+		PWARN("we support only simple values (parsed as %d)", svalue->type);
 		return NULL;
 	}
 	char * qvalue_name = svalue->d.name->data;
 	if (NULL == qvalue_name)
 	{
-		printf ("Error: we missing value\n");
+		PWARN("missing value");
 		return NULL;
 	}
 	qvalue_name = dequote_string (qvalue_name);
@@ -222,7 +226,7 @@
 	{
 		if (NULL == query->kvp_join)
 		{
-			printf ("Error: missing kvp frame\n");
+			PWARN ("missing kvp frame");
 			return NULL;
 		}
 		KvpValue *kv = kvp_frame_get_value (query->kvp_join, qvalue_name+5);
@@ -259,7 +263,7 @@
 			case KVP_TYPE_GLIST:
 			case KVP_TYPE_NUMERIC:
 			case KVP_TYPE_FRAME:
-				printf ("Error: unhandled kvp type=%d\n", kvt);
+				PWARN ("unhandled kvp type=%d", kvt);
 				return NULL;
 		}
 	}
@@ -281,7 +285,7 @@
 		default:
 			/* XXX for string-type queries, we should be able to
 			 * support 'IN' for substring search.  Also regex. */
-			printf ("Error: unsupported compare op for now\n");
+			PWARN ("Unsupported compare op (parsed as %s)", cond->op);
 			return NULL;
 	}
 
@@ -298,11 +302,12 @@
 		
 	if (NULL == table_name)
 	{
-		printf ("Error: Need to specify a table to query\n");
+		PWARN ("Need to specify an object class to query");
 		return NULL;
 	}
 			
 	QofType param_type = qof_class_get_parameter_type (table_name, param_name);
+	if (!param_type) return NULL;  /* Can't happen */
 
 	if (!strcmp (param_type, QOF_TYPE_STRING))
 	{
@@ -347,7 +352,7 @@
 		int rc = qof_scan_date_secs (qvalue_name, &exact);
 		if (0 == rc) 
 		{
-			printf ("Error: unable to parse date: %s\n", qvalue_name);
+			PWARN ("unable to parse date: %s", qvalue_name);
 			return NULL;
 		}
 		Timespec ts;
@@ -374,7 +379,7 @@
 		gboolean rc = string_to_guid (qvalue_name, guid);
 		if (0 == rc)
 		{
-			printf ("Error: unable to parse guid: %s\n", qvalue_name);
+			PWARN ("unable to parse guid: %s", qvalue_name);
 			return NULL;
 		}
 
@@ -395,7 +400,7 @@
 #endif
 	else
 	{
-		printf ("Error: predicate type unsupported for now \n");
+		PWARN ("The predicate type \"%s\" is unsupported for now", param_type);
 		return NULL;
 	}
 
@@ -510,14 +515,14 @@
 
 	if (!query->parse_result) 
 	{
-		printf ("parse error\n"); // XXX replace 
+		PWARN ("parse error"); 
 		return NULL;
 	}
 
 	if (SQL_select != query->parse_result->type)
 	{
-		printf ("Error: currently, only SELECT statements are supported, "
-		                     "got type=%d\n", query->parse_result);
+		PWARN("currently, only SELECT statements are supported, "
+		                     "got type=%d", query->parse_result);
 		return NULL;
 	}
 
Index: qofquerycore-p.h
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/qofquerycore-p.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -Lsrc/engine/qofquerycore-p.h -Lsrc/engine/qofquerycore-p.h -u -r1.6 -r1.7
--- src/engine/qofquerycore-p.h
+++ src/engine/qofquerycore-p.h
@@ -37,22 +37,22 @@
 void qof_query_core_shutdown (void);
 
 /* 
- * An arbitrary Query Predicate.  Given the gnucash object and the
+ * An arbitrary Query Predicate.  Given the object and the
  * particular parameter get-function (obtained from the registry by
  * the Query internals), compare the object's parameter to the
- * predicate data
+ * predicate data.
  */
 typedef int (*QofQueryPredicateFunc) (gpointer object,
-			       QofAccessFunc get_fcn,
+			       QofParam *getter,
 			       QofQueryPredData *pdata);
 
 /* A callback for how to compare two (same-type) objects based on a
- * common get_fcn (parameter member), using the provided comparrison
+ * common getter (parameter member), using the provided comparison
  * options (which are the type-specific options).
  */
 typedef int (*QofCompareFunc) (gpointer a, gpointer b,
                               gint compare_options,
-                              QofAccessFunc get_fcn);
+                              QofParam *getter);
 
 /* Lookup functions */
 QofQueryPredicateFunc qof_query_core_get_predicate (char const *type);
Index: qofclass.h
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/qofclass.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -Lsrc/engine/qofclass.h -Lsrc/engine/qofclass.h -u -r1.3 -r1.4
--- src/engine/qofclass.h
+++ src/engine/qofclass.h
@@ -56,14 +56,24 @@
 /** Type of Paramters (String, Date, Numeric, GUID, etc.) */
 typedef const char * QofType;
 
+typedef struct _QofParam QofParam;
+
 /** The QofAccessFunc defines an arbitrary function pointer
  *  for access functions.  This is needed because C doesn't have
  *  templates, so we just cast a lot.  Real functions must be of
  *  the form:
  *
- * param_type getter_func (object_type *self);
+ *        param_type getter_func (object_type *self);
+ *  or
+ *        param_type getter_func (object_type *self, QofParam *param);
+ *
+ * The additional argument 'param' allows generic getter functions
+ * to be implemented, because this argument provides for a way to
+ * identify the expected getter_func return type at runtime.  It
+ * also provides a place for the user to hang additional user-defined
+ * data.
  */
-typedef gpointer (*QofAccessFunc)(gpointer);
+typedef gpointer (*QofAccessFunc)(gpointer object, const QofParam *param);
 
 /** The QofSetterFunc defines an function pointer for parameter
  *  setters. Real functions must be of the form:
@@ -79,16 +89,24 @@
  *    object (QofIdType) or it can be a core data type (QofType).
  * -- param_getfcn is the function to actually obtain the parameter
  * -- param_setfcn is the function to actually set the parameter
+ * -- param_userdata is a place where the user can place any desiered
+ *    user-defined data (and thus can be used by the user-defined
+ *    setter/getter).
  *
  * Either the getter or the setter may be NULL.
+ *
+ *  XXX todo/fixme: need to define a destroy callback, so that when
+ * the param memory is freed, the callback can be used to release the 
+ * user-defined data.
  */
-typedef struct _QofParam 
+struct _QofParam 
 {
   const char       * param_name;
   QofType            param_type;
   QofAccessFunc      param_getfcn;
   QofSetterFunc      param_setfcn;
-} QofParam;
+  gpointer           param_userdata;
+};
 
 /** This function is the default sort function for a particular object type */
 typedef int (*QofSortFunc)(gpointer, gpointer);
Index: qofbook.h
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/qofbook.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -Lsrc/engine/qofbook.h -Lsrc/engine/qofbook.h -u -r1.8 -r1.9
--- src/engine/qofbook.h
+++ src/engine/qofbook.h
@@ -71,7 +71,12 @@
     associated with it. */
 void      qof_book_destroy (QofBook *book);
 
-/** \return The table of entities of the given type. */
+/** \return The table of entities of the given 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 
+ *  memory) in which case what happens??).
+ */
 QofCollection  * qof_book_get_collection (QofBook *, QofIdType);
 
 /** Invoke the indicated callback on each collection in the book. */
@@ -81,10 +86,13 @@
 /** \return The kvp data for the book */
 KvpFrame   * qof_book_get_slots (QofBook *book);
 
-/** The qof_book_set_data() allows
- *    arbitrary pointers to structs to be stored in QofBook.
- *    This is the "prefered" method for extending QofBook to hold
- *    new data types.
+/** The qof_book_set_data() allows arbitrary pointers to structs 
+ *    to be stored in QofBook. This is the "prefered" method for 
+ *    extending QofBook to hold new data types.
+ *
+ * XXX FIXME: we need to add a destroy callback, so that when the
+ * book gets destroyed, the user gets notified and thus has a chance
+ * to clean up.
  */
 void qof_book_set_data (QofBook *book, const char *key, gpointer data);
 
Index: qofobject.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/qofobject.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -Lsrc/engine/qofobject.c -Lsrc/engine/qofobject.c -u -r1.10 -r1.11
--- src/engine/qofobject.c
+++ src/engine/qofobject.c
@@ -135,6 +135,11 @@
   ENTER ("type=%s", type_name);
 
   obj = qof_object_lookup (type_name);
+  if (!obj)
+  {
+    PERR ("No object of type %s", type_name);
+    return;
+  }
   col = qof_book_get_collection (book, obj->e_type);
   PINFO ("lookup obj=%p for type=%s", obj, type_name);
   if (!obj) return;
Index: qofclass.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/qofclass.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -Lsrc/engine/qofclass.c -Lsrc/engine/qofclass.c -u -r1.1 -r1.2
--- src/engine/qofclass.c
+++ src/engine/qofclass.c
@@ -46,9 +46,10 @@
 /********************************************************************/
 /* PUBLISHED API FUNCTIONS */
 
-void qof_class_register (QofIdTypeConst obj_name,
-                 QofSortFunc default_sort_function,
-                 const QofParam *params)
+void 
+qof_class_register (QofIdTypeConst obj_name,
+                    QofSortFunc default_sort_function,
+                    const QofParam *params)
 {
   int i;
 
@@ -74,7 +75,8 @@
   }
 }
 
-void qof_class_init(void)
+void 
+qof_class_init(void)
 {
   if (initialized) return;
   initialized = TRUE;
@@ -83,7 +85,8 @@
   sortTable = g_hash_table_new (g_str_hash, g_str_equal);
 }
 
-void qof_class_shutdown (void)
+void 
+qof_class_shutdown (void)
 {
   if (!initialized) return;
   initialized = FALSE;
@@ -105,8 +108,10 @@
 
   ht = g_hash_table_lookup (paramTable, obj_name);
   if (!ht)
-    PERR ("no object type %s", obj_name);
-  g_return_val_if_fail (ht, NULL);
+  {
+    PERR ("no object of type %s", obj_name);
+    return NULL;
+  }
 
   return (g_hash_table_lookup (ht, parameter));
 }
Index: gnc-general-search.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/gnome-search/gnc-general-search.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -Lsrc/gnome-search/gnc-general-search.c -Lsrc/gnome-search/gnc-general-search.c -u -r1.2 -r1.3
--- src/gnome-search/gnc-general-search.c
+++ src/gnome-search/gnc-general-search.c
@@ -62,7 +62,7 @@
 	GNCSearchCB		search_cb;
 	gpointer		user_data;
 	GNCSearchWindow *	sw;
-	QueryAccess		get_guid;
+	const QofParam * get_guid;
 	gint			component_id;
 };
 
@@ -295,11 +295,11 @@
 			GNCSearchCB search_cb, gpointer user_data)
 {
 	GNCGeneralSearch *gsl;
-	QueryAccess get_guid;
+	const QofParam *get_guid;
 
 	g_return_val_if_fail (type && label && search_cb, NULL);
 
-	get_guid = gncQueryObjectGetParameterGetter (type, QUERY_PARAM_GUID);
+	get_guid = qof_class_get_parameter (type, QOF_QUERY_PARAM_GUID);
 	g_return_val_if_fail (get_guid, NULL);
 
 	gsl = gtk_type_new (gnc_general_search_get_type ());
@@ -341,9 +341,11 @@
 
 	gnc_gui_component_clear_watches (gsl->priv->component_id);
 
-	if (selection) {
-		gsl->priv->guid = * ((GUID *)(gsl->priv->get_guid
-					      (gsl->selected_item)));
+	if (selection) 
+   {
+      const QofParam *get_guid = gsl->priv->get_guid;
+		gsl->priv->guid = * ((GUID *)(get_guid->param_getfcn
+					      (gsl->selected_item, get_guid)));
 		gnc_gui_component_watch_entity
 			(gsl->priv->component_id, &(gsl->priv->guid),
 			 GNC_EVENT_MODIFY | GNC_EVENT_DESTROY);
Index: dialog-search.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/gnome-search/dialog-search.c,v
retrieving revision 1.39
retrieving revision 1.40
diff -Lsrc/gnome-search/dialog-search.c -Lsrc/gnome-search/dialog-search.c -u -r1.39 -r1.40
--- src/gnome-search/dialog-search.c
+++ src/gnome-search/dialog-search.c
@@ -90,7 +90,7 @@
   /* What we're searching for, and how */
   GNCIdTypeConst search_for;
   GNCSearchType	grouping;	/* Match Any, Match All */
-  QueryAccess	get_guid;	/* Function to GetGUID from the object */
+  const QofParam * get_guid;	/* Function to GetGUID from the object */
   int		search_type;	/* New, Narrow, Add, Delete */
 
   /* Our query status */
@@ -441,14 +441,15 @@
 
   res = (sw->new_item_cb)(sw->user_data);
 
-  if (res) {
-    const GUID *guid = (const GUID *) ((sw->get_guid)(res));
+  if (res) 
+  {
+    const GUID *guid = (const GUID *) ((sw->get_guid->param_getfcn)(res, sw->get_guid));
     QueryOp op = QUERY_OR;
 
     if (!sw->q) {
       if (!sw->start_q) {
-	sw->start_q = gncQueryCreateFor (sw->search_for);
-	gncQuerySetBook (sw->start_q, gnc_get_current_book ());
+        sw->start_q = gncQueryCreateFor (sw->search_for);
+        gncQuerySetBook (sw->start_q, gnc_get_current_book ());
       }
       sw->q = gncQueryCopy (sw->start_q);
       op = QUERY_AND;
@@ -882,8 +883,8 @@
   sw->free_cb = free_cb;
 
   /* Grab the get_guid function */
-  sw->get_guid = gncQueryObjectGetParameterGetter (sw->search_for,
-						   QUERY_PARAM_GUID);
+  sw->get_guid = qof_class_get_parameter (sw->search_for,
+						   QOF_QUERY_PARAM_GUID);
   if (start_query)
     sw->start_q = gncQueryCopy (start_query);
   sw->q = show_start_query;
Index: search-param.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/gnome-utils/search-param.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -Lsrc/gnome-utils/search-param.c -Lsrc/gnome-utils/search-param.c -u -r1.5 -r1.6
--- src/gnome-utils/search-param.c
+++ src/gnome-utils/search-param.c
@@ -171,7 +171,7 @@
       break;
 
     /* Save the converter */
-    converters = g_slist_prepend (converters, objDef->param_getfcn);
+    converters = g_slist_prepend (converters, (gpointer) objDef);
 
     /* And reset for the next parameter */
     type = search_type = objDef->param_type;
@@ -372,13 +372,13 @@
   else
   {
     GSList *converters = gnc_search_param_get_converters (param);
-    QueryAccess fcn = NULL;
     gpointer res = object;
 
     /* Do all the object conversions */
-    for (; converters; converters = converters->next) {
-      fcn = converters->data;
-      res = fcn (res);
+    for (; converters; converters = converters->next) 
+    {
+      QofParam *qp = converters->data;
+      res = (qp->param_getfcn) (res, qp);
     }
 
     return res;
Index: gnc-query-list.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/gnome-utils/gnc-query-list.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -Lsrc/gnome-utils/gnc-query-list.c -Lsrc/gnome-utils/gnc-query-list.c -u -r1.8 -r1.9
--- src/gnome-utils/gnc-query-list.c
+++ src/gnome-utils/gnc-query-list.c
@@ -43,9 +43,10 @@
   LAST_SIGNAL
 };
 
-struct _GNCQueryListPriv {
-  QueryAccess	get_guid;
-  gint		component_id;
+struct _GNCQueryListPriv 
+{
+  const QofParam * get_guid;
+  gint	          component_id;
 };
 
 /* Impossible to get at runtime. Assume this is a reasonable number */
@@ -125,8 +126,8 @@
 
   /* cache the function to get the guid of this query type */
   list->priv->get_guid =
-    gncQueryObjectGetParameterGetter (gncQueryGetSearchFor (query),
-				      QUERY_PARAM_GUID);
+    qof_class_get_parameter (qof_query_get_search_for(query),
+                  QOF_QUERY_PARAM_GUID);
 
   /* Initialize the CList */
   gnc_query_list_init_clist(list);
@@ -776,6 +777,7 @@
   {
     GList *node;
     gint row;
+    QofParam *qp= NULL;
 
     for (i = 0, node = list->column_params; node; node = node->next)
     {
@@ -783,33 +785,35 @@
       GSList *converters = gnc_search_param_get_converters (param);
       const char *type = gnc_search_param_get_param_type (param);
       gpointer res = item->data;
-      QueryAccess fcn = NULL;
 
       /* if this is a boolean, ignore it now -- we'll use a checkmark later */
       if (!safe_strcmp (type, QUERYCORE_BOOLEAN)) {
-	strings[i++] = g_strdup("");
-	continue;
+        strings[i++] = g_strdup("");
+        continue;
       }
 
       /* Do all the object conversions */
-      for (; converters; converters = converters->next) {
-	fcn = converters->data;
-
-	if (converters->next)
-	  res = fcn (res);
+      for (; converters; converters = converters->next) 
+      {
+         qp = converters->data;
+         if (converters->next)
+         {
+            res = (qp->param_getfcn)(res, qp);
+         }
       }
 
       /* Now convert this to a text value for the row */
       if (!safe_strcmp(type, QUERYCORE_DEBCRED) ||
-	  !safe_strcmp(type, QUERYCORE_NUMERIC))
+          !safe_strcmp(type, QUERYCORE_NUMERIC))
       {
-	gnc_numeric (*nfcn)(gpointer) = (gnc_numeric(*)(gpointer))fcn;
-	gnc_numeric value = nfcn(res);
-	if (list->numeric_abs)
-	  value = gnc_numeric_abs (value);
-	strings[i++] = g_strdup(xaccPrintAmount(value,gnc_default_print_info(FALSE)));
+        gnc_numeric (*nfcn)(gpointer, QofParam *) = 
+                (gnc_numeric(*)(gpointer, QofParam *))(qp->param_getfcn);
+        gnc_numeric value = nfcn(res, qp);
+        if (list->numeric_abs)
+          value = gnc_numeric_abs (value);
+        strings[i++] = g_strdup(xaccPrintAmount(value,gnc_default_print_info(FALSE)));
       } else
-	strings[i++] = gncQueryCoreToString (type, res, fcn);
+        strings[i++] = gncQueryCoreToString (type, res, qp);
     }
 
     row = gtk_clist_append (GTK_CLIST(list), (gchar **) strings);
@@ -818,14 +822,15 @@
     /* Free up our strings */
     for (i = 0; i < list->num_columns; i++) {
       if (strings[i])
-	g_free (strings[i]);
+        g_free (strings[i]);
     }
 
     /* Now update any checkmarks */
     update_booleans (list, row);
 
     /* and set a watcher on this item */
-    guid = (const GUID*)((list->priv->get_guid)(item->data));
+    const QofParam *gup = list->priv->get_guid;
+    guid = (const GUID*)((gup->param_getfcn)(item->data, gup));
     gnc_gui_component_watch_entity (list->priv->component_id, guid,
 				    GNC_EVENT_MODIFY | GNC_EVENT_DESTROY);
 


More information about the Gnucash-changes mailing list