(CHECK_FRAME, CHECK_LIVE_FRAME): Remove unused argument `i' in macros.
[bpt/emacs.git] / src / dired.c
CommitLineData
14d55bce 1/* Lisp functions for making directory listings.
0a974c85
GM
2 Copyright (C) 1985, 1986, 1993, 1994, 1999, 2000, 2001
3 Free Software Foundation, Inc.
14d55bce
RS
4
5This file is part of GNU Emacs.
6
7GNU Emacs is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
7c938215 9the Free Software Foundation; either version 2, or (at your option)
14d55bce
RS
10any later version.
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
18along with GNU Emacs; see the file COPYING. If not, write to
3b7ad313
EN
19the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20Boston, MA 02111-1307, USA. */
14d55bce
RS
21
22
3964b9a7
RS
23#include <config.h>
24
14d55bce
RS
25#include <stdio.h>
26#include <sys/types.h>
27#include <sys/stat.h>
28
68c45bf0 29#include "systime.h"
7cc9f69f 30#include <errno.h>
68c45bf0 31
3ed991aa
RS
32#ifdef VMS
33#include <string.h>
34#include <rms.h>
35#include <rmsdef.h>
36#endif
37
dfcf069d
AS
38#ifdef HAVE_UNISTD_H
39#include <unistd.h>
40#endif
41
d6717cdb
JB
42/* The d_nameln member of a struct dirent includes the '\0' character
43 on some systems, but not on others. What's worse, you can't tell
44 at compile-time which one it will be, since it really depends on
45 the sort of system providing the filesystem you're reading from,
46 not the system you are running on. Paul Eggert
47 <eggert@bi.twinsun.com> says this occurs when Emacs is running on a
48 SunOS 4.1.2 host, reading a directory that is remote-mounted from a
49 Solaris 2.1 host and is in a native Solaris 2.1 filesystem.
50
51 Since applying strlen to the name always works, we'll just do that. */
52#define NAMLEN(p) strlen (p->d_name)
53
14d55bce
RS
54#ifdef SYSV_SYSTEM_DIR
55
56#include <dirent.h>
57#define DIRENTRY struct dirent
14d55bce 58
128ecc89 59#else /* not SYSV_SYSTEM_DIR */
14d55bce
RS
60
61#ifdef NONSYSTEM_DIR_LIBRARY
62#include "ndir.h"
63#else /* not NONSYSTEM_DIR_LIBRARY */
128ecc89
RS
64#ifdef MSDOS
65#include <dirent.h>
66#else
14d55bce 67#include <sys/dir.h>
128ecc89 68#endif
14d55bce
RS
69#endif /* not NONSYSTEM_DIR_LIBRARY */
70
851cab13
DL
71#include <sys/stat.h>
72
128ecc89 73#ifndef MSDOS
14d55bce 74#define DIRENTRY struct direct
14d55bce
RS
75
76extern DIR *opendir ();
77extern struct direct *readdir ();
78
128ecc89
RS
79#endif /* not MSDOS */
80#endif /* not SYSV_SYSTEM_DIR */
81
82#ifdef MSDOS
83#define DIRENTRY_NONEMPTY(p) ((p)->d_name[0] != 0)
84#else
85#define DIRENTRY_NONEMPTY(p) ((p)->d_ino)
14d55bce
RS
86#endif
87
14d55bce
RS
88#include "lisp.h"
89#include "buffer.h"
90#include "commands.h"
bd33479f
KH
91#include "charset.h"
92#include "coding.h"
14d55bce 93#include "regex.h"
14d55bce 94
e50c66d3
KH
95/* Returns a search buffer, with a fastmap allocated and ready to go. */
96extern struct re_pattern_buffer *compile_pattern ();
c7e466e1 97
851cab13
DL
98/* From filemode.c. Can't go in Lisp.h because of `stat'. */
99extern void filemodestring P_ ((struct stat *, char *));
100
14d55bce
RS
101/* if system does not have symbolic links, it does not have lstat.
102 In that case, use ordinary stat instead. */
103
104#ifndef S_IFLNK
105#define lstat stat
106#endif
107
97e98a56 108extern int completion_ignore_case;
f676868d 109extern Lisp_Object Vcompletion_regexp_list;
bd33479f 110extern Lisp_Object Vfile_name_coding_system, Vdefault_file_name_coding_system;
ccbcf979 111
14d55bce 112Lisp_Object Vcompletion_ignored_extensions;
14d55bce 113Lisp_Object Qcompletion_ignore_case;
32f4334d 114Lisp_Object Qdirectory_files;
4424b255 115Lisp_Object Qdirectory_files_and_attributes;
32f4334d
RS
116Lisp_Object Qfile_name_completion;
117Lisp_Object Qfile_name_all_completions;
434e6714 118Lisp_Object Qfile_attributes;
4424b255 119Lisp_Object Qfile_attributes_lessp;
14d55bce 120\f
2488aba5
AI
121
122Lisp_Object
123directory_files_internal_unwind (dh)
124 Lisp_Object dh;
125{
126 DIR *d = (DIR *) ((XINT (XCAR (dh)) << 16) + XINT (XCDR (dh)));
127 closedir (d);
128 return Qnil;
129}
130
4424b255
GV
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. */
f69f9da1 134
4424b255
GV
135Lisp_Object
136directory_files_internal (directory, full, match, nosort, attrs)
23bd240f 137 Lisp_Object directory, full, match, nosort;
4424b255 138 int attrs;
14d55bce
RS
139{
140 DIR *d;
388ac098
GM
141 int directory_nbytes;
142 Lisp_Object list, dirfilename, encoded_directory;
6bbd7a29 143 struct re_pattern_buffer *bufp = NULL;
96d64004 144 int needsep = 0;
2488aba5 145 int count = specpdl_ptr - specpdl;
388ac098 146 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
8e42f043
GM
147 DIRENTRY *dp;
148 int retry_p;
32f4334d 149
96d64004 150 /* Because of file name handlers, these functions might call
6155fae1 151 Ffuncall, and cause a GC. */
388ac098
GM
152 list = encoded_directory = dirfilename = Qnil;
153 GCPRO5 (match, directory, list, dirfilename, encoded_directory);
96d64004 154 directory = Fexpand_file_name (directory, Qnil);
96d64004 155 dirfilename = Fdirectory_file_name (directory);
6155fae1 156
265a9e55 157 if (!NILP (match))
14d55bce
RS
158 {
159 CHECK_STRING (match, 3);
ebb9e16f
JB
160
161 /* MATCH might be a flawed regular expression. Rather than
8e6208c5 162 catching and signaling our own errors, we just call
ebb9e16f 163 compile_pattern to do the work for us. */
c872c6b2
RS
164 /* Pass 1 for the MULTIBYTE arg
165 because we do make multibyte strings if the contents warrant. */
14d55bce 166#ifdef VMS
e50c66d3 167 bufp = compile_pattern (match, 0,
3e937712 168 buffer_defaults.downcase_table, 0, 1);
14d55bce 169#else
3e937712 170 bufp = compile_pattern (match, 0, Qnil, 0, 1);
14d55bce
RS
171#endif
172 }
173
b3edfc9b 174 /* Note: ENCODE_FILE and DECODE_FILE can GC because they can run
388ac098
GM
175 run_pre_post_conversion_on_str which calls Lisp directly and
176 indirectly. */
24c2a54f 177 dirfilename = ENCODE_FILE (dirfilename);
24c2a54f
RS
178 encoded_directory = ENCODE_FILE (directory);
179
e50c66d3 180 /* Now *bufp is the compiled form of MATCH; don't call anything
6155fae1
JB
181 which might compile a new regexp until we're done with the loop! */
182
183 /* Do this opendir after anything which might signal an error; if
8e6208c5 184 an error is signaled while the directory stream is open, we
6155fae1
JB
185 have to make sure it gets closed, and setting up an
186 unwind_protect to do so would be a pain. */
8e42f043
GM
187 retry:
188
6155fae1 189 d = opendir (XSTRING (dirfilename)->data);
388ac098 190 if (d == NULL)
23bd240f 191 report_file_error ("Opening directory", Fcons (directory, Qnil));
14d55bce 192
2488aba5
AI
193 /* Unfortunately, we can now invoke expand-file-name and
194 file-attributes on filenames, both of which can throw, so we must
195 do a proper unwind-protect. */
196 record_unwind_protect (directory_files_internal_unwind,
197 Fcons (make_number (((unsigned long) d) >> 16),
198 make_number (((unsigned long) d) & 0xffff)));
199
388ac098 200 directory_nbytes = STRING_BYTES (XSTRING (directory));
c81a9bdc 201 re_match_object = Qt;
14d55bce 202
96d64004
AS
203 /* Decide whether we need to add a directory separator. */
204#ifndef VMS
388ac098
GM
205 if (directory_nbytes == 0
206 || !IS_ANY_SEP (XSTRING (directory)->data[directory_nbytes - 1]))
96d64004 207 needsep = 1;
e540cbed 208#endif /* not VMS */
96d64004 209
8e42f043 210 /* Loop reading blocks until EOF or error. */
f69f9da1 211 for (;;)
14d55bce 212 {
f69f9da1
GM
213 errno = 0;
214 dp = readdir (d);
215
216#ifdef EAGAIN
217 if (dp == NULL && errno == EAGAIN)
218 continue;
219#endif
220
221 if (dp == NULL)
222 break;
223
128ecc89 224 if (DIRENTRY_NONEMPTY (dp))
14d55bce 225 {
e23f810c 226 int len;
2488aba5 227 int wanted = 0;
388ac098
GM
228 Lisp_Object name, finalname;
229 struct gcpro gcpro1, gcpro2;
e23f810c
KH
230
231 len = NAMLEN (dp);
9ad4f3e5 232 name = finalname = make_unibyte_string (dp->d_name, len);
388ac098
GM
233 GCPRO2 (finalname, name);
234
235 /* Note: ENCODE_FILE can GC; it should protect its argument,
236 though. */
237 name = DECODE_FILE (name);
e23f810c
KH
238 len = STRING_BYTES (XSTRING (name));
239
2488aba5
AI
240 /* Now that we have unwind_protect in place, we might as well
241 allow matching to be interrupted. */
242 immediate_quit = 1;
243 QUIT;
244
265a9e55 245 if (NILP (match)
e23f810c 246 || (0 <= re_search (bufp, XSTRING (name)->data, len, 0, len, 0)))
388ac098 247 wanted = 1;
2488aba5
AI
248
249 immediate_quit = 0;
250
251 if (wanted)
14d55bce 252 {
265a9e55 253 if (!NILP (full))
14d55bce 254 {
e23f810c 255 Lisp_Object fullname;
388ac098
GM
256 int nbytes = len + directory_nbytes + needsep;
257 int nchars;
5617588f 258
388ac098 259 fullname = make_uninit_multibyte_string (nbytes, nbytes);
e23f810c 260 bcopy (XSTRING (directory)->data, XSTRING (fullname)->data,
388ac098
GM
261 directory_nbytes);
262
5617588f 263 if (needsep)
cb154426 264 XSTRING (fullname)->data[directory_nbytes] = DIRECTORY_SEP;
388ac098 265
e23f810c 266 bcopy (XSTRING (name)->data,
388ac098
GM
267 XSTRING (fullname)->data + directory_nbytes + needsep,
268 len);
269
270 nchars = chars_in_text (XSTRING (fullname)->data, nbytes);
271
272 /* Some bug somewhere. */
273 if (nchars > nbytes)
274 abort ();
275
e23f810c 276 XSTRING (fullname)->size = nchars;
388ac098 277 if (nchars == nbytes)
e23f810c 278 SET_STRING_BYTES (XSTRING (fullname), -1);
388ac098 279
4424b255
GV
280 finalname = fullname;
281 }
aab9c564
KH
282 else
283 finalname = name;
4424b255
GV
284
285 if (attrs)
286 {
287 /* Construct an expanded filename for the directory entry.
288 Use the decoded names for input to Ffile_attributes. */
388ac098
GM
289 Lisp_Object decoded_fullname, fileattrs;
290 struct gcpro gcpro1, gcpro2;
291
292 decoded_fullname = fileattrs = Qnil;
293 GCPRO2 (decoded_fullname, fileattrs);
4424b255 294
388ac098 295 /* Both Fexpand_file_name and Ffile_attributes can GC. */
4424b255
GV
296 decoded_fullname = Fexpand_file_name (name, directory);
297 fileattrs = Ffile_attributes (decoded_fullname);
298
299 list = Fcons (Fcons (finalname, fileattrs), list);
388ac098 300 UNGCPRO;
4424b255
GV
301 }
302 else
388ac098 303 list = Fcons (finalname, list);
14d55bce 304 }
388ac098
GM
305
306 UNGCPRO;
14d55bce
RS
307 }
308 }
2488aba5 309
8e42f043 310 retry_p = 0;
8e42f043
GM
311#ifdef EINTR
312 retry_p |= errno == EINTR;
313#endif
314
14d55bce 315 closedir (d);
2488aba5
AI
316
317 /* Discard the unwind protect. */
318 specpdl_ptr = specpdl + count;
319
8e42f043 320 if (retry_p)
76846b31
GM
321 {
322 list = Qnil;
323 goto retry;
324 }
8e42f043 325
388ac098
GM
326 if (NILP (nosort))
327 list = Fsort (Fnreverse (list),
328 attrs ? Qfile_attributes_lessp : Qstring_lessp);
329
330 RETURN_UNGCPRO (list);
14d55bce 331}
4424b255
GV
332
333
334DEFUN ("directory-files", Fdirectory_files, Sdirectory_files, 1, 4, 0,
335 "Return a list of names of files in DIRECTORY.\n\
336There are three optional arguments:\n\
337If FULL is non-nil, return absolute file names. Otherwise return names\n\
338 that are relative to the specified directory.\n\
339If MATCH is non-nil, mention only file names that match the regexp MATCH.\n\
340If NOSORT is non-nil, the list is not sorted--its order is unpredictable.\n\
341 NOSORT is useful if you plan to sort the result yourself.")
342 (directory, full, match, nosort)
343 Lisp_Object directory, full, match, nosort;
344{
345 Lisp_Object handler;
346
347 /* If the file name has special constructs in it,
348 call the corresponding file handler. */
349 handler = Ffind_file_name_handler (directory, Qdirectory_files);
350 if (!NILP (handler))
351 {
352 Lisp_Object args[6];
353
354 args[0] = handler;
355 args[1] = Qdirectory_files;
356 args[2] = directory;
357 args[3] = full;
358 args[4] = match;
359 args[5] = nosort;
360 return Ffuncall (6, args);
361 }
362
363 return directory_files_internal (directory, full, match, nosort, 0);
364}
365
366DEFUN ("directory-files-and-attributes", Fdirectory_files_and_attributes, Sdirectory_files_and_attributes, 1, 4, 0,
367 "Return a list of names of files and their attributes in DIRECTORY.\n\
368There are three optional arguments:\n\
369If FULL is non-nil, return absolute file names. Otherwise return names\n\
370 that are relative to the specified directory.\n\
371If MATCH is non-nil, mention only file names that match the regexp MATCH.\n\
372If NOSORT is non-nil, the list is not sorted--its order is unpredictable.\n\
373 NOSORT is useful if you plan to sort the result yourself.")
374 (directory, full, match, nosort)
375 Lisp_Object directory, full, match, nosort;
376{
377 Lisp_Object handler;
378
379 /* If the file name has special constructs in it,
380 call the corresponding file handler. */
381 handler = Ffind_file_name_handler (directory, Qdirectory_files_and_attributes);
382 if (!NILP (handler))
383 {
384 Lisp_Object args[6];
385
386 args[0] = handler;
387 args[1] = Qdirectory_files_and_attributes;
388 args[2] = directory;
389 args[3] = full;
390 args[4] = match;
391 args[5] = nosort;
392 return Ffuncall (6, args);
393 }
394
395 return directory_files_internal (directory, full, match, nosort, 1);
396}
397
14d55bce
RS
398\f
399Lisp_Object file_name_completion ();
400
401DEFUN ("file-name-completion", Ffile_name_completion, Sfile_name_completion,
402 2, 2, 0,
23bd240f 403 "Complete file name FILE in directory DIRECTORY.\n\
14d55bce 404Returns the longest string\n\
7b6540dd 405common to all file names in DIRECTORY that start with FILE.\n\
14d55bce 406If there is only one and FILE matches it exactly, returns t.\n\
d013f29b
EZ
407Returns nil if DIR contains no name starting with FILE.\n\
408\n\
409This function ignores some of the possible completions as\n\
410determined by the variable `completion-ignored-extensions', which see.")
23bd240f
EN
411 (file, directory)
412 Lisp_Object file, directory;
14d55bce 413{
32f4334d 414 Lisp_Object handler;
32f4334d 415
8436e231 416 /* If the directory name has special constructs in it,
32f4334d 417 call the corresponding file handler. */
23bd240f 418 handler = Ffind_file_name_handler (directory, Qfile_name_completion);
32f4334d 419 if (!NILP (handler))
23bd240f 420 return call3 (handler, Qfile_name_completion, file, directory);
32f4334d 421
8436e231
RS
422 /* If the file name has special constructs in it,
423 call the corresponding file handler. */
424 handler = Ffind_file_name_handler (file, Qfile_name_completion);
425 if (!NILP (handler))
23bd240f 426 return call3 (handler, Qfile_name_completion, file, directory);
8436e231 427
23bd240f 428 return file_name_completion (file, directory, 0, 0);
14d55bce
RS
429}
430
431DEFUN ("file-name-all-completions", Ffile_name_all_completions,
432 Sfile_name_all_completions, 2, 2, 0,
23bd240f
EN
433 "Return a list of all completions of file name FILE in directory DIRECTORY.\n\
434These are all file names in directory DIRECTORY which begin with FILE.")
435 (file, directory)
436 Lisp_Object file, directory;
14d55bce 437{
32f4334d
RS
438 Lisp_Object handler;
439
8436e231 440 /* If the directory name has special constructs in it,
32f4334d 441 call the corresponding file handler. */
23bd240f 442 handler = Ffind_file_name_handler (directory, Qfile_name_all_completions);
32f4334d 443 if (!NILP (handler))
23bd240f 444 return call3 (handler, Qfile_name_all_completions, file, directory);
32f4334d 445
8436e231
RS
446 /* If the file name has special constructs in it,
447 call the corresponding file handler. */
448 handler = Ffind_file_name_handler (file, Qfile_name_all_completions);
449 if (!NILP (handler))
23bd240f 450 return call3 (handler, Qfile_name_all_completions, file, directory);
8436e231 451
23bd240f 452 return file_name_completion (file, directory, 1, 0);
14d55bce
RS
453}
454
dfcf069d
AS
455static int file_name_completion_stat ();
456
14d55bce
RS
457Lisp_Object
458file_name_completion (file, dirname, all_flag, ver_flag)
459 Lisp_Object file, dirname;
460 int all_flag, ver_flag;
461{
462 DIR *d;
6bbd7a29 463 int bestmatchsize = 0, skip;
14d55bce
RS
464 register int compare, matchsize;
465 unsigned char *p1, *p2;
466 int matchcount = 0;
467 Lisp_Object bestmatch, tem, elt, name;
24c2a54f
RS
468 Lisp_Object encoded_file;
469 Lisp_Object encoded_dir;
14d55bce
RS
470 struct stat st;
471 int directoryp;
472 int passcount;
473 int count = specpdl_ptr - specpdl;
24c2a54f 474 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
3fcc88cc 475
6bbd7a29
GM
476 elt = Qnil;
477
14d55bce
RS
478#ifdef VMS
479 extern DIRENTRY * readdirver ();
480
481 DIRENTRY *((* readfunc) ());
482
483 /* Filename completion on VMS ignores case, since VMS filesys does. */
484 specbind (Qcompletion_ignore_case, Qt);
485
486 readfunc = readdir;
487 if (ver_flag)
488 readfunc = readdirver;
489 file = Fupcase (file);
490#else /* not VMS */
491 CHECK_STRING (file, 0);
492#endif /* not VMS */
493
128ecc89
RS
494#ifdef FILE_SYSTEM_CASE
495 file = FILE_SYSTEM_CASE (file);
496#endif
14d55bce 497 bestmatch = Qnil;
24c2a54f
RS
498 encoded_file = encoded_dir = Qnil;
499 GCPRO5 (file, dirname, bestmatch, encoded_file, encoded_dir);
3fcc88cc 500 dirname = Fexpand_file_name (dirname, Qnil);
14d55bce 501
24c2a54f
RS
502 /* Do completion on the encoded file name
503 because the other names in the directory are (we presume)
504 encoded likewise. We decode the completed string at the end. */
505 encoded_file = ENCODE_FILE (file);
506
507 encoded_dir = ENCODE_FILE (dirname);
508
14d55bce
RS
509 /* With passcount = 0, ignore files that end in an ignored extension.
510 If nothing found then try again with passcount = 1, don't ignore them.
511 If looking for all completions, start with passcount = 1,
512 so always take even the ignored ones.
513
514 ** It would not actually be helpful to the user to ignore any possible
515 completions when making a list of them.** */
516
265a9e55 517 for (passcount = !!all_flag; NILP (bestmatch) && passcount < 2; passcount++)
14d55bce 518 {
24c2a54f
RS
519 d = opendir (XSTRING (Fdirectory_file_name (encoded_dir))->data);
520 if (!d)
14d55bce
RS
521 report_file_error ("Opening directory", Fcons (dirname, Qnil));
522
523 /* Loop reading blocks */
524 /* (att3b compiler bug requires do a null comparison this way) */
525 while (1)
526 {
527 DIRENTRY *dp;
528 int len;
529
530#ifdef VMS
531 dp = (*readfunc) (d);
532#else
533 dp = readdir (d);
534#endif
535 if (!dp) break;
536
537 len = NAMLEN (dp);
538
265a9e55 539 if (!NILP (Vquit_flag) && NILP (Vinhibit_quit))
14d55bce 540 goto quit;
128ecc89 541 if (! DIRENTRY_NONEMPTY (dp)
24c2a54f
RS
542 || len < XSTRING (encoded_file)->size
543 || 0 <= scmp (dp->d_name, XSTRING (encoded_file)->data,
544 XSTRING (encoded_file)->size))
14d55bce
RS
545 continue;
546
24c2a54f 547 if (file_name_completion_stat (encoded_dir, dp, &st) < 0)
14d55bce
RS
548 continue;
549
550 directoryp = ((st.st_mode & S_IFMT) == S_IFDIR);
551 tem = Qnil;
ad456ad4
RS
552 if (directoryp)
553 {
554#ifndef TRIVIAL_DIRECTORY_ENTRY
555#define TRIVIAL_DIRECTORY_ENTRY(n) (!strcmp (n, ".") || !strcmp (n, ".."))
556#endif
557 /* "." and ".." are never interesting as completions, but are
558 actually in the way in a directory contains only one file. */
559 if (!passcount && TRIVIAL_DIRECTORY_ENTRY (dp->d_name))
560 continue;
d013f29b
EZ
561 if (!passcount && len > XSTRING (encoded_file)->size)
562 /* Ignore directories if they match an element of
563 completion-ignored-extensions which ends in a slash. */
564 for (tem = Vcompletion_ignored_extensions;
565 CONSP (tem); tem = XCDR (tem))
566 {
567 int elt_len;
568
569 elt = XCAR (tem);
570 if (!STRINGP (elt))
571 continue;
572 elt_len = XSTRING (elt)->size - 1; /* -1 for trailing / */
7a8d465a 573 if (elt_len <= 0)
d013f29b
EZ
574 continue;
575 p1 = XSTRING (elt)->data;
576 if (p1[elt_len] != '/')
577 continue;
578 skip = len - elt_len;
579 if (skip < 0)
580 continue;
581
582 if (0 <= scmp (dp->d_name + skip, p1, elt_len))
583 continue;
584 break;
585 }
ad456ad4
RS
586 }
587 else
14d55bce
RS
588 {
589 /* Compare extensions-to-be-ignored against end of this file name */
590 /* if name is not an exact match against specified string */
24c2a54f 591 if (!passcount && len > XSTRING (encoded_file)->size)
14d55bce
RS
592 /* and exit this for loop if a match is found */
593 for (tem = Vcompletion_ignored_extensions;
70949dac 594 CONSP (tem); tem = XCDR (tem))
14d55bce 595 {
70949dac 596 elt = XCAR (tem);
88cf1852 597 if (!STRINGP (elt)) continue;
14d55bce
RS
598 skip = len - XSTRING (elt)->size;
599 if (skip < 0) continue;
600
601 if (0 <= scmp (dp->d_name + skip,
602 XSTRING (elt)->data,
603 XSTRING (elt)->size))
604 continue;
605 break;
606 }
607 }
608
f676868d
KH
609 /* If an ignored-extensions match was found,
610 don't process this name as a completion. */
611 if (!passcount && CONSP (tem))
612 continue;
613
614 if (!passcount)
14d55bce 615 {
f676868d
KH
616 Lisp_Object regexps;
617 Lisp_Object zero;
617b3bfe 618 XSETFASTINT (zero, 0);
f676868d
KH
619
620 /* Ignore this element if it fails to match all the regexps. */
621 for (regexps = Vcompletion_regexp_list; CONSP (regexps);
70949dac 622 regexps = XCDR (regexps))
f676868d 623 {
1c56232f
EZ
624 tem = Fstring_match (XCAR (regexps),
625 make_string (dp->d_name, len), zero);
f676868d
KH
626 if (NILP (tem))
627 break;
628 }
629 if (CONSP (regexps))
630 continue;
631 }
14d55bce 632
f676868d 633 /* Update computation of how much all possible completions match */
14d55bce 634
f676868d
KH
635 matchcount++;
636
637 if (all_flag || NILP (bestmatch))
638 {
639 /* This is a possible completion */
640 if (directoryp)
14d55bce 641 {
f676868d
KH
642 /* This completion is a directory; make it end with '/' */
643 name = Ffile_name_as_directory (make_string (dp->d_name, len));
644 }
645 else
646 name = make_string (dp->d_name, len);
647 if (all_flag)
648 {
bd33479f 649 name = DECODE_FILE (name);
f676868d 650 bestmatch = Fcons (name, bestmatch);
14d55bce
RS
651 }
652 else
653 {
f676868d
KH
654 bestmatch = name;
655 bestmatchsize = XSTRING (name)->size;
656 }
657 }
658 else
659 {
660 compare = min (bestmatchsize, len);
661 p1 = XSTRING (bestmatch)->data;
662 p2 = (unsigned char *) dp->d_name;
663 matchsize = scmp(p1, p2, compare);
664 if (matchsize < 0)
665 matchsize = compare;
666 if (completion_ignore_case)
667 {
668 /* If this is an exact match except for case,
669 use it as the best match rather than one that is not
670 an exact match. This way, we get the case pattern
671 of the actual match. */
f5ec5d3d
RS
672 /* This tests that the current file is an exact match
673 but BESTMATCH is not (it is too long). */
f676868d
KH
674 if ((matchsize == len
675 && matchsize + !!directoryp
676 < XSTRING (bestmatch)->size)
677 ||
678 /* If there is no exact match ignoring case,
679 prefer a match that does not change the case
680 of the input. */
f5ec5d3d
RS
681 /* If there is more than one exact match aside from
682 case, and one of them is exact including case,
683 prefer that one. */
684 /* This == checks that, of current file and BESTMATCH,
685 either both or neither are exact. */
f676868d
KH
686 (((matchsize == len)
687 ==
688 (matchsize + !!directoryp
689 == XSTRING (bestmatch)->size))
24c2a54f
RS
690 && !bcmp (p2, XSTRING (encoded_file)->data, XSTRING (encoded_file)->size)
691 && bcmp (p1, XSTRING (encoded_file)->data, XSTRING (encoded_file)->size)))
97e98a56 692 {
f676868d
KH
693 bestmatch = make_string (dp->d_name, len);
694 if (directoryp)
695 bestmatch = Ffile_name_as_directory (bestmatch);
97e98a56 696 }
14d55bce 697 }
f676868d
KH
698
699 /* If this dirname all matches, see if implicit following
700 slash does too. */
701 if (directoryp
702 && compare == matchsize
703 && bestmatchsize > matchsize
0b39d75d 704 && IS_ANY_SEP (p1[matchsize]))
f676868d
KH
705 matchsize++;
706 bestmatchsize = matchsize;
14d55bce
RS
707 }
708 }
709 closedir (d);
710 }
711
3fcc88cc
RS
712 UNGCPRO;
713 bestmatch = unbind_to (count, bestmatch);
14d55bce 714
265a9e55 715 if (all_flag || NILP (bestmatch))
24c2a54f 716 {
bd33479f
KH
717 if (STRINGP (bestmatch))
718 bestmatch = DECODE_FILE (bestmatch);
24c2a54f
RS
719 return bestmatch;
720 }
14d55bce
RS
721 if (matchcount == 1 && bestmatchsize == XSTRING (file)->size)
722 return Qt;
24c2a54f
RS
723 bestmatch = Fsubstring (bestmatch, make_number (0),
724 make_number (bestmatchsize));
725 /* Now that we got the right initial segment of BESTMATCH,
726 decode it from the coding system in use. */
bd33479f 727 bestmatch = DECODE_FILE (bestmatch);
24c2a54f
RS
728 return bestmatch;
729
14d55bce
RS
730 quit:
731 if (d) closedir (d);
732 Vquit_flag = Qnil;
733 return Fsignal (Qquit, Qnil);
734}
735
dfcf069d 736static int
14d55bce
RS
737file_name_completion_stat (dirname, dp, st_addr)
738 Lisp_Object dirname;
739 DIRENTRY *dp;
740 struct stat *st_addr;
741{
742 int len = NAMLEN (dp);
743 int pos = XSTRING (dirname)->size;
7e3cf34f 744 int value;
14d55bce
RS
745 char *fullname = (char *) alloca (len + pos + 2);
746
04924ee3
RS
747#ifdef MSDOS
748#if __DJGPP__ > 1
749 /* Some fields of struct stat are *very* expensive to compute on MS-DOS,
750 but aren't required here. Avoid computing the following fields:
751 st_inode, st_size and st_nlink for directories, and the execute bits
752 in st_mode for non-directory files with non-standard extensions. */
753
754 unsigned short save_djstat_flags = _djstat_flags;
755
756 _djstat_flags = _STAT_INODE | _STAT_EXEC_MAGIC | _STAT_DIRSIZE;
757#endif /* __DJGPP__ > 1 */
758#endif /* MSDOS */
759
14d55bce
RS
760 bcopy (XSTRING (dirname)->data, fullname, pos);
761#ifndef VMS
0b39d75d
RS
762 if (!IS_DIRECTORY_SEP (fullname[pos - 1]))
763 fullname[pos++] = DIRECTORY_SEP;
14d55bce
RS
764#endif
765
766 bcopy (dp->d_name, fullname + pos, len);
767 fullname[pos + len] = 0;
768
a889bd0e 769#ifdef S_IFLNK
7e3cf34f
RS
770 /* We want to return success if a link points to a nonexistent file,
771 but we want to return the status for what the link points to,
772 in case it is a directory. */
773 value = lstat (fullname, st_addr);
774 stat (fullname, st_addr);
775 return value;
a889bd0e 776#else
04924ee3
RS
777 value = stat (fullname, st_addr);
778#ifdef MSDOS
779#if __DJGPP__ > 1
780 _djstat_flags = save_djstat_flags;
781#endif /* __DJGPP__ > 1 */
782#endif /* MSDOS */
783 return value;
784#endif /* S_IFLNK */
14d55bce
RS
785}
786\f
3ed991aa
RS
787#ifdef VMS
788
789DEFUN ("file-name-all-versions", Ffile_name_all_versions,
790 Sfile_name_all_versions, 2, 2, 0,
23bd240f
EN
791 "Return a list of all versions of file name FILE in directory DIRECTORY.")
792 (file, directory)
793 Lisp_Object file, directory;
3ed991aa 794{
23bd240f 795 return file_name_completion (file, directory, 1, 1);
3ed991aa
RS
796}
797
798DEFUN ("file-version-limit", Ffile_version_limit, Sfile_version_limit, 1, 1, 0,
799 "Return the maximum number of versions allowed for FILE.\n\
800Returns nil if the file cannot be opened or if there is no version limit.")
801 (filename)
802 Lisp_Object filename;
803{
804 Lisp_Object retval;
805 struct FAB fab;
806 struct RAB rab;
807 struct XABFHC xabfhc;
808 int status;
809
810 filename = Fexpand_file_name (filename, Qnil);
811 fab = cc$rms_fab;
812 xabfhc = cc$rms_xabfhc;
813 fab.fab$l_fna = XSTRING (filename)->data;
814 fab.fab$b_fns = strlen (fab.fab$l_fna);
815 fab.fab$l_xab = (char *) &xabfhc;
816 status = sys$open (&fab, 0, 0);
817 if (status != RMS$_NORMAL) /* Probably non-existent file */
818 return Qnil;
819 sys$close (&fab, 0, 0);
820 if (xabfhc.xab$w_verlimit == 32767)
821 return Qnil; /* No version limit */
822 else
823 return make_number (xabfhc.xab$w_verlimit);
824}
825
826#endif /* VMS */
827\f
14d55bce
RS
828Lisp_Object
829make_time (time)
e5124be7 830 time_t time;
14d55bce
RS
831{
832 return Fcons (make_number (time >> 16),
833 Fcons (make_number (time & 0177777), Qnil));
834}
835
836DEFUN ("file-attributes", Ffile_attributes, Sfile_attributes, 1, 1, 0,
837 "Return a list of attributes of file FILENAME.\n\
838Value is nil if specified file cannot be opened.\n\
839Otherwise, list elements are:\n\
840 0. t for directory, string (name linked to) for symbolic link, or nil.\n\
841 1. Number of links to file.\n\
842 2. File uid.\n\
843 3. File gid.\n\
844 4. Last access time, as a list of two integers.\n\
845 First integer has high-order 16 bits of time, second has low 16 bits.\n\
846 5. Last modification time, likewise.\n\
847 6. Last status change time, likewise.\n\
cb1846b4
EZ
848 7. Size in bytes.\n\
849 This is a floating point number if the size is too large for an integer.\n\
14d55bce
RS
850 8. File modes, as a string of ten letters or dashes as in ls -l.\n\
851 9. t iff file's gid would change if file were deleted and recreated.\n\
cb1846b4 85210. inode number. If inode number is larger than the Emacs integer,\n\
6d4e6528
RS
853 this is a cons cell containing two integers: first the high part,\n\
854 then the low 16 bits.\n\
61984904
EZ
85511. Device number. If it is larger than the Emacs integer, this is\n\
856 a cons cell, similar to the inode number.\n\
14d55bce 857\n\
ccbcf979 858If file does not exist, returns nil.")
14d55bce
RS
859 (filename)
860 Lisp_Object filename;
861{
862 Lisp_Object values[12];
24c2a54f 863 Lisp_Object encoded;
14d55bce 864 struct stat s;
0a974c85 865#if defined (BSD4_2) || defined (BSD4_3)
b3edfc9b 866 Lisp_Object dirname;
14d55bce 867 struct stat sdir;
b3edfc9b 868#endif
14d55bce 869 char modes[10];
32f4334d 870 Lisp_Object handler;
14d55bce
RS
871
872 filename = Fexpand_file_name (filename, Qnil);
32f4334d
RS
873
874 /* If the file name has special constructs in it,
875 call the corresponding file handler. */
a617e913 876 handler = Ffind_file_name_handler (filename, Qfile_attributes);
32f4334d
RS
877 if (!NILP (handler))
878 return call2 (handler, Qfile_attributes, filename);
879
24c2a54f
RS
880 encoded = ENCODE_FILE (filename);
881
882 if (lstat (XSTRING (encoded)->data, &s) < 0)
14d55bce
RS
883 return Qnil;
884
885 switch (s.st_mode & S_IFMT)
886 {
887 default:
888 values[0] = Qnil; break;
889 case S_IFDIR:
890 values[0] = Qt; break;
891#ifdef S_IFLNK
892 case S_IFLNK:
893 values[0] = Ffile_symlink_p (filename); break;
894#endif
895 }
896 values[1] = make_number (s.st_nlink);
897 values[2] = make_number (s.st_uid);
898 values[3] = make_number (s.st_gid);
899 values[4] = make_time (s.st_atime);
900 values[5] = make_time (s.st_mtime);
901 values[6] = make_time (s.st_ctime);
68c45bf0 902 values[7] = make_number (s.st_size);
cb1846b4 903 /* If the size is out of range for an integer, return a float. */
60fc6069 904 if (XINT (values[7]) != s.st_size)
cb1846b4 905 values[7] = make_float ((double)s.st_size);
14d55bce
RS
906 filemodestring (&s, modes);
907 values[8] = make_string (modes, 10);
0a974c85 908#if defined (BSD4_2) || defined (BSD4_3) /* file gid will be dir gid */
14d55bce 909 dirname = Ffile_name_directory (filename);
24c2a54f
RS
910 if (! NILP (dirname))
911 encoded = ENCODE_FILE (dirname);
912 if (! NILP (dirname) && stat (XSTRING (encoded)->data, &sdir) == 0)
14d55bce
RS
913 values[9] = (sdir.st_gid != s.st_gid) ? Qt : Qnil;
914 else /* if we can't tell, assume worst */
915 values[9] = Qt;
916#else /* file gid will be egid */
917 values[9] = (s.st_gid != getegid ()) ? Qt : Qnil;
918#endif /* BSD4_2 (or BSD4_3) */
ce4200f6 919 /* Cast -1 to avoid warning if int is not as wide as VALBITS. */
f8edfd76 920 if (FIXNUM_OVERFLOW_P (s.st_ino))
4c637faa
RS
921 /* To allow inode numbers larger than VALBITS, separate the bottom
922 16 bits. */
923 values[10] = Fcons (make_number (s.st_ino >> 16),
924 make_number (s.st_ino & 0xffff));
925 else
926 /* But keep the most common cases as integers. */
927 values[10] = make_number (s.st_ino);
68c45bf0
PE
928
929 /* Likewise for device. */
f8edfd76 930 if (FIXNUM_OVERFLOW_P (s.st_dev))
68c45bf0
PE
931 values[11] = Fcons (make_number (s.st_dev >> 16),
932 make_number (s.st_dev & 0xffff));
933 else
934 values[11] = make_number (s.st_dev);
935
14d55bce
RS
936 return Flist (sizeof(values) / sizeof(values[0]), values);
937}
4424b255
GV
938
939DEFUN ("file-attributes-lessp", Ffile_attributes_lessp, Sfile_attributes_lessp, 2, 2, 0,
940 "Return t if first arg file attributes list is less than second.\n\
941Comparison is in lexicographic order and case is significant.")
942 (f1, f2)
943 Lisp_Object f1, f2;
944{
945 return Fstring_lessp (Fcar (f1), Fcar (f2));
946}
14d55bce 947\f
dfcf069d 948void
14d55bce
RS
949syms_of_dired ()
950{
32f4334d 951 Qdirectory_files = intern ("directory-files");
4424b255 952 Qdirectory_files_and_attributes = intern ("directory-files-and-attributes");
32f4334d
RS
953 Qfile_name_completion = intern ("file-name-completion");
954 Qfile_name_all_completions = intern ("file-name-all-completions");
434e6714 955 Qfile_attributes = intern ("file-attributes");
4424b255 956 Qfile_attributes_lessp = intern ("file-attributes-lessp");
32f4334d 957
a2d3836c 958 staticpro (&Qdirectory_files);
4424b255 959 staticpro (&Qdirectory_files_and_attributes);
a2d3836c
EN
960 staticpro (&Qfile_name_completion);
961 staticpro (&Qfile_name_all_completions);
962 staticpro (&Qfile_attributes);
4424b255 963 staticpro (&Qfile_attributes_lessp);
a2d3836c 964
14d55bce 965 defsubr (&Sdirectory_files);
4424b255 966 defsubr (&Sdirectory_files_and_attributes);
14d55bce
RS
967 defsubr (&Sfile_name_completion);
968#ifdef VMS
969 defsubr (&Sfile_name_all_versions);
3ed991aa 970 defsubr (&Sfile_version_limit);
14d55bce
RS
971#endif /* VMS */
972 defsubr (&Sfile_name_all_completions);
973 defsubr (&Sfile_attributes);
4424b255 974 defsubr (&Sfile_attributes_lessp);
14d55bce
RS
975
976#ifdef VMS
977 Qcompletion_ignore_case = intern ("completion-ignore-case");
978 staticpro (&Qcompletion_ignore_case);
979#endif /* VMS */
980
981 DEFVAR_LISP ("completion-ignored-extensions", &Vcompletion_ignored_extensions,
982 "*Completion ignores filenames ending in any string in this list.\n\
d013f29b
EZ
983Directories are ignored if they match any string in this list which\n\
984ends in a slash.\n\
14d55bce
RS
985This variable does not affect lists of possible completions,\n\
986but does affect the commands that actually do completions.");
987 Vcompletion_ignored_extensions = Qnil;
988}