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