Module Name: src
Committed By: tnozaki
Date: Sat Jun 19 13:26:52 UTC 2010
Modified Files:
src/lib/libc/citrus: citrus_lc_ctype.c
src/lib/libc/locale: Makefile.inc bsdctype.c bsdctype_local.h
global_locale.c localeio.c localeio.h localeio_lc_ctype.c rune.c
runetable.c runetype_file.h runetype_local.h
Removed Files:
src/lib/libc/locale: runeglue.c
Log Message:
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.
To generate a diff of this commit:
cvs rdiff -u -r1.8 -r1.9 src/lib/libc/citrus/citrus_lc_ctype.c
cvs rdiff -u -r1.57 -r1.58 src/lib/libc/locale/Makefile.inc
cvs rdiff -u -r1.7 -r1.8 src/lib/libc/locale/bsdctype.c
cvs rdiff -u -r1.1 -r1.2 src/lib/libc/locale/bsdctype_local.h \
src/lib/libc/locale/runetype_file.h
cvs rdiff -u -r1.10 -r1.11 src/lib/libc/locale/global_locale.c \
src/lib/libc/locale/runetype_local.h
cvs rdiff -u -r1.4 -r1.5 src/lib/libc/locale/localeio.c
cvs rdiff -u -r1.3 -r1.4 src/lib/libc/locale/localeio.h
cvs rdiff -u -r1.5 -r1.6 src/lib/libc/locale/localeio_lc_ctype.c
cvs rdiff -u -r1.38 -r1.39 src/lib/libc/locale/rune.c
cvs rdiff -u -r1.20 -r0 src/lib/libc/locale/runeglue.c
cvs rdiff -u -r1.26 -r1.27 src/lib/libc/locale/runetable.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/lib/libc/citrus/citrus_lc_ctype.c
diff -u src/lib/libc/citrus/citrus_lc_ctype.c:1.8 src/lib/libc/citrus/citrus_lc_ctype.c:1.9
--- src/lib/libc/citrus/citrus_lc_ctype.c:1.8 Sun Jun 13 04:14:56 2010
+++ src/lib/libc/citrus/citrus_lc_ctype.c Sat Jun 19 13:26:51 2010
@@ -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 @@
#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 @@
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 @@
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
Index: src/lib/libc/locale/Makefile.inc
diff -u src/lib/libc/locale/Makefile.inc:1.57 src/lib/libc/locale/Makefile.inc:1.58
--- src/lib/libc/locale/Makefile.inc:1.57 Mon Jun 7 13:52:30 2010
+++ src/lib/libc/locale/Makefile.inc Sat Jun 19 13:26:52 2010
@@ -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 @@
# 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
Index: src/lib/libc/locale/bsdctype.c
diff -u src/lib/libc/locale/bsdctype.c:1.7 src/lib/libc/locale/bsdctype.c:1.8
--- src/lib/libc/locale/bsdctype.c:1.7 Sun Jun 13 04:14:57 2010
+++ src/lib/libc/locale/bsdctype.c Sat Jun 19 13:26:52 2010
@@ -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 @@
#include <unistd.h>
#include "bsdctype_local.h"
+#include "runetype_file.h"
const _BSDCTypeLocale _DefaultBSDCTypeLocale = {
_C_ctype_,
@@ -61,6 +61,15 @@
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 @@
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;
-
- 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);
+ const _FileRuneLocale *frl;
+ int i;
+
+ _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;
- }
- switch (*var) {
- case 'B':
- ret = _bsdctype_read_file(var, lenvar, blp);
- break;
- default:
- ret = EFTYPE;
- }
- munmap(var, lenvar);
- return ret;
-err:
- ret = errno;
- close(fd);
- return ret;
+ return 0;
}
int
-_bsdctype_load(const char * __restrict path,
+_bsdctype_load(const char * __restrict var, size_t lenvar,
_BSDCTypeLocale ** __restrict pbl)
{
- int sverr, ret;
+ int ret;
_BSDCTypeLocalePriv *blp;
- sverr = errno;
- errno = 0;
+ _DIAGASSERT(var != NULL || lenvar < 1);
+ _DIAGASSERT(pbl != NULL);
+
+ if (lenvar < 1)
+ return EFTYPE;
blp = malloc(sizeof(*blp));
- if (blp == NULL) {
- ret = errno;
- errno = sverr;
- return ret;
- }
+ if (blp == NULL)
+ return errno;
_bsdctype_init_priv(blp);
- ret = _bsdctype_load_priv(path, blp);
- if (ret) {
- free(blp);
- errno = sverr;
- return ret;
+ switch (*var) {
+ case 'B':
+ _bsdctype_read_file(var, lenvar, blp);
+ break;
+ case 'R':
+ _bsdctype_read_runetype(var, lenvar, blp);
+ break;
+ default:
+ ret = EFTYPE;
}
- *pbl = &blp->bl;
- return 0;
+ if (ret)
+ free(blp);
+ else
+ *pbl = &blp->bl;
+ return ret;
}
Index: src/lib/libc/locale/bsdctype_local.h
diff -u src/lib/libc/locale/bsdctype_local.h:1.1 src/lib/libc/locale/bsdctype_local.h:1.2
--- src/lib/libc/locale/bsdctype_local.h:1.1 Sun Jun 13 04:14:57 2010
+++ src/lib/libc/locale/bsdctype_local.h Sat Jun 19 13:26:52 2010
@@ -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 *_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_*/
Index: src/lib/libc/locale/runetype_file.h
diff -u src/lib/libc/locale/runetype_file.h:1.1 src/lib/libc/locale/runetype_file.h:1.2
--- src/lib/libc/locale/runetype_file.h:1.1 Sun Jun 13 04:14:57 2010
+++ src/lib/libc/locale/runetype_file.h Sat Jun 19 13:26:52 2010
@@ -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 @@
#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.
Index: src/lib/libc/locale/global_locale.c
diff -u src/lib/libc/locale/global_locale.c:1.10 src/lib/libc/locale/global_locale.c:1.11
--- src/lib/libc/locale/global_locale.c:1.10 Sun Jun 13 04:14:57 2010
+++ src/lib/libc/locale/global_locale.c Sat Jun 19 13:26:52 2010
@@ -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 @@
#ifdef WITH_RUNE
#include "runetype_local.h"
#else
-#include "bsdctype_locale.h"
+#include "bsdctype_local.h"
#endif
#include "setlocale_local.h"
Index: src/lib/libc/locale/runetype_local.h
diff -u src/lib/libc/locale/runetype_local.h:1.10 src/lib/libc/locale/runetype_local.h:1.11
--- src/lib/libc/locale/runetype_local.h:1.10 Sun Jun 13 04:14:57 2010
+++ src/lib/libc/locale/runetype_local.h Sat Jun 19 13:26:52 2010
@@ -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 @@
/*
* 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 *_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_ */
Index: src/lib/libc/locale/localeio.c
diff -u src/lib/libc/locale/localeio.c:1.4 src/lib/libc/locale/localeio.c:1.5
--- src/lib/libc/locale/localeio.c:1.4 Sun May 30 08:28:53 2010
+++ src/lib/libc/locale/localeio.c Sat Jun 19 13:26:52 2010
@@ -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>
@@ -51,6 +52,54 @@
#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)
{
Index: src/lib/libc/locale/localeio.h
diff -u src/lib/libc/locale/localeio.h:1.3 src/lib/libc/locale/localeio.h:1.4
--- src/lib/libc/locale/localeio.h:1.3 Sun Jan 11 02:46:28 2009
+++ src/lib/libc/locale/localeio.h Sat Jun 19 13:26:52 2010
@@ -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
Index: src/lib/libc/locale/localeio_lc_ctype.c
diff -u src/lib/libc/locale/localeio_lc_ctype.c:1.5 src/lib/libc/locale/localeio_lc_ctype.c:1.6
--- src/lib/libc/locale/localeio_lc_ctype.c:1.5 Sun Jun 13 04:14:57 2010
+++ src/lib/libc/locale/localeio_lc_ctype.c Sat Jun 19 13:26:52 2010
@@ -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 @@
#include "bsdctype_local.h"
#include "aliasname_local.h"
+#include "localeio.h"
#include "setlocale_local.h"
@@ -68,6 +69,9 @@
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 @@
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
Index: src/lib/libc/locale/rune.c
diff -u src/lib/libc/locale/rune.c:1.38 src/lib/libc/locale/rune.c:1.39
--- src/lib/libc/locale/rune.c:1.38 Sun Jun 13 04:14:57 2010
+++ src/lib/libc/locale/rune.c Sat Jun 19 13:26:52 2010
@@ -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));
-
-static int
-readrange(_RuneLocale *rl, _RuneRange *rr, _FileRuneRange *frr, void *lastp,
- FILE *fp)
-{
- uint32_t i;
- _RuneEntry *re;
- _FileRuneEntry fre;
+#include "multibyte.h"
- _DIAGASSERT(rl != NULL);
- _DIAGASSERT(rr != NULL);
- _DIAGASSERT(frr != NULL);
- _DIAGASSERT(lastp != NULL);
- _DIAGASSERT(fp != NULL);
-
- re = (_RuneEntry *)rl->rl_variable;
-
- rr->rr_nranges = ntohl(frr->frr_nranges);
- if (rr->rr_nranges == 0) {
- rr->rr_rune_ranges = NULL;
- return 0;
- }
+#include "_wctype_local.h"
+#include "_wctrans_local.h"
- 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++;
+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;
- if ((void *)re > lastp)
- return -1;
- }
- rl->rl_variable = re;
- return 0;
+static __inline void
+_rune_wctype_init(_RuneLocale *rl)
+{
+ memcpy(&rl->rl_wctype, &_DefaultRuneLocale.rl_wctype,
+ sizeof(rl->rl_wctype));
}
-static int
-readentry(_RuneRange *rr, FILE *fp)
+static __inline void
+_rune_wctrans_init(_RuneLocale *rl)
{
- _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;
+ 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;
}
-/* XXX: temporary implementation */
-static void
-find_codeset(_RuneLocale *rl)
+static __inline void
+_rune_init_priv(_RuneLocalePriv *rlp)
{
- char *top, *codeset, *tail, *ep;
+#if _CTYPE_CACHE_SIZE != _CTYPE_NUM_CHARS
+ int i;
- /* 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);
+ 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);
}
-void
-_freeentry(_RuneRange *rr)
+static __inline void
+_rune_find_codeset(char *s, size_t n,
+ const char *var, size_t lenvar)
{
- _RuneEntry *re;
- uint32_t i;
+ const char *endvar;
- _DIAGASSERT(rr != NULL);
+#define _RUNE_CODESET_LEN (sizeof(_RUNE_CODESET)-1)
- 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;
+ 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';
}
-void
-_wctype_init(_RuneLocale *rl)
+static __inline int
+_rune_read_file(const char * __restrict var, size_t lenvar,
+ _RuneLocale ** __restrict prl)
{
- memcpy(&rl->rl_wctype, &_DefaultRuneLocale.rl_wctype,
- sizeof(rl->rl_wctype));
-}
-
-
-_RuneLocale *
-_Read_RuneMagi(fp)
- FILE *fp;
-{
- /* file */
- _FileRuneLocale frl;
- /* host data */
- char *hostdata;
- size_t hostdatalen;
- void *lastp;
+ int ret, i;
+ const _FileRuneLocale *frl;
+ const _FileRuneEntry *fre;
+ const uint32_t *frune;
+ _RuneLocalePriv *rlp;
_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);
+ _RuneEntry *re;
+ uint32_t *rune;
+ uint32_t runetype_len, maplower_len, mapupper_len, variable_len;
+ size_t len, n;
+
+ 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;
+
+ 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;
+
+ fre = (const _FileRuneEntry *)(const void *)(frl + 1);
+ frune = (const uint32_t *)(const void *)(fre + len);
+
+ variable_len = be32toh((uint32_t)frl->frl_variable_len);
+
+ n = (len * sizeof(*fre)) + variable_len;
+ if (lenvar < n)
+ return EFTYPE;
+ lenvar -= n;
+
+ n = sizeof(*rlp) + (len * sizeof(*re)) + lenvar;
+ rlp = (_RuneLocalePriv *)malloc(n);
+ if (rlp == NULL)
+ return ENOMEM;
+ _rune_init_priv(rlp);
+
+ rl = &rlp->rl;
+ re = (_RuneEntry *)(void *)(rlp + 1);
+ rune = (uint32_t *)(void *)(re + len);
+
+ 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]);
+ }
+
+#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)
+
+ READ_RANGE(runetype);
+ READ_RANGE(maplower);
+ READ_RANGE(mapupper);
+
+ memcpy((void *)rune, (void const *)frune, variable_len);
+ rl->rl_variable_len = variable_len;
+ rl->rl_variable = (void *)rune;
+
+ 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)
- /* error if we have junk at the tail */
- if (ftell(fp) != sb.st_size) {
- _freeentry(&rl->rl_runetype_ext);
- free(hostdata);
- return NULL;
+ CONVERT_MAP(lower);
+ CONVERT_MAP(upper);
+ }
}
+ *prl = rl;
+ return 0;
- return(rl);
+err:
+ free(rlp);
+ return ret;
}
-void
-_NukeRune(rl)
- _RuneLocale *rl;
+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;
- _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);
+ 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;
}
-/*
- * read in old LC_CTYPE declaration file, convert into runelocale info
- */
-_RuneLocale *
-_Read_CTypeAsRune(fp)
- FILE *fp;
+int
+_rune_load(const char * __restrict var, size_t lenvar,
+ _RuneLocale ** __restrict prl)
{
- 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;
- _RuneLocale *rl;
- struct stat sb;
- int x;
-
- _DIAGASSERT(fp != NULL);
+ int ret;
- if (fstat(fileno(fp), &sb) < 0)
- return NULL;
+ _DIAGASSERT(var != NULL || lenvar < 1);
+ _DIAGASSERT(prl != NULL);
- if (sb.st_size < (off_t)sizeof(id))
- return NULL;
- /* XXX more validation? */
-
- /* Someone might have read the magic number once already */
- rewind(fp);
-
- if (fread(id, sizeof(id), 1, fp) != 1)
- goto bad;
- if (memcmp(id, _CTYPE_ID, sizeof(id)) != 0)
- goto bad;
-
- if (fread(&i, sizeof(u_int32_t), 1, fp) != 1)
- goto bad;
- if ((i = ntohl(i)) != _CTYPE_REV)
- goto bad;
-
- if (fread(&len, sizeof(u_int32_t), 1, fp) != 1)
- goto bad;
- if ((len = ntohl(len)) != _CTYPE_CACHE_SIZE)
- goto bad;
-
- 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]);
+ 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;
}
-
- _wctype_init(rl);
-
- /*
- * __runetable_to_netbsd_ctype() will be called from
- * setrunelocale.c:_newrunelocale(), and fill old ctype table.
- */
-
- free(new_ctype);
- free(new_toupper);
- free(new_tolower);
- return(rl);
-
-bad:
- if (new_ctype)
- free(new_ctype);
- if (new_toupper)
- free(new_toupper);
- if (new_tolower)
- free(new_tolower);
- return NULL;
+ return ret;
}
Index: src/lib/libc/locale/runetable.c
diff -u src/lib/libc/locale/runetable.c:1.26 src/lib/libc/locale/runetable.c:1.27
--- src/lib/libc/locale/runetable.c:1.26 Sun Jun 13 04:14:57 2010
+++ src/lib/libc/locale/runetable.c Sat Jun 19 13:26:52 2010
@@ -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 @@
#include "runetype_local.h"
const _RuneLocale _DefaultRuneLocale = {
- _RUNECT10_MAGIC,
- "NONE",
- _DEFAULT_INVALID_RUNE,
-
{ /*00*/ _RUNETYPE_C,
_RUNETYPE_C,
_RUNETYPE_C,