aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog66
-rw-r--r--iconv/gconv_builtin.h36
-rw-r--r--iconv/gconv_int.h13
-rw-r--r--iconv/gconv_simple.c268
-rw-r--r--iconv/iconv_prog.c15
-rw-r--r--iconvdata/8bit-gap.c4
-rw-r--r--iconvdata/8bit-generic.c4
-rw-r--r--iconvdata/Makefile14
-rw-r--r--iconvdata/TESTS9
-rw-r--r--iconvdata/big5.c2
-rw-r--r--iconvdata/euccn.c2
-rw-r--r--iconvdata/eucjp.c2
-rw-r--r--iconvdata/euckr.c2
-rw-r--r--iconvdata/euctw.c2
-rw-r--r--iconvdata/gconv-modules125
-rw-r--r--iconvdata/iso646.c2
-rw-r--r--iconvdata/iso6937.c2
-rw-r--r--iconvdata/iso8859-1.c2
-rw-r--r--iconvdata/johab.c2
-rwxr-xr-xiconvdata/run-iconv-test.sh8
-rw-r--r--iconvdata/sjis.c2
-rw-r--r--iconvdata/t61.c2
-rw-r--r--iconvdata/testdata/ISO-8859-1..UTF812
-rw-r--r--iconvdata/testdata/ISO-8859-1012
-rw-r--r--iconvdata/testdata/ISO-8859-10..UCS2bin0 -> 788 bytes
-rw-r--r--iconvdata/testdata/ISO-8859-212
-rw-r--r--iconvdata/testdata/ISO-8859-2..UCS4bin0 -> 1576 bytes
-rw-r--r--iconvdata/testdata/ISO-8859-2..UTF812
-rw-r--r--iconvdata/testdata/ISO-8859-312
-rw-r--r--iconvdata/testdata/ISO-8859-412
-rw-r--r--iconvdata/testdata/ISO-8859-512
-rw-r--r--iconvdata/testdata/ISO-8859-612
-rw-r--r--iconvdata/testdata/ISO-8859-712
-rw-r--r--iconvdata/testdata/ISO-8859-811
-rw-r--r--iconvdata/testdata/ISO-8859-912
-rw-r--r--iconvdata/uhc.c2
-rw-r--r--stdlib/testmb.c6
-rw-r--r--sysdeps/i386/bits/byteswap.h6
-rw-r--r--wcsmbs/wcsmbsload.c12
39 files changed, 565 insertions, 176 deletions
diff --git a/ChangeLog b/ChangeLog
index 0068610dc3..65210542a1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,8 +1,73 @@
+1998-04-15 16:41 Ulrich Drepper <drepper@cygnus.com>
+
+ Don't name internal representation since it might be different from
+ the external form (namely on little endian machines).
+ * iconv/gconv_builtin.h: Add UCS4 support. Change references to
+ UCS4 into references to INTERNAL.
+ * iconv/gconv_simple.c: Implement UCS4<->INTERNAL converters.
+ Add endianess support to UCS functions. Change references to
+ UCS4 into references to INTERNAL.
+ * iconv/gconv_int.h: Change references to UCS4 into references to
+ INTERNAL.
+ * iconv/iconv_prog.c: Don't mention INTERNAL in --list output.
+ * iconvdata/gconv-modules: Change accordingly.
+ * wcsmbs/wcsmbsload.c: Change names to use INTERNAL.
+
+ * iconv/gconv_simple.c: Adjust input buffer pointer for output buffer
+ overflow.
+ * iconvdata/8bit-gap.c: Likewise.
+ * iconvdata/8bit-generic.c: Likewise.
+ * iconvdata/big5.c: Likewise.
+ * iconvdata/euccn.c: Likewise.
+ * iconvdata/eucjp.c: Likewise.
+ * iconvdata/euckr.c: Likewise.
+ * iconvdata/euctw.c: Likewise.
+ * iconvdata/iso646.c: Likewise.
+ * iconvdata/iso6937.c: Likewise.
+ * iconvdata/iso8859-1.c: Likewise.
+ * iconvdata/johab.c: Likewise.
+ * iconvdata/sjis.c: Likewise.
+ * iconvdata/t61.c: Likewise.
+ * iconvdata/uhc.c: Likewise.
+
+ * iconvdata/8bit-gap.c: Correct access to to_ucs4 array.
+ * iconvdata/8bit-generic.c: Likewise.
+
+ * iconvdata/TESTS: Add more tests.
+
+ * sysdeps/i386/bits/byteswap.h: Change to use "=r" when ror is used.
+
+1998-04-15 11:47 Ulrich Drepper <drepper@cygnus.com>
+
+ * iconvdata/Makefile: Better rules to run tests.
+
+ * iconvdata/testdata/ISO-8859-1..UTF8: New file.
+ * iconvdata/testdata/ISO-8859-10: Likewise.
+ * iconvdata/testdata/ISO-8859-10..UCS2: Likewise.
+ * iconvdata/testdata/ISO-8859-2: Likewise.
+ * iconvdata/testdata/ISO-8859-2..UCS4: Likewise.
+ * iconvdata/testdata/ISO-8859-2..UTF8: Likewise.
+ * iconvdata/testdata/ISO-8859-3: Likewise.
+ * iconvdata/testdata/ISO-8859-4: Likewise.
+ * iconvdata/testdata/ISO-8859-5: Likewise.
+ * iconvdata/testdata/ISO-8859-6: Likewise.
+ * iconvdata/testdata/ISO-8859-7: Likewise.
+ * iconvdata/testdata/ISO-8859-8: Likewise.
+ * iconvdata/testdata/ISO-8859-9: Likewise.
+
1998-04-15 Ulrich Drepper <drepper@cygnus.com>
+ * iconvdata/run-iconv-test.sh: Handle $from..$t file to compare
+ intermediate result (if available).
+
* iconv/gconv_simple.c (__gconv_transform_ucs4_ascii): Fix typo in
last change.
+ * iconvdata/Makefile: Add rules to run run-iconv-test.sh.
+ (distribute): Add run-iconv-test.sh and testdata/*.
+
+ * stdlib/testmb.c (main): Simplify mbc array handling.
+
1998-04-14 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
* elf/dl-minimal.c (__strtol_internal): Correct range check. Fix
@@ -27,6 +92,7 @@
* iconvdata/Makefile: Add rules to run tests.
* iconvdata/TESTS: New file.
* iconvdata/run-iconv-test.sh: New file.
+ * iconvdata/testdata/ISO-8859-1: New file.
* iconv/iconv_prog.c (main): Call process_block with OUTPUT stream,
not stdout.
diff --git a/iconv/gconv_builtin.h b/iconv/gconv_builtin.h
index 9c98c3513d..265dca1f01 100644
--- a/iconv/gconv_builtin.h
+++ b/iconv/gconv_builtin.h
@@ -18,27 +18,41 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
+BUILTIN_ALIAS ("UCS4//", "ISO-10646/UCS4/")
+BUILTIN_ALIAS ("UCS-4//", "ISO-10646/UCS4/")
+BUILTIN_ALIAS ("ISO-10646//", "ISO-10646/UCS4/")
+BUILTIN_ALIAS ("10646-1:1993//", "ISO-10646/UCS4/")
+BUILTIN_ALIAS ("10646-1:1993/UCS4/", "ISO-10646/UCS4/")
+
+BUILTIN_TRANSFORMATION (NULL, "INTERNAL", 8,
+ "ISO-10646/UCS4/", 1, "=INTERNAL->ucs4",
+ __gconv_transform_internal_ucs4, NULL, NULL)
+BUILTIN_TRANSFORMATION (NULL, "ISO-10646/UCS4/", 15,
+ "INTERNAL", 1, "=ucs4->INTERNAL",
+ __gconv_transform_internal_ucs4, NULL, NULL)
+/* Please note that we need only one function for both direction. */
+
BUILTIN_ALIAS ("UTF8//", "ISO-10646/UTF8/")
BUILTIN_ALIAS ("UTF-8//", "ISO-10646/UTF8/")
-BUILTIN_TRANSFORMATION (NULL, "ISO-10646/UCS4/", 15,
- "ISO-10646/UTF8/", 1, "=ucs4->utf8",
- __gconv_transform_ucs4_utf8, NULL, NULL)
+BUILTIN_TRANSFORMATION (NULL, "INTERNAL", 8,
+ "ISO-10646/UTF8/", 1, "=INTERNAL->utf8",
+ __gconv_transform_internal_utf8, NULL, NULL)
BUILTIN_TRANSFORMATION ("ISO-10646/UTF-?8/", "ISO-10646/UTF", 13,
- "ISO-10646/UCS4/", 1, "=utf8->ucs4",
- __gconv_transform_utf8_ucs4, NULL, NULL)
+ "INTERNAL", 1, "=utf8->INTERNAL",
+ __gconv_transform_utf8_internal, NULL, NULL)
BUILTIN_ALIAS ("UCS2//", "ISO-10646/UCS2/")
BUILTIN_ALIAS ("UCS-2//", "ISO-10646/UCS2/")
-BUILTIN_TRANSFORMATION (NULL, "ISO-10646/UCS2/", 15, "ISO-10646/UCS4/",
- 1, "=ucs2->ucs4",
- __gconv_transform_ucs2_ucs4, NULL, NULL)
+BUILTIN_TRANSFORMATION (NULL, "ISO-10646/UCS2/", 15, "INTERNAL",
+ 1, "=ucs2->INTERNAL",
+ __gconv_transform_ucs2_internal, NULL, NULL)
-BUILTIN_TRANSFORMATION (NULL, "ISO-10646/UCS4/", 15, "ISO-10646/UCS2/",
- 1, "=ucs4->ucs2",
- __gconv_transform_ucs4_ucs2, NULL, NULL)
+BUILTIN_TRANSFORMATION (NULL, "INTERNAL", 8, "ISO-10646/UCS2/",
+ 1, "=INTERNAL->ucs2",
+ __gconv_transform_internal_ucs2, NULL, NULL)
BUILTIN_TRANSFORMATION ("(.*)", NULL, 0, "\\1", 1, "=dummy",
__gconv_transform_dummy, NULL, NULL)
diff --git a/iconv/gconv_int.h b/iconv/gconv_int.h
index 35ec31a7b8..a1475f8508 100644
--- a/iconv/gconv_int.h
+++ b/iconv/gconv_int.h
@@ -153,12 +153,13 @@ extern void __gconv_get_builtin_trans (const char *__name,
int __do_flush)
__BUILTIN_TRANS (__gconv_transform_dummy);
-__BUILTIN_TRANS (__gconv_transform_ascii_ucs4);
-__BUILTIN_TRANS (__gconv_transform_ucs4_ascii);
-__BUILTIN_TRANS (__gconv_transform_ucs4_utf8);
-__BUILTIN_TRANS (__gconv_transform_utf8_ucs4);
-__BUILTIN_TRANS (__gconv_transform_ucs2_ucs4);
-__BUILTIN_TRANS (__gconv_transform_ucs4_ucs2);
+__BUILTIN_TRANS (__gconv_transform_ascii_internal);
+__BUILTIN_TRANS (__gconv_transform_internal_ascii);
+__BUILTIN_TRANS (__gconv_transform_utf8_internal);
+__BUILTIN_TRANS (__gconv_transform_internal_utf8);
+__BUILTIN_TRANS (__gconv_transform_ucs2_internal);
+__BUILTIN_TRANS (__gconv_transform_internal_ucs2);
+__BUILTIN_TRANS (__gconv_transform_internal_ucs4);
# undef __BUITLIN_TRANS
#endif
diff --git a/iconv/gconv_simple.c b/iconv/gconv_simple.c
index 38b6b56adb..b72e61edcc 100644
--- a/iconv/gconv_simple.c
+++ b/iconv/gconv_simple.c
@@ -18,6 +18,8 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
+#include <byteswap.h>
+#include <endian.h>
#include <errno.h>
#include <gconv.h>
#include <stdint.h>
@@ -76,16 +78,21 @@ __gconv_transform_dummy (struct gconv_step *step, struct gconv_step_data *data,
}
-/* Convert from ISO 646-IRV to ISO 10646/UCS4. */
+/* Transform from the internal, UCS4-like format, to UCS4. The
+ difference between the internal ucs4 format and the real UCS4
+ format is, if any, the endianess. The Unicode/ISO 10646 says that
+ unless some higher protocol specifies it differently, the byte
+ order is big endian.*/
int
-__gconv_transform_ascii_ucs4 (struct gconv_step *step,
- struct gconv_step_data *data, const char *inbuf,
- size_t *inlen, size_t *written, int do_flush)
+__gconv_transform_internal_ucs4 (struct gconv_step *step,
+ struct gconv_step_data *data,
+ const char *inbuf, size_t *inlen,
+ size_t *written, int do_flush)
{
struct gconv_step *next_step = step + 1;
struct gconv_step_data *next_data = data + 1;
gconv_fct fct = next_step->fct;
- size_t do_write;
+ size_t do_write = 0;
int result;
/* If the function is called with no input this means we have to reset
@@ -95,7 +102,6 @@ __gconv_transform_ascii_ucs4 (struct gconv_step *step,
{
/* Clear the state. */
memset (data->statep, '\0', sizeof (mbstate_t));
- do_write = 0;
/* Call the steps down the chain if there are any. */
if (data->is_last)
@@ -114,12 +120,126 @@ __gconv_transform_ascii_ucs4 (struct gconv_step *step,
else
{
int save_errno = errno;
- do_write = 0;
result = GCONV_OK;
do
{
- const unsigned char *newinbuf = inbuf;
+ size_t n_convert = (MIN (*inlen,
+ (data->outbufsize - data->outbufavail))
+ / sizeof (wchar_t));
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ /* Sigh, we have to do some real work. */
+ wchar_t *outbuf = (wchar_t *) &data->outbuf[data->outbufavail];
+ size_t cnt;
+
+ for (cnt = 0; cnt < n_convert; ++cnt)
+ outbuf[cnt] = bswap_32 (((wchar_t *) inbuf)[cnt]);
+
+#elif __BYTE_ORDER == __BIG_ENDIAN
+ /* Simply copy the data. */
+ memcpy (&data->outbuf[data->outbufsize], inbuf,
+ n_convert * sizeof (wchar_t));
+#else
+# error "This endianess is not supported."
+#endif
+
+ *inlen -= n_convert * sizeof (wchar_t);
+ inbuf += n_convert * sizeof (wchar_t);
+ data->outbufavail += n_convert * sizeof (wchar_t);
+ do_write += n_convert;
+
+ if (*inlen > 0 && *inlen < sizeof (wchar_t))
+ {
+ /* We have an incomplete character at the end. */
+ result = GCONV_INCOMPLETE_INPUT;
+ break;
+ }
+
+ if (data->is_last)
+ {
+ /* This is the last step. */
+ result = (*inlen < sizeof (wchar_t)
+ ? GCONV_EMPTY_INPUT : GCONV_FULL_OUTPUT);
+ break;
+ }
+
+ /* Status so far. */
+ result = GCONV_EMPTY_INPUT;
+
+ if (data->outbufavail > 0)
+ {
+ /* Call the functions below in the chain. */
+ size_t newavail = data->outbufavail;
+
+ result = (*fct) (next_step, next_data, data->outbuf, &newavail,
+ written, 0);
+
+ /* Correct the output buffer. */
+ if (newavail != data->outbufavail && newavail > 0)
+ {
+ memmove (data->outbuf,
+ &data->outbuf[data->outbufavail - newavail],
+ newavail);
+ data->outbufavail = newavail;
+ }
+ }
+ }
+ while (*inlen >= sizeof (wchar_t) && result == GCONV_EMPTY_INPUT);
+
+ __set_errno (save_errno);
+ }
+
+ if (written != NULL && data->is_last)
+ *written = do_write;
+
+ return result;
+}
+
+
+/* Convert from ISO 646-IRV to the internal (UCS4-like) format. */
+int
+__gconv_transform_ascii_internal (struct gconv_step *step,
+ struct gconv_step_data *data,
+ const char *inbuf, size_t *inlen,
+ size_t *written, int do_flush)
+{
+ struct gconv_step *next_step = step + 1;
+ struct gconv_step_data *next_data = data + 1;
+ gconv_fct fct = next_step->fct;
+ size_t do_write = 0;
+ int result;
+
+ /* If the function is called with no input this means we have to reset
+ to the initial state. The possibly partly converted input is
+ dropped. */
+ if (do_flush)
+ {
+ /* Clear the state. */
+ memset (data->statep, '\0', sizeof (mbstate_t));
+
+ /* Call the steps down the chain if there are any. */
+ if (data->is_last)
+ result = GCONV_OK;
+ else
+ {
+ struct gconv_step *next_step = step + 1;
+ struct gconv_step_data *next_data = data + 1;
+
+ result = (*fct) (next_step, next_data, NULL, 0, written, 1);
+
+ /* Clear output buffer. */
+ data->outbufavail = 0;
+ }
+ }
+ else
+ {
+ const unsigned char *newinbuf = inbuf;
+ int save_errno = errno;
+
+ result = GCONV_OK;
+ do
+ {
size_t actually = 0;
size_t cnt = 0;
@@ -193,9 +313,10 @@ __gconv_transform_ascii_ucs4 (struct gconv_step *step,
/* Convert from ISO 10646/UCS to ISO 646-IRV. */
int
-__gconv_transform_ucs4_ascii (struct gconv_step *step,
- struct gconv_step_data *data, const char *inbuf,
- size_t *inlen, size_t *written, int do_flush)
+__gconv_transform_internal_ascii (struct gconv_step *step,
+ struct gconv_step_data *data,
+ const char *inbuf, size_t *inlen,
+ size_t *written, int do_flush)
{
struct gconv_step *next_step = step + 1;
struct gconv_step_data *next_data = data + 1;
@@ -228,13 +349,13 @@ __gconv_transform_ucs4_ascii (struct gconv_step *step,
}
else
{
+ const wchar_t *newinbuf = (const wchar_t *) inbuf;
int save_errno = errno;
do_write = 0;
result = GCONV_OK;
do
{
- const wchar_t *newinbuf = (const wchar_t *) inbuf;
size_t actually = 0;
size_t cnt = 0;
@@ -264,11 +385,18 @@ __gconv_transform_ucs4_ascii (struct gconv_step *step,
if (result != GCONV_OK)
break;
+ /* Check for incomplete input. */
+ if (*inlen > 0 && *inlen < sizeof (wchar_t))
+ {
+ /* We have an incomplete character at the end. */
+ result = GCONV_INCOMPLETE_INPUT;
+ break;
+ }
+
if (data->is_last)
{
/* This is the last step. */
- result = (*inlen < sizeof (wchar_t)
- ? GCONV_EMPTY_INPUT : GCONV_FULL_OUTPUT);
+ result = *inlen == 0 ? GCONV_EMPTY_INPUT : GCONV_FULL_OUTPUT;
break;
}
@@ -306,9 +434,10 @@ __gconv_transform_ucs4_ascii (struct gconv_step *step,
int
-__gconv_transform_ucs4_utf8 (struct gconv_step *step,
- struct gconv_step_data *data, const char *inbuf,
- size_t *inlen, size_t *written, int do_flush)
+__gconv_transform_internal_utf8 (struct gconv_step *step,
+ struct gconv_step_data *data,
+ const char *inbuf, size_t *inlen,
+ size_t *written, int do_flush)
{
struct gconv_step *next_step = step + 1;
struct gconv_step_data *next_data = data + 1;
@@ -341,13 +470,13 @@ __gconv_transform_ucs4_utf8 (struct gconv_step *step,
}
else
{
+ const wchar_t *newinbuf = (const wchar_t *) inbuf;
int save_errno = errno;
do_write = 0;
result = GCONV_OK;
do
{
- const wchar_t *newinbuf = (const wchar_t *) inbuf;
size_t cnt = 0;
while (data->outbufavail < data->outbufsize
@@ -397,16 +526,24 @@ __gconv_transform_ucs4_utf8 (struct gconv_step *step,
/* Remember how much we converted. */
do_write += cnt;
*inlen -= cnt * sizeof (wchar_t);
+ newinbuf += cnt;
/* Check whether an illegal character appeared. */
if (result != GCONV_OK)
break;
+ /* Check for incomplete input. */
+ if (*inlen > 0 && *inlen < sizeof (wchar_t))
+ {
+ /* We have an incomplete character at the end. */
+ result = GCONV_INCOMPLETE_INPUT;
+ break;
+ }
+
if (data->is_last)
{
/* This is the last step. */
- result = (*inlen < sizeof (wchar_t)
- ? GCONV_EMPTY_INPUT : GCONV_FULL_OUTPUT);
+ result = *inlen == 0 ? GCONV_EMPTY_INPUT : GCONV_FULL_OUTPUT;
break;
}
@@ -444,9 +581,10 @@ __gconv_transform_ucs4_utf8 (struct gconv_step *step,
int
-__gconv_transform_utf8_ucs4 (struct gconv_step *step,
- struct gconv_step_data *data, const char *inbuf,
- size_t *inlen, size_t *written, int do_flush)
+__gconv_transform_utf8_internal (struct gconv_step *step,
+ struct