(U-0002195D): Add `ideographic-structure'; add `sound@ja/on'; add
[chise/xemacs-chise.git.1] / src / mule-ccl.c
index 9a38087..1907762 100644 (file)
@@ -31,7 +31,7 @@ Boston, MA 02111-1307, USA.  */
 
 #include "lisp.h"
 #include "buffer.h"
-#include "mule-charset.h"
+#include "character.h"
 #include "mule-ccl.h"
 #include "file-coding.h"
 
@@ -677,35 +677,35 @@ static int stack_idx_of_map_multiple;
                                   r[7] = LOWER_BYTE (SJIS (Y, Z) */
 
 /* Terminate CCL program successfully.  */
-#define CCL_SUCCESS                    \
-do {                                   \
-  ccl->status = CCL_STAT_SUCCESS;      \
+#define CCL_SUCCESS                    \
+  do {                                 \
+    ccl->status = CCL_STAT_SUCCESS;    \
   /* The "if (1)" inhibits the warning \
      "end-of loop code not reached" */ \
   if (1) goto ccl_finish;              \
-} while (0)
+  } while (0)
 
 /* Suspend CCL program because of reading from empty input buffer or
    writing to full output buffer.  When this program is resumed, the
    same I/O command is executed.  */
-#define CCL_SUSPEND(stat)              \
-do {                                   \
-  ic--;                                        \
+#define CCL_SUSPEND(stat)      \
+  do {                         \
+    ic--;                      \
   ccl->status = (stat);                        \
   /* The "if (1)" inhibits the warning \
      "end-of loop code not reached" */ \
   if (1) goto ccl_finish;              \
-} while (0)
+  } while (0)
 
 /* Terminate CCL program because of invalid command.  Should not occur
    in the normal case.  */
-#define CCL_INVALID_CMD                        \
-do {                                   \
-  ccl->status = CCL_STAT_INVALID_CMD;  \
+#define CCL_INVALID_CMD                        \
+  do {                                 \
+    ccl->status = CCL_STAT_INVALID_CMD;        \
   /* The "if (1)" inhibits the warning \
      "end-of loop code not reached" */ \
   if (1) goto ccl_error_handler;       \
-} while (0)
+  } while (0)
 
 /* Encode one character CH to multibyte form and write to the current
    output buffer.  At encoding time, if CH is less than 256, CH is
@@ -833,6 +833,9 @@ do {                                        \
       }                                                        \
   } while (0)
 
+#define POSSIBLE_LEADING_BYTE_P(leading_byte) \
+  ((leading_byte > MIN_LEADING_BYTE) && \
+   (leading_byte - MIN_LEADING_BYTE) < NUM_LEADING_BYTES)
 
 /* Set C to the character code made from CHARSET and CODE.  This is
    like MAKE_CHAR but check the validity of CHARSET and CODE.  If they
@@ -1279,61 +1282,79 @@ ccl_driver (struct ccl_program *ccl,
        case CCL_Extension:
          switch (EXCMD)
            {
+#ifndef UTF2000
            case CCL_ReadMultibyteChar2:
              if (!src)
                CCL_INVALID_CMD;
 
-             if (src >= src_end)
-               {
-                 src++;
-                 goto ccl_read_multibyte_character_suspend;
-               }
-
-             i = *src++;
-             if (i < 0x80)
-               {
-                 /* ASCII */
-                 reg[rrr] = i;
-                 reg[RRR] = LEADING_BYTE_ASCII;
-               }
-             else if (i <= MAX_LEADING_BYTE_OFFICIAL_1)
-               {
-                 if (src >= src_end)
-                   goto ccl_read_multibyte_character_suspend;
-                 reg[RRR] = i;
-                 reg[rrr] = (*src++ & 0x7F);
-               }
-             else if (i <= MAX_LEADING_BYTE_OFFICIAL_2)
-               {
-                 if ((src + 1) >= src_end)
-                   goto ccl_read_multibyte_character_suspend;
-                 reg[RRR] = i;
-                 i = (*src++ & 0x7F);
-                 reg[rrr] = ((i << 7) | (*src & 0x7F));
-                 src++;
-               }
-             else if (i == PRE_LEADING_BYTE_PRIVATE_1)
-               {
-                 if ((src + 1) >= src_end)
-                   goto ccl_read_multibyte_character_suspend;
-                 reg[RRR] = *src++;
-                 reg[rrr] = (*src++ & 0x7F);
-               }
-             else if (i == PRE_LEADING_BYTE_PRIVATE_2)
-               {
-                 if ((src + 2) >= src_end)
+               if (src >= src_end)
+                 {
+                   src++;
                    goto ccl_read_multibyte_character_suspend;
-                 reg[RRR] = *src++;
-                 i = (*src++ & 0x7F);
-                 reg[rrr] = ((i << 7) | (*src & 0x7F));
-                 src++;
-               }
-             else
-               {
-                 /* INVALID CODE.  Return a single byte character.  */
-                 reg[RRR] = LEADING_BYTE_ASCII;
-                 reg[rrr] = i;
-               }
+                 }
+
+               i = *src++;
+               if (i < 0x80)
+                 {
+                   /* ASCII */
+                   reg[rrr] = i;
+                   reg[RRR] = LEADING_BYTE_ASCII;
+                 }
+               /* Previously, these next two elses were reversed in order,
+                  which should have worked fine, but is more fragile than
+                  this order. */
+               else if (LEADING_BYTE_CONTROL_1 == i)
+                 {
+                   if (src >= src_end)
+                     goto ccl_read_multibyte_character_suspend;
+                   reg[RRR] = i;
+                   reg[rrr] = (*src++ - 0xA0);
+                 }
+               else if (i <= MAX_LEADING_BYTE_OFFICIAL_1)
+                 {
+                   if (src >= src_end)
+                     goto ccl_read_multibyte_character_suspend;
+                   reg[RRR] = i;
+                   reg[rrr] = (*src++ & 0x7F);
+                 }
+               else if (LEADING_BYTE_CONTROL_1 == i)
+                 {
+                   if (src >= src_end)
+                     goto ccl_read_multibyte_character_suspend;
+                   reg[RRR] = i;
+                   reg[rrr] = (*src++ - 0xA0);
+                 }
+               else if (i <= MAX_LEADING_BYTE_OFFICIAL_2)
+                 {
+                   if ((src + 1) >= src_end)
+                     goto ccl_read_multibyte_character_suspend;
+                   reg[RRR] = i;
+                   i = (*src++ & 0x7F);
+                   reg[rrr] = ((i << 7) | (*src & 0x7F));
+                   src++;
+                 }
+               else if (i == PRE_LEADING_BYTE_PRIVATE_1)
+                 {
+                   if ((src + 1) >= src_end)
+                     goto ccl_read_multibyte_character_suspend;
+                   reg[RRR] = *src++;
+                   reg[rrr] = (*src++ & 0x7F);
+                 }
+               else if (i == PRE_LEADING_BYTE_PRIVATE_2)
+                 {
+                   if ((src + 2) >= src_end)
+                     goto ccl_read_multibyte_character_suspend;
+                   reg[RRR] = *src++;
+                   i = (*src++ & 0x7F);
+                   reg[rrr] = ((i << 7) | (*src & 0x7F));
+                   src++;
+                 }
+               else
+                 {
+                   /* INVALID CODE.  Return a single byte character.  */
+                   reg[RRR] = LEADING_BYTE_ASCII;
+                   reg[rrr] = i;
+                 }
              break;
 
            ccl_read_multibyte_character_suspend:
@@ -1347,22 +1368,39 @@ ccl_driver (struct ccl_program *ccl,
                CCL_SUSPEND (CCL_STAT_SUSPEND_BY_SRC);
 
              break;
+#endif
 
+#ifndef UTF2000
            case CCL_WriteMultibyteChar2:
              i = reg[RRR]; /* charset */
-             if (i == LEADING_BYTE_ASCII)
+             if (i == LEADING_BYTE_ASCII) 
                i = reg[rrr] & 0xFF;
-             else if (XCHARSET_DIMENSION (CHARSET_BY_LEADING_BYTE (i)) == 1)
-               i = (((i - FIELD2_TO_OFFICIAL_LEADING_BYTE) << 7)
-                    | (reg[rrr] & 0x7F));
-             else if (i < MAX_LEADING_BYTE_OFFICIAL_2)
-               i = ((i - FIELD1_TO_OFFICIAL_LEADING_BYTE) << 14) | reg[rrr];
-             else
-               i = ((i - FIELD1_TO_PRIVATE_LEADING_BYTE) << 14) | reg[rrr];
+             else if (LEADING_BYTE_CONTROL_1 == i)
+               i = ((reg[rrr] & 0xFF) - 0xA0);
+             else if (POSSIBLE_LEADING_BYTE_P(i) &&
+                      !NILP(CHARSET_BY_LEADING_BYTE(i)))
+               {
+                 if (XCHARSET_DIMENSION (CHARSET_BY_LEADING_BYTE (i)) == 1)
+                   i = (((i - FIELD2_TO_OFFICIAL_LEADING_BYTE) << 7)
+                        | (reg[rrr] & 0x7F));
+                 else if (i <= MAX_LEADING_BYTE_OFFICIAL_2)
+                   i = ((i - FIELD1_TO_OFFICIAL_LEADING_BYTE) << 14) 
+                     | reg[rrr];
+                 else
+                   i = ((i - FIELD1_TO_PRIVATE_LEADING_BYTE) << 14) | reg[rrr];
+               }
+             else 
+               {
+                 /* No charset we know about; use U+3012 GETA MARK */
+                 i = MAKE_CHAR
+                   (CHARSET_BY_LEADING_BYTE(LEADING_BYTE_JAPANESE_JISX0208),
+                    34, 46);
+               }
 
              CCL_WRITE_CHAR (i);
 
              break;
+#endif
 
            case CCL_TranslateCharacter:
 #if 0
@@ -1417,7 +1455,6 @@ ccl_driver (struct ccl_program *ccl,
 
                for (;i < j;i++)
                  {
-
                    size = XVECTOR (Vcode_conversion_map_vector)->size;
                    point = XINT (ccl_prog[ic++]);
                    if (point >= size) continue;