QOF  0.8.7
Files | Macros | Functions
Utilities: Miscellany

Files

file  qofutil.h
 QOF utility functions.
 

Macros

#define QOF_MOD_UTIL   "qof-utilities"
 
#define stpcpy   g_stpcpy
 omitted if stpcpy exists.
 
#define CACHE_INSERT(str)   qof_util_string_cache_insert((gconstpointer)(str))
 
#define CACHE_REMOVE(str)   qof_util_string_cache_remove((str))
 
#define CACHE_REPLACE(dst, src)
 
#define QOF_CACHE_NEW(void)   qof_util_string_cache_insert("")
 

Functions

gint safe_strcmp (const gchar *da, const gchar *db)
 
gint safe_strcasecmp (const gchar *da, const gchar *db)
 
gint null_strcmp (const gchar *da, const gchar *db)
 
gchar * strncasestr (const guchar *str1, const guchar *str2, size_t len)
 
gchar * strcasestr (const gchar *str1, const gchar *str2)
 
gchar * ultostr (gulong val, gint base)
 
gboolean qof_util_string_isnum (const guchar *s)
 
gint qof_util_double_compare (gdouble v1, gdouble v2)
 Compare two gdouble values.
 
const gchar * qof_util_whitespace_filter (const gchar *val)
 
gint qof_util_bool_to_int (const gchar *val)
 
gchar * qof_util_param_to_string (QofEntity *ent, const QofParam *param)
 Converts a parameter to a string for storage or display. More...
 
gboolean qof_util_param_set_string (QofEntity *ent, const QofParam *param, const gchar *value_string)
 Set a parameter from a value string. More...
 
gchar * qof_util_make_utf8 (gchar *string)
 Convert strings received from the wrapped objects into UTF-8. More...
 
void qof_util_string_cache_destroy (void)
 
void qof_util_string_cache_remove (gconstpointer key)
 
gpointer qof_util_string_cache_insert (gconstpointer key)
 
gboolean qof_util_param_edit (QofInstance *inst, const QofParam *param)
 Prepare to edit a parameter. More...
 
gboolean qof_util_param_commit (QofInstance *inst, const QofParam *param)
 Commit this parameter change, with undo support. More...
 

typedef enum as string macros

#define ENUM_BODY(name, value)    name value,
 
#define AS_STRING_CASE(name, value)    case name: { return #name; }
 
#define FROM_STRING_CASE(name, value)
 
#define DEFINE_ENUM(name, list)
 
#define AS_STRING_DEC(name, list)    const gchar* name##asString(name n);
 
#define AS_STRING_FUNC(name, list)
 
#define FROM_STRING_DEC(name, list)
 
#define FROM_STRING_FUNC(name, list)
 

enum as string with no typedef

Similar but used when the enum is NOT a typedef Make sure you use the DEFINE_ENUM_NON_TYPEDEF macro.

You can precede the FROM_STRING_FUNC_NON_TYPEDEF and AS_STRING_FUNC_NON_TYPEDEF macros with the keyword static if appropriate.

ENUM_BODY is used in both types.

#define DEFINE_ENUM_NON_TYPEDEF(name, list)
 
#define FROM_STRING_DEC_NON_TYPEDEF(name, list)
 
#define FROM_STRING_CASE_NON_TYPEDEF(name, value)   if (strcmp(str, #name) == 0) { *type = name; }
 
#define FROM_STRING_FUNC_NON_TYPEDEF(name, list)
 
#define AS_STRING_DEC_NON_TYPEDEF(name, list)    const gchar* name##asString(enum name n);
 
#define AS_STRING_FUNC_NON_TYPEDEF(name, list)
 
#define AS_STRING_CASE_NON_TYPEDEF(name, value)    case name: { return #name; }
 

Convenience wrappers

void qof_init (void)
 Initialise the Query Object Framework. More...
 
void qof_close (void)
 Safely close down the Query Object Framework. More...
 

Detailed Description

Macro Definition Documentation

#define AS_STRING_FUNC (   name,
  list 
)
Value:
const gchar* name##asString(name n) { \
switch (n) { \
list(AS_STRING_CASE) \
default: return ""; } }

Definition at line 66 of file qofutil.h.

#define AS_STRING_FUNC_NON_TYPEDEF (   name,
  list 
)
Value:
const gchar* name##asString(enum name n) { \
switch (n) { \
list(AS_STRING_CASE_NON_TYPEDEF) \
default: return ""; } }

Definition at line 119 of file qofutil.h.

#define CACHE_REPLACE (   dst,
  src 
)
Value:
do { \
gpointer tmp = CACHE_INSERT((src)); \
CACHE_REMOVE((dst)); \
(dst) = tmp; \
} while (0)

Definition at line 325 of file qofutil.h.

#define DEFINE_ENUM (   name,
  list 
)
Value:
typedef enum { \
list(ENUM_BODY) \
}name;

Definition at line 58 of file qofutil.h.

#define DEFINE_ENUM_NON_TYPEDEF (   name,
  list 
)
Value:
enum name { \
list(ENUM_BODY) \
};

Definition at line 98 of file qofutil.h.

#define FROM_STRING_CASE (   name,
  value 
)
Value:
if (strcmp(str, #name) == 0) { \
return name; }

Definition at line 54 of file qofutil.h.

#define FROM_STRING_DEC (   name,
  list 
)
Value:
name name##fromString \
(const gchar* str);

Definition at line 72 of file qofutil.h.

#define FROM_STRING_DEC_NON_TYPEDEF (   name,
  list 
)
Value:
void name##fromString \
(const gchar* str, enum name *type);

Definition at line 103 of file qofutil.h.

#define FROM_STRING_FUNC (   name,
  list 
)
Value:
name name##fromString \
(const gchar* str) { \
if(str == NULL) { return 0; } \
list(FROM_STRING_CASE) \
return 0; }

Definition at line 76 of file qofutil.h.

#define FROM_STRING_FUNC_NON_TYPEDEF (   name,
  list 
)
Value:
void name##fromString \
(const gchar* str, enum name *type) { \
if(str == NULL) { return; } \
list(FROM_STRING_CASE_NON_TYPEDEF) }

Definition at line 110 of file qofutil.h.

Function Documentation

gint null_strcmp ( const gchar *  da,
const gchar *  db 
)
inline

The null_strcmp compares strings a and b the same way that strcmp() does, except that either may be null. This routine assumes that a null string is equal to the empty string.

Definition at line 115 of file qofutil.c.

116 {
117  if (da && db)
118  return strcmp (da, db);
119  if (!da && db && 0 == db[0])
120  return 0;
121  if (!db && da && 0 == da[0])
122  return 0;
123  if (!da && db)
124  return -1;
125  if (da && !db)
126  return +1;
127  return 0;
128 }
void qof_close ( void  )

Safely close down the Query Object Framework.

Use in place of separate close / shutdown functions (like guid_shutdown(), qof_query_shutdown() etc.) to protect against future changes.

Definition at line 840 of file qofutil.c.

841 {
842  qof_query_shutdown ();
843  qof_object_shutdown ();
844  guid_shutdown ();
845  qof_date_close ();
847 }
void qof_date_close(void)
close down the QofDate tables
Definition: qofdate.c:156
void guid_shutdown(void)
Definition: guid.c:437
void qof_util_string_cache_destroy(void)
Definition: qofutil.c:443
void qof_init ( void  )

Initialise the Query Object Framework.

Use in place of separate init functions (like guid_init() and qof_query_init() etc.) to protect against future changes.

Definition at line 829 of file qofutil.c.

830 {
831  qof_util_get_string_cache ();
832  guid_init ();
833  qof_date_init ();
834  qof_object_initialize ();
835  qof_query_init ();
837 }
gboolean qof_book_register(void)
Definition: qofbook.c:376
void qof_date_init(void)
initialise the QofDate tables
Definition: qofdate.c:67
void qof_query_init(void)
Definition: qofquery.c:1375
void guid_init(void)
Definition: guid.c:285
gint qof_util_bool_to_int ( const gchar *  val)

Return integer 1 if the string starts with 't' or 'T' or contains the word 'true' or 'TRUE'; if string is a number, return that number. (Leading whitespace is ignored).

Definition at line 252 of file qofutil.c.

253 {
254  const gchar *p = qof_util_whitespace_filter (val);
255  if (!p)
256  return 0;
257  if ('t' == p[0])
258  return 1;
259  if ('T' == p[0])
260  return 1;
261  if ('y' == p[0])
262  return 1;
263  if ('Y' == p[0])
264  return 1;
265  if (strstr (p, "true"))
266  return 1;
267  if (strstr (p, "TRUE"))
268  return 1;
269  if (strstr (p, "yes"))
270  return 1;
271  if (strstr (p, "YES"))
272  return 1;
273  return atoi (val);
274 }
const gchar * qof_util_whitespace_filter(const gchar *val)
Definition: qofutil.c:234
gchar* qof_util_make_utf8 ( gchar *  string)

Convert strings received from the wrapped objects into UTF-8.

A wrapper for g_locale_to_utf8 that removes the extra arguments. If the string is already valid UTF-8, it is returned unchanged.

Returns
the converted string or the original, unchanged, string on error or if the string is already UTF-8.

Definition at line 333 of file qofutil.c.

334 {
335  gchar *value;
336 
337  if (!string)
338  return NULL;
339  if (g_utf8_validate (string, -1, NULL))
340  return string;
341  value = g_locale_to_utf8 (string, -1, NULL, NULL, NULL);
342  if (!value)
343  {
344  PWARN (" unable to convert from locale %s", string);
345  PINFO ("trying to convert from ISO-8859-15.");
346  value = g_convert (string, -1, "UTF-8", "ISO-8859-15",
347  NULL, NULL, NULL);
348  if (!value)
349  {
350  PERR (" conversion failed");
351  return string;
352  }
353  return value;
354  }
355  return value;
356 }
#define PERR(format, args...)
Definition: qoflog.h:183
#define PINFO(format, args...)
Definition: qoflog.h:199
#define PWARN(format, args...)
Definition: qoflog.h:191
gboolean qof_util_param_commit ( QofInstance inst,
const QofParam param 
)

Commit this parameter change, with undo support.

Calls the commit() routine of the backend to commit an edit. If an undo operation has been started, also maintains the undo record so the change can be undone.

param_name can only be NULL if the QofSQLite backend is not in use.

Parameters
instThe QofInstance.
paramThe parameter being modified.
Returns
FALSE on error, otherwise TRUE.

Definition at line 309 of file qofutil.c.

310 {
311  QofUndo *undo_data;
312  QofBackend * be;
313 
314  if (!inst)
315  return FALSE;
316  (inst->editlevel)--;
317  if (0 < inst->editlevel)
318  return FALSE;
319  be = qof_book_get_backend (inst->book);
320  inst->param = param;
321  if (be && qof_backend_commit_exists (be))
322  qof_backend_run_commit (be, inst);
323  if (param != NULL)
324  {
325  undo_data = inst->book->undo_data;
326  if (undo_data->undo_operation_open)
327  qof_undo_commit (inst, param);
328  }
329  return TRUE;
330 }
QofUndo * undo_data
Definition: qofbook-p.h:90
QofBackend * qof_book_get_backend(QofBook *book)
Retrieve the backend used by this book.
Definition: qofbook.c:154
const QofParam * param
Definition: qofinstance-p.h:53
void qof_undo_commit(QofInstance *instance, const QofParam *param)
Definition: qofundo.c:549
QofBook * book
Definition: qofinstance-p.h:42
gboolean qof_util_param_edit ( QofInstance inst,
const QofParam param 
)

Prepare to edit a parameter.

Calls the begin() routine of the backend to prepare for an edit. If an undo operation has been started, also prepares an undo record.

param_name can only be NULL if the QofSQLite backend is not in use.

Note
The intention is that preparing and committing parameter changes is done outside the object using QofParam->param_setfcn but objects can obtain the QofParam themselves if preferred.

Making parameter changes using qof_util_param_edit and qof_util_param_commit makes for simpler QofUndo code because the undo handlers are called implicitly.

qof_book_start_operation (book, "edit PARAM_X");
param = qof_class_get_parameter(OBJ_TYPE, PARAM_NAME);
retbool = qof_util_param_edit (inst, param);
if (retbool)
    param->param_setfcn(ent, value);
retbool = qof_util_param_commit (inst, param);
Parameters
instThe QofInstance.
paramThe parameter being modified.
Returns
FALSE on error, otherwise TRUE.

Definition at line 281 of file qofutil.c.

282 {
283  QofBackend *be;
284  QofUndo *undo_data;
285 
286  if (!inst)
287  return FALSE;
288  (inst->editlevel)++;
289  if (1 < inst->editlevel)
290  return FALSE;
291  if (0 >= inst->editlevel)
292  inst->editlevel = 1;
293  be = qof_book_get_backend (inst->book);
294  if (param != NULL)
295  {
296  undo_data = inst->book->undo_data;
297  inst->param = param;
298  if (undo_data->undo_operation_open)
299  qof_undo_modify (inst, param);
300  }
301  if (be && qof_backend_begin_exists (be))
302  qof_backend_run_begin (be, inst);
303  else
304  inst->dirty = TRUE;
305  return TRUE;
306 }
QofUndo * undo_data
Definition: qofbook-p.h:90
QofBackend * qof_book_get_backend(QofBook *book)
Retrieve the backend used by this book.
Definition: qofbook.c:154
const QofParam * param
Definition: qofinstance-p.h:53
QofBook * book
Definition: qofinstance-p.h:42
void qof_undo_modify(QofInstance *instance, const QofParam *param)
Definition: qofundo.c:525
gboolean qof_util_param_set_string ( QofEntity ent,
const QofParam param,
const gchar *  value_string 
)

Set a parameter from a value string.

Used by string-based backends to set a value from a string previously written out to storage.

The string must be the same format as produced by qof_util_param_to_string for the same parameter type.

Parameters
entThe entity in which the value is to be set.
paramThe parameter that stores the value.
value_stringA string of exactly the same format as produced by qof_util_param_to_string for the parameter type.

e.g. a numeric type would require a string like 50/100 and a time type would require a UTC date stamp like 1907-10-07T03:34:29Z

Returns
FALSE if the string does not match the required type or cannot be set, TRUE on success.

Definition at line 647 of file qofutil.c.

649 {
650  void (*string_setter) (QofEntity *, const gchar *);
651  void (*time_setter) (QofEntity *, QofTime *);
652  void (*numeric_setter) (QofEntity *, QofNumeric);
653  void (*guid_setter) (QofEntity *, const GUID *);
654  void (*double_setter) (QofEntity *, gdouble);
655  void (*boolean_setter) (QofEntity *, gboolean);
656  void (*i32_setter) (QofEntity *, gint32);
657  void (*i64_setter) (QofEntity *, gint64);
658  void (*char_setter) (QofEntity *, gchar);
659 /* void (*kvp_frame_setter) (QofEntity *, KvpFrame *);
660  void (*reference_setter) (QofEntity *, QofEntity *);
661  void (*collection_setter) (QofEntity *, QofCollection *);*/
662 
663  g_return_val_if_fail (ent, FALSE);
664  g_return_val_if_fail (param, FALSE);
665  g_return_val_if_fail (value_string, FALSE);
666 
667  if (safe_strcmp (param->param_type, QOF_TYPE_STRING) == 0)
668  {
669  string_setter =
670  (void (*)(QofEntity *,
671  const gchar *)) param->param_setfcn;
672  if (string_setter != NULL)
673  string_setter (ent, value_string);
674 // registered_type = TRUE;
675  }
676  if (safe_strcmp (param->param_type, QOF_TYPE_TIME) == 0)
677  {
678  QofTime *qt;
679  QofDate *qd;
680 
681  qd = qof_date_parse (value_string, QOF_DATE_FORMAT_UTC);
682  if (!qd)
683  return FALSE;
684  qt = qof_date_to_qtime (qd);
685  time_setter =
686  (void (*)(QofEntity *, QofTime *))
687  param->param_setfcn;
688  if ((time_setter != NULL) && (qof_time_is_valid (qt)))
689  time_setter (ent, qt);
690  qof_date_free (qd);
691 // registered_type = TRUE;
692  }
693  if ((safe_strcmp (param->param_type, QOF_TYPE_NUMERIC) == 0) ||
694  (safe_strcmp (param->param_type, QOF_TYPE_DEBCRED) == 0))
695  {
696  QofNumeric num;
697  numeric_setter =
698  (void (*)(QofEntity *,
699  QofNumeric)) param->param_setfcn;
700  if (!qof_numeric_from_string (value_string, &num) ||
701  (qof_numeric_check (num) != QOF_ERROR_OK))
702  return FALSE;
703  if (numeric_setter != NULL)
704  numeric_setter (ent, num);
705 // registered_type = TRUE;
706  }
707  if (safe_strcmp (param->param_type, QOF_TYPE_GUID) == 0)
708  {
709  GUID * guid;
710 
711  guid = guid_malloc();
712  guid_new (guid);
713  guid_setter =
714  (void (*)(QofEntity *,
715  const GUID *)) param->param_setfcn;
716  if (!string_to_guid(value_string, guid))
717  return FALSE;
718  if (guid_setter != NULL)
719  guid_setter (ent, guid);
720 // registered_type = TRUE;
721  }
722  if (safe_strcmp (param->param_type, QOF_TYPE_INT32) == 0)
723  {
724  gint32 i32;
725  gchar *tail;
726 
727  errno = 0;
728  i32_setter =
729  (void (*)(QofEntity *, gint32)) param->param_setfcn;
730  i32 =
731  (gint32) strtol (value_string, &tail, 0);
732  if ((i32_setter != NULL) && (errno == 0))
733 
734  i32_setter (ent, i32);
735 // registered_type = TRUE;
736  }
737  if (safe_strcmp (param->param_type, QOF_TYPE_INT64) == 0)
738  {
739  gint64 i64;
740  gchar *tail;
741 
742  errno = 0;
743  i64 = strtoll (value_string, &tail, 0);
744  i64_setter =
745  (void (*)(QofEntity *, gint64)) param->param_setfcn;
746  if ((i64_setter != NULL) && (errno == 0))
747  i64_setter (ent, i64);
748 // registered_type = TRUE;
749  }
750  if (safe_strcmp (param->param_type, QOF_TYPE_DOUBLE) == 0)
751  {
752  gdouble db;
753  gchar *tail;
754 
755  errno = 0;
756  db = strtod (value_string, &tail);
757  double_setter =
758  (void (*)(QofEntity *, gdouble)) param->param_setfcn;
759  if ((double_setter != NULL) && (errno == 0))
760  double_setter (ent, db);
761 // registered_type = TRUE;
762  }
763  if (safe_strcmp (param->param_type, QOF_TYPE_BOOLEAN) == 0)
764  {
765  gint val;
766  gboolean G_GNUC_UNUSED b;
767 
768  boolean_setter =
769  (void (*)(QofEntity *, gboolean)) param->param_setfcn;
770  val = qof_util_bool_to_int(value_string);
771  if ((val > 1) || (val < 0))
772  return FALSE;
773  b = (val == 1) ? TRUE : FALSE;
774  if (boolean_setter != NULL)
775  boolean_setter (ent, val);
776 // registered_type = TRUE;
777  }
778  if (safe_strcmp (param->param_type, QOF_TYPE_KVP) == 0)
779  {
780  /* unsupported */
781  return FALSE;
782 /* KvpFrame * frame;
783  KvpValue * value;
784 
785  kvp_frame_setter =
786  (void (*)(QofEntity *, KvpFrame *)) param->param_setfcn;
787  if (kvp_frame_setter != NULL)
788  kvp_frame_setter (rule->targetEnt, cm_kvp);
789 // registered_type = TRUE;*/
790  }
791  if (safe_strcmp (param->param_type, QOF_TYPE_CHAR) == 0)
792  {
793  char_setter =
794  (void (*)(QofEntity *, gchar)) param->param_setfcn;
795  if (char_setter != NULL)
796  char_setter (ent, value_string[0]);
797 // registered_type = TRUE;
798  }
799  if (safe_strcmp (param->param_type, QOF_TYPE_COLLECT) == 0)
800  {
801  /* unsupported */
802  return FALSE;
803  }
804  if (safe_strcmp (param->param_type, QOF_TYPE_CHOICE) == 0)
805  {
806  /* unsupported*/
807  return FALSE;
808  }
809 /* if (registered_type == FALSE)
810  {
811  referenceEnt =
812  cm_param->param_getfcn (rule->importEnt, cm_param);
813  if (referenceEnt)
814  {
815  reference_setter =
816  (void (*)(QofEntity *, QofEntity *)) cm_param->
817  param_setfcn;
818  if (reference_setter != NULL)
819  {
820  reference_setter (rule->targetEnt, referenceEnt);
821  }
822  }
823  }*/
824  return TRUE;
825 }
QofNumericErrorCode qof_numeric_check(QofNumeric in)
Definition: qofnumeric.c:39
#define QOF_DATE_FORMAT_UTC
QOF UTC format, xsd:date compatible. QOF_UTC_DATE_FORMAT "%Y-%m-%dT%H:%M:%SZ".
Definition: qofdate.h:277
#define QOF_TYPE_COLLECT
secondary collections are used for one-to-many references between entities and are implemented using ...
Definition: qofclass.h:121
struct _QofNumeric QofNumeric
A rational-number type.
Definition: qofnumeric.h:61
void qof_date_free(QofDate *date)
Definition: qofdate.c:642
GUID * guid_malloc(void)
Definition: guid.c:64
gboolean string_to_guid(const gchar *string, GUID *guid)
gint qof_util_bool_to_int(const gchar *val)
Definition: qofutil.c:252
QofTime * qof_date_to_qtime(const QofDate *qd)
Definition: qofdate.c:926
Full range replacement for struct tm.
Definition: qofdate.h:138
QofDate * qof_date_parse(const gchar *str, QofDateFormat df)
Convert a timestamp to a QofTime.
Definition: qofdate.c:557
gboolean qof_numeric_from_string(const gchar *str, QofNumeric *n)
Definition: qofnumeric.c:1116
Definition: guid.h:53
void guid_new(GUID *guid)
Definition: guid.c:444
struct QofTime64 QofTime
Use a 64-bit signed int QofTime.
Definition: qoftime.h:112
gint safe_strcmp(const gchar *da, const gchar *db)
Definition: qofutil.c:75
#define QOF_TYPE_CHOICE
Identify an object as containing a choice.
Definition: qofchoice.h:103
gchar* qof_util_param_to_string ( QofEntity ent,
const QofParam param 
)

Converts a parameter to a string for storage or display.

The returned string must be freed by the caller.

Use qof_util_param_set_string to set the parameter using the string. Designed for backends that store all values as strings.

Definition at line 464 of file qofutil.c.

465 {
466  gchar *param_string;
467  gchar param_sa[GUID_ENCODING_LENGTH + 1];
468  gboolean known_type;
469  QofType paramType;
470  const GUID *param_guid;
471  QofNumeric param_numeric, (*numeric_getter) (QofEntity *, const QofParam *);
472  gdouble param_double, (*double_getter) (QofEntity *, const QofParam *);
473  gboolean param_boolean, (*boolean_getter) (QofEntity *, const QofParam *);
474  gint32 param_i32, (*int32_getter) (QofEntity *, const QofParam *);
475  gint64 param_i64, (*int64_getter) (QofEntity *, const QofParam *);
476  gchar param_char, (*char_getter) (QofEntity *, const QofParam *);
477 
478  param_string = NULL;
479  known_type = FALSE;
480  g_return_val_if_fail (ent && param, NULL);
481  paramType = param->param_type;
482  if (safe_strcmp (paramType, QOF_TYPE_STRING) == 0)
483  {
484  param_string = g_strdup (param->param_getfcn (ent, param));
485  if (param_string == NULL)
486  param_string = g_strdup("");
487  known_type = TRUE;
488  return param_string;
489  }
490  if (safe_strcmp (paramType, QOF_TYPE_TIME) == 0)
491  {
492  QofTime *param_qt;
493  QofDate *qd;
494  param_qt = param->param_getfcn (ent, param);
495  qd = qof_date_from_qtime (param_qt);
496  return qof_date_print (qd, QOF_DATE_FORMAT_UTC);
497  }
498  if ((safe_strcmp (paramType, QOF_TYPE_NUMERIC) == 0) ||
499  (safe_strcmp (paramType, QOF_TYPE_DEBCRED) == 0))
500  {
501  numeric_getter =
502  (QofNumeric (*)(QofEntity *, const QofParam *)) param->param_getfcn;
503  param_numeric = numeric_getter (ent, param);
504  param_string = g_strdup (qof_numeric_to_string (param_numeric));
505  known_type = TRUE;
506  return param_string;
507  }
508  if (safe_strcmp (paramType, QOF_TYPE_GUID) == 0)
509  {
510  param_guid = param->param_getfcn (ent, param);
511  guid_to_string_buff (param_guid, param_sa);
512  param_string = g_strdup (param_sa);
513  known_type = TRUE;
514  return param_string;
515  }
516  if (safe_strcmp (paramType, QOF_TYPE_INT32) == 0)
517  {
518  int32_getter =
519  (gint32 (*)(QofEntity *, const QofParam *)) param->param_getfcn;
520  param_i32 = int32_getter (ent, param);
521  param_string = g_strdup_printf ("%d", param_i32);
522  known_type = TRUE;
523  return param_string;
524  }
525  if (safe_strcmp (paramType, QOF_TYPE_INT64) == 0)
526  {
527  int64_getter =
528  (gint64 (*)(QofEntity *, const QofParam *)) param->param_getfcn;
529  param_i64 = int64_getter (ent, param);
530  param_string = g_strdup_printf ("%" G_GINT64_FORMAT, param_i64);
531  known_type = TRUE;
532  return param_string;
533  }
534  if (safe_strcmp (paramType, QOF_TYPE_DOUBLE) == 0)
535  {
536  double_getter =
537  (double (*)(QofEntity *, const QofParam *)) param->param_getfcn;
538  param_double = double_getter (ent, param);
539  param_string = g_strdup_printf ("%f", param_double);
540  known_type = TRUE;
541  return param_string;
542  }
543  if (safe_strcmp (paramType, QOF_TYPE_BOOLEAN) == 0)
544  {
545  boolean_getter =
546  (gboolean (*)(QofEntity *, const QofParam *)) param->param_getfcn;
547  param_boolean = boolean_getter (ent, param);
548  /* Boolean values need to be lowercase for QSF validation. */
549  if (param_boolean == TRUE)
550  {
551  param_string = g_strdup ("true");
552  }
553  else
554  {
555  param_string = g_strdup ("false");
556  }
557  known_type = TRUE;
558  return param_string;
559  }
560  /* "kvp" contains repeating values, cannot be a single string for the frame. */
561  if (safe_strcmp (paramType, QOF_TYPE_KVP) == 0)
562  {
563  KvpFrame *frame = NULL;
564  frame = param->param_getfcn (ent, param);
565  known_type = TRUE;
566  if (!kvp_frame_is_empty (frame))
567  {
568  GHashTable *hash = kvp_frame_get_hash (frame);
569  param_string = g_strdup_printf ("%s(%d)", QOF_TYPE_KVP,
570  g_hash_table_size (hash));
571  }
572  /* ensure a newly allocated string is returned, even
573  if the frame is empty. */
574  else
575  {
576  param_string = g_strdup("");
577  }
578  return param_string;
579  }
580  if (safe_strcmp (paramType, QOF_TYPE_CHAR) == 0)
581  {
582  char_getter =
583  (gchar (*)(QofEntity *, const QofParam *)) param->param_getfcn;
584  param_char = char_getter (ent, param);
585  known_type = TRUE;
586  return g_strdup_printf ("%c", param_char);
587  }
588  /* "collect" contains repeating values, cannot be a single string. */
589  if (safe_strcmp (paramType, QOF_TYPE_COLLECT) == 0)
590  {
591  QofCollection *col = NULL;
592  col = param->param_getfcn (ent, param);
593  known_type = TRUE;
594  return g_strdup_printf ("%s(%d)",
596  }
597  if (safe_strcmp (paramType, QOF_TYPE_CHOICE) == 0)
598  {
599  QofEntity *child = NULL;
600  child = param->param_getfcn (ent, param);
601  if (!child)
602  {
603  return param_string;
604  }
605  known_type = TRUE;
606  return g_strdup (qof_object_printable (child->e_type, child));
607  }
608  if (safe_strcmp (paramType, QOF_PARAM_BOOK) == 0)
609  {
610  QofBackend *be;
611  QofBook *book;
612  book = param->param_getfcn (ent, param);
613  PINFO (" book param %p", book);
614  be = qof_book_get_backend (book);
615  known_type = TRUE;
616  PINFO (" backend=%p", be);
617  if (!be)
618  {
619  return QOF_PARAM_BOOK;
620  }
621  param_string = g_strdup (be->fullpath);
622  PINFO (" fullpath=%s", param_string);
623  if (param_string)
624  {
625  return param_string;
626  }
627  param_guid = qof_entity_get_guid ((QofEntity*)book);
628  guid_to_string_buff (param_guid, param_sa);
629  PINFO (" book GUID=%s", param_sa);
630  param_string = g_strdup (param_sa);
631  return param_string;
632  }
633  if (!known_type)
634  {
635  QofEntity *child = NULL;
636  child = param->param_getfcn (ent, param);
637  if (!child)
638  {
639  return param_string;
640  }
641  return g_strdup (qof_object_printable (child->e_type, child));
642  }
643  return g_strdup ("");
644 }
#define QOF_DATE_FORMAT_UTC
QOF UTC format, xsd:date compatible. QOF_UTC_DATE_FORMAT "%Y-%m-%dT%H:%M:%SZ".
Definition: qofdate.h:277
gchar * fullpath
Definition: qofbackend-p.h:332
#define QOF_TYPE_COLLECT
secondary collections are used for one-to-many references between entities and are implemented using ...
Definition: qofclass.h:121
#define PINFO(format, args...)
Definition: qoflog.h:199
struct _QofNumeric QofNumeric
A rational-number type.
Definition: qofnumeric.h:61
QofDate * qof_date_from_qtime(const QofTime *qt)
Definition: qofdate.c:884
struct _KvpFrame KvpFrame
Definition: kvpframe.h:74
gchar * qof_date_print(const QofDate *date, QofDateFormat df)
Convert a QofDate to a timestamp according to the specified date format.
Definition: qofdate.c:581
gboolean kvp_frame_is_empty(KvpFrame *frame)
Definition: kvpframe.c:134
#define GUID_ENCODING_LENGTH
Definition: guid.h:64
#define QOF_PARAM_BOOK
Definition: qofquery.h:104
Full range replacement for struct tm.
Definition: qofdate.h:138
struct QofCollection_s QofCollection
Definition: qofid.h:138
guint qof_collection_count(QofCollection *col)
Definition: qofid.c:322
const gchar * qof_object_printable(QofIdTypeConst type_name, gpointer obj)
Definition: qofobject.c:205
gchar * guid_to_string_buff(const GUID *guid, gchar *buff)
const gchar * QofType
Definition: qofclass.h:125
QofIdType qof_collection_get_type(QofCollection *col)
Definition: qofid.c:146
Definition: guid.h:53
gchar * qof_numeric_to_string(QofNumeric n)
Definition: qofnumeric.c:1084
struct QofTime64 QofTime
Use a 64-bit signed int QofTime.
Definition: qoftime.h:112
const GUID * qof_entity_get_guid(QofEntity *ent)
Definition: qofid.c:105
QofBackend * qof_book_get_backend(QofBook *book)
Retrieve the backend used by this book.
Definition: qofbook.c:154
gint safe_strcmp(const gchar *da, const gchar *db)
Definition: qofutil.c:75
#define QOF_TYPE_CHOICE
Identify an object as containing a choice.
Definition: qofchoice.h:103
void qof_util_string_cache_destroy ( void  )

The QOF String Cache:

Many strings used throughout QOF and QOF applications are likely to be duplicated.

QOF provides a reference counted cache system for the strings, which shares strings whenever possible.

Use qof_util_string_cache_insert to insert a string into the cache (it will return a pointer to the cached string). Basically you should use this instead of g_strdup.

Use qof_util_string_cache_remove (giving it a pointer to a cached string) if the string is unused. If this is the last reference to the string it will be removed from the cache, otherwise it will just decrement the reference count. Basically you should use this instead of g_free.

Just in case it's not clear: The remove function must NOT be called for the string you passed INTO the insert function. It must be called for the cached string that is returned by the insert function.

Note that all the work is done when inserting or removing. Once cached the strings are just plain C strings.

The string cache is demand-created on first use.Destroy the qof_util_string_cache

Definition at line 443 of file qofutil.c.

443  {
444  if (qof_string_cache) {
445  qof_cache_destroy (qof_string_cache);
446  }
447  qof_string_cache = NULL;
448 }
gpointer qof_util_string_cache_insert ( gconstpointer  key)

You can use this function with g_hash_table_insert(), for the key (or value), as long as you use the destroy notifier above.

Definition at line 456 of file qofutil.c.

456  {
457  if (key) {
458  return qof_cache_insert(qof_util_get_string_cache(), (gpointer)key);
459  }
460  return NULL;
461 }
void qof_util_string_cache_remove ( gconstpointer  key)

You can use this function as a destroy notifier for a GHashTable that uses common strings as keys (or values, for that matter.)

Definition at line 450 of file qofutil.c.

450  {
451  if (key) {
452  qof_cache_remove (qof_util_get_string_cache (), key);
453  }
454 }
gboolean qof_util_string_isnum ( const guchar *  s)

Returns true if string s is a number, possibly surrounded by whitespace.

Definition at line 198 of file qofutil.c.

199 {
200  if (s == NULL)
201  return FALSE;
202  if (*s == 0)
203  return FALSE;
204 
205  while (*s && isspace (*s))
206  s++;
207 
208  if (*s == 0)
209  return FALSE;
210  if (!isdigit (*s))
211  return FALSE;
212 
213  while (*s && isdigit (*s))
214  s++;
215 
216  if (*s == 0)
217  return TRUE;
218 
219  while (*s && isspace (*s))
220  s++;
221 
222  if (*s == 0)
223  return TRUE;
224 
225  return FALSE;
226 }
const gchar* qof_util_whitespace_filter ( const gchar *  val)

Return NULL if the field is whitespace (blank, tab, formfeed etc.) Else return pointer to first non-whitespace character.

Definition at line 234 of file qofutil.c.

235 {
236  size_t len;
237  if (!val)
238  return NULL;
239 
240  len = strspn (val, "\a\b\t\n\v\f\r ");
241  if (0 == val[len])
242  return NULL;
243  return val + len;
244 }
gint safe_strcasecmp ( const gchar *  da,
const gchar *  db 
)

case sensitive comparison of strings da and db - either may be NULL. A non-NULL string is greater than a NULL string.

Parameters
dastring 1.
dbstring 2.
Returns
If da == NULL && db != NULL, returns -1. If da != NULL && db == NULL, returns +1. If da != NULL && db != NULL, returns the result of strcmp(da, db). If da == NULL && db == NULL, returns 0.

Definition at line 95 of file qofutil.c.

96 {
97  if ((da) && (db))
98  {
99  if ((da) != (db))
100  {
101  gint retval = strcasecmp ((da), (db));
102  /* if strings differ, return */
103  if (retval)
104  return retval;
105  }
106  }
107  else if ((!(da)) && (db))
108  return -1;
109  else if ((da) && (!(db)))
110  return +1;
111  return 0;
112 }
gint safe_strcmp ( const gchar *  da,
const gchar *  db 
)

The safe_strcmp compares strings da and db the same way that strcmp() does, except that either may be null. This routine assumes that a non-null string is always greater than a null string.

Parameters
dastring 1.
dbstring 2.
Returns
If da == NULL && db != NULL, returns -1. If da != NULL && db == NULL, returns +1. If da != NULL && db != NULL, returns the result of strcmp(da, db). If da == NULL && db == NULL, returns 0.
Todo:
replace with g_strcmp0 from glib 2.16

Definition at line 75 of file qofutil.c.

76 {
77  if ((da) && (db))
78  {
79  if ((da) != (db))
80  {
81  gint retval = strcmp ((da), (db));
82  /* if strings differ, return */
83  if (retval)
84  return retval;
85  }
86  }
87  else if ((!(da)) && (db))
88  return -1;
89  else if ((da) && (!(db)))
90  return +1;
91  return 0;
92 }
gchar* strncasestr ( const guchar *  str1,
const guchar *  str2,
size_t  len 
)

Search for str2 in first nchar chars of str1, ignore case. Return pointer to first match, or null. These are just like that strnstr and the strstr functions, except that they ignore the case.

Definition at line 45 of file qofutil.c.

46 {
47  while (*str1 && len--)
48  {
49  if (toupper (*str1) == toupper (*str2))
50  {
51  size_t l;
52  l = strlen ((gchar*)str2);
53  if (strncasecmp ((gchar*)str1, (gchar*)str2, l) == 0)
54  return (gchar *) str1;
55  }
56  str1++;
57  }
58  return NULL;
59 }
gchar* ultostr ( gulong  val,
gint  base 
)

The ultostr() subroutine is the inverse of strtoul(). It accepts a number and prints it in the indicated base. The returned string should be g_freed when done.

Definition at line 134 of file qofutil.c.

135 {
136  gchar buf[MAX_DIGITS];
137  gulong broke[MAX_DIGITS];
138  gint i;
139  gulong places = 0, reval;
140 
141  if ((2 > base) || (36 < base))
142  return NULL;
143 
144  /* count digits */
145  places = 0;
146  for (i = 0; i < MAX_DIGITS; i++)
147  {
148  broke[i] = val;
149  places++;
150  val /= base;
151  if (0 == val)
152  break;
153  }
154 
155  /* normalize */
156  reval = 0;
157  for (i = places - 2; i >= 0; i--)
158  {
159  reval += broke[i + 1];
160  reval *= base;
161  broke[i] -= reval;
162  }
163 
164  /* print */
165  for (i = 0; i < (gint) places; i++)
166  {
167  if (10 > broke[i])
168  {
169  buf[places - 1 - i] = 0x30 + broke[i]; /* ascii digit zero */
170  }
171  else
172  {
173  buf[places - 1 - i] = 0x41 - 10 + broke[i]; /* ascii capital A */
174  }
175  }
176  buf[places] = 0x0;
177 
178  return g_strdup (buf);
179 }