Mercurial > hg > xemacs-beta
comparison src/fileio.c @ 446:1ccc32a20af4 r21-2-38
Import from CVS: tag r21-2-38
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:37:21 +0200 |
parents | 576fb035e263 |
children | 223736d75acb |
comparison
equal
deleted
inserted
replaced
445:34f3776fcf0e | 446:1ccc32a20af4 |
---|---|
746 An initial `~USER/' expands to USER's home directory. | 746 An initial `~USER/' expands to USER's home directory. |
747 See also the function `substitute-in-file-name'. | 747 See also the function `substitute-in-file-name'. |
748 */ | 748 */ |
749 (name, default_directory)) | 749 (name, default_directory)) |
750 { | 750 { |
751 /* This function can GC. GC-checked 2000-07-11 ben */ | 751 /* This function can GC. GC-checked 2000-11-18 */ |
752 Bufbyte *nm; | 752 Bufbyte *nm; |
753 | 753 |
754 Bufbyte *newdir, *p, *o; | 754 Bufbyte *newdir, *p, *o; |
755 int tlen; | 755 int tlen; |
756 Bufbyte *target; | 756 Bufbyte *target; |
759 int collapse_newdir = 1; | 759 int collapse_newdir = 1; |
760 #else | 760 #else |
761 struct passwd *pw; | 761 struct passwd *pw; |
762 #endif /* WIN32_NATIVE */ | 762 #endif /* WIN32_NATIVE */ |
763 int length; | 763 int length; |
764 Lisp_Object handler; | 764 Lisp_Object handler = Qnil; |
765 #ifdef CYGWIN | 765 #ifdef CYGWIN |
766 char *user; | 766 char *user; |
767 #endif | 767 #endif |
768 struct gcpro gcpro1, gcpro2; | 768 struct gcpro gcpro1, gcpro2, gcpro3; |
769 | 769 |
770 /* both of these get set below */ | 770 /* both of these get set below */ |
771 GCPRO2 (name, default_directory); | 771 GCPRO3 (name, default_directory, handler); |
772 | 772 |
773 CHECK_STRING (name); | 773 CHECK_STRING (name); |
774 | 774 |
775 /* If the file name has special constructs in it, | 775 /* If the file name has special constructs in it, |
776 call the corresponding file handler. */ | 776 call the corresponding file handler. */ |
777 handler = Ffind_file_name_handler (name, Qexpand_file_name); | 777 handler = Ffind_file_name_handler (name, Qexpand_file_name); |
778 if (!NILP (handler)) | 778 if (!NILP (handler)) |
779 { | 779 RETURN_UNGCPRO (call3_check_string (handler, Qexpand_file_name, |
780 UNGCPRO; | 780 name, default_directory)); |
781 return call3_check_string (handler, Qexpand_file_name, name, | |
782 default_directory); | |
783 } | |
784 | 781 |
785 /* Use the buffer's default-directory if DEFAULT_DIRECTORY is omitted. */ | 782 /* Use the buffer's default-directory if DEFAULT_DIRECTORY is omitted. */ |
786 if (NILP (default_directory)) | 783 if (NILP (default_directory)) |
787 default_directory = current_buffer->directory; | 784 default_directory = current_buffer->directory; |
788 if (! STRINGP (default_directory)) | 785 if (! STRINGP (default_directory)) |
790 | 787 |
791 if (!NILP (default_directory)) | 788 if (!NILP (default_directory)) |
792 { | 789 { |
793 handler = Ffind_file_name_handler (default_directory, Qexpand_file_name); | 790 handler = Ffind_file_name_handler (default_directory, Qexpand_file_name); |
794 if (!NILP (handler)) | 791 if (!NILP (handler)) |
795 { | 792 RETURN_UNGCPRO (call3 (handler, Qexpand_file_name, |
796 UNGCPRO; | 793 name, default_directory)); |
797 return call3 (handler, Qexpand_file_name, name, default_directory); | |
798 } | |
799 } | 794 } |
800 | 795 |
801 o = XSTRING_DATA (default_directory); | 796 o = XSTRING_DATA (default_directory); |
802 | 797 |
803 /* Make sure DEFAULT_DIRECTORY is properly expanded. | 798 /* Make sure DEFAULT_DIRECTORY is properly expanded. |
1320 | 1315 |
1321 Since we depend on undocumented semantics of various system realpath()s, | 1316 Since we depend on undocumented semantics of various system realpath()s, |
1322 we just use our own version in realpath.c. */ | 1317 we just use our own version in realpath.c. */ |
1323 for (;;) | 1318 for (;;) |
1324 { | 1319 { |
1325 p = (Extbyte *) memchr (p + 1, '/', elen - (p + 1 - path)); | 1320 Extbyte *pos; |
1326 if (p) | 1321 |
1327 *p = 0; | 1322 #ifdef WIN32_NATIVE |
1323 if (IS_DRIVE (p[0]) && IS_DEVICE_SEP (p[1]) | |
1324 && IS_DIRECTORY_SEP (p[2])) | |
1325 /* don't test c: on windows */ | |
1326 p = p+2; | |
1327 else if (IS_DIRECTORY_SEP (p[0]) && IS_DIRECTORY_SEP (p[1])) | |
1328 /* start after // */ | |
1329 p = p+1; | |
1330 #endif | |
1331 for (pos = p + 1; pos < path + elen; pos++) | |
1332 if (IS_DIRECTORY_SEP (*pos)) | |
1333 { | |
1334 *(p = pos) = 0; | |
1335 break; | |
1336 } | |
1337 if (p != pos) | |
1338 p = 0; | |
1328 | 1339 |
1329 if (xrealpath ((char *) path, resolved_path)) | 1340 if (xrealpath ((char *) path, resolved_path)) |
1330 { | 1341 { |
1331 if (p) | 1342 if (p) |
1332 *p = '/'; | 1343 *p = DIRECTORY_SEP; |
1333 else | 1344 else |
1334 break; | 1345 break; |
1335 | 1346 |
1336 } | 1347 } |
1337 else if (errno == ENOENT || errno == EACCES) | 1348 else if (errno == ENOENT || errno == EACCES) |
1346 | 1357 |
1347 if (p) | 1358 if (p) |
1348 { | 1359 { |
1349 int plen = elen - (p - path); | 1360 int plen = elen - (p - path); |
1350 | 1361 |
1351 if (rlen > 1 && resolved_path[rlen - 1] == '/') | 1362 if (rlen > 1 && IS_DIRECTORY_SEP (resolved_path[rlen - 1])) |
1352 rlen = rlen - 1; | 1363 rlen = rlen - 1; |
1353 | 1364 |
1354 if (plen + rlen + 1 > countof (resolved_path)) | 1365 if (plen + rlen + 1 > countof (resolved_path)) |
1355 goto toolong; | 1366 goto toolong; |
1356 | 1367 |
1357 resolved_path[rlen] = '/'; | 1368 resolved_path[rlen] = DIRECTORY_SEP; |
1358 memcpy (resolved_path + rlen + 1, p + 1, plen + 1 - 1); | 1369 memcpy (resolved_path + rlen + 1, p + 1, plen + 1 - 1); |
1359 } | 1370 } |
1360 break; | 1371 break; |
1361 } | 1372 } |
1362 else | 1373 else |
1365 } | 1376 } |
1366 | 1377 |
1367 { | 1378 { |
1368 Lisp_Object resolved_name; | 1379 Lisp_Object resolved_name; |
1369 int rlen = strlen (resolved_path); | 1380 int rlen = strlen (resolved_path); |
1370 if (elen > 0 && XSTRING_BYTE (expanded_name, elen - 1) == '/' | 1381 if (elen > 0 && IS_DIRECTORY_SEP (XSTRING_BYTE (expanded_name, elen - 1)) |
1371 && !(rlen > 0 && resolved_path[rlen - 1] == '/')) | 1382 && !(rlen > 0 && IS_DIRECTORY_SEP (resolved_path[rlen - 1]))) |
1372 { | 1383 { |
1373 if (rlen + 1 > countof (resolved_path)) | 1384 if (rlen + 1 > countof (resolved_path)) |
1374 goto toolong; | 1385 goto toolong; |
1375 resolved_path[rlen++] = '/'; | 1386 resolved_path[rlen++] = DIRECTORY_SEP; |
1376 resolved_path[rlen] = '\0'; | 1387 resolved_path[rlen] = '\0'; |
1377 } | 1388 } |
1378 TO_INTERNAL_FORMAT (DATA, (resolved_path, rlen), | 1389 TO_INTERNAL_FORMAT (DATA, (resolved_path, rlen), |
1379 LISP_STRING, resolved_name, | 1390 LISP_STRING, resolved_name, |
1380 Qfile_name); | 1391 Qfile_name); |
3392 { | 3403 { |
3393 if (visiting_other) | 3404 if (visiting_other) |
3394 message ("Wrote %s", XSTRING_DATA (visit_file)); | 3405 message ("Wrote %s", XSTRING_DATA (visit_file)); |
3395 else | 3406 else |
3396 { | 3407 { |
3397 Lisp_Object fsp; | 3408 Lisp_Object fsp = Qnil; |
3398 struct gcpro nngcpro1; | 3409 struct gcpro nngcpro1; |
3399 | 3410 |
3400 NNGCPRO1 (fsp); | 3411 NNGCPRO1 (fsp); |
3401 fsp = Ffile_symlink_p (fn); | 3412 fsp = Ffile_symlink_p (fn); |
3402 if (NILP (fsp)) | 3413 if (NILP (fsp)) |
3733 lisp_to_time (time_list, &the_time); | 3744 lisp_to_time (time_list, &the_time); |
3734 current_buffer->modtime = (int) the_time; | 3745 current_buffer->modtime = (int) the_time; |
3735 } | 3746 } |
3736 else | 3747 else |
3737 { | 3748 { |
3738 Lisp_Object filename; | 3749 Lisp_Object filename = Qnil; |
3739 struct stat st; | 3750 struct stat st; |
3740 Lisp_Object handler; | 3751 Lisp_Object handler; |
3741 struct gcpro gcpro1, gcpro2, gcpro3; | 3752 struct gcpro gcpro1, gcpro2, gcpro3; |
3742 | 3753 |
3743 GCPRO3 (filename, time_list, current_buffer->filename); | 3754 GCPRO3 (filename, time_list, current_buffer->filename); |