QOF
0.8.7
|
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 ***************************** */