about summary refs log tree commit diff
path: root/iconvdata/iso-2022-kr.c
diff options
context:
space:
mode:
Diffstat (limited to 'iconvdata/iso-2022-kr.c')
-rw-r--r--iconvdata/iso-2022-kr.c146
1 files changed, 62 insertions, 84 deletions
diff --git a/iconvdata/iso-2022-kr.c b/iconvdata/iso-2022-kr.c
index 166fa15072..6746f9c2ac 100644
--- a/iconvdata/iso-2022-kr.c
+++ b/iconvdata/iso-2022-kr.c
@@ -44,7 +44,7 @@
 #define MAX_NEEDED_TO		4
 #define PREPARE_LOOP \
   int save_set;								      \
-  int set = data->statep->count;					      \
+  int *setp = &data->statep->count;					      \
   if (!FROM_DIRECTION && !data->internal_use && data->invocation_counter == 0)\
     {									      \
       /* Emit the designator sequence.  */				      \
@@ -56,7 +56,7 @@
       *outbuf++ = ')';							      \
       *outbuf++ = 'C';							      \
     }
-#define EXTRA_LOOP_ARGS		, set
+#define EXTRA_LOOP_ARGS		, setp
 
 
 /* The COUNT element of the state keeps track of the currently selected
@@ -72,27 +72,27 @@ enum
    the output state to the initial state.  This has to be done during the
    flushing.  */
 #define EMIT_SHIFT_TO_INIT \
-  if (data->statep->count != 0)						      \
+  if (data->statep->count != ASCII_set)					      \
     {									      \
-      if (step->data == &from_object)					      \
+      if (FROM_DIRECTION)						      \
 	/* It's easy, we don't have to emit anything, we just reset the	      \
 	   state for the input.  */					      \
-	data->statep->count = 0;					      \
+	data->statep->count = ASCII_set;				      \
       else								      \
 	{								      \
 	  char *outbuf = data->outbuf;					      \
 	  								      \
 	  /* We are not in the initial state.  To switch back we have	      \
-	     to emit `SO'.  */						      \
+	     to emit `SI'.  */						      \
 	  if (outbuf == data->outbufend)				      \
 	    /* We don't have enough room in the output buffer.  */	      \
 	    status = GCONV_FULL_OUTPUT;					      \
 	  else								      \
 	    {								      \
 	      /* Write out the shift sequence.  */			      \
-	      *outbuf++ = SO;						      \
+	      *outbuf++ = SI;						      \
 	      data->outbuf = outbuf;					      \
-	      data->statep->count = 0;					      \
+	      data->statep->count = ASCII_set;				      \
 	    }								      \
 	}								      \
     }
@@ -102,9 +102,9 @@ enum
    and retore the state.  */
 #define SAVE_RESET_STATE(Save) \
   if (Save)								      \
-    save_set = set;							      \
+    save_set = *setp;							      \
   else									      \
-    set = save_set
+    *setp = save_set
 
 
 /* First define the conversion function from ISO-2022-JP to UCS4.  */
@@ -127,14 +127,14 @@ enum
     if (ch == ESC)							      \
       {									      \
 	/* We don't really have to handle escape sequences since all the      \
-	   switching is done using the SI and SO bytes.  Butwe have to	      \
+	   switching is done using the SI and SO bytes.  But we have to	      \
 	   recognize `Esc $ ) C' since this is a kind of flag for this	      \
 	   encoding.  We simply ignore it.  */				      \
 	if (inptr + 1 > inend						      \
 	    || (inptr[1] == '$'						      \
 		&& (inptr + 2 > inend					      \
 		    || (inptr[2] == ')' && inptr + 3 > inend))))	      \
-			    						      \
+									      \
 	  {								      \
 	    result = GCONV_EMPTY_INPUT;					      \
 	    break;							      \
@@ -146,14 +146,14 @@ enum
 	    continue;							      \
 	  }								      \
       }									      \
-    else if (ch == SI)							      \
+    else if (ch == SO)							      \
       {									      \
 	/* Switch to use KSC.  */					      \
 	++inptr;							      \
 	set = KSC5601_set;						      \
 	continue;							      \
       }									      \
-    else if (ch == SO)							      \
+    else if (ch == SI)							      \
       {									      \
 	/* Switch to use ASCII.  */					      \
 	++inptr;							      \
@@ -161,9 +161,16 @@ enum
 	continue;							      \
       }									      \
 									      \
-    if (set == ASCII_set || ch < 0x21 || ch == 0x7f)			      \
-      /* Almost done, just advance the input pointer.  */		      \
-      ++inptr;								      \
+    if (set == ASCII_set)						      \
+      {									      \
+	if (ch >= 0x80)							      \
+	  {								      \
+	    result = GCONV_ILLEGAL_INPUT;				      \
+	    break;							      \
+	  }								      \
+	/* Almost done, just advance the input pointer.  */		      \
+	++inptr;							      \
+      }									      \
     else								      \
       {									      \
 	assert (set == KSC5601_set);					      \
@@ -186,7 +193,9 @@ enum
 									      \
     *((uint32_t *) outptr)++ = ch;					      \
   }
-#define EXTRA_LOOP_DECLS	, int set
+#define EXTRA_LOOP_DECLS	, int *setp
+#define INIT_PARAMS		int set = *setp
+#define UPDATE_PARAMS		*setp = set
 #include <iconv/loop.c>
 
 
@@ -197,97 +206,66 @@ enum
 #define LOOPFCT			TO_LOOP
 #define BODY \
   {									      \
-    unsigned char ch;							      \
+    uint32_t ch;							      \
     size_t written = 0;							      \
 									      \
     ch = *((uint32_t *) inptr);						      \
 									      \
     /* First see whether we can write the character using the currently	      \
        selected character set.  */					      \
-    if (set == ASCII_set || (ch >= 0x01 && (ch < 0x21 || ch == 0x7f)))	      \
+    if (ch < 0x80)							      \
       {									      \
-	/* Please note that the NUL byte is *not* matched if we are not	      \
-	   currently using the ASCII charset.  This is because we must	      \
-	   switch to the initial state whenever a NUL byte is written.  */    \
-	if (ch <= 0x7f)							      \
+	if (set != ASCII_set)						      \
 	  {								      \
-	    *outptr++ = ch;						      \
-	    written = 1;						      \
+	    *outptr++ = SI;						      \
+	    set = ASCII_set;						      \
+	    if (NEED_LENGTH_TEST && outptr == outend)			      \
+	      {								      \
+		result = GCONV_FULL_OUTPUT;				      \
+		break;							      \
+	      }								      \
 	  }								      \
+ 									      \
+	*outptr++ = ch;							      \
+	written = 1;							      \
       }									      \
     else								      \
       {									      \
-	assert (set == KSC5601_set);					      \
+	char buf[2];							      \
 									      \
-	written = ucs4_to_ksc5601 (ch, outptr,				      \
-				   (NEED_LENGTH_TEST ? outend - outptr : 2)); \
+	written = ucs4_to_ksc5601 (ch, buf, 2);				      \
 									      \
-	if (NEED_LENGTH_TEST && written == 0)				      \
+	if (written == UNKNOWN_10646_CHAR)				      \
 	  {								      \
-	    result = GCONV_FULL_OUTPUT;					      \
+	    /* Illegal character.  */					      \
+	    result = GCONV_ILLEGAL_INPUT;				      \
 	    break;							      \
 	  }								      \
-	if (written == UNKNOWN_10646_CHAR)				      \
-	  {								      \
-	    /* Either this is an unknown character or we have to switch	      \
-	       the currently selected character set.  The character sets      \
-	       do not code entirely separate parts of ISO 10646 and	      \
-	       therefore there is no single correct result.  If we choose     \
-	       the character set to use wrong we might be end up with	      \
-	       using yet another character set for the next character	      \
-	       though the current and the next could be encoded with one      \
-	       character set.  We leave this kind of optimization for	      \
-	       later and now simply use a fixed order in which we test for    \
-	       availability  */						      \
-									      \
-	    if (ch <= 0x7f)						      \
-	      {								      \
-		/* We must encode using ASCII.  First write out the	      \
-		   escape sequence.  */					      \
-		*outptr++ = SO;						      \
-		set = ASCII_set;					      \
-									      \
-		if (NEED_LENGTH_TEST && outptr == outend)		      \
-		  {							      \
-		    result = GCONV_FULL_OUTPUT;				      \
-		    break;						      \
-		  }							      \
-									      \
-		*outptr++ = ch;						      \
-	      }								      \
-	    else							      \
-	      {								      \
-		char buf[2];						      \
+	assert (written == 2);						      \
 									      \
-		written = ucs4_to_ksc5601 (ch, buf, 2);			      \
-		if (written != UNKNOWN_10646_CHAR)			      \
-		  {							      \
-		    /* We use KSC 5601.  */				      \
-		    *outptr++ = SI;					      \
-		    set = KSC5601_set;					      \
-									      \
-		    if (NEED_LENGTH_TEST && outptr + 2 > outend)	      \
-		      {							      \
-			result = GCONV_FULL_OUTPUT;			      \
-			break;						      \
-		      }							      \
+	/* We use KSC 5601.  */						      \
+	if (set != KSC5601_set)						      \
+	  {								      \
+	    *outptr++ = SO;						      \
+	    set = KSC5601_set;						      \
+	  }								      \
 									      \
-		    *outptr++ = buf[0];					      \
-		    *outptr++ = buf[1];					      \
-		  }							      \
-		else							      \
-		  {							      \
-		    result = GCONV_ILLEGAL_INPUT;			      \
-		    break;						      \
-		  }							      \
-	      }								      \
+	if (NEED_LENGTH_TEST && outptr + 2 > outend)			      \
+	  {								      \
+	    result = GCONV_FULL_OUTPUT;					      \
+	    break;							      \
 	  }								      \
+									      \
+	*outptr++ = buf[0];						      \
+	*outptr++ = buf[1];						      \
       }									      \
 									      \
     /* Now that we wrote the output increment the input pointer.  */	      \
     inptr += 4;								      \
   }
-#define EXTRA_LOOP_DECLS	, int set
+#define EXTRA_LOOP_DECLS	, int *setp
+#define INIT_PARAMS		int set = *setp
+#define UPDATE_PARAMS		*setp = set
 #include <iconv/loop.c>