*** 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"
d2f6dae8 91#include "character.h"
bd33479f
KH
92#include "charset.h"
93#include "coding.h"
14d55bce 94#include "regex.h"
14d55bce 95
e50c66d3
KH
96/* Returns a search buffer, with a fastmap allocated and ready to go. */
97extern struct re_pattern_buffer *compile_pattern ();
c7e466e1 98
851cab13
DL
99/* From filemode.c. Can't go in Lisp.h because of `stat'. */
100extern void filemodestring P_ ((struct stat *, char *));
101
14d55bce
RS
102/* if system does not have symbolic links, it does not have lstat.
103 In that case, use ordinary stat instead. */
104
105#ifndef S_IFLNK
106#define lstat stat
107#endif
108
97e98a56 109extern int completion_ignore_case;
f676868d 110extern Lisp_Object Vcompletion_regexp_list;
bd33479f 111extern Lisp_Object Vfile_name_coding_system, Vdefault_file_name_coding_system;
ccbcf979 112
14d55bce 113Lisp_Object Vcompletion_ignored_extensions;
14d55bce 114Lisp_Object Qcompletion_ignore_case;
32f4334d 115Lisp_Object Qdirectory_files;
4424b255 116Lisp_Object Qdirectory_files_and_attributes;
32f4334d
RS
117Lisp_Object Qfile_name_completion;
118Lisp_Object Qfile_name_all_completions;
434e6714 119Lisp_Object Qfile_attributes;
4424b255 120Lisp_Object Qfile_attributes_lessp;
b3f04ced
RS
121
122static int scmp P_ ((unsigned char *, unsigned char *, int));
14d55bce 123\f
2488aba5
AI
124
125Lisp_Object
126directory_files_internal_unwind (dh)
127 Lisp_Object dh;
128{
129 DIR *d = (DIR *) ((XINT (XCAR (dh)) << 16) + XINT (XCDR (dh)));
130 closedir (d);
131 return Qnil;
132}
133
177c0ea7 134/* Function shared by Fdirectory_files and Fdirectory_files_and_attributes.
4424b255
GV
135 When ATTRS is zero, return a list of directory filenames; when
136 non-zero, return a list of directory filenames and their attributes. */
f69f9da1 137
4424b255
GV
138Lisp_Object
139directory_files_internal (directory, full, match, nosort, attrs)
23bd240f 140 Lisp_Object directory, full, match, nosort;
4424b255 141 int attrs;
14d55bce
RS
142{
143 DIR *d;
388ac098
GM
144 int directory_nbytes;
145 Lisp_Object list, dirfilename, encoded_directory;
6bbd7a29 146 struct re_pattern_buffer *bufp = NULL;
96d64004 147 int needsep = 0;
aed13378 148 int count = SPECPDL_INDEX ();
388ac098 149 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
8e42f043
GM
150 DIRENTRY *dp;
151 int retry_p;
32f4334d 152
96d64004 153 /* Because of file name handlers, these functions might call
6155fae1 154 Ffuncall, and cause a GC. */
388ac098
GM
155 list = encoded_directory = dirfilename = Qnil;
156 GCPRO5 (match, directory, list, dirfilename, encoded_directory);
96d64004 157 dirfilename = Fdirectory_file_name (directory);
6155fae1 158
265a9e55 159 if (!NILP (match))
14d55bce 160 {
b7826503 161 CHECK_STRING (match);
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 189 retry:
177c0ea7 190
d5db4077 191 d = opendir (SDATA (dirfilename));
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
d5db4077 202 directory_nbytes = SBYTES (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 207 if (directory_nbytes == 0
d5db4077 208 || !IS_ANY_SEP (SREF (directory, 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
177c0ea7 222
f69f9da1
GM
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 235 GCPRO2 (finalname, name);
177c0ea7 236
388ac098
GM
237 /* Note: ENCODE_FILE can GC; it should protect its argument,
238 though. */
239 name = DECODE_FILE (name);
d5db4077 240 len = SBYTES (name);
e23f810c 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)
d5db4077 248 || (0 <= re_search (bufp, SDATA (name), 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);
d5db4077 262 bcopy (SDATA (directory), SDATA (fullname),
388ac098 263 directory_nbytes);
177c0ea7 264
5617588f 265 if (needsep)
d549c5db 266 SSET (fullname, directory_nbytes, DIRECTORY_SEP);
177c0ea7 267
d5db4077
KR
268 bcopy (SDATA (name),
269 SDATA (fullname) + directory_nbytes + needsep,
388ac098 270 len);
177c0ea7 271
d5db4077 272 nchars = chars_in_text (SDATA (fullname), nbytes);
388ac098
GM
273
274 /* Some bug somewhere. */
275 if (nchars > nbytes)
276 abort ();
177c0ea7 277
437fcd47 278 STRING_SET_CHARS (fullname, nchars);
388ac098 279 if (nchars == nbytes)
d5db4077 280 STRING_SET_UNIBYTE (fullname);
177c0ea7 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);
177c0ea7 331
388ac098 332 RETURN_UNGCPRO (list);
14d55bce 333}
4424b255
GV
334
335
336DEFUN ("directory-files", Fdirectory_files, Sdirectory_files, 1, 4, 0,
335c5470
PJ
337 doc: /* Return a list of names of files in DIRECTORY.
338There are three optional arguments:
339If FULL is non-nil, return absolute file names. Otherwise return names
340 that are relative to the specified directory.
341If MATCH is non-nil, mention only file names that match the regexp MATCH.
342If NOSORT is non-nil, the list is not sorted--its order is unpredictable.
343 NOSORT is useful if you plan to sort the result yourself. */)
344 (directory, full, match, nosort)
4424b255
GV
345 Lisp_Object directory, full, match, nosort;
346{
347 Lisp_Object handler;
4ece81a6 348 directory = Fexpand_file_name (directory, Qnil);
4424b255
GV
349
350 /* If the file name has special constructs in it,
351 call the corresponding file handler. */
352 handler = Ffind_file_name_handler (directory, Qdirectory_files);
353 if (!NILP (handler))
354 {
355 Lisp_Object args[6];
356
357 args[0] = handler;
358 args[1] = Qdirectory_files;
359 args[2] = directory;
360 args[3] = full;
361 args[4] = match;
362 args[5] = nosort;
363 return Ffuncall (6, args);
364 }
365
366 return directory_files_internal (directory, full, match, nosort, 0);
367}
368
335c5470
PJ
369DEFUN ("directory-files-and-attributes", Fdirectory_files_and_attributes,
370 Sdirectory_files_and_attributes, 1, 4, 0,
371 doc: /* Return a list of names of files and their attributes in DIRECTORY.
372There are three optional arguments:
373If FULL is non-nil, return absolute file names. Otherwise return names
374 that are relative to the specified directory.
375If MATCH is non-nil, mention only file names that match the regexp MATCH.
376If NOSORT is non-nil, the list is not sorted--its order is unpredictable.
377 NOSORT is useful if you plan to sort the result yourself. */)
378 (directory, full, match, nosort)
4424b255
GV
379 Lisp_Object directory, full, match, nosort;
380{
381 Lisp_Object handler;
4ece81a6 382 directory = Fexpand_file_name (directory, Qnil);
4424b255
GV
383
384 /* If the file name has special constructs in it,
385 call the corresponding file handler. */
386 handler = Ffind_file_name_handler (directory, Qdirectory_files_and_attributes);
387 if (!NILP (handler))
388 {
389 Lisp_Object args[6];
390
391 args[0] = handler;
392 args[1] = Qdirectory_files_and_attributes;
393 args[2] = directory;
394 args[3] = full;
395 args[4] = match;
396 args[5] = nosort;
397 return Ffuncall (6, args);
398 }
399
400 return directory_files_internal (directory, full, match, nosort, 1);
401}
402
14d55bce
RS
403\f
404Lisp_Object file_name_completion ();
405
406DEFUN ("file-name-completion", Ffile_name_completion, Sfile_name_completion,
335c5470
PJ
407 2, 2, 0,
408 doc: /* Complete file name FILE in directory DIRECTORY.
409Returns the longest string
410common to all file names in DIRECTORY that start with FILE.
411If there is only one and FILE matches it exactly, returns t.
412Returns nil if DIR contains no name starting with FILE.
413
414This function ignores some of the possible completions as
415determined by the variable `completion-ignored-extensions', which see. */)
416 (file, directory)
23bd240f 417 Lisp_Object file, directory;
14d55bce 418{
32f4334d 419 Lisp_Object handler;
32f4334d 420
8436e231 421 /* If the directory name has special constructs in it,
32f4334d 422 call the corresponding file handler. */
23bd240f 423 handler = Ffind_file_name_handler (directory, Qfile_name_completion);
32f4334d 424 if (!NILP (handler))
23bd240f 425 return call3 (handler, Qfile_name_completion, file, directory);
32f4334d 426
8436e231
RS
427 /* If the file name has special constructs in it,
428 call the corresponding file handler. */
429 handler = Ffind_file_name_handler (file, Qfile_name_completion);
430 if (!NILP (handler))
23bd240f 431 return call3 (handler, Qfile_name_completion, file, directory);
8436e231 432
23bd240f 433 return file_name_completion (file, directory, 0, 0);
14d55bce
RS
434}
435
436DEFUN ("file-name-all-completions", Ffile_name_all_completions,
335c5470
PJ
437 Sfile_name_all_completions, 2, 2, 0,
438 doc: /* Return a list of all completions of file name FILE in directory DIRECTORY.
439These are all file names in directory DIRECTORY which begin with FILE. */)
440 (file, directory)
23bd240f 441 Lisp_Object file, directory;
14d55bce 442{
32f4334d
RS
443 Lisp_Object handler;
444
8436e231 445 /* If the directory name has special constructs in it,
32f4334d 446 call the corresponding file handler. */
23bd240f 447 handler = Ffind_file_name_handler (directory, Qfile_name_all_completions);
32f4334d 448 if (!NILP (handler))
23bd240f 449 return call3 (handler, Qfile_name_all_completions, file, directory);
32f4334d 450
8436e231
RS
451 /* If the file name has special constructs in it,
452 call the corresponding file handler. */
453 handler = Ffind_file_name_handler (file, Qfile_name_all_completions);
454 if (!NILP (handler))
23bd240f 455 return call3 (handler, Qfile_name_all_completions, file, directory);
8436e231 456
23bd240f 457 return file_name_completion (file, directory, 1, 0);
14d55bce
RS
458}
459
dfcf069d
AS
460static int file_name_completion_stat ();
461
14d55bce
RS
462Lisp_Object
463file_name_completion (file, dirname, all_flag, ver_flag)
464 Lisp_Object file, dirname;
465 int all_flag, ver_flag;
466{
467 DIR *d;
6bbd7a29 468 int bestmatchsize = 0, skip;
14d55bce
RS
469 register int compare, matchsize;
470 unsigned char *p1, *p2;
471 int matchcount = 0;
472 Lisp_Object bestmatch, tem, elt, name;
24c2a54f
RS
473 Lisp_Object encoded_file;
474 Lisp_Object encoded_dir;
14d55bce
RS
475 struct stat st;
476 int directoryp;
477 int passcount;
aed13378 478 int count = SPECPDL_INDEX ();
24c2a54f 479 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
3fcc88cc 480
6bbd7a29
GM
481 elt = Qnil;
482
14d55bce
RS
483#ifdef VMS
484 extern DIRENTRY * readdirver ();
485
486 DIRENTRY *((* readfunc) ());
487
488 /* Filename completion on VMS ignores case, since VMS filesys does. */
489 specbind (Qcompletion_ignore_case, Qt);
490
491 readfunc = readdir;
492 if (ver_flag)
493 readfunc = readdirver;
494 file = Fupcase (file);
495#else /* not VMS */
b7826503 496 CHECK_STRING (file);
14d55bce
RS
497#endif /* not VMS */
498
128ecc89
RS
499#ifdef FILE_SYSTEM_CASE
500 file = FILE_SYSTEM_CASE (file);
501#endif
14d55bce 502 bestmatch = Qnil;
24c2a54f
RS
503 encoded_file = encoded_dir = Qnil;
504 GCPRO5 (file, dirname, bestmatch, encoded_file, encoded_dir);
3fcc88cc 505 dirname = Fexpand_file_name (dirname, Qnil);
14d55bce 506
24c2a54f
RS
507 /* Do completion on the encoded file name
508 because the other names in the directory are (we presume)
509 encoded likewise. We decode the completed string at the end. */
510 encoded_file = ENCODE_FILE (file);
511
512 encoded_dir = ENCODE_FILE (dirname);
513
14d55bce
RS
514 /* With passcount = 0, ignore files that end in an ignored extension.
515 If nothing found then try again with passcount = 1, don't ignore them.
516 If looking for all completions, start with passcount = 1,
517 so always take even the ignored ones.
518
519 ** It would not actually be helpful to the user to ignore any possible
520 completions when making a list of them.** */
521
265a9e55 522 for (passcount = !!all_flag; NILP (bestmatch) && passcount < 2; passcount++)
14d55bce 523 {
c3a3229c
RS
524 int inner_count = SPECPDL_INDEX ();
525
d5db4077 526 d = opendir (SDATA (Fdirectory_file_name (encoded_dir)));
24c2a54f 527 if (!d)
14d55bce
RS
528 report_file_error ("Opening directory", Fcons (dirname, Qnil));
529
62e3881f
RS
530 record_unwind_protect (directory_files_internal_unwind,
531 Fcons (make_number (((unsigned long) d) >> 16),
532 make_number (((unsigned long) d) & 0xffff)));
533
14d55bce
RS
534 /* Loop reading blocks */
535 /* (att3b compiler bug requires do a null comparison this way) */
536 while (1)
537 {
538 DIRENTRY *dp;
539 int len;
540
541#ifdef VMS
542 dp = (*readfunc) (d);
543#else
544 dp = readdir (d);
545#endif
546 if (!dp) break;
547
548 len = NAMLEN (dp);
549
c3a3229c 550 QUIT;
128ecc89 551 if (! DIRENTRY_NONEMPTY (dp)
d5db4077
KR
552 || len < SCHARS (encoded_file)
553 || 0 <= scmp (dp->d_name, SDATA (encoded_file),
554 SCHARS (encoded_file)))
14d55bce
RS
555 continue;
556
24c2a54f 557 if (file_name_completion_stat (encoded_dir, dp, &st) < 0)
14d55bce
RS
558 continue;
559
560 directoryp = ((st.st_mode & S_IFMT) == S_IFDIR);
561 tem = Qnil;
ad456ad4
RS
562 if (directoryp)
563 {
564#ifndef TRIVIAL_DIRECTORY_ENTRY
565#define TRIVIAL_DIRECTORY_ENTRY(n) (!strcmp (n, ".") || !strcmp (n, ".."))
566#endif
567 /* "." and ".." are never interesting as completions, but are
568 actually in the way in a directory contains only one file. */
569 if (!passcount && TRIVIAL_DIRECTORY_ENTRY (dp->d_name))
570 continue;
d5db4077 571 if (!passcount && len > SCHARS (encoded_file))
d013f29b
EZ
572 /* Ignore directories if they match an element of
573 completion-ignored-extensions which ends in a slash. */
574 for (tem = Vcompletion_ignored_extensions;
575 CONSP (tem); tem = XCDR (tem))
576 {
577 int elt_len;
578
579 elt = XCAR (tem);
580 if (!STRINGP (elt))
581 continue;
a74aaa9d
EZ
582 /* Need to encode ELT, since scmp compares unibyte
583 strings only. */
584 elt = ENCODE_FILE (elt);
d5db4077 585 elt_len = SCHARS (elt) - 1; /* -1 for trailing / */
7a8d465a 586 if (elt_len <= 0)
d013f29b 587 continue;
d5db4077 588 p1 = SDATA (elt);
d013f29b
EZ
589 if (p1[elt_len] != '/')
590 continue;
591 skip = len - elt_len;
592 if (skip < 0)
593 continue;
594
595 if (0 <= scmp (dp->d_name + skip, p1, elt_len))
596 continue;
597 break;
598 }
ad456ad4
RS
599 }
600 else
14d55bce
RS
601 {
602 /* Compare extensions-to-be-ignored against end of this file name */
603 /* if name is not an exact match against specified string */
d5db4077 604 if (!passcount && len > SCHARS (encoded_file))
14d55bce
RS
605 /* and exit this for loop if a match is found */
606 for (tem = Vcompletion_ignored_extensions;
70949dac 607 CONSP (tem); tem = XCDR (tem))
14d55bce 608 {
70949dac 609 elt = XCAR (tem);
88cf1852 610 if (!STRINGP (elt)) continue;
a74aaa9d
EZ
611 /* Need to encode ELT, since scmp compares unibyte
612 strings only. */
613 elt = ENCODE_FILE (elt);
d5db4077 614 skip = len - SCHARS (elt);
14d55bce
RS
615 if (skip < 0) continue;
616
617 if (0 <= scmp (dp->d_name + skip,
d5db4077
KR
618 SDATA (elt),
619 SCHARS (elt)))
14d55bce
RS
620 continue;
621 break;
622 }
623 }
624
f676868d
KH
625 /* If an ignored-extensions match was found,
626 don't process this name as a completion. */
627 if (!passcount && CONSP (tem))
628 continue;
629
630 if (!passcount)
14d55bce 631 {
f676868d
KH
632 Lisp_Object regexps;
633 Lisp_Object zero;
617b3bfe 634 XSETFASTINT (zero, 0);
f676868d
KH
635
636 /* Ignore this element if it fails to match all the regexps. */
637 for (regexps = Vcompletion_regexp_list; CONSP (regexps);
70949dac 638 regexps = XCDR (regexps))
f676868d 639 {
1c56232f
EZ
640 tem = Fstring_match (XCAR (regexps),
641 make_string (dp->d_name, len), zero);
f676868d
KH
642 if (NILP (tem))
643 break;
644 }
645 if (CONSP (regexps))
646 continue;
647 }
14d55bce 648
f676868d 649 /* Update computation of how much all possible completions match */
14d55bce 650
f676868d
KH
651 matchcount++;
652
653 if (all_flag || NILP (bestmatch))
654 {
655 /* This is a possible completion */
656 if (directoryp)
14d55bce 657 {
f676868d
KH
658 /* This completion is a directory; make it end with '/' */
659 name = Ffile_name_as_directory (make_string (dp->d_name, len));
660 }
661 else
662 name = make_string (dp->d_name, len);
663 if (all_flag)
664 {
bd33479f 665 name = DECODE_FILE (name);
f676868d 666 bestmatch = Fcons (name, bestmatch);
14d55bce
RS
667 }
668 else
669 {
f676868d 670 bestmatch = name;
d5db4077 671 bestmatchsize = SCHARS (name);
f676868d
KH
672 }
673 }
674 else
675 {
676 compare = min (bestmatchsize, len);
d5db4077 677 p1 = SDATA (bestmatch);
f676868d
KH
678 p2 = (unsigned char *) dp->d_name;
679 matchsize = scmp(p1, p2, compare);
680 if (matchsize < 0)
681 matchsize = compare;
682 if (completion_ignore_case)
683 {
684 /* If this is an exact match except for case,
685 use it as the best match rather than one that is not
686 an exact match. This way, we get the case pattern
687 of the actual match. */
f5ec5d3d
RS
688 /* This tests that the current file is an exact match
689 but BESTMATCH is not (it is too long). */
f676868d 690 if ((matchsize == len
177c0ea7 691 && matchsize + !!directoryp
d5db4077 692 < SCHARS (bestmatch))
f676868d
KH
693 ||
694 /* If there is no exact match ignoring case,
695 prefer a match that does not change the case
696 of the input. */
f5ec5d3d
RS
697 /* If there is more than one exact match aside from
698 case, and one of them is exact including case,
699 prefer that one. */
700 /* This == checks that, of current file and BESTMATCH,
701 either both or neither are exact. */
f676868d
KH
702 (((matchsize == len)
703 ==
177c0ea7 704 (matchsize + !!directoryp
d5db4077
KR
705 == SCHARS (bestmatch)))
706 && !bcmp (p2, SDATA (encoded_file), SCHARS (encoded_file))
707 && bcmp (p1, SDATA (encoded_file), SCHARS (encoded_file))))
97e98a56 708 {
f676868d
KH
709 bestmatch = make_string (dp->d_name, len);
710 if (directoryp)
711 bestmatch = Ffile_name_as_directory (bestmatch);
97e98a56 712 }
14d55bce 713 }
f676868d
KH
714
715 /* If this dirname all matches, see if implicit following
716 slash does too. */
717 if (directoryp
718 && compare == matchsize
719 && bestmatchsize > matchsize
0b39d75d 720 && IS_ANY_SEP (p1[matchsize]))
f676868d
KH
721 matchsize++;
722 bestmatchsize = matchsize;
14d55bce
RS
723 }
724 }
c3a3229c
RS
725 /* This closes the directory. */
726 bestmatch = unbind_to (inner_count, bestmatch);
14d55bce
RS
727 }
728
3fcc88cc 729 UNGCPRO;
c3a3229c 730 bestmatch = unbind_to (count, bestmatch);
14d55bce 731
265a9e55 732 if (all_flag || NILP (bestmatch))
24c2a54f 733 {
bd33479f
KH
734 if (STRINGP (bestmatch))
735 bestmatch = DECODE_FILE (bestmatch);
24c2a54f
RS
736 return bestmatch;
737 }
d5db4077 738 if (matchcount == 1 && bestmatchsize == SCHARS (file))
14d55bce 739 return Qt;
24c2a54f
RS
740 bestmatch = Fsubstring (bestmatch, make_number (0),
741 make_number (bestmatchsize));
742 /* Now that we got the right initial segment of BESTMATCH,
743 decode it from the coding system in use. */
bd33479f 744 bestmatch = DECODE_FILE (bestmatch);
24c2a54f 745 return bestmatch;
14d55bce
RS
746}
747
b3f04ced
RS
748/* Compare exactly LEN chars of strings at S1 and S2,
749 ignoring case if appropriate.
750 Return -1 if strings match,
751 else number of chars that match at the beginning. */
752
753static int
754scmp (s1, s2, len)
755 register unsigned char *s1, *s2;
756 int len;
757{
758 register int l = len;
759
760 if (completion_ignore_case)
761 {
762 while (l && DOWNCASE (*s1++) == DOWNCASE (*s2++))
763 l--;
764 }
765 else
766 {
767 while (l && *s1++ == *s2++)
768 l--;
769 }
770 if (l == 0)
771 return -1;
772 else
773 return len - l;
774}
775
dfcf069d 776static int
14d55bce
RS
777file_name_completion_stat (dirname, dp, st_addr)
778 Lisp_Object dirname;
779 DIRENTRY *dp;
780 struct stat *st_addr;
781{
782 int len = NAMLEN (dp);
d5db4077 783 int pos = SCHARS (dirname);
7e3cf34f 784 int value;
14d55bce
RS
785 char *fullname = (char *) alloca (len + pos + 2);
786
04924ee3
RS
787#ifdef MSDOS
788#if __DJGPP__ > 1
789 /* Some fields of struct stat are *very* expensive to compute on MS-DOS,
790 but aren't required here. Avoid computing the following fields:
791 st_inode, st_size and st_nlink for directories, and the execute bits
792 in st_mode for non-directory files with non-standard extensions. */
793
794 unsigned short save_djstat_flags = _djstat_flags;
795
796 _djstat_flags = _STAT_INODE | _STAT_EXEC_MAGIC | _STAT_DIRSIZE;
797#endif /* __DJGPP__ > 1 */
798#endif /* MSDOS */
799
d5db4077 800 bcopy (SDATA (dirname), fullname, pos);
14d55bce 801#ifndef VMS
0b39d75d
RS
802 if (!IS_DIRECTORY_SEP (fullname[pos - 1]))
803 fullname[pos++] = DIRECTORY_SEP;
14d55bce
RS
804#endif
805
806 bcopy (dp->d_name, fullname + pos, len);
807 fullname[pos + len] = 0;
808
a889bd0e 809#ifdef S_IFLNK
7e3cf34f
RS
810 /* We want to return success if a link points to a nonexistent file,
811 but we want to return the status for what the link points to,
812 in case it is a directory. */
813 value = lstat (fullname, st_addr);
814 stat (fullname, st_addr);
815 return value;
a889bd0e 816#else
04924ee3
RS
817 value = stat (fullname, st_addr);
818#ifdef MSDOS
819#if __DJGPP__ > 1
820 _djstat_flags = save_djstat_flags;
821#endif /* __DJGPP__ > 1 */
822#endif /* MSDOS */
823 return value;
824#endif /* S_IFLNK */
14d55bce
RS
825}
826\f
3ed991aa
RS
827#ifdef VMS
828
829DEFUN ("file-name-all-versions", Ffile_name_all_versions,
335c5470
PJ
830 Sfile_name_all_versions, 2, 2, 0,
831 doc: /* Return a list of all versions of file name FILE in directory DIRECTORY. */)
832 (file, directory)
23bd240f 833 Lisp_Object file, directory;
3ed991aa 834{
23bd240f 835 return file_name_completion (file, directory, 1, 1);
3ed991aa
RS
836}
837
838DEFUN ("file-version-limit", Ffile_version_limit, Sfile_version_limit, 1, 1, 0,
335c5470
PJ
839 doc: /* Return the maximum number of versions allowed for FILE.
840Returns nil if the file cannot be opened or if there is no version limit. */)
841 (filename)
3ed991aa
RS
842 Lisp_Object filename;
843{
844 Lisp_Object retval;
845 struct FAB fab;
846 struct RAB rab;
847 struct XABFHC xabfhc;
848 int status;
849
850 filename = Fexpand_file_name (filename, Qnil);
851 fab = cc$rms_fab;
852 xabfhc = cc$rms_xabfhc;
d5db4077 853 fab.fab$l_fna = SDATA (filename);
3ed991aa
RS
854 fab.fab$b_fns = strlen (fab.fab$l_fna);
855 fab.fab$l_xab = (char *) &xabfhc;
856 status = sys$open (&fab, 0, 0);
857 if (status != RMS$_NORMAL) /* Probably non-existent file */
858 return Qnil;
859 sys$close (&fab, 0, 0);
860 if (xabfhc.xab$w_verlimit == 32767)
861 return Qnil; /* No version limit */
862 else
863 return make_number (xabfhc.xab$w_verlimit);
864}
865
866#endif /* VMS */
867\f
14d55bce
RS
868Lisp_Object
869make_time (time)
e5124be7 870 time_t time;
14d55bce
RS
871{
872 return Fcons (make_number (time >> 16),
873 Fcons (make_number (time & 0177777), Qnil));
874}
875
876DEFUN ("file-attributes", Ffile_attributes, Sfile_attributes, 1, 1, 0,
335c5470
PJ
877 doc: /* Return a list of attributes of file FILENAME.
878Value is nil if specified file cannot be opened.
879Otherwise, list elements are:
880 0. t for directory, string (name linked to) for symbolic link, or nil.
881 1. Number of links to file.
882 2. File uid.
883 3. File gid.
884 4. Last access time, as a list of two integers.
885 First integer has high-order 16 bits of time, second has low 16 bits.
886 5. Last modification time, likewise.
887 6. Last status change time, likewise.
888 7. Size in bytes.
889 This is a floating point number if the size is too large for an integer.
890 8. File modes, as a string of ten letters or dashes as in ls -l.
891 9. t iff file's gid would change if file were deleted and recreated.
89210. inode number. If inode number is larger than the Emacs integer,
893 this is a cons cell containing two integers: first the high part,
894 then the low 16 bits.
89511. Device number. If it is larger than the Emacs integer, this is
896 a cons cell, similar to the inode number.
897
898If file does not exist, returns nil. */)
899 (filename)
14d55bce
RS
900 Lisp_Object filename;
901{
902 Lisp_Object values[12];
24c2a54f 903 Lisp_Object encoded;
14d55bce 904 struct stat s;
0a974c85 905#if defined (BSD4_2) || defined (BSD4_3)
b3edfc9b 906 Lisp_Object dirname;
14d55bce 907 struct stat sdir;
b3edfc9b 908#endif
14d55bce 909 char modes[10];
32f4334d 910 Lisp_Object handler;
14d55bce
RS
911
912 filename = Fexpand_file_name (filename, Qnil);
32f4334d
RS
913
914 /* If the file name has special constructs in it,
915 call the corresponding file handler. */
a617e913 916 handler = Ffind_file_name_handler (filename, Qfile_attributes);
32f4334d
RS
917 if (!NILP (handler))
918 return call2 (handler, Qfile_attributes, filename);
919
24c2a54f
RS
920 encoded = ENCODE_FILE (filename);
921
d5db4077 922 if (lstat (SDATA (encoded), &s) < 0)
14d55bce
RS
923 return Qnil;
924
925 switch (s.st_mode & S_IFMT)
926 {
927 default:
928 values[0] = Qnil; break;
929 case S_IFDIR:
930 values[0] = Qt; break;
931#ifdef S_IFLNK
932 case S_IFLNK:
933 values[0] = Ffile_symlink_p (filename); break;
934#endif
935 }
936 values[1] = make_number (s.st_nlink);
937 values[2] = make_number (s.st_uid);
938 values[3] = make_number (s.st_gid);
939 values[4] = make_time (s.st_atime);
940 values[5] = make_time (s.st_mtime);
941 values[6] = make_time (s.st_ctime);
68c45bf0 942 values[7] = make_number (s.st_size);
cb1846b4 943 /* If the size is out of range for an integer, return a float. */
60fc6069 944 if (XINT (values[7]) != s.st_size)
cb1846b4 945 values[7] = make_float ((double)s.st_size);
4bc12672
JR
946 /* If the size is negative, and its type is long, convert it back to
947 positive. */
948 if (s.st_size < 0 && sizeof (s.st_size) == sizeof (long))
949 values[7] = make_float ((double) ((unsigned long) s.st_size));
950
14d55bce
RS
951 filemodestring (&s, modes);
952 values[8] = make_string (modes, 10);
0a974c85 953#if defined (BSD4_2) || defined (BSD4_3) /* file gid will be dir gid */
14d55bce 954 dirname = Ffile_name_directory (filename);
24c2a54f
RS
955 if (! NILP (dirname))
956 encoded = ENCODE_FILE (dirname);
d5db4077 957 if (! NILP (dirname) && stat (SDATA (encoded), &sdir) == 0)
14d55bce
RS
958 values[9] = (sdir.st_gid != s.st_gid) ? Qt : Qnil;
959 else /* if we can't tell, assume worst */
960 values[9] = Qt;
961#else /* file gid will be egid */
962 values[9] = (s.st_gid != getegid ()) ? Qt : Qnil;
963#endif /* BSD4_2 (or BSD4_3) */
f8edfd76 964 if (FIXNUM_OVERFLOW_P (s.st_ino))
4c637faa
RS
965 /* To allow inode numbers larger than VALBITS, separate the bottom
966 16 bits. */
967 values[10] = Fcons (make_number (s.st_ino >> 16),
968 make_number (s.st_ino & 0xffff));
969 else
970 /* But keep the most common cases as integers. */
971 values[10] = make_number (s.st_ino);
68c45bf0
PE
972
973 /* Likewise for device. */
f8edfd76 974 if (FIXNUM_OVERFLOW_P (s.st_dev))
68c45bf0
PE
975 values[11] = Fcons (make_number (s.st_dev >> 16),
976 make_number (s.st_dev & 0xffff));
977 else
978 values[11] = make_number (s.st_dev);
979
14d55bce
RS
980 return Flist (sizeof(values) / sizeof(values[0]), values);
981}
4424b255
GV
982
983DEFUN ("file-attributes-lessp", Ffile_attributes_lessp, Sfile_attributes_lessp, 2, 2, 0,
335c5470
PJ
984 doc: /* Return t if first arg file attributes list is less than second.
985Comparison is in lexicographic order and case is significant. */)
986 (f1, f2)
4424b255
GV
987 Lisp_Object f1, f2;
988{
989 return Fstring_lessp (Fcar (f1), Fcar (f2));
990}
14d55bce 991\f
dfcf069d 992void
14d55bce
RS
993syms_of_dired ()
994{
32f4334d 995 Qdirectory_files = intern ("directory-files");
4424b255 996 Qdirectory_files_and_attributes = intern ("directory-files-and-attributes");
32f4334d
RS
997 Qfile_name_completion = intern ("file-name-completion");
998 Qfile_name_all_completions = intern ("file-name-all-completions");
434e6714 999 Qfile_attributes = intern ("file-attributes");
4424b255 1000 Qfile_attributes_lessp = intern ("file-attributes-lessp");
32f4334d 1001
a2d3836c 1002 staticpro (&Qdirectory_files);
4424b255 1003 staticpro (&Qdirectory_files_and_attributes);
a2d3836c
EN
1004 staticpro (&Qfile_name_completion);
1005 staticpro (&Qfile_name_all_completions);
1006 staticpro (&Qfile_attributes);
4424b255 1007 staticpro (&Qfile_attributes_lessp);
a2d3836c 1008
14d55bce 1009 defsubr (&Sdirectory_files);
4424b255 1010 defsubr (&Sdirectory_files_and_attributes);
14d55bce
RS
1011 defsubr (&Sfile_name_completion);
1012#ifdef VMS
1013 defsubr (&Sfile_name_all_versions);
3ed991aa 1014 defsubr (&Sfile_version_limit);
14d55bce
RS
1015#endif /* VMS */
1016 defsubr (&Sfile_name_all_completions);
1017 defsubr (&Sfile_attributes);
4424b255 1018 defsubr (&Sfile_attributes_lessp);
14d55bce
RS
1019
1020#ifdef VMS
1021 Qcompletion_ignore_case = intern ("completion-ignore-case");
1022 staticpro (&Qcompletion_ignore_case);
1023#endif /* VMS */
1024
1025 DEFVAR_LISP ("completion-ignored-extensions", &Vcompletion_ignored_extensions,
335c5470
PJ
1026 doc: /* *Completion ignores filenames ending in any string in this list.
1027Directories are ignored if they match any string in this list which
1028ends in a slash.
1029This variable does not affect lists of possible completions,
1030but does affect the commands that actually do completions. */);
14d55bce
RS
1031 Vcompletion_ignored_extensions = Qnil;
1032}