diff src/fileio.c @ 26855:68a90068d489

(Fsubstitute_in_file_name): Adjusted for the change of CHAR_STRING. (Finsert_file_contents): Set Vlast_coding_system_used before calling signal_after_change. Call update_compositions if some texts are inserted.. (Fwrite_region): Adjusted for the change of a_write and e_write. (a_write): Argument changed. Work based on character position, not byte position. (e_write): Argument changed. Handle new way of composition.
author Kenichi Handa <handa@m17n.org>
date Wed, 15 Dec 1999 00:11:24 +0000
parents 936b39bd05b4
children ac336ecd19ff
line wrap: on
line diff
--- a/src/fileio.c	Wed Dec 15 00:10:49 1999 +0000
+++ b/src/fileio.c	Wed Dec 15 00:11:24 1999 +0000
@@ -235,9 +235,10 @@
 
 Lisp_Object Qcar_less_than_car;
 
-static int a_write P_ ((int, char *, int, int,
+static int a_write P_ ((int, Lisp_Object, int, int,
 			Lisp_Object *, struct coding_system *));
-static int e_write P_ ((int, char *, int, struct coding_system *));
+static int e_write P_ ((int, Lisp_Object, int, int, struct coding_system *));
+
 
 void
 report_file_error (string, data)
@@ -2090,21 +2091,10 @@
 	  {
 	    /* If the original string is multibyte,
 	       convert what we substitute into multibyte.  */
-	    unsigned char workbuf[4], *str;
-	    int len;
-
 	    while (*o)
 	      {
-		int c = *o++;
-		c = unibyte_char_to_multibyte (c);
-		if (! SINGLE_BYTE_CHAR_P (c))
-		  {
-		    len = CHAR_STRING (c, workbuf, str);
-		    bcopy (str, x, len);
-		    x += len;
-		  }
-		else
-		  *x++ = c;
+		int c = unibyte_char_to_multibyte (*o++);
+		x += CHAR_STRING (c, x);
 	      }
 	  }
 	else
@@ -4228,15 +4218,18 @@
       inserted = XFASTINT (insval);
     }
 
+  if (set_coding_system)
+    Vlast_coding_system_used = coding.symbol;
+
   /* Call after-change hooks for the inserted text, aside from the case
      of normal visiting (not with REPLACE), which is done in a new buffer
      "before" the buffer is changed.  */
   if (inserted > 0 && total > 0
       && (NILP (visit) || !NILP (replace)))
-    signal_after_change (PT, 0, inserted);
-
-  if (set_coding_system)
-    Vlast_coding_system_used = coding.symbol;
+    {
+      signal_after_change (PT, 0, inserted);
+      update_compositions (PT, PT, CHECK_BORDER);
+    }
 
   if (inserted > 0)
     {
@@ -4652,9 +4645,8 @@
 
   if (STRINGP (start))
     {
-      failure = 0 > a_write (desc, XSTRING (start)->data,
-			     STRING_BYTES (XSTRING (start)), 0, &annotations,
-			     &coding);
+      failure = 0 > a_write (desc, start, 0, XSTRING (start)->size,
+			     &annotations, &coding);
       save_errno = errno;
     }
   else if (XINT (start) != XINT (end))
@@ -4665,17 +4657,17 @@
 
       if (XINT (start) < GPT)
 	{
-	  failure = 0 > a_write (desc, BYTE_POS_ADDR (tem),
-				 min (GPT_BYTE, end1) - tem, tem, &annotations,
-				 &coding);
+	  failure = 0 > a_write (desc, Qnil, XINT (start),
+				 min (GPT, XINT (end)) - XINT (start),
+				 &annotations, &coding);
 	  save_errno = errno;
 	}
 
       if (XINT (end) > GPT && !failure)
 	{
-	  tem = max (tem, GPT_BYTE);
-	  failure = 0 > a_write (desc, BYTE_POS_ADDR (tem), end1 - tem,
-				 tem, &annotations, &coding);
+	  tem = max (XINT (start), GPT);
+	  failure = 0 > a_write (desc, Qnil, tem , XINT (end) - tem,
+				 &annotations, &coding);
 	  save_errno = errno;
 	}
     }
@@ -4683,7 +4675,7 @@
     {
       /* If file was empty, still need to write the annotations */
       coding.mode |= CODING_MODE_LAST_BLOCK;
-      failure = 0 > a_write (desc, "", 0, XINT (start), &annotations, &coding);
+      failure = 0 > a_write (desc, Qnil, XINT (end), 0, &annotations, &coding);
       save_errno = errno;
     }
 
@@ -4693,7 +4685,7 @@
     {
       /* We have to flush out a data. */
       coding.mode |= CODING_MODE_LAST_BLOCK;
-      failure = 0 > e_write (desc, "", 0, &coding);
+      failure = 0 > e_write (desc, Qnil, 0, 0, &coding);
       save_errno = errno;
     }
 
@@ -4876,10 +4868,10 @@
   return annotations;
 }
 
-/* Write to descriptor DESC the NBYTES bytes starting at ADDR,
-   assuming they start at byte position BYTEPOS in the buffer.
+/* Write to descriptor DESC the NCHARS chars starting at POS of STRING.
+   If STRING is nil, POS is the character position in the current buffer.
    Intersperse with them the annotations from *ANNOT
-   which fall within the range of byte positions BYTEPOS to BYTEPOS + NBYTES,
+   which fall within the range of POS to POS + NCHARS,
    each at its appropriate position.
 
    We modify *ANNOT by discarding elements as we use them up.
@@ -4887,44 +4879,42 @@
    The return value is negative in case of system call failure.  */
 
 static int
-a_write (desc, addr, nbytes, bytepos, annot, coding)
+a_write (desc, string, pos, nchars, annot, coding)
      int desc;
-     register char *addr;
-     register int nbytes;
-     int bytepos;
+     Lisp_Object string;
+     register int nchars;
+     int pos;
      Lisp_Object *annot;
      struct coding_system *coding;
 {
   Lisp_Object tem;
   int nextpos;
-  int lastpos = bytepos + nbytes;
+  int lastpos = pos + nchars;
 
   while (NILP (*annot) || CONSP (*annot))
     {
       tem = Fcar_safe (Fcar (*annot));
-      nextpos = bytepos - 1;
+      nextpos = pos - 1;
       if (INTEGERP (tem))
-	nextpos = CHAR_TO_BYTE (XFASTINT (tem));
+	nextpos = XFASTINT (tem);
 
       /* If there are no more annotations in this range,
 	 output the rest of the range all at once.  */
-      if (! (nextpos >= bytepos && nextpos <= lastpos))
-	return e_write (desc, addr, lastpos - bytepos, coding);
+      if (! (nextpos >= pos && nextpos <= lastpos))
+	return e_write (desc, string, pos, lastpos, coding);
 
       /* Output buffer text up to the next annotation's position.  */
-      if (nextpos > bytepos)
+      if (nextpos > pos)
 	{
-	  if (0 > e_write (desc, addr, nextpos - bytepos, coding))
+	  if (0 > e_write (desc, string, pos, nextpos, coding));
 	    return -1;
-	  addr += nextpos - bytepos;
-	  bytepos = nextpos;
+	  pos = nextpos;
 	}
       /* Output the annotation.  */
       tem = Fcdr (Fcar (*annot));
       if (STRINGP (tem))
 	{
-	  if (0 > e_write (desc, XSTRING (tem)->data, STRING_BYTES (XSTRING (tem)),
-			   coding))
+	  if (0 > e_write (desc, tem, 0, XSTRING (tem)->size, coding));
 	    return -1;
 	}
       *annot = Fcdr (*annot);
@@ -4936,17 +4926,45 @@
 #define WRITE_BUF_SIZE (16 * 1024)
 #endif
 
-/* Write NBYTES bytes starting at ADDR into descriptor DESC,
-   encoding them with coding system CODING.  */
+/* Write text in the range START and END into descriptor DESC,
+   encoding them with coding system CODING.  If STRING is nil, START
+   and END are character positions of the current buffer, else they
+   are indexes to the string STRING.  */
 
 static int
-e_write (desc, addr, nbytes, coding)
+e_write (desc, string, start, end, coding)
      int desc;
-     register char *addr;
-     register int nbytes;
+     Lisp_Object string;
+     int start, end;
      struct coding_system *coding;
 {
+  register char *addr;
+  register int nbytes;
   char buf[WRITE_BUF_SIZE];
+  int composing = coding->composing;
+  int return_val = 0;
+
+  if (start >= end)
+    coding->composing = COMPOSITION_DISABLED;
+  if (coding->composing != COMPOSITION_DISABLED)
+    coding_save_composition (coding, start, end, string);
+
+  if (STRINGP (string))
+    {
+      addr = XSTRING (string)->data;
+      nbytes = STRING_BYTES (XSTRING (string));
+    }
+  else if (start < end)
+    {
+      /* It is assured that the gap is not in the range START and END-1.  */
+      addr = CHAR_POS_ADDR (start);
+      nbytes = CHAR_TO_BYTE (end) - CHAR_TO_BYTE (start);
+    }
+  else
+    {
+      addr = "";
+      nbytes = 0;
+    }
 
   /* We used to have a code for handling selective display here.  But,
      now it is handled within encode_coding.  */
@@ -4955,21 +4973,33 @@
       int result;
 
       result = encode_coding (coding, addr, buf, nbytes, WRITE_BUF_SIZE);
-      nbytes -= coding->consumed, addr += coding->consumed;
       if (coding->produced > 0)
 	{
 	  coding->produced -= emacs_write (desc, buf, coding->produced);
-	  if (coding->produced) return -1;
+	  if (coding->produced)
+	    {
+	      return_val = -1;
+	      break;
+	    }
 	}
       if (result == CODING_FINISH_INSUFFICIENT_SRC)
 	{
 	  /* The source text ends by an incomplete multibyte form.
              There's no way other than write it out as is.  */
 	  nbytes -= emacs_write (desc, addr, nbytes);
-	  if (nbytes) return -1;
+	  if (nbytes)
+	    {
+	      return_val = -1;
+	      break;
+	    }
 	}
       if (nbytes <= 0)
 	break;
+      nbytes -= coding->consumed;
+      addr += coding->consumed;
+      start += coding->consumed_char;
+      if (coding->cmp_data)
+	coding_adjust_composition_offset (coding, start);
     }
   return 0;
 }