(Vdoc_file_name, Vfile_name_coding_system)
[bpt/emacs.git] / src / dired.c
CommitLineData
14d55bce 1/* Lisp functions for making directory listings.
45c7d781 2 Copyright (C) 1985, 1986, 1993, 1994, 1999, 2000, 2001, 2004
0a974c85 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
0e6195ed
LH
29#ifdef VMS
30#include "vms-pwd.h"
31#else
32#include <pwd.h>
33#include <grp.h>
34#endif
35
68c45bf0 36#include "systime.h"
7cc9f69f 37#include <errno.h>
68c45bf0 38
3ed991aa
RS
39#ifdef VMS
40#include <string.h>
41#include <rms.h>
42#include <rmsdef.h>
43#endif
44
dfcf069d
AS
45#ifdef HAVE_UNISTD_H
46#include <unistd.h>
47#endif
48
d6717cdb
JB
49/* The d_nameln member of a struct dirent includes the '\0' character
50 on some systems, but not on others. What's worse, you can't tell
51 at compile-time which one it will be, since it really depends on
52 the sort of system providing the filesystem you're reading from,
53 not the system you are running on. Paul Eggert
54 <eggert@bi.twinsun.com> says this occurs when Emacs is running on a
55 SunOS 4.1.2 host, reading a directory that is remote-mounted from a
56 Solaris 2.1 host and is in a native Solaris 2.1 filesystem.
57
58 Since applying strlen to the name always works, we'll just do that. */
59#define NAMLEN(p) strlen (p->d_name)
60
14d55bce
RS
61#ifdef SYSV_SYSTEM_DIR
62
63#include <dirent.h>
64#define DIRENTRY struct dirent
14d55bce 65
128ecc89 66#else /* not SYSV_SYSTEM_DIR */
14d55bce
RS
67
68#ifdef NONSYSTEM_DIR_LIBRARY
69#include "ndir.h"
70#else /* not NONSYSTEM_DIR_LIBRARY */
128ecc89
RS
71#ifdef MSDOS
72#include <dirent.h>
73#else
14d55bce 74#include <sys/dir.h>
128ecc89 75#endif
14d55bce
RS
76#endif /* not NONSYSTEM_DIR_LIBRARY */
77
851cab13
DL
78#include <sys/stat.h>
79
128ecc89 80#ifndef MSDOS
14d55bce 81#define DIRENTRY struct direct
14d55bce
RS
82
83extern DIR *opendir ();
84extern struct direct *readdir ();
85
128ecc89
RS
86#endif /* not MSDOS */
87#endif /* not SYSV_SYSTEM_DIR */
88
89#ifdef MSDOS
90#define DIRENTRY_NONEMPTY(p) ((p)->d_name[0] != 0)
91#else
92#define DIRENTRY_NONEMPTY(p) ((p)->d_ino)
14d55bce
RS
93#endif
94
14d55bce
RS
95#include "lisp.h"
96#include "buffer.h"
97#include "commands.h"
bd33479f
KH
98#include "charset.h"
99#include "coding.h"
14d55bce 100#include "regex.h"
14d55bce 101
e50c66d3
KH
102/* Returns a search buffer, with a fastmap allocated and ready to go. */
103extern struct re_pattern_buffer *compile_pattern ();
c7e466e1 104
851cab13
DL
105/* From filemode.c. Can't go in Lisp.h because of `stat'. */
106extern void filemodestring P_ ((struct stat *, char *));
107
14d55bce
RS
108/* if system does not have symbolic links, it does not have lstat.
109 In that case, use ordinary stat instead. */
110
111#ifndef S_IFLNK
112#define lstat stat
113#endif
114
97e98a56 115extern int completion_ignore_case;
f676868d 116extern Lisp_Object Vcompletion_regexp_list;
bd33479f 117extern Lisp_Object Vfile_name_coding_system, Vdefault_file_name_coding_system;
ccbcf979 118
14d55bce 119Lisp_Object Vcompletion_ignored_extensions;
14d55bce 120Lisp_Object Qcompletion_ignore_case;
32f4334d 121Lisp_Object Qdirectory_files;
4424b255 122Lisp_Object Qdirectory_files_and_attributes;
32f4334d
RS
123Lisp_Object Qfile_name_completion;
124Lisp_Object Qfile_name_all_completions;
434e6714 125Lisp_Object Qfile_attributes;
4424b255 126Lisp_Object Qfile_attributes_lessp;
b3f04ced
RS
127
128static int scmp P_ ((unsigned char *, unsigned char *, int));
14d55bce 129\f
2488aba5
AI
130
131Lisp_Object
132directory_files_internal_unwind (dh)
133 Lisp_Object dh;
134{
135 DIR *d = (DIR *) ((XINT (XCAR (dh)) << 16) + XINT (XCDR (dh)));
136 closedir (d);
137 return Qnil;
138}
139
177c0ea7 140/* Function shared by Fdirectory_files and Fdirectory_files_and_attributes.
4424b255 141 When ATTRS is zero, return a list of directory filenames; when
0e6195ed
LH
142 non-zero, return a list of directory filenames and their attributes.
143 In the latter case, ID_FORMAT is passed to Ffile_attributes. */
f69f9da1 144
4424b255 145Lisp_Object
0e6195ed 146directory_files_internal (directory, full, match, nosort, attrs, id_format)
23bd240f 147 Lisp_Object directory, full, match, nosort;
4424b255 148 int attrs;
0e6195ed 149 Lisp_Object id_format;
14d55bce
RS
150{
151 DIR *d;
388ac098
GM
152 int directory_nbytes;
153 Lisp_Object list, dirfilename, encoded_directory;
6bbd7a29 154 struct re_pattern_buffer *bufp = NULL;
96d64004 155 int needsep = 0;
aed13378 156 int count = SPECPDL_INDEX ();
388ac098 157 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
8e42f043
GM
158 DIRENTRY *dp;
159 int retry_p;
32f4334d 160
96d64004 161 /* Because of file name handlers, these functions might call
6155fae1 162 Ffuncall, and cause a GC. */
388ac098
GM
163 list = encoded_directory = dirfilename = Qnil;
164 GCPRO5 (match, directory, list, dirfilename, encoded_directory);
96d64004 165 dirfilename = Fdirectory_file_name (directory);
6155fae1 166
265a9e55 167 if (!NILP (match))
14d55bce 168 {
b7826503 169 CHECK_STRING (match);
ebb9e16f
JB
170
171 /* MATCH might be a flawed regular expression. Rather than
8e6208c5 172 catching and signaling our own errors, we just call
ebb9e16f 173 compile_pattern to do the work for us. */
c872c6b2
RS
174 /* Pass 1 for the MULTIBYTE arg
175 because we do make multibyte strings if the contents warrant. */
14d55bce 176#ifdef VMS
e50c66d3 177 bufp = compile_pattern (match, 0,
3e937712 178 buffer_defaults.downcase_table, 0, 1);
14d55bce 179#else
3e937712 180 bufp = compile_pattern (match, 0, Qnil, 0, 1);
14d55bce
RS
181#endif
182 }
183
b3edfc9b 184 /* Note: ENCODE_FILE and DECODE_FILE can GC because they can run
388ac098
GM
185 run_pre_post_conversion_on_str which calls Lisp directly and
186 indirectly. */
24c2a54f 187 dirfilename = ENCODE_FILE (dirfilename);
24c2a54f
RS
188 encoded_directory = ENCODE_FILE (directory);
189
e50c66d3 190 /* Now *bufp is the compiled form of MATCH; don't call anything
6155fae1
JB
191 which might compile a new regexp until we're done with the loop! */
192
193 /* Do this opendir after anything which might signal an error; if
8e6208c5 194 an error is signaled while the directory stream is open, we
6155fae1
JB
195 have to make sure it gets closed, and setting up an
196 unwind_protect to do so would be a pain. */
8e42f043 197 retry:
177c0ea7 198
d5db4077 199 d = opendir (SDATA (dirfilename));
388ac098 200 if (d == NULL)
23bd240f 201 report_file_error ("Opening directory", Fcons (directory, Qnil));
14d55bce 202
2488aba5
AI
203 /* Unfortunately, we can now invoke expand-file-name and
204 file-attributes on filenames, both of which can throw, so we must
205 do a proper unwind-protect. */
206 record_unwind_protect (directory_files_internal_unwind,
207 Fcons (make_number (((unsigned long) d) >> 16),
208 make_number (((unsigned long) d) & 0xffff)));
209
d5db4077 210 directory_nbytes = SBYTES (directory);
c81a9bdc 211 re_match_object = Qt;
14d55bce 212
96d64004
AS
213 /* Decide whether we need to add a directory separator. */
214#ifndef VMS
388ac098 215 if (directory_nbytes == 0
d5db4077 216 || !IS_ANY_SEP (SREF (directory, directory_nbytes - 1)))
96d64004 217 needsep = 1;
e540cbed 218#endif /* not VMS */
96d64004 219
8e42f043 220 /* Loop reading blocks until EOF or error. */
f69f9da1 221 for (;;)
14d55bce 222 {
f69f9da1
GM
223 errno = 0;
224 dp = readdir (d);
225
226#ifdef EAGAIN
227 if (dp == NULL && errno == EAGAIN)
228 continue;
229#endif
177c0ea7 230
f69f9da1
GM
231 if (dp == NULL)
232 break;
233
128ecc89 234 if (DIRENTRY_NONEMPTY (dp))
14d55bce 235 {
e23f810c 236 int len;
2488aba5 237 int wanted = 0;
388ac098
GM
238 Lisp_Object name, finalname;
239 struct gcpro gcpro1, gcpro2;
e23f810c
KH
240
241 len = NAMLEN (dp);
9ad4f3e5 242 name = finalname = make_unibyte_string (dp->d_name, len);
388ac098 243 GCPRO2 (finalname, name);
177c0ea7 244
388ac098
GM
245 /* Note: ENCODE_FILE can GC; it should protect its argument,
246 though. */
247 name = DECODE_FILE (name);
d5db4077 248 len = SBYTES (name);
e23f810c 249
2488aba5
AI
250 /* Now that we have unwind_protect in place, we might as well
251 allow matching to be interrupted. */
252 immediate_quit = 1;
253 QUIT;
254
265a9e55 255 if (NILP (match)
d5db4077 256 || (0 <= re_search (bufp, SDATA (name), len, 0, len, 0)))
388ac098 257 wanted = 1;
2488aba5
AI
258
259 immediate_quit = 0;
260
261 if (wanted)
14d55bce 262 {
265a9e55 263 if (!NILP (full))
14d55bce 264 {
e23f810c 265 Lisp_Object fullname;
388ac098
GM
266 int nbytes = len + directory_nbytes + needsep;
267 int nchars;
5617588f 268
388ac098 269 fullname = make_uninit_multibyte_string (nbytes, nbytes);
d5db4077 270 bcopy (SDATA (directory), SDATA (fullname),
388ac098 271 directory_nbytes);
177c0ea7 272
5617588f 273 if (needsep)
d549c5db 274 SSET (fullname, directory_nbytes, DIRECTORY_SEP);
177c0ea7 275
d5db4077
KR
276 bcopy (SDATA (name),
277 SDATA (fullname) + directory_nbytes + needsep,
388ac098 278 len);
177c0ea7 279
d5db4077 280 nchars = chars_in_text (SDATA (fullname), nbytes);
388ac098
GM
281
282 /* Some bug somewhere. */
283 if (nchars > nbytes)
284 abort ();
177c0ea7 285
437fcd47 286 STRING_SET_CHARS (fullname, nchars);
388ac098 287 if (nchars == nbytes)
d5db4077 288 STRING_SET_UNIBYTE (fullname);
177c0ea7 289
4424b255
GV
290 finalname = fullname;
291 }
aab9c564
KH
292 else
293 finalname = name;
4424b255
GV
294
295 if (attrs)
296 {
297 /* Construct an expanded filename for the directory entry.
298 Use the decoded names for input to Ffile_attributes. */
388ac098
GM
299 Lisp_Object decoded_fullname, fileattrs;
300 struct gcpro gcpro1, gcpro2;
301
302 decoded_fullname = fileattrs = Qnil;
303 GCPRO2 (decoded_fullname, fileattrs);
4424b255 304
388ac098 305 /* Both Fexpand_file_name and Ffile_attributes can GC. */
4424b255 306 decoded_fullname = Fexpand_file_name (name, directory);
0e6195ed 307 fileattrs = Ffile_attributes (decoded_fullname, id_format);
4424b255
GV
308
309 list = Fcons (Fcons (finalname, fileattrs), list);
388ac098 310 UNGCPRO;
4424b255
GV
311 }
312 else
388ac098 313 list = Fcons (finalname, list);
14d55bce 314 }
388ac098
GM
315
316 UNGCPRO;
14d55bce
RS
317 }
318 }
2488aba5 319
8e42f043 320 retry_p = 0;
8e42f043
GM
321#ifdef EINTR
322 retry_p |= errno == EINTR;
323#endif
324
14d55bce 325 closedir (d);
2488aba5
AI
326
327 /* Discard the unwind protect. */
328 specpdl_ptr = specpdl + count;
329
8e42f043 330 if (retry_p)
76846b31
GM
331 {
332 list = Qnil;
333 goto retry;
334 }
8e42f043 335
388ac098
GM
336 if (NILP (nosort))
337 list = Fsort (Fnreverse (list),
338 attrs ? Qfile_attributes_lessp : Qstring_lessp);
177c0ea7 339
388ac098 340 RETURN_UNGCPRO (list);
14d55bce 341}
4424b255
GV
342
343
344DEFUN ("directory-files", Fdirectory_files, Sdirectory_files, 1, 4, 0,
335c5470
PJ
345 doc: /* Return a list of names of files in DIRECTORY.
346There are three optional arguments:
347If FULL is non-nil, return absolute file names. Otherwise return names
348 that are relative to the specified directory.
349If MATCH is non-nil, mention only file names that match the regexp MATCH.
350If NOSORT is non-nil, the list is not sorted--its order is unpredictable.
351 NOSORT is useful if you plan to sort the result yourself. */)
352 (directory, full, match, nosort)
4424b255
GV
353 Lisp_Object directory, full, match, nosort;
354{
355 Lisp_Object handler;
4ece81a6 356 directory = Fexpand_file_name (directory, Qnil);
4424b255
GV
357
358 /* If the file name has special constructs in it,
359 call the corresponding file handler. */
360 handler = Ffind_file_name_handler (directory, Qdirectory_files);
361 if (!NILP (handler))
b9148500
LH
362 return call5 (handler, Qdirectory_files, directory,
363 full, match, nosort);
4424b255 364
0e6195ed 365 return directory_files_internal (directory, full, match, nosort, 0, Qnil);
4424b255
GV
366}
367
335c5470 368DEFUN ("directory-files-and-attributes", Fdirectory_files_and_attributes,
0e6195ed 369 Sdirectory_files_and_attributes, 1, 5, 0,
335c5470 370 doc: /* Return a list of names of files and their attributes in DIRECTORY.
0e6195ed 371There are four optional arguments:
335c5470
PJ
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.
0e6195ed
LH
376 NOSORT is useful if you plan to sort the result yourself.
377ID-FORMAT specifies the preferred format of attributes uid and gid, see
378`file-attributes' for further documentation. */)
379 (directory, full, match, nosort, id_format)
380 Lisp_Object directory, full, match, nosort, id_format;
4424b255
GV
381{
382 Lisp_Object handler;
4ece81a6 383 directory = Fexpand_file_name (directory, Qnil);
4424b255
GV
384
385 /* If the file name has special constructs in it,
386 call the corresponding file handler. */
387 handler = Ffind_file_name_handler (directory, Qdirectory_files_and_attributes);
388 if (!NILP (handler))
b9148500
LH
389 return call6 (handler, Qdirectory_files_and_attributes,
390 directory, full, match, nosort, id_format);
4424b255 391
0e6195ed 392 return directory_files_internal (directory, full, match, nosort, 1, id_format);
4424b255
GV
393}
394
14d55bce
RS
395\f
396Lisp_Object file_name_completion ();
397
398DEFUN ("file-name-completion", Ffile_name_completion, Sfile_name_completion,
335c5470
PJ
399 2, 2, 0,
400 doc: /* Complete file name FILE in directory DIRECTORY.
401Returns the longest string
402common to all file names in DIRECTORY that start with FILE.
403If there is only one and FILE matches it exactly, returns t.
404Returns nil if DIR contains no name starting with FILE.
405
406This function ignores some of the possible completions as
407determined by the variable `completion-ignored-extensions', which see. */)
408 (file, directory)
23bd240f 409 Lisp_Object file, directory;
14d55bce 410{
32f4334d 411 Lisp_Object handler;
32f4334d 412
8436e231 413 /* If the directory name has special constructs in it,
32f4334d 414 call the corresponding file handler. */
23bd240f 415 handler = Ffind_file_name_handler (directory, Qfile_name_completion);
32f4334d 416 if (!NILP (handler))
23bd240f 417 return call3 (handler, Qfile_name_completion, file, directory);
32f4334d 418
8436e231
RS
419 /* If the file name has special constructs in it,
420 call the corresponding file handler. */
421 handler = Ffind_file_name_handler (file, Qfile_name_completion);
422 if (!NILP (handler))
23bd240f 423 return call3 (handler, Qfile_name_completion, file, directory);
8436e231 424
23bd240f 425 return file_name_completion (file, directory, 0, 0);
14d55bce
RS
426}
427
428DEFUN ("file-name-all-completions", Ffile_name_all_completions,
335c5470
PJ
429 Sfile_name_all_completions, 2, 2, 0,
430 doc: /* Return a list of all completions of file name FILE in directory DIRECTORY.
431These are all file names in directory DIRECTORY which begin with FILE. */)
432 (file, directory)
23bd240f 433 Lisp_Object file, directory;
14d55bce 434{
32f4334d
RS
435 Lisp_Object handler;
436
8436e231 437 /* If the directory name has special constructs in it,
32f4334d 438 call the corresponding file handler. */
23bd240f 439 handler = Ffind_file_name_handler (directory, Qfile_name_all_completions);
32f4334d 440 if (!NILP (handler))
23bd240f 441 return call3 (handler, Qfile_name_all_completions, file, directory);
32f4334d 442
8436e231
RS
443 /* If the file name has special constructs in it,
444 call the corresponding file handler. */
445 handler = Ffind_file_name_handler (file, Qfile_name_all_completions);
446 if (!NILP (handler))
23bd240f 447 return call3 (handler, Qfile_name_all_completions, file, directory);
8436e231 448
23bd240f 449 return file_name_completion (file, directory, 1, 0);
14d55bce
RS
450}
451
dfcf069d
AS
452static int file_name_completion_stat ();
453
14d55bce
RS
454Lisp_Object
455file_name_completion (file, dirname, all_flag, ver_flag)
456 Lisp_Object file, dirname;
457 int all_flag, ver_flag;
458{
459 DIR *d;
6bbd7a29 460 int bestmatchsize = 0, skip;
14d55bce
RS
461 register int compare, matchsize;
462 unsigned char *p1, *p2;
463 int matchcount = 0;
464 Lisp_Object bestmatch, tem, elt, name;
24c2a54f
RS
465 Lisp_Object encoded_file;
466 Lisp_Object encoded_dir;
14d55bce
RS
467 struct stat st;
468 int directoryp;
469 int passcount;
aed13378 470 int count = SPECPDL_INDEX ();
24c2a54f 471 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
3fcc88cc 472
6bbd7a29
GM
473 elt = Qnil;
474
14d55bce
RS
475#ifdef VMS
476 extern DIRENTRY * readdirver ();
477
478 DIRENTRY *((* readfunc) ());
479
480 /* Filename completion on VMS ignores case, since VMS filesys does. */
481 specbind (Qcompletion_ignore_case, Qt);
482
483 readfunc = readdir;
484 if (ver_flag)
485 readfunc = readdirver;
486 file = Fupcase (file);
487#else /* not VMS */
b7826503 488 CHECK_STRING (file);
14d55bce
RS
489#endif /* not VMS */
490
128ecc89
RS
491#ifdef FILE_SYSTEM_CASE
492 file = FILE_SYSTEM_CASE (file);
493#endif
14d55bce 494 bestmatch = Qnil;
24c2a54f
RS
495 encoded_file = encoded_dir = Qnil;
496 GCPRO5 (file, dirname, bestmatch, encoded_file, encoded_dir);
3fcc88cc 497 dirname = Fexpand_file_name (dirname, Qnil);
14d55bce 498
24c2a54f
RS
499 /* Do completion on the encoded file name
500 because the other names in the directory are (we presume)
501 encoded likewise. We decode the completed string at the end. */
502 encoded_file = ENCODE_FILE (file);
503
504 encoded_dir = ENCODE_FILE (dirname);
505
14d55bce
RS
506 /* With passcount = 0, ignore files that end in an ignored extension.
507 If nothing found then try again with passcount = 1, don't ignore them.
508 If looking for all completions, start with passcount = 1,
509 so always take even the ignored ones.
510
511 ** It would not actually be helpful to the user to ignore any possible
512 completions when making a list of them.** */
513
265a9e55 514 for (passcount = !!all_flag; NILP (bestmatch) && passcount < 2; passcount++)
14d55bce 515 {
c3a3229c
RS
516 int inner_count = SPECPDL_INDEX ();
517
d5db4077 518 d = opendir (SDATA (Fdirectory_file_name (encoded_dir)));
24c2a54f 519 if (!d)
14d55bce
RS
520 report_file_error ("Opening directory", Fcons (dirname, Qnil));
521
62e3881f
RS
522 record_unwind_protect (directory_files_internal_unwind,
523 Fcons (make_number (((unsigned long) d) >> 16),
524 make_number (((unsigned long) d) & 0xffff)));
525
14d55bce
RS
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
c3a3229c 542 QUIT;
128ecc89 543 if (! DIRENTRY_NONEMPTY (dp)
d5db4077
KR
544 || len < SCHARS (encoded_file)
545 || 0 <= scmp (dp->d_name, SDATA (encoded_file),
546 SCHARS (encoded_file)))
14d55bce
RS
547 continue;
548
24c2a54f 549 if (file_name_completion_stat (encoded_dir, dp, &st) < 0)
14d55bce
RS
550 continue;
551
552 directoryp = ((st.st_mode & S_IFMT) == S_IFDIR);
553 tem = Qnil;
ad456ad4
RS
554 if (directoryp)
555 {
556#ifndef TRIVIAL_DIRECTORY_ENTRY
557#define TRIVIAL_DIRECTORY_ENTRY(n) (!strcmp (n, ".") || !strcmp (n, ".."))
558#endif
559 /* "." and ".." are never interesting as completions, but are
560 actually in the way in a directory contains only one file. */
561 if (!passcount && TRIVIAL_DIRECTORY_ENTRY (dp->d_name))
562 continue;
d5db4077 563 if (!passcount && len > SCHARS (encoded_file))
d013f29b
EZ
564 /* Ignore directories if they match an element of
565 completion-ignored-extensions which ends in a slash. */
566 for (tem = Vcompletion_ignored_extensions;
567 CONSP (tem); tem = XCDR (tem))
568 {
569 int elt_len;
570
571 elt = XCAR (tem);
572 if (!STRINGP (elt))
573 continue;
a74aaa9d
EZ
574 /* Need to encode ELT, since scmp compares unibyte
575 strings only. */
576 elt = ENCODE_FILE (elt);
d5db4077 577 elt_len = SCHARS (elt) - 1; /* -1 for trailing / */
7a8d465a 578 if (elt_len <= 0)
d013f29b 579 continue;
d5db4077 580 p1 = SDATA (elt);
d013f29b
EZ
581 if (p1[elt_len] != '/')
582 continue;
583 skip = len - elt_len;
584 if (skip < 0)
585 continue;
586
587 if (0 <= scmp (dp->d_name + skip, p1, elt_len))
588 continue;
589 break;
590 }
ad456ad4
RS
591 }
592 else
14d55bce
RS
593 {
594 /* Compare extensions-to-be-ignored against end of this file name */
595 /* if name is not an exact match against specified string */
d5db4077 596 if (!passcount && len > SCHARS (encoded_file))
14d55bce
RS
597 /* and exit this for loop if a match is found */
598 for (tem = Vcompletion_ignored_extensions;
70949dac 599 CONSP (tem); tem = XCDR (tem))
14d55bce 600 {
70949dac 601 elt = XCAR (tem);
88cf1852 602 if (!STRINGP (elt)) continue;
a74aaa9d
EZ
603 /* Need to encode ELT, since scmp compares unibyte
604 strings only. */
605 elt = ENCODE_FILE (elt);
d5db4077 606 skip = len - SCHARS (elt);
14d55bce
RS
607 if (skip < 0) continue;
608
609 if (0 <= scmp (dp->d_name + skip,
d5db4077
KR
610 SDATA (elt),
611 SCHARS (elt)))
14d55bce
RS
612 continue;
613 break;
614 }
615 }
616
f676868d
KH
617 /* If an ignored-extensions match was found,
618 don't process this name as a completion. */
619 if (!passcount && CONSP (tem))
620 continue;
621
622 if (!passcount)
14d55bce 623 {
f676868d
KH
624 Lisp_Object regexps;
625 Lisp_Object zero;
617b3bfe 626 XSETFASTINT (zero, 0);
f676868d
KH
627
628 /* Ignore this element if it fails to match all the regexps. */
629 for (regexps = Vcompletion_regexp_list; CONSP (regexps);
70949dac 630 regexps = XCDR (regexps))
f676868d 631 {
1c56232f
EZ
632 tem = Fstring_match (XCAR (regexps),
633 make_string (dp->d_name, len), zero);
f676868d
KH
634 if (NILP (tem))
635 break;
636 }
637 if (CONSP (regexps))
638 continue;
639 }
14d55bce 640
f676868d 641 /* Update computation of how much all possible completions match */
14d55bce 642
f676868d
KH
643 matchcount++;
644
645 if (all_flag || NILP (bestmatch))
646 {
647 /* This is a possible completion */
648 if (directoryp)
14d55bce 649 {
f676868d
KH
650 /* This completion is a directory; make it end with '/' */
651 name = Ffile_name_as_directory (make_string (dp->d_name, len));
652 }
653 else
654 name = make_string (dp->d_name, len);
655 if (all_flag)
656 {
bd33479f 657 name = DECODE_FILE (name);
f676868d 658 bestmatch = Fcons (name, bestmatch);
14d55bce
RS
659 }
660 else
661 {
f676868d 662 bestmatch = name;
d5db4077 663 bestmatchsize = SCHARS (name);
f676868d
KH
664 }
665 }
666 else
667 {
668 compare = min (bestmatchsize, len);
d5db4077 669 p1 = SDATA (bestmatch);
f676868d
KH
670 p2 = (unsigned char *) dp->d_name;
671 matchsize = scmp(p1, p2, compare);
672 if (matchsize < 0)
673 matchsize = compare;
674 if (completion_ignore_case)
675 {
676 /* If this is an exact match except for case,
677 use it as the best match rather than one that is not
678 an exact match. This way, we get the case pattern
679 of the actual match. */
f5ec5d3d
RS
680 /* This tests that the current file is an exact match
681 but BESTMATCH is not (it is too long). */
f676868d 682 if ((matchsize == len
177c0ea7 683 && matchsize + !!directoryp
d5db4077 684 < SCHARS (bestmatch))
f676868d
KH
685 ||
686 /* If there is no exact match ignoring case,
687 prefer a match that does not change the case
688 of the input. */
f5ec5d3d
RS
689 /* If there is more than one exact match aside from
690 case, and one of them is exact including case,
691 prefer that one. */
692 /* This == checks that, of current file and BESTMATCH,
693 either both or neither are exact. */
f676868d
KH
694 (((matchsize == len)
695 ==
177c0ea7 696 (matchsize + !!directoryp
d5db4077
KR
697 == SCHARS (bestmatch)))
698 && !bcmp (p2, SDATA (encoded_file), SCHARS (encoded_file))
699 && bcmp (p1, SDATA (encoded_file), SCHARS (encoded_file))))
97e98a56 700 {
f676868d
KH
701 bestmatch = make_string (dp->d_name, len);
702 if (directoryp)
703 bestmatch = Ffile_name_as_directory (bestmatch);
97e98a56 704 }
14d55bce 705 }
f676868d
KH
706
707 /* If this dirname all matches, see if implicit following
708 slash does too. */
709 if (directoryp
710 && compare == matchsize
711 && bestmatchsize > matchsize
0b39d75d 712 && IS_ANY_SEP (p1[matchsize]))
f676868d
KH
713 matchsize++;
714 bestmatchsize = matchsize;
14d55bce
RS
715 }
716 }
c3a3229c
RS
717 /* This closes the directory. */
718 bestmatch = unbind_to (inner_count, bestmatch);
14d55bce
RS
719 }
720
3fcc88cc 721 UNGCPRO;
c3a3229c 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 737 return bestmatch;
14d55bce
RS
738}
739
b3f04ced
RS
740/* Compare exactly LEN chars of strings at S1 and S2,
741 ignoring case if appropriate.
742 Return -1 if strings match,
743 else number of chars that match at the beginning. */
744
745static int
746scmp (s1, s2, len)
747 register unsigned char *s1, *s2;
748 int len;
749{
750 register int l = len;
751
752 if (completion_ignore_case)
753 {
754 while (l && DOWNCASE (*s1++) == DOWNCASE (*s2++))
755 l--;
756 }
757 else
758 {
759 while (l && *s1++ == *s2++)
760 l--;
761 }
762 if (l == 0)
763 return -1;
764 else
765 return len - l;
766}
767
dfcf069d 768static int
14d55bce
RS
769file_name_completion_stat (dirname, dp, st_addr)
770 Lisp_Object dirname;
771 DIRENTRY *dp;
772 struct stat *st_addr;
773{
774 int len = NAMLEN (dp);
d5db4077 775 int pos = SCHARS (dirname);
7e3cf34f 776 int value;
14d55bce
RS
777 char *fullname = (char *) alloca (len + pos + 2);
778
04924ee3
RS
779#ifdef MSDOS
780#if __DJGPP__ > 1
781 /* Some fields of struct stat are *very* expensive to compute on MS-DOS,
782 but aren't required here. Avoid computing the following fields:
783 st_inode, st_size and st_nlink for directories, and the execute bits
784 in st_mode for non-directory files with non-standard extensions. */
785
786 unsigned short save_djstat_flags = _djstat_flags;
787
788 _djstat_flags = _STAT_INODE | _STAT_EXEC_MAGIC | _STAT_DIRSIZE;
789#endif /* __DJGPP__ > 1 */
790#endif /* MSDOS */
791
d5db4077 792 bcopy (SDATA (dirname), fullname, pos);
14d55bce 793#ifndef VMS
0b39d75d
RS
794 if (!IS_DIRECTORY_SEP (fullname[pos - 1]))
795 fullname[pos++] = DIRECTORY_SEP;
14d55bce
RS
796#endif
797
798 bcopy (dp->d_name, fullname + pos, len);
799 fullname[pos + len] = 0;
800
a889bd0e 801#ifdef S_IFLNK
7e3cf34f
RS
802 /* We want to return success if a link points to a nonexistent file,
803 but we want to return the status for what the link points to,
804 in case it is a directory. */
805 value = lstat (fullname, st_addr);
806 stat (fullname, st_addr);
807 return value;
a889bd0e 808#else
04924ee3
RS
809 value = stat (fullname, st_addr);
810#ifdef MSDOS
811#if __DJGPP__ > 1
812 _djstat_flags = save_djstat_flags;
813#endif /* __DJGPP__ > 1 */
814#endif /* MSDOS */
815 return value;
816#endif /* S_IFLNK */
14d55bce
RS
817}
818\f
3ed991aa
RS
819#ifdef VMS
820
821DEFUN ("file-name-all-versions", Ffile_name_all_versions,
335c5470
PJ
822 Sfile_name_all_versions, 2, 2, 0,
823 doc: /* Return a list of all versions of file name FILE in directory DIRECTORY. */)
824 (file, directory)
23bd240f 825 Lisp_Object file, directory;
3ed991aa 826{
23bd240f 827 return file_name_completion (file, directory, 1, 1);
3ed991aa
RS
828}
829
830DEFUN ("file-version-limit", Ffile_version_limit, Sfile_version_limit, 1, 1, 0,
335c5470
PJ
831 doc: /* Return the maximum number of versions allowed for FILE.
832Returns nil if the file cannot be opened or if there is no version limit. */)
833 (filename)
3ed991aa
RS
834 Lisp_Object filename;
835{
836 Lisp_Object retval;
837 struct FAB fab;
838 struct RAB rab;
839 struct XABFHC xabfhc;
840 int status;
841
842 filename = Fexpand_file_name (filename, Qnil);
843 fab = cc$rms_fab;
844 xabfhc = cc$rms_xabfhc;
d5db4077 845 fab.fab$l_fna = SDATA (filename);
3ed991aa
RS
846 fab.fab$b_fns = strlen (fab.fab$l_fna);
847 fab.fab$l_xab = (char *) &xabfhc;
848 status = sys$open (&fab, 0, 0);
849 if (status != RMS$_NORMAL) /* Probably non-existent file */
850 return Qnil;
851 sys$close (&fab, 0, 0);
852 if (xabfhc.xab$w_verlimit == 32767)
853 return Qnil; /* No version limit */
854 else
855 return make_number (xabfhc.xab$w_verlimit);
856}
857
858#endif /* VMS */
859\f
14d55bce
RS
860Lisp_Object
861make_time (time)
e5124be7 862 time_t time;
14d55bce
RS
863{
864 return Fcons (make_number (time >> 16),
865 Fcons (make_number (time & 0177777), Qnil));
866}
867
0e6195ed 868DEFUN ("file-attributes", Ffile_attributes, Sfile_attributes, 1, 2, 0,
335c5470
PJ
869 doc: /* Return a list of attributes of file FILENAME.
870Value is nil if specified file cannot be opened.
0e6195ed
LH
871
872ID-FORMAT specifies the preferred format of attributes uid and gid (see
873below) - valid values are 'string and 'integer. The latter is the default,
874but we plan to change that, so you should specify a non-nil value for
875ID-FORMAT if you use the returned uid or gid.
876
877Elements of the attribute list are:
335c5470
PJ
878 0. t for directory, string (name linked to) for symbolic link, or nil.
879 1. Number of links to file.
0e6195ed
LH
880 2. File uid as a string or an integer. If a string value cannot be
881 looked up, the integer value is returned.
882 3. File gid, likewise.
335c5470
PJ
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
0e6195ed
LH
895 a cons cell, similar to the inode number. */)
896 (filename, id_format)
897 Lisp_Object filename, id_format;
14d55bce
RS
898{
899 Lisp_Object values[12];
24c2a54f 900 Lisp_Object encoded;
14d55bce 901 struct stat s;
0e6195ed
LH
902 struct passwd *pw;
903 struct group *gr;
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 916 if (!NILP (handler))
d8e18df7
SM
917 { /* Only pass the extra arg if it is used to help backward compatibility
918 with old file handlers which do not implement the new arg. --Stef */
919 if (NILP (id_format))
920 return call2 (handler, Qfile_attributes, filename);
921 else
922 return call3 (handler, Qfile_attributes, filename, id_format);
923 }
32f4334d 924
24c2a54f
RS
925 encoded = ENCODE_FILE (filename);
926
d5db4077 927 if (lstat (SDATA (encoded), &s) < 0)
14d55bce
RS
928 return Qnil;
929
930 switch (s.st_mode & S_IFMT)
931 {
932 default:
933 values[0] = Qnil; break;
934 case S_IFDIR:
935 values[0] = Qt; break;
936#ifdef S_IFLNK
937 case S_IFLNK:
938 values[0] = Ffile_symlink_p (filename); break;
939#endif
940 }
941 values[1] = make_number (s.st_nlink);
0e6195ed
LH
942 if (NILP (id_format) || EQ (id_format, Qinteger))
943 {
944 values[2] = make_number (s.st_uid);
945 values[3] = make_number (s.st_gid);
946 }
947 else
948 {
949 pw = (struct passwd *) getpwuid (s.st_uid);
45c7d781 950 values[2] = (pw ? build_string (pw->pw_name) : make_number (s.st_uid));
0e6195ed 951 gr = (struct group *) getgrgid (s.st_gid);
45c7d781 952 values[3] = (gr ? build_string (gr->gr_name) : make_number (s.st_gid));
0e6195ed 953 }
14d55bce
RS
954 values[4] = make_time (s.st_atime);
955 values[5] = make_time (s.st_mtime);
956 values[6] = make_time (s.st_ctime);
68c45bf0 957 values[7] = make_number (s.st_size);
cb1846b4 958 /* If the size is out of range for an integer, return a float. */
60fc6069 959 if (XINT (values[7]) != s.st_size)
cb1846b4 960 values[7] = make_float ((double)s.st_size);
4bc12672
JR
961 /* If the size is negative, and its type is long, convert it back to
962 positive. */
963 if (s.st_size < 0 && sizeof (s.st_size) == sizeof (long))
964 values[7] = make_float ((double) ((unsigned long) s.st_size));
965
14d55bce
RS
966 filemodestring (&s, modes);
967 values[8] = make_string (modes, 10);
0a974c85 968#if defined (BSD4_2) || defined (BSD4_3) /* file gid will be dir gid */
14d55bce 969 dirname = Ffile_name_directory (filename);
24c2a54f
RS
970 if (! NILP (dirname))
971 encoded = ENCODE_FILE (dirname);
d5db4077 972 if (! NILP (dirname) && stat (SDATA (encoded), &sdir) == 0)
14d55bce
RS
973 values[9] = (sdir.st_gid != s.st_gid) ? Qt : Qnil;
974 else /* if we can't tell, assume worst */
975 values[9] = Qt;
976#else /* file gid will be egid */
977 values[9] = (s.st_gid != getegid ()) ? Qt : Qnil;
978#endif /* BSD4_2 (or BSD4_3) */
f8edfd76 979 if (FIXNUM_OVERFLOW_P (s.st_ino))
4c637faa
RS
980 /* To allow inode numbers larger than VALBITS, separate the bottom
981 16 bits. */
982 values[10] = Fcons (make_number (s.st_ino >> 16),
983 make_number (s.st_ino & 0xffff));
984 else
985 /* But keep the most common cases as integers. */
986 values[10] = make_number (s.st_ino);
68c45bf0
PE
987
988 /* Likewise for device. */
f8edfd76 989 if (FIXNUM_OVERFLOW_P (s.st_dev))
68c45bf0
PE
990 values[11] = Fcons (make_number (s.st_dev >> 16),
991 make_number (s.st_dev & 0xffff));
992 else
993 values[11] = make_number (s.st_dev);
994
14d55bce
RS
995 return Flist (sizeof(values) / sizeof(values[0]), values);
996}
4424b255
GV
997
998DEFUN ("file-attributes-lessp", Ffile_attributes_lessp, Sfile_attributes_lessp, 2, 2, 0,
335c5470
PJ
999 doc: /* Return t if first arg file attributes list is less than second.
1000Comparison is in lexicographic order and case is significant. */)
1001 (f1, f2)
4424b255
GV
1002 Lisp_Object f1, f2;
1003{
1004 return Fstring_lessp (Fcar (f1), Fcar (f2));
1005}
14d55bce 1006\f
dfcf069d 1007void
14d55bce
RS
1008syms_of_dired ()
1009{
32f4334d 1010 Qdirectory_files = intern ("directory-files");
4424b255 1011 Qdirectory_files_and_attributes = intern ("directory-files-and-attributes");
32f4334d
RS
1012 Qfile_name_completion = intern ("file-name-completion");
1013 Qfile_name_all_completions = intern ("file-name-all-completions");
434e6714 1014 Qfile_attributes = intern ("file-attributes");
4424b255 1015 Qfile_attributes_lessp = intern ("file-attributes-lessp");
32f4334d 1016
a2d3836c 1017 staticpro (&Qdirectory_files);
4424b255 1018 staticpro (&Qdirectory_files_and_attributes);
a2d3836c
EN
1019 staticpro (&Qfile_name_completion);
1020 staticpro (&Qfile_name_all_completions);
1021 staticpro (&Qfile_attributes);
4424b255 1022 staticpro (&Qfile_attributes_lessp);
a2d3836c 1023
14d55bce 1024 defsubr (&Sdirectory_files);
4424b255 1025 defsubr (&Sdirectory_files_and_attributes);
14d55bce
RS
1026 defsubr (&Sfile_name_completion);
1027#ifdef VMS
1028 defsubr (&Sfile_name_all_versions);
3ed991aa 1029 defsubr (&Sfile_version_limit);
14d55bce
RS
1030#endif /* VMS */
1031 defsubr (&Sfile_name_all_completions);
1032 defsubr (&Sfile_attributes);
4424b255 1033 defsubr (&Sfile_attributes_lessp);
14d55bce
RS
1034
1035#ifdef VMS
1036 Qcompletion_ignore_case = intern ("completion-ignore-case");
1037 staticpro (&Qcompletion_ignore_case);
1038#endif /* VMS */
1039
1040 DEFVAR_LISP ("completion-ignored-extensions", &Vcompletion_ignored_extensions,
335c5470
PJ
1041 doc: /* *Completion ignores filenames ending in any string in this list.
1042Directories are ignored if they match any string in this list which
1043ends in a slash.
1044This variable does not affect lists of possible completions,
1045but does affect the commands that actually do completions. */);
14d55bce
RS
1046 Vcompletion_ignored_extensions = Qnil;
1047}
ab5796a9
MB
1048
1049/* arch-tag: 1ac8deca-4d8f-4d41-ade9-089154d98c03
1050 (do not change this comment) */