Try to fix bug#5314. This is probably not the final word, tho.
[bpt/emacs.git] / src / fileio.c
index 93b6a1d..d6cb814 100644 (file)
@@ -1,7 +1,7 @@
 /* File IO for GNU Emacs.
    Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995, 1996,
                  1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-                 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+                 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -28,6 +28,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <stdio.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <setjmp.h>
 
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
@@ -193,6 +194,9 @@ Lisp_Object Vauto_save_list_file_name;
 /* Whether or not files are auto-saved into themselves.  */
 Lisp_Object Vauto_save_visited_file_name;
 
+/* Whether or not to continue auto-saving after a large deletion.  */
+Lisp_Object Vauto_save_include_big_deletions;
+
 /* On NT, specifies the directory separator character, used (eg.) when
    expanding file names.  This can be bound to / or \. */
 Lisp_Object Vdirectory_sep_char;
@@ -203,7 +207,7 @@ int write_region_inhibit_fsync;
 #endif
 
 /* Non-zero means call move-file-to-trash in Fdelete_file or
-   Fdelete_directory.  */
+   Fdelete_directory_internal.  */
 int delete_by_moving_to_trash;
 
 Lisp_Object Qdelete_by_moving_to_trash;
@@ -221,8 +225,6 @@ extern int minibuf_level;
 
 extern int minibuffer_auto_raise;
 
-extern int history_delete_duplicates;
-
 /* These variables describe handlers that have "already" had a chance
    to handle the current operation.
 
@@ -275,7 +277,7 @@ report_file_error (string, data)
            int c;
 
            str = (char *) SDATA (errstring);
-           c = STRING_CHAR (str, 0);
+           c = STRING_CHAR (str);
            Faset (errstring, make_number (0), make_number (DOWNCASE (c)));
          }
 
@@ -314,7 +316,7 @@ Lisp_Object Qfile_name_as_directory;
 Lisp_Object Qcopy_file;
 Lisp_Object Qmake_directory_internal;
 Lisp_Object Qmake_directory;
-Lisp_Object Qdelete_directory;
+Lisp_Object Qdelete_directory_internal;
 Lisp_Object Qdelete_file;
 Lisp_Object Qrename_file;
 Lisp_Object Qadd_name_to_file;
@@ -424,9 +426,11 @@ Given a Unix syntax file name, returns a string ending in slash.  */)
     return call2 (handler, Qfile_name_directory, filename);
 
   filename = FILE_SYSTEM_CASE (filename);
-  beg = SDATA (filename);
 #ifdef DOS_NT
-  beg = strcpy (alloca (strlen (beg) + 1), beg);
+  beg = (unsigned char *) alloca (SBYTES (filename) + 1);
+  bcopy (SDATA (filename), beg, SBYTES (filename) + 1);
+#else
+  beg = SDATA (filename);
 #endif
   p = beg + SBYTES (filename);
 
@@ -653,7 +657,7 @@ In Unix-syntax, this function just removes the final slash.  */)
                                STRING_MULTIBYTE (directory));
 }
 
-static char make_temp_name_tbl[64] =
+static const char make_temp_name_tbl[64] =
 {
   'A','B','C','D','E','F','G','H',
   'I','J','K','L','M','N','O','P',
@@ -941,10 +945,9 @@ filesystem tree, not (expand-file-name ".."  dirname).  */)
        }
     }
 
-  nm = SDATA (name);
-
   /* Make a local copy of nm[] to protect it from GC in DECODE_FILE below. */
-  nm = strcpy (alloca (strlen (nm) + 1), nm);
+  nm = (unsigned char *) alloca (SBYTES (name) + 1);
+  bcopy (SDATA (name), nm, SBYTES (name) + 1);
 
 #ifdef DOS_NT
   /* Note if special escape prefix is present, but remove for now.  */
@@ -1643,11 +1646,12 @@ those `/' is discarded.  */)
   if (!NILP (handler))
     return call2 (handler, Qsubstitute_in_file_name, filename);
 
-  nm = SDATA (filename);
   /* Always work on a copy of the string, in case GC happens during
      decode of environment variables, causing the original Lisp_String
      data to be relocated.  */
-  nm = strcpy (alloca (strlen (nm) + 1), nm);
+  nm = (unsigned char *) alloca (SBYTES (filename) + 1);
+  bcopy (SDATA (filename), nm, SBYTES (filename) + 1);
+
 #ifdef DOS_NT
   CORRECT_DIR_SEPS (nm);
   substituted = (strcmp (nm, SDATA (filename)) != 0);
@@ -2131,7 +2135,8 @@ DEFUN ("make-directory-internal", Fmake_directory_internal,
   return Qnil;
 }
 
-DEFUN ("delete-directory", Fdelete_directory, Sdelete_directory, 1, 1, "FDelete directory: ",
+DEFUN ("delete-directory-internal", Fdelete_directory_internal,
+       Sdelete_directory_internal, 1, 1, 0,
        doc: /* Delete the directory named DIRECTORY.  Does not follow symlinks.  */)
      (directory)
      Lisp_Object directory;
@@ -2143,10 +2148,6 @@ DEFUN ("delete-directory", Fdelete_directory, Sdelete_directory, 1, 1, "FDelete
   CHECK_STRING (directory);
   directory = Fdirectory_file_name (Fexpand_file_name (directory, Qnil));
 
-  handler = Ffind_file_name_handler (directory, Qdelete_directory);
-  if (!NILP (handler))
-    return call2 (handler, Qdelete_directory, directory);
-
   if (delete_by_moving_to_trash)
     return call1 (Qmove_file_to_trash, directory);
 
@@ -3048,8 +3049,6 @@ Lisp_Object Qfind_buffer_file_type;
 #define READ_BUF_SIZE (64 << 10)
 #endif
 
-extern void adjust_markers_for_delete P_ ((int, int, int, int));
-
 /* This function is called after Lisp functions to decide a coding
    system are called, or when they cause an error.  Before they are
    called, the current buffer is set unibyte and it contains only a
@@ -3094,8 +3093,8 @@ decide_coding_unwind (unwind_data)
 /* Used to pass values from insert-file-contents to read_non_regular.  */
 
 static int non_regular_fd;
-static int non_regular_inserted;
-static int non_regular_nbytes;
+static EMACS_INT non_regular_inserted;
+static EMACS_INT non_regular_nbytes;
 
 
 /* Read from a non-regular file.
@@ -3106,7 +3105,7 @@ static int non_regular_nbytes;
 static Lisp_Object
 read_non_regular ()
 {
-  int nbytes;
+  EMACS_INT nbytes;
 
   immediate_quit = 1;
   QUIT;
@@ -3156,15 +3155,15 @@ variable `last-coding-system-used' to the coding system actually used.  */)
 {
   struct stat st;
   register int fd;
-  int inserted = 0;
+  EMACS_INT inserted = 0;
   int nochange = 0;
-  register int how_much;
-  register int unprocessed;
+  register EMACS_INT how_much;
+  register EMACS_INT unprocessed;
   int count = SPECPDL_INDEX ();
   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
   Lisp_Object handler, val, insval, orig_filename, old_undo;
   Lisp_Object p;
-  int total = 0;
+  EMACS_INT total = 0;
   int not_regular = 0;
   unsigned char read_buf[READ_BUF_SIZE];
   struct coding_system coding;
@@ -3340,7 +3339,7 @@ variable `last-coding-system-used' to the coding system actually used.  */)
                 We assume that the 1K-byte and 3K-byte for heading
                 and tailing respectively are sufficient for this
                 purpose.  */
-             int nread;
+             EMACS_INT nread;
 
              if (st.st_size <= (1024 * 4))
                nread = emacs_read (fd, read_buf, 1024 * 4);
@@ -3450,9 +3449,9 @@ variable `last-coding-system-used' to the coding system actually used.  */)
       /* same_at_start and same_at_end count bytes,
         because file access counts bytes
         and BEG and END count bytes.  */
-      int same_at_start = BEGV_BYTE;
-      int same_at_end = ZV_BYTE;
-      int overlap;
+      EMACS_INT same_at_start = BEGV_BYTE;
+      EMACS_INT same_at_end = ZV_BYTE;
+      EMACS_INT overlap;
       /* There is still a possibility we will find the need to do code
         conversion.  If that happens, we set this variable to 1 to
         give up on handling REPLACE in the optimized way.  */
@@ -3471,7 +3470,7 @@ variable `last-coding-system-used' to the coding system actually used.  */)
         match the text at the beginning of the buffer.  */
       while (1)
        {
-         int nread, bufpos;
+         EMACS_INT nread, bufpos;
 
          nread = emacs_read (fd, buffer, sizeof buffer);
          if (nread < 0)
@@ -3522,7 +3521,7 @@ variable `last-coding-system-used' to the coding system actually used.  */)
         already found that decoding is necessary, don't waste time.  */
       while (!giveup_match_end)
        {
-         int total_read, nread, bufpos, curpos, trial;
+         EMACS_INT total_read, nread, bufpos, curpos, trial;
 
          /* At what file position are we now scanning?  */
          curpos = XINT (end) - (ZV_BYTE - same_at_end);
@@ -3578,7 +3577,7 @@ variable `last-coding-system-used' to the coding system actually used.  */)
 
       if (! giveup_match_end)
        {
-         int temp;
+         EMACS_INT temp;
 
          /* We win!  We can handle REPLACE the optimized way.  */
 
@@ -3638,7 +3637,7 @@ variable `last-coding-system-used' to the coding system actually used.  */)
       EMACS_INT overlap;
       EMACS_INT bufpos;
       unsigned char *decoded;
-      int temp;
+      EMACS_INT temp;
       int this_count = SPECPDL_INDEX ();
       int multibyte = ! NILP (current_buffer->enable_multibyte_characters);
       Lisp_Object conversion_buffer;
@@ -3663,8 +3662,9 @@ variable `last-coding-system-used' to the coding system actually used.  */)
          /* We read one bunch by one (READ_BUF_SIZE bytes) to allow
             quitting while reading a huge while.  */
          /* try is reserved in some compilers (Microsoft C) */
-         int trytry = min (total - how_much, READ_BUF_SIZE - unprocessed);
-         int this;
+         EMACS_INT trytry = min (total - how_much,
+                                 READ_BUF_SIZE - unprocessed);
+         EMACS_INT this;
 
          /* Allow quitting out of the actual I/O.  */
          immediate_quit = 1;
@@ -3713,6 +3713,7 @@ variable `last-coding-system-used' to the coding system actually used.  */)
        }
 
       coding_system = CODING_ID_NAME (coding.id);
+      set_coding_system = 1;
       decoded = BUF_BEG_ADDR (XBUFFER (conversion_buffer));
       inserted = (BUF_Z_BYTE (XBUFFER (conversion_buffer))
                  - BUF_BEG_BYTE (XBUFFER (conversion_buffer)));
@@ -3867,13 +3868,13 @@ variable `last-coding-system-used' to the coding system actually used.  */)
   /* Here, we don't do code conversion in the loop.  It is done by
      decode_coding_gap after all data are read into the buffer.  */
   {
-    int gap_size = GAP_SIZE;
+    EMACS_INT gap_size = GAP_SIZE;
 
     while (how_much < total)
       {
        /* try is reserved in some compilers (Microsoft C) */
-       int trytry = min (total - how_much, READ_BUF_SIZE);
-       int this;
+       EMACS_INT trytry = min (total - how_much, READ_BUF_SIZE);
+       EMACS_INT this;
 
        if (not_regular)
          {
@@ -4096,7 +4097,7 @@ variable `last-coding-system-used' to the coding system actually used.  */)
        }
 
       SAVE_MODIFF = MODIFF;
-      current_buffer->auto_save_modified = MODIFF;
+      BUF_AUTOSAVE_MODIFF (current_buffer) = MODIFF;
       XSETFASTINT (current_buffer->save_length, Z - BEG);
 #ifdef CLASH_DETECTION
       if (NILP (handler))
@@ -4130,7 +4131,7 @@ variable `last-coding-system-used' to the coding system actually used.  */)
     {
       /* Don't run point motion or modification hooks when decoding.  */
       int count = SPECPDL_INDEX ();
-      int old_inserted = inserted;
+      EMACS_INT old_inserted = inserted;
       specbind (Qinhibit_point_motion_hooks, Qt);
       specbind (Qinhibit_modification_hooks, Qt);
 
@@ -4156,9 +4157,9 @@ variable `last-coding-system-used' to the coding system actually used.  */)
             Hence we temporarily save `point' and `inserted' here and
             restore `point' iff format-decode did not insert or delete
             any text.  Otherwise we leave `point' at point-min.  */
-         int opoint = PT;
-         int opoint_byte = PT_BYTE;
-         int oinserted = ZV - BEGV;
+         EMACS_INT opoint = PT;
+         EMACS_INT opoint_byte = PT_BYTE;
+         EMACS_INT oinserted = ZV - BEGV;
          int ochars_modiff = CHARS_MODIFF;
 
          TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
@@ -4194,9 +4195,9 @@ variable `last-coding-system-used' to the coding system actually used.  */)
            {
              /* For the rationale of this see the comment on
                 format-decode above.  */
-             int opoint = PT;
-             int opoint_byte = PT_BYTE;
-             int oinserted = ZV - BEGV;
+             EMACS_INT opoint = PT;
+             EMACS_INT opoint_byte = PT_BYTE;
+             EMACS_INT oinserted = ZV - BEGV;
              int ochars_modiff = CHARS_MODIFF;
 
              TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
@@ -5306,7 +5307,7 @@ A non-nil CURRENT-ONLY argument means save only current buffer.  */)
           and file changed since last real save.  */
        if (STRINGP (b->auto_save_file_name)
            && BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)
-           && b->auto_save_modified < BUF_MODIFF (b)
+           && BUF_AUTOSAVE_MODIFF (b) < BUF_MODIFF (b)
            /* -1 means we've turned off autosaving for a while--see below.  */
            && XINT (b->save_length) >= 0
            && (do_handled_files
@@ -5322,8 +5323,10 @@ A non-nil CURRENT-ONLY argument means save only current buffer.  */)
                && EMACS_SECS (before_time) - b->auto_save_failure_time < 1200)
              continue;
 
-           if ((XFASTINT (b->save_length) * 10
-                > (BUF_Z (b) - BUF_BEG (b)) * 13)
+           set_buffer_internal (b);
+           if (NILP (Vauto_save_include_big_deletions)
+               && (XFASTINT (b->save_length) * 10
+                   > (BUF_Z (b) - BUF_BEG (b)) * 13)
                /* A short file is likely to change a large fraction;
                   spare the user annoying messages.  */
                && XFASTINT (b->save_length) > 5000
@@ -5342,12 +5345,11 @@ A non-nil CURRENT-ONLY argument means save only current buffer.  */)
                Fsleep_for (make_number (1), Qnil);
                continue;
              }
-           set_buffer_internal (b);
            if (!auto_saved && NILP (no_message))
              message1 ("Auto-saving...");
            internal_condition_case (auto_save_1, Qt, auto_save_error);
            auto_saved++;
-           b->auto_save_modified = BUF_MODIFF (b);
+           BUF_AUTOSAVE_MODIFF (b) = BUF_MODIFF (b);
            XSETFASTINT (current_buffer->save_length, Z - BEG);
            set_buffer_internal (old);
 
@@ -5392,7 +5394,9 @@ DEFUN ("set-buffer-auto-saved", Fset_buffer_auto_saved,
 No auto-save file will be written until the buffer changes again.  */)
      ()
 {
-  current_buffer->auto_save_modified = MODIFF;
+  /* FIXME: This should not be called in indirect buffers, since
+     they're not autosaved.  */
+  BUF_AUTOSAVE_MODIFF (current_buffer) = MODIFF;
   XSETFASTINT (current_buffer->save_length, Z - BEG);
   current_buffer->auto_save_failure_time = -1;
   return Qnil;
@@ -5415,7 +5419,9 @@ in the visited file.  If the buffer has no visited file,
 then any auto-save counts as "recent".  */)
      ()
 {
-  return (SAVE_MODIFF < current_buffer->auto_save_modified) ? Qt : Qnil;
+  /* FIXME: maybe we should return nil for indirect buffers since
+     they're never autosaved.  */
+  return (SAVE_MODIFF < BUF_AUTOSAVE_MODIFF (current_buffer) ? Qt : Qnil);
 }
 \f
 /* Reading and completing file names */
@@ -5456,51 +5462,43 @@ Fread_file_name (prompt, dir, default_filename, mustmatch, initial, predicate)
 }
 
 \f
-void
-init_fileio_once ()
-{
-  /* Must be set before any path manipulation is performed.  */
-  XSETFASTINT (Vdirectory_sep_char, '/');
-}
-
-\f
 void
 syms_of_fileio ()
 {
-  Qoperations = intern ("operations");
-  Qexpand_file_name = intern ("expand-file-name");
-  Qsubstitute_in_file_name = intern ("substitute-in-file-name");
-  Qdirectory_file_name = intern ("directory-file-name");
-  Qfile_name_directory = intern ("file-name-directory");
-  Qfile_name_nondirectory = intern ("file-name-nondirectory");
-  Qunhandled_file_name_directory = intern ("unhandled-file-name-directory");
-  Qfile_name_as_directory = intern ("file-name-as-directory");
-  Qcopy_file = intern ("copy-file");
-  Qmake_directory_internal = intern ("make-directory-internal");
-  Qmake_directory = intern ("make-directory");
-  Qdelete_directory = intern ("delete-directory");
-  Qdelete_file = intern ("delete-file");
-  Qrename_file = intern ("rename-file");
-  Qadd_name_to_file = intern ("add-name-to-file");
-  Qmake_symbolic_link = intern ("make-symbolic-link");
-  Qfile_exists_p = intern ("file-exists-p");
-  Qfile_executable_p = intern ("file-executable-p");
-  Qfile_readable_p = intern ("file-readable-p");
-  Qfile_writable_p = intern ("file-writable-p");
-  Qfile_symlink_p = intern ("file-symlink-p");
-  Qaccess_file = intern ("access-file");
-  Qfile_directory_p = intern ("file-directory-p");
-  Qfile_regular_p = intern ("file-regular-p");
-  Qfile_accessible_directory_p = intern ("file-accessible-directory-p");
-  Qfile_modes = intern ("file-modes");
-  Qset_file_modes = intern ("set-file-modes");
-  Qset_file_times = intern ("set-file-times");
-  Qfile_newer_than_file_p = intern ("file-newer-than-file-p");
-  Qinsert_file_contents = intern ("insert-file-contents");
-  Qwrite_region = intern ("write-region");
-  Qverify_visited_file_modtime = intern ("verify-visited-file-modtime");
-  Qset_visited_file_modtime = intern ("set-visited-file-modtime");
-  Qauto_save_coding = intern ("auto-save-coding");
+  Qoperations = intern_c_string ("operations");
+  Qexpand_file_name = intern_c_string ("expand-file-name");
+  Qsubstitute_in_file_name = intern_c_string ("substitute-in-file-name");
+  Qdirectory_file_name = intern_c_string ("directory-file-name");
+  Qfile_name_directory = intern_c_string ("file-name-directory");
+  Qfile_name_nondirectory = intern_c_string ("file-name-nondirectory");
+  Qunhandled_file_name_directory = intern_c_string ("unhandled-file-name-directory");
+  Qfile_name_as_directory = intern_c_string ("file-name-as-directory");
+  Qcopy_file = intern_c_string ("copy-file");
+  Qmake_directory_internal = intern_c_string ("make-directory-internal");
+  Qmake_directory = intern_c_string ("make-directory");
+  Qdelete_directory_internal = intern_c_string ("delete-directory-internal");
+  Qdelete_file = intern_c_string ("delete-file");
+  Qrename_file = intern_c_string ("rename-file");
+  Qadd_name_to_file = intern_c_string ("add-name-to-file");
+  Qmake_symbolic_link = intern_c_string ("make-symbolic-link");
+  Qfile_exists_p = intern_c_string ("file-exists-p");
+  Qfile_executable_p = intern_c_string ("file-executable-p");
+  Qfile_readable_p = intern_c_string ("file-readable-p");
+  Qfile_writable_p = intern_c_string ("file-writable-p");
+  Qfile_symlink_p = intern_c_string ("file-symlink-p");
+  Qaccess_file = intern_c_string ("access-file");
+  Qfile_directory_p = intern_c_string ("file-directory-p");
+  Qfile_regular_p = intern_c_string ("file-regular-p");
+  Qfile_accessible_directory_p = intern_c_string ("file-accessible-directory-p");
+  Qfile_modes = intern_c_string ("file-modes");
+  Qset_file_modes = intern_c_string ("set-file-modes");
+  Qset_file_times = intern_c_string ("set-file-times");
+  Qfile_newer_than_file_p = intern_c_string ("file-newer-than-file-p");
+  Qinsert_file_contents = intern_c_string ("insert-file-contents");
+  Qwrite_region = intern_c_string ("write-region");
+  Qverify_visited_file_modtime = intern_c_string ("verify-visited-file-modtime");
+  Qset_visited_file_modtime = intern_c_string ("set-visited-file-modtime");
+  Qauto_save_coding = intern_c_string ("auto-save-coding");
 
   staticpro (&Qoperations);
   staticpro (&Qexpand_file_name);
@@ -5513,7 +5511,7 @@ syms_of_fileio ()
   staticpro (&Qcopy_file);
   staticpro (&Qmake_directory_internal);
   staticpro (&Qmake_directory);
-  staticpro (&Qdelete_directory);
+  staticpro (&Qdelete_directory_internal);
   staticpro (&Qdelete_file);
   staticpro (&Qrename_file);
   staticpro (&Qadd_name_to_file);
@@ -5537,21 +5535,21 @@ syms_of_fileio ()
   staticpro (&Qset_visited_file_modtime);
   staticpro (&Qauto_save_coding);
 
-  Qfile_name_history = intern ("file-name-history");
+  Qfile_name_history = intern_c_string ("file-name-history");
   Fset (Qfile_name_history, Qnil);
   staticpro (&Qfile_name_history);
 
-  Qfile_error = intern ("file-error");
+  Qfile_error = intern_c_string ("file-error");
   staticpro (&Qfile_error);
-  Qfile_already_exists = intern ("file-already-exists");
+  Qfile_already_exists = intern_c_string ("file-already-exists");
   staticpro (&Qfile_already_exists);
-  Qfile_date_error = intern ("file-date-error");
+  Qfile_date_error = intern_c_string ("file-date-error");
   staticpro (&Qfile_date_error);
-  Qexcl = intern ("excl");
+  Qexcl = intern_c_string ("excl");
   staticpro (&Qexcl);
 
 #ifdef DOS_NT
-  Qfind_buffer_file_type = intern ("find-buffer-file-type");
+  Qfind_buffer_file_type = intern_c_string ("find-buffer-file-type");
   staticpro (&Qfind_buffer_file_type);
 #endif /* DOS_NT */
 
@@ -5571,34 +5569,35 @@ instead use `file-name-coding-system' to get a constant encoding
 of file names regardless of the current language environment.  */);
   Vdefault_file_name_coding_system = Qnil;
 
-  Qformat_decode = intern ("format-decode");
+  Qformat_decode = intern_c_string ("format-decode");
   staticpro (&Qformat_decode);
-  Qformat_annotate_function = intern ("format-annotate-function");
+  Qformat_annotate_function = intern_c_string ("format-annotate-function");
   staticpro (&Qformat_annotate_function);
-  Qafter_insert_file_set_coding = intern ("after-insert-file-set-coding");
+  Qafter_insert_file_set_coding = intern_c_string ("after-insert-file-set-coding");
   staticpro (&Qafter_insert_file_set_coding);
 
-  Qcar_less_than_car = intern ("car-less-than-car");
+  Qcar_less_than_car = intern_c_string ("car-less-than-car");
   staticpro (&Qcar_less_than_car);
 
   Fput (Qfile_error, Qerror_conditions,
-       list2 (Qfile_error, Qerror));
+       Fpurecopy (list2 (Qfile_error, Qerror)));
   Fput (Qfile_error, Qerror_message,
-       build_string ("File error"));
+       make_pure_c_string ("File error"));
 
   Fput (Qfile_already_exists, Qerror_conditions,
-       list3 (Qfile_already_exists, Qfile_error, Qerror));
+       Fpurecopy (list3 (Qfile_already_exists, Qfile_error, Qerror)));
   Fput (Qfile_already_exists, Qerror_message,
-       build_string ("File already exists"));
+       make_pure_c_string ("File already exists"));
 
   Fput (Qfile_date_error, Qerror_conditions,
-       list3 (Qfile_date_error, Qfile_error, Qerror));
+       Fpurecopy (list3 (Qfile_date_error, Qfile_error, Qerror)));
   Fput (Qfile_date_error, Qerror_message,
-       build_string ("Cannot set file date"));
+       make_pure_c_string ("Cannot set file date"));
 
   DEFVAR_LISP ("directory-sep-char", &Vdirectory_sep_char,
               doc: /* Directory separator character for built-in functions that return file names.
 The value is always ?/.  Don't use this variable, just use `/'.  */);
+  XSETFASTINT (Vdirectory_sep_char, '/');
 
   DEFVAR_LISP ("file-name-handler-alist", &Vfile_name_handler_alist,
               doc: /* *Alist of elements (REGEXP . HANDLER) for file names handled specially.
@@ -5664,7 +5663,7 @@ buffer current.  */);
   Vwrite_region_annotate_functions = Qnil;
   staticpro (&Qwrite_region_annotate_functions);
   Qwrite_region_annotate_functions
-    = intern ("write-region-annotate-functions");
+    = intern_c_string ("write-region-annotate-functions");
 
   DEFVAR_LISP ("write-region-post-annotation-function",
               &Vwrite_region_post_annotation_function,
@@ -5705,6 +5704,13 @@ a non-nil value.  */);
 Normally auto-save files are written under other names.  */);
   Vauto_save_visited_file_name = Qnil;
 
+  DEFVAR_LISP ("auto-save-include-big-deletions", &Vauto_save_include_big_deletions,
+              doc: /* If non-nil, auto-save even if a large part of the text is deleted.
+If nil, deleting a substantial portion of the text disables auto-save
+in the buffer; this is the default behavior, because the auto-save
+file is usually more useful if it contains the deleted text.  */);
+  Vauto_save_include_big_deletions = Qnil;
+
 #ifdef HAVE_FSYNC
   DEFVAR_BOOL ("write-region-inhibit-fsync", &write_region_inhibit_fsync,
               doc: /* *Non-nil means don't call fsync in `write-region'.
@@ -5718,8 +5724,8 @@ A non-nil value may result in data loss!  */);
 When non-nil, the function `move-file-to-trash' will be used by
 `delete-file' and `delete-directory'.  */);
   delete_by_moving_to_trash = 0;
-  Qdelete_by_moving_to_trash = intern ("delete-by-moving-to-trash");
-  Qmove_file_to_trash = intern ("move-file-to-trash");
+  Qdelete_by_moving_to_trash = intern_c_string ("delete-by-moving-to-trash");
+  Qmove_file_to_trash = intern_c_string ("move-file-to-trash");
   staticpro (&Qmove_file_to_trash);
 
   defsubr (&Sfind_file_name_handler);
@@ -5733,7 +5739,7 @@ When non-nil, the function `move-file-to-trash' will be used by
   defsubr (&Ssubstitute_in_file_name);
   defsubr (&Scopy_file);
   defsubr (&Smake_directory_internal);
-  defsubr (&Sdelete_directory);
+  defsubr (&Sdelete_directory_internal);
   defsubr (&Sdelete_file);
   defsubr (&Srename_file);
   defsubr (&Sadd_name_to_file);