summaryrefslogtreecommitdiff
path: root/src/fileio.c
diff options
context:
space:
mode:
authorKenichi Handa <handa@m17n.org>1999-12-15 00:11:24 +0000
committerKenichi Handa <handa@m17n.org>1999-12-15 00:11:24 +0000
commitce51c54c3fee569d6dd0857971cd42f47f0b718d (patch)
treeb2ce0cd13d783930dd26134d1f5e9da35f86b8f7 /src/fileio.c
parent9d100795e3a2bda1a03724fb539851bb2cf15df2 (diff)
downloademacs-ce51c54c3fee569d6dd0857971cd42f47f0b718d.tar.gz
(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.
Diffstat (limited to 'src/fileio.c')
-rw-r--r--src/fileio.c142
1 files changed, 86 insertions, 56 deletions
diff --git a/src/fileio.c b/src/fileio.c
index 9a346ac9436..17be8acfaab 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -235,9 +235,10 @@ Lisp_Object Qfile_name_history;
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 @@ duplicates what `expand-file-name' does.")
{
/* 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 @@ actually used.")
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 @@ This does code conversion according to the value of\n\
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 @@ This does code conversion according to the value of\n\
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 @@ This does code conversion according to the value of\n\
{
/* 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 @@ This does code conversion according to the value of\n\
{
/* 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 @@ build_annotations (start, end, pre_write_conversion)
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 @@ build_annotations (start, end, pre_write_conversion)
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 @@ a_write (desc, addr, nbytes, bytepos, annot, coding)
#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 @@ e_write (desc, addr, nbytes, coding)
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;
}