QOF: Utilities: Miscellany

QOF 0.7.5

Files | Macros | Functions
Utilities: Miscellany
Query Object Framework

## Files
file | qofutil.h
| QOF utility functions.

## Macros
#define | QOF_SCANF_LLD "%qd"
#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

## ◆ AS_STRING_FUNC

#define AS_STRING_FUNC | ( |  | name,
|  |  | list
| ) |  |

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

Definition at line 73 of file qofutil.h.

## ◆ AS_STRING_FUNC_NON_TYPEDEF

#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 126 of file qofutil.h.

## ◆ CACHE_REPLACE

#define CACHE_REPLACE | ( |  | dst,
|  |  | src
| ) |  |

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

Definition at line 330 of file qofutil.h.

## ◆ DEFINE_ENUM

#define DEFINE_ENUM | ( |  | name,
|  |  | list
| ) |  |

Value:
typedef enum { \
list(ENUM_BODY) \
}name;

Definition at line 65 of file qofutil.h.

## ◆ DEFINE_ENUM_NON_TYPEDEF

#define DEFINE_ENUM_NON_TYPEDEF | ( |  | name,
|  |  | list
| ) |  |

Value:
enum name { \
list(ENUM_BODY) \
};

Definition at line 105 of file qofutil.h.

## ◆ FROM_STRING_CASE

#define FROM_STRING_CASE | ( |  | name,
|  |  | value
| ) |  |

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

Definition at line 61 of file qofutil.h.

## ◆ FROM_STRING_DEC

#define FROM_STRING_DEC | ( |  | name,
|  |  | list
| ) |  |

Value:
name name##fromString \
(const gchar* str);

Definition at line 79 of file qofutil.h.

## ◆ FROM_STRING_DEC_NON_TYPEDEF

#define FROM_STRING_DEC_NON_TYPEDEF | ( |  | name,
|  |  | list
| ) |  |

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

Definition at line 110 of file qofutil.h.

## ◆ FROM_STRING_FUNC

#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 83 of file qofutil.h.

## ◆ FROM_STRING_FUNC_NON_TYPEDEF

#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 117 of file qofutil.h.

## ◆ QOF_SCANF_LLD

#define QOF_SCANF_LLD "%qd"

Do not use these for printf, only scanf

Definition at line 47 of file qofutil.h.

## Function Documentation

## ◆ null_strcmp()

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 112 of file qofutil.c.

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 }

## ◆ qof_close()

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 844 of file qofutil.c.

845 {
846 qof_query_shutdown ();
847 qof_object_shutdown ();
848 guid_shutdown ();
849 qof_date_close ();
850 qof_util_string_cache_destroy ();
851 }
qof_date_close
void qof_date_close(void)
close down the QofDate tables
Definition: qofdate.c:156
guid_shutdown
void guid_shutdown(void)
Definition: guid.c:477
qof_util_string_cache_destroy
void qof_util_string_cache_destroy(void)
Definition: qofutil.c:424

## ◆ qof_init()

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 833 of file qofutil.c.

834 {
835 qof_util_get_string_cache ();
836 guid_init ();
837 qof_date_init ();
838 qof_object_initialize ();
839 qof_query_init ();
840 qof_book_register ();
841 }
qof_book_register
gboolean qof_book_register(void)
Definition: qofbook.c:376
qof_date_init
void qof_date_init(void)
initialise the QofDate tables
Definition: qofdate.c:67
qof_query_init
void qof_query_init(void)
Definition: qofquery.c:1375
qof_util_get_string_cache
GCache * qof_util_get_string_cache(void)
Definition: qofutil.c:407
guid_init
void guid_init(void)
Definition: guid.c:325

## ◆ qof_util_bool_to_int()

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 249 of file qofutil.c.

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 }
qof_util_whitespace_filter
const gchar * qof_util_whitespace_filter(const gchar *val)
Definition: qofutil.c:231

## ◆ qof_util_make_utf8()

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 330 of file qofutil.c.

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 }
PERR
#define PERR(format, args...)
Definition: qoflog.h:183
PINFO
#define PINFO(format, args...)
Definition: qoflog.h:199
PWARN
#define PWARN(format, args...)
Definition: qoflog.h:191

## ◆ qof_util_param_commit()

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

  inst | The QofInstance.
  param | The parameter being modified.

Returns
  FALSE on error, otherwise TRUE.

Definition at line 306 of file qofutil.c.

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 }
QofUndo_s
Definition: qofundo-p.h:56
_QofBook::undo_data
QofUndo * undo_data
Definition: qofbook-p.h:90
qof_book_get_backend
QofBackend * qof_book_get_backend(QofBook *book)
Retrieve the backend used by this book.
Definition: qofbook.c:154
QofInstance_s::param
const QofParam * param
Definition: qofinstance-p.h:52
qof_undo_commit
void qof_undo_commit(QofInstance *instance, const QofParam *param)
Definition: qofundo.c:571
QofInstance_s::book
QofBook * book
Definition: qofinstance-p.h:41
QofBackend_s
Definition: qofbackend-p.h:283

## ◆ qof_util_param_edit()

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

  inst | The QofInstance.
  param | The parameter being modified.

Returns
  FALSE on error, otherwise TRUE.

Definition at line 278 of file qofutil.c.

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 }
QofUndo_s
Definition: qofundo-p.h:56
_QofBook::undo_data
QofUndo * undo_data
Definition: qofbook-p.h:90
qof_book_get_backend
QofBackend * qof_book_get_backend(QofBook *book)
Retrieve the backend used by this book.
Definition: qofbook.c:154
QofInstance_s::param
const QofParam * param
Definition: qofinstance-p.h:52
QofInstance_s::book
QofBook * book
Definition: qofinstance-p.h:41
qof_undo_modify
void qof_undo_modify(QofInstance *instance, const QofParam *param)
Definition: qofundo.c:547
QofBackend_s
Definition: qofbackend-p.h:283

## ◆ qof_util_param_set_string()

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

  ent | The entity in which the value is to be set.
  param | The parameter that stores the value.
  value_string | A 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.

< secondary collections are used for one-to-many references between entities and are implemented using QofCollection. These are NOT the same as the main collections in the QofBook. -# Each QofCollection contains one or many entities - all of a single type. -# The entity type within the collection can be determined at run time. -# Easy conversions to GList or whatever in the param_setfcn handler. -# Each parameter can have its own collection. -# Each entity can have a different type of collection to its siblings, provided that it is acceptable to the set function. -# Each object decides which types are acceptable for which parameter in the set functions. This is then part of the API for that object. QOF_TYPE_COLLECT has two functions, both related to one-to-many links: - Represent a reference between 2 entities with a list of acceptable types. (one object linked to many types of single entities) - Represent a reference between one entity and many entities of another type. (one object linked to many entities of a single type.) If the set function can handle it, it could also be used for true one-to-many links: one object linked to many entities of many types. n.b. Always subject to each collection holding only one type at runtime. (otherwise use books).

Definition at line 644 of file qofutil.c.

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 }
QOF_TYPE_DATE
#define QOF_TYPE_DATE
Definition: deprecated.h:336
qof_numeric_check
QofNumericErrorCode qof_numeric_check(QofNumeric in)
Definition: qofnumeric.c:44
QOF_DATE_FORMAT_UTC
#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
QOF_TYPE_COLLECT
#define QOF_TYPE_COLLECT
Definition: qofclass.h:93
QofNumeric
struct _QofNumeric QofNumeric
A rational-number type.
Definition: qofnumeric.h:61
qof_date_free
void qof_date_free(QofDate *date)
Definition: qofdate.c:608
guid_malloc
GUID * guid_malloc(void)
Definition: guid.c:100
QofEntity_s
Definition: qofid.h:147
string_to_guid
gboolean string_to_guid(const gchar *string, GUID *guid)
qof_util_bool_to_int
gint qof_util_bool_to_int(const gchar *val)
Definition: qofutil.c:249
qof_date_to_qtime
QofTime * qof_date_to_qtime(const QofDate *qd)
Definition: qofdate.c:892
QofDate_s
Full range replacement for struct tm.
Definition: qofdate.h:138
qof_date_parse
QofDate * qof_date_parse(const gchar *str, QofDateFormat df)
Convert a timestamp to a QofTime.
Definition: qofdate.c:525
qof_numeric_from_string
gboolean qof_numeric_from_string(const gchar *str, QofNumeric *n)
Definition: qofnumeric.c:1121
_QofNumeric
Definition: qofnumeric.h:52
QOF_ERROR_OK
Definition: qofnumeric.h:209
_GUID
Definition: guid.h:53
guid_new
void guid_new(GUID *guid)
Definition: guid.c:487
QofTime
struct QofTime64 QofTime
Use a 64-bit signed int QofTime.
Definition: qoftime.h:120
safe_strcmp
gint safe_strcmp(const gchar *da, const gchar *db)
Definition: qofutil.c:72
QOF_TYPE_CHOICE
#define QOF_TYPE_CHOICE
Identify an object as containing a choice.
Definition: qofchoice.h:103

## ◆ qof_util_param_to_string()

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.

< secondary collections are used for one-to-many references between entities and are implemented using QofCollection. These are NOT the same as the main collections in the QofBook. -# Each QofCollection contains one or many entities - all of a single type. -# The entity type within the collection can be determined at run time. -# Easy conversions to GList or whatever in the param_setfcn handler. -# Each parameter can have its own collection. -# Each entity can have a different type of collection to its siblings, provided that it is acceptable to the set function. -# Each object decides which types are acceptable for which parameter in the set functions. This is then part of the API for that object. QOF_TYPE_COLLECT has two functions, both related to one-to-many links: - Represent a reference between 2 entities with a list of acceptable types. (one object linked to many types of single entities) - Represent a reference between one entity and many entities of another type. (one object linked to many entities of a single type.) If the set function can handle it, it could also be used for true one-to-many links: one object linked to many entities of many types. n.b. Always subject to each collection holding only one type at runtime. (otherwise use books).

Definition at line 447 of file qofutil.c.

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)",
592 qof_collection_get_type (col), qof_collection_count (col));
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 }
QOF_TYPE_DATE
#define QOF_TYPE_DATE
Definition: deprecated.h:336
QOF_DATE_FORMAT_UTC
#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
QofBackend_s::fullpath
gchar * fullpath
Definition: qofbackend-p.h:338
QOF_TYPE_COLLECT
#define QOF_TYPE_COLLECT
Definition: qofclass.h:93
PINFO
#define PINFO(format, args...)
Definition: qoflog.h:199
Timespec
struct timespec64 Timespec
QofNumeric
struct _QofNumeric QofNumeric
A rational-number type.
Definition: qofnumeric.h:61
_QofParam
Definition: qofclass.h:195
QOF_UTC_DATE_FORMAT
#define QOF_UTC_DATE_FORMAT
UTC date format string.
Definition: qofdate.h:244
qof_date_from_qtime
QofDate * qof_date_from_qtime(const QofTime *qt)
Definition: qofdate.c:850
QofEntity_s
Definition: qofid.h:147
KvpFrame
struct _KvpFrame KvpFrame
Definition: kvpframe.h:74
qof_date_print
gchar * qof_date_print(const QofDate *date, QofDateFormat df)
Convert a QofDate to a timestamp according to the specified date format.
Definition: qofdate.c:547
timespec64
Definition: qoftime.h:97
kvp_frame_is_empty
gboolean kvp_frame_is_empty(KvpFrame *frame)
Definition: kvpframe.c:137
GUID_ENCODING_LENGTH
#define GUID_ENCODING_LENGTH
Definition: guid.h:64
QOF_PARAM_BOOK
#define QOF_PARAM_BOOK
Definition: qofquery.h:104
QofDate_s
Full range replacement for struct tm.
Definition: qofdate.h:138
QofCollection
struct QofCollection_s QofCollection
Definition: qofid.h:138
qof_collection_count
guint qof_collection_count(QofCollection *col)
Definition: qofid.c:351
qof_object_printable
const gchar * qof_object_printable(QofIdTypeConst type_name, gpointer obj)
Definition: qofobject.c:205
_QofNumeric
Definition: qofnumeric.h:52
guid_to_string_buff
gchar * guid_to_string_buff(const GUID *guid, gchar *buff)
MAX_DATE_LENGTH
#define MAX_DATE_LENGTH
The maximum length of a string used for or created by dates.
Definition: qofdate.h:87
QofType
const gchar * QofType
Definition: qofclass.h:150
qof_collection_get_type
QofIdType qof_collection_get_type(QofCollection *col)
Definition: qofid.c:175
_GUID
Definition: guid.h:53
qof_numeric_to_string
gchar * qof_numeric_to_string(QofNumeric n)
Definition: qofnumeric.c:1089
QofTime
struct QofTime64 QofTime
Use a 64-bit signed int QofTime.
Definition: qoftime.h:120
qof_entity_get_guid
const GUID * qof_entity_get_guid(QofEntity *ent)
Definition: qofid.c:105
qof_book_get_backend
QofBackend * qof_book_get_backend(QofBook *book)
Retrieve the backend used by this book.
Definition: qofbook.c:154
_QofBook
Definition: qofbook-p.h:48
safe_strcmp
gint safe_strcmp(const gchar *da, const gchar *db)
Definition: qofutil.c:72
QOF_TYPE_CHOICE
#define QOF_TYPE_CHOICE
Identify an object as containing a choice.
Definition: qofchoice.h:103
QofBackend_s
Definition: qofbackend-p.h:283

## ◆ qof_util_string_cache_destroy()

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 424 of file qofutil.c.

425 {
426 if (qof_string_cache)
427 g_cache_destroy (qof_string_cache);
428 qof_string_cache = NULL;
429 }

## ◆ qof_util_string_cache_insert()

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 439 of file qofutil.c.

440 {
441 if (key)
442 return g_cache_insert(qof_util_get_string_cache(), (gpointer)key);
443 return NULL;
444 }
qof_util_get_string_cache
GCache * qof_util_get_string_cache(void)
Definition: qofutil.c:407

## ◆ qof_util_string_cache_remove()

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 432 of file qofutil.c.

433 {
434 if (key)
435 g_cache_remove (qof_util_get_string_cache (), key);
436 }
qof_util_get_string_cache
GCache * qof_util_get_string_cache(void)
Definition: qofutil.c:407

## ◆ qof_util_string_isnum()

gboolean qof_util_string_isnum | ( | const guchar * | s | ) |

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

Definition at line 195 of file qofutil.c.

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 }

## ◆ qof_util_whitespace_filter()

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 231 of file qofutil.c.

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 }

## ◆ safe_strcasecmp()

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

  da | string 1.
  db | string 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 92 of file qofutil.c.

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 }

## ◆ safe_strcmp()

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

  da | string 1.
  db | string 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 72 of file qofutil.c.

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 }

## ◆ strncasestr()

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 if (strncasecmp (str1, str2, strlen (str2)) == 0)
52 return (gchar *) str1;
53 }
54 str1++;
55 }
56 return NULL;
57 }

## ◆ ultostr()

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 131 of file qofutil.c.

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 }