* chartab.c (ASET_RANGE, GET_SUB_CHAR_TABLE): Remove unused macros.
[bpt/emacs.git] / src / dired.c
index c7f4774..9606368 100644 (file)
@@ -1,6 +1,5 @@
 /* Lisp functions for making directory listings.
-   Copyright (C) 1985, 1986, 1993, 1994, 1999, 2000, 2001, 2002, 2003,
-                 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+   Copyright (C) 1985-1986, 1993-1994, 1999-2011 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -31,10 +30,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <grp.h>
 
 #include <errno.h>
-
-#ifdef HAVE_UNISTD_H
 #include <unistd.h>
-#endif
 
 /* The d_nameln member of a struct dirent includes the '\0' character
    on some systems, but not on others.  What's worse, you can't tell
@@ -48,32 +44,26 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
    Since applying strlen to the name always works, we'll just do that.  */
 #define NAMLEN(p) strlen (p->d_name)
 
-#ifdef SYSV_SYSTEM_DIR
+#ifdef HAVE_DIRENT_H
 
 #include <dirent.h>
 #define DIRENTRY struct dirent
 
-#else /* not SYSV_SYSTEM_DIR */
+#else /* not HAVE_DIRENT_H */
 
-#ifdef MSDOS
-#include <dirent.h>
-#else
 #include <sys/dir.h>
-#endif
-
 #include <sys/stat.h>
 
-#ifndef MSDOS
 #define DIRENTRY struct direct
 
-extern DIR *opendir ();
-extern struct direct *readdir ();
+extern DIR *opendir (char *);
+extern struct direct *readdir (DIR *);
+
+#endif /* HAVE_DIRENT_H */
 
-#endif /* not MSDOS */
-#endif /* not SYSV_SYSTEM_DIR */
+#include <filemode.h>
 
-/* Some versions of Cygwin don't have d_ino in `struct dirent'.  */
-#if defined(MSDOS) || defined(__CYGWIN__)
+#ifdef MSDOS
 #define DIRENTRY_NONEMPTY(p) ((p)->d_name[0] != 0)
 #else
 #define DIRENTRY_NONEMPTY(p) ((p)->d_ino)
@@ -90,24 +80,10 @@ extern struct direct *readdir ();
 #include "blockinput.h"
 
 /* Returns a search buffer, with a fastmap allocated and ready to go.  */
-extern struct re_pattern_buffer *compile_pattern ();
-
-/* From filemode.c.  Can't go in Lisp.h because of `stat'.  */
-extern void filemodestring P_ ((struct stat *, char *));
-
-/* if system does not have symbolic links, it does not have lstat.
-   In that case, use ordinary stat instead.  */
+extern struct re_pattern_buffer *compile_pattern (Lisp_Object,
+                                                 struct re_registers *,
+                                                 Lisp_Object, int, int);
 
-#ifndef S_IFLNK
-#define lstat stat
-#endif
-
-extern int completion_ignore_case;
-extern Lisp_Object Qcompletion_ignore_case;
-extern Lisp_Object Vcompletion_regexp_list;
-extern Lisp_Object Vw32_get_true_file_attributes;
-
-Lisp_Object Vcompletion_ignored_extensions;
 Lisp_Object Qdirectory_files;
 Lisp_Object Qdirectory_files_and_attributes;
 Lisp_Object Qfile_name_completion;
@@ -115,7 +91,7 @@ Lisp_Object Qfile_name_all_completions;
 Lisp_Object Qfile_attributes;
 Lisp_Object Qfile_attributes_lessp;
 
-static int scmp P_ ((unsigned char *, unsigned char *, int));
+static int scmp (const char *, const char *, int);
 \f
 #ifdef WINDOWSNT
 Lisp_Object
@@ -127,8 +103,7 @@ directory_files_internal_w32_unwind (Lisp_Object arg)
 #endif
 
 Lisp_Object
-directory_files_internal_unwind (dh)
-     Lisp_Object dh;
+directory_files_internal_unwind (Lisp_Object dh)
 {
   DIR *d = (DIR *) XSAVE_VALUE (dh)->pointer;
   BLOCK_INPUT;
@@ -143,10 +118,7 @@ directory_files_internal_unwind (dh)
    In the latter case, ID_FORMAT is passed to Ffile_attributes.  */
 
 Lisp_Object
-directory_files_internal (directory, full, match, nosort, attrs, id_format)
-     Lisp_Object directory, full, match, nosort;
-     int attrs;
-     Lisp_Object id_format;
+directory_files_internal (Lisp_Object directory, Lisp_Object full, Lisp_Object match, Lisp_Object nosort, int attrs, Lisp_Object id_format)
 {
   DIR *d;
   int directory_nbytes;
@@ -178,7 +150,7 @@ directory_files_internal (directory, full, match, nosort, attrs, id_format)
 # ifdef WINDOWSNT
       /* Windows users want case-insensitive wildcards.  */
       bufp = compile_pattern (match, 0,
-                             buffer_defaults.case_canon_table, 0, 1);
+                             BVAR (&buffer_defaults, case_canon_table), 0, 1);
 # else /* !WINDOWSNT */
       bufp = compile_pattern (match, 0, Qnil, 0, 1);
 # endif         /* !WINDOWSNT */
@@ -196,7 +168,7 @@ directory_files_internal (directory, full, match, nosort, attrs, id_format)
      which might compile a new regexp until we're done with the loop!  */
 
   BLOCK_INPUT;
-  d = opendir (SDATA (dirfilename));
+  d = opendir (SSDATA (dirfilename));
   UNBLOCK_INPUT;
   if (d == NULL)
     report_file_error ("Opening directory", Fcons (directory, Qnil));
@@ -210,7 +182,6 @@ directory_files_internal (directory, full, match, nosort, attrs, id_format)
 #ifdef WINDOWSNT
   if (attrs)
     {
-      extern Lisp_Object Qlocal;
       extern int is_slow_fs (const char *);
 
       /* Do this only once to avoid doing it (in w32.c:stat) for each
@@ -279,7 +250,7 @@ directory_files_internal (directory, full, match, nosort, attrs, id_format)
          QUIT;
 
          if (NILP (match)
-             || (0 <= re_search (bufp, SDATA (name), len, 0, len, 0)))
+             || (0 <= re_search (bufp, SSDATA (name), len, 0, len, 0)))
            wanted = 1;
 
          immediate_quit = 0;
@@ -293,15 +264,14 @@ directory_files_internal (directory, full, match, nosort, attrs, id_format)
                  int nchars;
 
                  fullname = make_uninit_multibyte_string (nbytes, nbytes);
-                 bcopy (SDATA (directory), SDATA (fullname),
-                        directory_nbytes);
+                 memcpy (SDATA (fullname), SDATA (directory),
+                         directory_nbytes);
 
                  if (needsep)
                    SSET (fullname, directory_nbytes, DIRECTORY_SEP);
 
-                 bcopy (SDATA (name),
-                        SDATA (fullname) + directory_nbytes + needsep,
-                        len);
+                 memcpy (SDATA (fullname) + directory_nbytes + needsep,
+                         SDATA (name), len);
 
                  nchars = chars_in_text (SDATA (fullname), nbytes);
 
@@ -371,8 +341,7 @@ If MATCH is non-nil, mention only file names that match the regexp MATCH.
 If NOSORT is non-nil, the list is not sorted--its order is unpredictable.
  Otherwise, the list returned is sorted with `string-lessp'.
  NOSORT is useful if you plan to sort the result yourself.  */)
-     (directory, full, match, nosort)
-     Lisp_Object directory, full, match, nosort;
+  (Lisp_Object directory, Lisp_Object full, Lisp_Object match, Lisp_Object nosort)
 {
   Lisp_Object handler;
   directory = Fexpand_file_name (directory, Qnil);
@@ -400,8 +369,7 @@ ID-FORMAT specifies the preferred format of attributes uid and gid, see
 `file-attributes' for further documentation.
 On MS-Windows, performance depends on `w32-get-true-file-attributes',
 which see.  */)
-     (directory, full, match, nosort, id_format)
-     Lisp_Object directory, full, match, nosort, id_format;
+  (Lisp_Object directory, Lisp_Object full, Lisp_Object match, Lisp_Object nosort, Lisp_Object id_format)
 {
   Lisp_Object handler;
   directory = Fexpand_file_name (directory, Qnil);
@@ -417,7 +385,7 @@ which see.  */)
 }
 
 \f
-Lisp_Object file_name_completion ();
+Lisp_Object file_name_completion (Lisp_Object file, Lisp_Object dirname, int all_flag, int ver_flag, Lisp_Object predicate);
 
 DEFUN ("file-name-completion", Ffile_name_completion, Sfile_name_completion,
        2, 3, 0,
@@ -432,8 +400,7 @@ completion (in absolute form) and ignore it if PREDICATE returns nil.
 
 This function ignores some of the possible completions as
 determined by the variable `completion-ignored-extensions', which see.  */)
-     (file, directory, predicate)
-     Lisp_Object file, directory, predicate;
+  (Lisp_Object file, Lisp_Object directory, Lisp_Object predicate)
 {
   Lisp_Object handler;
 
@@ -456,8 +423,7 @@ DEFUN ("file-name-all-completions", Ffile_name_all_completions,
        Sfile_name_all_completions, 2, 2, 0,
        doc: /* Return a list of all completions of file name FILE in directory DIRECTORY.
 These are all file names in directory DIRECTORY which begin with FILE.  */)
-     (file, directory)
-     Lisp_Object file, directory;
+  (Lisp_Object file, Lisp_Object directory)
 {
   Lisp_Object handler;
 
@@ -476,14 +442,11 @@ These are all file names in directory DIRECTORY which begin with FILE.  */)
   return file_name_completion (file, directory, 1, 0, Qnil);
 }
 
-static int file_name_completion_stat ();
+static int file_name_completion_stat (Lisp_Object dirname, DIRENTRY *dp, struct stat *st_addr);
 Lisp_Object Qdefault_directory;
 
 Lisp_Object
-file_name_completion (file, dirname, all_flag, ver_flag, predicate)
-     Lisp_Object file, dirname;
-     int all_flag, ver_flag;
-     Lisp_Object predicate;
+file_name_completion (Lisp_Object file, Lisp_Object dirname, int all_flag, int ver_flag, Lisp_Object predicate)
 {
   DIR *d;
   int bestmatchsize = 0;
@@ -527,7 +490,7 @@ file_name_completion (file, dirname, all_flag, ver_flag, predicate)
   encoded_dir = ENCODE_FILE (dirname);
 
   BLOCK_INPUT;
-  d = opendir (SDATA (Fdirectory_file_name (encoded_dir)));
+  d = opendir (SSDATA (Fdirectory_file_name (encoded_dir)));
   UNBLOCK_INPUT;
   if (!d)
     report_file_error ("Opening directory", Fcons (dirname, Qnil));
@@ -562,14 +525,14 @@ file_name_completion (file, dirname, all_flag, ver_flag, predicate)
       QUIT;
       if (! DIRENTRY_NONEMPTY (dp)
          || len < SCHARS (encoded_file)
-         || 0 <= scmp (dp->d_name, SDATA (encoded_file),
+         || 0 <= scmp (dp->d_name, SSDATA (encoded_file),
                        SCHARS (encoded_file)))
        continue;
 
       if (file_name_completion_stat (encoded_dir, dp, &st) < 0)
        continue;
 
-      directoryp = ((st.st_mode & S_IFMT) == S_IFDIR);
+      directoryp = S_ISDIR (st.st_mode);
       tem = Qnil;
       /* If all_flag is set, always include all.
         It would not actually be helpful to the user to ignore any possible
@@ -587,7 +550,7 @@ file_name_completion (file, dirname, all_flag, ver_flag, predicate)
              && matchcount > 1
              && !includeall /* This match may allow includeall to 0.  */
              && len >= bestmatchsize
-             && 0 > scmp (dp->d_name, SDATA (bestmatch), bestmatchsize))
+             && 0 > scmp (dp->d_name, SSDATA (bestmatch), bestmatchsize))
            continue;
 #endif
 
@@ -607,7 +570,7 @@ file_name_completion (file, dirname, all_flag, ver_flag, predicate)
                     CONSP (tem); tem = XCDR (tem))
                  {
                    int elt_len;
-                   unsigned char *p1;
+                   char *p1;
 
                    elt = XCAR (tem);
                    if (!STRINGP (elt))
@@ -618,7 +581,7 @@ file_name_completion (file, dirname, all_flag, ver_flag, predicate)
                    elt_len = SCHARS (elt) - 1; /* -1 for trailing / */
                    if (elt_len <= 0)
                      continue;
-                   p1 = SDATA (elt);
+                   p1 = SSDATA (elt);
                    if (p1[elt_len] != '/')
                      continue;
                    skip = len - elt_len;
@@ -648,7 +611,7 @@ file_name_completion (file, dirname, all_flag, ver_flag, predicate)
                    if (skip < 0) continue;
 
                    if (0 <= scmp (dp->d_name + skip,
-                                  SDATA (elt),
+                                  SSDATA (elt),
                                   SCHARS (elt)))
                      continue;
                    break;
@@ -825,15 +788,15 @@ file_name_completion (file, dirname, all_flag, ver_flag, predicate)
    else number of chars that match at the beginning.  */
 
 static int
-scmp (s1, s2, len)
-     register unsigned char *s1, *s2;
-     int len;
+scmp (const char *s1, const char *s2, int len)
 {
   register int l = len;
 
   if (completion_ignore_case)
     {
-      while (l && DOWNCASE (*s1++) == DOWNCASE (*s2++))
+      while (l
+            && (DOWNCASE ((unsigned char) *s1++)
+                == DOWNCASE ((unsigned char) *s2++)))
        l--;
     }
   else
@@ -848,10 +811,7 @@ scmp (s1, s2, len)
 }
 
 static int
-file_name_completion_stat (dirname, dp, st_addr)
-     Lisp_Object dirname;
-     DIRENTRY *dp;
-     struct stat *st_addr;
+file_name_completion_stat (Lisp_Object dirname, DIRENTRY *dp, struct stat *st_addr)
 {
   int len = NAMLEN (dp);
   int pos = SCHARS (dirname);
@@ -869,32 +829,27 @@ file_name_completion_stat (dirname, dp, st_addr)
   _djstat_flags = _STAT_INODE | _STAT_EXEC_MAGIC | _STAT_DIRSIZE;
 #endif /* MSDOS */
 
-  bcopy (SDATA (dirname), fullname, pos);
+  memcpy (fullname, SDATA (dirname), pos);
   if (!IS_DIRECTORY_SEP (fullname[pos - 1]))
     fullname[pos++] = DIRECTORY_SEP;
 
-  bcopy (dp->d_name, fullname + pos, len);
+  memcpy (fullname + pos, dp->d_name, len);
   fullname[pos + len] = 0;
 
-#ifdef S_IFLNK
   /* We want to return success if a link points to a nonexistent file,
      but we want to return the status for what the link points to,
      in case it is a directory.  */
   value = lstat (fullname, st_addr);
-  stat (fullname, st_addr);
-  return value;
-#else
-  value = stat (fullname, st_addr);
+  if (value == 0 && S_ISLNK (st_addr->st_mode))
+    stat (fullname, st_addr);
 #ifdef MSDOS
   _djstat_flags = save_djstat_flags;
 #endif /* MSDOS */
   return value;
-#endif /* S_IFLNK */
 }
 \f
 Lisp_Object
-make_time (time)
-     time_t time;
+make_time (time_t time)
 {
   return Fcons (make_number (time >> 16),
                Fcons (make_number (time & 0177777), Qnil));
@@ -973,8 +928,7 @@ which see.
 
 On some FAT-based filesystems, only the date of last access is recorded,
 so last access time will always be midnight of that day.  */)
-     (filename, id_format)
-     Lisp_Object filename, id_format;
+  (Lisp_Object filename, Lisp_Object id_format)
 {
   Lisp_Object values[12];
   Lisp_Object encoded;
@@ -983,7 +937,11 @@ so last access time will always be midnight of that day.  */)
   Lisp_Object dirname;
   struct stat sdir;
 #endif /* BSD4_2 */
-  char modes[10];
+
+  /* An array to hold the mode string generated by filemodestring,
+     including its terminating space and null byte.  */
+  char modes[sizeof "-rwxr-xr-x "];
+
   Lisp_Object handler;
   struct gcpro gcpro1;
   char *uname = NULL, *gname = NULL;
@@ -1006,20 +964,11 @@ so last access time will always be midnight of that day.  */)
   encoded = ENCODE_FILE (filename);
   UNGCPRO;
 
-  if (lstat (SDATA (encoded), &s) < 0)
+  if (lstat (SSDATA (encoded), &s) < 0)
     return Qnil;
 
-  switch (s.st_mode & S_IFMT)
-    {
-    default:
-      values[0] = Qnil; break;
-    case S_IFDIR:
-      values[0] = Qt; break;
-#ifdef S_IFLNK
-    case S_IFLNK:
-      values[0] = Ffile_symlink_p (filename); break;
-#endif
-    }
+  values[0] = (S_ISLNK (s.st_mode) ? Ffile_symlink_p (filename)
+              : S_ISDIR (s.st_mode) ? Qt : Qnil);
   values[1] = make_number (s.st_nlink);
 
   if (!(NILP (id_format) || EQ (id_format, Qinteger)))
@@ -1096,14 +1045,13 @@ so last access time will always be midnight of that day.  */)
 DEFUN ("file-attributes-lessp", Ffile_attributes_lessp, Sfile_attributes_lessp, 2, 2, 0,
        doc: /* Return t if first arg file attributes list is less than second.
 Comparison is in lexicographic order and case is significant.  */)
-     (f1, f2)
-     Lisp_Object f1, f2;
+  (Lisp_Object f1, Lisp_Object f2)
 {
   return Fstring_lessp (Fcar (f1), Fcar (f2));
 }
 \f
 void
-syms_of_dired ()
+syms_of_dired (void)
 {
   Qdirectory_files = intern_c_string ("directory-files");
   Qdirectory_files_and_attributes = intern_c_string ("directory-files-and-attributes");
@@ -1128,7 +1076,7 @@ syms_of_dired ()
   defsubr (&Sfile_attributes);
   defsubr (&Sfile_attributes_lessp);
 
-  DEFVAR_LISP ("completion-ignored-extensions", &Vcompletion_ignored_extensions,
+  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
 these strings or when displaying a list of completions.
@@ -1136,6 +1084,3 @@ It ignores directory names if they match any string in this list which
 ends in a slash.  */);
   Vcompletion_ignored_extensions = Qnil;
 }
-
-/* arch-tag: 1ac8deca-4d8f-4d41-ade9-089154d98c03
-   (do not change this comment) */