Mercurial > emacs
comparison 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 |
comparison
equal
deleted
inserted
replaced
26854:c8f8089c339b | 26855:68a90068d489 |
---|---|
233 Lisp_Object Qexcl; | 233 Lisp_Object Qexcl; |
234 Lisp_Object Qfile_name_history; | 234 Lisp_Object Qfile_name_history; |
235 | 235 |
236 Lisp_Object Qcar_less_than_car; | 236 Lisp_Object Qcar_less_than_car; |
237 | 237 |
238 static int a_write P_ ((int, char *, int, int, | 238 static int a_write P_ ((int, Lisp_Object, int, int, |
239 Lisp_Object *, struct coding_system *)); | 239 Lisp_Object *, struct coding_system *)); |
240 static int e_write P_ ((int, char *, int, struct coding_system *)); | 240 static int e_write P_ ((int, Lisp_Object, int, int, struct coding_system *)); |
241 | |
241 | 242 |
242 void | 243 void |
243 report_file_error (string, data) | 244 report_file_error (string, data) |
244 char *string; | 245 char *string; |
245 Lisp_Object data; | 246 Lisp_Object data; |
2088 | 2089 |
2089 if (STRING_MULTIBYTE (filename)) | 2090 if (STRING_MULTIBYTE (filename)) |
2090 { | 2091 { |
2091 /* If the original string is multibyte, | 2092 /* If the original string is multibyte, |
2092 convert what we substitute into multibyte. */ | 2093 convert what we substitute into multibyte. */ |
2093 unsigned char workbuf[4], *str; | |
2094 int len; | |
2095 | |
2096 while (*o) | 2094 while (*o) |
2097 { | 2095 { |
2098 int c = *o++; | 2096 int c = unibyte_char_to_multibyte (*o++); |
2099 c = unibyte_char_to_multibyte (c); | 2097 x += CHAR_STRING (c, x); |
2100 if (! SINGLE_BYTE_CHAR_P (c)) | |
2101 { | |
2102 len = CHAR_STRING (c, workbuf, str); | |
2103 bcopy (str, x, len); | |
2104 x += len; | |
2105 } | |
2106 else | |
2107 *x++ = c; | |
2108 } | 2098 } |
2109 } | 2099 } |
2110 else | 2100 else |
2111 { | 2101 { |
2112 strcpy (x, o); | 2102 strcpy (x, o); |
4226 Qnil, make_number (inserted), visit); | 4216 Qnil, make_number (inserted), visit); |
4227 CHECK_NUMBER (insval, 0); | 4217 CHECK_NUMBER (insval, 0); |
4228 inserted = XFASTINT (insval); | 4218 inserted = XFASTINT (insval); |
4229 } | 4219 } |
4230 | 4220 |
4221 if (set_coding_system) | |
4222 Vlast_coding_system_used = coding.symbol; | |
4223 | |
4231 /* Call after-change hooks for the inserted text, aside from the case | 4224 /* Call after-change hooks for the inserted text, aside from the case |
4232 of normal visiting (not with REPLACE), which is done in a new buffer | 4225 of normal visiting (not with REPLACE), which is done in a new buffer |
4233 "before" the buffer is changed. */ | 4226 "before" the buffer is changed. */ |
4234 if (inserted > 0 && total > 0 | 4227 if (inserted > 0 && total > 0 |
4235 && (NILP (visit) || !NILP (replace))) | 4228 && (NILP (visit) || !NILP (replace))) |
4236 signal_after_change (PT, 0, inserted); | 4229 { |
4237 | 4230 signal_after_change (PT, 0, inserted); |
4238 if (set_coding_system) | 4231 update_compositions (PT, PT, CHECK_BORDER); |
4239 Vlast_coding_system_used = coding.symbol; | 4232 } |
4240 | 4233 |
4241 if (inserted > 0) | 4234 if (inserted > 0) |
4242 { | 4235 { |
4243 p = Vafter_insert_file_functions; | 4236 p = Vafter_insert_file_functions; |
4244 while (!NILP (p)) | 4237 while (!NILP (p)) |
4650 failure = 0; | 4643 failure = 0; |
4651 immediate_quit = 1; | 4644 immediate_quit = 1; |
4652 | 4645 |
4653 if (STRINGP (start)) | 4646 if (STRINGP (start)) |
4654 { | 4647 { |
4655 failure = 0 > a_write (desc, XSTRING (start)->data, | 4648 failure = 0 > a_write (desc, start, 0, XSTRING (start)->size, |
4656 STRING_BYTES (XSTRING (start)), 0, &annotations, | 4649 &annotations, &coding); |
4657 &coding); | |
4658 save_errno = errno; | 4650 save_errno = errno; |
4659 } | 4651 } |
4660 else if (XINT (start) != XINT (end)) | 4652 else if (XINT (start) != XINT (end)) |
4661 { | 4653 { |
4662 register int end1 = CHAR_TO_BYTE (XINT (end)); | 4654 register int end1 = CHAR_TO_BYTE (XINT (end)); |
4663 | 4655 |
4664 tem = CHAR_TO_BYTE (XINT (start)); | 4656 tem = CHAR_TO_BYTE (XINT (start)); |
4665 | 4657 |
4666 if (XINT (start) < GPT) | 4658 if (XINT (start) < GPT) |
4667 { | 4659 { |
4668 failure = 0 > a_write (desc, BYTE_POS_ADDR (tem), | 4660 failure = 0 > a_write (desc, Qnil, XINT (start), |
4669 min (GPT_BYTE, end1) - tem, tem, &annotations, | 4661 min (GPT, XINT (end)) - XINT (start), |
4670 &coding); | 4662 &annotations, &coding); |
4671 save_errno = errno; | 4663 save_errno = errno; |
4672 } | 4664 } |
4673 | 4665 |
4674 if (XINT (end) > GPT && !failure) | 4666 if (XINT (end) > GPT && !failure) |
4675 { | 4667 { |
4676 tem = max (tem, GPT_BYTE); | 4668 tem = max (XINT (start), GPT); |
4677 failure = 0 > a_write (desc, BYTE_POS_ADDR (tem), end1 - tem, | 4669 failure = 0 > a_write (desc, Qnil, tem , XINT (end) - tem, |
4678 tem, &annotations, &coding); | 4670 &annotations, &coding); |
4679 save_errno = errno; | 4671 save_errno = errno; |
4680 } | 4672 } |
4681 } | 4673 } |
4682 else | 4674 else |
4683 { | 4675 { |
4684 /* If file was empty, still need to write the annotations */ | 4676 /* If file was empty, still need to write the annotations */ |
4685 coding.mode |= CODING_MODE_LAST_BLOCK; | 4677 coding.mode |= CODING_MODE_LAST_BLOCK; |
4686 failure = 0 > a_write (desc, "", 0, XINT (start), &annotations, &coding); | 4678 failure = 0 > a_write (desc, Qnil, XINT (end), 0, &annotations, &coding); |
4687 save_errno = errno; | 4679 save_errno = errno; |
4688 } | 4680 } |
4689 | 4681 |
4690 if (CODING_REQUIRE_FLUSHING (&coding) | 4682 if (CODING_REQUIRE_FLUSHING (&coding) |
4691 && !(coding.mode & CODING_MODE_LAST_BLOCK) | 4683 && !(coding.mode & CODING_MODE_LAST_BLOCK) |
4692 && ! failure) | 4684 && ! failure) |
4693 { | 4685 { |
4694 /* We have to flush out a data. */ | 4686 /* We have to flush out a data. */ |
4695 coding.mode |= CODING_MODE_LAST_BLOCK; | 4687 coding.mode |= CODING_MODE_LAST_BLOCK; |
4696 failure = 0 > e_write (desc, "", 0, &coding); | 4688 failure = 0 > e_write (desc, Qnil, 0, 0, &coding); |
4697 save_errno = errno; | 4689 save_errno = errno; |
4698 } | 4690 } |
4699 | 4691 |
4700 immediate_quit = 0; | 4692 immediate_quit = 0; |
4701 | 4693 |
4874 | 4866 |
4875 UNGCPRO; | 4867 UNGCPRO; |
4876 return annotations; | 4868 return annotations; |
4877 } | 4869 } |
4878 | 4870 |
4879 /* Write to descriptor DESC the NBYTES bytes starting at ADDR, | 4871 /* Write to descriptor DESC the NCHARS chars starting at POS of STRING. |
4880 assuming they start at byte position BYTEPOS in the buffer. | 4872 If STRING is nil, POS is the character position in the current buffer. |
4881 Intersperse with them the annotations from *ANNOT | 4873 Intersperse with them the annotations from *ANNOT |
4882 which fall within the range of byte positions BYTEPOS to BYTEPOS + NBYTES, | 4874 which fall within the range of POS to POS + NCHARS, |
4883 each at its appropriate position. | 4875 each at its appropriate position. |
4884 | 4876 |
4885 We modify *ANNOT by discarding elements as we use them up. | 4877 We modify *ANNOT by discarding elements as we use them up. |
4886 | 4878 |
4887 The return value is negative in case of system call failure. */ | 4879 The return value is negative in case of system call failure. */ |
4888 | 4880 |
4889 static int | 4881 static int |
4890 a_write (desc, addr, nbytes, bytepos, annot, coding) | 4882 a_write (desc, string, pos, nchars, annot, coding) |
4891 int desc; | 4883 int desc; |
4892 register char *addr; | 4884 Lisp_Object string; |
4893 register int nbytes; | 4885 register int nchars; |
4894 int bytepos; | 4886 int pos; |
4895 Lisp_Object *annot; | 4887 Lisp_Object *annot; |
4896 struct coding_system *coding; | 4888 struct coding_system *coding; |
4897 { | 4889 { |
4898 Lisp_Object tem; | 4890 Lisp_Object tem; |
4899 int nextpos; | 4891 int nextpos; |
4900 int lastpos = bytepos + nbytes; | 4892 int lastpos = pos + nchars; |
4901 | 4893 |
4902 while (NILP (*annot) || CONSP (*annot)) | 4894 while (NILP (*annot) || CONSP (*annot)) |
4903 { | 4895 { |
4904 tem = Fcar_safe (Fcar (*annot)); | 4896 tem = Fcar_safe (Fcar (*annot)); |
4905 nextpos = bytepos - 1; | 4897 nextpos = pos - 1; |
4906 if (INTEGERP (tem)) | 4898 if (INTEGERP (tem)) |
4907 nextpos = CHAR_TO_BYTE (XFASTINT (tem)); | 4899 nextpos = XFASTINT (tem); |
4908 | 4900 |
4909 /* If there are no more annotations in this range, | 4901 /* If there are no more annotations in this range, |
4910 output the rest of the range all at once. */ | 4902 output the rest of the range all at once. */ |
4911 if (! (nextpos >= bytepos && nextpos <= lastpos)) | 4903 if (! (nextpos >= pos && nextpos <= lastpos)) |
4912 return e_write (desc, addr, lastpos - bytepos, coding); | 4904 return e_write (desc, string, pos, lastpos, coding); |
4913 | 4905 |
4914 /* Output buffer text up to the next annotation's position. */ | 4906 /* Output buffer text up to the next annotation's position. */ |
4915 if (nextpos > bytepos) | 4907 if (nextpos > pos) |
4916 { | 4908 { |
4917 if (0 > e_write (desc, addr, nextpos - bytepos, coding)) | 4909 if (0 > e_write (desc, string, pos, nextpos, coding)); |
4918 return -1; | 4910 return -1; |
4919 addr += nextpos - bytepos; | 4911 pos = nextpos; |
4920 bytepos = nextpos; | |
4921 } | 4912 } |
4922 /* Output the annotation. */ | 4913 /* Output the annotation. */ |
4923 tem = Fcdr (Fcar (*annot)); | 4914 tem = Fcdr (Fcar (*annot)); |
4924 if (STRINGP (tem)) | 4915 if (STRINGP (tem)) |
4925 { | 4916 { |
4926 if (0 > e_write (desc, XSTRING (tem)->data, STRING_BYTES (XSTRING (tem)), | 4917 if (0 > e_write (desc, tem, 0, XSTRING (tem)->size, coding)); |
4927 coding)) | |
4928 return -1; | 4918 return -1; |
4929 } | 4919 } |
4930 *annot = Fcdr (*annot); | 4920 *annot = Fcdr (*annot); |
4931 } | 4921 } |
4932 return 0; | 4922 return 0; |
4934 | 4924 |
4935 #ifndef WRITE_BUF_SIZE | 4925 #ifndef WRITE_BUF_SIZE |
4936 #define WRITE_BUF_SIZE (16 * 1024) | 4926 #define WRITE_BUF_SIZE (16 * 1024) |
4937 #endif | 4927 #endif |
4938 | 4928 |
4939 /* Write NBYTES bytes starting at ADDR into descriptor DESC, | 4929 /* Write text in the range START and END into descriptor DESC, |
4940 encoding them with coding system CODING. */ | 4930 encoding them with coding system CODING. If STRING is nil, START |
4931 and END are character positions of the current buffer, else they | |
4932 are indexes to the string STRING. */ | |
4941 | 4933 |
4942 static int | 4934 static int |
4943 e_write (desc, addr, nbytes, coding) | 4935 e_write (desc, string, start, end, coding) |
4944 int desc; | 4936 int desc; |
4945 register char *addr; | 4937 Lisp_Object string; |
4946 register int nbytes; | 4938 int start, end; |
4947 struct coding_system *coding; | 4939 struct coding_system *coding; |
4948 { | 4940 { |
4941 register char *addr; | |
4942 register int nbytes; | |
4949 char buf[WRITE_BUF_SIZE]; | 4943 char buf[WRITE_BUF_SIZE]; |
4944 int composing = coding->composing; | |
4945 int return_val = 0; | |
4946 | |
4947 if (start >= end) | |
4948 coding->composing = COMPOSITION_DISABLED; | |
4949 if (coding->composing != COMPOSITION_DISABLED) | |
4950 coding_save_composition (coding, start, end, string); | |
4951 | |
4952 if (STRINGP (string)) | |
4953 { | |
4954 addr = XSTRING (string)->data; | |
4955 nbytes = STRING_BYTES (XSTRING (string)); | |
4956 } | |
4957 else if (start < end) | |
4958 { | |
4959 /* It is assured that the gap is not in the range START and END-1. */ | |
4960 addr = CHAR_POS_ADDR (start); | |
4961 nbytes = CHAR_TO_BYTE (end) - CHAR_TO_BYTE (start); | |
4962 } | |
4963 else | |
4964 { | |
4965 addr = ""; | |
4966 nbytes = 0; | |
4967 } | |
4950 | 4968 |
4951 /* We used to have a code for handling selective display here. But, | 4969 /* We used to have a code for handling selective display here. But, |
4952 now it is handled within encode_coding. */ | 4970 now it is handled within encode_coding. */ |
4953 while (1) | 4971 while (1) |
4954 { | 4972 { |
4955 int result; | 4973 int result; |
4956 | 4974 |
4957 result = encode_coding (coding, addr, buf, nbytes, WRITE_BUF_SIZE); | 4975 result = encode_coding (coding, addr, buf, nbytes, WRITE_BUF_SIZE); |
4958 nbytes -= coding->consumed, addr += coding->consumed; | |
4959 if (coding->produced > 0) | 4976 if (coding->produced > 0) |
4960 { | 4977 { |
4961 coding->produced -= emacs_write (desc, buf, coding->produced); | 4978 coding->produced -= emacs_write (desc, buf, coding->produced); |
4962 if (coding->produced) return -1; | 4979 if (coding->produced) |
4980 { | |
4981 return_val = -1; | |
4982 break; | |
4983 } | |
4963 } | 4984 } |
4964 if (result == CODING_FINISH_INSUFFICIENT_SRC) | 4985 if (result == CODING_FINISH_INSUFFICIENT_SRC) |
4965 { | 4986 { |
4966 /* The source text ends by an incomplete multibyte form. | 4987 /* The source text ends by an incomplete multibyte form. |
4967 There's no way other than write it out as is. */ | 4988 There's no way other than write it out as is. */ |
4968 nbytes -= emacs_write (desc, addr, nbytes); | 4989 nbytes -= emacs_write (desc, addr, nbytes); |
4969 if (nbytes) return -1; | 4990 if (nbytes) |
4991 { | |
4992 return_val = -1; | |
4993 break; | |
4994 } | |
4970 } | 4995 } |
4971 if (nbytes <= 0) | 4996 if (nbytes <= 0) |
4972 break; | 4997 break; |
4998 nbytes -= coding->consumed; | |
4999 addr += coding->consumed; | |
5000 start += coding->consumed_char; | |
5001 if (coding->cmp_data) | |
5002 coding_adjust_composition_offset (coding, start); | |
4973 } | 5003 } |
4974 return 0; | 5004 return 0; |
4975 } | 5005 } |
4976 | 5006 |
4977 DEFUN ("verify-visited-file-modtime", Fverify_visited_file_modtime, | 5007 DEFUN ("verify-visited-file-modtime", Fverify_visited_file_modtime, |