QOF  0.8.7
qofutil.c
00001 /********************************************************************\
00002  * qofutil.c -- QOF utility functions                               *
00003  * Copyright (C) 1997 Robin D. Clark                                *
00004  * Copyright (C) 1997-2001,2004 Linas Vepstas <linas@linas.org>     *
00005  * Copyright 2006,2008  Neil Williams  <linux@codehelp.co.uk>       *
00006  *                                                                  *
00007  * This program is free software; you can redistribute it and/or    *
00008  * modify it under the terms of the GNU General Public License as   *
00009  * published by the Free Software Foundation; either version 2 of   *
00010  * the License, or (at your option) any later version.              *
00011  *                                                                  *
00012  * This program is distributed in the hope that it will be useful,  *
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
00015  * GNU General Public License for more details.                     *
00016  *                                                                  *
00017  * You should have received a copy of the GNU General Public License*
00018  * along with this program; if not, contact:                        *
00019  *                                                                  *
00020  * Free Software Foundation           Voice:  +1-617-542-5942       *
00021  * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
00022  * Boston, MA  02110-1301,  USA       gnu@gnu.org                   *
00023  *                                                                  *
00024  *   Author: Rob Clark (rclark@cs.hmc.edu)                          *
00025  *   Author: Linas Vepstas (linas@linas.org)                        *
00026 \********************************************************************/
00027 
00028 #include "config.h"
00029 
00030 #include <errno.h>
00031 #include <ctype.h>
00032 #include <glib.h>
00033 #include <stdlib.h>
00034 #include <string.h>
00035 #include <math.h>
00036 #include "qof.h"
00037 #include "qofundo-p.h"
00038 #include "qofbook-p.h"
00039 
00040 static QofLogModule log_module = QOF_MOD_UTIL;
00041 
00042 /* Search for str2 in first nchar chars of str1, ignore case..  Return
00043  * pointer to first match, or null.  */
00044 gchar *
00045 strncasestr (const guchar * str1, const guchar * str2, size_t len)
00046 {
00047     while (*str1 && len--)
00048     {
00049         if (toupper (*str1) == toupper (*str2))
00050         {
00051             size_t l;
00052             l = strlen ((gchar*)str2);
00053             if (strncasecmp ((gchar*)str1, (gchar*)str2, l) == 0)
00054                 return (gchar *) str1;
00055         }
00056         str1++;
00057     }
00058     return NULL;
00059 }
00060 
00061 #ifndef HAVE_STRCASESTR
00062 /* Search for str2 in str1, ignore case.  Return pointer to first
00063  * match, or null.  */
00064 gchar *
00065 strcasestr (const gchar * str1, const gchar * str2)
00066 {
00067     size_t len = strlen (str1);
00068     gchar *retval = strncasestr (str1, str2, len);
00069     return retval;
00070 }
00071 #endif
00072 
00074 gint
00075 safe_strcmp (const gchar * da, const gchar * db)
00076 {
00077     if ((da) && (db))
00078     {
00079         if ((da) != (db))
00080         {
00081             gint retval = strcmp ((da), (db));
00082             /* if strings differ, return */
00083             if (retval)
00084                 return retval;
00085         }
00086     }
00087     else if ((!(da)) && (db))
00088         return -1;
00089     else if ((da) && (!(db)))
00090         return +1;
00091     return 0;
00092 }
00093 
00094 gint
00095 safe_strcasecmp (const gchar * da, const gchar * db)
00096 {
00097     if ((da) && (db))
00098     {
00099         if ((da) != (db))
00100         {
00101             gint retval = strcasecmp ((da), (db));
00102             /* if strings differ, return */
00103             if (retval)
00104                 return retval;
00105         }
00106     }
00107     else if ((!(da)) && (db))
00108         return -1;
00109     else if ((da) && (!(db)))
00110         return +1;
00111     return 0;
00112 }
00113 
00114 inline gint
00115 null_strcmp (const gchar * da, const gchar * db)
00116 {
00117     if (da && db)
00118         return strcmp (da, db);
00119     if (!da && db && 0 == db[0])
00120         return 0;
00121     if (!db && da && 0 == da[0])
00122         return 0;
00123     if (!da && db)
00124         return -1;
00125     if (da && !db)
00126         return +1;
00127     return 0;
00128 }
00129 
00130 #define MAX_DIGITS 50
00131 
00132 /* inverse of strtoul */
00133 gchar *
00134 ultostr (gulong val, gint base)
00135 {
00136     gchar buf[MAX_DIGITS];
00137     gulong broke[MAX_DIGITS];
00138     gint i;
00139     gulong places = 0, reval;
00140 
00141     if ((2 > base) || (36 < base))
00142         return NULL;
00143 
00144     /* count digits */
00145     places = 0;
00146     for (i = 0; i < MAX_DIGITS; i++)
00147     {
00148         broke[i] = val;
00149         places++;
00150         val /= base;
00151         if (0 == val)
00152             break;
00153     }
00154 
00155     /* normalize */
00156     reval = 0;
00157     for (i = places - 2; i >= 0; i--)
00158     {
00159         reval += broke[i + 1];
00160         reval *= base;
00161         broke[i] -= reval;
00162     }
00163 
00164     /* print */
00165     for (i = 0; i < (gint) places; i++)
00166     {
00167         if (10 > broke[i])
00168         {
00169             buf[places - 1 - i] = 0x30 + broke[i];  /* ascii digit zero */
00170         }
00171         else
00172         {
00173             buf[places - 1 - i] = 0x41 - 10 + broke[i]; /* ascii capital A */
00174         }
00175     }
00176     buf[places] = 0x0;
00177 
00178     return g_strdup (buf);
00179 }
00180 
00181 inline gint
00182 qof_util_double_compare (gdouble d1, gdouble d2)
00183 {
00184     if (isnan (d1) && isnan (d2))
00185         return 0;
00186     if (d1 < d2)
00187         return -1;
00188     if (d1 > d2)
00189         return 1;
00190     return 0;
00191 }
00192 
00193 /* =================================================================== */
00194 /* returns TRUE if the string is a number, possibly with whitespace */
00195 /* =================================================================== */
00196 
00197 gboolean
00198 qof_util_string_isnum (const guchar * s)
00199 {
00200     if (s == NULL)
00201         return FALSE;
00202     if (*s == 0)
00203         return FALSE;
00204 
00205     while (*s && isspace (*s))
00206         s++;
00207 
00208     if (*s == 0)
00209         return FALSE;
00210     if (!isdigit (*s))
00211         return FALSE;
00212 
00213     while (*s && isdigit (*s))
00214         s++;
00215 
00216     if (*s == 0)
00217         return TRUE;
00218 
00219     while (*s && isspace (*s))
00220         s++;
00221 
00222     if (*s == 0)
00223         return TRUE;
00224 
00225     return FALSE;
00226 }
00227 
00228 /* =================================================================== */
00229 /* Return NULL if the field is whitespace (blank, tab, formfeed etc.)
00230  * Else return pointer to first non-whitespace character. */
00231 /* =================================================================== */
00232 
00233 const gchar *
00234 qof_util_whitespace_filter (const gchar * val)
00235 {
00236     size_t len;
00237     if (!val)
00238         return NULL;
00239 
00240     len = strspn (val, "\a\b\t\n\v\f\r ");
00241     if (0 == val[len])
00242         return NULL;
00243     return val + len;
00244 }
00245 
00246 /* =================================================================== */
00247 /* Return integer 1 if the string starts with 't' or 'T' or contains the
00248  * word 'true' or 'TRUE'; if string is a number, return that number. */
00249 /* =================================================================== */
00250 
00251 gint
00252 qof_util_bool_to_int (const gchar * val)
00253 {
00254     const gchar *p = qof_util_whitespace_filter (val);
00255     if (!p)
00256         return 0;
00257     if ('t' == p[0])
00258         return 1;
00259     if ('T' == p[0])
00260         return 1;
00261     if ('y' == p[0])
00262         return 1;
00263     if ('Y' == p[0])
00264         return 1;
00265     if (strstr (p, "true"))
00266         return 1;
00267     if (strstr (p, "TRUE"))
00268         return 1;
00269     if (strstr (p, "yes"))
00270         return 1;
00271     if (strstr (p, "YES"))
00272         return 1;
00273     return atoi (val);
00274 }
00275 
00276 /* =================================================================== */
00277 /* Entity edit and commit utilities */
00278 /* =================================================================== */
00279 
00280 gboolean
00281 qof_util_param_edit (QofInstance * inst, const QofParam *param)
00282 {
00283     QofBackend *be;
00284     QofUndo *undo_data;
00285 
00286     if (!inst)
00287         return FALSE;
00288     (inst->editlevel)++;
00289     if (1 < inst->editlevel)
00290         return FALSE;
00291     if (0 >= inst->editlevel)
00292         inst->editlevel = 1;
00293     be = qof_book_get_backend (inst->book);
00294     if (param != NULL)
00295     {
00296         undo_data = inst->book->undo_data;
00297         inst->param = param;
00298         if (undo_data->undo_operation_open)
00299             qof_undo_modify (inst, param);
00300     }
00301     if (be && qof_backend_begin_exists (be))
00302         qof_backend_run_begin (be, inst);
00303     else
00304         inst->dirty = TRUE;
00305     return TRUE;
00306 }
00307 
00308 gboolean
00309 qof_util_param_commit (QofInstance * inst, const QofParam * param)
00310 {
00311     QofUndo *undo_data;
00312     QofBackend * be;
00313 
00314     if (!inst)
00315         return FALSE;
00316     (inst->editlevel)--;
00317     if (0 < inst->editlevel)
00318         return FALSE;
00319     be = qof_book_get_backend (inst->book);
00320     inst->param = param;
00321     if (be && qof_backend_commit_exists (be))
00322         qof_backend_run_commit (be, inst);
00323     if (param != NULL)
00324     {
00325         undo_data = inst->book->undo_data;
00326         if (undo_data->undo_operation_open)
00327             qof_undo_commit (inst, param);
00328     }
00329     return TRUE;
00330 }
00331 
00332 gchar *
00333 qof_util_make_utf8 (gchar * string)
00334 {
00335     gchar *value;
00336 
00337     if (!string)
00338         return NULL;
00339     if (g_utf8_validate (string, -1, NULL))
00340         return string;
00341     value = g_locale_to_utf8 (string, -1, NULL, NULL, NULL);
00342     if (!value)
00343     {
00344         PWARN (" unable to convert from locale %s", string);
00345         PINFO ("trying to convert from ISO-8859-15.");
00346         value = g_convert (string, -1, "UTF-8", "ISO-8859-15",
00347             NULL, NULL, NULL);
00348         if (!value)
00349         {
00350             PERR (" conversion failed");
00351             return string;
00352         }
00353         return value;
00354     }
00355     return value;
00356 }
00357 
00358 /* =================================================================== */
00359 /* The QOF string cache - reimplements a limited GCache for strings    */
00360 /* =================================================================== */
00361 
00362 typedef struct {
00363     GHashTable *key_table;
00364     GHashTable *value_table;
00365 }QStrCache;
00366 
00367 static QStrCache *qof_string_cache = NULL;
00368 
00369 typedef struct {
00370     gpointer value;
00371     gint ref_count;
00372 } QStrCacheNode;
00373 
00374 static inline QStrCacheNode* g_cache_node_new (gpointer value) {
00375     QStrCacheNode *node = g_slice_new (QStrCacheNode);
00376     node->value = value;
00377     node->ref_count = 1;
00378     return node;
00379 }
00380 
00381 static inline void g_cache_node_destroy (QStrCacheNode *node) {
00382     g_slice_free (QStrCacheNode, node);
00383 }
00384 
00385 static QStrCache* qof_cache_new (void) {
00386     QStrCache *cache;
00387     cache = g_slice_new (QStrCache);
00388     cache->key_table = g_hash_table_new (g_str_hash, g_str_equal);
00389     cache->value_table = g_hash_table_new (g_str_hash, NULL);
00390     return cache;
00391 }
00392 
00393 static void qof_cache_destroy (QStrCache *cache) {
00394     g_return_if_fail (cache != NULL);
00395     g_hash_table_destroy (cache->key_table);
00396     g_hash_table_destroy (cache->value_table);
00397     g_slice_free (QStrCache, cache);
00398 }
00399 
00400 static gpointer qof_cache_insert (QStrCache *cache, gpointer key) {
00401     QStrCacheNode *node;
00402     gpointer value;
00403 
00404     g_return_val_if_fail (cache != NULL, NULL);
00405     node = g_hash_table_lookup (cache->key_table, key);
00406     if (node) {
00407         node->ref_count += 1;
00408         return node->value;
00409     }
00410     key = g_strdup (key);
00411     value = g_strdup (key);
00412     node = g_cache_node_new (value);
00413     g_hash_table_insert (cache->key_table, key, node);
00414     g_hash_table_insert (cache->value_table, value, key);
00415     return node->value;
00416 }
00417 
00418 static void qof_cache_remove (QStrCache *cache, gconstpointer value) {
00419     QStrCacheNode *node;
00420     gpointer key;
00421 
00422     g_return_if_fail (cache != NULL);
00423     key = g_hash_table_lookup (cache->value_table, value);
00424     node = g_hash_table_lookup (cache->key_table, key);
00425     g_return_if_fail (node != NULL);
00426     node->ref_count -= 1;
00427     if (node->ref_count == 0) {
00428         g_hash_table_remove (cache->value_table, value);
00429         g_hash_table_remove (cache->key_table, key);
00430         g_free (key);
00431         g_free (node->value);
00432         g_cache_node_destroy (node);
00433     }
00434 }
00435 
00436 static QStrCache * qof_util_get_string_cache (void) {
00437     if (!qof_string_cache) {
00438         qof_string_cache = qof_cache_new ();
00439     }
00440     return qof_string_cache;
00441 }
00442 
00443 void qof_util_string_cache_destroy (void) {
00444     if (qof_string_cache) {
00445         qof_cache_destroy (qof_string_cache);
00446     }
00447     qof_string_cache = NULL;
00448 }
00449 
00450 void qof_util_string_cache_remove (gconstpointer key) {
00451     if (key) {
00452         qof_cache_remove (qof_util_get_string_cache (), key);
00453     }
00454 }
00455 
00456 gpointer qof_util_string_cache_insert (gconstpointer key) {
00457     if (key) {
00458         return qof_cache_insert(qof_util_get_string_cache(), (gpointer)key);
00459     }
00460     return NULL;
00461 }
00462 
00463 gchar *
00464 qof_util_param_to_string (QofEntity * ent, const QofParam * param)
00465 {
00466     gchar *param_string;
00467     gchar param_sa[GUID_ENCODING_LENGTH + 1];
00468     gboolean known_type;
00469     QofType paramType;
00470     const GUID *param_guid;
00471     QofNumeric param_numeric, (*numeric_getter) (QofEntity *, const QofParam *);
00472     gdouble param_double, (*double_getter) (QofEntity *, const QofParam *);
00473     gboolean param_boolean, (*boolean_getter) (QofEntity *, const QofParam *);
00474     gint32 param_i32, (*int32_getter) (QofEntity *, const QofParam *);
00475     gint64 param_i64, (*int64_getter) (QofEntity *, const QofParam *);
00476     gchar param_char, (*char_getter) (QofEntity *, const QofParam *);
00477 
00478     param_string = NULL;
00479     known_type = FALSE;
00480     g_return_val_if_fail (ent && param, NULL);
00481     paramType = param->param_type;
00482     if (safe_strcmp (paramType, QOF_TYPE_STRING) == 0)
00483     {
00484         param_string = g_strdup (param->param_getfcn (ent, param));
00485         if (param_string == NULL)
00486             param_string = g_strdup("");
00487         known_type = TRUE;
00488         return param_string;
00489     }
00490     if (safe_strcmp (paramType, QOF_TYPE_TIME) == 0)
00491     {
00492         QofTime *param_qt;
00493         QofDate *qd;
00494         param_qt = param->param_getfcn (ent, param);
00495         qd = qof_date_from_qtime (param_qt);
00496         return qof_date_print (qd, QOF_DATE_FORMAT_UTC);
00497     }
00498     if ((safe_strcmp (paramType, QOF_TYPE_NUMERIC) == 0) ||
00499         (safe_strcmp (paramType, QOF_TYPE_DEBCRED) == 0))
00500     {
00501         numeric_getter =
00502             (QofNumeric (*)(QofEntity *, const QofParam *)) param->param_getfcn;
00503         param_numeric = numeric_getter (ent, param);
00504         param_string = g_strdup (qof_numeric_to_string (param_numeric));
00505         known_type = TRUE;
00506         return param_string;
00507     }
00508     if (safe_strcmp (paramType, QOF_TYPE_GUID) == 0)
00509     {
00510         param_guid = param->param_getfcn (ent, param);
00511         guid_to_string_buff (param_guid, param_sa);
00512         param_string = g_strdup (param_sa);
00513         known_type = TRUE;
00514         return param_string;
00515     }
00516     if (safe_strcmp (paramType, QOF_TYPE_INT32) == 0)
00517     {
00518         int32_getter =
00519             (gint32 (*)(QofEntity *, const QofParam *)) param->param_getfcn;
00520         param_i32 = int32_getter (ent, param);
00521         param_string = g_strdup_printf ("%d", param_i32);
00522         known_type = TRUE;
00523         return param_string;
00524     }
00525     if (safe_strcmp (paramType, QOF_TYPE_INT64) == 0)
00526     {
00527         int64_getter =
00528             (gint64 (*)(QofEntity *, const QofParam *)) param->param_getfcn;
00529         param_i64 = int64_getter (ent, param);
00530         param_string = g_strdup_printf ("%" G_GINT64_FORMAT, param_i64);
00531         known_type = TRUE;
00532         return param_string;
00533     }
00534     if (safe_strcmp (paramType, QOF_TYPE_DOUBLE) == 0)
00535     {
00536         double_getter =
00537             (double (*)(QofEntity *, const QofParam *)) param->param_getfcn;
00538         param_double = double_getter (ent, param);
00539         param_string = g_strdup_printf ("%f", param_double);
00540         known_type = TRUE;
00541         return param_string;
00542     }
00543     if (safe_strcmp (paramType, QOF_TYPE_BOOLEAN) == 0)
00544     {
00545         boolean_getter =
00546             (gboolean (*)(QofEntity *, const QofParam *)) param->param_getfcn;
00547         param_boolean = boolean_getter (ent, param);
00548         /* Boolean values need to be lowercase for QSF validation. */
00549         if (param_boolean == TRUE)
00550         {
00551             param_string = g_strdup ("true");
00552         }
00553         else
00554         {
00555             param_string = g_strdup ("false");
00556         }
00557         known_type = TRUE;
00558         return param_string;
00559     }
00560     /* "kvp" contains repeating values, cannot be a single string for the frame. */
00561     if (safe_strcmp (paramType, QOF_TYPE_KVP) == 0)
00562     {
00563         KvpFrame *frame = NULL;
00564         frame = param->param_getfcn (ent, param);
00565         known_type = TRUE;
00566         if (!kvp_frame_is_empty (frame))
00567         {
00568             GHashTable *hash = kvp_frame_get_hash (frame);
00569             param_string = g_strdup_printf ("%s(%d)", QOF_TYPE_KVP,
00570                 g_hash_table_size (hash));
00571         }
00572         /* ensure a newly allocated string is returned, even
00573         if the frame is empty. */
00574         else
00575         {
00576             param_string = g_strdup("");
00577         }
00578         return param_string;
00579     }
00580     if (safe_strcmp (paramType, QOF_TYPE_CHAR) == 0)
00581     {
00582         char_getter =
00583             (gchar (*)(QofEntity *, const QofParam *)) param->param_getfcn;
00584         param_char = char_getter (ent, param);
00585         known_type = TRUE;
00586         return g_strdup_printf ("%c", param_char);
00587     }
00588     /* "collect" contains repeating values, cannot be a single string. */
00589     if (safe_strcmp (paramType, QOF_TYPE_COLLECT) == 0)
00590     {
00591         QofCollection *col = NULL;
00592         col = param->param_getfcn (ent, param);
00593         known_type = TRUE;
00594         return g_strdup_printf ("%s(%d)",
00595             qof_collection_get_type (col), qof_collection_count (col));
00596     }
00597     if (safe_strcmp (paramType, QOF_TYPE_CHOICE) == 0)
00598     {
00599         QofEntity *child = NULL;
00600         child = param->param_getfcn (ent, param);
00601         if (!child)
00602         {
00603             return param_string;
00604         }
00605         known_type = TRUE;
00606         return g_strdup (qof_object_printable (child->e_type, child));
00607     }
00608     if (safe_strcmp (paramType, QOF_PARAM_BOOK) == 0)
00609     {
00610         QofBackend *be;
00611         QofBook *book;
00612         book = param->param_getfcn (ent, param);
00613         PINFO (" book param %p", book);
00614         be = qof_book_get_backend (book);
00615         known_type = TRUE;
00616         PINFO (" backend=%p", be);
00617         if (!be)
00618         {
00619             return QOF_PARAM_BOOK;
00620         }
00621         param_string = g_strdup (be->fullpath);
00622         PINFO (" fullpath=%s", param_string);
00623         if (param_string)
00624         {
00625             return param_string;
00626         }
00627         param_guid = qof_entity_get_guid ((QofEntity*)book);
00628         guid_to_string_buff (param_guid, param_sa);
00629         PINFO (" book GUID=%s", param_sa);
00630         param_string = g_strdup (param_sa);
00631         return param_string;
00632     }
00633     if (!known_type)
00634     {
00635         QofEntity *child = NULL;
00636         child = param->param_getfcn (ent, param);
00637         if (!child)
00638         {
00639             return param_string;
00640         }
00641         return g_strdup (qof_object_printable (child->e_type, child));
00642     }
00643     return g_strdup ("");
00644 }
00645 
00646 gboolean
00647 qof_util_param_set_string (QofEntity * ent, const QofParam * param,
00648     const gchar * value_string)
00649 {
00650     void (*string_setter) (QofEntity *, const gchar *);
00651     void (*time_setter) (QofEntity *, QofTime *);
00652     void (*numeric_setter) (QofEntity *, QofNumeric);
00653     void (*guid_setter) (QofEntity *, const GUID *);
00654     void (*double_setter) (QofEntity *, gdouble);
00655     void (*boolean_setter) (QofEntity *, gboolean);
00656     void (*i32_setter) (QofEntity *, gint32);
00657     void (*i64_setter) (QofEntity *, gint64);
00658     void (*char_setter) (QofEntity *, gchar);
00659 /*  void (*kvp_frame_setter) (QofEntity *, KvpFrame *);
00660     void (*reference_setter) (QofEntity *, QofEntity *);
00661     void (*collection_setter) (QofEntity *, QofCollection *);*/
00662 
00663     g_return_val_if_fail (ent, FALSE);
00664     g_return_val_if_fail (param, FALSE);
00665     g_return_val_if_fail (value_string, FALSE);
00666 
00667     if (safe_strcmp (param->param_type, QOF_TYPE_STRING) == 0)
00668     {
00669         string_setter =
00670             (void (*)(QofEntity *,
00671                 const gchar *)) param->param_setfcn;
00672         if (string_setter != NULL)
00673             string_setter (ent, value_string);
00674 //      registered_type = TRUE;
00675     }
00676     if (safe_strcmp (param->param_type, QOF_TYPE_TIME) == 0)
00677     {
00678         QofTime *qt;
00679         QofDate *qd;
00680 
00681         qd = qof_date_parse (value_string, QOF_DATE_FORMAT_UTC);
00682         if (!qd)
00683             return FALSE;
00684         qt = qof_date_to_qtime (qd);
00685         time_setter =
00686             (void (*)(QofEntity *, QofTime *))
00687             param->param_setfcn;
00688         if ((time_setter != NULL) && (qof_time_is_valid (qt)))
00689             time_setter (ent, qt);
00690         qof_date_free (qd);
00691 //      registered_type = TRUE;
00692     }
00693     if ((safe_strcmp (param->param_type, QOF_TYPE_NUMERIC) == 0) ||
00694         (safe_strcmp (param->param_type, QOF_TYPE_DEBCRED) == 0))
00695     {
00696         QofNumeric num;
00697         numeric_setter =
00698             (void (*)(QofEntity *,
00699                 QofNumeric)) param->param_setfcn;
00700         if (!qof_numeric_from_string (value_string, &num) ||
00701             (qof_numeric_check (num) != QOF_ERROR_OK))
00702             return FALSE;
00703         if (numeric_setter != NULL)
00704             numeric_setter (ent, num);
00705 //      registered_type = TRUE;
00706     }
00707     if (safe_strcmp (param->param_type, QOF_TYPE_GUID) == 0)
00708     {
00709         GUID * guid;
00710 
00711         guid = guid_malloc();
00712         guid_new (guid);
00713         guid_setter =
00714             (void (*)(QofEntity *,
00715                 const GUID *)) param->param_setfcn;
00716         if (!string_to_guid(value_string, guid))
00717             return FALSE;
00718         if (guid_setter != NULL)
00719             guid_setter (ent, guid);
00720 //      registered_type = TRUE;
00721     }
00722     if (safe_strcmp (param->param_type, QOF_TYPE_INT32) == 0)
00723     {
00724         gint32 i32;
00725         gchar *tail;
00726 
00727         errno = 0;
00728         i32_setter =
00729             (void (*)(QofEntity *, gint32)) param->param_setfcn;
00730         i32 =
00731             (gint32) strtol (value_string, &tail, 0);
00732         if ((i32_setter != NULL) && (errno == 0))
00733 
00734             i32_setter (ent, i32);
00735 //      registered_type = TRUE;
00736     }
00737     if (safe_strcmp (param->param_type, QOF_TYPE_INT64) == 0)
00738     {
00739         gint64 i64;
00740         gchar *tail;
00741 
00742         errno = 0;
00743         i64 = strtoll (value_string, &tail, 0);
00744         i64_setter =
00745             (void (*)(QofEntity *, gint64)) param->param_setfcn;
00746         if ((i64_setter != NULL) && (errno == 0))
00747             i64_setter (ent, i64);
00748 //      registered_type = TRUE;
00749     }
00750     if (safe_strcmp (param->param_type, QOF_TYPE_DOUBLE) == 0)
00751     {
00752         gdouble db;
00753         gchar *tail;
00754 
00755         errno = 0;
00756         db = strtod (value_string, &tail);
00757         double_setter =
00758             (void (*)(QofEntity *, gdouble)) param->param_setfcn;
00759         if ((double_setter != NULL) && (errno == 0))
00760             double_setter (ent, db);
00761 //      registered_type = TRUE;
00762     }
00763     if (safe_strcmp (param->param_type, QOF_TYPE_BOOLEAN) == 0)
00764     {
00765         gint val;
00766         gboolean G_GNUC_UNUSED b;
00767 
00768         boolean_setter =
00769             (void (*)(QofEntity *, gboolean)) param->param_setfcn;
00770         val = qof_util_bool_to_int(value_string);
00771         if ((val > 1) || (val < 0))
00772             return FALSE;
00773         b = (val == 1) ? TRUE : FALSE;
00774         if (boolean_setter != NULL)
00775             boolean_setter (ent, val);
00776 //      registered_type = TRUE;
00777     }
00778     if (safe_strcmp (param->param_type, QOF_TYPE_KVP) == 0)
00779     {
00780         /* unsupported */
00781         return FALSE;
00782 /*      KvpFrame * frame;
00783         KvpValue * value;
00784 
00785         kvp_frame_setter =
00786             (void (*)(QofEntity *, KvpFrame *)) param->param_setfcn;
00787         if (kvp_frame_setter != NULL)
00788             kvp_frame_setter (rule->targetEnt, cm_kvp);
00789 //      registered_type = TRUE;*/
00790     }
00791     if (safe_strcmp (param->param_type, QOF_TYPE_CHAR) == 0)
00792     {
00793         char_setter =
00794             (void (*)(QofEntity *, gchar)) param->param_setfcn;
00795         if (char_setter != NULL)
00796             char_setter (ent, value_string[0]);
00797 //      registered_type = TRUE;
00798     }
00799     if (safe_strcmp (param->param_type, QOF_TYPE_COLLECT) == 0)
00800     {
00801         /* unsupported */
00802         return FALSE;
00803     }
00804     if (safe_strcmp (param->param_type, QOF_TYPE_CHOICE) == 0)
00805     {
00806         /* unsupported*/
00807         return FALSE;
00808     }
00809 /*  if (registered_type == FALSE)
00810     {
00811         referenceEnt =
00812             cm_param->param_getfcn (rule->importEnt, cm_param);
00813         if (referenceEnt)
00814         {
00815             reference_setter =
00816                 (void (*)(QofEntity *, QofEntity *)) cm_param->
00817                 param_setfcn;
00818             if (reference_setter != NULL)
00819             {
00820                 reference_setter (rule->targetEnt, referenceEnt);
00821             }
00822         }
00823     }*/
00824     return TRUE;
00825 }
00826 
00827 
00828 void
00829 qof_init (void)
00830 {
00831     qof_util_get_string_cache ();
00832     guid_init ();
00833     qof_date_init ();
00834     qof_object_initialize ();
00835     qof_query_init ();
00836     qof_book_register ();
00837 }
00838 
00839 void
00840 qof_close (void)
00841 {
00842     qof_query_shutdown ();
00843     qof_object_shutdown ();
00844     guid_shutdown ();
00845     qof_date_close ();
00846     qof_util_string_cache_destroy ();
00847 }
00848 
00849 /* ************************ END OF FILE ***************************** */