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