1. refactoring new locale-db(RuneCT10) loading method with mmap(2).

2. remove unused field from _RuneLocale.
3. localeio(CITRUS=no) can read new locale-db(RuneCT10) now.
This commit is contained in:
tnozaki 2010-06-19 13:26:51 +00:00
parent 9b010439be
commit 3cc4120729
13 changed files with 526 additions and 712 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: citrus_lc_ctype.c,v 1.8 2010/06/13 04:14:56 tnozaki Exp $ */
/* $NetBSD: citrus_lc_ctype.c,v 1.9 2010/06/19 13:26:51 tnozaki Exp $ */
/*-
* Copyright (c)2008 Citrus Project,
@ -28,7 +28,7 @@
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: citrus_lc_ctype.c,v 1.8 2010/06/13 04:14:56 tnozaki Exp $");
__RCSID("$NetBSD: citrus_lc_ctype.c,v 1.9 2010/06/19 13:26:51 tnozaki Exp $");
#endif /* LIBC_SCCS and not lint */
#include "reentrant.h"
@ -56,6 +56,7 @@ __RCSID("$NetBSD: citrus_lc_ctype.c,v 1.8 2010/06/13 04:14:56 tnozaki Exp $");
#include "citrus_aliasname_local.h"
#include "citrus_module.h"
#include "citrus_ctype.h"
#include "citrus_mmap.h"
#include "runetype_local.h"
#include "multibyte.h"
@ -77,9 +78,8 @@ _citrus_LC_CTYPE_create_impl(const char * __restrict root,
const char * __restrict name, _RuneLocale ** __restrict pdata)
{
char path[PATH_MAX + 1];
FILE *fp;
_RuneLocale *data;
int ret;
struct _region r;
_DIAGASSERT(root != NULL);
_DIAGASSERT(name != NULL);
@ -87,37 +87,12 @@ _citrus_LC_CTYPE_create_impl(const char * __restrict root,
snprintf(path, sizeof(path),
"%s/%s/LC_CTYPE", root, name);
fp = fopen(path, "r");
if (fp == NULL)
return ENOENT;
data = _Read_RuneMagi(fp);
if (data == NULL) {
data = _Read_CTypeAsRune(fp);
if (data == NULL) {
fclose(fp);
return EFTYPE;
}
ret = _citrus_map_file(&r, path);
if (!ret) {
ret = _rune_load((const char *)r.r_head, r.r_size, pdata);
_citrus_unmap_file(&r);
}
fclose(fp);
ret = _citrus_ctype_open(&data->rl_citrus_ctype, data->rl_encoding,
data->rl_variable, data->rl_variable_len, _PRIVSIZE);
if (!ret)
ret = __runetable_to_netbsd_ctype(data);
if (ret || __mb_len_max_runtime <
_citrus_ctype_get_mb_cur_max(data->rl_citrus_ctype)) {
_NukeRune(data);
return EINVAL;
}
data->rl_wctrans[_WCTRANS_INDEX_LOWER].te_name = "tolower";
data->rl_wctrans[_WCTRANS_INDEX_LOWER].te_cached = &data->rl_maplower[0];
data->rl_wctrans[_WCTRANS_INDEX_LOWER].te_extmap = &data->rl_maplower_ext;
data->rl_wctrans[_WCTRANS_INDEX_UPPER].te_name = "toupper";
data->rl_wctrans[_WCTRANS_INDEX_UPPER].te_cached = &data->rl_mapupper[0];
data->rl_wctrans[_WCTRANS_INDEX_UPPER].te_extmap = &data->rl_mapupper_ext;
*pdata = data;
return 0;
return ret;
}
static __inline void

View File

@ -1,5 +1,5 @@
# from: @(#)Makefile.inc 5.1 (Berkeley) 2/18/91
# $NetBSD: Makefile.inc,v 1.57 2010/06/07 13:52:30 tnozaki Exp $
# $NetBSD: Makefile.inc,v 1.58 2010/06/19 13:26:52 tnozaki Exp $
# locale sources
.PATH: ${ARCHDIR}/locale ${.CURDIR}/locale
@ -16,10 +16,9 @@ SRCS+= _def_messages.c _def_monetary.c _def_numeric.c _def_time.c \
# citrus multibyte locale support
# we have quirk for libc.a - see the last part of lib/libc/Makefile
CPPFLAGS+= -DWITH_RUNE -I${.CURDIR}
SRCS+= _wctrans.c _wctype.c rune.c runeglue.c runetable.c \
SRCS+= _wctrans.c _wctype.c rune.c runetable.c \
multibyte_c90.c multibyte_amd1.c iswctype_mb.c
CPPFLAGS.rune.c+= -I${LIBCDIR}/citrus
CPPFLAGS.runeglue.c+= -I${LIBCDIR}/citrus
CPPFLAGS.runetable.c+= -I${LIBCDIR}/citrus
CPPFLAGS.multibyte_c90.c+= -I${LIBCDIR}/citrus
CPPFLAGS.multibyte_amd1.c+= -I${LIBCDIR}/citrus

View File

@ -1,4 +1,4 @@
/* $NetBSD: bsdctype.c,v 1.7 2010/06/13 04:14:57 tnozaki Exp $ */
/* $NetBSD: bsdctype.c,v 1.8 2010/06/19 13:26:52 tnozaki Exp $ */
/*-
* Copyright (c)2008 Citrus Project,
@ -28,11 +28,10 @@
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: bsdctype.c,v 1.7 2010/06/13 04:14:57 tnozaki Exp $");
__RCSID("$NetBSD: bsdctype.c,v 1.8 2010/06/19 13:26:52 tnozaki Exp $");
#endif /* LIBC_SCCS and not lint */
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/endian.h>
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
@ -42,6 +41,7 @@ __RCSID("$NetBSD: bsdctype.c,v 1.7 2010/06/13 04:14:57 tnozaki Exp $");
#include <unistd.h>
#include "bsdctype_local.h"
#include "runetype_file.h"
const _BSDCTypeLocale _DefaultBSDCTypeLocale = {
_C_ctype_,
@ -61,6 +61,15 @@ typedef struct {
static __inline void
_bsdctype_init_priv(_BSDCTypeLocalePriv *blp)
{
#if _CTYPE_CACHE_SIZE != _CTYPE_NUM_CHARS
int i;
for (i = _CTYPE_CACHE_SIZE; i < _CTYPE_NUM_CHARS; ++i) {
blp->blp_ctype_tab [i + 1] = 0;
blp->blp_tolower_tab[i + 1] = i;
blp->blp_toupper_tab[i + 1] = i;
}
#endif
blp->blp_ctype_tab [0] = 0;
blp->blp_tolower_tab[0] = EOF;
blp->blp_toupper_tab[0] = EOF;
@ -77,103 +86,93 @@ _bsdctype_read_file(const char * __restrict var, size_t lenvar,
uint32_t value;
int i;
_DIAGASSERT(blp != NULL);
if (lenvar < sizeof(*fbl))
return EFTYPE;
fbl = (const _FileBSDCTypeLocale *)(const void *)var;
if (memcmp(&fbl->fbl_id[0], _CTYPE_ID, sizeof(fbl->fbl_id)))
return EFTYPE;
value = ntohl(fbl->fbl_rev);
value = be32toh(fbl->fbl_rev);
if (value != _CTYPE_REV)
return EFTYPE;
value = ntohl(fbl->fbl_num_chars);
value = be32toh(fbl->fbl_num_chars);
if (value != _CTYPE_CACHE_SIZE)
return EFTYPE;
for (i = 0; i < _CTYPE_CACHE_SIZE; ++i) {
blp->blp_ctype_tab [i + 1] = fbl->fbl_ctype_tab[i];
blp->blp_tolower_tab[i + 1] = ntohs(fbl->fbl_tolower_tab[i]);
blp->blp_toupper_tab[i + 1] = ntohs(fbl->fbl_toupper_tab[i]);
blp->blp_tolower_tab[i + 1] = be16toh(fbl->fbl_tolower_tab[i]);
blp->blp_toupper_tab[i + 1] = be16toh(fbl->fbl_toupper_tab[i]);
}
#if _CTYPE_CACHE_SIZE != _CTYPE_NUM_CHARS
for (i = _CTYPE_CACHE_SIZE; i < _CTYPE_NUM_CHARS; ++i) {
blp->blp_ctype_tab [i + 1] = 0;
blp->blp_tolower_tab[i + 1] = i;
blp->blp_toupper_tab[i + 1] = i;
}
#endif
return 0;
}
static __inline int
_bsdctype_load_priv(const char * __restrict path,
_bsdctype_read_runetype(const char * __restrict var, size_t lenvar,
_BSDCTypeLocalePriv * __restrict blp)
{
int fd, ret;
struct stat st;
size_t lenvar;
char *var;
const _FileRuneLocale *frl;
int i;
fd = open(path, O_RDONLY);
if (fd == -1)
goto err;
if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
goto err;
if (fstat(fd, &st) == -1)
goto err;
if (!S_ISREG(st.st_mode)) {
close(fd);
return EBADF;
}
lenvar = (size_t)st.st_size;
if (lenvar < 1) {
close(fd);
_DIAGASSERT(blp != NULL);
if (lenvar < sizeof(*frl))
return EFTYPE;
lenvar -= sizeof(*frl);
frl = (const _FileRuneLocale *)(const void *)var;
if (memcmp(_RUNECT10_MAGIC, &frl->frl_magic[0], sizeof(frl->frl_magic)))
return EFTYPE;
if (frl->frl_encoding[0] != 'N' || frl->frl_encoding[1] != 'O' ||
frl->frl_encoding[2] != 'N' || frl->frl_encoding[3] != 'E' ||
frl->frl_encoding[4] != '\0') /* XXX */
return EFTYPE;
if (be32toh(frl->frl_runetype_ext.frr_nranges) != 0 ||
be32toh(frl->frl_maplower_ext.frr_nranges) != 0 ||
be32toh(frl->frl_mapupper_ext.frr_nranges) != 0)
return EFTYPE;
if (lenvar < be32toh((uint32_t)frl->frl_variable_len))
return EFTYPE;
for (i = 0; i < _CTYPE_CACHE_SIZE; ++i) {
blp->blp_ctype_tab [i + 1] = (unsigned char)
_runetype_to_ctype((_RuneType)
be32toh(frl->frl_runetype[i]));
blp->blp_tolower_tab[i + 1] = (short)
be32toh((uint32_t)frl->frl_maplower[i]);
blp->blp_toupper_tab[i + 1] = (short)
be32toh((uint32_t)frl->frl_mapupper[i]);
}
var = mmap(NULL, lenvar, PROT_READ,
MAP_FILE|MAP_PRIVATE, fd, (off_t)0);
if (var == MAP_FAILED)
goto err;
if (close(fd) == -1) {
ret = errno;
munmap(var, lenvar);
return ret;
}
return 0;
}
int
_bsdctype_load(const char * __restrict var, size_t lenvar,
_BSDCTypeLocale ** __restrict pbl)
{
int ret;
_BSDCTypeLocalePriv *blp;
_DIAGASSERT(var != NULL || lenvar < 1);
_DIAGASSERT(pbl != NULL);
if (lenvar < 1)
return EFTYPE;
blp = malloc(sizeof(*blp));
if (blp == NULL)
return errno;
_bsdctype_init_priv(blp);
switch (*var) {
case 'B':
ret = _bsdctype_read_file(var, lenvar, blp);
_bsdctype_read_file(var, lenvar, blp);
break;
case 'R':
_bsdctype_read_runetype(var, lenvar, blp);
break;
default:
ret = EFTYPE;
}
munmap(var, lenvar);
return ret;
err:
ret = errno;
close(fd);
return ret;
}
int
_bsdctype_load(const char * __restrict path,
_BSDCTypeLocale ** __restrict pbl)
{
int sverr, ret;
_BSDCTypeLocalePriv *blp;
sverr = errno;
errno = 0;
blp = malloc(sizeof(*blp));
if (blp == NULL) {
ret = errno;
errno = sverr;
return ret;
}
_bsdctype_init_priv(blp);
ret = _bsdctype_load_priv(path, blp);
if (ret) {
if (ret)
free(blp);
errno = sverr;
return ret;
}
*pbl = &blp->bl;
return 0;
else
*pbl = &blp->bl;
return ret;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: bsdctype_local.h,v 1.1 2010/06/13 04:14:57 tnozaki Exp $ */
/* $NetBSD: bsdctype_local.h,v 1.2 2010/06/19 13:26:52 tnozaki Exp $ */
/*-
* Copyright (c)2008 Citrus Project,
@ -41,7 +41,8 @@ extern const _BSDCTypeLocale _DefaultBSDCTypeLocale;
extern const _BSDCTypeLocale *_CurrentBSDCTypeLocale;
__BEGIN_DECLS
int _bsdctype_load(const char * __restrict, _BSDCTypeLocale ** __restrict);
int _bsdctype_load(const char * __restrict, size_t,
_BSDCTypeLocale ** __restrict);
__END_DECLS
#endif /*_BSDCTYPE_LOCAL_H_*/

View File

@ -1,4 +1,4 @@
/* $NetBSD: global_locale.c,v 1.10 2010/06/13 04:14:57 tnozaki Exp $ */
/* $NetBSD: global_locale.c,v 1.11 2010/06/19 13:26:52 tnozaki Exp $ */
/*-
* Copyright (c)2008 Citrus Project,
@ -28,7 +28,7 @@
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: global_locale.c,v 1.10 2010/06/13 04:14:57 tnozaki Exp $");
__RCSID("$NetBSD: global_locale.c,v 1.11 2010/06/19 13:26:52 tnozaki Exp $");
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
@ -42,7 +42,7 @@ __RCSID("$NetBSD: global_locale.c,v 1.10 2010/06/13 04:14:57 tnozaki Exp $");
#ifdef WITH_RUNE
#include "runetype_local.h"
#else
#include "bsdctype_locale.h"
#include "bsdctype_local.h"
#endif
#include "setlocale_local.h"

View File

@ -1,4 +1,4 @@
/* $NetBSD: localeio.c,v 1.4 2010/05/30 08:28:53 tnozaki Exp $ */
/* $NetBSD: localeio.c,v 1.5 2010/06/19 13:26:52 tnozaki Exp $ */
/*
* Copyright (c) 2008, The NetBSD Foundation, Inc.
* All rights reserved.
@ -30,13 +30,14 @@
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: localeio.c,v 1.4 2010/05/30 08:28:53 tnozaki Exp $");
__RCSID("$NetBSD: localeio.c,v 1.5 2010/06/19 13:26:52 tnozaki Exp $");
#endif /* LIBC_SCCS and not lint */
#include "namespace.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <assert.h>
#include <errno.h>
@ -50,6 +51,54 @@ __RCSID("$NetBSD: localeio.c,v 1.4 2010/05/30 08:28:53 tnozaki Exp $");
#include "localeio.h"
int
_localeio_map_file(const char * __restrict path,
void ** __restrict pvar, size_t * __restrict plenvar)
{
int fd, ret;
struct stat st;
void *var;
size_t lenvar;
_DIAGASSERT(path != NULL);
_DIAGASSERT(pvar != NULL);
_DIAGASSERT(plenvar != NULL);
fd = open(path, O_RDONLY);
if (fd == -1)
return errno;
if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1 || fstat(fd, &st) == 1) {
ret = errno;
goto error;
}
if (!S_ISREG(st.st_mode)) {
ret = EBADF;
goto error;
}
lenvar = (size_t)st.st_size;
if (lenvar < 1) {
ret = EFTYPE;
goto error;
}
var = mmap(NULL, lenvar, PROT_READ,
MAP_FILE|MAP_PRIVATE, fd, (off_t)0);
if (var == MAP_FAILED) {
ret = errno;
goto error;
}
*pvar = var;
*plenvar = lenvar;
return 0;
error:
return ret;
}
void
_localeio_unmap_file(void *var, size_t lenvar)
{
munmap(var, lenvar);
}
int
__loadlocale(const char *name, size_t nstr, size_t nbytes,
size_t localesize, void *currentlocale)

View File

@ -1,4 +1,4 @@
/* $NetBSD: localeio.h,v 1.3 2009/01/11 02:46:28 christos Exp $ */
/* $NetBSD: localeio.h,v 1.4 2010/06/19 13:26:52 tnozaki Exp $ */
/*
* Copyright (c) 2008, The NetBSD Foundation, Inc.
* All rights reserved.
@ -29,5 +29,8 @@
*/
__BEGIN_DECLS
int _localeio_map_file(const char * __restrict,
void ** __restrict, size_t * __restrict);
void _localeio_unmap_file(void *, size_t);
int __loadlocale(const char *, size_t, size_t, size_t, void *);
__END_DECLS

View File

@ -1,4 +1,4 @@
/* $NetBSD: localeio_lc_ctype.c,v 1.5 2010/06/13 04:14:57 tnozaki Exp $ */
/* $NetBSD: localeio_lc_ctype.c,v 1.6 2010/06/19 13:26:52 tnozaki Exp $ */
/*-
* Copyright (c)2008 Citrus Project,
@ -28,7 +28,7 @@
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: localeio_lc_ctype.c,v 1.5 2010/06/13 04:14:57 tnozaki Exp $");
__RCSID("$NetBSD: localeio_lc_ctype.c,v 1.6 2010/06/19 13:26:52 tnozaki Exp $");
#endif /* LIBC_SCCS and not lint */
#include "reentrant.h"
@ -47,6 +47,7 @@ __RCSID("$NetBSD: localeio_lc_ctype.c,v 1.5 2010/06/13 04:14:57 tnozaki Exp $");
#include "bsdctype_local.h"
#include "aliasname_local.h"
#include "localeio.h"
#include "setlocale_local.h"
@ -68,6 +69,9 @@ _localeio_LC_CTYPE_create_impl(const char * __restrict root,
const char * __restrict name, _BSDCTypeLocale ** __restrict pdata)
{
char path[PATH_MAX + 1];
void *var;
size_t lenvar;
int ret;
_DIAGASSERT(root != NULL);
_DIAGASSERT(name != NULL);
@ -75,7 +79,12 @@ _localeio_LC_CTYPE_create_impl(const char * __restrict root,
snprintf(path, sizeof(path),
"%s/%s/LC_CTYPE", root, name);
return _bsdctype_load(path, pdata);
ret = _localeio_map_file(path, &var, &lenvar);
if (!ret) {
ret = _bsdctype_load((const char *)var, lenvar, pdata);
_localeio_unmap_file(var, lenvar);
}
return ret;
}
static __inline void

View File

@ -1,7 +1,7 @@
/* $NetBSD: rune.c,v 1.38 2010/06/13 04:14:57 tnozaki Exp $ */
/* $NetBSD: rune.c,v 1.39 2010/06/19 13:26:52 tnozaki Exp $ */
/*-
* Copyright (c)1999 Citrus Project,
* Copyright (c)2010 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -26,468 +26,321 @@
* SUCH DAMAGE.
*/
/*-
* Copyright (c) 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Paul Borman at Krystal Technologies.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
#if 0
static char sccsid[] = "@(#)rune.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: rune.c,v 1.38 2010/06/13 04:14:57 tnozaki Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
#include "namespace.h"
#include <sys/types.h>
#include <sys/ctype_bits.h>
#include <sys/endian.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#define __SETLOCALE_SOURCE__
#include <locale.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <wchar.h>
#include "setlocale_local.h"
#include "citrus_module.h"
#include "citrus_ctype.h"
#include "bsdctype_local.h"
#include "runetype_local.h"
#include "bsdctype_local.h"
static int readrange __P((_RuneLocale *, _RuneRange *, _FileRuneRange *, void *, FILE *));
static void _freeentry __P((_RuneRange *));
static void _wctype_init __P((_RuneLocale *rl));
#include "multibyte.h"
static int
readrange(_RuneLocale *rl, _RuneRange *rr, _FileRuneRange *frr, void *lastp,
FILE *fp)
{
uint32_t i;
_RuneEntry *re;
_FileRuneEntry fre;
#include "_wctype_local.h"
#include "_wctrans_local.h"
_DIAGASSERT(rl != NULL);
_DIAGASSERT(rr != NULL);
_DIAGASSERT(frr != NULL);
_DIAGASSERT(lastp != NULL);
_DIAGASSERT(fp != NULL);
typedef struct {
_RuneLocale rl;
unsigned char rlp_ctype_tab [_CTYPE_NUM_CHARS + 1];
short rlp_tolower_tab[_CTYPE_NUM_CHARS + 1];
short rlp_toupper_tab[_CTYPE_NUM_CHARS + 1];
char rlp_codeset[33]; /* XXX */
} _RuneLocalePriv;
re = (_RuneEntry *)rl->rl_variable;
rr->rr_nranges = ntohl(frr->frr_nranges);
if (rr->rr_nranges == 0) {
rr->rr_rune_ranges = NULL;
return 0;
}
rr->rr_rune_ranges = re;
for (i = 0; i < rr->rr_nranges; i++) {
if (fread(&fre, sizeof(fre), 1, fp) != 1)
return -1;
re->re_min = ntohl((u_int32_t)fre.fre_min);
re->re_max = ntohl((u_int32_t)fre.fre_max);
re->re_map = ntohl((u_int32_t)fre.fre_map);
re++;
if ((void *)re > lastp)
return -1;
}
rl->rl_variable = re;
return 0;
}
static int
readentry(_RuneRange *rr, FILE *fp)
{
_RuneEntry *re;
size_t l, i, j;
int error;
_DIAGASSERT(rr != NULL);
_DIAGASSERT(fp != NULL);
re = rr->rr_rune_ranges;
for (i = 0; i < rr->rr_nranges; i++) {
if (re[i].re_map != 0) {
re[i].re_rune_types = NULL;
continue;
}
l = re[i].re_max - re[i].re_min + 1;
re[i].re_rune_types = malloc(l * sizeof(_RuneType));
if (!re[i].re_rune_types) {
error = ENOMEM;
goto fail;
}
memset(re[i].re_rune_types, 0, l * sizeof(_RuneType));
if (fread(re[i].re_rune_types, sizeof(_RuneType), l, fp) != l)
goto fail2;
for (j = 0; j < l; j++)
re[i].re_rune_types[j] = ntohl(re[i].re_rune_types[j]);
}
return 0;
fail:
for (j = 0; j < i; j++) {
free(re[j].re_rune_types);
re[j].re_rune_types = NULL;
}
return error;
fail2:
for (j = 0; j <= i; j++) {
free(re[j].re_rune_types);
re[j].re_rune_types = NULL;
}
return errno;
}
/* XXX: temporary implementation */
static void
find_codeset(_RuneLocale *rl)
{
char *top, *codeset, *tail, *ep;
/* end of rl_variable region */
ep = (char *)rl->rl_variable;
ep += rl->rl_variable_len;
rl->rl_codeset = NULL;
if (!(top = strstr(rl->rl_variable, _RUNE_CODESET)))
return;
tail = strpbrk(top, " \t");
codeset = top + sizeof(_RUNE_CODESET) - 1;
if (tail) {
*top = *tail;
*tail = '\0';
rl->rl_codeset = strdup(codeset);
strlcpy(top + 1, tail + 1, (unsigned)(ep - (top + 1)));
} else {
*top = '\0';
rl->rl_codeset = strdup(codeset);
}
}
void
_freeentry(_RuneRange *rr)
{
_RuneEntry *re;
uint32_t i;
_DIAGASSERT(rr != NULL);
re = rr->rr_rune_ranges;
for (i = 0; i < rr->rr_nranges; i++) {
if (re[i].re_rune_types)
free(re[i].re_rune_types);
re[i].re_rune_types = NULL;
}
}
void
_wctype_init(_RuneLocale *rl)
static __inline void
_rune_wctype_init(_RuneLocale *rl)
{
memcpy(&rl->rl_wctype, &_DefaultRuneLocale.rl_wctype,
sizeof(rl->rl_wctype));
sizeof(rl->rl_wctype));
}
_RuneLocale *
_Read_RuneMagi(fp)
FILE *fp;
static __inline void
_rune_wctrans_init(_RuneLocale *rl)
{
/* file */
_FileRuneLocale frl;
/* host data */
char *hostdata;
size_t hostdatalen;
void *lastp;
_RuneLocale *rl;
struct stat sb;
int x;
_DIAGASSERT(fp != NULL);
if (fstat(fileno(fp), &sb) < 0)
return NULL;
if (sb.st_size < (off_t)sizeof(_FileRuneLocale))
return NULL;
/* XXX more validation? */
/* Someone might have read the magic number once already */
rewind(fp);
if (fread(&frl, sizeof(frl), 1, fp) != 1)
return NULL;
if (memcmp(frl.frl_magic, _RUNECT10_MAGIC, sizeof(frl.frl_magic)))
return NULL;
hostdatalen = sizeof(*rl) + ntohl((u_int32_t)frl.frl_variable_len) +
ntohl(frl.frl_runetype_ext.frr_nranges) * sizeof(_RuneEntry) +
ntohl(frl.frl_maplower_ext.frr_nranges) * sizeof(_RuneEntry) +
ntohl(frl.frl_mapupper_ext.frr_nranges) * sizeof(_RuneEntry);
if ((hostdata = malloc(hostdatalen)) == NULL)
return NULL;
memset(hostdata, 0, hostdatalen);
lastp = hostdata + hostdatalen;
rl = (_RuneLocale *)(void *)hostdata;
rl->rl_variable = rl + 1;
memcpy(rl->rl_magic, frl.frl_magic, sizeof(rl->rl_magic));
memcpy(rl->rl_encoding, frl.frl_encoding, sizeof(rl->rl_encoding));
rl->rl_invalid_rune = ntohl((u_int32_t)frl.frl_invalid_rune);
rl->rl_variable_len = ntohl((u_int32_t)frl.frl_variable_len);
for (x = 0; x < _CTYPE_CACHE_SIZE; ++x) {
rl->rl_runetype[x] = ntohl(frl.frl_runetype[x]);
/* XXX assumes rune_t = u_int32_t */
rl->rl_maplower[x] = ntohl((u_int32_t)frl.frl_maplower[x]);
rl->rl_mapupper[x] = ntohl((u_int32_t)frl.frl_mapupper[x]);
}
if (readrange(rl, &rl->rl_runetype_ext, &frl.frl_runetype_ext, lastp, fp))
{
free(hostdata);
return NULL;
}
if (readrange(rl, &rl->rl_maplower_ext, &frl.frl_maplower_ext, lastp, fp))
{
free(hostdata);
return NULL;
}
if (readrange(rl, &rl->rl_mapupper_ext, &frl.frl_mapupper_ext, lastp, fp))
{
free(hostdata);
return NULL;
}
if (readentry(&rl->rl_runetype_ext, fp) != 0) {
free(hostdata);
return NULL;
}
if ((u_int8_t *)rl->rl_variable + rl->rl_variable_len >
(u_int8_t *)lastp) {
_freeentry(&rl->rl_runetype_ext);
free(hostdata);
return NULL;
}
if (rl->rl_variable_len == 0)
rl->rl_variable = NULL;
if (rl->rl_variable == NULL ||
fread(rl->rl_variable, rl->rl_variable_len, 1, fp) != 1) {
_freeentry(&rl->rl_runetype_ext);
free(hostdata);
return NULL;
}
find_codeset(rl);
_wctype_init(rl);
/* error if we have junk at the tail */
if (ftell(fp) != sb.st_size) {
_freeentry(&rl->rl_runetype_ext);
free(hostdata);
return NULL;
}
return(rl);
rl->rl_wctrans[_WCTRANS_INDEX_LOWER].te_name = "tolower";
rl->rl_wctrans[_WCTRANS_INDEX_LOWER].te_cached = &rl->rl_maplower[0];
rl->rl_wctrans[_WCTRANS_INDEX_LOWER].te_extmap = &rl->rl_maplower_ext;
rl->rl_wctrans[_WCTRANS_INDEX_UPPER].te_name = "toupper";
rl->rl_wctrans[_WCTRANS_INDEX_UPPER].te_cached = &rl->rl_mapupper[0];
rl->rl_wctrans[_WCTRANS_INDEX_UPPER].te_extmap = &rl->rl_mapupper_ext;
}
void
_NukeRune(rl)
_RuneLocale *rl;
static __inline void
_rune_init_priv(_RuneLocalePriv *rlp)
{
#if _CTYPE_CACHE_SIZE != _CTYPE_NUM_CHARS
int i;
_DIAGASSERT(rl != NULL);
if (rl != &_DefaultRuneLocale) {
_freeentry(&rl->rl_runetype_ext);
if (rl->rl_codeset)
free(__UNCONST(rl->rl_codeset));
if (rl->rl_citrus_ctype)
_citrus_ctype_close(rl->rl_citrus_ctype);
free(__UNCONST(rl->rl_ctype_tab));
free(__UNCONST(rl->rl_tolower_tab));
free(__UNCONST(rl->rl_toupper_tab));
free(rl);
for (i = _CTYPE_CACHE_SIZE; i < _CTYPE_NUM_CHARS; ++i) {
rlp->rlp_ctype_tab [i + 1] = 0;
rlp->rlp_tolower_tab[i + 1] = i;
rlp->rlp_toupper_tab[i + 1] = i;
}
#endif
rlp->rlp_ctype_tab [0] = 0;
rlp->rlp_tolower_tab[0] = EOF;
rlp->rlp_toupper_tab[0] = EOF;
rlp->rl.rl_ctype_tab = (const unsigned char *)&rlp->rlp_ctype_tab[0];
rlp->rl.rl_tolower_tab = (const short *)&rlp->rlp_tolower_tab[0];
rlp->rl.rl_toupper_tab = (const short *)&rlp->rlp_toupper_tab[0];
rlp->rl.rl_codeset = (const char *)&rlp->rlp_codeset[0];
_rune_wctype_init(&rlp->rl);
_rune_wctrans_init(&rlp->rl);
}
/*
* read in old LC_CTYPE declaration file, convert into runelocale info
*/
_RuneLocale *
_Read_CTypeAsRune(fp)
FILE *fp;
static __inline void
_rune_find_codeset(char *s, size_t n,
const char *var, size_t lenvar)
{
char id[sizeof(_CTYPE_ID) - 1];
u_int32_t i, len;
u_int8_t *new_ctype = NULL;
int16_t *new_toupper = NULL, *new_tolower = NULL;
/* host data */
char *hostdata = NULL;
size_t hostdatalen;
const char *endvar;
#define _RUNE_CODESET_LEN (sizeof(_RUNE_CODESET)-1)
for (/**/; lenvar > _RUNE_CODESET_LEN; ++var, --lenvar) {
if (!memcmp(var, _RUNE_CODESET, _RUNE_CODESET_LEN)) {
endvar = &var[_RUNE_CODESET_LEN];
while (n-- > 1 && lenvar-- > _RUNE_CODESET_LEN) {
if (*endvar == ' ' || *endvar == '\t')
break;
*s++ = *endvar++;
}
break;
}
}
*s = '\0';
}
static __inline int
_rune_read_file(const char * __restrict var, size_t lenvar,
_RuneLocale ** __restrict prl)
{
int ret, i;
const _FileRuneLocale *frl;
const _FileRuneEntry *fre;
const uint32_t *frune;
_RuneLocalePriv *rlp;
_RuneLocale *rl;
struct stat sb;
int x;
_RuneEntry *re;
uint32_t *rune;
uint32_t runetype_len, maplower_len, mapupper_len, variable_len;
size_t len, n;
_DIAGASSERT(fp != NULL);
if (lenvar < sizeof(*frl))
return EFTYPE;
lenvar -= sizeof(*frl);
frl = (const _FileRuneLocale *)(const void *)var;
if (memcmp(_RUNECT10_MAGIC, &frl->frl_magic[0], sizeof(frl->frl_magic)))
return EFTYPE;
if (fstat(fileno(fp), &sb) < 0)
return NULL;
runetype_len = be32toh(frl->frl_runetype_ext.frr_nranges);
maplower_len = be32toh(frl->frl_maplower_ext.frr_nranges);
mapupper_len = be32toh(frl->frl_mapupper_ext.frr_nranges);
len = runetype_len + maplower_len + mapupper_len;
if (sb.st_size < (off_t)sizeof(id))
return NULL;
/* XXX more validation? */
fre = (const _FileRuneEntry *)(const void *)(frl + 1);
frune = (const uint32_t *)(const void *)(fre + len);
/* Someone might have read the magic number once already */
rewind(fp);
variable_len = be32toh((uint32_t)frl->frl_variable_len);
if (fread(id, sizeof(id), 1, fp) != 1)
goto bad;
if (memcmp(id, _CTYPE_ID, sizeof(id)) != 0)
goto bad;
n = (len * sizeof(*fre)) + variable_len;
if (lenvar < n)
return EFTYPE;
lenvar -= n;
if (fread(&i, sizeof(u_int32_t), 1, fp) != 1)
goto bad;
if ((i = ntohl(i)) != _CTYPE_REV)
goto bad;
n = sizeof(*rlp) + (len * sizeof(*re)) + lenvar;
rlp = (_RuneLocalePriv *)malloc(n);
if (rlp == NULL)
return ENOMEM;
_rune_init_priv(rlp);
if (fread(&len, sizeof(u_int32_t), 1, fp) != 1)
goto bad;
if ((len = ntohl(len)) != _CTYPE_CACHE_SIZE)
goto bad;
rl = &rlp->rl;
re = (_RuneEntry *)(void *)(rlp + 1);
rune = (uint32_t *)(void *)(re + len);
if ((new_ctype = malloc(sizeof(u_int8_t) * (1 + len))) == NULL ||
(new_toupper = malloc(sizeof(int16_t) * (1 + len))) == NULL ||
(new_tolower = malloc(sizeof(int16_t) * (1 + len))) == NULL)
goto bad;
new_ctype[0] = 0;
if (fread(&new_ctype[1], sizeof(u_int8_t), len, fp) != len)
goto bad;
new_toupper[0] = EOF;
if (fread(&new_toupper[1], sizeof(int16_t), len, fp) != len)
goto bad;
new_tolower[0] = EOF;
if (fread(&new_tolower[1], sizeof(int16_t), len, fp) != len)
goto bad;
hostdatalen = sizeof(*rl);
if ((hostdata = malloc(hostdatalen)) == NULL)
goto bad;
memset(hostdata, 0, hostdatalen);
rl = (_RuneLocale *)(void *)hostdata;
rl->rl_variable = NULL;
memcpy(rl->rl_magic, _RUNECT10_MAGIC, sizeof(rl->rl_magic));
memcpy(rl->rl_encoding, "NONE", 4);
rl->rl_invalid_rune = _DefaultRuneLocale.rl_invalid_rune; /*XXX*/
rl->rl_variable_len = 0;
for (x = 0; x < _CTYPE_CACHE_SIZE; ++x) {
if ((uint32_t) x > len)
continue;
/*
* TWEAKS!
* - old locale file declarations do not have proper _B
* in many cases.
* - isprint() declaration in ctype.h incorrectly uses _B.
* _B means "isprint but !isgraph", not "isblank" with the
* declaration.
* - _X and _RUNETYPE_X have negligible difference in meaning.
* - we don't set digit value, fearing that it would be
* too much of hardcoding. we may need to revisit it.
*/
if (new_ctype[1 + x] & _U)
rl->rl_runetype[x] |= _RUNETYPE_U;
if (new_ctype[1 + x] & _L)
rl->rl_runetype[x] |= _RUNETYPE_L;
if (new_ctype[1 + x] & _N)
rl->rl_runetype[x] |= _RUNETYPE_D;
if (new_ctype[1 + x] & _S)
rl->rl_runetype[x] |= _RUNETYPE_S;
if (new_ctype[1 + x] & _P)
rl->rl_runetype[x] |= _RUNETYPE_P;
if (new_ctype[1 + x] & _C)
rl->rl_runetype[x] |= _RUNETYPE_C;
/* derived flag bits, duplicate of ctype.h */
if (new_ctype[1 + x] & (_U | _L))
rl->rl_runetype[x] |= _RUNETYPE_A;
if (new_ctype[1 + x] & (_N | _X))
rl->rl_runetype[x] |= _RUNETYPE_X;
if (new_ctype[1 + x] & (_P|_U|_L|_N))
rl->rl_runetype[x] |= _RUNETYPE_G;
/* we don't really trust _B in the file. see above. */
if (new_ctype[1 + x] & _B)
rl->rl_runetype[x] |= _RUNETYPE_B;
if ((new_ctype[1 + x] & (_P|_U|_L|_N|_B)) || x == ' ')
rl->rl_runetype[x] |= (_RUNETYPE_R | _RUNETYPE_SW1);
if (x == ' ' || x == '\t')
rl->rl_runetype[x] |= _RUNETYPE_B;
/* XXX may fail on non-8bit encoding only */
rl->rl_mapupper[x] = ntohs(new_toupper[1 + x]);
rl->rl_maplower[x] = ntohs(new_tolower[1 + x]);
for (i = 0; i < _CTYPE_CACHE_SIZE; ++i) {
rl->rl_runetype[i] = be32toh(frl->frl_runetype[i]);
rl->rl_maplower[i] = be32toh((uint32_t)frl->frl_maplower[i]);
rl->rl_mapupper[i] = be32toh((uint32_t)frl->frl_mapupper[i]);
}
_wctype_init(rl);
#define READ_RANGE(name) \
do { \
const _FileRuneEntry *end_fre; \
const uint32_t *end_frune; \
\
rl->rl_##name##_ext.rr_nranges = name##_len; \
rl->rl_##name##_ext.rr_rune_ranges = re; \
\
end_fre = fre + name##_len; \
while (fre < end_fre) { \
re->re_min = be32toh((uint32_t)fre->fre_min); \
re->re_max = be32toh((uint32_t)fre->fre_max); \
re->re_map = be32toh((uint32_t)fre->fre_map); \
if (re->re_map != 0) { \
re->re_rune_types = NULL; \
} else { \
re->re_rune_types = rune; \
len = re->re_max - re->re_min + 1; \
n = len * sizeof(*frune); \
if (lenvar < n) { \
ret = EFTYPE; \
goto err; \
} \
lenvar -= n; \
end_frune = frune + len; \
while (frune < end_frune) \
*rune++ = be32toh(*frune++); \
} \
++fre, ++re; \
} \
} while (/*CONSTCOND*/0)
/*
* __runetable_to_netbsd_ctype() will be called from
* setrunelocale.c:_newrunelocale(), and fill old ctype table.
*/
READ_RANGE(runetype);
READ_RANGE(maplower);
READ_RANGE(mapupper);
free(new_ctype);
free(new_toupper);
free(new_tolower);
return(rl);
memcpy((void *)rune, (void const *)frune, variable_len);
rl->rl_variable_len = variable_len;
rl->rl_variable = (void *)rune;
bad:
if (new_ctype)
free(new_ctype);
if (new_toupper)
free(new_toupper);
if (new_tolower)
free(new_tolower);
return NULL;
if (lenvar > 0) {
ret = EFTYPE;
goto err;
}
_rune_find_codeset(rlp->rlp_codeset, sizeof(rlp->rlp_codeset),
(const char *)rl->rl_variable, rl->rl_variable_len);
ret = _citrus_ctype_open(&rl->rl_citrus_ctype, frl->frl_encoding,
rl->rl_variable, rl->rl_variable_len, _PRIVSIZE);
if (ret)
goto err;
if (__mb_len_max_runtime <
_citrus_ctype_get_mb_cur_max(rl->rl_citrus_ctype)) {
ret = EINVAL;
goto err;
}
for (i = 0; i < _CTYPE_CACHE_SIZE; ++i) {
wint_t wc;
ret = _citrus_ctype_btowc(rl->rl_citrus_ctype, i, &wc);
if (ret)
goto err;
if (wc == WEOF) {
rlp->rlp_ctype_tab[i + 1] = 0;
rlp->rlp_tolower_tab[i + 1] = i;
rlp->rlp_toupper_tab[i + 1] = i;
} else {
rlp->rlp_ctype_tab[i + 1] = (unsigned char)
_runetype_to_ctype(_runetype_priv(rl, wc));
#define CONVERT_MAP(name) \
do { \
wint_t map; \
int c; \
\
map = _towctrans_priv(wc, _wctrans_##name(rl)); \
if (map == wc || (_citrus_ctype_wctob(rl->rl_citrus_ctype, \
map, &c) || c == EOF)) \
c = i; \
rlp->rlp_to##name##_tab[i + 1] = (short)c; \
} while (/*CONSTCOND*/0)
CONVERT_MAP(lower);
CONVERT_MAP(upper);
}
}
*prl = rl;
return 0;
err:
free(rlp);
return ret;
}
static __inline int
_rune_read_bsdctype(const char * __restrict var, size_t lenvar,
_RuneLocale ** __restrict prl)
{
const _FileBSDCTypeLocale *fbl;
uint32_t value;
int i, bits;
uint16_t lower, upper;
_RuneLocalePriv *rlp;
_RuneLocale *rl;
if (lenvar < sizeof(*fbl))
return EFTYPE;
fbl = (const _FileBSDCTypeLocale *)(const void *)var;
if (memcmp(&fbl->fbl_id[0], _CTYPE_ID, sizeof(fbl->fbl_id)))
return EFTYPE;
value = be32toh(fbl->fbl_rev);
if (value != _CTYPE_REV)
return EFTYPE;
value = be32toh(fbl->fbl_num_chars);
if (value != _CTYPE_CACHE_SIZE)
return EFTYPE;
rlp = (_RuneLocalePriv *)malloc(sizeof(*rlp));
if (rlp == NULL)
return ENOMEM;
_rune_init_priv(rlp);
rl = &rlp->rl;
for (i = 0; i < _CTYPE_CACHE_SIZE; ++i) {
bits = fbl->fbl_ctype_tab[i];
lower = be16toh(fbl->fbl_tolower_tab[i]);
upper = be16toh(fbl->fbl_toupper_tab[i]);
rlp->rlp_ctype_tab [i + 1] = (unsigned char)bits;
rlp->rlp_tolower_tab[i + 1] = (short)lower;
rlp->rlp_toupper_tab[i + 1] = (short)upper;
rl->rl_runetype[i] = _runetype_from_ctype(bits, i);
rl->rl_maplower[i] = (__nbrune_t)lower;
rl->rl_mapupper[i] = (__nbrune_t)upper;
}
*prl = rl;
return 0;
}
int
_rune_load(const char * __restrict var, size_t lenvar,
_RuneLocale ** __restrict prl)
{
int ret;
_DIAGASSERT(var != NULL || lenvar < 1);
_DIAGASSERT(prl != NULL);
if (lenvar < 1)
return EFTYPE;
switch (*var) {
case 'R':
ret = _rune_read_file(var, lenvar, prl);
break;
case 'B':
ret = _rune_read_bsdctype(var, lenvar, prl);
break;
default:
ret = EFTYPE;
}
return ret;
}

View File

@ -1,148 +0,0 @@
/* $NetBSD: runeglue.c,v 1.20 2010/06/13 04:14:57 tnozaki Exp $ */
/*-
* Copyright (c)1999 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Id: runeglue.c,v 1.7 2000/12/22 22:52:29 itojun Exp
*/
/*
* Glue code to hide "rune" facility from user programs.
* This is important to keep backward/future compatibility.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: runeglue.c,v 1.20 2010/06/13 04:14:57 tnozaki Exp $");
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <sys/ctype_bits.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include "citrus_module.h"
#include "citrus_ctype.h"
#include "runetype_local.h"
#if EOF != -1
#error "EOF != -1"
#endif
int
__runetable_to_netbsd_ctype(rl)
_RuneLocale *rl;
{
int i, ch;
unsigned char *new_ctype;
short *new_toupper, *new_tolower;
_DIAGASSERT(rl != NULL);
new_ctype = malloc(sizeof(*new_ctype) * (1 + _CTYPE_NUM_CHARS));
if (!new_ctype)
return -1;
new_toupper = malloc(sizeof(*new_toupper) * (1 + _CTYPE_NUM_CHARS));
if (!new_toupper) {
free(new_ctype);
return -1;
}
new_tolower = malloc(sizeof(*new_tolower) * (1 + _CTYPE_NUM_CHARS));
if (!new_tolower) {
free(new_ctype);
free(new_toupper);
return -1;
}
memset(new_ctype, 0, sizeof(*new_ctype) * (1 + _CTYPE_NUM_CHARS));
memset(new_toupper, 0, sizeof(*new_toupper) * (1 + _CTYPE_NUM_CHARS));
memset(new_tolower, 0, sizeof(*new_tolower) * (1 + _CTYPE_NUM_CHARS));
new_ctype[0] = 0;
new_toupper[0] = EOF;
new_tolower[0] = EOF;
for (i = 0; i < _CTYPE_CACHE_SIZE; i++) {
new_ctype[i + 1] = 0;
new_toupper[i + 1] = i;
new_tolower[i + 1] = i;
/* XXX: FIXME
* expected 'x' == L'x', see defect report #279
* http://www.open-std.org/JTC1/SC22/WG14/www/docs/dr_279.htm
*/
if (_citrus_ctype_wctob(rl->rl_citrus_ctype, (wint_t)i, &ch)) {
free(new_ctype);
free(new_toupper);
free(new_tolower);
return -1;
}
if (ch == EOF)
continue;
if (rl->rl_runetype[i] & _RUNETYPE_U)
new_ctype[i + 1] |= _U;
if (rl->rl_runetype[i] & _RUNETYPE_L)
new_ctype[i + 1] |= _L;
if (rl->rl_runetype[i] & _RUNETYPE_D)
new_ctype[i + 1] |= _N;
if (rl->rl_runetype[i] & _RUNETYPE_S)
new_ctype[i + 1] |= _S;
if (rl->rl_runetype[i] & _RUNETYPE_P)
new_ctype[i + 1] |= _P;
if (rl->rl_runetype[i] & _RUNETYPE_C)
new_ctype[i + 1] |= _C;
if (rl->rl_runetype[i] & _RUNETYPE_X)
new_ctype[i + 1] |= _X;
/*
* TWEAK! _B has been used incorrectly (or with older
* declaration) in ctype.h isprint() macro.
* _B does not mean isblank, it means "isprint && !isgraph".
* the following is okay since isblank() was hardcoded in
* function (i.e. isblank() is inherently locale unfriendly).
*/
#if 1
if ((rl->rl_runetype[i] & (_RUNETYPE_R | _RUNETYPE_G)) == _RUNETYPE_R)
new_ctype[i + 1] |= _B;
#else
if (rl->rl_runetype[i] & _RUNETYPE_B)
new_ctype[i + 1] |= _B;
#endif
new_toupper[i + 1] = (short)rl->rl_mapupper[i];
new_tolower[i + 1] = (short)rl->rl_maplower[i];
}
/* LINTED const cast */
rl->rl_ctype_tab = (const unsigned char *)new_ctype;
/* LINTED const cast */
rl->rl_toupper_tab = (const short *)new_toupper;
/* LINTED const cast */
rl->rl_tolower_tab = (const short *)new_tolower;
return 0;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: runetable.c,v 1.26 2010/06/13 04:14:57 tnozaki Exp $ */
/* $NetBSD: runetable.c,v 1.27 2010/06/19 13:26:52 tnozaki Exp $ */
/*-
* Copyright (c) 1993
@ -39,7 +39,7 @@
#if 0
static char sccsid[] = "@(#)table.c 8.1 (Berkeley) 6/27/93";
#else
__RCSID("$NetBSD: runetable.c,v 1.26 2010/06/13 04:14:57 tnozaki Exp $");
__RCSID("$NetBSD: runetable.c,v 1.27 2010/06/19 13:26:52 tnozaki Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
@ -52,10 +52,6 @@ __RCSID("$NetBSD: runetable.c,v 1.26 2010/06/13 04:14:57 tnozaki Exp $");
#include "runetype_local.h"
const _RuneLocale _DefaultRuneLocale = {
_RUNECT10_MAGIC,
"NONE",
_DEFAULT_INVALID_RUNE,
{ /*00*/ _RUNETYPE_C,
_RUNETYPE_C,
_RUNETYPE_C,

View File

@ -1,4 +1,4 @@
/* $NetBSD: runetype_file.h,v 1.1 2010/06/13 04:14:57 tnozaki Exp $ */
/* $NetBSD: runetype_file.h,v 1.2 2010/06/19 13:26:52 tnozaki Exp $ */
/*-
* Copyright (c) 1993
@ -39,6 +39,7 @@
#include <sys/cdefs.h>
#include <sys/types.h>
#include <sys/ctype_bits.h>
#include "ctype_local.h"
@ -78,6 +79,92 @@ typedef uint32_t _RuneType;
#define _RUNETYPE_SW2 UINT32_C(0x80000000) /* 2 width character */
#define _RUNETYPE_SW3 UINT32_C(0xc0000000) /* 3 width character */
static __inline int
_runetype_to_ctype(_RuneType bits)
{
int ret;
if (bits == (_RuneType)0)
return 0;
ret = 0;
if (bits & _RUNETYPE_U)
ret |= _U;
if (bits & _RUNETYPE_L)
ret |= _L;
if (bits & _RUNETYPE_D)
ret |= _N;
if (bits & _RUNETYPE_S)
ret |= _S;
if (bits & _RUNETYPE_P)
ret |= _P;
if (bits & _RUNETYPE_C)
ret |= _C;
if (bits & _RUNETYPE_X)
ret |= _X;
/*
* TWEAK! _B has been used incorrectly (or with older
* declaration) in ctype.h isprint() macro.
* _B does not mean isblank, it means "isprint && !isgraph".
* the following is okay since isblank() was hardcoded in
* function (i.e. isblank() is inherently locale unfriendly).
*/
#if 1
if ((bits & (_RUNETYPE_R | _RUNETYPE_G)) == _RUNETYPE_R)
ret |= _B;
#else
if (bits & _RUNETYPE_B)
ret |= _B;
#endif
return ret;
}
static __inline _RuneType
_runetype_from_ctype(int bits, int ch)
{
_RuneType ret;
/*
* TWEAKS!
* - old locale file declarations do not have proper _B
* in many cases.
* - isprint() declaration in ctype.h incorrectly uses _B.
* _B means "isprint but !isgraph", not "isblank" with the
* declaration.
* - _X and _RUNETYPE_X have negligible difference in meaning.
* - we don't set digit value, fearing that it would be
* too much of hardcoding. we may need to revisit it.
*/
ret = (_RuneType)0;
if (bits & _U)
ret |= _RUNETYPE_U;
if (bits & _L)
ret |= _RUNETYPE_L;
if (bits & _N)
ret |= _RUNETYPE_D;
if (bits & _S)
ret |= _RUNETYPE_S;
if (bits & _P)
ret |= _RUNETYPE_P;
if (bits & _C)
ret |= _RUNETYPE_C;
/* derived flag bits, duplicate of ctype.h */
if (bits & (_U|_L))
ret |= _RUNETYPE_A;
if (bits & (_N|_X))
ret |= _RUNETYPE_X;
if (bits & (_P|_U|_L|_N))
ret |= _RUNETYPE_G;
/* we don't really trust _B in the file. see above. */
if (bits & _B)
ret |= _RUNETYPE_B;
if ((bits & (_P|_U|_L|_N|_B)) || ch == ' ')
ret |= (_RUNETYPE_R | _RUNETYPE_SW1);
if (ch == ' ' || ch == '\t')
ret |= _RUNETYPE_B;
return ret;
}
/*
* rune file format. network endian.

View File

@ -1,4 +1,4 @@
/* $NetBSD: runetype_local.h,v 1.10 2010/06/13 04:14:57 tnozaki Exp $ */
/* $NetBSD: runetype_local.h,v 1.11 2010/06/19 13:26:52 tnozaki Exp $ */
/*-
* Copyright (c) 1993
@ -105,9 +105,6 @@ typedef struct _RuneLocale {
/*
* copied from _FileRuneLocale
*/
char rl_magic[8]; /* Magic saying what version we are */
char rl_encoding[32];/* ASCII name of this encoding */
__nbrune_t rl_invalid_rune;
_RuneType rl_runetype[_CTYPE_CACHE_SIZE];
__nbrune_t rl_maplower[_CTYPE_CACHE_SIZE];
__nbrune_t rl_mapupper[_CTYPE_CACHE_SIZE];
@ -138,13 +135,7 @@ extern const _RuneLocale _DefaultRuneLocale;
extern const _RuneLocale *_CurrentRuneLocale;
__BEGIN_DECLS
/* rune.c */
extern _RuneLocale *_Read_RuneMagi(FILE *fp);
extern _RuneLocale *_Read_CTypeAsRune(FILE *fp);
extern void _NukeRune(_RuneLocale *);
/* runeglue.c */
extern int __runetable_to_netbsd_ctype(_RuneLocale *);
int _rune_load(const char * __restrict, size_t, _RuneLocale ** __restrict);
__END_DECLS
#endif /* !_RUNETYPE_LOCAL_H_ */