1998-04-05  Ulrich Drepper  <drepper@cygnus.com>

	* iconv/gconv_simple.c: Rewrite to not make use of the mb*towc*
	and wc*tomb* functions.

1998-04-04 15:16  Philip Blundell  <Philip.Blundell@pobox.com>

	* sysdeps/unix/start.c: Fix typo.

1998-04-04  Ulrich Drepper  <drepper@cygnus.com>

	* iconv/gconv_db.c (__gconv_find_transform): Fix typo.
This commit is contained in:
Ulrich Drepper 1998-04-05 11:23:12 +00:00
parent 923609d149
commit a904b5d93a
4 changed files with 176 additions and 30 deletions

View File

@ -1,3 +1,16 @@
1998-04-05 Ulrich Drepper <drepper@cygnus.com>
* iconv/gconv_simple.c: Rewrite to not make use of the mb*towc*
and wc*tomb* functions.
1998-04-04 15:16 Philip Blundell <Philip.Blundell@pobox.com>
* sysdeps/unix/start.c: Fix typo.
1998-04-04 Ulrich Drepper <drepper@cygnus.com>
* iconv/gconv_db.c (__gconv_find_transform): Fix typo.
1998-04-03 23:38 Ulrich Drepper <drepper@cygnus.com> 1998-04-03 23:38 Ulrich Drepper <drepper@cygnus.com>
* sysdeps/libm-ieee754/e_acos.c: Optimize by splitting large * sysdeps/libm-ieee754/e_acos.c: Optimize by splitting large

View File

@ -534,9 +534,9 @@ __gconv_find_transform (const char *toset, const char *fromset,
do do
if (steps[--cnt].counter++ == 0) if (steps[--cnt].counter++ == 0)
{ {
steps[--cnt].shlib_handle = steps[cnt].shlib_handle =
__gconv_find_shlib (steps[--cnt].modname); __gconv_find_shlib (steps[cnt].modname);
if (steps[--cnt].shlib_handle == NULL) if (steps[cnt].shlib_handle == NULL)
{ {
/* Oops, this is the second time we use this module (after /* Oops, this is the second time we use this module (after
unloading) and this time loading failed!? */ unloading) and this time loading failed!? */

View File

@ -26,6 +26,24 @@
#include <wchar.h> #include <wchar.h>
#include <sys/param.h> #include <sys/param.h>
#ifndef EILSEQ
# define EILSEQ EINVAL
#endif
/* These are definitions used by some of the functions for handling
UTF-8 encoding below. */
static const wchar_t encoding_mask[] =
{
~0x7ff, ~0xffff, ~0x1fffff, ~0x3ffffff
};
static const unsigned char encoding_byte[] =
{
0xc0, 0xe0, 0xf0, 0xf8, 0xfc
};
int int
__gconv_transform_dummy (struct gconv_step *step, struct gconv_step_data *data, __gconv_transform_dummy (struct gconv_step *step, struct gconv_step_data *data,
@ -97,30 +115,70 @@ __gconv_transform_ucs4_utf8 (struct gconv_step *step,
int save_errno = errno; int save_errno = errno;
do_write = 0; do_write = 0;
result = GCONV_OK;
do do
{ {
const char *newinbuf = inbuf; const wchar_t *newinbuf = (const wchar_t *) inbuf;
size_t actually; size_t actually = 0;
size_t cnt = 0;
errno = 0; while (data->outbufavail < data->outbufsize
actually = __wmemrtombs (&data->outbuf[data->outbufavail], && cnt * sizeof (wchar_t) <= *inlen)
(const wchar_t **) &newinbuf, {
*inlen / sizeof (wchar_t), wchar_t wc = newinbuf[cnt];
data->outbufsize - data->outbufavail,
data->statep); if (wc < 0 && wc > 0x7fffffff)
{
/* This is no correct ISO 10646 character. */
result = GCONV_ILLEGAL_INPUT;
break;
}
if (wc < 0x80)
{
/* It's an one byte sequence. */
data->outbuf[data->outbufavail++] = (char) wc;
++actually;
}
else
{
size_t step;
size_t start;
for (step = 2; step < 6; ++step)
if ((wc & encoding_mask[step - 2]) == 0)
break;
if (data->outbufavail + step >= data->outbufsize)
/* Too long. */
break;
start = data->outbufavail;
data->outbufavail += step;
actually += step;
data->outbuf[start] = encoding_byte[step - 2];
--step;
do
{
data->outbuf[start + step] = 0x80 | (wc & 0x3f);
wc >>= 6;
}
while (--step > 0);
data->outbuf[start] |= wc;
}
++cnt;
}
/* Remember how much we converted. */ /* Remember how much we converted. */
do_write += newinbuf - inbuf; do_write += cnt * sizeof (wchar_t);
*inlen -= newinbuf - inbuf; *inlen -= cnt * sizeof (wchar_t);
data->outbufavail += actually; data->outbufavail += actually;
/* Check whether an illegal character appeared. */ /* Check whether an illegal character appeared. */
if (errno != 0) if (result != GCONV_OK)
{ break;
result = GCONV_ILLEGAL_INPUT;
break;
}
if (data->is_last) if (data->is_last)
{ {
@ -199,26 +257,101 @@ __gconv_transform_utf8_ucs4 (struct gconv_step *step,
int save_errno = errno; int save_errno = errno;
do_write = 0; do_write = 0;
result = GCONV_OK;
do do
{ {
const char *newinbuf = inbuf; wchar_t *outbuf = (wchar_t *) &data->outbuf[data->outbufavail];
size_t actually; size_t cnt = 0;
size_t actually = 0;
errno = 0; while (data->outbufavail + sizeof (wchar_t) <= data->outbufsize
actually = __wmemrtowcs ((wchar_t *) &data->outbuf[data->outbufavail], && cnt < *inlen)
&newinbuf, *inlen, {
((data->outbufsize size_t start = cnt;
- data->outbufavail) / sizeof (wchar_t)), wchar_t value;
data->statep); unsigned char byte;
int count;
/* Next input byte. */
byte = inbuf[cnt++];
if (byte < 0x80)
{
/* One byte sequence. */
count = 0;
value = byte;
}
else if ((byte & 0xe0) == 0xc0)
{
count = 1;
value = byte & 0x1f;
}
else if ((byte & 0xf0) == 0xe0)
{
/* We expect three bytes. */
count = 2;
value = byte & 0x0f;
}
else if ((byte & 0xf8) == 0xf0)
{
/* We expect four bytes. */
count = 3;
value = byte & 0x07;
}
else if ((byte & 0xfc) == 0xf8)
{
/* We expect five bytes. */
count = 4;
value = byte & 0x03;
}
else if ((byte & 0xfe) == 0xfc)
{
/* We expect six bytes. */
count = 5;
value = byte & 0x01;
}
else
{
/* This is an illegal encoding. */
result = GCONV_ILLEGAL_INPUT;
break;
}
/* Read the possible remaining bytes. */
while (cnt < *inbuf && count > 0)
{
byte = inbuf[cnt++];
--count;
if ((byte & 0xc0) != 0x80)
{
/* This is an illegal encoding. */
result = GCONV_ILLEGAL_INPUT;
break;
}
value <<= 6;
value |= byte & 0x3f;
}
if (result != GCONV_OK)
{
cnt = start;
break;
}
*outbuf++ = value;
++actually;
}
/* Remember how much we converted. */ /* Remember how much we converted. */
do_write += actually; do_write += actually;
*inlen -= newinbuf - inbuf; *inlen -= cnt;
data->outbufavail += actually * sizeof (wchar_t); data->outbufavail += actually * sizeof (wchar_t);
/* Check whether an illegal character appeared. */ /* Check whether an illegal character appeared. */
if (errno != 0) if (result != GCONV_OK)
{ {
result = GCONV_ILLEGAL_INPUT; result = GCONV_ILLEGAL_INPUT;
break; break;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1991, 1993, 1995, 1996, 1997 Free Software Foundation, Inc. /* Copyright (C) 1991, 93, 95, 96, 97, 98 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -37,7 +37,7 @@ weak_alias (__data_start, data_start)
#ifndef errno #ifndef errno
volatile int __errno; volatile int __errno;
string_alias (__errno, errno) strong_alias (__errno, errno)
#endif #endif
extern void __libc_init __P ((int argc, char **argv, char **envp)); extern void __libc_init __P ((int argc, char **argv, char **envp));