GnuCash c935c2f+
Loading...
Searching...
No Matches
Files | Macros | Functions

Files

file  qof-string-cache.h
 QOF String cache functions.
 
file  qofutil.h
 QOF utility functions.
 

Macros

#define QOF_MOD_UTIL   "qof.utilities"
 
#define CACHE_INSERT(str)   qof_string_cache_insert((str))
 
#define CACHE_REMOVE(str)   qof_string_cache_remove((str))
 
#define CACHE_REPLACE(dst, src)
 
#define QOF_CACHE_NEW(void)   qof_string_cache_insert("")
 
#define QOF_MOD_UTIL   "qof.utilities"
 
#define stpcpy   g_stpcpy
 

Functions

void qof_string_cache_init (void)
 The QOF String Cache:
 
void qof_string_cache_destroy (void)
 Destroy the qof_string_cache.
 
void qof_string_cache_remove (const char *key)
 You can use this function as a destroy notifier for a GHashTable that uses common strings as keys (or values, for that matter.)
 
const char * qof_string_cache_insert (const char *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.
 
const char * qof_string_cache_replace (const char *dst, const char *src)
 Same as CACHE_REPLACE below, but safe to call from C++.
 
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.
 
gboolean qof_utf8_substr_nocase (const gchar *haystack, const gchar *needle)
 Search for an occurrence of the substring needle in the string haystack, ignoring case.
 
gint safe_strcasecmp (const gchar *da, const gchar *db)
 case sensitive comparison of strings da and db - either may be NULL.
 
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.
 
gchar * ultostr (gulong val, gint base)
 The ultostr() subroutine is the inverse of strtoul().
 
gboolean gnc_strisnum (const gchar *s)
 Returns true if string s is a number, possibly surrounded by whitespace.
 
gboolean qof_begin_edit (QofInstance *inst)
 begin_edit
 
gboolean qof_commit_edit (QofInstance *inst)
 commit_edit helpers
 
gboolean qof_commit_edit_part2 (QofInstance *inst, void(*on_error)(QofInstance *, QofBackendError), void(*on_done)(QofInstance *), void(*on_free)(QofInstance *))
 part2 – deal with the backend
 

Convenience wrappers

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

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; }
 

Detailed Description

Macro Definition Documentation

◆ AS_STRING_CASE

#define AS_STRING_CASE (   name,
  value 
)     case name: { return #name; }

Definition at line 56 of file qofutil.h.

57 : { return #name; }

◆ AS_STRING_CASE_NON_TYPEDEF

#define AS_STRING_CASE_NON_TYPEDEF (   name,
  value 
)     case name: { return #name; }

Definition at line 130 of file qofutil.h.

131 : { return #name; }

◆ AS_STRING_DEC

#define AS_STRING_DEC (   name,
  list 
)     const gchar* name##asString(name n);

Definition at line 68 of file qofutil.h.

◆ AS_STRING_DEC_NON_TYPEDEF

#define AS_STRING_DEC_NON_TYPEDEF (   name,
  list 
)     const gchar* name##asString(enum name n);

Definition at line 121 of file qofutil.h.

◆ 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 71 of file qofutil.h.

72 { \
73 switch (n) { \
74 list(AS_STRING_CASE) \
75 default: return ""; } }

◆ 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 124 of file qofutil.h.

125 { \
126 switch (n) { \
127 list(AS_STRING_CASE_NON_TYPEDEF) \
128 default: return ""; } }

◆ CACHE_INSERT

#define CACHE_INSERT (   str)    qof_string_cache_insert((str))

Definition at line 93 of file qof-string-cache.h.

◆ CACHE_REMOVE

#define CACHE_REMOVE (   str)    qof_string_cache_remove((str))

Definition at line 94 of file qof-string-cache.h.

◆ CACHE_REPLACE

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

Definition at line 103 of file qof-string-cache.h.

103 { \
104 const char *tmp = CACHE_INSERT((src)); \
105 CACHE_REMOVE((dst)); \
106 (dst) = tmp; \
107 } while (0)

◆ DEFINE_ENUM

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

Definition at line 63 of file qofutil.h.

64 { \
65 list(ENUM_BODY) \
66 }name;

◆ DEFINE_ENUM_NON_TYPEDEF

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

Definition at line 103 of file qofutil.h.

104 { \
105 list(ENUM_BODY) \
106 };

◆ ENUM_BODY

#define ENUM_BODY (   name,
  value 
)     name value,

Definition at line 53 of file qofutil.h.

◆ FROM_STRING_CASE

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

Definition at line 59 of file qofutil.h.

60 { \
61 return name; }

◆ FROM_STRING_CASE_NON_TYPEDEF

#define FROM_STRING_CASE_NON_TYPEDEF (   name,
  value 
)     if (strcmp(str, #name) == 0) { *type = name; }

Definition at line 112 of file qofutil.h.

113 { *type = name; }

◆ FROM_STRING_DEC

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

Definition at line 77 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 108 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 81 of file qofutil.h.

83 { \
84 if(str == NULL) { return 0; } \
85 list(FROM_STRING_CASE) \
86 return 0; }

◆ 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 115 of file qofutil.h.

117 { \
118 if(str == NULL) { return; } \
119 list(FROM_STRING_CASE_NON_TYPEDEF) }

◆ QOF_CACHE_NEW

#define QOF_CACHE_NEW (   void)    qof_string_cache_insert("")

Definition at line 109 of file qof-string-cache.h.

◆ QOF_MOD_UTIL [1/2]

#define QOF_MOD_UTIL   "qof.utilities"

Definition at line 41 of file qof-string-cache.h.

◆ QOF_MOD_UTIL [2/2]

#define QOF_MOD_UTIL   "qof.utilities"

Definition at line 48 of file qofutil.h.

◆ stpcpy

#define stpcpy   g_stpcpy

Definition at line 199 of file qofutil.h.

Function Documentation

◆ g_hash_table_foreach_sorted()

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

41{
42 GList *iter;
43 GList *keys = g_list_sort(g_hash_table_get_keys(hash_table), compare_func);
44
45 for (iter = keys; iter; iter = iter->next)
46 {
47 func(iter->data, g_hash_table_lookup(hash_table, iter->data), user_data);
48 }
49
50 g_list_free(keys);
51}

◆ gnc_strisnum()

gboolean gnc_strisnum ( const gchar *  s)

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

Definition at line 187 of file qofutil.cpp.

188{
189 if (s == NULL) return FALSE;
190 if (*s == 0) return FALSE;
191
192 while (*s && isspace(*s))
193 s++;
194
195 if (*s == 0) return FALSE;
196 if (!isdigit(*s)) return FALSE;
197
198 while (*s && isdigit(*s))
199 s++;
200
201 if (*s == 0) return TRUE;
202
203 while (*s && isspace(*s))
204 s++;
205
206 if (*s == 0) return TRUE;
207
208 return FALSE;
209}

◆ null_strcmp()

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 123 of file qofutil.cpp.

124{
125 if (da && db) return strcmp (da, db);
126 if (!da && db && 0 == db[0]) return 0;
127 if (!db && da && 0 == da[0]) return 0;
128 if (!da && db) return -1;
129 if (da && !db) return +1;
130 return 0;
131}

◆ qof_begin_edit()

gboolean qof_begin_edit ( QofInstance inst)

begin_edit

Parameters
instan instance of QofInstance

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

Definition at line 936 of file qofinstance.cpp.

937{
938 QofInstancePrivate *priv;
939
940 if (!inst) return FALSE;
941
942 priv = GET_PRIVATE(inst);
943 priv->editlevel++;
944 if (1 < priv->editlevel) return FALSE;
945 if (0 >= priv->editlevel)
946 priv->editlevel = 1;
947
948 auto be = qof_book_get_backend(priv->book);
949 if (be)
950 be->begin(inst);
951 else
952 priv->dirty = TRUE;
953
954 return TRUE;
955}
QofBackend * qof_book_get_backend(const QofBook *book)
Retrieve the backend used by this book.
Definition qofbook.cpp:440

◆ qof_close()

void qof_close ( void  )

Safely close down the Query Object Framework.

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

Definition at line 269 of file qofutil.cpp.

270{
271 qof_query_shutdown ();
272 qof_object_shutdown ();
273 QofBackend::release_backends();
276}
void qof_log_shutdown(void)
Be nice, close the logfile if possible.
Definition qoflog.cpp:264
void qof_string_cache_destroy(void)
Destroy the qof_string_cache.

◆ qof_commit_edit()

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
instan instance of QofInstance

Definition at line 957 of file qofinstance.cpp.

958{
959 QofInstancePrivate *priv;
960
961 if (!inst) return FALSE;
962
963 priv = GET_PRIVATE(inst);
964 priv->editlevel--;
965 if (0 < priv->editlevel) return FALSE;
966
967 if (0 > priv->editlevel)
968 {
969 PERR ("unbalanced call - resetting (was %d)", priv->editlevel);
970 priv->editlevel = 0;
971 }
972 return TRUE;
973}
#define PERR(format, args...)
Log a serious error.
Definition qoflog.h:244

◆ qof_commit_edit_part2()

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
instan instance of QofInstance
on_errora function called if there is a backend error. void (*on_error)(inst, QofBackendError)
on_donea function called after the commit is completed successfully for an object which remained valid. void (*on_done)(inst)
on_freea 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 976 of file qofinstance.cpp.

980{
981 QofInstancePrivate *priv;
982
983 priv = GET_PRIVATE(inst);
984
985 if (priv->dirty &&
986 !(priv->infant && priv->do_free)) {
987 qof_collection_mark_dirty(priv->collection);
988 qof_book_mark_session_dirty(priv->book);
989 }
990
991 /* See if there's a backend. If there is, invoke it. */
992 auto be = qof_book_get_backend(priv->book);
993 if (be)
994 {
995 QofBackendError errcode;
996
997 /* clear errors */
998 do
999 {
1000 errcode = be->get_error();
1001 }
1002 while (errcode != ERR_BACKEND_NO_ERR);
1003
1004 be->commit(inst);
1005 errcode = be->get_error();
1006 if (errcode != ERR_BACKEND_NO_ERR)
1007 {
1008 /* XXX Should perform a rollback here */
1009 priv->do_free = FALSE;
1010
1011 /* Push error back onto the stack */
1012 be->set_error (errcode);
1013 if (on_error)
1014 on_error(inst, errcode);
1015 return FALSE;
1016 }
1017 if (!priv->dirty) //Cleared if the save was successful
1018 priv->infant = FALSE;
1019 }
1020
1021 if (priv->do_free)
1022 {
1023 if (on_free)
1024 on_free(inst);
1025 return TRUE;
1026 }
1027
1028 if (on_done)
1029 on_done(inst);
1030 return TRUE;
1031}
QofBackendError
The errors that can be reported to the GUI & other front-end users.
Definition qofbackend.h:58
void qof_book_mark_session_dirty(QofBook *book)
The qof_book_mark_dirty() routine marks the book as having been modified.
Definition qofbook.cpp:397
QofCollection * collection
Entity collection.

◆ qof_init()

void qof_init ( void  )

Initialise the Query Object Framework.

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

Definition at line 259 of file qofutil.cpp.

260{
261 qof_log_init();
263 qof_object_initialize ();
265 qof_book_register ();
266}
void qof_log_init(void)
Initialize the error logging subsystem.
Definition qoflog.cpp:156
void qof_query_init(void)
Subsystem initialization and shutdown.
void qof_string_cache_init(void)
The QOF String Cache:

◆ qof_string_cache_destroy()

void qof_string_cache_destroy ( void  )

Destroy the qof_string_cache.

Definition at line 70 of file qof-string-cache.cpp.

71{
72 if (qof_string_cache)
73 {
74 g_hash_table_destroy(qof_string_cache);
75 }
76 qof_string_cache = NULL;
77}

◆ qof_string_cache_init()

void qof_string_cache_init ( 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_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_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. Initialize the string cache

Definition at line 64 of file qof-string-cache.cpp.

65{
66 (void)qof_get_string_cache();
67}

◆ qof_string_cache_insert()

const char * qof_string_cache_insert ( const char *  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 107 of file qof-string-cache.cpp.

108{
109 if (key)
110 {
111 if (key[0] == 0)
112 {
113 return "";
114 }
115
116 GHashTable* cache = qof_get_string_cache();
117 gpointer value;
118 gpointer cache_key;
119 if (g_hash_table_lookup_extended(cache, key, &cache_key, &value))
120 {
121 guint* refcount = (guint*)value;
122 ++(*refcount);
123 return static_cast <char *> (cache_key);
124 }
125 else
126 {
127 gpointer new_key = g_strdup(static_cast<const char*>(key));
128 guint* refcount = static_cast<unsigned int*>(g_malloc(sizeof(guint)));
129 *refcount = 1;
130 g_hash_table_insert(cache, new_key, refcount);
131 return static_cast <char *> (new_key);
132 }
133 }
134 return NULL;
135}

◆ qof_string_cache_remove()

void qof_string_cache_remove ( const char *  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 82 of file qof-string-cache.cpp.

83{
84 if (key && key[0] != 0)
85 {
86 GHashTable* cache = qof_get_string_cache();
87 gpointer value;
88 gpointer cache_key;
89 if (g_hash_table_lookup_extended(cache, key, &cache_key, &value))
90 {
91 guint* refcount = (guint*)value;
92 if (*refcount == 1)
93 {
94 g_hash_table_remove(cache, key);
95 }
96 else
97 {
98 --(*refcount);
99 }
100 }
101 }
102}

◆ qof_string_cache_replace()

const char * qof_string_cache_replace ( const char *  dst,
const char *  src 
)

Same as CACHE_REPLACE below, but safe to call from C++.

Definition at line 138 of file qof-string-cache.cpp.

139{
140 const char * tmp {qof_string_cache_insert (src)};
142 return tmp;
143}
const char * qof_string_cache_insert(const char *key)
You can use this function with g_hash_table_insert(), for the key (or value), as long as you use the ...
void qof_string_cache_remove(const char *key)
You can use this function as a destroy notifier for a GHashTable that uses common strings as keys (or...

◆ qof_utf8_substr_nocase()

gboolean qof_utf8_substr_nocase ( const gchar *  haystack,
const gchar *  needle 
)

Search for an occurrence 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.cpp.

55{
56 gchar *haystack_casefold, *haystack_normalized;
57 gchar *needle_casefold, *needle_normalized;
58 gchar *p;
59
60 g_return_val_if_fail (haystack && needle, FALSE);
61
62 haystack_casefold = g_utf8_casefold (haystack, -1);
63 haystack_normalized = g_utf8_normalize (haystack_casefold, -1,
64 G_NORMALIZE_NFC);
65 g_free (haystack_casefold);
66
67 needle_casefold = g_utf8_casefold (needle, -1);
68 needle_normalized = g_utf8_normalize (needle_casefold, -1, G_NORMALIZE_NFC);
69 g_free (needle_casefold);
70
71 p = strstr (haystack_normalized, needle_normalized);
72 g_free (haystack_normalized);
73 g_free (needle_normalized);
74
75 return p != NULL;
76}

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

101{
102 if ((da) && (db))
103 {
104 if ((da) != (db))
105 {
106 gint retval = qof_utf8_strcasecmp ((da), (db));
107 /* if strings differ, return */
108 if (retval) return retval;
109 }
110 }
111 else if ((!(da)) && (db))
112 {
113 return -1;
114 }
115 else if ((da) && (!(db)))
116 {
117 return +1;
118 }
119 return 0;
120}

◆ 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 137 of file qofutil.cpp.

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