about summary refs log tree commit diff
path: root/iconvdata/johab.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1998-04-20 18:41:05 +0000
committerUlrich Drepper <drepper@redhat.com>1998-04-20 18:41:05 +0000
commit8619129f3f0d5a9db6208be5bae6c2a8c9ce61a5 (patch)
tree033b6528f39a85f12db9d0859dbd1b90c2906eee /iconvdata/johab.c
parentf1fa8b68f3e7623a3ef86dcd0c7d090ccf0389f5 (diff)
downloadglibc-8619129f3f0d5a9db6208be5bae6c2a8c9ce61a5.tar.gz
glibc-8619129f3f0d5a9db6208be5bae6c2a8c9ce61a5.tar.xz
glibc-8619129f3f0d5a9db6208be5bae6c2a8c9ce61a5.zip
Update.
1998-04-20 18:00  Ulrich Drepper  <drepper@cygnus.com>

	* libc.map: Add __dgettext to GLIBC_2.0 and __libc_longjmp, and
	__libc_siglongjmp to GLIBC_2.1.

	* elf/dl-minimal.c (__assert_perror_fail): Don't use strerror, use
	__strerror_r.

	* iconv/Makefile: Don't run tests now.

	* iconv/iconv_prog.c (process_block): If loop is repeated, call iconv
	with correct output buffer.

	Major rewrite of the low-level gconv functionality.
	* iconv/gconv.c: Rewritten.
	* iconv/gconv.h: Likewise.
	* iconv/gconv_builtin.c: Likewise.
	* iconv/gconv_builtin.h: Likewise.
	* iconv/gconv_conf.c: Likewise.
	* iconv/gconv_int.h: Likewise.
	* iconv/gconv_open.c: Likewise.
	* iconv/gconv_simple.c: Likewise.
	* iconv/iconv.c: Likewise.
	* iconvdata/8bit-gap.c: Likewise.
	* iconvdata/8bit-generic.c: Likewise.
	* iconvdata/Makefile: Likewise.
	* iconvdata/big5.c: Likewise.
	* iconvdata/cns11643.c: Likewise.
	* iconvdata/cns11643.h: Likewise.
	* iconvdata/cns11643l1.c: Likewise.
	* iconvdata/cns11643l1.h: Likewise.
	* iconvdata/ebcdic-at-de-a.c: Likewise.
	* iconvdata/ebcdic-at-de.c: Likewise.
	* iconvdata/ebcdic-ca-fr.c: Likewise.
	* iconvdata/euccn.c: Likewise.
	* iconvdata/eucjp.c: Likewise.
	* iconvdata/euckr.c: Likewise.
	* iconvdata/euctw.c: Likewise.
	* iconvdata/gb2312.c: Likewise.
	* iconvdata/gb2312.h: Likewise.
	* iconvdata/hp-roman8.c: Likewise.
	* iconvdata/iso646.c: Likewise.
	* iconvdata/iso6937.c: Likewise.
	* iconvdata/iso8859-1.c: Likewise.
	* iconvdata/iso8859-10.c: Likewise.
	* iconvdata/iso8859-2.c: Likewise.
	* iconvdata/iso8859-3.c: Likewise.
	* iconvdata/iso8859-4.c: Likewise.
	* iconvdata/iso8859-5.c: Likewise.
	* iconvdata/iso8859-6.c: Likewise.
	* iconvdata/iso8859-7.c: Likewise.
	* iconvdata/iso8859-8.c: Likewise.
	* iconvdata/iso8859-9.c: Likewise.
	* iconvdata/jis0201.c: Likewise.
	* iconvdata/jis0201.h: Likewise.
	* iconvdata/jis0208.c: Likewise.
	* iconvdata/jis0208.h: Likewise.
	* iconvdata/jis0212.c: Likewise.
	* iconvdata/jis0212.h: Likewise.
	* iconvdata/johab.c: Likewise.
	* iconvdata/koi-8.c: Likewise.
	* iconvdata/koi8-r.c: Likewise.
	* iconvdata/ksc5601.c: Likewise.
	* iconvdata/ksc5601.h: Likewise.
	* iconvdata/latin-greek-1.c: Likewise.
	* iconvdata/latin-greek.c: Likewise.
	* iconvdata/run-iconv-test.sh: Likewise.
	* iconvdata/sjis.c: Likewise.
	* iconvdata/t61.c: Likewise.
	* iconvdata/uhc.c: Likewise.
	* wcsmbs/btowc.c: Likewise.
	* wcsmbs/mbrtowc.c: Likewise.
	* wcsmbs/mbsnrtowcs.c: Likewise.
	* wcsmbs/mbsrtowcs.c: Likewise.
	* wcsmbs/wcrtomb.c: Likewise.
	* wcsmbs/wcsmbsload.c: Likewise.
	* wcsmbs/wcsnrtombs.c: Likewise.
	* wcsmbs/wcsrtombs.c: Likewise.
	* wcsmbs/wctob.c: Likewise.
	* iconv/loop.c: New file.
	* iconv/skeleton.c: New file.

	* stdlib/mblen.c: Handle empty input string correctly.
	* stdlib/mbtowc.c: Likewise.

	* posix/getopt.c: Various cleanups.

	* sysdeps/arm/bits/setjmp.h: Add copyright text.
	* sysdeps/i386/bits/setjmp.h: Likewise.
	* sysdeps/m68k/bits/setjmp.h: Likewise.
	* sysdeps/powerpc/bits/setjmp.h: Likewise.
	* sysdeps/sparc/sparc32/bits/setjmp.h: Likewise.

	* sysdeps/generic/longjmp.c: Rename function to __libc_siglongjmp
	and make longjmp weak alias.

1998-04-18 20:29  Philip Blundell  <Philip.Blundell@pobox.com>

	* iconv/Makefile (routines): Only include gconv_dl if building for
	an ELF system - dynamic linking is not available on a.out.
	(CFLAGS-gconv_conf.c): Define STATIC_GCONV if omitting gconv_dl
	due to above check.
	* iconv/gconv_db.c: If STATIC_GCONV defined, don't try to call
	routines from gconv_dl.

1998-04-17  Gordon Matzigkeit  <gord@profitpress.com>

	* csu/init.c (_IO_stdin_used): Protect with USE_IN_LIBIO so that
	we can compile without libio.

1998-04-20 16:28  Ulrich Drepper  <drepper@cygnus.com>

	* sysdeps/mach/hurd/Subdirs: Remove login.

1998-04-11  Gordon Matzigkeit  <gord@profitpress.com>

	* db2/compat.h: Include <errno.h>, to make sure we get the
	definition of EFTYPE before we define it ourselves.

1998-04-10  Gordon Matzigkeit  <gord@profitpress.com>

	* sysdeps/generic/bits/socket.h: Protect against multiple inclusion.
	* sysdeps/mach/hurd/bits/ioctls.h: Likewise.
	Fix typo to allow inclusion from sys/ioctl.h again.

1998-04-16  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* iconvdata/*.[ch]: Clean up namespace.  Optimize character lookup.

1998-04-16  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* libc.map: Export __strerror_r.  Remove _strerror_internal.

1998-04-16  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* sysdeps/generic/strcasestr.c: Undefine strcasestr, not strstr.
	Also undefine __strcasestr.

1998-04-16  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* posix/regex.c: Rename __re_max_failures back to re_max_failures,
	aliases do not work with global variables due to copy relocations.

1998-04-20 15:12  Ulrich Drepper  <drepper@cygnus.com>

	* manual/creature.texi: Fix type.  Patch by Andreas Schwab.

1998-04-20 13:47  Ulrich Drepper  <drepper@cygnus.com>

	* signal/sighold.c: Include stddef.h for NULL definition.
	* signal/sigrelse.c: Likewise.
	* sysdeps/posix/sigignore.c: Likewise.
	* sysdeps/posix/sigset.c: Likewise.
	* sysdeps/posix/waitid.c: Likewise.
	* sysdeps/unix/sysv/linux/rt_sigsuspend.c: Likewise.
	* sysdeps/unix/sysv/linux/rt_sigtimedwait.c: Likewise.
	* sysdeps/unix/sysv/linux/sigwaitinfo.c: Likewise.
	* wcsmbs/mbsrtowcs.c: Include stdlib.h for MB_CUR_MAX.
	Patch by Franz Sirl <Franz.Sirl-kernel@lauterbach.com>.

1998-04-13  Mark Kettenis  <kettenis@phys.uva.nl>

	* login/Makefile (headers): Remove utmpx.h and bits/utmpx.h.
	* login/getutent.c (getutxent): Remove alias.
	* login/getutent_r.c (setutxent, pututxline, endutxent):
	Remove aliases.
	* login/getutid.c (getutxid): Remove alias.
	* login/getutline.c (getutxline): Remove alias.
	* login/utmp.h: Add prototypes for __updwtmp, __getutent,
	__getutid, __getutline and __pututline.
	* login/utmpx.h: Moved to ...
	* sysdeps/gnu/utmpx.h: ... here.  [__USE_GNU]: Define UTMPX_FILE,
	UTMPX_FILENAME, WTMPX_FILE and WTMPX_FILENAME, declare utmpxname
	and updwtmpx.
	* login/updwtmp.c: Moved to ...
	* sysdeps/generic/updwtmp.c: ... here.  (updwtmp): Generalized by
	allowing file name transformation.
	* sysdeps/gnu/updwtmp.c: New file.  Use generic implementation with
	additional file name transformation.
	* sysdeps/unix/sysv/linux/updwtmp.c: Likewise.
	* login/utmp_file.c: Moved to ...
	* sysdeps/generic/utmp_file.c: ... here.  (setutent_file):
	Generalized by allowing file name transformation.  Do not
	print error message.  Library functions should not print them.
	Reported by Jim Meyering.
	* sysdeps/gnu/utmp_file.c: New file.  Use generic implementation
	with additional file name transformation.
	* sysdeps/unix/sysv/linux/utmp_file.c: Likewise.
	* sysdeps/gnu/Makefile [$(subdir)=login] (sysdep_routines): Add
	setutxent, getutxent, endutxent, getutxid, getutxid, getutxline,
	pututxline, utmpxname and updwtmpx.  (sysdep_headers): Add utmpx.h
	and bits/utmpx.h.
	* sysdeps/gnu/bits/utmpx.h [__USE_GNU] Include paths.h.
	(_PATH_UTMPX): Define to _PATH_UTMP.  (_PATH_WTMPX): Define to
	_PATH_WTMPX.  (RUN_LVL): Define only if __USE_GNU.  (ACCOUNTING):
	Define if __USE_GNU.
	* sysdeps/gnu/setutxent.c: New file.
	* sysdeps/gnu/getutxent.c: New file.
	* sysdeps/gnu/endutxent.c: New file.
	* sysdeps/gnu/getutxid.c: New file.
	* sysdeps/gnu/getutxline.c: New file.
	* sysdeps/gnu/pututxline.c: New file.
	* sysdeps/gnu/utmpxname.c: New file.
	* sysdeps/gnu/updwtmpx.c: New file.
	* sysdeps/unix/sysv/linux/paths.h (_PATH_UTMP_DB): Remove.
	* sysdeps/generic/bits/utmpx.h: Remove.

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

	* posix/wordexp-test.c (main): Initialize ifs element of ts for
	~root test.

1998-04-17 07:53  H.J. Lu  <hjl@gnu.org>

	* sysdeps/unix/sysv/linux/i386/s_pread64.S: Fix a typo.

1998-04-17 11:32  Ulrich Drepper  <drepper@cygnus.com>

	* libio/oldfileops.c (_IO_old_file_seekoff): Define temporary st
	variable using _G_stat64.
	* libio/fileops.c: Remove macro definition of fstat, it is in the
	global header.
	Reported by Thorsten Kukuk <kukuk@weber.uni-paderborn.de>.

1998-04-17  Philip Blundell  <pb@nexus.co.uk>

	* sysdeps/arm/strlen.S: New file, based on code by Matthew Wilcox
	<willy@odie.barnet.ac.uk>.

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

	* inet/netinet/in.h (IN6_IS_ADDR_MC_NODELOCAL): New macro,
	required by IPv6 Basic API.
	(IN6_IS_ADDR_MC_LINKLOCAL): Likewise.
	(IN6_IS_ADDR_MC_SITELOCAL): Likewise.
	(IN6_IS_ADDR_MC_ORGLOCAL): Likewise.
	(IN6_IS_ADDR_MC_GLOBAL): Likewise.
Diffstat (limited to 'iconvdata/johab.c')
-rw-r--r--iconvdata/johab.c546
1 files changed, 214 insertions, 332 deletions
diff --git a/iconvdata/johab.c b/iconvdata/johab.c
index c9912a71d0..6a582c0b70 100644
--- a/iconvdata/johab.c
+++ b/iconvdata/johab.c
@@ -1,7 +1,8 @@
 /* Mapping tables for JOHAB handling.
    Copyright (C) 1998 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
-   Contributed by Jungshik Shin <jshin@pantheon.yale.edu>, 1998.
+   Contributed by Jungshik Shin <jshin@pantheon.yale.edu>
+   and Ulrich Drepper <drepper@cygnus.com>, 1998.
 
    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public License as
@@ -18,16 +19,9 @@
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
-#include <gconv.h>
 #include <stdint.h>
-#include <string.h>
-#include <wchar.h>
 #include <ksc5601.h>
 
-/* Direction of the transformation.  */
-static int to_johab_object;
-static int from_johab_object;
-
 /* The table for Bit pattern to Hangul Jamo
    5 bits each are used to encode
    leading consonants(19 + 1 filler), medial vowels(21 + 1 filler)
@@ -37,19 +31,19 @@ static int from_johab_object;
    0 : Filler, -1: invalid, >= 1 : valid
 
  */
-const int init[32] =
+static const int init[32] =
 {
   -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
   19, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
 };
-const int mid[32] =
+static const int mid[32] =
 {
   -1, -1, 0, 1, 2, 3, 4, 5,
   -1, -1, 6, 7, 8, 9, 10, 11,
   -1, -1, 12, 13, 14, 15, 16, 17,
   -1, -1, 18, 19, 20, 21, -1, -1
 };
-const int final[32] =
+static const int final[32] =
 {
   -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
   -1, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, -1, -1
@@ -63,14 +57,14 @@ const int final[32] =
    block [0x3131,0x314e] or Hangul Conjoining Jamo block, [0x1100,0x11ff]
 
  */
-const wchar_t init_to_ucs[19] =
+static const uint32_t init_to_ucs[19] =
 {
   0x3131, 0x3132, 0x3134, 0x3137, 0x3138, 0x3139, 0x3141, 0x3142,
   0x3143, 0x3145, 0x3146, 0x3147, 0x3148, 0x3149, 0x314a, 0x314b,
   0x314c, 0x314d, 0x314e
 };
 
-const wchar_t final_to_ucs[27] =
+static const uint32_t final_to_ucs[27] =
 {
   L'\0', L'\0', 0x3133, L'\0', 0x3135, 0x3136, L'\0', L'\0',
   0x313a, 0x313b, 0x314c, 0x313d, 0x313e, 0x313f,
@@ -88,7 +82,7 @@ const wchar_t final_to_ucs[27] =
    to get the same result arithmetically.
 
  */
-const int init_to_bit[19] =
+static const int init_to_bit[19] =
 {
   0x8800, 0x8c00, 0x9000, 0x9400, 0x9800, 0x9c00,
   0xa000, 0xa400, 0xa800, 0xac00, 0xb000, 0xb400,
@@ -96,7 +90,7 @@ const int init_to_bit[19] =
   0xd000
 };
 
-const int mid_to_bit[21] =
+static const int mid_to_bit[21] =
 {
           0x0060, 0x0080, 0x00a0, 0x00c0, 0x00e0,
   0x0140, 0x0160, 0x0180, 0x01a0, 0x01c0, 0x1e0,
@@ -104,7 +98,7 @@ const int mid_to_bit[21] =
   0x0340, 0x0360, 0x0380, 0x03a0
 };
 
-const int final_to_bit[28] =
+static const int final_to_bit[28] =
 {
   1, 2, 3, 4, 5, 6, 7, 8, 9, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
   0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d
@@ -118,7 +112,7 @@ const int final_to_bit[28] =
    2. Unicode 2.0 manual
 
  */
-const uint16_t jamo_from_ucs_table[51] =
+static const uint16_t jamo_from_ucs_table[51] =
 {
   0x8841, 0x8c41,
   0x8444,
@@ -137,21 +131,20 @@ const uint16_t jamo_from_ucs_table[51] =
 };
 
 
-static inline wchar_t
-johab_sym_hanja_to_ucs (int idx, int c1, int c2)
+static inline uint32_t
+johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2)
 {
   if (idx <= 0xdefe)
-    return (wchar_t) ksc5601_sym_to_ucs[(c1 - 0xd9) * 188 + c2
-					- (c2 > 0x90 ? 0x43 : 0x31)];
+    return (uint32_t) __ksc5601_sym_to_ucs[(c1 - 0xd9) * 188 + c2
+					   - (c2 > 0x90 ? 0x43 : 0x31)];
   else
-    return (wchar_t) ksc5601_hanja_to_ucs[(c1 - 0xe0) * 188 + c2
-					  - (c2 > 0x90 ? 0x43 : 0x31)];
+    return (uint32_t) __ksc5601_hanja_to_ucs[(c1 - 0xe0) * 188 + c2
+					     - (c2 > 0x90 ? 0x43 : 0x31)];
 }
 
 static uint16_t
-johab_hanja_from_ucs (wchar_t ch)
+johab_hanja_from_ucs (uint32_t ch)
 {
-
   uint16_t idx;
   if (ucs4_to_ksc5601_hanja (ch, &idx))
     {
@@ -168,7 +161,7 @@ johab_hanja_from_ucs (wchar_t ch)
 }
 
 static uint16_t
-johab_sym_from_ucs (wchar_t ch)
+johab_sym_from_ucs (uint32_t ch)
 {
   uint16_t idx;
   if (ucs4_to_ksc5601_sym (ch, &idx))
@@ -186,9 +179,8 @@ johab_sym_from_ucs (wchar_t ch)
 }
 
 
-
 static inline void
-johab_from_ucs4 (wchar_t ch, unsigned char *cp)
+johab_from_ucs4 (uint32_t ch, unsigned char *cp)
 {
   if (ch >= 0x7f)
     {
@@ -215,315 +207,205 @@ johab_from_ucs4 (wchar_t ch, unsigned char *cp)
       else
 	idx = johab_sym_from_ucs (ch);
 
-      *cp = (char) (idx / 256);
-      *(cp + 1) = (char) (idx & 0xff);
+      cp[0] = (unsigned char) (idx / 256);
+      cp[1] = (unsigned char) (idx & 0xff);
 
     }
   else
     {
-      *cp = (char) (0x7f & ch);
-      *(cp + 1) = (char) 0;
+      cp[0] = (unsigned char) ch;
+      cp[1] = 0;
     }
-
-}
-
-
-int
-gconv_init (struct gconv_step *step)
-{
-  /* Determine which direction.  */
-  if (strcasestr (step->from_name, "JOHAB") != NULL)
-    step->data = &from_johab_object;
-  else if (strcasestr (step->to_name, "JOHAB") != NULL)
-    step->data = &to_johab_object;
-  else
-    return GCONV_NOCONV;
-
-  return GCONV_OK;
-}
-
-
-void
-gconv_end (struct gconv_step *data)
-{
-  /* Nothing to do.  */
 }
 
 
-int
-gconv (struct gconv_step *step, struct gconv_step_data *data,
-       const char *inbuf, size_t *inbufsize, size_t * written, int do_flush)
-{
-  struct gconv_step *next_step = step + 1;
-  struct gconv_step_data *next_data = data + 1;
-  gconv_fct fct = next_step->fct;
-  size_t do_write;
-  int result;
-
-  /* If the function is called with no input this means we have to reset
-     to the initial state.  The possibly partly converted input is
-     dropped.  */
-  if (do_flush)
-    {
-      do_write = 0;
-
-      /* Call the steps down the chain if there are any.  */
-      if (data->is_last)
-	result = GCONV_OK;
-      else
-	{
-	  struct gconv_step *next_step = step + 1;
-	  struct gconv_step_data *next_data = data + 1;
-
-	  result = (*fct) (next_step, next_data, NULL, 0, written, 1);
-
-	  /* Clear output buffer.  */
-	  data->outbufavail = 0;
-	}
-    }
-  else
-    {
-      do_write = 0;
-
-      do
-	{
-	  result = GCONV_OK;
-
-	  if (step->data == &from_johab_object)
-	    {
-	      size_t inchars = *inbufsize;
-	      size_t outwchars = data->outbufavail;
-	      char *outbuf = data->outbuf;
-	      size_t cnt = 0;
-
-	      while (cnt < inchars
-		     && (outwchars + sizeof (wchar_t) <= data->outbufsize))
-		{
-		  int inchar = (unsigned char) inbuf[cnt];
-		  wchar_t ch;
-		  /* half-width Korean Currency WON sign
-		     if (inchar == 0x5c)
-		     ch =  0x20a9;
-		     else if (inchar < 0x7f)
-		     ch = (wchar_t) inchar;
-		  */
-		  if (inchar < 0x7f)
-		    ch = (wchar_t) inchar;
-
-		  /* Johab : 1. Hangul
-		     1st byte : 0x84-0xd3
-		     2nd byte : 0x41-0x7e, 0x81-0xfe
-		     2. Hanja & Symbol  :
-		     1st byte : 0xd8-0xde, 0xe0-0xf9
-		     2nd byte : 0x31-0x7e, 0x91-0xfe
-		     0xd831-0xd87e and 0xd891-0xd8fe are user-defined area */
-
-		  else if (inchar > 0xf9 || inchar == 0xdf
-			   || (inchar > 0x7e && inchar < 0x84)
-			   || (inchar > 0xd3 && inchar < 0xd9))
-		    /* These are illegal.  */
-		    ch = L'\0';
-		  else
-		    {
-		      /* Two-byte character.  First test whether the next
-		         character is also available.  */
-		      int inchar2;
-		      int idx;
-
-		      if (cnt + 1 >= inchars)
-			{
-			  /* The second character is not available.  Store
-			     the intermediate result.  */
-			  result = GCONV_INCOMPLETE_INPUT;
-			  break;
-			}
-
-		      inchar2 = (unsigned char) inbuf[++cnt];
-		      idx = inchar * 256 + inchar2;
-		      if (inchar <= 0xd3)
-			{	/* Hangul */
-			  int i, m, f;
-			  i = init[(idx & 0x7c00) >> 10];
-			  m = mid[(idx & 0x03e0) >> 5];
-			  f = final[idx & 0x001f];
-			  if (i == -1 || m == -1 || f == -1)
-			    /* This is illegal.  */
-			    ch = L'\0';
-			  else if (i > 0 && m > 0)
-			    ch = ((i - 1) * 21 + (m - 1)) * 28 + f + 0xac00;
-			  else if (i > 0 && m == 0 & f == 0)
-			    ch = init_to_ucs[i - 1];
-			  else if (i == 0 && m > 0 & f == 0)
-			    ch = 0x314e + m;	/* 0x314f + m - 1 */
-			  else if (i == 0 && m == 0 & f > 0)
-			    ch = final_to_ucs[f - 1];	/* round trip?? */
-			  else
-			    /* This is illegal.  */
-			    ch = L'\0';
-			}
-		      else
-			{
-			  if (inchar2 < 0x31
-			      || (inchar2 > 0x7e && inchar2 < 0x91)
-			      || inchar2 == 0xff)
-			    /* This is illegal.  */
-			    ch = L'\0';
-			  else if (inchar == 0xda
-				   && inchar2 > 0xa0 && inchar2 < 0xd4)
-			    /* This is illegal.  */
-			    /* Modern Hangul Jaso is defined elsewhere
-			       in Johab */
-			    ch = L'\0';
-			  else
-			    {
-			      ch = johab_sym_hanja_to_ucs (idx, inchar,
-							   inchar2);
-			      /*                if (idx <= 0xdefe)
-			         ch = ksc5601_sym_to_ucs[(inchar - 0xd9) * 192
-			         + inchar2
-			         -  (inchar2>0x90 ? 0x43 : 0x31)];
-
-			         else
-			         ch = ksc5601_hanja_to_ucs[(inchar - 0xe0) *192
-			         + inchar2
-			         -  (inchar2>0x90 ? 0x43 : 0x31)];
-			       */
-			    }
-			}
-
-		      if (ch == L'\0')
-			--cnt;
-		    }
-
-		  if (ch == L'\0' && inbuf[cnt] != '\0')
-		    {
-		      /* This is an illegal character.  */
-		      result = GCONV_ILLEGAL_INPUT;
-		      break;
-		    }
-
-		  *((wchar_t *) (outbuf + outwchars)) = ch;
-		  ++do_write;
-		  outwchars += sizeof (wchar_t);
-		  ++cnt;
-		}
-	      *inbufsize -= cnt;
-	      inbuf += cnt;
-	      data->outbufavail = outwchars;
-	    }
-	  else
-	    {
-	      size_t inwchars = *inbufsize;
-	      size_t outchars = data->outbufavail;
-	      char *outbuf = data->outbuf;
-	      size_t cnt = 0;
-	      int extra = 0;
-
-	      while (inwchars >= cnt + sizeof (wchar_t)
-		     && outchars < data->outbufsize)
-		{
-		  wchar_t ch = *((wchar_t *) (inbuf + cnt));
-		  unsigned char cp[2];
-		  /*
-		    if (ch >= (sizeof (from_ucs4_lat1)
-			/ sizeof (from_ucs4_lat1[0])))
-		      {
-			if (ch >= 0x0391 && ch <= 0x0451)
-			  cp = from_ucs4_greek[ch - 0x391];
-			else if (ch >= 0x2010 && ch <= 0x9fa0)
-			  cp = from_ucs4_cjk[ch - 0x02010];
-			else
-			  break;
-		      }
-		    else
-		      cp = from_ucs4_lat1[ch];
-		  */
-		  johab_from_ucs4 (ch, cp);
-
-		  if (cp[0] == '\0' && ch != 0)
-		    /* Illegal character.  */
-		    break;
-
-		  outbuf[outchars] = cp[0];
-		  /* Now test for a possible second byte and write this
-		     if possible.  */
-		  if (cp[1] != '\0')
-		    {
-		      if (outchars + 1 >= data->outbufsize)
-			{
-			  /* The result does not fit into the buffer.  */
-			  extra = 1;
-			  break;
-			}
-		      outbuf[++outchars] = cp[1];
-		    }
-
-		  ++do_write;
-		  ++outchars;
-		  cnt += sizeof (wchar_t);
-		}
-	      *inbufsize -= cnt;
-	      inbuf += cnt;
-	      data->outbufavail = outchars;
-
-	      if (outchars + extra < data->outbufsize)
-		{
-		  /* If there is still room in the output buffer something
-		     is wrong with the input.  */
-		  if (inwchars >= cnt + sizeof (wchar_t))
-		    {
-		      /* An error occurred.  */
-		      result = GCONV_ILLEGAL_INPUT;
-		      break;
-		    }
-		  if (inwchars != cnt)
-		    {
-		      /* There are some unprocessed bytes at the end of the
-		         input buffer.  */
-		      result = GCONV_INCOMPLETE_INPUT;
-		      break;
-		    }
-		}
-	    }
-
-	  if (result != GCONV_OK)
-	    break;
-
-	  if (data->is_last)
-	    {
-	      /* This is the last step.  */
-	      result = (*inbufsize > (step->data == &from_johab_object
-				      ? 0 : sizeof (wchar_t) - 1)
-			? GCONV_FULL_OUTPUT : GCONV_EMPTY_INPUT);
-	      break;
-	    }
-
-	  /* Status so far.  */
-	  result = GCONV_EMPTY_INPUT;
-
-	  if (data->outbufavail > 0)
-	    {
-	      /* Call the functions below in the chain.  */
-	      size_t newavail = data->outbufavail;
-
-	      result = (*fct) (next_step, next_data, data->outbuf, &newavail,
-			       written, 0);
-
-	      /* Correct the output buffer.  */
-	      if (newavail != data->outbufavail && newavail > 0)
-		{
-		  memmove (data->outbuf,
-			   &data->outbuf[data->outbufavail - newavail],
-			   newavail);
-		  data->outbufavail = newavail;
-		}
-	    }
-	}
-      while (*inbufsize > 0 && result == GCONV_EMPTY_INPUT);
-    }
-
-  if (written != NULL && data->is_last)
-    *written = do_write;
-
-  return result;
-}
+/* Definitions used in the body of the `gconv' function.  */
+#define CHARSET_NAME		"JOHAB"
+#define FROM_LOOP		from_johab
+#define TO_LOOP			to_johab
+#define DEFINE_INIT		1
+#define DEFINE_FINI		1
+#define MIN_NEEDED_FROM		1
+#define MAX_NEEDED_FROM		2
+#define MIN_NEEDED_TO		4
+
+
+/* First define the conversion function from JOHAB to UCS4.  */
+#define MIN_NEEDED_INPUT	MIN_NEEDED_FROM
+#define MAX_NEEDED_INPUT	MAX_NEEDED_FROM
+#define MIN_NEEDED_OUTPUT	MIN_NEEDED_TO
+#define LOOPFCT			FROM_LOOP
+#define BODY \
+  {									      \
+    uint32_t ch = *inptr;						      \
+									      \
+    /* half-width Korean Currency WON sign				      \
+       if (ch == 0x5c)							      \
+	 ch =  0x20a9;							      \
+       else if (ch < 0x7f)						      \
+	 ch = (wchar_t) ch;						      \
+    */									      \
+    if (ch < 0x7f)							      \
+      /* Plain ASCII.  */						      \
+      ++inptr;								      \
+    /* Johab : 1. Hangul						      \
+       1st byte : 0x84-0xd3						      \
+       2nd byte : 0x41-0x7e, 0x81-0xfe					      \
+       2. Hanja & Symbol  :						      \
+       1st byte : 0xd8-0xde, 0xe0-0xf9					      \
+       2nd byte : 0x31-0x7e, 0x91-0xfe					      \
+       0xd831-0xd87e and 0xd891-0xd8fe are user-defined area */		      \
+    else								      \
+      {									      \
+	if (ch > 0xf9 || ch == 0xdf || (ch > 0x7e && ch < 0x84)		      \
+	    || (ch > 0xd3 && ch < 0xd9))				      \
+	  {								      \
+	    /* These are illegal.  */					      \
+	    result = GCONV_ILLEGAL_INPUT;				      \
+	    break;							      \
+	  }								      \
+	else								      \
+	  {								      \
+	    /* Two-byte character.  First test whether the next		      \
+	       character is also available.  */				      \
+	    uint32_t ch2;						      \
+	    uint_fast32_t idx;						      \
+									      \
+	    if (NEED_LENGTH_TEST && inptr + 1 >= inend)			      \
+	      {								      \
+		/* The second character is not available.  Store the	      \
+		   intermediate result.  */				      \
+		result = GCONV_INCOMPLETE_INPUT;			      \
+		break;							      \
+	      }								      \
+									      \
+	    ch2 = inptr[1];						      \
+	    idx = ch * 256 + ch2;					      \
+	    if (ch <= 0xd3)						      \
+	      {								      \
+		/* Hangul */						      \
+		uint_fast32_t i, m, f;					      \
+									      \
+		i = init[(idx & 0x7c00) >> 10];				      \
+		m = mid[(idx & 0x03e0) >> 5];				      \
+		f = final[idx & 0x001f];				      \
+									      \
+		if (i == -1 || m == -1 || f == -1)			      \
+		  {							      \
+		    /* This is illegal.  */				      \
+		    result = GCONV_ILLEGAL_INPUT;			      \
+		    break;						      \
+		  }							      \
+		else if (i > 0 && m > 0)				      \
+		  ch = ((i - 1) * 21 + (m - 1)) * 28 + f + 0xac00;	      \
+		else if (i > 0 && m == 0 & f == 0)			      \
+		  ch = init_to_ucs[i - 1];				      \
+		else if (i == 0 && m > 0 & f == 0)			      \
+		  ch = 0x314e + m;	/* 0x314f + m - 1 */		      \
+		else if (i == 0 && m == 0 & f > 0)			      \
+		  ch = final_to_ucs[f - 1];	/* round trip?? */	      \
+		else							      \
+		  {							      \
+		    /* This is illegal.  */				      \
+		    result = GCONV_ILLEGAL_INPUT;			      \
+		    break;						      \
+		  }							      \
+	      }								      \
+	    else							      \
+	      {								      \
+		if (ch2 < 0x31 || (ch2 > 0x7e && ch2 < 0x91) || ch2 == 0xff)  \
+		  {							      \
+		    /* This is illegal.  */				      \
+		    result = GCONV_ILLEGAL_INPUT;			      \
+		    break;						      \
+		  }							      \
+		else if (ch == 0xda && ch2 > 0xa0 && ch2 < 0xd4)	      \
+		  {							      \
+		    /* This is illegal.  Modern Hangul Jaso is defined	      \
+		       elsewhere in Johab */				      \
+		    result = GCONV_ILLEGAL_INPUT;			      \
+		    break;						      \
+		  }							      \
+		else							      \
+		  {							      \
+		    ch = johab_sym_hanja_to_ucs (idx, ch, ch2);		      \
+		    /* if (idx <= 0xdefe)				      \
+			 ch = __ksc5601_sym_to_ucs[(ch - 0xd9) * 192	      \
+						   + ch2 - (ch2 > 0x90	      \
+							    ? 0x43 : 0x31)];  \
+		       else						      \
+		         ch = __ksc5601_hanja_to_ucs[(ch - 0xe0) *192	      \
+						     + ch2 -  (ch2 > 0x90     \
+							       ?0x43 : 0x31)];\
+		    */							      \
+		  }							      \
+	      }								      \
+	  }								      \
+									      \
+	if (ch == 0)							      \
+	  {								      \
+	    /* This is an illegal character.  */			      \
+	    result = GCONV_ILLEGAL_INPUT;				      \
+	    break;							      \
+	  }								      \
+									      \
+	inptr += 2;							      \
+      }									      \
+									      \
+    *((uint32_t *) outptr)++ = ch;					      \
+  }
+#include <iconv/loop.c>
+
+
+/* Next, define the other direction.  */
+#define MIN_NEEDED_INPUT	MIN_NEEDED_TO
+#define MIN_NEEDED_OUTPUT	MIN_NEEDED_FROM
+#define MAX_NEEDED_OUTPUT	MAX_NEEDED_FROM
+#define LOOPFCT			TO_LOOP
+#define BODY \
+  {									      \
+    uint32_t ch = *((uint32_t *) inptr);				      \
+    unsigned char cp[2];						      \
+    /*									      \
+       if (ch >= (sizeof (from_ucs4_lat1) / sizeof (from_ucs4_lat1[0])))      \
+	 {								      \
+	   if (ch >= 0x0391 && ch <= 0x0451)				      \
+	     cp = from_ucs4_greek[ch - 0x391];				      \
+	   else if (ch >= 0x2010 && ch <= 0x9fa0)			      \
+	     cp = from_ucs4_cjk[ch - 0x02010];				      \
+	   else								      \
+	     break;							      \
+	 }								      \
+       else								      \
+	 cp = from_ucs4_lat1[ch];					      \
+    */									      \
+    johab_from_ucs4 (ch, cp);						      \
+									      \
+    if (cp[0] == '\0' && ch != 0)					      \
+      {									      \
+	/* Illegal character.  */					      \
+	result = GCONV_ILLEGAL_INPUT;					      \
+	break;								      \
+      }									      \
+									      \
+    *outptr++ = cp[0];							      \
+    /* Now test for a possible second byte and write this if possible.  */    \
+    if (cp[1] != '\0')							      \
+      {									      \
+	if (NEED_LENGTH_TEST && outptr >= outend)			      \
+	  {								      \
+	    /* The result does not fit into the buffer.  */		      \
+	    --outptr;							      \
+	    result = GCONV_FULL_OUTPUT;					      \
+	    break;							      \
+	  }								      \
+	*outptr++ = cp[1];						      \
+      }									      \
+									      \
+    inptr += 4;								      \
+  }
+#include <iconv/loop.c>
+
+
+/* Now define the toplevel functions.  */
+#include <iconv/skeleton.c>