/* Lisp functions for making directory listings.
- Copyright (C) 1985, 1986, 1993, 1994 Free Software Foundation, Inc.
+ Copyright (C) 1985, 1986, 1993, 1994, 1999 Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include <sys/types.h>
#include <sys/stat.h>
+#include "systime.h"
+
#ifdef VMS
#include <string.h>
#include <rms.h>
#endif
#endif /* not NONSYSTEM_DIR_LIBRARY */
+#include <sys/stat.h>
+
#ifndef MSDOS
#define DIRENTRY struct direct
/* 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 *));
+
#define min(a, b) ((a) < (b) ? (a) : (b))
/* if system does not have symbolic links, it does not have lstat.
Lisp_Object Vcompletion_ignored_extensions;
Lisp_Object Qcompletion_ignore_case;
Lisp_Object Qdirectory_files;
+Lisp_Object Qdirectory_files_and_attributes;
Lisp_Object Qfile_name_completion;
Lisp_Object Qfile_name_all_completions;
Lisp_Object Qfile_attributes;
+Lisp_Object Qfile_attributes_lessp;
\f
-DEFUN ("directory-files", Fdirectory_files, Sdirectory_files, 1, 4, 0,
- "Return a list of names of files in DIRECTORY.\n\
-There are three optional arguments:\n\
-If FULL is non-nil, return absolute file names. Otherwise return names\n\
- that are relative to the specified directory.\n\
-If MATCH is non-nil, mention only file names that match the regexp MATCH.\n\
-If NOSORT is non-nil, the list is not sorted--its order is unpredictable.\n\
- NOSORT is useful if you plan to sort the result yourself.")
- (directory, full, match, nosort)
+/* Function shared by Fdirectory_files and Fdirectory_files_and_attributes.
+ When ATTRS is zero, return a list of directory filenames; when
+ non-zero, return a list of directory filenames and their attributes. */
+Lisp_Object
+directory_files_internal (directory, full, match, nosort, attrs)
Lisp_Object directory, full, match, nosort;
+ int attrs;
{
DIR *d;
int dirnamelen;
int needsep = 0;
struct gcpro gcpro1, gcpro2;
- /* If the file name has special constructs in it,
- call the corresponding file handler. */
- handler = Ffind_file_name_handler (directory, Qdirectory_files);
- if (!NILP (handler))
- {
- Lisp_Object args[6];
-
- args[0] = handler;
- args[1] = Qdirectory_files;
- args[2] = directory;
- args[3] = full;
- args[4] = match;
- args[5] = nosort;
- return Ffuncall (6, args);
- }
-
/* Because of file name handlers, these functions might call
Ffuncall, and cause a GC. */
GCPRO1 (match);
if (NILP (match)
|| (0 <= re_search (bufp, XSTRING (name)->data, len, 0, len, 0)))
{
+ Lisp_Object finalname;
+
+ finalname = name;
if (!NILP (full))
{
int afterdirindex = dirnamelen;
XSTRING (fullname)->size = nchars;
if (nchars == STRING_BYTES (XSTRING (fullname)))
SET_STRING_BYTES (XSTRING (fullname), -1);
- name = fullname;
+ finalname = fullname;
+ }
+
+ if (attrs)
+ {
+ /* Construct an expanded filename for the directory entry.
+ Use the decoded names for input to Ffile_attributes. */
+ Lisp_Object decoded_fullname;
+ Lisp_Object fileattrs;
+
+ decoded_fullname = Fexpand_file_name (name, directory);
+ fileattrs = Ffile_attributes (decoded_fullname);
+
+ list = Fcons (Fcons (finalname, fileattrs), list);
+ }
+ else
+ {
+ list = Fcons (finalname, list);
}
- list = Fcons (name, list);
}
}
}
UNGCPRO;
if (!NILP (nosort))
return list;
- return Fsort (Fnreverse (list), Qstring_lessp);
+ if (attrs)
+ return Fsort (Fnreverse (list), Qfile_attributes_lessp);
+ else
+ return Fsort (Fnreverse (list), Qstring_lessp);
+}
+
+
+DEFUN ("directory-files", Fdirectory_files, Sdirectory_files, 1, 4, 0,
+ "Return a list of names of files in DIRECTORY.\n\
+There are three optional arguments:\n\
+If FULL is non-nil, return absolute file names. Otherwise return names\n\
+ that are relative to the specified directory.\n\
+If MATCH is non-nil, mention only file names that match the regexp MATCH.\n\
+If NOSORT is non-nil, the list is not sorted--its order is unpredictable.\n\
+ NOSORT is useful if you plan to sort the result yourself.")
+ (directory, full, match, nosort)
+ Lisp_Object directory, full, match, nosort;
+{
+ Lisp_Object handler;
+
+ /* If the file name has special constructs in it,
+ call the corresponding file handler. */
+ handler = Ffind_file_name_handler (directory, Qdirectory_files);
+ if (!NILP (handler))
+ {
+ Lisp_Object args[6];
+
+ args[0] = handler;
+ args[1] = Qdirectory_files;
+ args[2] = directory;
+ args[3] = full;
+ args[4] = match;
+ args[5] = nosort;
+ return Ffuncall (6, args);
+ }
+
+ return directory_files_internal (directory, full, match, nosort, 0);
}
+
+DEFUN ("directory-files-and-attributes", Fdirectory_files_and_attributes, Sdirectory_files_and_attributes, 1, 4, 0,
+ "Return a list of names of files and their attributes in DIRECTORY.\n\
+There are three optional arguments:\n\
+If FULL is non-nil, return absolute file names. Otherwise return names\n\
+ that are relative to the specified directory.\n\
+If MATCH is non-nil, mention only file names that match the regexp MATCH.\n\
+If NOSORT is non-nil, the list is not sorted--its order is unpredictable.\n\
+ NOSORT is useful if you plan to sort the result yourself.")
+ (directory, full, match, nosort)
+ Lisp_Object directory, full, match, nosort;
+{
+ Lisp_Object handler;
+
+ /* If the file name has special constructs in it,
+ call the corresponding file handler. */
+ handler = Ffind_file_name_handler (directory, Qdirectory_files_and_attributes);
+ if (!NILP (handler))
+ {
+ Lisp_Object args[6];
+
+ args[0] = handler;
+ args[1] = Qdirectory_files_and_attributes;
+ args[2] = directory;
+ args[3] = full;
+ args[4] = match;
+ args[5] = nosort;
+ return Ffuncall (6, args);
+ }
+
+ return directory_files_internal (directory, full, match, nosort, 1);
+}
+
\f
Lisp_Object file_name_completion ();
if (!passcount && len > XSTRING (encoded_file)->size)
/* and exit this for loop if a match is found */
for (tem = Vcompletion_ignored_extensions;
- CONSP (tem); tem = XCONS (tem)->cdr)
+ CONSP (tem); tem = XCDR (tem))
{
- elt = XCONS (tem)->car;
+ elt = XCAR (tem);
if (!STRINGP (elt)) continue;
skip = len - XSTRING (elt)->size;
if (skip < 0) continue;
/* Ignore this element if it fails to match all the regexps. */
for (regexps = Vcompletion_regexp_list; CONSP (regexps);
- regexps = XCONS (regexps)->cdr)
+ regexps = XCDR (regexps))
{
- tem = Fstring_match (XCONS (regexps)->car, elt, zero);
+ tem = Fstring_match (XCAR (regexps), elt, zero);
if (NILP (tem))
break;
}
\f
Lisp_Object
make_time (time)
- int time;
+ time_t time;
{
return Fcons (make_number (time >> 16),
Fcons (make_number (time & 0177777), Qnil));
values[4] = make_time (s.st_atime);
values[5] = make_time (s.st_mtime);
values[6] = make_time (s.st_ctime);
- values[7] = make_number ((int) s.st_size);
+ values[7] = make_number (s.st_size);
/* If the size is out of range for an integer, return a float. */
if (XINT (values[7]) != s.st_size)
values[7] = make_float ((double)s.st_size);
else
/* But keep the most common cases as integers. */
values[10] = make_number (s.st_ino);
- values[11] = make_number (s.st_dev);
+
+ /* Likewise for device. */
+ if (s.st_dev & (((EMACS_INT) (-1)) << VALBITS))
+ values[11] = Fcons (make_number (s.st_dev >> 16),
+ make_number (s.st_dev & 0xffff));
+ else
+ values[11] = make_number (s.st_dev);
+
return Flist (sizeof(values) / sizeof(values[0]), values);
}
+
+DEFUN ("file-attributes-lessp", Ffile_attributes_lessp, Sfile_attributes_lessp, 2, 2, 0,
+ "Return t if first arg file attributes list is less than second.\n\
+Comparison is in lexicographic order and case is significant.")
+ (f1, f2)
+ Lisp_Object f1, f2;
+{
+ return Fstring_lessp (Fcar (f1), Fcar (f2));
+}
\f
void
syms_of_dired ()
{
Qdirectory_files = intern ("directory-files");
+ Qdirectory_files_and_attributes = intern ("directory-files-and-attributes");
Qfile_name_completion = intern ("file-name-completion");
Qfile_name_all_completions = intern ("file-name-all-completions");
Qfile_attributes = intern ("file-attributes");
+ Qfile_attributes_lessp = intern ("file-attributes-lessp");
staticpro (&Qdirectory_files);
+ staticpro (&Qdirectory_files_and_attributes);
staticpro (&Qfile_name_completion);
staticpro (&Qfile_name_all_completions);
staticpro (&Qfile_attributes);
+ staticpro (&Qfile_attributes_lessp);
defsubr (&Sdirectory_files);
+ defsubr (&Sdirectory_files_and_attributes);
defsubr (&Sfile_name_completion);
#ifdef VMS
defsubr (&Sfile_name_all_versions);
#endif /* VMS */
defsubr (&Sfile_name_all_completions);
defsubr (&Sfile_attributes);
+ defsubr (&Sfile_attributes_lessp);
#ifdef VMS
Qcompletion_ignore_case = intern ("completion-ignore-case");