Mercurial > hg > xemacs-beta
comparison src/dired.c @ 396:6719134a07c2 r21-2-13
Import from CVS: tag r21-2-13
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:12:05 +0200 |
parents | bbff43aa5eb7 |
children | 74fd4e045ea6 |
comparison
equal
deleted
inserted
replaced
395:de2c2a7459d2 | 396:6719134a07c2 |
---|---|
59 will be returned; subdirectories will be excluded. If FILES-ONLY is not | 59 will be returned; subdirectories will be excluded. If FILES-ONLY is not |
60 nil and not t, then only the subdirectories will be returned. Otherwise, | 60 nil and not t, then only the subdirectories will be returned. Otherwise, |
61 if FILES-ONLY is nil (the default) then both files and subdirectories will | 61 if FILES-ONLY is nil (the default) then both files and subdirectories will |
62 be returned. | 62 be returned. |
63 */ | 63 */ |
64 (dirname, full, match, nosort, files_only)) | 64 (directory, full, match, nosort, files_only)) |
65 { | 65 { |
66 /* This function can GC */ | 66 /* This function can GC */ |
67 DIR *d; | 67 DIR *d; |
68 Lisp_Object list = Qnil; | 68 Lisp_Object list = Qnil; |
69 Bytecount dirnamelen; | 69 Bytecount directorylen; |
70 Lisp_Object handler; | 70 Lisp_Object handler; |
71 struct re_pattern_buffer *bufp = NULL; | 71 struct re_pattern_buffer *bufp = NULL; |
72 int speccount = specpdl_depth (); | 72 int speccount = specpdl_depth (); |
73 char *statbuf, *statbuf_tail; | 73 char *statbuf, *statbuf_tail; |
74 | 74 |
75 struct gcpro gcpro1, gcpro2; | 75 struct gcpro gcpro1, gcpro2; |
76 GCPRO2 (dirname, list); | 76 GCPRO2 (directory, list); |
77 | 77 |
78 /* If the file name has special constructs in it, | 78 /* If the file name has special constructs in it, |
79 call the corresponding file handler. */ | 79 call the corresponding file handler. */ |
80 handler = Ffind_file_name_handler (dirname, Qdirectory_files); | 80 handler = Ffind_file_name_handler (directory, Qdirectory_files); |
81 if (!NILP (handler)) | 81 if (!NILP (handler)) |
82 { | 82 { |
83 UNGCPRO; | 83 UNGCPRO; |
84 if (!NILP (files_only)) | 84 if (!NILP (files_only)) |
85 return call6 (handler, Qdirectory_files, dirname, full, match, nosort, | 85 return call6 (handler, Qdirectory_files, directory, full, match, |
86 files_only); | 86 nosort, files_only); |
87 else | 87 else |
88 return call5 (handler, Qdirectory_files, dirname, full, match, | 88 return call5 (handler, Qdirectory_files, directory, full, match, |
89 nosort); | 89 nosort); |
90 } | 90 } |
91 | 91 |
92 /* #### why do we do Fexpand_file_name after file handlers here, | 92 /* #### why do we do Fexpand_file_name after file handlers here, |
93 but earlier everywhere else? */ | 93 but earlier everywhere else? */ |
94 dirname = Fexpand_file_name (dirname, Qnil); | 94 directory = Fexpand_file_name (directory, Qnil); |
95 dirname = Ffile_name_as_directory (dirname); | 95 directory = Ffile_name_as_directory (directory); |
96 dirnamelen = XSTRING_LENGTH (dirname); | 96 directorylen = XSTRING_LENGTH (directory); |
97 | 97 |
98 statbuf = (char *)alloca (dirnamelen + MAXNAMLEN + 1); | 98 statbuf = (char *)alloca (directorylen + MAXNAMLEN + 1); |
99 memcpy (statbuf, XSTRING_DATA (dirname), dirnamelen); | 99 memcpy (statbuf, XSTRING_DATA (directory), directorylen); |
100 statbuf_tail = statbuf + dirnamelen; | 100 statbuf_tail = statbuf + directorylen; |
101 | 101 |
102 /* XEmacs: this should come after Ffile_name_as_directory() to avoid | 102 /* XEmacs: this should come after Ffile_name_as_directory() to avoid |
103 potential regexp cache smashage. It comes before the opendir() | 103 potential regexp cache smashage. It comes before the opendir() |
104 because it might signal an error. */ | 104 because it might signal an error. */ |
105 if (!NILP (match)) | 105 if (!NILP (match)) |
116 which might compile a new regexp until we're done with the loop! */ | 116 which might compile a new regexp until we're done with the loop! */ |
117 | 117 |
118 /* Do this opendir after anything which might signal an error. | 118 /* Do this opendir after anything which might signal an error. |
119 NOTE: the above comment is old; previously, there was no | 119 NOTE: the above comment is old; previously, there was no |
120 unwind-protection in case of error, but now there is. */ | 120 unwind-protection in case of error, but now there is. */ |
121 d = opendir ((char *) XSTRING_DATA (dirname)); | 121 d = opendir ((char *) XSTRING_DATA (directory)); |
122 if (!d) | 122 if (!d) |
123 report_file_error ("Opening directory", list1 (dirname)); | 123 report_file_error ("Opening directory", list1 (directory)); |
124 | 124 |
125 record_unwind_protect (close_directory_unwind, make_opaque_ptr ((void *)d)); | 125 record_unwind_protect (close_directory_unwind, make_opaque_ptr ((void *)d)); |
126 | 126 |
127 /* Loop reading blocks */ | 127 /* Loop reading blocks */ |
128 while (1) | 128 while (1) |
155 malloced buffer, and free it. It is undefined how | 155 malloced buffer, and free it. It is undefined how |
156 stat() will react to this, but we avoid a buffer | 156 stat() will react to this, but we avoid a buffer |
157 overrun. */ | 157 overrun. */ |
158 if (len > MAXNAMLEN) | 158 if (len > MAXNAMLEN) |
159 { | 159 { |
160 cur_statbuf = (char *)xmalloc (dirnamelen + len + 1); | 160 cur_statbuf = (char *)xmalloc (directorylen + len + 1); |
161 memcpy (cur_statbuf, statbuf, dirnamelen); | 161 memcpy (cur_statbuf, statbuf, directorylen); |
162 cur_statbuf_tail = cur_statbuf + dirnamelen; | 162 cur_statbuf_tail = cur_statbuf + directorylen; |
163 } | 163 } |
164 memcpy (cur_statbuf_tail, dp->d_name, len); | 164 memcpy (cur_statbuf_tail, dp->d_name, len); |
165 cur_statbuf_tail[len] = 0; | 165 cur_statbuf_tail[len] = 0; |
166 | 166 |
167 if (stat (cur_statbuf, &st) < 0) | 167 if (stat (cur_statbuf, &st) < 0) |
180 | 180 |
181 { | 181 { |
182 Lisp_Object name = | 182 Lisp_Object name = |
183 make_string ((Bufbyte *)dp->d_name, len); | 183 make_string ((Bufbyte *)dp->d_name, len); |
184 if (!NILP (full)) | 184 if (!NILP (full)) |
185 name = concat2 (dirname, name); | 185 name = concat2 (directory, name); |
186 | 186 |
187 list = Fcons (name, list); | 187 list = Fcons (name, list); |
188 } | 188 } |
189 } | 189 } |
190 } | 190 } |
195 | 195 |
196 RETURN_UNGCPRO (list); | 196 RETURN_UNGCPRO (list); |
197 } | 197 } |
198 | 198 |
199 static Lisp_Object file_name_completion (Lisp_Object file, | 199 static Lisp_Object file_name_completion (Lisp_Object file, |
200 Lisp_Object dirname, | 200 Lisp_Object directory, |
201 int all_flag, int ver_flag); | 201 int all_flag, int ver_flag); |
202 | 202 |
203 DEFUN ("file-name-completion", Ffile_name_completion, 2, 2, 0, /* | 203 DEFUN ("file-name-completion", Ffile_name_completion, 2, 2, 0, /* |
204 Complete file name FILE in directory DIR. | 204 Complete file name FILE in directory DIRECTORY. |
205 Returns the longest string common to all filenames in DIR | 205 Returns the longest string common to all filenames in DIRECTORY |
206 that start with FILE. | 206 that start with FILE. |
207 If there is only one and FILE matches it exactly, returns t. | 207 If there is only one and FILE matches it exactly, returns t. |
208 Returns nil if DIR contains no name starting with FILE. | 208 Returns nil if DIRECTORY contains no name starting with FILE. |
209 | 209 |
210 Filenames which end with any member of `completion-ignored-extensions' | 210 Filenames which end with any member of `completion-ignored-extensions' |
211 are not considered as possible completions for FILE unless there is no | 211 are not considered as possible completions for FILE unless there is no |
212 other possible completion. `completion-ignored-extensions' is not applied | 212 other possible completion. `completion-ignored-extensions' is not applied |
213 to the names of directories. | 213 to the names of directories. |
214 */ | 214 */ |
215 (file, dirname)) | 215 (file, directory)) |
216 { | 216 { |
217 /* This function can GC. GC checked 1996.04.06. */ | 217 /* This function can GC. GC checked 1996.04.06. */ |
218 Lisp_Object handler; | 218 Lisp_Object handler; |
219 | 219 |
220 /* If the directory name has special constructs in it, | 220 /* If the directory name has special constructs in it, |
221 call the corresponding file handler. */ | 221 call the corresponding file handler. */ |
222 handler = Ffind_file_name_handler (dirname, Qfile_name_completion); | 222 handler = Ffind_file_name_handler (directory, Qfile_name_completion); |
223 if (!NILP (handler)) | 223 if (!NILP (handler)) |
224 return call3 (handler, Qfile_name_completion, file, dirname); | 224 return call3 (handler, Qfile_name_completion, file, directory); |
225 | 225 |
226 /* If the file name has special constructs in it, | 226 /* If the file name has special constructs in it, |
227 call the corresponding file handler. */ | 227 call the corresponding file handler. */ |
228 handler = Ffind_file_name_handler (file, Qfile_name_completion); | 228 handler = Ffind_file_name_handler (file, Qfile_name_completion); |
229 if (!NILP (handler)) | 229 if (!NILP (handler)) |
230 return call3 (handler, Qfile_name_completion, file, dirname); | 230 return call3 (handler, Qfile_name_completion, file, directory); |
231 | 231 |
232 return file_name_completion (file, dirname, 0, 0); | 232 return file_name_completion (file, directory, 0, 0); |
233 } | 233 } |
234 | 234 |
235 DEFUN ("file-name-all-completions", Ffile_name_all_completions, 2, 2, 0, /* | 235 DEFUN ("file-name-all-completions", Ffile_name_all_completions, 2, 2, 0, /* |
236 Return a list of all completions of file name FILE in directory DIR. | 236 Return a list of all completions of file name FILE in directory DIRECTORY. |
237 These are all file names in directory DIR which begin with FILE. | 237 These are all file names in directory DIRECTORY which begin with FILE. |
238 | 238 |
239 Filenames which end with any member of `completion-ignored-extensions' | 239 File names which end with any member of `completion-ignored-extensions' |
240 are not considered as possible completions for FILE unless there is no | 240 are not considered as possible completions for FILE unless there is no |
241 other possible completion. `completion-ignored-extensions' is not applied | 241 other possible completion. `completion-ignored-extensions' is not applied |
242 to the names of directories. | 242 to the names of directories. |
243 */ | 243 */ |
244 (file, dirname)) | 244 (file, directory)) |
245 { | 245 { |
246 /* This function can GC. GC checked 1997.06.04. */ | 246 /* This function can GC. GC checked 1997.06.04. */ |
247 Lisp_Object handler; | 247 Lisp_Object handler; |
248 struct gcpro gcpro1; | 248 struct gcpro gcpro1; |
249 | 249 |
250 GCPRO1 (dirname); | 250 GCPRO1 (directory); |
251 dirname = Fexpand_file_name (dirname, Qnil); | 251 directory = Fexpand_file_name (directory, Qnil); |
252 /* If the file name has special constructs in it, | 252 /* If the file name has special constructs in it, |
253 call the corresponding file handler. */ | 253 call the corresponding file handler. */ |
254 handler = Ffind_file_name_handler (dirname, Qfile_name_all_completions); | 254 handler = Ffind_file_name_handler (directory, Qfile_name_all_completions); |
255 UNGCPRO; | 255 UNGCPRO; |
256 if (!NILP (handler)) | 256 if (!NILP (handler)) |
257 return call3 (handler, Qfile_name_all_completions, file, | 257 return call3 (handler, Qfile_name_all_completions, file, |
258 dirname); | 258 directory); |
259 | 259 |
260 return file_name_completion (file, dirname, 1, 0); | 260 return file_name_completion (file, directory, 1, 0); |
261 } | 261 } |
262 | 262 |
263 static int | 263 static int |
264 file_name_completion_stat (Lisp_Object dirname, DIRENTRY *dp, | 264 file_name_completion_stat (Lisp_Object directory, DIRENTRY *dp, |
265 struct stat *st_addr) | 265 struct stat *st_addr) |
266 { | 266 { |
267 Bytecount len = NAMLEN (dp); | 267 Bytecount len = NAMLEN (dp); |
268 Bytecount pos = XSTRING_LENGTH (dirname); | 268 Bytecount pos = XSTRING_LENGTH (directory); |
269 int value; | 269 int value; |
270 char *fullname = (char *) alloca (len + pos + 2); | 270 char *fullname = (char *) alloca (len + pos + 2); |
271 | 271 |
272 memcpy (fullname, XSTRING_DATA (dirname), pos); | 272 memcpy (fullname, XSTRING_DATA (directory), pos); |
273 if (!IS_DIRECTORY_SEP (fullname[pos - 1])) | 273 if (!IS_DIRECTORY_SEP (fullname[pos - 1])) |
274 fullname[pos++] = DIRECTORY_SEP; | 274 fullname[pos++] = DIRECTORY_SEP; |
275 | 275 |
276 memcpy (fullname + pos, dp->d_name, len); | 276 memcpy (fullname + pos, dp->d_name, len); |
277 fullname[pos + len] = 0; | 277 fullname[pos + len] = 0; |
304 free_cons (XCONS (locative)); | 304 free_cons (XCONS (locative)); |
305 return Qnil; | 305 return Qnil; |
306 } | 306 } |
307 | 307 |
308 static Lisp_Object | 308 static Lisp_Object |
309 file_name_completion (Lisp_Object file, Lisp_Object dirname, int all_flag, | 309 file_name_completion (Lisp_Object file, Lisp_Object directory, int all_flag, |
310 int ver_flag) | 310 int ver_flag) |
311 { | 311 { |
312 /* This function can GC */ | 312 /* This function can GC */ |
313 DIR *d = 0; | 313 DIR *d = 0; |
314 int matchcount = 0; | 314 int matchcount = 0; |
319 int speccount = specpdl_depth (); | 319 int speccount = specpdl_depth (); |
320 Charcount file_name_length; | 320 Charcount file_name_length; |
321 Lisp_Object locative; | 321 Lisp_Object locative; |
322 struct gcpro gcpro1, gcpro2, gcpro3; | 322 struct gcpro gcpro1, gcpro2, gcpro3; |
323 | 323 |
324 GCPRO3 (file, dirname, bestmatch); | 324 GCPRO3 (file, directory, bestmatch); |
325 | 325 |
326 CHECK_STRING (file); | 326 CHECK_STRING (file); |
327 | 327 |
328 #ifdef WINDOWSNT | 328 #ifdef WINDOWSNT |
329 /* Filename completion on Windows ignores case, since Windows | 329 /* Filename completion on Windows ignores case, since Windows |
332 #endif /* WINDOWSNT */ | 332 #endif /* WINDOWSNT */ |
333 | 333 |
334 #ifdef FILE_SYSTEM_CASE | 334 #ifdef FILE_SYSTEM_CASE |
335 file = FILE_SYSTEM_CASE (file); | 335 file = FILE_SYSTEM_CASE (file); |
336 #endif | 336 #endif |
337 dirname = Fexpand_file_name (dirname, Qnil); | 337 directory = Fexpand_file_name (directory, Qnil); |
338 file_name_length = XSTRING_CHAR_LENGTH (file); | 338 file_name_length = XSTRING_CHAR_LENGTH (file); |
339 | 339 |
340 /* With passcount = 0, ignore files that end in an ignored extension. | 340 /* With passcount = 0, ignore files that end in an ignored extension. |
341 If nothing found then try again with passcount = 1, don't ignore them. | 341 If nothing found then try again with passcount = 1, don't ignore them. |
342 If looking for all completions, start with passcount = 1, | 342 If looking for all completions, start with passcount = 1, |
353 locative = noseeum_cons (Qnil, Qnil); | 353 locative = noseeum_cons (Qnil, Qnil); |
354 record_unwind_protect (file_name_completion_unwind, locative); | 354 record_unwind_protect (file_name_completion_unwind, locative); |
355 | 355 |
356 for (passcount = !!all_flag; NILP (bestmatch) && passcount < 2; passcount++) | 356 for (passcount = !!all_flag; NILP (bestmatch) && passcount < 2; passcount++) |
357 { | 357 { |
358 d = opendir ((char *) XSTRING_DATA (Fdirectory_file_name (dirname))); | 358 d = opendir ((char *) XSTRING_DATA (Fdirectory_file_name (directory))); |
359 if (!d) | 359 if (!d) |
360 report_file_error ("Opening directory", list1 (dirname)); | 360 report_file_error ("Opening directory", list1 (directory)); |
361 XCAR (locative) = make_opaque_ptr ((void *)d); | 361 XCAR (locative) = make_opaque_ptr ((void *)d); |
362 | 362 |
363 /* Loop reading blocks */ | 363 /* Loop reading blocks */ |
364 while (1) | 364 while (1) |
365 { | 365 { |
385 if (! DIRENTRY_NONEMPTY (dp) | 385 if (! DIRENTRY_NONEMPTY (dp) |
386 || cclen < file_name_length | 386 || cclen < file_name_length |
387 || 0 <= scmp (d_name, XSTRING_DATA (file), file_name_length)) | 387 || 0 <= scmp (d_name, XSTRING_DATA (file), file_name_length)) |
388 continue; | 388 continue; |
389 | 389 |
390 if (file_name_completion_stat (dirname, dp, &st) < 0) | 390 if (file_name_completion_stat (directory, dp, &st) < 0) |
391 continue; | 391 continue; |
392 | 392 |
393 directoryp = ((st.st_mode & S_IFMT) == S_IFDIR); | 393 directoryp = ((st.st_mode & S_IFMT) == S_IFDIR); |
394 if (directoryp) | 394 if (directoryp) |
395 { | 395 { |
499 if (directoryp) | 499 if (directoryp) |
500 bestmatch = Ffile_name_as_directory (bestmatch); | 500 bestmatch = Ffile_name_as_directory (bestmatch); |
501 } | 501 } |
502 } | 502 } |
503 | 503 |
504 /* If this dirname all matches, | 504 /* If this directory all matches, |
505 see if implicit following slash does too. */ | 505 see if implicit following slash does too. */ |
506 if (directoryp | 506 if (directoryp |
507 && compare == matchsize | 507 && compare == matchsize |
508 && bestmatchsize > matchsize | 508 && bestmatchsize > matchsize |
509 && IS_ANY_SEP (charptr_emchar_n (p1, matchsize))) | 509 && IS_ANY_SEP (charptr_emchar_n (p1, matchsize))) |
829 */ | 829 */ |
830 (filename)) | 830 (filename)) |
831 { | 831 { |
832 /* This function can GC. GC checked 1997.06.04. */ | 832 /* This function can GC. GC checked 1997.06.04. */ |
833 Lisp_Object values[12]; | 833 Lisp_Object values[12]; |
834 Lisp_Object dirname = Qnil; | 834 Lisp_Object directory = Qnil; |
835 struct stat s; | 835 struct stat s; |
836 char modes[10]; | 836 char modes[10]; |
837 Lisp_Object handler; | 837 Lisp_Object handler; |
838 struct gcpro gcpro1, gcpro2; | 838 struct gcpro gcpro1, gcpro2; |
839 | 839 |
840 GCPRO2 (filename, dirname); | 840 GCPRO2 (filename, directory); |
841 filename = Fexpand_file_name (filename, Qnil); | 841 filename = Fexpand_file_name (filename, Qnil); |
842 | 842 |
843 /* If the file name has special constructs in it, | 843 /* If the file name has special constructs in it, |
844 call the corresponding file handler. */ | 844 call the corresponding file handler. */ |
845 handler = Ffind_file_name_handler (filename, Qfile_attributes); | 845 handler = Ffind_file_name_handler (filename, Qfile_attributes); |
854 UNGCPRO; | 854 UNGCPRO; |
855 return Qnil; | 855 return Qnil; |
856 } | 856 } |
857 | 857 |
858 #ifdef BSD4_2 | 858 #ifdef BSD4_2 |
859 dirname = Ffile_name_directory (filename); | 859 directory = Ffile_name_directory (filename); |
860 #endif | 860 #endif |
861 | 861 |
862 #ifdef MSDOS | 862 #ifdef MSDOS |
863 { | 863 { |
864 char *tmpnam = (char *) XSTRING_DATA (Ffile_name_nondirectory (filename)); | 864 char *tmpnam = (char *) XSTRING_DATA (Ffile_name_nondirectory (filename)); |
904 values[8] = make_string ((Bufbyte *) modes, 10); | 904 values[8] = make_string ((Bufbyte *) modes, 10); |
905 #if defined (BSD4_2) || defined (BSD4_3) /* file gid will be dir gid */ | 905 #if defined (BSD4_2) || defined (BSD4_3) /* file gid will be dir gid */ |
906 { | 906 { |
907 struct stat sdir; | 907 struct stat sdir; |
908 | 908 |
909 if (!NILP (dirname) && stat ((char *) XSTRING_DATA (dirname), &sdir) == 0) | 909 if (!NILP (directory) && stat ((char *) XSTRING_DATA (directory), &sdir) == 0) |
910 values[9] = (sdir.st_gid != s.st_gid) ? Qt : Qnil; | 910 values[9] = (sdir.st_gid != s.st_gid) ? Qt : Qnil; |
911 else /* if we can't tell, assume worst */ | 911 else /* if we can't tell, assume worst */ |
912 values[9] = Qt; | 912 values[9] = Qt; |
913 } | 913 } |
914 #else /* file gid will be egid */ | 914 #else /* file gid will be egid */ |