]> git.saurik.com Git - apple/libc.git/blob - locale/FreeBSD/rune.c
Libc-1439.100.3.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 #pragma clang diagnostic push
38 #pragma clang diagnostic ignored "-Wstrict-prototypes"
39
40 #ifndef RUNEOFF32
41 #if defined(LIBC_SCCS) && !defined(lint)
42 static char sccsid[] = "@(#)rune.c 8.1 (Berkeley) 6/4/93";
43 #endif /* LIBC_SCCS and not lint */
44 #include <sys/cdefs.h>
45 __FBSDID("$FreeBSD: src/lib/libc/locale/rune.c,v 1.12 2004/07/29 06:16:19 tjr Exp $");
46
47 #include "xlocale_private.h"
48
49 #include "namespace.h"
50 #include <arpa/inet.h>
51 #include <errno.h>
52 #include <runetype.h>
53 #else
54 #include "runetype.h"
55 #endif /* !RUNEOFF32 */
56 #include <stdio.h>
57 #ifndef RUNEOFF32
58 #include <string.h>
59 #include <stdlib.h>
60 #include <sys/types.h>
61 #include <sys/stat.h>
62 #include "un-namespace.h"
63 #endif /* !RUNEOFF32 */
64
65 #if defined(__LP64__) || defined(RUNEOFF32)
66 /*
67 * Because the LC_CTYPE files were created with a 32-bit program, we need
68 * to adjust for the larger pointers in LP64 (the longs have already been
69 * replaced by 32-bit equivalents). Also, natural alignment will pad
70 * 64-bit types to 8-byte boundaries, and make structures containing
71 * 64-bit types sized to 8-byte boundaries.
72 */
73 #include <stddef.h>
74 #ifndef RUNEOFF32
75 #include "rune32.h"
76 #define BYTES32BITS 4
77 #define BYTES64BITS 8
78 /* whether to skip over a pointer or not (one-to-one with off64) */
79 int skip[] = {
80 1,
81 1,
82 0,
83 1,
84 0,
85 1,
86 0,
87 1,
88 1,
89 1,
90 0
91 };
92 #endif /* !RUNEOFF32 */
93 int off64[] = {
94 offsetof(_RuneLocale, __sgetrune),
95 offsetof(_RuneLocale, __sputrune),
96 offsetof(_RuneLocale, __runetype_ext),
97 offsetof(_RuneLocale, __runetype_ext) + offsetof(_RuneRange, __ranges),
98 offsetof(_RuneLocale, __maplower_ext),
99 offsetof(_RuneLocale, __maplower_ext) + offsetof(_RuneRange, __ranges),
100 offsetof(_RuneLocale, __mapupper_ext),
101 offsetof(_RuneLocale, __mapupper_ext) + offsetof(_RuneRange, __ranges),
102 offsetof(_RuneLocale, __variable),
103 offsetof(_RuneLocale, __charclasses),
104 sizeof(_RuneLocale)
105 };
106 #define NOFF (sizeof(off64) / sizeof(int))
107 #ifdef RUNEOFF32
108 /*
109 * This program generates a header file (on stdout) that containes the 32-bit
110 * offsets, plus some 32-bit sizes
111 */
112 main()
113 {
114 int i;
115 printf("#define SIZEOF32_RUNEENTRY %d\n", sizeof(_RuneEntry));
116 printf("#define SIZEOF32_RUNELOCALE %d\n", sizeof(_RuneLocale));
117 printf("int off32[] = {\n");
118 for(i = 0; i < NOFF; i++)
119 printf("\t%d,\n", off64[i]);
120 printf("};\n");
121 return 0;
122 }
123 #endif /* RUNEOFF32 */
124 #else /* !__LP64__ && !RUNEOFF32 */
125 #define SIZEOF32_RUNELOCALE sizeof(_RuneLocale)
126 #endif /* __LP64__ || RUNEOFF32 */
127
128 #ifndef RUNEOFF32
129 struct __xlocale_st_runelocale *
130 _Read_RuneMagi(fp)
131 FILE *fp;
132 {
133 struct __xlocale_st_runelocale *data;
134 void *lastp;
135 _RuneLocale *rl;
136 _RuneEntry *rr;
137 struct stat sb;
138 int x, saverr;
139
140 if (_fstat(fileno(fp), &sb) < 0)
141 return (NULL);
142
143 if (sb.st_size < SIZEOF32_RUNELOCALE) {
144 errno = EFTYPE;
145 return (NULL);
146 }
147
148 #ifdef __LP64__
149 /* will adjust later */
150 if ((data = (struct __xlocale_st_runelocale *)malloc(sizeof(struct __xlocale_st_runelocale))) == NULL)
151 #else /* !__LP64__ */
152 if ((data = (struct __xlocale_st_runelocale *)malloc(sizeof(struct __xlocale_st_runelocale) - sizeof(_RuneLocale) + sb.st_size)) == NULL)
153 #endif /* __LP64__ */
154 return (NULL);
155 data->__refcount = 1;
156 data->__free_extra = NULL;
157
158 errno = 0;
159 rewind(fp); /* Someone might have read the magic number once already */
160 if (errno) {
161 saverr = errno;
162 free(data);
163 errno = saverr;
164 return (NULL);
165 }
166
167 rl = &data->_CurrentRuneLocale;
168
169 #ifdef __LP64__
170 if (fread(rl, SIZEOF32_RUNELOCALE, 1, fp) != 1)
171 #else /* !__LP64__ */
172 if (fread(rl, sb.st_size, 1, fp) != 1)
173 #endif /* __LP64__ */
174 {
175 saverr = errno;
176 free(data);
177 errno = saverr;
178 return (NULL);
179 }
180
181 #ifndef __LP64__
182 lastp = (char *)rl + sb.st_size;
183
184 rl->__variable = rl + 1;
185 #endif /* __LP64__ */
186
187 if (memcmp(rl->__magic, _RUNE_MAGIC_A, sizeof(rl->__magic))) {
188 free(data);
189 errno = EFTYPE;
190 return (NULL);
191 }
192
193 #ifdef __LP64__
194 /* shift things into the right position */
195 for (x = NOFF - 2; x >= 0; x--)
196 memmove((char *)rl + off64[x] + (skip[x] ? BYTES64BITS : 0),
197 (char *)rl + off32[x] + (skip[x] ? BYTES32BITS : 0),
198 off32[x + 1] - off32[x] - (skip[x] ? BYTES32BITS : 0));
199 #endif /* __LP64__ */
200 #if __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN
201 rl->__invalid_rune = ntohl(rl->__invalid_rune);
202 rl->__variable_len = ntohl(rl->__variable_len);
203 rl->__ncharclasses = ntohl(rl->__ncharclasses);
204 rl->__runetype_ext.__nranges = ntohl(rl->__runetype_ext.__nranges);
205 rl->__maplower_ext.__nranges = ntohl(rl->__maplower_ext.__nranges);
206 rl->__mapupper_ext.__nranges = ntohl(rl->__mapupper_ext.__nranges);
207
208 for (x = 0; x < _CACHED_RUNES; ++x) {
209 rl->__runetype[x] = ntohl(rl->__runetype[x]);
210 rl->__maplower[x] = ntohl(rl->__maplower[x]);
211 rl->__mapupper[x] = ntohl(rl->__mapupper[x]);
212 }
213 #endif /* __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN */
214
215 #ifdef __LP64__
216 {
217 int count = rl->__runetype_ext.__nranges + rl->__maplower_ext.__nranges
218 + rl->__mapupper_ext.__nranges;
219 int extra = sb.st_size - SIZEOF32_RUNELOCALE - count * SIZEOF32_RUNEENTRY - rl->__ncharclasses * sizeof(_RuneCharClass);
220 _RuneEntry *rp;
221
222 if (extra < 0) {
223 saverr = errno;
224 free(data);
225 errno = saverr;
226 return (NULL);
227 }
228 if ((data = (struct __xlocale_st_runelocale *)reallocf(data, sizeof(struct __xlocale_st_runelocale)
229 + count * sizeof(_RuneEntry)
230 + rl->__ncharclasses * sizeof(_RuneCharClass)
231 + extra)) == NULL)
232 return (NULL);
233 rl = &data->_CurrentRuneLocale;
234 rl->__variable = rl + 1;
235 rp = (_RuneEntry *)rl->__variable;
236 for (x = 0; x < count; x++, rp++)
237 if (fread(rp, SIZEOF32_RUNEENTRY, 1, fp) != 1) {
238 saverr = errno;
239 free(data);
240 errno = saverr;
241 return (NULL);
242 }
243 if (rl->__ncharclasses > 0) {
244 if (fread(rp, sizeof(_RuneCharClass), rl->__ncharclasses, fp) != rl->__ncharclasses) {
245 saverr = errno;
246 free(data);
247 errno = saverr;
248 return (NULL);
249 }
250 rp = (_RuneEntry *)((char *)rp + rl->__ncharclasses * sizeof(_RuneCharClass));
251 }
252 if (extra > 0 && fread(rp, extra, 1, fp) != 1) {
253 saverr = errno;
254 free(data);
255 errno = saverr;
256 return (NULL);
257 }
258 lastp = (char *)rp + extra;
259 }
260 #endif /* __LP64__ */
261 rl->__runetype_ext.__ranges = (_RuneEntry *)rl->__variable;
262 rl->__variable = rl->__runetype_ext.__ranges +
263 rl->__runetype_ext.__nranges;
264 if (rl->__variable > lastp) {
265 free(data);
266 errno = EFTYPE;
267 return (NULL);
268 }
269
270 rl->__maplower_ext.__ranges = (_RuneEntry *)rl->__variable;
271 rl->__variable = rl->__maplower_ext.__ranges +
272 rl->__maplower_ext.__nranges;
273 if (rl->__variable > lastp) {
274 free(data);
275 errno = EFTYPE;
276 return (NULL);
277 }
278
279 rl->__mapupper_ext.__ranges = (_RuneEntry *)rl->__variable;
280 rl->__variable = rl->__mapupper_ext.__ranges +
281 rl->__mapupper_ext.__nranges;
282 if (rl->__variable > lastp) {
283 free(data);
284 errno = EFTYPE;
285 return (NULL);
286 }
287
288 for (x = 0; x < rl->__runetype_ext.__nranges; ++x) {
289 rr = rl->__runetype_ext.__ranges;
290
291 #if __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN
292 rr[x].__min = ntohl(rr[x].__min);
293 rr[x].__max = ntohl(rr[x].__max);
294 #endif /* __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN */
295 if ((rr[x].__map = ntohl(rr[x].__map)) == 0) {
296 int len = rr[x].__max - rr[x].__min + 1;
297 rr[x].__types = rl->__variable;
298 rl->__variable = rr[x].__types + len;
299 if (rl->__variable > lastp) {
300 free(data);
301 errno = EFTYPE;
302 return (NULL);
303 }
304 #if __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN
305 while (len-- > 0)
306 rr[x].__types[len] = ntohl(rr[x].__types[len]);
307 #endif /* __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN */
308 } else
309 rr[x].__types = 0;
310 }
311
312 #if __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN
313 for (x = 0; x < rl->__maplower_ext.__nranges; ++x) {
314 rr = rl->__maplower_ext.__ranges;
315
316 rr[x].__min = ntohl(rr[x].__min);
317 rr[x].__max = ntohl(rr[x].__max);
318 rr[x].__map = ntohl(rr[x].__map);
319 }
320
321 for (x = 0; x < rl->__mapupper_ext.__nranges; ++x) {
322 rr = rl->__mapupper_ext.__ranges;
323
324 rr[x].__min = ntohl(rr[x].__min);
325 rr[x].__max = ntohl(rr[x].__max);
326 rr[x].__map = ntohl(rr[x].__map);
327 }
328 #endif /* __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN */
329
330 if (rl->__ncharclasses > 0) {
331 rl->__charclasses = (_RuneCharClass *)rl->__variable;
332 rl->__variable = (void *)(rl->__charclasses + rl->__ncharclasses);
333 if (rl->__variable > lastp) {
334 free(data);
335 errno = EFTYPE;
336 return (NULL);
337 }
338 #if __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN
339 for (x = 0; x < rl->__ncharclasses; ++x)
340 rl->__charclasses[x].__mask = ntohl(rl->__charclasses[x].__mask);
341 #endif /* __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN */
342 }
343
344 if (((char *)rl->__variable) + rl->__variable_len > (char *)lastp) {
345 free(data);
346 errno = EFTYPE;
347 return (NULL);
348 }
349
350 /*
351 * Go out and zero pointers that should be zero.
352 */
353 if (!rl->__variable_len)
354 rl->__variable = 0;
355
356 if (!rl->__runetype_ext.__nranges)
357 rl->__runetype_ext.__ranges = 0;
358
359 if (!rl->__maplower_ext.__nranges)
360 rl->__maplower_ext.__ranges = 0;
361
362 if (!rl->__mapupper_ext.__nranges)
363 rl->__mapupper_ext.__ranges = 0;
364
365 data->__datasize = lastp - (void *)data;
366 return (data);
367 }
368 #endif /* !RUNEOFF32 */
369 #pragma clang diagnostic pop