/[emacs]/emacs/src/fileio.c
ViewVC logotype

Diff of /emacs/src/fileio.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.439 by eliz, Tue Feb 26 18:41:36 2002 UTC revision 1.439.2.1 by handa, Fri Mar 1 01:38:37 2002 UTC
# Line 87  extern int errno; Line 87  extern int errno;
87  #include "lisp.h"  #include "lisp.h"
88  #include "intervals.h"  #include "intervals.h"
89  #include "buffer.h"  #include "buffer.h"
90  #include "charset.h"  #include "character.h"
91  #include "coding.h"  #include "coding.h"
92  #include "window.h"  #include "window.h"
93    
# Line 3576  actually used.  */) Line 3576  actually used.  */)
3576    unsigned char buffer[1 << 14];    unsigned char buffer[1 << 14];
3577    int replace_handled = 0;    int replace_handled = 0;
3578    int set_coding_system = 0;    int set_coding_system = 0;
3579    int coding_system_decided = 0;    Lisp_Object coding_system;
3580    int read_quit = 0;    int read_quit = 0;
3581    
3582    if (current_buffer->base_buffer && ! NILP (visit))    if (current_buffer->base_buffer && ! NILP (visit))
# Line 3713  actually used.  */) Line 3713  actually used.  */)
3713          }          }
3714      }      }
3715    
3716      /* The value Qnil means that the coding system is not yet
3717         decided.  */
3718      coding_system = Qnil;
3719    if (BEG < Z)    if (BEG < Z)
3720      {      {
3721        /* Decide the coding system to use for reading the file now        /* Decide the coding system to use for reading the file now
3722           because we can't use an optimized method for handling           because we can't use an optimized method for handling
3723           `coding:' tag if the current buffer is not empty.  */           `coding:' tag if the current buffer is not empty.  */
       Lisp_Object val;  
       val = Qnil;  
   
3724        if (!NILP (Vcoding_system_for_read))        if (!NILP (Vcoding_system_for_read))
3725          val = Vcoding_system_for_read;          coding_system = Vcoding_system_for_read;
3726        else if (! NILP (replace))        else if (! NILP (replace))
3727          /* In REPLACE mode, we can use the same coding system          /* In REPLACE mode, we can use the same coding system
3728             that was used to visit the file.  */             that was used to visit the file.  */
3729          val = current_buffer->buffer_file_coding_system;          coding_system = current_buffer->buffer_file_coding_system;
3730        else        else
3731          {          {
3732            /* Don't try looking inside a file for a coding system            /* Don't try looking inside a file for a coding system
# Line 3773  actually used.  */) Line 3773  actually used.  */)
3773                    current_buffer->enable_multibyte_characters = Qnil;                    current_buffer->enable_multibyte_characters = Qnil;
3774                    insert_1_both (read_buf, nread, nread, 0, 0, 0);                    insert_1_both (read_buf, nread, nread, 0, 0, 0);
3775                    TEMP_SET_PT_BOTH (BEG, BEG_BYTE);                    TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
3776                    val = call2 (Vset_auto_coding_function,                    coding_system = call2 (Vset_auto_coding_function,
3777                                 filename, make_number (nread));                                                  filename, make_number (nread));
3778                    set_buffer_internal (prev);                    set_buffer_internal (prev);
3779    
3780                    /* Remove the binding for standard-output.  */                    /* Remove the binding for standard-output.  */
# Line 3791  actually used.  */) Line 3791  actually used.  */)
3791                  }                  }
3792              }              }
3793    
3794            if (NILP (val))            if (NILP (coding_system))
3795              {              {
3796                /* If we have not yet decided a coding system, check                /* If we have not yet decided a coding system, check
3797                   file-coding-system-alist.  */                   file-coding-system-alist.  */
# Line 3805  actually used.  */) Line 3805  actually used.  */)
3805              }              }
3806          }          }
3807    
3808        setup_coding_system (Fcheck_coding_system (val), &coding);        if (NILP (coding_system))
3809        /* Ensure we set Vlast_coding_system_used.  */          coding_system = Qundecided;
3810        set_coding_system = 1;        else
3811            CHECK_CODING_SYSTEM (coding_system);
3812    
3813        if (NILP (current_buffer->enable_multibyte_characters)        if (NILP (current_buffer->enable_multibyte_characters))
           && ! NILP (val))  
3814          /* We must suppress all character code conversion except for          /* We must suppress all character code conversion except for
3815             end-of-line conversion.  */             end-of-line conversion.  */
3816          setup_raw_text_coding_system (&coding);          coding_system = raw_text_coding_system (coding_system);
3817    
3818        coding.src_multibyte = 0;        setup_coding_system (coding_system, &coding);
3819        coding.dst_multibyte        /* Ensure we set Vlast_coding_system_used.  */
3820          = !NILP (current_buffer->enable_multibyte_characters);        set_coding_system = 1;
       coding_system_decided = 1;  
3821      }      }
3822    
3823    /* If requested, replace the accessible part of the buffer    /* If requested, replace the accessible part of the buffer
# Line 3837  actually used.  */) Line 3836  actually used.  */)
3836       and let the following if-statement handle the replace job.  */       and let the following if-statement handle the replace job.  */
3837    if (!NILP (replace)    if (!NILP (replace)
3838        && BEGV < ZV        && BEGV < ZV
3839        && !(coding.common_flags & CODING_REQUIRE_DECODING_MASK))        && (NILP (coding_system)
3840              || ! CODING_REQUIRE_DECODING (&coding)))
3841      {      {
3842        /* same_at_start and same_at_end count bytes,        /* same_at_start and same_at_end count bytes,
3843           because file access counts bytes           because file access counts bytes
# Line 3872  actually used.  */) Line 3872  actually used.  */)
3872            else if (nread == 0)            else if (nread == 0)
3873              break;              break;
3874    
3875            if (coding.type == coding_type_undecided)            if (CODING_REQUIRE_DETECTION (&coding))
             detect_coding (&coding, buffer, nread);  
           if (coding.common_flags & CODING_REQUIRE_DECODING_MASK)  
             /* We found that the file should be decoded somehow.  
                Let's give up here.  */  
3876              {              {
3877                giveup_match_end = 1;                coding_system = detect_coding_system (buffer, nread, 1, 0,
3878                break;                                                      coding_system);
3879                  setup_coding_system (coding_system, &coding);
3880              }              }
3881              if (CODING_REQUIRE_DECODING (&coding))
3882            if (coding.eol_type == CODING_EOL_UNDECIDED)              /* We found that the file should be decoded somehow.
             detect_eol (&coding, buffer, nread);  
           if (coding.eol_type != CODING_EOL_UNDECIDED  
               && coding.eol_type != CODING_EOL_LF)  
             /* We found that the format of eol should be decoded.  
3883                 Let's give up here.  */                 Let's give up here.  */
3884              {              {
3885                giveup_match_end = 1;                giveup_match_end = 1;
# Line 4033  actually used.  */) Line 4026  actually used.  */)
4026        int same_at_end = ZV_BYTE;        int same_at_end = ZV_BYTE;
4027        int overlap;        int overlap;
4028        int bufpos;        int bufpos;
4029        /* Make sure that the gap is large enough.  */        unsigned char *decoded;
       int bufsize = 2 * st.st_size;  
       unsigned char *conversion_buffer = (unsigned char *) xmalloc (bufsize);  
4030        int temp;        int temp;
4031          int this_count = BINDING_STACK_SIZE ();
4032          Lisp_Object conversion_buffer
4033            = make_conversion_work_buffer (! NILP (current_buffer
4034                                                   ->enable_multibyte_characters));
4035    
4036          record_unwind_protect (code_conversion_restore, save_excursion_save ());
4037    
4038        /* First read the whole file, performing code conversion into        /* First read the whole file, performing code conversion into
4039           CONVERSION_BUFFER.  */           CONVERSION_BUFFER.  */
4040    
4041        if (lseek (fd, XINT (beg), 0) < 0)        if (lseek (fd, XINT (beg), 0) < 0)
4042          {          {
           xfree (conversion_buffer);  
4043            report_file_error ("Setting file position",            report_file_error ("Setting file position",
4044                               Fcons (orig_filename, Qnil));                               Fcons (orig_filename, Qnil));
4045          }          }
# Line 4055  actually used.  */) Line 4051  actually used.  */)
4051    
4052        while (how_much < total)        while (how_much < total)
4053          {          {
4054              /* We read one bunch by one (READ_BUF_SIZE bytes) to allow
4055                 quitting while reading a huge while.  */
4056            /* try is reserved in some compilers (Microsoft C) */            /* try is reserved in some compilers (Microsoft C) */
4057            int trytry = min (total - how_much, READ_BUF_SIZE - unprocessed);            int trytry = min (total - how_much, READ_BUF_SIZE - unprocessed);
           unsigned char *destination = read_buf + unprocessed;  
4058            int this;            int this;
4059    
4060            /* Allow quitting out of the actual I/O.  */            /* Allow quitting out of the actual I/O.  */
4061            immediate_quit = 1;            immediate_quit = 1;
4062            QUIT;            QUIT;
4063            this = emacs_read (fd, destination, trytry);            this = emacs_read (fd, read_buf + unprocessed, trytry);
4064            immediate_quit = 0;            immediate_quit = 0;
4065    
4066            if (this < 0 || this + unprocessed == 0)            if (this <= 0)
4067              {              {
4068                how_much = this;                if (this < 0)
4069                    how_much = this;
4070                break;                break;
4071              }              }
4072    
4073            how_much += this;            how_much += this;
4074    
4075            if (CODING_MAY_REQUIRE_DECODING (&coding))            decode_coding_c_string (&coding, read_buf, unprocessed + this,
4076              {                                    conversion_buffer);
4077                int require, result;            unprocessed = coding.carryover_bytes;
4078              if (coding.carryover_bytes > 0)
4079                this += unprocessed;              bcopy (coding.carryover, read_buf, unprocessed);
4080            }        
4081                /* If we are using more space than estimated,        
4082                   make CONVERSION_BUFFER bigger.  */        emacs_close (fd);
               require = decoding_buffer_size (&coding, this);  
               if (inserted + require + 2 * (total - how_much) > bufsize)  
                 {  
                   bufsize = inserted + require + 2 * (total - how_much);  
                   conversion_buffer = (unsigned char *) xrealloc (conversion_buffer, bufsize);  
                 }  
   
               /* Convert this batch with results in CONVERSION_BUFFER.  */  
               if (how_much >= total)  /* This is the last block.  */  
                 coding.mode |= CODING_MODE_LAST_BLOCK;  
               if (coding.composing != COMPOSITION_DISABLED)  
                 coding_allocate_composition_data (&coding, BEGV);  
               result = decode_coding (&coding, read_buf,  
                                       conversion_buffer + inserted,  
                                       this, bufsize - inserted);  
   
               /* Save for next iteration whatever we didn't convert.  */  
               unprocessed = this - coding.consumed;  
               bcopy (read_buf + coding.consumed, read_buf, unprocessed);  
               if (!NILP (current_buffer->enable_multibyte_characters))  
                 this = coding.produced;  
               else  
                 this = str_as_unibyte (conversion_buffer + inserted,  
                                        coding.produced);  
             }  
   
           inserted += this;  
         }  
4083    
4084        /* At this point, INSERTED is how many characters (i.e. bytes)        /* At this point, HOW_MUCH should equal TOTAL, or should be <= 0
4085           are present in CONVERSION_BUFFER.           if we couldn't read the file.  */
          HOW_MUCH should equal TOTAL,  
          or should be <= 0 if we couldn't read the file.  */  
4086    
4087        if (how_much < 0)        if (how_much < 0)
4088          {          {
           xfree (conversion_buffer);  
   
4089            if (how_much == -1)            if (how_much == -1)
4090              error ("IO error reading %s: %s",              error ("IO error reading %s: %s",
4091                     XSTRING (orig_filename)->data, emacs_strerror (errno));                     XSTRING (orig_filename)->data, emacs_strerror (errno));
# Line 4127  actually used.  */) Line 4093  actually used.  */)
4093              error ("maximum buffer size exceeded");              error ("maximum buffer size exceeded");
4094          }          }
4095    
4096        /* Compare the beginning of the converted file        if (unprocessed > 0)
4097           with the buffer text.  */          {
4098              coding.mode |= CODING_MODE_LAST_BLOCK;
4099              decode_coding_c_string (&coding, read_buf, unprocessed,
4100                                      conversion_buffer);
4101              coding.mode &= ~CODING_MODE_LAST_BLOCK;
4102            }
4103    
4104          decoded = BUF_BEG_ADDR (XBUFFER (conversion_buffer));
4105          inserted = BUF_Z_BYTE (XBUFFER (conversion_buffer));
4106    
4107          /* Compare the beginning of the converted string with the buffer
4108             text.  */
4109    
4110        bufpos = 0;        bufpos = 0;
4111        while (bufpos < inserted && same_at_start < same_at_end        while (bufpos < inserted && same_at_start < same_at_end
4112               && FETCH_BYTE (same_at_start) == conversion_buffer[bufpos])               && FETCH_BYTE (same_at_start) == decoded[bufpos])
4113          same_at_start++, bufpos++;          same_at_start++, bufpos++;
4114    
4115        /* If the file matches the buffer completely,        /* If the file matches the head of buffer completely,
4116           there's no need to replace anything.  */           there's no need to replace anything.  */
4117    
4118        if (bufpos == inserted)        if (bufpos == inserted)
4119          {          {
           xfree (conversion_buffer);  
           emacs_close (fd);  
4120            specpdl_ptr--;            specpdl_ptr--;
4121            /* Truncate the buffer to the size of the file.  */            /* Truncate the buffer to the size of the file.  */
4122            del_range_byte (same_at_start, same_at_end, 0);            del_range_byte (same_at_start, same_at_end, 0);
# Line 4149  actually used.  */) Line 4124  actually used.  */)
4124            goto handled;            goto handled;
4125          }          }
4126    
4127        /* Extend the start of non-matching text area to multibyte        /* Extend the start of non-matching text area to the previous
4128           character boundary.  */           multibyte character boundary.  */
4129        if (! NILP (current_buffer->enable_multibyte_characters))        if (! NILP (current_buffer->enable_multibyte_characters))
4130          while (same_at_start > BEGV_BYTE          while (same_at_start > BEGV_BYTE
4131                 && ! CHAR_HEAD_P (FETCH_BYTE (same_at_start)))                 && ! CHAR_HEAD_P (FETCH_BYTE (same_at_start)))
# Line 4163  actually used.  */) Line 4138  actually used.  */)
4138        /* Compare with same_at_start to avoid counting some buffer text        /* Compare with same_at_start to avoid counting some buffer text
4139           as matching both at the file's beginning and at the end.  */           as matching both at the file's beginning and at the end.  */
4140        while (bufpos > 0 && same_at_end > same_at_start        while (bufpos > 0 && same_at_end > same_at_start
4141               && FETCH_BYTE (same_at_end - 1) == conversion_buffer[bufpos - 1])               && FETCH_BYTE (same_at_end - 1) == decoded[bufpos - 1])
4142          same_at_end--, bufpos--;          same_at_end--, bufpos--;
4143    
4144        /* Extend the end of non-matching text area to multibyte        /* Extend the end of non-matching text area to the next
4145           character boundary.  */           multibyte character boundary.  */
4146        if (! NILP (current_buffer->enable_multibyte_characters))        if (! NILP (current_buffer->enable_multibyte_characters))
4147          while (same_at_end < ZV_BYTE          while (same_at_end < ZV_BYTE
4148                 && ! CHAR_HEAD_P (FETCH_BYTE (same_at_end)))                 && ! CHAR_HEAD_P (FETCH_BYTE (same_at_end)))
# Line 4185  actually used.  */) Line 4160  actually used.  */)
4160    
4161        /* Replace the chars that we need to replace,        /* Replace the chars that we need to replace,
4162           and update INSERTED to equal the number of bytes           and update INSERTED to equal the number of bytes
4163           we are taking from the file.  */           we are taking from the decoded string.  */
4164        inserted -= (Z_BYTE - same_at_end) + (same_at_start - BEG_BYTE);        inserted -= (Z_BYTE - same_at_end) + (same_at_start - BEG_BYTE);
4165    
4166        if (same_at_end != same_at_start)        if (same_at_end != same_at_start)
4167          {          {      
4168            del_range_byte (same_at_start, same_at_end, 0);            del_range_byte (same_at_start, same_at_end, 0);
4169            temp = GPT;            temp = GPT;
4170            same_at_start = GPT_BYTE;            same_at_start = GPT_BYTE;
# Line 4200  actually used.  */) Line 4175  actually used.  */)
4175          }          }
4176        /* Insert from the file at the proper position.  */        /* Insert from the file at the proper position.  */
4177        SET_PT_BOTH (temp, same_at_start);        SET_PT_BOTH (temp, same_at_start);
4178        insert_1 (conversion_buffer + same_at_start - BEG_BYTE, inserted,        insert_from_buffer (XBUFFER (conversion_buffer),
4179                  0, 0, 0);                            buf_bytepos_to_charpos (XBUFFER (conversion_buffer),
4180        if (coding.cmp_data && coding.cmp_data->used)                                                    same_at_start),
4181          coding_restore_composition (&coding, Fcurrent_buffer ());                            buf_bytepos_to_charpos (XBUFFER (conversion_buffer),
4182        coding_free_composition_data (&coding);                                                    same_at_start + inserted),
4183                                0);
4184        /* Set `inserted' to the number of inserted characters.  */        /* Set `inserted' to the number of inserted characters.  */
4185        inserted = PT - temp;        inserted = PT - temp;
4186    
4187        xfree (conversion_buffer);        unbind_to (this_count, Qnil);
       emacs_close (fd);  
       specpdl_ptr--;  
4188    
4189        goto handled;        goto handled;
4190      }      }
# Line 4255  actually used.  */) Line 4228  actually used.  */)
4228    inserted = 0;    inserted = 0;
4229        
4230    /* Here, we don't do code conversion in the loop.  It is done by    /* Here, we don't do code conversion in the loop.  It is done by
4231       code_convert_region after all data are read into the buffer.  */       decode_coding_gap after all data are read into the buffer.  */
4232    {    {
4233      int gap_size = GAP_SIZE;      int gap_size = GAP_SIZE;
4234            
# Line 4346  actually used.  */) Line 4319  actually used.  */)
4319    
4320   notfound:   notfound:
4321    
4322    if (! coding_system_decided)    if (NILP (coding_system))
4323      {      {
4324        /* The coding system is not yet decided.  Decide it by an        /* The coding system is not yet decided.  Decide it by an
4325           optimized method for handling `coding:' tag.           optimized method for handling `coding:' tag.
4326    
4327           Note that we can get here only if the buffer was empty           Note that we can get here only if the buffer was empty
4328           before the insertion.  */           before the insertion.  */
       Lisp_Object val;  
       val = Qnil;  
4329    
4330        if (!NILP (Vcoding_system_for_read))        if (!NILP (Vcoding_system_for_read))
4331          val = Vcoding_system_for_read;          coding_system = Vcoding_system_for_read;
4332        else        else
4333          {          {
4334            /* Since we are sure that the current buffer was empty            /* Since we are sure that the current buffer was empty
# Line 4378  actually used.  */) Line 4349  actually used.  */)
4349    
4350            if (inserted > 0 && ! NILP (Vset_auto_coding_function))            if (inserted > 0 && ! NILP (Vset_auto_coding_function))
4351              {              {
4352                val = call2 (Vset_auto_coding_function,                coding_system = call2 (Vset_auto_coding_function,
4353                             filename, make_number (inserted));                                              filename, make_number (inserted));
4354              }              }
4355    
4356            if (NILP (val))            if (NILP (coding_system))
4357              {              {
4358                /* If the coding system is not yet decided, check                /* If the coding system is not yet decided, check
4359                   file-coding-system-alist.  */                   file-coding-system-alist.  */
# Line 4392  actually used.  */) Line 4363  actually used.  */)
4363                args[2] = visit, args[3] = beg, args[4] = end, args[5] = Qnil;                args[2] = visit, args[3] = beg, args[4] = end, args[5] = Qnil;
4364                coding_systems = Ffind_operation_coding_system (6, args);                coding_systems = Ffind_operation_coding_system (6, args);
4365                if (CONSP (coding_systems))                if (CONSP (coding_systems))
4366                  val = XCAR (coding_systems);                  coding_system = XCAR (coding_systems);
4367              }              }
4368    
4369            unbind_to (count, Qnil);            unbind_to (count, Qnil);
4370            inserted = Z_BYTE - BEG_BYTE;            inserted = Z_BYTE - BEG_BYTE;
4371          }          }
4372    
4373        /* The following kludgy code is to avoid some compiler bug.        if (NILP (coding_system))
4374           We can't simply do          coding_system = Qundecided;
4375           setup_coding_system (val, &coding);        else
4376           on some system.  */          CHECK_CODING_SYSTEM (coding_system);
       {  
         struct coding_system temp_coding;  
         setup_coding_system (val, &temp_coding);  
         bcopy (&temp_coding, &coding, sizeof coding);  
       }  
       /* Ensure we set Vlast_coding_system_used.  */  
       set_coding_system = 1;  
4377    
4378        if (NILP (current_buffer->enable_multibyte_characters)        if (NILP (current_buffer->enable_multibyte_characters))
           && ! NILP (val))  
4379          /* We must suppress all character code conversion except for          /* We must suppress all character code conversion except for
4380             end-of-line conversion.  */             end-of-line conversion.  */
4381          setup_raw_text_coding_system (&coding);          coding_system = raw_text_coding_system (coding_system);
4382        coding.src_multibyte = 0;  
4383        coding.dst_multibyte        setup_coding_system (coding_system, &coding);
4384          = !NILP (current_buffer->enable_multibyte_characters);        /* Ensure we set Vlast_coding_system_used.  */
4385          set_coding_system = 1;
4386      }      }
4387    
4388    if (!NILP (visit)    if (!NILP (visit))
       /* Can't do this if part of the buffer might be preserved.  */  
       && NILP (replace)  
       && (coding.type == coding_type_no_conversion  
           || coding.type == coding_type_raw_text))  
4389      {      {
4390        /* Visiting a file with these coding system makes the buffer        /* When we visit a file by raw-text, we change the buffer to
4391           unibyte. */           unibyte.  If we have not yet decided how to decode a text,
4392        current_buffer->enable_multibyte_characters = Qnil;           decide it at first by detecting the file's encoding.  */
4393        coding.dst_multibyte = 0;        if (CODING_REQUIRE_DETECTION (&coding))
4394            {
4395              coding_system = detect_coding_system (PT_ADDR, inserted, 1, 0,
4396                                                    coding_system);
4397              setup_coding_system (coding_system, &coding);
4398            }
4399    
4400          if (CODING_FOR_UNIBYTE (&coding)
4401              /* Can't do this if part of the buffer might be preserved.  */
4402              && NILP (replace))
4403            /* Visiting a file with these coding system makes the buffer
4404               unibyte. */
4405            current_buffer->enable_multibyte_characters = Qnil;
4406      }      }
4407    
4408    if (inserted > 0 || coding.type == coding_type_ccl)    if (CODING_REQUIRE_DETECTION (&coding)
4409          || CODING_REQUIRE_DECODING (&coding))
4410      {      {
4411        if (CODING_MAY_REQUIRE_DECODING (&coding))        move_gap_both (PT, PT_BYTE);
4412          {        GAP_SIZE += inserted;
4413            code_convert_region (PT, PT_BYTE, PT + inserted, PT_BYTE + inserted,        ZV_BYTE -= inserted;
4414                                 &coding, 0, 0);        Z_BYTE -= inserted;
4415            inserted = coding.produced_char;        ZV -= inserted;
4416          }        Z -= inserted;
4417        else        decode_coding_gap (&coding, inserted, inserted);
4418          adjust_after_insert (PT, PT_BYTE, PT + inserted, PT_BYTE + inserted,        inserted = coding.produced_char;
4419                               inserted);      }
4420      }    else if (inserted > 0)
4421        adjust_after_insert (PT, PT_BYTE, PT + inserted, PT_BYTE + inserted,
4422                             inserted);
4423    
4424  #ifdef DOS_NT  #ifdef DOS_NT
4425    /* Use the conversion type to determine buffer-file-type    /* Use the conversion type to determine buffer-file-type
4426       (find-buffer-file-type is now used to help determine the       (find-buffer-file-type is now used to help determine the
4427       conversion).  */       conversion).  */
4428    if ((coding.eol_type == CODING_EOL_UNDECIDED    if ((coding.eol_type == eol_type_undecided
4429         || coding.eol_type == CODING_EOL_LF)         || coding.eol_type == eol_type_lf)
4430        && ! CODING_REQUIRE_DECODING (&coding))        && ! CODING_REQUIRE_DECODING (&coding))
4431      current_buffer->buffer_file_type = Qt;      current_buffer->buffer_file_type = Qt;
4432    else    else
# Line 4515  actually used.  */) Line 4490  actually used.  */)
4490      }      }
4491    
4492    if (set_coding_system)    if (set_coding_system)
4493      Vlast_coding_system_used = coding.symbol;      Vlast_coding_system_used = coding_system;
4494    
4495    /* Call after-change hooks for the inserted text, aside from the case    /* Call after-change hooks for the inserted text, aside from the case
4496       of normal visiting (not with REPLACE), which is done in a new buffer       of normal visiting (not with REPLACE), which is done in a new buffer
# Line 4560  actually used.  */) Line 4535  actually used.  */)
4535  }  }
4536    
4537  static Lisp_Object build_annotations P_ ((Lisp_Object, Lisp_Object));  static Lisp_Object build_annotations P_ ((Lisp_Object, Lisp_Object));
 static Lisp_Object build_annotations_2 P_ ((Lisp_Object, Lisp_Object,  
                                             Lisp_Object, Lisp_Object));  
4538    
4539  /* If build_annotations switched buffers, switch back to BUF.  /* If build_annotations switched buffers, switch back to BUF.
4540     Kill the temporary buffer that was selected in the meantime.     Kill the temporary buffer that was selected in the meantime.
# Line 4643  choose_write_coding_system (start, end, Line 4616  choose_write_coding_system (start, end,
4616            using_default_coding = 1;            using_default_coding = 1;
4617          }          }
4618                            
4619          if (! NILP (val) && ! force_raw_text)
4620            {
4621              Lisp_Object spec, attrs;
4622    
4623              CHECK_CODING_SYSTEM_GET_SPEC (val, spec);
4624              attrs = AREF (spec, 0);
4625              if (EQ (CODING_ATTR_TYPE (attrs), Qraw_text))
4626                force_raw_text = 1;
4627            }
4628    
4629        if (!force_raw_text        if (!force_raw_text
4630            && !NILP (Ffboundp (Vselect_safe_coding_system_function)))            && !NILP (Ffboundp (Vselect_safe_coding_system_function)))
4631          /* Confirm that VAL can surely encode the current region.  */          /* Confirm that VAL can surely encode the current region.  */
4632          val = call3 (Vselect_safe_coding_system_function, start, end, val);          val = call3 (Vselect_safe_coding_system_function, start, end, val);
4633    
4634        setup_coding_system (Fcheck_coding_system (val), coding);        /* If the decided coding-system doesn't specify end-of-line
4635        if (coding->eol_type == CODING_EOL_UNDECIDED           format, we use that of
4636            && !using_default_coding)           `default-buffer-file-coding-system'.  */
4637          {        if (! using_default_coding)
4638            if (! EQ (default_buffer_file_coding.symbol,          val = (coding_inherit_eol_type
4639                      buffer_defaults.buffer_file_coding_system))                 (val, buffer_defaults.buffer_file_coding_system));
             setup_coding_system (buffer_defaults.buffer_file_coding_system,  
                                  &default_buffer_file_coding);  
           if (default_buffer_file_coding.eol_type != CODING_EOL_UNDECIDED)  
             {  
               Lisp_Object subsidiaries;  
   
               coding->eol_type = default_buffer_file_coding.eol_type;  
               subsidiaries = Fget (coding->symbol, Qeol_type);  
               if (VECTORP (subsidiaries)  
                   && XVECTOR (subsidiaries)->size == 3)  
                 coding->symbol  
                   = XVECTOR (subsidiaries)->contents[coding->eol_type];  
             }  
         }  
4640    
4641          /* If we decide not to encode text, use `raw-text' or one of its
4642             subsidiaries.  */
4643        if (force_raw_text)        if (force_raw_text)
4644          setup_raw_text_coding_system (coding);          val = raw_text_coding_system (val);
       goto done_setup_coding;  
4645      }      }
4646    
4647    setup_coding_system (Fcheck_coding_system (val), coding);    setup_coding_system (Fcheck_coding_system (val), coding);
4648    
  done_setup_coding:  
4649    if (!STRINGP (start) && !NILP (current_buffer->selective_display))    if (!STRINGP (start) && !NILP (current_buffer->selective_display))
4650      coding->mode |= CODING_MODE_SELECTIVE_DISPLAY;      coding->mode |= CODING_MODE_SELECTIVE_DISPLAY;
4651  }  }
# Line 4816  This does code conversion according to t Line 4785  This does code conversion according to t
4785       unsavable chars (as was the case with X-Symbol).  */       unsavable chars (as was the case with X-Symbol).  */
4786    choose_write_coding_system (start, end, filename,    choose_write_coding_system (start, end, filename,
4787                                append, visit, lockname, &coding);                                append, visit, lockname, &coding);
4788    Vlast_coding_system_used = coding.symbol;    Vlast_coding_system_used = CODING_ID_NAME (coding.id);
4789    
4790    given_buffer = current_buffer;    given_buffer = current_buffer;
   annotations = build_annotations_2 (start, end,  
                                      coding.pre_write_conversion, annotations);  
4791    if (current_buffer != given_buffer)    if (current_buffer != given_buffer)
4792      {      {
4793        XSETFASTINT (start, BEGV);        XSETFASTINT (start, BEGV);
# Line 4963  This does code conversion according to t Line 4930  This does code conversion according to t
4930    if (GPT > BEG && GPT_ADDR[-1] != '\n')    if (GPT > BEG && GPT_ADDR[-1] != '\n')
4931      move_gap (find_next_newline (GPT, 1));      move_gap (find_next_newline (GPT, 1));
4932  #else  #else
4933    #if 0
4934      /* The new encoding routine doesn't require the following.  */
4935    
4936    /* Whether VMS or not, we must move the gap to the next of newline    /* Whether VMS or not, we must move the gap to the next of newline
4937       when we must put designation sequences at beginning of line.  */       when we must put designation sequences at beginning of line.  */
4938    if (INTEGERP (start)    if (INTEGERP (start)
# Line 4976  This does code conversion according to t Line 4946  This does code conversion according to t
4946        SET_PT_BOTH (opoint, opoint_byte);        SET_PT_BOTH (opoint, opoint_byte);
4947      }      }
4948  #endif  #endif
4949    #endif
4950    
4951    failure = 0;    failure = 0;
4952    immediate_quit = 1;    immediate_quit = 1;
# Line 4988  This does code conversion according to t Line 4959  This does code conversion according to t
4959      }      }
4960    else if (XINT (start) != XINT (end))    else if (XINT (start) != XINT (end))
4961      {      {
4962        tem = CHAR_TO_BYTE (XINT (start));        failure = 0 > a_write (desc, Qnil,
4963                                 XINT (start), XINT (end) - XINT (start),
4964        if (XINT (start) < GPT)                               &annotations, &coding);
4965          {        save_errno = errno;
           failure = 0 > a_write (desc, Qnil, XINT (start),  
                                  min (GPT, XINT (end)) - XINT (start),  
                                  &annotations, &coding);  
           save_errno = errno;  
         }  
   
       if (XINT (end) > GPT && !failure)  
         {  
           tem = max (XINT (start), GPT);  
           failure = 0 > a_write (desc, Qnil, tem , XINT (end) - tem,  
                                  &annotations, &coding);  
           save_errno = errno;  
         }  
4966      }      }
4967    else    else
4968      {      {
# Line 5020  This does code conversion according to t Line 4978  This does code conversion according to t
4978      {      {
4979        /* We have to flush out a data. */        /* We have to flush out a data. */
4980        coding.mode |= CODING_MODE_LAST_BLOCK;        coding.mode |= CODING_MODE_LAST_BLOCK;
4981        failure = 0 > e_write (desc, Qnil, 0, 0, &coding);        failure = 0 > e_write (desc, Qnil, 1, 1, &coding);
4982        save_errno = errno;        save_errno = errno;
4983      }      }
4984    
# Line 5196  build_annotations (start, end) Line 5154  build_annotations (start, end)
5154    return annotations;    return annotations;
5155  }  }
5156    
 static Lisp_Object  
 build_annotations_2 (start, end, pre_write_conversion, annotations)  
      Lisp_Object start, end, pre_write_conversion, annotations;  
 {  
   struct gcpro gcpro1;  
   Lisp_Object res;  
   
   GCPRO1 (annotations);  
   /* At last, do the same for the function PRE_WRITE_CONVERSION  
      implied by the current coding-system.  */  
   if (!NILP (pre_write_conversion))  
     {  
       struct buffer *given_buffer = current_buffer;  
       Vwrite_region_annotations_so_far = annotations;  
       res = call2 (pre_write_conversion, start, end);  
       Flength (res);  
       annotations = (current_buffer != given_buffer  
                      ? res  
                      : merge (annotations, res, Qcar_less_than_car));  
     }  
   
   UNGCPRO;  
   return annotations;  
 }  
5157    
5158  /* Write to descriptor DESC the NCHARS chars starting at POS of STRING.  /* Write to descriptor DESC the NCHARS chars starting at POS of STRING.
5159     If STRING is nil, POS is the character position in the current buffer.     If STRING is nil, POS is the character position in the current buffer.
# Line 5291  e_write (desc, string, start, end, codin Line 5225  e_write (desc, string, start, end, codin
5225       int start, end;       int start, end;
5226       struct coding_system *coding;       struct coding_system *coding;
5227  {  {
   register char *addr;  
   register int nbytes;  
   char buf[WRITE_BUF_SIZE];  
5228    int return_val = 0;    int return_val = 0;
5229    
   if (start >= end)  
     coding->composing = COMPOSITION_DISABLED;  
   if (coding->composing != COMPOSITION_DISABLED)  
     coding_save_composition (coding, start, end, string);  
   
5230    if (STRINGP (string))    if (STRINGP (string))
5231      {      {
5232        addr = XSTRING (string)->data;        start = 0;
5233        nbytes = STRING_BYTES (XSTRING (string));        end = XSTRING (string)->size;
       coding->src_multibyte = STRING_MULTIBYTE (string);  
     }  
   else if (start < end)  
     {  
       /* It is assured that the gap is not in the range START and END-1.  */  
       addr = CHAR_POS_ADDR (start);  
       nbytes = CHAR_TO_BYTE (end) - CHAR_TO_BYTE (start);  
       coding->src_multibyte  
         = !NILP (current_buffer->enable_multibyte_characters);  
     }  
   else  
     {  
       addr = "";  
       nbytes = 0;  
       coding->src_multibyte = 1;  
5234      }      }
5235    
5236      coding->mode |= CODING_MODE_FIXED_DESTINATION;
5237      if (! NILP (current_buffer->selective_display))
5238        coding->mode |= CODING_MODE_SELECTIVE_DISPLAY;
5239    
5240    /* We used to have a code for handling selective display here.  But,    /* We used to have a code for handling selective display here.  But,
5241       now it is handled within encode_coding.  */       now it is handled within encode_coding.  */
5242    while (1)    do
5243      {      {
5244        int result;        if (STRINGP (string))
5245            encode_coding_object (coding, string,
5246                                  start, string_char_to_byte (string, start),
5247                                  end, string_char_to_byte (string, end), Qt);
5248          else
5249            encode_coding_object (coding, Fcurrent_buffer (),
5250                                  start, CHAR_TO_BYTE (start),
5251                                  end, CHAR_TO_BYTE (end), Qt);
5252    
       result = encode_coding (coding, addr, buf, nbytes, WRITE_BUF_SIZE);  
5253        if (coding->produced > 0)        if (coding->produced > 0)
5254          {          {
5255            coding->produced -= emacs_write (desc, buf, coding->produced);            coding->produced -= emacs_write (desc,
5256                                               XSTRING (coding->dst_object)->data,
5257                                               coding->produced);
5258            if (coding->produced)            if (coding->produced)
5259              {              {
5260                return_val = -1;                return_val = -1;
5261                break;                break;
5262              }              }
5263          }          }
       nbytes -= coding->consumed;  
       addr += coding->consumed;  
       if (result == CODING_FINISH_INSUFFICIENT_SRC  
           && nbytes > 0)  
         {  
           /* The source text ends by an incomplete multibyte form.  
              There's no way other than write it out as is.  */  
           nbytes -= emacs_write (desc, addr, nbytes);  
           if (nbytes)  
             {  
               return_val = -1;  
               break;  
             }  
         }  
       if (nbytes <= 0)  
         break;  
5264        start += coding->consumed_char;        start += coding->consumed_char;
       if (coding->cmp_data)  
         coding_adjust_composition_offset (coding, start);  
5265      }      }
5266      while (start < end);
   if (coding->cmp_data)  
     coding_free_composition_data (coding);  
5267    
5268    return return_val;    return return_val;
5269  }  }

Legend:
Removed from v.1.439  
changed lines
  Added in v.1.439.2.1

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26