/[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.492 by monnier, Tue Jul 22 19:07:20 2003 UTC revision 1.492.2.1 by handa, Mon Sep 8 12:48:10 2003 UTC
# Line 75  extern int errno; Line 75  extern int errno;
75  #include "lisp.h"  #include "lisp.h"
76  #include "intervals.h"  #include "intervals.h"
77  #include "buffer.h"  #include "buffer.h"
78  #include "charset.h"  #include "character.h"
79  #include "coding.h"  #include "coding.h"
80  #include "window.h"  #include "window.h"
81    
# Line 295  restore_point_unwind (location) Line 295  restore_point_unwind (location)
295    Fset_marker (location, Qnil, Qnil);    Fset_marker (location, Qnil, Qnil);
296    return Qnil;    return Qnil;
297  }  }
298    
299    /* Kill the working buffer for code conversion.  */
300    
301    static Lisp_Object
302    kill_workbuf_unwind (workbuf)
303         Lisp_Object workbuf;
304    {
305      if (! NILP (workbuf) && ! NILP (Fbuffer_live_p (workbuf)))
306        Fkill_buffer (workbuf);
307      return Qnil;
308    }
309    
310  Lisp_Object Qexpand_file_name;  Lisp_Object Qexpand_file_name;
311  Lisp_Object Qsubstitute_in_file_name;  Lisp_Object Qsubstitute_in_file_name;
# Line 3632  actually used.  */) Line 3643  actually used.  */)
3643    unsigned char buffer[1 << 14];    unsigned char buffer[1 << 14];
3644    int replace_handled = 0;    int replace_handled = 0;
3645    int set_coding_system = 0;    int set_coding_system = 0;
3646    int coding_system_decided = 0;    Lisp_Object coding_system;
3647    int read_quit = 0;    int read_quit = 0;
3648    
3649    if (current_buffer->base_buffer && ! NILP (visit))    if (current_buffer->base_buffer && ! NILP (visit))
# Line 3650  actually used.  */) Line 3661  actually used.  */)
3661    CHECK_STRING (filename);    CHECK_STRING (filename);
3662    filename = Fexpand_file_name (filename, Qnil);    filename = Fexpand_file_name (filename, Qnil);
3663    
3664      /* The value Qnil means that the coding system is not yet
3665         decided.  */
3666      coding_system = Qnil;
3667    
3668    /* If the file name has special constructs in it,    /* If the file name has special constructs in it,
3669       call the corresponding file handler.  */       call the corresponding file handler.  */
3670    handler = Ffind_file_name_handler (filename, Qinsert_file_contents);    handler = Ffind_file_name_handler (filename, Qinsert_file_contents);
# Line 3773  actually used.  */) Line 3788  actually used.  */)
3788      }      }
3789    
3790    if (EQ (Vcoding_system_for_read, Qauto_save_coding))    if (EQ (Vcoding_system_for_read, Qauto_save_coding))
3791      {      coding_system = Qutf_8_emacs;
       /* We use emacs-mule for auto saving... */  
       setup_coding_system (Qemacs_mule, &coding);  
       /* ... but with the special flag to indicate to read in a  
          multibyte sequence for eight-bit-control char as is.  */  
       coding.flags = 1;  
       coding.src_multibyte = 0;  
       coding.dst_multibyte  
         = !NILP (current_buffer->enable_multibyte_characters);  
       coding.eol_type = CODING_EOL_LF;  
       coding_system_decided = 1;  
     }  
3792    else if (BEG < Z)    else if (BEG < Z)
3793      {      {
3794        /* Decide the coding system to use for reading the file now        /* Decide the coding system to use for reading the file now
3795           because we can't use an optimized method for handling           because we can't use an optimized method for handling
3796           `coding:' tag if the current buffer is not empty.  */           `coding:' tag if the current buffer is not empty.  */
       Lisp_Object val;  
       val = Qnil;  
   
3797        if (!NILP (Vcoding_system_for_read))        if (!NILP (Vcoding_system_for_read))
3798          val = Vcoding_system_for_read;          coding_system = Vcoding_system_for_read;
3799        else if (! NILP (replace))        else if (! NILP (replace))
3800          /* In REPLACE mode, we can use the same coding system          /* In REPLACE mode, we can use the same coding system
3801             that was used to visit the file.  */             that was used to visit the file.  */
3802          val = current_buffer->buffer_file_coding_system;          coding_system = current_buffer->buffer_file_coding_system;
3803        else        else
3804          {          {
3805            /* Don't try looking inside a file for a coding system            /* Don't try looking inside a file for a coding system
# Line 3854  actually used.  */) Line 3855  actually used.  */)
3855    
3856                    insert_1_both (read_buf, nread, nread, 0, 0, 0);                    insert_1_both (read_buf, nread, nread, 0, 0, 0);
3857                    TEMP_SET_PT_BOTH (BEG, BEG_BYTE);                    TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
3858                    val = call2 (Vset_auto_coding_function,                    coding_system = call2 (Vset_auto_coding_function,
3859                                 filename, make_number (nread));                                           filename, make_number (nread));
3860                    set_buffer_internal (prev);                    set_buffer_internal (prev);
3861    
3862                    /* Discard the unwind protect for recovering the                    /* Discard the unwind protect for recovering the
# Line 3869  actually used.  */) Line 3870  actually used.  */)
3870                  }                  }
3871              }              }
3872    
3873            if (NILP (val))            if (NILP (coding_system))
3874              {              {
3875                /* If we have not yet decided a coding system, check                /* If we have not yet decided a coding system, check
3876                   file-coding-system-alist.  */                   file-coding-system-alist.  */
3877                Lisp_Object args[6], coding_systems;                Lisp_Object args[6];
3878    
3879                args[0] = Qinsert_file_contents, args[1] = orig_filename;                args[0] = Qinsert_file_contents, args[1] = orig_filename;
3880                args[2] = visit, args[3] = beg, args[4] = end, args[5] = replace;                args[2] = visit, args[3] = beg, args[4] = end, args[5] = replace;
3881                coding_systems = Ffind_operation_coding_system (6, args);                coding_system = Ffind_operation_coding_system (6, args);
3882                if (CONSP (coding_systems))                if (CONSP (coding_system))
3883                  val = XCAR (coding_systems);                  coding_system = XCAR (coding_system);
3884              }              }
3885          }          }
3886    
3887        setup_coding_system (Fcheck_coding_system (val), &coding);        if (NILP (coding_system))
3888        /* Ensure we set Vlast_coding_system_used.  */          coding_system = Qundecided;
3889        set_coding_system = 1;        else
3890            CHECK_CODING_SYSTEM (coding_system);
3891    
3892        if (NILP (current_buffer->enable_multibyte_characters)        if (NILP (current_buffer->enable_multibyte_characters))
           && ! NILP (val))  
3893          /* We must suppress all character code conversion except for          /* We must suppress all character code conversion except for
3894             end-of-line conversion.  */             end-of-line conversion.  */
3895          setup_raw_text_coding_system (&coding);          coding_system = raw_text_coding_system (coding_system);
3896    
3897        coding.src_multibyte = 0;        setup_coding_system (coding_system, &coding);
3898        coding.dst_multibyte        /* Ensure we set Vlast_coding_system_used.  */
3899          = !NILP (current_buffer->enable_multibyte_characters);        set_coding_system = 1;
       coding_system_decided = 1;  
3900      }      }
3901    
3902    /* If requested, replace the accessible part of the buffer    /* If requested, replace the accessible part of the buffer
# Line 3915  actually used.  */) Line 3915  actually used.  */)
3915       and let the following if-statement handle the replace job.  */       and let the following if-statement handle the replace job.  */
3916    if (!NILP (replace)    if (!NILP (replace)
3917        && BEGV < ZV        && BEGV < ZV
3918        && !(coding.common_flags & CODING_REQUIRE_DECODING_MASK))        && (NILP (coding_system)
3919              || ! CODING_REQUIRE_DECODING (&coding)))
3920      {      {
3921        /* same_at_start and same_at_end count bytes,        /* same_at_start and same_at_end count bytes,
3922           because file access counts bytes           because file access counts bytes
# Line 3950  actually used.  */) Line 3951  actually used.  */)
3951            else if (nread == 0)            else if (nread == 0)
3952              break;              break;
3953    
3954            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.  */  
3955              {              {
3956                giveup_match_end = 1;                coding_system = detect_coding_system (buffer, nread, 1, 0,
3957                break;                                                      coding_system);
3958                  setup_coding_system (coding_system, &coding);
3959              }              }
3960    
3961            if (coding.eol_type == CODING_EOL_UNDECIDED)            if (CODING_REQUIRE_DECODING (&coding))
3962              detect_eol (&coding, buffer, nread);              /* We found that the file should be decoded somehow.
           if (coding.eol_type != CODING_EOL_UNDECIDED  
               && coding.eol_type != CODING_EOL_LF)  
             /* We found that the format of eol should be decoded.  
3963                 Let's give up here.  */                 Let's give up here.  */
3964              {              {
3965                giveup_match_end = 1;                giveup_match_end = 1;
# Line 4109  actually used.  */) Line 4104  actually used.  */)
4104      {      {
4105        int same_at_start = BEGV_BYTE;        int same_at_start = BEGV_BYTE;
4106        int same_at_end = ZV_BYTE;        int same_at_end = ZV_BYTE;
4107          int same_at_start_charpos;
4108          int inserted_chars;
4109        int overlap;        int overlap;
4110        int bufpos;        int bufpos;
4111        /* 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);  
4112        int temp;        int temp;
4113          int this_count = SPECPDL_INDEX ();
4114          int multibyte = ! NILP (current_buffer->enable_multibyte_characters);
4115          Lisp_Object conversion_buffer
4116            = make_conversion_work_buffer (-1, multibyte);
4117          struct gcpro1;
4118    
4119          record_unwind_protect (kill_workbuf_unwind, conversion_buffer);
4120    
4121        /* First read the whole file, performing code conversion into        /* First read the whole file, performing code conversion into
4122           CONVERSION_BUFFER.  */           CONVERSION_BUFFER.  */
4123    
4124        if (lseek (fd, XINT (beg), 0) < 0)        if (lseek (fd, XINT (beg), 0) < 0)
4125          {          report_file_error ("Setting file position",
4126            xfree (conversion_buffer);                             Fcons (orig_filename, Qnil));
           report_file_error ("Setting file position",  
                              Fcons (orig_filename, Qnil));  
         }  
4127    
4128        total = st.st_size;       /* Total bytes in the file.  */        total = st.st_size;       /* Total bytes in the file.  */
4129        how_much = 0;             /* Bytes read from file so far.  */        how_much = 0;             /* Bytes read from file so far.  */
4130        inserted = 0;             /* Bytes put into CONVERSION_BUFFER so far.  */        inserted = 0;             /* Bytes put into CONVERSION_BUFFER so far.  */
4131        unprocessed = 0;          /* Bytes not processed in previous loop.  */        unprocessed = 0;          /* Bytes not processed in previous loop.  */
4132    
4133          GCPRO1 (conversion_buffer);
4134        while (how_much < total)        while (how_much < total)
4135          {          {
4136              /* We read one bunch by one (READ_BUF_SIZE bytes) to allow
4137                 quitting while reading a huge while.  */
4138            /* try is reserved in some compilers (Microsoft C) */            /* try is reserved in some compilers (Microsoft C) */
4139            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;  
4140            int this;            int this;
4141    
4142            /* Allow quitting out of the actual I/O.  */            /* Allow quitting out of the actual I/O.  */
4143            immediate_quit = 1;            immediate_quit = 1;
4144            QUIT;            QUIT;
4145            this = emacs_read (fd, destination, trytry);            this = emacs_read (fd, read_buf + unprocessed, trytry);
4146            immediate_quit = 0;            immediate_quit = 0;
4147    
4148            if (this < 0 || this + unprocessed == 0)            if (this <= 0)
4149              {              {
4150                how_much = this;                if (this < 0)
4151                    how_much = this;
4152                break;                break;
4153              }              }
4154    
4155            how_much += this;            how_much += this;
4156    
4157            if (CODING_MAY_REQUIRE_DECODING (&coding))            BUF_SET_PT (XBUFFER (conversion_buffer),
4158              {                        BUF_Z (XBUFFER (conversion_buffer)));
4159                int require, result;            decode_coding_c_string (&coding, read_buf, unprocessed + this,
4160                                      conversion_buffer);
4161                this += unprocessed;            unprocessed = coding.carryover_bytes;
4162              if (coding.carryover_bytes > 0)
4163                /* If we are using more space than estimated,              bcopy (coding.carryover, read_buf, unprocessed);
                  make CONVERSION_BUFFER bigger.  */  
               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;  
4164          }          }
4165          UNGCPRO;
4166          emacs_close (fd);
4167    
4168        /* At this point, INSERTED is how many characters (i.e. bytes)        /* At this point, HOW_MUCH should equal TOTAL, or should be <= 0
4169           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.  */  
4170    
4171        if (how_much < 0)        if (how_much < 0)
4172          {          {
           xfree (conversion_buffer);  
   
4173            if (how_much == -1)            if (how_much == -1)
4174              error ("IO error reading %s: %s",              error ("IO error reading %s: %s",
4175                     SDATA (orig_filename), emacs_strerror (errno));                     SDATA (orig_filename), emacs_strerror (errno));
# Line 4205  actually used.  */) Line 4177  actually used.  */)
4177              error ("maximum buffer size exceeded");              error ("maximum buffer size exceeded");
4178          }          }
4179    
4180        /* Compare the beginning of the converted file        if (unprocessed > 0)
4181           with the buffer text.  */          {
4182              coding.mode |= CODING_MODE_LAST_BLOCK;
4183              decode_coding_c_string (&coding, read_buf, unprocessed,
4184                                      conversion_buffer);
4185              coding.mode &= ~CODING_MODE_LAST_BLOCK;
4186            }
4187    
4188          decoded = BUF_BEG_ADDR (XBUFFER (conversion_buffer));
4189          inserted = (BUF_Z_BYTE (XBUFFER (conversion_buffer))
4190                      - BUF_BEG_BYTE (XBUFFER (conversion_buffer)));
4191    
4192          /* Compare the beginning of the converted string with the buffer
4193             text.  */
4194    
4195        bufpos = 0;        bufpos = 0;
4196        while (bufpos < inserted && same_at_start < same_at_end        while (bufpos < inserted && same_at_start < same_at_end
4197               && FETCH_BYTE (same_at_start) == conversion_buffer[bufpos])               && FETCH_BYTE (same_at_start) == decoded[bufpos])
4198          same_at_start++, bufpos++;          same_at_start++, bufpos++;
4199    
4200        /* If the file matches the buffer completely,        /* If the file matches the head of buffer completely,
4201           there's no need to replace anything.  */           there's no need to replace anything.  */
4202    
4203        if (bufpos == inserted)        if (bufpos == inserted)
4204          {          {
           xfree (conversion_buffer);  
           emacs_close (fd);  
4205            specpdl_ptr--;            specpdl_ptr--;
4206            /* Truncate the buffer to the size of the file.  */            /* Truncate the buffer to the size of the file.  */
4207            del_range_byte (same_at_start, same_at_end, 0);            del_range_byte (same_at_start, same_at_end, 0);
# Line 4227  actually used.  */) Line 4209  actually used.  */)
4209            goto handled;            goto handled;
4210          }          }
4211    
4212        /* Extend the start of non-matching text area to multibyte        /* Extend the start of non-matching text area to the previous
4213           character boundary.  */           multibyte character boundary.  */
4214        if (! NILP (current_buffer->enable_multibyte_characters))        if (! NILP (current_buffer->enable_multibyte_characters))
4215          while (same_at_start > BEGV_BYTE          while (same_at_start > BEGV_BYTE
4216                 && ! CHAR_HEAD_P (FETCH_BYTE (same_at_start)))                 && ! CHAR_HEAD_P (FETCH_BYTE (same_at_start)))
# Line 4241  actually used.  */) Line 4223  actually used.  */)
4223        /* Compare with same_at_start to avoid counting some buffer text        /* Compare with same_at_start to avoid counting some buffer text
4224           as matching both at the file's beginning and at the end.  */           as matching both at the file's beginning and at the end.  */
4225        while (bufpos > 0 && same_at_end > same_at_start        while (bufpos > 0 && same_at_end > same_at_start
4226               && FETCH_BYTE (same_at_end - 1) == conversion_buffer[bufpos - 1])               && FETCH_BYTE (same_at_end - 1) == decoded[bufpos - 1])
4227          same_at_end--, bufpos--;          same_at_end--, bufpos--;
4228    
4229        /* Extend the end of non-matching text area to multibyte        /* Extend the end of non-matching text area to the next
4230           character boundary.  */           multibyte character boundary.  */
4231        if (! NILP (current_buffer->enable_multibyte_characters))        if (! NILP (current_buffer->enable_multibyte_characters))
4232          while (same_at_end < ZV_BYTE          while (same_at_end < ZV_BYTE
4233                 && ! CHAR_HEAD_P (FETCH_BYTE (same_at_end)))                 && ! CHAR_HEAD_P (FETCH_BYTE (same_at_end)))
# Line 4263  actually used.  */) Line 4245  actually used.  */)
4245    
4246        /* Replace the chars that we need to replace,        /* Replace the chars that we need to replace,
4247           and update INSERTED to equal the number of bytes           and update INSERTED to equal the number of bytes
4248           we are taking from the file.  */           we are taking from the decoded string.  */
4249        inserted -= (Z_BYTE - same_at_end) + (same_at_start - BEG_BYTE);        inserted -= (Z_BYTE - same_at_end) + (same_at_start - BEG_BYTE);
4250    
4251        if (same_at_end != same_at_start)        if (same_at_end != same_at_start)
# Line 4278  actually used.  */) Line 4260  actually used.  */)
4260          }          }
4261        /* Insert from the file at the proper position.  */        /* Insert from the file at the proper position.  */
4262        SET_PT_BOTH (temp, same_at_start);        SET_PT_BOTH (temp, same_at_start);
4263        insert_1 (conversion_buffer + same_at_start - BEG_BYTE, inserted,        same_at_start_charpos
4264                  0, 0, 0);          = buf_bytepos_to_charpos (XBUFFER (conversion_buffer),
4265        if (coding.cmp_data && coding.cmp_data->used)                                    same_at_start);
4266          coding_restore_composition (&coding, Fcurrent_buffer ());        inserted_chars
4267        coding_free_composition_data (&coding);          = (buf_bytepos_to_charpos (XBUFFER (conversion_buffer),
4268                                       same_at_start + inserted)
4269               - same_at_start_charpos);
4270          insert_from_buffer (XBUFFER (conversion_buffer),
4271                              same_at_start_charpos, inserted_chars, 0);
4272        /* Set `inserted' to the number of inserted characters.  */        /* Set `inserted' to the number of inserted characters.  */
4273        inserted = PT - temp;        inserted = PT - temp;
4274    
4275        xfree (conversion_buffer);        unbind_to (this_count, Qnil);
       emacs_close (fd);  
       specpdl_ptr--;  
4276    
4277        goto handled;        goto handled;
4278      }      }
# Line 4333  actually used.  */) Line 4316  actually used.  */)
4316    inserted = 0;    inserted = 0;
4317    
4318    /* 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
4319       code_convert_region after all data are read into the buffer.  */       decode_coding_gap after all data are read into the buffer.  */
4320    {    {
4321      int gap_size = GAP_SIZE;      int gap_size = GAP_SIZE;
4322    
# Line 4424  actually used.  */) Line 4407  actually used.  */)
4407    
4408   notfound:   notfound:
4409    
4410    if (! coding_system_decided)    if (NILP (coding_system))
4411      {      {
4412        /* The coding system is not yet decided.  Decide it by an        /* The coding system is not yet decided.  Decide it by an
4413           optimized method for handling `coding:' tag.           optimized method for handling `coding:' tag.
4414    
4415           Note that we can get here only if the buffer was empty           Note that we can get here only if the buffer was empty
4416           before the insertion.  */           before the insertion.  */
       Lisp_Object val;  
       val = Qnil;  
4417    
4418        if (!NILP (Vcoding_system_for_read))        if (!NILP (Vcoding_system_for_read))
4419          val = Vcoding_system_for_read;          coding_system = Vcoding_system_for_read;
4420        else        else
4421          {          {
4422            /* Since we are sure that the current buffer was empty            /* Since we are sure that the current buffer was empty
# Line 4456  actually used.  */) Line 4437  actually used.  */)
4437    
4438            if (inserted > 0 && ! NILP (Vset_auto_coding_function))            if (inserted > 0 && ! NILP (Vset_auto_coding_function))
4439              {              {
4440                val = call2 (Vset_auto_coding_function,                coding_system = call2 (Vset_auto_coding_function,
4441                             filename, make_number (inserted));                                       filename, make_number (inserted));
4442              }              }
4443    
4444            if (NILP (val))            if (NILP (coding_system))
4445              {              {
4446                /* If the coding system is not yet decided, check                /* If the coding system is not yet decided, check
4447                   file-coding-system-alist.  */                   file-coding-system-alist.  */
4448                Lisp_Object args[6], coding_systems;                Lisp_Object args[6];
4449    
4450                args[0] = Qinsert_file_contents, args[1] = orig_filename;                args[0] = Qinsert_file_contents, args[1] = orig_filename;
4451                args[2] = visit, args[3] = beg, args[4] = end, args[5] = Qnil;                args[2] = visit, args[3] = beg, args[4] = end, args[5] = Qnil;
4452                coding_systems = Ffind_operation_coding_system (6, args);                coding_system = Ffind_operation_coding_system (6, args);
4453                if (CONSP (coding_systems))                if (CONSP (coding_system))
4454                  val = XCAR (coding_systems);                  coding_system = XCAR (coding_system);
4455              }              }
4456    
4457            unbind_to (count, Qnil);            unbind_to (count, Qnil);
4458            inserted = Z_BYTE - BEG_BYTE;            inserted = Z_BYTE - BEG_BYTE;
4459          }          }
4460    
4461        /* The following kludgy code is to avoid some compiler bug.        if (NILP (coding_system))
4462           We can't simply do          coding_system = Qundecided;
4463           setup_coding_system (val, &coding);        else
4464           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;  
4465    
4466        if (NILP (current_buffer->enable_multibyte_characters)        if (NILP (current_buffer->enable_multibyte_characters))
           && ! NILP (val))  
4467          /* We must suppress all character code conversion except for          /* We must suppress all character code conversion except for
4468             end-of-line conversion.  */             end-of-line conversion.  */
4469          setup_raw_text_coding_system (&coding);          coding_system = raw_text_coding_system (coding_system);
4470        coding.src_multibyte = 0;        setup_coding_system (coding_system, &coding);
4471        coding.dst_multibyte        /* Ensure we set Vlast_coding_system_used.  */
4472          = !NILP (current_buffer->enable_multibyte_characters);        set_coding_system = 1;
4473      }      }
4474    
4475    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))  
4476      {      {
4477        /* Visiting a file with these coding system makes the buffer        /* When we visit a file by raw-text, we change the buffer to
4478           unibyte. */           unibyte.  If we have not yet decided how to decode a text,
4479        current_buffer->enable_multibyte_characters = Qnil;           decide it at first by detecting the file's encoding.  */
4480        coding.dst_multibyte = 0;        if (CODING_REQUIRE_DETECTION (&coding))
4481      }          {
4482              coding_system = detect_coding_system (PT_ADDR, inserted, 1, 0,
4483    if (inserted > 0 || coding.type == coding_type_ccl)                                                  coding_system);
4484              setup_coding_system (coding_system, &coding);
4485            }
4486    
4487          if (CODING_FOR_UNIBYTE (&coding)
4488              /* Can't do this if part of the buffer might be preserved.  */
4489              && NILP (replace))
4490            /* Visiting a file with these coding system makes the buffer
4491               unibyte. */
4492            current_buffer->enable_multibyte_characters = Qnil;
4493        }
4494    
4495      coding.dst_multibyte = ! NILP (current_buffer->enable_multibyte_characters);
4496      if ((CODING_REQUIRE_DETECTION (&coding)
4497           || CODING_REQUIRE_DECODING (&coding))
4498          && (inserted > 0 || CODING_REQUIRE_FLUSHING (&coding)))
4499      {      {
4500        if (CODING_MAY_REQUIRE_DECODING (&coding))        move_gap_both (PT, PT_BYTE);
4501          {        GAP_SIZE += inserted;
4502            code_convert_region (PT, PT_BYTE, PT + inserted, PT_BYTE + inserted,        ZV_BYTE -= inserted;
4503                                 &coding, 0, 0);        Z_BYTE -= inserted;
4504            inserted = coding.produced_char;        ZV -= inserted;
4505          }        Z -= inserted;
4506        else        decode_coding_gap (&coding, inserted, inserted);
4507          adjust_after_insert (PT, PT_BYTE, PT + inserted, PT_BYTE + inserted,        inserted = coding.produced_char;
4508                               inserted);      }
4509      }    else if (inserted > 0)
4510        adjust_after_insert (PT, PT_BYTE, PT + inserted, PT_BYTE + inserted,
4511                             inserted);
4512    
4513    /* Now INSERTED is measured in characters.  */    /* Now INSERTED is measured in characters.  */
4514    
# Line 4530  actually used.  */) Line 4516  actually used.  */)
4516    /* Use the conversion type to determine buffer-file-type    /* Use the conversion type to determine buffer-file-type
4517       (find-buffer-file-type is now used to help determine the       (find-buffer-file-type is now used to help determine the
4518       conversion).  */       conversion).  */
4519    if ((coding.eol_type == CODING_EOL_UNDECIDED    if ((coding.eol_type == eol_type_undecided
4520         || coding.eol_type == CODING_EOL_LF)         || coding.eol_type == eol_type_lf)
4521        && ! CODING_REQUIRE_DECODING (&coding))        && ! CODING_REQUIRE_DECODING (&coding))
4522      current_buffer->buffer_file_type = Qt;      current_buffer->buffer_file_type = Qt;
4523    else    else
# Line 4572  actually used.  */) Line 4558  actually used.  */)
4558      }      }
4559    
4560    if (set_coding_system)    if (set_coding_system)
4561      Vlast_coding_system_used = coding.symbol;      Vlast_coding_system_used = coding_system;
4562    
4563    if (! NILP (Ffboundp (Qafter_insert_file_set_coding)))    if (! NILP (Ffboundp (Qafter_insert_file_set_coding)))
4564      {      {
# Line 4650  actually used.  */) Line 4636  actually used.  */)
4636  }  }
4637    
4638  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));  
4639    
4640  /* If build_annotations switched buffers, switch back to BUF.  /* If build_annotations switched buffers, switch back to BUF.
4641     Kill the temporary buffer that was selected in the meantime.     Kill the temporary buffer that was selected in the meantime.
# Line 4676  build_annotations_unwind (buf) Line 4660  build_annotations_unwind (buf)
4660    
4661  /* Decide the coding-system to encode the data with.  */  /* Decide the coding-system to encode the data with.  */
4662    
4663  void  static Lisp_Object
4664  choose_write_coding_system (start, end, filename,  choose_write_coding_system (start, end, filename,
4665                              append, visit, lockname, coding)                              append, visit, lockname, coding)
4666       Lisp_Object start, end, filename, append, visit, lockname;       Lisp_Object start, end, filename, append, visit, lockname;
# Line 4685  choose_write_coding_system (start, end, Line 4669  choose_write_coding_system (start, end,
4669    Lisp_Object val;    Lisp_Object val;
4670    
4671    if (auto_saving)    if (auto_saving)
4672      {      val = Qutf_8_emacs;
       /* We use emacs-mule for auto saving... */  
       setup_coding_system (Qemacs_mule, coding);  
       /* ... but with the special flag to indicate not to strip off  
          leading code of eight-bit-control chars.  */  
       coding->flags = 1;  
       goto done_setup_coding;  
     }  
4673    else if (!NILP (Vcoding_system_for_write))    else if (!NILP (Vcoding_system_for_write))
4674      {      {
4675        val = Vcoding_system_for_write;        val = Vcoding_system_for_write;
# Line 4739  choose_write_coding_system (start, end, Line 4716  choose_write_coding_system (start, end,
4716              val = XCDR (coding_systems);              val = XCDR (coding_systems);
4717          }          }
4718    
4719        if (NILP (val)        if (NILP (val))
           && !NILP (current_buffer->buffer_file_coding_system))  
4720          {          {
4721            /* If we still have not decided a coding system, use the            /* If we still have not decided a coding system, use the
4722               default value of buffer-file-coding-system.  */               default value of buffer-file-coding-system.  */
# Line 4748  choose_write_coding_system (start, end, Line 4724  choose_write_coding_system (start, end,
4724            using_default_coding = 1;            using_default_coding = 1;
4725          }          }
4726    
4727          if (! NILP (val) && ! force_raw_text)
4728            {
4729              Lisp_Object spec, attrs;
4730    
4731              CHECK_CODING_SYSTEM_GET_SPEC (val, spec);
4732              attrs = AREF (spec, 0);
4733              if (EQ (CODING_ATTR_TYPE (attrs), Qraw_text))
4734                force_raw_text = 1;
4735            }
4736    
4737        if (!force_raw_text        if (!force_raw_text
4738            && !NILP (Ffboundp (Vselect_safe_coding_system_function)))            && !NILP (Ffboundp (Vselect_safe_coding_system_function)))
4739          /* Confirm that VAL can surely encode the current region.  */          /* Confirm that VAL can surely encode the current region.  */
4740          val = call5 (Vselect_safe_coding_system_function,          val = call5 (Vselect_safe_coding_system_function,
4741                       start, end, val, Qnil, filename);                       start, end, val, Qnil, filename);
4742    
4743        setup_coding_system (Fcheck_coding_system (val), coding);        /* If the decided coding-system doesn't specify end-of-line
4744        if (coding->eol_type == CODING_EOL_UNDECIDED           format, we use that of
4745            && !using_default_coding)           `default-buffer-file-coding-system'.  */
4746          {        if (! using_default_coding
4747            if (! EQ (default_buffer_file_coding.symbol,            && ! NILP (buffer_defaults.buffer_file_coding_system))
4748                      buffer_defaults.buffer_file_coding_system))          val = (coding_inherit_eol_type
4749              setup_coding_system (buffer_defaults.buffer_file_coding_system,                 (val, 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];  
             }  
         }  
4750    
4751          /* If we decide not to encode text, use `raw-text' or one of its
4752             subsidiaries.  */
4753        if (force_raw_text)        if (force_raw_text)
4754          setup_raw_text_coding_system (coding);          val = raw_text_coding_system (val);
       goto done_setup_coding;  
4755      }      }
4756    
4757    setup_coding_system (Fcheck_coding_system (val), coding);    setup_coding_system (val, coding);
4758      if (! NILP (val)
4759          && VECTORP (CODING_ID_EOL_TYPE (coding->id)))
4760        val = AREF (CODING_ID_EOL_TYPE (coding->id), 0);
4761    
  done_setup_coding:  
4762    if (!STRINGP (start) && !NILP (current_buffer->selective_display))    if (!STRINGP (start) && !NILP (current_buffer->selective_display))
4763      coding->mode |= CODING_MODE_SELECTIVE_DISPLAY;      coding->mode |= CODING_MODE_SELECTIVE_DISPLAY;
4764      return val;
4765  }  }
4766    
4767  DEFUN ("write-region", Fwrite_region, Swrite_region, 3, 7,  DEFUN ("write-region", Fwrite_region, Swrite_region, 3, 7,
# Line 4928  This does code conversion according to t Line 4905  This does code conversion according to t
4905       We used to make this choice before calling build_annotations, but that       We used to make this choice before calling build_annotations, but that
4906       leads to problems when a write-annotate-function takes care of       leads to problems when a write-annotate-function takes care of
4907       unsavable chars (as was the case with X-Symbol).  */       unsavable chars (as was the case with X-Symbol).  */
4908    choose_write_coding_system (start, end, filename,    Vlast_coding_system_used
4909                                append, visit, lockname, &coding);      = choose_write_coding_system (start, end, filename,
4910    Vlast_coding_system_used = coding.symbol;                                    append, visit, lockname, &coding);
   
   given_buffer = current_buffer;  
   if (! STRINGP (start))  
     {  
       annotations = build_annotations_2 (start, end,  
                                          coding.pre_write_conversion, annotations);  
       if (current_buffer != given_buffer)  
         {  
           XSETFASTINT (start, BEGV);  
           XSETFASTINT (end, ZV);  
         }  
     }  
4911    
4912  #ifdef CLASH_DETECTION  #ifdef CLASH_DETECTION
4913    if (!auto_saving)    if (!auto_saving)
# Line 5080  This does code conversion according to t Line 5045  This does code conversion according to t
5045    if (GPT > BEG && GPT_ADDR[-1] != '\n')    if (GPT > BEG && GPT_ADDR[-1] != '\n')
5046      move_gap (find_next_newline (GPT, 1));      move_gap (find_next_newline (GPT, 1));
5047  #else  #else
5048    #if 0
5049      /* The new encoding routine doesn't require the following.  */
5050    
5051    /* 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
5052       when we must put designation sequences at beginning of line.  */       when we must put designation sequences at beginning of line.  */
5053    if (INTEGERP (start)    if (INTEGERP (start)
# Line 5093  This does code conversion according to t Line 5061  This does code conversion according to t
5061        SET_PT_BOTH (opoint, opoint_byte);        SET_PT_BOTH (opoint, opoint_byte);
5062      }      }
5063  #endif  #endif
5064    #endif
5065    
5066    failure = 0;    failure = 0;
5067    immediate_quit = 1;    immediate_quit = 1;
# Line 5105  This does code conversion according to t Line 5074  This does code conversion according to t
5074      }      }
5075    else if (XINT (start) != XINT (end))    else if (XINT (start) != XINT (end))
5076      {      {
5077        tem = CHAR_TO_BYTE (XINT (start));        failure = 0 > a_write (desc, Qnil,
5078                                 XINT (start), XINT (end) - XINT (start),
5079        if (XINT (start) < GPT)                               &annotations, &coding);
5080          {        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;  
         }  
5081      }      }
5082    else    else
5083      {      {
# Line 5137  This does code conversion according to t Line 5093  This does code conversion according to t
5093      {      {
5094        /* We have to flush out a data. */        /* We have to flush out a data. */
5095        coding.mode |= CODING_MODE_LAST_BLOCK;        coding.mode |= CODING_MODE_LAST_BLOCK;
5096        failure = 0 > e_write (desc, Qnil, 0, 0, &coding);        failure = 0 > e_write (desc, Qnil, 1, 1, &coding);
5097        save_errno = errno;        save_errno = errno;
5098      }      }
5099    
# Line 5327  build_annotations (start, end) Line 5283  build_annotations (start, end)
5283    return annotations;    return annotations;
5284  }  }
5285    
 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;  
 }  
5286    
5287  /* Write to descriptor DESC the NCHARS chars starting at POS of STRING.  /* Write to descriptor DESC the NCHARS chars starting at POS of STRING.
5288     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 5422  e_write (desc, string, start, end, codin Line 5354  e_write (desc, string, start, end, codin
5354       int start, end;       int start, end;
5355       struct coding_system *coding;       struct coding_system *coding;
5356  {  {
   register char *addr;  
   register int nbytes;  
   char buf[WRITE_BUF_SIZE];  
5357    int return_val = 0;    int return_val = 0;
5358    
   if (start >= end)  
     coding->composing = COMPOSITION_DISABLED;  
   if (coding->composing != COMPOSITION_DISABLED)  
     coding_save_composition (coding, start, end, string);  
   
5359    if (STRINGP (string))    if (STRINGP (string))
5360      {      {
5361        addr = SDATA (string);        start = 0;
5362        nbytes = SBYTES (string);        end = SCHARS (string);
       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;  
5363      }      }
5364    
5365    /* We used to have a code for handling selective display here.  But,    /* We used to have a code for handling selective display here.  But,
5366       now it is handled within encode_coding.  */       now it is handled within encode_coding.  */
5367    while (1)    do
5368      {      {
5369        int result;        if (STRINGP (string))
5370            encode_coding_object (coding, string,
5371                                  start, string_char_to_byte (string, start),
5372                                  end, string_char_to_byte (string, end), Qt);
5373          else
5374            encode_coding_object (coding, Fcurrent_buffer (),
5375                                  start, CHAR_TO_BYTE (start),
5376                                  end, CHAR_TO_BYTE (end), Qt);
5377    
       result = encode_coding (coding, addr, buf, nbytes, WRITE_BUF_SIZE);  
5378        if (coding->produced > 0)        if (coding->produced > 0)
5379          {          {
5380            coding->produced -= emacs_write (desc, buf, coding->produced);            coding->produced -= emacs_write (desc, SDATA (coding->dst_object),
5381                                               coding->produced);
5382    
5383            if (coding->produced)            if (coding->produced)
5384              {              {
5385                return_val = -1;                return_val = -1;
5386                break;                break;
5387              }              }
5388          }          }
       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;  
5389        start += coding->consumed_char;        start += coding->consumed_char;
       if (coding->cmp_data)  
         coding_adjust_composition_offset (coding, start);  
5390      }      }
5391      while (start < end);
   if (coding->cmp_data)  
     coding_free_composition_data (coding);  
5392    
5393    return return_val;    return return_val;
5394  }  }

Legend:
Removed from v.1.492  
changed lines
  Added in v.1.492.2.1

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