]> git.saurik.com Git - apple/libc.git/blame - locale/FreeBSD/rune.c
Libc-1244.50.9.tar.gz
[apple/libc.git] / locale / FreeBSD / rune.c
CommitLineData
5b2abdfb 1/*-
e9ce8d39
A
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
ad3c9f2a 37#ifndef RUNEOFF32
5b2abdfb
A
38#if defined(LIBC_SCCS) && !defined(lint)
39static char sccsid[] = "@(#)rune.c 8.1 (Berkeley) 6/4/93";
40#endif /* LIBC_SCCS and not lint */
9385eb3d 41#include <sys/cdefs.h>
3d9156a7 42__FBSDID("$FreeBSD: src/lib/libc/locale/rune.c,v 1.12 2004/07/29 06:16:19 tjr Exp $");
e9ce8d39 43
ad3c9f2a
A
44#include "xlocale_private.h"
45
9385eb3d
A
46#include "namespace.h"
47#include <arpa/inet.h>
48#include <errno.h>
3d9156a7 49#include <runetype.h>
ad3c9f2a
A
50#else
51#include "runetype.h"
52#endif /* !RUNEOFF32 */
e9ce8d39 53#include <stdio.h>
ad3c9f2a 54#ifndef RUNEOFF32
5b2abdfb 55#include <string.h>
e9ce8d39 56#include <stdlib.h>
5b2abdfb
A
57#include <sys/types.h>
58#include <sys/stat.h>
9385eb3d 59#include "un-namespace.h"
ad3c9f2a 60#endif /* !RUNEOFF32 */
e9ce8d39 61
ad3c9f2a
A
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) */
76int 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 */
90int 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 */
109main()
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
126struct __xlocale_st_runelocale *
e9ce8d39
A
127_Read_RuneMagi(fp)
128 FILE *fp;
129{
ad3c9f2a 130 struct __xlocale_st_runelocale *data;
e9ce8d39
A
131 void *lastp;
132 _RuneLocale *rl;
133 _RuneEntry *rr;
134 struct stat sb;
9385eb3d 135 int x, saverr;
e9ce8d39 136
9385eb3d
A
137 if (_fstat(fileno(fp), &sb) < 0)
138 return (NULL);
e9ce8d39 139
ad3c9f2a 140 if (sb.st_size < SIZEOF32_RUNELOCALE) {
9385eb3d
A
141 errno = EFTYPE;
142 return (NULL);
143 }
e9ce8d39 144
ad3c9f2a
A
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__ */
9385eb3d 151 return (NULL);
ad3c9f2a
A
152 data->__refcount = 1;
153 data->__free_extra = NULL;
e9ce8d39 154
9385eb3d 155 errno = 0;
e9ce8d39 156 rewind(fp); /* Someone might have read the magic number once already */
9385eb3d
A
157 if (errno) {
158 saverr = errno;
159 free(data);
160 errno = saverr;
161 return (NULL);
162 }
e9ce8d39 163
ad3c9f2a
A
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 {
9385eb3d 172 saverr = errno;
e9ce8d39 173 free(data);
9385eb3d
A
174 errno = saverr;
175 return (NULL);
e9ce8d39
A
176 }
177
ad3c9f2a
A
178#ifndef __LP64__
179 lastp = (char *)rl + sb.st_size;
e9ce8d39 180
3d9156a7 181 rl->__variable = rl + 1;
ad3c9f2a 182#endif /* __LP64__ */
e9ce8d39 183
ad3c9f2a 184 if (memcmp(rl->__magic, _RUNE_MAGIC_A, sizeof(rl->__magic))) {
e9ce8d39 185 free(data);
9385eb3d
A
186 errno = EFTYPE;
187 return (NULL);
e9ce8d39
A
188 }
189
ad3c9f2a
A
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
3d9156a7
A
198 rl->__invalid_rune = ntohl(rl->__invalid_rune);
199 rl->__variable_len = ntohl(rl->__variable_len);
ad3c9f2a 200 rl->__ncharclasses = ntohl(rl->__ncharclasses);
3d9156a7
A
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);
e9ce8d39
A
204
205 for (x = 0; x < _CACHED_RUNES; ++x) {
3d9156a7
A
206 rl->__runetype[x] = ntohl(rl->__runetype[x]);
207 rl->__maplower[x] = ntohl(rl->__maplower[x]);
208 rl->__mapupper[x] = ntohl(rl->__mapupper[x]);
e9ce8d39 209 }
ad3c9f2a 210#endif /* __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN */
e9ce8d39 211
ad3c9f2a
A
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__ */
3d9156a7
A
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) {
e9ce8d39 262 free(data);
9385eb3d
A
263 errno = EFTYPE;
264 return (NULL);
e9ce8d39
A
265 }
266
3d9156a7
A
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) {
e9ce8d39 271 free(data);
9385eb3d
A
272 errno = EFTYPE;
273 return (NULL);
e9ce8d39
A
274 }
275
3d9156a7
A
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) {
e9ce8d39 280 free(data);
9385eb3d
A
281 errno = EFTYPE;
282 return (NULL);
e9ce8d39
A
283 }
284
3d9156a7
A
285 for (x = 0; x < rl->__runetype_ext.__nranges; ++x) {
286 rr = rl->__runetype_ext.__ranges;
e9ce8d39 287
ad3c9f2a 288#if __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN
3d9156a7
A
289 rr[x].__min = ntohl(rr[x].__min);
290 rr[x].__max = ntohl(rr[x].__max);
ad3c9f2a 291#endif /* __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN */
3d9156a7
A
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) {
e9ce8d39 297 free(data);
9385eb3d
A
298 errno = EFTYPE;
299 return (NULL);
e9ce8d39 300 }
ad3c9f2a 301#if __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN
e9ce8d39 302 while (len-- > 0)
3d9156a7 303 rr[x].__types[len] = ntohl(rr[x].__types[len]);
ad3c9f2a 304#endif /* __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN */
e9ce8d39 305 } else
3d9156a7 306 rr[x].__types = 0;
e9ce8d39
A
307 }
308
ad3c9f2a 309#if __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN
3d9156a7
A
310 for (x = 0; x < rl->__maplower_ext.__nranges; ++x) {
311 rr = rl->__maplower_ext.__ranges;
e9ce8d39 312
3d9156a7
A
313 rr[x].__min = ntohl(rr[x].__min);
314 rr[x].__max = ntohl(rr[x].__max);
315 rr[x].__map = ntohl(rr[x].__map);
e9ce8d39
A
316 }
317
3d9156a7
A
318 for (x = 0; x < rl->__mapupper_ext.__nranges; ++x) {
319 rr = rl->__mapupper_ext.__ranges;
e9ce8d39 320
3d9156a7
A
321 rr[x].__min = ntohl(rr[x].__min);
322 rr[x].__max = ntohl(rr[x].__max);
323 rr[x].__map = ntohl(rr[x].__map);
e9ce8d39 324 }
ad3c9f2a
A
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
3d9156a7 341 if (((char *)rl->__variable) + rl->__variable_len > (char *)lastp) {
e9ce8d39 342 free(data);
9385eb3d
A
343 errno = EFTYPE;
344 return (NULL);
e9ce8d39
A
345 }
346
347 /*
348 * Go out and zero pointers that should be zero.
349 */
3d9156a7
A
350 if (!rl->__variable_len)
351 rl->__variable = 0;
e9ce8d39 352
3d9156a7
A
353 if (!rl->__runetype_ext.__nranges)
354 rl->__runetype_ext.__ranges = 0;
e9ce8d39 355
3d9156a7
A
356 if (!rl->__maplower_ext.__nranges)
357 rl->__maplower_ext.__ranges = 0;
e9ce8d39 358
3d9156a7
A
359 if (!rl->__mapupper_ext.__nranges)
360 rl->__mapupper_ext.__ranges = 0;
e9ce8d39 361
ad3c9f2a
A
362 data->__datasize = lastp - (void *)data;
363 return (data);
e9ce8d39 364}
ad3c9f2a 365#endif /* !RUNEOFF32 */