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