Mercurial > hg > xemacs-beta
comparison src/fileio.c @ 657:ce0b3f2eff35
[xemacs-hg @ 2001-09-09 04:37:41 by andyp]
DDE, netinstall and cygwin file fixes
author | andyp |
---|---|
date | Sun, 09 Sep 2001 04:37:48 +0000 |
parents | b39c14581166 |
children | 6e99cc8c6ca5 |
comparison
equal
deleted
inserted
replaced
656:4035041996d8 | 657:ce0b3f2eff35 |
---|---|
51 #ifdef HPUX_PRE_8_0 | 51 #ifdef HPUX_PRE_8_0 |
52 #include <errnet.h> | 52 #include <errnet.h> |
53 #endif /* HPUX_PRE_8_0 */ | 53 #endif /* HPUX_PRE_8_0 */ |
54 #endif /* HPUX */ | 54 #endif /* HPUX */ |
55 | 55 |
56 #if defined(WIN32_NATIVE) || defined(CYGWIN) | |
57 #define WIN32_FILENAMES | |
56 #ifdef WIN32_NATIVE | 58 #ifdef WIN32_NATIVE |
57 #include "nt.h" | 59 #include "nt.h" |
60 #endif /* WIN32_NATIVE */ | |
58 #define IS_DRIVE(x) isalpha (x) | 61 #define IS_DRIVE(x) isalpha (x) |
59 /* Need to lower-case the drive letter, or else expanded | 62 /* Need to lower-case the drive letter, or else expanded |
60 filenames will sometimes compare inequal, because | 63 filenames will sometimes compare inequal, because |
61 `expand-file-name' doesn't always down-case the drive letter. */ | 64 `expand-file-name' doesn't always down-case the drive letter. */ |
62 #define DRIVE_LETTER(x) tolower (x) | 65 #define DRIVE_LETTER(x) tolower (x) |
63 #endif /* WIN32_NATIVE */ | 66 #ifndef CORRECT_DIR_SEPS |
67 #define CORRECT_DIR_SEPS(s) \ | |
68 normalize_filename(s, DIRECTORY_SEP) | |
69 /* Default implementation that coerces a file to use path_sep. */ | |
70 static void | |
71 normalize_filename (char *fp, char path_sep) | |
72 { | |
73 /* Always lower-case drive letters a-z, even if the filesystem | |
74 preserves case in filenames. | |
75 This is so filenames can be compared by string comparison | |
76 functions that are case-sensitive. Even case-preserving filesystems | |
77 do not distinguish case in drive letters. */ | |
78 if (fp[1] == ':' && *fp >= 'A' && *fp <= 'Z') | |
79 { | |
80 *fp += 'a' - 'A'; | |
81 fp += 2; | |
82 } | |
83 | |
84 while (*fp) | |
85 { | |
86 if (*fp == '/' || *fp == '\\') | |
87 *fp = path_sep; | |
88 fp++; | |
89 } | |
90 } | |
91 #endif /* CORRECT_DIR_SEPS */ | |
92 #endif /* WIN32_NATIVE || CYGWIN */ | |
64 | 93 |
65 int lisp_to_time (Lisp_Object, time_t *); | 94 int lisp_to_time (Lisp_Object, time_t *); |
66 Lisp_Object time_to_lisp (time_t); | 95 Lisp_Object time_to_lisp (time_t); |
67 | 96 |
68 /* Nonzero during writing of auto-save files */ | 97 /* Nonzero during writing of auto-save files */ |
357 #endif | 386 #endif |
358 beg = XSTRING_DATA (filename); | 387 beg = XSTRING_DATA (filename); |
359 p = beg + XSTRING_LENGTH (filename); | 388 p = beg + XSTRING_LENGTH (filename); |
360 | 389 |
361 while (p != beg && !IS_ANY_SEP (p[-1]) | 390 while (p != beg && !IS_ANY_SEP (p[-1]) |
362 #ifdef WIN32_NATIVE | 391 #ifdef WIN32_FILENAMES |
363 /* only recognize drive specifier at beginning */ | 392 /* only recognize drive specifier at beginning */ |
364 && !(p[-1] == ':' && p == beg + 2) | 393 && !(p[-1] == ':' && p == beg + 2) |
365 #endif | 394 #endif |
366 ) p--; | 395 ) p--; |
367 | 396 |
412 | 441 |
413 beg = XSTRING_DATA (filename); | 442 beg = XSTRING_DATA (filename); |
414 end = p = beg + XSTRING_LENGTH (filename); | 443 end = p = beg + XSTRING_LENGTH (filename); |
415 | 444 |
416 while (p != beg && !IS_ANY_SEP (p[-1]) | 445 while (p != beg && !IS_ANY_SEP (p[-1]) |
417 #ifdef WIN32_NATIVE | 446 #ifdef WIN32_FILENAMES |
418 /* only recognize drive specifier at beginning */ | 447 /* only recognize drive specifier at beginning */ |
419 && !(p[-1] == ':' && p == beg + 2) | 448 && !(p[-1] == ':' && p == beg + 2) |
420 #endif | 449 #endif |
421 ) p--; | 450 ) p--; |
422 | 451 |
516 /* Process as Unix format: just remove any final slash. | 545 /* Process as Unix format: just remove any final slash. |
517 But leave "/" unchanged; do not change it to "". */ | 546 But leave "/" unchanged; do not change it to "". */ |
518 strcpy (dst, src); | 547 strcpy (dst, src); |
519 if (slen > 1 | 548 if (slen > 1 |
520 && IS_DIRECTORY_SEP (dst[slen - 1]) | 549 && IS_DIRECTORY_SEP (dst[slen - 1]) |
521 #ifdef WIN32_NATIVE | 550 #ifdef WIN32_FILENAMES |
522 && !IS_ANY_SEP (dst[slen - 2]) | 551 && !IS_ANY_SEP (dst[slen - 2]) |
523 #endif /* WIN32_NATIVE */ | 552 #endif /* WIN32_FILENAMES */ |
524 ) | 553 ) |
525 dst[slen - 1] = 0; | 554 dst[slen - 1] = 0; |
526 return 1; | 555 return 1; |
527 } | 556 } |
528 | 557 |
685 Bufbyte *nm; | 714 Bufbyte *nm; |
686 | 715 |
687 Bufbyte *newdir, *p, *o; | 716 Bufbyte *newdir, *p, *o; |
688 int tlen; | 717 int tlen; |
689 Bufbyte *target; | 718 Bufbyte *target; |
690 #ifdef WIN32_NATIVE | 719 #ifdef WIN32_FILENAMES |
691 int drive = 0; | 720 int drive = 0; |
692 int collapse_newdir = 1; | 721 int collapse_newdir = 1; |
693 #else | 722 #endif |
723 #ifndef WIN32_NATIVE | |
694 struct passwd *pw; | 724 struct passwd *pw; |
695 #endif /* WIN32_NATIVE */ | 725 #endif /* WIN32_FILENAMES */ |
696 int length; | 726 int length; |
697 Lisp_Object handler = Qnil; | 727 Lisp_Object handler = Qnil; |
698 #ifdef CYGWIN | 728 #ifdef CYGWIN |
699 char *user; | 729 char *user; |
700 #endif | 730 #endif |
740 The EQ test avoids infinite recursion. */ | 770 The EQ test avoids infinite recursion. */ |
741 if (! NILP (default_directory) && !EQ (default_directory, name) | 771 if (! NILP (default_directory) && !EQ (default_directory, name) |
742 /* Save time in some common cases - as long as default_directory | 772 /* Save time in some common cases - as long as default_directory |
743 is not relative, it can be canonicalized with name below (if it | 773 is not relative, it can be canonicalized with name below (if it |
744 is needed at all) without requiring it to be expanded now. */ | 774 is needed at all) without requiring it to be expanded now. */ |
745 #ifdef WIN32_NATIVE | 775 #ifdef WIN32_FILENAMES |
746 /* Detect Windows file names with drive specifiers. */ | 776 /* Detect Windows file names with drive specifiers. */ |
747 && ! (IS_DRIVE (o[0]) && (IS_DEVICE_SEP (o[1]) && IS_DIRECTORY_SEP (o[2]))) | 777 && ! (IS_DRIVE (o[0]) && (IS_DEVICE_SEP (o[1]) && IS_DIRECTORY_SEP (o[2]))) |
748 /* Detect Windows file names in UNC format. */ | 778 /* Detect Windows file names in UNC format. */ |
749 && ! (IS_DIRECTORY_SEP (o[0]) && IS_DIRECTORY_SEP (o[1])) | 779 && ! (IS_DIRECTORY_SEP (o[0]) && IS_DIRECTORY_SEP (o[1])) |
750 | 780 #endif /* not WIN32_FILENAMES */ |
751 #else /* not WIN32_NATIVE */ | 781 #ifndef WIN32_NATIVE |
752 | |
753 /* Detect Unix absolute file names (/... alone is not absolute on | 782 /* Detect Unix absolute file names (/... alone is not absolute on |
754 Windows). */ | 783 Windows). */ |
755 && ! (IS_DIRECTORY_SEP (o[0])) | 784 && ! (IS_DIRECTORY_SEP (o[0])) |
756 #endif /* not WIN32_NATIVE */ | 785 #endif /* not WIN32_NATIVE */ |
757 ) | 786 ) |
764 | 793 |
765 /* #### dmoore - this is ugly, clean this up. Looks like nm pointing | 794 /* #### dmoore - this is ugly, clean this up. Looks like nm pointing |
766 into name should be safe during all of this, though. */ | 795 into name should be safe during all of this, though. */ |
767 nm = XSTRING_DATA (name); | 796 nm = XSTRING_DATA (name); |
768 | 797 |
769 #ifdef WIN32_NATIVE | 798 #ifdef WIN32_FILENAMES |
770 /* We will force directory separators to be either all \ or /, so make | 799 /* We will force directory separators to be either all \ or /, so make |
771 a local copy to modify, even if there ends up being no change. */ | 800 a local copy to modify, even if there ends up being no change. */ |
772 nm = strcpy ((char *)alloca (strlen ((char *)nm) + 1), (char *)nm); | 801 nm = strcpy ((char *)alloca (strlen ((char *)nm) + 1), (char *)nm); |
773 | 802 |
774 /* Find and remove drive specifier if present; this makes nm absolute | 803 /* Find and remove drive specifier if present; this makes nm absolute |
775 even if the rest of the name appears to be relative. */ | 804 even if the rest of the name appears to be relative. */ |
776 { | 805 { |
777 Bufbyte *colon = (Bufbyte *) strrchr ((char *)nm, ':'); | 806 Bufbyte *colon = (Bufbyte *) strrchr ((char *)nm, ':'); |
778 | 807 |
779 if (colon) | 808 if (colon) |
809 { | |
780 /* Only recognize colon as part of drive specifier if there is a | 810 /* Only recognize colon as part of drive specifier if there is a |
781 single alphabetic character preceding the colon (and if the | 811 single alphabetic character preceding the colon (and if the |
782 character before the drive letter, if present, is a directory | 812 character before the drive letter, if present, is a directory |
783 separator); this is to support the remote system syntax used by | 813 separator); this is to support the remote system syntax used by |
784 ange-ftp, and the "po:username" syntax for POP mailboxes. */ | 814 ange-ftp, and the "po:username" syntax for POP mailboxes. */ |
795 { | 825 { |
796 while (--colon >= nm) | 826 while (--colon >= nm) |
797 if (colon[0] == ':') | 827 if (colon[0] == ':') |
798 goto look_again; | 828 goto look_again; |
799 } | 829 } |
830 } | |
800 } | 831 } |
801 | 832 |
802 /* If we see "c://somedir", we want to strip the first slash after the | 833 /* If we see "c://somedir", we want to strip the first slash after the |
803 colon when stripping the drive letter. Otherwise, this expands to | 834 colon when stripping the drive letter. Otherwise, this expands to |
804 "//somedir". */ | 835 "//somedir". */ |
805 if (drive && IS_DIRECTORY_SEP (nm[0]) && IS_DIRECTORY_SEP (nm[1])) | 836 if (drive && IS_DIRECTORY_SEP (nm[0]) && IS_DIRECTORY_SEP (nm[1])) |
806 nm++; | 837 nm++; |
807 #endif /* WIN32_NATIVE */ | 838 #endif /* WIN32_FILENAMES */ |
808 | 839 |
809 /* If nm is absolute, look for /./ or /../ sequences; if none are | 840 /* If nm is absolute, look for /./ or /../ sequences; if none are |
810 found, we can probably return right away. We will avoid allocating | 841 found, we can probably return right away. We will avoid allocating |
811 a new string if name is already fully expanded. */ | 842 a new string if name is already fully expanded. */ |
812 if ( | 843 if ( |
840 lose = 1; | 871 lose = 1; |
841 p++; | 872 p++; |
842 } | 873 } |
843 if (!lose) | 874 if (!lose) |
844 { | 875 { |
845 #ifdef WIN32_NATIVE | 876 #ifdef WIN32_FILENAMES |
846 /* Make sure directories are all separated with / or \ as | 877 if (drive || IS_DIRECTORY_SEP (nm[1])) |
847 desired, but avoid allocation of a new string when not | |
848 required. */ | |
849 CORRECT_DIR_SEPS (nm); | |
850 if (IS_DIRECTORY_SEP (nm[1])) | |
851 { | 878 { |
852 if (strcmp (nm, XSTRING_DATA (name)) != 0) | 879 /* Make sure directories are all separated with / or \ as |
853 name = build_string (nm); | 880 desired, but avoid allocation of a new string when not |
881 required. */ | |
882 CORRECT_DIR_SEPS (nm); | |
883 if (IS_DIRECTORY_SEP (nm[1])) | |
884 { | |
885 if (strcmp (nm, XSTRING_DATA (name)) != 0) | |
886 name = build_string (nm); | |
887 } | |
888 /* drive must be set, so this is okay */ | |
889 else if (strcmp (nm - 2, XSTRING_DATA (name)) != 0) | |
890 { | |
891 name = make_string (nm - 2, p - nm + 2); | |
892 XSTRING_DATA (name)[0] = DRIVE_LETTER (drive); | |
893 XSTRING_DATA (name)[1] = ':'; | |
894 } | |
895 RETURN_UNGCPRO (name); | |
854 } | 896 } |
855 /* drive must be set, so this is okay */ | 897 #endif /* not WIN32_FILENAMES */ |
856 else if (strcmp (nm - 2, XSTRING_DATA (name)) != 0) | 898 #ifndef WIN32_NATIVE |
857 { | |
858 name = make_string (nm - 2, p - nm + 2); | |
859 XSTRING_DATA (name)[0] = DRIVE_LETTER (drive); | |
860 XSTRING_DATA (name)[1] = ':'; | |
861 } | |
862 RETURN_UNGCPRO (name); | |
863 #else /* not WIN32_NATIVE */ | |
864 if (nm == XSTRING_DATA (name)) | 899 if (nm == XSTRING_DATA (name)) |
865 RETURN_UNGCPRO (name); | 900 RETURN_UNGCPRO (name); |
866 RETURN_UNGCPRO (build_string ((char *) nm)); | 901 RETURN_UNGCPRO (build_string ((char *) nm)); |
867 #endif /* not WIN32_NATIVE */ | 902 #endif /* not WIN32_NATIVE */ |
868 } | 903 } |
899 TO_INTERNAL_FORMAT (C_STRING, newdir_external, | 934 TO_INTERNAL_FORMAT (C_STRING, newdir_external, |
900 C_STRING_ALLOCA, (* ((char **) &newdir)), | 935 C_STRING_ALLOCA, (* ((char **) &newdir)), |
901 Qfile_name); | 936 Qfile_name); |
902 | 937 |
903 nm++; | 938 nm++; |
904 #ifdef WIN32_NATIVE | 939 #ifdef WIN32_FILENAMES |
905 collapse_newdir = 0; | 940 collapse_newdir = 0; |
906 #endif | 941 #endif |
907 } | 942 } |
908 else /* ~user/filename */ | 943 else /* ~user/filename */ |
909 { | 944 { |
949 /* If we don't find a user of that name, leave the name | 984 /* If we don't find a user of that name, leave the name |
950 unchanged; don't move nm forward to p. */ | 985 unchanged; don't move nm forward to p. */ |
951 } | 986 } |
952 } | 987 } |
953 | 988 |
954 #ifdef WIN32_NATIVE | 989 #ifdef WIN32_FILENAMES |
955 /* On DOS and Windows, nm is absolute if a drive name was specified; | 990 /* On DOS and Windows, nm is absolute if a drive name was specified; |
956 use the drive's current directory as the prefix if needed. */ | 991 use the drive's current directory as the prefix if needed. */ |
957 if (!newdir && drive) | 992 if (!newdir && drive) |
958 { | 993 { |
994 #ifdef WIN32_NATIVE | |
959 /* Get default directory if needed to make nm absolute. */ | 995 /* Get default directory if needed to make nm absolute. */ |
960 if (!IS_DIRECTORY_SEP (nm[0])) | 996 if (!IS_DIRECTORY_SEP (nm[0])) |
961 { | 997 { |
962 newdir = alloca (MAXPATHLEN + 1); | 998 newdir = alloca (MAXPATHLEN + 1); |
963 if (!_getdcwd (toupper (drive) - 'A' + 1, newdir, MAXPATHLEN)) | 999 if (!_getdcwd (toupper (drive) - 'A' + 1, newdir, MAXPATHLEN)) |
964 newdir = NULL; | 1000 newdir = NULL; |
965 } | 1001 } |
1002 #endif /* WIN32_NATIVE */ | |
966 if (!newdir) | 1003 if (!newdir) |
967 { | 1004 { |
968 /* Either nm starts with /, or drive isn't mounted. */ | 1005 /* Either nm starts with /, or drive isn't mounted. */ |
969 newdir = alloca (4); | 1006 newdir = alloca (4); |
970 newdir[0] = DRIVE_LETTER (drive); | 1007 newdir[0] = DRIVE_LETTER (drive); |
971 newdir[1] = ':'; | 1008 newdir[1] = ':'; |
972 newdir[2] = '/'; | 1009 newdir[2] = '/'; |
973 newdir[3] = 0; | 1010 newdir[3] = 0; |
974 } | 1011 } |
975 } | 1012 } |
976 #endif /* WIN32_NATIVE */ | 1013 #endif /* WIN32_FILENAMES */ |
977 | 1014 |
978 /* Finally, if no prefix has been specified and nm is not absolute, | 1015 /* Finally, if no prefix has been specified and nm is not absolute, |
979 then it must be expanded relative to default_directory. */ | 1016 then it must be expanded relative to default_directory. */ |
980 | 1017 |
981 if (1 | 1018 if (1 |
982 #ifndef WIN32_NATIVE | 1019 #ifndef WIN32_NATIVE |
983 /* /... alone is not absolute on DOS and Windows. */ | 1020 /* /... alone is not absolute on DOS and Windows. */ |
984 && !IS_DIRECTORY_SEP (nm[0]) | 1021 && !IS_DIRECTORY_SEP (nm[0]) |
985 #else | 1022 #endif |
1023 #ifdef WIN32_FILENAMES | |
986 && !(IS_DIRECTORY_SEP (nm[0]) && IS_DIRECTORY_SEP (nm[1])) | 1024 && !(IS_DIRECTORY_SEP (nm[0]) && IS_DIRECTORY_SEP (nm[1])) |
987 #endif | 1025 #endif |
988 && !newdir) | 1026 && !newdir) |
989 { | 1027 { |
990 newdir = XSTRING_DATA (default_directory); | 1028 newdir = XSTRING_DATA (default_directory); |
991 } | 1029 } |
992 | 1030 |
993 #ifdef WIN32_NATIVE | 1031 #ifdef WIN32_FILENAMES |
994 if (newdir) | 1032 if (newdir) |
995 { | 1033 { |
996 /* First ensure newdir is an absolute name. */ | 1034 /* First ensure newdir is an absolute name. */ |
997 if ( | 1035 if ( |
998 /* Detect Windows file names with drive specifiers. */ | 1036 /* Detect Windows file names with drive specifiers. */ |
1000 && IS_DEVICE_SEP (newdir[1]) && IS_DIRECTORY_SEP (newdir[2])) | 1038 && IS_DEVICE_SEP (newdir[1]) && IS_DIRECTORY_SEP (newdir[2])) |
1001 /* Detect Windows file names in UNC format. */ | 1039 /* Detect Windows file names in UNC format. */ |
1002 && ! (IS_DIRECTORY_SEP (newdir[0]) && IS_DIRECTORY_SEP (newdir[1])) | 1040 && ! (IS_DIRECTORY_SEP (newdir[0]) && IS_DIRECTORY_SEP (newdir[1])) |
1003 /* Detect drive spec by itself */ | 1041 /* Detect drive spec by itself */ |
1004 && ! (IS_DEVICE_SEP (newdir[1]) && newdir[2] == 0) | 1042 && ! (IS_DEVICE_SEP (newdir[1]) && newdir[2] == 0) |
1043 /* Detect unix format. */ | |
1044 #ifndef WIN32_NATIVE | |
1045 && ! (IS_DIRECTORY_SEP (newdir[0])) | |
1046 #endif | |
1005 ) | 1047 ) |
1006 { | 1048 { |
1007 /* Effectively, let newdir be (expand-file-name newdir cwd). | 1049 /* Effectively, let newdir be (expand-file-name newdir cwd). |
1008 Because of the admonition against calling expand-file-name | 1050 Because of the admonition against calling expand-file-name |
1009 when we have pointers into lisp strings, we accomplish this | 1051 when we have pointers into lisp strings, we accomplish this |
1023 nm = tmp; | 1065 nm = tmp; |
1024 } | 1066 } |
1025 newdir = alloca (MAXPATHLEN + 1); | 1067 newdir = alloca (MAXPATHLEN + 1); |
1026 if (drive) | 1068 if (drive) |
1027 { | 1069 { |
1070 #ifdef WIN32_NATIVE | |
1028 if (!_getdcwd (toupper (drive) - 'A' + 1, newdir, MAXPATHLEN)) | 1071 if (!_getdcwd (toupper (drive) - 'A' + 1, newdir, MAXPATHLEN)) |
1072 #endif | |
1029 newdir = "/"; | 1073 newdir = "/"; |
1030 } | 1074 } |
1031 else | 1075 else |
1032 getwd (newdir); | 1076 getwd (newdir); |
1033 } | 1077 } |
1039 newdir += 2; | 1083 newdir += 2; |
1040 } | 1084 } |
1041 | 1085 |
1042 /* Keep only a prefix from newdir if nm starts with slash | 1086 /* Keep only a prefix from newdir if nm starts with slash |
1043 (/ /server/share for UNC, nothing otherwise). */ | 1087 (/ /server/share for UNC, nothing otherwise). */ |
1044 if (IS_DIRECTORY_SEP (nm[0]) && collapse_newdir) | 1088 if (IS_DIRECTORY_SEP (nm[0]) |
1089 #ifndef WIN32_NATIVE | |
1090 && IS_DIRECTORY_SEP (nm[1]) | |
1091 #endif | |
1092 && collapse_newdir) | |
1045 { | 1093 { |
1046 if (IS_DIRECTORY_SEP (newdir[0]) && IS_DIRECTORY_SEP (newdir[1])) | 1094 if (IS_DIRECTORY_SEP (newdir[0]) && IS_DIRECTORY_SEP (newdir[1])) |
1047 { | 1095 { |
1048 newdir = strcpy (alloca (strlen (newdir) + 1), newdir); | 1096 newdir = strcpy (alloca (strlen (newdir) + 1), newdir); |
1049 p = newdir + 2; | 1097 p = newdir + 2; |
1054 } | 1102 } |
1055 else | 1103 else |
1056 newdir = ""; | 1104 newdir = ""; |
1057 } | 1105 } |
1058 } | 1106 } |
1059 #endif /* WIN32_NATIVE */ | 1107 #endif /* WIN32_FILENAMES */ |
1060 | 1108 |
1061 if (newdir) | 1109 if (newdir) |
1062 { | 1110 { |
1063 /* Get rid of any slash at the end of newdir, unless newdir is | 1111 /* Get rid of any slash at the end of newdir, unless newdir is |
1064 just // (an incomplete UNC name). */ | 1112 just // (an incomplete UNC name). */ |
1065 length = strlen ((char *) newdir); | 1113 length = strlen ((char *) newdir); |
1066 if (length > 1 && IS_DIRECTORY_SEP (newdir[length - 1]) | 1114 if (length > 1 && IS_DIRECTORY_SEP (newdir[length - 1]) |
1067 #ifdef WIN32_NATIVE | 1115 #ifdef WIN32_FILENAMES |
1068 && !(length == 2 && IS_DIRECTORY_SEP (newdir[0])) | 1116 && !(length == 2 && IS_DIRECTORY_SEP (newdir[0])) |
1069 #endif | 1117 #endif |
1070 ) | 1118 ) |
1071 { | 1119 { |
1072 Bufbyte *temp = (Bufbyte *) alloca (length); | 1120 Bufbyte *temp = (Bufbyte *) alloca (length); |
1079 else | 1127 else |
1080 tlen = 0; | 1128 tlen = 0; |
1081 | 1129 |
1082 /* Now concatenate the directory and name to new space in the stack frame */ | 1130 /* Now concatenate the directory and name to new space in the stack frame */ |
1083 tlen += strlen ((char *) nm) + 1; | 1131 tlen += strlen ((char *) nm) + 1; |
1084 #ifdef WIN32_NATIVE | 1132 #ifdef WIN32_FILENAMES |
1085 /* Add reserved space for drive name. (The Microsoft x86 compiler | 1133 /* Add reserved space for drive name. (The Microsoft x86 compiler |
1086 produces incorrect code if the following two lines are combined.) */ | 1134 produces incorrect code if the following two lines are combined.) */ |
1087 target = (Bufbyte *) alloca (tlen + 2); | 1135 target = (Bufbyte *) alloca (tlen + 2); |
1088 target += 2; | 1136 target += 2; |
1089 #else /* not WIN32_NATIVE */ | 1137 #else /* not WIN32_FILENAMES */ |
1090 target = (Bufbyte *) alloca (tlen); | 1138 target = (Bufbyte *) alloca (tlen); |
1091 #endif /* not WIN32_NATIVE */ | 1139 #endif /* not WIN32_FILENAMES */ |
1092 *target = 0; | 1140 *target = 0; |
1093 | 1141 |
1094 if (newdir) | 1142 if (newdir) |
1095 { | 1143 { |
1096 if (nm[0] == 0 || IS_DIRECTORY_SEP (nm[0])) | 1144 if (nm[0] == 0 || IS_DIRECTORY_SEP (nm[0])) |
1135 /* Keep initial / only if this is the whole name. */ | 1183 /* Keep initial / only if this is the whole name. */ |
1136 if (o == target && IS_ANY_SEP (*o) && p[3] == 0) | 1184 if (o == target && IS_ANY_SEP (*o) && p[3] == 0) |
1137 ++o; | 1185 ++o; |
1138 p += 3; | 1186 p += 3; |
1139 } | 1187 } |
1140 #ifdef WIN32_NATIVE | 1188 #ifdef WIN32_FILENAMES |
1141 /* if drive is set, we're not dealing with an UNC, so | 1189 /* if drive is set, we're not dealing with an UNC, so |
1142 multiple dir-seps are redundant (and reportedly cause trouble | 1190 multiple dir-seps are redundant (and reportedly cause trouble |
1143 under win95) */ | 1191 under win95) */ |
1144 else if (drive && IS_DIRECTORY_SEP (p[0]) && IS_DIRECTORY_SEP (p[1])) | 1192 else if (drive && IS_DIRECTORY_SEP (p[0]) && IS_DIRECTORY_SEP (p[1])) |
1145 ++p; | 1193 ++p; |
1148 { | 1196 { |
1149 *o++ = *p++; | 1197 *o++ = *p++; |
1150 } | 1198 } |
1151 } | 1199 } |
1152 | 1200 |
1153 #ifdef WIN32_NATIVE | 1201 #ifdef WIN32_FILENAMES |
1154 /* At last, set drive name, except for network file name. */ | 1202 /* At last, set drive name, except for network file name. */ |
1155 if (drive) | 1203 if (drive) |
1156 { | 1204 { |
1157 target -= 2; | 1205 target -= 2; |
1158 target[0] = DRIVE_LETTER (drive); | 1206 target[0] = DRIVE_LETTER (drive); |
1159 target[1] = ':'; | 1207 target[1] = ':'; |
1160 } | 1208 } |
1209 #ifdef WIN32_NATIVE | |
1161 else | 1210 else |
1162 { | 1211 { |
1163 assert (IS_DIRECTORY_SEP (target[0]) && IS_DIRECTORY_SEP (target[1])); | 1212 assert (IS_DIRECTORY_SEP (target[0]) && IS_DIRECTORY_SEP (target[1])); |
1164 } | 1213 } |
1214 #endif | |
1165 CORRECT_DIR_SEPS (target); | 1215 CORRECT_DIR_SEPS (target); |
1166 #endif /* WIN32_NATIVE */ | 1216 #endif /* WIN32_FILENAMES */ |
1167 | 1217 |
1168 RETURN_UNGCPRO (make_string (target, o - target)); | 1218 RETURN_UNGCPRO (make_string (target, o - target)); |
1169 } | 1219 } |
1170 | 1220 |
1171 DEFUN ("file-truename", Ffile_truename, 1, 2, 0, /* | 1221 DEFUN ("file-truename", Ffile_truename, 1, 2, 0, /* |
1238 we just use our own version in realpath.c. */ | 1288 we just use our own version in realpath.c. */ |
1239 for (;;) | 1289 for (;;) |
1240 { | 1290 { |
1241 Extbyte *pos; | 1291 Extbyte *pos; |
1242 | 1292 |
1243 #ifdef WIN32_NATIVE | 1293 #ifdef WIN32_FILENAMES |
1244 if (IS_DRIVE (p[0]) && IS_DEVICE_SEP (p[1]) | 1294 if (IS_DRIVE (p[0]) && IS_DEVICE_SEP (p[1]) |
1245 && IS_DIRECTORY_SEP (p[2])) | 1295 && IS_DIRECTORY_SEP (p[2])) |
1246 /* don't test c: on windows */ | 1296 /* don't test c: on windows */ |
1247 p = p+2; | 1297 p = p+2; |
1248 else if (IS_DIRECTORY_SEP (p[0]) && IS_DIRECTORY_SEP (p[1])) | 1298 else if (IS_DIRECTORY_SEP (p[0]) && IS_DIRECTORY_SEP (p[1])) |
1358 /* If /~ or // appears, discard everything through first slash. */ | 1408 /* If /~ or // appears, discard everything through first slash. */ |
1359 | 1409 |
1360 for (p = nm; p != endp; p++) | 1410 for (p = nm; p != endp; p++) |
1361 { | 1411 { |
1362 if ((p[0] == '~' | 1412 if ((p[0] == '~' |
1363 #if defined (WIN32_NATIVE) || defined (CYGWIN) | 1413 #if defined (WIN32_FILENAMES) |
1364 /* // at start of file name is meaningful in WindowsNT systems */ | 1414 /* // at start of file name is meaningful in WindowsNT systems */ |
1365 || (IS_DIRECTORY_SEP (p[0]) && p - 1 != nm) | 1415 || (IS_DIRECTORY_SEP (p[0]) && p - 1 != nm) |
1366 #else /* not (WIN32_NATIVE || CYGWIN) */ | 1416 #else /* not (WIN32_FILENAMES) */ |
1367 || IS_DIRECTORY_SEP (p[0]) | 1417 || IS_DIRECTORY_SEP (p[0]) |
1368 #endif /* not (WIN32_NATIVE || CYGWIN) */ | 1418 #endif /* not (WIN32_FILENAMES) */ |
1369 ) | 1419 ) |
1370 && p != nm | 1420 && p != nm |
1371 && (IS_DIRECTORY_SEP (p[-1]))) | 1421 && (IS_DIRECTORY_SEP (p[-1]))) |
1372 { | 1422 { |
1373 nm = p; | 1423 nm = p; |
1374 substituted = 1; | 1424 substituted = 1; |
1375 } | 1425 } |
1376 #ifdef WIN32_NATIVE | 1426 #ifdef WIN32_FILENAMES |
1377 /* see comment in expand-file-name about drive specifiers */ | 1427 /* see comment in expand-file-name about drive specifiers */ |
1378 else if (IS_DRIVE (p[0]) && p[1] == ':' | 1428 else if (IS_DRIVE (p[0]) && p[1] == ':' |
1379 && p > nm && IS_DIRECTORY_SEP (p[-1])) | 1429 && p > nm && IS_DIRECTORY_SEP (p[-1])) |
1380 { | 1430 { |
1381 nm = p; | 1431 nm = p; |
1382 substituted = 1; | 1432 substituted = 1; |
1383 } | 1433 } |
1384 #endif /* WIN32_NATIVE */ | 1434 #endif /* WIN32_FILENAMES */ |
1385 } | 1435 } |
1386 | 1436 |
1387 /* See if any variables are substituted into the string | 1437 /* See if any variables are substituted into the string |
1388 and find the total length of their values in `total' */ | 1438 and find the total length of their values in `total' */ |
1389 | 1439 |
1489 | 1539 |
1490 /* If /~ or // appears, discard everything through first slash. */ | 1540 /* If /~ or // appears, discard everything through first slash. */ |
1491 | 1541 |
1492 for (p = xnm; p != x; p++) | 1542 for (p = xnm; p != x; p++) |
1493 if ((p[0] == '~' | 1543 if ((p[0] == '~' |
1494 #if defined (WIN32_NATIVE) | 1544 #if defined (WIN32_FILENAMES) |
1495 || (IS_DIRECTORY_SEP (p[0]) && p - 1 != xnm) | 1545 || (IS_DIRECTORY_SEP (p[0]) && p - 1 != xnm) |
1496 #else /* not WIN32_NATIVE */ | 1546 #else /* not WIN32_FILENAMES */ |
1497 || IS_DIRECTORY_SEP (p[0]) | 1547 || IS_DIRECTORY_SEP (p[0]) |
1498 #endif /* not WIN32_NATIVE */ | 1548 #endif /* not WIN32_FILENAMES */ |
1499 ) | 1549 ) |
1500 /* don't do p[-1] if that would go off the beginning --jwz */ | 1550 /* don't do p[-1] if that would go off the beginning --jwz */ |
1501 && p != nm && p > xnm && IS_DIRECTORY_SEP (p[-1])) | 1551 && p != nm && p > xnm && IS_DIRECTORY_SEP (p[-1])) |
1502 xnm = p; | 1552 xnm = p; |
1503 #ifdef WIN32_NATIVE | 1553 #ifdef WIN32_FILENAMES |
1504 else if (IS_DRIVE (p[0]) && p[1] == ':' | 1554 else if (IS_DRIVE (p[0]) && p[1] == ':' |
1505 && p > nm && IS_DIRECTORY_SEP (p[-1])) | 1555 && p > nm && IS_DIRECTORY_SEP (p[-1])) |
1506 xnm = p; | 1556 xnm = p; |
1507 #endif | 1557 #endif |
1508 | 1558 |
2095 Bufbyte *ptr; | 2145 Bufbyte *ptr; |
2096 | 2146 |
2097 CHECK_STRING (filename); | 2147 CHECK_STRING (filename); |
2098 ptr = XSTRING_DATA (filename); | 2148 ptr = XSTRING_DATA (filename); |
2099 return (IS_DIRECTORY_SEP (*ptr) || *ptr == '~' | 2149 return (IS_DIRECTORY_SEP (*ptr) || *ptr == '~' |
2100 #ifdef WIN32_NATIVE | 2150 #ifdef WIN32_FILENAMES |
2101 || (IS_DRIVE (*ptr) && ptr[1] == ':' && IS_DIRECTORY_SEP (ptr[2])) | 2151 || (IS_DRIVE (*ptr) && ptr[1] == ':' && IS_DIRECTORY_SEP (ptr[2])) |
2102 #endif | 2152 #endif |
2103 ) ? Qt : Qnil; | 2153 ) ? Qt : Qnil; |
2104 } | 2154 } |
2105 | 2155 |
2213 call the corresponding file handler. */ | 2263 call the corresponding file handler. */ |
2214 handler = Ffind_file_name_handler (abspath, Qfile_readable_p); | 2264 handler = Ffind_file_name_handler (abspath, Qfile_readable_p); |
2215 if (!NILP (handler)) | 2265 if (!NILP (handler)) |
2216 RETURN_UNGCPRO (call2 (handler, Qfile_readable_p, abspath)); | 2266 RETURN_UNGCPRO (call2 (handler, Qfile_readable_p, abspath)); |
2217 | 2267 |
2218 #if defined(WIN32_NATIVE) || defined(CYGWIN) | 2268 #if defined(WIN32_FILENAMES) |
2219 /* Under MS-DOS and Windows, open does not work for directories. */ | 2269 /* Under MS-DOS and Windows, open does not work for directories. */ |
2220 UNGCPRO; | 2270 UNGCPRO; |
2221 if (access ((char *) XSTRING_DATA (abspath), 0) == 0) | 2271 if (access ((char *) XSTRING_DATA (abspath), 0) == 0) |
2222 return Qt; | 2272 return Qt; |
2223 else | 2273 else |
2224 return Qnil; | 2274 return Qnil; |
2225 #else /* not WIN32_NATIVE */ | 2275 #else /* not WIN32_FILENAMES */ |
2226 { | 2276 { |
2227 int desc = interruptible_open ((char *) XSTRING_DATA (abspath), O_RDONLY | OPEN_BINARY, 0); | 2277 int desc = interruptible_open ((char *) XSTRING_DATA (abspath), O_RDONLY | OPEN_BINARY, 0); |
2228 UNGCPRO; | 2278 UNGCPRO; |
2229 if (desc < 0) | 2279 if (desc < 0) |
2230 return Qnil; | 2280 return Qnil; |
2231 close (desc); | 2281 close (desc); |
2232 return Qt; | 2282 return Qt; |
2233 } | 2283 } |
2234 #endif /* not WIN32_NATIVE */ | 2284 #endif /* not WIN32_FILENAMES */ |
2235 } | 2285 } |
2236 | 2286 |
2237 /* Having this before file-symlink-p mysteriously caused it to be forgotten | 2287 /* Having this before file-symlink-p mysteriously caused it to be forgotten |
2238 on the RT/PC. */ | 2288 on the RT/PC. */ |
2239 DEFUN ("file-writable-p", Ffile_writable_p, 1, 1, 0, /* | 2289 DEFUN ("file-writable-p", Ffile_writable_p, 1, 1, 0, /* |