(XTread_socket) <PropertyNotify>: Put the code
[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 {
70949dac 598 tem = Fstring_match (XCAR (regexps), elt, zero);
f676868d
KH
599 if (NILP (tem))
600 break;
601 }
602 if (CONSP (regexps))
603 continue;
604 }
14d55bce 605
f676868d 606 /* Update computation of how much all possible completions match */
14d55bce 607
f676868d
KH
608 matchcount++;
609
610 if (all_flag || NILP (bestmatch))
611 {
612 /* This is a possible completion */
613 if (directoryp)
14d55bce 614 {
f676868d
KH
615 /* This completion is a directory; make it end with '/' */
616 name = Ffile_name_as_directory (make_string (dp->d_name, len));
617 }
618 else
619 name = make_string (dp->d_name, len);
620 if (all_flag)
621 {
bd33479f 622 name = DECODE_FILE (name);
f676868d 623 bestmatch = Fcons (name, bestmatch);
14d55bce
RS
624 }
625 else
626 {
f676868d
KH
627 bestmatch = name;
628 bestmatchsize = XSTRING (name)->size;
629 }
630 }
631 else
632 {
633 compare = min (bestmatchsize, len);
634 p1 = XSTRING (bestmatch)->data;
635 p2 = (unsigned char *) dp->d_name;
636 matchsize = scmp(p1, p2, compare);
637 if (matchsize < 0)
638 matchsize = compare;
639 if (completion_ignore_case)
640 {
641 /* If this is an exact match except for case,
642 use it as the best match rather than one that is not
643 an exact match. This way, we get the case pattern
644 of the actual match. */
f5ec5d3d
RS
645 /* This tests that the current file is an exact match
646 but BESTMATCH is not (it is too long). */
f676868d
KH
647 if ((matchsize == len
648 && matchsize + !!directoryp
649 < XSTRING (bestmatch)->size)
650 ||
651 /* If there is no exact match ignoring case,
652 prefer a match that does not change the case
653 of the input. */
f5ec5d3d
RS
654 /* If there is more than one exact match aside from
655 case, and one of them is exact including case,
656 prefer that one. */
657 /* This == checks that, of current file and BESTMATCH,
658 either both or neither are exact. */
f676868d
KH
659 (((matchsize == len)
660 ==
661 (matchsize + !!directoryp
662 == XSTRING (bestmatch)->size))
24c2a54f
RS
663 && !bcmp (p2, XSTRING (encoded_file)->data, XSTRING (encoded_file)->size)
664 && bcmp (p1, XSTRING (encoded_file)->data, XSTRING (encoded_file)->size)))
97e98a56 665 {
f676868d
KH
666 bestmatch = make_string (dp->d_name, len);
667 if (directoryp)
668 bestmatch = Ffile_name_as_directory (bestmatch);
97e98a56 669 }
14d55bce 670 }
f676868d
KH
671
672 /* If this dirname all matches, see if implicit following
673 slash does too. */
674 if (directoryp
675 && compare == matchsize
676 && bestmatchsize > matchsize
0b39d75d 677 && IS_ANY_SEP (p1[matchsize]))
f676868d
KH
678 matchsize++;
679 bestmatchsize = matchsize;
14d55bce
RS
680 }
681 }
682 closedir (d);
683 }
684
3fcc88cc
RS
685 UNGCPRO;
686 bestmatch = unbind_to (count, bestmatch);
14d55bce 687
265a9e55 688 if (all_flag || NILP (bestmatch))
24c2a54f 689 {
bd33479f
KH
690 if (STRINGP (bestmatch))
691 bestmatch = DECODE_FILE (bestmatch);
24c2a54f
RS
692 return bestmatch;
693 }
14d55bce
RS
694 if (matchcount == 1 && bestmatchsize == XSTRING (file)->size)
695 return Qt;
24c2a54f
RS
696 bestmatch = Fsubstring (bestmatch, make_number (0),
697 make_number (bestmatchsize));
698 /* Now that we got the right initial segment of BESTMATCH,
699 decode it from the coding system in use. */
bd33479f 700 bestmatch = DECODE_FILE (bestmatch);
24c2a54f
RS
701 return bestmatch;
702
14d55bce
RS
703 quit:
704 if (d) closedir (d);
705 Vquit_flag = Qnil;
706 return Fsignal (Qquit, Qnil);
707}
708
dfcf069d 709static int
14d55bce
RS
710file_name_completion_stat (dirname, dp, st_addr)
711 Lisp_Object dirname;
712 DIRENTRY *dp;
713 struct stat *st_addr;
714{
715 int len = NAMLEN (dp);
716 int pos = XSTRING (dirname)->size;
7e3cf34f 717 int value;
14d55bce
RS
718 char *fullname = (char *) alloca (len + pos + 2);
719
04924ee3
RS
720#ifdef MSDOS
721#if __DJGPP__ > 1
722 /* Some fields of struct stat are *very* expensive to compute on MS-DOS,
723 but aren't required here. Avoid computing the following fields:
724 st_inode, st_size and st_nlink for directories, and the execute bits
725 in st_mode for non-directory files with non-standard extensions. */
726
727 unsigned short save_djstat_flags = _djstat_flags;
728
729 _djstat_flags = _STAT_INODE | _STAT_EXEC_MAGIC | _STAT_DIRSIZE;
730#endif /* __DJGPP__ > 1 */
731#endif /* MSDOS */
732
14d55bce
RS
733 bcopy (XSTRING (dirname)->data, fullname, pos);
734#ifndef VMS
0b39d75d
RS
735 if (!IS_DIRECTORY_SEP (fullname[pos - 1]))
736 fullname[pos++] = DIRECTORY_SEP;
14d55bce
RS
737#endif
738
739 bcopy (dp->d_name, fullname + pos, len);
740 fullname[pos + len] = 0;
741
a889bd0e 742#ifdef S_IFLNK
7e3cf34f
RS
743 /* We want to return success if a link points to a nonexistent file,
744 but we want to return the status for what the link points to,
745 in case it is a directory. */
746 value = lstat (fullname, st_addr);
747 stat (fullname, st_addr);
748 return value;
a889bd0e 749#else
04924ee3
RS
750 value = stat (fullname, st_addr);
751#ifdef MSDOS
752#if __DJGPP__ > 1
753 _djstat_flags = save_djstat_flags;
754#endif /* __DJGPP__ > 1 */
755#endif /* MSDOS */
756 return value;
757#endif /* S_IFLNK */
14d55bce
RS
758}
759\f
3ed991aa
RS
760#ifdef VMS
761
762DEFUN ("file-name-all-versions", Ffile_name_all_versions,
763 Sfile_name_all_versions, 2, 2, 0,
23bd240f
EN
764 "Return a list of all versions of file name FILE in directory DIRECTORY.")
765 (file, directory)
766 Lisp_Object file, directory;
3ed991aa 767{
23bd240f 768 return file_name_completion (file, directory, 1, 1);
3ed991aa
RS
769}
770
771DEFUN ("file-version-limit", Ffile_version_limit, Sfile_version_limit, 1, 1, 0,
772 "Return the maximum number of versions allowed for FILE.\n\
773Returns nil if the file cannot be opened or if there is no version limit.")
774 (filename)
775 Lisp_Object filename;
776{
777 Lisp_Object retval;
778 struct FAB fab;
779 struct RAB rab;
780 struct XABFHC xabfhc;
781 int status;
782
783 filename = Fexpand_file_name (filename, Qnil);
784 fab = cc$rms_fab;
785 xabfhc = cc$rms_xabfhc;
786 fab.fab$l_fna = XSTRING (filename)->data;
787 fab.fab$b_fns = strlen (fab.fab$l_fna);
788 fab.fab$l_xab = (char *) &xabfhc;
789 status = sys$open (&fab, 0, 0);
790 if (status != RMS$_NORMAL) /* Probably non-existent file */
791 return Qnil;
792 sys$close (&fab, 0, 0);
793 if (xabfhc.xab$w_verlimit == 32767)
794 return Qnil; /* No version limit */
795 else
796 return make_number (xabfhc.xab$w_verlimit);
797}
798
799#endif /* VMS */
800\f
14d55bce
RS
801Lisp_Object
802make_time (time)
e5124be7 803 time_t time;
14d55bce
RS
804{
805 return Fcons (make_number (time >> 16),
806 Fcons (make_number (time & 0177777), Qnil));
807}
808
809DEFUN ("file-attributes", Ffile_attributes, Sfile_attributes, 1, 1, 0,
810 "Return a list of attributes of file FILENAME.\n\
811Value is nil if specified file cannot be opened.\n\
812Otherwise, list elements are:\n\
813 0. t for directory, string (name linked to) for symbolic link, or nil.\n\
814 1. Number of links to file.\n\
815 2. File uid.\n\
816 3. File gid.\n\
817 4. Last access time, as a list of two integers.\n\
818 First integer has high-order 16 bits of time, second has low 16 bits.\n\
819 5. Last modification time, likewise.\n\
820 6. Last status change time, likewise.\n\
cb1846b4
EZ
821 7. Size in bytes.\n\
822 This is a floating point number if the size is too large for an integer.\n\
14d55bce
RS
823 8. File modes, as a string of ten letters or dashes as in ls -l.\n\
824 9. t iff file's gid would change if file were deleted and recreated.\n\
cb1846b4 82510. inode number. If inode number is larger than the Emacs integer,\n\
6d4e6528
RS
826 this is a cons cell containing two integers: first the high part,\n\
827 then the low 16 bits.\n\
14d55bce
RS
82811. Device number.\n\
829\n\
ccbcf979 830If file does not exist, returns nil.")
14d55bce
RS
831 (filename)
832 Lisp_Object filename;
833{
834 Lisp_Object values[12];
24c2a54f 835 Lisp_Object encoded;
14d55bce 836 struct stat s;
0a974c85 837#if defined (BSD4_2) || defined (BSD4_3)
b3edfc9b 838 Lisp_Object dirname;
14d55bce 839 struct stat sdir;
b3edfc9b 840#endif
14d55bce 841 char modes[10];
32f4334d 842 Lisp_Object handler;
14d55bce
RS
843
844 filename = Fexpand_file_name (filename, Qnil);
32f4334d
RS
845
846 /* If the file name has special constructs in it,
847 call the corresponding file handler. */
a617e913 848 handler = Ffind_file_name_handler (filename, Qfile_attributes);
32f4334d
RS
849 if (!NILP (handler))
850 return call2 (handler, Qfile_attributes, filename);
851
24c2a54f
RS
852 encoded = ENCODE_FILE (filename);
853
854 if (lstat (XSTRING (encoded)->data, &s) < 0)
14d55bce
RS
855 return Qnil;
856
857 switch (s.st_mode & S_IFMT)
858 {
859 default:
860 values[0] = Qnil; break;
861 case S_IFDIR:
862 values[0] = Qt; break;
863#ifdef S_IFLNK
864 case S_IFLNK:
865 values[0] = Ffile_symlink_p (filename); break;
866#endif
867 }
868 values[1] = make_number (s.st_nlink);
869 values[2] = make_number (s.st_uid);
870 values[3] = make_number (s.st_gid);
871 values[4] = make_time (s.st_atime);
872 values[5] = make_time (s.st_mtime);
873 values[6] = make_time (s.st_ctime);
68c45bf0 874 values[7] = make_number (s.st_size);
cb1846b4 875 /* If the size is out of range for an integer, return a float. */
60fc6069 876 if (XINT (values[7]) != s.st_size)
cb1846b4 877 values[7] = make_float ((double)s.st_size);
14d55bce
RS
878 filemodestring (&s, modes);
879 values[8] = make_string (modes, 10);
0a974c85 880#if defined (BSD4_2) || defined (BSD4_3) /* file gid will be dir gid */
14d55bce 881 dirname = Ffile_name_directory (filename);
24c2a54f
RS
882 if (! NILP (dirname))
883 encoded = ENCODE_FILE (dirname);
884 if (! NILP (dirname) && stat (XSTRING (encoded)->data, &sdir) == 0)
14d55bce
RS
885 values[9] = (sdir.st_gid != s.st_gid) ? Qt : Qnil;
886 else /* if we can't tell, assume worst */
887 values[9] = Qt;
888#else /* file gid will be egid */
889 values[9] = (s.st_gid != getegid ()) ? Qt : Qnil;
890#endif /* BSD4_2 (or BSD4_3) */
ce4200f6
RS
891 /* Cast -1 to avoid warning if int is not as wide as VALBITS. */
892 if (s.st_ino & (((EMACS_INT) (-1)) << VALBITS))
4c637faa
RS
893 /* To allow inode numbers larger than VALBITS, separate the bottom
894 16 bits. */
895 values[10] = Fcons (make_number (s.st_ino >> 16),
896 make_number (s.st_ino & 0xffff));
897 else
898 /* But keep the most common cases as integers. */
899 values[10] = make_number (s.st_ino);
68c45bf0
PE
900
901 /* Likewise for device. */
902 if (s.st_dev & (((EMACS_INT) (-1)) << VALBITS))
903 values[11] = Fcons (make_number (s.st_dev >> 16),
904 make_number (s.st_dev & 0xffff));
905 else
906 values[11] = make_number (s.st_dev);
907
14d55bce
RS
908 return Flist (sizeof(values) / sizeof(values[0]), values);
909}
4424b255
GV
910
911DEFUN ("file-attributes-lessp", Ffile_attributes_lessp, Sfile_attributes_lessp, 2, 2, 0,
912 "Return t if first arg file attributes list is less than second.\n\
913Comparison is in lexicographic order and case is significant.")
914 (f1, f2)
915 Lisp_Object f1, f2;
916{
917 return Fstring_lessp (Fcar (f1), Fcar (f2));
918}
14d55bce 919\f
dfcf069d 920void
14d55bce
RS
921syms_of_dired ()
922{
32f4334d 923 Qdirectory_files = intern ("directory-files");
4424b255 924 Qdirectory_files_and_attributes = intern ("directory-files-and-attributes");
32f4334d
RS
925 Qfile_name_completion = intern ("file-name-completion");
926 Qfile_name_all_completions = intern ("file-name-all-completions");
434e6714 927 Qfile_attributes = intern ("file-attributes");
4424b255 928 Qfile_attributes_lessp = intern ("file-attributes-lessp");
32f4334d 929
a2d3836c 930 staticpro (&Qdirectory_files);
4424b255 931 staticpro (&Qdirectory_files_and_attributes);
a2d3836c
EN
932 staticpro (&Qfile_name_completion);
933 staticpro (&Qfile_name_all_completions);
934 staticpro (&Qfile_attributes);
4424b255 935 staticpro (&Qfile_attributes_lessp);
a2d3836c 936
14d55bce 937 defsubr (&Sdirectory_files);
4424b255 938 defsubr (&Sdirectory_files_and_attributes);
14d55bce
RS
939 defsubr (&Sfile_name_completion);
940#ifdef VMS
941 defsubr (&Sfile_name_all_versions);
3ed991aa 942 defsubr (&Sfile_version_limit);
14d55bce
RS
943#endif /* VMS */
944 defsubr (&Sfile_name_all_completions);
945 defsubr (&Sfile_attributes);
4424b255 946 defsubr (&Sfile_attributes_lessp);
14d55bce
RS
947
948#ifdef VMS
949 Qcompletion_ignore_case = intern ("completion-ignore-case");
950 staticpro (&Qcompletion_ignore_case);
951#endif /* VMS */
952
953 DEFVAR_LISP ("completion-ignored-extensions", &Vcompletion_ignored_extensions,
954 "*Completion ignores filenames ending in any string in this list.\n\
955This variable does not affect lists of possible completions,\n\
956but does affect the commands that actually do completions.");
957 Vcompletion_ignored_extensions = Qnil;
958}