QOF  0.7.5
qofutil.c
1 /********************************************************************\
2  * qofutil.c -- QOF utility functions *
3  * Copyright (C) 1997 Robin D. Clark *
4  * Copyright (C) 1997-2001,2004 Linas Vepstas <linas@linas.org> *
5  * Copyright 2006 Neil Williams <linux@codehelp.co.uk> *
6  * *
7  * This program is free software; you can redistribute it and/or *
8  * modify it under the terms of the GNU General Public License as *
9  * published by the Free Software Foundation; either version 2 of *
10  * the License, or (at your option) any later version. *
11  * *
12  * This program is distributed in the hope that it will be useful, *
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15  * GNU General Public License for more details. *
16  * *
17  * You should have received a copy of the GNU General Public License*
18  * along with this program; if not, contact: *
19  * *
20  * Free Software Foundation Voice: +1-617-542-5942 *
21  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
22  * Boston, MA 02110-1301, USA gnu@gnu.org *
23  * *
24  * Author: Rob Clark (rclark@cs.hmc.edu) *
25  * Author: Linas Vepstas (linas@linas.org) *
26 \********************************************************************/
27 
28 #include "config.h"
29 
30 #include <errno.h>
31 #include <ctype.h>
32 #include <glib.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <math.h>
36 #include "qof.h"
37 #include "qofundo-p.h"
38 #include "qofbook-p.h"
39 
40 static QofLogModule log_module = QOF_MOD_UTIL;
41 
42 /* Search for str2 in first nchar chars of str1, ignore case.. Return
43  * pointer to first match, or null. */
44 gchar *
45 strncasestr (const guchar * str1, const guchar * str2, size_t len)
46 {
47  while (*str1 && len--)
48  {
49  if (toupper (*str1) == toupper (*str2))
50  {
51  if (strncasecmp (str1, str2, strlen (str2)) == 0)
52  return (gchar *) str1;
53  }
54  str1++;
55  }
56  return NULL;
57 }
58 
59 #ifndef HAVE_STRCASESTR
60 /* Search for str2 in str1, ignore case. Return pointer to first
61  * match, or null. */
62 gchar *
63 strcasestr (const gchar * str1, const gchar * str2)
64 {
65  size_t len = strlen (str1);
66  gchar *retval = strncasestr (str1, str2, len);
67  return retval;
68 }
69 #endif
70 
71 gint
72 safe_strcmp (const gchar * da, const gchar * db)
73 {
74  if ((da) && (db))
75  {
76  if ((da) != (db))
77  {
78  gint retval = strcmp ((da), (db));
79  /* if strings differ, return */
80  if (retval)
81  return retval;
82  }
83  }
84  else if ((!(da)) && (db))
85  return -1;
86  else if ((da) && (!(db)))
87  return +1;
88  return 0;
89 }
90 
91 gint
92 safe_strcasecmp (const gchar * da, const gchar * db)
93 {
94  if ((da) && (db))
95  {
96  if ((da) != (db))
97  {
98  gint retval = strcasecmp ((da), (db));
99  /* if strings differ, return */
100  if (retval)
101  return retval;
102  }
103  }
104  else if ((!(da)) && (db))
105  return -1;
106  else if ((da) && (!(db)))
107  return +1;
108  return 0;
109 }
110 
111 inline gint
112 null_strcmp (const gchar * da, const gchar * db)
113 {
114  if (da && db)
115  return strcmp (da, db);
116  if (!da && db && 0 == db[0])
117  return 0;
118  if (!db && da && 0 == da[0])
119  return 0;
120  if (!da && db)
121  return -1;
122  if (da && !db)
123  return +1;
124  return 0;
125 }
126 
127 #define MAX_DIGITS 50
128 
129 /* inverse of strtoul */
130 gchar *
131 ultostr (gulong val, gint base)
132 {
133  gchar buf[MAX_DIGITS];
134  gulong broke[MAX_DIGITS];
135  gint i;
136  gulong places = 0, reval;
137 
138  if ((2 > base) || (36 < base))
139  return NULL;
140 
141  /* count digits */
142  places = 0;
143  for (i = 0; i < MAX_DIGITS; i++)
144  {
145  broke[i] = val;
146  places++;
147  val /= base;
148  if (0 == val)
149  break;
150  }
151 
152  /* normalize */
153  reval = 0;
154  for (i = places - 2; i >= 0; i--)
155  {
156  reval += broke[i + 1];
157  reval *= base;
158  broke[i] -= reval;
159  }
160 
161  /* print */
162  for (i = 0; i < (gint) places; i++)
163  {
164  if (10 > broke[i])
165  {
166  buf[places - 1 - i] = 0x30 + broke[i]; /* ascii digit zero */
167  }
168  else
169  {
170  buf[places - 1 - i] = 0x41 - 10 + broke[i]; /* ascii capital A */
171  }
172  }
173  buf[places] = 0x0;
174 
175  return g_strdup (buf);
176 }
177 
178 inline gint
179 qof_util_double_compare (gdouble d1, gdouble d2)
180 {
181  if (isnan (d1) && isnan (d2))
182  return 0;
183  if (d1 < d2)
184  return -1;
185  if (d1 > d2)
186  return 1;
187  return 0;
188 }
189 
190 /* =================================================================== */
191 /* returns TRUE if the string is a number, possibly with whitespace */
192 /* =================================================================== */
193 
194 gboolean
195 qof_util_string_isnum (const guchar * s)
196 {
197  if (s == NULL)
198  return FALSE;
199  if (*s == 0)
200  return FALSE;
201 
202  while (*s && isspace (*s))
203  s++;
204 
205  if (*s == 0)
206  return FALSE;
207  if (!isdigit (*s))
208  return FALSE;
209 
210  while (*s && isdigit (*s))
211  s++;
212 
213  if (*s == 0)
214  return TRUE;
215 
216  while (*s && isspace (*s))
217  s++;
218 
219  if (*s == 0)
220  return TRUE;
221 
222  return FALSE;
223 }
224 
225 /* =================================================================== */
226 /* Return NULL if the field is whitespace (blank, tab, formfeed etc.)
227  * Else return pointer to first non-whitespace character. */
228 /* =================================================================== */
229 
230 const gchar *
231 qof_util_whitespace_filter (const gchar * val)
232 {
233  size_t len;
234  if (!val)
235  return NULL;
236 
237  len = strspn (val, "\a\b\t\n\v\f\r ");
238  if (0 == val[len])
239  return NULL;
240  return val + len;
241 }
242 
243 /* =================================================================== */
244 /* Return integer 1 if the string starts with 't' or 'T' or contains the
245  * word 'true' or 'TRUE'; if string is a number, return that number. */
246 /* =================================================================== */
247 
248 gint
249 qof_util_bool_to_int (const gchar * val)
250 {
251  const gchar *p = qof_util_whitespace_filter (val);
252  if (!p)
253  return 0;
254  if ('t' == p[0])
255  return 1;
256  if ('T' == p[0])
257  return 1;
258  if ('y' == p[0])
259  return 1;
260  if ('Y' == p[0])
261  return 1;
262  if (strstr (p, "true"))
263  return 1;
264  if (strstr (p, "TRUE"))
265  return 1;
266  if (strstr (p, "yes"))
267  return 1;
268  if (strstr (p, "YES"))
269  return 1;
270  return atoi (val);
271 }
272 
273 /* =================================================================== */
274 /* Entity edit and commit utilities */
275 /* =================================================================== */
276 
277 gboolean
279 {
280  QofBackend *be;
281  QofUndo *undo_data;
282 
283  if (!inst)
284  return FALSE;
285  (inst->editlevel)++;
286  if (1 < inst->editlevel)
287  return FALSE;
288  if (0 >= inst->editlevel)
289  inst->editlevel = 1;
290  be = qof_book_get_backend (inst->book);
291  if (param != NULL)
292  {
293  undo_data = inst->book->undo_data;
294  inst->param = param;
295  if (undo_data->undo_operation_open)
296  qof_undo_modify (inst, param);
297  }
298  if (be && qof_backend_begin_exists (be))
299  qof_backend_run_begin (be, inst);
300  else
301  inst->dirty = TRUE;
302  return TRUE;
303 }
304 
305 gboolean
307 {
308  QofUndo *undo_data;
309  QofBackend * be;
310 
311  if (!inst)
312  return FALSE;
313  (inst->editlevel)--;
314  if (0 < inst->editlevel)
315  return FALSE;
316  be = qof_book_get_backend (inst->book);
317  inst->param = param;
318  if (be && qof_backend_commit_exists (be))
319  qof_backend_run_commit (be, inst);
320  if (param != NULL)
321  {
322  undo_data = inst->book->undo_data;
323  if (undo_data->undo_operation_open)
324  qof_undo_commit (inst, param);
325  }
326  return TRUE;
327 }
328 
329 gchar *
330 qof_util_make_utf8 (gchar * string)
331 {
332  gchar *value;
333 
334  if (!string)
335  return NULL;
336  if (g_utf8_validate (string, -1, NULL))
337  return string;
338  value = g_locale_to_utf8 (string, -1, NULL, NULL, NULL);
339  if (!value)
340  {
341  PWARN (" unable to convert from locale %s", string);
342  PINFO ("trying to convert from ISO-8859-15.");
343  value = g_convert (string, -1, "UTF-8", "ISO-8859-15",
344  NULL, NULL, NULL);
345  if (!value)
346  {
347  PERR (" conversion failed");
348  return string;
349  }
350  return value;
351  }
352  return value;
353 }
354 
355 /* =================================================================== */
356 /* The QOF string cache */
357 /* =================================================================== */
358 
359 static GCache *qof_string_cache = NULL;
360 
361 #ifdef THESE_CAN_BE_USEFUL_FOR_DEGUGGING
362 static guint
363 g_str_hash_KEY (gconstpointer v)
364 {
365  return g_str_hash (v);
366 }
367 
368 static guint
369 g_str_hash_VAL (gconstpointer v)
370 {
371  return g_str_hash (v);
372 }
373 
374 static gpointer
375 g_strdup_VAL (gpointer v)
376 {
377  return g_strdup (v);
378 }
379 
380 static gpointer
381 g_strdup_KEY (gpointer v)
382 {
383  return g_strdup (v);
384 }
385 static void
386 g_free_VAL (gpointer v)
387 {
388  return g_free (v);
389 }
390 static void
391 g_free_KEY (gpointer v)
392 {
393  return g_free (v);
394 }
395 
396 static gboolean
397 qof_util_str_equal (gconstpointer v, gconstpointer v2)
398 {
399  return (v && v2) ? g_str_equal (v, v2) : FALSE;
400 }
401 #endif
402 #ifdef QOF_DISABLE_DEPRECATED
403 static GCache *
405 #else
406 GCache *
408 #endif
409 {
410  if (!qof_string_cache)
411  {
412  qof_string_cache = g_cache_new ((GCacheNewFunc) g_strdup, /* value_new_func */
413  g_free, /* value_destroy_func */
414  (GCacheDupFunc) g_strdup, /* key_dup_func */
415  g_free, /* key_destroy_func */
416  g_str_hash, /* hash_key_func */
417  g_str_hash, /* hash_value_func */
418  g_str_equal); /* key_equal_func */
419  }
420  return qof_string_cache;
421 }
422 
423 void
425 {
426  if (qof_string_cache)
427  g_cache_destroy (qof_string_cache);
428  qof_string_cache = NULL;
429 }
430 
431 void
432 qof_util_string_cache_remove (gconstpointer key)
433 {
434  if (key)
435  g_cache_remove (qof_util_get_string_cache (), key);
436 }
437 
438 gpointer
439 qof_util_string_cache_insert (gconstpointer key)
440 {
441  if (key)
442  return g_cache_insert(qof_util_get_string_cache(), (gpointer)key);
443  return NULL;
444 }
445 
446 gchar *
448 {
449  gchar *param_string;
450  gchar param_sa[GUID_ENCODING_LENGTH + 1];
451  gboolean known_type;
452  QofType paramType;
453  const GUID *param_guid;
454  QofNumeric param_numeric, (*numeric_getter) (QofEntity *, const QofParam *);
455  gdouble param_double, (*double_getter) (QofEntity *, const QofParam *);
456  gboolean param_boolean, (*boolean_getter) (QofEntity *, const QofParam *);
457  gint32 param_i32, (*int32_getter) (QofEntity *, const QofParam *);
458  gint64 param_i64, (*int64_getter) (QofEntity *, const QofParam *);
459  gchar param_char, (*char_getter) (QofEntity *, const QofParam *);
460 
461  param_string = NULL;
462  known_type = FALSE;
463  g_return_val_if_fail (ent && param, NULL);
464  paramType = param->param_type;
465  if (safe_strcmp (paramType, QOF_TYPE_STRING) == 0)
466  {
467  param_string = g_strdup (param->param_getfcn (ent, param));
468  if (param_string == NULL)
469  {
470  param_string = "";
471  }
472  known_type = TRUE;
473  return param_string;
474  }
475  if (safe_strcmp (paramType, QOF_TYPE_TIME) == 0)
476  {
477  QofTime *param_qt;
478  QofDate *qd;
479  param_qt = param->param_getfcn (ent, param);
480  qd = qof_date_from_qtime (param_qt);
481  return qof_date_print (qd, QOF_DATE_FORMAT_UTC);
482  }
483 #ifndef QOF_DISABLE_DEPRECATED
484  if (safe_strcmp (paramType, QOF_TYPE_DATE) == 0)
485  {
486  Timespec param_ts, (*date_getter) (QofEntity *, const QofParam *);
487  time_t param_t;
488  gchar param_date[MAX_DATE_LENGTH];
489 
490  date_getter =
491  (Timespec (*)(QofEntity *, const QofParam *)) param->param_getfcn;
492  param_ts = date_getter (ent, param);
493  param_t = param_ts.tv_sec;
494  strftime (param_date, MAX_DATE_LENGTH,
495  QOF_UTC_DATE_FORMAT, gmtime (&param_t));
496  param_string = g_strdup (param_date);
497  known_type = TRUE;
498  return param_string;
499  }
500 #endif
501  if ((safe_strcmp (paramType, QOF_TYPE_NUMERIC) == 0) ||
502  (safe_strcmp (paramType, QOF_TYPE_DEBCRED) == 0))
503  {
504  numeric_getter =
505  (QofNumeric (*)(QofEntity *, const QofParam *)) param->param_getfcn;
506  param_numeric = numeric_getter (ent, param);
507  param_string = g_strdup (qof_numeric_to_string (param_numeric));
508  known_type = TRUE;
509  return param_string;
510  }
511  if (safe_strcmp (paramType, QOF_TYPE_GUID) == 0)
512  {
513  param_guid = param->param_getfcn (ent, param);
514  guid_to_string_buff (param_guid, param_sa);
515  param_string = g_strdup (param_sa);
516  known_type = TRUE;
517  return param_string;
518  }
519  if (safe_strcmp (paramType, QOF_TYPE_INT32) == 0)
520  {
521  int32_getter =
522  (gint32 (*)(QofEntity *, const QofParam *)) param->param_getfcn;
523  param_i32 = int32_getter (ent, param);
524  param_string = g_strdup_printf ("%d", param_i32);
525  known_type = TRUE;
526  return param_string;
527  }
528  if (safe_strcmp (paramType, QOF_TYPE_INT64) == 0)
529  {
530  int64_getter =
531  (gint64 (*)(QofEntity *, const QofParam *)) param->param_getfcn;
532  param_i64 = int64_getter (ent, param);
533  param_string = g_strdup_printf ("%" G_GINT64_FORMAT, param_i64);
534  known_type = TRUE;
535  return param_string;
536  }
537  if (safe_strcmp (paramType, QOF_TYPE_DOUBLE) == 0)
538  {
539  double_getter =
540  (double (*)(QofEntity *, const QofParam *)) param->param_getfcn;
541  param_double = double_getter (ent, param);
542  param_string = g_strdup_printf ("%f", param_double);
543  known_type = TRUE;
544  return param_string;
545  }
546  if (safe_strcmp (paramType, QOF_TYPE_BOOLEAN) == 0)
547  {
548  boolean_getter =
549  (gboolean (*)(QofEntity *, const QofParam *)) param->param_getfcn;
550  param_boolean = boolean_getter (ent, param);
551  /* Boolean values need to be lowercase for QSF validation. */
552  if (param_boolean == TRUE)
553  {
554  param_string = g_strdup ("true");
555  }
556  else
557  {
558  param_string = g_strdup ("false");
559  }
560  known_type = TRUE;
561  return param_string;
562  }
563  /* "kvp" contains repeating values, cannot be a single string for the frame. */
564  if (safe_strcmp (paramType, QOF_TYPE_KVP) == 0)
565  {
566  KvpFrame *frame = NULL;
567  frame = param->param_getfcn (ent, param);
568  known_type = TRUE;
569  if (!kvp_frame_is_empty (frame))
570  {
571  GHashTable *hash = kvp_frame_get_hash (frame);
572  param_string = g_strdup_printf ("%s(%d)", QOF_TYPE_KVP,
573  g_hash_table_size (hash));
574  }
575  return param_string;
576  }
577  if (safe_strcmp (paramType, QOF_TYPE_CHAR) == 0)
578  {
579  char_getter =
580  (gchar (*)(QofEntity *, const QofParam *)) param->param_getfcn;
581  param_char = char_getter (ent, param);
582  known_type = TRUE;
583  return g_strdup_printf ("%c", param_char);
584  }
585  /* "collect" contains repeating values, cannot be a single string. */
586  if (safe_strcmp (paramType, QOF_TYPE_COLLECT) == 0)
587  {
588  QofCollection *col = NULL;
589  col = param->param_getfcn (ent, param);
590  known_type = TRUE;
591  return g_strdup_printf ("%s(%d)",
593  }
594  if (safe_strcmp (paramType, QOF_TYPE_CHOICE) == 0)
595  {
596  QofEntity *child = NULL;
597  child = param->param_getfcn (ent, param);
598  if (!child)
599  {
600  return param_string;
601  }
602  known_type = TRUE;
603  return g_strdup (qof_object_printable (child->e_type, child));
604  }
605  if (safe_strcmp (paramType, QOF_PARAM_BOOK) == 0)
606  {
607  QofBackend *be;
608  QofBook *book;
609  book = param->param_getfcn (ent, param);
610  PINFO (" book param %p", book);
611  be = qof_book_get_backend (book);
612  known_type = TRUE;
613  PINFO (" backend=%p", be);
614  if (!be)
615  {
616  return QOF_PARAM_BOOK;
617  }
618  param_string = g_strdup (be->fullpath);
619  PINFO (" fullpath=%s", param_string);
620  if (param_string)
621  {
622  return param_string;
623  }
624  param_guid = qof_entity_get_guid ((QofEntity*)book);
625  guid_to_string_buff (param_guid, param_sa);
626  PINFO (" book GUID=%s", param_sa);
627  param_string = g_strdup (param_sa);
628  return param_string;
629  }
630  if (!known_type)
631  {
632  QofEntity *child = NULL;
633  child = param->param_getfcn (ent, param);
634  if (!child)
635  {
636  return param_string;
637  }
638  return g_strdup (qof_object_printable (child->e_type, child));
639  }
640  return g_strdup ("");
641 }
642 
643 gboolean
645  const gchar * value_string)
646 {
647  void (*string_setter) (QofEntity *, const gchar *);
648  void (*time_setter) (QofEntity *, QofTime *);
649  void (*numeric_setter) (QofEntity *, QofNumeric);
650  void (*guid_setter) (QofEntity *, const GUID *);
651  void (*double_setter) (QofEntity *, gdouble);
652  void (*boolean_setter) (QofEntity *, gboolean);
653  void (*i32_setter) (QofEntity *, gint32);
654  void (*i64_setter) (QofEntity *, gint64);
655  void (*char_setter) (QofEntity *, gchar);
656 /* void (*kvp_frame_setter) (QofEntity *, KvpFrame *);
657  void (*reference_setter) (QofEntity *, QofEntity *);
658  void (*collection_setter) (QofEntity *, QofCollection *);*/
659 
660  g_return_val_if_fail (ent, FALSE);
661  g_return_val_if_fail (param, FALSE);
662  g_return_val_if_fail (value_string, FALSE);
663 
664  if (safe_strcmp (param->param_type, QOF_TYPE_STRING) == 0)
665  {
666  string_setter =
667  (void (*)(QofEntity *,
668  const gchar *)) param->param_setfcn;
669  if (string_setter != NULL)
670  string_setter (ent, value_string);
671 // registered_type = TRUE;
672  }
673  if (safe_strcmp (param->param_type, QOF_TYPE_TIME) == 0)
674  {
675  QofTime *qt;
676  QofDate *qd;
677 
678  qd = qof_date_parse (value_string, QOF_DATE_FORMAT_UTC);
679  if (!qd)
680  return FALSE;
681  qt = qof_date_to_qtime (qd);
682  time_setter =
683  (void (*)(QofEntity *, QofTime *))
684  param->param_setfcn;
685  if ((time_setter != NULL) && (qof_time_is_valid (qt)))
686  time_setter (ent, qt);
687  qof_date_free (qd);
688 // registered_type = TRUE;
689  }
690 #ifndef QOF_DISABLE_DEPRECATED
691  if (safe_strcmp (param->param_type, QOF_TYPE_DATE) == 0)
692  {
693  return FALSE;
694 // registered_type = TRUE;
695  }
696 #endif
697  if ((safe_strcmp (param->param_type, QOF_TYPE_NUMERIC) == 0) ||
698  (safe_strcmp (param->param_type, QOF_TYPE_DEBCRED) == 0))
699  {
700  QofNumeric num;
701  numeric_setter =
702  (void (*)(QofEntity *,
703  QofNumeric)) param->param_setfcn;
704  if (!qof_numeric_from_string (value_string, &num) ||
705  (qof_numeric_check (num) != QOF_ERROR_OK))
706  return FALSE;
707  if (numeric_setter != NULL)
708  numeric_setter (ent, num);
709 // registered_type = TRUE;
710  }
711  if (safe_strcmp (param->param_type, QOF_TYPE_GUID) == 0)
712  {
713  GUID * guid;
714 
715  guid = guid_malloc();
716  guid_new (guid);
717  guid_setter =
718  (void (*)(QofEntity *,
719  const GUID *)) param->param_setfcn;
720  if (!string_to_guid(value_string, guid))
721  return FALSE;
722  if (guid_setter != NULL)
723  guid_setter (ent, guid);
724 // registered_type = TRUE;
725  }
726  if (safe_strcmp (param->param_type, QOF_TYPE_INT32) == 0)
727  {
728  gint32 i32;
729  gchar *tail;
730 
731  errno = 0;
732  i32_setter =
733  (void (*)(QofEntity *, gint32)) param->param_setfcn;
734  i32 =
735  (gint32) strtol (value_string, &tail, 0);
736  if ((i32_setter != NULL) && (errno == 0))
737 
738  i32_setter (ent, i32);
739 // registered_type = TRUE;
740  }
741  if (safe_strcmp (param->param_type, QOF_TYPE_INT64) == 0)
742  {
743  gint64 i64;
744  gchar *tail;
745 
746  errno = 0;
747  i64 = strtoll (value_string, &tail, 0);
748  i64_setter =
749  (void (*)(QofEntity *, gint64)) param->param_setfcn;
750  if ((i64_setter != NULL) && (errno == 0))
751  i64_setter (ent, i64);
752 // registered_type = TRUE;
753  }
754  if (safe_strcmp (param->param_type, QOF_TYPE_DOUBLE) == 0)
755  {
756  gdouble db;
757  gchar *tail;
758 
759  errno = 0;
760  db = strtod (value_string, &tail);
761  double_setter =
762  (void (*)(QofEntity *, gdouble)) param->param_setfcn;
763  if ((double_setter != NULL) && (errno == 0))
764  double_setter (ent, db);
765 // registered_type = TRUE;
766  }
767  if (safe_strcmp (param->param_type, QOF_TYPE_BOOLEAN) == 0)
768  {
769  gint val;
770  gboolean b;
771 
772  boolean_setter =
773  (void (*)(QofEntity *, gboolean)) param->param_setfcn;
774  val = qof_util_bool_to_int(value_string);
775  if ((val > 1) || (val < 0))
776  return FALSE;
777  b = (val == 1) ? TRUE : FALSE;
778  if (boolean_setter != NULL)
779  boolean_setter (ent, val);
780 // registered_type = TRUE;
781  }
782  if (safe_strcmp (param->param_type, QOF_TYPE_KVP) == 0)
783  {
784  /* unsupported */
785  return FALSE;
786 /* KvpFrame * frame;
787  KvpValue * value;
788 
789  kvp_frame_setter =
790  (void (*)(QofEntity *, KvpFrame *)) param->param_setfcn;
791  if (kvp_frame_setter != NULL)
792  kvp_frame_setter (rule->targetEnt, cm_kvp);
793 // registered_type = TRUE;*/
794  }
795  if (safe_strcmp (param->param_type, QOF_TYPE_CHAR) == 0)
796  {
797  char_setter =
798  (void (*)(QofEntity *, gchar)) param->param_setfcn;
799  if (char_setter != NULL)
800  char_setter (ent, value_string[0]);
801 // registered_type = TRUE;
802  }
803  if (safe_strcmp (param->param_type, QOF_TYPE_COLLECT) == 0)
804  {
805  /* unsupported */
806  return FALSE;
807  }
808  if (safe_strcmp (param->param_type, QOF_TYPE_CHOICE) == 0)
809  {
810  /* unsupported*/
811  return FALSE;
812  }
813 /* if (registered_type == FALSE)
814  {
815  referenceEnt =
816  cm_param->param_getfcn (rule->importEnt, cm_param);
817  if (referenceEnt)
818  {
819  reference_setter =
820  (void (*)(QofEntity *, QofEntity *)) cm_param->
821  param_setfcn;
822  if (reference_setter != NULL)
823  {
824  reference_setter (rule->targetEnt, referenceEnt);
825  }
826  }
827  }*/
828  return TRUE;
829 }
830 
831 
832 void
833 qof_init (void)
834 {
836  guid_init ();
837  qof_date_init ();
838  qof_object_initialize ();
839  qof_query_init ();
841 }
842 
843 void
844 qof_close (void)
845 {
846  qof_query_shutdown ();
847  qof_object_shutdown ();
848  guid_shutdown ();
849  qof_date_close ();
851 }
852 
853 /* ************************ END OF FILE ***************************** */