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