130 |
return Qnil; |
return Qnil; |
131 |
} |
} |
132 |
|
|
133 |
/* Function shared by Fdirectory_files and Fdirectory_files_and_attributes. |
/* Function shared by Fdirectory_files and Fdirectory_files_and_attributes. |
134 |
When ATTRS is zero, return a list of directory filenames; when |
When ATTRS is zero, return a list of directory filenames; when |
135 |
non-zero, return a list of directory filenames and their attributes. */ |
non-zero, return a list of directory filenames and their attributes. */ |
136 |
|
|
144 |
Lisp_Object list, dirfilename, encoded_directory; |
Lisp_Object list, dirfilename, encoded_directory; |
145 |
struct re_pattern_buffer *bufp = NULL; |
struct re_pattern_buffer *bufp = NULL; |
146 |
int needsep = 0; |
int needsep = 0; |
147 |
int count = specpdl_ptr - specpdl; |
int count = SPECPDL_INDEX (); |
148 |
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; |
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; |
149 |
DIRENTRY *dp; |
DIRENTRY *dp; |
150 |
int retry_p; |
int retry_p; |
153 |
Ffuncall, and cause a GC. */ |
Ffuncall, and cause a GC. */ |
154 |
list = encoded_directory = dirfilename = Qnil; |
list = encoded_directory = dirfilename = Qnil; |
155 |
GCPRO5 (match, directory, list, dirfilename, encoded_directory); |
GCPRO5 (match, directory, list, dirfilename, encoded_directory); |
|
directory = Fexpand_file_name (directory, Qnil); |
|
156 |
dirfilename = Fdirectory_file_name (directory); |
dirfilename = Fdirectory_file_name (directory); |
157 |
|
|
158 |
if (!NILP (match)) |
if (!NILP (match)) |
186 |
have to make sure it gets closed, and setting up an |
have to make sure it gets closed, and setting up an |
187 |
unwind_protect to do so would be a pain. */ |
unwind_protect to do so would be a pain. */ |
188 |
retry: |
retry: |
189 |
|
|
190 |
d = opendir (XSTRING (dirfilename)->data); |
d = opendir (SDATA (dirfilename)); |
191 |
if (d == NULL) |
if (d == NULL) |
192 |
report_file_error ("Opening directory", Fcons (directory, Qnil)); |
report_file_error ("Opening directory", Fcons (directory, Qnil)); |
193 |
|
|
198 |
Fcons (make_number (((unsigned long) d) >> 16), |
Fcons (make_number (((unsigned long) d) >> 16), |
199 |
make_number (((unsigned long) d) & 0xffff))); |
make_number (((unsigned long) d) & 0xffff))); |
200 |
|
|
201 |
directory_nbytes = STRING_BYTES (XSTRING (directory)); |
directory_nbytes = SBYTES (directory); |
202 |
re_match_object = Qt; |
re_match_object = Qt; |
203 |
|
|
204 |
/* Decide whether we need to add a directory separator. */ |
/* Decide whether we need to add a directory separator. */ |
205 |
#ifndef VMS |
#ifndef VMS |
206 |
if (directory_nbytes == 0 |
if (directory_nbytes == 0 |
207 |
|| !IS_ANY_SEP (XSTRING (directory)->data[directory_nbytes - 1])) |
|| !IS_ANY_SEP (SREF (directory, directory_nbytes - 1))) |
208 |
needsep = 1; |
needsep = 1; |
209 |
#endif /* not VMS */ |
#endif /* not VMS */ |
210 |
|
|
218 |
if (dp == NULL && errno == EAGAIN) |
if (dp == NULL && errno == EAGAIN) |
219 |
continue; |
continue; |
220 |
#endif |
#endif |
221 |
|
|
222 |
if (dp == NULL) |
if (dp == NULL) |
223 |
break; |
break; |
224 |
|
|
232 |
len = NAMLEN (dp); |
len = NAMLEN (dp); |
233 |
name = finalname = make_unibyte_string (dp->d_name, len); |
name = finalname = make_unibyte_string (dp->d_name, len); |
234 |
GCPRO2 (finalname, name); |
GCPRO2 (finalname, name); |
235 |
|
|
236 |
/* Note: ENCODE_FILE can GC; it should protect its argument, |
/* Note: ENCODE_FILE can GC; it should protect its argument, |
237 |
though. */ |
though. */ |
238 |
name = DECODE_FILE (name); |
name = DECODE_FILE (name); |
239 |
len = STRING_BYTES (XSTRING (name)); |
len = SBYTES (name); |
240 |
|
|
241 |
/* Now that we have unwind_protect in place, we might as well |
/* Now that we have unwind_protect in place, we might as well |
242 |
allow matching to be interrupted. */ |
allow matching to be interrupted. */ |
244 |
QUIT; |
QUIT; |
245 |
|
|
246 |
if (NILP (match) |
if (NILP (match) |
247 |
|| (0 <= re_search (bufp, XSTRING (name)->data, len, 0, len, 0))) |
|| (0 <= re_search (bufp, SDATA (name), len, 0, len, 0))) |
248 |
wanted = 1; |
wanted = 1; |
249 |
|
|
250 |
immediate_quit = 0; |
immediate_quit = 0; |
258 |
int nchars; |
int nchars; |
259 |
|
|
260 |
fullname = make_uninit_multibyte_string (nbytes, nbytes); |
fullname = make_uninit_multibyte_string (nbytes, nbytes); |
261 |
bcopy (XSTRING (directory)->data, XSTRING (fullname)->data, |
bcopy (SDATA (directory), SDATA (fullname), |
262 |
directory_nbytes); |
directory_nbytes); |
263 |
|
|
264 |
if (needsep) |
if (needsep) |
265 |
XSTRING (fullname)->data[directory_nbytes] = DIRECTORY_SEP; |
SSET (fullname, directory_nbytes, DIRECTORY_SEP); |
266 |
|
|
267 |
bcopy (XSTRING (name)->data, |
bcopy (SDATA (name), |
268 |
XSTRING (fullname)->data + directory_nbytes + needsep, |
SDATA (fullname) + directory_nbytes + needsep, |
269 |
len); |
len); |
270 |
|
|
271 |
nchars = chars_in_text (XSTRING (fullname)->data, nbytes); |
nchars = chars_in_text (SDATA (fullname), nbytes); |
272 |
|
|
273 |
/* Some bug somewhere. */ |
/* Some bug somewhere. */ |
274 |
if (nchars > nbytes) |
if (nchars > nbytes) |
275 |
abort (); |
abort (); |
276 |
|
|
277 |
XSTRING (fullname)->size = nchars; |
STRING_SET_CHARS (fullname, nchars); |
278 |
if (nchars == nbytes) |
if (nchars == nbytes) |
279 |
SET_STRING_BYTES (XSTRING (fullname), -1); |
STRING_SET_UNIBYTE (fullname); |
280 |
|
|
281 |
finalname = fullname; |
finalname = fullname; |
282 |
} |
} |
283 |
else |
else |
327 |
if (NILP (nosort)) |
if (NILP (nosort)) |
328 |
list = Fsort (Fnreverse (list), |
list = Fsort (Fnreverse (list), |
329 |
attrs ? Qfile_attributes_lessp : Qstring_lessp); |
attrs ? Qfile_attributes_lessp : Qstring_lessp); |
330 |
|
|
331 |
RETURN_UNGCPRO (list); |
RETURN_UNGCPRO (list); |
332 |
} |
} |
333 |
|
|
344 |
Lisp_Object directory, full, match, nosort; |
Lisp_Object directory, full, match, nosort; |
345 |
{ |
{ |
346 |
Lisp_Object handler; |
Lisp_Object handler; |
347 |
|
directory = Fexpand_file_name (directory, Qnil); |
348 |
|
|
349 |
/* If the file name has special constructs in it, |
/* If the file name has special constructs in it, |
350 |
call the corresponding file handler. */ |
call the corresponding file handler. */ |
378 |
Lisp_Object directory, full, match, nosort; |
Lisp_Object directory, full, match, nosort; |
379 |
{ |
{ |
380 |
Lisp_Object handler; |
Lisp_Object handler; |
381 |
|
directory = Fexpand_file_name (directory, Qnil); |
382 |
|
|
383 |
/* If the file name has special constructs in it, |
/* If the file name has special constructs in it, |
384 |
call the corresponding file handler. */ |
call the corresponding file handler. */ |
474 |
struct stat st; |
struct stat st; |
475 |
int directoryp; |
int directoryp; |
476 |
int passcount; |
int passcount; |
477 |
int count = specpdl_ptr - specpdl; |
int count = SPECPDL_INDEX (); |
478 |
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; |
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; |
479 |
|
|
480 |
elt = Qnil; |
elt = Qnil; |
520 |
|
|
521 |
for (passcount = !!all_flag; NILP (bestmatch) && passcount < 2; passcount++) |
for (passcount = !!all_flag; NILP (bestmatch) && passcount < 2; passcount++) |
522 |
{ |
{ |
523 |
d = opendir (XSTRING (Fdirectory_file_name (encoded_dir))->data); |
int inner_count = SPECPDL_INDEX (); |
524 |
|
|
525 |
|
d = opendir (SDATA (Fdirectory_file_name (encoded_dir))); |
526 |
if (!d) |
if (!d) |
527 |
report_file_error ("Opening directory", Fcons (dirname, Qnil)); |
report_file_error ("Opening directory", Fcons (dirname, Qnil)); |
528 |
|
|
529 |
|
record_unwind_protect (directory_files_internal_unwind, |
530 |
|
Fcons (make_number (((unsigned long) d) >> 16), |
531 |
|
make_number (((unsigned long) d) & 0xffff))); |
532 |
|
|
533 |
/* Loop reading blocks */ |
/* Loop reading blocks */ |
534 |
/* (att3b compiler bug requires do a null comparison this way) */ |
/* (att3b compiler bug requires do a null comparison this way) */ |
535 |
while (1) |
while (1) |
546 |
|
|
547 |
len = NAMLEN (dp); |
len = NAMLEN (dp); |
548 |
|
|
549 |
if (!NILP (Vquit_flag) && NILP (Vinhibit_quit)) |
QUIT; |
|
goto quit; |
|
550 |
if (! DIRENTRY_NONEMPTY (dp) |
if (! DIRENTRY_NONEMPTY (dp) |
551 |
|| len < XSTRING (encoded_file)->size |
|| len < SCHARS (encoded_file) |
552 |
|| 0 <= scmp (dp->d_name, XSTRING (encoded_file)->data, |
|| 0 <= scmp (dp->d_name, SDATA (encoded_file), |
553 |
XSTRING (encoded_file)->size)) |
SCHARS (encoded_file))) |
554 |
continue; |
continue; |
555 |
|
|
556 |
if (file_name_completion_stat (encoded_dir, dp, &st) < 0) |
if (file_name_completion_stat (encoded_dir, dp, &st) < 0) |
567 |
actually in the way in a directory contains only one file. */ |
actually in the way in a directory contains only one file. */ |
568 |
if (!passcount && TRIVIAL_DIRECTORY_ENTRY (dp->d_name)) |
if (!passcount && TRIVIAL_DIRECTORY_ENTRY (dp->d_name)) |
569 |
continue; |
continue; |
570 |
if (!passcount && len > XSTRING (encoded_file)->size) |
if (!passcount && len > SCHARS (encoded_file)) |
571 |
/* Ignore directories if they match an element of |
/* Ignore directories if they match an element of |
572 |
completion-ignored-extensions which ends in a slash. */ |
completion-ignored-extensions which ends in a slash. */ |
573 |
for (tem = Vcompletion_ignored_extensions; |
for (tem = Vcompletion_ignored_extensions; |
581 |
/* Need to encode ELT, since scmp compares unibyte |
/* Need to encode ELT, since scmp compares unibyte |
582 |
strings only. */ |
strings only. */ |
583 |
elt = ENCODE_FILE (elt); |
elt = ENCODE_FILE (elt); |
584 |
elt_len = XSTRING (elt)->size - 1; /* -1 for trailing / */ |
elt_len = SCHARS (elt) - 1; /* -1 for trailing / */ |
585 |
if (elt_len <= 0) |
if (elt_len <= 0) |
586 |
continue; |
continue; |
587 |
p1 = XSTRING (elt)->data; |
p1 = SDATA (elt); |
588 |
if (p1[elt_len] != '/') |
if (p1[elt_len] != '/') |
589 |
continue; |
continue; |
590 |
skip = len - elt_len; |
skip = len - elt_len; |
600 |
{ |
{ |
601 |
/* Compare extensions-to-be-ignored against end of this file name */ |
/* Compare extensions-to-be-ignored against end of this file name */ |
602 |
/* if name is not an exact match against specified string */ |
/* if name is not an exact match against specified string */ |
603 |
if (!passcount && len > XSTRING (encoded_file)->size) |
if (!passcount && len > SCHARS (encoded_file)) |
604 |
/* and exit this for loop if a match is found */ |
/* and exit this for loop if a match is found */ |
605 |
for (tem = Vcompletion_ignored_extensions; |
for (tem = Vcompletion_ignored_extensions; |
606 |
CONSP (tem); tem = XCDR (tem)) |
CONSP (tem); tem = XCDR (tem)) |
610 |
/* Need to encode ELT, since scmp compares unibyte |
/* Need to encode ELT, since scmp compares unibyte |
611 |
strings only. */ |
strings only. */ |
612 |
elt = ENCODE_FILE (elt); |
elt = ENCODE_FILE (elt); |
613 |
skip = len - XSTRING (elt)->size; |
skip = len - SCHARS (elt); |
614 |
if (skip < 0) continue; |
if (skip < 0) continue; |
615 |
|
|
616 |
if (0 <= scmp (dp->d_name + skip, |
if (0 <= scmp (dp->d_name + skip, |
617 |
XSTRING (elt)->data, |
SDATA (elt), |
618 |
XSTRING (elt)->size)) |
SCHARS (elt))) |
619 |
continue; |
continue; |
620 |
break; |
break; |
621 |
} |
} |
667 |
else |
else |
668 |
{ |
{ |
669 |
bestmatch = name; |
bestmatch = name; |
670 |
bestmatchsize = XSTRING (name)->size; |
bestmatchsize = SCHARS (name); |
671 |
} |
} |
672 |
} |
} |
673 |
else |
else |
674 |
{ |
{ |
675 |
compare = min (bestmatchsize, len); |
compare = min (bestmatchsize, len); |
676 |
p1 = XSTRING (bestmatch)->data; |
p1 = SDATA (bestmatch); |
677 |
p2 = (unsigned char *) dp->d_name; |
p2 = (unsigned char *) dp->d_name; |
678 |
matchsize = scmp(p1, p2, compare); |
matchsize = scmp(p1, p2, compare); |
679 |
if (matchsize < 0) |
if (matchsize < 0) |
687 |
/* This tests that the current file is an exact match |
/* This tests that the current file is an exact match |
688 |
but BESTMATCH is not (it is too long). */ |
but BESTMATCH is not (it is too long). */ |
689 |
if ((matchsize == len |
if ((matchsize == len |
690 |
&& matchsize + !!directoryp |
&& matchsize + !!directoryp |
691 |
< XSTRING (bestmatch)->size) |
< SCHARS (bestmatch)) |
692 |
|| |
|| |
693 |
/* If there is no exact match ignoring case, |
/* If there is no exact match ignoring case, |
694 |
prefer a match that does not change the case |
prefer a match that does not change the case |
700 |
either both or neither are exact. */ |
either both or neither are exact. */ |
701 |
(((matchsize == len) |
(((matchsize == len) |
702 |
== |
== |
703 |
(matchsize + !!directoryp |
(matchsize + !!directoryp |
704 |
== XSTRING (bestmatch)->size)) |
== SCHARS (bestmatch))) |
705 |
&& !bcmp (p2, XSTRING (encoded_file)->data, XSTRING (encoded_file)->size) |
&& !bcmp (p2, SDATA (encoded_file), SCHARS (encoded_file)) |
706 |
&& bcmp (p1, XSTRING (encoded_file)->data, XSTRING (encoded_file)->size))) |
&& bcmp (p1, SDATA (encoded_file), SCHARS (encoded_file)))) |
707 |
{ |
{ |
708 |
bestmatch = make_string (dp->d_name, len); |
bestmatch = make_string (dp->d_name, len); |
709 |
if (directoryp) |
if (directoryp) |
721 |
bestmatchsize = matchsize; |
bestmatchsize = matchsize; |
722 |
} |
} |
723 |
} |
} |
724 |
closedir (d); |
/* This closes the directory. */ |
725 |
|
bestmatch = unbind_to (inner_count, bestmatch); |
726 |
} |
} |
727 |
|
|
728 |
UNGCPRO; |
UNGCPRO; |
734 |
bestmatch = DECODE_FILE (bestmatch); |
bestmatch = DECODE_FILE (bestmatch); |
735 |
return bestmatch; |
return bestmatch; |
736 |
} |
} |
737 |
if (matchcount == 1 && bestmatchsize == XSTRING (file)->size) |
if (matchcount == 1 && bestmatchsize == SCHARS (file)) |
738 |
return Qt; |
return Qt; |
739 |
bestmatch = Fsubstring (bestmatch, make_number (0), |
bestmatch = Fsubstring (bestmatch, make_number (0), |
740 |
make_number (bestmatchsize)); |
make_number (bestmatchsize)); |
742 |
decode it from the coding system in use. */ |
decode it from the coding system in use. */ |
743 |
bestmatch = DECODE_FILE (bestmatch); |
bestmatch = DECODE_FILE (bestmatch); |
744 |
return bestmatch; |
return bestmatch; |
|
|
|
|
quit: |
|
|
if (d) closedir (d); |
|
|
Vquit_flag = Qnil; |
|
|
return Fsignal (Qquit, Qnil); |
|
745 |
} |
} |
746 |
|
|
747 |
/* Compare exactly LEN chars of strings at S1 and S2, |
/* Compare exactly LEN chars of strings at S1 and S2, |
779 |
struct stat *st_addr; |
struct stat *st_addr; |
780 |
{ |
{ |
781 |
int len = NAMLEN (dp); |
int len = NAMLEN (dp); |
782 |
int pos = XSTRING (dirname)->size; |
int pos = SCHARS (dirname); |
783 |
int value; |
int value; |
784 |
char *fullname = (char *) alloca (len + pos + 2); |
char *fullname = (char *) alloca (len + pos + 2); |
785 |
|
|
796 |
#endif /* __DJGPP__ > 1 */ |
#endif /* __DJGPP__ > 1 */ |
797 |
#endif /* MSDOS */ |
#endif /* MSDOS */ |
798 |
|
|
799 |
bcopy (XSTRING (dirname)->data, fullname, pos); |
bcopy (SDATA (dirname), fullname, pos); |
800 |
#ifndef VMS |
#ifndef VMS |
801 |
if (!IS_DIRECTORY_SEP (fullname[pos - 1])) |
if (!IS_DIRECTORY_SEP (fullname[pos - 1])) |
802 |
fullname[pos++] = DIRECTORY_SEP; |
fullname[pos++] = DIRECTORY_SEP; |
849 |
filename = Fexpand_file_name (filename, Qnil); |
filename = Fexpand_file_name (filename, Qnil); |
850 |
fab = cc$rms_fab; |
fab = cc$rms_fab; |
851 |
xabfhc = cc$rms_xabfhc; |
xabfhc = cc$rms_xabfhc; |
852 |
fab.fab$l_fna = XSTRING (filename)->data; |
fab.fab$l_fna = SDATA (filename); |
853 |
fab.fab$b_fns = strlen (fab.fab$l_fna); |
fab.fab$b_fns = strlen (fab.fab$l_fna); |
854 |
fab.fab$l_xab = (char *) &xabfhc; |
fab.fab$l_xab = (char *) &xabfhc; |
855 |
status = sys$open (&fab, 0, 0); |
status = sys$open (&fab, 0, 0); |
918 |
|
|
919 |
encoded = ENCODE_FILE (filename); |
encoded = ENCODE_FILE (filename); |
920 |
|
|
921 |
if (lstat (XSTRING (encoded)->data, &s) < 0) |
if (lstat (SDATA (encoded), &s) < 0) |
922 |
return Qnil; |
return Qnil; |
923 |
|
|
924 |
switch (s.st_mode & S_IFMT) |
switch (s.st_mode & S_IFMT) |
942 |
/* If the size is out of range for an integer, return a float. */ |
/* If the size is out of range for an integer, return a float. */ |
943 |
if (XINT (values[7]) != s.st_size) |
if (XINT (values[7]) != s.st_size) |
944 |
values[7] = make_float ((double)s.st_size); |
values[7] = make_float ((double)s.st_size); |
945 |
|
/* If the size is negative, and its type is long, convert it back to |
946 |
|
positive. */ |
947 |
|
if (s.st_size < 0 && sizeof (s.st_size) == sizeof (long)) |
948 |
|
values[7] = make_float ((double) ((unsigned long) s.st_size)); |
949 |
|
|
950 |
filemodestring (&s, modes); |
filemodestring (&s, modes); |
951 |
values[8] = make_string (modes, 10); |
values[8] = make_string (modes, 10); |
952 |
#if defined (BSD4_2) || defined (BSD4_3) /* file gid will be dir gid */ |
#if defined (BSD4_2) || defined (BSD4_3) /* file gid will be dir gid */ |
953 |
dirname = Ffile_name_directory (filename); |
dirname = Ffile_name_directory (filename); |
954 |
if (! NILP (dirname)) |
if (! NILP (dirname)) |
955 |
encoded = ENCODE_FILE (dirname); |
encoded = ENCODE_FILE (dirname); |
956 |
if (! NILP (dirname) && stat (XSTRING (encoded)->data, &sdir) == 0) |
if (! NILP (dirname) && stat (SDATA (encoded), &sdir) == 0) |
957 |
values[9] = (sdir.st_gid != s.st_gid) ? Qt : Qnil; |
values[9] = (sdir.st_gid != s.st_gid) ? Qt : Qnil; |
958 |
else /* if we can't tell, assume worst */ |
else /* if we can't tell, assume worst */ |
959 |
values[9] = Qt; |
values[9] = Qt; |
960 |
#else /* file gid will be egid */ |
#else /* file gid will be egid */ |
961 |
values[9] = (s.st_gid != getegid ()) ? Qt : Qnil; |
values[9] = (s.st_gid != getegid ()) ? Qt : Qnil; |
962 |
#endif /* BSD4_2 (or BSD4_3) */ |
#endif /* BSD4_2 (or BSD4_3) */ |
|
/* Cast -1 to avoid warning if int is not as wide as VALBITS. */ |
|
963 |
if (FIXNUM_OVERFLOW_P (s.st_ino)) |
if (FIXNUM_OVERFLOW_P (s.st_ino)) |
964 |
/* To allow inode numbers larger than VALBITS, separate the bottom |
/* To allow inode numbers larger than VALBITS, separate the bottom |
965 |
16 bits. */ |
16 bits. */ |