/* Lisp functions for making directory listings.
- Copyright (C) 1985, 1986, 1993, 1994, 1999 Free Software Foundation, Inc.
+ Copyright (C) 1985, 1986, 1993, 1994, 1999, 2000, 2001
+ Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include <sys/stat.h>
#include "systime.h"
+#include <errno.h>
#ifdef VMS
#include <string.h>
/* 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.
In that case, use ordinary stat instead. */
/* 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;
if (!NILP (match))
{
- CHECK_STRING (match, 3);
+ CHECK_STRING (match);
/* MATCH might be a flawed regular expression. Rather than
catching and signaling our own errors, we just call
#endif /* not VMS */
/* Loop reading blocks until EOF or error. */
- while ((dp = readdir (d)) != NULL)
+ for (;;)
{
+ errno = 0;
+ dp = readdir (d);
+
+#ifdef EAGAIN
+ if (dp == NULL && errno == EAGAIN)
+ continue;
+#endif
+
+ if (dp == NULL)
+ break;
+
if (DIRENTRY_NONEMPTY (dp))
{
int len;
struct gcpro gcpro1, gcpro2;
len = NAMLEN (dp);
- name = finalname = make_string (dp->d_name, len);
+ name = finalname = make_unibyte_string (dp->d_name, len);
GCPRO2 (finalname, name);
/* Note: ENCODE_FILE can GC; it should protect its argument,
}
retry_p = 0;
-#ifdef EAGAIN
- retry_p |= errno == EAGAIN;
-#endif
#ifdef EINTR
retry_p |= errno == EINTR;
#endif
specpdl_ptr = specpdl + count;
if (retry_p)
- goto retry;
+ {
+ list = Qnil;
+ goto retry;
+ }
if (NILP (nosort))
list = Fsort (Fnreverse (list),
Returns the longest string\n\
common to all file names in DIRECTORY that start with FILE.\n\
If there is only one and FILE matches it exactly, returns t.\n\
-Returns nil if DIR contains no name starting with FILE.")
+Returns nil if DIR contains no name starting with FILE.\n\
+\n\
+This function ignores some of the possible completions as\n\
+determined by the variable `completion-ignored-extensions', which see.")
(file, directory)
Lisp_Object file, directory;
{
readfunc = readdirver;
file = Fupcase (file);
#else /* not VMS */
- CHECK_STRING (file, 0);
+ CHECK_STRING (file);
#endif /* not VMS */
#ifdef FILE_SYSTEM_CASE
actually in the way in a directory contains only one file. */
if (!passcount && TRIVIAL_DIRECTORY_ENTRY (dp->d_name))
continue;
+ if (!passcount && len > XSTRING (encoded_file)->size)
+ /* Ignore directories if they match an element of
+ completion-ignored-extensions which ends in a slash. */
+ for (tem = Vcompletion_ignored_extensions;
+ CONSP (tem); tem = XCDR (tem))
+ {
+ int elt_len;
+
+ elt = XCAR (tem);
+ if (!STRINGP (elt))
+ continue;
+ elt_len = XSTRING (elt)->size - 1; /* -1 for trailing / */
+ if (elt_len <= 0)
+ continue;
+ p1 = XSTRING (elt)->data;
+ if (p1[elt_len] != '/')
+ continue;
+ skip = len - elt_len;
+ if (skip < 0)
+ continue;
+
+ if (0 <= scmp (dp->d_name + skip, p1, elt_len))
+ continue;
+ break;
+ }
}
else
{
for (regexps = Vcompletion_regexp_list; CONSP (regexps);
regexps = XCDR (regexps))
{
- tem = Fstring_match (XCAR (regexps), elt, zero);
+ tem = Fstring_match (XCAR (regexps),
+ make_string (dp->d_name, len), zero);
if (NILP (tem))
break;
}
10. inode number. If inode number is larger than the Emacs integer,\n\
this is a cons cell containing two integers: first the high part,\n\
then the low 16 bits.\n\
-11. Device number.\n\
+11. Device number. If it is larger than the Emacs integer, this is\n\
+ a cons cell, similar to the inode number.\n\
\n\
If file does not exist, returns nil.")
(filename)
Lisp_Object values[12];
Lisp_Object encoded;
struct stat s;
-#ifdef BSD4_2
+#if defined (BSD4_2) || defined (BSD4_3)
Lisp_Object dirname;
struct stat sdir;
#endif
values[7] = make_float ((double)s.st_size);
filemodestring (&s, modes);
values[8] = make_string (modes, 10);
-#ifdef BSD4_3 /* Gross kludge to avoid lack of "#if defined(...)" in VMS */
-#define BSD4_2 /* A new meaning to the term `backwards compatibility' */
-#endif
-#ifdef BSD4_2 /* file gid will be dir gid */
+#if defined (BSD4_2) || defined (BSD4_3) /* file gid will be dir gid */
dirname = Ffile_name_directory (filename);
if (! NILP (dirname))
encoded = ENCODE_FILE (dirname);
#else /* file gid will be egid */
values[9] = (s.st_gid != getegid ()) ? Qt : Qnil;
#endif /* BSD4_2 (or BSD4_3) */
-#ifdef BSD4_3
-#undef BSD4_2 /* ok, you can look again without throwing up */
-#endif
/* Cast -1 to avoid warning if int is not as wide as VALBITS. */
- if (s.st_ino & (((EMACS_INT) (-1)) << VALBITS))
+ if (FIXNUM_OVERFLOW_P (s.st_ino))
/* To allow inode numbers larger than VALBITS, separate the bottom
16 bits. */
values[10] = Fcons (make_number (s.st_ino >> 16),
values[10] = make_number (s.st_ino);
/* Likewise for device. */
- if (s.st_dev & (((EMACS_INT) (-1)) << VALBITS))
+ if (FIXNUM_OVERFLOW_P (s.st_dev))
values[11] = Fcons (make_number (s.st_dev >> 16),
make_number (s.st_dev & 0xffff));
else
DEFVAR_LISP ("completion-ignored-extensions", &Vcompletion_ignored_extensions,
"*Completion ignores filenames ending in any string in this list.\n\
+Directories are ignored if they match any string in this list which\n\
+ends in a slash.\n\
This variable does not affect lists of possible completions,\n\
but does affect the commands that actually do completions.");
Vcompletion_ignored_extensions = Qnil;