1 /* Lisp functions for making directory listings.
2 Copyright (C) 1985, 1986, 1993, 1994, 1999 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>
40 /* The d_nameln member of a struct dirent includes the '\0' character
41 on some systems, but not on others. What's worse, you can't tell
42 at compile-time which one it will be, since it really depends on
43 the sort of system providing the filesystem you're reading from,
44 not the system you are running on. Paul Eggert
45 <eggert@bi.twinsun.com> says this occurs when Emacs is running on a
46 SunOS 4.1.2 host, reading a directory that is remote-mounted from a
47 Solaris 2.1 host and is in a native Solaris 2.1 filesystem.
49 Since applying strlen to the name always works, we'll just do that. */
50 #define NAMLEN(p) strlen (p->d_name)
52 #ifdef SYSV_SYSTEM_DIR
55 #define DIRENTRY struct dirent
57 #else /* not SYSV_SYSTEM_DIR */
59 #ifdef NONSYSTEM_DIR_LIBRARY
61 #else /* not NONSYSTEM_DIR_LIBRARY */
67 #endif /* not NONSYSTEM_DIR_LIBRARY */
72 #define DIRENTRY struct direct
74 extern DIR *opendir ();
75 extern struct direct
*readdir ();
77 #endif /* not MSDOS */
78 #endif /* not SYSV_SYSTEM_DIR */
81 #define DIRENTRY_NONEMPTY(p) ((p)->d_name[0] != 0)
83 #define DIRENTRY_NONEMPTY(p) ((p)->d_ino)
93 /* Returns a search buffer, with a fastmap allocated and ready to go. */
94 extern struct re_pattern_buffer
*compile_pattern ();
96 /* From filemode.c. Can't go in Lisp.h because of `stat'. */
97 extern void filemodestring
P_ ((struct stat
*, char *));
99 #define min(a, b) ((a) < (b) ? (a) : (b))
101 /* if system does not have symbolic links, it does not have lstat.
102 In that case, use ordinary stat instead. */
108 extern int completion_ignore_case
;
109 extern Lisp_Object Vcompletion_regexp_list
;
110 extern Lisp_Object Vfile_name_coding_system
, Vdefault_file_name_coding_system
;
112 Lisp_Object Vcompletion_ignored_extensions
;
113 Lisp_Object Qcompletion_ignore_case
;
114 Lisp_Object Qdirectory_files
;
115 Lisp_Object Qdirectory_files_and_attributes
;
116 Lisp_Object Qfile_name_completion
;
117 Lisp_Object Qfile_name_all_completions
;
118 Lisp_Object Qfile_attributes
;
119 Lisp_Object Qfile_attributes_lessp
;
123 directory_files_internal_unwind (dh
)
126 DIR *d
= (DIR *) ((XINT (XCAR (dh
)) << 16) + XINT (XCDR (dh
)));
131 /* Function shared by Fdirectory_files and Fdirectory_files_and_attributes.
132 When ATTRS is zero, return a list of directory filenames; when
133 non-zero, return a list of directory filenames and their attributes. */
135 directory_files_internal (directory
, full
, match
, nosort
, attrs
)
136 Lisp_Object directory
, full
, match
, nosort
;
141 Lisp_Object list
, name
, dirfilename
;
142 Lisp_Object encoded_directory
;
144 struct re_pattern_buffer
*bufp
= NULL
;
146 int count
= specpdl_ptr
- specpdl
;
147 struct gcpro gcpro1
, gcpro2
;
149 /* Because of file name handlers, these functions might call
150 Ffuncall, and cause a GC. */
152 directory
= Fexpand_file_name (directory
, Qnil
);
154 GCPRO2 (match
, directory
);
155 dirfilename
= Fdirectory_file_name (directory
);
160 CHECK_STRING (match
, 3);
162 /* MATCH might be a flawed regular expression. Rather than
163 catching and signaling our own errors, we just call
164 compile_pattern to do the work for us. */
165 /* Pass 1 for the MULTIBYTE arg
166 because we do make multibyte strings if the contents warrant. */
168 bufp
= compile_pattern (match
, 0,
169 buffer_defaults
.downcase_table
, 0, 1);
171 bufp
= compile_pattern (match
, 0, Qnil
, 0, 1);
175 dirfilename
= ENCODE_FILE (dirfilename
);
177 encoded_directory
= ENCODE_FILE (directory
);
179 /* Now *bufp is the compiled form of MATCH; don't call anything
180 which might compile a new regexp until we're done with the loop! */
182 /* Do this opendir after anything which might signal an error; if
183 an error is signaled while the directory stream is open, we
184 have to make sure it gets closed, and setting up an
185 unwind_protect to do so would be a pain. */
186 d
= opendir (XSTRING (dirfilename
)->data
);
188 report_file_error ("Opening directory", Fcons (directory
, Qnil
));
190 /* Unfortunately, we can now invoke expand-file-name and
191 file-attributes on filenames, both of which can throw, so we must
192 do a proper unwind-protect. */
193 record_unwind_protect (directory_files_internal_unwind
,
194 Fcons (make_number (((unsigned long) d
) >> 16),
195 make_number (((unsigned long) d
) & 0xffff)));
198 dirnamelen
= STRING_BYTES (XSTRING (directory
));
199 re_match_object
= Qt
;
201 /* Decide whether we need to add a directory separator. */
204 || !IS_ANY_SEP (XSTRING (directory
)->data
[dirnamelen
- 1]))
208 GCPRO2 (encoded_directory
, list
);
210 /* Loop reading blocks */
213 DIRENTRY
*dp
= readdir (d
);
216 if (DIRENTRY_NONEMPTY (dp
))
222 name
= DECODE_FILE (make_string (dp
->d_name
, len
));
223 len
= STRING_BYTES (XSTRING (name
));
225 /* Now that we have unwind_protect in place, we might as well
226 allow matching to be interrupted. */
231 || (0 <= re_search (bufp
, XSTRING (name
)->data
, len
, 0, len
, 0)))
240 Lisp_Object finalname
;
245 int afterdirindex
= dirnamelen
;
246 int total
= len
+ dirnamelen
;
248 Lisp_Object fullname
;
250 fullname
= make_uninit_multibyte_string (total
+ needsep
,
252 bcopy (XSTRING (directory
)->data
, XSTRING (fullname
)->data
,
255 XSTRING (fullname
)->data
[afterdirindex
++] = DIRECTORY_SEP
;
256 bcopy (XSTRING (name
)->data
,
257 XSTRING (fullname
)->data
+ afterdirindex
, len
);
258 nchars
= chars_in_text (XSTRING (fullname
)->data
,
259 afterdirindex
+ len
);
260 XSTRING (fullname
)->size
= nchars
;
261 if (nchars
== STRING_BYTES (XSTRING (fullname
)))
262 SET_STRING_BYTES (XSTRING (fullname
), -1);
263 finalname
= fullname
;
268 /* Construct an expanded filename for the directory entry.
269 Use the decoded names for input to Ffile_attributes. */
270 Lisp_Object decoded_fullname
;
271 Lisp_Object fileattrs
;
273 decoded_fullname
= Fexpand_file_name (name
, directory
);
274 fileattrs
= Ffile_attributes (decoded_fullname
);
276 list
= Fcons (Fcons (finalname
, fileattrs
), list
);
280 list
= Fcons (finalname
, list
);
288 /* Discard the unwind protect. */
289 specpdl_ptr
= specpdl
+ count
;
295 return Fsort (Fnreverse (list
), Qfile_attributes_lessp
);
297 return Fsort (Fnreverse (list
), Qstring_lessp
);
301 DEFUN ("directory-files", Fdirectory_files
, Sdirectory_files
, 1, 4, 0,
302 "Return a list of names of files in DIRECTORY.\n\
303 There are three optional arguments:\n\
304 If FULL is non-nil, return absolute file names. Otherwise return names\n\
305 that are relative to the specified directory.\n\
306 If MATCH is non-nil, mention only file names that match the regexp MATCH.\n\
307 If NOSORT is non-nil, the list is not sorted--its order is unpredictable.\n\
308 NOSORT is useful if you plan to sort the result yourself.")
309 (directory
, full
, match
, nosort
)
310 Lisp_Object directory
, full
, match
, nosort
;
314 /* If the file name has special constructs in it,
315 call the corresponding file handler. */
316 handler
= Ffind_file_name_handler (directory
, Qdirectory_files
);
322 args
[1] = Qdirectory_files
;
327 return Ffuncall (6, args
);
330 return directory_files_internal (directory
, full
, match
, nosort
, 0);
333 DEFUN ("directory-files-and-attributes", Fdirectory_files_and_attributes
, Sdirectory_files_and_attributes
, 1, 4, 0,
334 "Return a list of names of files and their attributes in DIRECTORY.\n\
335 There are three optional arguments:\n\
336 If FULL is non-nil, return absolute file names. Otherwise return names\n\
337 that are relative to the specified directory.\n\
338 If MATCH is non-nil, mention only file names that match the regexp MATCH.\n\
339 If NOSORT is non-nil, the list is not sorted--its order is unpredictable.\n\
340 NOSORT is useful if you plan to sort the result yourself.")
341 (directory
, full
, match
, nosort
)
342 Lisp_Object directory
, full
, match
, nosort
;
346 /* If the file name has special constructs in it,
347 call the corresponding file handler. */
348 handler
= Ffind_file_name_handler (directory
, Qdirectory_files_and_attributes
);
354 args
[1] = Qdirectory_files_and_attributes
;
359 return Ffuncall (6, args
);
362 return directory_files_internal (directory
, full
, match
, nosort
, 1);
366 Lisp_Object
file_name_completion ();
368 DEFUN ("file-name-completion", Ffile_name_completion
, Sfile_name_completion
,
370 "Complete file name FILE in directory DIRECTORY.\n\
371 Returns the longest string\n\
372 common to all file names in DIRECTORY that start with FILE.\n\
373 If there is only one and FILE matches it exactly, returns t.\n\
374 Returns nil if DIR contains no name starting with FILE.")
376 Lisp_Object file
, directory
;
380 /* If the directory name has special constructs in it,
381 call the corresponding file handler. */
382 handler
= Ffind_file_name_handler (directory
, Qfile_name_completion
);
384 return call3 (handler
, Qfile_name_completion
, file
, directory
);
386 /* If the file name has special constructs in it,
387 call the corresponding file handler. */
388 handler
= Ffind_file_name_handler (file
, Qfile_name_completion
);
390 return call3 (handler
, Qfile_name_completion
, file
, directory
);
392 return file_name_completion (file
, directory
, 0, 0);
395 DEFUN ("file-name-all-completions", Ffile_name_all_completions
,
396 Sfile_name_all_completions
, 2, 2, 0,
397 "Return a list of all completions of file name FILE in directory DIRECTORY.\n\
398 These are all file names in directory DIRECTORY which begin with FILE.")
400 Lisp_Object file
, directory
;
404 /* If the directory name has special constructs in it,
405 call the corresponding file handler. */
406 handler
= Ffind_file_name_handler (directory
, Qfile_name_all_completions
);
408 return call3 (handler
, Qfile_name_all_completions
, file
, directory
);
410 /* If the file name has special constructs in it,
411 call the corresponding file handler. */
412 handler
= Ffind_file_name_handler (file
, Qfile_name_all_completions
);
414 return call3 (handler
, Qfile_name_all_completions
, file
, directory
);
416 return file_name_completion (file
, directory
, 1, 0);
419 static int file_name_completion_stat ();
422 file_name_completion (file
, dirname
, all_flag
, ver_flag
)
423 Lisp_Object file
, dirname
;
424 int all_flag
, ver_flag
;
428 int bestmatchsize
= 0, skip
;
429 register int compare
, matchsize
;
430 unsigned char *p1
, *p2
;
432 Lisp_Object bestmatch
, tem
, elt
, name
;
433 Lisp_Object encoded_file
;
434 Lisp_Object encoded_dir
;
438 int count
= specpdl_ptr
- specpdl
;
439 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
, gcpro5
;
444 extern DIRENTRY
* readdirver ();
446 DIRENTRY
*((* readfunc
) ());
448 /* Filename completion on VMS ignores case, since VMS filesys does. */
449 specbind (Qcompletion_ignore_case
, Qt
);
453 readfunc
= readdirver
;
454 file
= Fupcase (file
);
456 CHECK_STRING (file
, 0);
459 #ifdef FILE_SYSTEM_CASE
460 file
= FILE_SYSTEM_CASE (file
);
463 encoded_file
= encoded_dir
= Qnil
;
464 GCPRO5 (file
, dirname
, bestmatch
, encoded_file
, encoded_dir
);
465 dirname
= Fexpand_file_name (dirname
, Qnil
);
467 /* Do completion on the encoded file name
468 because the other names in the directory are (we presume)
469 encoded likewise. We decode the completed string at the end. */
470 encoded_file
= ENCODE_FILE (file
);
472 encoded_dir
= ENCODE_FILE (dirname
);
474 /* With passcount = 0, ignore files that end in an ignored extension.
475 If nothing found then try again with passcount = 1, don't ignore them.
476 If looking for all completions, start with passcount = 1,
477 so always take even the ignored ones.
479 ** It would not actually be helpful to the user to ignore any possible
480 completions when making a list of them.** */
482 for (passcount
= !!all_flag
; NILP (bestmatch
) && passcount
< 2; passcount
++)
484 d
= opendir (XSTRING (Fdirectory_file_name (encoded_dir
))->data
);
486 report_file_error ("Opening directory", Fcons (dirname
, Qnil
));
488 /* Loop reading blocks */
489 /* (att3b compiler bug requires do a null comparison this way) */
496 dp
= (*readfunc
) (d
);
504 if (!NILP (Vquit_flag
) && NILP (Vinhibit_quit
))
506 if (! DIRENTRY_NONEMPTY (dp
)
507 || len
< XSTRING (encoded_file
)->size
508 || 0 <= scmp (dp
->d_name
, XSTRING (encoded_file
)->data
,
509 XSTRING (encoded_file
)->size
))
512 if (file_name_completion_stat (encoded_dir
, dp
, &st
) < 0)
515 directoryp
= ((st
.st_mode
& S_IFMT
) == S_IFDIR
);
519 #ifndef TRIVIAL_DIRECTORY_ENTRY
520 #define TRIVIAL_DIRECTORY_ENTRY(n) (!strcmp (n, ".") || !strcmp (n, ".."))
522 /* "." and ".." are never interesting as completions, but are
523 actually in the way in a directory contains only one file. */
524 if (!passcount
&& TRIVIAL_DIRECTORY_ENTRY (dp
->d_name
))
529 /* Compare extensions-to-be-ignored against end of this file name */
530 /* if name is not an exact match against specified string */
531 if (!passcount
&& len
> XSTRING (encoded_file
)->size
)
532 /* and exit this for loop if a match is found */
533 for (tem
= Vcompletion_ignored_extensions
;
534 CONSP (tem
); tem
= XCDR (tem
))
537 if (!STRINGP (elt
)) continue;
538 skip
= len
- XSTRING (elt
)->size
;
539 if (skip
< 0) continue;
541 if (0 <= scmp (dp
->d_name
+ skip
,
543 XSTRING (elt
)->size
))
549 /* If an ignored-extensions match was found,
550 don't process this name as a completion. */
551 if (!passcount
&& CONSP (tem
))
558 XSETFASTINT (zero
, 0);
560 /* Ignore this element if it fails to match all the regexps. */
561 for (regexps
= Vcompletion_regexp_list
; CONSP (regexps
);
562 regexps
= XCDR (regexps
))
564 tem
= Fstring_match (XCAR (regexps
), elt
, zero
);
572 /* Update computation of how much all possible completions match */
576 if (all_flag
|| NILP (bestmatch
))
578 /* This is a possible completion */
581 /* This completion is a directory; make it end with '/' */
582 name
= Ffile_name_as_directory (make_string (dp
->d_name
, len
));
585 name
= make_string (dp
->d_name
, len
);
588 name
= DECODE_FILE (name
);
589 bestmatch
= Fcons (name
, bestmatch
);
594 bestmatchsize
= XSTRING (name
)->size
;
599 compare
= min (bestmatchsize
, len
);
600 p1
= XSTRING (bestmatch
)->data
;
601 p2
= (unsigned char *) dp
->d_name
;
602 matchsize
= scmp(p1
, p2
, compare
);
605 if (completion_ignore_case
)
607 /* If this is an exact match except for case,
608 use it as the best match rather than one that is not
609 an exact match. This way, we get the case pattern
610 of the actual match. */
611 /* This tests that the current file is an exact match
612 but BESTMATCH is not (it is too long). */
613 if ((matchsize
== len
614 && matchsize
+ !!directoryp
615 < XSTRING (bestmatch
)->size
)
617 /* If there is no exact match ignoring case,
618 prefer a match that does not change the case
620 /* If there is more than one exact match aside from
621 case, and one of them is exact including case,
623 /* This == checks that, of current file and BESTMATCH,
624 either both or neither are exact. */
627 (matchsize
+ !!directoryp
628 == XSTRING (bestmatch
)->size
))
629 && !bcmp (p2
, XSTRING (encoded_file
)->data
, XSTRING (encoded_file
)->size
)
630 && bcmp (p1
, XSTRING (encoded_file
)->data
, XSTRING (encoded_file
)->size
)))
632 bestmatch
= make_string (dp
->d_name
, len
);
634 bestmatch
= Ffile_name_as_directory (bestmatch
);
638 /* If this dirname all matches, see if implicit following
641 && compare
== matchsize
642 && bestmatchsize
> matchsize
643 && IS_ANY_SEP (p1
[matchsize
]))
645 bestmatchsize
= matchsize
;
652 bestmatch
= unbind_to (count
, bestmatch
);
654 if (all_flag
|| NILP (bestmatch
))
656 if (STRINGP (bestmatch
))
657 bestmatch
= DECODE_FILE (bestmatch
);
660 if (matchcount
== 1 && bestmatchsize
== XSTRING (file
)->size
)
662 bestmatch
= Fsubstring (bestmatch
, make_number (0),
663 make_number (bestmatchsize
));
664 /* Now that we got the right initial segment of BESTMATCH,
665 decode it from the coding system in use. */
666 bestmatch
= DECODE_FILE (bestmatch
);
672 return Fsignal (Qquit
, Qnil
);
676 file_name_completion_stat (dirname
, dp
, st_addr
)
679 struct stat
*st_addr
;
681 int len
= NAMLEN (dp
);
682 int pos
= XSTRING (dirname
)->size
;
684 char *fullname
= (char *) alloca (len
+ pos
+ 2);
688 /* Some fields of struct stat are *very* expensive to compute on MS-DOS,
689 but aren't required here. Avoid computing the following fields:
690 st_inode, st_size and st_nlink for directories, and the execute bits
691 in st_mode for non-directory files with non-standard extensions. */
693 unsigned short save_djstat_flags
= _djstat_flags
;
695 _djstat_flags
= _STAT_INODE
| _STAT_EXEC_MAGIC
| _STAT_DIRSIZE
;
696 #endif /* __DJGPP__ > 1 */
699 bcopy (XSTRING (dirname
)->data
, fullname
, pos
);
701 if (!IS_DIRECTORY_SEP (fullname
[pos
- 1]))
702 fullname
[pos
++] = DIRECTORY_SEP
;
705 bcopy (dp
->d_name
, fullname
+ pos
, len
);
706 fullname
[pos
+ len
] = 0;
709 /* We want to return success if a link points to a nonexistent file,
710 but we want to return the status for what the link points to,
711 in case it is a directory. */
712 value
= lstat (fullname
, st_addr
);
713 stat (fullname
, st_addr
);
716 value
= stat (fullname
, st_addr
);
719 _djstat_flags
= save_djstat_flags
;
720 #endif /* __DJGPP__ > 1 */
728 DEFUN ("file-name-all-versions", Ffile_name_all_versions
,
729 Sfile_name_all_versions
, 2, 2, 0,
730 "Return a list of all versions of file name FILE in directory DIRECTORY.")
732 Lisp_Object file
, directory
;
734 return file_name_completion (file
, directory
, 1, 1);
737 DEFUN ("file-version-limit", Ffile_version_limit
, Sfile_version_limit
, 1, 1, 0,
738 "Return the maximum number of versions allowed for FILE.\n\
739 Returns nil if the file cannot be opened or if there is no version limit.")
741 Lisp_Object filename
;
746 struct XABFHC xabfhc
;
749 filename
= Fexpand_file_name (filename
, Qnil
);
751 xabfhc
= cc$rms_xabfhc
;
752 fab
.fab$l_fna
= XSTRING (filename
)->data
;
753 fab
.fab$b_fns
= strlen (fab
.fab$l_fna
);
754 fab
.fab$l_xab
= (char *) &xabfhc
;
755 status
= sys$
open (&fab
, 0, 0);
756 if (status
!= RMS$_NORMAL
) /* Probably non-existent file */
758 sys$
close (&fab
, 0, 0);
759 if (xabfhc
.xab$w_verlimit
== 32767)
760 return Qnil
; /* No version limit */
762 return make_number (xabfhc
.xab$w_verlimit
);
771 return Fcons (make_number (time
>> 16),
772 Fcons (make_number (time
& 0177777), Qnil
));
775 DEFUN ("file-attributes", Ffile_attributes
, Sfile_attributes
, 1, 1, 0,
776 "Return a list of attributes of file FILENAME.\n\
777 Value is nil if specified file cannot be opened.\n\
778 Otherwise, list elements are:\n\
779 0. t for directory, string (name linked to) for symbolic link, or nil.\n\
780 1. Number of links to file.\n\
783 4. Last access time, as a list of two integers.\n\
784 First integer has high-order 16 bits of time, second has low 16 bits.\n\
785 5. Last modification time, likewise.\n\
786 6. Last status change time, likewise.\n\
788 This is a floating point number if the size is too large for an integer.\n\
789 8. File modes, as a string of ten letters or dashes as in ls -l.\n\
790 9. t iff file's gid would change if file were deleted and recreated.\n\
791 10. inode number. If inode number is larger than the Emacs integer,\n\
792 this is a cons cell containing two integers: first the high part,\n\
793 then the low 16 bits.\n\
794 11. Device number.\n\
796 If file does not exist, returns nil.")
798 Lisp_Object filename
;
800 Lisp_Object values
[12];
808 filename
= Fexpand_file_name (filename
, Qnil
);
810 /* If the file name has special constructs in it,
811 call the corresponding file handler. */
812 handler
= Ffind_file_name_handler (filename
, Qfile_attributes
);
814 return call2 (handler
, Qfile_attributes
, filename
);
816 encoded
= ENCODE_FILE (filename
);
818 if (lstat (XSTRING (encoded
)->data
, &s
) < 0)
821 switch (s
.st_mode
& S_IFMT
)
824 values
[0] = Qnil
; break;
826 values
[0] = Qt
; break;
829 values
[0] = Ffile_symlink_p (filename
); break;
832 values
[1] = make_number (s
.st_nlink
);
833 values
[2] = make_number (s
.st_uid
);
834 values
[3] = make_number (s
.st_gid
);
835 values
[4] = make_time (s
.st_atime
);
836 values
[5] = make_time (s
.st_mtime
);
837 values
[6] = make_time (s
.st_ctime
);
838 values
[7] = make_number (s
.st_size
);
839 /* If the size is out of range for an integer, return a float. */
840 if (XINT (values
[7]) != s
.st_size
)
841 values
[7] = make_float ((double)s
.st_size
);
842 filemodestring (&s
, modes
);
843 values
[8] = make_string (modes
, 10);
844 #ifdef BSD4_3 /* Gross kludge to avoid lack of "#if defined(...)" in VMS */
845 #define BSD4_2 /* A new meaning to the term `backwards compatibility' */
847 #ifdef BSD4_2 /* file gid will be dir gid */
848 dirname
= Ffile_name_directory (filename
);
849 if (! NILP (dirname
))
850 encoded
= ENCODE_FILE (dirname
);
851 if (! NILP (dirname
) && stat (XSTRING (encoded
)->data
, &sdir
) == 0)
852 values
[9] = (sdir
.st_gid
!= s
.st_gid
) ? Qt
: Qnil
;
853 else /* if we can't tell, assume worst */
855 #else /* file gid will be egid */
856 values
[9] = (s
.st_gid
!= getegid ()) ? Qt
: Qnil
;
857 #endif /* BSD4_2 (or BSD4_3) */
859 #undef BSD4_2 /* ok, you can look again without throwing up */
861 /* Cast -1 to avoid warning if int is not as wide as VALBITS. */
862 if (s
.st_ino
& (((EMACS_INT
) (-1)) << VALBITS
))
863 /* To allow inode numbers larger than VALBITS, separate the bottom
865 values
[10] = Fcons (make_number (s
.st_ino
>> 16),
866 make_number (s
.st_ino
& 0xffff));
868 /* But keep the most common cases as integers. */
869 values
[10] = make_number (s
.st_ino
);
871 /* Likewise for device. */
872 if (s
.st_dev
& (((EMACS_INT
) (-1)) << VALBITS
))
873 values
[11] = Fcons (make_number (s
.st_dev
>> 16),
874 make_number (s
.st_dev
& 0xffff));
876 values
[11] = make_number (s
.st_dev
);
878 return Flist (sizeof(values
) / sizeof(values
[0]), values
);
881 DEFUN ("file-attributes-lessp", Ffile_attributes_lessp
, Sfile_attributes_lessp
, 2, 2, 0,
882 "Return t if first arg file attributes list is less than second.\n\
883 Comparison is in lexicographic order and case is significant.")
887 return Fstring_lessp (Fcar (f1
), Fcar (f2
));
893 Qdirectory_files
= intern ("directory-files");
894 Qdirectory_files_and_attributes
= intern ("directory-files-and-attributes");
895 Qfile_name_completion
= intern ("file-name-completion");
896 Qfile_name_all_completions
= intern ("file-name-all-completions");
897 Qfile_attributes
= intern ("file-attributes");
898 Qfile_attributes_lessp
= intern ("file-attributes-lessp");
900 staticpro (&Qdirectory_files
);
901 staticpro (&Qdirectory_files_and_attributes
);
902 staticpro (&Qfile_name_completion
);
903 staticpro (&Qfile_name_all_completions
);
904 staticpro (&Qfile_attributes
);
905 staticpro (&Qfile_attributes_lessp
);
907 defsubr (&Sdirectory_files
);
908 defsubr (&Sdirectory_files_and_attributes
);
909 defsubr (&Sfile_name_completion
);
911 defsubr (&Sfile_name_all_versions
);
912 defsubr (&Sfile_version_limit
);
914 defsubr (&Sfile_name_all_completions
);
915 defsubr (&Sfile_attributes
);
916 defsubr (&Sfile_attributes_lessp
);
919 Qcompletion_ignore_case
= intern ("completion-ignore-case");
920 staticpro (&Qcompletion_ignore_case
);
923 DEFVAR_LISP ("completion-ignored-extensions", &Vcompletion_ignored_extensions
,
924 "*Completion ignores filenames ending in any string in this list.\n\
925 This variable does not affect lists of possible completions,\n\
926 but does affect the commands that actually do completions.");
927 Vcompletion_ignored_extensions
= Qnil
;