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