Module Name:    src
Committed By:   joerg
Date:           Wed Aug 16 13:53:20 UTC 2017

Modified Files:
        src/distrib/sets/lists/debug: mi
        src/distrib/sets/lists/tests: mi
        src/include: monetary.h
        src/lib/libc/stdlib: strfmon.3 strfmon.c
        src/tests/lib/libc/locale: Makefile
Added Files:
        src/tests/lib/libc/locale: t_strfmon.c

Log Message:
Add missing strfmon_l. Noticed by Bruno Haible. Add test case.


To generate a diff of this commit:
cvs rdiff -u -r1.223 -r1.224 src/distrib/sets/lists/debug/mi
cvs rdiff -u -r1.760 -r1.761 src/distrib/sets/lists/tests/mi
cvs rdiff -u -r1.2 -r1.3 src/include/monetary.h
cvs rdiff -u -r1.5 -r1.6 src/lib/libc/stdlib/strfmon.3
cvs rdiff -u -r1.10 -r1.11 src/lib/libc/stdlib/strfmon.c
cvs rdiff -u -r1.11 -r1.12 src/tests/lib/libc/locale/Makefile
cvs rdiff -u -r0 -r1.1 src/tests/lib/libc/locale/t_strfmon.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/distrib/sets/lists/debug/mi
diff -u src/distrib/sets/lists/debug/mi:1.223 src/distrib/sets/lists/debug/mi:1.224
--- src/distrib/sets/lists/debug/mi:1.223	Fri Aug 11 20:47:58 2017
+++ src/distrib/sets/lists/debug/mi	Wed Aug 16 13:53:19 2017
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.223 2017/08/11 20:47:58 ryo Exp $
+# $NetBSD: mi,v 1.224 2017/08/16 13:53:19 joerg Exp $
 ./etc/mtree/set.debug                           comp-sys-root
 ./usr/lib					comp-sys-usr		compatdir
 ./usr/lib/i18n/libBIG5_g.a			comp-c-debuglib		debuglib,compatfile
@@ -1954,6 +1954,7 @@
 ./usr/libdata/debug/usr/tests/lib/libc/locale/t_mbstowcs.debug		tests-lib-debug		debug,atf,compattestfile
 ./usr/libdata/debug/usr/tests/lib/libc/locale/t_mbtowc.debug		tests-lib-debug		debug,atf,compattestfile
 ./usr/libdata/debug/usr/tests/lib/libc/locale/t_sprintf.debug		tests-lib-debug		debug,atf,compattestfile
+./usr/libdata/debug/usr/tests/lib/libc/locale/t_strfmon.debug		tests-lib-debug		debug,atf,compattestfile
 ./usr/libdata/debug/usr/tests/lib/libc/locale/t_toupper.debug		tests-lib-debug		debug,atf,compattestfile
 ./usr/libdata/debug/usr/tests/lib/libc/locale/t_wcscoll.debug		tests-lib-debug		debug,atf,compattestfile
 ./usr/libdata/debug/usr/tests/lib/libc/locale/t_wcscspn.debug		tests-lib-debug		debug,atf,compattestfile

Index: src/distrib/sets/lists/tests/mi
diff -u src/distrib/sets/lists/tests/mi:1.760 src/distrib/sets/lists/tests/mi:1.761
--- src/distrib/sets/lists/tests/mi:1.760	Thu Aug 10 04:31:58 2017
+++ src/distrib/sets/lists/tests/mi	Wed Aug 16 13:53:20 2017
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.760 2017/08/10 04:31:58 ryo Exp $
+# $NetBSD: mi,v 1.761 2017/08/16 13:53:20 joerg Exp $
 #
 # Note: don't delete entries from here - mark them as "obsolete" instead.
 #
@@ -2551,6 +2551,7 @@
 ./usr/tests/lib/libc/locale/t_mbstowcs		tests-lib-tests		compattestfile,atf
 ./usr/tests/lib/libc/locale/t_mbtowc		tests-lib-tests		compattestfile,atf
 ./usr/tests/lib/libc/locale/t_sprintf		tests-lib-tests		compattestfile,atf
+./usr/tests/lib/libc/locale/t_strfmon		tests-lib-tests		compattestfile,atf
 ./usr/tests/lib/libc/locale/t_toupper		tests-lib-tests		compattestfile,atf
 ./usr/tests/lib/libc/locale/t_wcscoll		tests-lib-tests		compattestfile,atf
 ./usr/tests/lib/libc/locale/t_wcscspn		tests-lib-tests		compattestfile,atf

Index: src/include/monetary.h
diff -u src/include/monetary.h:1.2 src/include/monetary.h:1.3
--- src/include/monetary.h:1.2	Sun Sep 21 16:59:46 2008
+++ src/include/monetary.h	Wed Aug 16 13:53:20 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: monetary.h,v 1.2 2008/09/21 16:59:46 christos Exp $	*/
+/*	$NetBSD: monetary.h,v 1.3 2017/08/16 13:53:20 joerg Exp $	*/
 
 /*-
  * Copyright (c) 2001 Alexey Zelkin <phan...@freebsd.org>
@@ -44,6 +44,16 @@ typedef	_BSD_SSIZE_T_	ssize_t;
 #undef	_BSD_SSIZE_T_
 #endif
 
+#if defined(_NETBSD_SOURCE)
+#  ifndef __LOCALE_T_DECLARED
+typedef struct _locale		*locale_t;
+#  define __LOCALE_T_DECLARED
+#  endif
+__BEGIN_DECLS
+ssize_t	strfmon_l(char * __restrict, size_t, locale_t, const char * __restrict, ...)
+    __attribute__((__format__(__strfmon__, 4, 5)));
+#endif
+
 __BEGIN_DECLS
 ssize_t	strfmon(char * __restrict, size_t, const char * __restrict, ...)
     __attribute__((__format__(__strfmon__, 3, 4)));

Index: src/lib/libc/stdlib/strfmon.3
diff -u src/lib/libc/stdlib/strfmon.3:1.5 src/lib/libc/stdlib/strfmon.3:1.6
--- src/lib/libc/stdlib/strfmon.3:1.5	Tue Mar 18 18:20:37 2014
+++ src/lib/libc/stdlib/strfmon.3	Wed Aug 16 13:53:20 2017
@@ -1,4 +1,4 @@
-.\"	$NetBSD: strfmon.3,v 1.5 2014/03/18 18:20:37 riastradh Exp $
+.\"	$NetBSD: strfmon.3,v 1.6 2017/08/16 13:53:20 joerg Exp $
 .\"
 .\" Copyright (c) 2001 Jeroen Ruigrok van der Werven <asmo...@freebsd.org>
 .\" All rights reserved.
@@ -26,7 +26,7 @@
 .\"
 .\" 	From: FreeBSD: Id: strfmon.3,v 1.7 2003/01/06 06:21:25 tjr Exp
 .\"
-.Dd October 12, 2002
+.Dd August 15, 2017
 .Dt STRFMON 3
 .Os
 .Sh NAME
@@ -38,6 +38,8 @@
 .In monetary.h
 .Ft ssize_t
 .Fn strfmon "char * restrict s" "size_t maxsize" "const char * restrict format" "..."
+.Ft ssize_t
+.Fn strfmon_l "char * restrict s" "size_t maxsize" "locale_t loc" "const char * restrict format" "..."
 .Sh DESCRIPTION
 The
 .Fn strfmon
@@ -49,6 +51,14 @@ No more than
 .Fa maxsize
 bytes are placed into the array.
 .Pp
+The
+.Fn strfmon_l
+function behaves the same as
+.fn strfmon ,
+but uses the locale
+.Fa loc 
+instead of the process global locale.
+.Pp
 The format string is composed of zero or more directives:
 ordinary characters (not
 .Cm % ) ,

Index: src/lib/libc/stdlib/strfmon.c
diff -u src/lib/libc/stdlib/strfmon.c:1.10 src/lib/libc/stdlib/strfmon.c:1.11
--- src/lib/libc/stdlib/strfmon.c:1.10	Wed Mar 21 14:19:15 2012
+++ src/lib/libc/stdlib/strfmon.c	Wed Aug 16 13:53:20 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: strfmon.c,v 1.10 2012/03/21 14:19:15 christos Exp $	*/
+/*	$NetBSD: strfmon.c,v 1.11 2017/08/16 13:53:20 joerg Exp $	*/
 
 /*-
  * Copyright (c) 2001 Alexey Zelkin <phan...@freebsd.org>
@@ -32,14 +32,11 @@
 #if 0
 __FBSDID("$FreeBSD: src/lib/libc/stdlib/strfmon.c,v 1.14 2003/03/20 08:18:55 ache Exp $");
 #else
-__RCSID("$NetBSD: strfmon.c,v 1.10 2012/03/21 14:19:15 christos Exp $");
+__RCSID("$NetBSD: strfmon.c,v 1.11 2017/08/16 13:53:20 joerg Exp $");
 #endif
 #endif /* LIBC_SCCS and not lint */
 
-#if defined(__NetBSD__)
 #include "namespace.h"
-#include <monetary.h>
-#endif
 
 #include <sys/types.h>
 #include <assert.h>
@@ -47,11 +44,14 @@ __RCSID("$NetBSD: strfmon.c,v 1.10 2012/
 #include <errno.h>
 #include <limits.h>
 #include <locale.h>
+#include <monetary.h>
 #include <stdarg.h>
+#include <stddef.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <stddef.h>
+
+#include "setlocale_local.h"
 
 /* internal flags */
 #define	NEED_GROUPING		0x01	/* print digits grouped (default) */
@@ -104,15 +104,14 @@ __RCSID("$NetBSD: strfmon.c,v 1.10 2012/
 	groups++;						\
 } while (/* CONSTCOND */ 0)
 
-static void __setup_vars(int, char *, char *, char *, const char **);
-static int __calc_left_pad(int, char *);
-static char *__format_grouped_double(double, int *, int, int, int);
-
-ssize_t
-strfmon(char * __restrict s, size_t maxsize, const char * __restrict format,
-    ...)
+static void __setup_vars(struct lconv *, int, char *, char *, char *, const char **);
+static int __calc_left_pad(struct lconv *, int, char *);
+static char *__format_grouped_double(struct lconv *, double, int *, int, int, int);
+
+static ssize_t
+vstrfmon_l(char * __restrict s, size_t maxsize, locale_t loc,
+    const char * __restrict format, va_list ap)
 {
-	va_list		ap;
 	char 		*dst;		/* output destination pointer */
 	const char 	*fmt;		/* current format poistion pointer */
 	struct lconv 	*lc;		/* pointer to lconv structure */
@@ -136,9 +135,7 @@ strfmon(char * __restrict s, size_t maxs
 	char		*tmpptr;	/* temporary vars */
 	int		sverrno;
 
-        va_start(ap, format);
-
-	lc = localeconv();
+	lc = localeconv_l(loc);
 	dst = s;
 	fmt = format;
 	asciivalue = NULL;
@@ -263,21 +260,21 @@ strfmon(char * __restrict s, size_t maxs
 
 		/* fill left_prec with amount of padding chars */
 		if (left_prec >= 0) {
-			pad_size = __calc_left_pad((flags ^ IS_NEGATIVE),
+			pad_size = __calc_left_pad(lc, (flags ^ IS_NEGATIVE),
 							currency_symbol) -
-				   __calc_left_pad(flags, currency_symbol);
+				   __calc_left_pad(lc, flags, currency_symbol);
 			if (pad_size < 0)
 				pad_size = 0;
 		}
 
-		asciivalue = __format_grouped_double(value, &flags,
+		asciivalue = __format_grouped_double(lc, value, &flags,
 				left_prec, right_prec, pad_char);
 		if (asciivalue == NULL)
 			goto end_error;		/* errno already set     */
 						/* to ENOMEM by malloc() */
 
 		/* set some variables for later use */
-		__setup_vars(flags, &cs_precedes, &sep_by_space,
+		__setup_vars(lc, flags, &cs_precedes, &sep_by_space,
 				&sign_posn, &signstr);
 
 		/*
@@ -392,7 +389,6 @@ strfmon(char * __restrict s, size_t maxs
 	}
 
 	PRINT('\0');
-	va_end(ap);
 	free(asciivalue);
 	free(currency_symbol);
 	return (dst - s - 1);	/* return size of put data except trailing '\0' */
@@ -411,14 +407,12 @@ end_error:
 	if (currency_symbol != NULL)
 		free(currency_symbol);
 	errno = sverrno;
-	va_end(ap);
 	return (-1);
 }
 
 static void
-__setup_vars(int flags, char *cs_precedes, char *sep_by_space,
+__setup_vars(struct lconv *lc, int flags, char *cs_precedes, char *sep_by_space,
 		char *sign_posn, const char **signstr) {
-	struct lconv *lc = localeconv();
 
 	if ((flags & IS_NEGATIVE) && (flags & USE_INTL_CURRENCY)) {
 		*cs_precedes = lc->int_n_cs_precedes;
@@ -454,13 +448,13 @@ __setup_vars(int flags, char *cs_precede
 }
 
 static int
-__calc_left_pad(int flags, char *cur_symb) {
+__calc_left_pad(struct lconv *lc, int flags, char *cur_symb) {
 
 	char cs_precedes, sep_by_space, sign_posn;
 	const char *signstr;
 	size_t left_chars = 0;
 
-	__setup_vars(flags, &cs_precedes, &sep_by_space, &sign_posn, &signstr);
+	__setup_vars(lc, flags, &cs_precedes, &sep_by_space, &sign_posn, &signstr);
 
 	if (cs_precedes != 0) {
 		left_chars += strlen(cur_symb);
@@ -506,7 +500,7 @@ get_groups(int size, char *grouping) {
 
 /* convert double to ASCII */
 static char *
-__format_grouped_double(double value, int *flags,
+__format_grouped_double(struct lconv *lc, double value, int *flags,
 			int left_prec, int right_prec, int pad_char) {
 
 	char		*rslt;
@@ -518,7 +512,6 @@ __format_grouped_double(double value, in
 
 	int		padded;
 
-	struct lconv	*lc = localeconv();
 	char		*grouping;
 	char		decimal_point;
 	char		thousands_sep;
@@ -627,3 +620,31 @@ __format_grouped_double(double value, in
 	free(avalue);
 	return (rslt);
 }
+
+ssize_t
+strfmon(char * __restrict s, size_t maxsize, const char * __restrict format,
+    ...)
+{
+	ssize_t rv;
+	va_list ap;
+
+	va_start(ap, format);
+	rv = vstrfmon_l(s, maxsize, _current_locale(), format, ap);
+	va_end(ap);
+
+	return rv;
+}
+
+ssize_t
+strfmon_l(char * __restrict s, size_t maxsize, locale_t loc,
+    const char * __restrict format, ...)
+{
+	ssize_t rv;
+	va_list ap;
+
+	va_start(ap, format);
+	rv = vstrfmon_l(s, maxsize, loc, format, ap);
+	va_end(ap);
+
+	return rv;
+}

Index: src/tests/lib/libc/locale/Makefile
diff -u src/tests/lib/libc/locale/Makefile:1.11 src/tests/lib/libc/locale/Makefile:1.12
--- src/tests/lib/libc/locale/Makefile:1.11	Sun Jul 23 18:51:21 2017
+++ src/tests/lib/libc/locale/Makefile	Wed Aug 16 13:53:20 2017
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.11 2017/07/23 18:51:21 perseant Exp $
+# $NetBSD: Makefile,v 1.12 2017/08/16 13:53:20 joerg Exp $
 
 .include <bsd.own.mk>
 
@@ -21,6 +21,7 @@ TESTS_C+=	t_wctype
 TESTS_C+=	t_btowc
 TESTS_C+=	t_wcscoll
 TESTS_C+=	t_ducet
+TESTS_C+=	t_strfmon
 
 COPTS.t_wctomb.c += -Wno-stack-protector
 COPTS.t_digittoint.c += -Wno-unused-variable

Added files:

Index: src/tests/lib/libc/locale/t_strfmon.c
diff -u /dev/null src/tests/lib/libc/locale/t_strfmon.c:1.1
--- /dev/null	Wed Aug 16 13:53:20 2017
+++ src/tests/lib/libc/locale/t_strfmon.c	Wed Aug 16 13:53:20 2017
@@ -0,0 +1,76 @@
+/* $NetBSD: t_strfmon.c,v 1.1 2017/08/16 13:53:20 joerg Exp $ */
+
+/*-
+ * Copyright (c) 2017 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Joerg Sonnenberger.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_strfmon.c,v 1.1 2017/08/16 13:53:20 joerg Exp $");
+
+#include <atf-c.h>
+#include <locale.h>
+#include <monetary.h>
+
+ATF_TC(strfmon);
+
+ATF_TC_HEAD(strfmon, tc)
+{
+	atf_tc_set_md_var(tc, "descr",
+		"Checks strfmon_l under diferent locales");
+}
+
+ATF_TC_BODY(strfmon, tc)
+{
+	const struct {
+		const char *locale;
+		const char *expected;
+	} tests[] = {
+	    { "C", "[**1234.57] [**1234.57]" },
+	    { "de_DE.UTF-8", "[ **1234,57 €] [ **1.234,57 EUR ]" },
+	    { "en_GB.UTF-8", "[ £**1234.57] [ GBP **1,234.57]" },
+	};
+	locale_t loc;
+	size_t i;
+	char buf[80];
+	for (i = 0; i < __arraycount(tests); ++i) {
+		loc = newlocale(LC_MONETARY_MASK, tests[i].locale, 0);
+		ATF_REQUIRE(loc != 0);
+		strfmon_l(buf, sizeof(buf), loc, "[%^=*#6n] [%=*#6i]",
+		    1234.567, 1234.567);
+		ATF_REQUIRE_STREQ(tests[i].expected, buf);
+		freelocale(loc);
+	}
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+	ATF_TP_ADD_TC(tp, strfmon);
+
+	return atf_no_error();
+}

Reply via email to