aboutsummaryrefslogtreecommitdiffstats
path: root/src/fileio.c
diff options
context:
space:
mode:
authorKenichi Handa1998-06-15 01:11:27 +0000
committerKenichi Handa1998-06-15 01:11:27 +0000
commitf736ffbf3aa1e9d490c3828446122cac7e045ee1 (patch)
treed3cc93196ec3e750966fbe48b1402f69753334ac /src/fileio.c
parentb5cadc4fb015987e7fa5a292812ae435ca626883 (diff)
downloademacs-f736ffbf3aa1e9d490c3828446122cac7e045ee1.tar.gz
emacs-f736ffbf3aa1e9d490c3828446122cac7e045ee1.zip
(Finsert_file_contents): Redo the change for handling
set-auto-coding while adding a kludgy code to avoid a compiler bug.
Diffstat (limited to 'src/fileio.c')
-rw-r--r--src/fileio.c335
1 files changed, 187 insertions, 148 deletions
diff --git a/src/fileio.c b/src/fileio.c
index 2e2aa1e30e6..e0e568d346b 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -3246,6 +3246,26 @@ Lisp_Object Qfind_buffer_file_type;
3246#define READ_BUF_SIZE (64 << 10) 3246#define READ_BUF_SIZE (64 << 10)
3247#endif 3247#endif
3248 3248
3249/* This function is called when a function bound to
3250 Vset_auto_coding_function causes some error. At that time, a text
3251 of a file has already been inserted in the current buffer, but,
3252 markers has not yet been adjusted. Thus we must adjust markers
3253 here. We are sure that the buffer was empty before the text of the
3254 file was inserted. */
3255
3256static Lisp_Object
3257set_auto_coding_unwind (multibyte)
3258 Lisp_Object multibyte;
3259{
3260 int inserted = Z_BYTE - BEG_BYTE;
3261
3262 if (!NILP (multibyte))
3263 inserted = multibyte_chars_in_text (GPT_ADDR - inserted, inserted);
3264 adjust_after_insert (PT, PT_BYTE, Z, Z_BYTE, inserted);
3265
3266 return Qnil;
3267}
3268
3249DEFUN ("insert-file-contents", Finsert_file_contents, Sinsert_file_contents, 3269DEFUN ("insert-file-contents", Finsert_file_contents, Sinsert_file_contents,
3250 1, 5, 0, 3270 1, 5, 0,
3251 "Insert contents of file FILENAME after point.\n\ 3271 "Insert contents of file FILENAME after point.\n\
@@ -3290,6 +3310,7 @@ actually used.")
3290 unsigned char buffer[1 << 14]; 3310 unsigned char buffer[1 << 14];
3291 int replace_handled = 0; 3311 int replace_handled = 0;
3292 int set_coding_system = 0; 3312 int set_coding_system = 0;
3313 int coding_system_decided = 0;
3293 3314
3294 if (current_buffer->base_buffer && ! NILP (visit)) 3315 if (current_buffer->base_buffer && ! NILP (visit))
3295 error ("Cannot do file visiting in an indirect buffer"); 3316 error ("Cannot do file visiting in an indirect buffer");
@@ -3394,161 +3415,107 @@ actually used.")
3394 } 3415 }
3395 } 3416 }
3396 3417
3397 /* Decide the coding-system of the file. */ 3418 if (BEG < Z)
3398 { 3419 {
3399 Lisp_Object val; 3420 /* Decide the coding system to use for reading the file now
3400 val = Qnil; 3421 because we can't use an optimized method for handling
3401 3422 `coding:' tag if the current buffer is not empty. */
3402 if (!NILP (Vcoding_system_for_read)) 3423 Lisp_Object val;
3403 val = Vcoding_system_for_read; 3424 val = Qnil;
3404 else if (! NILP (replace))
3405 /* In REPLACE mode, we can use the same coding system
3406 that was used to visit the file. */
3407 val = current_buffer->buffer_file_coding_system;
3408 else if (! not_regular)
3409 {
3410 /* Don't try looking inside a file for a coding system specification
3411 if it is not seekable. */
3412 if (! NILP (Vset_auto_coding_function))
3413 {
3414 /* Find a coding system specified in the heading two lines
3415 or in the tailing several lines of the file. We assume
3416 that the 1K-byte and 3K-byte for heading and tailing
3417 respectively are sufficient fot this purpose. */
3418 int nread;
3419 int beginning_of_end, end_of_beginning;
3420
3421 if (st.st_size <= (1024 * 4))
3422 {
3423 nread = read (fd, read_buf, 1024 * 4);
3424 end_of_beginning = nread;
3425 beginning_of_end = 0;
3426 }
3427 else
3428 {
3429 nread = read (fd, read_buf, 1024);
3430 end_of_beginning = nread;
3431 beginning_of_end = nread;
3432 if (nread >= 0)
3433 {
3434 if (lseek (fd, st.st_size - (1024 * 3), 0) < 0)
3435 report_file_error ("Setting file position",
3436 Fcons (orig_filename, Qnil));
3437 nread += read (fd, read_buf + nread, 1024 * 3);
3438 }
3439 }
3440 3425
3441 if (nread < 0) 3426 if (!NILP (Vcoding_system_for_read))
3442 error ("IO error reading %s: %s", 3427 val = Vcoding_system_for_read;
3443 XSTRING (orig_filename)->data, strerror (errno)); 3428 else if (! NILP (replace))
3444 else if (nread > 0) 3429 /* In REPLACE mode, we can use the same coding system
3445 { 3430 that was used to visit the file. */
3446 int i; 3431 val = current_buffer->buffer_file_coding_system;
3447 int possible_spec = 0; 3432 else
3448 unsigned char *p, *p1; 3433 {
3449 Lisp_Object tem; 3434 /* Don't try looking inside a file for a coding system
3450 unsigned char *copy = (unsigned char *) alloca (nread + 1); 3435 specification if it is not seekable. */
3451 3436 if (! not_regular && ! NILP (Vset_auto_coding_function))
3452 /* Make a copy of the contents of read_buf in COPY, 3437 {
3453 and convert it to lower case so we can compare 3438 /* Find a coding system specified in the heading two
3454 more efficiently. */ 3439 lines or in the tailing several lines of the file.
3455 bcopy (read_buf, copy, nread); 3440 We assume that the 1K-byte and 3K-byte for heading
3456 for (i = 0; i < nread; i++) 3441 and tailing respectively are sufficient fot this
3457 copy[i] = DOWNCASE (copy[i]); 3442 purpose. */
3458 /* Ensure various comparisons fail at end of data. */ 3443 int how_many, nread;
3459 copy[nread] = 0; 3444
3460 3445 if (st.st_size <= (1024 * 4))
3461 /* Now test quickly whether the file contains a -*- line. */ 3446 nread = read (fd, read_buf, 1024 * 4);
3462 p = copy; 3447 else
3463 while (*p != '\n' && p - copy < end_of_beginning) 3448 {
3464 p++; 3449 nread = read (fd, read_buf, 1024);
3465 if (copy[0] == '#' && copy[1] == '!') 3450 if (nread >= 0)
3466 while (*p != '\n' && p - copy < end_of_beginning) 3451 {
3467 p++; 3452 if (lseek (fd, st.st_size - (1024 * 3), 0) < 0)
3468 p1 = copy; 3453 report_file_error ("Setting file position",
3469 while (p - p1 >= 3) 3454 Fcons (orig_filename, Qnil));
3470 { 3455 nread += read (fd, read_buf + nread, 1024 * 3);
3471 if (p1[0] == '-' && p1[1] == '*' && p1[2] == '-') 3456 }
3472 { 3457 }
3473 while (p - p1 >= 7)
3474 {
3475 if (! bcmp ("coding:", p1, 7))
3476 {
3477 possible_spec = 1;
3478 goto win;
3479 }
3480 p1++;
3481 }
3482 break;
3483 }
3484 p1++;
3485 }
3486 3458
3487 /* Test quickly whether the file 3459 if (nread < 0)
3488 contains a local variables list. */ 3460 error ("IO error reading %s: %s",
3489 p = &copy[nread - 1]; 3461 XSTRING (orig_filename)->data, strerror (errno));
3490 p1 = &copy[beginning_of_end]; 3462 else if (nread > 0)
3491 while (p > p1) 3463 {
3492 { 3464 int count = specpdl_ptr - specpdl;
3493 if (p[0] == '\n' && p[1] == '\f') 3465 struct buffer *prev = current_buffer;
3494 break; 3466
3495 p--; 3467 record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
3496 } 3468 temp_output_buffer_setup (" *code-converting-work*");
3497 p1 = &copy[nread]; 3469 set_buffer_internal (XBUFFER (Vstandard_output));
3498 while (p1 - p >= 16) 3470 current_buffer->enable_multibyte_characters = Qnil;
3499 { 3471 insert_1_both (read_buf, nread, nread, 0, 0, 0);
3500 if (! bcmp ("local variables:", p, 16)) 3472 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
3501 { 3473 val = call1 (Vset_auto_coding_function, make_number (nread));
3502 possible_spec = 1; 3474 set_buffer_internal (prev);
3503 break; 3475 /* Discard the unwind protect for recovering the
3504 } 3476 current buffer. */
3505 p++; 3477 specpdl_ptr--;
3506 } 3478
3507 win: 3479 /* Rewind the file for the actual read done later. */
3480 if (lseek (fd, 0, 0) < 0)
3481 report_file_error ("Setting file position",
3482 Fcons (orig_filename, Qnil));
3483 }
3484 }
3508 3485
3509 if (possible_spec) 3486 if (NILP (val))
3510 { 3487 {
3511 /* Always make this a unibyte string 3488 /* If we have not yet decided a coding system, check
3512 because we have not yet decoded it. */ 3489 file-coding-system-alist. */
3513 tem = make_unibyte_string (read_buf, nread); 3490 Lisp_Object args[6], coding_systems;
3514 val = call1 (Vset_auto_coding_function, tem); 3491
3515 } 3492 args[0] = Qinsert_file_contents, args[1] = orig_filename;
3493 args[2] = visit, args[3] = beg, args[4] = end, args[5] = replace;
3494 coding_systems = Ffind_operation_coding_system (6, args);
3495 if (CONSP (coding_systems))
3496 val = XCONS (coding_systems)->car;
3497 }
3498 }
3516 3499
3517 /* Rewind the file for the actual read done later. */ 3500 setup_coding_system (Fcheck_coding_system (val), &coding);
3518 if (lseek (fd, 0, 0) < 0)
3519 report_file_error ("Setting file position",
3520 Fcons (orig_filename, Qnil));
3521 }
3522 }
3523 if (NILP (val))
3524 {
3525 Lisp_Object args[6], coding_systems;
3526 3501
3527 args[0] = Qinsert_file_contents, args[1] = orig_filename; 3502 if (NILP (Vcoding_system_for_read)
3528 args[2] = visit, args[3] = beg, args[4] = end, args[5] = replace; 3503 && NILP (current_buffer->enable_multibyte_characters))
3529 coding_systems = Ffind_operation_coding_system (6, args); 3504 {
3530 if (CONSP (coding_systems)) 3505 /* We must suppress all text conversion except for end-of-line
3531 val = XCONS (coding_systems)->car; 3506 conversion. */
3532 } 3507 int eol_type;
3533 }
3534 3508
3535 if (NILP (Vcoding_system_for_read) 3509 eol_type = coding.eol_type;
3536 && NILP (current_buffer->enable_multibyte_characters)) 3510 setup_coding_system (Qraw_text, &coding);
3537 { 3511 coding.eol_type = eol_type;
3538 /* We must suppress all text conversion except for end-of-line 3512 }
3539 conversion. */
3540 struct coding_system coding_temp;
3541 3513
3542 setup_coding_system (Fcheck_coding_system (val), &coding_temp); 3514 coding_system_decided = 1;
3543 setup_coding_system (Qraw_text, &coding); 3515 }
3544 coding.eol_type = coding_temp.eol_type;
3545 }
3546 else
3547 setup_coding_system (Fcheck_coding_system (val), &coding);
3548 3516
3549 /* Ensure we always set Vlast_coding_system_used. */ 3517 /* Ensure we always set Vlast_coding_system_used. */
3550 set_coding_system = 1; 3518 set_coding_system = 1;
3551 }
3552 3519
3553 /* If requested, replace the accessible part of the buffer 3520 /* If requested, replace the accessible part of the buffer
3554 with the file contents. Avoid replacing text at the 3521 with the file contents. Avoid replacing text at the
@@ -3565,6 +3532,7 @@ actually used.")
3565 But if we discover the need for conversion, we give up on this method 3532 But if we discover the need for conversion, we give up on this method
3566 and let the following if-statement handle the replace job. */ 3533 and let the following if-statement handle the replace job. */
3567 if (!NILP (replace) 3534 if (!NILP (replace)
3535 && BEGV < ZV
3568 && ! CODING_REQUIRE_DECODING (&coding) 3536 && ! CODING_REQUIRE_DECODING (&coding)
3569 && (coding.eol_type == CODING_EOL_UNDECIDED 3537 && (coding.eol_type == CODING_EOL_UNDECIDED
3570 || coding.eol_type == CODING_EOL_LF)) 3538 || coding.eol_type == CODING_EOL_LF))
@@ -3743,7 +3711,7 @@ actually used.")
3743 is needed, in a simple way that needs a lot of memory. 3711 is needed, in a simple way that needs a lot of memory.
3744 The preceding if-statement handles the case of no conversion 3712 The preceding if-statement handles the case of no conversion
3745 in a more optimized way. */ 3713 in a more optimized way. */
3746 if (!NILP (replace) && ! replace_handled) 3714 if (!NILP (replace) && ! replace_handled && BEGV < ZV)
3747 { 3715 {
3748 int same_at_start = BEGV_BYTE; 3716 int same_at_start = BEGV_BYTE;
3749 int same_at_end = ZV_BYTE; 3717 int same_at_end = ZV_BYTE;
@@ -3995,6 +3963,77 @@ actually used.")
3995 3963
3996 if (inserted > 0) 3964 if (inserted > 0)
3997 { 3965 {
3966 if (! coding_system_decided)
3967 {
3968 /* The coding system is not yet decided. Decide it by an
3969 optimized method for handling `coding:' tag. */
3970 Lisp_Object val;
3971 val = Qnil;
3972
3973 if (!NILP (Vcoding_system_for_read))
3974 val = Vcoding_system_for_read;
3975 else
3976 {
3977 if (! NILP (Vset_auto_coding_function))
3978 {
3979 /* Since we are sure that the current buffer was
3980 empty before the insertion, we can toggle
3981 enable-multibyte-characters directly here without
3982 taking care of marker adjustment and byte
3983 combining problem. */
3984 Lisp_Object prev_multibyte;
3985 int count = specpdl_ptr - specpdl;
3986
3987 prev_multibyte = current_buffer->enable_multibyte_characters;
3988 current_buffer->enable_multibyte_characters = Qnil;
3989 record_unwind_protect (set_auto_coding_unwind,
3990 prev_multibyte);
3991 val = call1 (Vset_auto_coding_function,
3992 make_number (inserted));
3993 /* Discard the unwind protect for recovering the
3994 error of Vset_auto_coding_function. */
3995 specpdl_ptr--;
3996 current_buffer->enable_multibyte_characters = prev_multibyte;
3997 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
3998 }
3999
4000 if (NILP (val))
4001 {
4002 /* If the coding system is not yet decided, check
4003 file-coding-system-alist. */
4004 Lisp_Object args[6], coding_systems;
4005
4006 args[0] = Qinsert_file_contents, args[1] = orig_filename;
4007 args[2] = visit, args[3] = beg, args[4] = end, args[5] = Qnil;
4008 coding_systems = Ffind_operation_coding_system (6, args);
4009 if (CONSP (coding_systems))
4010 val = XCONS (coding_systems)->car;
4011 }
4012 }
4013
4014 /* The following kludgy code is to avoid some compiler bug.
4015 We can't simply do
4016 setup_coding_system (val, &coding);
4017 on some system. */
4018 {
4019 struct coding_system temp_coding;
4020 setup_coding_system (val, &temp_coding);
4021 bcopy (&temp_coding, &coding, sizeof coding);
4022 }
4023
4024 if (NILP (Vcoding_system_for_read)
4025 && NILP (current_buffer->enable_multibyte_characters))
4026 {
4027 /* We must suppress all text conversion except for
4028 end-of-line conversion. */
4029 int eol_type;
4030
4031 eol_type = coding.eol_type;
4032 setup_coding_system (Qraw_text, &coding);
4033 coding.eol_type = eol_type;
4034 }
4035 }
4036
3998 if (CODING_MAY_REQUIRE_DECODING (&coding)) 4037 if (CODING_MAY_REQUIRE_DECODING (&coding))
3999 { 4038 {
4000 /* Here, we don't have to consider byte combining (see the 4039 /* Here, we don't have to consider byte combining (see the