GnuCash 2.3.0
Files | Defines | Functions
Misc Utilities
Query Object Framework

Files

file  qofutil.h
 

QOF utility functions.


Defines

#define QOF_MOD_UTIL   "qof.utilities"
#define stpcpy   g_stpcpy
#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

void g_hash_table_foreach_sorted (GHashTable *hash_table, GHFunc func, gpointer user_data, GCompareFunc compare_func)
gboolean qof_utf8_substr_nocase (const gchar *haystack, const gchar *needle)
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 * ultostr (gulong val, gint base)
gboolean gnc_strisnum (const gchar *s)
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_begin_edit (QofInstance *inst)
gboolean qof_commit_edit (QofInstance *inst)
gboolean qof_commit_edit_part2 (QofInstance *inst, void(*on_error)(QofInstance *, QofBackendError), void(*on_done)(QofInstance *), void(*on_free)(QofInstance *))

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.

Define 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 82 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 135 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 280 of file qofutil.h.

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

Definition at line 74 of file qofutil.h.

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

Definition at line 114 of file qofutil.h.

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

Definition at line 70 of file qofutil.h.

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

Definition at line 88 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 119 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 92 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 126 of file qofutil.h.

#define QOF_MOD_UTIL   "qof.utilities"

Do not use these for printf, only scanf

Definition at line 59 of file qofutil.h.


Function Documentation

void g_hash_table_foreach_sorted ( GHashTable *  hash_table,
GHFunc  func,
gpointer  user_data,
GCompareFunc  compare_func 
)

Calls the given function for each of the key/value pairs in the GHashTable in an order determined by the GCompareFunc applied to the keys. The function is passed the key and value of each pair, and the given user_data parameter.

Definition at line 40 of file qofutil.c.

{
    GList *iter;
    GList *keys = g_list_sort(g_hash_table_get_keys(hash_table), compare_func);

    for (iter = keys; iter; iter = iter->next)
    {
        func(iter->data, g_hash_table_lookup(hash_table, iter->data), user_data);
    }

    g_list_free(keys);
}
gboolean gnc_strisnum ( const gchar *  s)

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

Definition at line 210 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;
}
gint null_strcmp ( const gchar *  da,
const gchar *  db 
)

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 146 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;
}
gboolean qof_begin_edit ( QofInstance inst)

begin_edit

Parameters:
inst,:an instance of QofInstance

The caller should use this macro first and then perform any other operations.

Definition at line 954 of file qofinstance.c.

{
    QofInstancePrivate *priv;
    QofBackend * be;

    if (!inst) return FALSE;

    priv = GET_PRIVATE(inst);
    priv->editlevel++;
    if (1 < priv->editlevel) return FALSE;
    if (0 >= priv->editlevel)
        priv->editlevel = 1;

    be = qof_book_get_backend(priv->book);
    if (be && qof_backend_begin_exists(be))
        qof_backend_run_begin(be, inst);
    else
        priv->dirty = TRUE;

    return TRUE;
}
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 339 of file qofutil.c.

{
    qof_query_shutdown ();
    qof_object_shutdown ();
    guid_shutdown ();
    qof_finalize_backend_libraries();
    qof_util_string_cache_destroy ();
    qof_log_shutdown();
}
gboolean qof_commit_edit ( QofInstance inst)

commit_edit helpers

The caller should call PART1 as the first thing, then perform any local operations prior to calling the backend. Then call PART2. part1 -- deal with the editlevel

Parameters:
inst,:an instance of QofInstance

Definition at line 976 of file qofinstance.c.

{
    QofInstancePrivate *priv;

    if (!inst) return FALSE;

    priv = GET_PRIVATE(inst);
    priv->editlevel--;
    if (0 < priv->editlevel) return FALSE;

#if 0
    if ((0 == priv->editlevel) && priv->dirty)
    {
        QofBackend * be = qof_book_get_backend(priv->book);
        if (be && qof_backend_commit_exists(be))
        {
            qof_backend_run_commit(be, inst);
        }
    }
#endif
    if (0 > priv->editlevel)
    {
        PERR ("unbalanced call - resetting (was %d)", priv->editlevel);
        priv->editlevel = 0;
    }
    return TRUE;
}
gboolean qof_commit_edit_part2 ( QofInstance inst,
void(*)(QofInstance *, QofBackendError on_error,
void(*)(QofInstance *)  on_done,
void(*)(QofInstance *)  on_free 
)

part2 -- deal with the backend

Parameters:
inst,:an instance of QofInstance
on_error,:a function called if there is a backend error. void (*on_error)(inst, QofBackendError)
on_done,:a function called after the commit is completed successfully for an object which remained valid. void (*on_done)(inst)
on_free,:a function called if the commit succeeded and the instance is to be freed. void (*on_free)(inst)

Note that only *one* callback will be called (or zero, if that callback is NULL). In particular, 'on_done' will not be called for an object which is to be freed.

Returns TRUE, if the commit succeeded, FALSE otherwise.

Definition at line 1005 of file qofinstance.c.

{
    QofInstancePrivate *priv;
    QofBackend * be;
    gboolean dirty;

    priv = GET_PRIVATE(inst);
    dirty = priv->dirty;

    /* See if there's a backend.  If there is, invoke it. */
    be = qof_book_get_backend(priv->book);
    if (be && qof_backend_commit_exists(be))
    {
        QofBackendError errcode;

        /* clear errors */
        do
        {
            errcode = qof_backend_get_error(be);
        }
        while (ERR_BACKEND_NO_ERR != errcode);

        qof_backend_run_commit(be, inst);
        errcode = qof_backend_get_error(be);
        if (ERR_BACKEND_NO_ERR != errcode)
        {
            /* XXX Should perform a rollback here */
            priv->do_free = FALSE;

            /* Push error back onto the stack */
            qof_backend_set_error (be, errcode);
            if (on_error)
                on_error(inst, errcode);
            return FALSE;
        }
        /* XXX the backend commit code should clear dirty!! */
        priv->dirty = FALSE;
    }
//    if (dirty && qof_get_alt_dirty_mode() &&
//        !(priv->infant && priv->do_free)) {
//      qof_collection_mark_dirty(priv->collection);
//      qof_book_mark_dirty(priv->book);
//    }
    priv->infant = FALSE;

    if (priv->do_free)
    {
        if (on_free)
            on_free(inst);
        return TRUE;
    }

    if (on_done)
        on_done(inst);
    return TRUE;
}
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 327 of file qofutil.c.

{
    g_type_init();
    qof_log_init();
    qof_util_get_string_cache ();
    guid_init ();
    qof_object_initialize ();
    qof_query_init ();
    qof_book_register ();
}
gboolean qof_utf8_substr_nocase ( const gchar *  haystack,
const gchar *  needle 
)

Search for an occurence of the substring needle in the string haystack, ignoring case. Return TRUE if one is found or FALSE otherwise.

Definition at line 54 of file qofutil.c.

{
    gchar *haystack_casefold, *haystack_normalized;
    gchar *needle_casefold, *needle_normalized;
    gchar *p;

    g_return_val_if_fail (haystack && needle, FALSE);

    haystack_casefold = g_utf8_casefold (haystack, -1);
    haystack_normalized = g_utf8_normalize (haystack_casefold, -1,
                                            G_NORMALIZE_ALL);
    g_free (haystack_casefold);

    needle_casefold = g_utf8_casefold (needle, -1);
    needle_normalized = g_utf8_normalize (needle_casefold, -1, G_NORMALIZE_ALL);
    g_free (needle_casefold);

    p = strstr (haystack_normalized, needle_normalized);
    g_free (haystack_normalized);
    g_free (needle_normalized);

    return p != NULL;
}
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 304 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 319 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 312 of file qofutil.c.

{
    if (key)
        g_cache_remove(qof_util_get_string_cache(), key);
}
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 123 of file qofutil.c.

{
    if ((da) && (db))
    {
        if ((da) != (db))
        {
            gint retval = qof_utf8_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 100 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* 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 160 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);
}
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines