]> git.saurik.com Git - apple/libc.git/blame - locale.subproj/rune.c
Libc-186.tar.gz
[apple/libc.git] / locale.subproj / rune.c
CommitLineData
e9ce8d39
A
1/*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22/*
23 * Copyright (c) 1993
24 * The Regents of the University of California. All rights reserved.
25 *
26 * This code is derived from software contributed to Berkeley by
27 * Paul Borman at Krystal Technologies.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 * 1. Redistributions of source code must retain the above copyright
33 * notice, this list of conditions and the following disclaimer.
34 * 2. Redistributions in binary form must reproduce the above copyright
35 * notice, this list of conditions and the following disclaimer in the
36 * documentation and/or other materials provided with the distribution.
37 * 3. All advertising materials mentioning features or use of this software
38 * must display the following acknowledgement:
39 * This product includes software developed by the University of
40 * California, Berkeley and its contributors.
41 * 4. Neither the name of the University nor the names of its contributors
42 * may be used to endorse or promote products derived from this software
43 * without specific prior written permission.
44 *
45 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
46 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
49 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
51 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
54 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
55 * SUCH DAMAGE.
56 */
57
58
59#include <sys/types.h>
60#include <sys/stat.h>
61
62#include <ctype.h>
63#include <errno.h>
64#include <limits.h>
65#include <rune.h>
66#include <stdio.h>
67#include <stdlib.h>
68
69extern int _none_init __P((_RuneLocale *));
70extern int _UTF2_init __P((_RuneLocale *));
71extern int _EUC_init __P((_RuneLocale *));
72static _RuneLocale *_Read_RuneMagi __P((FILE *));
73
74static char *PathLocale = 0;
75
76int
77setrunelocale(encoding)
78 char *encoding;
79{
80 FILE *fp;
81 char name[PATH_MAX];
82 _RuneLocale *rl;
83
84 if (!encoding)
85 return(EFAULT);
86
87 /*
88 * The "C" and "POSIX" locale are always here.
89 */
90 if (!strcmp(encoding, "C") || !strcmp(encoding, "POSIX")) {
91 _CurrentRuneLocale = &_DefaultRuneLocale;
92 return(0);
93 }
94
3b2a1fe8 95 if (!PathLocale)
e9ce8d39
A
96 PathLocale = _PATH_LOCALE;
97
98 sprintf(name, "%s/%s/LC_CTYPE", PathLocale, encoding);
99
100 if ((fp = fopen(name, "r")) == NULL)
101 return(ENOENT);
102
103 if ((rl = _Read_RuneMagi(fp)) == 0) {
104 fclose(fp);
105 return(EFTYPE);
106 }
107
108 if (!rl->encoding[0] || !strcmp(rl->encoding, "UTF2")) {
109 return(_UTF2_init(rl));
110 } else if (!strcmp(rl->encoding, "NONE")) {
111 return(_none_init(rl));
112 } else if (!strcmp(rl->encoding, "EUC")) {
113 return(_EUC_init(rl));
114 } else
115 return(EINVAL);
116}
117
118void
119setinvalidrune(ir)
120 rune_t ir;
121{
122 _INVALID_RUNE = ir;
123}
124
125static _RuneLocale *
126_Read_RuneMagi(fp)
127 FILE *fp;
128{
129 char *data;
130 void *np;
131 void *lastp;
132 _RuneLocale *rl;
133 _RuneEntry *rr;
134 struct stat sb;
135 int x;
136
137 if (fstat(fileno(fp), &sb) < 0)
138 return(0);
139
140 if (sb.st_size < sizeof(_RuneLocale))
141 return(0);
142
143 if ((data = malloc(sb.st_size)) == NULL)
144 return(0);
145
146 rewind(fp); /* Someone might have read the magic number once already */
147
148 if (fread(data, sb.st_size, 1, fp) != 1) {
149 free(data);
150 return(0);
151 }
152
153 rl = (_RuneLocale *)data;
154 lastp = data + sb.st_size;
155
156 rl->variable = rl + 1;
157
158 if (memcmp(rl->magic, _RUNE_MAGIC_1, sizeof(rl->magic))) {
159 free(data);
160 return(0);
161 }
162
163 rl->invalid_rune = ntohl(rl->invalid_rune);
164 rl->variable_len = ntohl(rl->variable_len);
165 rl->runetype_ext.nranges = ntohl(rl->runetype_ext.nranges);
166 rl->maplower_ext.nranges = ntohl(rl->maplower_ext.nranges);
167 rl->mapupper_ext.nranges = ntohl(rl->mapupper_ext.nranges);
168
169 for (x = 0; x < _CACHED_RUNES; ++x) {
170 rl->runetype[x] = ntohl(rl->runetype[x]);
171 rl->maplower[x] = ntohl(rl->maplower[x]);
172 rl->mapupper[x] = ntohl(rl->mapupper[x]);
173 }
174
175 rl->runetype_ext.ranges = (_RuneEntry *)rl->variable;
176 rl->variable = rl->runetype_ext.ranges + rl->runetype_ext.nranges;
177 if (rl->variable > lastp) {
178 free(data);
179 return(0);
180 }
181
182 rl->maplower_ext.ranges = (_RuneEntry *)rl->variable;
183 rl->variable = rl->maplower_ext.ranges + rl->maplower_ext.nranges;
184 if (rl->variable > lastp) {
185 free(data);
186 return(0);
187 }
188
189 rl->mapupper_ext.ranges = (_RuneEntry *)rl->variable;
190 rl->variable = rl->mapupper_ext.ranges + rl->mapupper_ext.nranges;
191 if (rl->variable > lastp) {
192 free(data);
193 return(0);
194 }
195
196 for (x = 0; x < rl->runetype_ext.nranges; ++x) {
197 rr = rl->runetype_ext.ranges;
198
199 rr[x].min = ntohl(rr[x].min);
200 rr[x].max = ntohl(rr[x].max);
201 if ((rr[x].map = ntohl(rr[x].map)) == 0) {
202 int len = rr[x].max - rr[x].min + 1;
203 rr[x].types = rl->variable;
204 rl->variable = rr[x].types + len;
205 if (rl->variable > lastp) {
206 free(data);
207 return(0);
208 }
209 while (len-- > 0)
210 rr[x].types[len] = ntohl(rr[x].types[len]);
211 } else
212 rr[x].types = 0;
213 }
214
215 for (x = 0; x < rl->maplower_ext.nranges; ++x) {
216 rr = rl->maplower_ext.ranges;
217
218 rr[x].min = ntohl(rr[x].min);
219 rr[x].max = ntohl(rr[x].max);
220 rr[x].map = ntohl(rr[x].map);
221 }
222
223 for (x = 0; x < rl->mapupper_ext.nranges; ++x) {
224 rr = rl->mapupper_ext.ranges;
225
226 rr[x].min = ntohl(rr[x].min);
227 rr[x].max = ntohl(rr[x].max);
228 rr[x].map = ntohl(rr[x].map);
229 }
230 if (((char *)rl->variable) + rl->variable_len > (char *)lastp) {
231 free(data);
232 return(0);
233 }
234
235 /*
236 * Go out and zero pointers that should be zero.
237 */
238 if (!rl->variable_len)
239 rl->variable = 0;
240
241 if (!rl->runetype_ext.nranges)
242 rl->runetype_ext.ranges = 0;
243
244 if (!rl->maplower_ext.nranges)
245 rl->maplower_ext.ranges = 0;
246
247 if (!rl->mapupper_ext.nranges)
248 rl->mapupper_ext.ranges = 0;
249
250 return(rl);
251}
252
253unsigned long
254___runetype(c)
255 _BSD_RUNE_T_ c;
256{
257 int x;
258 _RuneRange *rr = &_CurrentRuneLocale->runetype_ext;
259 _RuneEntry *re = rr->ranges;
260
261 if (c == EOF)
262 return(0);
263 for (x = 0; x < rr->nranges; ++x, ++re) {
264 if (c < re->min)
265 return(0L);
266 if (c <= re->max) {
267 if (re->types)
268 return(re->types[c - re->min]);
269 else
270 return(re->map);
271 }
272 }
273 return(0L);
274}
275
276_BSD_RUNE_T_
277___toupper(c)
278 _BSD_RUNE_T_ c;
279{
280 int x;
281 _RuneRange *rr = &_CurrentRuneLocale->mapupper_ext;
282 _RuneEntry *re = rr->ranges;
283
284 if (c == EOF)
285 return(EOF);
286 for (x = 0; x < rr->nranges; ++x, ++re) {
287 if (c < re->min)
288 return(c);
289 if (c <= re->max)
290 return(re->map + c - re->min);
291 }
292 return(c);
293}
294
295_BSD_RUNE_T_
296___tolower(c)
297 _BSD_RUNE_T_ c;
298{
299 int x;
300 _RuneRange *rr = &_CurrentRuneLocale->maplower_ext;
301 _RuneEntry *re = rr->ranges;
302
303 if (c == EOF)
304 return(EOF);
305 for (x = 0; x < rr->nranges; ++x, ++re) {
306 if (c < re->min)
307 return(c);
308 if (c <= re->max)
309 return(re->map + c - re->min);
310 }
311 return(c);
312}
313
314
315#if !defined(_USE_CTYPE_INLINE_) && !defined(_USE_CTYPE_MACROS_)
316/*
317 * See comments in <machine/ansi.h>
318 */
319int
320__istype(c, f)
321 _BSD_RUNE_T_ c;
322 unsigned long f;
323{
324 return ((((c & _CRMASK) ? ___runetype(c)
325 : _CurrentRuneLocale->runetype[c]) & f) ? 1 : 0);
326}
327
328int
329__isctype(_BSD_RUNE_T_ c, unsigned long f)
330 _BSD_RUNE_T_ c;
331 unsigned long f;
332{
333 return ((((c & _CRMASK) ? 0
334 : _DefaultRuneLocale.runetype[c]) & f) ? 1 : 0);
335}
336
337_BSD_RUNE_T_
338toupper(c)
339 _BSD_RUNE_T_ c;
340{
341 return ((c & _CRMASK) ?
342 ___toupper(c) : _CurrentRuneLocale->mapupper[c]);
343}
344
345_BSD_RUNE_T_
346tolower(c)
347 _BSD_RUNE_T_ c;
348{
349 return ((c & _CRMASK) ?
350 ___tolower(c) : _CurrentRuneLocale->maplower[c]);
351}
352#endif