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