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