GnuCash 2.4.99
qofutil.c
00001 /********************************************************************\
00002  * qofutil.c -- QOF utility functions                               *
00003  * Copyright (C) 1997 Robin D. Clark                                *
00004  * Copyright (C) 1997-2001,2004 Linas Vepstas <linas@linas.org>     *
00005  * Copyright 2006  Neil Williams  <linux@codehelp.co.uk>            *
00006  *                                                                  *
00007  * This program is free software; you can redistribute it and/or    *
00008  * modify it under the terms of the GNU General Public License as   *
00009  * published by the Free Software Foundation; either version 2 of   *
00010  * the License, or (at your option) any later version.              *
00011  *                                                                  *
00012  * This program is distributed in the hope that it will be useful,  *
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
00015  * GNU General Public License for more details.                     *
00016  *                                                                  *
00017  * You should have received a copy of the GNU General Public License*
00018  * along with this program; if not, contact:                        *
00019  *                                                                  *
00020  * Free Software Foundation           Voice:  +1-617-542-5942       *
00021  * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
00022  * Boston, MA  02110-1301,  USA       gnu@gnu.org                   *
00023  *                                                                  *
00024  *   Author: Rob Clark (rclark@cs.hmc.edu)                          *
00025  *   Author: Linas Vepstas (linas@linas.org)                        *
00026 \********************************************************************/
00027 
00028 #include "config.h"
00029 
00030 #include <ctype.h>
00031 #include <glib.h>
00032 #include <stdlib.h>
00033 #include <string.h>
00034 #include "qof.h"
00035 #include "qofbackend-p.h"
00036 
00037 static QofLogModule log_module = QOF_MOD_UTIL;
00038 
00039 void
00040 g_hash_table_foreach_sorted(GHashTable *hash_table, GHFunc func, gpointer user_data, GCompareFunc compare_func)
00041 {
00042     GList *iter;
00043     GList *keys = g_list_sort(g_hash_table_get_keys(hash_table), compare_func);
00044 
00045     for (iter = keys; iter; iter = iter->next)
00046     {
00047         func(iter->data, g_hash_table_lookup(hash_table, iter->data), user_data);
00048     }
00049 
00050     g_list_free(keys);
00051 }
00052 
00053 gboolean
00054 qof_utf8_substr_nocase (const gchar *haystack, const gchar *needle)
00055 {
00056     gchar *haystack_casefold, *haystack_normalized;
00057     gchar *needle_casefold, *needle_normalized;
00058     gchar *p;
00059 
00060     g_return_val_if_fail (haystack && needle, FALSE);
00061 
00062     haystack_casefold = g_utf8_casefold (haystack, -1);
00063     haystack_normalized = g_utf8_normalize (haystack_casefold, -1,
00064                                             G_NORMALIZE_ALL);
00065     g_free (haystack_casefold);
00066 
00067     needle_casefold = g_utf8_casefold (needle, -1);
00068     needle_normalized = g_utf8_normalize (needle_casefold, -1, G_NORMALIZE_ALL);
00069     g_free (needle_casefold);
00070 
00071     p = strstr (haystack_normalized, needle_normalized);
00072     g_free (haystack_normalized);
00073     g_free (needle_normalized);
00074 
00075     return p != NULL;
00076 }
00077 
00081 static gint
00082 qof_utf8_strcasecmp (const gchar *da, const gchar *db)
00083 {
00084     gchar *da_casefold, *db_casefold;
00085     gint retval;
00086 
00087     g_return_val_if_fail (da != NULL, 0);
00088     g_return_val_if_fail (db != NULL, 0);
00089 
00090     da_casefold = g_utf8_casefold (da, -1);
00091     db_casefold = g_utf8_casefold (db, -1);
00092     retval = g_utf8_collate (da_casefold, db_casefold);
00093     g_free (da_casefold);
00094     g_free (db_casefold);
00095 
00096     return retval;
00097 }
00098 
00099 gint
00100 safe_strcmp (const gchar * da, const gchar * db)
00101 {
00102     if ((da) && (db))
00103     {
00104         if ((da) != (db))
00105         {
00106             gint retval = strcmp ((da), (db));
00107             /* if strings differ, return */
00108             if (retval) return retval;
00109         }
00110     }
00111     else if ((!(da)) && (db))
00112     {
00113         return -1;
00114     }
00115     else if ((da) && (!(db)))
00116     {
00117         return +1;
00118     }
00119     return 0;
00120 }
00121 
00122 gint
00123 safe_strcasecmp (const gchar * da, const gchar * db)
00124 {
00125     if ((da) && (db))
00126     {
00127         if ((da) != (db))
00128         {
00129             gint retval = qof_utf8_strcasecmp ((da), (db));
00130             /* if strings differ, return */
00131             if (retval) return retval;
00132         }
00133     }
00134     else if ((!(da)) && (db))
00135     {
00136         return -1;
00137     }
00138     else if ((da) && (!(db)))
00139     {
00140         return +1;
00141     }
00142     return 0;
00143 }
00144 
00145 gint
00146 null_strcmp (const gchar * da, const gchar * db)
00147 {
00148     if (da && db) return strcmp (da, db);
00149     if (!da && db && 0 == db[0]) return 0;
00150     if (!db && da && 0 == da[0]) return 0;
00151     if (!da && db) return -1;
00152     if (da && !db) return +1;
00153     return 0;
00154 }
00155 
00156 #define MAX_DIGITS 50
00157 
00158 /* inverse of strtoul */
00159 gchar *
00160 ultostr (gulong val, gint base)
00161 {
00162     gchar buf[MAX_DIGITS];
00163     gulong broke[MAX_DIGITS];
00164     gint i;
00165     gulong places = 0, reval;
00166 
00167     if ((2 > base) || (36 < base)) return NULL;
00168 
00169     /* count digits */
00170     places = 0;
00171     for (i = 0; i < MAX_DIGITS; i++)
00172     {
00173         broke[i] = val;
00174         places ++;
00175         val /= base;
00176         if (0 == val) break;
00177     }
00178 
00179     /* normalize */
00180     reval = 0;
00181     for (i = places - 2; i >= 0; i--)
00182     {
00183         reval += broke[i+1];
00184         reval *= base;
00185         broke[i] -= reval;
00186     }
00187 
00188     /* print */
00189     for (i = 0; i < (gint)places; i++)
00190     {
00191         if (10 > broke[i])
00192         {
00193             buf[places-1-i] = 0x30 + broke[i];  /* ascii digit zero */
00194         }
00195         else
00196         {
00197             buf[places-1-i] = 0x41 - 10 + broke[i];  /* ascii capital A */
00198         }
00199     }
00200     buf[places] = 0x0;
00201 
00202     return g_strdup (buf);
00203 }
00204 
00205 /* =================================================================== */
00206 /* returns TRUE if the string is a number, possibly with whitespace */
00207 /* =================================================================== */
00208 
00209 gboolean
00210 gnc_strisnum(const gchar *s)
00211 {
00212     if (s == NULL) return FALSE;
00213     if (*s == 0) return FALSE;
00214 
00215     while (*s && isspace(*s))
00216         s++;
00217 
00218     if (*s == 0) return FALSE;
00219     if (!isdigit(*s)) return FALSE;
00220 
00221     while (*s && isdigit(*s))
00222         s++;
00223 
00224     if (*s == 0) return TRUE;
00225 
00226     while (*s && isspace(*s))
00227         s++;
00228 
00229     if (*s == 0) return TRUE;
00230 
00231     return FALSE;
00232 }
00233 
00234 /* =================================================================== */
00235 /* Return NULL if the field is whitespace (blank, tab, formfeed etc.)
00236  * Else return pointer to first non-whitespace character. */
00237 /* =================================================================== */
00238 
00239 static const gchar *
00240 qof_util_whitespace_filter (const gchar * val)
00241 {
00242     size_t len;
00243     if (!val) return NULL;
00244 
00245     len = strspn (val, "\a\b\t\n\v\f\r ");
00246     if (0 == val[len]) return NULL;
00247     return val + len;
00248 }
00249 
00250 #ifdef THESE_CAN_BE_USEFUL_FOR_DEGUGGING
00251 static guint g_str_hash_KEY(gconstpointer v)
00252 {
00253     return g_str_hash(v);
00254 }
00255 static guint g_str_hash_VAL(gconstpointer v)
00256 {
00257     return g_str_hash(v);
00258 }
00259 static gpointer g_strdup_VAL(gpointer v)
00260 {
00261     return g_strdup(v);
00262 }
00263 static gpointer g_strdup_KEY(gpointer v)
00264 {
00265     return g_strdup(v);
00266 }
00267 static void g_free_VAL(gpointer v)
00268 {
00269     return g_free(v);
00270 }
00271 static void g_free_KEY(gpointer v)
00272 {
00273     return g_free(v);
00274 }
00275 static gboolean qof_util_str_equal(gconstpointer v, gconstpointer v2)
00276 {
00277     return (v && v2) ? g_str_equal(v, v2) : FALSE;
00278 }
00279 #endif
00280 
00281 void
00282 qof_init (void)
00283 {
00284     g_type_init();
00285     qof_log_init();
00286     qof_string_cache_init();
00287     guid_init ();
00288     qof_object_initialize ();
00289     qof_query_init ();
00290     qof_book_register ();
00291 }
00292 
00293 void
00294 qof_close(void)
00295 {
00296     qof_query_shutdown ();
00297     qof_object_shutdown ();
00298     guid_shutdown ();
00299     qof_finalize_backend_libraries();
00300     qof_string_cache_destroy ();
00301     qof_log_shutdown();
00302 }
00303 
00304 /* ************************ END OF FILE ***************************** */
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines