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;