QOF  0.7.5
Utilities: Miscellany

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.
gboolean qof_util_param_set_string (QofEntity *ent, const QofParam *param, const gchar *value_string)
 Set a parameter from a value string.
gchar * qof_util_make_utf8 (gchar *string)
 Convert strings received from the wrapped objects into UTF-8.
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.
gboolean qof_util_param_commit (QofInstance *inst, const QofParam *param)
 Commit this parameter change, with undo support.

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.
void qof_close (void)
 Safely close down the Query Object Framework.

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

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

Definition at line 65 of file qofutil.h.

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

Definition at line 105 of file qofutil.h.

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

Definition at line 61 of file qofutil.h.

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

Definition at line 79 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 110 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 83 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 117 of file qofutil.h.

#define QOF_SCANF_LLD   "%qd"

Do not use these for printf, only scanf

Definition at line 47 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 112 of file qofutil.c.

{
if (da && db)
return strcmp (da, db);
if (!da && db && 0 == db[0])
return 0;
if (!db && da && 0 == da[0])
return 0;
if (!da && db)
return -1;
if (da && !db)
return +1;
return 0;
}
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.

{
qof_query_shutdown ();
qof_object_shutdown ();
}
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.

{
qof_object_initialize ();
}
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.

{
const gchar *p = qof_util_whitespace_filter (val);
if (!p)
return 0;
if ('t' == p[0])
return 1;
if ('T' == p[0])
return 1;
if ('y' == p[0])
return 1;
if ('Y' == p[0])
return 1;
if (strstr (p, "true"))
return 1;
if (strstr (p, "TRUE"))
return 1;
if (strstr (p, "yes"))
return 1;
if (strstr (p, "YES"))
return 1;
return atoi (val);
}
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.

{
gchar *value;
if (!string)
return NULL;
if (g_utf8_validate (string, -1, NULL))
return string;
value = g_locale_to_utf8 (string, -1, NULL, NULL, NULL);
if (!value)
{
PWARN (" unable to convert from locale %s", string);
PINFO ("trying to convert from ISO-8859-15.");
value = g_convert (string, -1, "UTF-8", "ISO-8859-15",
NULL, NULL, NULL);
if (!value)
{
PERR (" conversion failed");
return string;
}
return value;
}
return value;
}
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 306 of file qofutil.c.

{
QofUndo *undo_data;
QofBackend * be;
if (!inst)
return FALSE;
(inst->editlevel)--;
if (0 < inst->editlevel)
return FALSE;
be = qof_book_get_backend (inst->book);
inst->param = param;
if (be && qof_backend_commit_exists (be))
qof_backend_run_commit (be, inst);
if (param != NULL)
{
undo_data = inst->book->undo_data;
if (undo_data->undo_operation_open)
qof_undo_commit (inst, param);
}
return TRUE;
}
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 278 of file qofutil.c.

{
QofUndo *undo_data;
if (!inst)
return FALSE;
(inst->editlevel)++;
if (1 < inst->editlevel)
return FALSE;
if (0 >= inst->editlevel)
inst->editlevel = 1;
be = qof_book_get_backend (inst->book);
if (param != NULL)
{
undo_data = inst->book->undo_data;
inst->param = param;
if (undo_data->undo_operation_open)
qof_undo_modify (inst, param);
}
if (be && qof_backend_begin_exists (be))
qof_backend_run_begin (be, inst);
else
inst->dirty = TRUE;
return TRUE;
}
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.

< 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.

{
void (*string_setter) (QofEntity *, const gchar *);
void (*time_setter) (QofEntity *, QofTime *);
void (*numeric_setter) (QofEntity *, QofNumeric);
void (*guid_setter) (QofEntity *, const GUID *);
void (*double_setter) (QofEntity *, gdouble);
void (*boolean_setter) (QofEntity *, gboolean);
void (*i32_setter) (QofEntity *, gint32);
void (*i64_setter) (QofEntity *, gint64);
void (*char_setter) (QofEntity *, gchar);
/* void (*kvp_frame_setter) (QofEntity *, KvpFrame *);
void (*reference_setter) (QofEntity *, QofEntity *);
void (*collection_setter) (QofEntity *, QofCollection *);*/
g_return_val_if_fail (ent, FALSE);
g_return_val_if_fail (param, FALSE);
g_return_val_if_fail (value_string, FALSE);
if (safe_strcmp (param->param_type, QOF_TYPE_STRING) == 0)
{
string_setter =
(void (*)(QofEntity *,
const gchar *)) param->param_setfcn;
if (string_setter != NULL)
string_setter (ent, value_string);
// registered_type = TRUE;
}
if (safe_strcmp (param->param_type, QOF_TYPE_TIME) == 0)
{
QofTime *qt;
QofDate *qd;
qd = qof_date_parse (value_string, QOF_DATE_FORMAT_UTC);
if (!qd)
return FALSE;
qt = qof_date_to_qtime (qd);
time_setter =
(void (*)(QofEntity *, QofTime *))
param->param_setfcn;
if ((time_setter != NULL) && (qof_time_is_valid (qt)))
time_setter (ent, qt);
// registered_type = TRUE;
}
#ifndef QOF_DISABLE_DEPRECATED
if (safe_strcmp (param->param_type, QOF_TYPE_DATE) == 0)
{
return FALSE;
// registered_type = TRUE;
}
#endif
if ((safe_strcmp (param->param_type, QOF_TYPE_NUMERIC) == 0) ||
(safe_strcmp (param->param_type, QOF_TYPE_DEBCRED) == 0))
{
numeric_setter =
(void (*)(QofEntity *,
QofNumeric)) param->param_setfcn;
if (!qof_numeric_from_string (value_string, &num) ||
return FALSE;
if (numeric_setter != NULL)
numeric_setter (ent, num);
// registered_type = TRUE;
}
if (safe_strcmp (param->param_type, QOF_TYPE_GUID) == 0)
{
GUID * guid;
guid = guid_malloc();
guid_new (guid);
guid_setter =
(void (*)(QofEntity *,
const GUID *)) param->param_setfcn;
if (!string_to_guid(value_string, guid))
return FALSE;
if (guid_setter != NULL)
guid_setter (ent, guid);
// registered_type = TRUE;
}
if (safe_strcmp (param->param_type, QOF_TYPE_INT32) == 0)
{
gint32 i32;
gchar *tail;
errno = 0;
i32_setter =
(void (*)(QofEntity *, gint32)) param->param_setfcn;
i32 =
(gint32) strtol (value_string, &tail, 0);
if ((i32_setter != NULL) && (errno == 0))
i32_setter (ent, i32);
// registered_type = TRUE;
}
if (safe_strcmp (param->param_type, QOF_TYPE_INT64) == 0)
{
gint64 i64;
gchar *tail;
errno = 0;
i64 = strtoll (value_string, &tail, 0);
i64_setter =
(void (*)(QofEntity *, gint64)) param->param_setfcn;
if ((i64_setter != NULL) && (errno == 0))
i64_setter (ent, i64);
// registered_type = TRUE;
}
if (safe_strcmp (param->param_type, QOF_TYPE_DOUBLE) == 0)
{
gdouble db;
gchar *tail;
errno = 0;
db = strtod (value_string, &tail);
double_setter =
(void (*)(QofEntity *, gdouble)) param->param_setfcn;
if ((double_setter != NULL) && (errno == 0))
double_setter (ent, db);
// registered_type = TRUE;
}
if (safe_strcmp (param->param_type, QOF_TYPE_BOOLEAN) == 0)
{
gint val;
gboolean b;
boolean_setter =
(void (*)(QofEntity *, gboolean)) param->param_setfcn;
val = qof_util_bool_to_int(value_string);
if ((val > 1) || (val < 0))
return FALSE;
b = (val == 1) ? TRUE : FALSE;
if (boolean_setter != NULL)
boolean_setter (ent, val);
// registered_type = TRUE;
}
if (safe_strcmp (param->param_type, QOF_TYPE_KVP) == 0)
{
/* unsupported */
return FALSE;
/* KvpFrame * frame;
KvpValue * value;
kvp_frame_setter =
(void (*)(QofEntity *, KvpFrame *)) param->param_setfcn;
if (kvp_frame_setter != NULL)
kvp_frame_setter (rule->targetEnt, cm_kvp);
// registered_type = TRUE;*/
}
if (safe_strcmp (param->param_type, QOF_TYPE_CHAR) == 0)
{
char_setter =
(void (*)(QofEntity *, gchar)) param->param_setfcn;
if (char_setter != NULL)
char_setter (ent, value_string[0]);
// registered_type = TRUE;
}
if (safe_strcmp (param->param_type, QOF_TYPE_COLLECT) == 0)
{
/* unsupported */
return FALSE;
}
if (safe_strcmp (param->param_type, QOF_TYPE_CHOICE) == 0)
{
/* unsupported*/
return FALSE;
}
/* if (registered_type == FALSE)
{
referenceEnt =
cm_param->param_getfcn (rule->importEnt, cm_param);
if (referenceEnt)
{
reference_setter =
(void (*)(QofEntity *, QofEntity *)) cm_param->
param_setfcn;
if (reference_setter != NULL)
{
reference_setter (rule->targetEnt, referenceEnt);
}
}
}*/
return TRUE;
}
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.

{
gchar *param_string;
gchar param_sa[GUID_ENCODING_LENGTH + 1];
gboolean known_type;
QofType paramType;
const GUID *param_guid;
QofNumeric param_numeric, (*numeric_getter) (QofEntity *, const QofParam *);
gdouble param_double, (*double_getter) (QofEntity *, const QofParam *);
gboolean param_boolean, (*boolean_getter) (QofEntity *, const QofParam *);
gint32 param_i32, (*int32_getter) (QofEntity *, const QofParam *);
gint64 param_i64, (*int64_getter) (QofEntity *, const QofParam *);
gchar param_char, (*char_getter) (QofEntity *, const QofParam *);
param_string = NULL;
known_type = FALSE;
g_return_val_if_fail (ent && param, NULL);
paramType = param->param_type;
if (safe_strcmp (paramType, QOF_TYPE_STRING) == 0)
{
param_string = g_strdup (param->param_getfcn (ent, param));
if (param_string == NULL)
{
param_string = "";
}
known_type = TRUE;
return param_string;
}
if (safe_strcmp (paramType, QOF_TYPE_TIME) == 0)
{
QofTime *param_qt;
QofDate *qd;
param_qt = param->param_getfcn (ent, param);
qd = qof_date_from_qtime (param_qt);
}
#ifndef QOF_DISABLE_DEPRECATED
if (safe_strcmp (paramType, QOF_TYPE_DATE) == 0)
{
Timespec param_ts, (*date_getter) (QofEntity *, const QofParam *);
time_t param_t;
gchar param_date[MAX_DATE_LENGTH];
date_getter =
(Timespec (*)(QofEntity *, const QofParam *)) param->param_getfcn;
param_ts = date_getter (ent, param);
param_t = param_ts.tv_sec;
strftime (param_date, MAX_DATE_LENGTH,
QOF_UTC_DATE_FORMAT, gmtime (&param_t));
param_string = g_strdup (param_date);
known_type = TRUE;
return param_string;
}
#endif
if ((safe_strcmp (paramType, QOF_TYPE_NUMERIC) == 0) ||
(safe_strcmp (paramType, QOF_TYPE_DEBCRED) == 0))
{
numeric_getter =
(QofNumeric (*)(QofEntity *, const QofParam *)) param->param_getfcn;
param_numeric = numeric_getter (ent, param);
param_string = g_strdup (qof_numeric_to_string (param_numeric));
known_type = TRUE;
return param_string;
}
if (safe_strcmp (paramType, QOF_TYPE_GUID) == 0)
{
param_guid = param->param_getfcn (ent, param);
guid_to_string_buff (param_guid, param_sa);
param_string = g_strdup (param_sa);
known_type = TRUE;
return param_string;
}
if (safe_strcmp (paramType, QOF_TYPE_INT32) == 0)
{
int32_getter =
(gint32 (*)(QofEntity *, const QofParam *)) param->param_getfcn;
param_i32 = int32_getter (ent, param);
param_string = g_strdup_printf ("%d", param_i32);
known_type = TRUE;
return param_string;
}
if (safe_strcmp (paramType, QOF_TYPE_INT64) == 0)
{
int64_getter =
(gint64 (*)(QofEntity *, const QofParam *)) param->param_getfcn;
param_i64 = int64_getter (ent, param);
param_string = g_strdup_printf ("%" G_GINT64_FORMAT, param_i64);
known_type = TRUE;
return param_string;
}
if (safe_strcmp (paramType, QOF_TYPE_DOUBLE) == 0)
{
double_getter =
(double (*)(QofEntity *, const QofParam *)) param->param_getfcn;
param_double = double_getter (ent, param);
param_string = g_strdup_printf ("%f", param_double);
known_type = TRUE;
return param_string;
}
if (safe_strcmp (paramType, QOF_TYPE_BOOLEAN) == 0)
{
boolean_getter =
(gboolean (*)(QofEntity *, const QofParam *)) param->param_getfcn;
param_boolean = boolean_getter (ent, param);
/* Boolean values need to be lowercase for QSF validation. */
if (param_boolean == TRUE)
{
param_string = g_strdup ("true");
}
else
{
param_string = g_strdup ("false");
}
known_type = TRUE;
return param_string;
}
/* "kvp" contains repeating values, cannot be a single string for the frame. */
if (safe_strcmp (paramType, QOF_TYPE_KVP) == 0)
{
KvpFrame *frame = NULL;
frame = param->param_getfcn (ent, param);
known_type = TRUE;
if (!kvp_frame_is_empty (frame))
{
GHashTable *hash = kvp_frame_get_hash (frame);
param_string = g_strdup_printf ("%s(%d)", QOF_TYPE_KVP,
g_hash_table_size (hash));
}
return param_string;
}
if (safe_strcmp (paramType, QOF_TYPE_CHAR) == 0)
{
char_getter =
(gchar (*)(QofEntity *, const QofParam *)) param->param_getfcn;
param_char = char_getter (ent, param);
known_type = TRUE;
return g_strdup_printf ("%c", param_char);
}
/* "collect" contains repeating values, cannot be a single string. */
if (safe_strcmp (paramType, QOF_TYPE_COLLECT) == 0)
{
QofCollection *col = NULL;
col = param->param_getfcn (ent, param);
known_type = TRUE;
return g_strdup_printf ("%s(%d)",
}
if (safe_strcmp (paramType, QOF_TYPE_CHOICE) == 0)
{
QofEntity *child = NULL;
child = param->param_getfcn (ent, param);
if (!child)
{
return param_string;
}
known_type = TRUE;
return g_strdup (qof_object_printable (child->e_type, child));
}
if (safe_strcmp (paramType, QOF_PARAM_BOOK) == 0)
{
QofBook *book;
book = param->param_getfcn (ent, param);
PINFO (" book param %p", book);
be = qof_book_get_backend (book);
known_type = TRUE;
PINFO (" backend=%p", be);
if (!be)
{
}
param_string = g_strdup (be->fullpath);
PINFO (" fullpath=%s", param_string);
if (param_string)
{
return param_string;
}
param_guid = qof_entity_get_guid ((QofEntity*)book);
guid_to_string_buff (param_guid, param_sa);
PINFO (" book GUID=%s", param_sa);
param_string = g_strdup (param_sa);
return param_string;
}
if (!known_type)
{
QofEntity *child = NULL;
child = param->param_getfcn (ent, param);
if (!child)
{
return param_string;
}
return g_strdup (qof_object_printable (child->e_type, child));
}
return g_strdup ("");
}
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.

{
if (qof_string_cache)
g_cache_destroy (qof_string_cache);
qof_string_cache = NULL;
}
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.

{
if (key)
return g_cache_insert(qof_util_get_string_cache(), (gpointer)key);
return NULL;
}
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.

{
if (key)
g_cache_remove (qof_util_get_string_cache (), key);
}
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.

{
if (s == NULL)
return FALSE;
if (*s == 0)
return FALSE;
while (*s && isspace (*s))
s++;
if (*s == 0)
return FALSE;
if (!isdigit (*s))
return FALSE;
while (*s && isdigit (*s))
s++;
if (*s == 0)
return TRUE;
while (*s && isspace (*s))
s++;
if (*s == 0)
return TRUE;
return FALSE;
}
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.

{
size_t len;
if (!val)
return NULL;
len = strspn (val, "\a\b\t\n\v\f\r ");
if (0 == val[len])
return NULL;
return val + len;
}
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 92 of file qofutil.c.

{
if ((da) && (db))
{
if ((da) != (db))
{
gint retval = strcasecmp ((da), (db));
/* if strings differ, return */
if (retval)
return retval;
}
}
else if ((!(da)) && (db))
return -1;
else if ((da) && (!(db)))
return +1;
return 0;
}
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.

Definition at line 72 of file qofutil.c.

{
if ((da) && (db))
{
if ((da) != (db))
{
gint retval = strcmp ((da), (db));
/* if strings differ, return */
if (retval)
return retval;
}
}
else if ((!(da)) && (db))
return -1;
else if ((da) && (!(db)))
return +1;
return 0;
}
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.

{
while (*str1 && len--)
{
if (toupper (*str1) == toupper (*str2))
{
if (strncasecmp (str1, str2, strlen (str2)) == 0)
return (gchar *) str1;
}
str1++;
}
return NULL;
}
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.

{
gchar buf[MAX_DIGITS];
gulong broke[MAX_DIGITS];
gint i;
gulong places = 0, reval;
if ((2 > base) || (36 < base))
return NULL;
/* count digits */
places = 0;
for (i = 0; i < MAX_DIGITS; i++)
{
broke[i] = val;
places++;
val /= base;
if (0 == val)
break;
}
/* normalize */
reval = 0;
for (i = places - 2; i >= 0; i--)
{
reval += broke[i + 1];
reval *= base;
broke[i] -= reval;
}
/* print */
for (i = 0; i < (gint) places; i++)
{
if (10 > broke[i])
{
buf[places - 1 - i] = 0x30 + broke[i]; /* ascii digit zero */
}
else
{
buf[places - 1 - i] = 0x41 - 10 + broke[i]; /* ascii capital A */
}
}
buf[places] = 0x0;
return g_strdup (buf);
}