GnuCash c935c2f+
Loading...
Searching...
No Matches
qofutil.cpp
1/********************************************************************\
2 * qofutil.c -- QOF utility functions *
3 * Copyright (C) 1997 Robin D. Clark *
4 * Copyright (C) 1997-2001,2004 Linas Vepstas <linas@linas.org> *
5 * Copyright 2006 Neil Williams <linux@codehelp.co.uk> *
6 * *
7 * This program is free software; you can redistribute it and/or *
8 * modify it under the terms of the GNU General Public License as *
9 * published by the Free Software Foundation; either version 2 of *
10 * the License, or (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License*
18 * along with this program; if not, contact: *
19 * *
20 * Free Software Foundation Voice: +1-617-542-5942 *
21 * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
22 * Boston, MA 02110-1301, USA gnu@gnu.org *
23 * *
24 * Author: Rob Clark (rclark@cs.hmc.edu) *
25 * Author: Linas Vepstas (linas@linas.org) *
26\********************************************************************/
27
28#include <config.h>
29
30#include <ctype.h>
31#include <glib.h>
32#include <stdlib.h>
33#include <string.h>
34#include "qof.h"
35#include "qof-backend.hpp"
36
37G_GNUC_UNUSED static QofLogModule log_module = QOF_MOD_UTIL;
38
39void
40g_hash_table_foreach_sorted(GHashTable *hash_table, GHFunc func, gpointer user_data, GCompareFunc compare_func)
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}
52
53gboolean
54qof_utf8_substr_nocase (const gchar *haystack, const gchar *needle)
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}
77
81static gint
82qof_utf8_strcasecmp (const gchar *da, const gchar *db)
83{
84 gchar *da_casefold, *db_casefold;
85 gint retval;
86
87 g_return_val_if_fail (da != NULL, 0);
88 g_return_val_if_fail (db != NULL, 0);
89
90 da_casefold = g_utf8_casefold (da, -1);
91 db_casefold = g_utf8_casefold (db, -1);
92 retval = g_utf8_collate (da_casefold, db_casefold);
93 g_free (da_casefold);
94 g_free (db_casefold);
95
96 return retval;
97}
98
99gint
100safe_strcasecmp (const gchar * da, const gchar * db)
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}
121
122gint
123null_strcmp (const gchar * da, const gchar * db)
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}
132
133#define MAX_DIGITS 50
134
135/* inverse of strtoul */
136gchar *
137ultostr (gulong val, gint base)
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}
181
182/* =================================================================== */
183/* returns TRUE if the string is a number, possibly with whitespace */
184/* =================================================================== */
185
186gboolean
187gnc_strisnum(const gchar *s)
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}
210
211/* =================================================================== */
212/* Return NULL if the field is whitespace (blank, tab, formfeed etc.)
213 * Else return pointer to first non-whitespace character. */
214/* =================================================================== */
215
216G_GNUC_UNUSED static const gchar *
217qof_util_whitespace_filter (const gchar * val)
218{
219 size_t len;
220 if (!val) return NULL;
221
222 len = strspn (val, "\a\b\t\n\v\f\r ");
223 if (0 == val[len]) return NULL;
224 return val + len;
225}
226
227#ifdef THESE_CAN_BE_USEFUL_FOR_DEGUGGING
228static guint g_str_hash_KEY(gconstpointer v)
229{
230 return g_str_hash(v);
231}
232static guint g_str_hash_VAL(gconstpointer v)
233{
234 return g_str_hash(v);
235}
236static gpointer g_strdup_VAL(gpointer v)
237{
238 return g_strdup(v);
239}
240static gpointer g_strdup_KEY(gpointer v)
241{
242 return g_strdup(v);
243}
244static void g_free_VAL(gpointer v)
245{
246 return g_free(v);
247}
248static void g_free_KEY(gpointer v)
249{
250 return g_free(v);
251}
252static gboolean qof_util_str_equal(gconstpointer v, gconstpointer v2)
253{
254 return (v && v2) ? g_str_equal(v, v2) : FALSE;
255}
256#endif
257
258void
260{
261 qof_log_init();
263 qof_object_initialize ();
265 qof_book_register ();
266}
267
268void
270{
271 qof_query_shutdown ();
272 qof_object_shutdown ();
273 QofBackend::release_backends();
276}
277
278/* ************************ END OF FILE ***************************** */
void qof_log_init(void)
Initialize the error logging subsystem.
Definition qoflog.cpp:156
void qof_log_shutdown(void)
Be nice, close the logfile if possible.
Definition qoflog.cpp:264
void qof_query_init(void)
Subsystem initialization and shutdown.
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 n...
Definition qofutil.cpp:123
void qof_string_cache_init(void)
The QOF String Cache:
gint safe_strcasecmp(const gchar *da, const gchar *db)
case sensitive comparison of strings da and db - either may be NULL.
Definition qofutil.cpp:100
void qof_string_cache_destroy(void)
Destroy the qof_string_cache.
gboolean gnc_strisnum(const gchar *s)
Returns true if string s is a number, possibly surrounded by whitespace.
Definition qofutil.cpp:187
void qof_init(void)
Initialise the Query Object Framework.
Definition qofutil.cpp:259
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 ...
Definition qofutil.cpp:40
gchar * ultostr(gulong val, gint base)
The ultostr() subroutine is the inverse of strtoul().
Definition qofutil.cpp:137
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.
Definition qofutil.cpp:54
void qof_close(void)
Safely close down the Query Object Framework.
Definition qofutil.cpp:269