1 /* Lisp functions for making directory listings.
2 Copyright (C) 1985, 1986, 1993, 1994 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
25 #include <sys/types.h>
34 /* The d_nameln member of a struct dirent includes the '\0' character
35 on some systems, but not on others. What's worse, you can't tell
36 at compile-time which one it will be, since it really depends on
37 the sort of system providing the filesystem you're reading from,
38 not the system you are running on. Paul Eggert
39 <eggert@bi.twinsun.com> says this occurs when Emacs is running on a
40 SunOS 4.1.2 host, reading a directory that is remote-mounted from a
41 Solaris 2.1 host and is in a native Solaris 2.1 filesystem.
43 Since applying strlen to the name always works, we'll just do that. */
44 #define NAMLEN(p) strlen (p->d_name)
46 #ifdef SYSV_SYSTEM_DIR
49 #define DIRENTRY struct dirent
51 #else /* not SYSV_SYSTEM_DIR */
53 #ifdef NONSYSTEM_DIR_LIBRARY
55 #else /* not NONSYSTEM_DIR_LIBRARY */
61 #endif /* not NONSYSTEM_DIR_LIBRARY */
64 #define DIRENTRY struct direct
66 extern DIR *opendir ();
67 extern struct direct
*readdir ();
69 #endif /* not MSDOS */
70 #endif /* not SYSV_SYSTEM_DIR */
73 #define DIRENTRY_NONEMPTY(p) ((p)->d_name[0] != 0)
75 #define DIRENTRY_NONEMPTY(p) ((p)->d_ino)
84 /* Returns a search buffer, with a fastmap allocated and ready to go. */
85 extern struct re_pattern_buffer
*compile_pattern ();
87 #define min(a, b) ((a) < (b) ? (a) : (b))
89 /* if system does not have symbolic links, it does not have lstat.
90 In that case, use ordinary stat instead. */
96 extern int completion_ignore_case
;
97 extern Lisp_Object Vcompletion_regexp_list
;
99 Lisp_Object Vcompletion_ignored_extensions
;
100 Lisp_Object Qcompletion_ignore_case
;
101 Lisp_Object Qdirectory_files
;
102 Lisp_Object Qfile_name_completion
;
103 Lisp_Object Qfile_name_all_completions
;
104 Lisp_Object Qfile_attributes
;
106 DEFUN ("directory-files", Fdirectory_files
, Sdirectory_files
, 1, 4, 0,
107 "Return a list of names of files in DIRECTORY.\n\
108 There are three optional arguments:\n\
109 If FULL is non-nil, return absolute file names. Otherwise return names\n\
110 that are relative to the specified directory.\n\
111 If MATCH is non-nil, mention only file names that match the regexp MATCH.\n\
112 If NOSORT is non-nil, the list is not sorted--its order is unpredictable.\n\
113 NOSORT is useful if you plan to sort the result yourself.")
114 (directory
, full
, match
, nosort
)
115 Lisp_Object directory
, full
, match
, nosort
;
119 Lisp_Object list
, name
, dirfilename
;
121 struct re_pattern_buffer
*bufp
;
123 /* If the file name has special constructs in it,
124 call the corresponding file handler. */
125 handler
= Ffind_file_name_handler (directory
, Qdirectory_files
);
131 args
[1] = Qdirectory_files
;
136 return Ffuncall (6, args
);
140 struct gcpro gcpro1
, gcpro2
;
142 /* Because of file name handlers, these functions might call
143 Ffuncall, and cause a GC. */
145 directory
= Fexpand_file_name (directory
, Qnil
);
147 GCPRO2 (match
, directory
);
148 dirfilename
= Fdirectory_file_name (directory
);
154 CHECK_STRING (match
, 3);
156 /* MATCH might be a flawed regular expression. Rather than
157 catching and signaling our own errors, we just call
158 compile_pattern to do the work for us. */
160 bufp
= compile_pattern (match
, 0,
161 buffer_defaults
.downcase_table
->contents
, 0);
163 bufp
= compile_pattern (match
, 0, 0, 0);
167 /* Now *bufp is the compiled form of MATCH; don't call anything
168 which might compile a new regexp until we're done with the loop! */
170 /* Do this opendir after anything which might signal an error; if
171 an error is signaled while the directory stream is open, we
172 have to make sure it gets closed, and setting up an
173 unwind_protect to do so would be a pain. */
174 d
= opendir (XSTRING (dirfilename
)->data
);
176 report_file_error ("Opening directory", Fcons (directory
, Qnil
));
179 dirnamelen
= XSTRING (directory
)->size
;
180 re_match_object
= Qt
;
182 /* Loop reading blocks */
185 DIRENTRY
*dp
= readdir (d
);
190 if (DIRENTRY_NONEMPTY (dp
))
193 || (0 <= re_search (bufp
, dp
->d_name
, len
, 0, len
, 0)))
197 int afterdirindex
= dirnamelen
;
198 int total
= len
+ dirnamelen
;
201 /* Decide whether we need to add a directory separator. */
204 || !IS_ANY_SEP (XSTRING (directory
)->data
[dirnamelen
- 1]))
208 name
= make_uninit_string (total
+ needsep
);
209 bcopy (XSTRING (directory
)->data
, XSTRING (name
)->data
,
212 XSTRING (name
)->data
[afterdirindex
++] = DIRECTORY_SEP
;
214 XSTRING (name
)->data
+ afterdirindex
, len
);
217 name
= make_string (dp
->d_name
, len
);
218 list
= Fcons (name
, list
);
225 return Fsort (Fnreverse (list
), Qstring_lessp
);
228 Lisp_Object
file_name_completion ();
230 DEFUN ("file-name-completion", Ffile_name_completion
, Sfile_name_completion
,
232 "Complete file name FILE in directory DIRECTORY.\n\
233 Returns the longest string\n\
234 common to all file names in DIRECTORY that start with FILE.\n\
235 If there is only one and FILE matches it exactly, returns t.\n\
236 Returns nil if DIR contains no name starting with FILE.")
238 Lisp_Object file
, directory
;
242 /* If the directory name has special constructs in it,
243 call the corresponding file handler. */
244 handler
= Ffind_file_name_handler (directory
, Qfile_name_completion
);
246 return call3 (handler
, Qfile_name_completion
, file
, directory
);
248 /* If the file name has special constructs in it,
249 call the corresponding file handler. */
250 handler
= Ffind_file_name_handler (file
, Qfile_name_completion
);
252 return call3 (handler
, Qfile_name_completion
, file
, directory
);
254 return file_name_completion (file
, directory
, 0, 0);
257 DEFUN ("file-name-all-completions", Ffile_name_all_completions
,
258 Sfile_name_all_completions
, 2, 2, 0,
259 "Return a list of all completions of file name FILE in directory DIRECTORY.\n\
260 These are all file names in directory DIRECTORY which begin with FILE.")
262 Lisp_Object file
, directory
;
266 /* If the directory name has special constructs in it,
267 call the corresponding file handler. */
268 handler
= Ffind_file_name_handler (directory
, Qfile_name_all_completions
);
270 return call3 (handler
, Qfile_name_all_completions
, file
, directory
);
272 /* If the file name has special constructs in it,
273 call the corresponding file handler. */
274 handler
= Ffind_file_name_handler (file
, Qfile_name_all_completions
);
276 return call3 (handler
, Qfile_name_all_completions
, file
, directory
);
278 return file_name_completion (file
, directory
, 1, 0);
282 file_name_completion (file
, dirname
, all_flag
, ver_flag
)
283 Lisp_Object file
, dirname
;
284 int all_flag
, ver_flag
;
288 int bestmatchsize
, skip
;
289 register int compare
, matchsize
;
290 unsigned char *p1
, *p2
;
292 Lisp_Object bestmatch
, tem
, elt
, name
;
296 int count
= specpdl_ptr
- specpdl
;
297 struct gcpro gcpro1
, gcpro2
, gcpro3
;
300 extern DIRENTRY
* readdirver ();
302 DIRENTRY
*((* readfunc
) ());
304 /* Filename completion on VMS ignores case, since VMS filesys does. */
305 specbind (Qcompletion_ignore_case
, Qt
);
309 readfunc
= readdirver
;
310 file
= Fupcase (file
);
312 CHECK_STRING (file
, 0);
315 #ifdef FILE_SYSTEM_CASE
316 file
= FILE_SYSTEM_CASE (file
);
319 GCPRO3 (file
, dirname
, bestmatch
);
320 dirname
= Fexpand_file_name (dirname
, Qnil
);
322 /* With passcount = 0, ignore files that end in an ignored extension.
323 If nothing found then try again with passcount = 1, don't ignore them.
324 If looking for all completions, start with passcount = 1,
325 so always take even the ignored ones.
327 ** It would not actually be helpful to the user to ignore any possible
328 completions when making a list of them.** */
330 for (passcount
= !!all_flag
; NILP (bestmatch
) && passcount
< 2; passcount
++)
332 if (!(d
= opendir (XSTRING (Fdirectory_file_name (dirname
))->data
)))
333 report_file_error ("Opening directory", Fcons (dirname
, Qnil
));
335 /* Loop reading blocks */
336 /* (att3b compiler bug requires do a null comparison this way) */
343 dp
= (*readfunc
) (d
);
351 if (!NILP (Vquit_flag
) && NILP (Vinhibit_quit
))
353 if (! DIRENTRY_NONEMPTY (dp
)
354 || len
< XSTRING (file
)->size
355 || 0 <= scmp (dp
->d_name
, XSTRING (file
)->data
,
356 XSTRING (file
)->size
))
359 if (file_name_completion_stat (dirname
, dp
, &st
) < 0)
362 directoryp
= ((st
.st_mode
& S_IFMT
) == S_IFDIR
);
366 #ifndef TRIVIAL_DIRECTORY_ENTRY
367 #define TRIVIAL_DIRECTORY_ENTRY(n) (!strcmp (n, ".") || !strcmp (n, ".."))
369 /* "." and ".." are never interesting as completions, but are
370 actually in the way in a directory contains only one file. */
371 if (!passcount
&& TRIVIAL_DIRECTORY_ENTRY (dp
->d_name
))
376 /* Compare extensions-to-be-ignored against end of this file name */
377 /* if name is not an exact match against specified string */
378 if (!passcount
&& len
> XSTRING (file
)->size
)
379 /* and exit this for loop if a match is found */
380 for (tem
= Vcompletion_ignored_extensions
;
381 CONSP (tem
); tem
= XCONS (tem
)->cdr
)
383 elt
= XCONS (tem
)->car
;
384 if (!STRINGP (elt
)) continue;
385 skip
= len
- XSTRING (elt
)->size
;
386 if (skip
< 0) continue;
388 if (0 <= scmp (dp
->d_name
+ skip
,
390 XSTRING (elt
)->size
))
396 /* If an ignored-extensions match was found,
397 don't process this name as a completion. */
398 if (!passcount
&& CONSP (tem
))
405 XSETFASTINT (zero
, 0);
407 /* Ignore this element if it fails to match all the regexps. */
408 for (regexps
= Vcompletion_regexp_list
; CONSP (regexps
);
409 regexps
= XCONS (regexps
)->cdr
)
411 tem
= Fstring_match (XCONS (regexps
)->car
, elt
, zero
);
419 /* Update computation of how much all possible completions match */
423 if (all_flag
|| NILP (bestmatch
))
425 /* This is a possible completion */
428 /* This completion is a directory; make it end with '/' */
429 name
= Ffile_name_as_directory (make_string (dp
->d_name
, len
));
432 name
= make_string (dp
->d_name
, len
);
435 bestmatch
= Fcons (name
, bestmatch
);
440 bestmatchsize
= XSTRING (name
)->size
;
445 compare
= min (bestmatchsize
, len
);
446 p1
= XSTRING (bestmatch
)->data
;
447 p2
= (unsigned char *) dp
->d_name
;
448 matchsize
= scmp(p1
, p2
, compare
);
451 if (completion_ignore_case
)
453 /* If this is an exact match except for case,
454 use it as the best match rather than one that is not
455 an exact match. This way, we get the case pattern
456 of the actual match. */
457 /* This tests that the current file is an exact match
458 but BESTMATCH is not (it is too long). */
459 if ((matchsize
== len
460 && matchsize
+ !!directoryp
461 < XSTRING (bestmatch
)->size
)
463 /* If there is no exact match ignoring case,
464 prefer a match that does not change the case
466 /* If there is more than one exact match aside from
467 case, and one of them is exact including case,
469 /* This == checks that, of current file and BESTMATCH,
470 either both or neither are exact. */
473 (matchsize
+ !!directoryp
474 == XSTRING (bestmatch
)->size
))
475 && !bcmp (p2
, XSTRING (file
)->data
, XSTRING (file
)->size
)
476 && bcmp (p1
, XSTRING (file
)->data
, XSTRING (file
)->size
)))
478 bestmatch
= make_string (dp
->d_name
, len
);
480 bestmatch
= Ffile_name_as_directory (bestmatch
);
484 /* If this dirname all matches, see if implicit following
487 && compare
== matchsize
488 && bestmatchsize
> matchsize
489 && IS_ANY_SEP (p1
[matchsize
]))
491 bestmatchsize
= matchsize
;
498 bestmatch
= unbind_to (count
, bestmatch
);
500 if (all_flag
|| NILP (bestmatch
))
502 if (matchcount
== 1 && bestmatchsize
== XSTRING (file
)->size
)
504 return Fsubstring (bestmatch
, make_number (0), make_number (bestmatchsize
));
508 return Fsignal (Qquit
, Qnil
);
511 file_name_completion_stat (dirname
, dp
, st_addr
)
514 struct stat
*st_addr
;
516 int len
= NAMLEN (dp
);
517 int pos
= XSTRING (dirname
)->size
;
519 char *fullname
= (char *) alloca (len
+ pos
+ 2);
523 /* Some fields of struct stat are *very* expensive to compute on MS-DOS,
524 but aren't required here. Avoid computing the following fields:
525 st_inode, st_size and st_nlink for directories, and the execute bits
526 in st_mode for non-directory files with non-standard extensions. */
528 unsigned short save_djstat_flags
= _djstat_flags
;
530 _djstat_flags
= _STAT_INODE
| _STAT_EXEC_MAGIC
| _STAT_DIRSIZE
;
531 #endif /* __DJGPP__ > 1 */
534 bcopy (XSTRING (dirname
)->data
, fullname
, pos
);
536 if (!IS_DIRECTORY_SEP (fullname
[pos
- 1]))
537 fullname
[pos
++] = DIRECTORY_SEP
;
540 bcopy (dp
->d_name
, fullname
+ pos
, len
);
541 fullname
[pos
+ len
] = 0;
544 /* We want to return success if a link points to a nonexistent file,
545 but we want to return the status for what the link points to,
546 in case it is a directory. */
547 value
= lstat (fullname
, st_addr
);
548 stat (fullname
, st_addr
);
551 value
= stat (fullname
, st_addr
);
554 _djstat_flags
= save_djstat_flags
;
555 #endif /* __DJGPP__ > 1 */
563 DEFUN ("file-name-all-versions", Ffile_name_all_versions
,
564 Sfile_name_all_versions
, 2, 2, 0,
565 "Return a list of all versions of file name FILE in directory DIRECTORY.")
567 Lisp_Object file
, directory
;
569 return file_name_completion (file
, directory
, 1, 1);
572 DEFUN ("file-version-limit", Ffile_version_limit
, Sfile_version_limit
, 1, 1, 0,
573 "Return the maximum number of versions allowed for FILE.\n\
574 Returns nil if the file cannot be opened or if there is no version limit.")
576 Lisp_Object filename
;
581 struct XABFHC xabfhc
;
584 filename
= Fexpand_file_name (filename
, Qnil
);
586 xabfhc
= cc$rms_xabfhc
;
587 fab
.fab$l_fna
= XSTRING (filename
)->data
;
588 fab
.fab$b_fns
= strlen (fab
.fab$l_fna
);
589 fab
.fab$l_xab
= (char *) &xabfhc
;
590 status
= sys$
open (&fab
, 0, 0);
591 if (status
!= RMS$_NORMAL
) /* Probably non-existent file */
593 sys$
close (&fab
, 0, 0);
594 if (xabfhc
.xab$w_verlimit
== 32767)
595 return Qnil
; /* No version limit */
597 return make_number (xabfhc
.xab$w_verlimit
);
606 return Fcons (make_number (time
>> 16),
607 Fcons (make_number (time
& 0177777), Qnil
));
610 DEFUN ("file-attributes", Ffile_attributes
, Sfile_attributes
, 1, 1, 0,
611 "Return a list of attributes of file FILENAME.\n\
612 Value is nil if specified file cannot be opened.\n\
613 Otherwise, list elements are:\n\
614 0. t for directory, string (name linked to) for symbolic link, or nil.\n\
615 1. Number of links to file.\n\
618 4. Last access time, as a list of two integers.\n\
619 First integer has high-order 16 bits of time, second has low 16 bits.\n\
620 5. Last modification time, likewise.\n\
621 6. Last status change time, likewise.\n\
622 7. Size in bytes (-1, if number is out of range).\n\
623 8. File modes, as a string of ten letters or dashes as in ls -l.\n\
624 9. t iff file's gid would change if file were deleted and recreated.\n\
626 11. Device number.\n\
628 If file does not exist, returns nil.")
630 Lisp_Object filename
;
632 Lisp_Object values
[12];
639 filename
= Fexpand_file_name (filename
, Qnil
);
641 /* If the file name has special constructs in it,
642 call the corresponding file handler. */
643 handler
= Ffind_file_name_handler (filename
, Qfile_attributes
);
645 return call2 (handler
, Qfile_attributes
, filename
);
647 if (lstat (XSTRING (filename
)->data
, &s
) < 0)
650 switch (s
.st_mode
& S_IFMT
)
653 values
[0] = Qnil
; break;
655 values
[0] = Qt
; break;
658 values
[0] = Ffile_symlink_p (filename
); break;
661 values
[1] = make_number (s
.st_nlink
);
662 values
[2] = make_number (s
.st_uid
);
663 values
[3] = make_number (s
.st_gid
);
664 values
[4] = make_time (s
.st_atime
);
665 values
[5] = make_time (s
.st_mtime
);
666 values
[6] = make_time (s
.st_ctime
);
667 values
[7] = make_number ((int) s
.st_size
);
668 /* If the size is out of range, give back -1. */
669 if (XINT (values
[7]) != s
.st_size
)
670 XSETINT (values
[7], -1);
671 filemodestring (&s
, modes
);
672 values
[8] = make_string (modes
, 10);
673 #ifdef BSD4_3 /* Gross kludge to avoid lack of "#if defined(...)" in VMS */
674 #define BSD4_2 /* A new meaning to the term `backwards compatibility' */
676 #ifdef BSD4_2 /* file gid will be dir gid */
677 dirname
= Ffile_name_directory (filename
);
678 if (! NILP (dirname
) && stat (XSTRING (dirname
)->data
, &sdir
) == 0)
679 values
[9] = (sdir
.st_gid
!= s
.st_gid
) ? Qt
: Qnil
;
680 else /* if we can't tell, assume worst */
682 #else /* file gid will be egid */
683 values
[9] = (s
.st_gid
!= getegid ()) ? Qt
: Qnil
;
684 #endif /* BSD4_2 (or BSD4_3) */
686 #undef BSD4_2 /* ok, you can look again without throwing up */
688 /* Cast -1 to avoid warning if int is not as wide as VALBITS. */
689 if (s
.st_ino
& (((EMACS_INT
) (-1)) << VALBITS
))
690 /* To allow inode numbers larger than VALBITS, separate the bottom
692 values
[10] = Fcons (make_number (s
.st_ino
>> 16),
693 make_number (s
.st_ino
& 0xffff));
695 /* But keep the most common cases as integers. */
696 values
[10] = make_number (s
.st_ino
);
697 values
[11] = make_number (s
.st_dev
);
698 return Flist (sizeof(values
) / sizeof(values
[0]), values
);
703 Qdirectory_files
= intern ("directory-files");
704 Qfile_name_completion
= intern ("file-name-completion");
705 Qfile_name_all_completions
= intern ("file-name-all-completions");
706 Qfile_attributes
= intern ("file-attributes");
708 staticpro (&Qdirectory_files
);
709 staticpro (&Qfile_name_completion
);
710 staticpro (&Qfile_name_all_completions
);
711 staticpro (&Qfile_attributes
);
713 defsubr (&Sdirectory_files
);
714 defsubr (&Sfile_name_completion
);
716 defsubr (&Sfile_name_all_versions
);
717 defsubr (&Sfile_version_limit
);
719 defsubr (&Sfile_name_all_completions
);
720 defsubr (&Sfile_attributes
);
723 Qcompletion_ignore_case
= intern ("completion-ignore-case");
724 staticpro (&Qcompletion_ignore_case
);
727 DEFVAR_LISP ("completion-ignored-extensions", &Vcompletion_ignored_extensions
,
728 "*Completion ignores filenames ending in any string in this list.\n\
729 This variable does not affect lists of possible completions,\n\
730 but does affect the commands that actually do completions.");
731 Vcompletion_ignored_extensions
= Qnil
;