1 --- strfmon.c.orig 2003-05-20 15:23:25.000000000 -0700
2 +++ strfmon.c 2005-04-27 23:34:08.000000000 -0700
5 __FBSDID("$FreeBSD: src/lib/libc/stdlib/strfmon.c,v 1.14 2003/03/20 08:18:55 ache Exp $");
7 +#include "xlocale_private.h"
16 -#define GET_NUMBER(VAR) do { \
17 +#define GET_NUMBER(VAR,LOC) do { \
19 - while (isdigit((unsigned char)*fmt)) { \
20 + while (isdigit_l((unsigned char)*fmt, (LOC))) { \
28 -static void __setup_vars(int, char *, char *, char *, char **);
29 -static int __calc_left_pad(int, char *);
30 -static char *__format_grouped_double(double, int *, int, int, int);
33 -strfmon(char * __restrict s, size_t maxsize, const char * __restrict format,
35 +static void __setup_vars(int, char *, char *, char *, char **, struct lconv *);
36 +static int __calc_left_pad(int, char *, struct lconv *);
37 +static char *__format_grouped_double(double, int *, int, int, int, struct lconv *, locale_t);
40 +_strfmon(char * __restrict s, size_t maxsize, locale_t loc,
41 + const char * __restrict format, va_list ap)
44 char *dst; /* output destination pointer */
45 const char *fmt; /* current format poistion pointer */
46 struct lconv *lc; /* pointer to lconv structure */
48 char *tmpptr; /* temporary vars */
51 - va_start(ap, format);
54 + lc = localeconv_l(loc);
62 - if (isdigit((unsigned char)*fmt)) {
64 + if (isdigit_l((unsigned char)*fmt, loc)) {
65 + GET_NUMBER(width, loc);
66 /* Do we have enough space to put number with
73 - if (!isdigit((unsigned char)*++fmt))
74 + if (!isdigit_l((unsigned char)*++fmt, loc))
76 - GET_NUMBER(left_prec);
77 + GET_NUMBER(left_prec, loc);
82 - if (!isdigit((unsigned char)*++fmt))
83 + if (!isdigit_l((unsigned char)*++fmt, loc))
85 - GET_NUMBER(right_prec);
86 + GET_NUMBER(right_prec, loc);
89 /* Conversion Characters */
92 if (flags & USE_INTL_CURRENCY) {
93 currency_symbol = strdup(lc->int_curr_symbol);
94 - if (currency_symbol != NULL)
95 + if (currency_symbol != NULL) {
96 space_char = *(currency_symbol+3);
97 + currency_symbol[3] = '\0';
100 currency_symbol = strdup(lc->currency_symbol);
102 @@ -239,21 +240,21 @@
103 /* fill left_prec with amount of padding chars */
104 if (left_prec >= 0) {
105 pad_size = __calc_left_pad((flags ^ IS_NEGATIVE),
107 - __calc_left_pad(flags, currency_symbol);
108 + currency_symbol, lc) -
109 + __calc_left_pad(flags, currency_symbol, lc);
114 asciivalue = __format_grouped_double(value, &flags,
115 - left_prec, right_prec, pad_char);
116 + left_prec, right_prec, pad_char, lc, loc);
117 if (asciivalue == NULL)
118 goto end_error; /* errno already set */
119 /* to ENOMEM by malloc() */
121 /* set some variables for later use */
122 __setup_vars(flags, &cs_precedes, &sep_by_space,
123 - &sign_posn, &signstr);
124 + &sign_posn, &signstr, lc);
127 * Description of some LC_MONETARY's values:
129 } else if (sep_by_space == 1)
132 - } else if (sign_posn == 1)
133 + } else if (sign_posn == 1) {
135 + if (sep_by_space == 2)
145 - if (sign_posn == 0 && (flags & IS_NEGATIVE))
147 + if (sign_posn == 0) {
148 + if (flags & IS_NEGATIVE)
150 + else if (left_prec >= 0)
154 if (dst - tmpptr < width) {
155 if (flags & LEFT_JUSTIFY) {
162 free(currency_symbol);
163 return (dst - s - 1); /* return size of put data except trailing '\0' */
164 @@ -385,15 +392,12 @@
165 if (currency_symbol != NULL)
166 free(currency_symbol);
173 __setup_vars(int flags, char *cs_precedes, char *sep_by_space,
174 - char *sign_posn, char **signstr) {
176 - struct lconv *lc = localeconv();
177 + char *sign_posn, char **signstr, struct lconv *lc) {
179 if ((flags & IS_NEGATIVE) && (flags & USE_INTL_CURRENCY)) {
180 *cs_precedes = lc->int_n_cs_precedes;
181 @@ -429,12 +433,12 @@
185 -__calc_left_pad(int flags, char *cur_symb) {
186 +__calc_left_pad(int flags, char *cur_symb, struct lconv *lc) {
188 char cs_precedes, sep_by_space, sign_posn, *signstr;
191 - __setup_vars(flags, &cs_precedes, &sep_by_space, &sign_posn, &signstr);
192 + __setup_vars(flags, &cs_precedes, &sep_by_space, &sign_posn, &signstr, lc);
194 if (cs_precedes != 0) {
195 left_chars += strlen(cur_symb);
201 + if (flags & IS_NEGATIVE)
205 left_chars += strlen(signstr);
210 /* convert double to ASCII */
211 +__private_extern__ const char *__fix_nogrouping(const char *);
214 __format_grouped_double(double value, int *flags,
215 - int left_prec, int right_prec, int pad_char) {
216 + int left_prec, int right_prec, int pad_char, struct lconv *lc, locale_t loc) {
220 @@ -492,14 +502,13 @@
224 - struct lconv *lc = localeconv();
231 - grouping = lc->mon_grouping;
232 + grouping = __fix_nogrouping(lc->mon_grouping);
233 decimal_point = *lc->mon_decimal_point;
234 if (decimal_point == '\0')
235 decimal_point = *lc->decimal_point;
237 left_prec += get_groups(left_prec, grouping);
239 /* convert to string */
240 - snprintf(fmt, sizeof(fmt), "%%%d.%df", left_prec + right_prec + 1,
241 + snprintf_l(fmt, sizeof(fmt), loc, "%%%d.%df", left_prec + right_prec + 1,
243 - avalue_size = asprintf(&avalue, fmt, value);
244 + avalue_size = asprintf_l(&avalue, loc, fmt, value);
254 +strfmon(char * __restrict s, size_t maxsize, const char * __restrict format,
260 + va_start(ap, format);
261 + ret = _strfmon(s, maxsize, __current_locale(), format, ap);
267 +strfmon_l(char * __restrict s, size_t maxsize, locale_t loc,
268 + const char * __restrict format, ...)
273 + NORMALIZE_LOCALE(loc);
274 + va_start(ap, format);
275 + ret = _strfmon(s, maxsize, loc, format, ap);