diff options
| author | Richard M. Stallman | 1997-12-31 22:16:35 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1997-12-31 22:16:35 +0000 |
| commit | ec7adf2664746ff3bb20c012f685451b9607ef42 (patch) | |
| tree | 57e1ff957b06d1c858ee9daa473b4c2922a8de1d /src | |
| parent | a9c26562b3d0790b1dadf242d8ad3b10bbafe381 (diff) | |
| download | emacs-ec7adf2664746ff3bb20c012f685451b9607ef42.tar.gz emacs-ec7adf2664746ff3bb20c012f685451b9607ef42.zip | |
(Finsert_file_contents): Update call to CHAR_HEAD_P.
(Fwrite_region): Use scan_newline.
(restore_point_unwind): Now static. Use Fgoto_char.
(Funhandled_file_name_directory): Doc fix.
(Finsert_file_contents): Handle bytes vs chars.
(Fwrite_region): Handle bytes vs chars.
(a_write): Take args in bytes; handle annotations labeled in chars.
(e_write): Rename args.
(Funhandled_file_name_directory): Doc fix.
(a_write, e_write): Now static.
Diffstat (limited to 'src')
| -rw-r--r-- | src/fileio.c | 231 |
1 files changed, 124 insertions, 107 deletions
diff --git a/src/fileio.c b/src/fileio.c index 2cf1693200c..4d477b19c8e 100644 --- a/src/fileio.c +++ b/src/fileio.c | |||
| @@ -230,6 +230,10 @@ Lisp_Object Qfile_name_history; | |||
| 230 | 230 | ||
| 231 | Lisp_Object Qcar_less_than_car; | 231 | Lisp_Object Qcar_less_than_car; |
| 232 | 232 | ||
| 233 | static int a_write P_ ((int, char *, int, int, | ||
| 234 | Lisp_Object, struct coding_system *)); | ||
| 235 | static int e_write P_ ((int, char *, int, struct coding_system *)); | ||
| 236 | |||
| 233 | void | 237 | void |
| 234 | report_file_error (string, data) | 238 | report_file_error (string, data) |
| 235 | char *string; | 239 | char *string; |
| @@ -259,11 +263,11 @@ close_file_unwind (fd) | |||
| 259 | 263 | ||
| 260 | /* Restore point, having saved it as a marker. */ | 264 | /* Restore point, having saved it as a marker. */ |
| 261 | 265 | ||
| 262 | Lisp_Object | 266 | static Lisp_Object |
| 263 | restore_point_unwind (location) | 267 | restore_point_unwind (location) |
| 264 | Lisp_Object location; | 268 | Lisp_Object location; |
| 265 | { | 269 | { |
| 266 | SET_PT (marker_position (location)); | 270 | Fgoto_char (location); |
| 267 | Fset_marker (location, Qnil, Qnil); | 271 | Fset_marker (location, Qnil, Qnil); |
| 268 | return Qnil; | 272 | return Qnil; |
| 269 | } | 273 | } |
| @@ -449,7 +453,7 @@ DEFUN ("unhandled-file-name-directory", Funhandled_file_name_directory, Sunhandl | |||
| 449 | A `directly usable' directory name is one that may be used without the\n\ | 453 | A `directly usable' directory name is one that may be used without the\n\ |
| 450 | intervention of any file handler.\n\ | 454 | intervention of any file handler.\n\ |
| 451 | If FILENAME is a directly usable file itself, return\n\ | 455 | If FILENAME is a directly usable file itself, return\n\ |
| 452 | (file-name-directory FILENAME).\n\ | 456 | \(file-name-directory FILENAME).\n\ |
| 453 | The `call-process' and `start-process' functions use this function to\n\ | 457 | The `call-process' and `start-process' functions use this function to\n\ |
| 454 | get a current directory to run processes in.") | 458 | get a current directory to run processes in.") |
| 455 | (filename) | 459 | (filename) |
| @@ -3076,13 +3080,14 @@ Lisp_Object Qfind_buffer_file_type; | |||
| 3076 | DEFUN ("insert-file-contents", Finsert_file_contents, Sinsert_file_contents, | 3080 | DEFUN ("insert-file-contents", Finsert_file_contents, Sinsert_file_contents, |
| 3077 | 1, 5, 0, | 3081 | 1, 5, 0, |
| 3078 | "Insert contents of file FILENAME after point.\n\ | 3082 | "Insert contents of file FILENAME after point.\n\ |
| 3079 | Returns list of absolute file name and length of data inserted.\n\ | 3083 | Returns list of absolute file name and number of bytes inserted.\n\ |
| 3080 | If second argument VISIT is non-nil, the buffer's visited filename\n\ | 3084 | If second argument VISIT is non-nil, the buffer's visited filename\n\ |
| 3081 | and last save file modtime are set, and it is marked unmodified.\n\ | 3085 | and last save file modtime are set, and it is marked unmodified.\n\ |
| 3082 | If visiting and the file does not exist, visiting is completed\n\ | 3086 | If visiting and the file does not exist, visiting is completed\n\ |
| 3083 | before the error is signaled.\n\ | 3087 | before the error is signaled.\n\ |
| 3084 | The optional third and fourth arguments BEG and END\n\ | 3088 | The optional third and fourth arguments BEG and END\n\ |
| 3085 | specify what portion of the file to insert.\n\ | 3089 | specify what portion of the file to insert.\n\ |
| 3090 | These arguments count bytes in the file, not characters in the buffer.\n\ | ||
| 3086 | If VISIT is non-nil, BEG and END must be nil.\n\ | 3091 | If VISIT is non-nil, BEG and END must be nil.\n\ |
| 3087 | \n\ | 3092 | \n\ |
| 3088 | If optional fifth argument REPLACE is non-nil,\n\ | 3093 | If optional fifth argument REPLACE is non-nil,\n\ |
| @@ -3101,7 +3106,8 @@ This does code conversion according to the value of\n\ | |||
| 3101 | { | 3106 | { |
| 3102 | struct stat st; | 3107 | struct stat st; |
| 3103 | register int fd; | 3108 | register int fd; |
| 3104 | register int inserted = 0; | 3109 | int inserted = 0; |
| 3110 | int inserted_chars = 0; | ||
| 3105 | register int how_much; | 3111 | register int how_much; |
| 3106 | register int unprocessed; | 3112 | register int unprocessed; |
| 3107 | int count = specpdl_ptr - specpdl; | 3113 | int count = specpdl_ptr - specpdl; |
| @@ -3114,6 +3120,7 @@ This does code conversion according to the value of\n\ | |||
| 3114 | struct coding_system coding; | 3120 | struct coding_system coding; |
| 3115 | unsigned char buffer[1 << 14]; | 3121 | unsigned char buffer[1 << 14]; |
| 3116 | int replace_handled = 0; | 3122 | int replace_handled = 0; |
| 3123 | int set_coding_system = 0; | ||
| 3117 | 3124 | ||
| 3118 | if (current_buffer->base_buffer && ! NILP (visit)) | 3125 | if (current_buffer->base_buffer && ! NILP (visit)) |
| 3119 | error ("Cannot do file visiting in an indirect buffer"); | 3126 | error ("Cannot do file visiting in an indirect buffer"); |
| @@ -3291,8 +3298,11 @@ This does code conversion according to the value of\n\ | |||
| 3291 | if (!NILP (replace) | 3298 | if (!NILP (replace) |
| 3292 | && ! CODING_REQUIRE_DECODING (&coding)) | 3299 | && ! CODING_REQUIRE_DECODING (&coding)) |
| 3293 | { | 3300 | { |
| 3294 | int same_at_start = BEGV; | 3301 | /* same_at_start and same_at_end count bytes, |
| 3295 | int same_at_end = ZV; | 3302 | because file access counts bytes |
| 3303 | and BEG and END count bytes. */ | ||
| 3304 | int same_at_start = BEGV_BYTE; | ||
| 3305 | int same_at_end = ZV_BYTE; | ||
| 3296 | int overlap; | 3306 | int overlap; |
| 3297 | /* There is still a possibility we will find the need to do code | 3307 | /* There is still a possibility we will find the need to do code |
| 3298 | conversion. If that happens, we set this variable to 1 to | 3308 | conversion. If that happens, we set this variable to 1 to |
| @@ -3343,7 +3353,7 @@ This does code conversion according to the value of\n\ | |||
| 3343 | } | 3353 | } |
| 3344 | 3354 | ||
| 3345 | bufpos = 0; | 3355 | bufpos = 0; |
| 3346 | while (bufpos < nread && same_at_start < ZV | 3356 | while (bufpos < nread && same_at_start < ZV_BYTE |
| 3347 | && FETCH_BYTE (same_at_start) == buffer[bufpos]) | 3357 | && FETCH_BYTE (same_at_start) == buffer[bufpos]) |
| 3348 | same_at_start++, bufpos++; | 3358 | same_at_start++, bufpos++; |
| 3349 | /* If we found a discrepancy, stop the scan. | 3359 | /* If we found a discrepancy, stop the scan. |
| @@ -3354,7 +3364,7 @@ This does code conversion according to the value of\n\ | |||
| 3354 | immediate_quit = 0; | 3364 | immediate_quit = 0; |
| 3355 | /* If the file matches the buffer completely, | 3365 | /* If the file matches the buffer completely, |
| 3356 | there's no need to replace anything. */ | 3366 | there's no need to replace anything. */ |
| 3357 | if (same_at_start - BEGV == XINT (end)) | 3367 | if (same_at_start - BEGV_BYTE == XINT (end)) |
| 3358 | { | 3368 | { |
| 3359 | close (fd); | 3369 | close (fd); |
| 3360 | specpdl_ptr--; | 3370 | specpdl_ptr--; |
| @@ -3372,7 +3382,7 @@ This does code conversion according to the value of\n\ | |||
| 3372 | int total_read, nread, bufpos, curpos, trial; | 3382 | int total_read, nread, bufpos, curpos, trial; |
| 3373 | 3383 | ||
| 3374 | /* At what file position are we now scanning? */ | 3384 | /* At what file position are we now scanning? */ |
| 3375 | curpos = XINT (end) - (ZV - same_at_end); | 3385 | curpos = XINT (end) - (ZV_BYTE - same_at_end); |
| 3376 | /* If the entire file matches the buffer tail, stop the scan. */ | 3386 | /* If the entire file matches the buffer tail, stop the scan. */ |
| 3377 | if (curpos == 0) | 3387 | if (curpos == 0) |
| 3378 | break; | 3388 | break; |
| @@ -3419,26 +3429,31 @@ This does code conversion according to the value of\n\ | |||
| 3419 | 3429 | ||
| 3420 | if (! giveup_match_end) | 3430 | if (! giveup_match_end) |
| 3421 | { | 3431 | { |
| 3432 | int temp; | ||
| 3433 | |||
| 3422 | /* We win! We can handle REPLACE the optimized way. */ | 3434 | /* We win! We can handle REPLACE the optimized way. */ |
| 3423 | 3435 | ||
| 3424 | /* Extends the end of non-matching text area to multibyte | 3436 | /* Extends the end of non-matching text area to multibyte |
| 3425 | character boundary. */ | 3437 | character boundary. */ |
| 3426 | if (! NILP (current_buffer->enable_multibyte_characters)) | 3438 | if (! NILP (current_buffer->enable_multibyte_characters)) |
| 3427 | while (same_at_end < ZV && ! CHAR_HEAD_P (POS_ADDR (same_at_end))) | 3439 | while (same_at_end < ZV_BYTE |
| 3440 | && ! CHAR_HEAD_P (FETCH_BYTE (same_at_end))) | ||
| 3428 | same_at_end++; | 3441 | same_at_end++; |
| 3429 | 3442 | ||
| 3430 | /* Don't try to reuse the same piece of text twice. */ | 3443 | /* Don't try to reuse the same piece of text twice. */ |
| 3431 | overlap = same_at_start - BEGV - (same_at_end + st.st_size - ZV); | 3444 | overlap = (same_at_start - BEGV_BYTE |
| 3445 | - (same_at_end + st.st_size - ZV)); | ||
| 3432 | if (overlap > 0) | 3446 | if (overlap > 0) |
| 3433 | same_at_end += overlap; | 3447 | same_at_end += overlap; |
| 3434 | 3448 | ||
| 3435 | /* Arrange to read only the nonmatching middle part of the file. */ | 3449 | /* Arrange to read only the nonmatching middle part of the file. */ |
| 3436 | XSETFASTINT (beg, XINT (beg) + (same_at_start - BEGV)); | 3450 | XSETFASTINT (beg, XINT (beg) + (same_at_start - BEGV_BYTE)); |
| 3437 | XSETFASTINT (end, XINT (end) - (ZV - same_at_end)); | 3451 | XSETFASTINT (end, XINT (end) - (ZV_BYTE - same_at_end)); |
| 3438 | 3452 | ||
| 3439 | del_range_1 (same_at_start, same_at_end, 0); | 3453 | del_range_byte (same_at_start, same_at_end, 0); |
| 3440 | /* Insert from the file at the proper position. */ | 3454 | /* Insert from the file at the proper position. */ |
| 3441 | SET_PT (same_at_start); | 3455 | temp = BYTE_TO_CHAR (same_at_start); |
| 3456 | SET_PT_BOTH (temp, same_at_start); | ||
| 3442 | 3457 | ||
| 3443 | /* If display currently starts at beginning of line, | 3458 | /* If display currently starts at beginning of line, |
| 3444 | keep it that way. */ | 3459 | keep it that way. */ |
| @@ -3460,13 +3475,14 @@ This does code conversion according to the value of\n\ | |||
| 3460 | in a more optimized way. */ | 3475 | in a more optimized way. */ |
| 3461 | if (!NILP (replace) && ! replace_handled) | 3476 | if (!NILP (replace) && ! replace_handled) |
| 3462 | { | 3477 | { |
| 3463 | int same_at_start = BEGV; | 3478 | int same_at_start = BEGV_BYTE; |
| 3464 | int same_at_end = ZV; | 3479 | int same_at_end = ZV_BYTE; |
| 3465 | int overlap; | 3480 | int overlap; |
| 3466 | int bufpos; | 3481 | int bufpos; |
| 3467 | /* Make sure that the gap is large enough. */ | 3482 | /* Make sure that the gap is large enough. */ |
| 3468 | int bufsize = 2 * st.st_size; | 3483 | int bufsize = 2 * st.st_size; |
| 3469 | unsigned char *conversion_buffer = (unsigned char *) xmalloc (bufsize); | 3484 | unsigned char *conversion_buffer = (unsigned char *) xmalloc (bufsize); |
| 3485 | int temp; | ||
| 3470 | 3486 | ||
| 3471 | /* First read the whole file, performing code conversion into | 3487 | /* First read the whole file, performing code conversion into |
| 3472 | CONVERSION_BUFFER. */ | 3488 | CONVERSION_BUFFER. */ |
| @@ -3585,7 +3601,7 @@ This does code conversion according to the value of\n\ | |||
| 3585 | same_at_end--, bufpos--; | 3601 | same_at_end--, bufpos--; |
| 3586 | 3602 | ||
| 3587 | /* Don't try to reuse the same piece of text twice. */ | 3603 | /* Don't try to reuse the same piece of text twice. */ |
| 3588 | overlap = same_at_start - BEGV - (same_at_end + inserted - ZV); | 3604 | overlap = same_at_start - BEGV_BYTE - (same_at_end + inserted - ZV_BYTE); |
| 3589 | if (overlap > 0) | 3605 | if (overlap > 0) |
| 3590 | same_at_end += overlap; | 3606 | same_at_end += overlap; |
| 3591 | 3607 | ||
| @@ -3597,11 +3613,12 @@ This does code conversion according to the value of\n\ | |||
| 3597 | /* Replace the chars that we need to replace, | 3613 | /* Replace the chars that we need to replace, |
| 3598 | and update INSERTED to equal the number of bytes | 3614 | and update INSERTED to equal the number of bytes |
| 3599 | we are taking from the file. */ | 3615 | we are taking from the file. */ |
| 3600 | inserted -= (Z - same_at_end) + (same_at_start - BEG); | 3616 | inserted -= (Z_BYTE - same_at_end) + (same_at_start - BEG_BYTE); |
| 3601 | move_gap (same_at_start); | 3617 | del_range_byte (same_at_start, same_at_end, 0); |
| 3602 | del_range_1 (same_at_start, same_at_end, 0); | 3618 | SET_PT_BOTH (GPT, GPT_BYTE); |
| 3603 | SET_PT (same_at_start); | 3619 | |
| 3604 | insert_1 (conversion_buffer + same_at_start - BEG, inserted, 0, 0); | 3620 | insert_1 (conversion_buffer + same_at_start - BEG_BYTE, inserted, |
| 3621 | 0, 0, 0); | ||
| 3605 | 3622 | ||
| 3606 | free (conversion_buffer); | 3623 | free (conversion_buffer); |
| 3607 | close (fd); | 3624 | close (fd); |
| @@ -3653,9 +3670,9 @@ This does code conversion according to the value of\n\ | |||
| 3653 | int trytry = min (total - how_much, READ_BUF_SIZE - unprocessed); | 3670 | int trytry = min (total - how_much, READ_BUF_SIZE - unprocessed); |
| 3654 | char *destination = (! (CODING_REQUIRE_DECODING (&coding) | 3671 | char *destination = (! (CODING_REQUIRE_DECODING (&coding) |
| 3655 | || CODING_REQUIRE_DETECTION (&coding)) | 3672 | || CODING_REQUIRE_DETECTION (&coding)) |
| 3656 | ? (char *) (POS_ADDR (PT + inserted - 1) + 1) | 3673 | ? (char *) (BYTE_POS_ADDR (PT_BYTE + inserted - 1) + 1) |
| 3657 | : read_buf + unprocessed); | 3674 | : read_buf + unprocessed); |
| 3658 | int this; | 3675 | int this, this_chars; |
| 3659 | 3676 | ||
| 3660 | /* Allow quitting out of the actual I/O. */ | 3677 | /* Allow quitting out of the actual I/O. */ |
| 3661 | immediate_quit = 1; | 3678 | immediate_quit = 1; |
| @@ -3677,6 +3694,7 @@ This does code conversion according to the value of\n\ | |||
| 3677 | if (! not_regular) | 3694 | if (! not_regular) |
| 3678 | how_much += this; | 3695 | how_much += this; |
| 3679 | 3696 | ||
| 3697 | this_chars = this; | ||
| 3680 | if (CODING_REQUIRE_DECODING (&coding) | 3698 | if (CODING_REQUIRE_DECODING (&coding) |
| 3681 | || CODING_REQUIRE_DETECTION (&coding)) | 3699 | || CODING_REQUIRE_DETECTION (&coding)) |
| 3682 | { | 3700 | { |
| @@ -3703,14 +3721,14 @@ This does code conversion according to the value of\n\ | |||
| 3703 | } | 3721 | } |
| 3704 | 3722 | ||
| 3705 | produced = decode_coding (&coding, read_buf, | 3723 | produced = decode_coding (&coding, read_buf, |
| 3706 | POS_ADDR (PT + inserted - 1) + 1, | 3724 | BYTE_POS_ADDR (PT_BYTE + inserted - 1) + 1, |
| 3707 | this, GAP_SIZE, &consumed); | 3725 | this, GAP_SIZE, &consumed); |
| 3708 | if (produced > 0) | 3726 | if (produced > 0) |
| 3709 | { | 3727 | { |
| 3710 | Lisp_Object temp; | 3728 | Lisp_Object temp; |
| 3711 | 3729 | ||
| 3712 | XSET (temp, Lisp_Int, Z + produced); | 3730 | XSET (temp, Lisp_Int, Z_BYTE + produced); |
| 3713 | if (Z + produced != XINT (temp)) | 3731 | if (Z_BYTE + produced != XINT (temp)) |
| 3714 | { | 3732 | { |
| 3715 | how_much = -2; | 3733 | how_much = -2; |
| 3716 | break; | 3734 | break; |
| @@ -3719,19 +3737,25 @@ This does code conversion according to the value of\n\ | |||
| 3719 | unprocessed = this - consumed; | 3737 | unprocessed = this - consumed; |
| 3720 | bcopy (read_buf + consumed, read_buf, unprocessed); | 3738 | bcopy (read_buf + consumed, read_buf, unprocessed); |
| 3721 | this = produced; | 3739 | this = produced; |
| 3740 | this_chars = chars_in_text (BYTE_POS_ADDR (PT_BYTE + inserted - 1) + 1, | ||
| 3741 | produced); | ||
| 3722 | } | 3742 | } |
| 3723 | 3743 | ||
| 3724 | GPT += this; | ||
| 3725 | GAP_SIZE -= this; | 3744 | GAP_SIZE -= this; |
| 3726 | ZV += this; | 3745 | GPT_BYTE += this; |
| 3727 | Z += this; | 3746 | ZV_BYTE += this; |
| 3747 | Z_BYTE += this; | ||
| 3748 | GPT += this_chars; | ||
| 3749 | ZV += this_chars; | ||
| 3750 | Z += this_chars; | ||
| 3751 | |||
| 3728 | if (GAP_SIZE > 0) | 3752 | if (GAP_SIZE > 0) |
| 3729 | /* Put an anchor to ensure multi-byte form ends at gap. */ | 3753 | /* Put an anchor to ensure multi-byte form ends at gap. */ |
| 3730 | *GPT_ADDR = 0; | 3754 | *GPT_ADDR = 0; |
| 3731 | inserted += this; | 3755 | inserted += this; |
| 3756 | inserted_chars += this_chars; | ||
| 3732 | } | 3757 | } |
| 3733 | 3758 | ||
| 3734 | |||
| 3735 | #ifdef DOS_NT | 3759 | #ifdef DOS_NT |
| 3736 | /* Use the conversion type to determine buffer-file-type | 3760 | /* Use the conversion type to determine buffer-file-type |
| 3737 | (find-buffer-file-type is now used to help determine the | 3761 | (find-buffer-file-type is now used to help determine the |
| @@ -3743,37 +3767,12 @@ This does code conversion according to the value of\n\ | |||
| 3743 | current_buffer->buffer_file_type = Qt; | 3767 | current_buffer->buffer_file_type = Qt; |
| 3744 | #endif | 3768 | #endif |
| 3745 | 3769 | ||
| 3746 | /* We don't have to consider file type of MSDOS because all files | ||
| 3747 | are read as binary and end-of-line format has already been | ||
| 3748 | decoded appropriately. */ | ||
| 3749 | #if 0 | ||
| 3750 | #ifdef DOS_NT | ||
| 3751 | /* Demacs 1.1.1 91/10/16 HIRANO Satoshi, MW July 1993 */ | ||
| 3752 | /* Determine file type from name and remove LFs from CR-LFs if the file | ||
| 3753 | is deemed to be a text file. */ | ||
| 3754 | { | ||
| 3755 | current_buffer->buffer_file_type | ||
| 3756 | = call1 (Qfind_buffer_file_type, orig_filename); | ||
| 3757 | if (NILP (current_buffer->buffer_file_type)) | ||
| 3758 | { | ||
| 3759 | int reduced_size | ||
| 3760 | = inserted - crlf_to_lf (inserted, POS_ADDR (PT - 1) + 1); | ||
| 3761 | ZV -= reduced_size; | ||
| 3762 | Z -= reduced_size; | ||
| 3763 | GPT -= reduced_size; | ||
| 3764 | GAP_SIZE += reduced_size; | ||
| 3765 | inserted -= reduced_size; | ||
| 3766 | } | ||
| 3767 | } | ||
| 3768 | #endif /* DOS_NT */ | ||
| 3769 | #endif /* 0 */ | ||
| 3770 | |||
| 3771 | if (inserted > 0) | 3770 | if (inserted > 0) |
| 3772 | { | 3771 | { |
| 3773 | record_insert (PT, inserted); | 3772 | record_insert (PT, inserted_chars); |
| 3774 | 3773 | ||
| 3775 | /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */ | 3774 | /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */ |
| 3776 | offset_intervals (current_buffer, PT, inserted); | 3775 | offset_intervals (current_buffer, PT, inserted_chars); |
| 3777 | MODIFF++; | 3776 | MODIFF++; |
| 3778 | } | 3777 | } |
| 3779 | 3778 | ||
| @@ -3788,6 +3787,8 @@ This does code conversion according to the value of\n\ | |||
| 3788 | else if (how_much == -2) | 3787 | else if (how_much == -2) |
| 3789 | error ("maximum buffer size exceeded"); | 3788 | error ("maximum buffer size exceeded"); |
| 3790 | 3789 | ||
| 3790 | set_coding_system = 1; | ||
| 3791 | |||
| 3791 | notfound: | 3792 | notfound: |
| 3792 | handled: | 3793 | handled: |
| 3793 | 3794 | ||
| @@ -3827,22 +3828,23 @@ This does code conversion according to the value of\n\ | |||
| 3827 | } | 3828 | } |
| 3828 | 3829 | ||
| 3829 | /* Decode file format */ | 3830 | /* Decode file format */ |
| 3830 | if (inserted > 0) | 3831 | if (inserted_chars > 0) |
| 3831 | { | 3832 | { |
| 3832 | insval = call3 (Qformat_decode, | 3833 | insval = call3 (Qformat_decode, |
| 3833 | Qnil, make_number (inserted), visit); | 3834 | Qnil, make_number (inserted_chars), visit); |
| 3834 | CHECK_NUMBER (insval, 0); | 3835 | CHECK_NUMBER (insval, 0); |
| 3835 | inserted = XFASTINT (insval); | 3836 | inserted_chars = XFASTINT (insval); |
| 3836 | } | 3837 | } |
| 3837 | 3838 | ||
| 3838 | /* Call after-change hooks for the inserted text, aside from the case | 3839 | /* Call after-change hooks for the inserted text, aside from the case |
| 3839 | of normal visiting (not with REPLACE), which is done in a new buffer | 3840 | of normal visiting (not with REPLACE), which is done in a new buffer |
| 3840 | "before" the buffer is changed. */ | 3841 | "before" the buffer is changed. */ |
| 3841 | if (inserted > 0 && total > 0 | 3842 | if (inserted_chars > 0 && total > 0 |
| 3842 | && (NILP (visit) || !NILP (replace))) | 3843 | && (NILP (visit) || !NILP (replace))) |
| 3843 | signal_after_change (PT, 0, inserted); | 3844 | signal_after_change (PT, 0, inserted_chars); |
| 3844 | 3845 | ||
| 3845 | Vlast_coding_system_used = coding.symbol; | 3846 | if (set_coding_system) |
| 3847 | Vlast_coding_system_used = coding.symbol; | ||
| 3846 | 3848 | ||
| 3847 | if (inserted > 0) | 3849 | if (inserted > 0) |
| 3848 | { | 3850 | { |
| @@ -3852,17 +3854,18 @@ This does code conversion according to the value of\n\ | |||
| 3852 | 3854 | ||
| 3853 | while (!NILP (p)) | 3855 | while (!NILP (p)) |
| 3854 | { | 3856 | { |
| 3855 | insval = call1 (Fcar (p), make_number (inserted)); | 3857 | insval = call1 (Fcar (p), make_number (inserted_chars)); |
| 3856 | if (!NILP (insval)) | 3858 | if (!NILP (insval)) |
| 3857 | { | 3859 | { |
| 3858 | CHECK_NUMBER (insval, 0); | 3860 | CHECK_NUMBER (insval, 0); |
| 3859 | inserted = XFASTINT (insval); | 3861 | inserted_chars = XFASTINT (insval); |
| 3860 | } | 3862 | } |
| 3861 | QUIT; | 3863 | QUIT; |
| 3862 | p = Fcdr (p); | 3864 | p = Fcdr (p); |
| 3863 | } | 3865 | } |
| 3864 | } | 3866 | } |
| 3865 | 3867 | ||
| 3868 | /* ??? Retval needs to be dealt with in all cases consistently. */ | ||
| 3866 | if (NILP (val)) | 3869 | if (NILP (val)) |
| 3867 | val = Fcons (orig_filename, | 3870 | val = Fcons (orig_filename, |
| 3868 | Fcons (make_number (inserted), | 3871 | Fcons (make_number (inserted), |
| @@ -3871,8 +3874,8 @@ This does code conversion according to the value of\n\ | |||
| 3871 | RETURN_UNGCPRO (unbind_to (count, val)); | 3874 | RETURN_UNGCPRO (unbind_to (count, val)); |
| 3872 | } | 3875 | } |
| 3873 | 3876 | ||
| 3874 | static Lisp_Object build_annotations (); | 3877 | static Lisp_Object build_annotations P_ ((Lisp_Object, Lisp_Object, |
| 3875 | extern Lisp_Object Ffile_locked_p (); | 3878 | Lisp_Object)); |
| 3876 | 3879 | ||
| 3877 | /* If build_annotations switched buffers, switch back to BUF. | 3880 | /* If build_annotations switched buffers, switch back to BUF. |
| 3878 | Kill the temporary buffer that was selected in the meantime. | 3881 | Kill the temporary buffer that was selected in the meantime. |
| @@ -4191,7 +4194,12 @@ to the file, instead of any buffer contents, and END is ignored.") | |||
| 4191 | && coding.type == coding_type_iso2022 | 4194 | && coding.type == coding_type_iso2022 |
| 4192 | && coding.flags & CODING_FLAG_ISO_DESIGNATE_AT_BOL | 4195 | && coding.flags & CODING_FLAG_ISO_DESIGNATE_AT_BOL |
| 4193 | && GPT > BEG && GPT_ADDR[-1] != '\n') | 4196 | && GPT > BEG && GPT_ADDR[-1] != '\n') |
| 4194 | move_gap (find_next_newline (GPT, 1)); | 4197 | { |
| 4198 | int opoint = PT, opoint_byte = PT_BYTE; | ||
| 4199 | scan_newline (PT, PT_BYTE, ZV, ZV_BYTE, 1, 0); | ||
| 4200 | move_gap_both (PT, PT_BYTE); | ||
| 4201 | SET_PT_BOTH (opoint, opoint_byte); | ||
| 4202 | } | ||
| 4195 | #endif | 4203 | #endif |
| 4196 | 4204 | ||
| 4197 | failure = 0; | 4205 | failure = 0; |
| @@ -4205,25 +4213,23 @@ to the file, instead of any buffer contents, and END is ignored.") | |||
| 4205 | } | 4213 | } |
| 4206 | else if (XINT (start) != XINT (end)) | 4214 | else if (XINT (start) != XINT (end)) |
| 4207 | { | 4215 | { |
| 4208 | int nwritten = 0; | 4216 | register int end1 = CHAR_TO_BYTE (XINT (end)); |
| 4217 | |||
| 4218 | tem = CHAR_TO_BYTE (XINT (start)); | ||
| 4219 | |||
| 4209 | if (XINT (start) < GPT) | 4220 | if (XINT (start) < GPT) |
| 4210 | { | 4221 | { |
| 4211 | register int end1 = XINT (end); | 4222 | failure = 0 > a_write (desc, BYTE_POS_ADDR (tem), |
| 4212 | tem = XINT (start); | 4223 | min (GPT_BYTE, end1) - tem, tem, &annotations, |
| 4213 | failure = 0 > a_write (desc, POS_ADDR (tem), | ||
| 4214 | min (GPT, end1) - tem, tem, &annotations, | ||
| 4215 | &coding); | 4224 | &coding); |
| 4216 | nwritten += min (GPT, end1) - tem; | ||
| 4217 | save_errno = errno; | 4225 | save_errno = errno; |
| 4218 | } | 4226 | } |
| 4219 | 4227 | ||
| 4220 | if (XINT (end) > GPT && !failure) | 4228 | if (XINT (end) > GPT && !failure) |
| 4221 | { | 4229 | { |
| 4222 | tem = XINT (start); | 4230 | tem = max (tem, GPT_BYTE); |
| 4223 | tem = max (tem, GPT); | 4231 | failure = 0 > a_write (desc, BYTE_POS_ADDR (tem), end1 - tem, |
| 4224 | failure = 0 > a_write (desc, POS_ADDR (tem), XINT (end) - tem, | ||
| 4225 | tem, &annotations, &coding); | 4232 | tem, &annotations, &coding); |
| 4226 | nwritten += XINT (end) - tem; | ||
| 4227 | save_errno = errno; | 4233 | save_errno = errno; |
| 4228 | } | 4234 | } |
| 4229 | } | 4235 | } |
| @@ -4329,7 +4335,7 @@ to the file, instead of any buffer contents, and END is ignored.") | |||
| 4329 | 4335 | ||
| 4330 | return Qnil; | 4336 | return Qnil; |
| 4331 | } | 4337 | } |
| 4332 | 4338 | ||
| 4333 | Lisp_Object merge (); | 4339 | Lisp_Object merge (); |
| 4334 | 4340 | ||
| 4335 | DEFUN ("car-less-than-car", Fcar_less_than_car, Scar_less_than_car, 2, 2, 0, | 4341 | DEFUN ("car-less-than-car", Fcar_less_than_car, Scar_less_than_car, 2, 2, 0, |
| @@ -4421,43 +4427,51 @@ build_annotations (start, end, pre_write_conversion) | |||
| 4421 | UNGCPRO; | 4427 | UNGCPRO; |
| 4422 | return annotations; | 4428 | return annotations; |
| 4423 | } | 4429 | } |
| 4424 | 4430 | ||
| 4425 | /* Write to descriptor DESC the LEN characters starting at ADDR, | 4431 | /* Write to descriptor DESC the NBYTES bytes starting at ADDR, |
| 4426 | assuming they start at position POS in the buffer. | 4432 | assuming they start at byte position BYTEPOS in the buffer. |
| 4427 | Intersperse with them the annotations from *ANNOT | 4433 | Intersperse with them the annotations from *ANNOT |
| 4428 | (those which fall within the range of positions POS to POS + LEN), | 4434 | which fall within the range of byte positions BYTEPOS to BYTEPOS + NBYTES, |
| 4429 | each at its appropriate position. | 4435 | each at its appropriate position. |
| 4430 | 4436 | ||
| 4431 | Modify *ANNOT by discarding elements as we output them. | 4437 | We modify *ANNOT by discarding elements as we use them up. |
| 4438 | |||
| 4432 | The return value is negative in case of system call failure. */ | 4439 | The return value is negative in case of system call failure. */ |
| 4433 | 4440 | ||
| 4434 | int | 4441 | static int |
| 4435 | a_write (desc, addr, len, pos, annot, coding) | 4442 | a_write (desc, addr, nbytes, bytepos, annot, coding) |
| 4436 | int desc; | 4443 | int desc; |
| 4437 | register char *addr; | 4444 | register char *addr; |
| 4438 | register int len; | 4445 | register int nbytes; |
| 4439 | int pos; | 4446 | int bytepos; |
| 4440 | Lisp_Object *annot; | 4447 | Lisp_Object *annot; |
| 4441 | struct coding_system *coding; | 4448 | struct coding_system *coding; |
| 4442 | { | 4449 | { |
| 4443 | Lisp_Object tem; | 4450 | Lisp_Object tem; |
| 4444 | int nextpos; | 4451 | int nextpos; |
| 4445 | int lastpos = pos + len; | 4452 | int lastpos = bytepos + nbytes; |
| 4446 | 4453 | ||
| 4447 | while (NILP (*annot) || CONSP (*annot)) | 4454 | while (NILP (*annot) || CONSP (*annot)) |
| 4448 | { | 4455 | { |
| 4449 | tem = Fcar_safe (Fcar (*annot)); | 4456 | tem = Fcar_safe (Fcar (*annot)); |
| 4450 | if (INTEGERP (tem) && XINT (tem) >= pos && XFASTINT (tem) <= lastpos) | 4457 | nextpos = 0; |
| 4451 | nextpos = XFASTINT (tem); | 4458 | if (INTEGERP (tem)) |
| 4452 | else | 4459 | nextpos = CHAR_TO_BYTE (XFASTINT (tem)); |
| 4453 | return e_write (desc, addr, lastpos - pos, coding); | 4460 | |
| 4454 | if (nextpos > pos) | 4461 | /* If there are no more annotations in this range, |
| 4462 | output the rest of the range all at once. */ | ||
| 4463 | if (! (nextpos >= bytepos && nextpos <= lastpos)) | ||
| 4464 | return e_write (desc, addr, lastpos - bytepos, coding); | ||
| 4465 | |||
| 4466 | /* Output buffer text up to the next annotation's position. */ | ||
| 4467 | if (nextpos > bytepos) | ||
| 4455 | { | 4468 | { |
| 4456 | if (0 > e_write (desc, addr, nextpos - pos, coding)) | 4469 | if (0 > e_write (desc, addr, nextpos - bytepos, coding)) |
| 4457 | return -1; | 4470 | return -1; |
| 4458 | addr += nextpos - pos; | 4471 | addr += nextpos - bytepos; |
| 4459 | pos = nextpos; | 4472 | bytepos = nextpos; |
| 4460 | } | 4473 | } |
| 4474 | /* Output the annotation. */ | ||
| 4461 | tem = Fcdr (Fcar (*annot)); | 4475 | tem = Fcdr (Fcar (*annot)); |
| 4462 | if (STRINGP (tem)) | 4476 | if (STRINGP (tem)) |
| 4463 | { | 4477 | { |
| @@ -4473,11 +4487,14 @@ a_write (desc, addr, len, pos, annot, coding) | |||
| 4473 | #define WRITE_BUF_SIZE (16 * 1024) | 4487 | #define WRITE_BUF_SIZE (16 * 1024) |
| 4474 | #endif | 4488 | #endif |
| 4475 | 4489 | ||
| 4476 | int | 4490 | /* Write NBYTES bytes starting at ADDR into descriptor DESC, |
| 4477 | e_write (desc, addr, len, coding) | 4491 | encoding them with coding system CODING. */ |
| 4492 | |||
| 4493 | static int | ||
| 4494 | e_write (desc, addr, nbytes, coding) | ||
| 4478 | int desc; | 4495 | int desc; |
| 4479 | register char *addr; | 4496 | register char *addr; |
| 4480 | register int len; | 4497 | register int nbytes; |
| 4481 | struct coding_system *coding; | 4498 | struct coding_system *coding; |
| 4482 | { | 4499 | { |
| 4483 | char buf[WRITE_BUF_SIZE]; | 4500 | char buf[WRITE_BUF_SIZE]; |
| @@ -4487,20 +4504,20 @@ e_write (desc, addr, len, coding) | |||
| 4487 | now it is handled within encode_coding. */ | 4504 | now it is handled within encode_coding. */ |
| 4488 | while (1) | 4505 | while (1) |
| 4489 | { | 4506 | { |
| 4490 | produced = encode_coding (coding, addr, buf, len, WRITE_BUF_SIZE, | 4507 | produced = encode_coding (coding, addr, buf, nbytes, WRITE_BUF_SIZE, |
| 4491 | &consumed); | 4508 | &consumed); |
| 4492 | len -= consumed, addr += consumed; | 4509 | nbytes -= consumed, addr += consumed; |
| 4493 | if (produced > 0) | 4510 | if (produced > 0) |
| 4494 | { | 4511 | { |
| 4495 | produced -= write (desc, buf, produced); | 4512 | produced -= write (desc, buf, produced); |
| 4496 | if (produced) return -1; | 4513 | if (produced) return -1; |
| 4497 | } | 4514 | } |
| 4498 | if (len <= 0) | 4515 | if (nbytes <= 0) |
| 4499 | break; | 4516 | break; |
| 4500 | } | 4517 | } |
| 4501 | return 0; | 4518 | return 0; |
| 4502 | } | 4519 | } |
| 4503 | 4520 | ||
| 4504 | DEFUN ("verify-visited-file-modtime", Fverify_visited_file_modtime, | 4521 | DEFUN ("verify-visited-file-modtime", Fverify_visited_file_modtime, |
| 4505 | Sverify_visited_file_modtime, 1, 1, 0, | 4522 | Sverify_visited_file_modtime, 1, 1, 0, |
| 4506 | "Return t if last mod time of BUF's visited file matches what BUF records.\n\ | 4523 | "Return t if last mod time of BUF's visited file matches what BUF records.\n\ |