Mercurial > emacs
comparison src/fileio.c @ 17723:f67a321c8fb6
(Fwrite_region): Add 7th optional arg
CODING_SYSTEM. Move gap after a newline code if we are encoding
in a coding system which requires designation sequences to be put
at beginning of line. Set coding.last_block to 1 before calling
a_write for an empty file.
(build_annotations): Code tuned up for handling
pre_write_conversion of a coding system.
(e_write): Delete code for handling carryover of code conversion.
It is now handled in encode_coding.
(auto_save_1): Supply 7th new arg CODING_SYSTEM as Qnil to
Fwrite_region.
author | Kenichi Handa <handa@m17n.org> |
---|---|
date | Sat, 10 May 1997 03:37:01 +0000 |
parents | ca4e00792be3 |
children | d7b187832881 |
comparison
equal
deleted
inserted
replaced
17722:27df69e20b98 | 17723:f67a321c8fb6 |
---|---|
3744 Fset_buffer (buf); | 3744 Fset_buffer (buf); |
3745 Fkill_buffer (tembuf); | 3745 Fkill_buffer (tembuf); |
3746 return Qnil; | 3746 return Qnil; |
3747 } | 3747 } |
3748 | 3748 |
3749 DEFUN ("write-region", Fwrite_region, Swrite_region, 3, 6, | 3749 DEFUN ("write-region", Fwrite_region, Swrite_region, 3, 7, |
3750 "r\nFWrite region to file: ", | 3750 "r\nFWrite region to file: \ni\ni\ni\nZCoding system: ", |
3751 "Write current region into specified file.\n\ | 3751 "Write current region into specified file.\n\ |
3752 When called from a program, takes three arguments:\n\ | 3752 When called from a program, takes three arguments:\n\ |
3753 START, END and FILENAME. START and END are buffer positions.\n\ | 3753 START, END and FILENAME. START and END are buffer positions.\n\ |
3754 Optional fourth argument APPEND if non-nil means\n\ | 3754 Optional fourth argument APPEND if non-nil means\n\ |
3755 append to existing file contents (if any).\n\ | 3755 append to existing file contents (if any).\n\ |
3761 VISIT is also the file name to lock and unlock for clash detection.\n\ | 3761 VISIT is also the file name to lock and unlock for clash detection.\n\ |
3762 If VISIT is neither t nor nil nor a string,\n\ | 3762 If VISIT is neither t nor nil nor a string,\n\ |
3763 that means do not print the \"Wrote file\" message.\n\ | 3763 that means do not print the \"Wrote file\" message.\n\ |
3764 The optional sixth arg LOCKNAME, if non-nil, specifies the name to\n\ | 3764 The optional sixth arg LOCKNAME, if non-nil, specifies the name to\n\ |
3765 use for locking and unlocking, overriding FILENAME and VISIT.\n\ | 3765 use for locking and unlocking, overriding FILENAME and VISIT.\n\ |
3766 The optional seventh arg CODING-SYSTEM, if non-nil, specifies the coding\n\ | |
3767 system to be used for encoding characters. For interactive use,\n\ | |
3768 you can specify it by giving a prefix argument. If no coding system\n\ | |
3769 is specified, the current region is encoded according to the value of\n\ | |
3770 `coding-system-for-write' or `coding-system-alist'. The variable\n\ | |
3771 `last-coding-system-used' is set the coding system actually used.\n\ | |
3766 Kludgy feature: if START is a string, then that string is written\n\ | 3772 Kludgy feature: if START is a string, then that string is written\n\ |
3767 to the file, instead of any buffer contents, and END is ignored.\n\ | 3773 to the file, instead of any buffer contents, and END is ignored.") |
3768 This does code conversion according to the value of\n\ | 3774 (start, end, filename, append, visit, lockname, coding_system_symbol) |
3769 `coding-system-for-write' or `coding-system-alist', and sets the variable\n\ | |
3770 `last-coding-system-used' to the coding system actually used.") | |
3771 (start, end, filename, append, visit, lockname) | |
3772 Lisp_Object start, end, filename, append, visit, lockname; | 3775 Lisp_Object start, end, filename, append, visit, lockname; |
3776 Lisp_Object coding_system_symbol; | |
3773 { | 3777 { |
3774 register int desc; | 3778 register int desc; |
3775 int failure; | 3779 int failure; |
3776 int save_errno; | 3780 int save_errno; |
3777 unsigned char *fn; | 3781 unsigned char *fn; |
3798 error ("Cannot do file visiting in an indirect buffer"); | 3802 error ("Cannot do file visiting in an indirect buffer"); |
3799 | 3803 |
3800 if (!NILP (start) && !STRINGP (start)) | 3804 if (!NILP (start) && !STRINGP (start)) |
3801 validate_region (&start, &end); | 3805 validate_region (&start, &end); |
3802 | 3806 |
3803 GCPRO4 (start, filename, visit, lockname); | 3807 GCPRO5 (start, filename, visit, lockname, coding_system_symbol); |
3804 filename = Fexpand_file_name (filename, Qnil); | |
3805 if (STRINGP (visit)) | |
3806 visit_file = Fexpand_file_name (visit, Qnil); | |
3807 else | |
3808 visit_file = filename; | |
3809 UNGCPRO; | |
3810 | |
3811 visiting = (EQ (visit, Qt) || STRINGP (visit)); | |
3812 quietly = !NILP (visit); | |
3813 | |
3814 annotations = Qnil; | |
3815 | |
3816 if (NILP (lockname)) | |
3817 lockname = visit_file; | |
3818 | |
3819 GCPRO5 (start, filename, annotations, visit_file, lockname); | |
3820 | |
3821 /* If the file name has special constructs in it, | |
3822 call the corresponding file handler. */ | |
3823 handler = Ffind_file_name_handler (filename, Qwrite_region); | |
3824 /* If FILENAME has no handler, see if VISIT has one. */ | |
3825 if (NILP (handler) && STRINGP (visit)) | |
3826 handler = Ffind_file_name_handler (visit, Qwrite_region); | |
3827 | |
3828 if (!NILP (handler)) | |
3829 { | |
3830 Lisp_Object val; | |
3831 val = call6 (handler, Qwrite_region, start, end, | |
3832 filename, append, visit); | |
3833 | |
3834 if (visiting) | |
3835 { | |
3836 SAVE_MODIFF = MODIFF; | |
3837 XSETFASTINT (current_buffer->save_length, Z - BEG); | |
3838 current_buffer->filename = visit_file; | |
3839 } | |
3840 UNGCPRO; | |
3841 return val; | |
3842 } | |
3843 | 3808 |
3844 /* Decide the coding-system to be encoded to. */ | 3809 /* Decide the coding-system to be encoded to. */ |
3845 { | 3810 { |
3846 Lisp_Object val; | 3811 Lisp_Object val; |
3847 | 3812 |
3848 if (auto_saving || NILP (current_buffer->enable_multibyte_characters)) | 3813 if (auto_saving || NILP (current_buffer->enable_multibyte_characters)) |
3849 val = Qnil; | 3814 val = Qnil; |
3815 else if (!NILP (coding_system_symbol)) | |
3816 val = coding_system_symbol; | |
3850 else if (!NILP (Vcoding_system_for_write)) | 3817 else if (!NILP (Vcoding_system_for_write)) |
3851 val = Vcoding_system_for_write; | 3818 val = Vcoding_system_for_write; |
3852 else if (!NILP (Flocal_variable_if_set_p (Qbuffer_file_coding_system, | 3819 else if (!NILP (Flocal_variable_if_set_p (Qbuffer_file_coding_system, |
3853 Qnil))) | 3820 Qnil))) |
3854 val = Fsymbol_value (Qbuffer_file_coding_system); | 3821 val = Fsymbol_value (Qbuffer_file_coding_system); |
3870 #ifdef DOS_NT | 3837 #ifdef DOS_NT |
3871 if (!NILP (current_buffer->buffer_file_type)) | 3838 if (!NILP (current_buffer->buffer_file_type)) |
3872 coding.eol_type = CODING_EOL_LF; | 3839 coding.eol_type = CODING_EOL_LF; |
3873 #endif /* DOS_NT */ | 3840 #endif /* DOS_NT */ |
3874 } | 3841 } |
3842 | |
3843 filename = Fexpand_file_name (filename, Qnil); | |
3844 if (STRINGP (visit)) | |
3845 visit_file = Fexpand_file_name (visit, Qnil); | |
3846 else | |
3847 visit_file = filename; | |
3848 UNGCPRO; | |
3849 | |
3850 visiting = (EQ (visit, Qt) || STRINGP (visit)); | |
3851 quietly = !NILP (visit); | |
3852 | |
3853 annotations = Qnil; | |
3854 | |
3855 if (NILP (lockname)) | |
3856 lockname = visit_file; | |
3857 | |
3858 GCPRO5 (start, filename, annotations, visit_file, lockname); | |
3859 | |
3860 /* If the file name has special constructs in it, | |
3861 call the corresponding file handler. */ | |
3862 handler = Ffind_file_name_handler (filename, Qwrite_region); | |
3863 /* If FILENAME has no handler, see if VISIT has one. */ | |
3864 if (NILP (handler) && STRINGP (visit)) | |
3865 handler = Ffind_file_name_handler (visit, Qwrite_region); | |
3866 | |
3867 if (!NILP (handler)) | |
3868 { | |
3869 Lisp_Object val; | |
3870 val = call6 (handler, Qwrite_region, start, end, | |
3871 filename, append, visit); | |
3872 | |
3873 if (visiting) | |
3874 { | |
3875 SAVE_MODIFF = MODIFF; | |
3876 XSETFASTINT (current_buffer->save_length, Z - BEG); | |
3877 current_buffer->filename = visit_file; | |
3878 } | |
3879 UNGCPRO; | |
3880 return val; | |
3881 } | |
3875 | 3882 |
3876 /* Special kludge to simplify auto-saving. */ | 3883 /* Special kludge to simplify auto-saving. */ |
3877 if (NILP (start)) | 3884 if (NILP (start)) |
3878 { | 3885 { |
3879 XSETFASTINT (start, BEG); | 3886 XSETFASTINT (start, BEG); |
4007 * | 4014 * |
4008 * Yech! | 4015 * Yech! |
4009 */ | 4016 */ |
4010 if (GPT > BEG && GPT_ADDR[-1] != '\n') | 4017 if (GPT > BEG && GPT_ADDR[-1] != '\n') |
4011 move_gap (find_next_newline (GPT, 1)); | 4018 move_gap (find_next_newline (GPT, 1)); |
4019 #else | |
4020 /* Whether VMS or not, we must move the gap to the next of newline | |
4021 when we must put designation sequences at beginning of line. */ | |
4022 if (INTEGERP (start) | |
4023 && coding.type == coding_type_iso2022 | |
4024 && coding.flags & CODING_FLAG_ISO_DESIGNATE_AT_BOL | |
4025 && GPT > BEG && GPT_ADDR[-1] != '\n') | |
4026 move_gap (find_next_newline (GPT, 1)); | |
4012 #endif | 4027 #endif |
4013 | 4028 |
4014 failure = 0; | 4029 failure = 0; |
4015 immediate_quit = 1; | 4030 immediate_quit = 1; |
4016 | 4031 |
4045 } | 4060 } |
4046 } | 4061 } |
4047 else | 4062 else |
4048 { | 4063 { |
4049 /* If file was empty, still need to write the annotations */ | 4064 /* If file was empty, still need to write the annotations */ |
4065 coding.last_block = 1; | |
4050 failure = 0 > a_write (desc, "", 0, XINT (start), &annotations, &coding); | 4066 failure = 0 > a_write (desc, "", 0, XINT (start), &annotations, &coding); |
4051 save_errno = errno; | 4067 save_errno = errno; |
4052 } | 4068 } |
4053 | 4069 |
4054 if (coding.require_flushing) | 4070 if (coding.require_flushing) |
4225 if (!NILP (pre_write_conversion)) | 4241 if (!NILP (pre_write_conversion)) |
4226 { | 4242 { |
4227 struct buffer *given_buffer = current_buffer; | 4243 struct buffer *given_buffer = current_buffer; |
4228 Vwrite_region_annotations_so_far = annotations; | 4244 Vwrite_region_annotations_so_far = annotations; |
4229 res = call2 (pre_write_conversion, start, end); | 4245 res = call2 (pre_write_conversion, start, end); |
4230 if (current_buffer != given_buffer) | |
4231 { | |
4232 start = BEGV; | |
4233 end = ZV; | |
4234 annotations = Qnil; | |
4235 } | |
4236 Flength (res); | 4246 Flength (res); |
4237 annotations = merge (annotations, res, Qcar_less_than_car); | 4247 annotations = (current_buffer != given_buffer |
4248 ? res | |
4249 : merge (annotations, res, Qcar_less_than_car)); | |
4238 } | 4250 } |
4239 | 4251 |
4240 UNGCPRO; | 4252 UNGCPRO; |
4241 return annotations; | 4253 return annotations; |
4242 } | 4254 } |
4307 while (1) | 4319 while (1) |
4308 { | 4320 { |
4309 produced = encode_coding (coding, addr, buf, len, WRITE_BUF_SIZE, | 4321 produced = encode_coding (coding, addr, buf, len, WRITE_BUF_SIZE, |
4310 &consumed); | 4322 &consumed); |
4311 len -= consumed, addr += consumed; | 4323 len -= consumed, addr += consumed; |
4312 if (produced == 0 && len > 0) | |
4313 { | |
4314 /* There was a carry over because of invalid codes in the source. | |
4315 We just write out them as is. */ | |
4316 bcopy (addr, buf, len); | |
4317 produced = len; | |
4318 len = 0; | |
4319 } | |
4320 if (produced > 0) | 4324 if (produced > 0) |
4321 { | 4325 { |
4322 produced -= write (desc, buf, produced); | 4326 produced -= write (desc, buf, produced); |
4323 if (produced) return -1; | 4327 if (produced) return -1; |
4324 } | 4328 } |
4451 auto_save_mode_bits = 0666; | 4455 auto_save_mode_bits = 0666; |
4452 | 4456 |
4453 return | 4457 return |
4454 Fwrite_region (Qnil, Qnil, | 4458 Fwrite_region (Qnil, Qnil, |
4455 current_buffer->auto_save_file_name, | 4459 current_buffer->auto_save_file_name, |
4456 Qnil, Qlambda, Qnil); | 4460 Qnil, Qlambda, Qnil, Qnil); |
4457 } | 4461 } |
4458 | 4462 |
4459 static Lisp_Object | 4463 static Lisp_Object |
4460 do_auto_save_unwind (desc) /* used as unwind-protect function */ | 4464 do_auto_save_unwind (desc) /* used as unwind-protect function */ |
4461 Lisp_Object desc; | 4465 Lisp_Object desc; |