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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
24 #include <sys/types.h>
33 /* The d_nameln member of a struct dirent includes the '\0' character
34 on some systems, but not on others. What's worse, you can't tell
35 at compile-time which one it will be, since it really depends on
36 the sort of system providing the filesystem you're reading from,
37 not the system you are running on. Paul Eggert
38 <eggert@bi.twinsun.com> says this occurs when Emacs is running on a
39 SunOS 4.1.2 host, reading a directory that is remote-mounted from a
40 Solaris 2.1 host and is in a native Solaris 2.1 filesystem.
42 Since applying strlen to the name always works, we'll just do that. */
43 #define NAMLEN(p) strlen (p->d_name)
45 #ifdef SYSV_SYSTEM_DIR
48 #define DIRENTRY struct dirent
50 #else /* not SYSV_SYSTEM_DIR */
52 #ifdef NONSYSTEM_DIR_LIBRARY
54 #else /* not NONSYSTEM_DIR_LIBRARY */
60 #endif /* not NONSYSTEM_DIR_LIBRARY */
63 #define DIRENTRY struct direct
65 extern DIR *opendir ();
66 extern struct direct
*readdir ();
68 #endif /* not MSDOS */
69 #endif /* not SYSV_SYSTEM_DIR */
72 #define DIRENTRY_NONEMPTY(p) ((p)->d_name[0] != 0)
74 #define DIRENTRY_NONEMPTY(p) ((p)->d_ino)
83 /* Returns a search buffer, with a fastmap allocated and ready to go. */
84 extern struct re_pattern_buffer
*compile_pattern ();
86 #define min(a, b) ((a) < (b) ? (a) : (b))
88 /* if system does not have symbolic links, it does not have lstat.
89 In that case, use ordinary stat instead. */
95 extern int completion_ignore_case
;
96 extern Lisp_Object Vcompletion_regexp_list
;
98 Lisp_Object Vcompletion_ignored_extensions
;
99 Lisp_Object Qcompletion_ignore_case
;
100 Lisp_Object Qdirectory_files
;
101 Lisp_Object Qfile_name_completion
;
102 Lisp_Object Qfile_name_all_completions
;
103 Lisp_Object Qfile_attributes
;
105 DEFUN ("directory-files", Fdirectory_files
, Sdirectory_files
, 1, 4, 0,
106 "Return a list of names of files in DIRECTORY.\n\
107 There are three optional arguments:\n\
108 If FULL is non-nil, absolute pathnames of the files are returned.\n\
109 If MATCH is non-nil, only pathnames containing that regexp are returned.\n\
110 If NOSORT is non-nil, the list is not sorted--its order is unpredictable.\n\
111 NOSORT is useful if you plan to sort the result yourself.")
112 (dirname
, full
, match
, nosort
)
113 Lisp_Object dirname
, full
, match
, nosort
;
117 Lisp_Object list
, name
, dirfilename
;
119 struct re_pattern_buffer
*bufp
;
121 /* If the file name has special constructs in it,
122 call the corresponding file handler. */
123 handler
= Ffind_file_name_handler (dirname
, Qdirectory_files
);
129 args
[1] = Qdirectory_files
;
134 return Ffuncall (6, args
);
138 struct gcpro gcpro1
, gcpro2
;
140 /* Because of file name handlers, these functions might call
141 Ffuncall, and cause a GC. */
143 dirname
= Fexpand_file_name (dirname
, Qnil
);
145 GCPRO2 (match
, dirname
);
146 dirfilename
= Fdirectory_file_name (dirname
);
152 CHECK_STRING (match
, 3);
154 /* MATCH might be a flawed regular expression. Rather than
155 catching and signalling our own errors, we just call
156 compile_pattern to do the work for us. */
158 bufp
= compile_pattern (match
, 0,
159 buffer_defaults
.downcase_table
->contents
, 0);
161 bufp
= compile_pattern (match
, 0, 0, 0);
165 /* Now *bufp is the compiled form of MATCH; don't call anything
166 which might compile a new regexp until we're done with the loop! */
168 /* Do this opendir after anything which might signal an error; if
169 an error is signalled while the directory stream is open, we
170 have to make sure it gets closed, and setting up an
171 unwind_protect to do so would be a pain. */
172 d
= opendir (XSTRING (dirfilename
)->data
);
174 report_file_error ("Opening directory", Fcons (dirname
, Qnil
));
177 length
= XSTRING (dirname
)->size
;
179 /* Loop reading blocks */
182 DIRENTRY
*dp
= readdir (d
);
187 if (DIRENTRY_NONEMPTY (dp
))
190 || (0 <= re_search (bufp
, dp
->d_name
, len
, 0, len
, 0)))
194 int index
= XSTRING (dirname
)->size
;
195 int total
= len
+ index
;
198 || !IS_ANY_SEP (XSTRING (dirname
)->data
[length
- 1]))
202 name
= make_uninit_string (total
);
203 bcopy (XSTRING (dirname
)->data
, XSTRING (name
)->data
,
207 || IS_ANY_SEP (XSTRING (dirname
)->data
[length
- 1]))
208 XSTRING (name
)->data
[index
++] = DIRECTORY_SEP
;
210 bcopy (dp
->d_name
, XSTRING (name
)->data
+ index
, len
);
213 name
= make_string (dp
->d_name
, len
);
214 list
= Fcons (name
, list
);
221 return Fsort (Fnreverse (list
), Qstring_lessp
);
224 Lisp_Object
file_name_completion ();
226 DEFUN ("file-name-completion", Ffile_name_completion
, Sfile_name_completion
,
228 "Complete file name FILE in directory DIR.\n\
229 Returns the longest string\n\
230 common to all filenames in DIR that start with FILE.\n\
231 If there is only one and FILE matches it exactly, returns t.\n\
232 Returns nil if DIR contains no name starting with FILE.")
234 Lisp_Object file
, dirname
;
238 /* If the file name has special constructs in it,
239 call the corresponding file handler. */
240 handler
= Ffind_file_name_handler (dirname
, Qfile_name_completion
);
242 return call3 (handler
, Qfile_name_completion
, file
, dirname
);
244 return file_name_completion (file
, dirname
, 0, 0);
247 DEFUN ("file-name-all-completions", Ffile_name_all_completions
,
248 Sfile_name_all_completions
, 2, 2, 0,
249 "Return a list of all completions of file name FILE in directory DIR.\n\
250 These are all file names in directory DIR which begin with FILE.")
252 Lisp_Object file
, dirname
;
256 /* If the file name has special constructs in it,
257 call the corresponding file handler. */
258 handler
= Ffind_file_name_handler (dirname
, Qfile_name_all_completions
);
260 return call3 (handler
, Qfile_name_all_completions
, file
, dirname
);
262 return file_name_completion (file
, dirname
, 1, 0);
266 file_name_completion (file
, dirname
, all_flag
, ver_flag
)
267 Lisp_Object file
, dirname
;
268 int all_flag
, ver_flag
;
272 int bestmatchsize
, skip
;
273 register int compare
, matchsize
;
274 unsigned char *p1
, *p2
;
276 Lisp_Object bestmatch
, tem
, elt
, name
;
280 int count
= specpdl_ptr
- specpdl
;
281 struct gcpro gcpro1
, gcpro2
, gcpro3
;
284 extern DIRENTRY
* readdirver ();
286 DIRENTRY
*((* readfunc
) ());
288 /* Filename completion on VMS ignores case, since VMS filesys does. */
289 specbind (Qcompletion_ignore_case
, Qt
);
293 readfunc
= readdirver
;
294 file
= Fupcase (file
);
296 CHECK_STRING (file
, 0);
299 #ifdef FILE_SYSTEM_CASE
300 file
= FILE_SYSTEM_CASE (file
);
303 GCPRO3 (file
, dirname
, bestmatch
);
304 dirname
= Fexpand_file_name (dirname
, Qnil
);
306 /* With passcount = 0, ignore files that end in an ignored extension.
307 If nothing found then try again with passcount = 1, don't ignore them.
308 If looking for all completions, start with passcount = 1,
309 so always take even the ignored ones.
311 ** It would not actually be helpful to the user to ignore any possible
312 completions when making a list of them.** */
314 for (passcount
= !!all_flag
; NILP (bestmatch
) && passcount
< 2; passcount
++)
316 if (!(d
= opendir (XSTRING (Fdirectory_file_name (dirname
))->data
)))
317 report_file_error ("Opening directory", Fcons (dirname
, Qnil
));
319 /* Loop reading blocks */
320 /* (att3b compiler bug requires do a null comparison this way) */
327 dp
= (*readfunc
) (d
);
335 if (!NILP (Vquit_flag
) && NILP (Vinhibit_quit
))
337 if (! DIRENTRY_NONEMPTY (dp
)
338 || len
< XSTRING (file
)->size
339 || 0 <= scmp (dp
->d_name
, XSTRING (file
)->data
,
340 XSTRING (file
)->size
))
343 if (file_name_completion_stat (dirname
, dp
, &st
) < 0)
346 directoryp
= ((st
.st_mode
& S_IFMT
) == S_IFDIR
);
350 #ifndef TRIVIAL_DIRECTORY_ENTRY
351 #define TRIVIAL_DIRECTORY_ENTRY(n) (!strcmp (n, ".") || !strcmp (n, ".."))
353 /* "." and ".." are never interesting as completions, but are
354 actually in the way in a directory contains only one file. */
355 if (!passcount
&& TRIVIAL_DIRECTORY_ENTRY (dp
->d_name
))
360 /* Compare extensions-to-be-ignored against end of this file name */
361 /* if name is not an exact match against specified string */
362 if (!passcount
&& len
> XSTRING (file
)->size
)
363 /* and exit this for loop if a match is found */
364 for (tem
= Vcompletion_ignored_extensions
;
365 CONSP (tem
); tem
= XCONS (tem
)->cdr
)
367 elt
= XCONS (tem
)->car
;
368 if (!STRINGP (elt
)) continue;
369 skip
= len
- XSTRING (elt
)->size
;
370 if (skip
< 0) continue;
372 if (0 <= scmp (dp
->d_name
+ skip
,
374 XSTRING (elt
)->size
))
380 /* If an ignored-extensions match was found,
381 don't process this name as a completion. */
382 if (!passcount
&& CONSP (tem
))
389 XSETFASTINT (zero
, 0);
391 /* Ignore this element if it fails to match all the regexps. */
392 for (regexps
= Vcompletion_regexp_list
; CONSP (regexps
);
393 regexps
= XCONS (regexps
)->cdr
)
395 tem
= Fstring_match (XCONS (regexps
)->car
, elt
, zero
);
403 /* Update computation of how much all possible completions match */
407 if (all_flag
|| NILP (bestmatch
))
409 /* This is a possible completion */
412 /* This completion is a directory; make it end with '/' */
413 name
= Ffile_name_as_directory (make_string (dp
->d_name
, len
));
416 name
= make_string (dp
->d_name
, len
);
419 bestmatch
= Fcons (name
, bestmatch
);
424 bestmatchsize
= XSTRING (name
)->size
;
429 compare
= min (bestmatchsize
, len
);
430 p1
= XSTRING (bestmatch
)->data
;
431 p2
= (unsigned char *) dp
->d_name
;
432 matchsize
= scmp(p1
, p2
, compare
);
435 if (completion_ignore_case
)
437 /* If this is an exact match except for case,
438 use it as the best match rather than one that is not
439 an exact match. This way, we get the case pattern
440 of the actual match. */
441 if ((matchsize
== len
442 && matchsize
+ !!directoryp
443 < XSTRING (bestmatch
)->size
)
445 /* If there is no exact match ignoring case,
446 prefer a match that does not change the case
450 (matchsize
+ !!directoryp
451 == XSTRING (bestmatch
)->size
))
452 /* If there is more than one exact match aside from
453 case, and one of them is exact including case,
455 && !bcmp (p2
, XSTRING (file
)->data
, XSTRING (file
)->size
)
456 && bcmp (p1
, XSTRING (file
)->data
, XSTRING (file
)->size
)))
458 bestmatch
= make_string (dp
->d_name
, len
);
460 bestmatch
= Ffile_name_as_directory (bestmatch
);
464 /* If this dirname all matches, see if implicit following
467 && compare
== matchsize
468 && bestmatchsize
> matchsize
469 && IS_ANY_SEP (p1
[matchsize
]))
471 bestmatchsize
= matchsize
;
478 bestmatch
= unbind_to (count
, bestmatch
);
480 if (all_flag
|| NILP (bestmatch
))
482 if (matchcount
== 1 && bestmatchsize
== XSTRING (file
)->size
)
484 return Fsubstring (bestmatch
, make_number (0), make_number (bestmatchsize
));
488 return Fsignal (Qquit
, Qnil
);
491 file_name_completion_stat (dirname
, dp
, st_addr
)
494 struct stat
*st_addr
;
496 int len
= NAMLEN (dp
);
497 int pos
= XSTRING (dirname
)->size
;
499 char *fullname
= (char *) alloca (len
+ pos
+ 2);
501 bcopy (XSTRING (dirname
)->data
, fullname
, pos
);
503 if (!IS_DIRECTORY_SEP (fullname
[pos
- 1]))
504 fullname
[pos
++] = DIRECTORY_SEP
;
507 bcopy (dp
->d_name
, fullname
+ pos
, len
);
508 fullname
[pos
+ len
] = 0;
511 /* We want to return success if a link points to a nonexistent file,
512 but we want to return the status for what the link points to,
513 in case it is a directory. */
514 value
= lstat (fullname
, st_addr
);
515 stat (fullname
, st_addr
);
518 return stat (fullname
, st_addr
);
524 DEFUN ("file-name-all-versions", Ffile_name_all_versions
,
525 Sfile_name_all_versions
, 2, 2, 0,
526 "Return a list of all versions of file name FILE in directory DIR.")
528 Lisp_Object file
, dirname
;
530 return file_name_completion (file
, dirname
, 1, 1);
533 DEFUN ("file-version-limit", Ffile_version_limit
, Sfile_version_limit
, 1, 1, 0,
534 "Return the maximum number of versions allowed for FILE.\n\
535 Returns nil if the file cannot be opened or if there is no version limit.")
537 Lisp_Object filename
;
542 struct XABFHC xabfhc
;
545 filename
= Fexpand_file_name (filename
, Qnil
);
547 xabfhc
= cc$rms_xabfhc
;
548 fab
.fab$l_fna
= XSTRING (filename
)->data
;
549 fab
.fab$b_fns
= strlen (fab
.fab$l_fna
);
550 fab
.fab$l_xab
= (char *) &xabfhc
;
551 status
= sys$
open (&fab
, 0, 0);
552 if (status
!= RMS$_NORMAL
) /* Probably non-existent file */
554 sys$
close (&fab
, 0, 0);
555 if (xabfhc
.xab$w_verlimit
== 32767)
556 return Qnil
; /* No version limit */
558 return make_number (xabfhc
.xab$w_verlimit
);
567 return Fcons (make_number (time
>> 16),
568 Fcons (make_number (time
& 0177777), Qnil
));
571 DEFUN ("file-attributes", Ffile_attributes
, Sfile_attributes
, 1, 1, 0,
572 "Return a list of attributes of file FILENAME.\n\
573 Value is nil if specified file cannot be opened.\n\
574 Otherwise, list elements are:\n\
575 0. t for directory, string (name linked to) for symbolic link, or nil.\n\
576 1. Number of links to file.\n\
579 4. Last access time, as a list of two integers.\n\
580 First integer has high-order 16 bits of time, second has low 16 bits.\n\
581 5. Last modification time, likewise.\n\
582 6. Last status change time, likewise.\n\
583 7. Size in bytes (-1, if number is out of range).\n\
584 8. File modes, as a string of ten letters or dashes as in ls -l.\n\
585 9. t iff file's gid would change if file were deleted and recreated.\n\
587 11. Device number.\n\
589 If file does not exist, returns nil.")
591 Lisp_Object filename
;
593 Lisp_Object values
[12];
600 filename
= Fexpand_file_name (filename
, Qnil
);
602 /* If the file name has special constructs in it,
603 call the corresponding file handler. */
604 handler
= Ffind_file_name_handler (filename
, Qfile_attributes
);
606 return call2 (handler
, Qfile_attributes
, filename
);
608 if (lstat (XSTRING (filename
)->data
, &s
) < 0)
613 char *tmpnam
= XSTRING (Ffile_name_nondirectory (filename
))->data
;
614 int l
= strlen (tmpnam
);
617 && S_ISREG (s
.st_mode
)
618 && (stricmp (&tmpnam
[l
- 4], ".com") == 0
619 || stricmp (&tmpnam
[l
- 4], ".exe") == 0
620 || stricmp (&tmpnam
[l
- 4], ".bat") == 0))
622 s
.st_mode
|= S_IEXEC
;
627 switch (s
.st_mode
& S_IFMT
)
630 values
[0] = Qnil
; break;
632 values
[0] = Qt
; break;
635 values
[0] = Ffile_symlink_p (filename
); break;
638 values
[1] = make_number (s
.st_nlink
);
639 values
[2] = make_number (s
.st_uid
);
640 values
[3] = make_number (s
.st_gid
);
641 values
[4] = make_time (s
.st_atime
);
642 values
[5] = make_time (s
.st_mtime
);
643 values
[6] = make_time (s
.st_ctime
);
644 values
[7] = make_number ((int) s
.st_size
);
645 /* If the size is out of range, give back -1. */
646 if (XINT (values
[7]) != s
.st_size
)
647 XSETINT (values
[7], -1);
648 filemodestring (&s
, modes
);
649 values
[8] = make_string (modes
, 10);
650 #ifdef BSD4_3 /* Gross kludge to avoid lack of "#if defined(...)" in VMS */
651 #define BSD4_2 /* A new meaning to the term `backwards compatibility' */
653 #ifdef BSD4_2 /* file gid will be dir gid */
654 dirname
= Ffile_name_directory (filename
);
655 if (! NILP (dirname
) && stat (XSTRING (dirname
)->data
, &sdir
) == 0)
656 values
[9] = (sdir
.st_gid
!= s
.st_gid
) ? Qt
: Qnil
;
657 else /* if we can't tell, assume worst */
659 #else /* file gid will be egid */
661 values
[9] = Qnil
; /* sorry, no group IDs on NT */
662 #else /* not WINDOWSNT */
663 values
[9] = (s
.st_gid
!= getegid ()) ? Qt
: Qnil
;
664 #endif /* not WINDOWSNT */
665 #endif /* BSD4_2 (or BSD4_3) */
667 #undef BSD4_2 /* ok, you can look again without throwing up */
670 /* NT inodes are 64 bits, so we need to dance a little... */
671 if (!get_inode_and_device_vals (filename
, &values
[10], &values
[11])) { ????
674 #else /* not WINDOWSNT */
675 values
[10] = make_number (s
.st_ino
);
676 values
[11] = make_number (s
.st_dev
);
677 #endif /* not WINDOWSNT */
678 return Flist (sizeof(values
) / sizeof(values
[0]), values
);
683 Qdirectory_files
= intern ("directory-files");
684 Qfile_name_completion
= intern ("file-name-completion");
685 Qfile_name_all_completions
= intern ("file-name-all-completions");
686 Qfile_attributes
= intern ("file-attributes");
688 defsubr (&Sdirectory_files
);
689 defsubr (&Sfile_name_completion
);
691 defsubr (&Sfile_name_all_versions
);
692 defsubr (&Sfile_version_limit
);
694 defsubr (&Sfile_name_all_completions
);
695 defsubr (&Sfile_attributes
);
698 Qcompletion_ignore_case
= intern ("completion-ignore-case");
699 staticpro (&Qcompletion_ignore_case
);
702 DEFVAR_LISP ("completion-ignored-extensions", &Vcompletion_ignored_extensions
,
703 "*Completion ignores filenames ending in any string in this list.\n\
704 This variable does not affect lists of possible completions,\n\
705 but does affect the commands that actually do completions.");
706 Vcompletion_ignored_extensions
= Qnil
;