Update.
authorUlrich Drepper <drepper@redhat.com>
Mon, 20 Apr 1998 18:41:05 +0000 (18:41 +0000)
committerUlrich Drepper <drepper@redhat.com>
Mon, 20 Apr 1998 18:41:05 +0000 (18:41 +0000)
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.

141 files changed:
ChangeLog
FAQ
FAQ.in
bits/socket.h
csu/init.c
db2/compat.h
elf/dl-minimal.c
iconv/Makefile
iconv/gconv.c
iconv/gconv.h
iconv/gconv_builtin.c
iconv/gconv_builtin.h
iconv/gconv_conf.c
iconv/gconv_db.c
iconv/gconv_int.h
iconv/gconv_open.c
iconv/gconv_simple.c
iconv/iconv.c
iconv/iconv_prog.c
iconv/loop.c [new file with mode: 0644]
iconv/skeleton.c [new file with mode: 0644]
iconvdata/8bit-gap.c
iconvdata/8bit-generic.c
iconvdata/Makefile
iconvdata/big5.c
iconvdata/cns11643.c
iconvdata/cns11643.h
iconvdata/cns11643l1.c
iconvdata/cns11643l1.h
iconvdata/ebcdic-at-de-a.c
iconvdata/ebcdic-at-de.c
iconvdata/ebcdic-ca-fr.c
iconvdata/euccn.c
iconvdata/eucjp.c
iconvdata/euckr.c
iconvdata/euctw.c
iconvdata/gb2312.c
iconvdata/gb2312.h
iconvdata/hp-roman8.c
iconvdata/iso646.c
iconvdata/iso6937.c
iconvdata/iso8859-1.c
iconvdata/iso8859-10.c
iconvdata/iso8859-2.c
iconvdata/iso8859-3.c
iconvdata/iso8859-4.c
iconvdata/iso8859-5.c
iconvdata/iso8859-6.c
iconvdata/iso8859-7.c
iconvdata/iso8859-8.c
iconvdata/iso8859-9.c
iconvdata/jis0201.c
iconvdata/jis0201.h
iconvdata/jis0208.c
iconvdata/jis0208.h
iconvdata/jis0212.c
iconvdata/jis0212.h
iconvdata/johab.c
iconvdata/koi-8.c
iconvdata/koi8-r.c
iconvdata/ksc5601.c
iconvdata/ksc5601.h
iconvdata/latin-greek-1.c
iconvdata/latin-greek.c
iconvdata/run-iconv-test.sh
iconvdata/sjis.c
iconvdata/t61.c
iconvdata/uhc.c
inet/netinet/in.h
libc.map
libio/fileops.c
libio/oldfileops.c
linuxthreads/ChangeLog
linuxthreads/Makefile
linuxthreads/internals.h
linuxthreads/ptlongjmp.c [new file with mode: 0644]
linuxthreads/spinlock.c [new file with mode: 0644]
linuxthreads/spinlock.h
login/Makefile
login/getutent.c
login/getutent_r.c
login/getutid.c
login/getutline.c
login/utmp.h
manual/creature.texi
posix/getopt.c
posix/regex.c
posix/wordexp-test.c
signal/sighold.c
signal/sigrelse.c
stdlib/mblen.c
stdlib/mbtowc.c
sysdeps/arm/bits/setjmp.h
sysdeps/arm/strlen.S [new file with mode: 0644]
sysdeps/generic/bits/socket.h
sysdeps/generic/endutxent.c [moved from sysdeps/generic/bits/utmpx.h with 63% similarity]
sysdeps/generic/getutxent.c [new file with mode: 0644]
sysdeps/generic/getutxid.c [new file with mode: 0644]
sysdeps/generic/getutxline.c [new file with mode: 0644]
sysdeps/generic/longjmp.c
sysdeps/generic/pututxline.c [new file with mode: 0644]
sysdeps/generic/setjmp.c
sysdeps/generic/setutxent.c [new file with mode: 0644]
sysdeps/generic/strcasestr.c
sysdeps/generic/updwtmp.c [moved from login/updwtmp.c with 57% similarity]
sysdeps/generic/updwtmpx.c [new file with mode: 0644]
sysdeps/generic/utmp_file.c [moved from login/utmp_file.c with 96% similarity]
sysdeps/generic/utmpxname.c [new file with mode: 0644]
sysdeps/gnu/Makefile
sysdeps/gnu/bits/utmpx.h
sysdeps/gnu/updwtmp.c [new file with mode: 0644]
sysdeps/gnu/utmp_file.c [new file with mode: 0644]
sysdeps/gnu/utmpx.h [moved from login/utmpx.h with 73% similarity]
sysdeps/i386/bits/setjmp.h
sysdeps/m68k/bits/setjmp.h
sysdeps/mach/hurd/Subdirs
sysdeps/mach/hurd/bits/ioctls.h
sysdeps/posix/sigignore.c
sysdeps/posix/sigset.c
sysdeps/posix/waitid.c
sysdeps/powerpc/bits/setjmp.h
sysdeps/powerpc/elf/start.c [deleted file]
sysdeps/sparc/sparc32/bits/setjmp.h
sysdeps/unix/sysv/linux/i386/s_pread64.S
sysdeps/unix/sysv/linux/paths.h
sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c
sysdeps/unix/sysv/linux/powerpc/syscall.h [deleted file]
sysdeps/unix/sysv/linux/rt_sigsuspend.c
sysdeps/unix/sysv/linux/rt_sigtimedwait.c
sysdeps/unix/sysv/linux/sigwaitinfo.c
sysdeps/unix/sysv/linux/updwtmp.c [new file with mode: 0644]
sysdeps/unix/sysv/linux/utmp_file.c [new file with mode: 0644]
wcsmbs/btowc.c
wcsmbs/mbrtowc.c
wcsmbs/mbsnrtowcs.c
wcsmbs/mbsrtowcs.c
wcsmbs/wcrtomb.c
wcsmbs/wcsmbsload.c
wcsmbs/wcsnrtombs.c
wcsmbs/wcsrtombs.c
wcsmbs/wctob.c

index 6521054..105bed4 100644 (file)
--- 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 6eb4ff0..ed46581 100644 (file)
--- 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>
 \f
 Local Variables:
diff --git a/FAQ.in b/FAQ.in
index 7ca0218..0a8277f 100644 (file)
--- 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>
 \f
 Local Variables:
index 5dc1e65..01844bc 100644 (file)
@@ -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 */
index 2b7a2ef..df08f6c 100644 (file)
@@ -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>
index 8652ad9..86909ae 100644 (file)
@@ -1,6 +1,7 @@
 /* Compatibility gunk for the db library.  */
 
 #include <sys/types.h>
+#include <errno.h>
 
 #ifndef EFTYPE
 # define EFTYPE EINVAL
index b0c8c46..70b5aee 100644 (file)
@@ -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);
 
 }
 
index 783b1d5..e4cd0fc 100644 (file)
 #
 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
index f8b7c80..aa58bdb 100644 (file)
    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;
 }
index f3f80f4..cd0e3de 100644 (file)
@@ -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;
 
index 6b14804..a970fcc 100644 (file)
@@ -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;
 }
index 265dca1..3d214ff 100644 (file)
@@ -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)
index c67a0d8..ae5ba19 100644 (file)
@@ -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"
index 9f4366b..62d8f05 100644 (file)
@@ -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;
 }
index a1475f8..86e892f 100644 (file)
@@ -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);
index d82dcfe..831794f 100644 (file)
@@ -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;
                }
            }
        }
index b72e61e..f2fec12 100644 (file)
@@ -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>
index fc0ed41..2f57295 100644 (file)
@@ -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:
index 569bd3b..2452a88 100644 (file)
@@ -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 (file)
index 0000000..b8657d5
--- /dev/null
@@ -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 (file)
index 0000000..3582f14
--- /dev/null
@@ -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
index a8d3c99..4065a6d 100644 (file)
    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>
index 19194ad..2ea3331 100644 (file)
    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>
index dd1c391..6957685 100644 (file)
@@ -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)) \
index a6a2580..2962712 100644 (file)
@@ -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>
index 9035482..bd1994f 100644 (file)
@@ -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",
index f791d4c..ccab801 100644 (file)
@@ -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;
index 730fb55..d106b3d 100644 (file)
@@ -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",
index 4f9d085..aa78c26 100644 (file)
    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;
index 7251490..654bdf8 100644 (file)
@@ -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.
 
    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>
index d9168fc..ab71885 100644 (file)
@@ -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.
 
    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>
index a42914e..91cf5aa 100644 (file)
@@ -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.
 
    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>
index f683836..90e82cb 100644 (file)
    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>
index e6a71cc..24ebed9 100644 (file)
    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>
index 2ad9478..50e4b40 100644 (file)
@@ -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
    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>
index fd422c1..406dd67 100644 (file)
    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>
index 89d7161..9cde1c8 100644 (file)
@@ -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",
index 922fcc8..df87950 100644 (file)
@@ -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;
index db36cea..62e29ea 100644 (file)
@@ -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.
 
    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>
index 53ca76c..3c40c8f 100644 (file)
@@ -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;
 }
index 21e3ab4..b121ffa 100644 (file)
    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>
index b9484a0..3e50b79 100644 (file)
    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>
index eb54e49..acce325 100644 (file)
@@ -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.
 
    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>
index fa07b75..8a5e624 100644 (file)
@@ -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.
 
    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>
index c31d388..10e52e4 100644 (file)
@@ -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.
 
    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>
index 7ae9847..01cdbf0 100644 (file)
@@ -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.
 
    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>
index b4791f1..edf0f47 100644 (file)
@@ -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.
 
    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>
index 1e88ec9..59ce3f2 100644 (file)
@@ -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.
 
    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>
index 63220bb..d75e93e 100644 (file)
@@ -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.
 
    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>
index 2246ae4..1612f14 100644 (file)
@@ -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.
 
    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>
index 5260362..063f189 100644 (file)
@@ -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.
 
    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>
index e8e04e1..65321e4 100644 (file)
@@ -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.
 
    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,
index 8f920f9..1514c88 100644 (file)
 #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;
 
index 8db4085..964f73d 100644 (file)
@@ -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",
index 94d2764..a83ee3b 100644 (file)
 #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];
index 7484c5e..eca645f 100644 (file)
@@ -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",
index cf5d919..4930437 100644 (file)
@@ -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];
index c9912a7..6a582c0 100644 (file)
@@ -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
    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>
index 2228456..b2332c2 100644 (file)
@@ -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.
 
    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>
index 502132b..ee317bd 100644 (file)
@@ -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.
 
    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>
index c919425..da64c43 100644 (file)
@@ -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},
index 0d86c7b..8a5c40e 100644 (file)
 #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);
index d62969a..37ccf09 100644 (file)
@@ -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.
 
    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>
index 90270e0..8810f4a 100644 (file)
@@ -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.
 
    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>
index ebafa2f..af6a136 100755 (executable)
@@ -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
 
index 33dc2f1..d65b905 100644 (file)
    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>
index b77ee71..8c288ad 100644 (file)
@@ -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>
index ed4b7ad..f3addd4 100644 (file)
    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>
index ff8476e..c6985ff 100644 (file)
@@ -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
   {
index 6a40713..bc3c286 100644 (file)
--- 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;
index 7e60f7c..e5ffb24 100644 (file)
@@ -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.
index 41fbc69..7cf4fdf 100644 (file)
@@ -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;
index 7913e08..ba2a20f 100644 (file)
@@ -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
index 8813ae1..cdfe06c 100644 (file)
@@ -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
index 0649e0d..c568296 100644 (file)
@@ -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 (file)
index 0000000..1397dba
--- /dev/null
@@ -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 (file)
index 0000000..170d9ae
--- /dev/null
@@ -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;
+    }
+  }
+}
index d324abb..1707d3e 100644 (file)
 
 /* 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)
index 5f7861b..96c75f7 100644 (file)
@@ -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 \
index eb99158..51e1475 100644 (file)
@@ -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)
index 96c458f..8391331 100644 (file)
@@ -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)
index 98e8e4a..91e3ea2 100644 (file)
@@ -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)
index 1e1ecb1..7fc402f 100644 (file)
@@ -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)
index 82f3fcc..ccf29b2 100644 (file)
@@ -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));
 
 
index 66e53ac..00e3aad 100644 (file)
@@ -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
index 7afe6c4..4cbf361 100644 (file)
 /* 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>
 
 #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
 #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')
index b7fb962..e2d31a0 100644 (file)
@@ -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;
index ba69476..81f93a1 100644 (file)
@@ -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))
index d2cb537..730bcac 100644 (file)
@@ -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
index 44e1001..971d60f 100644 (file)
@@ -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
index e43b076..d60a1fb 100644 (file)
@@ -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;
 }
index 61b46f8..50e7c09 100644 (file)
@@ -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;
 }
index 5cf9cd7..ea25a9b 100644 (file)
@@ -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 (file)
index 0000000..9acef4f
--- /dev/null
@@ -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)
index 5dc1e65..01844bc 100644 (file)
@@ -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 */
similarity index 63%
rename from sysdeps/generic/bits/utmpx.h
rename to sysdeps/generic/endutxent.c
index e22660f..cd8d7e4 100644 (file)
@@ -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
    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 (file)
index 0000000..f6f07d5
--- /dev/null
@@ -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 (file)
index 0000000..d58f4c3
--- /dev/null
@@ -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 (file)
index 0000000..4296ea6
--- /dev/null
@@ -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);
+}
index f46f160..1a4850f 100644 (file)
@@ -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 (file)
index 0000000..d1246bc
--- /dev/null
@@ -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);
+}
index 8b1dfa6..56230aa 100644 (file)
@@ -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 (file)
index 0000000..267a1bd
--- /dev/null
@@ -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 ();
+}
index ec8727d..a5786fa 100644 (file)
@@ -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)
similarity index 57%
rename from login/updwtmp.c
rename to sysdeps/generic/updwtmp.c
index 9965a61..d6f29b1 100644 (file)
@@ -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.
 
    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 (file)
index 0000000..097bf38
--- /dev/null
@@ -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);
+}
similarity index 96%
rename from login/utmp_file.c
rename to sysdeps/generic/utmp_file.c
index 9cdb88e..0867518 100644 (file)
@@ -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 (file)
index 0000000..41c9193
--- /dev/null
@@ -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);
+}
index e491fa2..762f79b 100644 (file)
@@ -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
index 4ecbb3a..b367bfb 100644 (file)
@@ -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
 #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 (file)
index 0000000..19a7765
--- /dev/null
@@ -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 (file)
index 0000000..05bbcd1
--- /dev/null
@@ -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>
similarity index 73%
rename from login/utmpx.h
rename to sysdeps/gnu/utmpx.h
index 5873bf9..e9f2389 100644 (file)
@@ -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  */
index 5cb60a8..4672922 100644 (file)
@@ -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
index 2991232..a302b72 100644 (file)
@@ -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
index 1145560..1e063e3 100644 (file)
    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 */
index f24aca7..497af57 100644 (file)
@@ -19,6 +19,8 @@
    Boston, MA 02111-1307, USA.  */
 
 #include <errno.h>
+#define __need_NULL
+#include <stddef.h>
 #include <signal.h>
 
 int
index 4bd3bf3..1a6b1a4 100644 (file)
@@ -17,6 +17,8 @@
    Boston, MA 02111-1307, USA.  */
 
 #include <errno.h>
+#define __need_NULL
+#include <stddef.h>
 #include <signal.h>
 
 
index a36883a..fa90211 100644 (file)
@@ -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>
 
index 7bb654c..65db364 100644 (file)
@@ -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 (file)
index d32aeee..0000000
+++ /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));
-}
index 0e61fe7..3d39132 100644 (file)
@@ -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
index 7f8816b..23d7d14 100644 (file)
@@ -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)
index 53c4fc5..cb5b571 100644 (file)
@@ -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"
 
index fa946cf..9e31ed4 100644 (file)
@@ -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 (file)
index c6bac3d..0000000
+++ /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
index dc32dcc..f6f4987 100644 (file)
@@ -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)
index 4513026..3bf9834 100644 (file)
@@ -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,
index 5f41ba0..da4624e 100644 (file)
@@ -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 (file)
index 0000000..e2156a1
--- /dev/null
@@ -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 (file)
index 0000000..5775270
--- /dev/null
@@ -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>
index 7efe62e..b40a98f 100644 (file)
@@ -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
index 14ca0b0..1dcaf96 100644 (file)
@@ -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
     {
index d408b39..46a718b 100644 (file)
@@ -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
index 8f9efb3..9172fd9 100644 (file)
@@ -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
index dcc2ef6..6fd33e0 100644 (file)
@@ -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;
index c7e5651..f4babc4 100644 (file)
@@ -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
index 0daf0e3..4b6232a 100644 (file)
@@ -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
index 7b59fc7..428ef3d 100644 (file)
@@ -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
index e70b4e7..b06d170 100644 (file)
@@ -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];