]>
Commit | Line | Data |
---|---|---|
3d9156a7 A |
1 | --- strfmon.c.orig 2003-05-20 15:23:25.000000000 -0700 |
2 | +++ strfmon.c 2005-02-27 11:52:19.000000000 -0800 | |
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 | @@ -239,21 +238,21 @@ | |
91 | /* fill left_prec with amount of padding chars */ | |
92 | if (left_prec >= 0) { | |
93 | pad_size = __calc_left_pad((flags ^ IS_NEGATIVE), | |
94 | - currency_symbol) - | |
95 | - __calc_left_pad(flags, currency_symbol); | |
96 | + currency_symbol, lc) - | |
97 | + __calc_left_pad(flags, currency_symbol, lc); | |
98 | if (pad_size < 0) | |
99 | pad_size = 0; | |
100 | } | |
101 | ||
102 | asciivalue = __format_grouped_double(value, &flags, | |
103 | - left_prec, right_prec, pad_char); | |
104 | + left_prec, right_prec, pad_char, lc, loc); | |
105 | if (asciivalue == NULL) | |
106 | goto end_error; /* errno already set */ | |
107 | /* to ENOMEM by malloc() */ | |
108 | ||
109 | /* set some variables for later use */ | |
110 | __setup_vars(flags, &cs_precedes, &sep_by_space, | |
111 | - &sign_posn, &signstr); | |
112 | + &sign_posn, &signstr, lc); | |
113 | ||
114 | /* | |
115 | * Description of some LC_MONETARY's values: | |
116 | @@ -366,7 +365,6 @@ | |
117 | } | |
118 | ||
119 | PRINT('\0'); | |
120 | - va_end(ap); | |
121 | free(asciivalue); | |
122 | free(currency_symbol); | |
123 | return (dst - s - 1); /* return size of put data except trailing '\0' */ | |
124 | @@ -385,15 +383,12 @@ | |
125 | if (currency_symbol != NULL) | |
126 | free(currency_symbol); | |
127 | errno = sverrno; | |
128 | - va_end(ap); | |
129 | return (-1); | |
130 | } | |
131 | ||
132 | static void | |
133 | __setup_vars(int flags, char *cs_precedes, char *sep_by_space, | |
134 | - char *sign_posn, char **signstr) { | |
135 | - | |
136 | - struct lconv *lc = localeconv(); | |
137 | + char *sign_posn, char **signstr, struct lconv *lc) { | |
138 | ||
139 | if ((flags & IS_NEGATIVE) && (flags & USE_INTL_CURRENCY)) { | |
140 | *cs_precedes = lc->int_n_cs_precedes; | |
141 | @@ -429,12 +424,12 @@ | |
142 | } | |
143 | ||
144 | static int | |
145 | -__calc_left_pad(int flags, char *cur_symb) { | |
146 | +__calc_left_pad(int flags, char *cur_symb, struct lconv *lc) { | |
147 | ||
148 | char cs_precedes, sep_by_space, sign_posn, *signstr; | |
149 | int left_chars = 0; | |
150 | ||
151 | - __setup_vars(flags, &cs_precedes, &sep_by_space, &sign_posn, &signstr); | |
152 | + __setup_vars(flags, &cs_precedes, &sep_by_space, &sign_posn, &signstr, lc); | |
153 | ||
154 | if (cs_precedes != 0) { | |
155 | left_chars += strlen(cur_symb); | |
156 | @@ -480,7 +475,7 @@ | |
157 | /* convert double to ASCII */ | |
158 | static char * | |
159 | __format_grouped_double(double value, int *flags, | |
160 | - int left_prec, int right_prec, int pad_char) { | |
161 | + int left_prec, int right_prec, int pad_char, struct lconv *lc, locale_t loc) { | |
162 | ||
163 | char *rslt; | |
164 | char *avalue; | |
165 | @@ -492,7 +487,6 @@ | |
166 | ||
167 | int padded; | |
168 | ||
169 | - struct lconv *lc = localeconv(); | |
170 | char *grouping; | |
171 | char decimal_point; | |
172 | char thousands_sep; | |
173 | @@ -526,9 +520,9 @@ | |
174 | left_prec += get_groups(left_prec, grouping); | |
175 | ||
176 | /* convert to string */ | |
177 | - snprintf(fmt, sizeof(fmt), "%%%d.%df", left_prec + right_prec + 1, | |
178 | + snprintf_l(fmt, sizeof(fmt), loc, "%%%d.%df", left_prec + right_prec + 1, | |
179 | right_prec); | |
180 | - avalue_size = asprintf(&avalue, fmt, value); | |
181 | + avalue_size = asprintf_l(&avalue, loc, fmt, value); | |
182 | if (avalue_size < 0) | |
183 | return (NULL); | |
184 | ||
185 | @@ -601,3 +595,30 @@ | |
186 | free(avalue); | |
187 | return (rslt); | |
188 | } | |
189 | + | |
190 | +ssize_t | |
191 | +strfmon(char * __restrict s, size_t maxsize, const char * __restrict format, | |
192 | + ...) | |
193 | +{ | |
194 | + ssize_t ret; | |
195 | + va_list ap; | |
196 | + | |
197 | + va_start(ap, format); | |
198 | + ret = _strfmon(s, maxsize, __current_locale(), format, ap); | |
199 | + va_end(ap); | |
200 | + return ret; | |
201 | +} | |
202 | + | |
203 | +ssize_t | |
204 | +strfmon_l(char * __restrict s, size_t maxsize, locale_t loc, | |
205 | + const char * __restrict format, ...) | |
206 | +{ | |
207 | + ssize_t ret; | |
208 | + va_list ap; | |
209 | + | |
210 | + NORMALIZE_LOCALE(loc); | |
211 | + va_start(ap, format); | |
212 | + ret = _strfmon(s, maxsize, loc, format, ap); | |
213 | + va_end(ap); | |
214 | + return ret; | |
215 | +} |