[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