]> git.saurik.com Git - apple/libc.git/blob - stdlib/FreeBSD/strfmon.c.patch
9ff3b5dc4f2a19e8ab69445ab70a99c2ee6dc32c
[apple/libc.git] / stdlib / FreeBSD / strfmon.c.patch
1 --- strfmon.c.orig 2003-05-20 15:23:25.000000000 -0700
2 +++ strfmon.c 2005-04-27 23:34:08.000000000 -0700
3 @@ -28,6 +28,8 @@
4 #include <sys/cdefs.h>
5 __FBSDID("$FreeBSD: src/lib/libc/stdlib/strfmon.c,v 1.14 2003/03/20 08:18:55 ache Exp $");
6
7 +#include "xlocale_private.h"
8 +
9 #include <sys/types.h>
10 #include <ctype.h>
11 #include <errno.h>
12 @@ -61,9 +63,9 @@
13 PRINT(*tmps++); \
14 } while (0)
15
16 -#define GET_NUMBER(VAR) do { \
17 +#define GET_NUMBER(VAR,LOC) do { \
18 VAR = 0; \
19 - while (isdigit((unsigned char)*fmt)) { \
20 + while (isdigit_l((unsigned char)*fmt, (LOC))) { \
21 VAR *= 10; \
22 VAR += *fmt - '0'; \
23 fmt++; \
24 @@ -83,15 +85,14 @@
25 groups++; \
26 } while (0)
27
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);
31 -
32 -ssize_t
33 -strfmon(char * __restrict s, size_t maxsize, const char * __restrict format,
34 - ...)
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);
38 +
39 +static ssize_t
40 +_strfmon(char * __restrict s, size_t maxsize, locale_t loc,
41 + const char * __restrict format, va_list ap)
42 {
43 - 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 */
47 @@ -115,9 +116,7 @@
48 char *tmpptr; /* temporary vars */
49 int sverrno;
50
51 - va_start(ap, format);
52 -
53 - lc = localeconv();
54 + lc = localeconv_l(loc);
55 dst = s;
56 fmt = format;
57 asciivalue = NULL;
58 @@ -181,8 +180,8 @@
59 }
60
61 /* field Width */
62 - if (isdigit((unsigned char)*fmt)) {
63 - GET_NUMBER(width);
64 + if (isdigit_l((unsigned char)*fmt, loc)) {
65 + GET_NUMBER(width, loc);
66 /* Do we have enough space to put number with
67 * required width ?
68 */
69 @@ -192,16 +191,16 @@
70
71 /* Left precision */
72 if (*fmt == '#') {
73 - if (!isdigit((unsigned char)*++fmt))
74 + if (!isdigit_l((unsigned char)*++fmt, loc))
75 goto format_error;
76 - GET_NUMBER(left_prec);
77 + GET_NUMBER(left_prec, loc);
78 }
79
80 /* Right precision */
81 if (*fmt == '.') {
82 - if (!isdigit((unsigned char)*++fmt))
83 + if (!isdigit_l((unsigned char)*++fmt, loc))
84 goto format_error;
85 - GET_NUMBER(right_prec);
86 + GET_NUMBER(right_prec, loc);
87 }
88
89 /* Conversion Characters */
90 @@ -219,8 +218,10 @@
91
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';
98 + }
99 } else
100 currency_symbol = strdup(lc->currency_symbol);
101
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),
106 - currency_symbol) -
107 - __calc_left_pad(flags, currency_symbol);
108 + currency_symbol, lc) -
109 + __calc_left_pad(flags, currency_symbol, lc);
110 if (pad_size < 0)
111 pad_size = 0;
112 }
113
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() */
120
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);
125
126 /*
127 * Description of some LC_MONETARY's values:
128 @@ -313,8 +314,11 @@
129 } else if (sep_by_space == 1)
130 PRINT(space_char);
131 }
132 - } else if (sign_posn == 1)
133 + } else if (sign_posn == 1) {
134 PRINTS(signstr);
135 + if (sep_by_space == 2)
136 + PRINT(' ');
137 + }
138
139 PRINTS(asciivalue);
140
141 @@ -348,8 +352,12 @@
142 PRINTS(signstr);
143 }
144
145 - if (sign_posn == 0 && (flags & IS_NEGATIVE))
146 - PRINT(')');
147 + if (sign_posn == 0) {
148 + if (flags & IS_NEGATIVE)
149 + PRINT(')');
150 + else if (left_prec >= 0)
151 + PRINT(' ');
152 + }
153
154 if (dst - tmpptr < width) {
155 if (flags & LEFT_JUSTIFY) {
156 @@ -366,7 +374,6 @@
157 }
158
159 PRINT('\0');
160 - va_end(ap);
161 free(asciivalue);
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);
167 errno = sverrno;
168 - va_end(ap);
169 return (-1);
170 }
171
172 static void
173 __setup_vars(int flags, char *cs_precedes, char *sep_by_space,
174 - char *sign_posn, char **signstr) {
175 -
176 - struct lconv *lc = localeconv();
177 + char *sign_posn, char **signstr, struct lconv *lc) {
178
179 if ((flags & IS_NEGATIVE) && (flags & USE_INTL_CURRENCY)) {
180 *cs_precedes = lc->int_n_cs_precedes;
181 @@ -429,12 +433,12 @@
182 }
183
184 static int
185 -__calc_left_pad(int flags, char *cur_symb) {
186 +__calc_left_pad(int flags, char *cur_symb, struct lconv *lc) {
187
188 char cs_precedes, sep_by_space, sign_posn, *signstr;
189 int left_chars = 0;
190
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);
193
194 if (cs_precedes != 0) {
195 left_chars += strlen(cur_symb);
196 @@ -443,6 +447,10 @@
197 }
198
199 switch (sign_posn) {
200 + case 0:
201 + if (flags & IS_NEGATIVE)
202 + left_chars++;
203 + break;
204 case 1:
205 left_chars += strlen(signstr);
206 break;
207 @@ -478,9 +486,11 @@
208 }
209
210 /* convert double to ASCII */
211 +__private_extern__ const char *__fix_nogrouping(const char *);
212 +
213 static 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) {
217
218 char *rslt;
219 char *avalue;
220 @@ -492,14 +502,13 @@
221
222 int padded;
223
224 - struct lconv *lc = localeconv();
225 char *grouping;
226 char decimal_point;
227 char thousands_sep;
228
229 int groups = 0;
230
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;
236 @@ -526,9 +535,9 @@
237 left_prec += get_groups(left_prec, grouping);
238
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,
242 right_prec);
243 - avalue_size = asprintf(&avalue, fmt, value);
244 + avalue_size = asprintf_l(&avalue, loc, fmt, value);
245 if (avalue_size < 0)
246 return (NULL);
247
248 @@ -601,3 +610,30 @@
249 free(avalue);
250 return (rslt);
251 }
252 +
253 +ssize_t
254 +strfmon(char * __restrict s, size_t maxsize, const char * __restrict format,
255 + ...)
256 +{
257 + ssize_t ret;
258 + va_list ap;
259 +
260 + va_start(ap, format);
261 + ret = _strfmon(s, maxsize, __current_locale(), format, ap);
262 + va_end(ap);
263 + return ret;
264 +}
265 +
266 +ssize_t
267 +strfmon_l(char * __restrict s, size_t maxsize, locale_t loc,
268 + const char * __restrict format, ...)
269 +{
270 + ssize_t ret;
271 + va_list ap;
272 +
273 + NORMALIZE_LOCALE(loc);
274 + va_start(ap, format);
275 + ret = _strfmon(s, maxsize, loc, format, ap);
276 + va_end(ap);
277 + return ret;
278 +}