Mercurial > emacs
comparison src/fileio.c @ 20713:bab57112b50e
(Finsert_file_contents): Even if
enable-multibyte-characters is nil, we must check `coding:' tag
and `file-coding-system-alist' to handle eol-conversion.
(Finsert_file_contents): Adjusted for the change of
struct coding_system and function decode_coding. For normail file
reading, use code_convert_region.
(Fwrite_region): Adjusted for the change of struct coding_system.
(e_write): Adjusted for the change of encode_coding.
author | Kenichi Handa <handa@m17n.org> |
---|---|
date | Thu, 22 Jan 1998 01:26:45 +0000 |
parents | 48745ae8daa0 |
children | 2e68ae1d1928 |
comparison
equal
deleted
inserted
replaced
20712:50255c536f0f | 20713:bab57112b50e |
---|---|
3141 Lisp_Object filename, visit, beg, end, replace; | 3141 Lisp_Object filename, visit, beg, end, replace; |
3142 { | 3142 { |
3143 struct stat st; | 3143 struct stat st; |
3144 register int fd; | 3144 register int fd; |
3145 int inserted = 0; | 3145 int inserted = 0; |
3146 int inserted_chars = 0; | |
3147 register int how_much; | 3146 register int how_much; |
3148 register int unprocessed; | 3147 register int unprocessed; |
3149 int count = specpdl_ptr - specpdl; | 3148 int count = specpdl_ptr - specpdl; |
3150 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; | 3149 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; |
3151 Lisp_Object handler, val, insval, orig_filename; | 3150 Lisp_Object handler, val, insval, orig_filename; |
3263 { | 3262 { |
3264 Lisp_Object val = Qnil; | 3263 Lisp_Object val = Qnil; |
3265 | 3264 |
3266 if (!NILP (Vcoding_system_for_read)) | 3265 if (!NILP (Vcoding_system_for_read)) |
3267 val = Vcoding_system_for_read; | 3266 val = Vcoding_system_for_read; |
3268 else if (NILP (current_buffer->enable_multibyte_characters)) | |
3269 val = Qemacs_mule; | |
3270 else | 3267 else |
3271 { | 3268 { |
3272 if (! NILP (Vset_auto_coding_function)) | 3269 if (! NILP (Vset_auto_coding_function)) |
3273 { | 3270 { |
3274 /* Find a coding system specified in the heading two lines | 3271 /* Find a coding system specified in the heading two lines |
3315 args[2] = visit, args[3] = beg, args[4] = end, args[5] = replace; | 3312 args[2] = visit, args[3] = beg, args[4] = end, args[5] = replace; |
3316 coding_systems = Ffind_operation_coding_system (6, args); | 3313 coding_systems = Ffind_operation_coding_system (6, args); |
3317 if (CONSP (coding_systems)) val = XCONS (coding_systems)->car; | 3314 if (CONSP (coding_systems)) val = XCONS (coding_systems)->car; |
3318 } | 3315 } |
3319 } | 3316 } |
3320 setup_coding_system (Fcheck_coding_system (val), &coding); | 3317 |
3318 if (NILP (Vcoding_system_for_read) | |
3319 && NILP (current_buffer->enable_multibyte_characters)) | |
3320 { | |
3321 /* We must suppress all text conversion except for end-of-line | |
3322 conversion. */ | |
3323 struct coding_system coding_temp; | |
3324 | |
3325 setup_coding_system (Fcheck_coding_system (val), &coding_temp); | |
3326 setup_coding_system (Qraw_text, &coding); | |
3327 coding.eol_type = coding_temp.eol_type; | |
3328 } | |
3329 else | |
3330 setup_coding_system (Fcheck_coding_system (val), &coding); | |
3321 } | 3331 } |
3322 | 3332 |
3323 /* If requested, replace the accessible part of the buffer | 3333 /* If requested, replace the accessible part of the buffer |
3324 with the file contents. Avoid replacing text at the | 3334 with the file contents. Avoid replacing text at the |
3325 beginning or end of the buffer that matches the file contents; | 3335 beginning or end of the buffer that matches the file contents; |
3456 /* If this discrepancy is because of code conversion, | 3466 /* If this discrepancy is because of code conversion, |
3457 we cannot use this method; giveup and try the other. */ | 3467 we cannot use this method; giveup and try the other. */ |
3458 if (same_at_end > same_at_start | 3468 if (same_at_end > same_at_start |
3459 && FETCH_BYTE (same_at_end - 1) >= 0200 | 3469 && FETCH_BYTE (same_at_end - 1) >= 0200 |
3460 && ! NILP (current_buffer->enable_multibyte_characters) | 3470 && ! NILP (current_buffer->enable_multibyte_characters) |
3461 && (CODING_REQUIRE_DECODING (&coding) | 3471 && (CODING_MAY_REQUIRE_DECODING (&coding))) |
3462 || CODING_REQUIRE_DETECTION (&coding))) | |
3463 giveup_match_end = 1; | 3472 giveup_match_end = 1; |
3464 break; | 3473 break; |
3465 } | 3474 } |
3466 } | 3475 } |
3467 immediate_quit = 0; | 3476 immediate_quit = 0; |
3557 break; | 3566 break; |
3558 } | 3567 } |
3559 | 3568 |
3560 how_much += this; | 3569 how_much += this; |
3561 | 3570 |
3562 if (CODING_REQUIRE_DECODING (&coding) | 3571 if (CODING_MAY_REQUIRE_DECODING (&coding)) |
3563 || CODING_REQUIRE_DETECTION (&coding)) | |
3564 { | 3572 { |
3565 int require, produced, consumed; | 3573 int require, result; |
3566 | 3574 |
3567 this += unprocessed; | 3575 this += unprocessed; |
3568 | 3576 |
3569 /* If we are using more space than estimated, | 3577 /* If we are using more space than estimated, |
3570 make CONVERSION_BUFFER bigger. */ | 3578 make CONVERSION_BUFFER bigger. */ |
3575 conversion_buffer = (unsigned char *) xrealloc (conversion_buffer, bufsize); | 3583 conversion_buffer = (unsigned char *) xrealloc (conversion_buffer, bufsize); |
3576 } | 3584 } |
3577 | 3585 |
3578 /* Convert this batch with results in CONVERSION_BUFFER. */ | 3586 /* Convert this batch with results in CONVERSION_BUFFER. */ |
3579 if (how_much >= total) /* This is the last block. */ | 3587 if (how_much >= total) /* This is the last block. */ |
3580 coding.last_block = 1; | 3588 coding.mode |= CODING_MODE_LAST_BLOCK; |
3581 produced = decode_coding (&coding, read_buf, | 3589 result = decode_coding (&coding, read_buf, |
3582 conversion_buffer + inserted, | 3590 conversion_buffer + inserted, |
3583 this, bufsize - inserted, | 3591 this, bufsize - inserted); |
3584 &consumed); | |
3585 | 3592 |
3586 /* Save for next iteration whatever we didn't convert. */ | 3593 /* Save for next iteration whatever we didn't convert. */ |
3587 unprocessed = this - consumed; | 3594 unprocessed = this - coding.consumed; |
3588 bcopy (read_buf + consumed, read_buf, unprocessed); | 3595 bcopy (read_buf + coding.consumed, read_buf, unprocessed); |
3589 this = produced; | 3596 this = coding.produced; |
3590 } | 3597 } |
3591 | 3598 |
3592 inserted += this; | 3599 inserted += this; |
3593 } | 3600 } |
3594 | 3601 |
3595 /* At this point, INSERTED is how many characters | 3602 /* At this point, INSERTED is how many characters (i.e. bytes) |
3596 are present in CONVERSION_BUFFER. | 3603 are present in CONVERSION_BUFFER. |
3597 HOW_MUCH should equal TOTAL, | 3604 HOW_MUCH should equal TOTAL, |
3598 or should be <= 0 if we couldn't read the file. */ | 3605 or should be <= 0 if we couldn't read the file. */ |
3599 | 3606 |
3600 if (how_much < 0) | 3607 if (how_much < 0) |
3694 report_file_error ("Setting file position", | 3701 report_file_error ("Setting file position", |
3695 Fcons (orig_filename, Qnil)); | 3702 Fcons (orig_filename, Qnil)); |
3696 } | 3703 } |
3697 | 3704 |
3698 /* In the following loop, HOW_MUCH contains the total bytes read so | 3705 /* In the following loop, HOW_MUCH contains the total bytes read so |
3699 far. Before exiting the loop, it is set to -1 if I/O error | 3706 far for a regular file, and not changed for a special file. But, |
3700 occurs, set to -2 if the maximum buffer size is exceeded. */ | 3707 before exiting the loop, it is set to a negative value if I/O |
3708 error occurs. */ | |
3701 how_much = 0; | 3709 how_much = 0; |
3702 /* Total bytes inserted. */ | 3710 /* Total bytes inserted. */ |
3703 inserted = 0; | 3711 inserted = 0; |
3704 /* Bytes not processed in the previous loop because short gap size. */ | 3712 /* Here, we don't do code conversion in the loop. It is done by |
3705 unprocessed = 0; | 3713 code_convert_region after all data are read into the buffer. */ |
3706 while (how_much < total) | 3714 while (how_much < total) |
3707 { | 3715 { |
3708 /* try is reserved in some compilers (Microsoft C) */ | 3716 /* try is reserved in some compilers (Microsoft C) */ |
3709 int trytry = min (total - how_much, READ_BUF_SIZE - unprocessed); | 3717 int trytry = min (total - how_much, READ_BUF_SIZE); |
3710 char *destination = (! (CODING_REQUIRE_DECODING (&coding) | 3718 int this; |
3711 || CODING_REQUIRE_DETECTION (&coding)) | 3719 |
3712 ? (char *) (BYTE_POS_ADDR (PT_BYTE + inserted - 1) + 1) | 3720 /* For a special file, GAP_SIZE should be checked every time. */ |
3713 : read_buf + unprocessed); | 3721 if (not_regular && GAP_SIZE < trytry) |
3714 int this, this_chars; | 3722 make_gap (total - GAP_SIZE); |
3715 | 3723 |
3716 /* Allow quitting out of the actual I/O. */ | 3724 /* Allow quitting out of the actual I/O. */ |
3717 immediate_quit = 1; | 3725 immediate_quit = 1; |
3718 QUIT; | 3726 QUIT; |
3719 this = read (fd, destination, trytry); | 3727 this = read (fd, BYTE_POS_ADDR (PT + inserted - 1) + 1, trytry); |
3720 immediate_quit = 0; | 3728 immediate_quit = 0; |
3721 | 3729 |
3722 if (this < 0 || this + unprocessed == 0) | 3730 if (this <= 0) |
3723 { | 3731 { |
3724 how_much = this; | 3732 how_much = this; |
3725 break; | 3733 break; |
3726 } | 3734 } |
3735 | |
3736 GAP_SIZE -= this; | |
3737 GPT_BYTE += this; | |
3738 ZV_BYTE += this; | |
3739 Z_BYTE += this; | |
3740 GPT += this; | |
3741 ZV += this; | |
3742 Z += this; | |
3727 | 3743 |
3728 /* For a regular file, where TOTAL is the real size, | 3744 /* For a regular file, where TOTAL is the real size, |
3729 count HOW_MUCH to compare with it. | 3745 count HOW_MUCH to compare with it. |
3730 For a special file, where TOTAL is just a buffer size, | 3746 For a special file, where TOTAL is just a buffer size, |
3731 so don't bother counting in HOW_MUCH. | 3747 so don't bother counting in HOW_MUCH. |
3732 (INSERTED is where we count the number of characters inserted.) */ | 3748 (INSERTED is where we count the number of characters inserted.) */ |
3733 if (! not_regular) | 3749 if (! not_regular) |
3734 how_much += this; | 3750 how_much += this; |
3735 | 3751 inserted += this; |
3736 if (CODING_REQUIRE_DECODING (&coding) | 3752 } |
3737 || CODING_REQUIRE_DETECTION (&coding)) | 3753 |
3738 { | 3754 if (GAP_SIZE > 0) |
3739 int require, produced, consumed; | 3755 /* Put an anchor to ensure multi-byte form ends at gap. */ |
3740 | 3756 *GPT_ADDR = 0; |
3741 this += unprocessed; | 3757 |
3742 /* Make sure that the gap is large enough. */ | 3758 close (fd); |
3743 require = decoding_buffer_size (&coding, this); | 3759 |
3744 if (GAP_SIZE < require) | 3760 /* Discard the unwind protect for closing the file. */ |
3745 make_gap (require - GAP_SIZE); | 3761 specpdl_ptr--; |
3746 | 3762 |
3747 if (! not_regular) | 3763 if (how_much < 0) |
3748 { | 3764 error ("IO error reading %s: %s", |
3749 if (how_much >= total) /* This is the last block. */ | 3765 XSTRING (orig_filename)->data, strerror (errno)); |
3750 coding.last_block = 1; | 3766 |
3751 } | 3767 if (inserted > 0) |
3752 else | 3768 { |
3753 { | 3769 if (CODING_MAY_REQUIRE_DECODING (&coding)) |
3754 /* If we encounter EOF, say it is the last block. (The | 3770 inserted = code_convert_region (PT, PT + inserted, &coding, 0, 0); |
3755 data this will apply to is the UNPROCESSED characters | 3771 |
3756 carried over from the last batch.) */ | 3772 #ifdef DOS_NT |
3757 if (this == 0) | 3773 /* Use the conversion type to determine buffer-file-type |
3758 coding.last_block = 1; | 3774 (find-buffer-file-type is now used to help determine the |
3759 } | 3775 conversion). */ |
3760 | 3776 if (coding.eol_type != CODING_EOL_UNDECIDED |
3761 produced = decode_coding (&coding, read_buf, | 3777 && coding.eol_type != CODING_EOL_LF) |
3762 BYTE_POS_ADDR (PT_BYTE + inserted - 1) + 1, | 3778 current_buffer->buffer_file_type = Qnil; |
3763 this, GAP_SIZE, &consumed); | |
3764 if (produced > 0) | |
3765 { | |
3766 Lisp_Object temp; | |
3767 | |
3768 XSET (temp, Lisp_Int, Z_BYTE + produced); | |
3769 if (Z_BYTE + produced != XINT (temp)) | |
3770 { | |
3771 how_much = -2; | |
3772 break; | |
3773 } | |
3774 } | |
3775 unprocessed = this - consumed; | |
3776 bcopy (read_buf + consumed, read_buf, unprocessed); | |
3777 this = produced; | |
3778 this_chars = chars_in_text (BYTE_POS_ADDR (PT_BYTE + inserted - 1) + 1, | |
3779 produced); | |
3780 } | |
3781 else if (! NILP (current_buffer->enable_multibyte_characters)) | |
3782 this_chars = chars_in_text (BYTE_POS_ADDR (PT_BYTE + inserted - 1) + 1, | |
3783 this); | |
3784 else | 3779 else |
3785 this_chars = this; | 3780 current_buffer->buffer_file_type = Qt; |
3786 | 3781 #endif |
3787 GAP_SIZE -= this; | 3782 |
3788 GPT_BYTE += this; | |
3789 ZV_BYTE += this; | |
3790 Z_BYTE += this; | |
3791 GPT += this_chars; | |
3792 ZV += this_chars; | |
3793 Z += this_chars; | |
3794 | |
3795 if (GAP_SIZE > 0) | |
3796 /* Put an anchor to ensure multi-byte form ends at gap. */ | |
3797 *GPT_ADDR = 0; | |
3798 inserted += this; | |
3799 inserted_chars += this_chars; | |
3800 } | |
3801 | |
3802 #ifdef DOS_NT | |
3803 /* Use the conversion type to determine buffer-file-type | |
3804 (find-buffer-file-type is now used to help determine the | |
3805 conversion). */ | |
3806 if (coding.eol_type != CODING_EOL_UNDECIDED | |
3807 && coding.eol_type != CODING_EOL_LF) | |
3808 current_buffer->buffer_file_type = Qnil; | |
3809 else | |
3810 current_buffer->buffer_file_type = Qt; | |
3811 #endif | |
3812 | |
3813 if (inserted > 0) | |
3814 { | |
3815 record_insert (PT, inserted_chars); | 3783 record_insert (PT, inserted_chars); |
3816 | 3784 |
3817 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */ | 3785 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */ |
3818 offset_intervals (current_buffer, PT, inserted_chars); | 3786 offset_intervals (current_buffer, PT, inserted_chars); |
3819 MODIFF++; | 3787 MODIFF++; |
3820 } | 3788 |
3821 | 3789 if (! NILP (coding.post_read_conversion)) |
3822 close (fd); | 3790 { |
3823 | 3791 Lisp_Object val; |
3824 /* Discard the unwind protect for closing the file. */ | 3792 |
3825 specpdl_ptr--; | 3793 val = call1 (coding.post_read_conversion, make_number (inserted)); |
3826 | 3794 if (!NILP (val)) |
3827 if (how_much == -1) | 3795 { |
3828 error ("IO error reading %s: %s", | 3796 CHECK_NUMBER (val, 0); |
3829 XSTRING (orig_filename)->data, strerror (errno)); | 3797 inserted = XFASTINT (val); |
3830 else if (how_much == -2) | 3798 } |
3831 error ("Maximum buffer size exceeded"); | 3799 } |
3800 } | |
3832 | 3801 |
3833 set_coding_system = 1; | 3802 set_coding_system = 1; |
3834 | 3803 |
3835 notfound: | 3804 notfound: |
3836 handled: | 3805 handled: |
3869 if (current_buffer->modtime == -1) | 3838 if (current_buffer->modtime == -1) |
3870 report_file_error ("Opening input file", Fcons (orig_filename, Qnil)); | 3839 report_file_error ("Opening input file", Fcons (orig_filename, Qnil)); |
3871 } | 3840 } |
3872 | 3841 |
3873 /* Decode file format */ | 3842 /* Decode file format */ |
3874 if (inserted_chars > 0) | 3843 if (inserted > 0) |
3875 { | 3844 { |
3876 insval = call3 (Qformat_decode, | 3845 insval = call3 (Qformat_decode, |
3877 Qnil, make_number (inserted_chars), visit); | 3846 Qnil, make_number (inserted), visit); |
3878 CHECK_NUMBER (insval, 0); | 3847 CHECK_NUMBER (insval, 0); |
3879 inserted_chars = XFASTINT (insval); | 3848 inserted = XFASTINT (insval); |
3880 } | 3849 } |
3881 | 3850 |
3882 /* Call after-change hooks for the inserted text, aside from the case | 3851 /* Call after-change hooks for the inserted text, aside from the case |
3883 of normal visiting (not with REPLACE), which is done in a new buffer | 3852 of normal visiting (not with REPLACE), which is done in a new buffer |
3884 "before" the buffer is changed. */ | 3853 "before" the buffer is changed. */ |
3885 if (inserted_chars > 0 && total > 0 | 3854 if (inserted > 0 && total > 0 |
3886 && (NILP (visit) || !NILP (replace))) | 3855 && (NILP (visit) || !NILP (replace))) |
3887 signal_after_change (PT, 0, inserted_chars); | 3856 signal_after_change (PT, 0, inserted); |
3888 | 3857 |
3889 if (set_coding_system) | 3858 if (set_coding_system) |
3890 Vlast_coding_system_used = coding.symbol; | 3859 Vlast_coding_system_used = coding.symbol; |
3891 | 3860 |
3892 if (inserted > 0) | 3861 if (inserted > 0) |
3893 { | 3862 { |
3894 p = Vafter_insert_file_functions; | 3863 p = Vafter_insert_file_functions; |
3895 if (!NILP (coding.post_read_conversion)) | |
3896 p = Fcons (coding.post_read_conversion, p); | |
3897 | |
3898 while (!NILP (p)) | 3864 while (!NILP (p)) |
3899 { | 3865 { |
3900 insval = call1 (Fcar (p), make_number (inserted_chars)); | 3866 insval = call1 (Fcar (p), make_number (inserted)); |
3901 if (!NILP (insval)) | 3867 if (!NILP (insval)) |
3902 { | 3868 { |
3903 CHECK_NUMBER (insval, 0); | 3869 CHECK_NUMBER (insval, 0); |
3904 inserted_chars = XFASTINT (insval); | 3870 inserted = XFASTINT (insval); |
3905 } | 3871 } |
3906 QUIT; | 3872 QUIT; |
3907 p = Fcdr (p); | 3873 p = Fcdr (p); |
3908 } | 3874 } |
3909 } | 3875 } |
4008 it means that the file was read with some kind of code | 3974 it means that the file was read with some kind of code |
4009 conversion or the varialbe is explicitely set by users. We | 3975 conversion or the varialbe is explicitely set by users. We |
4010 had better write it out with the same coding system even if | 3976 had better write it out with the same coding system even if |
4011 `enable-multibyte-characters' is nil. | 3977 `enable-multibyte-characters' is nil. |
4012 | 3978 |
4013 If is is not set locally, we anyway have to convert EOL | 3979 If it is not set locally, we anyway have to convert EOL |
4014 format if the default value of `buffer-file-coding-system' | 3980 format if the default value of `buffer-file-coding-system' |
4015 tells that it is not Unix-like (LF only) format. */ | 3981 tells that it is not Unix-like (LF only) format. */ |
4016 val = current_buffer->buffer_file_coding_system; | 3982 val = current_buffer->buffer_file_coding_system; |
4017 if (NILP (Flocal_variable_p (Qbuffer_file_coding_system, Qnil))) | 3983 if (NILP (Flocal_variable_p (Qbuffer_file_coding_system, Qnil))) |
4018 { | 3984 { |
4020 | 3986 |
4021 setup_coding_system (Fcheck_coding_system (val), &coding_temp); | 3987 setup_coding_system (Fcheck_coding_system (val), &coding_temp); |
4022 if (coding_temp.eol_type == CODING_EOL_CRLF | 3988 if (coding_temp.eol_type == CODING_EOL_CRLF |
4023 || coding_temp.eol_type == CODING_EOL_CR) | 3989 || coding_temp.eol_type == CODING_EOL_CR) |
4024 { | 3990 { |
4025 setup_coding_system (Qemacs_mule, &coding); | 3991 setup_coding_system (Qraw_text, &coding); |
4026 coding.eol_type = coding_temp.eol_type; | 3992 coding.eol_type = coding_temp.eol_type; |
4027 goto done_setup_coding; | 3993 goto done_setup_coding; |
4028 } | 3994 } |
4029 val = Qnil; | 3995 val = Qnil; |
4030 } | 3996 } |
4031 } | 3997 } |
4032 else | 3998 else |
4033 { | 3999 { |
4034 Lisp_Object args[7], coding_systems; | 4000 Lisp_Object args[7], coding_systems; |
4035 | 4001 |
4036 args[0] = Qwrite_region, args[1] = start, args[2] = end, | 4002 args[0] = Qwrite_region; args[1] = start; args[2] = end; |
4037 args[3] = filename, args[4] = append, args[5] = visit, | 4003 args[3] = filename; args[4] = append; args[5] = visit; |
4038 args[6] = lockname; | 4004 args[6] = lockname; |
4039 coding_systems = Ffind_operation_coding_system (7, args); | 4005 coding_systems = Ffind_operation_coding_system (7, args); |
4040 val = (CONSP (coding_systems) && !NILP (XCONS (coding_systems)->cdr) | 4006 val = (CONSP (coding_systems) && !NILP (XCONS (coding_systems)->cdr) |
4041 ? XCONS (coding_systems)->cdr | 4007 ? XCONS (coding_systems)->cdr |
4042 : current_buffer->buffer_file_coding_system); | 4008 : current_buffer->buffer_file_coding_system); |
4009 /* Confirm that VAL can surely encode the current region. */ | |
4010 if (Ffboundp (Vselect_safe_coding_system_function)) | |
4011 val = call3 (Vselect_safe_coding_system_function, start, end, val); | |
4043 } | 4012 } |
4044 setup_coding_system (Fcheck_coding_system (val), &coding); | 4013 setup_coding_system (Fcheck_coding_system (val), &coding); |
4045 | 4014 |
4046 done_setup_coding: | 4015 done_setup_coding: |
4047 if (!STRINGP (start) && !NILP (current_buffer->selective_display)) | 4016 if (!STRINGP (start) && !NILP (current_buffer->selective_display)) |
4048 coding.selective = 1; | 4017 coding.mode |= CODING_MODE_SELECTIVE_DISPLAY; |
4049 } | 4018 } |
4050 | 4019 |
4051 Vlast_coding_system_used = coding.symbol; | 4020 Vlast_coding_system_used = coding.symbol; |
4052 | 4021 |
4053 filename = Fexpand_file_name (filename, Qnil); | 4022 filename = Fexpand_file_name (filename, Qnil); |
4277 } | 4246 } |
4278 } | 4247 } |
4279 else | 4248 else |
4280 { | 4249 { |
4281 /* If file was empty, still need to write the annotations */ | 4250 /* If file was empty, still need to write the annotations */ |
4282 coding.last_block = 1; | 4251 coding.mode |= CODING_MODE_LAST_BLOCK; |
4283 failure = 0 > a_write (desc, "", 0, XINT (start), &annotations, &coding); | 4252 failure = 0 > a_write (desc, "", 0, XINT (start), &annotations, &coding); |
4284 save_errno = errno; | 4253 save_errno = errno; |
4285 } | 4254 } |
4286 | 4255 |
4287 if (CODING_REQUIRE_FLUSHING (&coding) && !coding.last_block | 4256 if (CODING_REQUIRE_FLUSHING (&coding) |
4257 && !(coding.mode & CODING_MODE_LAST_BLOCK) | |
4288 && ! failure) | 4258 && ! failure) |
4289 { | 4259 { |
4290 /* We have to flush out a data. */ | 4260 /* We have to flush out a data. */ |
4291 coding.last_block = 1; | 4261 coding.mode |= CODING_MODE_LAST_BLOCK; |
4292 failure = 0 > e_write (desc, "", 0, &coding); | 4262 failure = 0 > e_write (desc, "", 0, &coding); |
4293 save_errno = errno; | 4263 save_errno = errno; |
4294 } | 4264 } |
4295 | 4265 |
4296 immediate_quit = 0; | 4266 immediate_quit = 0; |
4540 register char *addr; | 4510 register char *addr; |
4541 register int nbytes; | 4511 register int nbytes; |
4542 struct coding_system *coding; | 4512 struct coding_system *coding; |
4543 { | 4513 { |
4544 char buf[WRITE_BUF_SIZE]; | 4514 char buf[WRITE_BUF_SIZE]; |
4545 int produced, consumed; | |
4546 | 4515 |
4547 /* We used to have a code for handling selective display here. But, | 4516 /* We used to have a code for handling selective display here. But, |
4548 now it is handled within encode_coding. */ | 4517 now it is handled within encode_coding. */ |
4549 while (1) | 4518 while (1) |
4550 { | 4519 { |
4551 produced = encode_coding (coding, addr, buf, nbytes, WRITE_BUF_SIZE, | 4520 encode_coding (coding, addr, buf, nbytes, WRITE_BUF_SIZE); |
4552 &consumed); | 4521 nbytes -= coding->consumed, addr += coding->consumed; |
4553 nbytes -= consumed, addr += consumed; | 4522 if (coding->produced > 0) |
4554 if (produced > 0) | 4523 { |
4555 { | 4524 coding->produced -= write (desc, buf, coding->produced); |
4556 produced -= write (desc, buf, produced); | 4525 if (coding->produced) return -1; |
4557 if (produced) return -1; | |
4558 } | 4526 } |
4559 if (nbytes <= 0) | 4527 if (nbytes <= 0) |
4560 break; | 4528 break; |
4561 } | 4529 } |
4562 return 0; | 4530 return 0; |