(detect_coding_iso2022): Do not exclude posibility of
[bpt/emacs.git] / src / fileio.c
index f59df5f..9ad7a42 100644 (file)
@@ -1,5 +1,5 @@
 /* File IO for GNU Emacs.
-   Copyright (C) 1985,86,87,88,93,94,95,96 Free Software Foundation, Inc.
+   Copyright (C) 1985,86,87,88,93,94,95,96,1997 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -198,6 +198,8 @@ extern Lisp_Object Vuser_login_name;
 
 extern int minibuf_level;
 
+extern int minibuffer_auto_raise;
+
 /* These variables describe handlers that have "already" had a chance
    to handle the current operation.
 
@@ -3063,10 +3065,13 @@ This does code conversion according to the value of\n\
 
   /* Decide the coding-system of the file.  */
   {
-    Lisp_Object val = Vcoding_system_for_read;
-    if (NILP (current_buffer->enable_multibyte_characters))
-      val = Qnil;
-    else if (NILP (val))
+    Lisp_Object val;
+
+    if (!NILP (Vcoding_system_for_read))
+      val = Vcoding_system_for_read;
+    else if (NILP (current_buffer->enable_multibyte_characters))
+      val = Qemacs_mule;
+    else
       {
        Lisp_Object args[6], coding_systems;
 
@@ -3078,6 +3083,16 @@ This does code conversion according to the value of\n\
     setup_coding_system (Fcheck_coding_system (val), &coding);
   }
 
+#ifdef DOS_NT
+  /* Use the conversion type to determine buffer-file-type
+     (find-buffer-file-type is now used to help determine the
+     conversion).  */
+  if (coding.type == coding_type_no_conversion)
+    current_buffer->buffer_file_type = Qt;
+  else
+    current_buffer->buffer_file_type = Qnil;
+#endif
+
   fd = -1;
 
 #ifndef APOLLO
@@ -3164,11 +3179,7 @@ This does code conversion according to the value of\n\
      But if we discover the need for conversion, we give up on this method
      and let the following if-statement handle the replace job.  */
   if (!NILP (replace)
-      && (! CODING_REQUIRE_CONVERSION (&coding)
-         || (coding.type == coding_type_undecided
-             && ! CODING_REQUIRE_EOL_CONVERSION (&coding))
-         || (coding.eol_type == CODING_EOL_UNDECIDED
-             && ! CODING_REQUIRE_TEXT_CONVERSION (&coding))))
+      && CODING_MAY_REQUIRE_NO_CONVERSION (&coding))
     {
       int same_at_start = BEGV;
       int same_at_end = ZV;
@@ -3203,7 +3214,8 @@ This does code conversion according to the value of\n\
          if (coding.type == coding_type_undecided)
            detect_coding (&coding, buffer, nread);
          if (coding.type != coding_type_undecided
-             && CODING_REQUIRE_TEXT_CONVERSION (&coding))
+             && coding.type != coding_type_no_conversion
+             && coding.type != coding_type_emacs_mule)
            /* We found that the file should be decoded somehow.
                Let's give up here.  */
            {
@@ -3214,7 +3226,7 @@ This does code conversion according to the value of\n\
          if (coding.eol_type == CODING_EOL_UNDECIDED)
            detect_eol (&coding, buffer, nread);
          if (coding.eol_type != CODING_EOL_UNDECIDED
-             && CODING_REQUIRE_EOL_CONVERSION (&coding))
+             && coding.eol_type != CODING_EOL_LF)
            /* We found that the format of eol should be decoded.
                Let's give up here.  */
            {
@@ -3288,7 +3300,8 @@ This does code conversion according to the value of\n\
                 we cannot use this method; giveup and try the other.  */
              if (same_at_end > same_at_start
                  && FETCH_BYTE (same_at_end - 1) >= 0200
-                 && ! NILP (current_buffer->enable_multibyte_characters))
+                 && ! NILP (current_buffer->enable_multibyte_characters)
+                 && ! CODING_REQUIRE_NO_CONVERSION (&coding))
                giveup_match_end = 1;
              break;
            }
@@ -3299,6 +3312,12 @@ This does code conversion according to the value of\n\
        {
          /* We win!  We can handle REPLACE the optimized way.  */
 
+         /* Extends the end of non-matching text area to multibyte
+             character boundary.  */
+         if (! NILP (current_buffer->enable_multibyte_characters))
+           while (same_at_end < ZV && ! CHAR_HEAD_P (POS_ADDR (same_at_end)))
+             same_at_end++;
+
          /* Don't try to reuse the same piece of text twice.  */
          overlap = same_at_start - BEGV - (same_at_end + st.st_size - ZV);
          if (overlap > 0)
@@ -3376,7 +3395,7 @@ This does code conversion according to the value of\n\
 
          how_much += this;
 
-         if (CODING_REQUIRE_CONVERSION (&coding))
+         if (! CODING_REQUIRE_NO_CONVERSION (&coding))
            {
              int require, produced, consumed;
 
@@ -3521,9 +3540,9 @@ This does code conversion according to the value of\n\
     {
        /* try is reserved in some compilers (Microsoft C) */
       int trytry = min (total - how_much, READ_BUF_SIZE - unprocessed);
-      char *destination = (CODING_REQUIRE_CONVERSION (&coding)
-                          ? read_buf + unprocessed
-                          : (char *) (POS_ADDR (PT + inserted - 1) + 1));
+      char *destination = (CODING_REQUIRE_NO_CONVERSION (&coding)
+                          ? (char *) (POS_ADDR (PT + inserted - 1) + 1)
+                          : read_buf + unprocessed);
       int this;
 
       /* Allow quitting out of the actual I/O.  */
@@ -3546,7 +3565,7 @@ This does code conversion according to the value of\n\
       if (! not_regular)
        how_much += this;
 
-      if (CODING_REQUIRE_CONVERSION (&coding))
+      if (! CODING_REQUIRE_NO_CONVERSION (&coding))
        {
          int require, produced, consumed;
 
@@ -3726,6 +3745,7 @@ This does code conversion according to the value of\n\
 }
 \f
 static Lisp_Object build_annotations ();
+extern Lisp_Object Ffile_locked_p ();
 
 /* If build_annotations switched buffers, switch back to BUF.
    Kill the temporary buffer that was selected in the meantime.
@@ -3788,8 +3808,7 @@ to the file, instead of any buffer contents, and END is ignored.")
   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
   struct buffer *given_buffer;
 #ifdef DOS_NT
-  int buffer_file_type
-    = NILP (current_buffer->buffer_file_type) ? O_TEXT : O_BINARY;
+  int buffer_file_type = O_BINARY;
 #endif /* DOS_NT */
   struct coding_system coding;
 
@@ -3805,13 +3824,14 @@ to the file, instead of any buffer contents, and END is ignored.")
   {
     Lisp_Object val;
 
-    if (auto_saving || NILP (current_buffer->enable_multibyte_characters))
+    if (auto_saving)
       val = Qnil;
     else if (!NILP (Vcoding_system_for_write))
       val = Vcoding_system_for_write;
-    else if (!NILP (Flocal_variable_if_set_p (Qbuffer_file_coding_system,
-                                             Qnil)))
-      val = Fsymbol_value (Qbuffer_file_coding_system);
+    else if (NILP (current_buffer->enable_multibyte_characters))
+      val = (NILP (Flocal_variable_p (Qbuffer_file_coding_system, Qnil))
+            ? Qnil
+            : Fsymbol_value (Qbuffer_file_coding_system));
     else
       {
        Lisp_Object args[7], coding_systems;
@@ -3820,17 +3840,13 @@ to the file, instead of any buffer contents, and END is ignored.")
          args[3] = filename, args[4] = append, args[5] = visit,
          args[6] = lockname;
        coding_systems = Ffind_operation_coding_system (7, args);
-       val = (CONSP (coding_systems)
+       val = (CONSP (coding_systems) && !NILP (XCONS (coding_systems)->cdr)
               ? XCONS (coding_systems)->cdr
               : current_buffer->buffer_file_coding_system);
       }
     setup_coding_system (Fcheck_coding_system (val), &coding); 
     if (!STRINGP (start) && !NILP (current_buffer->selective_display))
       coding.selective = 1;
-#ifdef DOS_NT
-    if (!NILP (current_buffer->buffer_file_type))
-      coding.eol_type = CODING_EOL_LF;
-#endif /* DOS_NT */
   }
 
   filename = Fexpand_file_name (filename, Qnil);
@@ -3897,7 +3913,7 @@ to the file, instead of any buffer contents, and END is ignored.")
       /* If we've locked this file for some other buffer,
         query before proceeding.  */
       if (!visiting && EQ (Ffile_locked_p (lockname), Qt))
-       call2 (intern ("ask-user-about-lock"), fn, Vuser_login_name);
+       call2 (intern ("ask-user-about-lock"), filename, Vuser_login_name);
 
       lock_file (lockname);
     }
@@ -4060,7 +4076,7 @@ to the file, instead of any buffer contents, and END is ignored.")
       save_errno = errno;
     }
 
-  if (coding.require_flushing)
+  if (coding.require_flushing && !coding.last_block)
     {
       /* We have to flush out a data. */
       coding.last_block = 1;
@@ -4464,6 +4480,14 @@ do_auto_save_unwind (stream)  /* used as unwind-protect function */
   return Qnil;
 }
 
+static Lisp_Object
+do_auto_save_unwind_1 (value)  /* used as unwind-protect function */
+     Lisp_Object value;
+{
+  minibuffer_auto_raise = XINT (value);
+  return Qnil;
+}
+
 DEFUN ("do-auto-save", Fdo_auto_save, Sdo_auto_save, 0, 2, "",
   "Auto-save all buffers that need it.\n\
 This is all buffers that have auto-saving enabled\n\
@@ -4488,6 +4512,7 @@ A non-nil CURRENT-ONLY argument means save only current buffer.")
   Lisp_Object lispstream;
   int count = specpdl_ptr - specpdl;
   int *ptr;
+  int orig_minibuffer_auto_raise = minibuffer_auto_raise;
 
   /* Ordinarily don't quit within this function,
      but don't make it impossible to quit (in case we get hung in I/O).  */
@@ -4522,7 +4547,9 @@ A non-nil CURRENT-ONLY argument means save only current buffer.")
     }
 
   record_unwind_protect (do_auto_save_unwind, lispstream);
-
+  record_unwind_protect (do_auto_save_unwind_1,
+                        make_number (minibuffer_auto_raise));
+  minibuffer_auto_raise = 0;
   auto_saving = 1;
 
   /* First, save all files which don't have handlers.  If Emacs is
@@ -4593,8 +4620,10 @@ A non-nil CURRENT-ONLY argument means save only current buffer.")
                && NILP (no_message))
              {
                /* It has shrunk too much; turn off auto-saving here.  */
+               minibuffer_auto_raise = orig_minibuffer_auto_raise;
                message ("Buffer %s has shrunk a lot; auto save turned off there",
                         XSTRING (b->name)->data);
+               minibuffer_auto_raise = 0;
                /* Turn off auto-saving until there's a real save,
                   and prevent any more warnings.  */
                XSETINT (b->save_length, -1);
@@ -4841,7 +4870,7 @@ DIR defaults to current buffer's directory default.")
   else if (STRINGP (initial))
     {
       insdef = initial;
-      insdef1 = Fcons (double_dollars (insdef), 0);
+      insdef1 = Fcons (double_dollars (insdef), make_number (0));
     }
   else
     insdef = Qnil, insdef1 = Qnil;
@@ -4855,6 +4884,13 @@ DIR defaults to current buffer's directory default.")
   val = Fcompleting_read (prompt, intern ("read-file-name-internal"),
                          dir, mustmatch, insdef1,
                          Qfile_name_history, default_filename);
+  /* If Fcompleting_read returned the default string itself
+     (rather than a new string with the same contents),
+     it has to mean that the user typed RET with the minibuffer empty.
+     In that case, we really want to return ""
+     so that commands such as set-visited-file-name can distinguish.  */
+  if (EQ (val, default_filename))
+    val = build_string ("");
 
 #ifdef VMS
   unbind_to (count, Qnil);
@@ -5065,7 +5101,7 @@ The value should be either ?/ or ?\\ (any other value is treated as ?\\).\n\
 This variable affects the built-in functions only on Windows,\n\
 on other platforms, it is initialized so that Lisp code can find out\n\
 what the normal separator is.");
-  Vdirectory_sep_char = '/';
+  XSETFASTINT (Vdirectory_sep_char, '/');
 
   DEFVAR_LISP ("file-name-handler-alist", &Vfile_name_handler_alist,
     "*Alist of elements (REGEXP . HANDLER) for file names handled specially.\n\