bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

strfmon in the C locale


From: Bruno Haible
Subject: strfmon in the C locale
Date: Sat, 23 Sep 2017 10:50:07 +0200
User-agent: KMail/5.1.3 (Linux/4.4.0-93-generic; KDE/5.18.0; x86_64; ; )

Test program:
=======================================================================
#include <locale.h>
#include <monetary.h>
#include <stdio.h>
int main ()
{
  char buf[80];
  printf ("currency = |%s|\n", localeconv()->currency_symbol);
  printf ("positive sign = |%s|\n", localeconv()->positive_sign);
  printf ("negative sign = |%s|\n", localeconv()->negative_sign);

  strfmon (buf, sizeof (buf), "%^#5.0n", 123.4);
  printf ("strfmon result for positive value = |%s|\n", buf);

  strfmon (buf, sizeof (buf), "%^#5.0n", -123.4);
  printf ("strfmon result for negative value = |%s|\n", buf);
}
=======================================================================

Results
=======

Result on glibc 2.23:
currency = ||
positive sign = ||
negative sign = ||
strfmon result for positive value = |   123|
strfmon result for negative value = |-  123|

Result on Solaris 10:
currency = ||
positive sign = ||
negative sign = ||
strfmon result for positive value = |  123|
strfmon result for negative value = |-  123|

Result on Mac OS X 10.12:
currency = ||
positive sign = ||
negative sign = ||
strfmon result for positive value = |   123 |
strfmon result for negative value = |(  123)|


Discussion
==========

The POSIX spec is at [1].

I don't think the Mac OS X 10.12 result is correct because the test
program does not specify the '+' nor '(' flag, and POSIX says

  If '+' is specified, the locale's equivalent of '+' and '-' are
  used (for example, in many locales, the empty string if positive and '-'
  if negative). If '(' is specified, negative amounts are enclosed within
  parentheses. If neither flag is specified, the '+' style is used.

I don't think the glibc and Solaris results are correct because they
show a '-' sign, although localeconv()->negative_sign is the empty
string (which is mandated by POSIX [2]).

The Solaris result is worse than the glibc one, because it produces
a different number of characters in the negative and in the positive
case, which is against what POSIX says for the '#' flag:

  To ensure alignment, any characters appearing before or after the
  number in the formatted output such as currency or sign symbols are
  padded as necessary with <space> characters to make their positive
  and negative formats an equal length.


The result I would have expected is therefore:
currency = ||
positive sign = ||
negative sign = ||
strfmon result for positive value = |  123|
strfmon result for negative value = |  123|


Conclusion
==========

strfmon in the C locale is unusable. strfmon in territory locales is
probably not much better.

I won't spend time to add workarounds for it, because

  * C is a system programming language, while strfmon is for
    applications. Applications nowadays are not being written in C
    any more (except in GNOME).

  * Especially applications that deal with money. Given the amount
    of programming mistakes one can do in C and the amount of
    security vulnerabilities that C programs have on average
    (compared to other programming languages), who would want to
    to write monetary applications in C?

Bruno

[1] http://pubs.opengroup.org/onlinepubs/9699919799/functions/strfmon.html
[2] 
http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap07.html#tag_07_03_03_01




reply via email to

[Prev in Thread] Current Thread [Next in Thread]