/* Lisp functions for making directory listings.
- Copyright (C) 1985, 1986, 1993, 1994, 1999, 2000, 2001, 2002, 2003,
- 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+ Copyright (C) 1985-1986, 1993-1994, 1999-2011 Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include <grp.h>
#include <errno.h>
-
-#ifdef HAVE_UNISTD_H
#include <unistd.h>
-#endif
/* The d_nameln member of a struct dirent includes the '\0' character
on some systems, but not on others. What's worse, you can't tell
Since applying strlen to the name always works, we'll just do that. */
#define NAMLEN(p) strlen (p->d_name)
-#ifdef SYSV_SYSTEM_DIR
+#ifdef HAVE_DIRENT_H
#include <dirent.h>
#define DIRENTRY struct dirent
-#else /* not SYSV_SYSTEM_DIR */
+#else /* not HAVE_DIRENT_H */
-#ifdef MSDOS
-#include <dirent.h>
-#else
#include <sys/dir.h>
-#endif
-
#include <sys/stat.h>
-#ifndef MSDOS
#define DIRENTRY struct direct
-extern DIR *opendir ();
-extern struct direct *readdir ();
+extern DIR *opendir (char *);
+extern struct direct *readdir (DIR *);
+
+#endif /* HAVE_DIRENT_H */
-#endif /* not MSDOS */
-#endif /* not SYSV_SYSTEM_DIR */
+#include <filemode.h>
-/* Some versions of Cygwin don't have d_ino in `struct dirent'. */
-#if defined(MSDOS) || defined(__CYGWIN__)
+#ifdef MSDOS
#define DIRENTRY_NONEMPTY(p) ((p)->d_name[0] != 0)
#else
#define DIRENTRY_NONEMPTY(p) ((p)->d_ino)
#include "blockinput.h"
/* 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 *));
-
-/* if system does not have symbolic links, it does not have lstat.
- In that case, use ordinary stat instead. */
+extern struct re_pattern_buffer *compile_pattern (Lisp_Object,
+ struct re_registers *,
+ Lisp_Object, int, int);
-#ifndef S_IFLNK
-#define lstat stat
-#endif
-
-extern int completion_ignore_case;
-extern Lisp_Object Qcompletion_ignore_case;
-extern Lisp_Object Vcompletion_regexp_list;
-extern Lisp_Object Vw32_get_true_file_attributes;
-
-Lisp_Object Vcompletion_ignored_extensions;
Lisp_Object Qdirectory_files;
Lisp_Object Qdirectory_files_and_attributes;
Lisp_Object Qfile_name_completion;
Lisp_Object Qfile_attributes;
Lisp_Object Qfile_attributes_lessp;
-static int scmp P_ ((unsigned char *, unsigned char *, int));
+static int scmp (const char *, const char *, int);
\f
#ifdef WINDOWSNT
Lisp_Object
#endif
Lisp_Object
-directory_files_internal_unwind (dh)
- Lisp_Object dh;
+directory_files_internal_unwind (Lisp_Object dh)
{
DIR *d = (DIR *) XSAVE_VALUE (dh)->pointer;
BLOCK_INPUT;
In the latter case, ID_FORMAT is passed to Ffile_attributes. */
Lisp_Object
-directory_files_internal (directory, full, match, nosort, attrs, id_format)
- Lisp_Object directory, full, match, nosort;
- int attrs;
- Lisp_Object id_format;
+directory_files_internal (Lisp_Object directory, Lisp_Object full, Lisp_Object match, Lisp_Object nosort, int attrs, Lisp_Object id_format)
{
DIR *d;
int directory_nbytes;
# ifdef WINDOWSNT
/* Windows users want case-insensitive wildcards. */
bufp = compile_pattern (match, 0,
- buffer_defaults.case_canon_table, 0, 1);
+ BVAR (&buffer_defaults, case_canon_table), 0, 1);
# else /* !WINDOWSNT */
bufp = compile_pattern (match, 0, Qnil, 0, 1);
# endif /* !WINDOWSNT */
which might compile a new regexp until we're done with the loop! */
BLOCK_INPUT;
- d = opendir (SDATA (dirfilename));
+ d = opendir (SSDATA (dirfilename));
UNBLOCK_INPUT;
if (d == NULL)
report_file_error ("Opening directory", Fcons (directory, Qnil));
#ifdef WINDOWSNT
if (attrs)
{
- extern Lisp_Object Qlocal;
extern int is_slow_fs (const char *);
/* Do this only once to avoid doing it (in w32.c:stat) for each
QUIT;
if (NILP (match)
- || (0 <= re_search (bufp, SDATA (name), len, 0, len, 0)))
+ || (0 <= re_search (bufp, SSDATA (name), len, 0, len, 0)))
wanted = 1;
immediate_quit = 0;
int nchars;
fullname = make_uninit_multibyte_string (nbytes, nbytes);
- bcopy (SDATA (directory), SDATA (fullname),
- directory_nbytes);
+ memcpy (SDATA (fullname), SDATA (directory),
+ directory_nbytes);
if (needsep)
SSET (fullname, directory_nbytes, DIRECTORY_SEP);
- bcopy (SDATA (name),
- SDATA (fullname) + directory_nbytes + needsep,
- len);
+ memcpy (SDATA (fullname) + directory_nbytes + needsep,
+ SDATA (name), len);
nchars = chars_in_text (SDATA (fullname), nbytes);
If NOSORT is non-nil, the list is not sorted--its order is unpredictable.
Otherwise, the list returned is sorted with `string-lessp'.
NOSORT is useful if you plan to sort the result yourself. */)
- (directory, full, match, nosort)
- Lisp_Object directory, full, match, nosort;
+ (Lisp_Object directory, Lisp_Object full, Lisp_Object match, Lisp_Object nosort)
{
Lisp_Object handler;
directory = Fexpand_file_name (directory, Qnil);
`file-attributes' for further documentation.
On MS-Windows, performance depends on `w32-get-true-file-attributes',
which see. */)
- (directory, full, match, nosort, id_format)
- Lisp_Object directory, full, match, nosort, id_format;
+ (Lisp_Object directory, Lisp_Object full, Lisp_Object match, Lisp_Object nosort, Lisp_Object id_format)
{
Lisp_Object handler;
directory = Fexpand_file_name (directory, Qnil);
}
\f
-Lisp_Object file_name_completion ();
+Lisp_Object file_name_completion (Lisp_Object file, Lisp_Object dirname, int all_flag, int ver_flag, Lisp_Object predicate);
DEFUN ("file-name-completion", Ffile_name_completion, Sfile_name_completion,
2, 3, 0,
This function ignores some of the possible completions as
determined by the variable `completion-ignored-extensions', which see. */)
- (file, directory, predicate)
- Lisp_Object file, directory, predicate;
+ (Lisp_Object file, Lisp_Object directory, Lisp_Object predicate)
{
Lisp_Object handler;
Sfile_name_all_completions, 2, 2, 0,
doc: /* 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, directory)
- Lisp_Object file, directory;
+ (Lisp_Object file, Lisp_Object directory)
{
Lisp_Object handler;
return file_name_completion (file, directory, 1, 0, Qnil);
}
-static int file_name_completion_stat ();
+static int file_name_completion_stat (Lisp_Object dirname, DIRENTRY *dp, struct stat *st_addr);
Lisp_Object Qdefault_directory;
Lisp_Object
-file_name_completion (file, dirname, all_flag, ver_flag, predicate)
- Lisp_Object file, dirname;
- int all_flag, ver_flag;
- Lisp_Object predicate;
+file_name_completion (Lisp_Object file, Lisp_Object dirname, int all_flag, int ver_flag, Lisp_Object predicate)
{
DIR *d;
int bestmatchsize = 0;
encoded_dir = ENCODE_FILE (dirname);
BLOCK_INPUT;
- d = opendir (SDATA (Fdirectory_file_name (encoded_dir)));
+ d = opendir (SSDATA (Fdirectory_file_name (encoded_dir)));
UNBLOCK_INPUT;
if (!d)
report_file_error ("Opening directory", Fcons (dirname, Qnil));
QUIT;
if (! DIRENTRY_NONEMPTY (dp)
|| len < SCHARS (encoded_file)
- || 0 <= scmp (dp->d_name, SDATA (encoded_file),
+ || 0 <= scmp (dp->d_name, SSDATA (encoded_file),
SCHARS (encoded_file)))
continue;
if (file_name_completion_stat (encoded_dir, dp, &st) < 0)
continue;
- directoryp = ((st.st_mode & S_IFMT) == S_IFDIR);
+ directoryp = S_ISDIR (st.st_mode);
tem = Qnil;
/* If all_flag is set, always include all.
It would not actually be helpful to the user to ignore any possible
&& matchcount > 1
&& !includeall /* This match may allow includeall to 0. */
&& len >= bestmatchsize
- && 0 > scmp (dp->d_name, SDATA (bestmatch), bestmatchsize))
+ && 0 > scmp (dp->d_name, SSDATA (bestmatch), bestmatchsize))
continue;
#endif
CONSP (tem); tem = XCDR (tem))
{
int elt_len;
- unsigned char *p1;
+ char *p1;
elt = XCAR (tem);
if (!STRINGP (elt))
elt_len = SCHARS (elt) - 1; /* -1 for trailing / */
if (elt_len <= 0)
continue;
- p1 = SDATA (elt);
+ p1 = SSDATA (elt);
if (p1[elt_len] != '/')
continue;
skip = len - elt_len;
if (skip < 0) continue;
if (0 <= scmp (dp->d_name + skip,
- SDATA (elt),
+ SSDATA (elt),
SCHARS (elt)))
continue;
break;
else number of chars that match at the beginning. */
static int
-scmp (s1, s2, len)
- register unsigned char *s1, *s2;
- int len;
+scmp (const char *s1, const char *s2, int len)
{
register int l = len;
if (completion_ignore_case)
{
- while (l && DOWNCASE (*s1++) == DOWNCASE (*s2++))
+ while (l
+ && (DOWNCASE ((unsigned char) *s1++)
+ == DOWNCASE ((unsigned char) *s2++)))
l--;
}
else
}
static int
-file_name_completion_stat (dirname, dp, st_addr)
- Lisp_Object dirname;
- DIRENTRY *dp;
- struct stat *st_addr;
+file_name_completion_stat (Lisp_Object dirname, DIRENTRY *dp, struct stat *st_addr)
{
int len = NAMLEN (dp);
int pos = SCHARS (dirname);
_djstat_flags = _STAT_INODE | _STAT_EXEC_MAGIC | _STAT_DIRSIZE;
#endif /* MSDOS */
- bcopy (SDATA (dirname), fullname, pos);
+ memcpy (fullname, SDATA (dirname), pos);
if (!IS_DIRECTORY_SEP (fullname[pos - 1]))
fullname[pos++] = DIRECTORY_SEP;
- bcopy (dp->d_name, fullname + pos, len);
+ memcpy (fullname + pos, dp->d_name, len);
fullname[pos + len] = 0;
-#ifdef S_IFLNK
/* We want to return success if a link points to a nonexistent file,
but we want to return the status for what the link points to,
in case it is a directory. */
value = lstat (fullname, st_addr);
- stat (fullname, st_addr);
- return value;
-#else
- value = stat (fullname, st_addr);
+ if (value == 0 && S_ISLNK (st_addr->st_mode))
+ stat (fullname, st_addr);
#ifdef MSDOS
_djstat_flags = save_djstat_flags;
#endif /* MSDOS */
return value;
-#endif /* S_IFLNK */
}
\f
Lisp_Object
-make_time (time)
- time_t time;
+make_time (time_t time)
{
return Fcons (make_number (time >> 16),
Fcons (make_number (time & 0177777), Qnil));
On some FAT-based filesystems, only the date of last access is recorded,
so last access time will always be midnight of that day. */)
- (filename, id_format)
- Lisp_Object filename, id_format;
+ (Lisp_Object filename, Lisp_Object id_format)
{
Lisp_Object values[12];
Lisp_Object encoded;
Lisp_Object dirname;
struct stat sdir;
#endif /* BSD4_2 */
- char modes[10];
+
+ /* An array to hold the mode string generated by filemodestring,
+ including its terminating space and null byte. */
+ char modes[sizeof "-rwxr-xr-x "];
+
Lisp_Object handler;
struct gcpro gcpro1;
char *uname = NULL, *gname = NULL;
encoded = ENCODE_FILE (filename);
UNGCPRO;
- if (lstat (SDATA (encoded), &s) < 0)
+ if (lstat (SSDATA (encoded), &s) < 0)
return Qnil;
- switch (s.st_mode & S_IFMT)
- {
- default:
- values[0] = Qnil; break;
- case S_IFDIR:
- values[0] = Qt; break;
-#ifdef S_IFLNK
- case S_IFLNK:
- values[0] = Ffile_symlink_p (filename); break;
-#endif
- }
+ values[0] = (S_ISLNK (s.st_mode) ? Ffile_symlink_p (filename)
+ : S_ISDIR (s.st_mode) ? Qt : Qnil);
values[1] = make_number (s.st_nlink);
if (!(NILP (id_format) || EQ (id_format, Qinteger)))
DEFUN ("file-attributes-lessp", Ffile_attributes_lessp, Sfile_attributes_lessp, 2, 2, 0,
doc: /* Return t if first arg file attributes list is less than second.
Comparison is in lexicographic order and case is significant. */)
- (f1, f2)
- Lisp_Object f1, f2;
+ (Lisp_Object f1, Lisp_Object f2)
{
return Fstring_lessp (Fcar (f1), Fcar (f2));
}
\f
void
-syms_of_dired ()
+syms_of_dired (void)
{
Qdirectory_files = intern_c_string ("directory-files");
Qdirectory_files_and_attributes = intern_c_string ("directory-files-and-attributes");
defsubr (&Sfile_attributes);
defsubr (&Sfile_attributes_lessp);
- DEFVAR_LISP ("completion-ignored-extensions", &Vcompletion_ignored_extensions,
+ DEFVAR_LISP ("completion-ignored-extensions", Vcompletion_ignored_extensions,
doc: /* Completion ignores file names ending in any string in this list.
It does not ignore them if all possible completions end in one of
these strings or when displaying a list of completions.
ends in a slash. */);
Vcompletion_ignored_extensions = Qnil;
}
-
-/* arch-tag: 1ac8deca-4d8f-4d41-ade9-089154d98c03
- (do not change this comment) */