GnuCash  5.6-139-g03622b03d0+
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 
37 G_GNUC_UNUSED static QofLogModule log_module = QOF_MOD_UTIL;
38 
39 void
40 g_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 
53 gboolean
54 qof_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 
81 static gint
82 qof_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 
99 gint
100 safe_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 
122 gint
123 null_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 */
136 gchar *
137 ultostr (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 
186 gboolean
187 gnc_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 
216 G_GNUC_UNUSED static const gchar *
217 qof_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
228 static guint g_str_hash_KEY(gconstpointer v)
229 {
230  return g_str_hash(v);
231 }
232 static guint g_str_hash_VAL(gconstpointer v)
233 {
234  return g_str_hash(v);
235 }
236 static gpointer g_strdup_VAL(gpointer v)
237 {
238  return g_strdup(v);
239 }
240 static gpointer g_strdup_KEY(gpointer v)
241 {
242  return g_strdup(v);
243 }
244 static void g_free_VAL(gpointer v)
245 {
246  return g_free(v);
247 }
248 static void g_free_KEY(gpointer v)
249 {
250  return g_free(v);
251 }
252 static gboolean qof_util_str_equal(gconstpointer v, gconstpointer v2)
253 {
254  return (v && v2) ? g_str_equal(v, v2) : FALSE;
255 }
256 #endif
257 
258 void
259 qof_init (void)
260 {
261  qof_log_init();
263  qof_object_initialize ();
264  qof_query_init ();
265  qof_book_register ();
266 }
267 
268 void
270 {
271  qof_query_shutdown ();
272  qof_object_shutdown ();
273  QofBackend::release_backends();
276 }
277 
278 /* ************************ END OF FILE ***************************** */
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_log_init(void)
Initialize the error logging subsystem.
Definition: qoflog.cpp:156
void qof_string_cache_destroy(void)
Destroy the qof_string_cache.
void qof_log_shutdown(void)
Be nice, close the logfile if possible.
Definition: qoflog.cpp:264
gboolean gnc_strisnum(const gchar *s)
Returns true if string s is a number, possibly surrounded by whitespace.
Definition: qofutil.cpp:187
void qof_query_init(void)
Subsystem initialization and shutdown.
Definition: qofquery.cpp:1341
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
gchar * ultostr(gulong val, gint base)
The ultostr() subroutine is the inverse of strtoul().
Definition: qofutil.cpp:137
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
void qof_close(void)
Safely close down the Query Object Framework.
Definition: qofutil.cpp:269
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_init(void)
Initialise the Query Object Framework.
Definition: qofutil.cpp:259
void qof_string_cache_init(void)
The QOF String Cache: