1 --- collate.c.orig 2004-11-25 11:38:16.000000000 -0800
2 +++ collate.c 2005-02-17 10:35:00.000000000 -0800
5 __FBSDID("$FreeBSD: src/lib/libc/locale/collate.c,v 1.33 2004/09/22 16:56:48 stefanf Exp $");
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)
12 #include "namespace.h"
13 #include <arpa/inet.h>
17 #include "libc_private.h"
19 -int __collate_load_error = 1;
20 -int __collate_substitute_nontrivial;
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;
26 void __collate_err(int ex, const char *f) __dead2;
29 -__collate_load_tables(const char *encoding)
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
35 +#undef __collate_load_error
36 +int __collate_load_error = 1;
38 +__private_extern__ int
39 +__collate_load_tables(const char *encoding, locale_t loc)
42 int i, saverr, chains;
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;
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;
62 * If the locale name is the same as our cache, use the cache.
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);
76 @@ -121,115 +136,106 @@
80 - if ((TMP_substitute_table =
81 - malloc(sizeof(__collate_substitute_table))) == NULL) {
85 - return (_LDP_ERROR);
87 - if ((TMP_char_pri_table =
88 - malloc(sizeof(__collate_char_pri_table))) == NULL) {
90 + malloc(sizeof(struct __xlocale_st_collate) + sizeof(struct __collate_st_chain_pri) * chains)) == NULL) {
92 - free(TMP_substitute_table);
95 - return (_LDP_ERROR);
97 - if ((TMP_chain_pri_table =
98 - malloc(sizeof(*__collate_chain_pri_table) * chains)) == NULL) {
100 - free(TMP_substitute_table);
101 - free(TMP_char_pri_table);
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);
110 #define FREAD(a, b, c, d) \
112 if (fread(a, b, c, d) != c) { \
114 - free(TMP_substitute_table); \
115 - free(TMP_char_pri_table); \
116 - free(TMP_chain_pri_table); \
120 return (_LDP_ERROR); \
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);
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);
147 + XL_RELEASE(loc->__lc_collate);
148 + loc->__lc_collate = cache;
149 + /* no need to retain, since we set __refcount to 2 above */
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;
161 - __collate_load_error = 0;
162 + loc->__collate_load_error = 0;
163 + if (loc == &__global_locale)
164 + __collate_load_error = 0;
166 return (_LDP_LOADED);
170 -__collate_substitute(s)
171 +__private_extern__ u_char *
172 +__collate_substitute_l(s, loc)
176 int dest_len, len, nlen;
177 - int delta = strlen(s);
178 + int delta = strlen((const char *)s);
179 u_char *dest_str = NULL;
181 if (s == NULL || *s == '\0')
182 - return (__collate_strdup(""));
183 + return (__collate_strdup((u_char *)""));
185 dest_str = malloc(dest_len = delta);
186 if (dest_str == NULL)
187 __collate_err(EX_OSERR, __func__);
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__);
197 - (void)strcpy(dest_str + len, __collate_substitute_table[*s++]);
198 + (void)strcpy((char *)(dest_str + len), (const char *)__collate_substitute_table[*s++]);
205 -__collate_lookup(t, len, prim, sec)
207 +__collate_substitute(s)
210 + return __collate_substitute_l(s, __current_locale());
213 +__private_extern__ void
214 +__collate_lookup_l(t, len, prim, sec, loc)
216 int *len, *prim, *sec;
219 struct __collate_st_chain_pri *p2;
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);
233 @@ -239,11 +245,19 @@
234 *sec = __collate_char_pri_table[*t].sec;
238 +__collate_lookup(t, len, prim, sec)
240 + int *len, *prim, *sec;
242 + return __collate_lookup_l(t, len, prim, sec, __current_locale());
249 - u_char *t = strdup(s);
250 + u_char *t = (u_char *)strdup((const char *)s);
253 __collate_err(EX_OSERR, __func__);
257 struct __collate_st_chain_pri *p2;
258 + locale_t loc = __current_locale();
260 printf("Substitute table:\n");
261 for (i = 0; i < UCHAR_MAX + 1; i++)
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++)