1 /* $NetBSD: src/lib/libc/locale/rune.c,v 1.26 2004/05/09 11:26:33 kleink Exp $ */
2 /* $DragonFly: src/lib/libc/locale/rune.c,v 1.6 2005/11/20 10:18:37 swildner Exp $ */
5 * Copyright (c)1999 Citrus Project,
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
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.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * The Regents of the University of California. All rights reserved.
34 * This code is derived from software contributed to Berkeley by
35 * Paul Borman at Krystal Technologies.
37 * Redistribution and use in source and binary forms, with or without
38 * modification, are permitted provided that the following conditions
40 * 1. Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * 2. Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in the
44 * documentation and/or other materials provided with the distribution.
45 * 3. Neither the name of the University nor the names of its contributors
46 * may be used to endorse or promote products derived from this software
47 * without specific prior written permission.
49 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
50 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
62 #include <sys/types.h>
71 #include <arpa/inet.h>
73 #include "../citrus/citrus_module.h"
74 #include "../citrus/citrus_ctype.h"
76 #include "rune_local.h"
78 static int readrange(_RuneLocale
*, _RuneRange
*, _FileRuneRange
*,
80 static void _freeentry(_RuneRange
*);
81 static void _wctype_init(_RuneLocale
*rl
);
84 readrange(_RuneLocale
*rl
, _RuneRange
*rr
, _FileRuneRange
*frr
, void *lastp
,
91 _DIAGASSERT(rl
!= NULL
);
92 _DIAGASSERT(rr
!= NULL
);
93 _DIAGASSERT(frr
!= NULL
);
94 _DIAGASSERT(lastp
!= NULL
);
95 _DIAGASSERT(fp
!= NULL
);
97 re
= (_RuneEntry
*)rl
->rl_variable
;
99 rr
->rr_nranges
= ntohl(frr
->frr_nranges
);
100 if (rr
->rr_nranges
== 0) {
101 rr
->rr_rune_ranges
= NULL
;
105 rr
->rr_rune_ranges
= re
;
106 for (i
= 0; i
< rr
->rr_nranges
; i
++) {
107 if (fread(&fre
, sizeof(fre
), 1, fp
) != 1)
110 re
->re_min
= ntohl((uint32_t)fre
.fre_min
);
111 re
->re_max
= ntohl((uint32_t)fre
.fre_max
);
112 re
->re_map
= ntohl((uint32_t)fre
.fre_map
);
115 if ((void *)re
> lastp
)
118 rl
->rl_variable
= re
;
123 readentry(_RuneRange
*rr
, FILE *fp
)
129 _DIAGASSERT(rr
!= NULL
);
130 _DIAGASSERT(fp
!= NULL
);
132 re
= rr
->rr_rune_ranges
;
133 for (i
= 0; i
< rr
->rr_nranges
; i
++) {
134 if (re
[i
].re_map
!= 0) {
135 re
[i
].re_rune_types
= NULL
;
139 l
= re
[i
].re_max
- re
[i
].re_min
+ 1;
140 re
[i
].re_rune_types
= malloc(l
* sizeof(_RuneType
));
141 if (!re
[i
].re_rune_types
) {
145 memset(re
[i
].re_rune_types
, 0, l
* sizeof(_RuneType
));
147 if (fread(re
[i
].re_rune_types
, sizeof(_RuneType
), l
, fp
) != l
)
150 for (j
= 0; j
< l
; j
++)
151 re
[i
].re_rune_types
[j
] = ntohl(re
[i
].re_rune_types
[j
]);
156 for (j
= 0; j
< i
; j
++) {
157 free(re
[j
].re_rune_types
);
158 re
[j
].re_rune_types
= NULL
;
163 for (j
= 0; j
<= i
; j
++) {
164 free(re
[j
].re_rune_types
);
165 re
[j
].re_rune_types
= NULL
;
170 /* XXX: temporary implementation */
172 find_codeset(_RuneLocale
*rl
)
174 char *top
, *codeset
, *tail
, *ep
;
176 /* end of rl_variable region */
177 ep
= (char *)rl
->rl_variable
;
178 ep
+= rl
->rl_variable_len
;
179 rl
->rl_codeset
= NULL
;
180 if (!(top
= strstr(rl
->rl_variable
, _RUNE_CODESET
)))
182 tail
= strpbrk(top
, " \t");
183 codeset
= top
+ sizeof(_RUNE_CODESET
) - 1;
187 rl
->rl_codeset
= strdup(codeset
);
188 strlcpy(top
+ 1, tail
+ 1, (unsigned)(ep
- (top
+ 1)));
191 rl
->rl_codeset
= strdup(codeset
);
196 _freeentry(_RuneRange
*rr
)
201 _DIAGASSERT(rr
!= NULL
);
203 re
= rr
->rr_rune_ranges
;
204 for (i
= 0; i
< rr
->rr_nranges
; i
++) {
205 if (re
[i
].re_rune_types
)
206 free(re
[i
].re_rune_types
);
207 re
[i
].re_rune_types
= NULL
;
212 _wctype_init(_RuneLocale
*rl
)
214 memcpy(&rl
->rl_wctype
, &_DefaultRuneLocale
.rl_wctype
,
215 sizeof(rl
->rl_wctype
));
220 _Read_RuneMagi(FILE *fp
)
232 _DIAGASSERT(fp
!= NULL
);
234 if (fstat(fileno(fp
), &sb
) < 0)
237 if (sb
.st_size
< sizeof(_FileRuneLocale
))
239 /* XXX more validation? */
241 /* Someone might have read the magic number once already */
244 if (fread(&frl
, sizeof(frl
), 1, fp
) != 1)
246 if (memcmp(frl
.frl_magic
, _RUNE_MAGIC_1
, sizeof(frl
.frl_magic
)))
249 hostdatalen
= sizeof(*rl
) + ntohl((u_int32_t
)frl
.frl_variable_len
) +
250 ntohl(frl
.frl_runetype_ext
.frr_nranges
) * sizeof(_RuneEntry
) +
251 ntohl(frl
.frl_maplower_ext
.frr_nranges
) * sizeof(_RuneEntry
) +
252 ntohl(frl
.frl_mapupper_ext
.frr_nranges
) * sizeof(_RuneEntry
);
254 if ((hostdata
= malloc(hostdatalen
)) == NULL
)
256 memset(hostdata
, 0, hostdatalen
);
257 lastp
= hostdata
+ hostdatalen
;
259 rl
= (_RuneLocale
*)(void *)hostdata
;
260 rl
->rl_variable
= rl
+ 1;
262 memcpy(rl
->rl_magic
, frl
.frl_magic
, sizeof(rl
->rl_magic
));
263 memcpy(rl
->rl_encoding
, frl
.frl_encoding
, sizeof(rl
->rl_encoding
));
265 rl
->rl_invalid_rune
= ntohl((u_int32_t
)frl
.frl_invalid_rune
);
266 rl
->rl_variable_len
= ntohl((u_int32_t
)frl
.frl_variable_len
);
268 for (x
= 0; x
< _CACHED_RUNES
; ++x
) {
269 rl
->rl_runetype
[x
] = ntohl(frl
.frl_runetype
[x
]);
271 /* XXX assumes rune_t = u_int32_t */
272 rl
->rl_maplower
[x
] = ntohl((uint32_t)frl
.frl_maplower
[x
]);
273 rl
->rl_mapupper
[x
] = ntohl((uint32_t)frl
.frl_mapupper
[x
]);
276 if (readrange(rl
, &rl
->rl_runetype_ext
, &frl
.frl_runetype_ext
,
281 if (readrange(rl
, &rl
->rl_maplower_ext
, &frl
.frl_maplower_ext
,
286 if (readrange(rl
, &rl
->rl_mapupper_ext
, &frl
.frl_mapupper_ext
,
292 if (readentry(&rl
->rl_runetype_ext
, fp
) != 0) {
297 if ((uint8_t *)rl
->rl_variable
+ rl
->rl_variable_len
>
299 _freeentry(&rl
->rl_runetype_ext
);
303 if (rl
->rl_variable_len
== 0)
304 rl
->rl_variable
= NULL
;
305 else if (fread(rl
->rl_variable
, rl
->rl_variable_len
, 1, fp
) != 1) {
306 _freeentry(&rl
->rl_runetype_ext
);
313 /* error if we have junk at the tail */
314 if (ftell(fp
) != sb
.st_size
) {
315 _freeentry(&rl
->rl_runetype_ext
);
324 _NukeRune(_RuneLocale
*rl
)
326 _DIAGASSERT(rl
!= NULL
);
328 if (rl
!= &_DefaultRuneLocale
) {
329 _freeentry(&rl
->rl_runetype_ext
);
330 if (rl
->rl_codeset
!= NULL
)
331 free(rl
->rl_codeset
);
332 if (rl
->rl_citrus_ctype
)
333 _citrus_ctype_close(rl
->rl_citrus_ctype
);