XEmacs 21.2.28 "Hermes".
[chise/xemacs-chise.git.1] / src / dired.c
index da7ed57..b7077e3 100644 (file)
@@ -31,6 +31,7 @@ Boston, MA 02111-1307, USA.  */
 #include "sysfile.h"
 #include "sysdir.h"
 #include "systime.h"
 #include "sysfile.h"
 #include "sysdir.h"
 #include "systime.h"
+#include "sysdep.h"
 #include "syspwd.h"
 
 Lisp_Object Vcompletion_ignored_extensions;
 #include "syspwd.h"
 
 Lisp_Object Vcompletion_ignored_extensions;
@@ -61,43 +62,43 @@ If FILES-ONLY is the symbol t, then only the "files" in the directory
  if FILES-ONLY is nil (the default) then both files and subdirectories will
  be returned.
 */
  if FILES-ONLY is nil (the default) then both files and subdirectories will
  be returned.
 */
-       (dirname, full, match, nosort, files_only))
+       (directory, full, match, nosort, files_only))
 {
   /* This function can GC */
   DIR *d;
   Lisp_Object list = Qnil;
 {
   /* This function can GC */
   DIR *d;
   Lisp_Object list = Qnil;
-  Bytecount dirnamelen;
+  Bytecount directorylen;
   Lisp_Object handler;
   struct re_pattern_buffer *bufp = NULL;
   int speccount = specpdl_depth ();
   char *statbuf, *statbuf_tail;
 
   struct gcpro gcpro1, gcpro2;
   Lisp_Object handler;
   struct re_pattern_buffer *bufp = NULL;
   int speccount = specpdl_depth ();
   char *statbuf, *statbuf_tail;
 
   struct gcpro gcpro1, gcpro2;
-  GCPRO2 (dirname, list);
+  GCPRO2 (directory, list);
 
   /* If the file name has special constructs in it,
      call the corresponding file handler.  */
 
   /* If the file name has special constructs in it,
      call the corresponding file handler.  */
-  handler = Ffind_file_name_handler (dirname, Qdirectory_files);
+  handler = Ffind_file_name_handler (directory, Qdirectory_files);
   if (!NILP (handler))
     {
       UNGCPRO;
       if (!NILP (files_only))
   if (!NILP (handler))
     {
       UNGCPRO;
       if (!NILP (files_only))
-       return call6 (handler, Qdirectory_files, dirname, full, match, nosort,
-                     files_only);
+       return call6 (handler, Qdirectory_files, directory, full, match,
+                     nosort, files_only);
       else
       else
-       return call5 (handler, Qdirectory_files, dirname, full, match,
+       return call5 (handler, Qdirectory_files, directory, full, match,
                      nosort);
     }
 
   /* #### why do we do Fexpand_file_name after file handlers here,
      but earlier everywhere else? */
                      nosort);
     }
 
   /* #### why do we do Fexpand_file_name after file handlers here,
      but earlier everywhere else? */
-  dirname = Fexpand_file_name (dirname, Qnil);
-  dirname = Ffile_name_as_directory (dirname);
-  dirnamelen = XSTRING_LENGTH (dirname);
+  directory = Fexpand_file_name (directory, Qnil);
+  directory = Ffile_name_as_directory (directory);
+  directorylen = XSTRING_LENGTH (directory);
 
 
-  statbuf = (char *)alloca (dirnamelen + MAXNAMLEN + 1);
-  memcpy (statbuf, XSTRING_DATA (dirname), dirnamelen);
-  statbuf_tail = statbuf + dirnamelen;
+  statbuf = (char *)alloca (directorylen + MAXNAMLEN + 1);
+  memcpy (statbuf, XSTRING_DATA (directory), directorylen);
+  statbuf_tail = statbuf + directorylen;
 
   /* XEmacs: this should come after Ffile_name_as_directory() to avoid
      potential regexp cache smashage.  It comes before the opendir()
 
   /* XEmacs: this should come after Ffile_name_as_directory() to avoid
      potential regexp cache smashage.  It comes before the opendir()
@@ -118,9 +119,9 @@ If FILES-ONLY is the symbol t, then only the "files" in the directory
   /* Do this opendir after anything which might signal an error.
      NOTE: the above comment is old; previously, there was no
      unwind-protection in case of error, but now there is.  */
   /* Do this opendir after anything which might signal an error.
      NOTE: the above comment is old; previously, there was no
      unwind-protection in case of error, but now there is.  */
-  d = opendir ((char *) XSTRING_DATA (dirname));
+  d = opendir ((char *) XSTRING_DATA (directory));
   if (!d)
   if (!d)
-    report_file_error ("Opening directory", list1 (dirname));
+    report_file_error ("Opening directory", list1 (directory));
 
   record_unwind_protect (close_directory_unwind, make_opaque_ptr ((void *)d));
 
 
   record_unwind_protect (close_directory_unwind, make_opaque_ptr ((void *)d));
 
@@ -139,38 +140,15 @@ If FILES-ONLY is the symbol t, then only the "files" in the directory
        {
          if (!NILP (files_only))
            {
        {
          if (!NILP (files_only))
            {
-             int dir_p;
              struct stat st;
              struct stat st;
-             char *cur_statbuf = statbuf;
-             char *cur_statbuf_tail = statbuf_tail;
-
-             /* #### I don't think the code under `if' is necessary
-                anymore.  The crashes in this function were reported
-                because MAXNAMLEN was used to remember the *whole*
-                statbuf, instead of using MAXPATHLEN.  This should be
-                tested after 21.0 is released.  */
-
-             /* We normally use the buffer created by alloca.
-                However, if the file name we get too big, we'll use a
-                malloced buffer, and free it.  It is undefined how
-                stat() will react to this, but we avoid a buffer
-                overrun.  */
-             if (len > MAXNAMLEN)
-               {
-                 cur_statbuf = (char *)xmalloc (dirnamelen + len + 1);
-                 memcpy (cur_statbuf, statbuf, dirnamelen);
-                 cur_statbuf_tail = cur_statbuf + dirnamelen;
-               }
-             memcpy (cur_statbuf_tail, dp->d_name, len);
-             cur_statbuf_tail[len] = 0;
+             int dir_p = 0;
 
 
-             if (stat (cur_statbuf, &st) < 0)
-               dir_p = 0;
-             else
-               dir_p = ((st.st_mode & S_IFMT) == S_IFDIR);
+             memcpy (statbuf_tail, dp->d_name, len);
+             statbuf_tail[len] = 0;
 
 
-             if (cur_statbuf != statbuf)
-               xfree (cur_statbuf);
+             if (stat (statbuf, &st) == 0
+                 && (st.st_mode & S_IFMT) == S_IFDIR)
+               dir_p = 1;
 
              if (EQ (files_only, Qt) && dir_p)
                continue;
 
              if (EQ (files_only, Qt) && dir_p)
                continue;
@@ -180,9 +158,9 @@ If FILES-ONLY is the symbol t, then only the "files" in the directory
 
          {
            Lisp_Object name =
 
          {
            Lisp_Object name =
-             make_ext_string ((Bufbyte *)dp->d_name, len, FORMAT_FILENAME);
+             make_string ((Bufbyte *)dp->d_name, len);
            if (!NILP (full))
            if (!NILP (full))
-             name = concat2 (dirname, name);
+             name = concat2 (directory, name);
 
            list = Fcons (name, list);
          }
 
            list = Fcons (name, list);
          }
@@ -197,79 +175,79 @@ If FILES-ONLY is the symbol t, then only the "files" in the directory
 }
 \f
 static Lisp_Object file_name_completion (Lisp_Object file,
 }
 \f
 static Lisp_Object file_name_completion (Lisp_Object file,
-                                         Lisp_Object dirname,
+                                         Lisp_Object directory,
                                          int all_flag, int ver_flag);
 
 DEFUN ("file-name-completion", Ffile_name_completion, 2, 2, 0, /*
                                          int all_flag, int ver_flag);
 
 DEFUN ("file-name-completion", Ffile_name_completion, 2, 2, 0, /*
-Complete file name FILE in directory DIR.
-Returns the longest string common to all filenames in DIR
+Complete file name FILE in directory DIRECTORY.
+Returns the longest string common to all filenames in DIRECTORY
 that start with FILE.
 If there is only one and FILE matches it exactly, returns t.
 that start with FILE.
 If there is only one and FILE matches it exactly, returns t.
-Returns nil if DIR contains no name starting with FILE.
+Returns nil if DIRECTORY contains no name starting with FILE.
 
 Filenames which end with any member of `completion-ignored-extensions'
 are not considered as possible completions for FILE unless there is no
 other possible completion.  `completion-ignored-extensions' is not applied
 to the names of directories.
 */
 
 Filenames which end with any member of `completion-ignored-extensions'
 are not considered as possible completions for FILE unless there is no
 other possible completion.  `completion-ignored-extensions' is not applied
 to the names of directories.
 */
-       (file, dirname))
+       (file, directory))
 {
   /* This function can GC.  GC checked 1996.04.06. */
   Lisp_Object handler;
 
   /* If the directory name has special constructs in it,
      call the corresponding file handler.  */
 {
   /* This function can GC.  GC checked 1996.04.06. */
   Lisp_Object handler;
 
   /* If the directory name has special constructs in it,
      call the corresponding file handler.  */
-  handler = Ffind_file_name_handler (dirname, Qfile_name_completion);
+  handler = Ffind_file_name_handler (directory, Qfile_name_completion);
   if (!NILP (handler))
   if (!NILP (handler))
-    return call3 (handler, Qfile_name_completion, file, dirname);
+    return call3 (handler, Qfile_name_completion, file, directory);
 
   /* If the file name has special constructs in it,
      call the corresponding file handler.  */
   handler = Ffind_file_name_handler (file, Qfile_name_completion);
   if (!NILP (handler))
 
   /* If the file name has special constructs in it,
      call the corresponding file handler.  */
   handler = Ffind_file_name_handler (file, Qfile_name_completion);
   if (!NILP (handler))
-    return call3 (handler, Qfile_name_completion, file, dirname);
+    return call3 (handler, Qfile_name_completion, file, directory);
 
 
-  return file_name_completion (file, dirname, 0, 0);
+  return file_name_completion (file, directory, 0, 0);
 }
 
 DEFUN ("file-name-all-completions", Ffile_name_all_completions, 2, 2, 0, /*
 }
 
 DEFUN ("file-name-all-completions", Ffile_name_all_completions, 2, 2, 0, /*
-Return a list of all completions of file name FILE in directory DIR.
-These are all file names in directory DIR which begin with FILE.
+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.
 
 
-Filenames which end with any member of `completion-ignored-extensions'
+File names which end with any member of `completion-ignored-extensions'
 are not considered as possible completions for FILE unless there is no
 other possible completion.  `completion-ignored-extensions' is not applied
 to the names of directories.
 */
 are not considered as possible completions for FILE unless there is no
 other possible completion.  `completion-ignored-extensions' is not applied
 to the names of directories.
 */
-       (file, dirname))
+       (file, directory))
 {
   /* This function can GC. GC checked 1997.06.04. */
   Lisp_Object handler;
   struct gcpro gcpro1;
 
 {
   /* This function can GC. GC checked 1997.06.04. */
   Lisp_Object handler;
   struct gcpro gcpro1;
 
-  GCPRO1 (dirname);
-  dirname = Fexpand_file_name (dirname, Qnil);
+  GCPRO1 (directory);
+  directory = Fexpand_file_name (directory, Qnil);
   /* If the file name has special constructs in it,
      call the corresponding file handler.  */
   /* If the file name has special constructs in it,
      call the corresponding file handler.  */
-  handler = Ffind_file_name_handler (dirname, Qfile_name_all_completions);
+  handler = Ffind_file_name_handler (directory, Qfile_name_all_completions);
   UNGCPRO;
   if (!NILP (handler))
     return call3 (handler, Qfile_name_all_completions, file,
   UNGCPRO;
   if (!NILP (handler))
     return call3 (handler, Qfile_name_all_completions, file,
-                 dirname);
+                 directory);
 
 
-  return file_name_completion (file, dirname, 1, 0);
+  return file_name_completion (file, directory, 1, 0);
 }
 
 static int
 }
 
 static int
-file_name_completion_stat (Lisp_Object dirname, DIRENTRY *dp,
+file_name_completion_stat (Lisp_Object directory, DIRENTRY *dp,
                           struct stat *st_addr)
 {
   Bytecount len = NAMLEN (dp);
                           struct stat *st_addr)
 {
   Bytecount len = NAMLEN (dp);
-  Bytecount pos = XSTRING_LENGTH (dirname);
+  Bytecount pos = XSTRING_LENGTH (directory);
   int value;
   char *fullname = (char *) alloca (len + pos + 2);
 
   int value;
   char *fullname = (char *) alloca (len + pos + 2);
 
-  memcpy (fullname, XSTRING_DATA (dirname), pos);
+  memcpy (fullname, XSTRING_DATA (directory), pos);
   if (!IS_DIRECTORY_SEP (fullname[pos - 1]))
     fullname[pos++] = DIRECTORY_SEP;
 
   if (!IS_DIRECTORY_SEP (fullname[pos - 1]))
     fullname[pos++] = DIRECTORY_SEP;
 
@@ -306,7 +284,7 @@ file_name_completion_unwind (Lisp_Object locative)
 }
 
 static Lisp_Object
 }
 
 static Lisp_Object
-file_name_completion (Lisp_Object file, Lisp_Object dirname, int all_flag,
+file_name_completion (Lisp_Object file, Lisp_Object directory, int all_flag,
                      int ver_flag)
 {
   /* This function can GC */
                      int ver_flag)
 {
   /* This function can GC */
@@ -321,7 +299,7 @@ file_name_completion (Lisp_Object file, Lisp_Object dirname, int all_flag,
   Lisp_Object locative;
   struct gcpro gcpro1, gcpro2, gcpro3;
 
   Lisp_Object locative;
   struct gcpro gcpro1, gcpro2, gcpro3;
 
-  GCPRO3 (file, dirname, bestmatch);
+  GCPRO3 (file, directory, bestmatch);
 
   CHECK_STRING (file);
 
 
   CHECK_STRING (file);
 
@@ -334,7 +312,7 @@ file_name_completion (Lisp_Object file, Lisp_Object dirname, int all_flag,
 #ifdef FILE_SYSTEM_CASE
   file = FILE_SYSTEM_CASE (file);
 #endif
 #ifdef FILE_SYSTEM_CASE
   file = FILE_SYSTEM_CASE (file);
 #endif
-  dirname = Fexpand_file_name (dirname, Qnil);
+  directory = Fexpand_file_name (directory, Qnil);
   file_name_length = XSTRING_CHAR_LENGTH (file);
 
   /* With passcount = 0, ignore files that end in an ignored extension.
   file_name_length = XSTRING_CHAR_LENGTH (file);
 
   /* With passcount = 0, ignore files that end in an ignored extension.
@@ -355,9 +333,9 @@ file_name_completion (Lisp_Object file, Lisp_Object dirname, int all_flag,
 
   for (passcount = !!all_flag; NILP (bestmatch) && passcount < 2; passcount++)
     {
 
   for (passcount = !!all_flag; NILP (bestmatch) && passcount < 2; passcount++)
     {
-      d = opendir ((char *) XSTRING_DATA (Fdirectory_file_name (dirname)));
+      d = opendir ((char *) XSTRING_DATA (Fdirectory_file_name (directory)));
       if (!d)
       if (!d)
-       report_file_error ("Opening directory", list1 (dirname));
+       report_file_error ("Opening directory", list1 (directory));
       XCAR (locative) = make_opaque_ptr ((void *)d);
 
       /* Loop reading blocks */
       XCAR (locative) = make_opaque_ptr ((void *)d);
 
       /* Loop reading blocks */
@@ -387,7 +365,7 @@ file_name_completion (Lisp_Object file, Lisp_Object dirname, int all_flag,
              || 0 <= scmp (d_name, XSTRING_DATA (file), file_name_length))
            continue;
 
              || 0 <= scmp (d_name, XSTRING_DATA (file), file_name_length))
            continue;
 
-          if (file_name_completion_stat (dirname, dp, &st) < 0)
+          if (file_name_completion_stat (directory, dp, &st) < 0)
             continue;
 
           directoryp = ((st.st_mode & S_IFMT) == S_IFDIR);
             continue;
 
           directoryp = ((st.st_mode & S_IFMT) == S_IFDIR);
@@ -501,7 +479,7 @@ file_name_completion (Lisp_Object file, Lisp_Object dirname, int all_flag,
                     }
                 }
 
                     }
                 }
 
-              /* If this dirname all matches,
+              /* If this directory all matches,
                  see if implicit following slash does too.  */
               if (directoryp
                   && compare == matchsize
                  see if implicit following slash does too.  */
               if (directoryp
                   && compare == matchsize
@@ -564,9 +542,7 @@ if and only if the completion returned in the car was unique.
        (user))
 {
   int uniq;
        (user))
 {
   int uniq;
-  Lisp_Object completed;
-
-  completed = user_name_completion (user, 0, &uniq);
+  Lisp_Object completed = user_name_completion (user, 0, &uniq);
   return Fcons (completed, uniq ? Qt : Qnil);
 }
 
   return Fcons (completed, uniq ? Qt : Qnil);
 }
 
@@ -579,54 +555,57 @@ These are all user names which begin with USER.
   return user_name_completion (user, 1, NULL);
 }
 
   return user_name_completion (user, 1, NULL);
 }
 
-static Lisp_Object
-user_name_completion_unwind (Lisp_Object locative)
+struct user_name
 {
 {
-  Lisp_Object obj1 = XCAR (locative);
-  Lisp_Object obj2 = XCDR (locative);
-  char **cache;
-  int clen, i;
+  Bufbyte *ptr;
+  size_t len;
+};
 
 
+struct user_cache
+{
+  struct user_name *user_names;
+  int length;
+  int size;
+  EMACS_TIME last_rebuild_time;
+};
+static struct user_cache user_cache;
+
+static void
+free_user_cache (struct user_cache *cache)
+{
+  int i;
+  for (i = 0; i < cache->length; i++)
+    xfree (cache->user_names[i].ptr);
+  xfree (cache->user_names);
+  xzero (*cache);
+}
 
 
-  if (!NILP (obj1) && !NILP (obj2))
-    {
-      /* clean up if interrupted building cache */
-      cache = *(char ***)get_opaque_ptr (obj1);
-      clen  = *(int *)get_opaque_ptr (obj2);
-      free_opaque_ptr (obj1);
-      free_opaque_ptr (obj2);
-      for (i = 0; i < clen; i++)
-        free (cache[i]);
-      free (cache);
-    }
-
-  free_cons (XCONS (locative));
+static Lisp_Object
+user_name_completion_unwind (Lisp_Object cache_incomplete_p)
+{
   endpwent ();
   endpwent ();
+  speed_up_interrupts ();
+
+  if (! NILP (XCAR (cache_incomplete_p)))
+    free_user_cache (&user_cache);
+
+  free_cons (XCONS (cache_incomplete_p));
 
   return Qnil;
 }
 
 
   return Qnil;
 }
 
-static char **user_cache;
-static int user_cache_len;
-static int user_cache_max;
-static long user_cache_time;
-
-#define  USER_CACHE_REBUILD  (24*60*60)  /* 1 day, in seconds */
+#define  USER_CACHE_TTL  (24*60*60)  /* Time to live: 1 day, in seconds */
 
 static Lisp_Object
 user_name_completion (Lisp_Object user, int all_flag, int *uniq)
 {
   /* This function can GC */
 
 static Lisp_Object
 user_name_completion (Lisp_Object user, int all_flag, int *uniq)
 {
   /* This function can GC */
-  struct passwd *pw;
   int matchcount = 0;
   Lisp_Object bestmatch = Qnil;
   Charcount bestmatchsize = 0;
   int matchcount = 0;
   Lisp_Object bestmatch = Qnil;
   Charcount bestmatchsize = 0;
-  int speccount = specpdl_depth ();
-  int i, cmax, clen;
-  char **cache;
   Charcount user_name_length;
   Charcount user_name_length;
-  Lisp_Object locative;
   EMACS_TIME t;
   EMACS_TIME t;
+  int i;
   struct gcpro gcpro1, gcpro2;
 
   GCPRO2 (user, bestmatch);
   struct gcpro gcpro1, gcpro2;
 
   GCPRO2 (user, bestmatch);
@@ -638,67 +617,49 @@ user_name_completion (Lisp_Object user, int all_flag, int *uniq)
   /* Cache user name lookups because it tends to be quite slow.
    * Rebuild the cache occasionally to catch changes */
   EMACS_GET_TIME (t);
   /* Cache user name lookups because it tends to be quite slow.
    * Rebuild the cache occasionally to catch changes */
   EMACS_GET_TIME (t);
-  if (user_cache  &&
-      EMACS_SECS (t) - user_cache_time > USER_CACHE_REBUILD)
-    {
-      for (i = 0; i < user_cache_len; i++)
-        free (user_cache[i]);
-      free (user_cache);
-      user_cache = NULL;
-      user_cache_len = 0;
-      user_cache_max = 0;
-    }
+  if (user_cache.user_names &&
+      (EMACS_SECS (t) - EMACS_SECS (user_cache.last_rebuild_time)
+       > USER_CACHE_TTL))
+    free_user_cache (&user_cache);
 
 
-  if (user_cache == NULL || user_cache_max <= 0)
+  if (!user_cache.user_names)
     {
     {
-      cmax  = 200;
-      clen  = 0;
-      cache = (char **) malloc (cmax*sizeof (char *));
+      struct passwd *pwd;
+      Lisp_Object cache_incomplete_p = noseeum_cons (Qt, Qnil);
+      int speccount = specpdl_depth ();
 
 
+      slow_down_interrupts ();
       setpwent ();
       setpwent ();
-      locative = noseeum_cons (Qnil, Qnil);
-      XCAR (locative) = make_opaque_ptr ((void *) &cache);
-      XCDR (locative) = make_opaque_ptr ((void *) &clen);
-      record_unwind_protect (user_name_completion_unwind, locative);
-      /* #### may need to slow down interrupts around call to getpwent
-       * below.  at least the call to getpwnam in Fuser_full_name
-       * is documented as needing it on irix. */
-      while ((pw = getpwent ()))
+      record_unwind_protect (user_name_completion_unwind, cache_incomplete_p);
+      while ((pwd = getpwent ()))
         {
         {
-          if (clen >= cmax)
-            {
-              cmax *= 2;
-              cache = (char **) realloc (cache, cmax*sizeof (char *));
-            }
-
           QUIT;
           QUIT;
-
-          cache[clen++] = strdup (pw->pw_name);
+         DO_REALLOC (user_cache.user_names, user_cache.size,
+                     user_cache.length + 1, struct user_name);
+         TO_INTERNAL_FORMAT (C_STRING, pwd->pw_name,
+                             MALLOC,
+                             (user_cache.user_names[user_cache.length].ptr,
+                              user_cache.user_names[user_cache.length].len),
+                             Qnative);
+         user_cache.length++;
         }
         }
-      free_opaque_ptr (XCAR (locative));
-      free_opaque_ptr (XCDR (locative));
-      XCAR (locative) = Qnil;
-      XCDR (locative) = Qnil;
+      XCAR (cache_incomplete_p) = Qnil;
+      unbind_to (speccount, Qnil);
 
 
-      unbind_to (speccount, Qnil); /* free locative cons, endpwent() */
-
-      user_cache_max = cmax;
-      user_cache_len = clen;
-      user_cache = cache;
-      user_cache_time = EMACS_SECS (t);
+      EMACS_GET_TIME (user_cache.last_rebuild_time);
     }
 
     }
 
-  for (i = 0; i < user_cache_len; i++)
+  for (i = 0; i < user_cache.length; i++)
     {
     {
-      Bufbyte *d_name = (Bufbyte *) user_cache[i];
-      Bytecount len = strlen ((char *) d_name);
+      Bufbyte *u_name = user_cache.user_names[i].ptr;
+      Bytecount len   = user_cache.user_names[i].len;
       /* scmp() works in chars, not bytes, so we have to compute this: */
       /* scmp() works in chars, not bytes, so we have to compute this: */
-      Charcount cclen = bytecount_to_charcount (d_name, len);
+      Charcount cclen = bytecount_to_charcount (u_name, len);
 
       QUIT;
 
 
       QUIT;
 
-      if (cclen < user_name_length   ||
-          0 <= scmp (d_name, XSTRING_DATA (user), user_name_length))
+      if (cclen < user_name_length
+         || 0 <= scmp_1 (u_name, XSTRING_DATA (user), user_name_length, 0))
         continue;
 
       matchcount++;    /* count matching completions */
         continue;
 
       matchcount++;    /* count matching completions */
@@ -709,7 +670,7 @@ user_name_completion (Lisp_Object user, int all_flag, int *uniq)
           struct gcpro ngcpro1;
           NGCPRO1 (name);
           /* This is a possible completion */
           struct gcpro ngcpro1;
           NGCPRO1 (name);
           /* This is a possible completion */
-          name = make_string (d_name, len);
+          name = make_string (u_name, len);
           if (all_flag)
             {
               bestmatch = Fcons (name, bestmatch);
           if (all_flag)
             {
               bestmatch = Fcons (name, bestmatch);
@@ -725,37 +686,11 @@ user_name_completion (Lisp_Object user, int all_flag, int *uniq)
         {
           Charcount compare = min (bestmatchsize, cclen);
           Bufbyte *p1 = XSTRING_DATA (bestmatch);
         {
           Charcount compare = min (bestmatchsize, cclen);
           Bufbyte *p1 = XSTRING_DATA (bestmatch);
-          Bufbyte *p2 = d_name;
-          Charcount matchsize = scmp (p1, p2, compare);
+          Bufbyte *p2 = u_name;
+          Charcount matchsize = scmp_1 (p1, p2, compare, 0);
 
           if (matchsize < 0)
             matchsize = compare;
 
           if (matchsize < 0)
             matchsize = compare;
-          if (completion_ignore_case)
-            {
-              /* If this is an exact match except for case,
-                 use it as the best match rather than one that is not
-                 an exact match.  This way, we get the case pattern
-                 of the actual match.  */
-              if ((matchsize == cclen
-                   && matchsize < XSTRING_CHAR_LENGTH (bestmatch))
-                  ||
-                  /* If there is no exact match ignoring case,
-                     prefer a match that does not change the case
-                     of the input.  */
-                  (((matchsize == cclen)
-                    ==
-                    (matchsize == XSTRING_CHAR_LENGTH (bestmatch)))
-                   /* If there is more than one exact match aside from
-                      case, and one of them is exact including case,
-                      prefer that one.  */
-                   && 0 > scmp_1 (p2, XSTRING_DATA (user),
-                                  user_name_length, 0)
-                   && 0 <= scmp_1 (p1, XSTRING_DATA (user),
-                                   user_name_length, 0)))
-                {
-                  bestmatch = make_string (d_name, len);
-                }
-            }
 
           bestmatchsize = matchsize;
         }
 
           bestmatchsize = matchsize;
         }
@@ -779,11 +714,11 @@ Lisp_Object
 make_directory_hash_table (CONST char *path)
 {
   DIR *d;
 make_directory_hash_table (CONST char *path)
 {
   DIR *d;
-  Lisp_Object hash =
-    make_lisp_hash_table (100, HASH_TABLE_NON_WEAK, HASH_TABLE_EQUAL);
   if ((d = opendir (path)))
     {
       DIRENTRY *dp;
   if ((d = opendir (path)))
     {
       DIRENTRY *dp;
+      Lisp_Object hash =
+       make_lisp_hash_table (20, HASH_TABLE_NON_WEAK, HASH_TABLE_EQUAL);
 
       while ((dp = readdir (d)))
        {
 
       while ((dp = readdir (d)))
        {
@@ -793,8 +728,10 @@ make_directory_hash_table (CONST char *path)
            Fputhash (make_string ((Bufbyte *) dp->d_name, len), Qt, hash);
        }
       closedir (d);
            Fputhash (make_string ((Bufbyte *) dp->d_name, len), Qt, hash);
        }
       closedir (d);
+      return hash;
     }
     }
-  return hash;
+  else
+    return Qnil;
 }
 \f
 Lisp_Object
 }
 \f
 Lisp_Object
@@ -831,13 +768,13 @@ If file does not exist, returns nil.
 {
   /* This function can GC. GC checked 1997.06.04. */
   Lisp_Object values[12];
 {
   /* This function can GC. GC checked 1997.06.04. */
   Lisp_Object values[12];
-  Lisp_Object dirname = Qnil;
+  Lisp_Object directory = Qnil;
   struct stat s;
   char modes[10];
   Lisp_Object handler;
   struct gcpro gcpro1, gcpro2;
 
   struct stat s;
   char modes[10];
   Lisp_Object handler;
   struct gcpro gcpro1, gcpro2;
 
-  GCPRO2 (filename, dirname);
+  GCPRO2 (filename, directory);
   filename = Fexpand_file_name (filename, Qnil);
 
   /* If the file name has special constructs in it,
   filename = Fexpand_file_name (filename, Qnil);
 
   /* If the file name has special constructs in it,
@@ -856,7 +793,7 @@ If file does not exist, returns nil.
     }
 
 #ifdef BSD4_2
     }
 
 #ifdef BSD4_2
-  dirname = Ffile_name_directory (filename);
+  directory = Ffile_name_directory (filename);
 #endif
 
 #ifdef MSDOS
 #endif
 
 #ifdef MSDOS
@@ -906,7 +843,7 @@ If file does not exist, returns nil.
   {
     struct stat sdir;
 
   {
     struct stat sdir;
 
-    if (!NILP (dirname) && stat ((char *) XSTRING_DATA (dirname), &sdir) == 0)
+    if (!NILP (directory) && stat ((char *) XSTRING_DATA (directory), &sdir) == 0)
       values[9] = (sdir.st_gid != s.st_gid) ? Qt : Qnil;
     else                        /* if we can't tell, assume worst */
       values[9] = Qt;
       values[9] = (sdir.st_gid != s.st_gid) ? Qt : Qnil;
     else                        /* if we can't tell, assume worst */
       values[9] = Qt;
@@ -955,8 +892,4 @@ It is used by the functions `file-name-completion' and
 `file-name-all-completions'.
 */ );
   Vcompletion_ignored_extensions = Qnil;
 `file-name-all-completions'.
 */ );
   Vcompletion_ignored_extensions = Qnil;
-
-  user_cache = NULL;
-  user_cache_len = 0;
-  user_cache_max = 0;
 }
 }