]> code.delx.au - gnu-emacs/blobdiff - src/dired.c
* lread.c (read_char): Add an extern declaration for this,
[gnu-emacs] / src / dired.c
index 0cdc062c699943f19cec90d95be51d4cd79352ee..451907fbbe428cdf44c55fa3ba22cc300c431965 100644 (file)
@@ -1,5 +1,5 @@
 /* Lisp functions for making directory listings.
-   Copyright (C) 1985, 1986 Free Software Foundation, Inc.
+   Copyright (C) 1985, 1986, 1992 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -24,6 +24,12 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 #include "config.h"
 
+#ifdef VMS
+#include <string.h>
+#include <rms.h>
+#include <rmsdef.h>
+#endif
+
 #ifdef SYSV_SYSTEM_DIR
 
 #include <dirent.h>
@@ -46,8 +52,6 @@ extern struct direct *readdir ();
 
 #endif
 
-#undef NULL
-
 #include "lisp.h"
 #include "buffer.h"
 #include "commands.h"
@@ -63,9 +67,16 @@ extern struct direct *readdir ();
 #define lstat stat
 #endif
 
+extern Lisp_Object find_file_handler ();
+
 Lisp_Object Vcompletion_ignored_extensions;
 
 Lisp_Object Qcompletion_ignore_case;
+
+Lisp_Object Qdirectory_files;
+Lisp_Object Qfile_name_completion;
+Lisp_Object Qfile_name_all_completions;
+Lisp_Object Qfile_attributes;
 \f
 DEFUN ("directory-files", Fdirectory_files, Sdirectory_files, 1, 4, 0,
   "Return a list of names of files in DIRECTORY.\n\
@@ -80,16 +91,36 @@ If NOSORT is non-nil, the list is not sorted--its order is unpredictable.\n\
   DIR *d;
   int length;
   Lisp_Object list, name;
+  Lisp_Object handler;
 
-  if (!NULL (match))
+  /* If the file name has special constructs in it,
+     call the corresponding file handler.  */
+  handler = find_file_handler (dirname);
+  if (!NILP (handler))
+    {
+      Lisp_Object args[6];
+
+      args[0] = handler;
+      args[1] = Qdirectory_files;
+      args[2] = dirname;
+      args[3] = full;
+      args[4] = match;
+      args[5] = nosort;
+      return Ffuncall (6, args);
+    }
+
+  if (!NILP (match))
     {
       CHECK_STRING (match, 3);
-      /* Compile it now so we don't get an error after opendir */
+
+      /* 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.  */
 #ifdef VMS
-      compile_pattern (match, &searchbuf,
+      compile_pattern (match, &searchbuf, 0
                       buffer_defaults.downcase_table->contents);
 #else
-      compile_pattern (match, &searchbuf, 0);
+      compile_pattern (match, &searchbuf, 0, 0);
 #endif
     }
 
@@ -110,10 +141,10 @@ If NOSORT is non-nil, the list is not sorted--its order is unpredictable.\n\
       len = NAMLEN (dp);
       if (dp->d_ino)
        {
-         if (NULL (match)
+         if (NILP (match)
              || (0 <= re_search (&searchbuf, dp->d_name, len, 0, len, 0)))
            {
-             if (!NULL (full))
+             if (!NILP (full))
                {
                  int index = XSTRING (dirname)->size;
                  int total = len + index;
@@ -140,7 +171,7 @@ If NOSORT is non-nil, the list is not sorted--its order is unpredictable.\n\
        }
     }
   closedir (d);
-  if (!NULL (nosort))
+  if (!NILP (nosort))
     return list;
   return Fsort (Fnreverse (list), Qstring_lessp);
 }
@@ -157,6 +188,7 @@ Returns nil if DIR contains no name starting with FILE.")
   (file, dirname)
      Lisp_Object file, dirname;
 {
+  Lisp_Object handler;
   /* Don't waste time trying to complete a null string.
      Besides, this case happens when user is being asked for
      a directory name and has supplied one ending in a /.
@@ -164,6 +196,13 @@ Returns nil if DIR contains no name starting with FILE.")
      even if there are some unique characters in that directory.  */
   if (XTYPE (file) == Lisp_String && XSTRING (file)->size == 0)
     return file;
+
+  /* If the file name has special constructs in it,
+     call the corresponding file handler.  */
+  handler = find_file_handler (dirname);
+  if (!NILP (handler))
+    return call3 (handler, Qfile_name_completion, file, dirname);
+
   return file_name_completion (file, dirname, 0, 0);
 }
 
@@ -174,22 +213,17 @@ These are all file names in directory DIR which begin with FILE.")
   (file, dirname)
      Lisp_Object file, dirname;
 {
-  return file_name_completion (file, dirname, 1, 0);
-}
+  Lisp_Object handler;
 
-#ifdef VMS
+  /* If the file name has special constructs in it,
+     call the corresponding file handler.  */
+  handler = find_file_handler (dirname);
+  if (!NILP (handler))
+    return call3 (handler, Qfile_name_all_completions, file, dirname);
 
-DEFUN ("file-name-all-versions", Ffile_name_all_versions,
-  Sfile_name_all_versions, 2, 2, 0,
-  "Return a list of all versions of file name FILE in directory DIR.")
-  (file, dirname)
-     Lisp_Object file, dirname;
-{
-  return file_name_completion (file, dirname, 1, 1);
+  return file_name_completion (file, dirname, 1, 0);
 }
 
-#endif /* VMS */
-
 Lisp_Object
 file_name_completion (file, dirname, all_flag, ver_flag)
      Lisp_Object file, dirname;
@@ -233,7 +267,7 @@ file_name_completion (file, dirname, all_flag, ver_flag)
      ** It would not actually be helpful to the user to ignore any possible
      completions when making a list of them.**  */
 
-  for (passcount = !!all_flag; NULL (bestmatch) && passcount < 2; passcount++)
+  for (passcount = !!all_flag; NILP (bestmatch) && passcount < 2; passcount++)
     {
       if (!(d = opendir (XSTRING (Fdirectory_file_name (dirname))->data)))
        report_file_error ("Opening directory", Fcons (dirname, Qnil));
@@ -254,7 +288,7 @@ file_name_completion (file, dirname, all_flag, ver_flag)
 
          len = NAMLEN (dp);
 
-         if (!NULL (Vquit_flag) && NULL (Vinhibit_quit))
+         if (!NILP (Vquit_flag) && NILP (Vinhibit_quit))
            goto quit;
          if (!dp->d_ino
              || len < XSTRING (file)->size
@@ -297,7 +331,7 @@ file_name_completion (file, dirname, all_flag, ver_flag)
 
              matchcount++;
 
-             if (all_flag || NULL (bestmatch))
+             if (all_flag || NILP (bestmatch))
                {
                  /* This is a possible completion */
                  if (directoryp)
@@ -341,7 +375,7 @@ file_name_completion (file, dirname, all_flag, ver_flag)
 
   unbind_to (count, Qnil);
 
-  if (all_flag || NULL (bestmatch))
+  if (all_flag || NILP (bestmatch))
     return bestmatch;
   if (matchcount == 1 && bestmatchsize == XSTRING (file)->size)
     return Qt;
@@ -373,6 +407,47 @@ file_name_completion_stat (dirname, dp, st_addr)
   return stat (fullname, st_addr);
 }
 \f
+#ifdef VMS
+
+DEFUN ("file-name-all-versions", Ffile_name_all_versions,
+  Sfile_name_all_versions, 2, 2, 0,
+  "Return a list of all versions of file name FILE in directory DIR.")
+  (file, dirname)
+     Lisp_Object file, dirname;
+{
+  return file_name_completion (file, dirname, 1, 1);
+}
+
+DEFUN ("file-version-limit", Ffile_version_limit, Sfile_version_limit, 1, 1, 0,
+  "Return the maximum number of versions allowed for FILE.\n\
+Returns nil if the file cannot be opened or if there is no version limit.")
+  (filename)
+     Lisp_Object filename;
+{
+  Lisp_Object retval;
+  struct FAB    fab;
+  struct RAB    rab;
+  struct XABFHC xabfhc;
+  int status;
+
+  filename = Fexpand_file_name (filename, Qnil);
+  fab      = cc$rms_fab;
+  xabfhc   = cc$rms_xabfhc;
+  fab.fab$l_fna = XSTRING (filename)->data;
+  fab.fab$b_fns = strlen (fab.fab$l_fna);
+  fab.fab$l_xab = (char *) &xabfhc;
+  status = sys$open (&fab, 0, 0);
+  if (status != RMS$_NORMAL)   /* Probably non-existent file */
+    return Qnil;
+  sys$close (&fab, 0, 0);
+  if (xabfhc.xab$w_verlimit == 32767)
+    return Qnil;               /* No version limit */
+  else
+    return make_number (xabfhc.xab$w_verlimit);
+}
+
+#endif /* VMS */
+\f
 Lisp_Object
 make_time (time)
      int time;
@@ -399,7 +474,7 @@ Otherwise, list elements are:\n\
 10. inode number.\n\
 11. Device number.\n\
 \n\
-If file does not exists, returns nil.")
+If file does not exist, returns nil.")
   (filename)
      Lisp_Object filename;
 {
@@ -408,8 +483,16 @@ If file does not exists, returns nil.")
   struct stat s;
   struct stat sdir;
   char modes[10];
+  Lisp_Object handler;
 
   filename = Fexpand_file_name (filename, Qnil);
+
+  /* If the file name has special constructs in it,
+     call the corresponding file handler.  */
+  handler = find_file_handler (filename);
+  if (!NILP (handler))
+    return call2 (handler, Qfile_attributes, filename);
+
   if (lstat (XSTRING (filename)->data, &s) < 0)
     return Qnil;
 
@@ -439,7 +522,7 @@ If file does not exists, returns nil.")
 #endif
 #ifdef BSD4_2                  /* file gid will be dir gid */
   dirname = Ffile_name_directory (filename);
-  if (dirname != Qnil && stat (XSTRING (dirname)->data, &sdir) == 0)
+  if (! NILP (dirname) && stat (XSTRING (dirname)->data, &sdir) == 0)
     values[9] = (sdir.st_gid != s.st_gid) ? Qt : Qnil;
   else                                 /* if we can't tell, assume worst */
     values[9] = Qt;
@@ -456,10 +539,16 @@ If file does not exists, returns nil.")
 \f
 syms_of_dired ()
 {
+  Qdirectory_files = intern ("directory-files");
+  Qfile_name_completion = intern ("file-name-completion");
+  Qfile_name_all_completions = intern ("file-name-all-completions");
+  Qfile_attributes = intern ("file-attributes");
+
   defsubr (&Sdirectory_files);
   defsubr (&Sfile_name_completion);
 #ifdef VMS
   defsubr (&Sfile_name_all_versions);
+  defsubr (&Sfile_version_limit);
 #endif /* VMS */
   defsubr (&Sfile_name_all_completions);
   defsubr (&Sfile_attributes);