changeset 88597:74b74f59bc09

(decode_coding_charset): Adjusted for the change of Fdefine_coding_system_internal. (Fdefine_coding_system_internal): For a coding system of `charset' type, store a list of charset IDs in `charset_attr_charset_valids' element of coding attributes.
author Kenichi Handa <handa@m17n.org>
date Wed, 22 May 2002 11:14:45 +0000
parents 235ee9d10206
children b88195f69856
files src/coding.c
diffstat 1 files changed, 100 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/src/coding.c	Wed May 22 11:14:25 2002 +0000
+++ b/src/coding.c	Wed May 22 11:14:45 2002 +0000
@@ -4320,6 +4320,8 @@
       ONE_MORE_BYTE (c);
       if (c == '\r')
 	{
+	  /* Here we assume that no charset maps '\r' to something
+	     else.  */
 	  if (EQ (eol_type, Qdos))
 	    {
 	      if (src < src_end
@@ -4333,28 +4335,70 @@
 	{
 	  Lisp_Object val;
 	  struct charset *charset;
+	  int dim;
+	  unsigned code;
 	  int c1;
 
 	  val = AREF (valids, c);
 	  if (NILP (val))
 	    goto invalid_code;
-	  charset = CHARSET_FROM_ID (XFASTINT (val));
-	  if (CHARSET_DIMENSION (charset) > 1)
+	  if (INTEGERP (val))
 	    {
-	      ONE_MORE_BYTE (c1);
-	      c = (c << 8) | c1;
-	      if (CHARSET_DIMENSION (charset) > 2)
+	      charset = CHARSET_FROM_ID (XFASTINT (val));
+	      dim = CHARSET_DIMENSION (charset);
+	      code = c;
+	      if (dim > 1)
 		{
 		  ONE_MORE_BYTE (c1);
-		  c = (c << 8) | c1;
-		  if (CHARSET_DIMENSION (charset) > 3)
+		  code = (code << 8) | c1;
+		  if (dim > 2)
 		    {
 		      ONE_MORE_BYTE (c1);
-		      c = (c << 8) | c1;
+		      code = (code << 8) | c1;
+		      if (dim > 3)
+			{
+			  ONE_MORE_BYTE (c1);
+			  code = (c << 8) | c1;
+			}
 		    }
 		}
+	      CODING_DECODE_CHAR (coding, src, src_base, src_end,
+				  charset, code, c);
 	    }
-	  CODING_DECODE_CHAR (coding, src, src_base, src_end, charset, c, c);
+	  else
+	    {
+	      /* VAL is a list of charset IDs.  It is assured that the
+		 list is sorted by charset dimensions (smaller one
+		 comes first).  */
+	      int b[4];
+	      int len = 1;
+
+	      b[0] = c;
+	      /* VAL is a list of charset IDs.  */
+	      while (CONSP (val))
+		{
+		  charset = CHARSET_FROM_ID (XFASTINT (XCAR (val)));
+		  dim = CHARSET_DIMENSION (charset);
+		  while (len < dim)
+		    {
+		      ONE_MORE_BYTE (c1);
+		      b[len++] = c1;
+		    }
+		  if (dim == 1)
+		    code = b[0];
+		  else if (dim == 2)
+		    code = (b[0] << 8) | b[1];
+		  else if (dim == 3)
+		    code = (b[0] << 16) | (b[1] << 8) | b[2];
+		  else
+		    code = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3];
+		  CODING_DECODE_CHAR (coding, src, src_base,
+				      src_end, charset, code, c);
+		  if (c >= 0)
+		    break;
+		  val = XCDR (val);
+		}
+	    }
 	  if (c < 0)
 	    goto invalid_code;
 	}
@@ -7366,20 +7410,61 @@
 
   if (EQ (coding_type, Qcharset))
     {
+      /* Generate a lisp vector of 256 elements.  Each element is nil,
+	 integer, or a list of charset IDs.
+
+	 If Nth element is nil, the byte code N is invalid in this
+	 coding system.
+
+	 If Nth element is a number NUM, N is the first byte of a
+	 charset whose ID is NUM.
+
+	 If Nth element is a list of charset IDs, N is the first byte
+	 of one of them.  The list is sorted by dimensions of the
+	 charsets.  A charset of smaller dimension comes firtst.
+      */
       val = Fmake_vector (make_number (256), Qnil);
 
       for (tail = charset_list; CONSP (tail); tail = XCDR (tail))
 	{
-	  struct charset *charset = CHARSET_FROM_ID (XINT (XCAR (tail)));
-	  int idx = (CHARSET_DIMENSION (charset) - 1) * 4;
-
+	  struct charset *charset = CHARSET_FROM_ID (XFASTINT (XCAR (tail)));
+	  int dim = CHARSET_DIMENSION (charset);
+	  int idx = (dim - 1) * 4;
+	  
 	  for (i = charset->code_space[idx];
 	       i <= charset->code_space[idx + 1]; i++)
 	    {
-	      if (NILP (AREF (val, i)))
-		ASET (val, i, XCAR (tail));
+	      Lisp_Object tmp, tmp2;
+	      int dim2;
+
+	      tmp = AREF (val, i);
+	      if (NILP (tmp))
+		tmp = XCAR (tail);
+	      else if (NUMBERP (tmp))
+		{
+		  dim2 = CHARSET_DIMENSION (CHARSET_FROM_ID (XFASTINT (tmp)));
+		  if (dim < dim2)
+		    tmp = Fcons (tmp, Fcons (XCAR (tail), Qnil));
+		  else
+		    tmp = Fcons (XCAR (tail), Fcons (tmp, Qnil));
+		}
 	      else
-		error ("Charsets conflicts in the first byte");
+		{
+		  for (tmp2 = tmp; CONSP (tmp2); tmp2 = XCDR (tmp2))
+		    {
+		      dim2 = CHARSET_DIMENSION (CHARSET_FROM_ID (XFASTINT (XCAR (tmp2))));
+		      if (dim < dim2)
+			break;
+		    }
+		  if (NILP (tmp2))
+		    tmp = nconc2 (tmp, Fcons (XCAR (tail), Qnil));
+		  else
+		    {
+		      XSETCDR (tmp2, Fcons (XCAR (tmp2), XCDR (tmp2)));
+		      XSETCAR (tmp2, XCAR (tail));
+		    }
+		}
+	      ASET (val, i, tmp);
 	    }
 	}
       ASET (attrs, coding_attr_charset_valids, val);