minix/lib/nbsd_libc/locale/bsdctype.c
Gianluca Guida b6cbf7203b Import unmodified NetBSD libc in trunk
This patch imports the unmodified current version of NetBSD libc.
The NetBSD includes are in /nbsd_include, while the libc code itself is 
split between lib/nbsd_libc and common/lib/libc.
2011-02-14 19:36:03 +00:00

179 lines
5.2 KiB
C

/* $NetBSD: bsdctype.c,v 1.9 2010/06/20 02:23:15 tnozaki Exp $ */
/*-
* Copyright (c)2008 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.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: bsdctype.c,v 1.9 2010/06/20 02:23:15 tnozaki Exp $");
#endif /* LIBC_SCCS and not lint */
#include <sys/endian.h>
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "bsdctype_local.h"
#include "runetype_misc.h"
const _BSDCTypeLocale _DefaultBSDCTypeLocale = {
_C_ctype_,
_C_tolower_,
_C_toupper_
};
const _BSDCTypeLocale *_CurrentBSDCTypeLocale = &_DefaultBSDCTypeLocale;
typedef struct {
_BSDCTypeLocale bl;
unsigned char blp_ctype_tab [_CTYPE_NUM_CHARS + 1];
short blp_tolower_tab[_CTYPE_NUM_CHARS + 1];
short blp_toupper_tab[_CTYPE_NUM_CHARS + 1];
} _BSDCTypeLocalePriv;
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;
blp->bl.bl_ctype_tab = &blp->blp_ctype_tab [0];
blp->bl.bl_tolower_tab = &blp->blp_tolower_tab[0];
blp->bl.bl_toupper_tab = &blp->blp_toupper_tab[0];
}
static __inline int
_bsdctype_read_file(const char * __restrict var, size_t lenvar,
_BSDCTypeLocalePriv * __restrict blp)
{
const _FileBSDCTypeLocale *fbl;
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 = be32toh(fbl->fbl_rev);
if (value != _CTYPE_REV)
return EFTYPE;
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] = be16toh(fbl->fbl_tolower_tab[i]);
blp->blp_toupper_tab[i + 1] = be16toh(fbl->fbl_toupper_tab[i]);
}
return 0;
}
static __inline int
_bsdctype_read_runetype(const char * __restrict var, size_t lenvar,
_BSDCTypeLocalePriv * __restrict blp)
{
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]);
}
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':
_bsdctype_read_file(var, lenvar, blp);
break;
case 'R':
_bsdctype_read_runetype(var, lenvar, blp);
break;
default:
ret = EFTYPE;
}
if (ret)
free(blp);
else
*pbl = &blp->bl;
return ret;
}