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]

Incorrect strfmon() formatting in glibc or standard example?


I'm working on correcting the strfmon() formatting in glibc, and ran
into one case where the example formatting given in The Open Group
Base Specifications Issue 6 do not make sense.  The glibc
implementation do not give the same output as given in the example,
and I am starting to believe that it is the glibc behaviour that make
most sense.

Here are some example code to demonstrate the problem, that using
parenthesis to indicate negative numbers fail to align the values
properly.

Do you agree that glibc make most sense, and that the standard example
should be changed?


/*
 * Bug in strfmon() example in The Open Group standard?
 *
 * I base this on the examples given at the bottom of
 * <URL:http://www.opengroup.org/onlinepubs/007904975/functions/strfmon.html>
 *
 * When formatting numbers using "%#5n" as the format string, both
 * positive and negative numbers are aligned with each other, but when
 * formatting using "%(#5n" they are not.
 *
 * These are the examples:
 *
 *   %#5n       [ $   123.45]     Aligned columns for values up to 99999
 *              [-$   123.45]
 *              [ $ 3,456.78]
 *
 *   %(#5n      [$   123.45]      Use an alternative pos/neg style
 *              [($   123.45)]
 *              [$ 3,456.78]
 *
 * I do not think this make sense, and believe that both formattings
 * should give aligned positive and negative numbers.  The example
 * should look like this:
 *
 *   %(#5n      [ $   123.45]      Use an alternative pos/neg style
 *              [($   123.45)]
 *              [ $ 3,456.78]
 *
 * This program make it possible to test the implementation.  I use
 * locale C instead of en_US to get a well defined locale instead of a
 * locale which might differ from platform to platform.  The only
 * difference should be the currency symbol.
 */
#include <stdio.h>
#include <monetary.h>
#include <locale.h>

int main()
{
  char *locale = "C";
  char buf[200];
  int i;

  struct {
    char *format;
    double value;
    char *expected;
  } tests[] =
    {
      /* These are the current GNU libc behaviour */
      { "%(#9n",  1234.56, "      1234.56"  },
      { "%(#9n", -1234.56, "(     1234.56)" },
      { "%#9n",   1234.56, "      1234.56"  },
      { "%#9n",  -1234.56, "-     1234.56"  },

      /* These should match the POSIX / Open Group standard */
      { "%(#5n",   123.45, "  123.45"       },/* incorrect in glibc */
      { "%(#5n",  -123.45, "(  123.45)"     },
      { "%(#5n",  3456.78, " 3456.78"       },/* incorrect in glibc */

      { "%#5n",    123.45, "   123.45"      },
      { "%#5n",   -123.45, "-  123.45"      },
    };

  if (NULL == setlocale (LC_MONETARY, "C"))
    {
      fprintf (stderr, "setlocale(LC_MONETARY, \"%s\")\n", locale);
      exit (1);
    }

  for (i = 0; i < (sizeof(tests) / sizeof(tests[0])); ++i)
    {
      if (strfmon (buf, sizeof(buf)-1, tests[i].format, tests[i].value) == -1)
	{
	  perror ("strfmon");
	  exit (2);
	}
      printf("\"%s\" \"%s\" %f ", buf, tests[i].format, tests[i].value);
      if (0 != strcmp(buf, tests[i].expected))
	  printf(" not as expected: \"%s\"", tests[i].expected);
      printf("\n");
    }
}


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