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