1 /* Lisp functions for making directory listings.
2 Copyright (C) 1985, 1986, 1992, 1993, 1994 Free Software Foundation, Inc.
4 This file is part of XEmacs.
6 XEmacs is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 XEmacs is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 You should have received a copy of the GNU General Public License
17 along with XEmacs; 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. */
21 /* Synched up with: FSF 19.30. */
37 Lisp_Object Vcompletion_ignored_extensions;
38 Lisp_Object Qdirectory_files;
39 Lisp_Object Qfile_name_completion;
40 Lisp_Object Qfile_name_all_completions;
41 Lisp_Object Qfile_attributes;
44 close_directory_unwind (Lisp_Object unwind_obj)
46 DIR *d = (DIR *)get_opaque_ptr (unwind_obj);
48 free_opaque_ptr (unwind_obj);
52 DEFUN ("directory-files", Fdirectory_files, 1, 5, 0, /*
53 Return a list of names of files in DIRECTORY.
54 There are four optional arguments:
55 If FULL is non-nil, absolute pathnames of the files are returned.
56 If MATCH is non-nil, only pathnames containing that regexp are returned.
57 If NOSORT is non-nil, the list is not sorted--its order is unpredictable.
58 NOSORT is useful if you plan to sort the result yourself.
59 If FILES-ONLY is the symbol t, then only the "files" in the directory
60 will be returned; subdirectories will be excluded. If FILES-ONLY is not
61 nil and not t, then only the subdirectories will be returned. Otherwise,
62 if FILES-ONLY is nil (the default) then both files and subdirectories will
65 (directory, full, match, nosort, files_only))
67 /* This function can GC */
69 Lisp_Object list = Qnil;
70 Bytecount directorylen;
72 struct re_pattern_buffer *bufp = NULL;
73 int speccount = specpdl_depth ();
74 char *statbuf, *statbuf_tail;
76 struct gcpro gcpro1, gcpro2;
77 GCPRO2 (directory, list);
79 /* If the file name has special constructs in it,
80 call the corresponding file handler. */
81 handler = Ffind_file_name_handler (directory, Qdirectory_files);
85 if (!NILP (files_only))
86 return call6 (handler, Qdirectory_files, directory, full, match,
89 return call5 (handler, Qdirectory_files, directory, full, match,
93 /* #### why do we do Fexpand_file_name after file handlers here,
94 but earlier everywhere else? */
95 directory = Fexpand_file_name (directory, Qnil);
96 directory = Ffile_name_as_directory (directory);
97 directorylen = XSTRING_LENGTH (directory);
99 statbuf = (char *)alloca (directorylen + MAXNAMLEN + 1);
100 memcpy (statbuf, XSTRING_DATA (directory), directorylen);
101 statbuf_tail = statbuf + directorylen;
103 /* XEmacs: this should come after Ffile_name_as_directory() to avoid
104 potential regexp cache smashage. It comes before the opendir()
105 because it might signal an error. */
108 CHECK_STRING (match);
110 /* MATCH might be a flawed regular expression. Rather than
111 catching and signalling our own errors, we just call
112 compile_pattern to do the work for us. */
113 bufp = compile_pattern (match, 0, 0, 0, ERROR_ME);
116 /* Now *bufp is the compiled form of MATCH; don't call anything
117 which might compile a new regexp until we're done with the loop! */
119 /* Do this opendir after anything which might signal an error.
120 NOTE: the above comment is old; previously, there was no
121 unwind-protection in case of error, but now there is. */
122 d = opendir ((char *) XSTRING_DATA (directory));
124 report_file_error ("Opening directory", list1 (directory));
126 record_unwind_protect (close_directory_unwind, make_opaque_ptr ((void *)d));
128 /* Loop reading blocks */
131 DIRENTRY *dp = readdir (d);
137 if (DIRENTRY_NONEMPTY (dp)
139 || (0 <= re_search (bufp, dp->d_name, len, 0, len, 0))))
141 if (!NILP (files_only))
146 memcpy (statbuf_tail, dp->d_name, len);
147 statbuf_tail[len] = 0;
149 if (stat (statbuf, &st) == 0
150 && (st.st_mode & S_IFMT) == S_IFDIR)
153 if (EQ (files_only, Qt) && dir_p)
155 else if (!EQ (files_only, Qt) && !dir_p)
161 make_string ((Bufbyte *)dp->d_name, len);
163 name = concat2 (directory, name);
165 list = Fcons (name, list);
169 unbind_to (speccount, Qnil); /* This will close the dir */
172 list = Fsort (Fnreverse (list), Qstring_lessp);
174 RETURN_UNGCPRO (list);
177 static Lisp_Object file_name_completion (Lisp_Object file,
178 Lisp_Object directory,
179 int all_flag, int ver_flag);
181 DEFUN ("file-name-completion", Ffile_name_completion, 2, 2, 0, /*
182 Complete file name FILE in directory DIRECTORY.
183 Returns the longest string common to all filenames in DIRECTORY
184 that start with FILE.
185 If there is only one and FILE matches it exactly, returns t.
186 Returns nil if DIRECTORY contains no name starting with FILE.
188 Filenames which end with any member of `completion-ignored-extensions'
189 are not considered as possible completions for FILE unless there is no
190 other possible completion. `completion-ignored-extensions' is not applied
191 to the names of directories.
195 /* This function can GC. GC checked 1996.04.06. */
198 /* If the directory name has special constructs in it,
199 call the corresponding file handler. */
200 handler = Ffind_file_name_handler (directory, Qfile_name_completion);
202 return call3 (handler, Qfile_name_completion, file, directory);
204 /* If the file name has special constructs in it,
205 call the corresponding file handler. */
206 handler = Ffind_file_name_handler (file, Qfile_name_completion);
208 return call3 (handler, Qfile_name_completion, file, directory);
210 return file_name_completion (file, directory, 0, 0);
213 DEFUN ("file-name-all-completions", Ffile_name_all_completions, 2, 2, 0, /*
214 Return a list of all completions of file name FILE in directory DIRECTORY.
215 These are all file names in directory DIRECTORY which begin with FILE.
217 File names which end with any member of `completion-ignored-extensions'
218 are not considered as possible completions for FILE unless there is no
219 other possible completion. `completion-ignored-extensions' is not applied
220 to the names of directories.
224 /* This function can GC. GC checked 1997.06.04. */
229 directory = Fexpand_file_name (directory, Qnil);
230 /* If the file name has special constructs in it,
231 call the corresponding file handler. */
232 handler = Ffind_file_name_handler (directory, Qfile_name_all_completions);
235 return call3 (handler, Qfile_name_all_completions, file,
238 return file_name_completion (file, directory, 1, 0);
242 file_name_completion_stat (Lisp_Object directory, DIRENTRY *dp,
243 struct stat *st_addr)
245 Bytecount len = NAMLEN (dp);
246 Bytecount pos = XSTRING_LENGTH (directory);
248 char *fullname = (char *) alloca (len + pos + 2);
250 memcpy (fullname, XSTRING_DATA (directory), pos);
251 if (!IS_DIRECTORY_SEP (fullname[pos - 1]))
252 fullname[pos++] = DIRECTORY_SEP;
254 memcpy (fullname + pos, dp->d_name, len);
255 fullname[pos + len] = 0;
258 /* We want to return success if a link points to a nonexistent file,
259 but we want to return the status for what the link points to,
260 in case it is a directory. */
261 value = lstat (fullname, st_addr);
262 if (S_ISLNK (st_addr->st_mode))
263 stat (fullname, st_addr);
265 value = stat (fullname, st_addr);
271 file_name_completion_unwind (Lisp_Object locative)
274 Lisp_Object obj = XCAR (locative);
278 d = (DIR *)get_opaque_ptr (obj);
280 free_opaque_ptr (obj);
282 free_cons (XCONS (locative));
287 file_name_completion (Lisp_Object file, Lisp_Object directory, int all_flag,
290 /* This function can GC */
293 Lisp_Object bestmatch = Qnil;
294 Charcount bestmatchsize = 0;
297 int speccount = specpdl_depth ();
298 Charcount file_name_length;
299 Lisp_Object locative;
300 struct gcpro gcpro1, gcpro2, gcpro3;
302 GCPRO3 (file, directory, bestmatch);
307 /* Filename completion on Windows ignores case, since Windows
309 specbind (Qcompletion_ignore_case, Qt);
310 #endif /* WINDOWSNT */
312 #ifdef FILE_SYSTEM_CASE
313 file = FILE_SYSTEM_CASE (file);
315 directory = Fexpand_file_name (directory, Qnil);
316 file_name_length = XSTRING_CHAR_LENGTH (file);
318 /* With passcount = 0, ignore files that end in an ignored extension.
319 If nothing found then try again with passcount = 1, don't ignore them.
320 If looking for all completions, start with passcount = 1,
321 so always take even the ignored ones.
323 ** It would not actually be helpful to the user to ignore any possible
324 completions when making a list of them.** */
326 /* We cannot use close_directory_unwind() because we change the
327 directory. The old code used to just avoid signaling errors, and
328 call closedir, but it was wrong, because it made sane handling of
329 QUIT impossible and, besides, various utility functions like
330 regexp_ignore_completion_p can signal errors. */
331 locative = noseeum_cons (Qnil, Qnil);
332 record_unwind_protect (file_name_completion_unwind, locative);
334 for (passcount = !!all_flag; NILP (bestmatch) && passcount < 2; passcount++)
336 d = opendir ((char *) XSTRING_DATA (Fdirectory_file_name (directory)));
338 report_file_error ("Opening directory", list1 (directory));
339 XCAR (locative) = make_opaque_ptr ((void *)d);
341 /* Loop reading blocks */
346 /* scmp() works in characters, not bytes, so we have to compute
350 int ignored_extension_p = 0;
356 /* Cast to Bufbyte* is OK, as readdir() Mule-encapsulates. */
357 d_name = (Bufbyte *) dp->d_name;
359 cclen = bytecount_to_charcount (d_name, len);
363 if (! DIRENTRY_NONEMPTY (dp)
364 || cclen < file_name_length
365 || 0 <= scmp (d_name, XSTRING_DATA (file), file_name_length))
368 if (file_name_completion_stat (directory, dp, &st) < 0)
371 directoryp = ((st.st_mode & S_IFMT) == S_IFDIR);
374 #ifndef TRIVIAL_DIRECTORY_ENTRY
375 #define TRIVIAL_DIRECTORY_ENTRY(n) (!strcmp (n, ".") || !strcmp (n, ".."))
377 /* "." and ".." are never interesting as completions, but are
378 actually in the way in a directory containing only one file. */
379 if (!passcount && TRIVIAL_DIRECTORY_ENTRY (dp->d_name))
384 /* Compare extensions-to-be-ignored against end of this file name */
385 /* if name is not an exact match against specified string. */
386 if (!passcount && cclen > file_name_length)
389 /* and exit this for loop if a match is found */
390 EXTERNAL_LIST_LOOP (tem, Vcompletion_ignored_extensions)
392 Lisp_Object elt = XCAR (tem);
397 skip = cclen - XSTRING_CHAR_LENGTH (elt);
398 if (skip < 0) continue;
400 if (0 > scmp (charptr_n_addr (d_name, skip),
402 XSTRING_CHAR_LENGTH (elt)))
404 ignored_extension_p = 1;
411 /* If an ignored-extensions match was found,
412 don't process this name as a completion. */
413 if (!passcount && ignored_extension_p)
416 if (!passcount && regexp_ignore_completion_p (d_name, Qnil, 0, cclen))
419 /* Update computation of how much all possible completions match */
422 if (all_flag || NILP (bestmatch))
424 Lisp_Object name = Qnil;
425 struct gcpro ngcpro1;
427 /* This is a possible completion */
428 name = make_string (d_name, len);
429 if (directoryp) /* Completion is a directory; end it with '/' */
430 name = Ffile_name_as_directory (name);
433 bestmatch = Fcons (name, bestmatch);
438 bestmatchsize = XSTRING_CHAR_LENGTH (name);
444 Charcount compare = min (bestmatchsize, cclen);
445 Bufbyte *p1 = XSTRING_DATA (bestmatch);
446 Bufbyte *p2 = d_name;
447 Charcount 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 if ((matchsize == cclen
458 && matchsize + !!directoryp
459 < XSTRING_CHAR_LENGTH (bestmatch))
461 /* If there is no exact match ignoring case,
462 prefer a match that does not change the case
464 (((matchsize == cclen)
466 (matchsize + !!directoryp
467 == XSTRING_CHAR_LENGTH (bestmatch)))
468 /* If there is more than one exact match aside from
469 case, and one of them is exact including case,
471 && 0 > scmp_1 (p2, XSTRING_DATA (file),
473 && 0 <= scmp_1 (p1, XSTRING_DATA (file),
474 file_name_length, 0)))
476 bestmatch = make_string (d_name, len);
478 bestmatch = Ffile_name_as_directory (bestmatch);
482 /* If this directory all matches,
483 see if implicit following slash does too. */
485 && compare == matchsize
486 && bestmatchsize > matchsize
487 && IS_ANY_SEP (charptr_emchar_n (p1, matchsize)))
489 bestmatchsize = matchsize;
493 free_opaque_ptr (XCAR (locative));
494 XCAR (locative) = Qnil;
497 unbind_to (speccount, Qnil);
501 if (all_flag || NILP (bestmatch))
503 if (matchcount == 1 && bestmatchsize == file_name_length)
505 return Fsubstring (bestmatch, Qzero, make_int (bestmatchsize));
510 /* The *pwent() functions do not exist on NT */
513 static Lisp_Object user_name_completion (Lisp_Object user,
517 DEFUN ("user-name-completion", Fuser_name_completion, 1, 1, 0, /*
518 Complete user name USER.
520 Returns the longest string common to all user names that start
521 with USER. If there is only one and USER matches it exactly,
522 returns t. Returns nil if there is no user name starting with USER.
526 return user_name_completion (user, 0, NULL);
529 DEFUN ("user-name-completion-1", Fuser_name_completion_1, 1, 1, 0, /*
530 Complete user name USER.
532 This function is identical to `user-name-completion', except that
533 the cons of the completion and an indication of whether the
534 completion was unique is returned.
536 The car of the returned value is the longest string common to all
537 user names that start with USER. If there is only one and USER
538 matches it exactly, the car is t. The car is nil if there is no
539 user name starting with USER. The cdr of the result is non-nil
540 if and only if the completion returned in the car was unique.
545 Lisp_Object completed = user_name_completion (user, 0, &uniq);
546 return Fcons (completed, uniq ? Qt : Qnil);
549 DEFUN ("user-name-all-completions", Fuser_name_all_completions, 1, 1, 0, /*
550 Return a list of all completions of user name USER.
551 These are all user names which begin with USER.
555 return user_name_completion (user, 1, NULL);
566 struct user_name *user_names;
569 EMACS_TIME last_rebuild_time;
571 static struct user_cache user_cache;
574 free_user_cache (struct user_cache *cache)
577 for (i = 0; i < cache->length; i++)
578 xfree (cache->user_names[i].ptr);
579 xfree (cache->user_names);
584 user_name_completion_unwind (Lisp_Object cache_incomplete_p)
587 speed_up_interrupts ();
589 if (! NILP (XCAR (cache_incomplete_p)))
590 free_user_cache (&user_cache);
592 free_cons (XCONS (cache_incomplete_p));
597 #define USER_CACHE_TTL (24*60*60) /* Time to live: 1 day, in seconds */
600 user_name_completion (Lisp_Object user, int all_flag, int *uniq)
602 /* This function can GC */
604 Lisp_Object bestmatch = Qnil;
605 Charcount bestmatchsize = 0;
606 Charcount user_name_length;
609 struct gcpro gcpro1, gcpro2;
611 GCPRO2 (user, bestmatch);
615 user_name_length = XSTRING_CHAR_LENGTH (user);
617 /* Cache user name lookups because it tends to be quite slow.
618 * Rebuild the cache occasionally to catch changes */
620 if (user_cache.user_names &&
621 (EMACS_SECS (t) - EMACS_SECS (user_cache.last_rebuild_time)
623 free_user_cache (&user_cache);
625 if (!user_cache.user_names)
628 Lisp_Object cache_incomplete_p = noseeum_cons (Qt, Qnil);
629 int speccount = specpdl_depth ();
631 slow_down_interrupts ();
633 record_unwind_protect (user_name_completion_unwind, cache_incomplete_p);
634 while ((pwd = getpwent ()))
637 DO_REALLOC (user_cache.user_names, user_cache.size,
638 user_cache.length + 1, struct user_name);
639 TO_INTERNAL_FORMAT (C_STRING, pwd->pw_name,
641 (user_cache.user_names[user_cache.length].ptr,
642 user_cache.user_names[user_cache.length].len),
646 XCAR (cache_incomplete_p) = Qnil;
647 unbind_to (speccount, Qnil);
649 EMACS_GET_TIME (user_cache.last_rebuild_time);
652 for (i = 0; i < user_cache.length; i++)
654 Bufbyte *u_name = user_cache.user_names[i].ptr;
655 Bytecount len = user_cache.user_names[i].len;
656 /* scmp() works in chars, not bytes, so we have to compute this: */
657 Charcount cclen = bytecount_to_charcount (u_name, len);
661 if (cclen < user_name_length
662 || 0 <= scmp_1 (u_name, XSTRING_DATA (user), user_name_length, 0))
665 matchcount++; /* count matching completions */
667 if (all_flag || NILP (bestmatch))
669 Lisp_Object name = Qnil;
670 struct gcpro ngcpro1;
672 /* This is a possible completion */
673 name = make_string (u_name, len);
676 bestmatch = Fcons (name, bestmatch);
681 bestmatchsize = XSTRING_CHAR_LENGTH (name);
687 Charcount compare = min (bestmatchsize, cclen);
688 Bufbyte *p1 = XSTRING_DATA (bestmatch);
689 Bufbyte *p2 = u_name;
690 Charcount matchsize = scmp_1 (p1, p2, compare, 0);
695 bestmatchsize = matchsize;
702 *uniq = (matchcount == 1);
704 if (all_flag || NILP (bestmatch))
706 if (matchcount == 1 && bestmatchsize == user_name_length)
708 return Fsubstring (bestmatch, Qzero, make_int (bestmatchsize));
710 #endif /* ! defined WINDOWSNT */
714 make_directory_hash_table (const char *path)
717 if ((d = opendir (path)))
721 make_lisp_hash_table (20, HASH_TABLE_NON_WEAK, HASH_TABLE_EQUAL);
723 while ((dp = readdir (d)))
725 Bytecount len = NAMLEN (dp);
726 if (DIRENTRY_NONEMPTY (dp))
727 /* Cast to Bufbyte* is OK, as readdir() Mule-encapsulates. */
728 Fputhash (make_string ((Bufbyte *) dp->d_name, len), Qt, hash);
738 wasteful_word_to_lisp (unsigned int item)
740 /* Compatibility: in other versions, file-attributes returns a LIST
741 of two 16 bit integers... */
742 Lisp_Object cons = word_to_lisp (item);
743 XCDR (cons) = Fcons (XCDR (cons), Qnil);
747 DEFUN ("file-attributes", Ffile_attributes, 1, 1, 0, /*
748 Return a list of attributes of file FILENAME.
749 Value is nil if specified file cannot be opened.
750 Otherwise, list elements are:
751 0. t for directory, string (name linked to) for symbolic link, or nil.
752 1. Number of links to file.
755 4. Last access time, as a list of two integers.
756 First integer has high-order 16 bits of time, second has low 16 bits.
757 5. Last modification time, likewise.
758 6. Last status change time, likewise.
759 7. Size in bytes. (-1, if number is out of range).
760 8. File modes, as a string of ten letters or dashes as in ls -l.
761 9. t iff file's gid would change if file were deleted and recreated.
765 If file does not exist, returns nil.
769 /* This function can GC. GC checked 1997.06.04. */
770 Lisp_Object values[12];
771 Lisp_Object directory = Qnil;
775 struct gcpro gcpro1, gcpro2;
777 GCPRO2 (filename, directory);
778 filename = Fexpand_file_name (filename, Qnil);
780 /* If the file name has special constructs in it,
781 call the corresponding file handler. */
782 handler = Ffind_file_name_handler (filename, Qfile_attributes);
786 return call2 (handler, Qfile_attributes, filename);
789 if (lstat ((char *) XSTRING_DATA (filename), &s) < 0)
796 directory = Ffile_name_directory (filename);
801 char *tmpnam = (char *) XSTRING_DATA (Ffile_name_nondirectory (filename));
802 int l = strlen (tmpnam);
805 && S_ISREG (s.st_mode)
806 && (stricmp (&tmpnam[l - 4], ".com") == 0 ||
807 stricmp (&tmpnam[l - 4], ".exe") == 0 ||
808 stricmp (&tmpnam[l - 4], ".bat") == 0))
810 s.st_mode |= S_IEXEC;
815 switch (s.st_mode & S_IFMT)
825 values[0] = Ffile_symlink_p (filename);
829 values[1] = make_int (s.st_nlink);
830 values[2] = make_int (s.st_uid);
831 values[3] = make_int (s.st_gid);
832 values[4] = wasteful_word_to_lisp (s.st_atime);
833 values[5] = wasteful_word_to_lisp (s.st_mtime);
834 values[6] = wasteful_word_to_lisp (s.st_ctime);
835 values[7] = make_int ((EMACS_INT) s.st_size);
836 /* If the size is out of range, give back -1. */
837 /* #### Fix when Emacs gets bignums! */
838 if (XINT (values[7]) != s.st_size)
839 values[7] = make_int (-1);
840 filemodestring (&s, modes);
841 values[8] = make_string ((Bufbyte *) modes, 10);
842 #if defined (BSD4_2) || defined (BSD4_3) /* file gid will be dir gid */
846 if (!NILP (directory) && stat ((char *) XSTRING_DATA (directory), &sdir) == 0)
847 values[9] = (sdir.st_gid != s.st_gid) ? Qt : Qnil;
848 else /* if we can't tell, assume worst */
851 #else /* file gid will be egid */
852 values[9] = (s.st_gid != getegid ()) ? Qt : Qnil;
853 #endif /* BSD4_2 or BSD4_3 */
854 values[10] = make_int (s.st_ino);
855 values[11] = make_int (s.st_dev);
857 return Flist (countof (values), values);
861 /************************************************************************/
863 /************************************************************************/
868 defsymbol (&Qdirectory_files, "directory-files");
869 defsymbol (&Qfile_name_completion, "file-name-completion");
870 defsymbol (&Qfile_name_all_completions, "file-name-all-completions");
871 defsymbol (&Qfile_attributes, "file-attributes");
873 DEFSUBR (Fdirectory_files);
874 DEFSUBR (Ffile_name_completion);
875 DEFSUBR (Ffile_name_all_completions);
877 DEFSUBR (Fuser_name_completion);
878 DEFSUBR (Fuser_name_completion_1);
879 DEFSUBR (Fuser_name_all_completions);
881 DEFSUBR (Ffile_attributes);
887 DEFVAR_LISP ("completion-ignored-extensions", &Vcompletion_ignored_extensions /*
888 *Completion ignores filenames ending in any string in this list.
889 This variable does not affect lists of possible completions,
890 but does affect the commands that actually do completions.
891 It is used by the functions `file-name-completion' and
892 `file-name-all-completions'.
894 Vcompletion_ignored_extensions = Qnil;