NetBSD-Bugs archive

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

standards/52282: printf(3) does not correctly interpret C/POSIX locale for %'d, %'f



>Number:         52282
>Category:       standards
>Synopsis:       printf(3) does not correctly interpret C/POSIX locale for %'d, %'f
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    standards-manager
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed Jun 07 22:50:00 +0000 2017
>Originator:     Konrad Schroder
>Release:        NetBSD-current 20170606
>Organization:
Happy Hopeless Hacker House
>Environment:
System: NetBSD mollari.NetBSD.org 7.1_RC2 NetBSD 7.1_RC2 (amd64-DOMU_SERVER) #2:
 Sun Mar 5 17:25:39 UTC 2017 spz%franklin.NetBSD.org@localhost:/home/netbsd/7/amd64/obj/sy
s/arch/amd64/compile/amd64-DOMU_SERVER amd64
Architecture: x86_64
Machine: amd64
>Description:
        IEEE Std 1003.1-2008 7.3.4 defines the POSIX locale to have
	an empty thousands separator and no grouping, but vfwprintf
	interprets this to mean "," and group by three.
        thousands separator as "", with no grouping, but printf(3) 
        interprets this to mean "," and groupings of three.
>How-To-Repeat:
#include <stdio.h>
#include <locale.h>
        setlocale(LC_NUMERIC, "POSIX");
        printf("%'f\n", 1234567.89);
}

The expected output is "1234567.890000" but the actual output is "1,234,567.890000".
>Fix:

Index: lib/libc/stdio/vfwprintf.c
===================================================================
RCS file: /cvsroot/src/lib/libc/stdio/vfwprintf.c,v
retrieving revision 1.34
diff -u -r1.34 vfwprintf.c
--- lib/libc/stdio/vfwprintf.c	20 Jan 2014 14:11:03 -0000	1.34
+++ lib/libc/stdio/vfwprintf.c	7 Jun 2017 22:38:51 -0000
@@ -923,15 +923,15 @@
 			sign = '+';
 			goto rflag;
 		case '\'':
-			flags |= GROUPING;
 			thousands_sep = *(localeconv_l(loc)->thousands_sep);
 			grouping = localeconv_l(loc)->grouping;
-			/* If the locale doesn't define the above, use sane
-			 * defaults - otherwise silly things happen! */
-			if (thousands_sep == 0)
-				thousands_sep = ',';
-			if (!grouping || !*grouping)
-				grouping = "\3";
+			/* Use grouping if defined by locale */
+			if (thousands_sep && grouping && *grouping)
+				flags |= GROUPING;
+			else {
+				thousands_sep = '\0';
+				grouping = "";
+			}
 			goto rflag;
 		case '.':
 			if ((ch = *fmt++) == '*') {



Home | Main Index | Thread Index | Old Index