Email List: Xaustin-review-lX
[All Lists]

Defect in XSH strfmon example

To: yyyyyyyyyyyyyyy@xxxxxxxxxxxxx
Subject: Defect in XSH strfmon example
From: Petter Reinholdtsen <yyyy@xxxxxxxxxx>
Date: Thu, 01 Jan 2004 18:17:29 +0100
  Defect report from : Petter Reinholdtsen, The Hungry Programmers

(Please direct followup comments direct to yyyyyyyyyyyyyy@xxxxxxxxxxxxx)

@ http://www.opengroup.org/onlinepubs/007904975/functions/strfmon.html section 
example objection

Problem:

  The strfmon() example for "%(#5n" and "%!(#5n" do not align positive
  and negative values.  This is in contrast to the example for "%#5n",
  which do align the values.  I believe the most sensible behaviour of
  strfmon() is to align both formats, and that the example should be
  changed.  I guess the standard text should be changed to document
  the correct format for these as well, but do not have any
  suggestions on how to change it.  These are the current 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]

    %!(#5n     [   123.45]       Disable the currency symbol
               [(   123.45)]
               [ 3,456.78]

  The current example with the alterntive pos/neg style do not match
  the current GNU libc output at the moment.  This is the reason I
  discovered this problem in the first place.  This is some example
  code to check the formatting on different platforms:
    
    /*
     * 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 are the POSIX / Open Group examples */
          { "%(#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");
        }
    }

Action:

  Change the examples using alternative pos/neg style to align the
  positive and the negative output strings like this, adding a leading
  space for positive values:

    %(#5n      [ $   123.45]      Use an alternative pos/neg style
               [($   123.45)]
               [ $ 3,456.78]

    %!(#5n     [    123.45]       Disable the currency symbol
               [(   123.45)]
               [  3,456.78]

  This would make the output consistent with the other format strings
  using a fixed presicion, and also align output containing positive
  and negative values.  The GNU libc implementation is already using
  this format.

<Prev in Thread] Current Thread [Next in Thread>
  • Defect in XSH strfmon example, Petter Reinholdtsen <=