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);