This is the mail archive of the
libc-alpha@sources.redhat.com
mailing list for the glibc project.
Re: LC_MONETARY:int_p_sep_by_space is ignored
[Petter Reinholdtsen]
> But this do not work, as the int_n_sep_by_space is ignored.
> Checking the code in stdlib/strfmon.c confirms this. Do you agree
> with my findings? I'll try to make some patches to fix it.
This is my current patch. Not sure if I am comfortable with it yet,
but send it here to get comments. This solves the problems with
formatting the international currency symbol. It doesn't solve the
left justify problem.
Index: stdlib/strfmon.c
===================================================================
RCS file: /cvs/glibc/libc/stdlib/strfmon.c,v
retrieving revision 1.23
diff -u -3 -p -u -r1.23 strfmon.c
--- stdlib/strfmon.c 3 Aug 2002 06:29:57 -0000 1.23
+++ stdlib/strfmon.c 26 Jun 2003 08:28:48 -0000
@@ -82,6 +82,17 @@ libc_hidden_proto (__printf_fp)
extern unsigned int __guess_grouping (unsigned int intdig_max,
const char *grouping, wchar_t sepchar);
+/* Use the value for international currency formatting when formatting
+ international currency if it is set, otherwise fall back to the
+ normal formatting */
+#define GET_VALUE(value, category, int_format, item, int_item) \
+do { \
+ value = CHAR_MAX; \
+ if (int_format) \
+ value = *_NL_CURRENT (category, int_item); \
+ if (value == CHAR_MAX) \
+ value = *_NL_CURRENT (category, item); \
+} while (0)
/* We have to overcome some problems with this implementation. On the
one hand the strfmon() function is specified in XPG4 and of course
@@ -128,6 +139,7 @@ __strfmon_l (char *s, size_t maxsize, __
__long_double_t ldbl;
}
fpnum;
+ int int_format;
int print_curr_symbol;
int left_prec;
int left_pad;
@@ -172,6 +184,7 @@ __strfmon_l (char *s, size_t maxsize, __
}
/* Defaults for formatting. */
+ int_format = 0; /* Use international curr. symbol */
print_curr_symbol = 1; /* Print the currency symbol. */
left_prec = -1; /* No left precision specified. */
right_prec = -1; /* No right precision specified. */
@@ -233,13 +246,6 @@ __strfmon_l (char *s, size_t maxsize, __
break;
}
- /* If not specified by the format string now find the values for
- the format specification. */
- if (p_sign_posn == -1)
- p_sign_posn = *_NL_CURRENT (LC_MONETARY, P_SIGN_POSN);
- if (n_sign_posn == -1)
- n_sign_posn = *_NL_CURRENT (LC_MONETARY, N_SIGN_POSN);
-
if (isdigit (*fmt))
{
/* Parse field width. */
@@ -307,29 +313,25 @@ __strfmon_l (char *s, size_t maxsize, __
/* Handle format specifier. */
switch (*fmt++)
{
- case 'i': /* Use international currency symbol. */
- currency_symbol = _NL_CURRENT (LC_MONETARY, INT_CURR_SYMBOL);
+ case 'i': { /* Use international currency symbol. */
+ const char *int_curr_symbol;
+ static char symbol[4];
+
+ int_curr_symbol = _NL_CURRENT (LC_MONETARY, INT_CURR_SYMBOL);
+ strncpy(symbol, int_curr_symbol, 3);
+ symbol[3] = '\0';
+
currency_symbol_len = 3;
- space_char = currency_symbol[3];
- if (right_prec == -1)
- {
- if (*_NL_CURRENT (LC_MONETARY, INT_FRAC_DIGITS) == CHAR_MAX)
- right_prec = 2;
- else
- right_prec = *_NL_CURRENT (LC_MONETARY, INT_FRAC_DIGITS);
- }
+ currency_symbol = &symbol[0];
+ space_char = int_curr_symbol[3];
+ int_format = 1;
break;
+ }
case 'n': /* Use national currency symbol. */
currency_symbol = _NL_CURRENT (LC_MONETARY, CURRENCY_SYMBOL);
currency_symbol_len = strlen (currency_symbol);
space_char = ' ';
- if (right_prec == -1)
- {
- if (*_NL_CURRENT (LC_MONETARY, FRAC_DIGITS) == CHAR_MAX)
- right_prec = 2;
- else
- right_prec = *_NL_CURRENT (LC_MONETARY, FRAC_DIGITS);
- }
+ int_format = 0;
break;
default: /* Any unrecognized format is an error. */
__set_errno (EINVAL);
@@ -337,6 +339,23 @@ __strfmon_l (char *s, size_t maxsize, __
return -1;
}
+ /* If not specified by the format string now find the values for
+ the format specification. */
+ if (p_sign_posn == -1)
+ GET_VALUE (p_sign_posn, LC_MONETARY, int_format,
+ P_SIGN_POSN, INT_P_SIGN_POSN);
+ if (n_sign_posn == -1)
+ GET_VALUE (n_sign_posn, LC_MONETARY, int_format,
+ N_SIGN_POSN, INT_N_SIGN_POSN);
+
+ if (right_prec == -1)
+ {
+ GET_VALUE (right_prec, LC_MONETARY, int_format,
+ FRAC_DIGITS, INT_FRAC_DIGITS);
+ if (right_prec == CHAR_MAX)
+ right_prec = 2;
+ }
+
/* If we have to print the digits grouped determine how many
extra characters this means. */
if (group && left_prec != -1)
@@ -369,27 +388,35 @@ __strfmon_l (char *s, size_t maxsize, __
negative sign we use a '-'. */
if (*sign_string == '\0')
sign_string = (const char *) "-";
- cs_precedes = *_NL_CURRENT (LC_MONETARY, N_CS_PRECEDES);
- sep_by_space = *_NL_CURRENT (LC_MONETARY, N_SEP_BY_SPACE);
+ GET_VALUE (cs_precedes, LC_MONETARY, int_format,
+ N_CS_PRECEDES, INT_N_CS_PRECEDES);
+ GET_VALUE (sep_by_space, LC_MONETARY, int_format,
+ N_SEP_BY_SPACE, INT_N_SEP_BY_SPACE);
sign_posn = n_sign_posn;
other_sign_string = _NL_CURRENT (LC_MONETARY, POSITIVE_SIGN);
- other_cs_precedes = *_NL_CURRENT (LC_MONETARY, P_CS_PRECEDES);
- other_sep_by_space = *_NL_CURRENT (LC_MONETARY, P_SEP_BY_SPACE);
+ GET_VALUE (other_cs_precedes, LC_MONETARY, int_format,
+ P_CS_PRECEDES, INT_P_CS_PRECEDES);
+ GET_VALUE (other_sep_by_space, LC_MONETARY, int_format,
+ P_SEP_BY_SPACE, INT_P_SEP_BY_SPACE);
other_sign_posn = p_sign_posn;
}
else
{
sign_string = _NL_CURRENT (LC_MONETARY, POSITIVE_SIGN);
- cs_precedes = *_NL_CURRENT (LC_MONETARY, P_CS_PRECEDES);
- sep_by_space = *_NL_CURRENT (LC_MONETARY, P_SEP_BY_SPACE);
+ GET_VALUE (cs_precedes, LC_MONETARY, int_format,
+ P_CS_PRECEDES, INT_P_CS_PRECEDES);
+ GET_VALUE (sep_by_space, LC_MONETARY, int_format,
+ P_SEP_BY_SPACE, INT_P_SEP_BY_SPACE);
sign_posn = p_sign_posn;
other_sign_string = _NL_CURRENT (LC_MONETARY, NEGATIVE_SIGN);
if (*other_sign_string == '\0')
other_sign_string = (const char *) "-";
- other_cs_precedes = *_NL_CURRENT (LC_MONETARY, N_CS_PRECEDES);
- other_sep_by_space = *_NL_CURRENT (LC_MONETARY, N_SEP_BY_SPACE);
+ GET_VALUE (other_cs_precedes, LC_MONETARY, int_format,
+ N_CS_PRECEDES, INT_N_CS_PRECEDES);
+ GET_VALUE (other_sep_by_space, LC_MONETARY, int_format,
+ N_SEP_BY_SPACE, INT_N_SEP_BY_SPACE);
other_sign_posn = n_sign_posn;
}