]>
Commit | Line | Data |
---|---|---|
3d9156a7 A |
1 | --- collate.c.orig 2004-11-25 11:38:16.000000000 -0800 |
2 | +++ collate.c 2005-02-17 10:35:00.000000000 -0800 | |
3 | @@ -28,6 +28,11 @@ | |
4 | #include <sys/cdefs.h> | |
5 | __FBSDID("$FreeBSD: src/lib/libc/locale/collate.c,v 1.33 2004/09/22 16:56:48 stefanf Exp $"); | |
9385eb3d | 6 | |
3d9156a7 A |
7 | +#include "xlocale_private.h" |
8 | +/* assumes the locale_t variable is named loc */ | |
9 | +#define __collate_substitute_table (loc->__lc_collate->__substitute_table) | |
10 | +#define __collate_char_pri_table (loc->__lc_collate->__char_pri_table) | |
11 | + | |
9385eb3d | 12 | #include "namespace.h" |
3d9156a7 | 13 | #include <arpa/inet.h> |
9385eb3d | 14 | #include <stdio.h> |
3d9156a7 A |
15 | @@ -44,36 +49,46 @@ |
16 | ||
17 | #include "libc_private.h" | |
18 | ||
19 | -int __collate_load_error = 1; | |
20 | -int __collate_substitute_nontrivial; | |
21 | - | |
22 | -u_char __collate_substitute_table[UCHAR_MAX + 1][STR_LEN]; | |
23 | -struct __collate_st_char_pri __collate_char_pri_table[UCHAR_MAX + 1]; | |
24 | -struct __collate_st_chain_pri *__collate_chain_pri_table; | |
25 | - | |
26 | void __collate_err(int ex, const char *f) __dead2; | |
27 | ||
28 | -int | |
29 | -__collate_load_tables(const char *encoding) | |
30 | +/* | |
31 | + * Normally, the __collate_* routines should all be __private_extern__, | |
32 | + * but grep is using them (3715846). Until we can provide an alternative, | |
33 | + * we leave them public, and provide a read-only __collate_load_error variable | |
34 | + */ | |
35 | +#undef __collate_load_error | |
36 | +int __collate_load_error = 1; | |
37 | + | |
38 | +__private_extern__ int | |
39 | +__collate_load_tables(const char *encoding, locale_t loc) | |
40 | { | |
41 | FILE *fp; | |
42 | int i, saverr, chains; | |
43 | uint32_t u32; | |
44 | char strbuf[STR_LEN], buf[PATH_MAX]; | |
45 | - void *TMP_substitute_table, *TMP_char_pri_table, *TMP_chain_pri_table; | |
46 | - static char collate_encoding[ENCODING_LEN + 1]; | |
47 | + struct __xlocale_st_collate *TMP; | |
48 | + static struct __xlocale_st_collate *cache = NULL; | |
49 | ||
50 | /* 'encoding' must be already checked. */ | |
51 | if (strcmp(encoding, "C") == 0 || strcmp(encoding, "POSIX") == 0) { | |
52 | - __collate_load_error = 1; | |
53 | + loc->__collate_load_error = 1; | |
54 | + if (loc == &__global_locale) | |
55 | + __collate_load_error = 1; | |
56 | + XL_RELEASE(loc->__lc_collate); | |
57 | + loc->__lc_collate = NULL; | |
58 | return (_LDP_CACHE); | |
59 | } | |
60 | ||
61 | /* | |
62 | * If the locale name is the same as our cache, use the cache. | |
63 | */ | |
64 | - if (strcmp(encoding, collate_encoding) == 0) { | |
65 | - __collate_load_error = 0; | |
66 | + if (cache && strcmp(encoding, cache->__encoding) == 0) { | |
67 | + loc->__collate_load_error = 0; | |
68 | + if (loc == &__global_locale) | |
69 | + __collate_load_error = 0; | |
70 | + XL_RELEASE(loc->__lc_collate); | |
71 | + loc->__lc_collate = cache; | |
72 | + XL_RETAIN(loc->__lc_collate); | |
73 | return (_LDP_CACHE); | |
74 | } | |
75 | ||
76 | @@ -121,115 +136,106 @@ | |
77 | } else | |
78 | chains = TABLE_SIZE; | |
79 | ||
80 | - if ((TMP_substitute_table = | |
81 | - malloc(sizeof(__collate_substitute_table))) == NULL) { | |
82 | - saverr = errno; | |
83 | - (void)fclose(fp); | |
84 | - errno = saverr; | |
85 | - return (_LDP_ERROR); | |
86 | - } | |
87 | - if ((TMP_char_pri_table = | |
88 | - malloc(sizeof(__collate_char_pri_table))) == NULL) { | |
89 | + if ((TMP = | |
90 | + malloc(sizeof(struct __xlocale_st_collate) + sizeof(struct __collate_st_chain_pri) * chains)) == NULL) { | |
91 | saverr = errno; | |
92 | - free(TMP_substitute_table); | |
93 | - (void)fclose(fp); | |
94 | - errno = saverr; | |
95 | - return (_LDP_ERROR); | |
96 | - } | |
97 | - if ((TMP_chain_pri_table = | |
98 | - malloc(sizeof(*__collate_chain_pri_table) * chains)) == NULL) { | |
99 | - saverr = errno; | |
100 | - free(TMP_substitute_table); | |
101 | - free(TMP_char_pri_table); | |
102 | (void)fclose(fp); | |
103 | errno = saverr; | |
104 | return (_LDP_ERROR); | |
105 | } | |
106 | + TMP->__refcount = 2; /* one for the locale, one for the cache */ | |
107 | + TMP->__free_extra = NULL; | |
108 | + TMP->__chain_pri_table = (struct __collate_st_chain_pri *)(TMP + 1); | |
109 | ||
110 | #define FREAD(a, b, c, d) \ | |
111 | { \ | |
112 | if (fread(a, b, c, d) != c) { \ | |
113 | saverr = errno; \ | |
114 | - free(TMP_substitute_table); \ | |
115 | - free(TMP_char_pri_table); \ | |
116 | - free(TMP_chain_pri_table); \ | |
117 | + free(TMP); \ | |
118 | (void)fclose(d); \ | |
119 | errno = saverr; \ | |
120 | return (_LDP_ERROR); \ | |
121 | } \ | |
122 | } | |
123 | ||
124 | - FREAD(TMP_substitute_table, sizeof(__collate_substitute_table), 1, fp); | |
125 | - FREAD(TMP_char_pri_table, sizeof(__collate_char_pri_table), 1, fp); | |
126 | - FREAD(TMP_chain_pri_table, | |
127 | - sizeof(*__collate_chain_pri_table), chains, fp); | |
128 | + FREAD(TMP->__substitute_table, sizeof(TMP->__substitute_table), 1, fp); | |
129 | + FREAD(TMP->__char_pri_table, sizeof(TMP->__char_pri_table), 1, fp); | |
130 | + FREAD(TMP->__chain_pri_table, | |
131 | + sizeof(struct __collate_st_chain_pri), chains, fp); | |
132 | (void)fclose(fp); | |
133 | ||
134 | - (void)strcpy(collate_encoding, encoding); | |
135 | - if (__collate_substitute_table_ptr != NULL) | |
136 | - free(__collate_substitute_table_ptr); | |
137 | - __collate_substitute_table_ptr = TMP_substitute_table; | |
138 | - if (__collate_char_pri_table_ptr != NULL) | |
139 | - free(__collate_char_pri_table_ptr); | |
140 | - __collate_char_pri_table_ptr = TMP_char_pri_table; | |
141 | - if (__collate_chain_pri_table != NULL) | |
142 | - free(__collate_chain_pri_table); | |
143 | - __collate_chain_pri_table = TMP_chain_pri_table; | |
144 | + (void)strcpy(TMP->__encoding, encoding); | |
145 | + XL_RELEASE(cache); | |
146 | + cache = TMP; | |
147 | + XL_RELEASE(loc->__lc_collate); | |
148 | + loc->__lc_collate = cache; | |
149 | + /* no need to retain, since we set __refcount to 2 above */ | |
150 | ||
151 | - __collate_substitute_nontrivial = 0; | |
152 | + loc->__collate_substitute_nontrivial = 0; | |
153 | for (i = 0; i < UCHAR_MAX + 1; i++) { | |
154 | if (__collate_substitute_table[i][0] != i || | |
155 | __collate_substitute_table[i][1] != 0) { | |
156 | - __collate_substitute_nontrivial = 1; | |
157 | + loc->__collate_substitute_nontrivial = 1; | |
158 | break; | |
159 | } | |
160 | } | |
161 | - __collate_load_error = 0; | |
162 | + loc->__collate_load_error = 0; | |
163 | + if (loc == &__global_locale) | |
164 | + __collate_load_error = 0; | |
165 | ||
166 | return (_LDP_LOADED); | |
167 | } | |
168 | ||
169 | -u_char * | |
170 | -__collate_substitute(s) | |
171 | +__private_extern__ u_char * | |
172 | +__collate_substitute_l(s, loc) | |
173 | const u_char *s; | |
174 | + locale_t loc; | |
175 | { | |
176 | int dest_len, len, nlen; | |
177 | - int delta = strlen(s); | |
178 | + int delta = strlen((const char *)s); | |
179 | u_char *dest_str = NULL; | |
180 | ||
181 | if (s == NULL || *s == '\0') | |
182 | - return (__collate_strdup("")); | |
183 | + return (__collate_strdup((u_char *)"")); | |
184 | delta += delta / 8; | |
185 | dest_str = malloc(dest_len = delta); | |
186 | if (dest_str == NULL) | |
187 | __collate_err(EX_OSERR, __func__); | |
188 | len = 0; | |
189 | while (*s) { | |
190 | - nlen = len + strlen(__collate_substitute_table[*s]); | |
191 | + nlen = len + strlen((const char *)__collate_substitute_table[*s]); | |
192 | if (dest_len <= nlen) { | |
193 | dest_str = reallocf(dest_str, dest_len = nlen + delta); | |
194 | if (dest_str == NULL) | |
195 | __collate_err(EX_OSERR, __func__); | |
196 | } | |
197 | - (void)strcpy(dest_str + len, __collate_substitute_table[*s++]); | |
198 | + (void)strcpy((char *)(dest_str + len), (const char *)__collate_substitute_table[*s++]); | |
199 | len = nlen; | |
200 | } | |
201 | return (dest_str); | |
202 | } | |
203 | ||
204 | -void | |
205 | -__collate_lookup(t, len, prim, sec) | |
206 | +u_char * | |
207 | +__collate_substitute(s) | |
208 | + const u_char *s; | |
209 | +{ | |
210 | + return __collate_substitute_l(s, __current_locale()); | |
211 | +} | |
212 | + | |
213 | +__private_extern__ void | |
214 | +__collate_lookup_l(t, len, prim, sec, loc) | |
215 | const u_char *t; | |
216 | int *len, *prim, *sec; | |
217 | + locale_t loc; | |
218 | { | |
219 | struct __collate_st_chain_pri *p2; | |
220 | ||
221 | *len = 1; | |
222 | *prim = *sec = 0; | |
223 | - for (p2 = __collate_chain_pri_table; p2->str[0] != '\0'; p2++) { | |
224 | + for (p2 = loc->__lc_collate->__chain_pri_table; p2->str[0] != '\0'; p2++) { | |
225 | if (*t == p2->str[0] && | |
226 | - strncmp(t, p2->str, strlen(p2->str)) == 0) { | |
227 | - *len = strlen(p2->str); | |
228 | + strncmp((const char *)t, (const char *)p2->str, strlen((const char *)p2->str)) == 0) { | |
229 | + *len = strlen((const char *)p2->str); | |
230 | *prim = p2->prim; | |
231 | *sec = p2->sec; | |
232 | return; | |
233 | @@ -239,11 +245,19 @@ | |
234 | *sec = __collate_char_pri_table[*t].sec; | |
235 | } | |
236 | ||
237 | +void | |
238 | +__collate_lookup(t, len, prim, sec) | |
239 | + const u_char *t; | |
240 | + int *len, *prim, *sec; | |
241 | +{ | |
242 | + return __collate_lookup_l(t, len, prim, sec, __current_locale()); | |
243 | +} | |
244 | + | |
245 | u_char * | |
246 | __collate_strdup(s) | |
247 | u_char *s; | |
248 | { | |
249 | - u_char *t = strdup(s); | |
250 | + u_char *t = (u_char *)strdup((const char *)s); | |
251 | ||
252 | if (t == NULL) | |
253 | __collate_err(EX_OSERR, __func__); | |
254 | @@ -274,6 +288,7 @@ | |
255 | { | |
256 | int i; | |
257 | struct __collate_st_chain_pri *p2; | |
258 | + locale_t loc = __current_locale(); | |
259 | ||
260 | printf("Substitute table:\n"); | |
261 | for (i = 0; i < UCHAR_MAX + 1; i++) | |
262 | @@ -281,7 +296,7 @@ | |
263 | printf("\t'%c' --> \"%s\"\n", i, | |
264 | __collate_substitute_table[i]); | |
265 | printf("Chain priority table:\n"); | |
266 | - for (p2 = __collate_chain_pri_table; p2->str[0] != '\0'; p2++) | |
267 | + for (p2 = loc->__lc_collate->__chain_pri_table; p2->str[0] != '\0'; p2++) | |
268 | printf("\t\"%s\" : %d %d\n", p2->str, p2->prim, p2->sec); | |
269 | printf("Char priority table:\n"); | |
270 | for (i = 0; i < UCHAR_MAX + 1; i++) |