Lisp_Object Qcompanion_bf;
Lisp_Object Qsorted_list, Qdesc_sorted_list, Qunsorted_list;
+Lisp_Object Qmatch_full;
Lisp_Object Qnoncyclic_directory, Qcyclic_directory;
Lisp_Object Qsymlink, Qalive_symlink, Qdead_symlink;
Lisp_Object Qwhiteout;
long unsigned int maxdepth;
_Bool fullp:1;
_Bool symlink_file_p:1;
+ _Bool matchfullp:1;
};
static Lisp_Object fname_as_directory(Lisp_Object);
}
#else /* defined(_DIRENT_HAVE_D_TYPE) && USE_D_TYPE */
statnam = (char*)XSTRING_DATA(fullname);
- if (sxemacs_stat(statnam, &st) == 0 &&
- (st.st_mode & S_IFMT) == S_IFDIR) {
- char *canon_name = NULL;
-
- /* ugly things may happen when a link
- * points back to a directory in our recurring
- * area, ln -s . foo is a candidate
- * now, we canonicalise the filename, i.e.
- * resolve all symlinks and afterwards we
- * store it to our companion bloom filter
- * The ugly things are even worse than in the
- * case of D_TYPE, since we !always! have to
- * check against the bloom filter.
- */
- canon_name = CANONICALISE_FILENAME(statnam);
-
- if (canon_name) {
- /* now, recycle full name */
- fullname = make_ext_string(
- canon_name, strlen(canon_name),
- Qfile_name);
- }
- fullname = fname_as_directory(fullname);
-
- /* now stat statnam */
- if (sxemacs_stat(statnam, &st) == 0 &&
- (st.st_mode & S_IFMT) == S_IFDIR &&
- /* does the bloom know about the dir? */
- !NILP(compbf) &&
- !(bloom_owns_p(XBLOOM(compbf), fullname))) {
+ if (lstat(statnam, &st) == 0) {
+ if ((st.st_mode & S_IFMT) == S_IFDIR) {
dir_p = 1;
- }
+ } else if ((st.st_mode & S_IFMT) == S_IFLNK && !opts->symlink_file_p) {
+ char *canon_name = NULL;
+
+ /* ugly things may happen when a link
+ * points back to a directory in our recurring
+ * area, ln -s . foo is a candidate
+ * now, we canonicalise the filename, i.e.
+ * resolve all symlinks and afterwards we
+ * store it to our companion bloom filter
+ * The ugly things are even worse than in the
+ * case of D_TYPE, since we !always! have to
+ * check against the bloom filter.
+ */
+ canon_name = CANONICALISE_FILENAME(statnam);
+
+ if (canon_name) {
+ /* now, recycle full name */
+ fullname = make_ext_string(
+ canon_name, strlen(canon_name),
+ Qfile_name);
+ }
+ fullname = fname_as_directory(fullname);
+
+ /* now stat statnam */
+ if (sxemacs_stat(statnam, &st) == 0 &&
+ (st.st_mode & S_IFMT) == S_IFDIR &&
+ /* does the bloom know about the dir? */
+ !NILP(compbf) &&
+ !(bloom_owns_p(XBLOOM(compbf), fullname))) {
+ dir_p = 1;
+ }
- if (canon_name) {
- xfree(canon_name);
+ if (canon_name) {
+ xfree(canon_name);
+ }
}
}
+
#endif /* defined(_DIRENT_HAVE_D_TYPE) && USE_D_TYPE */
/* argh, here is a design flaw!
dired_stack_push(ds, dsi);
}
- if (result_p && !NILP(match) && !pathname_matches_p(name, match, bufp)) {
+ if (result_p && !NILP(match)
+ && !pathname_matches_p((opts->matchfullp?fullname:name),
+ match, bufp)) {
result_p = 0;
}
\f
EXFUN(Fdirectory_files_recur, 8);
-DEFUN("directory-files", Fdirectory_files, 1, 5, 0, /*
+DEFUN("directory-files", Fdirectory_files, 1, 7, 0, /*
Return a list of names of files in DIRECTORY.
-Args are DIRECTORY &optional FULL MATCH RESULT-TYPE FILES_ONLY.
+Args are DIRECTORY &optional FULL MATCH RESULT-TYPE FILES_ONLY
+SYMLINK_IS_FILE BLOOM_FILTER
There are four optional arguments:
-If FULL is non-nil, absolute pathnames of the files are returned.
+FULL can be one of:
+- t to return absolute pathnames of the files.
+- match-full to return and match on absolute pathnames of the files.
+- nil to return relative filenames.
If MATCH is non-nil, it may be a string indicating a regular
expression which pathnames must meet in order to be returned.
Moreover, a predicate function can be specified which is called with
-one argument, the pathname in question. On non-nil return value,
-the pathname is considered in the final result, otherwise it is
-ignored.
+one argument, the pathname in question. On non-nil return value, the
+pathname is considered in the final result, otherwise it is ignored.
+Note that FULL affects whether the match is done on the filename of
+the full pathname.
Optional argument RESULT-TYPE can be one of:
- sorted-list (default) to return a list, sorted in alphabetically
subdirectories) in DIRECTORY
- subdir to return only subdirectories -- but *NOT* symlinks to
directories -- in DIRECTORY
+
+Optional argument SYMLINK-IS-FILE specifies whether symlinks
+should be resolved \(which is the default behaviour\) or whether
+they are treated as ordinary files \(non-nil\), in the latter
+case symlinks to directories are not recurred.
+
+Optional argument BLOOM-FILTER specifies a bloom filter where
+to put results in addition to the ordinary result list.
*/
- (directory, full, match, result_type, files_only))
+ (directory, full, match, result_type, files_only,
+ symlink_is_file, bloom_filter))
{
- Lisp_Object handler;
+ Lisp_Object handler = Qnil;
Lisp_Object result = Qnil;
- struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
+#if !defined HAVE_BDWGC || !defined EF_USE_BDWGC
+ /* just a convenience array for gc pro'ing */
+ Lisp_Object args[8] = {
+ directory, match, result_type, files_only,
+ symlink_is_file, bloom_filter, handler, result};
+#endif /* !BDWGC */
struct dfr_options_s opts = {
.maxdepth = 0,
.fullp = !NILP(full),
- .symlink_file_p = 0,
+ .symlink_file_p = !NILP(symlink_is_file),
+ .matchfullp = EQ(full,Qmatch_full),
};
+ struct gcpro gcpro1;
/* argument checks */
CHECK_STRING(directory);
- GCPRO6(directory, full, match, result_type, files_only, result);
+ GCPROn(args, countof(args));
directory = directory_files_canonicalise_dn(directory);
handler = Ffind_file_name_handler(directory, Qdirectory_files);
if (!NILP(handler)) {
UNGCPRO;
- return call6(handler, Qdirectory_files,
- directory, full, match, result_type, files_only);
+ return call8(handler, Qdirectory_files,
+ directory, full, match, result_type, files_only,
+ symlink_is_file, bloom_filter);
}
result = directory_files_magic(directory, match,
- files_only, /* bloom filter */Qnil,
+ files_only, bloom_filter,
&opts);
UNGCPRO;
Args are DIRECTORY &optional FULL MATCH RESULT_TYPE FILES-ONLY MAXDEPTH
SYMLINK_IS_FILE BLOOM_FILTER
-If FULL is non-nil, absolute pathnames of the files are returned.
+FULL can be one of:
+- t to return absolute pathnames of the files.
+- match-full to return and match on absolute pathnames of the files.
+- nil to return relative filenames.
If MATCH is non-nil, it may be a string indicating a regular
expression which pathnames must meet in order to be returned.
Moreover, a predicate function can be specified which is called with
-one argument, the pathname in question. On non-nil return value,
-the pathname is considered in the final result, otherwise it is
-ignored.
+one argument, the pathname in question. On non-nil return value, the
+pathname is considered in the final result, otherwise it is ignored.
+Note that FULL affects whether the match is done on the filename of
+the full pathname.
Optional argument RESULT-TYPE can be one of:
- sorted-list (default) to return a list, sorted in alphabetically
*/
(directory, full, match, result_type, files_only, maxdepth,
symlink_is_file, bloom_filter))
-#if 0
- (int nargs, Lisp_Object *args))
-#endif
{
Lisp_Object handler = Qnil, result = Qnil;
#if !defined HAVE_BDWGC || !defined EF_USE_BDWGC
.maxdepth = 64,
.fullp = !NILP(full),
.symlink_file_p = !NILP(symlink_is_file),
+ .matchfullp = EQ(full, Qmatch_full),
};
struct gcpro gcpro1;
defsymbol(&Qsorted_list, "sorted-list");
defsymbol(&Qdesc_sorted_list, "desc-sorted-list");
defsymbol(&Qunsorted_list, "unsorted-list");
+ defsymbol(&Qmatch_full, "match-full");
DEFSUBR(Fdirectory_files);
DEFSUBR(Fdirectory_files_recur);