Replace bcopy, bzero, bcmp by memcpy, memmove, memset, memcmp
[bpt/emacs.git] / src / dired.c
CommitLineData
14d55bce 1/* Lisp functions for making directory listings.
0b5538bd 2 Copyright (C) 1985, 1986, 1993, 1994, 1999, 2000, 2001, 2002, 2003,
114f9c96 3 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
14d55bce
RS
4
5This file is part of GNU Emacs.
6
9ec0b715 7GNU Emacs is free software: you can redistribute it and/or modify
14d55bce 8it under the terms of the GNU General Public License as published by
9ec0b715
GM
9the Free Software Foundation, either version 3 of the License, or
10(at your option) any later version.
14d55bce
RS
11
12GNU Emacs is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
9ec0b715 18along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
14d55bce
RS
19
20
3964b9a7
RS
21#include <config.h>
22
14d55bce
RS
23#include <stdio.h>
24#include <sys/types.h>
25#include <sys/stat.h>
d7306fe6 26#include <setjmp.h>
14d55bce 27
5b9c0a1d 28#ifdef HAVE_PWD_H
6b61353c 29#include <pwd.h>
5b9c0a1d 30#endif
6b61353c 31#include <grp.h>
6b61353c 32
7cc9f69f 33#include <errno.h>
68c45bf0 34
dfcf069d
AS
35#ifdef HAVE_UNISTD_H
36#include <unistd.h>
37#endif
38
d6717cdb
JB
39/* The d_nameln member of a struct dirent includes the '\0' character
40 on some systems, but not on others. What's worse, you can't tell
41 at compile-time which one it will be, since it really depends on
42 the sort of system providing the filesystem you're reading from,
43 not the system you are running on. Paul Eggert
44 <eggert@bi.twinsun.com> says this occurs when Emacs is running on a
45 SunOS 4.1.2 host, reading a directory that is remote-mounted from a
46 Solaris 2.1 host and is in a native Solaris 2.1 filesystem.
47
48 Since applying strlen to the name always works, we'll just do that. */
49#define NAMLEN(p) strlen (p->d_name)
50
14d55bce
RS
51#ifdef SYSV_SYSTEM_DIR
52
53#include <dirent.h>
54#define DIRENTRY struct dirent
14d55bce 55
128ecc89 56#else /* not SYSV_SYSTEM_DIR */
14d55bce 57
128ecc89
RS
58#ifdef MSDOS
59#include <dirent.h>
60#else
14d55bce 61#include <sys/dir.h>
128ecc89 62#endif
14d55bce 63
851cab13
DL
64#include <sys/stat.h>
65
128ecc89 66#ifndef MSDOS
14d55bce 67#define DIRENTRY struct direct
14d55bce
RS
68
69extern DIR *opendir ();
70extern struct direct *readdir ();
71
128ecc89
RS
72#endif /* not MSDOS */
73#endif /* not SYSV_SYSTEM_DIR */
74
8f7f8c65
EZ
75/* Some versions of Cygwin don't have d_ino in `struct dirent'. */
76#if defined(MSDOS) || defined(__CYGWIN__)
128ecc89
RS
77#define DIRENTRY_NONEMPTY(p) ((p)->d_name[0] != 0)
78#else
79#define DIRENTRY_NONEMPTY(p) ((p)->d_ino)
14d55bce
RS
80#endif
81
14d55bce 82#include "lisp.h"
fa8459a3 83#include "systime.h"
14d55bce
RS
84#include "buffer.h"
85#include "commands.h"
d2f6dae8 86#include "character.h"
bd33479f
KH
87#include "charset.h"
88#include "coding.h"
14d55bce 89#include "regex.h"
8c8a7c58 90#include "blockinput.h"
14d55bce 91
e50c66d3 92/* Returns a search buffer, with a fastmap allocated and ready to go. */
dd4c5104 93extern struct re_pattern_buffer *compile_pattern (Lisp_Object, struct re_registers *, Lisp_Object, int, int);
c7e466e1 94
851cab13 95/* From filemode.c. Can't go in Lisp.h because of `stat'. */
f57e2426 96extern void filemodestring (struct stat *, char *);
851cab13 97
14d55bce
RS
98/* if system does not have symbolic links, it does not have lstat.
99 In that case, use ordinary stat instead. */
100
101#ifndef S_IFLNK
102#define lstat stat
103#endif
104
97e98a56 105extern int completion_ignore_case;
ecd3f8b2 106extern Lisp_Object Qcompletion_ignore_case;
f676868d 107extern Lisp_Object Vcompletion_regexp_list;
65156807 108extern Lisp_Object Vw32_get_true_file_attributes;
ccbcf979 109
14d55bce 110Lisp_Object Vcompletion_ignored_extensions;
32f4334d 111Lisp_Object Qdirectory_files;
4424b255 112Lisp_Object Qdirectory_files_and_attributes;
32f4334d
RS
113Lisp_Object Qfile_name_completion;
114Lisp_Object Qfile_name_all_completions;
434e6714 115Lisp_Object Qfile_attributes;
4424b255 116Lisp_Object Qfile_attributes_lessp;
b3f04ced 117
f57e2426 118static int scmp (unsigned char *, unsigned char *, int);
14d55bce 119\f
65156807
EZ
120#ifdef WINDOWSNT
121Lisp_Object
122directory_files_internal_w32_unwind (Lisp_Object arg)
123{
124 Vw32_get_true_file_attributes = arg;
125 return Qnil;
126}
127#endif
2488aba5
AI
128
129Lisp_Object
971de7fb 130directory_files_internal_unwind (Lisp_Object dh)
2488aba5 131{
9d291bdf 132 DIR *d = (DIR *) XSAVE_VALUE (dh)->pointer;
d15b573e 133 BLOCK_INPUT;
2488aba5 134 closedir (d);
d15b573e 135 UNBLOCK_INPUT;
2488aba5
AI
136 return Qnil;
137}
138
177c0ea7 139/* Function shared by Fdirectory_files and Fdirectory_files_and_attributes.
4424b255 140 When ATTRS is zero, return a list of directory filenames; when
6b61353c
KH
141 non-zero, return a list of directory filenames and their attributes.
142 In the latter case, ID_FORMAT is passed to Ffile_attributes. */
f69f9da1 143
4424b255 144Lisp_Object
971de7fb 145directory_files_internal (Lisp_Object directory, Lisp_Object full, Lisp_Object match, Lisp_Object nosort, int attrs, Lisp_Object id_format)
14d55bce
RS
146{
147 DIR *d;
388ac098
GM
148 int directory_nbytes;
149 Lisp_Object list, dirfilename, encoded_directory;
6bbd7a29 150 struct re_pattern_buffer *bufp = NULL;
96d64004 151 int needsep = 0;
aed13378 152 int count = SPECPDL_INDEX ();
388ac098 153 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
8e42f043 154 DIRENTRY *dp;
65156807
EZ
155#ifdef WINDOWSNT
156 Lisp_Object w32_save = Qnil;
157#endif
32f4334d 158
96d64004 159 /* Because of file name handlers, these functions might call
6155fae1 160 Ffuncall, and cause a GC. */
388ac098
GM
161 list = encoded_directory = dirfilename = Qnil;
162 GCPRO5 (match, directory, list, dirfilename, encoded_directory);
96d64004 163 dirfilename = Fdirectory_file_name (directory);
6155fae1 164
265a9e55 165 if (!NILP (match))
14d55bce 166 {
b7826503 167 CHECK_STRING (match);
ebb9e16f
JB
168
169 /* MATCH might be a flawed regular expression. Rather than
8e6208c5 170 catching and signaling our own errors, we just call
ebb9e16f 171 compile_pattern to do the work for us. */
c872c6b2
RS
172 /* Pass 1 for the MULTIBYTE arg
173 because we do make multibyte strings if the contents warrant. */
1a9fbabe
EZ
174# ifdef WINDOWSNT
175 /* Windows users want case-insensitive wildcards. */
176 bufp = compile_pattern (match, 0,
177 buffer_defaults.case_canon_table, 0, 1);
178# else /* !WINDOWSNT */
3e937712 179 bufp = compile_pattern (match, 0, Qnil, 0, 1);
1a9fbabe 180# endif /* !WINDOWSNT */
14d55bce
RS
181 }
182
b3edfc9b 183 /* Note: ENCODE_FILE and DECODE_FILE can GC because they can run
388ac098
GM
184 run_pre_post_conversion_on_str which calls Lisp directly and
185 indirectly. */
6c8b4f07
SM
186 if (STRING_MULTIBYTE (dirfilename))
187 dirfilename = ENCODE_FILE (dirfilename);
188 encoded_directory = (STRING_MULTIBYTE (directory)
189 ? ENCODE_FILE (directory) : directory);
24c2a54f 190
e50c66d3 191 /* Now *bufp is the compiled form of MATCH; don't call anything
6155fae1
JB
192 which might compile a new regexp until we're done with the loop! */
193
d15b573e 194 BLOCK_INPUT;
d5db4077 195 d = opendir (SDATA (dirfilename));
d15b573e 196 UNBLOCK_INPUT;
388ac098 197 if (d == NULL)
23bd240f 198 report_file_error ("Opening directory", Fcons (directory, Qnil));
14d55bce 199
2488aba5
AI
200 /* Unfortunately, we can now invoke expand-file-name and
201 file-attributes on filenames, both of which can throw, so we must
202 do a proper unwind-protect. */
203 record_unwind_protect (directory_files_internal_unwind,
9d291bdf 204 make_save_value (d, 0));
2488aba5 205
65156807
EZ
206#ifdef WINDOWSNT
207 if (attrs)
208 {
209 extern Lisp_Object Qlocal;
210 extern int is_slow_fs (const char *);
211
212 /* Do this only once to avoid doing it (in w32.c:stat) for each
213 file in the directory, when we call Ffile_attributes below. */
214 record_unwind_protect (directory_files_internal_w32_unwind,
215 Vw32_get_true_file_attributes);
216 w32_save = Vw32_get_true_file_attributes;
217 if (EQ (Vw32_get_true_file_attributes, Qlocal))
218 {
65156807
EZ
219 /* w32.c:stat will notice these bindings and avoid calling
220 GetDriveType for each file. */
b6046155 221 if (is_slow_fs (SDATA (dirfilename)))
65156807
EZ
222 Vw32_get_true_file_attributes = Qnil;
223 else
224 Vw32_get_true_file_attributes = Qt;
225 }
226 }
227#endif
228
d5db4077 229 directory_nbytes = SBYTES (directory);
c81a9bdc 230 re_match_object = Qt;
14d55bce 231
96d64004 232 /* Decide whether we need to add a directory separator. */
388ac098 233 if (directory_nbytes == 0
d5db4077 234 || !IS_ANY_SEP (SREF (directory, directory_nbytes - 1)))
96d64004 235 needsep = 1;
96d64004 236
8e42f043 237 /* Loop reading blocks until EOF or error. */
f69f9da1 238 for (;;)
14d55bce 239 {
f69f9da1
GM
240 errno = 0;
241 dp = readdir (d);
242
9d291bdf 243 if (dp == NULL && (0
f69f9da1 244#ifdef EAGAIN
9d291bdf
SM
245 || errno == EAGAIN
246#endif
247#ifdef EINTR
248 || errno == EINTR
f69f9da1 249#endif
9d291bdf
SM
250 ))
251 { QUIT; continue; }
177c0ea7 252
f69f9da1
GM
253 if (dp == NULL)
254 break;
255
128ecc89 256 if (DIRENTRY_NONEMPTY (dp))
14d55bce 257 {
e23f810c 258 int len;
2488aba5 259 int wanted = 0;
388ac098
GM
260 Lisp_Object name, finalname;
261 struct gcpro gcpro1, gcpro2;
e23f810c
KH
262
263 len = NAMLEN (dp);
9ad4f3e5 264 name = finalname = make_unibyte_string (dp->d_name, len);
388ac098 265 GCPRO2 (finalname, name);
177c0ea7 266
6c8b4f07 267 /* Note: DECODE_FILE can GC; it should protect its argument,
388ac098
GM
268 though. */
269 name = DECODE_FILE (name);
d5db4077 270 len = SBYTES (name);
e23f810c 271
2488aba5
AI
272 /* Now that we have unwind_protect in place, we might as well
273 allow matching to be interrupted. */
274 immediate_quit = 1;
275 QUIT;
276
265a9e55 277 if (NILP (match)
d5db4077 278 || (0 <= re_search (bufp, SDATA (name), len, 0, len, 0)))
388ac098 279 wanted = 1;
2488aba5
AI
280
281 immediate_quit = 0;
282
283 if (wanted)
14d55bce 284 {
265a9e55 285 if (!NILP (full))
14d55bce 286 {
e23f810c 287 Lisp_Object fullname;
388ac098
GM
288 int nbytes = len + directory_nbytes + needsep;
289 int nchars;
5617588f 290
388ac098 291 fullname = make_uninit_multibyte_string (nbytes, nbytes);
72af86bd
AS
292 memcpy (SDATA (fullname), SDATA (directory),
293 directory_nbytes);
177c0ea7 294
5617588f 295 if (needsep)
d549c5db 296 SSET (fullname, directory_nbytes, DIRECTORY_SEP);
177c0ea7 297
72af86bd
AS
298 memcpy (SDATA (fullname) + directory_nbytes + needsep,
299 SDATA (name), len);
177c0ea7 300
d5db4077 301 nchars = chars_in_text (SDATA (fullname), nbytes);
388ac098
GM
302
303 /* Some bug somewhere. */
304 if (nchars > nbytes)
305 abort ();
177c0ea7 306
437fcd47 307 STRING_SET_CHARS (fullname, nchars);
388ac098 308 if (nchars == nbytes)
d5db4077 309 STRING_SET_UNIBYTE (fullname);
177c0ea7 310
4424b255
GV
311 finalname = fullname;
312 }
aab9c564
KH
313 else
314 finalname = name;
4424b255
GV
315
316 if (attrs)
317 {
318 /* Construct an expanded filename for the directory entry.
319 Use the decoded names for input to Ffile_attributes. */
388ac098
GM
320 Lisp_Object decoded_fullname, fileattrs;
321 struct gcpro gcpro1, gcpro2;
322
323 decoded_fullname = fileattrs = Qnil;
324 GCPRO2 (decoded_fullname, fileattrs);
4424b255 325
388ac098 326 /* Both Fexpand_file_name and Ffile_attributes can GC. */
4424b255 327 decoded_fullname = Fexpand_file_name (name, directory);
6b61353c 328 fileattrs = Ffile_attributes (decoded_fullname, id_format);
4424b255
GV
329
330 list = Fcons (Fcons (finalname, fileattrs), list);
388ac098 331 UNGCPRO;
4424b255
GV
332 }
333 else
388ac098 334 list = Fcons (finalname, list);
14d55bce 335 }
388ac098
GM
336
337 UNGCPRO;
14d55bce
RS
338 }
339 }
2488aba5 340
d15b573e 341 BLOCK_INPUT;
14d55bce 342 closedir (d);
d15b573e 343 UNBLOCK_INPUT;
65156807
EZ
344#ifdef WINDOWSNT
345 if (attrs)
346 Vw32_get_true_file_attributes = w32_save;
347#endif
2488aba5
AI
348
349 /* Discard the unwind protect. */
350 specpdl_ptr = specpdl + count;
351
388ac098
GM
352 if (NILP (nosort))
353 list = Fsort (Fnreverse (list),
354 attrs ? Qfile_attributes_lessp : Qstring_lessp);
177c0ea7 355
388ac098 356 RETURN_UNGCPRO (list);
14d55bce 357}
4424b255
GV
358
359
360DEFUN ("directory-files", Fdirectory_files, Sdirectory_files, 1, 4, 0,
335c5470
PJ
361 doc: /* Return a list of names of files in DIRECTORY.
362There are three optional arguments:
363If FULL is non-nil, return absolute file names. Otherwise return names
364 that are relative to the specified directory.
365If MATCH is non-nil, mention only file names that match the regexp MATCH.
366If NOSORT is non-nil, the list is not sorted--its order is unpredictable.
a489517b
JB
367 Otherwise, the list returned is sorted with `string-lessp'.
368 NOSORT is useful if you plan to sort the result yourself. */)
335c5470 369 (directory, full, match, nosort)
4424b255
GV
370 Lisp_Object directory, full, match, nosort;
371{
372 Lisp_Object handler;
4ece81a6 373 directory = Fexpand_file_name (directory, Qnil);
4424b255
GV
374
375 /* If the file name has special constructs in it,
376 call the corresponding file handler. */
377 handler = Ffind_file_name_handler (directory, Qdirectory_files);
378 if (!NILP (handler))
6b61353c
KH
379 return call5 (handler, Qdirectory_files, directory,
380 full, match, nosort);
4424b255 381
6b61353c 382 return directory_files_internal (directory, full, match, nosort, 0, Qnil);
4424b255
GV
383}
384
335c5470 385DEFUN ("directory-files-and-attributes", Fdirectory_files_and_attributes,
6b61353c 386 Sdirectory_files_and_attributes, 1, 5, 0,
335c5470 387 doc: /* Return a list of names of files and their attributes in DIRECTORY.
6b61353c 388There are four optional arguments:
335c5470
PJ
389If FULL is non-nil, return absolute file names. Otherwise return names
390 that are relative to the specified directory.
391If MATCH is non-nil, mention only file names that match the regexp MATCH.
392If NOSORT is non-nil, the list is not sorted--its order is unpredictable.
6b61353c
KH
393 NOSORT is useful if you plan to sort the result yourself.
394ID-FORMAT specifies the preferred format of attributes uid and gid, see
6c5665e9
EZ
395`file-attributes' for further documentation.
396On MS-Windows, performance depends on `w32-get-true-file-attributes',
397which see. */)
6b61353c
KH
398 (directory, full, match, nosort, id_format)
399 Lisp_Object directory, full, match, nosort, id_format;
4424b255
GV
400{
401 Lisp_Object handler;
4ece81a6 402 directory = Fexpand_file_name (directory, Qnil);
4424b255
GV
403
404 /* If the file name has special constructs in it,
405 call the corresponding file handler. */
406 handler = Ffind_file_name_handler (directory, Qdirectory_files_and_attributes);
407 if (!NILP (handler))
6b61353c
KH
408 return call6 (handler, Qdirectory_files_and_attributes,
409 directory, full, match, nosort, id_format);
4424b255 410
6b61353c 411 return directory_files_internal (directory, full, match, nosort, 1, id_format);
4424b255
GV
412}
413
14d55bce 414\f
971de7fb 415Lisp_Object file_name_completion (Lisp_Object file, Lisp_Object dirname, int all_flag, int ver_flag, Lisp_Object predicate);
14d55bce
RS
416
417DEFUN ("file-name-completion", Ffile_name_completion, Sfile_name_completion,
abfb1932 418 2, 3, 0,
335c5470
PJ
419 doc: /* Complete file name FILE in directory DIRECTORY.
420Returns the longest string
421common to all file names in DIRECTORY that start with FILE.
422If there is only one and FILE matches it exactly, returns t.
2f60660a 423Returns nil if DIRECTORY contains no name starting with FILE.
335c5470 424
b6ce54d6
RS
425If PREDICATE is non-nil, call PREDICATE with each possible
426completion (in absolute form) and ignore it if PREDICATE returns nil.
427
335c5470
PJ
428This function ignores some of the possible completions as
429determined by the variable `completion-ignored-extensions', which see. */)
abfb1932
RS
430 (file, directory, predicate)
431 Lisp_Object file, directory, predicate;
14d55bce 432{
32f4334d 433 Lisp_Object handler;
32f4334d 434
8436e231 435 /* If the directory name has special constructs in it,
32f4334d 436 call the corresponding file handler. */
23bd240f 437 handler = Ffind_file_name_handler (directory, Qfile_name_completion);
32f4334d 438 if (!NILP (handler))
abfb1932 439 return call4 (handler, Qfile_name_completion, file, directory, predicate);
32f4334d 440
8436e231
RS
441 /* If the file name has special constructs in it,
442 call the corresponding file handler. */
443 handler = Ffind_file_name_handler (file, Qfile_name_completion);
444 if (!NILP (handler))
abfb1932 445 return call4 (handler, Qfile_name_completion, file, directory, predicate);
8436e231 446
abfb1932 447 return file_name_completion (file, directory, 0, 0, predicate);
14d55bce
RS
448}
449
450DEFUN ("file-name-all-completions", Ffile_name_all_completions,
335c5470
PJ
451 Sfile_name_all_completions, 2, 2, 0,
452 doc: /* Return a list of all completions of file name FILE in directory DIRECTORY.
453These are all file names in directory DIRECTORY which begin with FILE. */)
454 (file, directory)
23bd240f 455 Lisp_Object file, directory;
14d55bce 456{
32f4334d
RS
457 Lisp_Object handler;
458
8436e231 459 /* If the directory name has special constructs in it,
32f4334d 460 call the corresponding file handler. */
23bd240f 461 handler = Ffind_file_name_handler (directory, Qfile_name_all_completions);
32f4334d 462 if (!NILP (handler))
23bd240f 463 return call3 (handler, Qfile_name_all_completions, file, directory);
32f4334d 464
8436e231
RS
465 /* If the file name has special constructs in it,
466 call the corresponding file handler. */
467 handler = Ffind_file_name_handler (file, Qfile_name_all_completions);
468 if (!NILP (handler))
23bd240f 469 return call3 (handler, Qfile_name_all_completions, file, directory);
8436e231 470
abfb1932 471 return file_name_completion (file, directory, 1, 0, Qnil);
14d55bce
RS
472}
473
438105ed 474static int file_name_completion_stat (Lisp_Object dirname, DIRENTRY *dp, struct stat *st_addr);
01bb4018 475Lisp_Object Qdefault_directory;
dfcf069d 476
14d55bce 477Lisp_Object
971de7fb 478file_name_completion (Lisp_Object file, Lisp_Object dirname, int all_flag, int ver_flag, Lisp_Object predicate)
14d55bce
RS
479{
480 DIR *d;
3271a8f5 481 int bestmatchsize = 0;
14d55bce 482 int matchcount = 0;
abfb1932
RS
483 /* If ALL_FLAG is 1, BESTMATCH is the list of all matches, decoded.
484 If ALL_FLAG is 0, BESTMATCH is either nil
485 or the best match so far, not decoded. */
14d55bce 486 Lisp_Object bestmatch, tem, elt, name;
24c2a54f
RS
487 Lisp_Object encoded_file;
488 Lisp_Object encoded_dir;
14d55bce
RS
489 struct stat st;
490 int directoryp;
3271a8f5
SM
491 /* If includeall is zero, exclude files in completion-ignored-extensions as
492 well as "." and "..". Until shown otherwise, assume we can't exclude
493 anything. */
494 int includeall = 1;
aed13378 495 int count = SPECPDL_INDEX ();
24c2a54f 496 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
3fcc88cc 497
6bbd7a29
GM
498 elt = Qnil;
499
b7826503 500 CHECK_STRING (file);
14d55bce 501
128ecc89
RS
502#ifdef FILE_SYSTEM_CASE
503 file = FILE_SYSTEM_CASE (file);
504#endif
14d55bce 505 bestmatch = Qnil;
24c2a54f
RS
506 encoded_file = encoded_dir = Qnil;
507 GCPRO5 (file, dirname, bestmatch, encoded_file, encoded_dir);
3fcc88cc 508 dirname = Fexpand_file_name (dirname, Qnil);
01bb4018 509 specbind (Qdefault_directory, dirname);
14d55bce 510
24c2a54f
RS
511 /* Do completion on the encoded file name
512 because the other names in the directory are (we presume)
513 encoded likewise. We decode the completed string at the end. */
2a54a229
SM
514 /* Actually, this is not quite true any more: we do most of the completion
515 work with decoded file names, but we still do some filtering based
516 on the encoded file name. */
6c8b4f07 517 encoded_file = STRING_MULTIBYTE (file) ? ENCODE_FILE (file) : file;
24c2a54f
RS
518
519 encoded_dir = ENCODE_FILE (dirname);
520
3271a8f5
SM
521 BLOCK_INPUT;
522 d = opendir (SDATA (Fdirectory_file_name (encoded_dir)));
523 UNBLOCK_INPUT;
524 if (!d)
525 report_file_error ("Opening directory", Fcons (dirname, Qnil));
14d55bce 526
3271a8f5
SM
527 record_unwind_protect (directory_files_internal_unwind,
528 make_save_value (d, 0));
14d55bce 529
3271a8f5
SM
530 /* Loop reading blocks */
531 /* (att3b compiler bug requires do a null comparison this way) */
532 while (1)
14d55bce 533 {
3271a8f5
SM
534 DIRENTRY *dp;
535 int len;
536 int canexclude = 0;
14d55bce 537
3271a8f5
SM
538 errno = 0;
539 dp = readdir (d);
540 if (dp == NULL && (0
9d291bdf 541# ifdef EAGAIN
3271a8f5 542 || errno == EAGAIN
9d291bdf
SM
543# endif
544# ifdef EINTR
3271a8f5 545 || errno == EINTR
9d291bdf 546# endif
3271a8f5
SM
547 ))
548 { QUIT; continue; }
9d291bdf 549
3271a8f5 550 if (!dp) break;
14d55bce 551
3271a8f5 552 len = NAMLEN (dp);
14d55bce 553
3271a8f5
SM
554 QUIT;
555 if (! DIRENTRY_NONEMPTY (dp)
556 || len < SCHARS (encoded_file)
557 || 0 <= scmp (dp->d_name, SDATA (encoded_file),
558 SCHARS (encoded_file)))
559 continue;
14d55bce 560
3271a8f5
SM
561 if (file_name_completion_stat (encoded_dir, dp, &st) < 0)
562 continue;
14d55bce 563
3271a8f5
SM
564 directoryp = ((st.st_mode & S_IFMT) == S_IFDIR);
565 tem = Qnil;
566 /* If all_flag is set, always include all.
567 It would not actually be helpful to the user to ignore any possible
568 completions when making a list of them. */
569 if (!all_flag)
570 {
571 int skip;
2cd298e2 572
7519c40d 573#if 0 /* FIXME: The `scmp' call compares an encoded and a decoded string. */
2cd298e2
SM
574 /* If this entry matches the current bestmatch, the only
575 thing it can do is increase matchcount, so don't bother
576 investigating it any further. */
577 if (!completion_ignore_case
578 /* The return result depends on whether it's the sole match. */
579 && matchcount > 1
580 && !includeall /* This match may allow includeall to 0. */
581 && len >= bestmatchsize
582 && 0 > scmp (dp->d_name, SDATA (bestmatch), bestmatchsize))
583 continue;
7519c40d 584#endif
2cd298e2 585
3271a8f5 586 if (directoryp)
ad456ad4
RS
587 {
588#ifndef TRIVIAL_DIRECTORY_ENTRY
589#define TRIVIAL_DIRECTORY_ENTRY(n) (!strcmp (n, ".") || !strcmp (n, ".."))
590#endif
abfb1932
RS
591 /* "." and ".." are never interesting as completions, and are
592 actually in the way in a directory with only one file. */
3271a8f5
SM
593 if (TRIVIAL_DIRECTORY_ENTRY (dp->d_name))
594 canexclude = 1;
595 else if (len > SCHARS (encoded_file))
d013f29b
EZ
596 /* Ignore directories if they match an element of
597 completion-ignored-extensions which ends in a slash. */
598 for (tem = Vcompletion_ignored_extensions;
599 CONSP (tem); tem = XCDR (tem))
600 {
601 int elt_len;
2a54a229 602 unsigned char *p1;
d013f29b
EZ
603
604 elt = XCAR (tem);
605 if (!STRINGP (elt))
606 continue;
a74aaa9d
EZ
607 /* Need to encode ELT, since scmp compares unibyte
608 strings only. */
609 elt = ENCODE_FILE (elt);
d5db4077 610 elt_len = SCHARS (elt) - 1; /* -1 for trailing / */
7a8d465a 611 if (elt_len <= 0)
d013f29b 612 continue;
d5db4077 613 p1 = SDATA (elt);
d013f29b
EZ
614 if (p1[elt_len] != '/')
615 continue;
616 skip = len - elt_len;
617 if (skip < 0)
618 continue;
619
620 if (0 <= scmp (dp->d_name + skip, p1, elt_len))
621 continue;
622 break;
623 }
ad456ad4
RS
624 }
625 else
3271a8f5 626 {
14d55bce
RS
627 /* Compare extensions-to-be-ignored against end of this file name */
628 /* if name is not an exact match against specified string */
3271a8f5 629 if (len > SCHARS (encoded_file))
14d55bce
RS
630 /* and exit this for loop if a match is found */
631 for (tem = Vcompletion_ignored_extensions;
70949dac 632 CONSP (tem); tem = XCDR (tem))
14d55bce 633 {
70949dac 634 elt = XCAR (tem);
88cf1852 635 if (!STRINGP (elt)) continue;
a74aaa9d
EZ
636 /* Need to encode ELT, since scmp compares unibyte
637 strings only. */
638 elt = ENCODE_FILE (elt);
d5db4077 639 skip = len - SCHARS (elt);
14d55bce
RS
640 if (skip < 0) continue;
641
642 if (0 <= scmp (dp->d_name + skip,
d5db4077
KR
643 SDATA (elt),
644 SCHARS (elt)))
14d55bce
RS
645 continue;
646 break;
647 }
648 }
649
f676868d
KH
650 /* If an ignored-extensions match was found,
651 don't process this name as a completion. */
3271a8f5
SM
652 if (CONSP (tem))
653 canexclude = 1;
f676868d 654
3271a8f5
SM
655 if (!includeall && canexclude)
656 /* We're not including all files and this file can be excluded. */
657 continue;
9c691c00 658
3271a8f5
SM
659 if (includeall && !canexclude)
660 { /* If we have one non-excludable file, we want to exclude the
661 excudable files. */
662 includeall = 0;
663 /* Throw away any previous excludable match found. */
664 bestmatch = Qnil;
665 bestmatchsize = 0;
666 matchcount = 0;
f676868d 667 }
3271a8f5
SM
668 }
669 /* FIXME: If we move this `decode' earlier we can eliminate
670 the repeated ENCODE_FILE on Vcompletion_ignored_extensions. */
671 name = make_unibyte_string (dp->d_name, len);
672 name = DECODE_FILE (name);
673
674 {
675 Lisp_Object regexps;
676 Lisp_Object zero;
677 XSETFASTINT (zero, 0);
678
679 /* Ignore this element if it fails to match all the regexps. */
cc524e3b
CY
680 if (completion_ignore_case)
681 {
682 for (regexps = Vcompletion_regexp_list; CONSP (regexps);
683 regexps = XCDR (regexps))
684 if (fast_string_match_ignore_case (XCAR (regexps), name) < 0)
685 break;
686 }
687 else
688 {
689 for (regexps = Vcompletion_regexp_list; CONSP (regexps);
690 regexps = XCDR (regexps))
691 if (fast_string_match (XCAR (regexps), name) < 0)
692 break;
693 }
694
3271a8f5
SM
695 if (CONSP (regexps))
696 continue;
697 }
698
699 /* This is a possible completion */
700 if (directoryp)
701 /* This completion is a directory; make it end with '/'. */
702 name = Ffile_name_as_directory (name);
703
704 /* Test the predicate, if any. */
705 if (!NILP (predicate))
706 {
707 Lisp_Object val;
708 struct gcpro gcpro1;
14d55bce 709
3271a8f5
SM
710 GCPRO1 (name);
711 val = call1 (predicate, name);
712 UNGCPRO;
c4c52bb7 713
3271a8f5
SM
714 if (NILP (val))
715 continue;
716 }
abfb1932 717
3271a8f5 718 /* Suitably record this match. */
14d55bce 719
3271a8f5 720 matchcount++;
f676868d 721
3271a8f5
SM
722 if (all_flag)
723 bestmatch = Fcons (name, bestmatch);
724 else if (NILP (bestmatch))
725 {
726 bestmatch = name;
727 bestmatchsize = SCHARS (name);
728 }
729 else
730 {
731 Lisp_Object zero = make_number (0);
732 /* FIXME: This is a copy of the code in Ftry_completion. */
733 int compare = min (bestmatchsize, SCHARS (name));
734 Lisp_Object tem
735 = Fcompare_strings (bestmatch, zero,
736 make_number (compare),
737 name, zero,
738 make_number (compare),
739 completion_ignore_case ? Qt : Qnil);
740 int matchsize
741 = (EQ (tem, Qt) ? compare
742 : XINT (tem) < 0 ? - XINT (tem) - 1
743 : XINT (tem) - 1);
744
745 if (completion_ignore_case)
f676868d 746 {
3271a8f5
SM
747 /* If this is an exact match except for case,
748 use it as the best match rather than one that is not
749 an exact match. This way, we get the case pattern
750 of the actual match. */
751 /* This tests that the current file is an exact match
752 but BESTMATCH is not (it is too long). */
753 if ((matchsize == SCHARS (name)
2cd298e2 754 && matchsize + !!directoryp < SCHARS (bestmatch))
3271a8f5
SM
755 ||
756 /* If there is no exact match ignoring case,
757 prefer a match that does not change the case
758 of the input. */
759 /* If there is more than one exact match aside from
760 case, and one of them is exact including case,
761 prefer that one. */
762 /* This == checks that, of current file and BESTMATCH,
763 either both or neither are exact. */
764 (((matchsize == SCHARS (name))
765 ==
766 (matchsize + !!directoryp == SCHARS (bestmatch)))
767 && (tem = Fcompare_strings (name, zero,
768 make_number (SCHARS (file)),
769 file, zero,
770 Qnil,
771 Qnil),
772 EQ (Qt, tem))
773 && (tem = Fcompare_strings (bestmatch, zero,
774 make_number (SCHARS (file)),
775 file, zero,
776 Qnil,
777 Qnil),
778 ! EQ (Qt, tem))))
779 bestmatch = name;
14d55bce 780 }
3271a8f5 781 bestmatchsize = matchsize;
2cd298e2
SM
782
783 /* If the best completion so far is reduced to the string
784 we're trying to complete, then we already know there's no
785 other completion, so there's no point looking any further. */
786 if (matchsize <= SCHARS (file)
787 && !includeall /* A future match may allow includeall to 0. */
788 /* If completion-ignore-case is non-nil, don't
789 short-circuit because we want to find the best
790 possible match *including* case differences. */
791 && (!completion_ignore_case || matchsize == 0)
792 /* The return value depends on whether it's the sole match. */
793 && matchcount > 1)
794 break;
795
14d55bce 796 }
14d55bce
RS
797 }
798
3fcc88cc 799 UNGCPRO;
3271a8f5 800 /* This closes the directory. */
c3a3229c 801 bestmatch = unbind_to (count, bestmatch);
14d55bce 802
265a9e55 803 if (all_flag || NILP (bestmatch))
2a54a229 804 return bestmatch;
928b5acc
SM
805 /* Return t if the supplied string is an exact match (counting case);
806 it does not require any change to be made. */
807 if (matchcount == 1 && !NILP (Fequal (bestmatch, file)))
14d55bce 808 return Qt;
24c2a54f
RS
809 bestmatch = Fsubstring (bestmatch, make_number (0),
810 make_number (bestmatchsize));
24c2a54f 811 return bestmatch;
14d55bce
RS
812}
813
b3f04ced
RS
814/* Compare exactly LEN chars of strings at S1 and S2,
815 ignoring case if appropriate.
816 Return -1 if strings match,
817 else number of chars that match at the beginning. */
818
819static int
971de7fb 820scmp (register unsigned char *s1, register unsigned char *s2, int len)
b3f04ced
RS
821{
822 register int l = len;
823
824 if (completion_ignore_case)
825 {
826 while (l && DOWNCASE (*s1++) == DOWNCASE (*s2++))
827 l--;
828 }
829 else
830 {
831 while (l && *s1++ == *s2++)
832 l--;
833 }
834 if (l == 0)
835 return -1;
836 else
837 return len - l;
838}
839
dfcf069d 840static int
438105ed 841file_name_completion_stat (Lisp_Object dirname, DIRENTRY *dp, struct stat *st_addr)
14d55bce
RS
842{
843 int len = NAMLEN (dp);
d5db4077 844 int pos = SCHARS (dirname);
7e3cf34f 845 int value;
14d55bce
RS
846 char *fullname = (char *) alloca (len + pos + 2);
847
04924ee3 848#ifdef MSDOS
04924ee3
RS
849 /* Some fields of struct stat are *very* expensive to compute on MS-DOS,
850 but aren't required here. Avoid computing the following fields:
851 st_inode, st_size and st_nlink for directories, and the execute bits
852 in st_mode for non-directory files with non-standard extensions. */
853
854 unsigned short save_djstat_flags = _djstat_flags;
855
856 _djstat_flags = _STAT_INODE | _STAT_EXEC_MAGIC | _STAT_DIRSIZE;
04924ee3
RS
857#endif /* MSDOS */
858
72af86bd 859 memcpy (fullname, SDATA (dirname), pos);
0b39d75d
RS
860 if (!IS_DIRECTORY_SEP (fullname[pos - 1]))
861 fullname[pos++] = DIRECTORY_SEP;
14d55bce 862
72af86bd 863 memcpy (fullname + pos, dp->d_name, len);
14d55bce
RS
864 fullname[pos + len] = 0;
865
a889bd0e 866#ifdef S_IFLNK
7e3cf34f
RS
867 /* We want to return success if a link points to a nonexistent file,
868 but we want to return the status for what the link points to,
869 in case it is a directory. */
870 value = lstat (fullname, st_addr);
871 stat (fullname, st_addr);
872 return value;
a889bd0e 873#else
04924ee3
RS
874 value = stat (fullname, st_addr);
875#ifdef MSDOS
04924ee3 876 _djstat_flags = save_djstat_flags;
04924ee3
RS
877#endif /* MSDOS */
878 return value;
879#endif /* S_IFLNK */
14d55bce
RS
880}
881\f
882Lisp_Object
971de7fb 883make_time (time_t time)
14d55bce
RS
884{
885 return Fcons (make_number (time >> 16),
886 Fcons (make_number (time & 0177777), Qnil));
887}
888
8aaaec6b
EZ
889static char *
890stat_uname (struct stat *st)
891{
892#ifdef WINDOWSNT
893 return st->st_uname;
894#else
895 struct passwd *pw = (struct passwd *) getpwuid (st->st_uid);
896
897 if (pw)
898 return pw->pw_name;
899 else
900 return NULL;
901#endif
902}
903
904static char *
905stat_gname (struct stat *st)
906{
907#ifdef WINDOWSNT
908 return st->st_gname;
909#else
910 struct group *gr = (struct group *) getgrgid (st->st_gid);
911
912 if (gr)
913 return gr->gr_name;
914 else
915 return NULL;
916#endif
917}
918
6b61353c 919DEFUN ("file-attributes", Ffile_attributes, Sfile_attributes, 1, 2, 0,
335c5470
PJ
920 doc: /* Return a list of attributes of file FILENAME.
921Value is nil if specified file cannot be opened.
6b61353c
KH
922
923ID-FORMAT specifies the preferred format of attributes uid and gid (see
e42cd1a7
JB
924below) - valid values are 'string and 'integer. The latter is the
925default, but we plan to change that, so you should specify a non-nil value
926for ID-FORMAT if you use the returned uid or gid.
6b61353c
KH
927
928Elements of the attribute list are:
335c5470
PJ
929 0. t for directory, string (name linked to) for symbolic link, or nil.
930 1. Number of links to file.
78e7d1fe
EZ
931 2. File uid as a string or a number. If a string value cannot be
932 looked up, a numeric value, either an integer or a float, is returned.
6b61353c 933 3. File gid, likewise.
335c5470
PJ
934 4. Last access time, as a list of two integers.
935 First integer has high-order 16 bits of time, second has low 16 bits.
e02131a2
EZ
936 (See a note below about access time on FAT-based filesystems.)
937 5. Last modification time, likewise. This is the time of the last
938 change to the file's contents.
939 6. Last status change time, likewise. This is the time of last change
940 to the file's attributes: owner and group, access mode bits, etc.
335c5470
PJ
941 7. Size in bytes.
942 This is a floating point number if the size is too large for an integer.
943 8. File modes, as a string of ten letters or dashes as in ls -l.
e0f24100 944 9. t if file's gid would change if file were deleted and recreated.
e02131a2
EZ
94510. inode number. If inode number is larger than what Emacs integer
946 can hold, but still fits into a 32-bit number, this is a cons cell
947 containing two integers: first the high part, then the low 16 bits.
948 If the inode number is wider than 32 bits, this is of the form
949 (HIGH MIDDLE . LOW): first the high 24 bits, then middle 24 bits,
950 and finally the low 16 bits.
95111. Filesystem device number. If it is larger than what the Emacs
952 integer can hold, this is a cons cell, similar to the inode number.
953
954On most filesystems, the combination of the inode and the device
955number uniquely identifies the file.
6c5665e9
EZ
956
957On MS-Windows, performance depends on `w32-get-true-file-attributes',
21f73755
EZ
958which see.
959
960On some FAT-based filesystems, only the date of last access is recorded,
961so last access time will always be midnight of that day. */)
6b61353c
KH
962 (filename, id_format)
963 Lisp_Object filename, id_format;
14d55bce
RS
964{
965 Lisp_Object values[12];
24c2a54f 966 Lisp_Object encoded;
14d55bce 967 struct stat s;
98601119 968#ifdef BSD4_2
b3edfc9b 969 Lisp_Object dirname;
14d55bce 970 struct stat sdir;
98601119 971#endif /* BSD4_2 */
14d55bce 972 char modes[10];
32f4334d 973 Lisp_Object handler;
7435aef8 974 struct gcpro gcpro1;
51105b13 975 char *uname = NULL, *gname = NULL;
14d55bce
RS
976
977 filename = Fexpand_file_name (filename, Qnil);
32f4334d
RS
978
979 /* If the file name has special constructs in it,
980 call the corresponding file handler. */
a617e913 981 handler = Ffind_file_name_handler (filename, Qfile_attributes);
32f4334d 982 if (!NILP (handler))
6b61353c
KH
983 { /* Only pass the extra arg if it is used to help backward compatibility
984 with old file handlers which do not implement the new arg. --Stef */
985 if (NILP (id_format))
986 return call2 (handler, Qfile_attributes, filename);
987 else
988 return call3 (handler, Qfile_attributes, filename, id_format);
989 }
32f4334d 990
7435aef8 991 GCPRO1 (filename);
24c2a54f 992 encoded = ENCODE_FILE (filename);
7435aef8 993 UNGCPRO;
24c2a54f 994
d5db4077 995 if (lstat (SDATA (encoded), &s) < 0)
14d55bce
RS
996 return Qnil;
997
998 switch (s.st_mode & S_IFMT)
999 {
1000 default:
1001 values[0] = Qnil; break;
1002 case S_IFDIR:
1003 values[0] = Qt; break;
1004#ifdef S_IFLNK
1005 case S_IFLNK:
1006 values[0] = Ffile_symlink_p (filename); break;
1007#endif
1008 }
1009 values[1] = make_number (s.st_nlink);
51105b13
EZ
1010
1011 if (!(NILP (id_format) || EQ (id_format, Qinteger)))
6b61353c 1012 {
8c8a7c58 1013 BLOCK_INPUT;
8aaaec6b 1014 uname = stat_uname (&s);
8aaaec6b 1015 gname = stat_gname (&s);
8c8a7c58 1016 UNBLOCK_INPUT;
6b61353c 1017 }
51105b13 1018 if (uname)
80904120 1019 values[2] = DECODE_SYSTEM (build_string (uname));
51105b13 1020 else
58a12889 1021 values[2] = make_fixnum_or_float (s.st_uid);
51105b13 1022 if (gname)
80904120 1023 values[3] = DECODE_SYSTEM (build_string (gname));
51105b13 1024 else
58a12889 1025 values[3] = make_fixnum_or_float (s.st_gid);
51105b13 1026
14d55bce
RS
1027 values[4] = make_time (s.st_atime);
1028 values[5] = make_time (s.st_mtime);
1029 values[6] = make_time (s.st_ctime);
58a12889 1030 values[7] = make_fixnum_or_float (s.st_size);
4bc12672
JR
1031 /* If the size is negative, and its type is long, convert it back to
1032 positive. */
1033 if (s.st_size < 0 && sizeof (s.st_size) == sizeof (long))
1034 values[7] = make_float ((double) ((unsigned long) s.st_size));
1035
14d55bce
RS
1036 filemodestring (&s, modes);
1037 values[8] = make_string (modes, 10);
98601119 1038#ifdef BSD4_2 /* file gid will be dir gid */
14d55bce 1039 dirname = Ffile_name_directory (filename);
24c2a54f
RS
1040 if (! NILP (dirname))
1041 encoded = ENCODE_FILE (dirname);
d5db4077 1042 if (! NILP (dirname) && stat (SDATA (encoded), &sdir) == 0)
01388a3d 1043 values[9] = (sdir.st_gid != s.st_gid) ? Qt : Qnil;
14d55bce
RS
1044 else /* if we can't tell, assume worst */
1045 values[9] = Qt;
1046#else /* file gid will be egid */
01388a3d 1047 values[9] = (s.st_gid != getegid ()) ? Qt : Qnil;
98601119 1048#endif /* not BSD4_2 */
58a12889 1049 if (!FIXNUM_OVERFLOW_P (s.st_ino))
e058f331 1050 /* Keep the most common cases as integers. */
58a12889
AS
1051 values[10] = make_number (s.st_ino);
1052 else if (!FIXNUM_OVERFLOW_P (s.st_ino >> 16))
4c637faa
RS
1053 /* To allow inode numbers larger than VALBITS, separate the bottom
1054 16 bits. */
e058f331
EZ
1055 values[10] = Fcons (make_number ((EMACS_INT)(s.st_ino >> 16)),
1056 make_number ((EMACS_INT)(s.st_ino & 0xffff)));
4c637faa 1057 else
e058f331
EZ
1058 {
1059 /* To allow inode numbers beyond 32 bits, separate into 2 24-bit
ff8ddc7b 1060 high parts and a 16-bit bottom part.
25ae5671
EZ
1061 The code on the next line avoids a compiler warning on
1062 systems where st_ino is 32 bit wide. (bug#766). */
ff8ddc7b 1063 EMACS_INT high_ino = s.st_ino >> 31 >> 1;
e058f331
EZ
1064 EMACS_INT low_ino = s.st_ino & 0xffffffff;
1065
1066 values[10] = Fcons (make_number (high_ino >> 8),
1067 Fcons (make_number (((high_ino & 0xff) << 16)
1068 + (low_ino >> 16)),
1069 make_number (low_ino & 0xffff)));
1070 }
68c45bf0 1071
58a12889
AS
1072 /* Likewise for device. */
1073 if (FIXNUM_OVERFLOW_P (s.st_dev))
68c45bf0
PE
1074 values[11] = Fcons (make_number (s.st_dev >> 16),
1075 make_number (s.st_dev & 0xffff));
1076 else
1077 values[11] = make_number (s.st_dev);
1078
14d55bce
RS
1079 return Flist (sizeof(values) / sizeof(values[0]), values);
1080}
4424b255
GV
1081
1082DEFUN ("file-attributes-lessp", Ffile_attributes_lessp, Sfile_attributes_lessp, 2, 2, 0,
335c5470
PJ
1083 doc: /* Return t if first arg file attributes list is less than second.
1084Comparison is in lexicographic order and case is significant. */)
1085 (f1, f2)
4424b255
GV
1086 Lisp_Object f1, f2;
1087{
1088 return Fstring_lessp (Fcar (f1), Fcar (f2));
1089}
14d55bce 1090\f
dfcf069d 1091void
971de7fb 1092syms_of_dired (void)
14d55bce 1093{
d67b4f80
DN
1094 Qdirectory_files = intern_c_string ("directory-files");
1095 Qdirectory_files_and_attributes = intern_c_string ("directory-files-and-attributes");
1096 Qfile_name_completion = intern_c_string ("file-name-completion");
1097 Qfile_name_all_completions = intern_c_string ("file-name-all-completions");
1098 Qfile_attributes = intern_c_string ("file-attributes");
1099 Qfile_attributes_lessp = intern_c_string ("file-attributes-lessp");
1100 Qdefault_directory = intern_c_string ("default-directory");
32f4334d 1101
a2d3836c 1102 staticpro (&Qdirectory_files);
4424b255 1103 staticpro (&Qdirectory_files_and_attributes);
a2d3836c
EN
1104 staticpro (&Qfile_name_completion);
1105 staticpro (&Qfile_name_all_completions);
1106 staticpro (&Qfile_attributes);
4424b255 1107 staticpro (&Qfile_attributes_lessp);
01bb4018 1108 staticpro (&Qdefault_directory);
a2d3836c 1109
14d55bce 1110 defsubr (&Sdirectory_files);
4424b255 1111 defsubr (&Sdirectory_files_and_attributes);
14d55bce 1112 defsubr (&Sfile_name_completion);
14d55bce
RS
1113 defsubr (&Sfile_name_all_completions);
1114 defsubr (&Sfile_attributes);
4424b255 1115 defsubr (&Sfile_attributes_lessp);
14d55bce 1116
14d55bce 1117 DEFVAR_LISP ("completion-ignored-extensions", &Vcompletion_ignored_extensions,
407a52c4
LT
1118 doc: /* Completion ignores file names ending in any string in this list.
1119It does not ignore them if all possible completions end in one of
1120these strings or when displaying a list of completions.
1121It ignores directory names if they match any string in this list which
1122ends in a slash. */);
14d55bce
RS
1123 Vcompletion_ignored_extensions = Qnil;
1124}
6b61353c
KH
1125
1126/* arch-tag: 1ac8deca-4d8f-4d41-ade9-089154d98c03
1127 (do not change this comment) */