This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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;
 	}
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]