[PATCH 1/2] localedef: Update LC_MONETARY handling (Bug 28845)

DJ Delorie dj@redhat.com
Tue Feb 8 03:46:24 GMT 2022


"Carlos O'Donell via Libc-alpha" <libc-alpha@sourceware.org> writes:
> diff --git a/locale/programs/ld-monetary.c b/locale/programs/ld-monetary.c

> +  /* Generally speaking there are 3 standards the define the default,
> +     warning, and error behaviour of LC_MONETARY.  They are ISO/IEC TR 30112,

spelling: behaviour -> behavior (4 occurrences)

(assuming we're standardizing on American English spellings)

> +	negative_sign		"<U002E>" i.e. "."

I almost said "should be -" but the standard actually says this.
Amusing, since n_sign_posn isn't required.

> +    Like with 30112, POSIX also considers no error if the keywords are
> +    missing, only that if the cateory as a whole is missing the referencing

spelling: cateory -> category (2 occurrences)

> +    In ISO C17 for the "C" locale all values are empty strings "", or
> +    CHAR_MAX, with the exception of decimal_point which is "." (defined
> +    in LC_NUMERIC).

The code actually uses a string with *contains* a CHAR_MAX char, which
confused me.  If this is allowed, this should be documented.  Example:

>        monetary->mon_grouping = (char *) "\177";

> +    Lastly, we must consider the legacy C/POSIX locale that implemented
> +    as a builtin in glibc and wether a default value mapping to the

spelling: wether -> whether

> -	record_error (0, 0, _("%s: field `%s' not defined"),		      \
> -		      "LC_MONETARY", #cat);				      \
> +	record_warning (_("%s: field `%s' not defined"),		      \
> +			"LC_MONETARY", #cat);				      \

Ok.

> +  /* Keyword: int_curr_symbol.  */
>    TEST_ELEM (int_curr_symbol, "");
> -  TEST_ELEM (currency_symbol, "");
> -  TEST_ELEM (mon_thousands_sep, "");
> -  TEST_ELEM (positive_sign, "");
> -  TEST_ELEM (negative_sign, "");
> -

Ok.

>    /* The international currency symbol must come from ISO 4217.  */
>    if (monetary->int_curr_symbol != NULL)
>      {
> @@ -247,41 +325,59 @@ not correspond to a valid name in ISO 4217 [--no-warnings=intcurrsym]"),
>  	}
>      }
>  
> -  /* The decimal point must not be empty.  This is not said explicitly
> -     in POSIX but ANSI C (ISO/IEC 9899) says in 4.4.2.1 it has to be
> -     != "".  */

Ok.

> +  /* Keyword: currency_symbol */
> +  TEST_ELEM (currency_symbol, "");

Ok.

> +  /* Keyword: mon_decimal_point */
> +  /* ISO C17 7.11.2.1.3 explicitly allows mon_decimal_point to be the
> +     empty string e.g. "".  This indicates the value is not available in the
> +     current locale or is of zero length.  However, if the value was never
> +     defined then we issue a warning and use a glibc-specific default.  ISO
> +     30112 in the i18n FDCC-Set uses <U002C> ",", and POSIX Issue 7 in the
> +     POSIX locale uses "".  It is specific to glibc that the default is <U002E>
> +     "."; we retain this existing behaviour for backwards compatibility.  */
>    if (monetary->mon_decimal_point == NULL)
>      {
>        if (! nothing)
> -	record_error (0, 0, _("%s: field `%s' not defined"),
> -		      "LC_MONETARY", "mon_decimal_point");
> +	record_warning (_("%s: field `%s' not defined, using defaults"),
> +			"LC_MONETARY", "mon_decimal_point");

Ok.

>        monetary->mon_decimal_point = ".";
>        monetary->mon_decimal_point_wc = L'.';
>      }
> -  else if (monetary->mon_decimal_point[0] == '\0' && ! be_quiet && ! nothing)

Ok.

> +
> +  /* Keyword: mon_thousands_sep */
> +  if (monetary->mon_thousands_sep == NULL)
>      {
> -      record_error (0, 0, _("\
> -%s: value for field `%s' must not be an empty string"),
> -		    "LC_MONETARY", "mon_decimal_point");
> +      if (! nothing)
> +	record_warning (_("%s: field `%s' not defined, using defaults"),
> +			"LC_MONETARY", "mon_thousands_sep");
> +      monetary->mon_thousands_sep = "";
> +      monetary->mon_thousands_sep_wc = L'\0';
>      }

Ok.

> +  /* Keyword: mon_grouping */
>    if (monetary->mon_grouping_len == 0)
>      {
>        if (! nothing)
> -	record_error (0, 0, _("%s: field `%s' not defined"),
> -		      "LC_MONETARY", "mon_grouping");
> -
> +	record_warning (_("%s: field `%s' not defined"),
> +			"LC_MONETARY", "mon_grouping");

Ok.

> +  /* Keyword: positive_sign */
> +  TEST_ELEM (positive_sign, "");
> +
> +  /* Keyword: negative_sign */
> +  TEST_ELEM (negative_sign, "");
> +

Ok.

>  #undef TEST_ELEM
>  #define TEST_ELEM(cat, min, max, initval) \
>    if (monetary->cat == -2)						      \
>      {									      \
>         if (! nothing)							      \
> -	 record_error (0, 0, _("%s: field `%s' not defined"),		      \
> -		       "LC_MONETARY", #cat);				      \
> +	 record_warning (_("%s: field `%s' not defined"),		      \
> +			 "LC_MONETARY", #cat);				      \

Ok.

> @@ -300,16 +396,11 @@ not correspond to a valid name in ISO 4217 [--no-warnings=intcurrsym]"),
>    TEST_ELEM (p_sign_posn, -1, 4, -1);
>    TEST_ELEM (n_sign_posn, -1, 4, -1);
>  
> -  /* The non-POSIX.2 extensions are optional.  */
> -  if (monetary->duo_int_curr_symbol == NULL)
> -    monetary->duo_int_curr_symbol = monetary->int_curr_symbol;
> -  if (monetary->duo_currency_symbol == NULL)
> -    monetary->duo_currency_symbol = monetary->currency_symbol;
> -
> -  if (monetary->duo_int_frac_digits == -2)
> -    monetary->duo_int_frac_digits = monetary->int_frac_digits;
> -  if (monetary->duo_frac_digits == -2)
> -    monetary->duo_frac_digits = monetary->frac_digits;

Ok.

> +  /* Keyword: crncystr */
> +  monetary->crncystr = (char *) xmalloc (strlen (monetary->currency_symbol)
> +					 + 2);
> +  monetary->crncystr[0] = monetary->p_cs_precedes ? '-' : '+';
> +  strcpy (&monetary->crncystr[1], monetary->currency_symbol);

Ok.

> +  /* The non-POSIX.2 extensions are optional.  */
> +  if (monetary->duo_int_curr_symbol == NULL)
> +    monetary->duo_int_curr_symbol = monetary->int_curr_symbol;
> +  if (monetary->duo_currency_symbol == NULL)
> +    monetary->duo_currency_symbol = monetary->currency_symbol;
> +
> +  if (monetary->duo_int_frac_digits == -2)
> +    monetary->duo_int_frac_digits = monetary->int_frac_digits;
> +  if (monetary->duo_frac_digits == -2)
> +    monetary->duo_frac_digits = monetary->frac_digits;

Ok.

> @@ -349,17 +451,15 @@ not correspond to a valid name in ISO 4217 [--no-warnings=intcurrsym]"),
>    if (monetary->duo_valid_to == 0)
>      monetary->duo_valid_to = 99991231;
>  
> +  /* Keyword: conversion_rate */
>    if (monetary->conversion_rate[0] == 0)
>      {
>        monetary->conversion_rate[0] = 1;
>        monetary->conversion_rate[1] = 1;
>      }
>  
> -  /* Create the crncystr entry.  */
> -  monetary->crncystr = (char *) xmalloc (strlen (monetary->currency_symbol)
> -					 + 2);
> -  monetary->crncystr[0] = monetary->p_cs_precedes ? '-' : '+';
> -  strcpy (&monetary->crncystr[1], monetary->currency_symbol);
> +  /* A value for monetary-decimal-point-wc was set when
> +     monetary_decimal_point was set, likewise for monetary-thousands-sep-wc.  */
>  }

Ok.



More information about the Libc-alpha mailing list