Mercurial > hg > xemacs-beta
comparison src/dired.c @ 219:262b8bb4a523 r20-4b8
Import from CVS: tag r20-4b8
author | cvs |
---|---|
date | Mon, 13 Aug 2007 10:09:35 +0200 |
parents | 41ff10fd062f |
children | 0e522484dd2a |
comparison
equal
deleted
inserted
replaced
218:c9f226976f56 | 219:262b8bb4a523 |
---|---|
180 } | 180 } |
181 | 181 |
182 if (!NILP (full)) | 182 if (!NILP (full)) |
183 name = concat2 (name_as_dir, | 183 name = concat2 (name_as_dir, |
184 make_ext_string ((Bufbyte *)dp->d_name, | 184 make_ext_string ((Bufbyte *)dp->d_name, |
185 len, FORMAT_BINARY)); | 185 len, FORMAT_FILENAME)); |
186 else | 186 else |
187 name = make_ext_string ((Bufbyte *)dp->d_name, | 187 name = make_ext_string ((Bufbyte *)dp->d_name, |
188 len, FORMAT_BINARY); | 188 len, FORMAT_FILENAME); |
189 | 189 |
190 list = Fcons (name, list); | 190 list = Fcons (name, list); |
191 } | 191 } |
192 } | 192 } |
193 } | 193 } |
290 #endif | 290 #endif |
291 return value; | 291 return value; |
292 } | 292 } |
293 | 293 |
294 static Lisp_Object | 294 static Lisp_Object |
295 file_name_completion_unwind (Lisp_Object unwind_obj) | |
296 { | |
297 DIR *d; | |
298 Lisp_Object obj = XCAR (unwind_obj); | |
299 | |
300 if (NILP (obj)) | |
301 return Qnil; | |
302 d = (DIR *)get_opaque_ptr (obj); | |
303 closedir (d); | |
304 free_opaque_ptr (obj); | |
305 return Qnil; | |
306 } | |
307 | |
308 static Lisp_Object | |
295 file_name_completion (Lisp_Object file, Lisp_Object dirname, int all_flag, | 309 file_name_completion (Lisp_Object file, Lisp_Object dirname, int all_flag, |
296 int ver_flag) | 310 int ver_flag) |
297 { | 311 { |
298 /* This function can GC */ | 312 /* This function can GC */ |
299 DIR *d = 0; | 313 DIR *d = 0; |
303 struct stat st; | 317 struct stat st; |
304 int passcount; | 318 int passcount; |
305 int speccount = specpdl_depth (); | 319 int speccount = specpdl_depth (); |
306 Charcount file_name_length; | 320 Charcount file_name_length; |
307 DIRENTRY *((*readfunc) (DIR *)) = readdir; | 321 DIRENTRY *((*readfunc) (DIR *)) = readdir; |
322 Lisp_Object unwind_closure; | |
308 struct gcpro gcpro1, gcpro2, gcpro3; | 323 struct gcpro gcpro1, gcpro2, gcpro3; |
309 | 324 |
310 GCPRO3 (file, dirname, bestmatch); | 325 GCPRO3 (file, dirname, bestmatch); |
311 | 326 |
312 CHECK_STRING (file); | 327 CHECK_STRING (file); |
313 | 328 |
314 /* #### The following is valid not only for VMS, but for NT too. */ | 329 #ifdef WINDOWSNT |
315 #ifdef VMS | 330 /* Filename completion on Windows ignores case, since Windows |
316 /* Filename completion on VMS ignores case, since VMS filesys does. */ | 331 filesystems do. */ |
317 specbind (Qcompletion_ignore_case, Qt); | 332 specbind (Qcompletion_ignore_case, Qt); |
318 | 333 #endif /* HAVE_WINDOWS */ |
319 if (ver_flag) | |
320 readfunc = readdirver; | |
321 #endif /* VMS */ | |
322 | 334 |
323 #ifdef FILE_SYSTEM_CASE | 335 #ifdef FILE_SYSTEM_CASE |
324 file = FILE_SYSTEM_CASE (file); | 336 file = FILE_SYSTEM_CASE (file); |
325 #endif | 337 #endif |
326 dirname = Fexpand_file_name (dirname, Qnil); | 338 dirname = Fexpand_file_name (dirname, Qnil); |
332 so always take even the ignored ones. | 344 so always take even the ignored ones. |
333 | 345 |
334 ** It would not actually be helpful to the user to ignore any possible | 346 ** It would not actually be helpful to the user to ignore any possible |
335 completions when making a list of them.** */ | 347 completions when making a list of them.** */ |
336 | 348 |
349 /* We cannot use close_directory_unwind() because we change the | |
350 directory. The old code used to just avoid signaling errors, and | |
351 call closedir, but it was wrong, because it made sane handling of | |
352 QUIT impossible and, besides, various utility functions like | |
353 regexp_ignore_completion_p can signal errors. */ | |
354 unwind_closure = Fcons (Qnil, Qnil); | |
355 record_unwind_protect (file_name_completion_unwind, unwind_closure); | |
356 | |
337 for (passcount = !!all_flag; NILP (bestmatch) && passcount < 2; passcount++) | 357 for (passcount = !!all_flag; NILP (bestmatch) && passcount < 2; passcount++) |
338 { | 358 { |
339 d = opendir ((char *) XSTRING_DATA (Fdirectory_file_name (dirname))); | 359 d = opendir ((char *) XSTRING_DATA (Fdirectory_file_name (dirname))); |
340 if (!d) | 360 if (!d) |
341 report_file_error ("Opening directory", list1 (dirname)); | 361 report_file_error ("Opening directory", list1 (dirname)); |
362 XCAR (unwind_closure) = make_opaque_ptr ((void *)d); | |
342 | 363 |
343 /* Loop reading blocks */ | 364 /* Loop reading blocks */ |
344 while (1) | 365 while (1) |
345 { | 366 { |
346 DIRENTRY *dp; | 367 DIRENTRY *dp; |
353 Bufbyte *d_name; | 374 Bufbyte *d_name; |
354 | 375 |
355 dp = (*readfunc) (d); | 376 dp = (*readfunc) (d); |
356 if (!dp) break; | 377 if (!dp) break; |
357 | 378 |
379 /* #### This is a bad idea, because d_name can contain | |
380 control characters, which can make XEmacs crash. This | |
381 should be handled properly with FORMAT_FILENAME. */ | |
358 d_name = (Bufbyte *) dp->d_name; | 382 d_name = (Bufbyte *) dp->d_name; |
359 len = NAMLEN (dp); | 383 len = NAMLEN (dp); |
360 cclen = bytecount_to_charcount (d_name, len); | 384 cclen = bytecount_to_charcount (d_name, len); |
361 | 385 |
362 /* Can't just use QUIT because we have to make sure the file | 386 QUIT; |
363 descriptor gets closed. */ | |
364 if (QUITP) | |
365 { | |
366 closedir (d); | |
367 signal_quit (); | |
368 } | |
369 | 387 |
370 if (! DIRENTRY_NONEMPTY (dp) | 388 if (! DIRENTRY_NONEMPTY (dp) |
371 || cclen < file_name_length | 389 || cclen < file_name_length |
372 || 0 <= scmp (d_name, XSTRING_DATA (file), file_name_length)) | 390 || 0 <= scmp (d_name, XSTRING_DATA (file), file_name_length)) |
373 continue; | 391 continue; |
392 /* if name is not an exact match against specified string. */ | 410 /* if name is not an exact match against specified string. */ |
393 if (!passcount && cclen > file_name_length) | 411 if (!passcount && cclen > file_name_length) |
394 { | 412 { |
395 Lisp_Object tem; | 413 Lisp_Object tem; |
396 /* and exit this for loop if a match is found */ | 414 /* and exit this for loop if a match is found */ |
397 for (tem = Vcompletion_ignored_extensions; | 415 EXTERNAL_LIST_LOOP (tem, Vcompletion_ignored_extensions) |
398 CONSP (tem); | |
399 tem = XCDR (tem)) | |
400 { | 416 { |
401 Lisp_Object elt = XCAR (tem); | 417 Lisp_Object elt = XCAR (tem); |
402 Charcount skip; | 418 Charcount skip; |
403 | 419 |
404 if (!STRINGP (elt)) continue; | 420 CHECK_STRING (elt); |
421 | |
405 skip = cclen - string_char_length (XSTRING (elt)); | 422 skip = cclen - string_char_length (XSTRING (elt)); |
406 if (skip < 0) continue; | 423 if (skip < 0) continue; |
407 | 424 |
408 if (0 > scmp (charptr_n_addr (d_name, skip), | 425 if (0 > scmp (charptr_n_addr (d_name, skip), |
409 XSTRING_DATA (elt), | 426 XSTRING_DATA (elt), |
496 matchsize++; | 513 matchsize++; |
497 bestmatchsize = matchsize; | 514 bestmatchsize = matchsize; |
498 } | 515 } |
499 } | 516 } |
500 closedir (d); | 517 closedir (d); |
518 free_opaque_ptr (XCAR (unwind_closure)); | |
519 XCAR (unwind_closure) = Qnil; | |
501 } | 520 } |
502 | 521 |
503 unbind_to (speccount, Qnil); | 522 unbind_to (speccount, Qnil); |
504 | 523 |
505 UNGCPRO; | 524 UNGCPRO; |
525 while ((dp = readdir (d))) | 544 while ((dp = readdir (d))) |
526 { | 545 { |
527 len = NAMLEN (dp); | 546 len = NAMLEN (dp); |
528 if (DIRENTRY_NONEMPTY (dp)) | 547 if (DIRENTRY_NONEMPTY (dp)) |
529 Fputhash (make_ext_string ((Bufbyte *) dp->d_name, len, | 548 Fputhash (make_ext_string ((Bufbyte *) dp->d_name, len, |
530 FORMAT_BINARY), Qt, hash); | 549 FORMAT_FILENAME), Qt, hash); |
531 } | 550 } |
532 closedir (d); | 551 closedir (d); |
533 } | 552 } |
534 return hash; | 553 return hash; |
535 } | 554 } |