LCOV - code coverage report
Current view: top level - libgnucash/engine - qofutil.cpp (source / functions) Coverage Total Hit
Test: gnucash.info Lines: 33.7 % 98 33
Test Date: 2026-11-02 18:19:43 Functions: 40.0 % 10 4
Legend: Lines:     hit not hit

            Line data    Source code
       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            0 : g_hash_table_foreach_sorted(GHashTable *hash_table, GHFunc func, gpointer user_data, GCompareFunc compare_func)
      41              : {
      42              :     GList *iter;
      43            0 :     GList *keys = g_list_sort(g_hash_table_get_keys(hash_table), compare_func);
      44              : 
      45            0 :     for (iter = keys; iter; iter = iter->next)
      46              :     {
      47            0 :         func(iter->data, g_hash_table_lookup(hash_table, iter->data), user_data);
      48              :     }
      49              : 
      50            0 :     g_list_free(keys);
      51            0 : }
      52              : 
      53              : gboolean
      54          297 : 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          297 :     g_return_val_if_fail (haystack && needle, FALSE);
      61              : 
      62          297 :     haystack_casefold = g_utf8_casefold (haystack, -1);
      63          297 :     haystack_normalized = g_utf8_normalize (haystack_casefold, -1,
      64              :                                             G_NORMALIZE_NFC);
      65          297 :     g_free (haystack_casefold);
      66              : 
      67          297 :     needle_casefold = g_utf8_casefold (needle, -1);
      68          297 :     needle_normalized = g_utf8_normalize (needle_casefold, -1, G_NORMALIZE_NFC);
      69          297 :     g_free (needle_casefold);
      70              : 
      71          297 :     p = strstr (haystack_normalized, needle_normalized);
      72          297 :     g_free (haystack_normalized);
      73          297 :     g_free (needle_normalized);
      74              : 
      75          297 :     return p != NULL;
      76              : }
      77              : 
      78              : /** Use g_utf8_casefold and g_utf8_collate to compare two utf8 strings,
      79              :  * ignore case. Return < 0 if da compares before db, 0 if they compare
      80              :  * equal, > 0 if da compares after db. */
      81              : static gint
      82            0 : qof_utf8_strcasecmp (const gchar *da, const gchar *db)
      83              : {
      84              :     gchar *da_casefold, *db_casefold;
      85              :     gint retval;
      86              : 
      87            0 :     g_return_val_if_fail (da != NULL, 0);
      88            0 :     g_return_val_if_fail (db != NULL, 0);
      89              : 
      90            0 :     da_casefold = g_utf8_casefold (da, -1);
      91            0 :     db_casefold = g_utf8_casefold (db, -1);
      92            0 :     retval = g_utf8_collate (da_casefold, db_casefold);
      93            0 :     g_free (da_casefold);
      94            0 :     g_free (db_casefold);
      95              : 
      96            0 :     return retval;
      97              : }
      98              : 
      99              : gint
     100            0 : safe_strcasecmp (const gchar * da, const gchar * db)
     101              : {
     102            0 :     if ((da) && (db))
     103              :     {
     104            0 :         if ((da) != (db))
     105              :         {
     106            0 :             gint retval = qof_utf8_strcasecmp ((da), (db));
     107              :             /* if strings differ, return */
     108            0 :             if (retval) return retval;
     109              :         }
     110            0 :     }
     111            0 :     else if ((!(da)) && (db))
     112              :     {
     113            0 :         return -1;
     114              :     }
     115            0 :     else if ((da) && (!(db)))
     116              :     {
     117            0 :         return +1;
     118              :     }
     119            0 :     return 0;
     120              : }
     121              : 
     122              : gint
     123           18 : null_strcmp (const gchar * da, const gchar * db)
     124              : {
     125           18 :     if (da && db) return strcmp (da, db);
     126            2 :     if (!da && db && 0 == db[0]) return 0;
     127            2 :     if (!db && da && 0 == da[0]) return 0;
     128            2 :     if (!da && db) return -1;
     129            2 :     if (da && !db) return +1;
     130            2 :     return 0;
     131              : }
     132              : 
     133              : #define MAX_DIGITS 50
     134              : 
     135              : /* inverse of strtoul */
     136              : gchar *
     137            0 : ultostr (gulong val, gint base)
     138              : {
     139              :     gchar buf[MAX_DIGITS];
     140              :     gulong broke[MAX_DIGITS];
     141              :     gint i;
     142            0 :     gulong places = 0, reval;
     143              : 
     144            0 :     if ((2 > base) || (36 < base)) return NULL;
     145              : 
     146              :     /* count digits */
     147            0 :     places = 0;
     148            0 :     for (i = 0; i < MAX_DIGITS; i++)
     149              :     {
     150            0 :         broke[i] = val;
     151            0 :         places ++;
     152            0 :         val /= base;
     153            0 :         if (0 == val) break;
     154              :     }
     155              : 
     156              :     /* normalize */
     157            0 :     reval = 0;
     158            0 :     for (i = places - 2; i >= 0; i--)
     159              :     {
     160            0 :         reval += broke[i+1];
     161            0 :         reval *= base;
     162            0 :         broke[i] -= reval;
     163              :     }
     164              : 
     165              :     /* print */
     166            0 :     for (i = 0; i < (gint)places; i++)
     167              :     {
     168            0 :         if (10 > broke[i])
     169              :         {
     170            0 :             buf[places-1-i] = 0x30 + broke[i];  /* ascii digit zero */
     171              :         }
     172              :         else
     173              :         {
     174            0 :             buf[places-1-i] = 0x41 - 10 + broke[i];  /* ascii capital A */
     175              :         }
     176              :     }
     177            0 :     buf[places] = 0x0;
     178              : 
     179            0 :     return g_strdup (buf);
     180              : }
     181              : 
     182              : /* =================================================================== */
     183              : /* returns TRUE if the string is a number, possibly with whitespace */
     184              : /* =================================================================== */
     185              : 
     186              : gboolean
     187            0 : gnc_strisnum(const gchar *s)
     188              : {
     189            0 :     if (s == NULL) return FALSE;
     190            0 :     if (*s == 0) return FALSE;
     191              : 
     192            0 :     while (*s && isspace(*s))
     193            0 :         s++;
     194              : 
     195            0 :     if (*s == 0) return FALSE;
     196            0 :     if (!isdigit(*s)) return FALSE;
     197              : 
     198            0 :     while (*s && isdigit(*s))
     199            0 :         s++;
     200              : 
     201            0 :     if (*s == 0) return TRUE;
     202              : 
     203            0 :     while (*s && isspace(*s))
     204            0 :         s++;
     205              : 
     206            0 :     if (*s == 0) return TRUE;
     207              : 
     208            0 :     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            0 : qof_util_whitespace_filter (const gchar * val)
     218              : {
     219              :     size_t len;
     220            0 :     if (!val) return NULL;
     221              : 
     222            0 :     len = strspn (val, "\a\b\t\n\v\f\r ");
     223            0 :     if (0 == val[len]) return NULL;
     224            0 :     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          117 : qof_init (void)
     260              : {
     261          117 :     qof_log_init();
     262          117 :     qof_string_cache_init();
     263          117 :     qof_object_initialize ();
     264          117 :     qof_query_init ();
     265          117 :     qof_book_register ();
     266          117 : }
     267              : 
     268              : void
     269           43 : qof_close(void)
     270              : {
     271           43 :     qof_query_shutdown ();
     272           43 :     qof_object_shutdown ();
     273           43 :     QofBackend::release_backends();
     274           43 :     qof_string_cache_destroy ();
     275           43 :     qof_log_shutdown();
     276           43 : }
     277              : 
     278              : /* ************************ END OF FILE ***************************** */
        

Generated by: LCOV version 2.0-1