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, /*