aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1998-04-20 18:41:05 +0000
committerUlrich Drepper <drepper@redhat.com>1998-04-20 18:41:05 +0000
commit8619129f3f0d5a9db6208be5bae6c2a8c9ce61a5 (patch)
tree033b6528f39a85f12db9d0859dbd1b90c2906eee
parentf1fa8b68f3e7623a3ef86dcd0c7d090ccf0389f5 (diff)
downloadglibc-8619129f3f0d5a9db6208be5bae6c2a8c9ce61a5.tar
glibc-8619129f3f0d5a9db6208be5bae6c2a8c9ce61a5.tar.gz
glibc-8619129f3f0d5a9db6208be5bae6c2a8c9ce61a5.tar.bz2
glibc-8619129f3f0d5a9db6208be5bae6c2a8c9ce61a5.zip
Update.
1998-04-20 18:00 Ulrich Drepper <drepper@cygnus.com> * libc.map: Add __dgettext to GLIBC_2.0 and __libc_longjmp, and __libc_siglongjmp to GLIBC_2.1. * elf/dl-minimal.c (__assert_perror_fail): Don't use strerror, use __strerror_r. * iconv/Makefile: Don't run tests now. * iconv/iconv_prog.c (process_block): If loop is repeated, call iconv with correct output buffer. Major rewrite of the low-level gconv functionality. * iconv/gconv.c: Rewritten. * iconv/gconv.h: Likewise. * iconv/gconv_builtin.c: Likewise. * iconv/gconv_builtin.h: Likewise. * iconv/gconv_conf.c: Likewise. * iconv/gconv_int.h: Likewise. * iconv/gconv_open.c: Likewise. * iconv/gconv_simple.c: Likewise. * iconv/iconv.c: Likewise. * iconvdata/8bit-gap.c: Likewise. * iconvdata/8bit-generic.c: Likewise. * iconvdata/Makefile: Likewise. * iconvdata/big5.c: Likewise. * iconvdata/cns11643.c: Likewise. * iconvdata/cns11643.h: Likewise. * iconvdata/cns11643l1.c: Likewise. * iconvdata/cns11643l1.h: Likewise. * iconvdata/ebcdic-at-de-a.c: Likewise. * iconvdata/ebcdic-at-de.c: Likewise. * iconvdata/ebcdic-ca-fr.c: Likewise. * iconvdata/euccn.c: Likewise. * iconvdata/eucjp.c: Likewise. * iconvdata/euckr.c: Likewise. * iconvdata/euctw.c: Likewise. * iconvdata/gb2312.c: Likewise. * iconvdata/gb2312.h: Likewise. * iconvdata/hp-roman8.c: Likewise. * iconvdata/iso646.c: Likewise. * iconvdata/iso6937.c: Likewise. * iconvdata/iso8859-1.c: Likewise. * iconvdata/iso8859-10.c: Likewise. * iconvdata/iso8859-2.c: Likewise. * iconvdata/iso8859-3.c: Likewise. * iconvdata/iso8859-4.c: Likewise. * iconvdata/iso8859-5.c: Likewise. * iconvdata/iso8859-6.c: Likewise. * iconvdata/iso8859-7.c: Likewise. * iconvdata/iso8859-8.c: Likewise. * iconvdata/iso8859-9.c: Likewise. * iconvdata/jis0201.c: Likewise. * iconvdata/jis0201.h: Likewise. * iconvdata/jis0208.c: Likewise. * iconvdata/jis0208.h: Likewise. * iconvdata/jis0212.c: Likewise. * iconvdata/jis0212.h: Likewise. * iconvdata/johab.c: Likewise. * iconvdata/koi-8.c: Likewise. * iconvdata/koi8-r.c: Likewise. * iconvdata/ksc5601.c: Likewise. * iconvdata/ksc5601.h: Likewise. * iconvdata/latin-greek-1.c: Likewise. * iconvdata/latin-greek.c: Likewise. * iconvdata/run-iconv-test.sh: Likewise. * iconvdata/sjis.c: Likewise. * iconvdata/t61.c: Likewise. * iconvdata/uhc.c: Likewise. * wcsmbs/btowc.c: Likewise. * wcsmbs/mbrtowc.c: Likewise. * wcsmbs/mbsnrtowcs.c: Likewise. * wcsmbs/mbsrtowcs.c: Likewise. * wcsmbs/wcrtomb.c: Likewise. * wcsmbs/wcsmbsload.c: Likewise. * wcsmbs/wcsnrtombs.c: Likewise. * wcsmbs/wcsrtombs.c: Likewise. * wcsmbs/wctob.c: Likewise. * iconv/loop.c: New file. * iconv/skeleton.c: New file. * stdlib/mblen.c: Handle empty input string correctly. * stdlib/mbtowc.c: Likewise. * posix/getopt.c: Various cleanups. * sysdeps/arm/bits/setjmp.h: Add copyright text. * sysdeps/i386/bits/setjmp.h: Likewise. * sysdeps/m68k/bits/setjmp.h: Likewise. * sysdeps/powerpc/bits/setjmp.h: Likewise. * sysdeps/sparc/sparc32/bits/setjmp.h: Likewise. * sysdeps/generic/longjmp.c: Rename function to __libc_siglongjmp and make longjmp weak alias. 1998-04-18 20:29 Philip Blundell <Philip.Blundell@pobox.com> * iconv/Makefile (routines): Only include gconv_dl if building for an ELF system - dynamic linking is not available on a.out. (CFLAGS-gconv_conf.c): Define STATIC_GCONV if omitting gconv_dl due to above check. * iconv/gconv_db.c: If STATIC_GCONV defined, don't try to call routines from gconv_dl. 1998-04-17 Gordon Matzigkeit <gord@profitpress.com> * csu/init.c (_IO_stdin_used): Protect with USE_IN_LIBIO so that we can compile without libio. 1998-04-20 16:28 Ulrich Drepper <drepper@cygnus.com> * sysdeps/mach/hurd/Subdirs: Remove login. 1998-04-11 Gordon Matzigkeit <gord@profitpress.com> * db2/compat.h: Include <errno.h>, to make sure we get the definition of EFTYPE before we define it ourselves. 1998-04-10 Gordon Matzigkeit <gord@profitpress.com> * sysdeps/generic/bits/socket.h: Protect against multiple inclusion. * sysdeps/mach/hurd/bits/ioctls.h: Likewise. Fix typo to allow inclusion from sys/ioctl.h again. 1998-04-16 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * iconvdata/*.[ch]: Clean up namespace. Optimize character lookup. 1998-04-16 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * libc.map: Export __strerror_r. Remove _strerror_internal. 1998-04-16 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * sysdeps/generic/strcasestr.c: Undefine strcasestr, not strstr. Also undefine __strcasestr. 1998-04-16 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * posix/regex.c: Rename __re_max_failures back to re_max_failures, aliases do not work with global variables due to copy relocations. 1998-04-20 15:12 Ulrich Drepper <drepper@cygnus.com> * manual/creature.texi: Fix type. Patch by Andreas Schwab. 1998-04-20 13:47 Ulrich Drepper <drepper@cygnus.com> * signal/sighold.c: Include stddef.h for NULL definition. * signal/sigrelse.c: Likewise. * sysdeps/posix/sigignore.c: Likewise. * sysdeps/posix/sigset.c: Likewise. * sysdeps/posix/waitid.c: Likewise. * sysdeps/unix/sysv/linux/rt_sigsuspend.c: Likewise. * sysdeps/unix/sysv/linux/rt_sigtimedwait.c: Likewise. * sysdeps/unix/sysv/linux/sigwaitinfo.c: Likewise. * wcsmbs/mbsrtowcs.c: Include stdlib.h for MB_CUR_MAX. Patch by Franz Sirl <Franz.Sirl-kernel@lauterbach.com>. 1998-04-13 Mark Kettenis <kettenis@phys.uva.nl> * login/Makefile (headers): Remove utmpx.h and bits/utmpx.h. * login/getutent.c (getutxent): Remove alias. * login/getutent_r.c (setutxent, pututxline, endutxent): Remove aliases. * login/getutid.c (getutxid): Remove alias. * login/getutline.c (getutxline): Remove alias. * login/utmp.h: Add prototypes for __updwtmp, __getutent, __getutid, __getutline and __pututline. * login/utmpx.h: Moved to ... * sysdeps/gnu/utmpx.h: ... here. [__USE_GNU]: Define UTMPX_FILE, UTMPX_FILENAME, WTMPX_FILE and WTMPX_FILENAME, declare utmpxname and updwtmpx. * login/updwtmp.c: Moved to ... * sysdeps/generic/updwtmp.c: ... here. (updwtmp): Generalized by allowing file name transformation. * sysdeps/gnu/updwtmp.c: New file. Use generic implementation with additional file name transformation. * sysdeps/unix/sysv/linux/updwtmp.c: Likewise. * login/utmp_file.c: Moved to ... * sysdeps/generic/utmp_file.c: ... here. (setutent_file): Generalized by allowing file name transformation. Do not print error message. Library functions should not print them. Reported by Jim Meyering. * sysdeps/gnu/utmp_file.c: New file. Use generic implementation with additional file name transformation. * sysdeps/unix/sysv/linux/utmp_file.c: Likewise. * sysdeps/gnu/Makefile [$(subdir)=login] (sysdep_routines): Add setutxent, getutxent, endutxent, getutxid, getutxid, getutxline, pututxline, utmpxname and updwtmpx. (sysdep_headers): Add utmpx.h and bits/utmpx.h. * sysdeps/gnu/bits/utmpx.h [__USE_GNU] Include paths.h. (_PATH_UTMPX): Define to _PATH_UTMP. (_PATH_WTMPX): Define to _PATH_WTMPX. (RUN_LVL): Define only if __USE_GNU. (ACCOUNTING): Define if __USE_GNU. * sysdeps/gnu/setutxent.c: New file. * sysdeps/gnu/getutxent.c: New file. * sysdeps/gnu/endutxent.c: New file. * sysdeps/gnu/getutxid.c: New file. * sysdeps/gnu/getutxline.c: New file. * sysdeps/gnu/pututxline.c: New file. * sysdeps/gnu/utmpxname.c: New file. * sysdeps/gnu/updwtmpx.c: New file. * sysdeps/unix/sysv/linux/paths.h (_PATH_UTMP_DB): Remove. * sysdeps/generic/bits/utmpx.h: Remove. 1998-04-20 Ulrich Drepper <drepper@cygnus.com> * posix/wordexp-test.c (main): Initialize ifs element of ts for ~root test. 1998-04-17 07:53 H.J. Lu <hjl@gnu.org> * sysdeps/unix/sysv/linux/i386/s_pread64.S: Fix a typo. 1998-04-17 11:32 Ulrich Drepper <drepper@cygnus.com> * libio/oldfileops.c (_IO_old_file_seekoff): Define temporary st variable using _G_stat64. * libio/fileops.c: Remove macro definition of fstat, it is in the global header. Reported by Thorsten Kukuk <kukuk@weber.uni-paderborn.de>. 1998-04-17 Philip Blundell <pb@nexus.co.uk> * sysdeps/arm/strlen.S: New file, based on code by Matthew Wilcox <willy@odie.barnet.ac.uk>. 1998-04-16 Philip Blundell <Philip.Blundell@pobox.com> * inet/netinet/in.h (IN6_IS_ADDR_MC_NODELOCAL): New macro, required by IPv6 Basic API. (IN6_IS_ADDR_MC_LINKLOCAL): Likewise. (IN6_IS_ADDR_MC_SITELOCAL): Likewise. (IN6_IS_ADDR_MC_ORGLOCAL): Likewise. (IN6_IS_ADDR_MC_GLOBAL): Likewise.
-rw-r--r--ChangeLog238
-rw-r--r--FAQ34
-rw-r--r--FAQ.in32
-rw-r--r--bits/socket.h5
-rw-r--r--csu/init.c4
-rw-r--r--db2/compat.h1
-rw-r--r--elf/dl-minimal.c5
-rw-r--r--iconv/Makefile10
-rw-r--r--iconv/gconv.c53
-rw-r--r--iconv/gconv.h14
-rw-r--r--iconv/gconv_builtin.c17
-rw-r--r--iconv/gconv_builtin.h21
-rw-r--r--iconv/gconv_conf.c4
-rw-r--r--iconv/gconv_db.c8
-rw-r--r--iconv/gconv_int.h13
-rw-r--r--iconv/gconv_open.c17
-rw-r--r--iconv/gconv_simple.c1220
-rw-r--r--iconv/iconv.c19
-rw-r--r--iconv/iconv_prog.c9
-rw-r--r--iconv/loop.c226
-rw-r--r--iconv/skeleton.c328
-rw-r--r--iconvdata/8bit-gap.c255
-rw-r--r--iconvdata/8bit-generic.c236
-rw-r--r--iconvdata/Makefile6
-rw-r--r--iconvdata/big5.c451
-rw-r--r--iconvdata/cns11643.c6
-rw-r--r--iconvdata/cns11643.h220
-rw-r--r--iconvdata/cns11643l1.c30
-rw-r--r--iconvdata/cns11643l1.h210
-rw-r--r--iconvdata/ebcdic-at-de-a.c11
-rw-r--r--iconvdata/ebcdic-at-de.c11
-rw-r--r--iconvdata/ebcdic-ca-fr.c11
-rw-r--r--iconvdata/euccn.c376
-rw-r--r--iconvdata/eucjp.c480
-rw-r--r--iconvdata/euckr.c377
-rw-r--r--iconvdata/euctw.c459
-rw-r--r--iconvdata/gb2312.c20
-rw-r--r--iconvdata/gb2312.h251
-rw-r--r--iconvdata/hp-roman8.c11
-rw-r--r--iconvdata/iso646.c12
-rw-r--r--iconvdata/iso6937.c464
-rw-r--r--iconvdata/iso8859-1.c217
-rw-r--r--iconvdata/iso8859-10.c10
-rw-r--r--iconvdata/iso8859-2.c10
-rw-r--r--iconvdata/iso8859-3.c10
-rw-r--r--iconvdata/iso8859-4.c10
-rw-r--r--iconvdata/iso8859-5.c10
-rw-r--r--iconvdata/iso8859-6.c10
-rw-r--r--iconvdata/iso8859-7.c10
-rw-r--r--iconvdata/iso8859-8.c10
-rw-r--r--iconvdata/iso8859-9.c10
-rw-r--r--iconvdata/jis0201.c6
-rw-r--r--iconvdata/jis0201.h8
-rw-r--r--iconvdata/jis0208.c16
-rw-r--r--iconvdata/jis0208.h34
-rw-r--r--iconvdata/jis0212.c13
-rw-r--r--iconvdata/jis0212.h32
-rw-r--r--iconvdata/johab.c546
-rw-r--r--iconvdata/koi-8.c10
-rw-r--r--iconvdata/koi8-r.c11
-rw-r--r--iconvdata/ksc5601.c12
-rw-r--r--iconvdata/ksc5601.h53
-rw-r--r--iconvdata/latin-greek-1.c9
-rw-r--r--iconvdata/latin-greek.c9
-rwxr-xr-xiconvdata/run-iconv-test.sh10
-rw-r--r--iconvdata/sjis.c407
-rw-r--r--iconvdata/t61.c370
-rw-r--r--iconvdata/uhc.c448
-rw-r--r--inet/netinet/in.h16
-rw-r--r--libc.map6
-rw-r--r--libio/fileops.c1
-rw-r--r--libio/oldfileops.c2
-rw-r--r--linuxthreads/ChangeLog11
-rw-r--r--linuxthreads/Makefile4
-rw-r--r--linuxthreads/internals.h17
-rw-r--r--linuxthreads/ptlongjmp.c44
-rw-r--r--linuxthreads/spinlock.c59
-rw-r--r--linuxthreads/spinlock.h4
-rw-r--r--login/Makefile2
-rw-r--r--login/getutent.c3
-rw-r--r--login/getutent_r.c5
-rw-r--r--login/getutid.c3
-rw-r--r--login/getutline.c3
-rw-r--r--login/utmp.h8
-rw-r--r--manual/creature.texi2
-rw-r--r--posix/getopt.c65
-rw-r--r--posix/regex.c21
-rw-r--r--posix/wordexp-test.c19
-rw-r--r--signal/sighold.c2
-rw-r--r--signal/sigrelse.c2
-rw-r--r--stdlib/mblen.c30
-rw-r--r--stdlib/mbtowc.c24
-rw-r--r--sysdeps/arm/bits/setjmp.h18
-rw-r--r--sysdeps/arm/strlen.S55
-rw-r--r--sysdeps/generic/bits/socket.h5
-rw-r--r--sysdeps/generic/endutxent.c (renamed from sysdeps/generic/bits/utmpx.h)27
-rw-r--r--sysdeps/generic/getutxent.c27
-rw-r--r--sysdeps/generic/getutxid.c27
-rw-r--r--sysdeps/generic/getutxline.c27
-rw-r--r--sysdeps/generic/longjmp.c10
-rw-r--r--sysdeps/generic/pututxline.c27
-rw-r--r--sysdeps/generic/setjmp.c6
-rw-r--r--sysdeps/generic/setutxent.c27
-rw-r--r--sysdeps/generic/strcasestr.c5
-rw-r--r--sysdeps/generic/updwtmp.c (renamed from login/updwtmp.c)27
-rw-r--r--sysdeps/generic/updwtmpx.c27
-rw-r--r--sysdeps/generic/utmp_file.c (renamed from login/utmp_file.c)18
-rw-r--r--sysdeps/generic/utmpxname.c27
-rw-r--r--sysdeps/gnu/Makefile7
-rw-r--r--sysdeps/gnu/bits/utmpx.h19
-rw-r--r--sysdeps/gnu/updwtmp.c30
-rw-r--r--sysdeps/gnu/utmp_file.c30
-rw-r--r--sysdeps/gnu/utmpx.h (renamed from login/utmpx.h)21
-rw-r--r--sysdeps/i386/bits/setjmp.h18
-rw-r--r--sysdeps/m68k/bits/setjmp.h18
-rw-r--r--sysdeps/mach/hurd/Subdirs1
-rw-r--r--sysdeps/mach/hurd/bits/ioctls.h7
-rw-r--r--sysdeps/posix/sigignore.c2
-rw-r--r--sysdeps/posix/sigset.c2
-rw-r--r--sysdeps/posix/waitid.c4
-rw-r--r--sysdeps/powerpc/bits/setjmp.h18
-rw-r--r--sysdeps/powerpc/elf/start.c125
-rw-r--r--sysdeps/sparc/sparc32/bits/setjmp.h18
-rw-r--r--sysdeps/unix/sysv/linux/i386/s_pread64.S2
-rw-r--r--sysdeps/unix/sysv/linux/paths.h1
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c5
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/syscall.h357
-rw-r--r--sysdeps/unix/sysv/linux/rt_sigsuspend.c4
-rw-r--r--sysdeps/unix/sysv/linux/rt_sigtimedwait.c4
-rw-r--r--sysdeps/unix/sysv/linux/sigwaitinfo.c4
-rw-r--r--sysdeps/unix/sysv/linux/updwtmp.c34
-rw-r--r--sysdeps/unix/sysv/linux/utmp_file.c34
-rw-r--r--wcsmbs/btowc.c8
-rw-r--r--wcsmbs/mbrtowc.c18
-rw-r--r--wcsmbs/mbsnrtowcs.c23
-rw-r--r--wcsmbs/mbsrtowcs.c23
-rw-r--r--wcsmbs/wcrtomb.c20
-rw-r--r--wcsmbs/wcsmbsload.c12
-rw-r--r--wcsmbs/wcsnrtombs.c35
-rw-r--r--wcsmbs/wcsrtombs.c35
-rw-r--r--wcsmbs/wctob.c13
141 files changed, 4524 insertions, 5617 deletions
diff --git a/ChangeLog b/ChangeLog
index 65210542a1..105bed4c21 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,241 @@
+1998-04-20 18:00 Ulrich Drepper <drepper@cygnus.com>
+
+ * libc.map: Add __dgettext to GLIBC_2.0 and __libc_longjmp, and
+ __libc_siglongjmp to GLIBC_2.1.
+
+ * elf/dl-minimal.c (__assert_perror_fail): Don't use strerror, use
+ __strerror_r.
+
+ * iconv/Makefile: Don't run tests now.
+
+ * iconv/iconv_prog.c (process_block): If loop is repeated, call iconv
+ with correct output buffer.
+
+ Major rewrite of the low-level gconv functionality.
+ * iconv/gconv.c: Rewritten.
+ * iconv/gconv.h: Likewise.
+ * iconv/gconv_builtin.c: Likewise.
+ * iconv/gconv_builtin.h: Likewise.
+ * iconv/gconv_conf.c: Likewise.
+ * iconv/gconv_int.h: Likewise.
+ * iconv/gconv_open.c: Likewise.
+ * iconv/gconv_simple.c: Likewise.
+ * iconv/iconv.c: Likewise.
+ * iconvdata/8bit-gap.c: Likewise.
+ * iconvdata/8bit-generic.c: Likewise.
+ * iconvdata/Makefile: Likewise.
+ * iconvdata/big5.c: Likewise.
+ * iconvdata/cns11643.c: Likewise.
+ * iconvdata/cns11643.h: Likewise.
+ * iconvdata/cns11643l1.c: Likewise.
+ * iconvdata/cns11643l1.h: Likewise.
+ * iconvdata/ebcdic-at-de-a.c: Likewise.
+ * iconvdata/ebcdic-at-de.c: Likewise.
+ * iconvdata/ebcdic-ca-fr.c: Likewise.
+ * iconvdata/euccn.c: Likewise.
+ * iconvdata/eucjp.c: Likewise.
+ * iconvdata/euckr.c: Likewise.
+ * iconvdata/euctw.c: Likewise.
+ * iconvdata/gb2312.c: Likewise.
+ * iconvdata/gb2312.h: Likewise.
+ * iconvdata/hp-roman8.c: Likewise.
+ * iconvdata/iso646.c: Likewise.
+ * iconvdata/iso6937.c: Likewise.
+ * iconvdata/iso8859-1.c: Likewise.
+ * iconvdata/iso8859-10.c: Likewise.
+ * iconvdata/iso8859-2.c: Likewise.
+ * iconvdata/iso8859-3.c: Likewise.
+ * iconvdata/iso8859-4.c: Likewise.
+ * iconvdata/iso8859-5.c: Likewise.
+ * iconvdata/iso8859-6.c: Likewise.
+ * iconvdata/iso8859-7.c: Likewise.
+ * iconvdata/iso8859-8.c: Likewise.
+ * iconvdata/iso8859-9.c: Likewise.
+ * iconvdata/jis0201.c: Likewise.
+ * iconvdata/jis0201.h: Likewise.
+ * iconvdata/jis0208.c: Likewise.
+ * iconvdata/jis0208.h: Likewise.
+ * iconvdata/jis0212.c: Likewise.
+ * iconvdata/jis0212.h: Likewise.
+ * iconvdata/johab.c: Likewise.
+ * iconvdata/koi-8.c: Likewise.
+ * iconvdata/koi8-r.c: Likewise.
+ * iconvdata/ksc5601.c: Likewise.
+ * iconvdata/ksc5601.h: Likewise.
+ * iconvdata/latin-greek-1.c: Likewise.
+ * iconvdata/latin-greek.c: Likewise.
+ * iconvdata/run-iconv-test.sh: Likewise.
+ * iconvdata/sjis.c: Likewise.
+ * iconvdata/t61.c: Likewise.
+ * iconvdata/uhc.c: Likewise.
+ * wcsmbs/btowc.c: Likewise.
+ * wcsmbs/mbrtowc.c: Likewise.
+ * wcsmbs/mbsnrtowcs.c: Likewise.
+ * wcsmbs/mbsrtowcs.c: Likewise.
+ * wcsmbs/wcrtomb.c: Likewise.
+ * wcsmbs/wcsmbsload.c: Likewise.
+ * wcsmbs/wcsnrtombs.c: Likewise.
+ * wcsmbs/wcsrtombs.c: Likewise.
+ * wcsmbs/wctob.c: Likewise.
+ * iconv/loop.c: New file.
+ * iconv/skeleton.c: New file.
+
+ * stdlib/mblen.c: Handle empty input string correctly.
+ * stdlib/mbtowc.c: Likewise.
+
+ * posix/getopt.c: Various cleanups.
+
+ * sysdeps/arm/bits/setjmp.h: Add copyright text.
+ * sysdeps/i386/bits/setjmp.h: Likewise.
+ * sysdeps/m68k/bits/setjmp.h: Likewise.
+ * sysdeps/powerpc/bits/setjmp.h: Likewise.
+ * sysdeps/sparc/sparc32/bits/setjmp.h: Likewise.
+
+ * sysdeps/generic/longjmp.c: Rename function to __libc_siglongjmp
+ and make longjmp weak alias.
+
+1998-04-18 20:29 Philip Blundell <Philip.Blundell@pobox.com>
+
+ * iconv/Makefile (routines): Only include gconv_dl if building for
+ an ELF system - dynamic linking is not available on a.out.
+ (CFLAGS-gconv_conf.c): Define STATIC_GCONV if omitting gconv_dl
+ due to above check.
+ * iconv/gconv_db.c: If STATIC_GCONV defined, don't try to call
+ routines from gconv_dl.
+
+1998-04-17 Gordon Matzigkeit <gord@profitpress.com>
+
+ * csu/init.c (_IO_stdin_used): Protect with USE_IN_LIBIO so that
+ we can compile without libio.
+
+1998-04-20 16:28 Ulrich Drepper <drepper@cygnus.com>
+
+ * sysdeps/mach/hurd/Subdirs: Remove login.
+
+1998-04-11 Gordon Matzigkeit <gord@profitpress.com>
+
+ * db2/compat.h: Include <errno.h>, to make sure we get the
+ definition of EFTYPE before we define it ourselves.
+
+1998-04-10 Gordon Matzigkeit <gord@profitpress.com>
+
+ * sysdeps/generic/bits/socket.h: Protect against multiple inclusion.
+ * sysdeps/mach/hurd/bits/ioctls.h: Likewise.
+ Fix typo to allow inclusion from sys/ioctl.h again.
+
+1998-04-16 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * iconvdata/*.[ch]: Clean up namespace. Optimize character lookup.
+
+1998-04-16 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * libc.map: Export __strerror_r. Remove _strerror_internal.
+
+1998-04-16 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * sysdeps/generic/strcasestr.c: Undefine strcasestr, not strstr.
+ Also undefine __strcasestr.
+
+1998-04-16 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * posix/regex.c: Rename __re_max_failures back to re_max_failures,
+ aliases do not work with global variables due to copy relocations.
+
+1998-04-20 15:12 Ulrich Drepper <drepper@cygnus.com>
+
+ * manual/creature.texi: Fix type. Patch by Andreas Schwab.
+
+1998-04-20 13:47 Ulrich Drepper <drepper@cygnus.com>
+
+ * signal/sighold.c: Include stddef.h for NULL definition.
+ * signal/sigrelse.c: Likewise.
+ * sysdeps/posix/sigignore.c: Likewise.
+ * sysdeps/posix/sigset.c: Likewise.
+ * sysdeps/posix/waitid.c: Likewise.
+ * sysdeps/unix/sysv/linux/rt_sigsuspend.c: Likewise.
+ * sysdeps/unix/sysv/linux/rt_sigtimedwait.c: Likewise.
+ * sysdeps/unix/sysv/linux/sigwaitinfo.c: Likewise.
+ * wcsmbs/mbsrtowcs.c: Include stdlib.h for MB_CUR_MAX.
+ Patch by Franz Sirl <Franz.Sirl-kernel@lauterbach.com>.
+
+1998-04-13 Mark Kettenis <kettenis@phys.uva.nl>
+
+ * login/Makefile (headers): Remove utmpx.h and bits/utmpx.h.
+ * login/getutent.c (getutxent): Remove alias.
+ * login/getutent_r.c (setutxent, pututxline, endutxent):
+ Remove aliases.
+ * login/getutid.c (getutxid): Remove alias.
+ * login/getutline.c (getutxline): Remove alias.
+ * login/utmp.h: Add prototypes for __updwtmp, __getutent,
+ __getutid, __getutline and __pututline.
+ * login/utmpx.h: Moved to ...
+ * sysdeps/gnu/utmpx.h: ... here. [__USE_GNU]: Define UTMPX_FILE,
+ UTMPX_FILENAME, WTMPX_FILE and WTMPX_FILENAME, declare utmpxname
+ and updwtmpx.
+ * login/updwtmp.c: Moved to ...
+ * sysdeps/generic/updwtmp.c: ... here. (updwtmp): Generalized by
+ allowing file name transformation.
+ * sysdeps/gnu/updwtmp.c: New file. Use generic implementation with
+ additional file name transformation.
+ * sysdeps/unix/sysv/linux/updwtmp.c: Likewise.
+ * login/utmp_file.c: Moved to ...
+ * sysdeps/generic/utmp_file.c: ... here. (setutent_file):
+ Generalized by allowing file name transformation. Do not
+ print error message. Library functions should not print them.
+ Reported by Jim Meyering.
+ * sysdeps/gnu/utmp_file.c: New file. Use generic implementation
+ with additional file name transformation.
+ * sysdeps/unix/sysv/linux/utmp_file.c: Likewise.
+ * sysdeps/gnu/Makefile [$(subdir)=login] (sysdep_routines): Add
+ setutxent, getutxent, endutxent, getutxid, getutxid, getutxline,
+ pututxline, utmpxname and updwtmpx. (sysdep_headers): Add utmpx.h
+ and bits/utmpx.h.
+ * sysdeps/gnu/bits/utmpx.h [__USE_GNU] Include paths.h.
+ (_PATH_UTMPX): Define to _PATH_UTMP. (_PATH_WTMPX): Define to
+ _PATH_WTMPX. (RUN_LVL): Define only if __USE_GNU. (ACCOUNTING):
+ Define if __USE_GNU.
+ * sysdeps/gnu/setutxent.c: New file.
+ * sysdeps/gnu/getutxent.c: New file.
+ * sysdeps/gnu/endutxent.c: New file.
+ * sysdeps/gnu/getutxid.c: New file.
+ * sysdeps/gnu/getutxline.c: New file.
+ * sysdeps/gnu/pututxline.c: New file.
+ * sysdeps/gnu/utmpxname.c: New file.
+ * sysdeps/gnu/updwtmpx.c: New file.
+ * sysdeps/unix/sysv/linux/paths.h (_PATH_UTMP_DB): Remove.
+ * sysdeps/generic/bits/utmpx.h: Remove.
+
+1998-04-20 Ulrich Drepper <drepper@cygnus.com>
+
+ * posix/wordexp-test.c (main): Initialize ifs element of ts for
+ ~root test.
+
+1998-04-17 07:53 H.J. Lu <hjl@gnu.org>
+
+ * sysdeps/unix/sysv/linux/i386/s_pread64.S: Fix a typo.
+
+1998-04-17 11:32 Ulrich Drepper <drepper@cygnus.com>
+
+ * libio/oldfileops.c (_IO_old_file_seekoff): Define temporary st
+ variable using _G_stat64.
+ * libio/fileops.c: Remove macro definition of fstat, it is in the
+ global header.
+ Reported by Thorsten Kukuk <kukuk@weber.uni-paderborn.de>.
+
+1998-04-17 Philip Blundell <pb@nexus.co.uk>
+
+ * sysdeps/arm/strlen.S: New file, based on code by Matthew Wilcox
+ <willy@odie.barnet.ac.uk>.
+
+1998-04-16 Philip Blundell <Philip.Blundell@pobox.com>
+
+ * inet/netinet/in.h (IN6_IS_ADDR_MC_NODELOCAL): New macro,
+ required by IPv6 Basic API.
+ (IN6_IS_ADDR_MC_LINKLOCAL): Likewise.
+ (IN6_IS_ADDR_MC_SITELOCAL): Likewise.
+ (IN6_IS_ADDR_MC_ORGLOCAL): Likewise.
+ (IN6_IS_ADDR_MC_GLOBAL): Likewise.
+
1998-04-15 16:41 Ulrich Drepper <drepper@cygnus.com>
Don't name internal representation since it might be different from
diff --git a/FAQ b/FAQ
index 6eb4ff0fef..ed4658149c 100644
--- a/FAQ
+++ b/FAQ
@@ -24,7 +24,7 @@ please let me know.
1.3. When I try to compile glibc I get only error messages.
What's wrong?
1.4. Do I need a special linker or archiver?
-1.5. What tools do I need for powerpc?
+1.5. Which compiler should I use for powerpc?
1.6. Do I need some more things to compile GNU C Library?
1.7. What version of the Linux kernel headers should be used?
1.8. When I run `nm -u libc.so' on the produced library I still
@@ -203,25 +203,19 @@ may have native linker support, but it's moot right now, because glibc
has not been ported to them.
-1.5. What tools do I need for powerpc?
+1.5. Which compiler should I use for powerpc?
-{GK} For a successful installation you definitely need the most recent
-tools. You can safely assume that anything earlier than binutils
-2.8.1.0.17 and egcs-1.0 will have problems. We'd advise at the moment
-binutils 2.8.1.0.18 and egcs-1.0.1.
+{GK} You want to use egcs 1.0.1 or later (together with the right
+versions of all the other tools, of course).
-In fact, egcs 1.0.1 currently has two serious bugs that prevent a
-clean make; one relates to switch statement folding, for which there
-is a temporary patch at
+In fact, egcs 1.0.1 has a serious bug that prevents a clean make,
+relating to switch statement folding. It also causes the resulting
+shared libraries to use more memory than they should. There is a
+patch at:
-<http://discus.anu.edu.au/~geoffk/egcs-1.0-geoffk.diff.gz>
+<http://discus.anu.edu.au/~geoffk/egcs-1.0.1-geoffk.diff>
-and the other relates to 'forbidden register spilled', for which the
-workaround is to put
-
-CFLAGS-condvar.c += -fno-inline
-
-in configparms. Later versions of egcs may fix these problems.
+Later versions of egcs may fix these problems.
1.6. Do I need some more things to compile GNU C Library?
@@ -247,7 +241,8 @@ in configparms. Later versions of egcs may fix these problems.
* When compiling for Linux, the header files of the Linux kernel must
be available to the compiler as <linux/*.h> and <asm/*.h>.
-* lots of disk space (~170MB for i?86-linux; more for RISC platforms).
+* lots of disk space (~170MB for i?86-linux; more for RISC platforms,
+ as much as 400MB).
* plenty of time. Compiling just the shared and static libraries for
i?86-linux takes approximately 1h on an i586@133, or 2.5h on
@@ -290,9 +285,6 @@ symbols:
* symbols starting with _dl_* come from the dynamic linker
-* symbols resolved by using libgcc.a
- (__udivdi3, __umoddi3, or similar)
-
* weak symbols, which need not be resolved at all (fabs for example)
Generally, you should make sure you find a real program which produces
@@ -1141,7 +1133,7 @@ Answers were given by:
{MK} Mark Kettenis, <kettenis@phys.uva.nl>
{ZW} Zack Weinberg, <zack@rabi.phys.columbia.edu>
{TK} Thorsten Kukuk, <kukuk@vt.uni-paderborn.de>
-{GK} Geoffrey Keating, <Geoff.Keating@anu.edu.au>
+{GK} Geoffrey Keating, <geoffk@ozemail.com.au>
{HJ} H.J. Lu, <hjl@gnu.org>
Local Variables:
diff --git a/FAQ.in b/FAQ.in
index 7ca0218ec6..0a8277fbe2 100644
--- a/FAQ.in
+++ b/FAQ.in
@@ -89,25 +89,19 @@ required. For Linux, get binutils-2.8.1.0.23 or later. Other systems
may have native linker support, but it's moot right now, because glibc
has not been ported to them.
-??powerpc What tools do I need for powerpc?
+??powerpc Which compiler should I use for powerpc?
-{GK} For a successful installation you definitely need the most recent
-tools. You can safely assume that anything earlier than binutils
-2.8.1.0.17 and egcs-1.0 will have problems. We'd advise at the moment
-binutils 2.8.1.0.18 and egcs-1.0.1.
+{GK} You want to use egcs 1.0.1 or later (together with the right
+versions of all the other tools, of course).
-In fact, egcs 1.0.1 currently has two serious bugs that prevent a
-clean make; one relates to switch statement folding, for which there
-is a temporary patch at
+In fact, egcs 1.0.1 has a serious bug that prevents a clean make,
+relating to switch statement folding. It also causes the resulting
+shared libraries to use more memory than they should. There is a
+patch at:
-<http://discus.anu.edu.au/~geoffk/egcs-1.0-geoffk.diff.gz>
+<http://discus.anu.edu.au/~geoffk/egcs-1.0.1-geoffk.diff>
-and the other relates to 'forbidden register spilled', for which the
-workaround is to put
-
-CFLAGS-condvar.c += -fno-inline
-
-in configparms. Later versions of egcs may fix these problems.
+Later versions of egcs may fix these problems.
?? Do I need some more things to compile GNU C Library?
@@ -133,7 +127,8 @@ in configparms. Later versions of egcs may fix these problems.
* When compiling for Linux, the header files of the Linux kernel must
be available to the compiler as <linux/*.h> and <asm/*.h>.
-* lots of disk space (~170MB for i?86-linux; more for RISC platforms).
+* lots of disk space (~170MB for i?86-linux; more for RISC platforms,
+ as much as 400MB).
* plenty of time. Compiling just the shared and static libraries for
i?86-linux takes approximately 1h on an i586@133, or 2.5h on
@@ -174,9 +169,6 @@ symbols:
* symbols starting with _dl_* come from the dynamic linker
-* symbols resolved by using libgcc.a
- (__udivdi3, __umoddi3, or similar)
-
* weak symbols, which need not be resolved at all (fabs for example)
Generally, you should make sure you find a real program which produces
@@ -981,7 +973,7 @@ Answers were given by:
{MK} Mark Kettenis, <kettenis@phys.uva.nl>
{ZW} Zack Weinberg, <zack@rabi.phys.columbia.edu>
{TK} Thorsten Kukuk, <kukuk@vt.uni-paderborn.de>
-{GK} Geoffrey Keating, <Geoff.Keating@anu.edu.au>
+{GK} Geoffrey Keating, <geoffk@ozemail.com.au>
{HJ} H.J. Lu, <hjl@gnu.org>
Local Variables:
diff --git a/bits/socket.h b/bits/socket.h
index 5dc1e65370..01844bc143 100644
--- a/bits/socket.h
+++ b/bits/socket.h
@@ -17,6 +17,9 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
+#ifndef __BITS_SOCKET_H
+#define __BITS_SOCKET_H 1
+
#if !defined _SYS_SOCKET_H && !defined _NETINET_IN_H
# error "Never include <bits/socket.h> directly; use <sys/socket.h> instead."
#endif
@@ -196,3 +199,5 @@ struct linger
int l_onoff; /* Nonzero to linger on close. */
int l_linger; /* Time to linger. */
};
+
+#endif /* bits/socket.h */
diff --git a/csu/init.c b/csu/init.c
index 2b7a2ef0ff..df08f6c918 100644
--- a/csu/init.c
+++ b/csu/init.c
@@ -1,5 +1,5 @@
/* Special startup support.
- Copyright (C) 1997 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it
@@ -26,7 +26,7 @@
write to the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#if defined __GNUC__ && __GNUC__ >= 2
+#if defined USE_IN_LIBIO && defined __GNUC__ && __GNUC__ >= 2
#undef _LIBC
#include <libio.h>
diff --git a/db2/compat.h b/db2/compat.h
index 8652ad97ec..86909aeb13 100644
--- a/db2/compat.h
+++ b/db2/compat.h
@@ -1,6 +1,7 @@
/* Compatibility gunk for the db library. */
#include <sys/types.h>
+#include <errno.h>
#ifndef EFTYPE
# define EFTYPE EINVAL
diff --git a/elf/dl-minimal.c b/elf/dl-minimal.c
index b0c8c465e4..70b5aeeeac 100644
--- a/elf/dl-minimal.c
+++ b/elf/dl-minimal.c
@@ -193,12 +193,15 @@ __assert_perror_fail (int errnum,
const char *file, unsigned int line,
const char *function)
{
+ char errbuf[64];
char buf[64];
buf[sizeof buf - 1] = '\0';
_dl_sysdep_fatal ("BUG IN DYNAMIC LINKER ld.so: ",
file, ": ", _itoa_word (line, buf + sizeof buf - 1, 10, 0),
": ", function ?: "", function ? ": " : "",
- "Unexpected error: ", strerror (errnum), "\n", NULL);
+ "Unexpected error: ",
+ __strerror_r (errnum, errbuf, sizeof (errbuf)), "\n",
+ NULL);
}
diff --git a/iconv/Makefile b/iconv/Makefile
index 783b1d55b5..e4cd0fc53d 100644
--- a/iconv/Makefile
+++ b/iconv/Makefile
@@ -21,10 +21,18 @@
#
subdir := iconv
+include ../Makeconfig
+
headers = iconv.h gconv.h
routines = iconv_open iconv iconv_close \
gconv_open gconv gconv_close gconv_db gconv_conf \
- gconv_dl gconv_builtin gconv_simple
+ gconv_builtin gconv_simple
+ifeq ($(elf),yes)
+routines += gconv_dl
+else
+CFLAGS-gconv_db.c = -DSTATIC_GCONV
+endif
+
distribute = gconv_builtin.h gconv_int.h
others = iconv_prog
diff --git a/iconv/gconv.c b/iconv/gconv.c
index f8b7c8050d..aa58bdba7d 100644
--- a/iconv/gconv.c
+++ b/iconv/gconv.c
@@ -19,39 +19,58 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
+#include <assert.h>
#include <gconv.h>
+#include <sys/param.h>
int
internal_function
-__gconv (gconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf,
- size_t *outbytesleft, size_t *converted)
+__gconv (gconv_t cd, const char **inbuf, const char *inbufend, char **outbuf,
+ char *outbufend, size_t *converted)
{
size_t last_step = cd->nsteps - 1;
- size_t oldinbytes = *inbytesleft;
int result;
if (cd == (gconv_t) -1L)
return GCONV_ILLEGAL_DESCRIPTOR;
- cd->data[last_step].outbuf = outbuf ? *outbuf : NULL;
- cd->data[last_step].outbufavail = 0;
- cd->data[last_step].outbufsize = *outbytesleft;
+ assert (converted != NULL);
+ *converted = 0;
- if (converted != NULL)
- *converted = 0;
+ if (inbuf == NULL || *inbuf == NULL)
+ /* We just flush. */
+ result = (*cd->steps->fct) (cd->steps, cd->data, NULL, NULL, converted, 1);
+ else
+ {
+ const char *last_start;
- result = (*cd->steps->fct) (cd->steps, cd->data,
- inbuf ? *inbuf : NULL, inbytesleft,
- converted, inbuf == NULL || *inbuf == NULL);
+ assert (outbuf != NULL && *outbuf != NULL);
+ cd->data[last_step].outbuf = *outbuf;
+ cd->data[last_step].outbufend = outbufend;
- if (inbuf != NULL && *inbuf != NULL)
- *inbuf += oldinbytes - *inbytesleft;
- if (outbuf != NULL && *outbuf != NULL)
- {
- *outbuf += cd->data[last_step].outbufavail;
- *outbytesleft -= cd->data[last_step].outbufavail;
+ do
+ {
+ /* See whether the input size is reasoable for the output
+ size. If not adjust it. */
+ size_t inlen = ((inbufend - *inbuf) / cd->steps->max_needed_from
+ * cd->steps->max_needed_from);
+
+ if (cd->nsteps > 1)
+ inlen = MIN (inlen, (((outbufend - cd->data[last_step].outbuf)
+ / cd->steps[last_step].max_needed_to)
+ * cd->steps[last_step].max_needed_to));
+
+ last_start = *inbuf;
+ result = (*cd->steps->fct) (cd->steps, cd->data, inbuf,
+ *inbuf + inlen, converted, 0);
+ }
+ while (result == GCONV_EMPTY_INPUT && last_start != *inbuf
+ && *inbuf + cd->steps->min_needed_from <= inbufend);
}
+ if (outbuf != NULL && *outbuf != NULL)
+ *outbuf = cd->data[last_step].outbuf;
+
return result;
}
diff --git a/iconv/gconv.h b/iconv/gconv.h
index f3f80f4c14..cd0e3de1dc 100644
--- a/iconv/gconv.h
+++ b/iconv/gconv.h
@@ -57,8 +57,8 @@ struct gconv_loaded_object;
/* Type of a conversion function. */
typedef int (*gconv_fct) __P ((struct gconv_step *,
- struct gconv_step_data *,
- __const char *, size_t *, size_t *, int));
+ struct gconv_step_data *, __const char **,
+ __const char *, size_t *, int));
/* Constructor and destructor for local data for conversion step. */
typedef int (*gconv_init_fct) __P ((struct gconv_step *));
@@ -80,6 +80,13 @@ struct gconv_step
gconv_init_fct init_fct;
gconv_end_fct end_fct;
+ /* Information about the number of bytes needed or produced in this
+ step. This helps optimizing the buffer sizes. */
+ int min_needed_from;
+ int max_needed_from;
+ int min_needed_to;
+ int max_needed_to;
+
void *data; /* Pointer to step-local data. */
};
@@ -88,8 +95,7 @@ struct gconv_step
struct gconv_step_data
{
char *outbuf; /* Output buffer for this step. */
- size_t outbufavail; /* Bytes already available in output buffer. */
- size_t outbufsize; /* Size of output buffer. */
+ char *outbufend; /* Address of first byte after the output buffer. */
int is_last;
diff --git a/iconv/gconv_builtin.c b/iconv/gconv_builtin.c
index 6b14804da3..a970fcc8f2 100644
--- a/iconv/gconv_builtin.c
+++ b/iconv/gconv_builtin.c
@@ -33,15 +33,25 @@ static struct builtin_map
gconv_init_fct init;
gconv_end_fct end;
+ int min_needed_from;
+ int max_needed_from;
+ int min_needed_to;
+ int max_needed_to;
+
} map[] =
{
#define BUILTIN_TRANSFORMATION(From, ConstPfx, ConstLen, To, Cost, Name, \
- Fct, Init, End) \
+ Fct, Init, End, MinF, MaxF, MinT, MaxT) \
{ \
name: Name, \
fct: Fct, \
init: Init, \
end: End, \
+ \
+ min_needed_from: MinF, \
+ max_needed_from: MaxF, \
+ min_needed_to: MinT, \
+ max_needed_to: MaxT \
},
#define BUILTIN_ALIAS(From, To)
@@ -66,4 +76,9 @@ __gconv_get_builtin_trans (const char *name, struct gconv_step *step)
step->end_fct = map[cnt].end;
step->counter = INT_MAX;
step->shlib_handle = NULL;
+
+ step->min_needed_from = map[cnt].min_needed_from;
+ step->max_needed_from = map[cnt].max_needed_from;
+ step->min_needed_to = map[cnt].min_needed_to;
+ step->max_needed_to = map[cnt].max_needed_to;
}
diff --git a/iconv/gconv_builtin.h b/iconv/gconv_builtin.h
index 265dca1f01..3d214ff4f0 100644
--- a/iconv/gconv_builtin.h
+++ b/iconv/gconv_builtin.h
@@ -26,10 +26,12 @@ 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)
+ __gconv_transform_internal_ucs4, NULL, NULL,
+ 4, 4, 4, 4)
BUILTIN_TRANSFORMATION (NULL, "ISO-10646/UCS4/", 15,
"INTERNAL", 1, "=ucs4->INTERNAL",
- __gconv_transform_internal_ucs4, NULL, NULL)
+ __gconv_transform_internal_ucs4, NULL, NULL,
+ 4, 4, 4, 4)
/* Please note that we need only one function for both direction. */
BUILTIN_ALIAS ("UTF8//", "ISO-10646/UTF8/")
@@ -37,22 +39,27 @@ BUILTIN_ALIAS ("UTF-8//", "ISO-10646/UTF8/")
BUILTIN_TRANSFORMATION (NULL, "INTERNAL", 8,
"ISO-10646/UTF8/", 1, "=INTERNAL->utf8",
- __gconv_transform_internal_utf8, NULL, NULL)
+ __gconv_transform_internal_utf8, NULL, NULL,
+ 4, 4, 1, 6)
BUILTIN_TRANSFORMATION ("ISO-10646/UTF-?8/", "ISO-10646/UTF", 13,
"INTERNAL", 1, "=utf8->INTERNAL",
- __gconv_transform_utf8_internal, NULL, NULL)
+ __gconv_transform_utf8_internal, NULL, NULL,
+ 1, 6, 4, 4)
BUILTIN_ALIAS ("UCS2//", "ISO-10646/UCS2/")
BUILTIN_ALIAS ("UCS-2//", "ISO-10646/UCS2/")
BUILTIN_TRANSFORMATION (NULL, "ISO-10646/UCS2/", 15, "INTERNAL",
1, "=ucs2->INTERNAL",
- __gconv_transform_ucs2_internal, NULL, NULL)
+ __gconv_transform_ucs2_internal, NULL, NULL,
+ 2, 2, 4, 4)
BUILTIN_TRANSFORMATION (NULL, "INTERNAL", 8, "ISO-10646/UCS2/",
1, "=INTERNAL->ucs2",
- __gconv_transform_internal_ucs2, NULL, NULL)
+ __gconv_transform_internal_ucs2, NULL, NULL,
+ 4, 4, 2, 2)
BUILTIN_TRANSFORMATION ("(.*)", NULL, 0, "\\1", 1, "=dummy",
- __gconv_transform_dummy, NULL, NULL)
+ __gconv_transform_dummy, NULL, NULL,
+ 1, 1, 1, 1)
diff --git a/iconv/gconv_conf.c b/iconv/gconv_conf.c
index c67a0d8f8c..ae5ba19e5d 100644
--- a/iconv/gconv_conf.c
+++ b/iconv/gconv_conf.c
@@ -47,7 +47,7 @@ static const char gconv_module_ext[] = MODULE_EXT;
static struct gconv_module builtin_modules[] =
{
#define BUILTIN_TRANSFORMATION(From, ConstPfx, ConstLen, To, Cost, Name, \
- Fct, Init, End) \
+ Fct, Init, End, MinF, MaxF, MinT, MaxT) \
{ \
from_pattern: From, \
from_constpfx: ConstPfx, \
@@ -69,7 +69,7 @@ static const char *
builtin_aliases[] =
{
#define BUILTIN_TRANSFORMATION(From, ConstPfx, ConstLen, To, Cost, Name, \
- Fct, Init, End)
+ Fct, Init, End, MinF, MaxF, MinT, MaxT)
#define BUILTIN_ALIAS(From, To) From " " To,
#include "gconv_builtin.h"
diff --git a/iconv/gconv_db.c b/iconv/gconv_db.c
index 9f4366b7df..62d8f0540c 100644
--- a/iconv/gconv_db.c
+++ b/iconv/gconv_db.c
@@ -192,6 +192,7 @@ gen_steps (struct derivation_step *best, const char *toset,
? __strdup (current->result_set)
: result[step_cnt + 1].from_name);
+#ifndef STATIC_GCONV
if (current->code->module_name[0] == '/')
{
/* Load the module, return handle for it. */
@@ -212,6 +213,7 @@ gen_steps (struct derivation_step *best, const char *toset,
result[step_cnt].end_fct = shlib_handle->end_fct;
}
else
+#endif
/* It's a builtin transformation. */
__gconv_get_builtin_trans (current->code->module_name,
&result[step_cnt]);
@@ -230,7 +232,9 @@ gen_steps (struct derivation_step *best, const char *toset,
{
if (result[step_cnt].end_fct != NULL)
(*result[step_cnt].end_fct) (&result[step_cnt]);
+#ifndef STATIC_GCONV
__gconv_release_shlib (result[step_cnt].shlib_handle);
+#endif
}
free (result);
*nsteps = 0;
@@ -525,6 +529,7 @@ __gconv_find_transform (const char *toset, const char *fromset,
result = find_derivation (toset, toset_expand, fromset, fromset_expand,
handle, nsteps);
+#ifndef STATIC_GCONV
/* Increment the user counter. */
if (result == GCONV_OK)
{
@@ -548,6 +553,7 @@ __gconv_find_transform (const char *toset, const char *fromset,
}
while (cnt > 0);
}
+#endif
/* Release the lock. */
__libc_lock_unlock (lock);
@@ -568,6 +574,7 @@ __gconv_close_transform (struct gconv_step *steps, size_t nsteps)
{
int result = GCONV_OK;
+#ifndef STATIC_GCONV
/* Acquire the lock. */
__libc_lock_lock (lock);
@@ -583,6 +590,7 @@ __gconv_close_transform (struct gconv_step *steps, size_t nsteps)
/* Release the lock. */
__libc_lock_unlock (lock);
+#endif
return result;
}
diff --git a/iconv/gconv_int.h b/iconv/gconv_int.h
index a1475f8508..86e892f874 100644
--- a/iconv/gconv_int.h
+++ b/iconv/gconv_int.h
@@ -34,8 +34,8 @@ struct gconv_alias
};
-/* Default size of intermediate buffers. */
-#define GCONV_DEFAULT_BUFSIZE 8160
+/* How many character should be conveted in one call? */
+#define GCONV_NCHAR_GOAL 8160
/* Structure describing one loaded shared object. This normally are
@@ -99,9 +99,8 @@ extern int __gconv_close (gconv_t cd)
according to rules described by CD and place up to *OUTBYTESLEFT
bytes in buffer starting at *OUTBUF. Return number of written
characters in *CONVERTED if this pointer is not null. */
-extern int __gconv (gconv_t __cd, const char **__inbuf, size_t *__inbytesleft,
- char **__outbuf, size_t *__outbytesleft,
- size_t *__converted)
+extern int __gconv (gconv_t __cd, const char **__inbuf, const char *inbufend,
+ char **__outbuf, char *outbufend, size_t *__converted)
internal_function;
/* Return in *HANDLE a pointer to an array with *NSTEPS elements describing
@@ -149,8 +148,8 @@ extern void __gconv_get_builtin_trans (const char *__name,
#ifdef _LIBC
# define __BUILTIN_TRANS(Name) \
extern int Name (struct gconv_step *__step, struct gconv_step_data *__data, \
- const char *__inbuf, size_t *__inlen, size_t *__written, \
- int __do_flush)
+ const char **__inbuf, const char *__inbufend, \
+ size_t *__written, int __do_flush)
__BUILTIN_TRANS (__gconv_transform_dummy);
__BUILTIN_TRANS (__gconv_transform_ascii_internal);
diff --git a/iconv/gconv_open.c b/iconv/gconv_open.c
index d82dcfee48..831794fc22 100644
--- a/iconv/gconv_open.c
+++ b/iconv/gconv_open.c
@@ -62,21 +62,24 @@ __gconv_open (const char *toset, const char *fromset, gconv_t *handle)
for (cnt = 0; cnt < nsteps; ++cnt)
{
/* If this is the last step we must not allocate an output
- buffer. Signal this to the initializer. */
+ buffer. */
data[cnt].is_last = cnt == nsteps - 1;
/* We use the `mbstate_t' member in DATA. */
data[cnt].statep = &data[cnt].__state;
/* Allocate the buffer. */
- data[cnt].outbufsize = GCONV_DEFAULT_BUFSIZE;
- data[cnt].outbuf = (char *) malloc (data[cnt].outbufsize);
- if (data[cnt].outbuf == NULL)
+ if (!data[cnt].is_last)
{
- res = GCONV_NOMEM;
- break;
+ data[cnt].outbuf =
+ (char *) malloc (GCONV_NCHAR_GOAL
+ * steps[cnt].max_needed_to);
+ if (data[cnt].outbuf == NULL)
+ {
+ res = GCONV_NOMEM;
+ break;
+ }
}
- data[cnt].outbufavail = 0;
}
}
}
diff --git a/iconv/gconv_simple.c b/iconv/gconv_simple.c
index b72e61edcc..f2fec12fb8 100644
--- a/iconv/gconv_simple.c
+++ b/iconv/gconv_simple.c
@@ -35,7 +35,7 @@
/* These are definitions used by some of the functions for handling
UTF-8 encoding below. */
-static const wchar_t encoding_mask[] =
+static const uint32_t encoding_mask[] =
{
~0x7ff, ~0xffff, ~0x1fffff, ~0x3ffffff
};
@@ -49,8 +49,8 @@ static const unsigned char encoding_byte[] =
int
__gconv_transform_dummy (struct gconv_step *step, struct gconv_step_data *data,
- const char *inbuf, size_t *inlen, size_t *written,
- int do_flush)
+ const char **inbuf, const char *inbufend,
+ size_t *written, int do_flush)
{
size_t do_write;
@@ -60,12 +60,12 @@ __gconv_transform_dummy (struct gconv_step *step, struct gconv_step_data *data,
do_write = 0;
else
{
- do_write = MIN (*inlen, data->outbufsize - data->outbufavail);
+ do_write = MIN (inbufend - *inbuf, data->outbufend - data->outbuf);
memcpy (data->outbuf, inbuf, do_write);
- *inlen -= do_write;
- data->outbufavail += do_write;
+ *inbuf -= do_write;
+ *data->outbuf += do_write;
}
/* ### TODO Actually, this number must be devided according to the
@@ -83,934 +83,330 @@ __gconv_transform_dummy (struct gconv_step *step, struct gconv_step_data *data,
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_internal_ucs4 (struct gconv_step *step,
- struct gconv_step_data *data,
- const char *inbuf, size_t *inlen,
- size_t *written, int do_flush)
+#define DEFINE_INIT 0
+#define DEFINE_FINI 0
+#define MIN_NEEDED_FROM 4
+#define MIN_NEEDED_TO 4
+#define FROM_DIRECTION 1
+#define FROM_LOOP internal_ucs4_loop
+#define TO_LOOP internal_ucs4_loop /* This is not used. */
+#define FUNCTION_NAME __gconv_transform_internal_ucs4
+
+
+static inline int
+internal_ucs4_loop (const unsigned char **inptrp, const unsigned char *inend,
+ unsigned char **outptrp, unsigned char *outend,
+ mbstate_t *state, void *data, size_t *converted)
{
- 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;
+ const unsigned char *inptr = *inptrp;
+ unsigned char *outptr = *outptrp;
+ size_t n_convert = MIN (inend - inptr, outend - outptr) / 4;
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
- {
- int save_errno = errno;
-
- result = GCONV_OK;
- do
- {
- 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;
+ /* Sigh, we have to do some real work. */
+ size_t cnt;
- for (cnt = 0; cnt < n_convert; ++cnt)
- outbuf[cnt] = bswap_32 (((wchar_t *) inbuf)[cnt]);
+ for (cnt = 0; cnt < n_convert; ++cnt)
+ *((uint32_t *) outptr)++ = bswap_32 (*((uint32_t *) inptr)++);
+ *inptrp = inptr;
+ *outptrp = outptr;
#elif __BYTE_ORDER == __BIG_ENDIAN
- /* Simply copy the data. */
- memcpy (&data->outbuf[data->outbufsize], inbuf,
- n_convert * sizeof (wchar_t));
+ /* Simply copy the data. */
+ *inptrp = inptr + n_convert * 4;
+ *outptrp = __mempcpy (outptr, inptr, n_convert * 4);
#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;
-
- while (data->outbufavail + sizeof (wchar_t) <= data->outbufsize
- && cnt < *inlen)
- {
- if (*newinbuf > '\x7f')
- {
- /* This is no correct ANSI_X3.4-1968 character. */
- result = GCONV_ILLEGAL_INPUT;
- break;
- }
-
- /* It's an one byte sequence. */
- *(wchar_t *) &data->outbuf[data->outbufavail]
- = (wchar_t) *newinbuf;
- data->outbufavail += sizeof (wchar_t);
- ++actually;
-
- ++newinbuf;
- ++cnt;
- }
-
- /* Remember how much we converted. */
- do_write += cnt * sizeof (wchar_t);
- *inlen -= cnt;
-
- /* Check whether an illegal character appeared. */
- if (result != GCONV_OK)
- break;
-
- if (data->is_last)
- {
- /* This is the last step. */
- result = (*inlen == 0 ? 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 > 0 && result == GCONV_EMPTY_INPUT);
-
- __set_errno (save_errno);
- }
-
- if (written != NULL && data->is_last)
- *written = do_write / sizeof (wchar_t);
-
- return result;
-}
-
-
-/* Convert from ISO 10646/UCS to ISO 646-IRV. */
-int
-__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;
- gconv_fct fct = next_step->fct;
- size_t do_write;
- 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));
- do_write = 0;
-
- /* 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 wchar_t *newinbuf = (const wchar_t *) inbuf;
- int save_errno = errno;
- do_write = 0;
-
- result = GCONV_OK;
- do
- {
- size_t actually = 0;
- size_t cnt = 0;
-
- while (data->outbufavail < data->outbufsize
- && cnt + 3 < *inlen)
- {
- if (*newinbuf < L'\0' || *newinbuf > L'\x7f')
- {
- /* This is no correct ANSI_X3.4-1968 character. */
- result = GCONV_ILLEGAL_INPUT;
- break;
- }
-
- /* It's an one byte sequence. */
- data->outbuf[data->outbufavail++] = (char) *newinbuf;
- ++actually;
-
- ++newinbuf;
- cnt += sizeof (wchar_t);
- }
-
- /* Remember how much we converted. */
- do_write += cnt / sizeof (wchar_t);
- *inlen -= 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 == 0 ? 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 > 0 && result == GCONV_EMPTY_INPUT);
-
- __set_errno (save_errno);
- }
-
- if (written != NULL && data->is_last)
- *written = do_write;
-
- return result;
-}
-
-
-int
-__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;
- gconv_fct fct = next_step->fct;
- size_t do_write;
- 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));
- do_write = 0;
-
- /* 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 wchar_t *newinbuf = (const wchar_t *) inbuf;
- int save_errno = errno;
- do_write = 0;
-
- result = GCONV_OK;
- do
- {
- size_t cnt = 0;
-
- while (data->outbufavail < data->outbufsize
- && cnt * sizeof (wchar_t) + 3 < *inlen)
- {
- wchar_t wc = newinbuf[cnt];
-
- 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;
- 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;
- 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. */
- 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 == 0 ? 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 > 0 && result == GCONV_EMPTY_INPUT);
-
- __set_errno (save_errno);
- }
-
- if (written != NULL && data->is_last)
- *written = do_write;
-
- return result;
-}
-
-
-int
-__gconv_transform_utf8_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;
- 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));
- do_write = 0;
-
- /* 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);
- }
- }
+ /* Determine the status. */
+ if (*outptrp == outend)
+ result = GCONV_FULL_OUTPUT;
+ else if (*inptrp == inend)
+ result = GCONV_EMPTY_INPUT;
else
- {
- int save_errno = errno;
- int extra = 0;
- do_write = 0;
-
- result = GCONV_OK;
- do
- {
- wchar_t *outbuf = (wchar_t *) &data->outbuf[data->outbufavail];
- size_t cnt = 0;
- size_t actually = 0;
-
- while (data->outbufavail + sizeof (wchar_t) <= data->outbufsize
- && cnt < *inlen)
- {
- size_t start = cnt;
- wchar_t value;
- 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;
- }
-
- if (cnt + count > *inlen)
- {
- /* We don't have enough input. */
- --cnt;
- extra = count;
- break;
- }
-
- /* Read the possible remaining bytes. */
- while (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. */
- do_write += actually;
- *inlen -= cnt;
- inbuf += cnt;
-
- data->outbufavail += actually * sizeof (wchar_t);
-
- /* Check whether an illegal character appeared. */
- if (result != GCONV_OK)
- {
- result = GCONV_ILLEGAL_INPUT;
- break;
- }
-
- if (*inlen > 0 && *inlen < extra)
- {
- /* We have an incomplete character at the end. */
- result = GCONV_INCOMPLETE_INPUT;
- break;
- }
-
- if (data->is_last)
- {
- /* This is the last step. */
- result = (data->outbufavail + sizeof (wchar_t) > data->outbufsize
- ? GCONV_FULL_OUTPUT : GCONV_EMPTY_INPUT);
- 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 > 0 && result == GCONV_EMPTY_INPUT);
-
- __set_errno (save_errno);
- }
+ result = GCONV_INCOMPLETE_INPUT;
- if (written != NULL && data->is_last)
- *written = do_write;
+ if (converted != NULL)
+ converted += n_convert;
return result;
}
+#include <iconv/skeleton.c>
-int
-__gconv_transform_ucs2_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;
- 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));
- do_write = 0;
-
- /* 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);
- }
- }
- else
- {
- const uint16_t *newinbuf = (const uint16_t *) inbuf;
- int save_errno = errno;
- do_write = 0;
-
- do
- {
- wchar_t *outbuf = (wchar_t *) &data->outbuf[data->outbufavail];
- size_t actually = 0;
-
- errno = 0;
- while (data->outbufavail + 4 <= data->outbufsize
- && *inlen >= 2)
- {
+/* Convert from ISO 646-IRV to the internal (UCS4-like) format. */
+#define DEFINE_INIT 0
+#define DEFINE_FINI 0
+#define MIN_NEEDED_FROM 1
+#define MIN_NEEDED_TO 4
+#define FROM_DIRECTION 1
+#define FROM_LOOP ascii_internal_loop
+#define TO_LOOP ascii_internal_loop /* This is not used. */
+#define FUNCTION_NAME __gconv_transform_ascii_internal
+
+#define MIN_NEEDED_INPUT MIN_NEEDED_FROM
+#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
+#define LOOPFCT FROM_LOOP
+#define BODY \
+ { \
+ if (*inptr > '\x7f') \
+ { \
+ /* This is no correct ANSI_X3.4-1968 character. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ \
+ /* It's an one byte sequence. */ \
+ *((uint32_t *) outptr)++ = *inptr++; \
+ }
+#include <iconv/loop.c>
+#include <iconv/skeleton.c>
+
+
+/* Convert from the internal (UCS4-like) format to ISO 646-IRV. */
+#define DEFINE_INIT 0
+#define DEFINE_FINI 0
+#define MIN_NEEDED_FROM 4
+#define MIN_NEEDED_TO 1
+#define FROM_DIRECTION 1
+#define FROM_LOOP internal_ascii_loop
+#define TO_LOOP internal_ascii_loop /* This is not used. */
+#define FUNCTION_NAME __gconv_transform_internal_ascii
+
+#define MIN_NEEDED_INPUT MIN_NEEDED_FROM
+#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
+#define LOOPFCT FROM_LOOP
+#define BODY \
+ { \
+ if (*((uint32_t *) inptr) > '\x7f') \
+ { \
+ /* This is no correct ANSI_X3.4-1968 character. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ \
+ /* It's an one byte sequence. */ \
+ *outptr++ = *((uint32_t *) inptr)++; \
+ }
+#include <iconv/loop.c>
+#include <iconv/skeleton.c>
+
+
+/* Convert from the internal (UCS4-like) format to UTF-8. */
+#define DEFINE_INIT 0
+#define DEFINE_FINI 0
+#define MIN_NEEDED_FROM 4
+#define MIN_NEEDED_TO 1
+#define MAX_NEEDED_TO 6
+#define FROM_DIRECTION 1
+#define FROM_LOOP internal_utf8_loop
+#define TO_LOOP internal_utf8_loop /* This is not used. */
+#define FUNCTION_NAME __gconv_transform_internal_utf8
+
+#define MIN_NEEDED_INPUT MIN_NEEDED_FROM
+#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
+#define LOOPFCT FROM_LOOP
+#define BODY \
+ { \
+ uint32_t wc = *((uint32_t *) inptr); \
+ \
+ /* Since we control every character we read this cannot happen. */ \
+ assert (wc <= 0x7fffffff); \
+ \
+ if (wc < 0x80) \
+ /* It's an one byte sequence. */ \
+ *outptr++ = (unsigned char) wc; \
+ else \
+ { \
+ size_t step; \
+ char *start; \
+ \
+ for (step = 2; step < 6; ++step) \
+ if ((wc & encoding_mask[step - 2]) == 0) \
+ break; \
+ \
+ if (outptr + step >= outend) \
+ { \
+ /* Too long. */ \
+ result = GCONV_FULL_OUTPUT; \
+ break; \
+ } \
+ \
+ start = outptr; \
+ *outptr = encoding_byte[step - 2]; \
+ outptr += step; \
+ --step; \
+ do \
+ { \
+ start[step] = 0x80 | (wc & 0x3f); \
+ wc >>= 6; \
+ } \
+ while (--step > 0); \
+ start[0] |= wc; \
+ } \
+ \
+ inptr += 4; \
+ }
+#include <iconv/loop.c>
+#include <iconv/skeleton.c>
+
+
+/* Convert from UTF-8 to the internal (UCS4-like) format. */
+#define DEFINE_INIT 0
+#define DEFINE_FINI 0
+#define MIN_NEEDED_FROM 1
+#define MAX_NEEDED_FROM 6
+#define MIN_NEEDED_TO 4
+#define FROM_DIRECTION 1
+#define FROM_LOOP utf8_internal_loop
+#define TO_LOOP utf8_internal_loop /* This is not used. */
+#define FUNCTION_NAME __gconv_transform_utf8_internal
+
+#define MIN_NEEDED_INPUT MIN_NEEDED_FROM
+#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
+#define LOOPFCT FROM_LOOP
+#define BODY \
+ { \
+ uint32_t ch; \
+ uint_fast32_t cnt; \
+ uint_fast32_t i; \
+ \
+ /* Next input byte. */ \
+ ch = *inptr; \
+ \
+ if (ch < 0x80) \
+ /* One byte sequence. */ \
+ cnt = 1; \
+ else if ((ch & 0xe0) == 0xc0) \
+ { \
+ cnt = 2; \
+ ch &= 0x1f; \
+ } \
+ else if ((ch & 0xf0) == 0xe0) \
+ { \
+ /* We expect three bytes. */ \
+ cnt = 3; \
+ ch &= 0x0f; \
+ } \
+ else if ((ch & 0xf8) == 0xf0) \
+ { \
+ /* We expect four bytes. */ \
+ cnt = 4; \
+ ch &= 0x07; \
+ } \
+ else if ((ch & 0xfc) == 0xf8) \
+ { \
+ /* We expect five bytes. */ \
+ cnt = 5; \
+ ch &= 0x03; \
+ } \
+ else if ((ch & 0xfe) == 0xfc) \
+ { \
+ /* We expect six bytes. */ \
+ cnt = 6; \
+ ch &= 0x01; \
+ } \
+ else \
+ { \
+ /* This is an illegal encoding. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ \
+ if (NEED_LENGTH_TEST && inptr + cnt >= inend) \
+ { \
+ /* We don't have enough input. */ \
+ result = GCONV_INCOMPLETE_INPUT; \
+ break; \
+ } \
+ \
+ /* Read the possible remaining bytes. */ \
+ for (i = 1; i < cnt; ++i) \
+ { \
+ uint32_t byte = inptr[i]; \
+ \
+ if ((byte & 0xc0) != 0x80) \
+ { \
+ /* This is an illegal encoding. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ \
+ ch <<= 6; \
+ ch |= byte & 0x3f; \
+ } \
+ \
+ /* Now adjust the pointers and store the result. */ \
+ inptr += cnt; \
+ *((uint32_t *) outptr)++ = ch; \
+ }
+#include <iconv/loop.c>
+#include <iconv/skeleton.c>
+
+
+/* Convert from UCS2 to the internal (UCS4-like) format. */
+#define DEFINE_INIT 0
+#define DEFINE_FINI 0
+#define MIN_NEEDED_FROM 2
+#define MIN_NEEDED_TO 4
+#define FROM_DIRECTION 1
+#define FROM_LOOP ucs2_internal_loop
+#define TO_LOOP ucs2_internal_loop /* This is not used. */
+#define FUNCTION_NAME __gconv_transform_ucs2_internal
+
+#define MIN_NEEDED_INPUT MIN_NEEDED_FROM
+#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
+#define LOOPFCT FROM_LOOP
#if __BYTE_ORDER == __LITTLE_ENDIAN
- outbuf[actually++] = (wchar_t) bswap_16 (*newinbuf++);
+# define BODY \
+ *((uint32_t *) outptr)++ = bswap_16 (*((uint16_t *) inptr)++);
#else
- outbuf[actually++] = (wchar_t) *newinbuf++;
+# define BODY \
+ *((uint32_t *) outptr)++ = *((uint16_t *) inptr)++;
#endif
- data->outbufavail += 4;
- *inlen -= 2;
- }
-
- /* Remember how much we converted. */
- do_write += actually * sizeof (wchar_t);
-
- if (*inlen == 1)
- {
- /* We have an incomplete character at the end. */
- result = GCONV_INCOMPLETE_INPUT;
- break;
- }
-
- /* Check whether an illegal character appeared. */
- if (errno != 0)
- {
- result = GCONV_ILLEGAL_INPUT;
- break;
- }
-
- if (data->is_last)
- {
- /* This is the last step. */
- result = (data->outbufavail + sizeof (wchar_t) > data->outbufsize
- ? GCONV_FULL_OUTPUT : GCONV_EMPTY_INPUT);
- 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 > 0 && result == GCONV_EMPTY_INPUT);
-
- __set_errno (save_errno);
- }
-
- if (written != NULL && data->is_last)
- *written = do_write;
-
- return result;
-}
-
-
-int
-__gconv_transform_internal_ucs2 (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;
- 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));
- do_write = 0;
-
- /* 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 wchar_t *newinbuf = (const wchar_t *) inbuf;
- int save_errno = errno;
- do_write = 0;
-
- do
- {
- uint16_t *outbuf = (uint16_t *) &data->outbuf[data->outbufavail];
- size_t actually = 0;
-
- errno = 0;
-
- while (data->outbufavail + 2 <= data->outbufsize
- && *inlen >= 4)
- {
- if (*newinbuf >= 0x10000)
- {
- __set_errno (EILSEQ);
- break;
- }
+#include <iconv/loop.c>
+#include <iconv/skeleton.c>
+
+
+/* Convert from the internal (UCS4-like) format to UCS2. */
+#define DEFINE_INIT 0
+#define DEFINE_FINI 0
+#define MIN_NEEDED_FROM 4
+#define MIN_NEEDED_TO 2
+#define FROM_DIRECTION 1
+#define FROM_LOOP internal_ucs2_loop
+#define TO_LOOP internal_ucs2_loop /* This is not used. */
+#define FUNCTION_NAME __gconv_transform_internal_ucs2
+
+#define MIN_NEEDED_INPUT MIN_NEEDED_FROM
+#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
+#define LOOPFCT FROM_LOOP
#if __BYTE_ORDER == __LITTLE_ENDIAN
- /* Please note that we use the `uint32_t' pointer as a
- `uint16_t' pointer which works since we are on a
- little endian machine. */
- outbuf[actually++] = bswap_16 (*((uint16_t *) newinbuf));
- ++newinbuf;
+# define BODY \
+ { \
+ if (*((uint32_t *) inptr) >= 0x10000) \
+ { \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ /* Please note that we use the `uint32_t' from-pointer as an `uint16_t' \
+ pointer which works since we are on a little endian machine. */ \
+ *((uint16_t *) outptr)++ = bswap_16 (*((uint16_t *) inptr)); \
+ inptr += 4; \
+ }
#else
- outbuf[actually++] = *newinbuf++;
+# define BODY \
+ { \
+ if (*((uint32_t *) inptr) >= 0x10000) \
+ { \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ *((uint16_t *) outptr)++ = *((uint32_t *) inptr)++; \
+ }
#endif
- *inlen -= 4;
- data->outbufavail += 2;
- }
-
- /* Remember how much we converted. */
- do_write += (const char *) newinbuf - inbuf;
-
- if (*inlen > 0 && *inlen < 4)
- {
- /* We have an incomplete input character. */
- result = GCONV_INCOMPLETE_INPUT;
- break;
- }
-
- /* Check whether an illegal character appeared. */
- if (errno != 0)
- {
- result = GCONV_ILLEGAL_INPUT;
- break;
- }
-
- if (data->is_last)
- {
- /* This is the last step. */
- result = *inlen == 0 ? 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 > 0 && result == GCONV_EMPTY_INPUT);
-
- __set_errno (save_errno);
- }
-
- if (written != NULL && data->is_last)
- *written = do_write / sizeof (wchar_t);
-
- return result;
-}
+#include <iconv/loop.c>
+#include <iconv/skeleton.c>
diff --git a/iconv/iconv.c b/iconv/iconv.c
index fc0ed41b50..2f57295097 100644
--- a/iconv/iconv.c
+++ b/iconv/iconv.c
@@ -32,10 +32,27 @@ iconv (iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf,
size_t *outbytesleft)
{
gconv_t gcd = (gconv_t) cd;
+ char *outstart = outbuf ? *outbuf : NULL;
size_t converted;
int result;
- result = __gconv (gcd, inbuf, inbytesleft, outbuf, outbytesleft, &converted);
+ if (inbuf == NULL || *inbuf == NULL)
+ {
+ result = __gconv (gcd, NULL, NULL, outbuf, outstart + *outbytesleft,
+ &converted);
+ }
+ else
+ {
+ const char *instart = *inbuf;
+
+ result = __gconv (gcd, inbuf, *inbuf + *inbytesleft, outbuf,
+ *outbuf + *outbytesleft, &converted);
+
+ *inbytesleft -= *inbuf - instart;
+ }
+ if (outstart != NULL)
+ *outbytesleft -= *outbuf - outstart;
+
switch (result)
{
case GCONV_ILLEGAL_DESCRIPTOR:
diff --git a/iconv/iconv_prog.c b/iconv/iconv_prog.c
index 569bd3b3ec..2452a88c5e 100644
--- a/iconv/iconv_prog.c
+++ b/iconv/iconv_prog.c
@@ -299,12 +299,15 @@ process_block (iconv_t cd, const char *addr, size_t len, FILE *output)
{
#define OUTBUF_SIZE 32768
char outbuf[OUTBUF_SIZE];
- char *outptr = outbuf;
- size_t outlen = OUTBUF_SIZE;
+ char *outptr;
+ size_t outlen;
+ size_t n;
while (len > 0)
{
- size_t n = iconv (cd, &addr, &len, &outptr, &outlen);
+ outptr = outbuf;
+ outlen = OUTBUF_SIZE;
+ n = iconv (cd, &addr, &len, &outptr, &outlen);
if (outptr != outbuf)
{
diff --git a/iconv/loop.c b/iconv/loop.c
new file mode 100644
index 0000000000..b8657d574c
--- /dev/null
+++ b/iconv/loop.c
@@ -0,0 +1,226 @@
+/* Conversion loop frame work.
+ Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* This file provides a frame for the reader loop in all conversion modules.
+ The actual code must (of course) be provided in the actual module source
+ code but certain actions can be written down generically, with some
+ customization options which are these:
+
+ MIN_NEEDED_INPUT minimal number of input bytes needed for the next
+ conversion.
+ MIN_NEEDED_OUTPUT minimal number of bytes produced by the next round
+ of conversion.
+
+ MAX_NEEDED_INPUT you guess it, this is the maximal number of input
+ bytes needed. It defaults to MIN_NEEDED_INPUT
+ MAX_NEEDED_OUTPUT likewise for output bytes.
+
+ Both values have a default of 1.
+
+ LOOPFCT name of the function created. If not specified
+ the name is `loop' but this prevents the use
+ of multiple functions in the same file.
+
+ COUNT_CONVERTED optional macro which is used to count the actual
+ number of characters converted. For some conversion
+ it is easy to compute the value afterwards, but for
+ others explicit counting is cheaper.
+
+ BODY this is supposed to expand to the body of the loop.
+ The user must provide this.
+*/
+
+#include <gconv.h>
+#include <sys/param.h> /* For MIN. */
+#define __need_size_t
+#include <stddef.h>
+
+
+/* We need at least one byte for the next round. */
+#ifndef MIN_NEEDED_INPUT
+# define MIN_NEEDED_INPUT 1
+#endif
+
+/* Let's see how many bytes we produce. */
+#ifndef MAX_NEEDED_INPUT
+# define MAX_NEEDED_INPUT MIN_NEEDED_INPUT
+#endif
+
+/* We produce at least one byte in the next round. */
+#ifndef MIN_NEEDED_OUTPUT
+# define MIN_NEEDED_OUTPUT 1
+#endif
+
+/* Let's see how many bytes we produce. */
+#ifndef MAX_NEEDED_OUTPUT
+# define MAX_NEEDED_OUTPUT MIN_NEEDED_OUTPUT
+#endif
+
+/* Default name for the function. */
+#ifndef LOOPFCT
+# define LOOPFCT loop
+#endif
+
+/* Make sure we have a loop body. */
+#ifndef BODY
+# error "Definition of BODY missing for function" LOOPFCT
+#endif
+
+/* We can calculate the number of converted characters easily if one
+ of the character sets has a fixed width. */
+#ifndef COUNT_CONVERTED
+# if MIN_NEEDED_INPUT == MAX_NEEDED_INPUT
+# if MIN_NEEDED_OUTPUT == MAX_NEEDED_OUTPUT
+/* Decide whether one of the charsets has size 1. */
+# if MIN_NEEDED_INPUT == 1
+# define COUNT_CONVERTED (inptr - *inptrp)
+# elif MIN_NEEDED_OUTPUT == 1
+# define COUNT_CONVERTED (outptr - *outptrp)
+# else
+/* Else we should see whether one of the two numbers is a power of 2. */
+# define COUNT_CONVERTED \
+ ((MIN_NEEDED_INPUT & (-MIN_NEEDED_INPUT)) == MIN_NEEDED_INPUT \
+ ? (inptr - *inptrp) : (outptr - *outptrp))
+# endif
+# else
+# define COUNT_CONVERTED (inptr - *inptrp)
+# endif
+# elif MIN_NEEDED_OUTPUT == MAX_NEEDED_OUTPUT
+# define COUNT_CONVERTED (outptr - *outptrp)
+# endif
+#endif
+
+
+/* The function returns the status, as defined in gconv.h. */
+static inline int
+LOOPFCT (const unsigned char **inptrp, const unsigned char *inend,
+ unsigned char **outptrp, unsigned char *outend, mbstate_t *state,
+ void *data, size_t *converted)
+{
+ int result = GCONV_OK;
+ const unsigned char *inptr = *inptrp;
+ unsigned char *outptr = *outptrp;
+#ifndef COUNT_CONVERTED
+ size_t done = 0;
+#endif
+
+ /* We run one loop where we avoid checks for underflow/overflow of the
+ buffers to speed up the conversion a bit. */
+ size_t min_in_rounds = (inend - inptr) / MAX_NEEDED_INPUT;
+ size_t min_out_rounds = (outend - outptr) / MAX_NEEDED_OUTPUT;
+ size_t min_rounds = MIN (min_in_rounds, min_out_rounds);
+
+#undef NEED_LENGTH_TEST
+#define NEED_LENGTH_TEST 0
+ while (min_rounds-- > 0)
+ {
+ /* Here comes the body the user provides. It can stop with RESULT
+ set to GCONV_INCOMPLETE_INPUT (if the size of the input characters
+ vary in size), GCONV_ILLEGAL_INPUT, or GCONV_FULL_OUTPUT (if the
+ output characters vary in size. */
+ BODY
+
+ /* If necessary count the successful conversion. */
+#ifndef COUNT_CONVERTED
+ ++done;
+#endif
+ }
+
+ if (result == GCONV_OK)
+ {
+#if MIN_NEEDED_INPUT == MAX_NEEDED_INPUT \
+ && MIN_NEEDED_OUTPUT == MAX_NEEDED_OUTPUT
+ /* We don't need to start another loop since we were able to determine
+ the maximal number of characters to copy in advance. What remains
+ to be determined is the status. */
+ if (inptr == inend)
+ /* No more input. */
+ result = GCONV_EMPTY_INPUT;
+ else if ((MIN_NEEDED_OUTPUT != 1 && outptr + MIN_NEEDED_OUTPUT > outend)
+ || (MIN_NEEDED_OUTPUT == 1 && outptr >= outend))
+ /* Overflow in the output buffer. */
+ result = GCONV_FULL_OUTPUT;
+ else
+ /* We have something left in the input buffer. */
+ result = GCONV_INCOMPLETE_INPUT;
+#else
+ result = GCONV_EMPTY_INPUT;
+
+# undef NEED_LENGTH_TEST
+# define NEED_LENGTH_TEST 1
+ while (inptr != inend)
+ {
+ /* `if' cases for MIN_NEEDED_OUTPUT ==/!= 1 is made to help the
+ compiler generating better code. It will optimized away
+ since MIN_NEEDED_OUTPUT is always a constant. */
+ if ((MIN_NEEDED_OUTPUT != 1 && outptr + MIN_NEEDED_OUTPUT > outend)
+ || (MIN_NEEDED_OUTPUT == 1 && outptr >= outend))
+ {
+ /* Overflow in the output buffer. */
+ result = GCONV_FULL_OUTPUT;
+ break;
+ }
+ if (MIN_NEEDED_INPUT > 1 && inptr + MIN_NEEDED_INPUT > inend)
+ {
+ /* We don't have enough input for another complete input
+ character. */
+ result = GCONV_INCOMPLETE_INPUT;
+ break;
+ }
+
+ /* Here comes the body the user provides. It can stop with
+ RESULT set to GCONV_INCOMPLETE_INPUT (if the size of the
+ input characters vary in size), GCONV_ILLEGAL_INPUT, or
+ GCONV_FULL_OUTPUT (if the output characters vary in size. */
+ BODY
+
+ /* If necessary count the successful conversion. */
+# ifndef COUNT_CONVERTED
+ ++done;
+# endif
+ }
+#endif /* Input and output charset are not both fixed width. */
+ }
+
+ /* Add the number of characters we actually converted. */
+#ifdef COUNT_CONVERTED
+ *converted += COUNT_CONVERTED;
+#else
+ *converted += done;
+#endif
+
+ /* Update the pointers pointed to by the parameters. */
+ *inptrp = inptr;
+ *outptrp = outptr;
+
+ return result;
+}
+
+
+/* We remove the macro definitions so that we can include this file again
+ for the definition of another function. */
+#undef MIN_NEEDED_INPUT
+#undef MAX_NEEDED_INPUT
+#undef MIN_NEEDED_OUTPUT
+#undef MAX_NEEDED_OUTPUT
+#undef LOOPFCT
+#undef COUNT_CONVERTED
+#undef BODY
+#undef LOOPFCT
diff --git a/iconv/skeleton.c b/iconv/skeleton.c
new file mode 100644
index 0000000000..3582f14110
--- /dev/null
+++ b/iconv/skeleton.c
@@ -0,0 +1,328 @@
+/* Skeleton for a converison module.
+ Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* This file can be included to provide definitions of several things
+ many modules have in common. It can be customized using the following
+ macros:
+
+ DEFINE_INIT define the default initializer. This requires the
+ following symbol to be defined.
+
+ CHARSET_NAME string with official name of the coded character
+ set (in all-caps)
+
+ DEFINE_FINI define the default destructor function.
+
+ MIN_NEEDED_FROM minimal number of bytes needed for the from-charset.
+ MIN_NEEDED_TO likewise for the to-charset.
+
+ MAX_NEEDED_FROM maximal number of bytes needed for the from-charset.
+ This macro is optional, it defaults to MIN_NEEDED_FROM.
+ MAX_NEEDED_TO likewise for the to-charset.
+
+ DEFINE_DIRECTION_OBJECTS
+ two objects will be defined to be used when the
+ `gconv' function must only distinguish two
+ directions. This is implied by DEFINE_INIT.
+ If this macro is not defined the following
+ macro must be available.
+
+ FROM_DIRECTION this macro is supposed to return a value != 0
+ if we convert from the current character set,
+ otherwise it return 0.
+
+ EMIT_SHIFT_TO_INIT this symbol is optional. If it is defined it
+ defines some code which writes out a sequence
+ of characters which bring the current state into
+ the initial state.
+
+ FROM_LOOP name of the function implementing the conversion
+ from the current characters.
+ TO_LOOP likewise for the other direction
+
+ RESET_STATE in case of an error we must reset the state for
+ the rerun so this macro must be defined for
+ stateful encodings. It takes an argument which
+ is nonzero when saving.
+
+ RESET_INPUT_BUFFER If the input character sets allow this the macro
+ can be defined to reset the input buffer pointers
+ to cover only those characters up to the error.
+
+ FUNCTION_NAME if not set the conversion function is named `gconv'.
+ */
+
+#include <assert.h>
+#include <gconv.h>
+#include <string.h>
+#define __need_size_t
+#define __need_NULL
+#include <stddef.h>
+
+
+/* The direction objects. */
+#if DEFINE_DIRECTION_OBJECTS || DEFINE_INIT
+static int from_object;
+static int to_object;
+
+# ifndef FROM_DIRECTION
+# define FROM_DIRECTION step->data == &from_object
+# endif
+#else
+# ifndef FROM_DIRECTION
+# error "FROM_DIRECTION must be provided if direction objects are not used"
+# endif
+#endif
+
+
+/* How many bytes are needed at most for the from-charset. */
+#ifndef MAX_NEEDED_FROM
+# define MAX_NEEDED_FROM MIN_NEEDED_FROM
+#endif
+
+/* Same for the to-charset. */
+#ifndef MAX_NEEDED_TO
+# define MAX_NEEDED_TO MIN_NEEDED_TO
+#endif
+
+
+/* For conversions from a fixed width character sets to another fixed width
+ character set we we can define RESET_INPUT_BUFFER is necessary. */
+#if !defined RESET_INPUT_BUFFER && !defined SAVE_RESET_STATE
+# if MIN_NEEDED_FROM == MAX_NEEDED_FROM && MIN_NEEDED_TO == MAX_NEEDED_TO
+/* We have to used these `if's here since the compiler cannot know that
+ (outbuf - outerr) is always divisible by MIN_NEEDED_TO. */
+# define RESET_INPUT_BUFFER \
+ if (MIN_NEEDED_FROM % MIN_NEEDED_TO == 0) \
+ *inbuf -= (outbuf - outerr) * (MIN_NEEDED_FROM / MIN_NEEDED_TO); \
+ else if (MIN_NEEDED_TO % MIN_NEEDED_FROM == 0) \
+ *inbuf -= (outbuf - outerr) / (MIN_NEEDED_TO / MIN_NEEDED_FROM); \
+ else \
+ *inbuf -= ((outbuf - outerr) / MIN_NEEDED_TO) * MIN_NEEDED_FROM
+# endif
+#endif
+
+
+/* The default init function. It simply matches the name and initializes
+ the step data to point to one of the objects above. */
+#if DEFINE_INIT
+# ifndef CHARSET_NAME
+# error "CHARSET_NAME not defined"
+# endif
+
+int
+gconv_init (struct gconv_step *step)
+{
+ /* Determine which direction. */
+ if (__strcasestr (step->from_name, CHARSET_NAME) != NULL)
+ step->data = &from_object;
+ else if (__strcasestr (step->to_name, CHARSET_NAME) != NULL)
+ step->data = &to_object;
+ else
+ return GCONV_NOCONV;
+
+ step->min_needed_from = MIN_NEEDED_FROM;
+ step->max_needed_from = MAX_NEEDED_FROM;
+ step->min_needed_to = MIN_NEEDED_TO;
+ step->max_needed_to = MAX_NEEDED_TO;
+
+ return GCONV_OK;
+}
+#endif
+
+
+/* The default destructor function does nothing in the moment and so
+ be define it at all. But we still provide the macro just in case
+ we need it some day. */
+#if DEFINE_FINI
+#endif
+
+
+/* This is the actual conversion function. */
+#ifndef FUNCTION_NAME
+# define FUNCTION_NAME gconv
+#endif
+
+int
+FUNCTION_NAME (struct gconv_step *step, struct gconv_step_data *data,
+ const char **inbuf, const char *inbufend, 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;
+ int status;
+
+ /* 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)
+ {
+ /* Call the steps down the chain if there are any. */
+ if (data->is_last)
+ status = GCONV_OK;
+ else
+ {
+#ifdef EMIT_SHIFT_TO_INIT
+ status = GCONV_OK;
+
+ EMIT_SHIFT_TO_INIT;
+
+ if (status == GCONV_OK)
+#endif
+ /* Give the modules below the same chance. */
+ status = (*fct) (next_step, next_data, NULL, NULL, written, 1);
+ }
+ }
+ else
+ {
+ /* This variable is used to count the number of characters we
+ actually converted. */
+ size_t converted = 0;
+
+ /* We preserve the initial values of the pointer variables. */
+ const char *inptr = *inbuf;
+ char *outbuf = data->outbuf;
+ char *outend = data->outbufend;
+ char *outptr;
+
+ do
+ {
+ /* Remember the start value for this round. */
+ inptr = *inbuf;
+ /* The outbuf buffer is empty. */
+ outptr = outbuf;
+
+ /* Save the state. */
+#ifdef SAVE_RESET_STATE
+ SAVE_RESET_STATE (1);
+#endif
+
+ if (FROM_DIRECTION)
+ /* Run the conversion loop. */
+ status = FROM_LOOP ((const unsigned char **) inbuf,
+ (const unsigned char *) inbufend,
+ (unsigned char **) &outbuf,
+ (unsigned char *) outend,
+ data->statep, step->data, &converted);
+ else
+ /* Run the conversion loop. */
+ status = TO_LOOP ((const unsigned char **) inbuf,
+ (const unsigned char *) inbufend,
+ (unsigned char **) &outbuf,
+ (unsigned char *) outend,
+ data->statep, step->data, &converted);
+
+ /* If this is the last step leave the loop, there is nothgin
+ we can do. */
+ if (data->is_last)
+ {
+ /* Store information about how many bytes are available. */
+ data->outbuf = outbuf;
+ break;
+ }
+
+ /* Write out all output which was produced. */
+ if (outbuf > outptr)
+ {
+ const char *outerr = outbuf;
+ int result;
+
+ result = (*fct) (next_step, next_data, &outerr, outbuf,
+ written, 0);
+
+ if (result != GCONV_EMPTY_INPUT)
+ {
+ if (outerr != outbuf)
+ {
+#ifdef RESET_INPUT_BUFFER
+ RESET_INPUT_BUFFER;
+#else
+ /* We have a problem with the in on of the functions
+ below. Undo the conversion upto the error point. */
+ size_t nstatus;
+
+ /* Reload the pointers. */
+ *inbuf = inptr;
+ outbuf = outptr;
+
+ /* Reset the state. */
+# ifdef SAVE_RESET_STATE
+ SAVE_RESET_STATE (0);
+# endif
+
+ if (FROM_DIRECTION)
+ /* Run the conversion loop. */
+ nstatus = FROM_LOOP ((const unsigned char **) inbuf,
+ (const unsigned char *) inbufend,
+ (unsigned char **) &outbuf,
+ (unsigned char *) outerr,
+ data->statep, step->data,
+ &converted);
+ else
+ /* Run the conversion loop. */
+ nstatus = TO_LOOP ((const unsigned char **) inbuf,
+ (const unsigned char *) inbufend,
+ (unsigned char **) &outbuf,
+ (unsigned char *) outerr,
+ data->statep, step->data,
+ &converted);
+
+ /* We must run out of output buffer space in this
+ rerun. */
+ assert (nstatus == GCONV_FULL_OUTPUT
+ && outbuf == outerr);
+#endif /* reset input buffer */
+ }
+
+ /* Change the status. */
+ status = result;
+ }
+ else
+ /* All the output is consumed, we can make another run
+ if everything was ok. */
+ if (status == GCONV_FULL_OUTPUT)
+ status = GCONV_OK;
+ }
+ }
+ while (status == GCONV_OK);
+
+ /* Remember how many characters we converted. */
+ *written += converted;
+ }
+
+ return status;
+}
+
+#undef DEFINE_INIT
+#undef CHARSET_NAME
+#undef DEFINE_FINI
+#undef MIN_NEEDED_FROM
+#undef MIN_NEEDED_TO
+#undef MAX_NEEDED_FROM
+#undef MAX_NEEDED_TO
+#undef DEFINE_DIRECTION_OBJECTS
+#undef FROM_DIRECTION
+#undef EMIT_SHIFT_TO_INIT
+#undef FROM_LOOP
+#undef TO_LOOP
+#undef RESET_STATE
+#undef RESET_INPUT_BUFFER
+#undef FUNCTION_NAME
diff --git a/iconvdata/8bit-gap.c b/iconvdata/8bit-gap.c
index a8d3c99a68..4065a6d777 100644
--- a/iconvdata/8bit-gap.c
+++ b/iconvdata/8bit-gap.c
@@ -19,10 +19,7 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#include <gconv.h>
#include <stdint.h>
-#include <string.h>
-
struct gap
{
@@ -34,192 +31,68 @@ struct gap
/* Now we can include the tables. */
#include TABLES
-/* We use three objects to describe the operation mode. */
-static int from_8bit_object;
-static int to_8bit_object;
-
-
-int
-gconv_init (struct gconv_step *step)
-{
- /* Determine which direction. */
- if (strcasestr (step->from_name, NAME) != NULL)
- step->data = &from_8bit_object;
- else if (strcasestr (step->to_name, NAME) != NULL)
- step->data = &to_8bit_object;
- else
- return GCONV_NOCONV;
-
- return GCONV_OK;
-}
-
-
-void
-gconv_end (struct gconv_step *data)
-{
- /* Nothing to do. */
-}
-
-
-int
-gconv (struct gconv_step *step, struct gconv_step_data *data,
- const char *inbuf, size_t *inbufsize, 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;
- 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)
- {
- do_write = 0;
-
- /* 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
- {
- do_write = 0;
-
- do
- {
- result = GCONV_OK;
-
- if (step->data == &from_8bit_object)
- {
- size_t inchars = *inbufsize;
- size_t outwchars = data->outbufavail;
- char *outbuf = data->outbuf;
- size_t cnt = 0;
-
- while (cnt < inchars
- && (outwchars + sizeof (wchar_t) <= data->outbufsize))
- {
- wchar_t ch = to_ucs4[((unsigned char *) inbuf)[cnt]];
-
- if (ch == L'\0' && inbuf[cnt] != '\0')
- {
- /* This is an illegal character. */
- result = GCONV_ILLEGAL_INPUT;
- break;
- }
-
- *((wchar_t *) (outbuf + outwchars)) = ch;
- ++do_write;
- outwchars += sizeof (wchar_t);
- ++cnt;
- }
- *inbufsize -= cnt;
- inbuf += cnt;
- data->outbufavail = outwchars;
- }
- else
- {
- size_t inwchars = *inbufsize;
- size_t outchars = data->outbufavail;
- char *outbuf = data->outbuf;
- size_t cnt = 0;
-
- while (inwchars >= cnt + sizeof (wchar_t)
- && outchars < data->outbufsize)
- {
- const struct gap *rp = from_idx;
- unsigned int ch = *((wchar_t *) (inbuf + cnt));
- char res;
-
- while (ch > rp->end)
- ++rp;
- if (ch < rp->start)
- /* No valid character. */
- break;
-
- res = from_ucs4[ch + rp->idx];
- if (res == '\0' && ch != 0)
- /* No valid character. */
- break;
-
- outbuf[outchars] = res;
- ++do_write;
- ++outchars;
- cnt += sizeof (wchar_t);
- }
- *inbufsize -= cnt;
- inbuf += cnt;
- data->outbufavail = outchars;
-
- if (outchars < data->outbufsize)
- {
- /* If there is still room in the output buffer something
- is wrong with the input. */
- if (inwchars >= cnt + sizeof (wchar_t))
- {
- /* An error occurred. */
- result = GCONV_ILLEGAL_INPUT;
- break;
- }
- if (inwchars != cnt)
- {
- /* There are some unprocessed bytes at the end of the
- input buffer. */
- result = GCONV_INCOMPLETE_INPUT;
- break;
- }
- }
- }
-
- if (result != GCONV_OK)
- break;
-
- if (data->is_last)
- {
- /* This is the last step. */
- result = (*inbufsize > (step->data == &from_8bit_object
- ? 0 : sizeof (wchar_t) - 1)
- ? GCONV_FULL_OUTPUT : GCONV_EMPTY_INPUT);
- 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 (*inbufsize > 0 && result == GCONV_EMPTY_INPUT);
- }
-
- if (written != NULL && data->is_last)
- *written = do_write;
- return result;
-}
+#define FROM_LOOP from_gap
+#define TO_LOOP to_gap
+#define DEFINE_INIT 1
+#define DEFINE_FINI 1
+#define MIN_NEEDED_FROM 1
+#define MIN_NEEDED_TO 4
+
+
+/* First define the conversion function from the 8bit charset to UCS4. */
+#define MIN_NEEDED_INPUT MIN_NEEDED_FROM
+#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
+#define LOOPFCT FROM_LOOP
+#define BODY \
+ { \
+ uint32_t ch = to_ucs4[*inptr]; \
+ \
+ if (HAS_HOLES && ch == L'\0' && *inptr != '\0') \
+ { \
+ /* This is an illegal character. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ \
+ *((uint32_t *) outptr)++ = ch; \
+ ++inptr; \
+ }
+#include <iconv/loop.c>
+
+
+/* Next, define the other direction. */
+#define MIN_NEEDED_INPUT MIN_NEEDED_TO
+#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM
+#define LOOPFCT TO_LOOP
+#define BODY \
+ { \
+ const struct gap *rp = from_idx; \
+ uint32_t ch = *((uint32_t *) inptr); \
+ unsigned char res; \
+ \
+ while (ch > rp->end) \
+ ++rp; \
+ if (ch < rp->start) \
+ { \
+ /* This is an illegal character. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ \
+ res = from_ucs4[ch + rp->idx]; \
+ if (ch != 0 && res == '\0') \
+ { \
+ /* This is an illegal character. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ \
+ *outptr++ = res; \
+ inptr += 4; \
+ }
+#include <iconv/loop.c>
+
+
+/* Now define the toplevel functions. */
+#include <iconv/skeleton.c>
diff --git a/iconvdata/8bit-generic.c b/iconvdata/8bit-generic.c
index 19194ad068..2ea333199e 100644
--- a/iconvdata/8bit-generic.c
+++ b/iconvdata/8bit-generic.c
@@ -18,186 +18,56 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#include <gconv.h>
-#include <string.h>
-
-/* We use three objects to describe the operation mode. */
-static int from_8bit_object;
-static int to_8bit_object;
-
-
-int
-gconv_init (struct gconv_step *step)
-{
- /* Determine which direction. */
- if (strcasestr (step->from_name, NAME) != NULL)
- step->data = &from_8bit_object;
- else if (strcasestr (step->to_name, NAME) != NULL)
- step->data = &to_8bit_object;
- else
- return GCONV_NOCONV;
-
- return GCONV_OK;
-}
-
-
-void
-gconv_end (struct gconv_step *data)
-{
- /* Nothing to do. */
-}
-
-
-int
-gconv (struct gconv_step *step, struct gconv_step_data *data,
- const char *inbuf, size_t *inbufsize, 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;
- 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)
- {
- do_write = 0;
-
- /* 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
- {
- do_write = 0;
-
- do
- {
- result = GCONV_OK;
-
- if (step->data == &from_8bit_object)
- {
- size_t inchars = *inbufsize;
- size_t outwchars = data->outbufavail;
- char *outbuf = data->outbuf;
- size_t cnt = 0;
-
- while (cnt < inchars
- && (outwchars + sizeof (wchar_t) <= data->outbufsize))
- {
- wchar_t ch = to_ucs4[((unsigned char *) inbuf)[cnt]];
-
- if (ch == L'\0' && inbuf[cnt] != '\0')
- {
- /* This is an illegal character. */
- result = GCONV_ILLEGAL_INPUT;
- break;
- }
-
- *((wchar_t *) (outbuf + outwchars)) = ch;
- ++do_write;
- outwchars += sizeof (wchar_t);
- ++cnt;
- }
- *inbufsize -= cnt;
- inbuf += cnt;
- data->outbufavail = outwchars;
- }
- else
- {
- size_t inwchars = *inbufsize;
- size_t outchars = data->outbufavail;
- char *outbuf = data->outbuf;
- size_t cnt = 0;
-
- while (inwchars >= cnt + sizeof (wchar_t)
- && outchars < data->outbufsize)
- {
- int ch = *((wchar_t *) (inbuf + cnt));
-
- if (ch >= sizeof (from_ucs4) / sizeof (from_ucs4[0])
- || ch < 0 || (from_ucs4[ch] == '\0' && ch != 0))
- break;
-
- outbuf[outchars] = from_ucs4[ch];
- ++do_write;
- ++outchars;
- cnt += sizeof (wchar_t);
- }
- *inbufsize -= cnt;
- inbuf += cnt;
- data->outbufavail = outchars;
-
- if (outchars < data->outbufsize)
- {
- /* If there is still room in the output buffer something
- is wrong with the input. */
- if (inwchars >= cnt + sizeof (wchar_t))
- {
- /* An error occurred. */
- result = GCONV_ILLEGAL_INPUT;
- break;
- }
- if (inwchars != cnt)
- {
- /* There are some unprocessed bytes at the end of the
- input buffer. */
- result = GCONV_INCOMPLETE_INPUT;
- break;
- }
- }
- }
-
- if (result != GCONV_OK)
- break;
-
- if (data->is_last)
- {
- /* This is the last step. */
- result = (*inbufsize > (step->data == &from_8bit_object
- ? 0 : sizeof (wchar_t) - 1)
- ? GCONV_FULL_OUTPUT : GCONV_EMPTY_INPUT);
- 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 (*inbufsize > 0 && result == GCONV_EMPTY_INPUT);
- }
-
- if (written != NULL && data->is_last)
- *written = do_write;
-
- return result;
-}
+#define FROM_LOOP from_generic
+#define TO_LOOP to_generic
+#define DEFINE_INIT 1
+#define DEFINE_FINI 1
+#define MIN_NEEDED_FROM 1
+#define MIN_NEEDED_TO 4
+
+
+/* First define the conversion function from the 8bit charset to UCS4. */
+#define MIN_NEEDED_INPUT MIN_NEEDED_FROM
+#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
+#define LOOPFCT FROM_LOOP
+#define BODY \
+ { \
+ uint32_t ch = to_ucs4[*inptr]; \
+ \
+ if (HAS_HOLES && ch == L'\0' && *inptr != '\0') \
+ { \
+ /* This is an illegal character. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ \
+ *((uint32_t *) outptr)++ = ch; \
+ ++inptr; \
+ }
+#include <iconv/loop.c>
+
+
+/* Next, define the other direction. */
+#define MIN_NEEDED_INPUT MIN_NEEDED_TO
+#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM
+#define LOOPFCT TO_LOOP
+#define BODY \
+ { \
+ uint32_t ch = *((uint32_t *) inptr); \
+ \
+ if (ch >= sizeof (from_ucs4) / sizeof (from_ucs4[0]) \
+ || (ch != 0 && from_ucs4[ch] == '\0')) \
+ { \
+ /* This is an illegal character. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ \
+ *outptr++ = from_ucs4[ch]; \
+ inptr += 4; \
+ }
+#include <iconv/loop.c>
+
+
+/* Now define the toplevel functions. */
+#include <iconv/skeleton.c>
diff --git a/iconvdata/Makefile b/iconvdata/Makefile
index dd1c391c6c..69576859ec 100644
--- a/iconvdata/Makefile
+++ b/iconvdata/Makefile
@@ -26,8 +26,8 @@ modules := ISO8859-1 ISO8859-2 ISO8859-3 ISO8859-4 ISO8859-5 \
ISO8859-6 ISO8859-7 ISO8859-8 ISO8859-9 ISO8859-10 \
T.61 ISO_6937 SJIS KOI-8 KOI8-R LATIN-GREEK LATIN-GREEK-1 \
HP-ROMAN8 EBCDIC-AT-DE EBCDIC-AT-DE-A EBCDIC-CA-FR \
- EUC-KR UHC JOHAB libJIS libKSC ISO646 BIG5 EUC-JP libGB \
- EUC-CN libCNS EUC-TW
+ EUC-KR UHC JOHAB libJIS libKSC BIG5 EUC-JP libGB \
+ EUC-CN libCNS EUC-TW # ISO646
modules.so := $(addsuffix .so, $(modules))
@@ -211,7 +211,7 @@ endif
include ../Rules
.PHONY: do-iconv-test
-tests: do-iconv-test
+#tests: do-iconv-test
do-iconv-test: run-iconv-test.sh $(objpfx)gconv-modules \
$(addprefix $(objpfx),$(modules.so)) \
diff --git a/iconvdata/big5.c b/iconvdata/big5.c
index a6a2580dd7..2962712167 100644
--- a/iconvdata/big5.c
+++ b/iconvdata/big5.c
@@ -8411,289 +8411,180 @@ static const char from_ucs4_tab13[][2] =
};
-/* Direction of the transformation. */
-static int to_big5_object;
-static int from_big5_object;
+/* Definitions used in the body of the `gconv' function. */
+#define CHARSET_NAME "BIG5"
+#define FROM_LOOP from_big5
+#define TO_LOOP to_big5
+#define DEFINE_INIT 1
+#define DEFINE_FINI 1
+#define MIN_NEEDED_FROM 1
+#define MAX_NEEDED_FROM 2
+#define MIN_NEEDED_TO 4
-int
-gconv_init (struct gconv_step *step)
-{
- /* Determine which direction. */
- if (strcasestr (step->from_name, "BIG5") != NULL)
- step->data = &from_big5_object;
- else if (strcasestr (step->to_name, "BIG5") != NULL)
- step->data = &to_big5_object;
- else
- return GCONV_NOCONV;
-
- return GCONV_OK;
-}
-
-
-void
-gconv_end (struct gconv_step *data)
-{
- /* Nothing to do. */
-}
-
-
-int
-gconv (struct gconv_step *step, struct gconv_step_data *data,
- const char *inbuf, size_t *inbufsize, 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;
- 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)
- {
- do_write = 0;
-
- /* Call the steps down the chain if there are any. */
- if (data->is_last)
- result = GCONV_OK;
- else
- {
- result = (*fct) (next_step, next_data, NULL, 0, written, 1);
-
- /* Clear output buffer. */
- data->outbufavail = 0;
- }
- }
- else
- {
- do_write = 0;
-
- do
- {
- result = GCONV_OK;
-
- if (step->data == &from_big5_object)
- {
- size_t inchars = *inbufsize;
- size_t outwchars = data->outbufavail;
- char *outbuf = data->outbuf;
- size_t cnt = 0;
-
- while (cnt < inchars
- && (outwchars + sizeof (wchar_t) <= data->outbufsize))
- {
- int inchar = inbuf[cnt];
- wchar_t ch;
-
- if (inchar < '\xa1' || inchar > '\xfe')
- ch = (wchar_t) inchar;
- else
- {
- /* Two-byte character. First test whether the next
- character is also available. */
- int inchar2;
- int idx;
-
- if (cnt + 1 >= inchars)
- {
- /* The second character is not available. Store
- the intermediate result. */
- result = GCONV_INCOMPLETE_INPUT;
- break;
- }
-
- idx = (inchar - 0xa1) * 157;
- inchar2 = inbuf[++cnt];
- /* See whether the second byte is in the correct
- range. */
- if (inchar2 >= '\x40' && inchar2 <= '\x7e')
- idx += inchar2 - 0x40;
- else if (inchar2 >= '\xa1' && inchar2 <= '\xfe')
- idx += 0x3f + (inchar2 - 0xa1);
- else
- {
- /* This is illegal. */
- --cnt;
- result = GCONV_ILLEGAL_INPUT;
- break;
- }
-
- /* Get the value from the table. */
- ch = big5_to_ucs[idx];
-
- if (ch == L'\0')
- --cnt;
- }
-
- if (ch == L'\0' && inbuf[cnt] != '\0')
- {
- /* This is an illegal character. */
- result = GCONV_ILLEGAL_INPUT;
- break;
- }
-
- *((wchar_t *) (outbuf + outwchars)) = ch;
- ++do_write;
- outwchars += sizeof (wchar_t);
- ++cnt;
- }
- *inbufsize -= cnt;
- inbuf += cnt;
- data->outbufavail = outwchars;
- }
- else
- {
- size_t inwchars = *inbufsize;
- size_t outchars = data->outbufavail;
- char *outbuf = data->outbuf;
- size_t cnt = 0;
- int extra = 0;
-
- while (inwchars >= cnt + sizeof (wchar_t)
- && outchars < data->outbufsize)
- {
- int ch = *((wchar_t *) (inbuf + cnt));
- char buf[2];
- const char *cp;
-
- if (ch >= (sizeof (from_ucs4_tab1)
- / sizeof (from_ucs4_tab1[0])))
- {
- if (ch >= 0x2c7 && ch <= 0x2d9)
- cp = from_ucs4_tab2[ch - 0x2c7];
- else if (ch >= 0x391 && ch <= 0x451)
- cp = from_ucs4_tab3[ch - 0x391];
- else if (ch >= 0x2013 && ch <= 0x203e)
- cp = from_ucs4_tab4[ch - 0x2013];
- else if (ch == 0x2103)
- cp = "\xa2\x4a";
- else if (ch == 0x2105)
- cp = "\xa1\xc1";
- else if (ch == 0x2109)
- cp = "\xa2\x4b";
- else if (ch >= 0x2160 && ch <= 0x2169)
- {
- buf[0] = '\xa2';
- buf[1] = '\xb9' + (ch - 0x2160);
- cp = buf;
- }
- else if (ch >= 0x2190 && ch <= 0x2199)
- cp = from_ucs4_tab5[ch - 0x2190];
- else if (ch >= 0x221a && ch <= 0x22bf)
- cp = from_ucs4_tab6[ch - 0x221a];
- else if (ch >= 0x2460 && ch <= 0x247d)
- cp = from_ucs4_tab7[ch - 0x2460];
- else if (ch >= 0x2500 && ch <= 0x2642)
- cp = from_ucs4_tab8[ch - 0x2500];
- else if (ch >= 0x3000 && ch <= 0x3129)
- cp = from_ucs4_tab9[ch - 0x3000];
- else if (ch == 0x32a3)
- cp = "\xa1\xc0";
- else if (ch >= 0x338e && ch <= 0x33d5)
- cp = from_ucs4_tab10[ch - 0x338e];
- else if (ch >= 0x4e00 && ch <= 0x9fa4)
- cp = from_ucs4_tab11[ch - 0x4e00];
- else if (ch == 0xfa0c)
- cp = "\xc9\x4a";
- else if (ch == 0xfa0d)
- cp = "\xdd\xfc";
- else if (ch >= 0xfe30 && ch <= 0xfe6b)
- cp = from_ucs4_tab12[ch - 0xfe30];
- else if (ch >= 0xff01 && ch <= 0xff64)
- cp = from_ucs4_tab13[ch - 0xff01];
- else
- /* Illegal character. */
- break;
- }
- else
- cp = from_ucs4_tab1[ch];
-
- if (cp[0] == '\0' && ch != 0)
- /* Illegal character. */
- break;
-
- outbuf[outchars] = cp[0];
- /* Now test for a possible second byte and write this
- if possible. */
- if (cp[1] != '\0')
- {
- if (outchars + 1 >= data->outbufsize)
- {
- /* The result does not fit into the buffer. */
- extra = 1;
- break;
- }
- outbuf[++outchars] = cp[1];
- }
-
- ++do_write;
- ++outchars;
- cnt += sizeof (wchar_t);
- }
- *inbufsize -= cnt;
- inbuf += cnt;
- data->outbufavail = outchars;
-
- if (outchars + extra < data->outbufsize)
- {
- /* If there is still room in the output buffer something
- is wrong with the input. */
- if (inwchars >= cnt + sizeof (wchar_t))
- {
- /* An error occurred. */
- result = GCONV_ILLEGAL_INPUT;
- break;
- }
- if (inwchars != cnt)
- {
- /* There are some unprocessed bytes at the end of the
- input buffer. */
- result = GCONV_INCOMPLETE_INPUT;
- break;
- }
- }
- }
-
- if (result != GCONV_OK)
- break;
-
- if (data->is_last)
- {
- /* This is the last step. */
- result = (*inbufsize > (step->data == &from_big5_object
- ? 0 : sizeof (wchar_t) - 1)
- ? GCONV_FULL_OUTPUT : GCONV_EMPTY_INPUT);
- break;
- }
-
- /* Status so far. */
- result = GCONV_EMPTY_INPUT;
-
- if (data->outbufavail > 0)
- {
- /* Call the functions below in the chain. */
- size_t newavail = data->outbufavail;
+/* First define the conversion function from Big5 to UCS4. */
+#define MIN_NEEDED_INPUT MIN_NEEDED_FROM
+#define MAX_NEEDED_INPUT MAX_NEEDED_FROM
+#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
+#define LOOPFCT FROM_LOOP
+#define BODY \
+ { \
+ uint32_t ch = *inptr; \
+ \
+ if (ch >= '\xa1' && ch <= '\xff') \
+ { \
+ /* Two-byte character. First test whether the next character \
+ is also available. */ \
+ uint32_t ch2; \
+ int idx; \
+ \
+ if (NEED_LENGTH_TEST && inptr + 1 >= inend) \
+ { \
+ /* The second character is not available. */ \
+ result = GCONV_INCOMPLETE_INPUT; \
+ break; \
+ } \
+ \
+ idx = (ch - 0xa1) * 157; \
+ ch2 = inptr[1]; \
+ /* See whether the second byte is in the correct range. */ \
+ if (ch2 >= '\x40' && ch2 <= '\x7e') \
+ idx += ch2 - 0x40; \
+ else if (ch2 >= '\xa1' && ch2 <= '\xfe') \
+ idx += 0x3f + (ch2 - 0xa1); \
+ else \
+ { \
+ /* This is illegal. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ \
+ /* Get the value from the table. */ \
+ ch = big5_to_ucs[idx]; \
+ \
+ /* Is this character defined? */ \
+ if (ch == L'\0' && *inptr != '\0') \
+ { \
+ /* This is an illegal character. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ \
+ inptr += 2; \
+ } \
+ else \
+ ++inptr; \
+ \
+ *((uint32_t *) outptr)++ = ch; \
+ }
+#include <iconv/loop.c>
- 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 (*inbufsize > 0 && result == GCONV_EMPTY_INPUT);
- }
+/* Next, define the other direction. */
+#define MIN_NEEDED_INPUT MIN_NEEDED_TO
+#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM
+#define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM
+#define LOOPFCT TO_LOOP
+#define BODY \
+ { \
+ uint32_t ch = *((uint32_t *) inptr); \
+ char buf[2]; \
+ const char *cp; \
+ \
+ if (ch >= sizeof (from_ucs4_tab1) / sizeof (from_ucs4_tab1[0])) \
+ switch (ch) \
+ { \
+ case 0x2c7 ... 0x2d9: \
+ cp = from_ucs4_tab2[ch - 0x2c7]; \
+ break; \
+ case 0x391 ... 0x451: \
+ cp = from_ucs4_tab3[ch - 0x391]; \
+ break; \
+ case 0x2013 ... 0x203e: \
+ cp = from_ucs4_tab4[ch - 0x2013]; \
+ break; \
+ case 0x2103: \
+ cp = "\xa2\x4a"; \
+ break; \
+ case 0x2105: \
+ cp = "\xa1\xc1"; \
+ break; \
+ case 0x2109: \
+ cp = "\xa2\x4b"; \
+ break; \
+ case 0x2160 ... 0x2169: \
+ { \
+ buf[0] = '\xa2'; \
+ buf[1] = '\xb9' + (ch - 0x2160); \
+ cp = buf; \
+ } \
+ break; \
+ case 0x2190 ... 0x2199: \
+ cp = from_ucs4_tab5[ch - 0x2190]; \
+ break; \
+ case 0x221a ... 0x22bf: \
+ cp = from_ucs4_tab6[ch - 0x221a]; \
+ break; \
+ case 0x2460 ... 0x247d: \
+ cp = from_ucs4_tab7[ch - 0x2460]; \
+ break; \
+ case 0x2500 ... 0x2642: \
+ cp = from_ucs4_tab8[ch - 0x2500]; \
+ break; \
+ case 0x3000 ... 0x3129: \
+ cp = from_ucs4_tab9[ch - 0x3000]; \
+ break; \
+ case 0x32a3: \
+ cp = "\xa1\xc0"; \
+ break; \
+ case 0x338e ... 0x33d5: \
+ cp = from_ucs4_tab10[ch - 0x338e]; \
+ break; \
+ case 0x4e00 ... 0x9fa4: \
+ cp = from_ucs4_tab11[ch - 0x4e00]; \
+ break; \
+ case 0xfa0c: \
+ cp = "\xc9\x4a"; \
+ break; \
+ case 0xfa0d: \
+ cp = "\xdd\xfc"; \
+ break; \
+ case 0xfe30 ... 0xfe6b: \
+ cp = from_ucs4_tab12[ch - 0xfe30]; \
+ break; \
+ case 0xff01 ... 0xff64: \
+ cp = from_ucs4_tab13[ch - 0xff01]; \
+ break; \
+ default: \
+ /* Illegal character. */ \
+ cp = ""; \
+ break; \
+ } \
+ else \
+ cp = from_ucs4_tab1[ch]; \
+ \
+ if (cp[0] == '\0' && ch != 0) \
+ { \
+ /* Illegal character. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ \
+ /* See whether there is enough room for the second byte we write. */ \
+ if (NEED_LENGTH_TEST && cp[1] != '\0' && outptr + 1 >= outend) \
+ { \
+ /* We have not enough room. */ \
+ result = GCONV_FULL_OUTPUT; \
+ break; \
+ } \
+ \
+ *outptr++ = cp[0]; \
+ if (cp[1] != '\0') \
+ *outptr++ = cp[1]; \
+ inptr += 4; \
+ }
+#include <iconv/loop.c>
- if (written != NULL && data->is_last)
- *written = do_write;
- return result;
-}
+/* Now define the toplevel functions. */
+#include <iconv/skeleton.c>
diff --git a/iconvdata/cns11643.c b/iconvdata/cns11643.c
index 903548261b..bd1994f1d9 100644
--- a/iconvdata/cns11643.c
+++ b/iconvdata/cns11643.c
@@ -44,7 +44,7 @@
printf ("\n");
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
-const uint16_t cns11643l2_to_ucs4_tab[] =
+const uint16_t __cns11643l2_to_ucs4_tab[] =
{
[0x0000] = 0x4e42, [0x0001] = 0x4e5c, [0x0002] = 0x51f5, [0x0003] = 0x531a,
[0x0004] = 0x5382, [0x0005] = 0x4e07, [0x0006] = 0x4e0c, [0x0007] = 0x4e47,
@@ -1985,7 +1985,7 @@ const uint16_t cns11643l2_to_ucs4_tab[] =
printf ("\n");
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
-const uint16_t cns11643l14_to_ucs4_tab[] =
+const uint16_t __cns11643l14_to_ucs4_tab[] =
{
[0x0000] = 0x4e28, [0x0001] = 0x4e36, [0x0002] = 0x4e3f, [0x0003] = 0x4e85,
[0x0004] = 0x4e05, [0x0005] = 0x4e04, [0x0006] = 0x5182, [0x0007] = 0x5196,
@@ -3064,7 +3064,7 @@ const uint16_t cns11643l14_to_ucs4_tab[] =
printf ("\n");
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
-const char cns11643_from_ucs4_tab[][3] =
+const char __cns11643_from_ucs4_tab[][3] =
{
[0x0000] = "\x01\x44\x21", [0x0001] = "\x01\x44\x23",
[0x0003] = "\x01\x44\x24", [0x0004] = "\x0e\x21\x26",
diff --git a/iconvdata/cns11643.h b/iconvdata/cns11643.h
index f791d4cdb3..ccab8011ce 100644
--- a/iconvdata/cns11643.h
+++ b/iconvdata/cns11643.h
@@ -21,8 +21,8 @@
#include <stdint.h>
/* Table for CNS 11643, plane 2 to UCS4 conversion. */
-extern const uint16_t cns11643l2_to_ucs4_tab[];
-extern const uint16_t cns11643l14_to_ucs4_tab[];
+extern const uint16_t __cns11643l2_to_ucs4_tab[];
+extern const uint16_t __cns11643l14_to_ucs4_tab[];
static inline wchar_t
@@ -54,19 +54,19 @@ cns11643_to_ucs4 (const char **s, size_t avail, unsigned char offset)
{
if (idx > 0x2196)
return UNKNOWN_10646_CHAR;
- result = cns11643l1_to_ucs4_tab[idx];
+ result = __cns11643l1_to_ucs4_tab[idx];
}
else if ((ch - 0x21 - offset) == 2)
{
if (idx > 0x1de1)
return UNKNOWN_10646_CHAR;
- result = cns11643l2_to_ucs4_tab[idx];
+ result = __cns11643l2_to_ucs4_tab[idx];
}
else if ((ch - 0x21 - offset) == 0xe)
{
if (idx > 0x19bd)
return UNKNOWN_10646_CHAR;
- result = cns11643l14_to_ucs4_tab[idx];
+ result = __cns11643l14_to_ucs4_tab[idx];
}
else
return UNKNOWN_10646_CHAR;
@@ -81,21 +81,21 @@ cns11643_to_ucs4 (const char **s, size_t avail, unsigned char offset)
/* Tables for the UCS4 -> CNS conversion. */
-extern const char cns11643l1_from_ucs4_tab1[][2];
-extern const char cns11643l1_from_ucs4_tab2[][2];
-extern const char cns11643l1_from_ucs4_tab3[][2];
-extern const char cns11643l1_from_ucs4_tab4[][2];
-extern const char cns11643l1_from_ucs4_tab5[][2];
-extern const char cns11643l1_from_ucs4_tab6[][2];
-extern const char cns11643l1_from_ucs4_tab7[][2];
-extern const char cns11643l1_from_ucs4_tab8[][2];
-extern const char cns11643l1_from_ucs4_tab9[][2];
-extern const char cns11643l1_from_ucs4_tab10[][2];
-extern const char cns11643l1_from_ucs4_tab11[][2];
-extern const char cns11643l1_from_ucs4_tab12[][2];
-extern const char cns11643l1_from_ucs4_tab13[][2];
-extern const char cns11643l1_from_ucs4_tab14[][2];
-extern const char cns11643_from_ucs4_tab[][3];
+extern const char __cns11643l1_from_ucs4_tab1[][2];
+extern const char __cns11643l1_from_ucs4_tab2[][2];
+extern const char __cns11643l1_from_ucs4_tab3[][2];
+extern const char __cns11643l1_from_ucs4_tab4[][2];
+extern const char __cns11643l1_from_ucs4_tab5[][2];
+extern const char __cns11643l1_from_ucs4_tab6[][2];
+extern const char __cns11643l1_from_ucs4_tab7[][2];
+extern const char __cns11643l1_from_ucs4_tab8[][2];
+extern const char __cns11643l1_from_ucs4_tab9[][2];
+extern const char __cns11643l1_from_ucs4_tab10[][2];
+extern const char __cns11643l1_from_ucs4_tab11[][2];
+extern const char __cns11643l1_from_ucs4_tab12[][2];
+extern const char __cns11643l1_from_ucs4_tab13[][2];
+extern const char __cns11643l1_from_ucs4_tab14[][2];
+extern const char __cns11643_from_ucs4_tab[][3];
static inline size_t
@@ -103,120 +103,104 @@ ucs4_to_cns11643 (wchar_t wch, char *s, size_t avail)
{
unsigned int ch = (unsigned int) wch;
char buf[2];
- const char *cp = NULL;
+ const char *cp = buf;
int needed = 2;
- if (ch < 0xa7)
- cp = "";
- else if (ch < 0xf7)
- cp = cns11643l1_from_ucs4_tab1[ch - 0xa7];
- else if (ch < 0x2c7)
- cp = "";
- else if (ch <= 0x2d9)
- cp = cns11643l1_from_ucs4_tab2[ch - 0x2c7];
- else if (ch < 0x391)
- cp = "";
- else if (ch <= 0x3c9)
- cp = cns11643l1_from_ucs4_tab3[ch - 0x391];
- else if (ch < 0x2013)
- cp = "";
- else if (ch <= 0x203e)
- cp = cns11643l1_from_ucs4_tab4[ch - 0x2013];
- else if (ch == 0x2103)
- cp = "\x22\x6a";
- else if (ch == 0x2105)
- cp = "\x22\x22";
- else if (ch == 0x2109)
- cp = "\x22\x6b";
- else if (ch < 0x2160)
- cp = "";
- else if (ch <= 0x2169)
+ switch (ch)
{
+ case 0xa7 ... 0xf7:
+ cp = __cns11643l1_from_ucs4_tab1[ch - 0xa7];
+ break;
+ case 0x2c7 ... 0x2d9:
+ cp = __cns11643l1_from_ucs4_tab2[ch - 0x2c7];
+ break;
+ case 0x391 ... 0x3c9:
+ cp = __cns11643l1_from_ucs4_tab3[ch - 0x391];
+ break;
+ case 0x2013 ... 0x203e:
+ cp = __cns11643l1_from_ucs4_tab4[ch - 0x2013];
+ break;
+ case 0x2103:
+ cp = "\x22\x6a";
+ break;
+ case 0x2105:
+ cp = "\x22\x22";
+ break;
+ case 0x2109:
+ cp = "\x22\x6b";
+ break;
+ case 0x2160 ...0x2169:
buf[0] = '\x24';
buf[1] = '\x2b' + (ch - 0x2160);
- cp = buf;
- }
- else if (ch < 0x2170)
- cp = "";
- else if (ch <= 0x2179)
- {
+ break;
+ case 0x2170 ... 0x2179:
buf[0] = '\x26';
buf[1] = '\x35' + (ch - 0x2170);
- cp = buf;
- }
- else if (ch < 0x2190)
- cp = "";
- else if (ch <= 0x2199)
- cp = cns11643l1_from_ucs4_tab5[ch - 0x2190];
- else if (ch < 0x2215)
- cp = "";
- else if (ch <= 0x2267)
- cp = cns11643l1_from_ucs4_tab6[ch - 0x2215];
- else if (ch == 0x22a5)
- cp = "\x22\x47";
- else if (ch == 0x22bf)
- cp = "\x22\x4a";
- else if (ch < 0x2400)
- cp = "";
- else if (ch <= 0x2421)
- cp = cns11643l1_from_ucs4_tab7[ch - 0x2400];
- else if (ch < 0x2460)
- cp = "";
- else if (ch <= 0x247d)
- cp = cns11643l1_from_ucs4_tab8[ch - 0x2460];
- else if (ch < 0x2500)
- cp = "";
- else if (ch <= 0x2642)
- cp = cns11643l1_from_ucs4_tab9[ch - 0x2500];
- else if (ch < 0x3000)
- cp = "";
- else if (ch <= 0x3029)
- cp = cns11643l1_from_ucs4_tab10[ch - 0x3000];
- else if (ch == 0x30fb)
- cp = "\x21\x26";
- else if (ch < 0x3105)
- cp = "";
- else if (ch <= 0x3129)
- {
+ break;
+ case 0x2190 ... 0x2199:
+ cp = __cns11643l1_from_ucs4_tab5[ch - 0x2190];
+ break;
+ case 0x2215 ... 0x2267:
+ cp = __cns11643l1_from_ucs4_tab6[ch - 0x2215];
+ break;
+ case 0x22a5:
+ cp = "\x22\x47";
+ break;
+ case 0x22bf:
+ cp = "\x22\x4a";
+ break;
+ case 0x2400 ... 0x2421:
+ cp = __cns11643l1_from_ucs4_tab7[ch - 0x2400];
+ break;
+ case 0x2460 ... 0x247d:
+ cp = __cns11643l1_from_ucs4_tab8[ch - 0x2460];
+ break;
+ case 0x2500 ... 0x2642:
+ cp = __cns11643l1_from_ucs4_tab9[ch - 0x2500];
+ case 0x3000 ... 0x3029:
+ cp = __cns11643l1_from_ucs4_tab10[ch - 0x3000];
+ break;
+ case 0x30fb:
+ cp = "\x21\x26";
+ break;
+ case 0x3105 ... 0x3129:
buf[0] = '\x25';
buf[1] = '\x26' + (ch - 0x3105);
- cp = buf;
- }
- else if (ch == 0x32a3)
- cp = "\x22\x21";
- else if (ch < 0x338e)
- cp = "";
- else if (ch <= 0x33d5)
- cp = cns11643l1_from_ucs4_tab11[ch - 0x338e];
- else if (ch < 0x4e00)
- cp = "";
- else if (ch <= 0x9f9c)
- {
- cp = cns11643l1_from_ucs4_tab12[ch - 0x4e00];
+ break;
+ case 0x32a3:
+ cp = "\x22\x21";
+ break;
+ case 0x338e ... 0x33d5:
+ cp = __cns11643l1_from_ucs4_tab11[ch - 0x338e];
+ break;
+ case 0x4e00 ... 0x9f9c:
+ cp = __cns11643l1_from_ucs4_tab12[ch - 0x4e00];
if (cp[0] == '\0')
{
/* Let's try the other planes. */
needed = 3;
- cp = cns11643_from_ucs4_tab[ch - 0x4e00];
+ cp = __cns11643_from_ucs4_tab[ch - 0x4e00];
}
+ break;
+ case 0xfe30 ... 0xfe6b:
+ cp = __cns11643l1_from_ucs4_tab13[ch - 0xfe30];
+ break;
+ case 0xff01 ... 0xff5d:
+ cp = __cns11643l1_from_ucs4_tab14[ch - 0xff01];
+ break;
+ case 0xffe0:
+ cp = "\x22\x66";
+ break;
+ case 0xffe1:
+ cp = "\x22\x67";
+ break;
+ case 0xffe5:
+ cp = "\x22\x64";
+ break;
+ default:
+ cp = "";
}
- else if (ch < 0xfe30)
- cp = "";
- else if (ch <= 0xfe6b)
- cp = cns11643l1_from_ucs4_tab13[ch - 0xfe30];
- else if (ch < 0xff01)
- cp = "";
- else if (ch <= 0xff5d)
- cp = cns11643l1_from_ucs4_tab14[ch - 0xff01];
- else if (ch == 0xffe0)
- cp = "\x22\x66";
- else if (ch == 0xffe1)
- cp = "\x22\x67";
- else if (ch == 0xffe5)
- cp = "\x22\x64";
- else
- cp = "";
if (cp[0] == '\0')
return UNKNOWN_10646_CHAR;
diff --git a/iconvdata/cns11643l1.c b/iconvdata/cns11643l1.c
index 730fb550ab..d106b3d34c 100644
--- a/iconvdata/cns11643l1.c
+++ b/iconvdata/cns11643l1.c
@@ -45,7 +45,7 @@
printf ("\n");
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
-const uint16_t cns11643l1_to_ucs4_tab[] =
+const uint16_t __cns11643l1_to_ucs4_tab[] =
{
[0x0000] = 0x3000, [0x0001] = 0xff0c, [0x0002] = 0x3001, [0x0003] = 0x3002,
[0x0004] = 0xff0e, [0x0005] = 0x30fb, [0x0006] = 0xff1b, [0x0007] = 0xff1a,
@@ -1517,7 +1517,7 @@ const uint16_t cns11643l1_to_ucs4_tab[] =
/* Some Latin1 characters, starting at U+00a7. */
-const char cns11643l1_from_ucs4_tab1[][2] =
+const char __cns11643l1_from_ucs4_tab1[][2] =
{
[0x00] = "\x21\x70", [0x09] = "\x22\x78", [0x0a] = "\x22\x34",
[0x10] = "\x21\x31", [0x30] = "\x22\x32", [0x50] = "\x22\x33"
@@ -1525,7 +1525,7 @@ const char cns11643l1_from_ucs4_tab1[][2] =
/* Some phonetic modifiers, starting at U+02c7. */
-const char cns11643l1_from_ucs4_tab2[][2] =
+const char __cns11643l1_from_ucs4_tab2[][2] =
{
[0x00] = "\x25\x6f", [0x02] = "\x25\x6d", [0x03] = "\x25\x6e",
[0x04] = "\x25\x70", [0x12] = "\x25\x6c"
@@ -1552,7 +1552,7 @@ const char cns11643l1_from_ucs4_tab2[][2] =
printf ("\n");
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
-const char cns11643l1_from_ucs4_tab3[][2] =
+const char __cns11643l1_from_ucs4_tab3[][2] =
{
[0x0000] = "\x24\x75", [0x0001] = "\x24\x76", [0x0002] = "\x24\x77",
[0x0003] = "\x24\x78", [0x0004] = "\x24\x79", [0x0005] = "\x24\x7a",
@@ -1593,7 +1593,7 @@ const char cns11643l1_from_ucs4_tab3[][2] =
printf ("\n");
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
-const char cns11643l1_from_ucs4_tab4[][2] =
+const char __cns11643l1_from_ucs4_tab4[][2] =
{
[0x0000] = "\x21\x39", [0x0001] = "\x21\x37", [0x0003] = "\x22\x5d",
[0x0005] = "\x21\x64", [0x0006] = "\x21\x65", [0x0009] = "\x21\x66",
@@ -1603,7 +1603,7 @@ const char cns11643l1_from_ucs4_tab4[][2] =
};
-const char cns11643l1_from_ucs4_tab5[][2] =
+const char __cns11643l1_from_ucs4_tab5[][2] =
{
[0x00] = "\x22\x58", [0x01] = "\x22\x55", [0x02] = "\x22\x57",
[0x03] = "\x22\x56", [0x06] = "\x22\x59", [0x07] = "\x22\x5a",
@@ -1631,7 +1631,7 @@ const char cns11643l1_from_ucs4_tab5[][2] =
printf ("\n");
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
-const char cns11643l1_from_ucs4_tab6[][2] =
+const char __cns11643l1_from_ucs4_tab6[][2] =
{
[0x0000] = "\x22\x61", [0x0005] = "\x22\x35", [0x0009] = "\x22\x3c",
[0x000a] = "\x22\x49", [0x000b] = "\x22\x48", [0x0014] = "\x22\x45",
@@ -1661,7 +1661,7 @@ const char cns11643l1_from_ucs4_tab6[][2] =
printf ("\n");
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
-const char cns11643l1_from_ucs4_tab7[][2] =
+const char __cns11643l1_from_ucs4_tab7[][2] =
{
[0x0000] = "\x42\x21", [0x0001] = "\x42\x22", [0x0002] = "\x42\x23",
[0x0003] = "\x42\x24", [0x0004] = "\x42\x25", [0x0005] = "\x42\x26",
@@ -1697,7 +1697,7 @@ const char cns11643l1_from_ucs4_tab7[][2] =
printf ("\n");
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
-const char cns11643l1_from_ucs4_tab8[][2] =
+const char __cns11643l1_from_ucs4_tab8[][2] =
{
[0x0000] = "\x26\x21", [0x0001] = "\x26\x22", [0x0002] = "\x26\x23",
[0x0003] = "\x26\x24", [0x0004] = "\x26\x25", [0x0005] = "\x26\x26",
@@ -1729,7 +1729,7 @@ const char cns11643l1_from_ucs4_tab8[][2] =
printf ("\n");
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
-const char cns11643l1_from_ucs4_tab9[][2] =
+const char __cns11643l1_from_ucs4_tab9[][2] =
{
[0x0000] = "\x23\x39", [0x0002] = "\x23\x3a", [0x000c] = "\x23\x3c",
[0x0010] = "\x23\x3d", [0x0014] = "\x23\x3e", [0x0018] = "\x23\x3f",
@@ -1774,7 +1774,7 @@ const char cns11643l1_from_ucs4_tab9[][2] =
printf ("\n");
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
-const char cns11643l1_from_ucs4_tab10[][2] =
+const char __cns11643l1_from_ucs4_tab10[][2] =
{
[0x0000] = "\x21\x21", [0x0001] = "\x21\x23", [0x0002] = "\x21\x24",
[0x0003] = "\x21\x71", [0x0008] = "\x21\x52", [0x0009] = "\x21\x53",
@@ -1809,7 +1809,7 @@ const char cns11643l1_from_ucs4_tab10[][2] =
printf ("\n");
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
-const char cns11643l1_from_ucs4_tab11[][2] =
+const char __cns11643l1_from_ucs4_tab11[][2] =
{
[0x0000] = "\x22\x75", [0x0001] = "\x22\x76", [0x000e] = "\x22\x70",
[0x000f] = "\x22\x71", [0x0010] = "\x22\x72", [0x0013] = "\x22\x74",
@@ -1838,7 +1838,7 @@ const char cns11643l1_from_ucs4_tab11[][2] =
printf ("\n");
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
-const char cns11643l1_from_ucs4_tab12[][2] =
+const char __cns11643l1_from_ucs4_tab12[][2] =
{
[0x0000] = "\x44\x21", [0x0001] = "\x44\x23", [0x0003] = "\x44\x24",
[0x0008] = "\x44\x37", [0x0009] = "\x44\x35", [0x000a] = "\x44\x38",
@@ -3667,7 +3667,7 @@ const char cns11643l1_from_ucs4_tab12[][2] =
printf ("\n");
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
-const char cns11643l1_from_ucs4_tab13[][2] =
+const char __cns11643l1_from_ucs4_tab13[][2] =
{
[0x0000] = "\x21\x2b", [0x0001] = "\x21\x36", [0x0002] = "\x21\x38",
[0x0005] = "\x21\x40", [0x0006] = "\x21\x41", [0x0007] = "\x21\x44",
@@ -3709,7 +3709,7 @@ const char cns11643l1_from_ucs4_tab13[][2] =
printf ("\n");
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
-const char cns11643l1_from_ucs4_tab14[][2] =
+const char __cns11643l1_from_ucs4_tab14[][2] =
{
[0x0000] = "\x21\x2a", [0x0002] = "\x21\x6c", [0x0003] = "\x22\x63",
[0x0004] = "\x22\x68", [0x0005] = "\x21\x6d", [0x0007] = "\x21\x3e",
diff --git a/iconvdata/cns11643l1.h b/iconvdata/cns11643l1.h
index 4f9d08513d..aa78c26d6c 100644
--- a/iconvdata/cns11643l1.h
+++ b/iconvdata/cns11643l1.h
@@ -19,9 +19,10 @@
Boston, MA 02111-1307, USA. */
#include <stdint.h>
+#include <gconv.h>
/* Table for CNS 11643, plane 1 to UCS4 conversion. */
-extern const uint16_t cns11643l1_to_ucs4_tab[];
+extern const uint16_t __cns11643l1_to_ucs4_tab[];
static inline wchar_t
@@ -47,25 +48,25 @@ cns11643l1_to_ucs4 (const char **s, size_t avail, unsigned char offset)
(*s) += 2;
- return cns11643l1_to_ucs4_tab[idx] ?: ((*s) -= 2, UNKNOWN_10646_CHAR);
+ return __cns11643l1_to_ucs4_tab[idx] ?: ((*s) -= 2, UNKNOWN_10646_CHAR);
}
/* Tables for the UCS4 -> CNS conversion. */
-extern const char cns11643l1_from_ucs4_tab1[][2];
-extern const char cns11643l1_from_ucs4_tab2[][2];
-extern const char cns11643l1_from_ucs4_tab3[][2];
-extern const char cns11643l1_from_ucs4_tab4[][2];
-extern const char cns11643l1_from_ucs4_tab5[][2];
-extern const char cns11643l1_from_ucs4_tab6[][2];
-extern const char cns11643l1_from_ucs4_tab7[][2];
-extern const char cns11643l1_from_ucs4_tab8[][2];
-extern const char cns11643l1_from_ucs4_tab9[][2];
-extern const char cns11643l1_from_ucs4_tab10[][2];
-extern const char cns11643l1_from_ucs4_tab11[][2];
-extern const char cns11643l1_from_ucs4_tab12[][2];
-extern const char cns11643l1_from_ucs4_tab13[][2];
-extern const char cns11643l1_from_ucs4_tab14[][2];
+extern const char __cns11643l1_from_ucs4_tab1[][2];
+extern const char __cns11643l1_from_ucs4_tab2[][2];
+extern const char __cns11643l1_from_ucs4_tab3[][2];
+extern const char __cns11643l1_from_ucs4_tab4[][2];
+extern const char __cns11643l1_from_ucs4_tab5[][2];
+extern const char __cns11643l1_from_ucs4_tab6[][2];
+extern const char __cns11643l1_from_ucs4_tab7[][2];
+extern const char __cns11643l1_from_ucs4_tab8[][2];
+extern const char __cns11643l1_from_ucs4_tab9[][2];
+extern const char __cns11643l1_from_ucs4_tab10[][2];
+extern const char __cns11643l1_from_ucs4_tab11[][2];
+extern const char __cns11643l1_from_ucs4_tab12[][2];
+extern const char __cns11643l1_from_ucs4_tab13[][2];
+extern const char __cns11643l1_from_ucs4_tab14[][2];
static inline size_t
@@ -73,110 +74,95 @@ ucs4_to_cns11643l1 (wchar_t wch, char *s, size_t avail)
{
unsigned int ch = (unsigned int) wch;
char buf[2];
- const char *cp = NULL;
-
- if (ch < 0xa7)
- cp = "";
- else if (ch < 0xf7)
- cp = cns11643l1_from_ucs4_tab1[ch - 0xa7];
- else if (ch < 0x2c7)
- cp = "";
- else if (ch <= 0x2d9)
- cp = cns11643l1_from_ucs4_tab2[ch - 0x2c7];
- else if (ch < 0x391)
- cp = "";
- else if (ch <= 0x3c9)
- cp = cns11643l1_from_ucs4_tab3[ch - 0x391];
- else if (ch < 0x2013)
- cp = "";
- else if (ch <= 0x203e)
- cp = cns11643l1_from_ucs4_tab4[ch - 0x2013];
- else if (ch == 0x2103)
- cp = "\x22\x6a";
- else if (ch == 0x2105)
- cp = "\x22\x22";
- else if (ch == 0x2109)
- cp = "\x22\x6b";
- else if (ch < 0x2160)
- cp = "";
- else if (ch <= 0x2169)
+ const char *cp = buf;
+
+ switch (ch)
{
+ case 0xa7 ... 0xf7:
+ cp = __cns11643l1_from_ucs4_tab1[ch - 0xa7];
+ break;
+ case 0x2c7 ... 0x2d9:
+ cp = __cns11643l1_from_ucs4_tab2[ch - 0x2c7];
+ break;
+ case 0x391 ... 0x3c9:
+ cp = __cns11643l1_from_ucs4_tab3[ch - 0x391];
+ case 0x2013 ... 0x203e:
+ cp = __cns11643l1_from_ucs4_tab4[ch - 0x2013];
+ case 0x2103:
+ cp = "\x22\x6a";
+ break;
+ case 0x2105:
+ cp = "\x22\x22";
+ break;
+ case 0x2109:
+ cp = "\x22\x6b";
+ break;
+ case 0x2160 ... 0x2169:
buf[0] = '\x24';
buf[1] = '\x2b' + (ch - 0x2160);
- cp = buf;
- }
- else if (ch < 0x2170)
- cp = "";
- else if (ch <= 0x2179)
- {
+ break;
+ case 0x2170 ... 0x2179:
buf[0] = '\x26';
buf[1] = '\x35' + (ch - 0x2170);
- cp = buf;
- }
- else if (ch < 0x2190)
- cp = "";
- else if (ch <= 0x2199)
- cp = cns11643l1_from_ucs4_tab5[ch - 0x2190];
- else if (ch < 0x2215)
- cp = "";
- else if (ch <= 0x2267)
- cp = cns11643l1_from_ucs4_tab6[ch - 0x2215];
- else if (ch == 0x22a5)
- cp = "\x22\x47";
- else if (ch == 0x22bf)
- cp = "\x22\x4a";
- else if (ch < 0x2400)
- cp = "";
- else if (ch <= 0x2421)
- cp = cns11643l1_from_ucs4_tab7[ch - 0x2400];
- else if (ch < 0x2460)
- cp = "";
- else if (ch <= 0x247d)
- cp = cns11643l1_from_ucs4_tab8[ch - 0x2460];
- else if (ch < 0x2500)
- cp = "";
- else if (ch <= 0x2642)
- cp = cns11643l1_from_ucs4_tab9[ch - 0x2500];
- else if (ch < 0x3000)
- cp = "";
- else if (ch <= 0x3029)
- cp = cns11643l1_from_ucs4_tab10[ch - 0x3000];
- else if (ch == 0x30fb)
- cp = "\x21\x26";
- else if (ch < 0x3105)
- cp = "";
- else if (ch <= 0x3129)
- {
+ break;
+ case 0x2190 ...0x2199:
+ cp = __cns11643l1_from_ucs4_tab5[ch - 0x2190];
+ break;
+ case 0x2215 ... 0x2267:
+ cp = __cns11643l1_from_ucs4_tab6[ch - 0x2215];
+ break;
+ case 0x22a5:
+ cp = "\x22\x47";
+ break;
+ case 0x22bf:
+ cp = "\x22\x4a";
+ break;
+ case 0x2400 ... 0x2421:
+ cp = __cns11643l1_from_ucs4_tab7[ch - 0x2400];
+ break;
+ case 0x2460 ... 0x247d:
+ cp = __cns11643l1_from_ucs4_tab8[ch - 0x2460];
+ break;
+ case 0x2500 ... 0x2642:
+ cp = __cns11643l1_from_ucs4_tab9[ch - 0x2500];
+ break;
+ case 0x3000 ... 0x3029:
+ cp = __cns11643l1_from_ucs4_tab10[ch - 0x3000];
+ break;
+ case 0x30fb:
+ cp = "\x21\x26";
+ break;
+ case 0x3105 ... 0x3129:
buf[0] = '\x25';
buf[1] = '\x26' + (ch - 0x3105);
- cp = buf;
+ break;
+ case 0x32a3:
+ cp = "\x22\x21";
+ break;
+ case 0x338e ... 0x33d5:
+ cp = __cns11643l1_from_ucs4_tab11[ch - 0x338e];
+ break;
+ case 0x4e00 ... 0x9f9c:
+ cp = __cns11643l1_from_ucs4_tab12[ch - 0x4e00];
+ break;
+ case 0xfe30 ... 0xfe6b:
+ cp = __cns11643l1_from_ucs4_tab13[ch - 0xfe30];
+ break;
+ case 0xff01 ... 0xff5d:
+ cp = __cns11643l1_from_ucs4_tab14[ch - 0xff01];
+ break;
+ case 0xffe0:
+ cp = "\x22\x66";
+ break;
+ case 0xffe1:
+ cp = "\x22\x67";
+ break;
+ case 0xffe5:
+ cp = "\x22\x64";
+ break;
+ default:
+ buf[0] = '\0';
}
- else if (ch == 0x32a3)
- cp = "\x22\x21";
- else if (ch < 0x338e)
- cp = "";
- else if (ch <= 0x33d5)
- cp = cns11643l1_from_ucs4_tab11[ch - 0x338e];
- else if (ch < 0x4e00)
- cp = "";
- else if (ch <= 0x9f9c)
- cp = cns11643l1_from_ucs4_tab12[ch - 0x4e00];
- else if (ch < 0xfe30)
- cp = "";
- else if (ch <= 0xfe6b)
- cp = cns11643l1_from_ucs4_tab13[ch - 0xfe30];
- else if (ch < 0xff01)
- cp = "";
- else if (ch <= 0xff5d)
- cp = cns11643l1_from_ucs4_tab14[ch - 0xff01];
- else if (ch == 0xffe0)
- cp = "\x22\x66";
- else if (ch == 0xffe1)
- cp = "\x22\x67";
- else if (ch == 0xffe5)
- cp = "\x22\x64";
- else
- cp = "";
if (cp[0] == '\0')
return UNKNOWN_10646_CHAR;
diff --git a/iconvdata/ebcdic-at-de-a.c b/iconvdata/ebcdic-at-de-a.c
index 7251490ae7..654bdf87fd 100644
--- a/iconvdata/ebcdic-at-de-a.c
+++ b/iconvdata/ebcdic-at-de-a.c
@@ -1,5 +1,5 @@
/* Conversion from and to EBCDIC-AT-DE-A.
- Copyright (C) 1997 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@@ -18,7 +18,12 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#include <wchar.h>
+#include <stdint.h>
+
+/* Get the conversion table. */
#include <ebcdic-at-de-a.h>
-#define NAME "EBCDIC-AT-DE-A"
+
+#define CHARSET_NAME "EBCDIC-AT-DE-A"
+#define HAS_HOLES 1 /* Not all 256 character are defined. */
+
#include <8bit-generic.c>
diff --git a/iconvdata/ebcdic-at-de.c b/iconvdata/ebcdic-at-de.c
index d9168fcc1d..ab718851d9 100644
--- a/iconvdata/ebcdic-at-de.c
+++ b/iconvdata/ebcdic-at-de.c
@@ -1,5 +1,5 @@
/* Conversion from and to EBCDIC-AT-DE.
- Copyright (C) 1997 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@@ -18,7 +18,12 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#include <wchar.h>
+#include <stdint.h>
+
+/* Get the conversion table. */
#include <ebcdic-at-de.h>
-#define NAME "EBCDIC-AT-DE"
+
+#define CHARSET_NAME "EBCDIC-AT-DE"
+#define HAS_HOLES 1 /* Not all 256 character are defined. */
+
#include <8bit-generic.c>
diff --git a/iconvdata/ebcdic-ca-fr.c b/iconvdata/ebcdic-ca-fr.c
index a42914e50e..91cf5aa388 100644
--- a/iconvdata/ebcdic-ca-fr.c
+++ b/iconvdata/ebcdic-ca-fr.c
@@ -1,5 +1,5 @@
/* Conversion from and to EBCDIC-CA-FR.
- Copyright (C) 1997 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@@ -18,7 +18,12 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#include <wchar.h>
+#include <stdint.h>
+
+/* Get the conversion table. */
#include <ebcdic-ca-fr.h>
-#define NAME "EBCDIC-CA-FR"
+
+#define CHARSET_NAME "EBCDIC-CA-FR"
+#define HAS_HOLES 1 /* Not all 256 character are defined. */
+
#include <8bit-generic.c>
diff --git a/iconvdata/euccn.c b/iconvdata/euccn.c
index f683836ff7..90e82cb41e 100644
--- a/iconvdata/euccn.c
+++ b/iconvdata/euccn.c
@@ -18,262 +18,124 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#include <gconv.h>
-#include <stdint.h>
-#include <string.h>
-#include <wchar.h>
#include <gb2312.h>
+#include <stdint.h>
-/* Direction of the transformation. */
-static int to_euccn_object;
-static int from_euccn_object;
-
-
-int
-gconv_init (struct gconv_step *step)
-{
- /* Determine which direction. */
- if (strcasestr (step->from_name, "EUC-CN") != NULL)
- step->data = &from_euccn_object;
- else if (strcasestr (step->to_name, "EUC-CN") != NULL)
- step->data = &to_euccn_object;
- else
- return GCONV_NOCONV;
-
- return GCONV_OK;
-}
-
-
-void
-gconv_end (struct gconv_step *data)
-{
- /* Nothing to do. */
-}
-
-
-int
-gconv (struct gconv_step *step, struct gconv_step_data *data,
- const char *inbuf, size_t *inbufsize, 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;
- 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)
- {
- do_write = 0;
-
- /* 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
- {
- do_write = 0;
-
- do
- {
- result = GCONV_OK;
-
- if (step->data == &from_euccn_object)
- {
- size_t inchars = *inbufsize;
- size_t outwchars = data->outbufavail;
- char *outbuf = data->outbuf;
- size_t cnt = 0;
-
- while (cnt < inchars
- && (outwchars + sizeof (wchar_t) <= data->outbufsize))
- {
- int inchar = (unsigned char) inbuf[cnt];
- wchar_t ch;
-
- if (inchar <= 0x7f)
- ch = (wchar_t) inchar;
- else if ((inchar <= 0xa0 || inchar > 0xfe)
- && inchar != 0x8e && inchar != 0x8f)
- /* This is illegal. */
- ch = L'\0';
- else
- {
- /* Two or more byte character. First test whether the
- next character is also available. */
- const char *endp;
- int inchar2;
-
- if (cnt + 1 >= inchars)
- {
- /* The second character is not available. Store
- the intermediate result. */
- result = GCONV_INCOMPLETE_INPUT;
- break;
- }
-
- inchar2 = (unsigned char) inbuf[++cnt];
-
- /* All second bytes of a multibyte character must be
- >= 0xa1. */
- if (inchar2 < 0xa1)
- {
- /* This is an illegal character. */
- --cnt;
- result = GCONV_ILLEGAL_INPUT;
- break;
- }
-
- /* This is code set 1: GB 2312-80. */
- endp = &inbuf[cnt - 1];
-
- ch = gb2312_to_ucs4 (&endp, 2, 0x80);
- if (ch != L'\0')
- ++cnt;
-
- if (ch == UNKNOWN_10646_CHAR)
- ch = L'\0';
-
- if (ch == L'\0')
- --cnt;
- }
-
- if (ch == L'\0' && inbuf[cnt] != '\0')
- {
- /* This is an illegal character. */
- result = GCONV_ILLEGAL_INPUT;
- break;
- }
-
- *((wchar_t *) (outbuf + outwchars)) = ch;
- ++do_write;
- outwchars += sizeof (wchar_t);
- ++cnt;
- }
- *inbufsize -= cnt;
- inbuf += cnt;
- data->outbufavail = outwchars;
- }
- else
- {
- size_t inwchars = *inbufsize;
- size_t outchars = data->outbufavail;
- char *outbuf = data->outbuf;
- size_t cnt = 0;
- int extra = 0;
-
- while (inwchars >= cnt + sizeof (wchar_t)
- && outchars < data->outbufsize)
- {
- wchar_t ch = *((wchar_t *) (inbuf + cnt));
-
- if (ch <= L'\x7f')
- /* It's plain ASCII. */
- outbuf[outchars] = ch;
- else
- {
- /* Try the JIS character sets. */
- size_t found;
-
- found = ucs4_to_gb2312 (ch, &outbuf[outchars],
- (data->outbufsize
- - outchars));
- if (found > 0)
- {
- /* It's a GB 2312 character, adjust it for
- EUC-CN. */
- outbuf[outchars++] += 0x80;
- outbuf[outchars] += 0x80;
- }
- else if (found == 0)
- {
- /* We ran out of space. */
- extra = 2;
- break;
- }
- else
- /* Illegal character. */
- break;
- }
-
- ++do_write;
- ++outchars;
- cnt += sizeof (wchar_t);
- }
- *inbufsize -= cnt;
- inbuf += cnt;
- data->outbufavail = outchars;
-
- if (outchars + extra < data->outbufsize)
- {
- /* If there is still room in the output buffer something
- is wrong with the input. */
- if (inwchars >= cnt + sizeof (wchar_t))
- {
- /* An error occurred. */
- result = GCONV_ILLEGAL_INPUT;
- break;
- }
- if (inwchars != cnt)
- {
- /* There are some unprocessed bytes at the end of the
- input buffer. */
- result = GCONV_INCOMPLETE_INPUT;
- break;
- }
- }
- }
-
- if (result != GCONV_OK)
- break;
-
- if (data->is_last)
- {
- /* This is the last step. */
- result = (*inbufsize > (step->data == &from_euccn_object
- ? 0 : sizeof (wchar_t) - 1)
- ? GCONV_FULL_OUTPUT : GCONV_EMPTY_INPUT);
- 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 (*inbufsize > 0 && result == GCONV_EMPTY_INPUT);
- }
-
- if (written != NULL && data->is_last)
- *written = do_write;
-
- return result;
-}
+/* Definitions used in the body of the `gconv' function. */
+#define CHARSET_NAME "EUC-CN"
+#define FROM_LOOP from_euc_cn
+#define TO_LOOP to_euc_cn
+#define DEFINE_INIT 1
+#define DEFINE_FINI 1
+#define MIN_NEEDED_FROM 1
+#define MAX_NEEDED_FROM 2
+#define MIN_NEEDED_TO 4
+
+
+/* First define the conversion function from ISO 8859-1 to UCS4. */
+#define MIN_NEEDED_INPUT MIN_NEEDED_FROM
+#define MAX_NEEDED_INPUT MAX_NEEDED_FROM
+#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
+#define LOOPFCT FROM_LOOP
+#define BODY \
+ { \
+ uint32_t ch = *inptr; \
+ \
+ if (ch <= 0x7f) \
+ ++inptr; \
+ else \
+ if ((ch <= 0xa0 || ch > 0xfe) && ch != 0x8e && ch != 0x8f) \
+ { \
+ /* This is illegal. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ else \
+ { \
+ /* Two or more byte character. First test whether the \
+ next character is also available. */ \
+ const char *endp; \
+ \
+ if (NEED_LENGTH_TEST && inptr + 1 >= inend) \
+ { \
+ /* The second character is not available. Store \
+ the intermediate result. */ \
+ result = GCONV_INCOMPLETE_INPUT; \
+ break; \
+ } \
+ \
+ ch = inptr[1]; \
+ \
+ /* All second bytes of a multibyte character must be >= 0xa1. */ \
+ if (ch < 0xa1) \
+ { \
+ /* This is an illegal character. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ \
+ /* This is code set 1: GB 2312-80. */ \
+ endp = inptr; \
+ \
+ ch = gb2312_to_ucs4 (&endp, 2, 0x80); \
+ if (ch == UNKNOWN_10646_CHAR) \
+ { \
+ /* This is an illegal character. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ \
+ inptr += 2; \
+ } \
+ \
+ *((uint32_t *) outptr)++ = ch; \
+ }
+#include <iconv/loop.c>
+
+
+/* Next, define the other direction. */
+#define MIN_NEEDED_INPUT MIN_NEEDED_TO
+#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM
+#define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM
+#define LOOPFCT TO_LOOP
+#define BODY \
+ { \
+ uint32_t ch = *((uint32_t *) inptr); \
+ \
+ if (ch <= L'\x7f') \
+ /* It's plain ASCII. */ \
+ *outptr++ = (unsigned char) ch; \
+ else \
+ { \
+ size_t found; \
+ \
+ found = ucs4_to_gb2312 (ch, outptr, \
+ (NEED_LENGTH_TEST \
+ ? outend - outptr : MAX_NEEDED_OUTPUT)); \
+ if (!NEED_LENGTH_TEST || found != 0) \
+ { \
+ if (found == UNKNOWN_10646_CHAR) \
+ { \
+ /* Illegal character. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ \
+ /* It's a GB 2312 character, adjust it for EUC-CN. */ \
+ *outptr++ += 0x80; \
+ *outptr++ += 0x80; \
+ } \
+ else \
+ { \
+ /* We ran out of space. */ \
+ result = GCONV_FULL_OUTPUT; \
+ break; \
+ } \
+ } \
+ inptr += 4; \
+ }
+#include <iconv/loop.c>
+
+
+/* Now define the toplevel functions. */
+#include <iconv/skeleton.c>
diff --git a/iconvdata/eucjp.c b/iconvdata/eucjp.c
index e6a71cc791..24ebed94ec 100644
--- a/iconvdata/eucjp.c
+++ b/iconvdata/eucjp.c
@@ -18,306 +18,190 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#include <gconv.h>
#include <stdint.h>
-#include <string.h>
-#include <wchar.h>
+#include <gconv.h>
#include <jis0201.h>
#include <jis0208.h>
#include <jis0212.h>
-/* Direction of the transformation. */
-static int to_eucjp_object;
-static int from_eucjp_object;
-
-
-int
-gconv_init (struct gconv_step *step)
-{
- /* Determine which direction. */
- if (strcasestr (step->from_name, "EUC-JP") != NULL)
- step->data = &from_eucjp_object;
- else if (strcasestr (step->to_name, "EUC-JP") != NULL)
- step->data = &to_eucjp_object;
- else
- return GCONV_NOCONV;
-
- return GCONV_OK;
-}
-
-
-void
-gconv_end (struct gconv_step *data)
-{
- /* Nothing to do. */
-}
-
-
-int
-gconv (struct gconv_step *step, struct gconv_step_data *data,
- const char *inbuf, size_t *inbufsize, 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;
- 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)
- {
- do_write = 0;
-
- /* 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
- {
- do_write = 0;
-
- do
- {
- result = GCONV_OK;
-
- if (step->data == &from_eucjp_object)
- {
- size_t inchars = *inbufsize;
- size_t outwchars = data->outbufavail;
- char *outbuf = data->outbuf;
- size_t cnt = 0;
-
- while (cnt < inchars
- && (outwchars + sizeof (wchar_t) <= data->outbufsize))
- {
- int inchar = (unsigned char) inbuf[cnt];
- wchar_t ch;
-
- if (inchar <= 0x7f)
- ch = (wchar_t) inchar;
- else if ((inchar <= 0xa0 || inchar > 0xfe)
- && inchar != 0x8e && inchar != 0x8f)
- /* This is illegal. */
- ch = L'\0';
- else
- {
- /* Two or more byte character. First test whether the
- next character is also available. */
- int inchar2;
-
- if (cnt + 1 >= inchars)
- {
- /* The second character is not available. Store
- the intermediate result. */
- result = GCONV_INCOMPLETE_INPUT;
- break;
- }
-
- inchar2 = (unsigned char) inbuf[++cnt];
-
- /* All second bytes of a multibyte character must be
- >= 0xa1. */
- if (inchar2 < 0xa1)
- {
- /* This is an illegal character. */
- --cnt;
- result = GCONV_ILLEGAL_INPUT;
- break;
- }
-
- if (inchar == '\x8e')
- /* This is code set 2: half-width katakana. */
- ch = jisx0201_to_ucs4 (inchar2);
- else if (inchar == '\x8f')
- {
- /* This is code set 3: JIS X 0212-1990. */
- const char *endp = &inbuf[cnt];
-
- ch = jisx0212_to_ucs4 (&endp, 1 + inchars - cnt,
- 0x80);
- cnt = endp - inbuf;
- }
- else
- {
- /* This is code set 1: JIS X 0208. */
- const char *endp = &inbuf[cnt - 1];
-
- ch = jisx0208_to_ucs4 (&endp, 2 + inchars - cnt,
- 0x80);
- if (ch != L'\0')
- ++cnt;
- }
-
- if (ch == UNKNOWN_10646_CHAR)
- ch = L'\0';
-
- if (ch == L'\0')
- --cnt;
- }
-
- if (ch == L'\0' && inbuf[cnt] != '\0')
- {
- /* This is an illegal character. */
- result = GCONV_ILLEGAL_INPUT;
- break;
- }
-
- *((wchar_t *) (outbuf + outwchars)) = ch;
- ++do_write;
- outwchars += sizeof (wchar_t);
- ++cnt;
- }
- *inbufsize -= cnt;
- inbuf += cnt;
- data->outbufavail = outwchars;
- }
- else
- {
- size_t inwchars = *inbufsize;
- size_t outchars = data->outbufavail;
- char *outbuf = data->outbuf;
- size_t cnt = 0;
- int extra = 0;
-
- while (inwchars >= cnt + sizeof (wchar_t)
- && outchars < data->outbufsize)
- {
- wchar_t ch = *((wchar_t *) (inbuf + cnt));
-
- if (ch <= L'\x7f')
- /* It's plain ASCII. */
- outbuf[outchars] = ch;
- else
- {
- /* Try the JIS character sets. */
- size_t found;
-
- found = ucs4_to_jisx0201 (ch, &outbuf[outchars]);
-
- if (found == UNKNOWN_10646_CHAR)
- {
- /* No JIS 0201 character. */
- found = ucs4_to_jisx0208 (ch, &outbuf[outchars],
- (data->outbufsize
- - outchars));
- if (found == 0)
- {
- /* We ran out of space. */
- extra = 2;
- break;
- }
- else if (found != UNKNOWN_10646_CHAR)
- {
- /* It's a JIS 0208 character, adjust it for
- EUC-JP. */
- outbuf[outchars++] += 0x80;
- outbuf[outchars] += 0x80;
- }
- else
- {
- /* No JIS 0208 character. */
- found = ucs4_to_jisx0212 (ch, &outbuf[outchars],
- (data->outbufsize
- - outchars));
-
- if (found == 0)
- {
- /* We ran out of space. */
- extra = 2;
- break;
- }
- else if (found != UNKNOWN_10646_CHAR)
- {
- /* It's a JIS 0212 character, adjust it for
- EUC-JP. */
- outbuf[outchars++] += 0x80;
- outbuf[outchars] += 0x80;
- }
- else
- /* Illegal character. */
- break;
- }
- }
- }
-
- ++do_write;
- ++outchars;
- cnt += sizeof (wchar_t);
- }
- *inbufsize -= cnt;
- inbuf += cnt;
- data->outbufavail = outchars;
-
- if (outchars + extra < data->outbufsize)
- {
- /* If there is still room in the output buffer something
- is wrong with the input. */
- if (inwchars >= cnt + sizeof (wchar_t))
- {
- /* An error occurred. */
- result = GCONV_ILLEGAL_INPUT;
- break;
- }
- if (inwchars != cnt)
- {
- /* There are some unprocessed bytes at the end of the
- input buffer. */
- result = GCONV_INCOMPLETE_INPUT;
- break;
- }
- }
- }
-
- if (result != GCONV_OK)
- break;
-
- if (data->is_last)
- {
- /* This is the last step. */
- result = (*inbufsize > (step->data == &from_eucjp_object
- ? 0 : sizeof (wchar_t) - 1)
- ? GCONV_FULL_OUTPUT : GCONV_EMPTY_INPUT);
- 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 (*inbufsize > 0 && result == GCONV_EMPTY_INPUT);
- }
-
- if (written != NULL && data->is_last)
- *written = do_write;
-
- return result;
-}
+/* Definitions used in the body of the `gconv' function. */
+#define CHARSET_NAME "EUC-JP"
+#define FROM_LOOP from_euc_jp
+#define TO_LOOP to_euc_jp
+#define DEFINE_INIT 1
+#define DEFINE_FINI 1
+#define MIN_NEEDED_FROM 1
+#define MAX_NEEDED_FROM 3
+#define MIN_NEEDED_TO 4
+
+
+/* First define the conversion function from EUC-JP to UCS4. */
+#define MIN_NEEDED_INPUT MIN_NEEDED_FROM
+#define MAX_NEEDED_INPUT MAX_NEEDED_FROM
+#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
+#define LOOPFCT FROM_LOOP
+#define BODY \
+ { \
+ uint32_t ch = *inptr; \
+ \
+ if (ch <= 0x7f) \
+ ++inptr; \
+ else if ((ch <= 0xa0 || ch > 0xfe) && ch != 0x8e && ch != 0x8f) \
+ { \
+ /* This is illegal. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ else \
+ { \
+ /* Two or more byte character. First test whether the next \
+ character is also available. */ \
+ int ch2; \
+ \
+ if (NEED_LENGTH_TEST && inptr + 1 >= inend) \
+ { \
+ /* The second character is not available. Store the \
+ intermediate result. */ \
+ result = GCONV_INCOMPLETE_INPUT; \
+ break; \
+ } \
+ \
+ ch2 = inptr[1]; \
+ \
+ /* All second bytes of a multibyte character must be >= 0xa1. */ \
+ if (ch2 < 0xa1) \
+ { \
+ /* This is an illegal character. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ \
+ if (ch == 0x8e) \
+ { \
+ /* This is code set 2: half-width katakana. */ \
+ ch = jisx0201_to_ucs4 (ch2); \
+ inptr += 2; \
+ } \
+ else \
+ { \
+ const unsigned char *endp; \
+ \
+ if (ch == 0x8f) \
+ { \
+ /* This is code set 3: JIS X 0212-1990. */ \
+ endp = inptr + 1; \
+ \
+ ch = jisx0212_to_ucs4 (&endp, \
+ NEED_LENGTH_TEST ? inend - endp : 2, \
+ 0x80); \
+ } \
+ else \
+ { \
+ /* This is code set 1: JIS X 0208. */ \
+ endp = inptr; \
+ \
+ ch = jisx0208_to_ucs4 (&endp, \
+ NEED_LENGTH_TEST ? inend - inptr : 2, \
+ 0x80); \
+ } \
+ \
+ if (NEED_LENGTH_TEST && ch == 0) \
+ { \
+ /* Not enough input available. */ \
+ result = GCONV_INCOMPLETE_INPUT; \
+ break; \
+ } \
+ if (ch == UNKNOWN_10646_CHAR) \
+ { \
+ /* Illegal character. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ inptr = endp; \
+ } \
+ } \
+ \
+ *((uint32_t *) outptr)++ = ch; \
+ }
+#include <iconv/loop.c>
+
+
+/* Next, define the other direction. */
+#define MIN_NEEDED_INPUT MIN_NEEDED_TO
+#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM
+#define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM
+#define LOOPFCT TO_LOOP
+#define BODY \
+ { \
+ uint32_t ch = *((uint32_t *) inptr); \
+ \
+ if (ch <= 0x7f) \
+ /* It's plain ASCII. */ \
+ *outptr++ = ch; \
+ else \
+ { \
+ /* Try the JIS character sets. */ \
+ size_t found; \
+ \
+ /* See whether we have room for at least two characters. */ \
+ if (NEED_LENGTH_TEST && outptr + 1 >= outend) \
+ { \
+ result = GCONV_FULL_OUTPUT; \
+ break; \
+ } \
+ \
+ found = ucs4_to_jisx0201 (ch, outptr + 1); \
+ if (found != UNKNOWN_10646_CHAR) \
+ { \
+ /* Yes, it's a JIS 0201 character. Store the shift byte. */ \
+ *outptr = 0x8e; \
+ outptr += 2; \
+ } \
+ else \
+ { \
+ /* No JIS 0201 character. */ \
+ found = ucs4_to_jisx0208 (ch, outptr, 2); \
+ /* Please note that we always have enough room for the output. */ \
+ if (found != UNKNOWN_10646_CHAR) \
+ { \
+ /* It's a JIS 0208 character, adjust it for EUC-JP. */ \
+ *outptr++ += 0x80; \
+ *outptr++ += 0x80; \
+ } \
+ else \
+ { \
+ /* No JIS 0208 character. */ \
+ found = ucs4_to_jisx0212 (ch, outptr + 1, \
+ (NEED_LENGTH_TEST \
+ ? outend - outptr - 1 : 2)); \
+ \
+ if (found == 0) \
+ { \
+ /* We ran out of space. */ \
+ result = GCONV_FULL_OUTPUT; \
+ break; \
+ } \
+ else if (found != UNKNOWN_10646_CHAR) \
+ { \
+ /* It's a JIS 0212 character, adjust it for EUC-JP. */ \
+ *outptr++ = 0x8f; \
+ *outptr++ += 0x80; \
+ *outptr++ += 0x80; \
+ } \
+ else \
+ { \
+ /* Illegal character. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ } \
+ } \
+ } \
+ \
+ inptr += 4; \
+ }
+#include <iconv/loop.c>
+
+
+/* Now define the toplevel functions. */
+#include <iconv/skeleton.c>
diff --git a/iconvdata/euckr.c b/iconvdata/euckr.c
index 2ad9478729..50e4b40838 100644
--- a/iconvdata/euckr.c
+++ b/iconvdata/euckr.c
@@ -1,7 +1,8 @@
/* Mapping tables for EUC-KR handling.
Copyright (C) 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
- Contributed by Jungshik Shin <jshin@pantheon.yale.edu>, 1998.
+ Contributed by Jungshik Shin <jshin@pantheon.yale.edu>
+ and Ulrich Drepper <drepper@cygnus.com>, 1998.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
@@ -18,276 +19,142 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#include <gconv.h>
#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <wchar.h>
#include <ksc5601.h>
-/* Direction of the transformation. */
-static int to_euckr_object;
-static int from_euckr_object;
-
static inline void
-euckr_from_ucs4(wchar_t ch, unsigned char *cp)
+euckr_from_ucs4 (uint32_t ch, unsigned char *cp)
{
if (ch > 0x7f)
{
- uint16_t idx=0;
+ uint16_t idx = 0;
if (ucs4_to_ksc5601 (ch, &idx))
idx |= 0x8080;
- *cp = (unsigned char) (idx/256);
- *(cp+1) = (unsigned char) (idx & 0xff) ;
+ cp[0] = (unsigned char) (idx / 256);
+ cp[1] = (unsigned char) (idx & 0xff);
}
- /* think about 0x5c ; '\' */
+ /* XXX Think about 0x5c ; '\'. */
else
{
- *cp = (unsigned char) (0x7f & ch) ;
- *(cp+1) = (unsigned char) 0;
+ cp[0] = (unsigned char) ch;
+ cp[1] = '\0';
}
}
-int
-gconv_init (struct gconv_step *step)
-{
- /* Determine which direction. */
- if (strcasestr (step->from_name, "EUC-KR") != NULL)
- step->data = &from_euckr_object;
- else if (strcasestr (step->to_name, "EUC-KR") != NULL)
- step->data = &to_euckr_object;
- else
- return GCONV_NOCONV;
-
- return GCONV_OK;
-}
-
-
-void
-gconv_end (struct gconv_step *data)
-{
- /* Nothing to do. */
-}
-
-
-int
-gconv (struct gconv_step *step, struct gconv_step_data *data,
- const char *inbuf, size_t *inbufsize, 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;
- 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)
- {
- do_write = 0;
-
- /* 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
- {
- do_write = 0;
-
- do
- {
- result = GCONV_OK;
-
- if (step->data == &from_euckr_object)
- {
- size_t inchars = *inbufsize;
- size_t outwchars = data->outbufavail;
- char *outbuf = data->outbuf;
- size_t cnt = 0;
-
- while (cnt < inchars
- && (outwchars + sizeof (wchar_t) <= data->outbufsize))
- {
- int inchar = (unsigned char) inbuf[cnt];
- wchar_t ch;
-
- /*
- half-width Korean Currency WON sign
-
- if (inchar == 0x5c)
- ch = 0x20a9;
- else if (inchar <= 0x7f)
- ch = (wchar_t) inchar;
- */
-
- if (inchar <= 0x7f)
- ch = (wchar_t) inchar;
-
-
-/* 0xfe(->0x7e : row 94) and 0xc9(->0x59 : row 41) are user-defined areas */
-
- else if ( inchar <= 0xa0 || inchar > 0xfe || inchar == 0xc9)
- /* This is illegal. */
- ch = L'\0';
- else
- {
- /* Two-byte character. First test whether the next
- character is also available. */
- int inchar2;
-
- if (cnt + 1 >= inchars)
- {
- /* The second character is not available. Store
- the intermediate result. */
- result = GCONV_INCOMPLETE_INPUT;
- break;
- }
-
- inchar2 = (unsigned char) inbuf[++cnt];
-
- ch = ksc5601_to_ucs4 ((uint16_t) (inchar * 256 + inchar2)
- & 0x7f7f);
- if (ch == UNKNOWN_10646_CHAR)
- ch = L'\0';
-
- if (ch == L'\0')
- --cnt;
- }
-
- if (ch == L'\0' && inbuf[cnt] != '\0')
- {
- /* This is an illegal character. */
- result = GCONV_ILLEGAL_INPUT;
- break;
- }
-
- *((wchar_t *) (outbuf + outwchars)) = ch;
- ++do_write;
- outwchars += sizeof (wchar_t);
- ++cnt;
- }
- *inbufsize -= cnt;
- inbuf += cnt;
- data->outbufavail = outwchars;
- }
- else
- {
- size_t inwchars = *inbufsize;
- size_t outchars = data->outbufavail;
- char *outbuf = data->outbuf;
- size_t cnt = 0;
- int extra = 0;
-
- while (inwchars >= cnt + sizeof (wchar_t)
- && outchars < data->outbufsize)
- {
- wchar_t ch = *((wchar_t *) (inbuf + cnt));
- unsigned char cp[2];
-
-/* decomposing Hangul syllables not available in KS C 5601 into Jamos
- should be considered either here or in euckr_from_ucs4() */
-
- euckr_from_ucs4(ch,cp) ;
-
- if (cp[0] == '\0' && ch != 0)
- /* Illegal character. */
- break;
-
- outbuf[outchars] = cp[0];
- /* Now test for a possible second byte and write this
- if possible. */
- if (cp[1] != '\0')
- {
- if (outchars + 1 >= data->outbufsize)
- {
- /* The result does not fit into the buffer. */
- extra = 1;
- break;
- }
- outbuf[++outchars] = cp[1];
- }
-
- ++do_write;
- ++outchars;
- cnt += sizeof (wchar_t);
- }
- *inbufsize -= cnt;
- inbuf += cnt;
- data->outbufavail = outchars;
-
- if (outchars + extra < data->outbufsize)
- {
- /* If there is still room in the output buffer something
- is wrong with the input. */
- if (inwchars >= cnt + sizeof (wchar_t))
- {
- /* An error occurred. */
- result = GCONV_ILLEGAL_INPUT;
- break;
- }
- if (inwchars != cnt)
- {
- /* There are some unprocessed bytes at the end of the
- input buffer. */
- result = GCONV_INCOMPLETE_INPUT;
- break;
- }
- }
- }
-
- if (result != GCONV_OK)
- break;
-
- if (data->is_last)
- {
- /* This is the last step. */
- result = (*inbufsize > (step->data == &from_euckr_object
- ? 0 : sizeof (wchar_t) - 1)
- ? GCONV_FULL_OUTPUT : GCONV_EMPTY_INPUT);
- 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 (*inbufsize > 0 && result == GCONV_EMPTY_INPUT);
- }
-
- if (written != NULL && data->is_last)
- *written = do_write;
-
- return result;
-}
+/* Definitions used in the body of the `gconv' function. */
+#define CHARSET_NAME "EUC-KR"
+#define FROM_LOOP from_euc_kr
+#define TO_LOOP to_euc_kr
+#define DEFINE_INIT 1
+#define DEFINE_FINI 1
+#define MIN_NEEDED_FROM 1
+#define MAX_NEEDED_FROM 2
+#define MIN_NEEDED_TO 4
+
+
+/* First define the conversion function from EUC-KR to UCS4. */
+#define MIN_NEEDED_INPUT MIN_NEEDED_FROM
+#define MAX_NEEDED_INPUT MAX_NEEDED_FROM
+#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
+#define LOOPFCT FROM_LOOP
+#define BODY \
+ { \
+ uint32_t ch = *inptr; \
+ \
+ /* Half-width Korean Currency WON sign \
+ \
+ if (inchar == 0x5c) \
+ ch = 0x20a9; \
+ else if (inchar <= 0x7f) \
+ ch = (wchar_t) inchar; \
+ */ \
+ \
+ if (ch <= 0x7f) \
+ /* Plain ASCII. */ \
+ ++inptr; \
+ /* 0xfe(->0x7e : row 94) and 0xc9(->0x59 : row 41) are \
+ user-defined areas. */ \
+ else if (ch <= 0xa0 || ch > 0xfe || ch == 0xc9) \
+ { \
+ /* This is illegal. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ else \
+ { \
+ /* Two-byte character. First test whether the next character \
+ is also available. */ \
+ int ch2; \
+ \
+ if (NEED_LENGTH_TEST && inptr + 1 >= inend) \
+ { \
+ /* The second character is not available. */ \
+ result = GCONV_INCOMPLETE_INPUT; \
+ break; \
+ } \
+ \
+ ch2 = inptr[1]; \
+ \
+ if (ch2 < 0xa1 || ch2 >= 0xfe \
+ || ((ch = ksc5601_to_ucs4 ((uint16_t) (ch * 256 + ch2) & 0x7f7f)) \
+ == UNKNOWN_10646_CHAR)) \
+ { \
+ /* This is an illegal character. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ \
+ inptr += 2; \
+ } \
+ \
+ *((uint32_t *) outptr)++ = ch; \
+ }
+#include <iconv/loop.c>
+
+
+/* Next, define the other direction. */
+#define MIN_NEEDED_INPUT MIN_NEEDED_TO
+#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM
+#define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM
+#define LOOPFCT TO_LOOP
+#define BODY \
+ { \
+ uint32_t ch = *((uint32_t *) inptr); \
+ unsigned char cp[2]; \
+ \
+ /* Decomposing Hangul syllables not available in KS C 5601 into \
+ Jamos should be considered either here or in euckr_from_ucs4() */ \
+ euckr_from_ucs4 (ch, cp) ; \
+ \
+ if (cp[0] == '\0' && ch != 0) \
+ { \
+ /* Illegal character. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ \
+ *outptr++ = cp[0]; \
+ /* Now test for a possible second byte and write this if possible. */ \
+ if (cp[1] != '\0') \
+ { \
+ if (NEED_LENGTH_TEST && outptr >= outend) \
+ { \
+ /* The result does not fit into the buffer. */ \
+ --outptr; \
+ result = GCONV_FULL_OUTPUT; \
+ break; \
+ } \
+ *outptr++ = cp[1]; \
+ } \
+ \
+ inptr += 4; \
+ }
+#include <iconv/loop.c>
+
+
+/* Now define the toplevel functions. */
+#include <iconv/skeleton.c>
diff --git a/iconvdata/euctw.c b/iconvdata/euctw.c
index fd422c1fb0..406dd67f29 100644
--- a/iconvdata/euctw.c
+++ b/iconvdata/euctw.c
@@ -18,302 +18,171 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#include <gconv.h>
#include <stdint.h>
-#include <string.h>
-#include <wchar.h>
#include <cns11643l1.h>
#include <cns11643.h>
-/* Direction of the transformation. */
-static int to_euctw_object;
-static int from_euctw_object;
-
-
-int
-gconv_init (struct gconv_step *step)
-{
- /* Determine which direction. */
- if (strcasestr (step->from_name, "EUC-TW") != NULL)
- step->data = &from_euctw_object;
- else if (strcasestr (step->to_name, "EUC-TW") != NULL)
- step->data = &to_euctw_object;
- else
- return GCONV_NOCONV;
-
- return GCONV_OK;
-}
-
-
-void
-gconv_end (struct gconv_step *data)
-{
- /* Nothing to do. */
-}
-
-
-int
-gconv (struct gconv_step *step, struct gconv_step_data *data,
- const char *inbuf, size_t *inbufsize, 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;
- 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)
- {
- do_write = 0;
-
- /* 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
- {
- do_write = 0;
-
- do
- {
- result = GCONV_OK;
-
- if (step->data == &from_euctw_object)
- {
- size_t inchars = *inbufsize;
- size_t outwchars = data->outbufavail;
- char *outbuf = data->outbuf;
- size_t cnt = 0;
-
- while (cnt < inchars
- && (outwchars + sizeof (wchar_t) <= data->outbufsize))
- {
- int inchar = (unsigned char) inbuf[cnt];
- wchar_t ch;
-
- if (inchar <= 0x7f)
- ch = (wchar_t) inchar;
- else if ((inchar <= 0xa0 || inchar > 0xfe)
- && inchar != 0x8e)
- /* This is illegal. */
- ch = L'\0';
- else
- {
- /* Two or more byte character. First test whether the
- next character is also available. */
- int inchar2;
-
- if (cnt + 1 + (inchar == 0x8e ? 2 : 0) >= inchars)
- {
- /* The second character is not available. Store
- the intermediate result. */
- result = GCONV_INCOMPLETE_INPUT;
- break;
- }
-
- inchar2 = (unsigned char) inbuf[++cnt];
-
- /* All second bytes of a multibyte character must be
- >= 0xa1. */
- if (inchar2 < 0xa1 && inchar2 == 0xff)
- {
- /* This is an illegal character. */
- --cnt;
- result = GCONV_ILLEGAL_INPUT;
- break;
- }
-
- if (inchar == '\x8e')
- {
- /* This is code set 2: CNS 11643, planes 1 to 16. */
- const char *endp = &inbuf[cnt];
-
- ch = cns11643_to_ucs4 (&endp, 2 + inchars - cnt,
- 0x80);
-
- if (ch == UNKNOWN_10646_CHAR)
- ch = L'\0';
- if (ch != L'\0')
- cnt += 2;
- }
- else
- {
- /* This is code set 1: CNS 11643, plane 1. */
- const char *endp = &inbuf[cnt - 1];
-
- ch = cns11643l1_to_ucs4 (&endp, 2 + inchars - cnt,
- 0x80);
-
- if (ch == UNKNOWN_10646_CHAR)
- ch = L'\0';
- if (ch != L'\0')
- ++cnt;
- }
-
- if (ch == L'\0')
- --cnt;
- }
-
- if (ch == L'\0' && inbuf[cnt] != '\0')
- {
- /* This is an illegal character. */
- result = GCONV_ILLEGAL_INPUT;
- break;
- }
-
- *((wchar_t *) (outbuf + outwchars)) = ch;
- ++do_write;
- outwchars += sizeof (wchar_t);
- ++cnt;
- }
- *inbufsize -= cnt;
- inbuf += cnt;
- data->outbufavail = outwchars;
- }
- else
- {
- size_t inwchars = *inbufsize;
- size_t outchars = data->outbufavail;
- char *outbuf = data->outbuf;
- size_t cnt = 0;
- int extra = 0;
-
- while (inwchars >= cnt + sizeof (wchar_t)
- && outchars < data->outbufsize)
- {
- wchar_t ch = *((wchar_t *) (inbuf + cnt));
-
- if (ch <= L'\x7f')
- /* It's plain ASCII. */
- outbuf[outchars] = ch;
- else
- {
- /* Try the JIS character sets. */
- size_t found;
-
- found = ucs4_to_cns11643l1 (ch, &outbuf[outchars],
- (data->outbufsize
- - outchars));
- if (found == 0)
- {
- /* We ran out of space. */
- extra = 2;
- break;
- }
- else if (found != UNKNOWN_10646_CHAR)
- {
- /* It's a CNS 11643, plane 1 character, adjust it
- for EUC-TW. */
- outbuf[outchars++] += 0x80;
- outbuf[outchars] += 0x80;
- }
- else
- {
- /* No CNS 11643, plane 1 character. */
- outbuf[outchars] = '\x8e';
-
- found = ucs4_to_cns11643 (ch, &outbuf[outchars + 1],
- (data->outbufsize
- - outchars - 1));
- if (found > 0)
- {
- /* It's a CNS 11643 character, adjust it for
- EUC-TW. */
- outbuf[++outchars] += 0xa0;
- outbuf[++outchars] += 0x80;
- outbuf[outchars] += 0x80;
- }
- else if (found == 0)
- {
- /* We ran out of space. */
- extra = 4;
- break;
- }
- else
- /* Illegal character. */
- break;
- }
- }
-
- ++do_write;
- ++outchars;
- cnt += sizeof (wchar_t);
- }
- *inbufsize -= cnt;
- inbuf += cnt;
- data->outbufavail = outchars;
-
- if (outchars + extra < data->outbufsize)
- {
- /* If there is still room in the output buffer something
- is wrong with the input. */
- if (inwchars >= cnt + sizeof (wchar_t))
- {
- /* An error occurred. */
- result = GCONV_ILLEGAL_INPUT;
- break;
- }
- if (inwchars != cnt)
- {
- /* There are some unprocessed bytes at the end of the
- input buffer. */
- result = GCONV_INCOMPLETE_INPUT;
- break;
- }
- }
- }
-
- if (result != GCONV_OK)
- break;
-
- if (data->is_last)
- {
- /* This is the last step. */
- result = (*inbufsize > (step->data == &from_euctw_object
- ? 0 : sizeof (wchar_t) - 1)
- ? GCONV_FULL_OUTPUT : GCONV_EMPTY_INPUT);
- 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 (*inbufsize > 0 && result == GCONV_EMPTY_INPUT);
- }
-
- if (written != NULL && data->is_last)
- *written = do_write;
-
- return result;
-}
+/* Definitions used in the body of the `gconv' function. */
+#define CHARSET_NAME "EUC-TW"
+#define FROM_LOOP from_euc_tw
+#define TO_LOOP to_euc_tw
+#define DEFINE_INIT 1
+#define DEFINE_FINI 1
+#define MIN_NEEDED_FROM 1
+#define MAX_NEEDED_FROM 4
+#define MIN_NEEDED_TO 4
+
+
+/* First define the conversion function from EUC-TW to UCS4. */
+#define MIN_NEEDED_INPUT MIN_NEEDED_FROM
+#define MAX_NEEDED_INPUT MAX_NEEDED_FROM
+#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
+#define LOOPFCT FROM_LOOP
+#define BODY \
+ { \
+ uint32_t ch = *inptr; \
+ \
+ if (ch <= 0x7f) \
+ /* Plain ASCII. */ \
+ ++inptr; \
+ else if ((ch <= 0xa0 || ch > 0xfe) && ch != 0x8e) \
+ { \
+ /* This is illegal. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ else \
+ { \
+ /* Two or more byte character. First test whether the next \
+ character is also available. */ \
+ uint32_t ch2; \
+ \
+ if (NEED_LENGTH_TEST && inptr + (ch == 0x8e ? 3 : 1) >= inend) \
+ { \
+ /* The second character is not available. Store the \
+ intermediate result. */ \
+ result = GCONV_INCOMPLETE_INPUT; \
+ break; \
+ } \
+ \
+ ch2 = *inptr; \
+ \
+ /* All second bytes of a multibyte character must be >= 0xa1. */ \
+ if (ch2 < 0xa1 || ch2 == 0xff) \
+ { \
+ /* This is an illegal character. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ \
+ if (ch == 0x8e) \
+ { \
+ /* This is code set 2: CNS 11643, planes 1 to 16. */ \
+ const char *endp = inptr + 1; \
+ \
+ ch = cns11643_to_ucs4 (&endp, \
+ NEED_LENGTH_TEST ? inend - inptr - 1 : 3, \
+ 0x80); \
+ /* Please note that we need not test for the missing input \
+ characters here anymore. */ \
+ if (ch == UNKNOWN_10646_CHAR) \
+ { \
+ /* Illegal input. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ \
+ inptr += 4; \
+ } \
+ else \
+ { \
+ /* This is code set 1: CNS 11643, plane 1. */ \
+ const char *endp = inptr; \
+ \
+ ch = cns11643l1_to_ucs4 (&endp, \
+ NEED_LENGTH_TEST ? inend - inptr : 2, \
+ 0x80); \
+ /* Please note that we need not test for the missing input \
+ characters here anymore. */ \
+ if (ch == UNKNOWN_10646_CHAR) \
+ { \
+ /* Illegal input. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ \
+ inptr += 2; \
+ } \
+ } \
+ \
+ *((uint32_t *) outptr)++ = ch; \
+ }
+#include <iconv/loop.c>
+
+
+/* Next, define the other direction. */
+#define MIN_NEEDED_INPUT MIN_NEEDED_TO
+#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM
+#define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM
+#define LOOPFCT TO_LOOP
+#define BODY \
+ { \
+ uint32_t ch = *((uint32_t *) inptr); \
+ \
+ if (ch <= 0x7f) \
+ /* It's plain ASCII. */ \
+ *outptr++ = ch; \
+ else \
+ { \
+ /* Try the JIS character sets. */ \
+ size_t found; \
+ \
+ found = ucs4_to_cns11643l1 (ch, outptr, \
+ NEED_LENGTH_TEST ? outend - outptr : 2); \
+ if (NEED_LENGTH_TEST && found == 0) \
+ { \
+ /* We ran out of space. */ \
+ result = GCONV_INCOMPLETE_INPUT; \
+ break; \
+ } \
+ if (found != UNKNOWN_10646_CHAR) \
+ { \
+ /* It's a CNS 11643, plane 1 character, adjust it for EUC-TW. */ \
+ *outptr++ += 0x80; \
+ *outptr++ += 0x80; \
+ } \
+ else \
+ { \
+ /* No CNS 11643, plane 1 character. */ \
+ \
+ found = ucs4_to_cns11643 (ch, outptr + 1, \
+ (NEED_LENGTH_TEST \
+ ? outend - outptr - 1 : 3)); \
+ if (NEED_LENGTH_TEST && found == 0) \
+ { \
+ /* We ran out of space. */ \
+ result = GCONV_INCOMPLETE_INPUT; \
+ break; \
+ } \
+ if (found == UNKNOWN_10646_CHAR) \
+ { \
+ /* No legal input. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ \
+ /* It's a CNS 11643 character, adjust it for EUC-TW. */ \
+ *outptr++ = '\x8e'; \
+ *outptr++ += 0xa0; \
+ *outptr++ += 0x80; \
+ *outptr++ += 0x80; \
+ } \
+ } \
+ \
+ inptr += 4; \
+ }
+#include <iconv/loop.c>
+
+
+/* Now define the toplevel functions. */
+#include <iconv/skeleton.c>
diff --git a/iconvdata/gb2312.c b/iconvdata/gb2312.c
index 89d716196f..9cde1c8fe7 100644
--- a/iconvdata/gb2312.c
+++ b/iconvdata/gb2312.c
@@ -40,7 +40,7 @@
printf ("\n");
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
-const uint16_t gb2312_to_ucs[] =
+const uint16_t __gb2312_to_ucs[] =
{
[0x0000] = 0x3000, [0x0001] = 0x3001, [0x0002] = 0x3002, [0x0003] = 0x30fb,
[0x0004] = 0x02c9, [0x0005] = 0x02c7, [0x0006] = 0x00a8, [0x0007] = 0x3003,
@@ -1907,7 +1907,7 @@ const uint16_t gb2312_to_ucs[] =
};
-const char gb2312_from_ucs4_tab1[][2] =
+const char __gb2312_from_ucs4_tab1[][2] =
{
[0x00] = "\x21\x68", [0x03] = "\x21\x6c", [0x04] = "\x21\x27",
[0x0c] = "\x21\x63", [0x0d] = "\x21\x40", [0x33] = "\x21\x41",
@@ -1939,7 +1939,7 @@ const char gb2312_from_ucs4_tab1[][2] =
printf ("\n");
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
-const char gb2312_from_ucs4_tab2[][2] =
+const char __gb2312_from_ucs4_tab2[][2] =
{
[0x0000] = "\x26\x21", [0x0001] = "\x26\x22", [0x0002] = "\x26\x23",
[0x0003] = "\x26\x24", [0x0004] = "\x26\x25", [0x0005] = "\x26\x26",
@@ -1980,7 +1980,7 @@ const char gb2312_from_ucs4_tab2[][2] =
printf ("\n");
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
-const char gb2312_from_ucs4_tab3[][2] =
+const char __gb2312_from_ucs4_tab3[][2] =
{
[0x0000] = "\x27\x27", [0x000f] = "\x27\x21", [0x0010] = "\x27\x22",
[0x0011] = "\x27\x23", [0x0012] = "\x27\x24", [0x0013] = "\x27\x25",
@@ -2027,7 +2027,7 @@ const char gb2312_from_ucs4_tab3[][2] =
printf ("\n");
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
-const char gb2312_from_ucs4_tab4[][2] =
+const char __gb2312_from_ucs4_tab4[][2] =
{
[0x0000] = "\x21\x2a", [0x0003] = "\x21\x2e", [0x0004] = "\x21\x2f",
[0x0007] = "\x21\x30", [0x0008] = "\x21\x31", [0x0011] = "\x21\x2d",
@@ -2059,7 +2059,7 @@ const char gb2312_from_ucs4_tab4[][2] =
But we have a problem here since U+2225 maps to either 0x212C or
0x214E. We simply choose the first solution here.
*/
-const char gb2312_from_ucs4_tab5[][2] =
+const char __gb2312_from_ucs4_tab5[][2] =
{
[0x0000] = "\x21\x66", [0x0013] = "\x21\x6d", [0x005d] = "\x22\x71",
[0x005e] = "\x22\x72", [0x005f] = "\x22\x73", [0x0060] = "\x22\x74",
@@ -2100,7 +2100,7 @@ const char gb2312_from_ucs4_tab5[][2] =
printf ("\n");
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
-const char gb2312_from_ucs4_tab6[][2] =
+const char __gb2312_from_ucs4_tab6[][2] =
{
[0x0000] = "\x22\x59", [0x0001] = "\x22\x5a", [0x0002] = "\x22\x5b",
[0x0003] = "\x22\x5c", [0x0004] = "\x22\x5d", [0x0005] = "\x22\x5e",
@@ -2142,7 +2142,7 @@ const char gb2312_from_ucs4_tab6[][2] =
printf ("\n");
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
-const char gb2312_from_ucs4_tab7[][2] =
+const char __gb2312_from_ucs4_tab7[][2] =
{
[0x0000] = "\x21\x21", [0x0001] = "\x21\x22", [0x0002] = "\x21\x23",
[0x0003] = "\x21\x28", [0x0005] = "\x21\x29", [0x0008] = "\x21\x34",
@@ -2243,7 +2243,7 @@ const char gb2312_from_ucs4_tab7[][2] =
printf ("\n");
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
-const char gb2312_from_ucs4_tab8[][2] =
+const char __gb2312_from_ucs4_tab8[][2] =
{
[0x0000] = "\x52\x3b", [0x0001] = "\x36\x21", [0x0003] = "\x46\x5f",
[0x0007] = "\x4d\x72", [0x0008] = "\x55\x49", [0x0009] = "\x48\x7d",
@@ -4523,7 +4523,7 @@ const char gb2312_from_ucs4_tab8[][2] =
printf ("\n");
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
-const char gb2312_from_ucs4_tab9[][2] =
+const char __gb2312_from_ucs4_tab9[][2] =
{
[0x0000] = "\x23\x21", [0x0001] = "\x23\x22", [0x0002] = "\x23\x23",
[0x0003] = "\x21\x67", [0x0004] = "\x23\x25", [0x0005] = "\x23\x26",
diff --git a/iconvdata/gb2312.h b/iconvdata/gb2312.h
index 922fcc8f77..df87950436 100644
--- a/iconvdata/gb2312.h
+++ b/iconvdata/gb2312.h
@@ -25,7 +25,7 @@
#include <stdint.h>
/* Conversion table. */
-extern const uint16_t gb2312_to_ucs[];
+extern const uint16_t __gb2312_to_ucs[];
static inline wchar_t
@@ -51,127 +51,166 @@ gb2312_to_ucs4 (const char **s, size_t avail, unsigned char offset)
(*s) += 2;
- return gb2312_to_ucs[idx] ?: ((*s) -= 2, UNKNOWN_10646_CHAR);
+ return __gb2312_to_ucs[idx] ?: ((*s) -= 2, UNKNOWN_10646_CHAR);
}
-extern const char gb2312_from_ucs4_tab1[][2];
-extern const char gb2312_from_ucs4_tab2[][2];
-extern const char gb2312_from_ucs4_tab3[][2];
-extern const char gb2312_from_ucs4_tab4[][2];
-extern const char gb2312_from_ucs4_tab5[][2];
-extern const char gb2312_from_ucs4_tab6[][2];
-extern const char gb2312_from_ucs4_tab7[][2];
-extern const char gb2312_from_ucs4_tab8[][2];
-extern const char gb2312_from_ucs4_tab9[][2];
+extern const char __gb2312_from_ucs4_tab1[][2];
+extern const char __gb2312_from_ucs4_tab2[][2];
+extern const char __gb2312_from_ucs4_tab3[][2];
+extern const char __gb2312_from_ucs4_tab4[][2];
+extern const char __gb2312_from_ucs4_tab5[][2];
+extern const char __gb2312_from_ucs4_tab6[][2];
+extern const char __gb2312_from_ucs4_tab7[][2];
+extern const char __gb2312_from_ucs4_tab8[][2];
+extern const char __gb2312_from_ucs4_tab9[][2];
static inline size_t
ucs4_to_gb2312 (wchar_t wch, char *s, size_t avail)
{
unsigned int ch = (unsigned int) wch;
char buf[2];
- const char *cp = NULL;
+ const char *cp = buf;
- if (ch < 0xa4)
- return UNKNOWN_10646_CHAR;
- else if (ch < 0x101)
- cp = gb2312_from_ucs4_tab1[ch - 0xa4];
- else if (ch == 0x113)
- cp = "\x28\x25";
- else if (ch == 0x11b)
- cp = "\x28\x27";
- else if (ch == 0x12b)
- cp = "\x28\x29";
- else if (ch == 0x14d)
- cp = "\x28\x2d";
- else if (ch == 0x16b)
- cp = "\x28\x31";
- else if (ch == 0x1ce)
- cp = "\x28\x23";
- else if (ch == 0x1d0)
- cp = "\x28\x2b";
- else if (ch == 0x1d2)
- cp = "\x28\x2f";
- else if (ch == 0x1d4)
- cp = "\x28\x33";
- else if (ch == 0x1d6)
- cp = "\x28\x35";
- else if (ch == 0x1d8)
- cp = "\x28\x36";
- else if (ch == 0x1da)
- cp = "\x28\x37";
- else if (ch == 0x1dc)
- cp = "\x28\x38";
- else if (ch == 0x2c7)
- cp = "\x21\x26";
- else if (ch == 0x2c9)
- cp = "\x21\x25";
- else if (ch >= 0x391 && ch <= 0x3c9)
- cp = gb2312_from_ucs4_tab2[ch - 0x391];
- else if (ch >= 0x401 && ch <= 0x451)
- cp = gb2312_from_ucs4_tab3[ch - 0x401];
- else if (ch >= 0x2015 && ch <= 0x203b)
- cp = gb2312_from_ucs4_tab4[ch - 0x2015];
- else if (ch >= 0x2103 && ch <= 0x22a5)
- cp = gb2312_from_ucs4_tab5[ch - 0x2103];
- else if (ch == 0x2313)
- cp = "\x21\x50";
- else if (ch >= 0x2460 && ch <= 0x249b)
- cp = gb2312_from_ucs4_tab6[ch - 0x2460];
- else if (ch >= 0x2500 && ch <= 0x254b)
+ switch (ch)
{
+ case 0xa4 ... 0x100:
+ cp = __gb2312_from_ucs4_tab1[ch - 0xa4];
+ break;
+ case 0x113:
+ cp = "\x28\x25";
+ break;
+ case 0x11b:
+ cp = "\x28\x27";
+ break;
+ case 0x12b:
+ cp = "\x28\x29";
+ break;
+ case 0x14d:
+ cp = "\x28\x2d";
+ break;
+ case 0x16b:
+ cp = "\x28\x31";
+ break;
+ case 0x1ce:
+ cp = "\x28\x23";
+ break;
+ case 0x1d0:
+ cp = "\x28\x2b";
+ break;
+ case 0x1d2:
+ cp = "\x28\x2f";
+ break;
+ case 0x1d4:
+ cp = "\x28\x33";
+ break;
+ case 0x1d6:
+ cp = "\x28\x35";
+ break;
+ case 0x1d8:
+ cp = "\x28\x36";
+ break;
+ case 0x1da:
+ cp = "\x28\x37";
+ break;
+ case 0x1dc:
+ cp = "\x28\x38";
+ break;
+ case 0x2c7:
+ cp = "\x21\x26";
+ break;
+ case 0x2c9:
+ cp = "\x21\x25";
+ break;
+ case 0x391 ... 0x3c9:
+ cp = __gb2312_from_ucs4_tab2[ch - 0x391];
+ break;
+ case 0x401 ... 0x451:
+ cp = __gb2312_from_ucs4_tab3[ch - 0x401];
+ break;
+ case 0x2015 ... 0x203b:
+ cp = __gb2312_from_ucs4_tab4[ch - 0x2015];
+ break;
+ case 0x2103 ... 0x22a5:
+ cp = __gb2312_from_ucs4_tab5[ch - 0x2103];
+ break;
+ case 0x2313:
+ cp = "\x21\x50";
+ break;
+ case 0x2460 ... 0x249b:
+ cp = __gb2312_from_ucs4_tab6[ch - 0x2460];
+ break;
+ case 0x2500 ... 0x254b:
buf[0] = '\x29';
buf[1] = '\x24' + (ch & 256);
- cp = buf;
- }
- else if (ch == 0x25a0)
- cp = "\x21\x76";
- else if (ch == 0x25a1)
- cp = "\x21\x75";
- else if (ch == 0x25b2)
- cp = "\x21\x78";
- else if (ch == 0x25b3)
- cp = "\x21\x77";
- else if (ch == 0x25c6)
- cp = "\x21\x74";
- else if (ch == 0x25c7)
- cp = "\x21\x73";
- else if (ch == 0x25cb)
- cp = "\x21\x70";
- else if (ch == 0x25ce)
- cp = "\x21\x72";
- else if (ch == 0x25cf)
- cp = "\x21\x71";
- else if (ch == 0x2605)
- cp = "\x21\x6f";
- else if (ch == 0x2606)
- cp = "\x21\x6e";
- else if (ch == 0x2640)
- cp = "\x21\x62";
- else if (ch == 0x2642)
- cp = "\x21\x61";
- else if (ch >= 0x3000 && ch <= 0x3129)
- cp = gb2312_from_ucs4_tab7[ch - 0x3000];
- else if (ch >= 0x3220 && ch <= 0x3229)
- {
+ break;
+ case 0x25a0:
+ cp = "\x21\x76";
+ break;
+ case 0x25a1:
+ cp = "\x21\x75";
+ break;
+ case 0x25b2:
+ cp = "\x21\x78";
+ break;
+ case 0x25b3:
+ cp = "\x21\x77";
+ break;
+ case 0x25c6:
+ cp = "\x21\x74";
+ break;
+ case 0x25c7:
+ cp = "\x21\x73";
+ break;
+ case 0x25cb:
+ cp = "\x21\x70";
+ break;
+ case 0x25ce:
+ cp = "\x21\x72";
+ break;
+ case 0x25cf:
+ cp = "\x21\x71";
+ break;
+ case 0x2605:
+ cp = "\x21\x6f";
+ break;
+ case 0x2606:
+ cp = "\x21\x6e";
+ break;
+ case 0x2640:
+ cp = "\x21\x62";
+ break;
+ case 0x2642:
+ cp = "\x21\x61";
+ break;
+ case 0x3000 ... 0x3129:
+ cp = __gb2312_from_ucs4_tab7[ch - 0x3000];
+ break;
+ case 0x3220 ... 0x3229:
buf[0] = '\x22';
buf[1] = '\x65' + (ch - 0x3220);
- cp = buf;
+ break;
+ case 0x4e00 ... 0x9fa0:
+ cp = __gb2312_from_ucs4_tab8[ch - 0x4e00];
+ break;
+ case 0xff01 ... 0xff5e:
+ cp = __gb2312_from_ucs4_tab9[ch - 0xff01];
+ break;
+ case 0xffe0:
+ cp = "\x21\x69";
+ break;
+ case 0xffe1:
+ cp = "\x21\x6a";
+ break;
+ case 0xffe3:
+ cp = "\x23\x7e";
+ break;
+ case 0xffe5:
+ cp = "\x23\x24";
+ break;
+ default:
+ return UNKNOWN_10646_CHAR;
}
- else if (ch >= 0x4e00 && ch <= 0x9fa0)
- cp = gb2312_from_ucs4_tab8[ch - 0x4e00];
- else if (ch >= 0xff01 && ch <= 0xff5e)
- cp = gb2312_from_ucs4_tab9[ch - 0xff01];
- else if (ch == 0xffe0)
- cp = "\x21\x69";
- else if (ch == 0xffe1)
- cp = "\x21\x6a";
- else if (ch == 0xffe3)
- cp = "\x23\x7e";
- else if (ch == 0xffe5)
- cp = "\x23\x24";
- else
- return UNKNOWN_10646_CHAR;
if (cp[1] != '\0' && avail < 2)
return 0;
diff --git a/iconvdata/hp-roman8.c b/iconvdata/hp-roman8.c
index db36ceab9d..62e29ea463 100644
--- a/iconvdata/hp-roman8.c
+++ b/iconvdata/hp-roman8.c
@@ -1,5 +1,5 @@
/* Conversion from and to HP-ROMAN8.
- Copyright (C) 1997 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@@ -18,7 +18,12 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#include <wchar.h>
+#include <stdint.h>
+
+/* Get the conversion table. */
#include <hp-roman8.h>
-#define NAME "HP-ROMAN8"
+
+#define CHARSET_NAME "HP-ROMAN8"
+#define HAS_HOLES 1 /* Not all 256 character are defined. */
+
#include <8bit-generic.c>
diff --git a/iconvdata/iso646.c b/iconvdata/iso646.c
index 53ca76cb14..3c40c8fd0c 100644
--- a/iconvdata/iso646.c
+++ b/iconvdata/iso646.c
@@ -292,19 +292,17 @@ gconv (struct gconv_step *step, struct gconv_step_data *data,
/* Correct the output buffer. */
if (newavail != data->outbufavail && newavail > 0)
- {
- memmove (data->outbuf,
- &data->outbuf[data->outbufavail - newavail],
- newavail);
- data->outbufavail = newavail;
- }
+ memmove (data->outbuf,
+ &data->outbuf[data->outbufavail - newavail],
+ newavail);
+ data->outbufavail = newavail;
}
}
while (*inbufsize > 0 && result == GCONV_EMPTY_INPUT);
}
if (written != NULL && data->is_last)
- *written = do_write;
+ *written += do_write;
return result;
}
diff --git a/iconvdata/iso6937.c b/iconvdata/iso6937.c
index 21e3ab4898..b121ffa77a 100644
--- a/iconvdata/iso6937.c
+++ b/iconvdata/iso6937.c
@@ -18,11 +18,10 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#include <gconv.h>
-#include <string.h>
+#include <stdint.h>
/* Data taken from the WG15 tables. */
-static const wchar_t to_ucs4[256] =
+static const uint32_t to_ucs4[256] =
{
/* 0x00 */ 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
/* 0x08 */ 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
@@ -60,7 +59,7 @@ static const wchar_t to_ucs4[256] =
/* The outer array range runs from 0xc1 to 0xcf, the inner range from 0x20
to 0x7f. */
-static const wchar_t to_ucs4_comb[15][96] =
+static const uint32_t to_ucs4_comb[15][96] =
{
/* 0xc1 */
{
@@ -371,290 +370,179 @@ static const char from_ucs4[][2] =
*/
};
-/* Direction of the transformation. */
-static int to_iso6937_object;
-static int from_iso6937_object;
+/* Definitions used in the body of the `gconv' function. */
+#define CHARSET_NAME "ISO_6937"
+#define FROM_LOOP from_iso6937
+#define TO_LOOP to_iso6937
+#define DEFINE_INIT 1
+#define DEFINE_FINI 1
+#define MIN_NEEDED_FROM 1
+#define MAX_NEEDED_FROM 2
+#define MIN_NEEDED_TO 4
+
+
+/* First define the conversion function from ISO 6937 to UCS4. */
+#define MIN_NEEDED_INPUT MIN_NEEDED_FROM
+#define MAX_NEEDED_INPUT MAX_NEEDED_FROM
+#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
+#define LOOPFCT FROM_LOOP
+#define BODY \
+ { \
+ uint32_t ch = *inptr; \
+ \
+ if (ch >= 0xc1 && ch <= 0xcf) \
+ { \
+ /* Composed character. First test whether the next character \
+ is also available. */ \
+ int ch2; \
+ \
+ if (inptr + 1 >= inend) \
+ { \
+ /* The second character is not available. Store the \
+ intermediate result. */ \
+ result = GCONV_INCOMPLETE_INPUT; \
+ break; \
+ } \
+ \
+ ch2 = inptr[1]; \
+ \
+ if (ch2 < 0x20 || ch2 >= 0x80) \
+ { \
+ /* This is illegal. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ \
+ ch = to_ucs4_comb[ch - 0xc1][ch2 - 0x20]; \
+ \
+ if (ch == 0) \
+ { \
+ /* Illegal character. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ \
+ inptr += 2; \
+ } \
+ else \
+ { \
+ ch = to_ucs4[ch]; \
+ \
+ if (ch == 0 && *inptr != '\0') \
+ { \
+ /* This is an illegal character. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ ++inptr; \
+ } \
+ \
+ *((uint32_t *) outptr)++ = ch; \
+ }
+#include <iconv/loop.c>
+
+
+/* Next, define the other direction. */
+#define MIN_NEEDED_INPUT MIN_NEEDED_TO
+#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM
+#define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM
+#define LOOPFCT TO_LOOP
+#define BODY \
+ { \
+ char tmp[2]; \
+ uint32_t ch = *((uint32_t *) inptr); \
+ const char *cp; \
+ \
+ if (ch >= sizeof (from_ucs4) / sizeof (from_ucs4[0])) \
+ { \
+ int fail = 0; \
+ switch (ch) \
+ { \
+ case 0x2c7: \
+ cp = "\xcf\x20"; \
+ break; \
+ case 0x2d8 ... 0x2dd: \
+ { \
+ static const char map[5] = "\xc6\xc7\xca\xce\xcd"; \
+ \
+ tmp[0] = map[ch - 0x2d8]; \
+ tmp[1] = ' '; \
+ cp = tmp; \
+ } \
+ break; \
+ case 0x2014: \
+ cp = "\xd0"; \
+ break; \
+ case 0x2018: \
+ cp = "\xa9"; \
+ break; \
+ case 0x2019: \
+ cp = "\xb9"; \
+ break; \
+ case 0x201c: \
+ cp = "\xaa"; \
+ break; \
+ case 0x201d: \
+ cp = "\xba"; \
+ break; \
+ case 0x2122: \
+ cp = "\xd4"; \
+ break; \
+ case 0x2126: \
+ cp = "\xe0"; \
+ break; \
+ case 0x215b ... 0x215e: \
+ tmp[0] = 0xdc + (ch - 0x215b); \
+ tmp[1] = '\0'; \
+ cp = tmp; \
+ break; \
+ case 0x2190 ... 0x2193: \
+ tmp[0] = 0xac + (ch - 0x2190); \
+ tmp[1] = '\0'; \
+ cp = tmp; \
+ break; \
+ case 0x266a: \
+ cp = "\xd5"; \
+ break; \
+ default: \
+ cp = NULL; \
+ fail = 1; \
+ } \
+ \
+ if (fail) \
+ { \
+ /* Illegal characters. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ } \
+ else if (from_ucs4[ch][0] == '\0' && ch != 0) \
+ { \
+ /* Illegal characters. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ else \
+ cp = from_ucs4[ch]; \
+ \
+ *outptr++ = cp[0]; \
+ /* Now test for a possible second byte and write this if possible. */ \
+ if (cp[1] != '\0') \
+ { \
+ if (NEED_LENGTH_TEST && outptr >= outend) \
+ { \
+ /* The result does not fit into the buffer. */ \
+ result = GCONV_FULL_OUTPUT; \
+ break; \
+ } \
+ *outptr++ = cp[1]; \
+ } \
+ \
+ inptr += 4; \
+ }
+#include <iconv/loop.c>
-int
-gconv_init (struct gconv_step *step)
-{
- /* Determine which direction. */
- if (strcasestr (step->from_name, "ISO_6937") != NULL)
- step->data = &from_iso6937_object;
- else if (strcasestr (step->to_name, "ISO_6937") != NULL)
- step->data = &to_iso6937_object;
- else
- return GCONV_NOCONV;
-
- return GCONV_OK;
-}
-
-
-void
-gconv_end (struct gconv_step *data)
-{
- /* Nothign to do. */
-}
-
-
-int
-gconv (struct gconv_step *step, struct gconv_step_data *data,
- const char *inbuf, size_t *inbufsize, 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;
- 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)
- {
- do_write = 0;
-
- /* 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
- {
- do_write = 0;
-
- do
- {
- result = GCONV_OK;
-
- if (step->data == &from_iso6937_object)
- {
- size_t inchars = *inbufsize;
- size_t outwchars = data->outbufavail;
- char *outbuf = data->outbuf;
- size_t cnt = 0;
-
- while (cnt < inchars
- && (outwchars + sizeof (wchar_t) <= data->outbufsize))
- {
- int inchar = inbuf[cnt];
- wchar_t ch;
-
- if (inchar >= '\xc1' && inchar <= '\xcf')
- {
- /* Composed character. First test whether the next
- character is also available. */
- int inchar2;
-
- if (cnt + 1 >= inchars)
- {
- /* The second character is not available. Store
- the intermediate result. */
- result = GCONV_INCOMPLETE_INPUT;
- break;
- }
-
- inchar2 = inbuf[++cnt];
-
- if (inchar2 < '\x20' || inchar2 >= '\x80')
- /* This is illegal. */
- ch = L'\0';
- else
- ch = to_ucs4_comb[inchar - 0xc1][inchar2 - 0x20];
-
- if (ch == L'\0')
- /* Undo the increment for illegal characters. */
- --cnt;
- }
- else
- ch = to_ucs4[inchar];
-
- if (ch == L'\0' && inbuf[cnt] != '\0')
- {
- /* This is an illegal character. */
- result = GCONV_ILLEGAL_INPUT;
- break;
- }
-
- *((wchar_t *) (outbuf + outwchars)) = ch;
- ++do_write;
- outwchars += sizeof (wchar_t);
- ++cnt;
- }
- *inbufsize -= cnt;
- inbuf += cnt;
- data->outbufavail = outwchars;
- }
- else
- {
- size_t inwchars = *inbufsize;
- size_t outchars = data->outbufavail;
- char *outbuf = data->outbuf;
- size_t cnt = 0;
- int extra = 0;
-
- while (inwchars >= cnt + sizeof (wchar_t)
- && outchars < data->outbufsize)
- {
- char tmp[2];
- int ch = *((wchar_t *) (inbuf + cnt));
- const char *cp;
-
- if (ch >= sizeof (from_ucs4) / sizeof (from_ucs4[0]))
- {
- int fail = 0;
- switch (ch)
- {
- case 0x2c7:
- cp = "\xcf\x20";
- break;
- case 0x2d8 ... 0x2dd:
- {
- static const char map[5] = "\xc6\xc7\xca\xce\xcd";
-
- tmp[0] = map[ch - 0x2d8];
- tmp[1] = ' ';
- cp = tmp;
- }
- break;
- case 0x2014:
- cp = "\xd0";
- break;
- case 0x2018:
- cp = "\xa9";
- break;
- case 0x2019:
- cp = "\xb9";
- break;
- case 0x201c:
- cp = "\xaa";
- break;
- case 0x201d:
- cp = "\xba";
- break;
- case 0x2122:
- cp = "\xd4";
- break;
- case 0x2126:
- cp = "\xe0";
- break;
- case 0x215b ... 0x215e:
- tmp[0] = 0xdc + (ch - 0x215b);
- tmp[1] = '\0';
- cp = tmp;
- break;
- case 0x2190 ... 0x2193:
- tmp[0] = 0xac + (ch - 0x2190);
- tmp[1] = '\0';
- cp = tmp;
- break;
- case 0x266a:
- cp = "\xd5";
- break;
- default:
- cp = NULL;
- fail = 1;
- }
-
- if (fail)
- /* Illegal characters. */
- break;
- }
- else if (ch < 0 || (from_ucs4[ch][0] == '\0' && ch != 0))
- break;
- else
- cp = from_ucs4[ch];
-
- outbuf[outchars] = cp[0];
- /* Now test for a possible second byte and write this
- if possible. */
- if (cp[1] != '\0')
- {
- if (outchars + 1 >= data->outbufsize)
- {
- /* The result does not fit into the buffer. */
- extra = 1;
- break;
- }
- outbuf[++outchars] = cp[1];
- }
-
- ++do_write;
- ++outchars;
- cnt += sizeof (wchar_t);
- }
- *inbufsize -= cnt;
- inbuf += cnt;
- data->outbufavail = outchars;
-
- if (outchars + extra < data->outbufsize)
- {
- /* If there is still room in the output buffer something
- is wrong with the input. */
- if (inwchars >= cnt + sizeof (wchar_t))
- {
- /* An error occurred. */
- result = GCONV_ILLEGAL_INPUT;
- break;
- }
- if (inwchars != cnt)
- {
- /* There are some unprocessed bytes at the end of the
- input buffer. */
- result = GCONV_INCOMPLETE_INPUT;
- break;
- }
- }
- }
-
- if (result != GCONV_OK)
- break;
-
- if (data->is_last)
- {
- /* This is the last step. */
- result = (*inbufsize > (step->data == &from_iso6937_object
- ? 0 : sizeof (wchar_t) - 1)
- ? GCONV_FULL_OUTPUT : GCONV_EMPTY_INPUT);
- 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 (*inbufsize > 0 && result == GCONV_EMPTY_INPUT);
- }
-
- if (written != NULL && data->is_last)
- *written = do_write;
- return result;
-}
+/* Now define the toplevel functions. */
+#include <iconv/skeleton.c>
diff --git a/iconvdata/iso8859-1.c b/iconvdata/iso8859-1.c
index b9484a06b7..3e50b79f17 100644
--- a/iconvdata/iso8859-1.c
+++ b/iconvdata/iso8859-1.c
@@ -18,179 +18,44 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#include <gconv.h>
-#include <string.h>
-
-/* Direction of the transformation. */
-static int to_iso88591_object;
-static int from_iso88591_object;
-
-
-int
-gconv_init (struct gconv_step *step)
-{
- /* Determine which direction. */
- if (strcasestr (step->from_name, "ISO-8859-1") != NULL)
- step->data = &from_iso88591_object;
- else if (strcasestr (step->to_name, "ISO-8859-1") != NULL)
- step->data = &to_iso88591_object;
- else
- return GCONV_NOCONV;
-
- return GCONV_OK;
-}
-
-
-void
-gconv_end (struct gconv_step *data)
-{
- /* Nothing to do. */
-}
-
-
-int
-gconv (struct gconv_step *step, struct gconv_step_data *data,
- const char *inbuf, size_t *inbufsize, 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;
- 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)
- {
- do_write = 0;
-
- /* 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
- {
- do_write = 0;
-
- do
- {
- result = GCONV_OK;
-
- if (step->data == &from_iso88591_object)
- {
- size_t inchars = *inbufsize;
- size_t outwchars = data->outbufavail;
- char *outbuf = data->outbuf;
- size_t cnt = 0;
-
- while (cnt < inchars
- && (outwchars + sizeof (wchar_t) <= data->outbufsize))
- {
- *((wchar_t *) (outbuf + outwchars)) =
- (unsigned char) inbuf[cnt];
- ++do_write;
- outwchars += sizeof (wchar_t);
- ++cnt;
- }
- *inbufsize -= cnt;
- inbuf += cnt;
- data->outbufavail = outwchars;
- }
- else
- {
- size_t inwchars = *inbufsize;
- size_t outchars = data->outbufavail;
- char *outbuf = data->outbuf;
- size_t cnt = 0;
-
- while (inwchars >= cnt + sizeof (wchar_t)
- && outchars < data->outbufsize)
- {
- if (*((wchar_t *) (inbuf + cnt)) >= L'\0'
- && *((wchar_t *) (inbuf + cnt)) <= L'\377')
- outbuf[outchars] = *((wchar_t *) (inbuf + cnt));
- else
- /* Here is where the transliteration would enter the
- scene. */
- break;
-
- ++do_write;
- ++outchars;
- cnt += sizeof (wchar_t);
- }
- *inbufsize -= cnt;
- inbuf += cnt;
- data->outbufavail = outchars;
-
- if (outchars < data->outbufsize)
- {
- /* If there is still room in the output buffer something
- is wrong with the input. */
- if (inwchars >= cnt + sizeof (wchar_t))
- {
- /* An error occurred. */
- result = GCONV_ILLEGAL_INPUT;
- break;
- }
- if (inwchars != cnt)
- {
- /* There are some unprocessed bytes at the end of the
- input buffer. */
- result = GCONV_INCOMPLETE_INPUT;
- break;
- }
- }
- }
-
- if (result != GCONV_OK)
- break;
-
- if (data->is_last)
- {
- /* This is the last step. */
- result = (*inbufsize > (step->data == &from_iso88591_object
- ? 0 : sizeof (wchar_t) - 1)
- ? GCONV_FULL_OUTPUT : GCONV_EMPTY_INPUT);
- 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 (*inbufsize > 0 && result == GCONV_EMPTY_INPUT);
- }
-
- if (written != NULL && data->is_last)
- *written = do_write;
-
- return result;
-}
+#include <stdint.h>
+
+/* Definitions used in the body of the `gconv' function. */
+#define CHARSET_NAME "ISO-8859-1"
+#define FROM_LOOP from_iso8859_1
+#define TO_LOOP to_iso8859_1
+#define DEFINE_INIT 1
+#define DEFINE_FINI 1
+#define MIN_NEEDED_FROM 1
+#define MIN_NEEDED_TO 4
+
+/* First define the conversion function from ISO 8859-1 to UCS4. */
+#define MIN_NEEDED_INPUT MIN_NEEDED_FROM
+#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
+#define LOOPFCT FROM_LOOP
+#define BODY \
+ *((uint32_t *) outptr)++ = *inptr++;
+#include <iconv/loop.c>
+
+
+/* Next, define the other direction. */
+#define MIN_NEEDED_INPUT MIN_NEEDED_FROM
+#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
+#define LOOPFCT TO_LOOP
+#define BODY \
+ { \
+ uint32_t ch = *((uint32_t *) inptr); \
+ if (ch > 0xff) \
+ { \
+ /* We have an illegal character. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ *outptr++ = (unsigned char) ch; \
+ inptr += 4; \
+ }
+#include <iconv/loop.c>
+
+
+/* Now define the toplevel functions. */
+#include <iconv/skeleton.c>
diff --git a/iconvdata/iso8859-10.c b/iconvdata/iso8859-10.c
index eb54e49342..acce3257e3 100644
--- a/iconvdata/iso8859-10.c
+++ b/iconvdata/iso8859-10.c
@@ -1,5 +1,5 @@
/* Conversion from and to ISO 8859-10.
- Copyright (C) 1997 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@@ -18,7 +18,11 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#include <wchar.h>
+/* Get the conversion table. */
+#include <stdint.h>
#include <iso8859-10.h>
-#define NAME "ISO-8859-10"
+
+#define CHARSET_NAME "ISO-8859-10"
+#define HAS_HOLES 0 /* All 256 character are defined. */
+
#include <8bit-generic.c>
diff --git a/iconvdata/iso8859-2.c b/iconvdata/iso8859-2.c
index fa07b752c6..8a5e62418f 100644
--- a/iconvdata/iso8859-2.c
+++ b/iconvdata/iso8859-2.c
@@ -1,5 +1,5 @@
/* Conversion from and to ISO 8859-2.
- Copyright (C) 1997 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@@ -18,7 +18,11 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#include <wchar.h>
+/* Get the conversion table. */
+#include <stdint.h>
#include <iso8859-2.h>
-#define NAME "ISO-8859-2"
+
+#define CHARSET_NAME "ISO-8859-2"
+#define HAS_HOLES 0 /* All 256 character are defined. */
+
#include <8bit-generic.c>
diff --git a/iconvdata/iso8859-3.c b/iconvdata/iso8859-3.c
index c31d388ca2..10e52e429f 100644
--- a/iconvdata/iso8859-3.c
+++ b/iconvdata/iso8859-3.c
@@ -1,5 +1,5 @@
/* Conversion from and to ISO 8859-3.
- Copyright (C) 1997 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@@ -18,7 +18,11 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#include <wchar.h>
+/* Get the conversion table. */
+#include <stdint.h>
#include <iso8859-3.h>
-#define NAME "ISO-8859-3"
+
+#define CHARSET_NAME "ISO-8859-3"
+#define HAS_HOLES 1 /* Not all 256 character are defined. */
+
#include <8bit-generic.c>
diff --git a/iconvdata/iso8859-4.c b/iconvdata/iso8859-4.c
index 7ae98473ca..01cdbf0b98 100644
--- a/iconvdata/iso8859-4.c
+++ b/iconvdata/iso8859-4.c
@@ -1,5 +1,5 @@
/* Conversion from and to ISO 8859-4.
- Copyright (C) 1997 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@@ -18,7 +18,11 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#include <wchar.h>
+/* Get the conversion table. */
+#include <stdint.h>
#include <iso8859-4.h>
-#define NAME "ISO-8859-4"
+
+#define CHARSET_NAME "ISO-8859-4"
+#define HAS_HOLES 0 /* All 256 character are defined. */
+
#include <8bit-generic.c>
diff --git a/iconvdata/iso8859-5.c b/iconvdata/iso8859-5.c
index b4791f1bf5..edf0f47b5c 100644
--- a/iconvdata/iso8859-5.c
+++ b/iconvdata/iso8859-5.c
@@ -1,5 +1,5 @@
/* Conversion from and to ISO 8859-5.
- Copyright (C) 1997 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@@ -18,7 +18,11 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#include <wchar.h>
+/* Get the conversion table. */
+#include <stdint.h>
#include <iso8859-5.h>
-#define NAME "ISO-8859-5"
+
+#define CHARSET_NAME "ISO-8859-5"
+#define HAS_HOLES 0 /* All 256 character are defined. */
+
#include <8bit-generic.c>
diff --git a/iconvdata/iso8859-6.c b/iconvdata/iso8859-6.c
index 1e88ec9d22..59ce3f2cc1 100644
--- a/iconvdata/iso8859-6.c
+++ b/iconvdata/iso8859-6.c
@@ -1,5 +1,5 @@
/* Conversion from and to ISO 8859-6.
- Copyright (C) 1997 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@@ -18,7 +18,11 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#include <wchar.h>
+/* Get the conversion table. */
+#include <stdint.h>
#include <iso8859-6.h>
-#define NAME "ISO-8859-6"
+
+#define CHARSET_NAME "ISO-8859-6"
+#define HAS_HOLES 1 /* Not all 256 character are defined. */
+
#include <8bit-generic.c>
diff --git a/iconvdata/iso8859-7.c b/iconvdata/iso8859-7.c
index 63220bb822..d75e93e204 100644
--- a/iconvdata/iso8859-7.c
+++ b/iconvdata/iso8859-7.c
@@ -1,5 +1,5 @@
/* Conversion from and to ISO 8859-7.
- Copyright (C) 1997 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@@ -18,7 +18,11 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#include <wchar.h>
+/* Get the conversion table. */
+#include <stdint.h>
#include <iso8859-7.h>
-#define NAME "ISO-8859-7"
+
+#define CHARSET_NAME "ISO-8859-7"
+#define HAS_HOLES 1 /* Not all 256 character are defined. */
+
#include <8bit-generic.c>
diff --git a/iconvdata/iso8859-8.c b/iconvdata/iso8859-8.c
index 2246ae4e52..1612f148f4 100644
--- a/iconvdata/iso8859-8.c
+++ b/iconvdata/iso8859-8.c
@@ -1,5 +1,5 @@
/* Conversion from and to ISO 8859-8.
- Copyright (C) 1997 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@@ -18,7 +18,11 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#include <wchar.h>
+/* Get the conversion table. */
+#include <stdint.h>
#include <iso8859-8.h>
-#define NAME "ISO-8859-8"
+
+#define CHARSET_NAME "ISO-8859-8"
+#define HAS_HOLES 1 /* Not all 256 character are defined. */
+
#include <8bit-generic.c>
diff --git a/iconvdata/iso8859-9.c b/iconvdata/iso8859-9.c
index 5260362f0c..063f189aba 100644
--- a/iconvdata/iso8859-9.c
+++ b/iconvdata/iso8859-9.c
@@ -1,5 +1,5 @@
/* Conversion from and to ISO 8859-9.
- Copyright (C) 1997 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@@ -18,7 +18,11 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#include <wchar.h>
+/* Get the conversion table. */
+#include <stdint.h>
#include <iso8859-9.h>
-#define NAME "ISO-8859-9"
+
+#define CHARSET_NAME "ISO-8859-9"
+#define HAS_HOLES 0 /* All 256 character are defined. */
+
#include <8bit-generic.c>
diff --git a/iconvdata/jis0201.c b/iconvdata/jis0201.c
index e8e04e171b..65321e4cd7 100644
--- a/iconvdata/jis0201.c
+++ b/iconvdata/jis0201.c
@@ -1,5 +1,5 @@
/* Mapping tables for JIS0201 handling.
- Copyright (C) 1997 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@@ -18,10 +18,10 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#include <wchar.h>
+#include <stdint.h>
-const wchar_t jisx0201_to_ucs4[256] =
+const uint32_t __jisx0201_to_ucs4[256] =
{
0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
diff --git a/iconvdata/jis0201.h b/iconvdata/jis0201.h
index 8f920f9ec8..1514c88d73 100644
--- a/iconvdata/jis0201.h
+++ b/iconvdata/jis0201.h
@@ -22,13 +22,13 @@
#define _JIS0201_H 1
/* Conversion table. */
-extern const wchar_t jis0201_to_ucs4[];
+extern const uint32_t __jis0201_to_ucs4[];
-static inline wchar_t
+static inline uint32_t
jisx0201_to_ucs4 (char ch)
{
- wchar_t val = jis0201_to_ucs4[(unsigned char) ch];
+ uint32_t val = __jis0201_to_ucs4[(unsigned char) ch];
if (val == 0 && ch != '\0')
val = UNKNOWN_10646_CHAR;
@@ -38,7 +38,7 @@ jisx0201_to_ucs4 (char ch)
static inline size_t
-ucs4_to_jisx0201 (wchar_t wch, char *s)
+ucs4_to_jisx0201 (uint32_t wch, char *s)
{
char ch;
diff --git a/iconvdata/jis0208.c b/iconvdata/jis0208.c
index 8db4085a9c..964f73dd26 100644
--- a/iconvdata/jis0208.c
+++ b/iconvdata/jis0208.c
@@ -1,5 +1,5 @@
/* Mapping tables for JIS0208 handling.
- Copyright (C) 1997 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@@ -18,7 +18,7 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#include <wchar.h>
+#include <stdint.h>
#include "jis0208.h"
@@ -58,7 +58,7 @@
printf ("\n");
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
-const uint16_t jis0208_to_ucs[0x1e80] =
+const uint16_t __jis0208_to_ucs[0x1e80] =
{
[0x0000] = 0x3000, [0x0001] = 0x3001, [0x0002] = 0x3002, [0x0003] = 0xff0c,
[0x0004] = 0xff0e, [0x0005] = 0x30fb, [0x0006] = 0xff1a, [0x0007] = 0xff1b,
@@ -1783,7 +1783,7 @@ const uint16_t jis0208_to_ucs[0x1e80] =
};
-const char jisx0208_from_ucs4_lat1[256][2] =
+const char __jisx0208_from_ucs4_lat1[256][2] =
{
[0x005C] = "\x21\x40", [0x00A2] = "\x21\x71", [0x00A3] = "\x21\x72",
[0x00A7] = "\x21\x78", [0x00A8] = "\x21\x2f", [0x00AC] = "\x22\x4c",
@@ -1814,7 +1814,7 @@ const char jisx0208_from_ucs4_lat1[256][2] =
printf ("\n");
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
-const char jisx0208_from_ucs4_greek[0xc1][2] =
+const char __jisx0208_from_ucs4_greek[0xc1][2] =
{
[0x00] = "\x26\x21", [0x01] = "\x26\x22", [0x02] = "\x26\x23",
[0x03] = "\x26\x24", [0x04] = "\x26\x25", [0x05] = "\x26\x26",
@@ -1887,7 +1887,7 @@ const char jisx0208_from_ucs4_greek[0xc1][2] =
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
-const struct jisx0208_ucs_idx jisx0208_from_ucs_idx[] =
+const struct jisx0208_ucs_idx __jisx0208_from_ucs_idx[] =
{
{ start: 0x2010, end: 0x2026, idx: 0 },
{ start: 0x2030, end: 0x2033, idx: 23 },
@@ -2596,7 +2596,7 @@ const struct jisx0208_ucs_idx jisx0208_from_ucs_idx[] =
{ start: 0x9f9c, end: 0x9fa0, idx: 14109 },
{ start: 0xff01, end: 0xff5d, idx: 14114 },
{ start: 0xffe3, end: 0xffe5, idx: 14207 },
- { start: 0 }
+ { start: 0xffff, end: 0xffff, idx: 0 }
};
@@ -2637,7 +2637,7 @@ const struct jisx0208_ucs_idx jisx0208_from_ucs_idx[] =
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
-const char jisx0208_from_ucs_tab[14210][2] =
+const char __jisx0208_from_ucs_tab[14210][2] =
{
"\x20\x10", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x20\x15",
"\x20\x16", "\x00\x00", "\x20\x18", "\x20\x19", "\x00\x00", "\x00\x00",
diff --git a/iconvdata/jis0208.h b/iconvdata/jis0208.h
index 94d27642c6..a83ee3bbda 100644
--- a/iconvdata/jis0208.h
+++ b/iconvdata/jis0208.h
@@ -25,12 +25,12 @@
#include <stdint.h>
/* Conversion table. */
-extern const uint16_t jis0208_to_ucs[];
+extern const uint16_t __jis0208_to_ucs[];
-extern const char jisx0208_from_ucs4_lat1[256][2];
-extern const char jisx0208_from_ucs4_greek[0xc1][2];
-extern const struct jisx0208_ucs_idx jisx0208_from_ucs_idx[];
-extern const char jisx0208_from_ucs_tab[][2];
+extern const char __jisx0208_from_ucs4_lat1[256][2];
+extern const char __jisx0208_from_ucs4_greek[0xc1][2];
+extern const struct jisx0208_ucs_idx __jisx0208_from_ucs_idx[];
+extern const char __jisx0208_from_ucs_tab[][2];
/* Struct for table with indeces in UCS mapping table. */
@@ -42,8 +42,8 @@ struct jisx0208_ucs_idx
};
-static inline wchar_t
-jisx0208_to_ucs4 (const char **s, size_t avail, unsigned char offset)
+static inline uint32_t
+jisx0208_to_ucs4 (const unsigned char **s, size_t avail, unsigned char offset)
{
unsigned char ch = *(*s);
unsigned char ch2;
@@ -65,34 +65,38 @@ jisx0208_to_ucs4 (const char **s, size_t avail, unsigned char offset)
(*s) += 2;
- return jis0208_to_ucs[idx] ?: ((*s) -= 2, UNKNOWN_10646_CHAR);
+ return __jis0208_to_ucs[idx] ?: ((*s) -= 2, UNKNOWN_10646_CHAR);
}
static inline size_t
-ucs4_to_jisx0208 (wchar_t wch, char *s, size_t avail)
+ucs4_to_jisx0208 (uint32_t wch, char *s, size_t avail)
{
unsigned int ch = (unsigned int) wch;
- const char *cp = NULL;
+ const char *cp;
if (avail < 2)
return 0;
if (ch < 0x100)
- cp = jisx0208_from_ucs4_lat1[ch];
+ cp = __jisx0208_from_ucs4_lat1[ch];
else if (ch >= 0x391 && ch <= 0x451)
- cp = jisx0208_from_ucs4_greek[ch];
+ cp = __jisx0208_from_ucs4_greek[ch];
else
{
- const struct jisx0208_ucs_idx *rp = jisx0208_from_ucs_idx;
+ const struct jisx0208_ucs_idx *rp = __jisx0208_from_ucs_idx;
+ if (ch >= 0xffff)
+ return UNKNOWN_10646_CHAR;
while (ch > rp->end)
++rp;
if (ch >= rp->start)
- cp = jisx0208_from_ucs_tab[rp->idx + ch - rp->start];
+ cp = __jisx0208_from_ucs_tab[rp->idx + ch - rp->start];
+ else
+ return UNKNOWN_10646_CHAR;
}
- if (cp == NULL || cp[0] == '\0')
+ if (cp[0] == '\0')
return UNKNOWN_10646_CHAR;
s[0] = cp[0];
diff --git a/iconvdata/jis0212.c b/iconvdata/jis0212.c
index 7484c5e84c..eca645f45a 100644
--- a/iconvdata/jis0212.c
+++ b/iconvdata/jis0212.c
@@ -19,7 +19,6 @@
Boston, MA 02111-1307, USA. */
#include <stdint.h>
-#include <wchar.h>
#include <jis0212.h>
@@ -54,7 +53,7 @@
$first, $last, $idx);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
-const struct jisx0212_idx jisx0212_to_ucs_idx[] =
+const struct jisx0212_idx __jisx0212_to_ucs_idx[] =
{
{ start: 0x006c, end: 0x0076, idx: 0 },
{ start: 0x007f, end: 0x0081, idx: 11 },
@@ -67,7 +66,7 @@ const struct jisx0212_idx jisx0212_to_ucs_idx[] =
{ start: 0x034e, end: 0x03a4, idx: 107 },
{ start: 0x03ac, end: 0x0402, idx: 194 },
{ start: 0x0582, end: 0x1c2a, idx: 281 },
- { start: 0 },
+ { start: 0xffff, end: 0xffff, idx: 0 },
};
@@ -109,7 +108,7 @@ const struct jisx0212_idx jisx0212_to_ucs_idx[] =
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
-const uint16_t jisx0212_to_ucs[] =
+const uint16_t __jisx0212_to_ucs[] =
{
0x02d8, 0x02c7, 0x00b8, 0x02d9, 0x02dd, 0x00af, 0x02db, 0x02da,
0x007e, 0x0384, 0x0385, 0x00a1, 0x00a6, 0x00bf, 0x00ba, 0x00aa,
@@ -905,7 +904,7 @@ const uint16_t jisx0212_to_ucs[] =
$first, $last, $idx);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
-const struct jisx0212_idx jisx0212_from_ucs_idx[] =
+const struct jisx0212_idx __jisx0212_from_ucs_idx[] =
{
{ start: 0x007e, end: 0x007e, idx: 0 },
{ start: 0x00a1, end: 0x00af, idx: 1 },
@@ -1654,7 +1653,7 @@ const struct jisx0212_idx jisx0212_from_ucs_idx[] =
{ start: 0x9f68, end: 0x9f7d, idx: 13393 },
{ start: 0x9f8f, end: 0x9f97, idx: 13415 },
{ start: 0x9f9e, end: 0x9fa5, idx: 13424 },
- { start: 0 }
+ { start: 0xffff, end: 0xffff, idx: 0 }
};
@@ -1697,7 +1696,7 @@ const struct jisx0212_idx jisx0212_from_ucs_idx[] =
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
-const char jisx0212_from_ucs[][2] =
+const char __jisx0212_from_ucs[][2] =
{
"\x7e\x00", "\xa1\x00", "\x00\x00", "\x00\x00", "\xa4\x00", "\x00\x00",
"\xa6\x00", "\x00\x00", "\x00\x00", "\xa9\x00", "\xaa\x00", "\x00\x00",
diff --git a/iconvdata/jis0212.h b/iconvdata/jis0212.h
index cf5d919109..4930437128 100644
--- a/iconvdata/jis0212.h
+++ b/iconvdata/jis0212.h
@@ -34,20 +34,20 @@ struct jisx0212_idx
};
/* Conversion table. */
-extern const struct jisx0212_idx jisx0212_to_ucs_idx[];
-extern const uint16_t jisx0212_to_ucs[];
+extern const struct jisx0212_idx __jisx0212_to_ucs_idx[];
+extern const uint16_t __jisx0212_to_ucs[];
-extern const struct jisx0212_idx jisx0212_from_ucs_idx[];
-extern const char jisx0212_from_ucs[][2];
+extern const struct jisx0212_idx __jisx0212_from_ucs_idx[];
+extern const char __jisx0212_from_ucs[][2];
static inline wchar_t
-jisx0212_to_ucs4 (const char **s, size_t avail, unsigned char offset)
+jisx0212_to_ucs4 (const unsigned char **s, size_t avail, unsigned char offset)
{
- const struct jisx0212_idx *rp = jisx0212_to_ucs_idx;
+ const struct jisx0212_idx *rp = __jisx0212_to_ucs_idx;
unsigned char ch = *(*s);
unsigned char ch2;
- wchar_t wch = L'\0';
+ uint32_t wch = 0;
int idx;
if (ch < offset || (ch - offset) <= 0x6d || (ch - offset) > 0xea)
@@ -62,10 +62,10 @@ jisx0212_to_ucs4 (const char **s, size_t avail, unsigned char offset)
idx = (ch - 0x21 - offset) * 94 + (ch2 - 0x21 - offset);
- while (idx < rp->start)
+ while (idx > rp->end)
++rp;
- if (idx <= rp->end)
- wch = jisx0212_to_ucs[rp->idx + idx - rp->start];
+ if (idx >= rp->start)
+ wch = __jisx0212_to_ucs[rp->idx + idx - rp->start];
if (wch != L'\0')
(*s) += 2;
@@ -79,16 +79,20 @@ jisx0212_to_ucs4 (const char **s, size_t avail, unsigned char offset)
static inline size_t
ucs4_to_jisx0212 (wchar_t wch, char *s, size_t avail)
{
- const struct jisx0212_idx *rp = jisx0212_from_ucs_idx;
+ const struct jisx0212_idx *rp = __jisx0212_from_ucs_idx;
unsigned int ch = (unsigned int) wch;
- const char *cp = NULL;
+ const char *cp;
+ if (ch >= 0xffff)
+ return UNKNOWN_10646_CHAR;
while (ch > rp->end)
++rp;
if (ch >= rp->start)
- cp = jisx0212_from_ucs[rp->idx + ch - rp->start];
+ cp = __jisx0212_from_ucs[rp->idx + ch - rp->start];
+ else
+ return UNKNOWN_10646_CHAR;
- if (cp == NULL || cp[0] == '\0')
+ if (cp[0] == '\0')
return UNKNOWN_10646_CHAR;
s[0] = cp[0];
diff --git a/iconvdata/johab.c b/iconvdata/johab.c
index c9912a71d0..6a582c0b70 100644
--- a/iconvdata/johab.c
+++ b/iconvdata/johab.c
@@ -1,7 +1,8 @@
/* Mapping tables for JOHAB handling.
Copyright (C) 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
- Contributed by Jungshik Shin <jshin@pantheon.yale.edu>, 1998.
+ Contributed by Jungshik Shin <jshin@pantheon.yale.edu>
+ and Ulrich Drepper <drepper@cygnus.com>, 1998.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
@@ -18,16 +19,9 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#include <gconv.h>
#include <stdint.h>
-#include <string.h>
-#include <wchar.h>
#include <ksc5601.h>
-/* Direction of the transformation. */
-static int to_johab_object;
-static int from_johab_object;
-
/* The table for Bit pattern to Hangul Jamo
5 bits each are used to encode
leading consonants(19 + 1 filler), medial vowels(21 + 1 filler)
@@ -37,19 +31,19 @@ static int from_johab_object;
0 : Filler, -1: invalid, >= 1 : valid
*/
-const int init[32] =
+static const int init[32] =
{
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
19, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
};
-const int mid[32] =
+static const int mid[32] =
{
-1, -1, 0, 1, 2, 3, 4, 5,
-1, -1, 6, 7, 8, 9, 10, 11,
-1, -1, 12, 13, 14, 15, 16, 17,
-1, -1, 18, 19, 20, 21, -1, -1
};
-const int final[32] =
+static const int final[32] =
{
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
-1, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, -1, -1
@@ -63,14 +57,14 @@ const int final[32] =
block [0x3131,0x314e] or Hangul Conjoining Jamo block, [0x1100,0x11ff]
*/
-const wchar_t init_to_ucs[19] =
+static const uint32_t init_to_ucs[19] =
{
0x3131, 0x3132, 0x3134, 0x3137, 0x3138, 0x3139, 0x3141, 0x3142,
0x3143, 0x3145, 0x3146, 0x3147, 0x3148, 0x3149, 0x314a, 0x314b,
0x314c, 0x314d, 0x314e
};
-const wchar_t final_to_ucs[27] =
+static const uint32_t final_to_ucs[27] =
{
L'\0', L'\0', 0x3133, L'\0', 0x3135, 0x3136, L'\0', L'\0',
0x313a, 0x313b, 0x314c, 0x313d, 0x313e, 0x313f,
@@ -88,7 +82,7 @@ const wchar_t final_to_ucs[27] =
to get the same result arithmetically.
*/
-const int init_to_bit[19] =
+static const int init_to_bit[19] =
{
0x8800, 0x8c00, 0x9000, 0x9400, 0x9800, 0x9c00,
0xa000, 0xa400, 0xa800, 0xac00, 0xb000, 0xb400,
@@ -96,7 +90,7 @@ const int init_to_bit[19] =
0xd000
};
-const int mid_to_bit[21] =
+static const int mid_to_bit[21] =
{
0x0060, 0x0080, 0x00a0, 0x00c0, 0x00e0,
0x0140, 0x0160, 0x0180, 0x01a0, 0x01c0, 0x1e0,
@@ -104,7 +98,7 @@ const int mid_to_bit[21] =
0x0340, 0x0360, 0x0380, 0x03a0
};
-const int final_to_bit[28] =
+static const int final_to_bit[28] =
{
1, 2, 3, 4, 5, 6, 7, 8, 9, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d
@@ -118,7 +112,7 @@ const int final_to_bit[28] =
2. Unicode 2.0 manual
*/
-const uint16_t jamo_from_ucs_table[51] =
+static const uint16_t jamo_from_ucs_table[51] =
{
0x8841, 0x8c41,
0x8444,
@@ -137,21 +131,20 @@ const uint16_t jamo_from_ucs_table[51] =
};
-static inline wchar_t
-johab_sym_hanja_to_ucs (int idx, int c1, int c2)
+static inline uint32_t
+johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2)
{
if (idx <= 0xdefe)
- return (wchar_t) ksc5601_sym_to_ucs[(c1 - 0xd9) * 188 + c2
- - (c2 > 0x90 ? 0x43 : 0x31)];
+ return (uint32_t) __ksc5601_sym_to_ucs[(c1 - 0xd9) * 188 + c2
+ - (c2 > 0x90 ? 0x43 : 0x31)];
else
- return (wchar_t) ksc5601_hanja_to_ucs[(c1 - 0xe0) * 188 + c2
- - (c2 > 0x90 ? 0x43 : 0x31)];
+ return (uint32_t) __ksc5601_hanja_to_ucs[(c1 - 0xe0) * 188 + c2
+ - (c2 > 0x90 ? 0x43 : 0x31)];
}
static uint16_t
-johab_hanja_from_ucs (wchar_t ch)
+johab_hanja_from_ucs (uint32_t ch)
{
-
uint16_t idx;
if (ucs4_to_ksc5601_hanja (ch, &idx))
{
@@ -168,7 +161,7 @@ johab_hanja_from_ucs (wchar_t ch)
}
static uint16_t
-johab_sym_from_ucs (wchar_t ch)
+johab_sym_from_ucs (uint32_t ch)
{
uint16_t idx;
if (ucs4_to_ksc5601_sym (ch, &idx))
@@ -186,9 +179,8 @@ johab_sym_from_ucs (wchar_t ch)
}
-
static inline void
-johab_from_ucs4 (wchar_t ch, unsigned char *cp)
+johab_from_ucs4 (uint32_t ch, unsigned char *cp)
{
if (ch >= 0x7f)
{
@@ -215,315 +207,205 @@ johab_from_ucs4 (wchar_t ch, unsigned char *cp)
else
idx = johab_sym_from_ucs (ch);
- *cp = (char) (idx / 256);
- *(cp + 1) = (char) (idx & 0xff);
+ cp[0] = (unsigned char) (idx / 256);
+ cp[1] = (unsigned char) (idx & 0xff);
}
else
{
- *cp = (char) (0x7f & ch);
- *(cp + 1) = (char) 0;
+ cp[0] = (unsigned char) ch;
+ cp[1] = 0;
}
-
-}
-
-
-int
-gconv_init (struct gconv_step *step)
-{
- /* Determine which direction. */
- if (strcasestr (step->from_name, "JOHAB") != NULL)
- step->data = &from_johab_object;
- else if (strcasestr (step->to_name, "JOHAB") != NULL)
- step->data = &to_johab_object;
- else
- return GCONV_NOCONV;
-
- return GCONV_OK;
-}
-
-
-void
-gconv_end (struct gconv_step *data)
-{
- /* Nothing to do. */
}
-int
-gconv (struct gconv_step *step, struct gconv_step_data *data,
- const char *inbuf, size_t *inbufsize, 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;
- 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)
- {
- do_write = 0;
-
- /* 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
- {
- do_write = 0;
-
- do
- {
- result = GCONV_OK;
-
- if (step->data == &from_johab_object)
- {
- size_t inchars = *inbufsize;
- size_t outwchars = data->outbufavail;
- char *outbuf = data->outbuf;
- size_t cnt = 0;
-
- while (cnt < inchars
- && (outwchars + sizeof (wchar_t) <= data->outbufsize))
- {
- int inchar = (unsigned char) inbuf[cnt];
- wchar_t ch;
- /* half-width Korean Currency WON sign
- if (inchar == 0x5c)
- ch = 0x20a9;
- else if (inchar < 0x7f)
- ch = (wchar_t) inchar;
- */
- if (inchar < 0x7f)
- ch = (wchar_t) inchar;
-
- /* Johab : 1. Hangul
- 1st byte : 0x84-0xd3
- 2nd byte : 0x41-0x7e, 0x81-0xfe
- 2. Hanja & Symbol :
- 1st byte : 0xd8-0xde, 0xe0-0xf9
- 2nd byte : 0x31-0x7e, 0x91-0xfe
- 0xd831-0xd87e and 0xd891-0xd8fe are user-defined area */
-
- else if (inchar > 0xf9 || inchar == 0xdf
- || (inchar > 0x7e && inchar < 0x84)
- || (inchar > 0xd3 && inchar < 0xd9))
- /* These are illegal. */
- ch = L'\0';
- else
- {
- /* Two-byte character. First test whether the next
- character is also available. */
- int inchar2;
- int idx;
-
- if (cnt + 1 >= inchars)
- {
- /* The second character is not available. Store
- the intermediate result. */
- result = GCONV_INCOMPLETE_INPUT;
- break;
- }
-
- inchar2 = (unsigned char) inbuf[++cnt];
- idx = inchar * 256 + inchar2;
- if (inchar <= 0xd3)
- { /* Hangul */
- int i, m, f;
- i = init[(idx & 0x7c00) >> 10];
- m = mid[(idx & 0x03e0) >> 5];
- f = final[idx & 0x001f];
- if (i == -1 || m == -1 || f == -1)
- /* This is illegal. */
- ch = L'\0';
- else if (i > 0 && m > 0)
- ch = ((i - 1) * 21 + (m - 1)) * 28 + f + 0xac00;
- else if (i > 0 && m == 0 & f == 0)
- ch = init_to_ucs[i - 1];
- else if (i == 0 && m > 0 & f == 0)
- ch = 0x314e + m; /* 0x314f + m - 1 */
- else if (i == 0 && m == 0 & f > 0)
- ch = final_to_ucs[f - 1]; /* round trip?? */
- else
- /* This is illegal. */
- ch = L'\0';
- }
- else
- {
- if (inchar2 < 0x31
- || (inchar2 > 0x7e && inchar2 < 0x91)
- || inchar2 == 0xff)
- /* This is illegal. */
- ch = L'\0';
- else if (inchar == 0xda
- && inchar2 > 0xa0 && inchar2 < 0xd4)
- /* This is illegal. */
- /* Modern Hangul Jaso is defined elsewhere
- in Johab */
- ch = L'\0';
- else
- {
- ch = johab_sym_hanja_to_ucs (idx, inchar,
- inchar2);
- /* if (idx <= 0xdefe)
- ch = ksc5601_sym_to_ucs[(inchar - 0xd9) * 192
- + inchar2
- - (inchar2>0x90 ? 0x43 : 0x31)];
-
- else
- ch = ksc5601_hanja_to_ucs[(inchar - 0xe0) *192
- + inchar2
- - (inchar2>0x90 ? 0x43 : 0x31)];
- */
- }
- }
-
- if (ch == L'\0')
- --cnt;
- }
-
- if (ch == L'\0' && inbuf[cnt] != '\0')
- {
- /* This is an illegal character. */
- result = GCONV_ILLEGAL_INPUT;
- break;
- }
-
- *((wchar_t *) (outbuf + outwchars)) = ch;
- ++do_write;
- outwchars += sizeof (wchar_t);
- ++cnt;
- }
- *inbufsize -= cnt;
- inbuf += cnt;
- data->outbufavail = outwchars;
- }
- else
- {
- size_t inwchars = *inbufsize;
- size_t outchars = data->outbufavail;
- char *outbuf = data->outbuf;
- size_t cnt = 0;
- int extra = 0;
-
- while (inwchars >= cnt + sizeof (wchar_t)
- && outchars < data->outbufsize)
- {
- wchar_t ch = *((wchar_t *) (inbuf + cnt));
- unsigned char cp[2];
- /*
- if (ch >= (sizeof (from_ucs4_lat1)
- / sizeof (from_ucs4_lat1[0])))
- {
- if (ch >= 0x0391 && ch <= 0x0451)
- cp = from_ucs4_greek[ch - 0x391];
- else if (ch >= 0x2010 && ch <= 0x9fa0)
- cp = from_ucs4_cjk[ch - 0x02010];
- else
- break;
- }
- else
- cp = from_ucs4_lat1[ch];
- */
- johab_from_ucs4 (ch, cp);
-
- if (cp[0] == '\0' && ch != 0)
- /* Illegal character. */
- break;
-
- outbuf[outchars] = cp[0];
- /* Now test for a possible second byte and write this
- if possible. */
- if (cp[1] != '\0')
- {
- if (outchars + 1 >= data->outbufsize)
- {
- /* The result does not fit into the buffer. */
- extra = 1;
- break;
- }
- outbuf[++outchars] = cp[1];
- }
-
- ++do_write;
- ++outchars;
- cnt += sizeof (wchar_t);
- }
- *inbufsize -= cnt;
- inbuf += cnt;
- data->outbufavail = outchars;
-
- if (outchars + extra < data->outbufsize)
- {
- /* If there is still room in the output buffer something
- is wrong with the input. */
- if (inwchars >= cnt + sizeof (wchar_t))
- {
- /* An error occurred. */
- result = GCONV_ILLEGAL_INPUT;
- break;
- }
- if (inwchars != cnt)
- {
- /* There are some unprocessed bytes at the end of the
- input buffer. */
- result = GCONV_INCOMPLETE_INPUT;
- break;
- }
- }
- }
-
- if (result != GCONV_OK)
- break;
-
- if (data->is_last)
- {
- /* This is the last step. */
- result = (*inbufsize > (step->data == &from_johab_object
- ? 0 : sizeof (wchar_t) - 1)
- ? GCONV_FULL_OUTPUT : GCONV_EMPTY_INPUT);
- 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 (*inbufsize > 0 && result == GCONV_EMPTY_INPUT);
- }
-
- if (written != NULL && data->is_last)
- *written = do_write;
-
- return result;
-}
+/* Definitions used in the body of the `gconv' function. */
+#define CHARSET_NAME "JOHAB"
+#define FROM_LOOP from_johab
+#define TO_LOOP to_johab
+#define DEFINE_INIT 1
+#define DEFINE_FINI 1
+#define MIN_NEEDED_FROM 1
+#define MAX_NEEDED_FROM 2
+#define MIN_NEEDED_TO 4
+
+
+/* First define the conversion function from JOHAB to UCS4. */
+#define MIN_NEEDED_INPUT MIN_NEEDED_FROM
+#define MAX_NEEDED_INPUT MAX_NEEDED_FROM
+#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
+#define LOOPFCT FROM_LOOP
+#define BODY \
+ { \
+ uint32_t ch = *inptr; \
+ \
+ /* half-width Korean Currency WON sign \
+ if (ch == 0x5c) \
+ ch = 0x20a9; \
+ else if (ch < 0x7f) \
+ ch = (wchar_t) ch; \
+ */ \
+ if (ch < 0x7f) \
+ /* Plain ASCII. */ \
+ ++inptr; \
+ /* Johab : 1. Hangul \
+ 1st byte : 0x84-0xd3 \
+ 2nd byte : 0x41-0x7e, 0x81-0xfe \
+ 2. Hanja & Symbol : \
+ 1st byte : 0xd8-0xde, 0xe0-0xf9 \
+ 2nd byte : 0x31-0x7e, 0x91-0xfe \
+ 0xd831-0xd87e and 0xd891-0xd8fe are user-defined area */ \
+ else \
+ { \
+ if (ch > 0xf9 || ch == 0xdf || (ch > 0x7e && ch < 0x84) \
+ || (ch > 0xd3 && ch < 0xd9)) \
+ { \
+ /* These are illegal. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ else \
+ { \
+ /* Two-byte character. First test whether the next \
+ character is also available. */ \
+ uint32_t ch2; \
+ uint_fast32_t idx; \
+ \
+ if (NEED_LENGTH_TEST && inptr + 1 >= inend) \
+ { \
+ /* The second character is not available. Store the \
+ intermediate result. */ \
+ result = GCONV_INCOMPLETE_INPUT; \
+ break; \
+ } \
+ \
+ ch2 = inptr[1]; \
+ idx = ch * 256 + ch2; \
+ if (ch <= 0xd3) \
+ { \
+ /* Hangul */ \
+ uint_fast32_t i, m, f; \
+ \
+ i = init[(idx & 0x7c00) >> 10]; \
+ m = mid[(idx & 0x03e0) >> 5]; \
+ f = final[idx & 0x001f]; \
+ \
+ if (i == -1 || m == -1 || f == -1) \
+ { \
+ /* This is illegal. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ else if (i > 0 && m > 0) \
+ ch = ((i - 1) * 21 + (m - 1)) * 28 + f + 0xac00; \
+ else if (i > 0 && m == 0 & f == 0) \
+ ch = init_to_ucs[i - 1]; \
+ else if (i == 0 && m > 0 & f == 0) \
+ ch = 0x314e + m; /* 0x314f + m - 1 */ \
+ else if (i == 0 && m == 0 & f > 0) \
+ ch = final_to_ucs[f - 1]; /* round trip?? */ \
+ else \
+ { \
+ /* This is illegal. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ } \
+ else \
+ { \
+ if (ch2 < 0x31 || (ch2 > 0x7e && ch2 < 0x91) || ch2 == 0xff) \
+ { \
+ /* This is illegal. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ else if (ch == 0xda && ch2 > 0xa0 && ch2 < 0xd4) \
+ { \
+ /* This is illegal. Modern Hangul Jaso is defined \
+ elsewhere in Johab */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ else \
+ { \
+ ch = johab_sym_hanja_to_ucs (idx, ch, ch2); \
+ /* if (idx <= 0xdefe) \
+ ch = __ksc5601_sym_to_ucs[(ch - 0xd9) * 192 \
+ + ch2 - (ch2 > 0x90 \
+ ? 0x43 : 0x31)]; \
+ else \
+ ch = __ksc5601_hanja_to_ucs[(ch - 0xe0) *192 \
+ + ch2 - (ch2 > 0x90 \
+ ?0x43 : 0x31)];\
+ */ \
+ } \
+ } \
+ } \
+ \
+ if (ch == 0) \
+ { \
+ /* This is an illegal character. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ \
+ inptr += 2; \
+ } \
+ \
+ *((uint32_t *) outptr)++ = ch; \
+ }
+#include <iconv/loop.c>
+
+
+/* Next, define the other direction. */
+#define MIN_NEEDED_INPUT MIN_NEEDED_TO
+#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM
+#define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM
+#define LOOPFCT TO_LOOP
+#define BODY \
+ { \
+ uint32_t ch = *((uint32_t *) inptr); \
+ unsigned char cp[2]; \
+ /* \
+ if (ch >= (sizeof (from_ucs4_lat1) / sizeof (from_ucs4_lat1[0]))) \
+ { \
+ if (ch >= 0x0391 && ch <= 0x0451) \
+ cp = from_ucs4_greek[ch - 0x391]; \
+ else if (ch >= 0x2010 && ch <= 0x9fa0) \
+ cp = from_ucs4_cjk[ch - 0x02010]; \
+ else \
+ break; \
+ } \
+ else \
+ cp = from_ucs4_lat1[ch]; \
+ */ \
+ johab_from_ucs4 (ch, cp); \
+ \
+ if (cp[0] == '\0' && ch != 0) \
+ { \
+ /* Illegal character. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ \
+ *outptr++ = cp[0]; \
+ /* Now test for a possible second byte and write this if possible. */ \
+ if (cp[1] != '\0') \
+ { \
+ if (NEED_LENGTH_TEST && outptr >= outend) \
+ { \
+ /* The result does not fit into the buffer. */ \
+ --outptr; \
+ result = GCONV_FULL_OUTPUT; \
+ break; \
+ } \
+ *outptr++ = cp[1]; \
+ } \
+ \
+ inptr += 4; \
+ }
+#include <iconv/loop.c>
+
+
+/* Now define the toplevel functions. */
+#include <iconv/skeleton.c>
diff --git a/iconvdata/koi-8.c b/iconvdata/koi-8.c
index 2228456801..b2332c2a6a 100644
--- a/iconvdata/koi-8.c
+++ b/iconvdata/koi-8.c
@@ -1,5 +1,5 @@
/* Conversion from and to KOI-8.
- Copyright (C) 1997 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@@ -18,7 +18,11 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#include <wchar.h>
+/* Get the conversion table. */
+#include <stdint.h>
#include <koi-8.h>
-#define NAME "KOI-8"
+
+#define CHARSET_NAME "KOI-8"
+#define HAS_HOLES 1 /* Not all 256 character are defined. */
+
#include <8bit-generic.c>
diff --git a/iconvdata/koi8-r.c b/iconvdata/koi8-r.c
index 502132b338..ee317bd25b 100644
--- a/iconvdata/koi8-r.c
+++ b/iconvdata/koi8-r.c
@@ -1,5 +1,5 @@
/* Conversion from and to KOI8-R.
- Copyright (C) 1997 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@@ -18,7 +18,12 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#include <wchar.h>
+#include <stdint.h>
+
+/* Specify the conversion table. */
#define TABLES <koi8-r.h>
-#define NAME "KOI8-R"
+
+#define CHARSET_NAME "KOI8-R"
+#define HAS_HOLES 1 /* Not all 256 character are defined. */
+
#include <8bit-gap.c>
diff --git a/iconvdata/ksc5601.c b/iconvdata/ksc5601.c
index c919425aa7..da64c430f4 100644
--- a/iconvdata/ksc5601.c
+++ b/iconvdata/ksc5601.c
@@ -18,7 +18,7 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#include <wchar.h>
+#include <stdint.h>
#include "ksc5601.h"
/*
@@ -50,7 +50,7 @@ perl tab21.pl > ksc_hangul1.tb
*/
-const uint16_t ksc5601_hangul_to_ucs[KSC5601_HANGUL]=
+const uint16_t __ksc5601_hangul_to_ucs[KSC5601_HANGUL]=
{
0xac00, 0xac01, 0xac04, 0xac07, 0xac08, 0xac09, 0xac0a, 0xac10,
0xac11, 0xac12, 0xac13, 0xac14, 0xac15, 0xac16, 0xac17, 0xac19,
@@ -369,7 +369,7 @@ grep -v '# HANGUL SYLLABLE' | perl tab11.pl > ksc_sym1.tb
*/
-const uint16_t ksc5601_sym_to_ucs[] =
+const uint16_t __ksc5601_sym_to_ucs[] =
{
[0x0000] = 0x3000, [0x0001] = 0x3001, [0x0002] = 0x3002, [0x0003] = 0x00b7,
[0x0004] = 0x2025, [0x0005] = 0x2026, [0x0006] = 0x00a8, [0x0007] = 0x3003,
@@ -646,7 +646,7 @@ perl tab12.pl > ksc_sym2.tb
*/
-const uint16_t ksc5601_sym_from_ucs[KSC5601_SYMBOL][2] =
+const uint16_t __ksc5601_sym_from_ucs[KSC5601_SYMBOL][2] =
{
{0x00a1, 0x222e}, {0x00a4, 0x2234}, {0x00a7, 0x2157}, {0x00a8, 0x2127},
{0x00aa, 0x2823}, {0x00ad, 0x2129}, {0x00b0, 0x2146}, {0x00b1, 0x213e},
@@ -914,7 +914,7 @@ perl tab21.pl > ksc_hanja1.tb
printf ("\n");
*/
-const uint16_t ksc5601_hanja_to_ucs[KSC5601_HANJA]=
+const uint16_t __ksc5601_hanja_to_ucs[KSC5601_HANJA]=
{
0x4f3d, 0x4f73, 0x5047, 0x50f9, 0x52a0, 0x53ef, 0x5475, 0x54e5,
0x5609, 0x5ac1, 0x5bb6, 0x6687, 0x67b6, 0x67b7, 0x67ef, 0x6b4c,
@@ -1550,7 +1550,7 @@ awk '{print $2,$1}' | sort -u | perl tab12.pl > ksc_hanja2.tb
*/
-const uint16_t ksc5601_hanja_from_ucs[KSC5601_HANJA][2]=
+const uint16_t __ksc5601_hanja_from_ucs[KSC5601_HANJA][2]=
{
{0x4e00, 0x6c69}, {0x4e01, 0x6f4b}, {0x4e03, 0x7652}, {0x4e07, 0x5832},
{0x4e08, 0x6d5b}, {0x4e09, 0x5f32}, {0x4e0a, 0x5f3e}, {0x4e0b, 0x793b},
diff --git a/iconvdata/ksc5601.h b/iconvdata/ksc5601.h
index 0d86c7b253..8a5c40e5dd 100644
--- a/iconvdata/ksc5601.h
+++ b/iconvdata/ksc5601.h
@@ -28,18 +28,18 @@
#include <stdint.h>
/* Conversion table. */
-extern const uint16_t ksc5601_hangul_to_ucs[KSC5601_HANGUL];
-extern const uint16_t ksc5601_sym_to_ucs[];
-extern const uint16_t ksc5601_sym_from_ucs[KSC5601_SYMBOL][2];
-extern const uint16_t ksc5601_hanja_to_ucs[KSC5601_HANJA];
-extern const uint16_t ksc5601_hanja_from_ucs[KSC5601_HANJA][2];
+extern const uint16_t __ksc5601_hangul_to_ucs[KSC5601_HANGUL];
+extern const uint16_t __ksc5601_sym_to_ucs[];
+extern const uint16_t __ksc5601_sym_from_ucs[KSC5601_SYMBOL][2];
+extern const uint16_t __ksc5601_hanja_to_ucs[KSC5601_HANJA];
+extern const uint16_t __ksc5601_hanja_from_ucs[KSC5601_HANJA][2];
/*
static inline wchar_t
ksc5601_to_ucs4 (char **s, size_t avail)
*/
-static inline wchar_t
+static inline uint32_t
ksc5601_to_ucs4 (uint16_t s)
{
unsigned char ch = s / 256;
@@ -61,23 +61,25 @@ ksc5601_to_ucs4 (uint16_t s)
Hangul in KS C 5601 : row 16 - row 40 */
if (idx >= 1410 && idx < 3760)
- return ksc5601_hangul_to_ucs[idx-1410];
+ return __ksc5601_hangul_to_ucs[idx-1410];
else if (idx > 3854)
/* Hanja : row 42 - row 93 : 3854 = 94 * (42-1) */
- return ksc5601_hanja_to_ucs[idx-3854];
+ return __ksc5601_hanja_to_ucs[idx-3854];
else
- return ksc5601_sym_to_ucs[idx] ?: UNKNOWN_10646_CHAR;
+ return __ksc5601_sym_to_ucs[idx] ?: UNKNOWN_10646_CHAR;
}
static inline size_t
-ucs4_to_ksc5601_hangul (wchar_t wch, uint16_t *s)
+ucs4_to_ksc5601_hangul (uint32_t wch, uint16_t *s)
{
- int l=0,m,u=KSC5601_HANGUL-1;
- wchar_t try;
+ int l = 0;
+ int m;
+ int u = KSC5601_HANGUL - 1;
+ uint32_t try;
while (l <= u)
{
- try = (wchar_t) ksc5601_hangul_to_ucs[m=(l+u)/2];
+ try = (uint32_t) __ksc5601_hangul_to_ucs[m=(l+u)/2];
if (try > wch)
u = m - 1;
else if (try < wch)
@@ -93,21 +95,24 @@ ucs4_to_ksc5601_hangul (wchar_t wch, uint16_t *s)
static inline size_t
-ucs4_to_ksc5601_hanja (wchar_t wch, uint16_t *s)
+ucs4_to_ksc5601_hanja (uint32_t wch, uint16_t *s)
{
- int l=0,m,u=KSC5601_HANJA-1;
- wchar_t try;
+ int l = 0;
+ int m;
+ int u = KSC5601_HANJA - 1;
+ uint32_t try;
while (l <= u)
{
- try = (wchar_t) ksc5601_hanja_from_ucs[m=(l+u)/2][0];
+ m = (l + u) / 2;
+ try = (uint32_t) __ksc5601_hanja_from_ucs[m][0];
if (try > wch)
u=m-1;
else if (try < wch)
l = m + 1;
else
{
- *s = ksc5601_hanja_from_ucs[m][1];
+ *s = __ksc5601_hanja_from_ucs[m][1];
return 2;
}
}
@@ -115,24 +120,24 @@ ucs4_to_ksc5601_hanja (wchar_t wch, uint16_t *s)
}
static inline size_t
-ucs4_to_ksc5601_sym (wchar_t wch, uint16_t *s)
+ucs4_to_ksc5601_sym (uint32_t wch, uint16_t *s)
{
int l = 0;
int m;
int u = KSC5601_SYMBOL - 1;
- wchar_t try;
+ uint32_t try;
while (l <= u)
{
m = (l + u) / 2;
- try = ksc5601_sym_from_ucs[m][0];
+ try = __ksc5601_sym_from_ucs[m][0];
if (try > wch)
u = m - 1;
else if (try < wch)
l = m + 1;
else
{
- *s = ksc5601_sym_from_ucs[m][1];
+ *s = __ksc5601_sym_from_ucs[m][1];
return 2;
}
}
@@ -146,13 +151,13 @@ ucs4_to_ksc5601 (wchar_t wch, char **s, size_t avail)
*/
static inline size_t
-ucs4_to_ksc5601 (wchar_t ch, uint16_t *s)
+ucs4_to_ksc5601 (uint32_t ch, uint16_t *s)
{
*s = (uint16_t) UNKNOWN_10646_CHAR; /* FIXIT */
if (ch >= 0xac00 && ch <= 0xd7a3)
return ucs4_to_ksc5601_hangul (ch, s);
- else if (ch >= 0x4e00 && ch <= 0x9fff || ch >= 0xf900 && ch <= 0xfa0b)
+ else if (ch >= 0x4e00 && ch <= 0x9fff || ch >= 0xf900 && ch <= 0xfa0b)
return ucs4_to_ksc5601_hanja (ch, s);
else
return ucs4_to_ksc5601_sym (ch, s);
diff --git a/iconvdata/latin-greek-1.c b/iconvdata/latin-greek-1.c
index d62969a77d..37ccf09c09 100644
--- a/iconvdata/latin-greek-1.c
+++ b/iconvdata/latin-greek-1.c
@@ -1,5 +1,5 @@
/* Conversion from and to LATIN-GREEK-1.
- Copyright (C) 1997 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@@ -18,7 +18,10 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#include <wchar.h>
+/* Specify the conversion table. */
#define TABLES <latin-greek-1.h>
-#define NAME "LATIN-GREEK-1"
+
+#define CHARSET_NAME "LATIN-GREEK-1"
+#define HAS_HOLES 1 /* Not all 256 character are defined. */
+
#include <8bit-gap.c>
diff --git a/iconvdata/latin-greek.c b/iconvdata/latin-greek.c
index 90270e0e07..8810f4a2e0 100644
--- a/iconvdata/latin-greek.c
+++ b/iconvdata/latin-greek.c
@@ -1,5 +1,5 @@
/* Conversion from and to LATIN-GREEK.
- Copyright (C) 1997 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@@ -18,7 +18,10 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#include <wchar.h>
+/* Specify the conversion table. */
#define TABLES <latin-greek.h>
-#define NAME "LATIN-GREEK"
+
+#define CHARSET_NAME "LATIN-GREEK"
+#define HAS_HOLES 1 /* Not all 256 character are defined. */
+
#include <8bit-gap.c>
diff --git a/iconvdata/run-iconv-test.sh b/iconvdata/run-iconv-test.sh
index ebafa2f298..af6a136c4a 100755
--- a/iconvdata/run-iconv-test.sh
+++ b/iconvdata/run-iconv-test.sh
@@ -52,10 +52,18 @@ while read from to targets; do
{ echo "*** conversion from $t to $to failed"; exit 1; }
test -s $temp1 && cmp testdata/$from $temp2 >& /dev/null ||
{ echo "*** $from -> t -> $to conversion failed"; exit 1; }
+ rm -f $temp1 $temp2
+
+ # Now test some bigger text, entirely in ASCII.
+ $ICONV -f $from -t $t testdata/suntzus |
+ $ICONV -f $t -t $to > $temp1 ||
+ { echo "*** conversion $from->$t->$to of suntzus failed"; exit 1; }
+ cmp testdata/suntzus.txt $temp1 ||
+ { echo "*** conversion $from->$t->$to of suntzus incorrect"; exit 1; }
+ rm -f $temp1
# All tests ok.
echo "$from -> $t -> $to ok"
- rm -f $temp1 $temp2
done
done < TESTS
diff --git a/iconvdata/sjis.c b/iconvdata/sjis.c
index 33dc2f1d65..d65b905b32 100644
--- a/iconvdata/sjis.c
+++ b/iconvdata/sjis.c
@@ -18,12 +18,10 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#include <gconv.h>
#include <stdint.h>
-#include <string.h>
#include <wchar.h>
-static const wchar_t halfkana_to_ucs4[] =
+static const uint32_t halfkana_to_ucs4[] =
{
0xff61, 0xff62, 0xff63, 0xff64, 0xff65, 0xff66, 0xff67, 0xff68,
0xff69, 0xff6a, 0xff6b, 0xff6c, 0xff6d, 0xff6e, 0xff6f, 0xff70,
@@ -3981,268 +3979,151 @@ static const char from_ucs4_cjk[32657][2] =
};
-/* Direction of the transformation. */
-static int to_sjis_object;
-static int from_sjis_object;
+/* Definitions used in the body of the `gconv' function. */
+#define CHARSET_NAME "SJIS"
+#define FROM_LOOP from_sjis
+#define TO_LOOP to_sjis
+#define DEFINE_INIT 1
+#define DEFINE_FINI 1
+#define MIN_NEEDED_FROM 1
+#define MAX_NEEDED_FROM 2
+#define MIN_NEEDED_TO 4
+/* First define the conversion function from SJIS to UCS4. */
+#define MIN_NEEDED_INPUT MIN_NEEDED_FROM
+#define MAX_NEEDED_INPUT MAX_NEEDED_FROM
+#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
+#define LOOPFCT FROM_LOOP
+#define BODY \
+ { \
+ uint32_t ch = *inptr; \
+ \
+ if (ch == 0x5c) \
+ { \
+ ch = 0xa5; \
+ ++inptr; \
+ } \
+ else if (ch == 0x7e) \
+ { \
+ ch = 0x203e; \
+ ++inptr; \
+ } \
+ else if (ch < 0x7e) \
+ ++inptr; \
+ else if (ch >= 0xa1 && ch <= 0xdf) \
+ { \
+ ch = halfkana_to_ucs4[ch - 0xa1]; \
+ ++inptr; \
+ } \
+ else if (ch > 0xea || ch == 0xa0 || ch == 0x7f || ch == 0x80) \
+ { \
+ /* These are illegal. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ else \
+ { \
+ /* Two-byte character. First test whether the next character \
+ is also available. */ \
+ uint32_t ch2; \
+ uint_fast32_t idx; \
+ \
+ if (NEED_LENGTH_TEST && inptr + 1 >= inend) \
+ { \
+ /* The second character is not available. Store \
+ the intermediate result. */ \
+ result = GCONV_INCOMPLETE_INPUT; \
+ break; \
+ } \
+ \
+ ch2 = inptr[1]; \
+ idx = ch * 256 + ch2; \
+ if (idx < 0x8140 || (idx > 0x84be && idx < 0x889f) \
+ || (idx > 0x89fc && idx < 0x9040) \
+ || (idx > 0x9ffc && idx < 0xe040) || idx > 0xeaa4) \
+ { \
+ /* This is illegal. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ else \
+ { \
+ /* We could pack the data a bit more dense. The second \
+ byte will never be 0x7f and it will also be never \
+ >0xfc. But this would mean yet more `if's. */ \
+ if (idx <= 0x84be) \
+ ch = cjk_block1[(ch - 0x81) * 192 + ch2 - 0x40]; \
+ else if (idx <= 0x89fc) \
+ ch = cjk_block2[(ch - 0x88) * 192 + ch2 - 0x9f]; \
+ else if (idx <= 0x9ffc) \
+ ch = cjk_block3[(ch - 0x90) * 192 + ch2 - 0x40]; \
+ else \
+ ch = cjk_block4[(ch - 0xe0) * 192 + ch2 - 0x40]; \
+ } \
+ \
+ if (ch == 0) \
+ { \
+ /* This is an illegal character. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ } \
+ \
+ *((uint32_t *) outptr)++ = ch; \
+ }
+#include <iconv/loop.c>
-int
-gconv_init (struct gconv_step *step)
-{
- /* Determine which direction. */
- if (strcasestr (step->from_name, "SJIS") != NULL)
- step->data = &from_sjis_object;
- else if (strcasestr (step->to_name, "SJIS") != NULL)
- step->data = &to_sjis_object;
- else
- return GCONV_NOCONV;
-
- return GCONV_OK;
-}
-
-
-void
-gconv_end (struct gconv_step *data)
-{
- /* Nothing to do. */
-}
-
-
-int
-gconv (struct gconv_step *step, struct gconv_step_data *data,
- const char *inbuf, size_t *inbufsize, 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;
- 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)
- {
- do_write = 0;
-
- /* Call the steps down the chain if there are any. */
- if (data->is_last)
- result = GCONV_OK;
- else
- {
- result = (*fct) (next_step, next_data, NULL, 0, written, 1);
-
- /* Clear output buffer. */
- data->outbufavail = 0;
- }
- }
- else
- {
- do_write = 0;
-
- do
- {
- result = GCONV_OK;
-
- if (step->data == &from_sjis_object)
- {
- size_t inchars = *inbufsize;
- size_t outwchars = data->outbufavail;
- char *outbuf = data->outbuf;
- size_t cnt = 0;
-
- while (cnt < inchars
- && (outwchars + sizeof (wchar_t) <= data->outbufsize))
- {
- int inchar = inbuf[cnt];
- wchar_t ch;
-
- if (inchar == 0x5c)
- ch = L'\xa5';
- else if (inchar == 0x7e)
- ch = 0x203e;
- else if (inchar < 0x7e)
- ch = (wchar_t) inchar;
- else if (inchar >= 0xa1 && inchar <= 0xdf)
- ch = halfkana_to_ucs4[inchar - 0xa1];
- else if (inchar > 0xea || inchar == 0xa0 || inchar == 0x7f
- || inchar == 0x80)
- /* These are illegal. */
- ch = L'\0';
- else
- {
- /* Two-byte character. First test whether the next
- character is also available. */
- int inchar2;
- int idx;
-
- if (cnt + 1 >= inchars)
- {
- /* The second character is not available. Store
- the intermediate result. */
- result = GCONV_INCOMPLETE_INPUT;
- break;
- }
-
- inchar2 = inbuf[++cnt];
- idx = inchar * 256 + inchar2;
- if (idx < 0x8140 || (idx > 0x84be && idx < 0x889f)
- || (idx > 0x89fc && idx < 0x9040)
- || (idx > 0x9ffc && idx < 0xe040) || idx > 0xeaa4)
- /* This is illegal. */
- ch = L'\0';
- else
- {
- /* We could pack the data a bit more dense.
- The second byte will never be 0x7f and it
- will also be never >0xfc. But this would
- mean yet more `if's. */
- if (idx <= 0x84be)
- ch = cjk_block1[(inchar - 0x81) * 192
- + inchar2 - 0x40];
- else if (idx <= 0x89fc)
- ch = cjk_block2[(inchar - 0x88) * 192
- + inchar2 - 0x9f];
- else if (idx <= 0x9ffc)
- ch = cjk_block3[(inchar - 0x90) * 192
- + inchar2 - 0x40];
- else
- ch = cjk_block4[(inchar - 0xe0) * 192
- + inchar2 - 0x40];
- }
-
- if (ch == L'\0')
- --cnt;
- }
-
- if (ch == L'\0' && inbuf[cnt] != '\0')
- {
- /* This is an illegal character. */
- result = GCONV_ILLEGAL_INPUT;
- break;
- }
-
- *((wchar_t *) (outbuf + outwchars)) = ch;
- ++do_write;
- outwchars += sizeof (wchar_t);
- ++cnt;
- }
- *inbufsize -= cnt;
- inbuf += cnt;
- data->outbufavail = outwchars;
- }
- else
- {
- size_t inwchars = *inbufsize;
- size_t outchars = data->outbufavail;
- char *outbuf = data->outbuf;
- size_t cnt = 0;
- int extra = 0;
-
- while (inwchars >= cnt + sizeof (wchar_t)
- && outchars < data->outbufsize)
- {
- int ch = *((wchar_t *) (inbuf + cnt));
- const char *cp;
-
- if (ch >= (sizeof (from_ucs4_lat1)
- / sizeof (from_ucs4_lat1[0])))
- {
- if (ch >= 0x0391 && ch <= 0x0451)
- cp = from_ucs4_greek[ch - 0x391];
- else if (ch >= 0x2010 && ch <= 0x9fa0)
- cp = from_ucs4_cjk[ch - 0x02010];
- else
- /* Illegal character. */
- break;
- }
- else
- cp = from_ucs4_lat1[ch];
-
- if (cp[0] == '\0' && ch != 0)
- /* Illegal character. */
- break;
-
- outbuf[outchars] = cp[0];
- /* Now test for a possible second byte and write this
- if possible. */
- if (cp[1] != '\0')
- {
- if (outchars + 1 >= data->outbufsize)
- {
- /* The result does not fit into the buffer. */
- extra = 1;
- break;
- }
- outbuf[++outchars] = cp[1];
- }
-
- ++do_write;
- ++outchars;
- cnt += sizeof (wchar_t);
- }
- *inbufsize -= cnt;
- inbuf += cnt;
- data->outbufavail = outchars;
-
- if (outchars + extra < data->outbufsize)
- {
- /* If there is still room in the output buffer something
- is wrong with the input. */
- if (inwchars >= cnt + sizeof (wchar_t))
- {
- /* An error occurred. */
- result = GCONV_ILLEGAL_INPUT;
- break;
- }
- if (inwchars != cnt)
- {
- /* There are some unprocessed bytes at the end of the
- input buffer. */
- result = GCONV_INCOMPLETE_INPUT;
- break;
- }
- }
- }
-
- if (result != GCONV_OK)
- break;
-
- if (data->is_last)
- {
- /* This is the last step. */
- result = (*inbufsize > (step->data == &from_sjis_object
- ? 0 : sizeof (wchar_t) - 1)
- ? GCONV_FULL_OUTPUT : GCONV_EMPTY_INPUT);
- 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 (*inbufsize > 0 && result == GCONV_EMPTY_INPUT);
- }
+/* Next, define the other direction. */
+#define MIN_NEEDED_INPUT MIN_NEEDED_TO
+#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM
+#define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM
+#define LOOPFCT TO_LOOP
+#define BODY \
+ { \
+ uint32_t ch = *((uint32_t *) inptr); \
+ const char *cp; \
+ \
+ if (ch >= (sizeof (from_ucs4_lat1) / sizeof (from_ucs4_lat1[0]))) \
+ { \
+ if (ch >= 0x0391 && ch <= 0x0451) \
+ cp = from_ucs4_greek[ch - 0x391]; \
+ else if (ch >= 0x2010 && ch <= 0x9fa0) \
+ cp = from_ucs4_cjk[ch - 0x02010]; \
+ else \
+ { \
+ /* Illegal character. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ } \
+ else \
+ cp = from_ucs4_lat1[ch]; \
+ \
+ if (cp[0] == '\0' && ch != 0) \
+ { \
+ /* Illegal character. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ \
+ *outptr++ = cp[0]; \
+ /* Now test for a possible second byte and write this if possible. */ \
+ if (cp[1] != '\0') \
+ { \
+ if (NEED_LENGTH_TEST && outptr >= outend) \
+ { \
+ /* The result does not fit into the buffer. */ \
+ result = GCONV_FULL_OUTPUT; \
+ break; \
+ } \
+ *outptr++ = cp[1]; \
+ } \
+ \
+ inptr += 4; \
+ }
+#include <iconv/loop.c>
- if (written != NULL && data->is_last)
- *written = do_write;
- return result;
-}
+/* Now define the toplevel functions. */
+#include <iconv/skeleton.c>
diff --git a/iconvdata/t61.c b/iconvdata/t61.c
index b77ee71248..8c288adca2 100644
--- a/iconvdata/t61.c
+++ b/iconvdata/t61.c
@@ -19,6 +19,7 @@
Boston, MA 02111-1307, USA. */
#include <gconv.h>
+#include <stdint.h>
#include <string.h>
/* Data taken from the WG15 tables. */
@@ -362,248 +363,133 @@ static const char from_ucs4[][2] =
*/
};
-/* Direction of the transformation. */
-static int to_t61_object;
-static int from_t61_object;
+/* Definitions used in the body of the `gconv' function. */
+#define CHARSET_NAME "T.61"
+#define FROM_LOOP from_t_61
+#define TO_LOOP to_t_61
+#define DEFINE_INIT 1
+#define DEFINE_FINI 1
+#define MIN_NEEDED_FROM 1
+#define MAX_NEEDED_FROM 2
+#define MIN_NEEDED_TO 4
+
+/* First define the conversion function from T.61 to UCS4. */
+#define MIN_NEEDED_INPUT MIN_NEEDED_FROM
+#define MAX_NEEDED_INPUT MAX_NEEDED_FROM
+#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
+#define LOOPFCT FROM_LOOP
+#define BODY \
+ { \
+ uint32_t ch = *inptr; \
+ \
+ if (ch >= 0xc1 && ch <= 0xcf) \
+ { \
+ /* Composed character. First test whether the next character \
+ is also available. */ \
+ uint32_t ch2; \
+ \
+ if (NEED_LENGTH_TEST && inptr + 1 >= inend) \
+ { \
+ /* The second character is not available. */ \
+ result = GCONV_INCOMPLETE_INPUT; \
+ break; \
+ } \
+ \
+ ch2 = inptr[1]; \
+ \
+ if (ch2 < 0x20 || ch2 >= 0x80) \
+ { \
+ /* This is illegal. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ \
+ ch = to_ucs4_comb[ch - 0xc1][ch2 - 0x20]; \
+ \
+ inptr += 2; \
+ } \
+ else \
+ { \
+ ch = to_ucs4[ch]; \
+ ++inptr; \
+ } \
+ \
+ if (ch == 0 && *inptr != '\0') \
+ { \
+ /* This is an illegal character. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ \
+ *((uint32_t *) outptr)++ = ch; \
+ }
+#include <iconv/loop.c>
+
+
+/* Next, define the other direction. */
+#define MIN_NEEDED_INPUT MIN_NEEDED_TO
+#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM
+#define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM
+#define LOOPFCT TO_LOOP
+#define BODY \
+ { \
+ char tmp[2]; \
+ uint32_t ch = *((uint32_t *) inptr); \
+ const char *cp; \
+ \
+ if (ch >= sizeof (from_ucs4) / sizeof (from_ucs4[0])) \
+ { \
+ if (ch == 0x2126) \
+ cp = "\xe0"; \
+ else if (ch == 0x2c7) \
+ cp = "\xcf\x20"; \
+ else if (ch < 0x2d8 || ch > 0x2dd) \
+ { \
+ /* Illegal characters. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ else \
+ { \
+ static const char map[5] = "\xc6\xc7\xca\xce\xcd"; \
+ \
+ tmp[0] = map[ch - 0x2d8]; \
+ tmp[1] = ' '; \
+ cp = tmp; \
+ } \
+ } \
+ else \
+ { \
+ cp = from_ucs4[ch]; \
+ \
+ if (cp[0] == '\0' && ch != 0) \
+ { \
+ /* Illegal. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ } \
+ \
+ *outptr++ = cp[0]; \
+ /* Now test for a possible second byte and write this if possible. */ \
+ if (cp[1] != '\0') \
+ { \
+ if (NEED_LENGTH_TEST && outptr >= outend) \
+ { \
+ /* The result does not fit into the buffer. */ \
+ --outptr; \
+ result = GCONV_FULL_OUTPUT; \
+ break; \
+ } \
+ \
+ *outptr++ = cp[1]; \
+ } \
+ \
+ inptr += 4; \
+ }
+#include <iconv/loop.c>
-int
-gconv_init (struct gconv_step *step)
-{
- /* Determine which direction. */
- if (strcasestr (step->from_name, "T.61") != NULL)
- step->data = &from_t61_object;
- else if (strcasestr (step->to_name, "T.61") != NULL)
- step->data = &to_t61_object;
- else
- return GCONV_NOCONV;
-
- return GCONV_OK;
-}
-
-
-void
-gconv_end (struct gconv_step *data)
-{
- /* Nothing to do. */
-}
-
-
-int
-gconv (struct gconv_step *step, struct gconv_step_data *data,
- const char *inbuf, size_t *inbufsize, 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;
- 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)
- {
- do_write = 0;
-
- /* 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
- {
- do_write = 0;
-
- do
- {
- result = GCONV_OK;
-
- if (step->data == &from_t61_object)
- {
- size_t inchars = *inbufsize;
- size_t outwchars = data->outbufavail;
- char *outbuf = data->outbuf;
- size_t cnt = 0;
-
- while (cnt < inchars
- && (outwchars + sizeof (wchar_t) <= data->outbufsize))
- {
- int inchar = inbuf[cnt];
- wchar_t ch;
-
- if (inchar >= '\xc1' && inchar <= '\xcf')
- {
- /* Composed character. First test whether the next
- character is also available. */
- int inchar2;
-
- if (cnt + 1 >= inchars)
- {
- /* The second character is not available. Store
- the intermediate result. */
- result = GCONV_INCOMPLETE_INPUT;
- break;
- }
-
- inchar2 = inbuf[++cnt];
-
- if (inchar2 < '\x20' || inchar2 >= '\x80')
- /* This is illegal. */
- ch = L'\0';
- else
- ch = to_ucs4_comb[inchar - 0xc1][inchar2 - 0x20];
-
- if (ch == L'\0')
- /* Undo the increment for illegal characters. */
- --cnt;
- }
- else
- ch = to_ucs4[inchar];
-
- if (ch == L'\0' && inbuf[cnt] != '\0')
- {
- /* This is an illegal character. */
- result = GCONV_ILLEGAL_INPUT;
- break;
- }
-
- *((wchar_t *) (outbuf + outwchars)) = ch;
- ++do_write;
- outwchars += sizeof (wchar_t);
- ++cnt;
- }
- *inbufsize -= cnt;
- inbuf += cnt;
- data->outbufavail = outwchars;
- }
- else
- {
- size_t inwchars = *inbufsize;
- size_t outchars = data->outbufavail;
- char *outbuf = data->outbuf;
- size_t cnt = 0;
- int extra = 0;
-
- while (inwchars >= cnt + sizeof (wchar_t)
- && outchars < data->outbufsize)
- {
- char tmp[2];
- int ch = *((wchar_t *) (inbuf + cnt));
- const char *cp;
-
- if (ch >= sizeof (from_ucs4) / sizeof (from_ucs4[0]))
- {
- if (ch == 0x2126)
- cp = "\xe0";
- else if (ch == 0x2c7)
- cp = "\xcf\x20";
- else if (ch < 0x2d8 || ch > 0x2dd)
- /* Illegal characters. */
- break;
- else
- {
- static const char map[5] = "\xc6\xc7\xca\xce\xcd";
-
- tmp[0] = map[ch - 0x2d8];
- tmp[1] = ' ';
- cp = tmp;
- }
- }
- else if (ch < 0 || (from_ucs4[ch][0] == '\0' && ch != 0))
- break;
- else
- cp = from_ucs4[ch];
-
- outbuf[outchars] = cp[0];
- /* Now test for a possible second byte and write this
- if possible. */
- if (cp[1] != '\0')
- {
- if (outchars + 1 >= data->outbufsize)
- {
- /* The result does not fit into the buffer. */
- extra = 1;
- break;
- }
- outbuf[++outchars] = cp[1];
- }
-
- ++do_write;
- ++outchars;
- cnt += sizeof (wchar_t);
- }
- *inbufsize -= cnt;
- inbuf += cnt;
- data->outbufavail = outchars;
-
- if (outchars + extra < data->outbufsize)
- {
- /* If there is still room in the output buffer something
- is wrong with the input. */
- if (inwchars >= cnt + sizeof (wchar_t))
- {
- /* An error occurred. */
- result = GCONV_ILLEGAL_INPUT;
- break;
- }
- if (inwchars != cnt)
- {
- /* There are some unprocessed bytes at the end of the
- input buffer. */
- result = GCONV_INCOMPLETE_INPUT;
- break;
- }
- }
- }
-
- if (result != GCONV_OK)
- break;
-
- if (data->is_last)
- {
- /* This is the last step. */
- result = (*inbufsize > (step->data == &from_t61_object
- ? 0 : sizeof (wchar_t) - 1)
- ? GCONV_FULL_OUTPUT : GCONV_EMPTY_INPUT);
- 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 (*inbufsize > 0 && result == GCONV_EMPTY_INPUT);
- }
-
- if (written != NULL && data->is_last)
- *written = do_write;
- return result;
-}
+/* Now define the toplevel functions. */
+#include <iconv/skeleton.c>
diff --git a/iconvdata/uhc.c b/iconvdata/uhc.c
index ed4b7adb70..f3addd4c4d 100644
--- a/iconvdata/uhc.c
+++ b/iconvdata/uhc.c
@@ -18,16 +18,9 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#include <gconv.h>
#include <stdint.h>
-#include <string.h>
-#include <wchar.h>
#include <ksc5601.h>
-/* Direction of the transformation. */
-static int to_uhc_object;
-static int from_uhc_object;
-
/*
egrep \
@@ -2576,20 +2569,20 @@ static const uint16_t uhc_hangul_from_ucs[11172]=
0xc64f, 0xc650, 0xc651, 0xc652
};
+
static inline void
-uhc_from_ucs4(wchar_t ch, unsigned char *cp)
+uhc_from_ucs4 (uint32_t ch, unsigned char *cp)
{
if (ch >= 0x7f)
{
uint16_t idx=0;
if (ch >= 0xac00 && ch <= 0xd7a3)
- idx = uhc_hangul_from_ucs[(int) ch - 0xac00];
- else if (ch >= 0x4e00 && ch <= 0x9fa5
- || ch >= 0xf900 && ch <= 0xfa0b)
+ idx = uhc_hangul_from_ucs[ch - 0xac00];
+ else if (ch >= 0x4e00 && ch <= 0x9fa5 || ch >= 0xf900 && ch <= 0xfa0b)
{
ucs4_to_ksc5601_hanja (ch,&idx);
- idx |= (idx ? 0x8080 : 0);
+ idx |= (idx ? 0x8080 : 0);
}
/* Half-width Korean Currency Won Sign
else if (ch == 0x20a9)
@@ -2598,286 +2591,169 @@ uhc_from_ucs4(wchar_t ch, unsigned char *cp)
else
{
ucs4_to_ksc5601_sym (ch, &idx);
- idx |= (idx ? 0x8080 : 0);
+ idx |= (idx ? 0x8080 : 0);
}
- *cp = (char) (idx / 256);
- *(cp + 1) = (char) (idx & 0xff) ;
+ cp[0] = (unsigned char) (idx / 256);
+ cp[1] = (unsigned char) (idx & 0xff);
}
- /* think about 0x5c ; '\' */
+ /* XXX Think about 0x5c ; '\'. */
else
{
- *cp = (char) (0x7f & ch) ;
- *(cp + 1) = (char) 0;
+ cp[0] = (unsigned char) ch;
+ cp[1] = (unsigned char) 0;
}
}
-int
-gconv_init (struct gconv_step *step)
-{
- /* Determine which direction. */
- if (strcasestr (step->from_name, "UHC") != NULL)
- step->data = &from_uhc_object;
- else if (strcasestr (step->to_name, "UHC") != NULL)
- step->data = &to_uhc_object;
- else
- return GCONV_NOCONV;
-
- return GCONV_OK;
-}
-
-
-void
-gconv_end (struct gconv_step *data)
-{
- /* Nothing to do. */
-}
-
-
-int
-gconv (struct gconv_step *step, struct gconv_step_data *data,
- const char *inbuf, size_t *inbufsize, 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;
- 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)
- {
- do_write = 0;
-
- /* 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
- {
- do_write = 0;
-
- do
- {
- result = GCONV_OK;
-
- if (step->data == &from_uhc_object)
- {
- size_t inchars = *inbufsize;
- size_t outwchars = data->outbufavail;
- char *outbuf = data->outbuf;
- size_t cnt = 0;
-
- while (cnt < inchars
- && (outwchars + sizeof (wchar_t) <= data->outbufsize))
- {
- int inchar = (unsigned char) inbuf[cnt];
- wchar_t ch;
-/* half-width Korean Currency WON sign
-
- if (inchar == 0x5c)
- ch = 0x20a9;
- else if (inchar <= 0x7f)
- ch = (wchar_t) inchar;
-*/
- if (inchar <= 0x7f)
- ch = (wchar_t) inchar;
-
-
- else if ( inchar <= 0x80 || inchar >= 0xfe || inchar == 0xc9)
- /* This is illegal. */
- ch = L'\0';
- else
- {
- /* Two-byte character. First test whether the next
- character is also available. */
- int inchar2;
-
- if (cnt + 1 >= inchars)
- {
- /* The second character is not available. Store
- the intermediate result. */
- result = GCONV_INCOMPLETE_INPUT;
- break;
- }
-
- inchar2 = (unsigned char) inbuf[++cnt];
-
-/*
- Additional code points not present in EUC-KR
-
- 1st byte 2nd byte
- 0x81-0xa0 0x41-0x5a, 0x61-0x7a, 0x81-0xfe total
- (32) (26) + (26) + (126) = 178 5696
-
- 0xa1-0xc5 0x41-0x5a 0x61-0x7a 0x81-0xa0
- (37) (26) + (26) + (32) = 84 3108
-
- 0xc6 0x41-0x52
- (1) (18) 18
-
- 8822
-
-
- 8822(only in UHC) + 2350(both in EUC-KR and UHC) = 11,172
-*/
-
- if ( inchar < 0xa1 || inchar2 < 0xa1)
- if ( inchar > 0xc6 || inchar2 <0x41 ||
- inchar2 > 0x5a && inchar2 < 0x61 ||
- inchar2 > 0x7a && inchar2 < 0x81 ||
- inchar == 0xc6 && inchar2 > 0x52 )
- ch = L'0';
- else
- {
- ch = uhc_extra_to_ucs[ inchar2 - 0x41
- - ( inchar2 > 0x80 ? 12 :
- ( inchar2 > 0x60 ? 6 : 0 ) )
- + ( inchar < 0xa1 ?
- (inchar - 0x81) * 178 :
- 5696 + (inchar - 0xa1) * 84 ) ] ;
- }
-
- else
- if ( ( ch = ksc5601_to_ucs4(
- (uint16_t) (inchar * 256 + inchar2) & 0x7f7f) )
- == UNKNOWN_10646_CHAR )
-
- ch = L'\0';
-
- if (ch == L'\0')
- --cnt;
- }
-
- if (ch == L'\0' && inbuf[cnt] != '\0')
- {
- /* This is an illegal character. */
- result = GCONV_ILLEGAL_INPUT;
- break;
- }
-
- *((wchar_t *) (outbuf + outwchars)) = ch;
- ++do_write;
- outwchars += sizeof (wchar_t);
- ++cnt;
- }
- *inbufsize -= cnt;
- inbuf += cnt;
- data->outbufavail = outwchars;
- }
- else
- {
- size_t inwchars = *inbufsize;
- size_t outchars = data->outbufavail;
- char *outbuf = data->outbuf;
- size_t cnt = 0;
- int extra = 0;
-
- while (inwchars >= cnt + sizeof (wchar_t)
- && outchars < data->outbufsize)
- {
- wchar_t ch = *((wchar_t *) (inbuf + cnt));
- unsigned char cp[2];
-
- uhc_from_ucs4(ch,cp) ;
-
- if (cp[0] == '\0' && ch != 0)
- /* Illegal character. */
- break;
-
- outbuf[outchars] = cp[0];
- /* Now test for a possible second byte and write this
- if possible. */
- if (cp[1] != '\0')
- {
- if (outchars + 1 >= data->outbufsize)
- {
- /* The result does not fit into the buffer. */
- extra = 1;
- break;
- }
- outbuf[++outchars] = cp[1];
- }
-
- ++do_write;
- ++outchars;
- cnt += sizeof (wchar_t);
- }
- *inbufsize -= cnt;
- inbuf += cnt;
- data->outbufavail = outchars;
-
- if (outchars + extra < data->outbufsize)
- {
- /* If there is still room in the output buffer something
- is wrong with the input. */
- if (inwchars >= cnt + sizeof (wchar_t))
- {
- /* An error occurred. */
- result = GCONV_ILLEGAL_INPUT;
- break;
- }
- if (inwchars != cnt)
- {
- /* There are some unprocessed bytes at the end of the
- input buffer. */
- result = GCONV_INCOMPLETE_INPUT;
- break;
- }
- }
- }
-
- if (result != GCONV_OK)
- break;
-
- if (data->is_last)
- {
- /* This is the last step. */
- result = (*inbufsize > (step->data == &from_uhc_object
- ? 0 : sizeof (wchar_t) - 1)
- ? GCONV_FULL_OUTPUT : GCONV_EMPTY_INPUT);
- 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 (*inbufsize > 0 && result == GCONV_EMPTY_INPUT);
- }
-
- if (written != NULL && data->is_last)
- *written = do_write;
-
- return result;
-}
+/* Definitions used in the body of the `gconv' function. */
+#define CHARSET_NAME "UHC"
+#define FROM_LOOP from_uhc
+#define TO_LOOP to_uhc
+#define DEFINE_INIT 1
+#define DEFINE_FINI 1
+#define MIN_NEEDED_FROM 1
+#define MAX_NEEDED_FROM 2
+#define MIN_NEEDED_TO 4
+
+/* First define the conversion function from UHC to UCS4. */
+#define MIN_NEEDED_INPUT MIN_NEEDED_FROM
+#define MAX_NEEDED_INPUT MAX_NEEDED_FROM
+#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
+#define LOOPFCT FROM_LOOP
+#define BODY \
+ { \
+ uint32_t ch = (uint32_t) *inptr; \
+ \
+/* half-width Korean Currency WON sign \
+ \
+ if (ch == 0x5c) \
+ ch = 0x20a9; \
+ else if (ch <= 0x7f) \
+ ch = (wchar_t) ch; \
+*/ \
+ if (ch <= 0x7f) \
+ ++inptr; \
+ else if (ch <= 0x80 || ch >= 0xfe || ch == 0xc9) \
+ { \
+ /* This is illegal. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ else \
+ { \
+ /* Two-byte character. First test whether the next character \
+ is also available. */ \
+ uint32_t ch2; \
+ \
+ if (NEED_LENGTH_TEST && inptr + 1 >= inend) \
+ { \
+ /* The second character is not available. Store \
+ the intermediate result. */ \
+ result = GCONV_INCOMPLETE_INPUT; \
+ break; \
+ } \
+ \
+ ch2 = inptr[1]; \
+ \
+/* \
+ Additional code points not present in EUC-KR \
+ \
+ 1st byte 2nd byte \
+ 0x81-0xa0 0x41-0x5a, 0x61-0x7a, 0x81-0xfe total \
+ (32) (26) + (26) + (126) = 178 5696 \
+ \
+ 0xa1-0xc5 0x41-0x5a 0x61-0x7a 0x81-0xa0 \
+ (37) (26) + (26) + (32) = 84 3108 \
+ \
+ 0xc6 0x41-0x52 \
+ (1) (18) 18 \
+ \
+ 8822 \
+ \
+ 8822(only in UHC) + 2350(both in EUC-KR and UHC) = 11,172 \
+*/ \
+ \
+ if (ch < 0xa1 || ch2 < 0xa1) \
+ { \
+ if (ch > 0xc6 || ch2 <0x41 || (ch2 > 0x5a && ch2 < 0x61) \
+ || (ch2 > 0x7a && ch2 < 0x81) || (ch == 0xc6 && ch2 > 0x52)) \
+ { \
+ /* This is not legal. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ \
+ ch = uhc_extra_to_ucs[ch2 - 0x41 \
+ - (ch2 > 0x80 ? 12 : (ch2 > 0x60 ? 6 : 0)) \
+ + (ch < 0xa1 \
+ ? (ch - 0x81) * 178 \
+ : 5696 + (ch - 0xa1) * 84)]; \
+ } \
+ else \
+ { \
+ ch = ksc5601_to_ucs4 ((ch * 256 + ch2) & 0x7f7f); \
+ \
+ if (ch == UNKNOWN_10646_CHAR) \
+ { \
+ /* Illegal. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ } \
+ \
+ if (ch == 0) \
+ { \
+ /* This is an illegal character. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ \
+ inptr += 2; \
+ } \
+ \
+ *((uint32_t *) outptr)++ = ch; \
+ }
+#include <iconv/loop.c>
+
+
+/* Next, define the other direction. */
+#define MIN_NEEDED_INPUT MIN_NEEDED_TO
+#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM
+#define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM
+#define LOOPFCT TO_LOOP
+#define BODY \
+ { \
+ uint32_t ch = *((uint32_t *) inptr); \
+ unsigned char cp[2]; \
+ \
+ uhc_from_ucs4 (ch, cp); \
+ \
+ if (cp[0] == '\0' && ch != 0) \
+ { \
+ /* Illegal character. */ \
+ result = GCONV_ILLEGAL_INPUT; \
+ break; \
+ } \
+ \
+ *outptr++ = cp[0]; \
+ /* Now test for a possible second byte and write this if possible. */ \
+ if (cp[1] != '\0') \
+ { \
+ if (NEED_LENGTH_TEST && outptr >= outend) \
+ { \
+ /* The result does not fit into the buffer. */ \
+ result = GCONV_FULL_OUTPUT; \
+ break; \
+ } \
+ \
+ *outptr++ = cp[1]; \
+ } \
+ \
+ inptr += 4; \
+ }
+#include <iconv/loop.c>
+
+
+/* Now define the toplevel functions. */
+#include <iconv/skeleton.c>
diff --git a/inet/netinet/in.h b/inet/netinet/in.h
index ff8476e5c7..c6985ffa0a 100644
--- a/inet/netinet/in.h
+++ b/inet/netinet/in.h
@@ -277,6 +277,22 @@ extern uint16_t htons __P ((uint16_t __hostshort));
extern int bindresvport __P ((int __sockfd, struct sockaddr_in *__sock_in));
+
+#define IN6_IS_ADDR_MC_NODELOCAL(a) \
+ (IN6_IS_ADDR_MULTICAST(a) && ((((u_int8_t *) (a))[1] & 0xf) == 0x1))
+
+#define IN6_IS_ADDR_MC_LINKLOCAL(a) \
+ (IN6_IS_ADDR_MULTICAST(a) && ((((u_int8_t *) (a))[1] & 0xf) == 0x2))
+
+#define IN6_IS_ADDR_MC_SITELOCAL(a) \
+ (IN6_IS_ADDR_MULTICAST(a) && ((((u_int8_t *) (a))[1] & 0xf) == 0x5))
+
+#define IN6_IS_ADDR_MC_ORGLOCAL(a) \
+ (IN6_IS_ADDR_MULTICAST(a) && ((((u_int8_t *) (a))[1] & 0xf) == 0x8))
+
+#define IN6_IS_ADDR_MC_GLOBAL(a) \
+ (IN6_IS_ADDR_MULTICAST(a) && ((((u_int8_t *) (a))[1] & 0xf) == 0xe))
+
/* IPv6 packet information. */
struct in6_pktinfo
{
diff --git a/libc.map b/libc.map
index 6a40713d81..bc3c28660e 100644
--- a/libc.map
+++ b/libc.map
@@ -100,11 +100,12 @@ GLIBC_2.0 {
__vsscanf; __vfscanf; __vsnprintf;
_rpc_dtablesize; _null_auth; _seterr_reply;
__res_randomid; __getpid;
- __strcasecmp; __write; _strerror_internal; _dl_sysdep_output;
+ __strcasecmp; __strerror_r; __write; _dl_sysdep_output;
_dl_debug_message;
__ffs;
__close; __connect; __fcntl; __lseek; __open; __read; __send; __wait;
__ieee_get_fp_control; __ieee_set_fp_control;
+ __dgettext;
# Exception handling support functions from libgcc
__register_frame; __register_frame_table; __deregister_frame;
@@ -440,13 +441,14 @@ GLIBC_2.1 {
__signbit; __signbitf; __signbitl; __libc_sa_len;
# functions used in other libraries
- _IO_fclose; _IO_fopen; _IO_fdopen; __asprintf;
+ _IO_fclose; _IO_fopen; _IO_fdopen; __asprintf; __strcasestr;
__syscall_rt_sigqueueinfo;
__xstat64; __fxstat64; __lxstat64;
__pread64; __pwrite64;
# helper functions
__libc_current_sigrtmin; __libc_current_sigrtmax; __libc_allocate_rtsig;
+ __libc_longjmp; __libc_siglongjmp;
# Since we have new signals this structure changed.
_sys_siglist; sys_siglist; sys_sigabbrev;
diff --git a/libio/fileops.c b/libio/fileops.c
index 7e60f7c8df..e5ffb245aa 100644
--- a/libio/fileops.c
+++ b/libio/fileops.c
@@ -48,7 +48,6 @@ extern int errno;
# define lseek(FD, Offset, Whence) __lseek (FD, Offset, Whence)
# define read(FD, Buf, NBytes) __read (FD, Buf, NBytes)
# define write(FD, Buf, NBytes) __write (FD, Buf, NBytes)
-# define fstat(FD, Buf) __fxstat (_STAT_VER, FD, Buf)
#endif
/* An fstream can be in at most one of put mode, get mode, or putback mode.
diff --git a/libio/oldfileops.c b/libio/oldfileops.c
index 41fbc692e8..7cf4fdf22c 100644
--- a/libio/oldfileops.c
+++ b/libio/oldfileops.c
@@ -483,7 +483,7 @@ _IO_old_file_seekoff (fp, offset, dir, mode)
break;
case _IO_seek_end:
{
- struct stat st;
+ struct _G_stat64 st;
if (_IO_SYSSTAT (fp, &st) == 0 && S_ISREG (st.st_mode))
{
offset += st.st_size;
diff --git a/linuxthreads/ChangeLog b/linuxthreads/ChangeLog
index 7913e085f1..ba2a20f4d0 100644
--- a/linuxthreads/ChangeLog
+++ b/linuxthreads/ChangeLog
@@ -1,3 +1,14 @@
+1998-04-20 14:55 Ulrich Drepper <drepper@cygnus.com>
+
+ * Makefile (libpthread-routines): Add ptlongjmp and spinlock.
+ * internals.h: Add definitions for new spinlock implementation.
+ * ptlongjmp.c: New file.
+ * spinlock.c: New file.
+ * spinlock.h (acquire): Don't reschedule using __sched_yield, use
+ new function __pthread_acquire to prevent deadlocks with thread
+ with different priorities.
+ Patches by Xavier Leroy <Xavier.Leroy@inria.fr>.
+
1998-03-16 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
* manager.c (__pthread_manager): Reduce first argument to select
diff --git a/linuxthreads/Makefile b/linuxthreads/Makefile
index 8813ae110f..cdfe06c66e 100644
--- a/linuxthreads/Makefile
+++ b/linuxthreads/Makefile
@@ -32,8 +32,8 @@ extra-libs := libpthread
extra-libs-others := $(extra-libs)
libpthread-routines := attr cancel condvar join manager mutex ptfork \
- pthread signals specific errno lockfile \
- semaphore wrapsyscall rwlock
+ ptlongjmp pthread signals specific errno lockfile \
+ semaphore spinlock wrapsyscall rwlock
libpthread-map := libpthread.map
include ../Rules
diff --git a/linuxthreads/internals.h b/linuxthreads/internals.h
index 0649e0d460..c56829684e 100644
--- a/linuxthreads/internals.h
+++ b/linuxthreads/internals.h
@@ -250,6 +250,23 @@ static inline pthread_descr thread_self (void)
#endif
}
+/* Max number of times we must spin on a spinlock calling sched_yield().
+ After MAX_SPIN_COUNT iterations, we put the calling thread to sleep. */
+
+#ifndef MAX_SPIN_COUNT
+#define MAX_SPIN_COUNT 50
+#endif
+
+/* Duration of sleep (in nanoseconds) when we can't acquire a spinlock
+ after MAX_SPIN_COUNT iterations of sched_yield().
+ With the 2.0 and 2.1 kernels, this MUST BE > 2ms.
+ (Otherwise the kernel does busy-waiting for realtime threads,
+ giving other threads no chance to run.) */
+
+#ifndef SPIN_SLEEP_DURATION
+#define SPIN_SLEEP_DURATION 2000001
+#endif
+
/* Debugging */
#ifdef DEBUG
diff --git a/linuxthreads/ptlongjmp.c b/linuxthreads/ptlongjmp.c
new file mode 100644
index 0000000000..1397dba43a
--- /dev/null
+++ b/linuxthreads/ptlongjmp.c
@@ -0,0 +1,44 @@
+/* Linuxthreads - a simple clone()-based implementation of Posix */
+/* threads for Linux. */
+/* Copyright (C) 1998 Xavier Leroy (Xavier.Leroy@inria.fr) */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU Library General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU Library General Public License for more details. */
+
+/* Redefine siglongjmp and longjmp so that they interact correctly
+ with cleanup handlers */
+
+#include <setjmp.h>
+#include "pthread.h"
+#include "internals.h"
+
+static void pthread_cleanup_upto(__jmp_buf target)
+{
+ pthread_descr self = thread_self();
+ struct _pthread_cleanup_buffer * c;
+
+ for (c = self->p_cleanup;
+ c != NULL && _JMPBUF_UNWINDS(target, c);
+ c = c->prev)
+ c->routine(c->arg);
+ self->p_cleanup = c;
+}
+
+void siglongjmp(sigjmp_buf env, int val)
+{
+ pthread_cleanup_upto(env->__jmpbuf);
+ __libc_siglongjmp(env, val);
+}
+
+void longjmp(jmp_buf env, int val)
+{
+ pthread_cleanup_upto(env->__jmpbuf);
+ __libc_longjmp(env, val);
+}
diff --git a/linuxthreads/spinlock.c b/linuxthreads/spinlock.c
new file mode 100644
index 0000000000..170d9ae8d0
--- /dev/null
+++ b/linuxthreads/spinlock.c
@@ -0,0 +1,59 @@
+/* Linuxthreads - a simple clone()-based implementation of Posix */
+/* threads for Linux. */
+/* Copyright (C) 1998 Xavier Leroy (Xavier.Leroy@inria.fr) */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU Library General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU Library General Public License for more details. */
+
+/* Spin locks */
+
+#include <sched.h>
+#include <time.h>
+#include "pthread.h"
+#include "internals.h"
+#include "spinlock.h"
+
+/* This function is called if the inlined test-and-set in acquire() failed */
+
+/* The retry strategy is as follows:
+ - We test and set the spinlock MAX_SPIN_COUNT times, calling
+ sched_yield() each time. This gives ample opportunity for other
+ threads with priority >= our priority to make progress and
+ release the spinlock.
+ - If a thread with priority < our priority owns the spinlock,
+ calling sched_yield() repeatedly is useless, since we're preventing
+ the owning thread from making progress and releasing the spinlock.
+ So, after MAX_SPIN_LOCK attemps, we suspend the calling thread
+ using nanosleep(). This again should give time to the owning thread
+ for releasing the spinlock.
+ Notice that the nanosleep() interval must not be too small,
+ since the kernel does busy-waiting for short intervals in a realtime
+ process (!). The smallest duration that guarantees thread
+ suspension is currently 2ms.
+ - When nanosleep() returns, we try again, doing MAX_SPIN_COUNT
+ sched_yield(), then sleeping again if needed. */
+
+void __pthread_acquire(int * spinlock)
+{
+ int cnt = 0;
+ struct timespec tm;
+
+ while (testandset(spinlock)) {
+ if (cnt < MAX_SPIN_COUNT) {
+ sched_yield();
+ cnt++;
+ } else {
+ tm.tv_sec = 0;
+ tm.tv_nsec = SPIN_SLEEP_DURATION;
+ nanosleep(&tm, NULL);
+ cnt = 0;
+ }
+ }
+}
diff --git a/linuxthreads/spinlock.h b/linuxthreads/spinlock.h
index d324abbc84..1707d3e42a 100644
--- a/linuxthreads/spinlock.h
+++ b/linuxthreads/spinlock.h
@@ -15,9 +15,11 @@
/* Spin locks */
+extern void __pthread_acquire(int * spinlock);
+
static inline void acquire(int * spinlock)
{
- while (testandset(spinlock)) __sched_yield();
+ if (testandset(spinlock)) __pthread_acquire(spinlock);
}
static inline void release(int * spinlock)
diff --git a/login/Makefile b/login/Makefile
index 5f7861b61c..96c75f7b4a 100644
--- a/login/Makefile
+++ b/login/Makefile
@@ -22,7 +22,7 @@
subdir := login
-headers := utmp.h bits/utmp.h utmpx.h bits/utmpx.h lastlog.h pty.h
+headers := utmp.h bits/utmp.h lastlog.h pty.h
routines := getutent getutent_r getutid getutline getutid_r getutline_r \
utmp_file utmp_daemon utmpname updwtmp \
diff --git a/login/getutent.c b/login/getutent.c
index eb99158592..51e147586e 100644
--- a/login/getutent.c
+++ b/login/getutent.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
@@ -35,4 +35,3 @@ __getutent (void)
return result;
}
weak_alias (__getutent, getutent)
-weak_alias (__getutent, getutxent)
diff --git a/login/getutent_r.c b/login/getutent_r.c
index 96c458f3a3..8391331cd5 100644
--- a/login/getutent_r.c
+++ b/login/getutent_r.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>
and Paul Janzen <pcj@primenet.com>, 1996.
@@ -143,7 +143,6 @@ __setutent (void)
__libc_lock_unlock (__libc_utmp_lock);
}
weak_alias (__setutent, setutent)
-weak_alias (__setutent, setutxent)
int
@@ -176,7 +175,6 @@ __pututline (const struct utmp *data)
return buffer;
}
weak_alias (__pututline, pututline)
-weak_alias (__pututline, pututxline)
void
@@ -190,4 +188,3 @@ __endutent (void)
__libc_lock_unlock (__libc_utmp_lock);
}
weak_alias (__endutent, endutent)
-weak_alias (__endutent, endutxent)
diff --git a/login/getutid.c b/login/getutid.c
index 98e8e4adc3..91e3ea20ac 100644
--- a/login/getutid.c
+++ b/login/getutid.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
@@ -35,4 +35,3 @@ __getutid (const struct utmp *id)
return result;
}
weak_alias (__getutid, getutid)
-weak_alias (__getutid, getutxid)
diff --git a/login/getutline.c b/login/getutline.c
index 1e1ecb1ce3..7fc402ffdd 100644
--- a/login/getutline.c
+++ b/login/getutline.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
@@ -35,4 +35,3 @@ __getutline (const struct utmp *line)
return result;
}
weak_alias (__getutline, getutline)
-weak_alias (__getutline, getutxline)
diff --git a/login/utmp.h b/login/utmp.h
index 82f3fcce9a..ccf29b27ad 100644
--- a/login/utmp.h
+++ b/login/utmp.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1996, 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -53,6 +53,8 @@ extern void logwtmp __P ((__const char *__ut_line, __const char *__ut_name,
__const char *__ut_host));
/* Append entry UTMP to the wtmp-like file WTMP_FILE. */
+extern void __updwtmp __P ((__const char *__wtmp_file,
+ __const struct utmp *__utmp));
extern void updwtmp __P ((__const char *__wtmp_file,
__const struct utmp *__utmp));
@@ -61,6 +63,7 @@ extern int __utmpname __P ((__const char *__file));
extern int utmpname __P ((__const char *__file));
/* Read next entry from a utmp-like file. */
+extern struct utmp *__getutent __P ((void));
extern struct utmp *getutent __P ((void));
/* Reset the input stream to the beginning of the file. */
@@ -73,13 +76,16 @@ extern void endutent __P ((void));
/* Search forward from the current point in the utmp file until the
next entry with a ut_type matching ID->ut_type. */
+extern struct utmp *__getutid __P ((__const struct utmp *__id));
extern struct utmp *getutid __P ((__const struct utmp *__id));
/* Search forward from the current point in the utmp file until the
next entry with a ut_line matching LINE->ut_line. */
+extern struct utmp *__getutline __P ((__const struct utmp *__line));
extern struct utmp *getutline __P ((__const struct utmp *__line));
/* Write out entry pointed to by UTMP_PTR into the utmp file. */
+extern struct utmp *__pututline __P ((__const struct utmp *__utmp_ptr));
extern struct utmp *pututline __P ((__const struct utmp *__utmp_ptr));
diff --git a/manual/creature.texi b/manual/creature.texi
index 66e53aceb4..00e3aada90 100644
--- a/manual/creature.texi
+++ b/manual/creature.texi
@@ -151,7 +151,7 @@ not generally used (see @code{_FILE_OFFSET_BITS}.
@comment (NONE)
@comment X/Open
-@defvr _FILE_OFFSET_BITS
+@defvr Macro _FILE_OFFSET_BITS
This macro lets decide which file system interface shall be used, one
replacing the other. While @code{_LARGEFILE64_SOURCE} makes the @w{64
bit} interface available as an additional interface
diff --git a/posix/getopt.c b/posix/getopt.c
index 7afe6c4a96..4cbf3614cc 100644
--- a/posix/getopt.c
+++ b/posix/getopt.c
@@ -24,19 +24,19 @@
/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
Ditto for AIX 3.2 and <stdlib.h>. */
#ifndef _NO_PROTO
-#define _NO_PROTO
+# define _NO_PROTO
#endif
#ifdef HAVE_CONFIG_H
-#include <config.h>
+# include <config.h>
#endif
#if !defined __STDC__ || !__STDC__
/* This is a separate conditional since some stdc systems
reject `defined (const)'. */
-#ifndef const
-#define const
-#endif
+# ifndef const
+# define const
+# endif
#endif
#include <stdio.h>
@@ -51,10 +51,10 @@
#define GETOPT_INTERFACE_VERSION 2
#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
-#include <gnu-versions.h>
-#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
-#define ELIDE_CODE
-#endif
+# include <gnu-versions.h>
+# if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
+# define ELIDE_CODE
+# endif
#endif
#ifndef ELIDE_CODE
@@ -65,26 +65,26 @@
#ifdef __GNU_LIBRARY__
/* Don't include stdlib.h for non-GNU C libraries because some of them
contain conflicting prototypes for getopt. */
-#include <stdlib.h>
-#include <unistd.h>
+# include <stdlib.h>
+# include <unistd.h>
#endif /* GNU C library. */
#ifdef VMS
-#include <unixlib.h>
-#if HAVE_STRING_H - 0
-#include <string.h>
-#endif
+# include <unixlib.h>
+# if HAVE_STRING_H - 0
+# include <string.h>
+# endif
#endif
#ifndef _
/* This is for other GNU distributions with internationalized messages.
When compiling libc, the _ macro is predefined. */
-#ifdef HAVE_LIBINTL_H
-# include <libintl.h>
-# define _(msgid) gettext (msgid)
-#else
-# define _(msgid) (msgid)
-#endif
+# ifdef HAVE_LIBINTL_H
+# include <libintl.h>
+# define _(msgid) gettext (msgid)
+# else
+# define _(msgid) (msgid)
+# endif
#endif
/* This version of `getopt' appears to the caller like standard Unix `getopt'
@@ -194,14 +194,19 @@ static char *posixly_correct;
because there are many ways it can cause trouble.
On some systems, it contains special magic macros that don't work
in GCC. */
-#include <string.h>
-#define my_index strchr
+# include <string.h>
+# define my_index strchr
#else
/* Avoid depending on library functions or files
whose names are inconsistent. */
-char *getenv ();
+#ifndef getenv
+extern char *getenv ();
+#endif
+#ifndef strncmp
+extern int strncmp ();
+#endif
static char *
my_index (str, chr)
@@ -222,11 +227,11 @@ my_index (str, chr)
#ifdef __GNUC__
/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
That was relevant to code that was here before. */
-#if !defined __STDC__ || !__STDC__
+# if (!defined __STDC__ || !__STDC__) && !defined strlen
/* gcc with -traditional declares the built-in strlen to return int,
and has done so at least since version 2.4.5. -- rms. */
extern int strlen (const char *);
-#endif /* not __STDC__ */
+# endif /* not __STDC__ */
#endif /* __GNUC__ */
#endif /* not __GNU_LIBRARY__ */
@@ -524,11 +529,11 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
from the shell indicating it is not an option. The later information
is only used when the used in the GNU libc. */
#ifdef _LIBC
-#define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \
- || (optind < nonoption_flags_len \
- && __getopt_nonoption_flags[optind] == '1'))
+# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \
+ || (optind < nonoption_flags_len \
+ && __getopt_nonoption_flags[optind] == '1'))
#else
-#define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
+# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
#endif
if (nextchar == NULL || *nextchar == '\0')
diff --git a/posix/regex.c b/posix/regex.c
index b7fb962d61..e2d31a0427 100644
--- a/posix/regex.c
+++ b/posix/regex.c
@@ -1083,17 +1083,9 @@ static const char *re_error_msgid[] =
# if defined MATCH_MAY_ALLOCATE
/* 4400 was enough to cause a crash on Alpha OSF/1,
whose default stack limit is 2mb. */
-# ifdef _LIBC
-long int __re_max_failures = 4000;
-# else
long int re_max_failures = 4000;
-# endif
# else
-# ifdef _LIBC
-long int __re_max_failures = 2000;
-# else
long int re_max_failures = 2000;
-# endif
# endif
union fail_stack_elt
@@ -1116,24 +1108,11 @@ typedef struct
# if defined MATCH_MAY_ALLOCATE
/* 4400 was enough to cause a crash on Alpha OSF/1,
whose default stack limit is 2mb. */
-# ifdef _LIBC
-int __re_max_failures = 20000;
-# else
int re_max_failures = 20000;
-# endif
# else
-# ifdef _LIBC
-int __re_max_failures = 2000;
-# else
int re_max_failures = 2000;
-# endif
# endif
-#ifdef _LIBC
-weak_alias (__re_max_failures, re_max_failures)
-# define re_max_failures __re_max_failures
-#endif
-
union fail_stack_elt
{
unsigned char *pointer;
diff --git a/posix/wordexp-test.c b/posix/wordexp-test.c
index ba69476e4c..81f93a1577 100644
--- a/posix/wordexp-test.c
+++ b/posix/wordexp-test.c
@@ -150,6 +150,7 @@ struct test_case_struct
};
static int testit (struct test_case_struct *tc);
+static int tests;
void
command_line_test (const char *words)
@@ -204,17 +205,28 @@ main (int argc, char *argv[])
{
struct test_case_struct ts;
+ printf ("Test %d (~root): ", ++tests);
+ fflush (stdout);
+
ts.retval = 0;
ts.env = NULL;
ts.words = "~root";
ts.flags = 0;
ts.wordc = 1;
ts.wordv[0] = pw->pw_dir;
+ ts.ifs = IFS;
if (testit (&ts))
- ++fail;
+ {
+ printf ("FAILED\n");
+ ++fail;
+ }
+ else
+ printf ("OK\n");
}
+ puts ("tests completed, now cleaning up");
+
/* Clean up */
for (i = 0; globfile[i]; ++i)
remove (globfile[i]);
@@ -225,6 +237,8 @@ main (int argc, char *argv[])
chdir (cwd);
rmdir (tmpdir);
+ printf ("tests failed: %d\n", fail);
+
return fail != 0;
}
@@ -232,7 +246,6 @@ main (int argc, char *argv[])
static int
testit (struct test_case_struct *tc)
{
- static int test;
int retval;
wordexp_t we;
int bzzzt = 0;
@@ -248,7 +261,7 @@ testit (struct test_case_struct *tc)
else
unsetenv ("IFS");
- printf ("Test %d: ", ++test);
+ printf ("Test %d (%s): ", ++tests, tc->words);
retval = wordexp (tc->words, &we, tc->flags);
if (retval != tc->retval || (retval == 0 && we.we_wordc != tc->wordc))
diff --git a/signal/sighold.c b/signal/sighold.c
index d2cb537912..730bcacb72 100644
--- a/signal/sighold.c
+++ b/signal/sighold.c
@@ -18,6 +18,8 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
+#define __need_NULL
+#include <stddef.h>
#include <signal.h>
int
diff --git a/signal/sigrelse.c b/signal/sigrelse.c
index 44e1001a06..971d60ffdf 100644
--- a/signal/sigrelse.c
+++ b/signal/sigrelse.c
@@ -18,6 +18,8 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
+#define __need_NULL
+#include <stddef.h>
#include <signal.h>
int
diff --git a/stdlib/mblen.c b/stdlib/mblen.c
index e43b076371..d60a1fb160 100644
--- a/stdlib/mblen.c
+++ b/stdlib/mblen.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -37,17 +37,23 @@ mblen (const char *s, size_t n)
restartable functions. We simply say here all encodings have a
state. */
if (s == NULL)
- return 1;
-
- state.count = 0;
- state.value = 0;
-
- result = __mbrtowc (NULL, s, n, &state);
-
- /* The `mbrtowc' functions tell us more than we need. Fold the -1
- and -2 result into -1. */
- if (result < 0)
- result = -1;
+ result = 1;
+ else if (*s == '\0')
+ /* According to the ISO C 89 standard this is the expected behaviour.
+ Idiotic, but true. */
+ result = 0;
+ else
+ {
+ state.count = 0;
+ state.value = 0;
+
+ result = __mbrtowc (NULL, s, n, &state);
+
+ /* The `mbrtowc' functions tell us more than we need. Fold the -1
+ and -2 result into -1. */
+ if (result < 0)
+ result = -1;
+ }
return result;
}
diff --git a/stdlib/mbtowc.c b/stdlib/mbtowc.c
index 61b46f882e..50e7c09834 100644
--- a/stdlib/mbtowc.c
+++ b/stdlib/mbtowc.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1992, 1995, 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 92, 95, 96, 97, 98 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -43,14 +43,22 @@ mbtowc (wchar_t *pwc, const char *s, size_t n)
restartable functions. We simply say here all encodings have a
state. */
if (s == NULL)
- return 1;
+ result = 1;
+ else if (*s == '\0')
+ {
+ if (pwc != NULL)
+ *pwc = L'\0';
+ result = 0;
+ }
+ else
+ {
+ result = __mbrtowc (pwc, s, n, &__no_r_state);
- result = __mbrtowc (pwc, s, n, &__no_r_state);
-
- /* The `mbrtowc' functions tell us more than we need. Fold the -1
- and -2 result into -1. */
- if (result < 0)
- result = -1;
+ /* The `mbrtowc' functions tell us more than we need. Fold the -1
+ and -2 result into -1. */
+ if (result < 0)
+ result = -1;
+ }
return result;
}
diff --git a/sysdeps/arm/bits/setjmp.h b/sysdeps/arm/bits/setjmp.h
index 5cf9cd75c7..ea25a9ba87 100644
--- a/sysdeps/arm/bits/setjmp.h
+++ b/sysdeps/arm/bits/setjmp.h
@@ -1,3 +1,21 @@
+/* Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
/* Define the machine-dependent type `jmp_buf'. ARM version. */
#ifndef _SETJMP_H
diff --git a/sysdeps/arm/strlen.S b/sysdeps/arm/strlen.S
new file mode 100644
index 0000000000..9acef4f935
--- /dev/null
+++ b/sysdeps/arm/strlen.S
@@ -0,0 +1,55 @@
+/* Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Code contributed by Matthew Wilcox <willy@odie.barnet.ac.uk>
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <sysdep.h>
+
+/* size_t strlen(const char *S)
+ * entry: r0 -> string
+ * exit: r0 = len
+ */
+
+ENTRY(strlen)
+ bic r1, r0, $3 @ addr of word containing first byte
+ ldr r2, [r1], $4 @ get the first word
+ ands r3, r0, $3 @ how many bytes are duff?
+ rsb r0, r3, $0 @ get - that number into counter.
+ beq Laligned @ skip into main check routine if no
+ @ more
+ orr r2, r2, $0xff000000 @ set this byte to non-zero
+ subs r3, r3, $1 @ any more to do?
+ orrgt r2, r2, $0x00ff0000 @ if so, set this byte
+ subs r3, r3, $1 @ more?
+ orrgt r2, r2, $0x0000ff00 @ then set.
+Laligned: @ here, we have a word in r2. Does it
+ tst r2, $0x000000ff @ contain any zeroes?
+ tstne r2, $0x0000ff00 @
+ tstne r2, $0x00ff0000 @
+ tstne r2, $0xff000000 @
+ addne r0, r0, $4 @ if not, the string is 4 bytes longer
+ ldrne r2, [r1], $4 @ and we continue to the next word
+ bne Laligned @
+Llastword: @ drop through to here once we find a
+ tst r2, $0x000000ff @ word that has a zero byte in it
+ addne r0, r0, $1 @
+ tstne r2, $0x0000ff00 @ and add up to 3 bytes on to it
+ addne r0, r0, $1 @
+ tstne r2, $0x00ff0000 @ (if first three all non-zero, 4th
+ addne r0, r0, $1 @ must be zero)
+ RETINSTR(mov,pc,lr)
+END(strlen)
diff --git a/sysdeps/generic/bits/socket.h b/sysdeps/generic/bits/socket.h
index 5dc1e65370..01844bc143 100644
--- a/sysdeps/generic/bits/socket.h
+++ b/sysdeps/generic/bits/socket.h
@@ -17,6 +17,9 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
+#ifndef __BITS_SOCKET_H
+#define __BITS_SOCKET_H 1
+
#if !defined _SYS_SOCKET_H && !defined _NETINET_IN_H
# error "Never include <bits/socket.h> directly; use <sys/socket.h> instead."
#endif
@@ -196,3 +199,5 @@ struct linger
int l_onoff; /* Nonzero to linger on close. */
int l_linger; /* Time to linger. */
};
+
+#endif /* bits/socket.h */
diff --git a/sysdeps/generic/bits/utmpx.h b/sysdeps/generic/endutxent.c
index e22660f6d6..cd8d7e4122 100644
--- a/sysdeps/generic/bits/utmpx.h
+++ b/sysdeps/generic/endutxent.c
@@ -1,5 +1,6 @@
-/* Structures and definitions for the user accounting database. Generic/BSDish
- Copyright (C) 1993, 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1998.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
@@ -16,19 +17,11 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#ifndef _UTMPX_H
-# error "Never include <bits/utmpx.h> directly; use <utmpx.h> instead."
-#endif
+#include <utmp.h>
+#include <utmpx.h>
-
-#define __UT_NAMESIZE 8
-#define __UT_LINESIZE 8
-#define __UT_HOSTSIZE 16
-
-struct utmpx
- {
- char ut_line[__UT_LINESIZE];
- char ut_name[__UT_NAMESIZE];
- char ut_host[__UT_HOSTSIZE];
- long int ut_time;
- };
+void
+endutxent (void)
+{
+ __endutent ();
+}
diff --git a/sysdeps/generic/getutxent.c b/sysdeps/generic/getutxent.c
new file mode 100644
index 0000000000..f6f07d5c44
--- /dev/null
+++ b/sysdeps/generic/getutxent.c
@@ -0,0 +1,27 @@
+/* Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <utmp.h>
+#include <utmpx.h>
+
+struct utmpx *
+getutxent (void)
+{
+ return (struct utmpx *) __getutent ();
+}
diff --git a/sysdeps/generic/getutxid.c b/sysdeps/generic/getutxid.c
new file mode 100644
index 0000000000..d58f4c307d
--- /dev/null
+++ b/sysdeps/generic/getutxid.c
@@ -0,0 +1,27 @@
+/* Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <utmp.h>
+#include <utmpx.h>
+
+struct utmpx *
+getutxid (const struct utmpx *id)
+{
+ return (struct utmpx *) __getutid ((const struct utmp *) id);
+}
diff --git a/sysdeps/generic/getutxline.c b/sysdeps/generic/getutxline.c
new file mode 100644
index 0000000000..4296ea615b
--- /dev/null
+++ b/sysdeps/generic/getutxline.c
@@ -0,0 +1,27 @@
+/* Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <utmp.h>
+#include <utmpx.h>
+
+struct utmpx *
+getutxline (const struct utmpx *line)
+{
+ return (struct utmpx *) __getutline ((const struct utmp *) line);
+}
diff --git a/sysdeps/generic/longjmp.c b/sysdeps/generic/longjmp.c
index f46f1601c3..1a4850f1b8 100644
--- a/sysdeps/generic/longjmp.c
+++ b/sysdeps/generic/longjmp.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1992, 1994, 1995, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 92, 94, 95, 97, 98 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -27,7 +27,7 @@ extern void _longjmp_unwind (jmp_buf env, int val);
to the position specified in ENV, causing the setjmp
call there to return VAL, or 1 if VAL is 0. */
void
-longjmp (sigjmp_buf env, int val)
+__libc_siglongjmp (sigjmp_buf env, int val)
{
/* Perform any cleanups needed by the frames being unwound. */
_longjmp_unwind (env, val);
@@ -41,5 +41,7 @@ longjmp (sigjmp_buf env, int val)
__longjmp (env[0].__jmpbuf, val ?: 1);
}
-weak_alias (longjmp, _longjmp)
-weak_alias (longjmp, siglongjmp)
+strong_alias (__libc_siglongjmp, __libc_longjmp)
+weak_alias (__libc_siglongjmp, _longjmp)
+weak_alias (__libc_siglongjmp, longjmp)
+weak_alias (__libc_siglongjmp, siglongjmp)
diff --git a/sysdeps/generic/pututxline.c b/sysdeps/generic/pututxline.c
new file mode 100644
index 0000000000..d1246bc5a4
--- /dev/null
+++ b/sysdeps/generic/pututxline.c
@@ -0,0 +1,27 @@
+/* Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <utmp.h>
+#include <utmpx.h>
+
+struct utmpx *
+pututxline (const struct utmpx *utmpx)
+{
+ return (struct utmpx *) __pututline ((const struct utmp *) utmpx);
+}
diff --git a/sysdeps/generic/setjmp.c b/sysdeps/generic/setjmp.c
index 8b1dfa6a83..56230aabf7 100644
--- a/sysdeps/generic/setjmp.c
+++ b/sysdeps/generic/setjmp.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 94, 95, 96, 97, 98 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -22,7 +22,7 @@
/* Save the current program position in ENV and return 0. */
int
-__sigsetjmp (jmp_buf env, int savemask)
+__libc_sigsetjmp (jmp_buf env, int savemask)
{
/* Save the signal mask if requested. */
__sigjmp_save (env, savemask);
@@ -32,6 +32,6 @@ __sigsetjmp (jmp_buf env, int savemask)
return 0;
}
-
+weak_alias (__libc_sigsetjmp, __sigsetjmp)
stub_warning (__sigsetjmp)
#include <stub-tag.h>
diff --git a/sysdeps/generic/setutxent.c b/sysdeps/generic/setutxent.c
new file mode 100644
index 0000000000..267a1bd7d1
--- /dev/null
+++ b/sysdeps/generic/setutxent.c
@@ -0,0 +1,27 @@
+/* Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <utmp.h>
+#include <utmpx.h>
+
+void
+setutxent (void)
+{
+ return __setutent ();
+}
diff --git a/sysdeps/generic/strcasestr.c b/sysdeps/generic/strcasestr.c
index ec8727d268..a5786fac58 100644
--- a/sysdeps/generic/strcasestr.c
+++ b/sysdeps/generic/strcasestr.c
@@ -1,5 +1,5 @@
/* Return the offset of one string within another.
- Copyright (C) 1994, 1996, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1994, 1996, 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -38,7 +38,8 @@
typedef unsigned chartype;
-#undef strstr
+#undef strcasestr
+#undef __strcasestr
char *
__strcasestr (phaystack, pneedle)
diff --git a/login/updwtmp.c b/sysdeps/generic/updwtmp.c
index 9965a61fbb..d6f29b1851 100644
--- a/login/updwtmp.c
+++ b/sysdeps/generic/updwtmp.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1997.
@@ -17,30 +17,25 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#include <unistd.h>
#include <utmp.h>
#include "utmp-private.h"
+#ifndef TRANSFORM_UTMP_FILE_NAME
+# define TRANSFORM_UTMP_FILE_NAME(file_name) (file_name)
+#endif
void
-updwtmp (const char *wtmp_file, const struct utmp *utmp)
+__updwtmp (const char *wtmp_file, const struct utmp *utmp)
{
/* See whether utmpd is running. */
if ((*__libc_utmp_daemon_functions.updwtmp) (wtmp_file, utmp) < 0)
{
- /* Use the normal file, but if the current file is _PATH_UTMP or
- _PATH_WTMP and the corresponding extended file (with an extra
- 'x' added to the pathname) exists, we use the extended file,
- because the original file is in a different format. */
- if (strcmp (wtmp_file, _PATH_UTMP) == 0
- && __access (_PATH_UTMP "x", F_OK) == 0)
- (*__libc_utmp_file_functions.updwtmp) (_PATH_UTMP "x", utmp);
- else if (strcmp (wtmp_file, _PATH_WTMP) == 0
- && __access (_PATH_WTMP "x", F_OK) == 0)
- (*__libc_utmp_file_functions.updwtmp) (_PATH_WTMP "x", utmp);
- else
- (*__libc_utmp_file_functions.updwtmp) (wtmp_file, utmp);
+ const char *file_name;
+
+ file_name = TRANSFORM_UTMP_FILE_NAME (wtmp_file);
+
+ (*__libc_utmp_file_functions.updwtmp) (file_name, utmp);
}
}
-
+weak_alias (__updwtmp, updwtmp)
diff --git a/sysdeps/generic/updwtmpx.c b/sysdeps/generic/updwtmpx.c
new file mode 100644
index 0000000000..097bf380d2
--- /dev/null
+++ b/sysdeps/generic/updwtmpx.c
@@ -0,0 +1,27 @@
+/* Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <utmp.h>
+#include <utmpx.h>
+
+void
+__updwtmpx (const char *wtmpx_file, const struct utmpx *utmpx)
+{
+ __updwtmp (wtmpx_file, (const struct utmp *) utmpx);
+}
diff --git a/login/utmp_file.c b/sysdeps/generic/utmp_file.c
index 9cdb88ebec..08675185ce 100644
--- a/login/utmp_file.c
+++ b/sysdeps/generic/utmp_file.c
@@ -61,19 +61,18 @@ struct utfuncs __libc_utmp_file_functions =
};
+#ifndef TRANSFORM_UTMP_FILE_NAME
+# define TRANSFORM_UTMP_FILE_NAME(file_name) (file_name)
+#endif
+
static int
setutent_file (void)
{
if (file_fd < 0)
{
- const char *file_name = __libc_utmp_file_name;
+ const char *file_name;
- if (strcmp (__libc_utmp_file_name, _PATH_UTMP) == 0
- && __access (_PATH_UTMP "x", F_OK) == 0)
- file_name = _PATH_UTMP "x";
- else if (strcmp (__libc_utmp_file_name, _PATH_WTMP) == 0
- && __access (_PATH_WTMP "x", F_OK) == 0)
- file_name = _PATH_WTMP "x";
+ file_name = TRANSFORM_UTMP_FILE_NAME (__libc_utmp_file_name);
file_fd = open (file_name, O_RDWR);
if (file_fd == -1)
@@ -81,10 +80,7 @@ setutent_file (void)
/* Hhm, read-write access did not work. Try read-only. */
file_fd = open (file_name, O_RDONLY);
if (file_fd == -1)
- {
- perror (_("while opening UTMP file"));
- return 0;
- }
+ return 0;
}
}
diff --git a/sysdeps/generic/utmpxname.c b/sysdeps/generic/utmpxname.c
new file mode 100644
index 0000000000..41c91937d0
--- /dev/null
+++ b/sysdeps/generic/utmpxname.c
@@ -0,0 +1,27 @@
+/* Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <utmp.h>
+#include <utmpx.h>
+
+int
+utmpxname (const char *file)
+{
+ return __utmpname (file);
+}
diff --git a/sysdeps/gnu/Makefile b/sysdeps/gnu/Makefile
index e491fa2be4..762f79b866 100644
--- a/sysdeps/gnu/Makefile
+++ b/sysdeps/gnu/Makefile
@@ -28,3 +28,10 @@ $(..)sysdeps/gnu/errlist.c: $(..)sysdeps/gnu/errlist.awk \
ifeq ($(with-cvs),yes)
test ! -d CVS || cvs commit -m'Regenerated from $^' $@
endif
+
+ifeq ($(subdir),login)
+sysdep_routines += setutxent getutxent endutxent getutxid getutxline \
+ pututxline utmpxname updwtmpx
+
+sysdep_headers += utmpx.h bits/utmpx.h
+endif
diff --git a/sysdeps/gnu/bits/utmpx.h b/sysdeps/gnu/bits/utmpx.h
index 4ecbb3a026..b367bfba3c 100644
--- a/sysdeps/gnu/bits/utmpx.h
+++ b/sysdeps/gnu/bits/utmpx.h
@@ -1,5 +1,5 @@
/* Structures and defenitions for the user accounting database. GNU version.
- Copyright (C) 1997 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998 Free Software Foundation, Inc.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
@@ -24,6 +24,13 @@
#include <sys/time.h>
+#ifdef __USE_GNU
+# include <paths.h>
+# define _PATH_UTMPX _PATH_UTMP
+# define _PATH_WTMPX _PATH_WTMP
+#endif
+
+
#define __UT_LINESIZE 32
#define __UT_NAMESIZE 32
#define __UT_HOSTSIZE 256
@@ -56,10 +63,12 @@ struct utmpx
};
-/* Values for the `ut_type' field of a `struct utmp'. */
+/* Values for the `ut_type' field of a `struct utmpx'. */
#define EMPTY 0 /* No valid user accounting information. */
-#define RUN_LVL 1 /* The system's runlevel. */
+#ifdef __USE_GNU
+# define RUN_LVL 1 /* The system's runlevel. */
+#endif
#define BOOT_TIME 2 /* Time of system boot. */
#define NEW_TIME 3 /* Time after system clock changed. */
#define OLD_TIME 4 /* Time when system clock changed. */
@@ -68,3 +77,7 @@ struct utmpx
#define LOGIN_PROCESS 6 /* Session leader of a logged in user. */
#define USER_PROCESS 7 /* Normal process. */
#define DEAD_PROCESS 8 /* Terminated process. */
+
+#ifdef __USE_GNU
+# define ACCOUNTING 9 /* System accounting. */
+#endif
diff --git a/sysdeps/gnu/updwtmp.c b/sysdeps/gnu/updwtmp.c
new file mode 100644
index 0000000000..19a77657b3
--- /dev/null
+++ b/sysdeps/gnu/updwtmp.c
@@ -0,0 +1,30 @@
+/* Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <string.h>
+#include <unistd.h>
+
+#define TRANSFORM_UTMP_FILE_NAME(file_name) \
+ ((strcmp (file_name, _PATH_UTMP "x") == 0 \
+ && __access (_PATH_UTMP "x", F_OK) != 0) ? _PATH_UTMP : \
+ ((strcmp (file_name, _PATH_WTMP "x") == 0 \
+ && __access (_PATH_WTMP "x", F_OK) != 0) ? _PATH_WTMP : \
+ file_name))
+
+#include <sysdeps/generic/updwtmp.c>
diff --git a/sysdeps/gnu/utmp_file.c b/sysdeps/gnu/utmp_file.c
new file mode 100644
index 0000000000..05bbcd1ce1
--- /dev/null
+++ b/sysdeps/gnu/utmp_file.c
@@ -0,0 +1,30 @@
+/* Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <string.h>
+#include <unistd.>
+
+#define TRANSFORM_UTMP_FILE_NAME(file_name) \
+ ((strcmp (file_name, _PATH_UTMP "x") == 0 \
+ && __access (_PATH_UTMP "x", F_OK) != 0) ? _PATH_UTMP : \
+ ((strcmp (file_name, _PATH_WTMP "x") == 0 \
+ && __access (_PATH_WTMP "x", F_OK) != 0) ? _PATH_WTMP : \
+ file_name))
+
+#include <sysdeps/generic/utmp_file.c>
diff --git a/login/utmpx.h b/sysdeps/gnu/utmpx.h
index 5873bf9310..e9f2389b75 100644
--- a/login/utmpx.h
+++ b/sysdeps/gnu/utmpx.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1997.
@@ -27,8 +27,16 @@ __BEGIN_DECLS
/* Get system dependent values and data structures. */
#include <bits/utmpx.h>
+#ifdef __USE_GNU
+/* Compatibility names for the strings of the canonical file names. */
+# define UTMPX_FILE _PATH_UTMPX
+# define UTMPX_FILENAME _PATH_UTMPX
+# define WTMPX_FILE _PATH_WTMPX
+# define WTMPX_FILENAME _PATH_WTMPX
+#endif
+
/* Open user accounting database. */
-extern void *setutxent __P ((void));
+extern void setutxent __P ((void));
/* Close user accounting database. */
extern void endutxent __P ((void));
@@ -45,6 +53,15 @@ extern struct utmpx *getutxline __P ((const struct utmpx *__line));
/* Write the entry UTMPX into the user accounting database. */
extern struct utmpx *pututxline __P ((const struct utmpx *__utmpx));
+#ifdef __USE_GNU
+/* Change name of the utmpx file to be examined. */
+extern int utmpxname __P ((__const char *__file));
+
+/* Append entry UTMP to the wtmpx-like file WTMPX_FILE. */
+extern void updwtmpx __P ((__const char *__wtmpx_file,
+ __const struct utmpx *__utmpx));
+#endif
+
__END_DECLS
#endif /* utmpx.h */
diff --git a/sysdeps/i386/bits/setjmp.h b/sysdeps/i386/bits/setjmp.h
index 5cb60a8c7d..46729224fd 100644
--- a/sysdeps/i386/bits/setjmp.h
+++ b/sysdeps/i386/bits/setjmp.h
@@ -1,3 +1,21 @@
+/* Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
/* Define the machine-dependent type `jmp_buf'. Intel 386 version. */
#ifndef _SETJMP_H
diff --git a/sysdeps/m68k/bits/setjmp.h b/sysdeps/m68k/bits/setjmp.h
index 2991232915..a302b72393 100644
--- a/sysdeps/m68k/bits/setjmp.h
+++ b/sysdeps/m68k/bits/setjmp.h
@@ -1,3 +1,21 @@
+/* Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
/* Define the machine-dependent type `jmp_buf'. m68k version. */
#ifndef _SETJMP_H
diff --git a/sysdeps/mach/hurd/Subdirs b/sysdeps/mach/hurd/Subdirs
index 739919f4b1..16b8348437 100644
--- a/sysdeps/mach/hurd/Subdirs
+++ b/sysdeps/mach/hurd/Subdirs
@@ -1,2 +1 @@
hurd
-login
diff --git a/sysdeps/mach/hurd/bits/ioctls.h b/sysdeps/mach/hurd/bits/ioctls.h
index 1145560ab9..1e063e3e66 100644
--- a/sysdeps/mach/hurd/bits/ioctls.h
+++ b/sysdeps/mach/hurd/bits/ioctls.h
@@ -16,7 +16,10 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#if !defined _HURD_IOCTL_H && !defined _SYS_IOCTLS_H
+#ifndef __BITS_IOCTLS_H
+#define __BITS_IOCTLS_H 1
+
+#if !defined _HURD_IOCTL_H && !defined _SYS_IOCTL_H
# error "Never use <bits/ioctls.h> directly; include <hurd/ioctl.h> instead."
#endif
@@ -345,3 +348,5 @@ enum __ioctl_datum { IOC_8, IOC_16, IOC_32, IOC_64 };
# define EXTA 14
# define EXTB 15
#endif /* USE_OLD_TTY */
+
+#endif /* bits/ioctls.h */
diff --git a/sysdeps/posix/sigignore.c b/sysdeps/posix/sigignore.c
index f24aca70c9..497af577f8 100644
--- a/sysdeps/posix/sigignore.c
+++ b/sysdeps/posix/sigignore.c
@@ -19,6 +19,8 @@
Boston, MA 02111-1307, USA. */
#include <errno.h>
+#define __need_NULL
+#include <stddef.h>
#include <signal.h>
int
diff --git a/sysdeps/posix/sigset.c b/sysdeps/posix/sigset.c
index 4bd3bf38c8..1a6b1a4fd3 100644
--- a/sysdeps/posix/sigset.c
+++ b/sysdeps/posix/sigset.c
@@ -17,6 +17,8 @@
Boston, MA 02111-1307, USA. */
#include <errno.h>
+#define __need_NULL
+#include <stddef.h>
#include <signal.h>
diff --git a/sysdeps/posix/waitid.c b/sysdeps/posix/waitid.c
index a36883a8d2..fa9021115f 100644
--- a/sysdeps/posix/waitid.c
+++ b/sysdeps/posix/waitid.c
@@ -1,5 +1,5 @@
/* Pseudo implementation of waitid.
- Copyright (C) 1997 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Zack Weinberg <zack@rabi.phys.columbia.edu>, 1997.
@@ -20,6 +20,8 @@
#include <errno.h>
#include <signal.h>
+#define __need_NULL
+#include <stddef.h>
#include <sys/wait.h>
#include <sys/types.h>
diff --git a/sysdeps/powerpc/bits/setjmp.h b/sysdeps/powerpc/bits/setjmp.h
index 7bb654c0bc..65db364555 100644
--- a/sysdeps/powerpc/bits/setjmp.h
+++ b/sysdeps/powerpc/bits/setjmp.h
@@ -1,3 +1,21 @@
+/* Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
/* Define the machine-dependent type `jmp_buf'. PowerPC version. */
#ifndef _SETJMP_H
diff --git a/sysdeps/powerpc/elf/start.c b/sysdeps/powerpc/elf/start.c
deleted file mode 100644
index d32aeee6c7..0000000000
--- a/sysdeps/powerpc/elf/start.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/* Startup code compliant to the ELF PowerPC ABI.
- Copyright (C) 1997 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the GNU C Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
-
-/* This is SVR4/PPC ABI compliant, and works under Linux when
- statically linked. */
-
-#include <unistd.h>
-#include <stdlib.h>
-
-/* Just a little assembler stub before gcc gets its hands on our
- stack pointer... */
-asm ("\
- .section \".text\"
- .align 2
- .globl _start
- .type _start,@function
-_start:
- # save the stack pointer, in case we're statically linked under Linux
- mr 8,1
- # set up an initial stack frame, and clear the LR
- addi 1,1,-16
- clrrwi 1,1,4
- li 0,0
- stw 0,0(1)
- mtlr 0
- # set r13 to point at the 'small data area'
- lis 13,_SDA_BASE_@ha
- addi 13,13,_SDA_BASE_@l
- # and continue below.
- b __start1
-0:
- .size _start,0b-_start
- # undo '.section text'.
- .previous
-");
-
-/* Define a symbol for the first piece of initialized data. */
-int __data_start = 0;
-weak_alias (__data_start, data_start)
-
-/* these probably should go, at least go somewhere else
- (sysdeps/mach/something?). */
-void (*_mach_init_routine) (void);
-void (*_thread_init_routine) (void);
-
-extern void __libc_init_first (int argc, char **argv, char **envp);
-extern int main (int argc, char **argv, char **envp, void *auxvec);
-#ifdef HAVE_INITFINI
-extern void _init (void);
-extern void _fini (void);
-#endif
-
-#if 0
-/* I'd like to say this, but it causes GCC to strip the whole procedure
- from the object file (this is sort of reasonable, because you've told
- GCC that the procedure is unused). :-( */
-static void __start1(int argc, char **argv, char **envp,
- void *auxvec, void (*exitfn) (void),
- char **stack_on_entry)
- __attribute__ ((unused));
-
-static
-#endif
-void
-__start1(int argc, char **argv, char **envp,
- void *auxvec, void (*exitfn) (void),
- char **stack_on_entry)
-{
- /* the PPC SVR4 ABI says that the top thing on the stack will
- be a NULL pointer, so if not we assume that we're being called
- as a statically-linked program by Linux... */
- if (*stack_on_entry != NULL)
- {
- /* ...in which case, we have argc as the top thing on the
- stack, followed by argv (NULL-terminated), envp (likewise),
- and the auxilary vector. */
- argc = *(int *) stack_on_entry;
- argv = stack_on_entry + 1;
- envp = argv + argc + 1;
- auxvec = envp;
- while (*(char **) auxvec != NULL)
- ++auxvec;
- ++auxvec;
- exitfn = NULL;
- }
-
- if (exitfn != NULL)
- atexit (exitfn);
-
- /* libc init routine, in case we are statically linked
- (otherwise ld.so will have called it when it loaded libc, but
- calling it twice doesn't hurt). */
- __libc_init_first (argc, argv, envp);
-
-#ifdef HAVE_INITFINI
- /* ELF constructors/destructors */
- atexit (_fini);
- _init ();
-#endif
-
- /* Stuff so we can build Mach/Linux executables (like vmlinux). */
- if (_mach_init_routine != 0)
- _mach_init_routine ();
- if (_thread_init_routine != 0)
- _thread_init_routine ();
-
- /* the rest of the program */
- exit (main (argc, argv, envp, auxvec));
-}
diff --git a/sysdeps/sparc/sparc32/bits/setjmp.h b/sysdeps/sparc/sparc32/bits/setjmp.h
index 0e61fe7805..3d39132eab 100644
--- a/sysdeps/sparc/sparc32/bits/setjmp.h
+++ b/sysdeps/sparc/sparc32/bits/setjmp.h
@@ -1,3 +1,21 @@
+/* Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
/* Define the machine-dependent type `jmp_buf'. SPARC version. */
#ifndef _SETJMP_H
diff --git a/sysdeps/unix/sysv/linux/i386/s_pread64.S b/sysdeps/unix/sysv/linux/i386/s_pread64.S
index 7f8816b3ba..23d7d14ba5 100644
--- a/sysdeps/unix/sysv/linux/i386/s_pread64.S
+++ b/sysdeps/unix/sysv/linux/i386/s_pread64.S
@@ -49,7 +49,7 @@ ENTRY (__syscall_pread64)
cmpl $-4095, %eax /* Check %eax for error. */
jae syscall_error /* Jump to error handler if error. */
#endif
- ret /* Return to caller. */
L(pseudo_end):
+ ret /* Return to caller. */
PSEUDO_END (__syscall_pread64)
diff --git a/sysdeps/unix/sysv/linux/paths.h b/sysdeps/unix/sysv/linux/paths.h
index 53c4fc5dcb..cb5b57122c 100644
--- a/sysdeps/unix/sysv/linux/paths.h
+++ b/sysdeps/unix/sysv/linux/paths.h
@@ -64,7 +64,6 @@
#define _PATH_TTY "/dev/tty"
#define _PATH_UNIX "/vmlinux"
#define _PATH_UTMP "/var/run/utmp"
-#define _PATH_UTMP_DB "/var/run/utmp.db"
#define _PATH_VI "/usr/bin/vi"
#define _PATH_WTMP "/var/log/wtmp"
diff --git a/sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c b/sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c
index fa946cf774..9e31ed4096 100644
--- a/sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c
+++ b/sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c
@@ -30,7 +30,7 @@
for (_tmp = (envp); *_tmp; ++_tmp) \
continue; \
/* The following '++' is important! */ \
- (auxp) = ++_tmp; \
+ ++_tmp; \
if (*_tmp == 0) \
{ \
size_t _test = (size_t)_tmp; \
@@ -42,8 +42,9 @@
vector will have to be laid out to allow for this \
test :-(. */ \
if (((ElfW(auxv_t) *)_test)->a_type <= AT_PHDR) \
- (auxp) = (ElfW(auxv_t) *) _tmp; \
+ _tmp = (char **)_test; \
} \
+ (auxp) = (ElfW(auxv_t) *) _tmp; \
} while (0)
diff --git a/sysdeps/unix/sysv/linux/powerpc/syscall.h b/sysdeps/unix/sysv/linux/powerpc/syscall.h
deleted file mode 100644
index c6bac3de5b..0000000000
--- a/sysdeps/unix/sysv/linux/powerpc/syscall.h
+++ /dev/null
@@ -1,357 +0,0 @@
-/* Copyright (C) 1997 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the GNU C Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
-
-#ifndef _SYSCALL_H
-#define _SYSCALL_H 1
-
-/* normally, we'd get syscalls from asm/unistd.h under Linux, but this
- is very broken under MkLinux/PPC, so we list them right here directly. */
-
-#define __NR_setup 0
-#define __NR_exit 1
-#define __NR_fork 2
-#define __NR_read 3
-#define __NR_write 4
-#define __NR_open 5
-#define __NR_close 6
-#define __NR_waitpid 7
-#define __NR_creat 8
-#define __NR_link 9
-#define __NR_unlink 10
-#define __NR_execve 11
-#define __NR_chdir 12
-#define __NR_time 13
-#define __NR_mknod 14
-#define __NR_chmod 15
-#define __NR_chown 16
-#define __NR_break 17
-#define __NR_oldstat 18
-#define __NR_lseek 19
-#define __NR_getpid 20
-#define __NR_mount 21
-#define __NR_umount 22
-#define __NR_setuid 23
-#define __NR_getuid 24
-#define __NR_stime 25
-#define __NR_ptrace 26
-#define __NR_alarm 27
-#define __NR_oldfstat 28
-#define __NR_pause 29
-#define __NR_utime 30
-#define __NR_stty 31
-#define __NR_gtty 32
-#define __NR_access 33
-#define __NR_nice 34
-#define __NR_ftime 35
-#define __NR_sync 36
-#define __NR_kill 37
-#define __NR_rename 38
-#define __NR_mkdir 39
-#define __NR_rmdir 40
-#define __NR_dup 41
-#define __NR_pipe 42
-#define __NR_times 43
-#define __NR_prof 44
-#define __NR_brk 45
-#define __NR_setgid 46
-#define __NR_getgid 47
-#define __NR_signal 48
-#define __NR_geteuid 49
-#define __NR_getegid 50
-#define __NR_acct 51
-#define __NR_phys 52
-#define __NR_lock 53
-#define __NR_ioctl 54
-#define __NR_fcntl 55
-#define __NR_mpx 56
-#define __NR_setpgid 57
-#define __NR_ulimit 58
-#define __NR_oldolduname 59
-#define __NR_umask 60
-#define __NR_chroot 61
-#define __NR_ustat 62
-#define __NR_dup2 63
-#define __NR_getppid 64
-#define __NR_getpgrp 65
-#define __NR_setsid 66
-#define __NR_sigaction 67
-#define __NR_sgetmask 68
-#define __NR_ssetmask 69
-#define __NR_setreuid 70
-#define __NR_setregid 71
-#define __NR_sigsuspend 72
-#define __NR_sigpending 73
-#define __NR_sethostname 74
-#define __NR_setrlimit 75
-#define __NR_getrlimit 76
-#define __NR_getrusage 77
-#define __NR_gettimeofday 78
-#define __NR_settimeofday 79
-#define __NR_getgroups 80
-#define __NR_setgroups 81
-#define __NR_select 82
-#define __NR_symlink 83
-#define __NR_oldlstat 84
-#define __NR_readlink 85
-#define __NR_uselib 86
-#define __NR_swapon 87
-#define __NR_reboot 88
-#define __NR_readdir 89
-#define __NR_mmap 90
-#define __NR_munmap 91
-#define __NR_truncate 92
-#define __NR_ftruncate 93
-#define __NR_fchmod 94
-#define __NR_fchown 95
-#define __NR_getpriority 96
-#define __NR_setpriority 97
-#define __NR_profil 98
-#define __NR_statfs 99
-#define __NR_fstatfs 100
-#define __NR_ioperm 101
-#define __NR_socketcall 102
-#define __NR_syslog 103
-#define __NR_setitimer 104
-#define __NR_getitimer 105
-#define __NR_stat 106
-#define __NR_lstat 107
-#define __NR_fstat 108
-#define __NR_olduname 109
-#define __NR_iopl 110
-#define __NR_vhangup 111
-#define __NR_idle 112
-#define __NR_vm86 113
-#define __NR_wait4 114
-#define __NR_swapoff 115
-#define __NR_sysinfo 116
-#define __NR_ipc 117
-#define __NR_fsync 118
-#define __NR_sigreturn 119
-#define __NR_clone 120
-#define __NR_setdomainname 121
-#define __NR_uname 122
-#define __NR_modify_ldt 123
-#define __NR_adjtimex 124
-#define __NR_mprotect 125
-#define __NR_sigprocmask 126
-#define __NR_create_module 127
-#define __NR_init_module 128
-#define __NR_delete_module 129
-#define __NR_get_kernel_syms 130
-#define __NR_quotactl 131
-#define __NR_getpgid 132
-#define __NR_fchdir 133
-#define __NR_bdflush 134
-#define __NR_sysfs 135
-#define __NR_personality 136
-#define __NR_afs_syscall 137 /* Syscall for Andrew File System */
-#define __NR_setfsuid 138
-#define __NR_setfsgid 139
-#define __NR__llseek 140
-#define __NR_getdents 141
-#define __NR__newselect 142
-#define __NR_flock 143
-#define __NR_msync 144
-#define __NR_readv 145
-#define __NR_writev 146
-#define __NR_getsid 147
-#define __NR_fdatasync 148
-#define __NR__sysctl 149
-#define __NR_mlock 150
-#define __NR_munlock 151
-#define __NR_mlockall 152
-#define __NR_munlockall 153
-#define __NR_sched_setparam 154
-#define __NR_sched_getparam 155
-#define __NR_sched_setscheduler 156
-#define __NR_sched_getscheduler 157
-#define __NR_sched_yield 158
-#define __NR_sched_get_priority_max 159
-#define __NR_sched_get_priority_min 160
-#define __NR_sched_rr_get_interval 161
-#define __NR_nanosleep 162
-#define __NR_mremap 163
-
-#ifndef _LIBC
-#define SYS_setup 0
-#define SYS_exit 1
-#define SYS_fork 2
-#define SYS_read 3
-#define SYS_write 4
-#define SYS_open 5
-#define SYS_close 6
-#define SYS_waitpid 7
-#define SYS_creat 8
-#define SYS_link 9
-#define SYS_unlink 10
-#define SYS_execve 11
-#define SYS_chdir 12
-#define SYS_time 13
-#define SYS_mknod 14
-#define SYS_chmod 15
-#define SYS_chown 16
-#define SYS_break 17
-#define SYS_oldstat 18
-#define SYS_lseek 19
-#define SYS_getpid 20
-#define SYS_mount 21
-#define SYS_umount 22
-#define SYS_setuid 23
-#define SYS_getuid 24
-#define SYS_stime 25
-#define SYS_ptrace 26
-#define SYS_alarm 27
-#define SYS_oldfstat 28
-#define SYS_pause 29
-#define SYS_utime 30
-#define SYS_stty 31
-#define SYS_gtty 32
-#define SYS_access 33
-#define SYS_nice 34
-#define SYS_ftime 35
-#define SYS_sync 36
-#define SYS_kill 37
-#define SYS_rename 38
-#define SYS_mkdir 39
-#define SYS_rmdir 40
-#define SYS_dup 41
-#define SYS_pipe 42
-#define SYS_times 43
-#define SYS_prof 44
-#define SYS_brk 45
-#define SYS_setgid 46
-#define SYS_getgid 47
-#define SYS_signal 48
-#define SYS_geteuid 49
-#define SYS_getegid 50
-#define SYS_acct 51
-#define SYS_phys 52
-#define SYS_lock 53
-#define SYS_ioctl 54
-#define SYS_fcntl 55
-#define SYS_mpx 56
-#define SYS_setpgid 57
-#define SYS_ulimit 58
-#define SYS_oldolduname 59
-#define SYS_umask 60
-#define SYS_chroot 61
-#define SYS_ustat 62
-#define SYS_dup2 63
-#define SYS_getppid 64
-#define SYS_getpgrp 65
-#define SYS_setsid 66
-#define SYS_sigaction 67
-#define SYS_sgetmask 68
-#define SYS_ssetmask 69
-#define SYS_setreuid 70
-#define SYS_setregid 71
-#define SYS_sigsuspend 72
-#define SYS_sigpending 73
-#define SYS_sethostname 74
-#define SYS_setrlimit 75
-#define SYS_getrlimit 76
-#define SYS_getrusage 77
-#define SYS_gettimeofday 78
-#define SYS_settimeofday 79
-#define SYS_getgroups 80
-#define SYS_setgroups 81
-#define SYS_select 82
-#define SYS_symlink 83
-#define SYS_oldlstat 84
-#define SYS_readlink 85
-#define SYS_uselib 86
-#define SYS_swapon 87
-#define SYS_reboot 88
-#define SYS_readdir 89
-#define SYS_mmap 90
-#define SYS_munmap 91
-#define SYS_truncate 92
-#define SYS_ftruncate 93
-#define SYS_fchmod 94
-#define SYS_fchown 95
-#define SYS_getpriority 96
-#define SYS_setpriority 97
-#define SYS_profil 98
-#define SYS_statfs 99
-#define SYS_fstatfs 100
-#define SYS_ioperm 101
-#define SYS_socketcall 102
-#define SYS_syslog 103
-#define SYS_setitimer 104
-#define SYS_getitimer 105
-#define SYS_stat 106
-#define SYS_lstat 107
-#define SYS_fstat 108
-#define SYS_olduname 109
-#define SYS_iopl 110
-#define SYS_vhangup 111
-#define SYS_idle 112
-#define SYS_vm86 113
-#define SYS_wait4 114
-#define SYS_swapoff 115
-#define SYS_sysinfo 116
-#define SYS_ipc 117
-#define SYS_fsync 118
-#define SYS_sigreturn 119
-#define SYS_clone 120
-#define SYS_setdomainname 121
-#define SYS_uname 122
-#define SYS_modify_ldt 123
-#define SYS_adjtimex 124
-#define SYS_mprotect 125
-#define SYS_sigprocmask 126
-#define SYS_create_module 127
-#define SYS_init_module 128
-#define SYS_delete_module 129
-#define SYS_get_kernel_syms 130
-#define SYS_quotactl 131
-#define SYS_getpgid 132
-#define SYS_fchdir 133
-#define SYS_bdflush 134
-#define SYS_sysfs 135
-#define SYS_personality 136
-#define SYS_afs_syscall 137 /* Syscall for Andrew File System */
-#define SYS_setfsuid 138
-#define SYS_setfsgid 139
-#define SYS__llseek 140
-#define SYS_getdents 141
-#define SYS__newselect 142
-#define SYS_flock 143
-#define SYS_msync 144
-#define SYS_readv 145
-#define SYS_writev 146
-#define SYS_getsid 147
-#define SYS_fdatasync 148
-#define SYS__sysctl 149
-#define SYS_mlock 150
-#define SYS_munlock 151
-#define SYS_mlockall 152
-#define SYS_munlockall 153
-#define SYS_sched_setparam 154
-#define SYS_sched_getparam 155
-#define SYS_sched_setscheduler 156
-#define SYS_sched_getscheduler 157
-#define SYS_sched_yield 158
-#define SYS_sched_get_priority_max 159
-#define SYS_sched_get_priority_min 160
-#define SYS_sched_rr_get_interval 161
-#define SYS_nanosleep 162
-#define SYS_mremap 163
-#endif
-
-#endif
diff --git a/sysdeps/unix/sysv/linux/rt_sigsuspend.c b/sysdeps/unix/sysv/linux/rt_sigsuspend.c
index dc32dcc067..f6f4987cd1 100644
--- a/sysdeps/unix/sysv/linux/rt_sigsuspend.c
+++ b/sysdeps/unix/sysv/linux/rt_sigsuspend.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -18,6 +18,8 @@
#include <errno.h>
#include <signal.h>
+#define __need_NULL
+#include <stddef.h>
int
__syscall_rt_sigsuspend (const sigset_t *set, size_t setsize)
diff --git a/sysdeps/unix/sysv/linux/rt_sigtimedwait.c b/sysdeps/unix/sysv/linux/rt_sigtimedwait.c
index 4513026f44..3bf9834fa7 100644
--- a/sysdeps/unix/sysv/linux/rt_sigtimedwait.c
+++ b/sysdeps/unix/sysv/linux/rt_sigtimedwait.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -18,6 +18,8 @@
#include <errno.h>
#include <signal.h>
+#define __need_NULL
+#include <stddef.h>
int
__syscall_rt_sigtimedwait (const sigset_t *set, siginfo_t *info,
diff --git a/sysdeps/unix/sysv/linux/sigwaitinfo.c b/sysdeps/unix/sysv/linux/sigwaitinfo.c
index 5f41ba054b..da4624e53e 100644
--- a/sysdeps/unix/sysv/linux/sigwaitinfo.c
+++ b/sysdeps/unix/sysv/linux/sigwaitinfo.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -17,6 +17,8 @@
Boston, MA 02111-1307, USA. */
#include <signal.h>
+#define __need_NULL
+#include <stddef.h>
extern int __syscall_rt_sigtimedwait (const sigset_t *, siginfo_t *,
const struct timespec *, size_t);
diff --git a/sysdeps/unix/sysv/linux/updwtmp.c b/sysdeps/unix/sysv/linux/updwtmp.c
new file mode 100644
index 0000000000..e2156a123b
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/updwtmp.c
@@ -0,0 +1,34 @@
+/* Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <string.h>
+#include <unistd.h>
+
+#define TRANSFORM_UTMP_FILE_NAME(file_name) \
+ ((strcmp (file_name, _PATH_UTMP) == 0 \
+ && __access (_PATH_UTMP "x", F_OK) == 0) ? (_PATH_UTMP "x") : \
+ ((strcmp (file_name, _PATH_WTMP) == 0 \
+ && __access ( _PATH_WTMP "x", F_OK) == 0) ? (_PATH_WTMP "x") : \
+ ((strcmp (file_name, _PATH_UTMP "x") == 0 \
+ && __access (_PATH_UTMP "x", F_OK) != 0) ? _PATH_UTMP : \
+ ((strcmp (file_name, _PATH_WTMP "x") == 0 \
+ && __access (_PATH_WTMP "x", F_OK) != 0) ? _PATH_WTMP : \
+ file_name))))
+
+#include <sysdeps/generic/updwtmp.c>
diff --git a/sysdeps/unix/sysv/linux/utmp_file.c b/sysdeps/unix/sysv/linux/utmp_file.c
new file mode 100644
index 0000000000..5775270123
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/utmp_file.c
@@ -0,0 +1,34 @@
+/* Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <string.h>
+#include <unistd.h>
+
+#define TRANSFORM_UTMP_FILE_NAME(file_name) \
+ ((strcmp (file_name, _PATH_UTMP) == 0 \
+ && __access (_PATH_UTMP "x", F_OK) == 0) ? (_PATH_UTMP "x") : \
+ ((strcmp (file_name, _PATH_WTMP) == 0 \
+ && __access ( _PATH_WTMP "x", F_OK) == 0) ? (_PATH_WTMP "x") : \
+ ((strcmp (file_name, _PATH_UTMP "x") == 0 \
+ && __access (_PATH_UTMP "x", F_OK) != 0) ? _PATH_UTMP : \
+ ((strcmp (file_name, _PATH_WTMP "x") == 0 \
+ && __access (_PATH_WTMP "x", F_OK) != 0) ? _PATH_WTMP : \
+ file_name))))
+
+#include <sysdeps/generic/utmp_file.c>
diff --git a/wcsmbs/btowc.c b/wcsmbs/btowc.c
index 7efe62e5f1..b40a98f65b 100644
--- a/wcsmbs/btowc.c
+++ b/wcsmbs/btowc.c
@@ -31,7 +31,7 @@ __btowc (c)
char buf[sizeof (wchar_t)];
struct gconv_step_data data;
char inbuf[1];
- size_t inbytes;
+ char *inptr = inbuf;
size_t converted;
int status;
@@ -42,8 +42,7 @@ __btowc (c)
/* Tell where we want the result. */
data.outbuf = (char *) buf;
- data.outbufavail = 0;
- data.outbufsize = sizeof (wchar_t);
+ data.outbufend = data.outbuf + sizeof (wchar_t);
data.is_last = 1;
data.statep = &data.__state;
@@ -55,10 +54,9 @@ __btowc (c)
/* Create the input string. */
inbuf[0] = c;
- inbytes = 1;
status = (*__wcsmbs_gconv_fcts.towc->fct) (__wcsmbs_gconv_fcts.towc,
- &data, inbuf, &inbytes,
+ &data, &inptr, inptr + 1,
&converted, 0);
/* The conversion failed. */
if (status != GCONV_OK && status != GCONV_FULL_OUTPUT
diff --git a/wcsmbs/mbrtowc.c b/wcsmbs/mbrtowc.c
index 14ca0b0975..1dcaf968ea 100644
--- a/wcsmbs/mbrtowc.c
+++ b/wcsmbs/mbrtowc.c
@@ -36,14 +36,15 @@ __mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)
{
wchar_t buf[1];
struct gconv_step_data data;
- size_t inbytes;
int status;
size_t result;
+ size_t dummy;
+ const char *inbuf;
+ char *outbuf = (char *) (pwc ?: buf);
/* Tell where we want the result. */
- data.outbuf = (char *) (pwc ?: buf);
- data.outbufavail = 0;
- data.outbufsize = sizeof (wchar_t);
+ data.outbuf = outbuf;
+ data.outbufend = outbuf + sizeof (wchar_t);
data.is_last = 1;
data.statep = ps ?: &state;
@@ -60,9 +61,10 @@ __mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)
update_conversion_ptrs ();
/* Do a normal conversion. */
- inbytes = n;
+ inbuf = s;
status = (*__wcsmbs_gconv_fcts.towc->fct) (__wcsmbs_gconv_fcts.towc,
- &data, s, &inbytes, NULL, 0);
+ &data, &inbuf, inbuf + n,
+ &dummy, 0);
/* There must not be any problems with the conversion but illegal input
characters. The output buffer must be large enough, otherwise the
@@ -76,14 +78,14 @@ __mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)
if (status == GCONV_OK || status == GCONV_EMPTY_INPUT
|| status == GCONV_FULL_OUTPUT)
{
- if (data.outbufavail > 0 && *(wchar_t *)data.outbuf == L'\0')
+ if (data.outbuf != outbuf && *(wchar_t *)data.outbuf == L'\0')
{
/* The converted character is the NUL character. */
assert (__mbsinit (data.statep));
result = 0;
}
else
- result = n - inbytes;
+ result = inbuf - s;
}
else
{
diff --git a/wcsmbs/mbsnrtowcs.c b/wcsmbs/mbsnrtowcs.c
index d408b39430..46a718b3f5 100644
--- a/wcsmbs/mbsnrtowcs.c
+++ b/wcsmbs/mbsnrtowcs.c
@@ -44,7 +44,7 @@ __mbsnrtowcs (dst, src, nmc, len, ps)
size_t len;
mbstate_t *ps;
{
- size_t inbytes_in;
+ const char *srcend;
struct gconv_step_data data;
size_t result = 0;
int status;
@@ -55,7 +55,7 @@ __mbsnrtowcs (dst, src, nmc, len, ps)
if (nmc == 0)
return 0;
- inbytes_in = __strnlen (*src, nmc - 1) + 1;
+ srcend = *src + __strnlen (*src, nmc - 1) + 1;
/* Make sure we use the correct function. */
update_conversion_ptrs ();
@@ -64,21 +64,15 @@ __mbsnrtowcs (dst, src, nmc, len, ps)
if (dst == NULL)
{
wchar_t buf[64]; /* Just an arbitrary size. */
- size_t inbytes = inbytes_in;
const char *inbuf = *src;
size_t written;
data.outbuf = (char *) buf;
- data.outbufsize = sizeof (buf);
+ data.outbufend = data.outbuf + sizeof (buf);
do
{
- inbuf += inbytes_in - inbytes;
- inbytes_in = inbytes;
- data.outbufavail = 0;
- written = 0;
-
status = (*__wcsmbs_gconv_fcts.towc->fct) (__wcsmbs_gconv_fcts.towc,
- &data, inbuf, &inbytes,
+ &data, &inbuf, srcend,
&written, 0);
result += written;
}
@@ -94,14 +88,11 @@ __mbsnrtowcs (dst, src, nmc, len, ps)
/* This code is based on the safe assumption that all internal
multi-byte encodings use the NUL byte only to mark the end
of the string. */
- size_t inbytes = inbytes_in;
-
data.outbuf = (char *) dst;
- data.outbufsize = len * sizeof (wchar_t);
- data.outbufavail = 0;
+ data.outbufend = data.outbuf + len * sizeof (wchar_t);
status = (*__wcsmbs_gconv_fcts.towc->fct) (__wcsmbs_gconv_fcts.towc,
- &data, *src, &inbytes,
+ &data, src, srcend,
&result, 0);
/* We have to determine whether the last character converted
@@ -114,8 +105,6 @@ __mbsnrtowcs (dst, src, nmc, len, ps)
*src = NULL;
--result;
}
- else
- *src += inbytes_in - inbytes;
}
/* There must not be any problems with the conversion but illegal input
diff --git a/wcsmbs/mbsrtowcs.c b/wcsmbs/mbsrtowcs.c
index 8f9efb3285..9172fd9ede 100644
--- a/wcsmbs/mbsrtowcs.c
+++ b/wcsmbs/mbsrtowcs.c
@@ -19,6 +19,7 @@
#include <errno.h>
#include <gconv.h>
+#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include <wcsmbsload.h>
@@ -55,22 +56,16 @@ __mbsrtowcs (dst, src, len, ps)
if (dst == NULL)
{
wchar_t buf[64]; /* Just an arbitrary size. */
- size_t inbytes_in = strlen (*src) + 1;
- size_t inbytes = inbytes_in;
+ const char *srcend = *src + strlen (*src) + 1;
const char *inbuf = *src;
size_t written;
data.outbuf = (char *) buf;
- data.outbufsize = sizeof (buf);
+ data.outbufend = data.outbuf + sizeof (buf);
do
{
- inbuf += inbytes_in - inbytes;
- inbytes_in = inbytes;
- data.outbufavail = 0;
- written = 0;
-
status = (*__wcsmbs_gconv_fcts.towc->fct) (__wcsmbs_gconv_fcts.towc,
- &data, inbuf, &inbytes,
+ &data, &inbuf, srcend,
&written, 0);
result += written;
}
@@ -86,15 +81,13 @@ __mbsrtowcs (dst, src, len, ps)
/* This code is based on the safe assumption that all internal
multi-byte encodings use the NUL byte only to mark the end
of the string. */
- size_t inbytes_in = __strnlen (*src, len * MB_CUR_MAX) + 1;
- size_t inbytes = inbytes_in;
+ const char *srcend = *src + __strnlen (*src, len * MB_CUR_MAX) + 1;
data.outbuf = (char *) dst;
- data.outbufsize = len * sizeof (wchar_t);
- data.outbufavail = 0;
+ data.outbufend = data.outbuf + len * sizeof (wchar_t);
status = (*__wcsmbs_gconv_fcts.towc->fct) (__wcsmbs_gconv_fcts.towc,
- &data, *src, &inbytes,
+ &data, src, srcend,
&result, 0);
/* We have to determine whether the last character converted
@@ -107,8 +100,6 @@ __mbsrtowcs (dst, src, len, ps)
*src = NULL;
--result;
}
- else
- *src += inbytes_in - inbytes;
}
/* There must not be any problems with the conversion but illegal input
diff --git a/wcsmbs/wcrtomb.c b/wcsmbs/wcrtomb.c
index dcc2ef67cd..6fd33e06b3 100644
--- a/wcsmbs/wcrtomb.c
+++ b/wcsmbs/wcrtomb.c
@@ -40,11 +40,11 @@ __wcrtomb (char *s, wchar_t wc, mbstate_t *ps)
struct gconv_step_data data;
int status;
size_t result;
+ size_t dummy;
/* Tell where we want the result. */
data.outbuf = s;
- data.outbufavail = 0;
- data.outbufsize = MB_CUR_MAX;
+ data.outbufend = s + MB_CUR_MAX;
data.is_last = 1;
data.statep = ps ?: &state;
@@ -64,23 +64,21 @@ __wcrtomb (char *s, wchar_t wc, mbstate_t *ps)
by a NUL byte. */
if (wc == L'\0')
{
- size_t inbytes = 0;
-
status = (*__wcsmbs_gconv_fcts.tomb->fct) (__wcsmbs_gconv_fcts.tomb,
- &data, NULL, &inbytes,
- NULL, 1);
+ &data, NULL, NULL, &dummy, 1);
if (status == GCONV_OK || status == GCONV_EMPTY_INPUT)
- data.outbuf[data.outbufavail++] = '\0';
+ *data.outbuf++ = '\0';
}
else
{
/* Do a normal conversion. */
- size_t inbytes = sizeof (wchar_t);
+ const char *inbuf = (const char *) &wc;
status = (*__wcsmbs_gconv_fcts.tomb->fct) (__wcsmbs_gconv_fcts.tomb,
- &data, (char *) &wc, &inbytes,
- NULL, 0);
+ &data, &inbuf,
+ inbuf + sizeof (wchar_t),
+ &dummy, 0);
}
/* There must not be any problems with the conversion but illegal input
@@ -94,7 +92,7 @@ __wcrtomb (char *s, wchar_t wc, mbstate_t *ps)
if (status == GCONV_OK || status == GCONV_EMPTY_INPUT
|| status == GCONV_FULL_OUTPUT)
- result = data.outbufavail;
+ result = data.outbuf - s;
else
{
result = (size_t) -1;
diff --git a/wcsmbs/wcsmbsload.c b/wcsmbs/wcsmbsload.c
index c7e5651fe6..f4babc4eb3 100644
--- a/wcsmbs/wcsmbsload.c
+++ b/wcsmbs/wcsmbsload.c
@@ -37,8 +37,8 @@ static struct gconv_step to_wc =
shlib_handle: NULL,
modname: NULL,
counter: INT_MAX,
- from_name: "ANSI_X3.4-1968",
- to_name: "#INTERNAL#",
+ from_name: "ANSI_X3.4-1968//",
+ to_name: "INTERNAL",
fct: __gconv_transform_ascii_internal,
init_fct: NULL,
end_fct: NULL,
@@ -50,8 +50,8 @@ static struct gconv_step to_mb =
shlib_handle: NULL,
modname: NULL,
counter: INT_MAX,
- from_name: "#INTERNAL#",
- to_name: "ANSI_X3.4-1968",
+ from_name: "INTERNAL",
+ to_name: "ANSI_X3.4-1968//",
fct: __gconv_transform_internal_ascii,
init_fct: NULL,
end_fct: NULL,
@@ -113,8 +113,8 @@ __wcsmbs_load_conv (const struct locale_data *new_category)
/* Get name of charset of the locale. */
charset_name = new_category->values[_NL_ITEM_INDEX(CODESET)].string;
- __wcsmbs_gconv_fcts.tomb = getfct (charset_name, "#INTERNAL#");
- __wcsmbs_gconv_fcts.towc = getfct ("#INTERNAL#", charset_name);
+ __wcsmbs_gconv_fcts.tomb = getfct (charset_name, "INTERNAL");
+ __wcsmbs_gconv_fcts.towc = getfct ("INTERNAL", charset_name);
/* If any of the conversion functions is not available we don't
use any since this would mean we cannot convert back and
diff --git a/wcsmbs/wcsnrtombs.c b/wcsmbs/wcsnrtombs.c
index 0daf0e3077..4b6232a182 100644
--- a/wcsmbs/wcsnrtombs.c
+++ b/wcsmbs/wcsnrtombs.c
@@ -44,7 +44,7 @@ __wcsnrtombs (dst, src, nwc, len, ps)
mbstate_t *ps;
{
struct gconv_step_data data;
- size_t inbytes_in;
+ const wchar_t *srcend;
int status;
size_t result;
@@ -54,7 +54,7 @@ __wcsnrtombs (dst, src, nwc, len, ps)
if (nwc == 0)
return 0;
- inbytes_in = (__wcsnlen (*src, nwc - 1) + 1) * sizeof (wchar_t);
+ srcend = *src + __wcsnlen (*src, nwc - 1) + 1;
/* Make sure we use the correct function. */
update_conversion_ptrs ();
@@ -63,30 +63,25 @@ __wcsnrtombs (dst, src, nwc, len, ps)
if (dst == NULL)
{
char buf[256]; /* Just an arbitrary value. */
- size_t inbytes = inbytes_in;
const wchar_t *inbuf = *src;
size_t written;
data.outbuf = buf;
- data.outbufsize = sizeof (buf);
+ data.outbufend = buf + sizeof (buf);
do
{
- inbuf += (inbytes_in - inbytes) / sizeof (wchar_t);
- inbytes_in = inbytes;
- data.outbufavail = 0;
- written = 0;
-
status = (*__wcsmbs_gconv_fcts.tomb->fct) (__wcsmbs_gconv_fcts.tomb,
&data,
- (const char *) inbuf,
- &inbytes, &written, 0);
+ (const char **) &inbuf,
+ (const char *) srcend,
+ &written, 0);
result += written;
}
while (status == GCONV_FULL_OUTPUT);
if ((status == GCONV_OK || status == GCONV_EMPTY_INPUT)
- && buf[data.outbufavail - 1] == '\0')
+ && data.outbuf[-1] == '\0')
/* Don't count the NUL character in. */
--result;
}
@@ -95,28 +90,24 @@ __wcsnrtombs (dst, src, nwc, len, ps)
/* This code is based on the safe assumption that all internal
multi-byte encodings use the NUL byte only to mark the end
of the string. */
- size_t inbytes = inbytes_in;
-
data.outbuf = dst;
- data.outbufavail = 0;
- data.outbufsize = len;
+ data.outbufend = dst + len;
status = (*__wcsmbs_gconv_fcts.tomb->fct) (__wcsmbs_gconv_fcts.tomb,
- &data, (const char *) *src,
- &inbytes, &result, 0);
+ &data, (const char **) src,
+ (const char *) srcend,
+ &result, 0);
/* We have to determine whether the last character converted
is the NUL character. */
if ((status == GCONV_OK || status == GCONV_EMPTY_INPUT)
- && dst[data.outbufavail - 1] == '\0')
+ && data.outbuf[-1] == '\0')
{
- assert (data.outbufavail > 0);
+ assert (data.outbuf != dst);
assert (__mbsinit (data.statep));
*src = NULL;
--result;
}
- else
- *src += result;
}
/* There must not be any problems with the conversion but illegal input
diff --git a/wcsmbs/wcsrtombs.c b/wcsmbs/wcsrtombs.c
index 7b59fc725a..428ef3d4dd 100644
--- a/wcsmbs/wcsrtombs.c
+++ b/wcsmbs/wcsrtombs.c
@@ -55,31 +55,26 @@ __wcsrtombs (dst, src, len, ps)
if (dst == NULL)
{
char buf[256]; /* Just an arbitrary value. */
- size_t inbytes_in = (__wcslen (*src) + 1) * sizeof (wchar_t);
- size_t inbytes = inbytes_in;
+ const wchar_t *srcend = *src + __wcslen (*src) + 1;
const wchar_t *inbuf = *src;
size_t written;
data.outbuf = buf;
- data.outbufsize = sizeof (buf);
+ data.outbufend = buf + sizeof (buf);
do
{
- inbuf += (inbytes_in - inbytes) / sizeof (wchar_t);
- inbytes_in = inbytes;
- data.outbufavail = 0;
- written = 0;
-
status = (*__wcsmbs_gconv_fcts.tomb->fct) (__wcsmbs_gconv_fcts.tomb,
&data,
- (const char *) inbuf,
- &inbytes, &written, 0);
+ (const char **) &inbuf,
+ (const char *) srcend,
+ &written, 0);
result += written;
}
while (status == GCONV_FULL_OUTPUT);
if ((status == GCONV_OK || status == GCONV_EMPTY_INPUT)
- && buf[data.outbufavail - 1] == '\0')
+ && data.outbuf[-1] == '\0')
/* Don't count the NUL character in. */
--result;
}
@@ -88,31 +83,27 @@ __wcsrtombs (dst, src, len, ps)
/* This code is based on the safe assumption that all internal
multi-byte encodings use the NUL byte only to mark the end
of the string. */
- size_t inbytes_in = ((__wcsnlen (*src, len * MB_CUR_MAX) + 1)
- * sizeof (wchar_t));
- size_t inbytes = inbytes_in;
+ const wchar_t *srcend = *src + __wcsnlen (*src, len * MB_CUR_MAX) + 1;
data.outbuf = dst;
- data.outbufavail = 0;
- data.outbufsize = len;
+ data.outbufend = dst + len;
status = (*__wcsmbs_gconv_fcts.tomb->fct) (__wcsmbs_gconv_fcts.tomb,
- &data, (const char *) *src,
- &inbytes, &result, 0);
+ &data, (const char **) src,
+ (const char *) srcend,
+ &result, 0);
/* We have to determine whether the last character converted
is the NUL character. */
if ((status == GCONV_OK || status == GCONV_EMPTY_INPUT
|| status == GCONV_FULL_OUTPUT)
- && dst[data.outbufavail - 1] == '\0')
+ && data.outbuf[-1] == '\0')
{
- assert (data.outbufavail > 0);
+ assert (data.outbuf != dst);
assert (__mbsinit (data.statep));
*src = NULL;
--result;
}
- else
- *src += result;
}
/* There must not be any problems with the conversion but illegal input
diff --git a/wcsmbs/wctob.c b/wcsmbs/wctob.c
index e70b4e7fe6..b06d170388 100644
--- a/wcsmbs/wctob.c
+++ b/wcsmbs/wctob.c
@@ -31,14 +31,13 @@ wctob (c)
char buf[MB_LEN_MAX];
struct gconv_step_data data;
wchar_t inbuf[1];
- size_t inbytes;
+ wchar_t *inptr = inbuf;
size_t converted;
int status;
/* Tell where we want the result. */
- data.outbuf = (char *) buf;
- data.outbufavail = 0;
- data.outbufsize = MB_LEN_MAX;
+ data.outbuf = buf;
+ data.outbufend = buf + MB_LEN_MAX;
data.is_last = 1;
data.statep = &data.__state;
@@ -50,15 +49,15 @@ wctob (c)
/* Create the input string. */
inbuf[0] = c;
- inbytes = sizeof (wchar_t);
status = (*__wcsmbs_gconv_fcts.tomb->fct) (__wcsmbs_gconv_fcts.tomb, &data,
- (const char *) inbuf, &inbytes,
+ (const char **) &inptr,
+ (const char *) &inbuf[1],
&converted, 0);
/* The conversion failed or the output is too long. */
if ((status != GCONV_OK && status != GCONV_FULL_OUTPUT
&& status != GCONV_EMPTY_INPUT)
- || data.outbufavail != 1)
+ || data.outbuf != buf + 1)
return EOF;
return buf[0];