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 }