]> git.saurik.com Git - apple/libc.git/blob - locale/FreeBSD/rune.c
Libc-1244.50.9.tar.gz
[apple/libc.git] / locale / FreeBSD / rune.c
1 /*-
2 * Copyright (c) 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Paul Borman at Krystal Technologies.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37 #ifndef RUNEOFF32
38 #if defined(LIBC_SCCS) && !defined(lint)
39 static char sccsid[] = "@(#)rune.c 8.1 (Berkeley) 6/4/93";
40 #endif /* LIBC_SCCS and not lint */
41 #include <sys/cdefs.h>
42 __FBSDID("$FreeBSD: src/lib/libc/locale/rune.c,v 1.12 2004/07/29 06:16:19 tjr Exp $");
43
44 #include "xlocale_private.h"
45
46 #include "namespace.h"
47 #include <arpa/inet.h>
48 #include <errno.h>
49 #include <runetype.h>
50 #else
51 #include "runetype.h"
52 #endif /* !RUNEOFF32 */
53 #include <stdio.h>
54 #ifndef RUNEOFF32
55 #include <string.h>
56 #include <stdlib.h>
57 #include <sys/types.h>
58 #include <sys/stat.h>
59 #include "un-namespace.h"
60 #endif /* !RUNEOFF32 */
61
62 #if defined(__LP64__) || defined(RUNEOFF32)
63 /*
64 * Because the LC_CTYPE files were created with a 32-bit program, we need
65 * to adjust for the larger pointers in LP64 (the longs have already been
66 * replaced by 32-bit equivalents). Also, natural alignment will pad
67 * 64-bit types to 8-byte boundaries, and make structures containing
68 * 64-bit types sized to 8-byte boundaries.
69 */
70 #include <stddef.h>
71 #ifndef RUNEOFF32
72 #include "rune32.h"
73 #define BYTES32BITS 4
74 #define BYTES64BITS 8
75 /* whether to skip over a pointer or not (one-to-one with off64) */
76 int skip[] = {
77 1,
78 1,
79 0,
80 1,
81 0,
82 1,
83 0,
84 1,
85 1,
86 1,
87 0
88 };
89 #endif /* !RUNEOFF32 */
90 int off64[] = {
91 offsetof(_RuneLocale, __sgetrune),
92 offsetof(_RuneLocale, __sputrune),
93 offsetof(_RuneLocale, __runetype_ext),
94 offsetof(_RuneLocale, __runetype_ext) + offsetof(_RuneRange, __ranges),
95 offsetof(_RuneLocale, __maplower_ext),
96 offsetof(_RuneLocale, __maplower_ext) + offsetof(_RuneRange, __ranges),
97 offsetof(_RuneLocale, __mapupper_ext),
98 offsetof(_RuneLocale, __mapupper_ext) + offsetof(_RuneRange, __ranges),
99 offsetof(_RuneLocale, __variable),
100 offsetof(_RuneLocale, __charclasses),
101 sizeof(_RuneLocale)
102 };
103 #define NOFF (sizeof(off64) / sizeof(int))
104 #ifdef RUNEOFF32
105 /*
106 * This program generates a header file (on stdout) that containes the 32-bit
107 * offsets, plus some 32-bit sizes
108 */
109 main()
110 {
111 int i;
112 printf("#define SIZEOF32_RUNEENTRY %d\n", sizeof(_RuneEntry));
113 printf("#define SIZEOF32_RUNELOCALE %d\n", sizeof(_RuneLocale));
114 printf("int off32[] = {\n");
115 for(i = 0; i < NOFF; i++)
116 printf("\t%d,\n", off64[i]);
117 printf("};\n");
118 return 0;
119 }
120 #endif /* RUNEOFF32 */
121 #else /* !__LP64__ && !RUNEOFF32 */
122 #define SIZEOF32_RUNELOCALE sizeof(_RuneLocale)
123 #endif /* __LP64__ || RUNEOFF32 */
124
125 #ifndef RUNEOFF32
126 struct __xlocale_st_runelocale *
127 _Read_RuneMagi(fp)
128 FILE *fp;
129 {
130 struct __xlocale_st_runelocale *data;
131 void *lastp;
132 _RuneLocale *rl;
133 _RuneEntry *rr;
134 struct stat sb;
135 int x, saverr;
136
137 if (_fstat(fileno(fp), &sb) < 0)
138 return (NULL);
139
140 if (sb.st_size < SIZEOF32_RUNELOCALE) {
141 errno = EFTYPE;
142 return (NULL);
143 }
144
145 #ifdef __LP64__
146 /* will adjust later */
147 if ((data = (struct __xlocale_st_runelocale *)malloc(sizeof(struct __xlocale_st_runelocale))) == NULL)
148 #else /* !__LP64__ */
149 if ((data = (struct __xlocale_st_runelocale *)malloc(sizeof(struct __xlocale_st_runelocale) - sizeof(_RuneLocale) + sb.st_size)) == NULL)
150 #endif /* __LP64__ */
151 return (NULL);
152 data->__refcount = 1;
153 data->__free_extra = NULL;
154
155 errno = 0;
156 rewind(fp); /* Someone might have read the magic number once already */
157 if (errno) {
158 saverr = errno;
159 free(data);
160 errno = saverr;
161 return (NULL);
162 }
163
164 rl = &data->_CurrentRuneLocale;
165
166 #ifdef __LP64__
167 if (fread(rl, SIZEOF32_RUNELOCALE, 1, fp) != 1)
168 #else /* !__LP64__ */
169 if (fread(rl, sb.st_size, 1, fp) != 1)
170 #endif /* __LP64__ */
171 {
172 saverr = errno;
173 free(data);
174 errno = saverr;
175 return (NULL);
176 }
177
178 #ifndef __LP64__
179 lastp = (char *)rl + sb.st_size;
180
181 rl->__variable = rl + 1;
182 #endif /* __LP64__ */
183
184 if (memcmp(rl->__magic, _RUNE_MAGIC_A, sizeof(rl->__magic))) {
185 free(data);
186 errno = EFTYPE;
187 return (NULL);
188 }
189
190 #ifdef __LP64__
191 /* shift things into the right position */
192 for (x = NOFF - 2; x >= 0; x--)
193 memmove((char *)rl + off64[x] + (skip[x] ? BYTES64BITS : 0),
194 (char *)rl + off32[x] + (skip[x] ? BYTES32BITS : 0),
195 off32[x + 1] - off32[x] - (skip[x] ? BYTES32BITS : 0));
196 #endif /* __LP64__ */
197 #if __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN
198 rl->__invalid_rune = ntohl(rl->__invalid_rune);
199 rl->__variable_len = ntohl(rl->__variable_len);
200 rl->__ncharclasses = ntohl(rl->__ncharclasses);
201 rl->__runetype_ext.__nranges = ntohl(rl->__runetype_ext.__nranges);
202 rl->__maplower_ext.__nranges = ntohl(rl->__maplower_ext.__nranges);
203 rl->__mapupper_ext.__nranges = ntohl(rl->__mapupper_ext.__nranges);
204
205 for (x = 0; x < _CACHED_RUNES; ++x) {
206 rl->__runetype[x] = ntohl(rl->__runetype[x]);
207 rl->__maplower[x] = ntohl(rl->__maplower[x]);
208 rl->__mapupper[x] = ntohl(rl->__mapupper[x]);
209 }
210 #endif /* __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN */
211
212 #ifdef __LP64__
213 {
214 int count = rl->__runetype_ext.__nranges + rl->__maplower_ext.__nranges
215 + rl->__mapupper_ext.__nranges;
216 int extra = sb.st_size - SIZEOF32_RUNELOCALE - count * SIZEOF32_RUNEENTRY - rl->__ncharclasses * sizeof(_RuneCharClass);
217 _RuneEntry *rp;
218
219 if (extra < 0) {
220 saverr = errno;
221 free(data);
222 errno = saverr;
223 return (NULL);
224 }
225 if ((data = (struct __xlocale_st_runelocale *)reallocf(data, sizeof(struct __xlocale_st_runelocale)
226 + count * sizeof(_RuneEntry)
227 + rl->__ncharclasses * sizeof(_RuneCharClass)
228 + extra)) == NULL)
229 return (NULL);
230 rl = &data->_CurrentRuneLocale;
231 rl->__variable = rl + 1;
232 rp = (_RuneEntry *)rl->__variable;
233 for (x = 0; x < count; x++, rp++)
234 if (fread(rp, SIZEOF32_RUNEENTRY, 1, fp) != 1) {
235 saverr = errno;
236 free(data);
237 errno = saverr;
238 return (NULL);
239 }
240 if (rl->__ncharclasses > 0) {
241 if (fread(rp, sizeof(_RuneCharClass), rl->__ncharclasses, fp) != rl->__ncharclasses) {
242 saverr = errno;
243 free(data);
244 errno = saverr;
245 return (NULL);
246 }
247 rp = (_RuneEntry *)((char *)rp + rl->__ncharclasses * sizeof(_RuneCharClass));
248 }
249 if (extra > 0 && fread(rp, extra, 1, fp) != 1) {
250 saverr = errno;
251 free(data);
252 errno = saverr;
253 return (NULL);
254 }
255 lastp = (char *)rp + extra;
256 }
257 #endif /* __LP64__ */
258 rl->__runetype_ext.__ranges = (_RuneEntry *)rl->__variable;
259 rl->__variable = rl->__runetype_ext.__ranges +
260 rl->__runetype_ext.__nranges;
261 if (rl->__variable > lastp) {
262 free(data);
263 errno = EFTYPE;
264 return (NULL);
265 }
266
267 rl->__maplower_ext.__ranges = (_RuneEntry *)rl->__variable;
268 rl->__variable = rl->__maplower_ext.__ranges +
269 rl->__maplower_ext.__nranges;
270 if (rl->__variable > lastp) {
271 free(data);
272 errno = EFTYPE;
273 return (NULL);
274 }
275
276 rl->__mapupper_ext.__ranges = (_RuneEntry *)rl->__variable;
277 rl->__variable = rl->__mapupper_ext.__ranges +
278 rl->__mapupper_ext.__nranges;
279 if (rl->__variable > lastp) {
280 free(data);
281 errno = EFTYPE;
282 return (NULL);
283 }
284
285 for (x = 0; x < rl->__runetype_ext.__nranges; ++x) {
286 rr = rl->__runetype_ext.__ranges;
287
288 #if __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN
289 rr[x].__min = ntohl(rr[x].__min);
290 rr[x].__max = ntohl(rr[x].__max);
291 #endif /* __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN */
292 if ((rr[x].__map = ntohl(rr[x].__map)) == 0) {
293 int len = rr[x].__max - rr[x].__min + 1;
294 rr[x].__types = rl->__variable;
295 rl->__variable = rr[x].__types + len;
296 if (rl->__variable > lastp) {
297 free(data);
298 errno = EFTYPE;
299 return (NULL);
300 }
301 #if __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN
302 while (len-- > 0)
303 rr[x].__types[len] = ntohl(rr[x].__types[len]);
304 #endif /* __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN */
305 } else
306 rr[x].__types = 0;
307 }
308
309 #if __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN
310 for (x = 0; x < rl->__maplower_ext.__nranges; ++x) {
311 rr = rl->__maplower_ext.__ranges;
312
313 rr[x].__min = ntohl(rr[x].__min);
314 rr[x].__max = ntohl(rr[x].__max);
315 rr[x].__map = ntohl(rr[x].__map);
316 }
317
318 for (x = 0; x < rl->__mapupper_ext.__nranges; ++x) {
319 rr = rl->__mapupper_ext.__ranges;
320
321 rr[x].__min = ntohl(rr[x].__min);
322 rr[x].__max = ntohl(rr[x].__max);
323 rr[x].__map = ntohl(rr[x].__map);
324 }
325 #endif /* __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN */
326
327 if (rl->__ncharclasses > 0) {
328 rl->__charclasses = (_RuneCharClass *)rl->__variable;
329 rl->__variable = (void *)(rl->__charclasses + rl->__ncharclasses);
330 if (rl->__variable > lastp) {
331 free(data);
332 errno = EFTYPE;
333 return (NULL);
334 }
335 #if __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN
336 for (x = 0; x < rl->__ncharclasses; ++x)
337 rl->__charclasses[x].__mask = ntohl(rl->__charclasses[x].__mask);
338 #endif /* __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN */
339 }
340
341 if (((char *)rl->__variable) + rl->__variable_len > (char *)lastp) {
342 free(data);
343 errno = EFTYPE;
344 return (NULL);
345 }
346
347 /*
348 * Go out and zero pointers that should be zero.
349 */
350 if (!rl->__variable_len)
351 rl->__variable = 0;
352
353 if (!rl->__runetype_ext.__nranges)
354 rl->__runetype_ext.__ranges = 0;
355
356 if (!rl->__maplower_ext.__nranges)
357 rl->__maplower_ext.__ranges = 0;
358
359 if (!rl->__mapupper_ext.__nranges)
360 rl->__mapupper_ext.__ranges = 0;
361
362 data->__datasize = lastp - (void *)data;
363 return (data);
364 }
365 #endif /* !RUNEOFF32 */