]> git.saurik.com Git - apple/libc.git/blame - locale/FreeBSD/rune.c
Libc-1439.40.11.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
70ad1dc8
A
37#pragma clang diagnostic push
38#pragma clang diagnostic ignored "-Wstrict-prototypes"
39
ad3c9f2a 40#ifndef RUNEOFF32
5b2abdfb
A
41#if defined(LIBC_SCCS) && !defined(lint)
42static char sccsid[] = "@(#)rune.c 8.1 (Berkeley) 6/4/93";
43#endif /* LIBC_SCCS and not lint */
9385eb3d 44#include <sys/cdefs.h>
3d9156a7 45__FBSDID("$FreeBSD: src/lib/libc/locale/rune.c,v 1.12 2004/07/29 06:16:19 tjr Exp $");
e9ce8d39 46
ad3c9f2a
A
47#include "xlocale_private.h"
48
9385eb3d
A
49#include "namespace.h"
50#include <arpa/inet.h>
51#include <errno.h>
3d9156a7 52#include <runetype.h>
ad3c9f2a
A
53#else
54#include "runetype.h"
55#endif /* !RUNEOFF32 */
e9ce8d39 56#include <stdio.h>
ad3c9f2a 57#ifndef RUNEOFF32
5b2abdfb 58#include <string.h>
e9ce8d39 59#include <stdlib.h>
5b2abdfb
A
60#include <sys/types.h>
61#include <sys/stat.h>
9385eb3d 62#include "un-namespace.h"
ad3c9f2a 63#endif /* !RUNEOFF32 */
e9ce8d39 64
ad3c9f2a
A
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) */
79int 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 */
93int 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 */
112main()
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
129struct __xlocale_st_runelocale *
e9ce8d39
A
130_Read_RuneMagi(fp)
131 FILE *fp;
132{
ad3c9f2a 133 struct __xlocale_st_runelocale *data;
e9ce8d39
A
134 void *lastp;
135 _RuneLocale *rl;
136 _RuneEntry *rr;
137 struct stat sb;
9385eb3d 138 int x, saverr;
e9ce8d39 139
9385eb3d
A
140 if (_fstat(fileno(fp), &sb) < 0)
141 return (NULL);
e9ce8d39 142
ad3c9f2a 143 if (sb.st_size < SIZEOF32_RUNELOCALE) {
9385eb3d
A
144 errno = EFTYPE;
145 return (NULL);
146 }
e9ce8d39 147
ad3c9f2a
A
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__ */
9385eb3d 154 return (NULL);
ad3c9f2a
A
155 data->__refcount = 1;
156 data->__free_extra = NULL;
e9ce8d39 157
9385eb3d 158 errno = 0;
e9ce8d39 159 rewind(fp); /* Someone might have read the magic number once already */
9385eb3d
A
160 if (errno) {
161 saverr = errno;
162 free(data);
163 errno = saverr;
164 return (NULL);
165 }
e9ce8d39 166
ad3c9f2a
A
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 {
9385eb3d 175 saverr = errno;
e9ce8d39 176 free(data);
9385eb3d
A
177 errno = saverr;
178 return (NULL);
e9ce8d39
A
179 }
180
ad3c9f2a
A
181#ifndef __LP64__
182 lastp = (char *)rl + sb.st_size;
e9ce8d39 183
3d9156a7 184 rl->__variable = rl + 1;
ad3c9f2a 185#endif /* __LP64__ */
e9ce8d39 186
ad3c9f2a 187 if (memcmp(rl->__magic, _RUNE_MAGIC_A, sizeof(rl->__magic))) {
e9ce8d39 188 free(data);
9385eb3d
A
189 errno = EFTYPE;
190 return (NULL);
e9ce8d39
A
191 }
192
ad3c9f2a
A
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
3d9156a7
A
201 rl->__invalid_rune = ntohl(rl->__invalid_rune);
202 rl->__variable_len = ntohl(rl->__variable_len);
ad3c9f2a 203 rl->__ncharclasses = ntohl(rl->__ncharclasses);
3d9156a7
A
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);
e9ce8d39
A
207
208 for (x = 0; x < _CACHED_RUNES; ++x) {
3d9156a7
A
209 rl->__runetype[x] = ntohl(rl->__runetype[x]);
210 rl->__maplower[x] = ntohl(rl->__maplower[x]);
211 rl->__mapupper[x] = ntohl(rl->__mapupper[x]);
e9ce8d39 212 }
ad3c9f2a 213#endif /* __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN */
e9ce8d39 214
ad3c9f2a
A
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__ */
3d9156a7
A
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) {
e9ce8d39 265 free(data);
9385eb3d
A
266 errno = EFTYPE;
267 return (NULL);
e9ce8d39
A
268 }
269
3d9156a7
A
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) {
e9ce8d39 274 free(data);
9385eb3d
A
275 errno = EFTYPE;
276 return (NULL);
e9ce8d39
A
277 }
278
3d9156a7
A
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) {
e9ce8d39 283 free(data);
9385eb3d
A
284 errno = EFTYPE;
285 return (NULL);
e9ce8d39
A
286 }
287
3d9156a7
A
288 for (x = 0; x < rl->__runetype_ext.__nranges; ++x) {
289 rr = rl->__runetype_ext.__ranges;
e9ce8d39 290
ad3c9f2a 291#if __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN
3d9156a7
A
292 rr[x].__min = ntohl(rr[x].__min);
293 rr[x].__max = ntohl(rr[x].__max);
ad3c9f2a 294#endif /* __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN */
3d9156a7
A
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) {
e9ce8d39 300 free(data);
9385eb3d
A
301 errno = EFTYPE;
302 return (NULL);
e9ce8d39 303 }
ad3c9f2a 304#if __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN
e9ce8d39 305 while (len-- > 0)
3d9156a7 306 rr[x].__types[len] = ntohl(rr[x].__types[len]);
ad3c9f2a 307#endif /* __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN */
e9ce8d39 308 } else
3d9156a7 309 rr[x].__types = 0;
e9ce8d39
A
310 }
311
ad3c9f2a 312#if __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN
3d9156a7
A
313 for (x = 0; x < rl->__maplower_ext.__nranges; ++x) {
314 rr = rl->__maplower_ext.__ranges;
e9ce8d39 315
3d9156a7
A
316 rr[x].__min = ntohl(rr[x].__min);
317 rr[x].__max = ntohl(rr[x].__max);
318 rr[x].__map = ntohl(rr[x].__map);
e9ce8d39
A
319 }
320
3d9156a7
A
321 for (x = 0; x < rl->__mapupper_ext.__nranges; ++x) {
322 rr = rl->__mapupper_ext.__ranges;
e9ce8d39 323
3d9156a7
A
324 rr[x].__min = ntohl(rr[x].__min);
325 rr[x].__max = ntohl(rr[x].__max);
326 rr[x].__map = ntohl(rr[x].__map);
e9ce8d39 327 }
ad3c9f2a
A
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
3d9156a7 344 if (((char *)rl->__variable) + rl->__variable_len > (char *)lastp) {
e9ce8d39 345 free(data);
9385eb3d
A
346 errno = EFTYPE;
347 return (NULL);
e9ce8d39
A
348 }
349
350 /*
351 * Go out and zero pointers that should be zero.
352 */
3d9156a7
A
353 if (!rl->__variable_len)
354 rl->__variable = 0;
e9ce8d39 355
3d9156a7
A
356 if (!rl->__runetype_ext.__nranges)
357 rl->__runetype_ext.__ranges = 0;
e9ce8d39 358
3d9156a7
A
359 if (!rl->__maplower_ext.__nranges)
360 rl->__maplower_ext.__ranges = 0;
e9ce8d39 361
3d9156a7
A
362 if (!rl->__mapupper_ext.__nranges)
363 rl->__mapupper_ext.__ranges = 0;
e9ce8d39 364
ad3c9f2a
A
365 data->__datasize = lastp - (void *)data;
366 return (data);
e9ce8d39 367}
ad3c9f2a 368#endif /* !RUNEOFF32 */
70ad1dc8 369#pragma clang diagnostic pop