use dynwind_begin and dynwind_end
[bpt/emacs.git] / src / dired.c
index 0e37568..6bec249 100644 (file)
@@ -1,5 +1,5 @@
 /* Lisp functions for making directory listings.
-   Copyright (C) 1985-1986, 1993-1994, 1999-2013 Free Software
+   Copyright (C) 1985-1986, 1993-1994, 1999-2014 Free Software
    Foundation, Inc.
 
 This file is part of GNU Emacs.
@@ -47,6 +47,10 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "regex.h"
 #include "blockinput.h"
 
+#ifdef MSDOS
+#include "msdos.h"     /* for fstatat */
+#endif
+
 static Lisp_Object Qdirectory_files;
 static Lisp_Object Qdirectory_files_and_attributes;
 static Lisp_Object Qfile_name_completion;
@@ -95,7 +99,7 @@ open_directory (char const *name, int *fdp)
       d = fdopendir (fd);
       opendir_errno = errno;
       if (! d)
-       close (fd);
+       emacs_close (fd);
     }
 #endif
 
@@ -107,22 +111,20 @@ open_directory (char const *name, int *fdp)
 }
 
 #ifdef WINDOWSNT
-Lisp_Object
+void
 directory_files_internal_w32_unwind (Lisp_Object arg)
 {
   Vw32_get_true_file_attributes = arg;
-  return Qnil;
 }
 #endif
 
-static Lisp_Object
-directory_files_internal_unwind (Lisp_Object dh)
+static void
+directory_files_internal_unwind (void *dh)
 {
-  DIR *d = XSAVE_POINTER (dh, 0);
+  DIR *d = dh;
   block_input ();
   closedir (d);
   unblock_input ();
-  return Qnil;
 }
 
 /* Function shared by Fdirectory_files and Fdirectory_files_and_attributes.
@@ -141,12 +143,9 @@ directory_files_internal (Lisp_Object directory, Lisp_Object full,
   Lisp_Object list, dirfilename, encoded_directory;
   struct re_pattern_buffer *bufp = NULL;
   bool needsep = 0;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  dynwind_begin ();
   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
   struct dirent *dp;
-#ifdef WINDOWSNT
-  Lisp_Object w32_save = Qnil;
-#endif
 
   /* Because of file name handlers, these functions might call
      Ffuncall, and cause a GC.  */
@@ -185,13 +184,12 @@ directory_files_internal (Lisp_Object directory, Lisp_Object full,
 
   d = open_directory (SSDATA (dirfilename), &fd);
   if (d == NULL)
-    report_file_error ("Opening directory", Fcons (directory, Qnil));
+    report_file_error ("Opening directory", directory);
 
   /* Unfortunately, we can now invoke expand-file-name and
      file-attributes on filenames, both of which can throw, so we must
      do a proper unwind-protect.  */
-  record_unwind_protect (directory_files_internal_unwind,
-                        make_save_pointer (d));
+  record_unwind_protect_ptr (directory_files_internal_unwind, d);
 
 #ifdef WINDOWSNT
   if (attrs)
@@ -202,7 +200,6 @@ directory_files_internal (Lisp_Object directory, Lisp_Object full,
         file in the directory, when we call Ffile_attributes below.  */
       record_unwind_protect (directory_files_internal_w32_unwind,
                             Vw32_get_true_file_attributes);
-      w32_save = Vw32_get_true_file_attributes;
       if (EQ (Vw32_get_true_file_attributes, Qlocal))
        {
          /* w32.c:stat will notice these bindings and avoid calling
@@ -258,7 +255,7 @@ directory_files_internal (Lisp_Object directory, Lisp_Object full,
       QUIT;
 
       if (NILP (match)
-         || (0 <= re_search (bufp, SSDATA (name), len, 0, len, 0)))
+         || re_search (bufp, SSDATA (name), len, 0, len, 0) >= 0)
        wanted = 1;
 
       immediate_quit = 0;
@@ -281,7 +278,7 @@ directory_files_internal (Lisp_Object directory, Lisp_Object full,
              memcpy (SDATA (fullname) + directory_nbytes + needsep,
                      SDATA (name), len);
 
-             nchars = chars_in_text (SDATA (fullname), nbytes);
+             nchars = multibyte_chars_in_text (SDATA (fullname), nbytes);
 
              /* Some bug somewhere.  */
              if (nchars > nbytes)
@@ -309,22 +306,13 @@ directory_files_internal (Lisp_Object directory, Lisp_Object full,
       UNGCPRO;
     }
 
-  block_input ();
-  closedir (d);
-  unblock_input ();
-#ifdef WINDOWSNT
-  if (attrs)
-    Vw32_get_true_file_attributes = w32_save;
-#endif
-
-  /* Discard the unwind protect.  */
-  specpdl_ptr = specpdl + count;
+  dynwind_end ();
 
   if (NILP (nosort))
     list = Fsort (Fnreverse (list),
                  attrs ? Qfile_attributes_lessp : Qstring_lessp);
 
-  RETURN_UNGCPRO (list);
+  return list;
 }
 
 
@@ -464,7 +452,7 @@ file_name_completion (Lisp_Object file, Lisp_Object dirname, bool all_flag,
      well as "." and "..".  Until shown otherwise, assume we can't exclude
      anything.  */
   bool includeall = 1;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  dynwind_begin ();
   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
 
   elt = Qnil;
@@ -488,10 +476,9 @@ file_name_completion (Lisp_Object file, Lisp_Object dirname, bool all_flag,
 
   d = open_directory (SSDATA (encoded_dir), &fd);
   if (!d)
-    report_file_error ("Opening directory", Fcons (dirname, Qnil));
+    report_file_error ("Opening directory", dirname);
 
-  record_unwind_protect (directory_files_internal_unwind,
-                        make_save_pointer (d));
+  record_unwind_protect_ptr (directory_files_internal_unwind, d);
 
   /* Loop reading blocks */
   /* (att3b compiler bug requires do a null comparison this way) */
@@ -517,8 +504,9 @@ file_name_completion (Lisp_Object file, Lisp_Object dirname, bool all_flag,
 
       QUIT;
       if (len < SCHARS (encoded_file)
-         || 0 <= scmp (dp->d_name, SSDATA (encoded_file),
-                       SCHARS (encoded_file)))
+         || (scmp (dp->d_name, SSDATA (encoded_file),
+                   SCHARS (encoded_file))
+             >= 0))
        continue;
 
       if (file_name_completion_stat (fd, dp, &st) < 0)
@@ -580,7 +568,7 @@ file_name_completion (Lisp_Object file, Lisp_Object dirname, bool all_flag,
                    if (skip < 0)
                      continue;
 
-                   if (0 <= scmp (dp->d_name + skip, p1, elt_len))
+                   if (scmp (dp->d_name + skip, p1, elt_len) >= 0)
                      continue;
                    break;
                  }
@@ -602,9 +590,8 @@ file_name_completion (Lisp_Object file, Lisp_Object dirname, bool all_flag,
                    skip = len - SCHARS (elt);
                    if (skip < 0) continue;
 
-                   if (0 <= scmp (dp->d_name + skip,
-                                  SSDATA (elt),
-                                  SCHARS (elt)))
+                   if (scmp (dp->d_name + skip, SSDATA (elt), SCHARS (elt))
+                       >= 0)
                      continue;
                    break;
                  }
@@ -756,7 +743,7 @@ file_name_completion (Lisp_Object file, Lisp_Object dirname, bool all_flag,
 
   UNGCPRO;
   /* This closes the directory.  */
-  bestmatch = unbind_to (count, bestmatch);
+  dynwind_end ();
 
   if (all_flag || NILP (bestmatch))
     return bestmatch;
@@ -962,11 +949,11 @@ file_attributes (int fd, char const *name, Lisp_Object id_format)
       unblock_input ();
     }
   if (uname)
-    values[2] = DECODE_SYSTEM (build_string (uname));
+    values[2] = DECODE_SYSTEM (build_unibyte_string (uname));
   else
     values[2] = make_fixnum_or_float (s.st_uid);
   if (gname)
-    values[3] = DECODE_SYSTEM (build_string (gname));
+    values[3] = DECODE_SYSTEM (build_unibyte_string (gname));
   else
     values[3] = make_fixnum_or_float (s.st_gid);
 
@@ -988,7 +975,7 @@ file_attributes (int fd, char const *name, Lisp_Object id_format)
   values[10] = INTEGER_TO_CONS (s.st_ino);
   values[11] = INTEGER_TO_CONS (s.st_dev);
 
-  return Flist (sizeof (values) / sizeof (values[0]), values);
+  return Flist (ARRAYELTS (values), values);
 }
 
 DEFUN ("file-attributes-lessp", Ffile_attributes_lessp, Sfile_attributes_lessp, 2, 2, 0,
@@ -1017,7 +1004,7 @@ return a list with one element, taken from `user-real-login-name'.  */)
 #endif
   if (EQ (users, Qnil))
     /* At least current user is always known. */
-    users = Fcons (Vuser_real_login_name, Qnil);
+    users = list1 (Vuser_real_login_name);
   return users;
 }
 
@@ -1041,6 +1028,8 @@ The value may be nil if not supported on this platform.  */)
 void
 syms_of_dired (void)
 {
+#include "dired.x"
+
   DEFSYM (Qdirectory_files, "directory-files");
   DEFSYM (Qdirectory_files_and_attributes, "directory-files-and-attributes");
   DEFSYM (Qfile_name_completion, "file-name-completion");
@@ -1049,15 +1038,6 @@ syms_of_dired (void)
   DEFSYM (Qfile_attributes_lessp, "file-attributes-lessp");
   DEFSYM (Qdefault_directory, "default-directory");
 
-  defsubr (&Sdirectory_files);
-  defsubr (&Sdirectory_files_and_attributes);
-  defsubr (&Sfile_name_completion);
-  defsubr (&Sfile_name_all_completions);
-  defsubr (&Sfile_attributes);
-  defsubr (&Sfile_attributes_lessp);
-  defsubr (&Ssystem_users);
-  defsubr (&Ssystem_groups);
-
   DEFVAR_LISP ("completion-ignored-extensions", Vcompletion_ignored_extensions,
               doc: /* Completion ignores file names ending in any string in this list.
 It does not ignore them if all possible completions end in one of