libc: Sync strfmon() with FreeBSD (brings in strfmon_l(), too).
authorSascha Wildner <saw@online.de>
Sun, 17 Nov 2013 23:24:23 +0000 (00:24 +0100)
committerSascha Wildner <saw@online.de>
Sun, 17 Nov 2013 23:24:23 +0000 (00:24 +0100)
lib/libc/stdlib/Makefile.inc
lib/libc/stdlib/strfmon.3
lib/libc/stdlib/strfmon.c

index 47295ba..f6d5a35 100644 (file)
@@ -62,6 +62,7 @@ MLINKS+=radixsort.3 sradixsort.3
 MLINKS+=rand.3 rand_r.3 rand.3 srand.3 rand.3 sranddev.3
 MLINKS+=random.3 initstate.3 random.3 setstate.3 random.3 srandom.3 \
        random.3 srandomdev.3
+MLINKS+=strfmon.3 strfmon_l.3
 MLINKS+=strtod.3 strtof.3 strtod.3 strtold.3
 MLINKS+=strtol.3 strtoimax.3 strtol.3 strtoll.3 strtol.3 strtoq.3
 MLINKS+=strtoul.3 strtoull.3 strtoul.3 strtoumax.3 strtoul.3 strtouq.3
index c87c754..486ebf2 100644 (file)
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD: src/lib/libc/stdlib/strfmon.3,v 1.7 2003/01/06 06:21:25 tjr Exp $
-.\" $NetBSD: strfmon.3,v 1.3 2005/04/04 08:19:00 wiz Exp $
+.\" $FreeBSD: head/lib/libc/stdlib/strfmon.3 237591 2012-06-26 05:34:31Z joel $
 .\"
-.Dd October 6, 2008
+.Dd November 17, 2013
 .Dt STRFMON 3
 .Os
 .Sh NAME
-.Nm strfmon
+.Nm strfmon ,
+.Nm strfmon_l
 .Nd convert monetary value to string
 .Sh LIBRARY
 .Lb libc
@@ -37,6 +37,9 @@
 .In monetary.h
 .Ft ssize_t
 .Fn strfmon "char * restrict s" "size_t maxsize" "const char * restrict format" "..."
+.In xlocale.h
+.Ft ssize_t
+.Fn strfmon_l "char * restrict s" "size_t maxsize" "locale_t loc" "const char * restrict format" "..."
 .Sh DESCRIPTION
 The
 .Fn strfmon
@@ -48,6 +51,12 @@ No more than
 .Fa maxsize
 bytes are placed into the array.
 .Pp
+The
+.Fn strfmon_l
+function does the same as
+.Fn strfmon
+but takes an explicit locale rather than using the current locale.
+.Pp
 The format string is composed of zero or more directives:
 ordinary characters (not
 .Cm % ) ,
@@ -116,20 +125,25 @@ character is written.
 .El
 .Sh RETURN VALUES
 If the total number of resulting bytes including the terminating
-.Dv NULL
+.Dv NUL
 byte is not more than
 .Fa maxsize ,
 .Fn strfmon
 returns the number of bytes placed into the array pointed to by
 .Fa s ,
 not including the terminating
-.Dv NULL
+.Dv NUL
 byte.
 Otherwise, \-1 is returned,
 the contents of the array are indeterminate,
 and
 .Va errno
 is set to indicate the error.
+.Pp
+The
+.Fn strfmon_l
+function returns the same values as
+.Fn strfmon .
 .Sh ERRORS
 The
 .Fn strfmon
@@ -150,6 +164,10 @@ The
 function
 conforms to
 .St -p1003.1-2001 .
+The
+.Fn strfmon_l
+function conforms to
+.St -p1003.1-2008 .
 .Sh AUTHORS
 .An -nosplit
 The
index 1194ba4..cf16924 100644 (file)
@@ -2,6 +2,11 @@
  * Copyright (c) 2001 Alexey Zelkin <phantom@FreeBSD.org>
  * All rights reserved.
  *
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -23,9 +28,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libc/stdlib/strfmon.c,v 1.19 2008/04/24 07:49:00 ru Exp $
- * $NetBSD: strfmon.c,v 1.3 2005/12/02 14:19:43 yamt Exp $
- * $DragonFly: src/lib/libc/stdlib/strfmon.c,v 1.1 2008/10/06 21:01:37 swildner Exp $
+ * $FreeBSD: head/lib/libc/stdlib/strfmon.c 227753 2011-11-20 14:45:42Z theraven $
  */
 
 #include <sys/types.h>
@@ -38,6 +41,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include "xlocale_private.h"
 
 /* internal flags */
 #define        NEED_GROUPING           0x01    /* print digits grouped (default) */
@@ -57,7 +61,7 @@
 } while (0)
 
 #define PRINTS(STR) do {                                       \
-       const char *tmps = STR;                                 \
+       char *tmps = STR;                                       \
        while (*tmps != '\0')                                   \
                PRINT(*tmps++);                                 \
 } while (0)
        groups++;                                               \
 } while (0)
 
-static void __setup_vars(int, char *, char *, char *, const char **);
+static void __setup_vars(int, char *, char *, char *, 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 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 */
@@ -114,14 +117,15 @@ strfmon(char * __restrict s, size_t maxsize, const char * __restrict format,
        char            cs_precedes,    /* values gathered from struct lconv */
                        sep_by_space,
                        sign_posn,
+                       *signstr,
                        *currency_symbol;
-       const char      *signstr;
+
        char            *tmpptr;        /* temporary vars */
        int             sverrno;
+       FIX_LOCALE(loc);
 
-        va_start(ap, format);
 
-       lc = localeconv();
+       lc = localeconv_l(loc);
        dst = s;
        fmt = format;
        asciivalue = NULL;
@@ -379,7 +383,6 @@ strfmon(char * __restrict s, size_t maxsize, const char * __restrict format,
        }
 
        PRINT('\0');
-       va_end(ap);
        free(asciivalue);
        free(currency_symbol);
        return (dst - s - 1);   /* return size of put data except trailing '\0' */
@@ -398,20 +401,44 @@ end_error:
        if (currency_symbol != NULL)
                free(currency_symbol);
        errno = sverrno;
-       va_end(ap);
        return (-1);
 }
+ssize_t
+strfmon_l(char * __restrict s, size_t maxsize, locale_t loc, const char * __restrict format,
+    ...)
+{
+       size_t ret;
+       va_list ap;
+       va_start(ap, format);
+       ret = vstrfmon_l(s, maxsize, loc, format, ap);
+       va_end(ap);
+       return ret;
+}
+
+ssize_t
+strfmon(char * __restrict s, size_t maxsize, const char * __restrict format,
+    ...)
+{
+       size_t ret;
+       va_list ap;
+       va_start(ap, format);
+       ret = vstrfmon_l(s, maxsize, __get_locale(), format, ap);
+       va_end(ap);
+       return ret;
+}
+
 
 static void
 __setup_vars(int flags, char *cs_precedes, char *sep_by_space,
-               char *sign_posn, const char **signstr) {
+               char *sign_posn, char **signstr) {
+
        struct lconv *lc = localeconv();
 
        if ((flags & IS_NEGATIVE) && (flags & USE_INTL_CURRENCY)) {
                *cs_precedes = lc->int_n_cs_precedes;
                *sep_by_space = lc->int_n_sep_by_space;
                *sign_posn = (flags & PARENTH_POSN) ? 0 : lc->int_n_sign_posn;
-               *signstr = (lc->negative_sign == '\0') ? "-"
+               *signstr = (lc->negative_sign[0] == '\0') ? "-"
                    : lc->negative_sign;
        } else if (flags & USE_INTL_CURRENCY) {
                *cs_precedes = lc->int_p_cs_precedes;
@@ -422,7 +449,7 @@ __setup_vars(int flags, char *cs_precedes, char *sep_by_space,
                *cs_precedes = lc->n_cs_precedes;
                *sep_by_space = lc->n_sep_by_space;
                *sign_posn = (flags & PARENTH_POSN) ? 0 : lc->n_sign_posn;
-               *signstr = (lc->negative_sign == '\0') ? "-"
+               *signstr = (lc->negative_sign[0] == '\0') ? "-"
                    : lc->negative_sign;
        } else {
                *cs_precedes = lc->p_cs_precedes;
@@ -443,8 +470,7 @@ __setup_vars(int flags, char *cs_precedes, char *sep_by_space,
 static int
 __calc_left_pad(int flags, char *cur_symb) {
 
-       char cs_precedes, sep_by_space, sign_posn;
-       const char *signstr;
+       char cs_precedes, sep_by_space, sign_posn, *signstr;
        int left_chars = 0;
 
        __setup_vars(flags, &cs_precedes, &sep_by_space, &sign_posn, &signstr);