(greek-babel): fix <' accent.
[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
177c0ea7 133/* Function shared by Fdirectory_files and Fdirectory_files_and_attributes.
4424b255
GV
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 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;
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 {
c3a3229c
RS
522 int inner_count = SPECPDL_INDEX ();
523
d5db4077 524 d = opendir (SDATA (Fdirectory_file_name (encoded_dir)));
24c2a54f 525 if (!d)
14d55bce
RS
526 report_file_error ("Opening directory", Fcons (dirname, Qnil));
527
62e3881f
RS
528 record_unwind_protect (directory_files_internal_unwind,
529 Fcons (make_number (((unsigned long) d) >> 16),
530 make_number (((unsigned long) d) & 0xffff)));
531
14d55bce
RS
532 /* Loop reading blocks */
533 /* (att3b compiler bug requires do a null comparison this way) */
534 while (1)
535 {
536 DIRENTRY *dp;
537 int len;
538
539#ifdef VMS
540 dp = (*readfunc) (d);
541#else
542 dp = readdir (d);
543#endif
544 if (!dp) break;
545
546 len = NAMLEN (dp);
547
c3a3229c 548 QUIT;
128ecc89 549 if (! DIRENTRY_NONEMPTY (dp)
d5db4077
KR
550 || len < SCHARS (encoded_file)
551 || 0 <= scmp (dp->d_name, SDATA (encoded_file),
552 SCHARS (encoded_file)))
14d55bce
RS
553 continue;
554
24c2a54f 555 if (file_name_completion_stat (encoded_dir, dp, &st) < 0)
14d55bce
RS
556 continue;
557
558 directoryp = ((st.st_mode & S_IFMT) == S_IFDIR);
559 tem = Qnil;
ad456ad4
RS
560 if (directoryp)
561 {
562#ifndef TRIVIAL_DIRECTORY_ENTRY
563#define TRIVIAL_DIRECTORY_ENTRY(n) (!strcmp (n, ".") || !strcmp (n, ".."))
564#endif
565 /* "." and ".." are never interesting as completions, but are
566 actually in the way in a directory contains only one file. */
567 if (!passcount && TRIVIAL_DIRECTORY_ENTRY (dp->d_name))
568 continue;
d5db4077 569 if (!passcount && len > SCHARS (encoded_file))
d013f29b
EZ
570 /* Ignore directories if they match an element of
571 completion-ignored-extensions which ends in a slash. */
572 for (tem = Vcompletion_ignored_extensions;
573 CONSP (tem); tem = XCDR (tem))
574 {
575 int elt_len;
576
577 elt = XCAR (tem);
578 if (!STRINGP (elt))
579 continue;
a74aaa9d
EZ
580 /* Need to encode ELT, since scmp compares unibyte
581 strings only. */
582 elt = ENCODE_FILE (elt);
d5db4077 583 elt_len = SCHARS (elt) - 1; /* -1 for trailing / */
7a8d465a 584 if (elt_len <= 0)
d013f29b 585 continue;
d5db4077 586 p1 = SDATA (elt);
d013f29b
EZ
587 if (p1[elt_len] != '/')
588 continue;
589 skip = len - elt_len;
590 if (skip < 0)
591 continue;
592
593 if (0 <= scmp (dp->d_name + skip, p1, elt_len))
594 continue;
595 break;
596 }
ad456ad4
RS
597 }
598 else
14d55bce
RS
599 {
600 /* Compare extensions-to-be-ignored against end of this file name */
601 /* if name is not an exact match against specified string */
d5db4077 602 if (!passcount && len > SCHARS (encoded_file))
14d55bce
RS
603 /* and exit this for loop if a match is found */
604 for (tem = Vcompletion_ignored_extensions;
70949dac 605 CONSP (tem); tem = XCDR (tem))
14d55bce 606 {
70949dac 607 elt = XCAR (tem);
88cf1852 608 if (!STRINGP (elt)) continue;
a74aaa9d
EZ
609 /* Need to encode ELT, since scmp compares unibyte
610 strings only. */
611 elt = ENCODE_FILE (elt);
d5db4077 612 skip = len - SCHARS (elt);
14d55bce
RS
613 if (skip < 0) continue;
614
615 if (0 <= scmp (dp->d_name + skip,
d5db4077
KR
616 SDATA (elt),
617 SCHARS (elt)))
14d55bce
RS
618 continue;
619 break;
620 }
621 }
622
f676868d
KH
623 /* If an ignored-extensions match was found,
624 don't process this name as a completion. */
625 if (!passcount && CONSP (tem))
626 continue;
627
628 if (!passcount)
14d55bce 629 {
f676868d
KH
630 Lisp_Object regexps;
631 Lisp_Object zero;
617b3bfe 632 XSETFASTINT (zero, 0);
f676868d
KH
633
634 /* Ignore this element if it fails to match all the regexps. */
635 for (regexps = Vcompletion_regexp_list; CONSP (regexps);
70949dac 636 regexps = XCDR (regexps))
f676868d 637 {
1c56232f
EZ
638 tem = Fstring_match (XCAR (regexps),
639 make_string (dp->d_name, len), zero);
f676868d
KH
640 if (NILP (tem))
641 break;
642 }
643 if (CONSP (regexps))
644 continue;
645 }
14d55bce 646
f676868d 647 /* Update computation of how much all possible completions match */
14d55bce 648
f676868d
KH
649 matchcount++;
650
651 if (all_flag || NILP (bestmatch))
652 {
653 /* This is a possible completion */
654 if (directoryp)
14d55bce 655 {
f676868d
KH
656 /* This completion is a directory; make it end with '/' */
657 name = Ffile_name_as_directory (make_string (dp->d_name, len));
658 }
659 else
660 name = make_string (dp->d_name, len);
661 if (all_flag)
662 {
bd33479f 663 name = DECODE_FILE (name);
f676868d 664 bestmatch = Fcons (name, bestmatch);
14d55bce
RS
665 }
666 else
667 {
f676868d 668 bestmatch = name;
d5db4077 669 bestmatchsize = SCHARS (name);
f676868d
KH
670 }
671 }
672 else
673 {
674 compare = min (bestmatchsize, len);
d5db4077 675 p1 = SDATA (bestmatch);
f676868d
KH
676 p2 = (unsigned char *) dp->d_name;
677 matchsize = scmp(p1, p2, compare);
678 if (matchsize < 0)
679 matchsize = compare;
680 if (completion_ignore_case)
681 {
682 /* If this is an exact match except for case,
683 use it as the best match rather than one that is not
684 an exact match. This way, we get the case pattern
685 of the actual match. */
f5ec5d3d
RS
686 /* This tests that the current file is an exact match
687 but BESTMATCH is not (it is too long). */
f676868d 688 if ((matchsize == len
177c0ea7 689 && matchsize + !!directoryp
d5db4077 690 < SCHARS (bestmatch))
f676868d
KH
691 ||
692 /* If there is no exact match ignoring case,
693 prefer a match that does not change the case
694 of the input. */
f5ec5d3d
RS
695 /* If there is more than one exact match aside from
696 case, and one of them is exact including case,
697 prefer that one. */
698 /* This == checks that, of current file and BESTMATCH,
699 either both or neither are exact. */
f676868d
KH
700 (((matchsize == len)
701 ==
177c0ea7 702 (matchsize + !!directoryp
d5db4077
KR
703 == SCHARS (bestmatch)))
704 && !bcmp (p2, SDATA (encoded_file), SCHARS (encoded_file))
705 && bcmp (p1, SDATA (encoded_file), SCHARS (encoded_file))))
97e98a56 706 {
f676868d
KH
707 bestmatch = make_string (dp->d_name, len);
708 if (directoryp)
709 bestmatch = Ffile_name_as_directory (bestmatch);
97e98a56 710 }
14d55bce 711 }
f676868d
KH
712
713 /* If this dirname all matches, see if implicit following
714 slash does too. */
715 if (directoryp
716 && compare == matchsize
717 && bestmatchsize > matchsize
0b39d75d 718 && IS_ANY_SEP (p1[matchsize]))
f676868d
KH
719 matchsize++;
720 bestmatchsize = matchsize;
14d55bce
RS
721 }
722 }
c3a3229c
RS
723 /* This closes the directory. */
724 bestmatch = unbind_to (inner_count, bestmatch);
14d55bce
RS
725 }
726
3fcc88cc 727 UNGCPRO;
c3a3229c 728 bestmatch = unbind_to (count, bestmatch);
14d55bce 729
265a9e55 730 if (all_flag || NILP (bestmatch))
24c2a54f 731 {
bd33479f
KH
732 if (STRINGP (bestmatch))
733 bestmatch = DECODE_FILE (bestmatch);
24c2a54f
RS
734 return bestmatch;
735 }
d5db4077 736 if (matchcount == 1 && bestmatchsize == SCHARS (file))
14d55bce 737 return Qt;
24c2a54f
RS
738 bestmatch = Fsubstring (bestmatch, make_number (0),
739 make_number (bestmatchsize));
740 /* Now that we got the right initial segment of BESTMATCH,
741 decode it from the coding system in use. */
bd33479f 742 bestmatch = DECODE_FILE (bestmatch);
24c2a54f 743 return bestmatch;
14d55bce
RS
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);
d5db4077 781 int pos = SCHARS (dirname);
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
d5db4077 798 bcopy (SDATA (dirname), fullname, pos);
14d55bce 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;
d5db4077 851 fab.fab$l_fna = SDATA (filename);
3ed991aa
RS
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
d5db4077 920 if (lstat (SDATA (encoded), &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);
4bc12672
JR
944 /* If the size is negative, and its type is long, convert it back to
945 positive. */
946 if (s.st_size < 0 && sizeof (s.st_size) == sizeof (long))
947 values[7] = make_float ((double) ((unsigned long) s.st_size));
948
14d55bce
RS
949 filemodestring (&s, modes);
950 values[8] = make_string (modes, 10);
0a974c85 951#if defined (BSD4_2) || defined (BSD4_3) /* file gid will be dir gid */
14d55bce 952 dirname = Ffile_name_directory (filename);
24c2a54f
RS
953 if (! NILP (dirname))
954 encoded = ENCODE_FILE (dirname);
d5db4077 955 if (! NILP (dirname) && stat (SDATA (encoded), &sdir) == 0)
14d55bce
RS
956 values[9] = (sdir.st_gid != s.st_gid) ? Qt : Qnil;
957 else /* if we can't tell, assume worst */
958 values[9] = Qt;
959#else /* file gid will be egid */
960 values[9] = (s.st_gid != getegid ()) ? Qt : Qnil;
961#endif /* BSD4_2 (or BSD4_3) */
f8edfd76 962 if (FIXNUM_OVERFLOW_P (s.st_ino))
4c637faa
RS
963 /* To allow inode numbers larger than VALBITS, separate the bottom
964 16 bits. */
965 values[10] = Fcons (make_number (s.st_ino >> 16),
966 make_number (s.st_ino & 0xffff));
967 else
968 /* But keep the most common cases as integers. */
969 values[10] = make_number (s.st_ino);
68c45bf0
PE
970
971 /* Likewise for device. */
f8edfd76 972 if (FIXNUM_OVERFLOW_P (s.st_dev))
68c45bf0
PE
973 values[11] = Fcons (make_number (s.st_dev >> 16),
974 make_number (s.st_dev & 0xffff));
975 else
976 values[11] = make_number (s.st_dev);
977
14d55bce
RS
978 return Flist (sizeof(values) / sizeof(values[0]), values);
979}
4424b255
GV
980
981DEFUN ("file-attributes-lessp", Ffile_attributes_lessp, Sfile_attributes_lessp, 2, 2, 0,
335c5470
PJ
982 doc: /* Return t if first arg file attributes list is less than second.
983Comparison is in lexicographic order and case is significant. */)
984 (f1, f2)
4424b255
GV
985 Lisp_Object f1, f2;
986{
987 return Fstring_lessp (Fcar (f1), Fcar (f2));
988}
14d55bce 989\f
dfcf069d 990void
14d55bce
RS
991syms_of_dired ()
992{
32f4334d 993 Qdirectory_files = intern ("directory-files");
4424b255 994 Qdirectory_files_and_attributes = intern ("directory-files-and-attributes");
32f4334d
RS
995 Qfile_name_completion = intern ("file-name-completion");
996 Qfile_name_all_completions = intern ("file-name-all-completions");
434e6714 997 Qfile_attributes = intern ("file-attributes");
4424b255 998 Qfile_attributes_lessp = intern ("file-attributes-lessp");
32f4334d 999
a2d3836c 1000 staticpro (&Qdirectory_files);
4424b255 1001 staticpro (&Qdirectory_files_and_attributes);
a2d3836c
EN
1002 staticpro (&Qfile_name_completion);
1003 staticpro (&Qfile_name_all_completions);
1004 staticpro (&Qfile_attributes);
4424b255 1005 staticpro (&Qfile_attributes_lessp);
a2d3836c 1006
14d55bce 1007 defsubr (&Sdirectory_files);
4424b255 1008 defsubr (&Sdirectory_files_and_attributes);
14d55bce
RS
1009 defsubr (&Sfile_name_completion);
1010#ifdef VMS
1011 defsubr (&Sfile_name_all_versions);
3ed991aa 1012 defsubr (&Sfile_version_limit);
14d55bce
RS
1013#endif /* VMS */
1014 defsubr (&Sfile_name_all_completions);
1015 defsubr (&Sfile_attributes);
4424b255 1016 defsubr (&Sfile_attributes_lessp);
14d55bce
RS
1017
1018#ifdef VMS
1019 Qcompletion_ignore_case = intern ("completion-ignore-case");
1020 staticpro (&Qcompletion_ignore_case);
1021#endif /* VMS */
1022
1023 DEFVAR_LISP ("completion-ignored-extensions", &Vcompletion_ignored_extensions,
335c5470
PJ
1024 doc: /* *Completion ignores filenames ending in any string in this list.
1025Directories are ignored if they match any string in this list which
1026ends in a slash.
1027This variable does not affect lists of possible completions,
1028but does affect the commands that actually do completions. */);
14d55bce
RS
1029 Vcompletion_ignored_extensions = Qnil;
1030}