This commit was generated by cvs2svn to compensate for changes in r5670,
[chise/xemacs-chise.git.1] / src / dired.c
index 472133e..e0639f9 100644 (file)
@@ -23,16 +23,17 @@ Boston, MA 02111-1307, USA.  */
 #include <config.h>
 #include "lisp.h"
 
-#include "buffer.h"
-#include "commands.h"
-#include "elhash.h"
-#include "regex.h"
-#include "opaque.h"
 #include "sysfile.h"
 #include "sysdir.h"
 #include "systime.h"
 #include "sysdep.h"
 #include "syspwd.h"
+#include "buffer.h"
+#include "commands.h"
+#include "elhash.h"
+#include "regex.h"
+#include "opaque.h"
+#include "syntax.h"
 
 Lisp_Object Vcompletion_ignored_extensions;
 Lisp_Object Qdirectory_files;
@@ -110,7 +111,7 @@ If FILES-ONLY is the symbol t, then only the "files" in the directory
       /* MATCH might be a flawed regular expression.  Rather than
         catching and signalling our own errors, we just call
         compile_pattern to do the work for us.  */
-      bufp = compile_pattern (match, 0, 0, 0, ERROR_ME);
+      bufp = compile_pattern (match, 0, Qnil, 0, ERROR_ME);
     }
 
   /* Now *bufp is the compiled form of MATCH; don't call anything
@@ -123,6 +124,10 @@ If FILES-ONLY is the symbol t, then only the "files" in the directory
   if (!d)
     report_file_error ("Opening directory", list1 (directory));
 
+  /* #### In Matt's code, this was Qt.  Why? */
+  regex_match_object = Qnil;
+  regex_emacs_buffer = current_buffer;
+
   record_unwind_protect (close_directory_unwind, make_opaque_ptr ((void *)d));
 
   /* Loop reading blocks */
@@ -146,7 +151,7 @@ If FILES-ONLY is the symbol t, then only the "files" in the directory
              memcpy (statbuf_tail, dp->d_name, len);
              statbuf_tail[len] = 0;
 
-             if (stat (statbuf, &st) == 0
+             if (xemacs_stat (statbuf, &st) == 0
                  && (st.st_mode & S_IFMT) == S_IFDIR)
                dir_p = 1;
 
@@ -179,18 +184,18 @@ static Lisp_Object file_name_completion (Lisp_Object file,
                                          int all_flag, int ver_flag);
 
 DEFUN ("file-name-completion", Ffile_name_completion, 2, 2, 0, /*
-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.
-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.
+Complete file name PARTIAL-FILENAME in directory DIRECTORY.
+Return the longest prefix common to all file names in DIRECTORY
+that start with PARTIAL-FILENAME.
+If there is only one and PARTIAL-FILENAME matches it exactly, return t.
+Return nil if DIRECTORY contains no name starting with PARTIAL-FILENAME.
+
+File names which end with any member of `completion-ignored-extensions'
+are not considered as possible completions for PARTIAL-FILENAME unless
+there is no other possible completion. `completion-ignored-extensions'
+is not applied to the names of directories.
 */
-       (file, directory))
+       (partial_filename, directory))
 {
   /* This function can GC.  GC checked 1996.04.06. */
   Lisp_Object handler;
@@ -199,27 +204,22 @@ to the names of directories.
      call the corresponding file handler.  */
   handler = Ffind_file_name_handler (directory, Qfile_name_completion);
   if (!NILP (handler))
-    return call3 (handler, Qfile_name_completion, file, directory);
+    return call3 (handler, Qfile_name_completion, partial_filename, directory);
 
   /* If the file name has special constructs in it,
      call the corresponding file handler.  */
-  handler = Ffind_file_name_handler (file, Qfile_name_completion);
+  handler = Ffind_file_name_handler (partial_filename, Qfile_name_completion);
   if (!NILP (handler))
-    return call3 (handler, Qfile_name_completion, file, directory);
+    return call3 (handler, Qfile_name_completion, partial_filename, directory);
 
-  return file_name_completion (file, directory, 0, 0);
+  return file_name_completion (partial_filename, directory, 0, 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 DIRECTORY.
-These are all file names in directory DIRECTORY which begin with FILE.
-
-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.
+Return a list of all completions of PARTIAL-FILENAME in DIRECTORY.
+These are all file names in DIRECTORY which begin with PARTIAL-FILENAME.
 */
-       (file, directory))
+       (partial_filename, directory))
 {
   /* This function can GC. GC checked 1997.06.04. */
   Lisp_Object handler;
@@ -232,10 +232,10 @@ to the names of directories.
   handler = Ffind_file_name_handler (directory, Qfile_name_all_completions);
   UNGCPRO;
   if (!NILP (handler))
-    return call3 (handler, Qfile_name_all_completions, file,
+    return call3 (handler, Qfile_name_all_completions, partial_filename,
                  directory);
 
-  return file_name_completion (file, directory, 1, 0);
+  return file_name_completion (partial_filename, directory, 1, 0);
 }
 
 static int
@@ -260,9 +260,9 @@ file_name_completion_stat (Lisp_Object directory, DIRENTRY *dp,
      in case it is a directory.  */
   value = lstat (fullname, st_addr);
   if (S_ISLNK (st_addr->st_mode))
-    stat (fullname, st_addr);
+    xemacs_stat (fullname, st_addr);
 #else
-  value = stat (fullname, st_addr);
+  value = xemacs_stat (fullname, st_addr);
 #endif
   return value;
 }
@@ -303,11 +303,11 @@ file_name_completion (Lisp_Object file, Lisp_Object directory, int all_flag,
 
   CHECK_STRING (file);
 
-#ifdef WINDOWSNT
+#ifdef WIN32_NATIVE
   /* Filename completion on Windows ignores case, since Windows
      filesystems do.  */
   specbind (Qcompletion_ignore_case, Qt);
-#endif /* WINDOWSNT */
+#endif /* WIN32_NATIVE */
 
 #ifdef FILE_SYSTEM_CASE
   file = FILE_SYSTEM_CASE (file);
@@ -507,58 +507,65 @@ file_name_completion (Lisp_Object file, Lisp_Object directory, int all_flag,
 
 \f
 
-/* The *pwent() functions do not exist on NT */
-#ifndef  WINDOWSNT
+/* The *pwent() functions do not exist on NT.  #### The NT equivalent
+   is NetUserEnum(), and rewriting to use it is not hard.*/
+#ifndef  WIN32_NATIVE
 
 static Lisp_Object user_name_completion (Lisp_Object user,
                                          int all_flag,
                                          int *uniq);
 
 DEFUN ("user-name-completion", Fuser_name_completion, 1, 1, 0, /*
-Complete user name USER.
-
-Returns the longest string common to all user names that start
-with USER.  If there is only one and USER matches it exactly,
-returns t.  Returns nil if there is no user name starting with USER.
+Complete user name from PARTIAL-USERNAME.
+Return the longest prefix common to all user names starting with
+PARTIAL-USERNAME.  If there is only one and PARTIAL-USERNAME matches
+it exactly, returns t.  Return nil if there is no user name starting
+with PARTIAL-USERNAME.
 */
-       (user))
+       (partial_username))
 {
-  return user_name_completion (user, 0, NULL);
+  return user_name_completion (partial_username, 0, NULL);
 }
 
 DEFUN ("user-name-completion-1", Fuser_name_completion_1, 1, 1, 0, /*
-Complete user name USER.
+Complete user name from PARTIAL-USERNAME.
 
 This function is identical to `user-name-completion', except that
 the cons of the completion and an indication of whether the
 completion was unique is returned.
 
-The car of the returned value is the longest string common to all
-user names that start with USER.  If there is only one and USER
-matches it exactly, the car is t.  The car is nil if there is no
-user name starting with USER.  The cdr of the result is non-nil
-if and only if the completion returned in the car was unique.
+The car of the returned value is the longest prefix common to all user
+names that start with PARTIAL-USERNAME.  If there is only one and
+PARTIAL-USERNAME matches it exactly, the car is t.  The car is nil if
+there is no user name starting with PARTIAL-USERNAME.  The cdr of the
+result is non-nil if and only if the completion returned in the car
+was unique.
 */
-       (user))
+       (partial_username))
 {
   int uniq;
-  Lisp_Object completed;
-
-  completed = user_name_completion (user, 0, &uniq);
+  Lisp_Object completed = user_name_completion (partial_username, 0, &uniq);
   return Fcons (completed, uniq ? Qt : Qnil);
 }
 
 DEFUN ("user-name-all-completions", Fuser_name_all_completions, 1, 1, 0, /*
-Return a list of all completions of user name USER.
-These are all user names which begin with USER.
+Return a list of all user name completions from PARTIAL-USERNAME.
+These are all the user names which begin with PARTIAL-USERNAME.
 */
-       (user))
+       (partial_username))
 {
-  return user_name_completion (user, 1, NULL);
+  return user_name_completion (partial_username, 1, NULL);
 }
 
-struct user_cache {
-  char **data;
+struct user_name
+{
+  Bufbyte *ptr;
+  size_t len;
+};
+
+struct user_cache
+{
+  struct user_name *user_names;
   int length;
   int size;
   EMACS_TIME last_rebuild_time;
@@ -570,27 +577,26 @@ free_user_cache (struct user_cache *cache)
 {
   int i;
   for (i = 0; i < cache->length; i++)
-    xfree (cache->data[i]);
-  xfree (cache->data);
+    xfree (cache->user_names[i].ptr);
+  xfree (cache->user_names);
+  xzero (*cache);
 }
 
 static Lisp_Object
-user_name_completion_unwind (Lisp_Object locative)
+user_name_completion_unwind (Lisp_Object cache_incomplete_p)
 {
-  int interrupted = !NILP (XCAR (locative));
+  endpwent ();
+  speed_up_interrupts ();
 
-  if (interrupted)
-    {
-      endpwent ();
-      speed_up_interrupts ();
-      free_user_cache (&user_cache);
-    }
-  free_cons (XCONS (locative));
+  if (! NILP (XCAR (cache_incomplete_p)))
+    free_user_cache (&user_cache);
+
+  free_cons (XCONS (cache_incomplete_p));
 
   return Qnil;
 }
 
-#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)
@@ -599,7 +605,6 @@ user_name_completion (Lisp_Object user, int all_flag, int *uniq)
   int matchcount = 0;
   Lisp_Object bestmatch = Qnil;
   Charcount bestmatchsize = 0;
-  int speccount = specpdl_depth ();
   Charcount user_name_length;
   EMACS_TIME t;
   int i;
@@ -614,41 +619,42 @@ 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);
-  if (user_cache.data  &&
+  if (user_cache.user_names &&
       (EMACS_SECS (t) - EMACS_SECS (user_cache.last_rebuild_time)
-       > USER_CACHE_REBUILD))
-    {
-      free_user_cache (&user_cache);
-      xzero (user_cache);
-    }
+       > USER_CACHE_TTL))
+    free_user_cache (&user_cache);
 
-  if (!user_cache.data)
+  if (!user_cache.user_names)
     {
       struct passwd *pwd;
-      Lisp_Object locative = noseeum_cons (Qt, Qnil);
+      Lisp_Object cache_incomplete_p = noseeum_cons (Qt, Qnil);
+      int speccount = specpdl_depth ();
+
       slow_down_interrupts ();
       setpwent ();
-      record_unwind_protect (user_name_completion_unwind, locative);
+      record_unwind_protect (user_name_completion_unwind, cache_incomplete_p);
       while ((pwd = getpwent ()))
         {
-         Bufbyte *pwuser;
           QUIT;
-         DO_REALLOC (user_cache.data, user_cache.size,
-                     user_cache.length + 1, char *);
-         GET_C_CHARPTR_INT_DATA_ALLOCA (pwd->pw_name, FORMAT_OS, pwuser);
-          user_cache.data[user_cache.length++] = xstrdup (pwuser);
+         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++;
         }
-      endpwent ();
-      speed_up_interrupts ();
-      XCAR (locative) = Qnil;
-      unbind_to (speccount, Qnil); /* free locative cons */
+      XCAR (cache_incomplete_p) = Qnil;
+      unbind_to (speccount, Qnil);
+
       EMACS_GET_TIME (user_cache.last_rebuild_time);
     }
 
   for (i = 0; i < user_cache.length; i++)
     {
-      Bufbyte *u_name = user_cache.data[i];
-      Bytecount len = strlen ((char *) u_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: */
       Charcount cclen = bytecount_to_charcount (u_name, len);
 
@@ -703,11 +709,11 @@ user_name_completion (Lisp_Object user, int all_flag, int *uniq)
     return Qt;
   return Fsubstring (bestmatch, Qzero, make_int (bestmatchsize));
 }
-#endif   /* ! defined WINDOWSNT */
+#endif   /* ! defined WIN32_NATIVE */
 
 \f
 Lisp_Object
-make_directory_hash_table (CONST char *path)
+make_directory_hash_table (const char *path)
 {
   DIR *d;
   if ((d = opendir (path)))
@@ -730,6 +736,9 @@ make_directory_hash_table (CONST char *path)
     return Qnil;
 }
 \f
+#if 0
+/* ... never used ... should use list2 directly anyway ... */
+/* NOTE: This function can never return a negative value. */
 Lisp_Object
 wasteful_word_to_lisp (unsigned int item)
 {
@@ -739,6 +748,7 @@ wasteful_word_to_lisp (unsigned int item)
   XCDR (cons) = Fcons (XCDR (cons), Qnil);
   return cons;
 }
+#endif
 
 DEFUN ("file-attributes", Ffile_attributes, 1, 1, 0, /*
 Return a list of attributes of file FILENAME.
@@ -792,7 +802,7 @@ If file does not exist, returns nil.
   directory = Ffile_name_directory (filename);
 #endif
 
-#ifdef MSDOS
+#if 0 /* #### shouldn't this apply to WIN32_NATIVE and maybe CYGWIN? */
   {
     char *tmpnam = (char *) XSTRING_DATA (Ffile_name_nondirectory (filename));
     int l = strlen (tmpnam);
@@ -806,7 +816,7 @@ If file does not exist, returns nil.
        s.st_mode |= S_IEXEC;
       }
   }
-#endif /* MSDOS */
+#endif
 
   switch (s.st_mode & S_IFMT)
     {
@@ -825,9 +835,9 @@ If file does not exist, returns nil.
   values[1] = make_int (s.st_nlink);
   values[2] = make_int (s.st_uid);
   values[3] = make_int (s.st_gid);
-  values[4] = wasteful_word_to_lisp (s.st_atime);
-  values[5] = wasteful_word_to_lisp (s.st_mtime);
-  values[6] = wasteful_word_to_lisp (s.st_ctime);
+  values[4] = make_time (s.st_atime);
+  values[5] = make_time (s.st_mtime);
+  values[6] = make_time (s.st_ctime);
   values[7] = make_int ((EMACS_INT) s.st_size);
   /* If the size is out of range, give back -1.  */
   /* #### Fix when Emacs gets bignums! */
@@ -839,7 +849,7 @@ If file does not exist, returns nil.
   {
     struct stat sdir;
 
-    if (!NILP (directory) && stat ((char *) XSTRING_DATA (directory), &sdir) == 0)
+    if (!NILP (directory) && xemacs_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;
@@ -869,7 +879,7 @@ syms_of_dired (void)
   DEFSUBR (Fdirectory_files);
   DEFSUBR (Ffile_name_completion);
   DEFSUBR (Ffile_name_all_completions);
-#ifndef  WINDOWSNT
+#ifndef  WIN32_NATIVE
   DEFSUBR (Fuser_name_completion);
   DEFSUBR (Fuser_name_completion_1);
   DEFSUBR (Fuser_name_all_completions);
@@ -884,8 +894,7 @@ vars_of_dired (void)
 *Completion ignores filenames ending in any string in this list.
 This variable does not affect lists of possible completions,
 but does affect the commands that actually do completions.
-It is used by the functions `file-name-completion' and
-`file-name-all-completions'.
+It is used by the function `file-name-completion'.
 */ );
   Vcompletion_ignored_extensions = Qnil;
 }