LCOV - code coverage report
Current view: top level - libgnucash/core-utils - gnc-locale-utils.c (source / functions) Coverage Total Hit
Test: gnucash.info Lines: 84.9 % 53 45
Test Date: 2026-10-13 17:01:30 Functions: 83.3 % 6 5
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /********************************************************************\
       2                 :             :  * gnc-locale-utils.c -- locale functions                           *
       3                 :             :  * Copyright (C) 2000 Dave Peticolas <dave@krondo.com>              *
       4                 :             :  *                                                                  *
       5                 :             :  * This program is free software; you can redistribute it and/or    *
       6                 :             :  * modify it under the terms of the GNU General Public License as   *
       7                 :             :  * published by the Free Software Foundation; either version 2 of   *
       8                 :             :  * the License, or (at your option) any later version.              *
       9                 :             :  *                                                                  *
      10                 :             :  * This program is distributed in the hope that it will be useful,  *
      11                 :             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
      12                 :             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
      13                 :             :  * GNU General Public License for more details.                     *
      14                 :             :  *                                                                  *
      15                 :             :  * You should have received a copy of the GNU General Public License*
      16                 :             :  * along with this program; if not, contact:                        *
      17                 :             :  *                                                                  *
      18                 :             :  * Free Software Foundation           Voice:  +1-617-542-5942       *
      19                 :             :  * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
      20                 :             :  * Boston, MA  02110-1301,  USA       gnu@gnu.org                   *
      21                 :             : \********************************************************************/
      22                 :             : 
      23                 :             : #include <config.h>
      24                 :             : 
      25                 :             : #include "gnc-locale-utils.h"
      26                 :             : 
      27                 :             : #include <glib.h>
      28                 :             : #include <glib/gi18n.h>
      29                 :             : 
      30                 :             : #ifdef G_OS_WIN32
      31                 :             : #include <windows.h>
      32                 :             : 
      33                 :             : static void
      34                 :             : gnc_lconv_set_utf8 (char **p_value, wchar_t *w_value, const char *default_value)
      35                 :             : {
      36                 :             :     g_return_if_fail (p_value != NULL);
      37                 :             :     if (w_value && *w_value)
      38                 :             :         *p_value = g_utf16_to_utf8 (w_value, -1, NULL, NULL, NULL);
      39                 :             :     else
      40                 :             :         *p_value = g_strdup (default_value);
      41                 :             : }
      42                 :             : 
      43                 :             : static LPCWSTR
      44                 :             : get_locale_name ()
      45                 :             : {
      46                 :             :     char* locale = setlocale(LC_MONETARY, NULL);
      47                 :             :     int len = 0;
      48                 :             :     len = strchr (locale, '.') - locale;
      49                 :             :     locale[2] = '-';
      50                 :             :     wchar_t *wlocale = g_utf8_to_utf16 (locale, len, NULL, NULL, NULL);
      51                 :             :     if (IsValidLocaleName(wlocale))
      52                 :             :         return wlocale;
      53                 :             :     return LOCALE_NAME_USER_DEFAULT;
      54                 :             : }
      55                 :             : 
      56                 :             : #define BUFSIZE 10 //Max size used by LOCALE_SGROUPING.
      57                 :             : static wchar_t*
      58                 :             : get_lconv_wide_val (LCTYPE lctype)
      59                 :             : {
      60                 :             :     static wchar_t buffer[BUFSIZE];
      61                 :             :     LPCWSTR locale = get_locale_name ();
      62                 :             :     memset (buffer, 0, BUFSIZE * sizeof(wchar_t));
      63                 :             :     int count =  GetLocaleInfoEx (locale, lctype, buffer, BUFSIZE);
      64                 :             :     if (!count)
      65                 :             :     {
      66                 :             :         g_error("GetLocaleInfo failed for %ld, %ld", lctype, GetLastError());
      67                 :             :         return NULL;
      68                 :             :     }
      69                 :             :     if (lctype == LOCALE_SGROUPING || lctype == LOCALE_SMONGROUPING)
      70                 :             :     {
      71                 :             :         buffer[0] &= 0x0f; // The standard localeconv is a single uint8
      72                 :             :         buffer[1] = '\0';
      73                 :             :     }
      74                 :             :     return buffer;
      75                 :             : }
      76                 :             : #else
      77                 :             : static void
      78                 :         340 : gnc_lconv_set_utf8 (char **p_value, char *default_value)
      79                 :             : {
      80                 :         340 :     char *value = *p_value;
      81                 :         340 :     *p_value = NULL;
      82                 :             : 
      83                 :         340 :     if ((value == NULL) || (value[0] == 0))
      84                 :         306 :         value = default_value;
      85                 :             : 
      86                 :         340 :     *p_value = g_locale_to_utf8 (value, -1, NULL, NULL, NULL);
      87                 :             : 
      88                 :         340 :     if (*p_value == NULL)
      89                 :             :     {
      90                 :             :         // The g_locale_to_utf8 conversion failed. FIXME: Should we rather
      91                 :             :         // use an empty string instead of the default_value? Not sure.
      92                 :           0 :         *p_value = default_value;
      93                 :             :     }
      94                 :         340 : }
      95                 :             : 
      96                 :             : #endif
      97                 :             : static void
      98                 :         272 : gnc_lconv_set_char (char *p_value, char default_value)
      99                 :             : {
     100                 :         272 :     if ((p_value != NULL) && (*p_value == CHAR_MAX))
     101                 :         272 :         *p_value = default_value;
     102                 :         272 : }
     103                 :             : 
     104                 :             : struct lconv *
     105                 :       35347 : gnc_localeconv (void)
     106                 :             : {
     107                 :             :     static struct lconv lc;
     108                 :             :     static gboolean lc_set = FALSE;
     109                 :             : 
     110                 :       35347 :     if (lc_set)
     111                 :       35313 :         return &lc;
     112                 :             : 
     113                 :          34 :     lc = *localeconv();
     114                 :             : #ifdef G_OS_WIN32
     115                 :             :     gnc_lconv_set_utf8(&lc.decimal_point,
     116                 :             :                        get_lconv_wide_val (LOCALE_SDECIMAL), ".");
     117                 :             :     gnc_lconv_set_utf8(&lc.thousands_sep,
     118                 :             :                        get_lconv_wide_val (LOCALE_STHOUSAND),",");
     119                 :             :     gnc_lconv_set_utf8(&lc.grouping,
     120                 :             :                        get_lconv_wide_val (LOCALE_SGROUPING), "\003");
     121                 :             :     gnc_lconv_set_utf8(&lc.int_curr_symbol,
     122                 :             :                        get_lconv_wide_val (LOCALE_SINTLSYMBOL), "USD ");
     123                 :             :     gnc_lconv_set_utf8(&lc.currency_symbol,
     124                 :             :                        get_lconv_wide_val (LOCALE_SCURRENCY), "$");
     125                 :             :     gnc_lconv_set_utf8(&lc.mon_decimal_point,
     126                 :             :                        get_lconv_wide_val (LOCALE_SMONDECIMALSEP), ".");
     127                 :             :     gnc_lconv_set_utf8(&lc.mon_thousands_sep,
     128                 :             :                        get_lconv_wide_val (LOCALE_SMONTHOUSANDSEP), ",");
     129                 :             :     gnc_lconv_set_utf8(&lc.mon_grouping,
     130                 :             :                        get_lconv_wide_val (LOCALE_SMONGROUPING), "\003");
     131                 :             :     gnc_lconv_set_utf8(&lc.negative_sign,
     132                 :             :                        get_lconv_wide_val (LOCALE_SNEGATIVESIGN), "-");
     133                 :             :     gnc_lconv_set_utf8(&lc.positive_sign,
     134                 :             :                        get_lconv_wide_val (LOCALE_SPOSITIVESIGN), "");
     135                 :             : #else
     136                 :          34 :     gnc_lconv_set_utf8(&lc.decimal_point, ".");
     137                 :          34 :     gnc_lconv_set_utf8(&lc.thousands_sep, ",");
     138                 :          34 :     gnc_lconv_set_utf8(&lc.grouping, "\003");
     139                 :          34 :     gnc_lconv_set_utf8(&lc.int_curr_symbol, "USD ");
     140                 :          34 :     gnc_lconv_set_utf8(&lc.currency_symbol, "$");
     141                 :          34 :     gnc_lconv_set_utf8(&lc.mon_decimal_point, ".");
     142                 :          34 :     gnc_lconv_set_utf8(&lc.mon_thousands_sep, ",");
     143                 :          34 :     gnc_lconv_set_utf8(&lc.mon_grouping, "\003");
     144                 :          34 :     gnc_lconv_set_utf8(&lc.negative_sign, "-");
     145                 :          34 :     gnc_lconv_set_utf8(&lc.positive_sign, "");
     146                 :             : #endif
     147                 :          34 :     gnc_lconv_set_char(&lc.frac_digits, 2);
     148                 :          34 :     gnc_lconv_set_char(&lc.int_frac_digits, 2);
     149                 :          34 :     gnc_lconv_set_char(&lc.p_cs_precedes, 1);
     150                 :          34 :     gnc_lconv_set_char(&lc.p_sep_by_space, 0);
     151                 :          34 :     gnc_lconv_set_char(&lc.n_cs_precedes, 1);
     152                 :          34 :     gnc_lconv_set_char(&lc.n_sep_by_space, 0);
     153                 :          34 :     gnc_lconv_set_char(&lc.p_sign_posn, 1);
     154                 :          34 :     gnc_lconv_set_char(&lc.n_sign_posn, 1);
     155                 :             : 
     156                 :          34 :     lc_set = TRUE;
     157                 :             : 
     158                 :          34 :     return &lc;
     159                 :             : }
     160                 :             : 
     161                 :             : const char *
     162                 :        1533 : gnc_locale_default_iso_currency_code (void)
     163                 :             : {
     164                 :             :     static char *code = NULL;
     165                 :             :     struct lconv *lc;
     166                 :             : 
     167                 :        1533 :     if (code)
     168                 :        1505 :         return code;
     169                 :             : 
     170                 :          28 :     lc = gnc_localeconv ();
     171                 :             : 
     172                 :          28 :     code = g_strdup (lc->int_curr_symbol);
     173                 :             : 
     174                 :             :     /* The int_curr_symbol includes a space at the end! Note: you
     175                 :             :      * can't just change "USD " to "USD" in gnc_localeconv, because
     176                 :             :      * that is only used if int_curr_symbol was not defined in the
     177                 :             :      * current locale. If it was, it will have the space! */
     178                 :          28 :     g_strstrip (code);
     179                 :             : 
     180                 :          28 :     return code;
     181                 :             : }
     182                 :             : 
     183                 :             : /* Return the number of decimal places for this locale. */
     184                 :             : int
     185                 :           0 : gnc_locale_decimal_places (void)
     186                 :             : {
     187                 :             :     static gboolean got_it = FALSE;
     188                 :             :     static int places;
     189                 :             :     struct lconv *lc;
     190                 :             : 
     191                 :           0 :     if (got_it)
     192                 :           0 :         return places;
     193                 :             : 
     194                 :           0 :     lc = gnc_localeconv();
     195                 :           0 :     places = lc->frac_digits;
     196                 :             : 
     197                 :             :     /* frac_digits is already initialized by gnc_localeconv, hopefully
     198                 :             :      * to a reasonable default. */
     199                 :           0 :     got_it = TRUE;
     200                 :             : 
     201                 :           0 :     return places;
     202                 :             : }
     203                 :             : 
     204                 :        2853 : gchar *gnc_locale_name (void)
     205                 :             : {
     206                 :             : # ifdef G_OS_WIN32
     207                 :             :     return g_win32_getlocale();
     208                 :             : # else /* !G_OS_WIN32 */
     209                 :        5706 :     return g_strdup (setlocale(LC_MONETARY, NULL));
     210                 :             : # endif /* G_OS_WIN32 */
     211                 :             : 
     212                 :             : }
        

Generated by: LCOV version 2.0-1