comparison src/fileio.c @ 265:8efd647ea9ca r20-5b31

Import from CVS: tag r20-5b31
author cvs
date Mon, 13 Aug 2007 10:25:37 +0200
parents 727739f917cb
children 966663fcf606
comparison
equal deleted inserted replaced
264:682d2a9d41a5 265:8efd647ea9ca
54 #endif /* HPUX */ 54 #endif /* HPUX */
55 55
56 #ifdef WINDOWSNT 56 #ifdef WINDOWSNT
57 #define NOMINMAX 1 57 #define NOMINMAX 1
58 #include <windows.h> 58 #include <windows.h>
59 #include <direct.h>
60 #include <fcntl.h>
59 #include <stdlib.h> 61 #include <stdlib.h>
60 #include <fcntl.h>
61 #endif /* not WINDOWSNT */ 62 #endif /* not WINDOWSNT */
62 63
63 #ifdef DOS_NT 64 #ifdef WINDOWSNT
64 #define CORRECT_DIR_SEPS(s) \ 65 #define CORRECT_DIR_SEPS(s) \
65 do { if ('/' == DIRECTORY_SEP) dostounix_filename (s); \ 66 do { if ('/' == DIRECTORY_SEP) dostounix_filename (s); \
66 else unixtodos_filename (s); \ 67 else unixtodos_filename (s); \
67 } while (0) 68 } while (0)
68 /* On Windows, drive letters must be alphabetic - on DOS, the Netware
69 redirector allows the six letters between 'Z' and 'a' as well. */
70 #ifdef MSDOS
71 #define IS_DRIVE(x) ((x) >= 'A' && (x) <= 'z')
72 #endif
73 #ifdef WINDOWSNT
74 #define IS_DRIVE(x) isalpha (x) 69 #define IS_DRIVE(x) isalpha (x)
75 #endif
76 /* Need to lower-case the drive letter, or else expanded 70 /* Need to lower-case the drive letter, or else expanded
77 filenames will sometimes compare inequal, because 71 filenames will sometimes compare inequal, because
78 `expand-file-name' doesn't always down-case the drive letter. */ 72 `expand-file-name' doesn't always down-case the drive letter. */
79 #define DRIVE_LETTER(x) (tolower (x)) 73 #define DRIVE_LETTER(x) (tolower (x))
80 #endif /* DOS_NT */ 74 #endif /* WINDOWSNT */
81 75
82 /* Nonzero during writing of auto-save files */ 76 /* Nonzero during writing of auto-save files */
83 static int auto_saving; 77 static int auto_saving;
84 78
85 /* Set by auto_save_1 to mode of original file so Fwrite_region_internal 79 /* Set by auto_save_1 to mode of original file so Fwrite_region_internal
121 expanding file names. This can be bound to / or \. 115 expanding file names. This can be bound to / or \.
122 116
123 This needs to be initialized statically, because file name functions 117 This needs to be initialized statically, because file name functions
124 are called during initialization. */ 118 are called during initialization. */
125 Lisp_Object Vdirectory_sep_char; 119 Lisp_Object Vdirectory_sep_char;
126
127 #ifdef DOS_NT
128 /* Until we can figure out how to deal with the functions in this file in
129 a civilized fashion, this will remain #ifdef'ed out. -slb */
130 /* For the benefit of backwards compatability with earlier versions of
131 Emacs on DOS_NT, provide a way to disable the REPLACE option support
132 in insert-file-contents. */
133 Lisp_Object Vinsert_file_contents_allow_replace;
134 #endif /* DOS_NT */
135 120
136 /* These variables describe handlers that have "already" had a chance 121 /* These variables describe handlers that have "already" had a chance
137 to handle the current operation. 122 to handle the current operation.
138 123
139 Vinhibit_file_name_handlers is a list of file name handlers. 124 Vinhibit_file_name_handlers is a list of file name handlers.
459 #endif 444 #endif
460 beg = XSTRING_DATA (file); 445 beg = XSTRING_DATA (file);
461 p = beg + XSTRING_LENGTH (file); 446 p = beg + XSTRING_LENGTH (file);
462 447
463 while (p != beg && !IS_ANY_SEP (p[-1]) 448 while (p != beg && !IS_ANY_SEP (p[-1])
464 #ifdef DOS_NT 449 #ifdef WINDOWSNT
465 /* only recognise drive specifier at beginning */ 450 /* only recognise drive specifier at beginning */
466 && !(p[-1] == ':' && p == beg + 2) 451 && !(p[-1] == ':' && p == beg + 2)
467 #endif 452 #endif
468 ) p--; 453 ) p--;
469 454
470 if (p == beg) 455 if (p == beg)
471 return Qnil; 456 return Qnil;
472 #ifdef DOS_NT 457 #ifdef WINDOWSNT
473 /* Expansion of "c:" to drive and default directory. */ 458 /* Expansion of "c:" to drive and default directory. */
474 /* (NT does the right thing.) */ 459 /* (NT does the right thing.) */
475 if (p == beg + 2 && beg[1] == ':') 460 if (p == beg + 2 && beg[1] == ':')
476 { 461 {
477 /* MAXPATHLEN+1 is guaranteed to be enough space for getdefdir. */ 462 /* MAXPATHLEN+1 is guaranteed to be enough space for getdefdir. */
483 beg = res; 468 beg = res;
484 p = beg + strlen ((char *) beg); 469 p = beg + strlen ((char *) beg);
485 } 470 }
486 } 471 }
487 CORRECT_DIR_SEPS (beg); 472 CORRECT_DIR_SEPS (beg);
488 #endif /* DOS_NT */ 473 #endif /* WINDOWSNT */
489 return make_string (beg, p - beg); 474 return make_string (beg, p - beg);
490 } 475 }
491 476
492 DEFUN ("file-name-nondirectory", Ffile_name_nondirectory, 1, 1, 0, /* 477 DEFUN ("file-name-nondirectory", Ffile_name_nondirectory, 1, 1, 0, /*
493 Return file name NAME sans its directory. 478 Return file name NAME sans its directory.
511 496
512 beg = XSTRING_DATA (file); 497 beg = XSTRING_DATA (file);
513 end = p = beg + XSTRING_LENGTH (file); 498 end = p = beg + XSTRING_LENGTH (file);
514 499
515 while (p != beg && !IS_ANY_SEP (p[-1]) 500 while (p != beg && !IS_ANY_SEP (p[-1])
516 #ifdef DOS_NT 501 #ifdef WINDOWSNT
517 /* only recognise drive specifier at beginning */ 502 /* only recognise drive specifier at beginning */
518 && !(p[-1] == ':' && p == beg + 2) 503 && !(p[-1] == ':' && p == beg + 2)
519 #endif 504 #endif
520 ) p--; 505 ) p--;
521 506
558 if (!IS_ANY_SEP (out[size])) 543 if (!IS_ANY_SEP (out[size]))
559 { 544 {
560 out[size + 1] = DIRECTORY_SEP; 545 out[size + 1] = DIRECTORY_SEP;
561 out[size + 2] = '\0'; 546 out[size + 2] = '\0';
562 } 547 }
563 #ifdef DOS_NT 548 #ifdef WINDOWSNT
564 CORRECT_DIR_SEPS (out); 549 CORRECT_DIR_SEPS (out);
565 #endif 550 #endif
566 return out; 551 return out;
567 } 552 }
568 553
594 } 579 }
595 580
596 /* 581 /*
597 * Convert from directory name to filename. 582 * Convert from directory name to filename.
598 * On UNIX, it's simple: just make sure there isn't a terminating / 583 * On UNIX, it's simple: just make sure there isn't a terminating /
599 584 *
600 * Value is nonzero if the string output is different from the input. 585 * Value is nonzero if the string output is different from the input.
601 */ 586 */
602 587
603 static int 588 static int
604 directory_file_name (CONST char *src, char *dst) 589 directory_file_name (CONST char *src, char *dst)
615 || (slen > 1 && dst[0] != '/' && dst[slen - 1] == '/')) 600 || (slen > 1 && dst[0] != '/' && dst[slen - 1] == '/'))
616 dst[slen - 1] = 0; 601 dst[slen - 1] = 0;
617 #else 602 #else
618 if (slen > 1 603 if (slen > 1
619 && IS_DIRECTORY_SEP (dst[slen - 1]) 604 && IS_DIRECTORY_SEP (dst[slen - 1])
620 #ifdef DOS_NT 605 #ifdef WINDOWSNT
621 && !IS_ANY_SEP (dst[slen - 2]) 606 && !IS_ANY_SEP (dst[slen - 2])
622 #endif /* DOS_NT */ 607 #endif /* WINDOWSNT */
623 ) 608 )
624 dst[slen - 1] = 0; 609 dst[slen - 1] = 0;
625 #endif /* APOLLO */ 610 #endif /* APOLLO */
626 #ifdef DOS_NT 611 #ifdef WINDOWSNT
627 CORRECT_DIR_SEPS (dst); 612 CORRECT_DIR_SEPS (dst);
628 #endif /* DOS_NT */ 613 #endif /* WINDOWSNT */
629 return 1; 614 return 1;
630 } 615 }
631 616
632 DEFUN ("directory-file-name", Fdirectory_file_name, 1, 1, 0, /* 617 DEFUN ("directory-file-name", Fdirectory_file_name, 1, 1, 0, /*
633 Return the file name of the directory named DIR. 618 Return the file name of the directory named DIR.
678 memcpy (data, XSTRING_DATA (prefix), len); 663 memcpy (data, XSTRING_DATA (prefix), len);
679 memcpy (data + len, suffix, countof (suffix)); 664 memcpy (data + len, suffix, countof (suffix));
680 /* !!#### does mktemp() Mule-encapsulate? */ 665 /* !!#### does mktemp() Mule-encapsulate? */
681 mktemp ((char *) data); 666 mktemp ((char *) data);
682 667
683 #ifdef DOS_NT 668 #ifdef WINDOWSNT
684 CORRECT_DIR_SEPS (XSTRING_DATA (val)); 669 CORRECT_DIR_SEPS (XSTRING_DATA (val));
685 #endif /* DOS_NT */ 670 #endif /* WINDOWSNT */
686 return val; 671 return val;
687 } 672 }
688 673
689 DEFUN ("expand-file-name", Fexpand_file_name, 1, 2, 0, /* 674 DEFUN ("expand-file-name", Fexpand_file_name, 1, 2, 0, /*
690 Convert filename NAME to absolute, and canonicalize it. 675 Convert filename NAME to absolute, and canonicalize it.
705 Bufbyte *nm; 690 Bufbyte *nm;
706 691
707 Bufbyte *newdir, *p, *o; 692 Bufbyte *newdir, *p, *o;
708 int tlen; 693 int tlen;
709 Bufbyte *target; 694 Bufbyte *target;
710 struct passwd *pw; 695 #ifdef WINDOWSNT
711 #ifdef DOS_NT
712 int drive = 0; 696 int drive = 0;
713 int collapse_newdir = 1; 697 int collapse_newdir = 1;
714 #endif /* DOS_NT */ 698 #else
699 struct passwd *pw;
700 #endif /* WINDOWSNT */
715 int length; 701 int length;
716 Lisp_Object handler; 702 Lisp_Object handler;
717 703
718 CHECK_STRING (name); 704 CHECK_STRING (name);
719 705
751 The EQ test avoids infinite recursion. */ 737 The EQ test avoids infinite recursion. */
752 if (! NILP (default_directory) && !EQ (default_directory, name) 738 if (! NILP (default_directory) && !EQ (default_directory, name)
753 /* Save time in some common cases - as long as default_directory 739 /* Save time in some common cases - as long as default_directory
754 is not relative, it can be canonicalized with name below (if it 740 is not relative, it can be canonicalized with name below (if it
755 is needed at all) without requiring it to be expanded now. */ 741 is needed at all) without requiring it to be expanded now. */
756 #ifdef DOS_NT 742 #ifdef WINDOWSNT
757 /* Detect MSDOS file names with drive specifiers. */ 743 /* Detect MSDOS file names with drive specifiers. */
758 && ! (IS_DRIVE (o[0]) && (IS_DEVICE_SEP (o[1]) && IS_DIRECTORY_SEP (o[2]))) 744 && ! (IS_DRIVE (o[0]) && (IS_DEVICE_SEP (o[1]) && IS_DIRECTORY_SEP (o[2])))
759 #ifdef WINDOWSNT
760 /* Detect Windows file names in UNC format. */ 745 /* Detect Windows file names in UNC format. */
761 && ! (IS_DIRECTORY_SEP (o[0]) && IS_DIRECTORY_SEP (o[1])) 746 && ! (IS_DIRECTORY_SEP (o[0]) && IS_DIRECTORY_SEP (o[1]))
762 #endif 747
763 #else /* not DOS_NT */ 748 #else /* not WINDOWSNT */
749
764 /* Detect Unix absolute file names (/... alone is not absolute on 750 /* Detect Unix absolute file names (/... alone is not absolute on
765 DOS or Windows). */ 751 DOS or Windows). */
766 && ! (IS_DIRECTORY_SEP (o[0])) 752 && ! (IS_DIRECTORY_SEP (o[0]))
767 #endif /* not DOS_NT */ 753 #endif /* not WINDOWSNT */
768 ) 754 )
769 { 755 {
770 struct gcpro gcpro1; 756 struct gcpro gcpro1;
771 757
772 GCPRO1 (name); 758 GCPRO1 (name);
780 766
781 /* #### dmoore - this is ugly, clean this up. Looks like nm pointing 767 /* #### dmoore - this is ugly, clean this up. Looks like nm pointing
782 into name should be safe during all of this, though. */ 768 into name should be safe during all of this, though. */
783 nm = XSTRING_DATA (name); 769 nm = XSTRING_DATA (name);
784 770
785 #ifdef DOS_NT 771 #ifdef WINDOWSNT
786 /* We will force directory separators to be either all \ or /, so make 772 /* We will force directory separators to be either all \ or /, so make
787 a local copy to modify, even if there ends up being no change. */ 773 a local copy to modify, even if there ends up being no change. */
788 nm = strcpy (alloca (strlen (nm) + 1), nm); 774 nm = strcpy (alloca (strlen (nm) + 1), nm);
789 775
790 /* Find and remove drive specifier if present; this makes nm absolute 776 /* Find and remove drive specifier if present; this makes nm absolute
813 if (colon[0] == ':') 799 if (colon[0] == ':')
814 goto look_again; 800 goto look_again;
815 } 801 }
816 } 802 }
817 803
818 #ifdef WINDOWSNT
819 /* If we see "c://somedir", we want to strip the first slash after the 804 /* If we see "c://somedir", we want to strip the first slash after the
820 colon when stripping the drive letter. Otherwise, this expands to 805 colon when stripping the drive letter. Otherwise, this expands to
821 "//somedir". */ 806 "//somedir". */
822 if (drive && IS_DIRECTORY_SEP (nm[0]) && IS_DIRECTORY_SEP (nm[1])) 807 if (drive && IS_DIRECTORY_SEP (nm[0]) && IS_DIRECTORY_SEP (nm[1]))
823 nm++; 808 nm++;
824 #endif /* WINDOWSNT */ 809
825 #endif /* DOS_NT */
826
827 #ifdef WINDOWSNT
828 /* Discard any previous drive specifier if nm is now in UNC format. */ 810 /* Discard any previous drive specifier if nm is now in UNC format. */
829 if (IS_DIRECTORY_SEP (nm[0]) && IS_DIRECTORY_SEP (nm[1])) 811 if (IS_DIRECTORY_SEP (nm[0]) && IS_DIRECTORY_SEP (nm[1]))
830 { 812 {
831 drive = 0; 813 drive = 0;
832 } 814 }
835 /* If nm is absolute, look for /./ or /../ sequences; if none are 817 /* If nm is absolute, look for /./ or /../ sequences; if none are
836 found, we can probably return right away. We will avoid allocating 818 found, we can probably return right away. We will avoid allocating
837 a new string if name is already fully expanded. */ 819 a new string if name is already fully expanded. */
838 if ( 820 if (
839 IS_DIRECTORY_SEP (nm[0]) 821 IS_DIRECTORY_SEP (nm[0])
840 #ifdef MSDOS
841 && drive
842 #endif
843 #ifdef WINDOWSNT 822 #ifdef WINDOWSNT
844 && (drive || IS_DIRECTORY_SEP (nm[1])) 823 && (drive || IS_DIRECTORY_SEP (nm[1]))
845 #endif 824 #endif
846 ) 825 )
847 { 826 {
869 lose = 1; 848 lose = 1;
870 p++; 849 p++;
871 } 850 }
872 if (!lose) 851 if (!lose)
873 { 852 {
874 #ifdef DOS_NT 853 #ifdef WINDOWSNT
875 /* Make sure directories are all separated with / or \ as 854 /* Make sure directories are all separated with / or \ as
876 desired, but avoid allocation of a new string when not 855 desired, but avoid allocation of a new string when not
877 required. */ 856 required. */
878 CORRECT_DIR_SEPS (nm); 857 CORRECT_DIR_SEPS (nm);
879 #ifdef WINDOWSNT
880 if (IS_DIRECTORY_SEP (nm[1])) 858 if (IS_DIRECTORY_SEP (nm[1]))
881 { 859 {
882 if (strcmp (nm, XSTRING_DATA (name)) != 0) 860 if (strcmp (nm, XSTRING_DATA (name)) != 0)
883 name = build_string (nm); 861 name = build_string (nm);
884 } 862 }
885 else
886 #endif
887 /* drive must be set, so this is okay */ 863 /* drive must be set, so this is okay */
888 if (strcmp (nm - 2, XSTRING_DATA (name)) != 0) 864 else if (strcmp (nm - 2, XSTRING_DATA (name)) != 0)
889 { 865 {
890 name = make_string (nm - 2, p - nm + 2); 866 name = make_string (nm - 2, p - nm + 2);
891 XSTRING_DATA (name)[0] = DRIVE_LETTER (drive); 867 XSTRING_DATA (name)[0] = DRIVE_LETTER (drive);
892 XSTRING_DATA (name)[1] = ':'; 868 XSTRING_DATA (name)[1] = ':';
893 } 869 }
894 return name; 870 return name;
895 #else /* not DOS_NT */ 871 #else /* not WINDOWSNT */
896 if (nm == XSTRING_DATA (name)) 872 if (nm == XSTRING_DATA (name))
897 return name; 873 return name;
898 return build_string (nm); 874 return build_string (nm);
899 #endif /* not DOS_NT */ 875 #endif /* not WINDOWSNT */
900 } 876 }
901 } 877 }
902 878
903 /* At this point, nm might or might not be an absolute file name. We 879 /* At this point, nm might or might not be an absolute file name. We
904 need to expand ~ or ~user if present, otherwise prefix nm with 880 need to expand ~ or ~user if present, otherwise prefix nm with
924 || nm[1] == 0) /* ~ by itself */ 900 || nm[1] == 0) /* ~ by itself */
925 { 901 {
926 if (!(newdir = (Bufbyte *) egetenv ("HOME"))) 902 if (!(newdir = (Bufbyte *) egetenv ("HOME")))
927 newdir = (Bufbyte *) ""; 903 newdir = (Bufbyte *) "";
928 nm++; 904 nm++;
929 #ifdef DOS_NT 905 #ifdef WINDOWSNT
930 collapse_newdir = 0; 906 collapse_newdir = 0;
931 #endif 907 #endif
932 } 908 }
933 else /* ~user/filename */ 909 else /* ~user/filename */
934 { 910 {
969 /* If we don't find a user of that name, leave the name 945 /* If we don't find a user of that name, leave the name
970 unchanged; don't move nm forward to p. */ 946 unchanged; don't move nm forward to p. */
971 } 947 }
972 } 948 }
973 949
974 #ifdef DOS_NT 950 #ifdef WINDOWSNT
975 /* On DOS and Windows, nm is absolute if a drive name was specified; 951 /* On DOS and Windows, nm is absolute if a drive name was specified;
976 use the drive's current directory as the prefix if needed. */ 952 use the drive's current directory as the prefix if needed. */
977 if (!newdir && drive) 953 if (!newdir && drive)
978 { 954 {
979 /* Get default directory if needed to make nm absolute. */ 955 /* Get default directory if needed to make nm absolute. */
991 newdir[1] = ':'; 967 newdir[1] = ':';
992 newdir[2] = '/'; 968 newdir[2] = '/';
993 newdir[3] = 0; 969 newdir[3] = 0;
994 } 970 }
995 } 971 }
996 #endif /* DOS_NT */ 972 #endif /* WINDOWSNT */
997 973
998 /* Finally, if no prefix has been specified and nm is not absolute, 974 /* Finally, if no prefix has been specified and nm is not absolute,
999 then it must be expanded relative to default_directory. */ 975 then it must be expanded relative to default_directory. */
1000 976
1001 if (1 977 if (1
1002 #ifndef DOS_NT 978 #ifndef WINDOWSNT
1003 /* /... alone is not absolute on DOS and Windows. */ 979 /* /... alone is not absolute on DOS and Windows. */
1004 && !IS_DIRECTORY_SEP (nm[0]) 980 && !IS_DIRECTORY_SEP (nm[0])
1005 #endif 981 #else
1006 #ifdef WINDOWSNT
1007 && !(IS_DIRECTORY_SEP (nm[0]) && IS_DIRECTORY_SEP (nm[1])) 982 && !(IS_DIRECTORY_SEP (nm[0]) && IS_DIRECTORY_SEP (nm[1]))
1008 #endif 983 #endif
1009 && !newdir) 984 && !newdir)
1010 { 985 {
1011 newdir = XSTRING_DATA (default_directory); 986 newdir = XSTRING_DATA (default_directory);
1012 } 987 }
1013 988
1014 #ifdef DOS_NT 989 #ifdef WINDOWSNT
1015 if (newdir) 990 if (newdir)
1016 { 991 {
1017 /* First ensure newdir is an absolute name. */ 992 /* First ensure newdir is an absolute name. */
1018 if ( 993 if (
1019 /* Detect MSDOS file names with drive specifiers. */ 994 /* Detect MSDOS file names with drive specifiers. */
1020 ! (IS_DRIVE (newdir[0]) 995 ! (IS_DRIVE (newdir[0])
1021 && IS_DEVICE_SEP (newdir[1]) && IS_DIRECTORY_SEP (newdir[2])) 996 && IS_DEVICE_SEP (newdir[1]) && IS_DIRECTORY_SEP (newdir[2]))
1022 #ifdef WINDOWSNT
1023 /* Detect Windows file names in UNC format. */ 997 /* Detect Windows file names in UNC format. */
1024 && ! (IS_DIRECTORY_SEP (newdir[0]) && IS_DIRECTORY_SEP (newdir[1])) 998 && ! (IS_DIRECTORY_SEP (newdir[0]) && IS_DIRECTORY_SEP (newdir[1]))
1025 #endif
1026 ) 999 )
1027 { 1000 {
1028 /* Effectively, let newdir be (expand-file-name newdir cwd). 1001 /* Effectively, let newdir be (expand-file-name newdir cwd).
1029 Because of the admonition against calling expand-file-name 1002 Because of the admonition against calling expand-file-name
1030 when we have pointers into lisp strings, we accomplish this 1003 when we have pointers into lisp strings, we accomplish this
1062 1035
1063 /* Keep only a prefix from newdir if nm starts with slash 1036 /* Keep only a prefix from newdir if nm starts with slash
1064 (/ /server/share for UNC, nothing otherwise). */ 1037 (/ /server/share for UNC, nothing otherwise). */
1065 if (IS_DIRECTORY_SEP (nm[0]) && collapse_newdir) 1038 if (IS_DIRECTORY_SEP (nm[0]) && collapse_newdir)
1066 { 1039 {
1067 #ifdef WINDOWSNT
1068 if (IS_DIRECTORY_SEP (newdir[0]) && IS_DIRECTORY_SEP (newdir[1])) 1040 if (IS_DIRECTORY_SEP (newdir[0]) && IS_DIRECTORY_SEP (newdir[1]))
1069 { 1041 {
1070 newdir = strcpy (alloca (strlen (newdir) + 1), newdir); 1042 newdir = strcpy (alloca (strlen (newdir) + 1), newdir);
1071 p = newdir + 2; 1043 p = newdir + 2;
1072 while (*p && !IS_DIRECTORY_SEP (*p)) p++; 1044 while (*p && !IS_DIRECTORY_SEP (*p)) p++;
1073 p++; 1045 p++;
1074 while (*p && !IS_DIRECTORY_SEP (*p)) p++; 1046 while (*p && !IS_DIRECTORY_SEP (*p)) p++;
1075 *p = 0; 1047 *p = 0;
1076 } 1048 }
1077 else 1049 else
1078 #endif
1079 newdir = ""; 1050 newdir = "";
1080 } 1051 }
1081 } 1052 }
1082 #endif /* DOS_NT */ 1053 #endif /* WINDOWSNT */
1083 1054
1084 if (newdir) 1055 if (newdir)
1085 { 1056 {
1086 /* Get rid of any slash at the end of newdir, unless newdir is 1057 /* Get rid of any slash at the end of newdir, unless newdir is
1087 just // (an incomplete UNC name). */ 1058 just // (an incomplete UNC name). */
1102 else 1073 else
1103 tlen = 0; 1074 tlen = 0;
1104 1075
1105 /* Now concatenate the directory and name to new space in the stack frame */ 1076 /* Now concatenate the directory and name to new space in the stack frame */
1106 tlen += strlen (nm) + 1; 1077 tlen += strlen (nm) + 1;
1107 #ifdef DOS_NT 1078 #ifdef WINDOWSNT
1108 /* Add reserved space for drive name. (The Microsoft x86 compiler 1079 /* Add reserved space for drive name. (The Microsoft x86 compiler
1109 produces incorrect code if the following two lines are combined.) */ 1080 produces incorrect code if the following two lines are combined.) */
1110 target = (Bufbyte *) alloca (tlen + 2); 1081 target = (Bufbyte *) alloca (tlen + 2);
1111 target += 2; 1082 target += 2;
1112 #else /* not DOS_NT */ 1083 #else /* not WINDOWSNT */
1113 target = (Bufbyte *) alloca (tlen); 1084 target = (Bufbyte *) alloca (tlen);
1114 #endif /* not DOS_NT */ 1085 #endif /* not WINDOWSNT */
1115 *target = 0; 1086 *target = 0;
1116 1087
1117 if (newdir) 1088 if (newdir)
1118 { 1089 {
1119 if (nm[0] == 0 || IS_DIRECTORY_SEP (nm[0])) 1090 if (nm[0] == 0 || IS_DIRECTORY_SEP (nm[0]))
1164 { 1135 {
1165 *o++ = *p++; 1136 *o++ = *p++;
1166 } 1137 }
1167 } 1138 }
1168 1139
1169 #ifdef DOS_NT
1170 /* At last, set drive name. */
1171 #ifdef WINDOWSNT 1140 #ifdef WINDOWSNT
1172 /* Except for network file name. */ 1141 /* At last, set drive name, except for network file name. */
1173 if (!(IS_DIRECTORY_SEP (target[0]) && IS_DIRECTORY_SEP (target[1]))) 1142 if (!(IS_DIRECTORY_SEP (target[0]) && IS_DIRECTORY_SEP (target[1])))
1174 #endif /* WINDOWSNT */
1175 { 1143 {
1176 if (!drive) abort (); 1144 if (!drive) abort ();
1177 target -= 2; 1145 target -= 2;
1178 target[0] = DRIVE_LETTER (drive); 1146 target[0] = DRIVE_LETTER (drive);
1179 target[1] = ':'; 1147 target[1] = ':';
1180 } 1148 }
1181 CORRECT_DIR_SEPS (target); 1149 CORRECT_DIR_SEPS (target);
1182 #endif /* DOS_NT */ 1150 #endif /* WINDOWSNT */
1183 1151
1184 return make_string (target, o - target); 1152 return make_string (target, o - target);
1185 } 1153 }
1186 1154
1187 #if 0 /* FSFmacs */ 1155 #if 0 /* FSFmacs */
1336 if (!NILP (handler)) 1304 if (!NILP (handler))
1337 return call2_check_string_or_nil (handler, Qsubstitute_in_file_name, 1305 return call2_check_string_or_nil (handler, Qsubstitute_in_file_name,
1338 string); 1306 string);
1339 1307
1340 nm = XSTRING_DATA (string); 1308 nm = XSTRING_DATA (string);
1341 #ifdef DOS_NT 1309 #ifdef WINDOWSNT
1342 nm = strcpy (alloca (strlen (nm) + 1), nm); 1310 nm = strcpy (alloca (strlen (nm) + 1), nm);
1343 CORRECT_DIR_SEPS (nm); 1311 CORRECT_DIR_SEPS (nm);
1344 substituted = (strcmp (nm, XSTRING_DATA (string)) != 0); 1312 substituted = (strcmp (nm, XSTRING_DATA (string)) != 0);
1345 #endif 1313 #endif
1346 endp = nm + XSTRING_LENGTH (string); 1314 endp = nm + XSTRING_LENGTH (string);
1362 && (IS_DIRECTORY_SEP (p[-1]))) 1330 && (IS_DIRECTORY_SEP (p[-1])))
1363 { 1331 {
1364 nm = p; 1332 nm = p;
1365 substituted = 1; 1333 substituted = 1;
1366 } 1334 }
1367 #ifdef DOS_NT 1335 #ifdef WINDOWSNT
1368 /* see comment in expand-file-name about drive specifiers */ 1336 /* see comment in expand-file-name about drive specifiers */
1369 else if (IS_DRIVE (p[0]) && p[1] == ':' 1337 else if (IS_DRIVE (p[0]) && p[1] == ':'
1370 && p > nm && IS_DIRECTORY_SEP (p[-1])) 1338 && p > nm && IS_DIRECTORY_SEP (p[-1]))
1371 { 1339 {
1372 nm = p; 1340 nm = p;
1373 substituted = 1; 1341 substituted = 1;
1374 } 1342 }
1375 #endif /* DOS_NT */ 1343 #endif /* WINDOWSNT */
1376 } 1344 }
1377 1345
1378 /* See if any variables are substituted into the string 1346 /* See if any variables are substituted into the string
1379 and find the total length of their values in `total' */ 1347 and find the total length of their values in `total' */
1380 1348
1410 1378
1411 /* Copy out the variable name */ 1379 /* Copy out the variable name */
1412 target = (Bufbyte *) alloca (s - o + 1); 1380 target = (Bufbyte *) alloca (s - o + 1);
1413 strncpy ((char *) target, (char *) o, s - o); 1381 strncpy ((char *) target, (char *) o, s - o);
1414 target[s - o] = 0; 1382 target[s - o] = 0;
1415 #ifdef DOS_NT 1383 #ifdef WINDOWSNT
1416 strupr (target); /* $home == $HOME etc. */ 1384 strupr (target); /* $home == $HOME etc. */
1417 #endif /* DOS_NT */ 1385 #endif /* WINDOWSNT */
1418 1386
1419 /* Get variable value */ 1387 /* Get variable value */
1420 o = (Bufbyte *) egetenv ((char *) target); 1388 o = (Bufbyte *) egetenv ((char *) target);
1421 if (!o) goto badvar; 1389 if (!o) goto badvar;
1422 total += strlen ((char *) o); 1390 total += strlen ((char *) o);
1461 1429
1462 /* Copy out the variable name */ 1430 /* Copy out the variable name */
1463 target = (Bufbyte *) alloca (s - o + 1); 1431 target = (Bufbyte *) alloca (s - o + 1);
1464 strncpy ((char *) target, (char *) o, s - o); 1432 strncpy ((char *) target, (char *) o, s - o);
1465 target[s - o] = 0; 1433 target[s - o] = 0;
1466 #ifdef DOS_NT 1434 #ifdef WINDOWSNT
1467 strupr (target); /* $home == $HOME etc. */ 1435 strupr (target); /* $home == $HOME etc. */
1468 #endif /* DOS_NT */ 1436 #endif /* WINDOWSNT */
1469 1437
1470 /* Get variable value */ 1438 /* Get variable value */
1471 o = (Bufbyte *) egetenv ((char *) target); 1439 o = (Bufbyte *) egetenv ((char *) target);
1472 if (!o) 1440 if (!o)
1473 goto badvar; 1441 goto badvar;
1489 #endif /* APOLLO || WINDOWSNT */ 1457 #endif /* APOLLO || WINDOWSNT */
1490 ) 1458 )
1491 /* don't do p[-1] if that would go off the beginning --jwz */ 1459 /* don't do p[-1] if that would go off the beginning --jwz */
1492 && p != nm && p > xnm && IS_DIRECTORY_SEP (p[-1])) 1460 && p != nm && p > xnm && IS_DIRECTORY_SEP (p[-1]))
1493 xnm = p; 1461 xnm = p;
1494 #ifdef DOS_NT 1462 #ifdef WINDOWSNT
1495 else if (IS_DRIVE (p[0]) && p[1] == ':' 1463 else if (IS_DRIVE (p[0]) && p[1] == ':'
1496 && p > nm && IS_DIRECTORY_SEP (p[-1])) 1464 && p > nm && IS_DIRECTORY_SEP (p[-1]))
1497 xnm = p; 1465 xnm = p;
1498 #endif 1466 #endif
1499 1467
1664 1632
1665 /* We can only copy regular files and symbolic links. Other files are not 1633 /* We can only copy regular files and symbolic links. Other files are not
1666 copyable by us. */ 1634 copyable by us. */
1667 input_file_statable_p = (fstat (ifd, &st) >= 0); 1635 input_file_statable_p = (fstat (ifd, &st) >= 0);
1668 1636
1669 #ifndef DOS_NT 1637 #ifndef WINDOWSNT
1670 if (out_st.st_mode != 0 1638 if (out_st.st_mode != 0
1671 && st.st_dev == out_st.st_dev && st.st_ino == out_st.st_ino) 1639 && st.st_dev == out_st.st_dev && st.st_ino == out_st.st_ino)
1672 { 1640 {
1673 errno = 0; 1641 errno = 0;
1674 report_file_error ("Input and output files are the same", 1642 report_file_error ("Input and output files are the same",
1693 report_file_error ("Non-regular file", list1 (filename)); 1661 report_file_error ("Non-regular file", list1 (filename));
1694 } 1662 }
1695 } 1663 }
1696 #endif /* S_ISREG && S_ISLNK */ 1664 #endif /* S_ISREG && S_ISLNK */
1697 1665
1698 #ifdef MSDOS
1699 /* System's default file type was set to binary by _fmode in emacs.c. */
1700 ofd = creat ((char *) XSTRING_DATA (newname), S_IREAD | S_IWRITE);
1701 #else /* not MSDOS */
1702 ofd = open( (char *) XSTRING_DATA (newname), 1666 ofd = open( (char *) XSTRING_DATA (newname),
1703 O_WRONLY | O_CREAT | O_TRUNC | OPEN_BINARY, CREAT_MODE); 1667 O_WRONLY | O_CREAT | O_TRUNC | OPEN_BINARY, CREAT_MODE);
1704 #endif /* not MSDOS */
1705 if (ofd < 0) 1668 if (ofd < 0)
1706 report_file_error ("Opening output file", list1 (newname)); 1669 report_file_error ("Opening output file", list1 (newname));
1707 1670
1708 { 1671 {
1709 Lisp_Object ofd_locative = noseeum_cons (make_int (ofd), Qnil); 1672 Lisp_Object ofd_locative = noseeum_cons (make_int (ofd), Qnil);
1729 EMACS_SET_SECS_USECS (mtime, st.st_mtime, 0); 1692 EMACS_SET_SECS_USECS (mtime, st.st_mtime, 0);
1730 if (set_file_times ((char *) XSTRING_DATA (newname), atime, 1693 if (set_file_times ((char *) XSTRING_DATA (newname), atime,
1731 mtime)) 1694 mtime))
1732 report_file_error ("I/O error", list1 (newname)); 1695 report_file_error ("I/O error", list1 (newname));
1733 } 1696 }
1734 #ifndef MSDOS
1735 chmod ((CONST char *) XSTRING_DATA (newname), 1697 chmod ((CONST char *) XSTRING_DATA (newname),
1736 st.st_mode & 07777); 1698 st.st_mode & 07777);
1737 #else /* MSDOS */
1738 #if defined (__DJGPP__) && __DJGPP__ > 1
1739 /* In DJGPP v2.0 and later, fstat usually returns true file mode bits,
1740 and if it can't, it tells so. Otherwise, under MSDOS we usually
1741 get only the READ bit, which will make the copied file read-only,
1742 so it's better not to chmod at all. */
1743 if ((_djstat_flags & _STFAIL_WRITEBIT) == 0)
1744 chmod ((char *) XSTRING_DATA (newname), st.st_mode & 07777);
1745 #endif /* DJGPP version 2 or newer */
1746 #endif /* MSDOS */
1747 } 1699 }
1748 1700
1749 /* We'll close it by hand */ 1701 /* We'll close it by hand */
1750 XCAR (ofd_locative) = Qnil; 1702 XCAR (ofd_locative) = Qnil;
1751 1703
2110 Bufbyte *ptr; 2062 Bufbyte *ptr;
2111 2063
2112 CHECK_STRING (filename); 2064 CHECK_STRING (filename);
2113 ptr = XSTRING_DATA (filename); 2065 ptr = XSTRING_DATA (filename);
2114 if (IS_DIRECTORY_SEP (*ptr) || *ptr == '~' 2066 if (IS_DIRECTORY_SEP (*ptr) || *ptr == '~'
2115 #ifdef DOS_NT 2067 #ifdef WINDOWSNT
2116 || (IS_DRIVE (*ptr) && ptr[1] == ':' && IS_DIRECTORY_SEP (ptr[2])) 2068 || (IS_DRIVE (*ptr) && ptr[1] == ':' && IS_DIRECTORY_SEP (ptr[2]))
2117 #endif 2069 #endif
2118 ) 2070 )
2119 return Qt; 2071 return Qt;
2120 else 2072 else
2124 /* Return nonzero if file FILENAME exists and can be executed. */ 2076 /* Return nonzero if file FILENAME exists and can be executed. */
2125 2077
2126 static int 2078 static int
2127 check_executable (char *filename) 2079 check_executable (char *filename)
2128 { 2080 {
2129 #ifdef DOS_NT 2081 #ifdef WINDOWSNT
2130 int len = strlen (filename);
2131 char *suffix;
2132 struct stat st; 2082 struct stat st;
2133 if (stat (filename, &st) < 0) 2083 if (stat (filename, &st) < 0)
2134 return 0; 2084 return 0;
2135 #if defined (WINDOWSNT)
2136 return ((st.st_mode & S_IEXEC) != 0); 2085 return ((st.st_mode & S_IEXEC) != 0);
2137 #else 2086 #else /* not WINDOWSNT */
2138 return (S_ISREG (st.st_mode)
2139 && len >= 5
2140 && (stricmp ((suffix = filename + len-4), ".com") == 0
2141 || stricmp (suffix, ".exe") == 0
2142 || stricmp (suffix, ".bat") == 0)
2143 || (st.st_mode & S_IFMT) == S_IFDIR);
2144 #endif /* not WINDOWSNT */
2145 #else /* not DOS_NT */
2146 #ifdef HAVE_EACCESS 2087 #ifdef HAVE_EACCESS
2147 return eaccess (filename, 1) >= 0; 2088 return eaccess (filename, 1) >= 0;
2148 #else 2089 #else
2149 /* Access isn't quite right because it uses the real uid 2090 /* Access isn't quite right because it uses the real uid
2150 and we really want to test with the effective uid. 2091 and we really want to test with the effective uid.
2151 But Unix doesn't give us a right way to do it. */ 2092 But Unix doesn't give us a right way to do it. */
2152 return access (filename, 1) >= 0; 2093 return access (filename, 1) >= 0;
2153 #endif /* HAVE_EACCESS */ 2094 #endif /* HAVE_EACCESS */
2154 #endif /* not DOS_NT */ 2095 #endif /* not WINDOWSNT */
2155 } 2096 }
2156 2097
2157 /* Return nonzero if file FILENAME exists and can be written. */ 2098 /* Return nonzero if file FILENAME exists and can be written. */
2158 2099
2159 static int 2100 static int
2160 check_writable (CONST char *filename) 2101 check_writable (CONST char *filename)
2161 { 2102 {
2162 #ifdef MSDOS
2163 struct stat st;
2164 if (stat (filename, &st) < 0)
2165 return 0;
2166 return (st.st_mode & S_IWRITE || (st.st_mode & S_IFMT) == S_IFDIR);
2167 #else /* not MSDOS */
2168 #ifdef HAVE_EACCESS 2103 #ifdef HAVE_EACCESS
2169 return (eaccess (filename, 2) >= 0); 2104 return (eaccess (filename, 2) >= 0);
2170 #else 2105 #else
2171 /* Access isn't quite right because it uses the real uid 2106 /* Access isn't quite right because it uses the real uid
2172 and we really want to test with the effective uid. 2107 and we really want to test with the effective uid.
2173 But Unix doesn't give us a right way to do it. 2108 But Unix doesn't give us a right way to do it.
2174 Opening with O_WRONLY could work for an ordinary file, 2109 Opening with O_WRONLY could work for an ordinary file,
2175 but would lose for directories. */ 2110 but would lose for directories. */
2176 return (access (filename, 2) >= 0); 2111 return (access (filename, 2) >= 0);
2177 #endif 2112 #endif
2178 #endif /* not MSDOS */
2179 } 2113 }
2180 2114
2181 DEFUN ("file-exists-p", Ffile_exists_p, 1, 1, 0, /* 2115 DEFUN ("file-exists-p", Ffile_exists_p, 1, 1, 0, /*
2182 Return t if file FILENAME exists. (This does not mean you can read it.) 2116 Return t if file FILENAME exists. (This does not mean you can read it.)
2183 See also `file-readable-p' and `file-attributes'. 2117 See also `file-readable-p' and `file-attributes'.
2241 (filename)) 2175 (filename))
2242 { 2176 {
2243 /* This function can GC */ 2177 /* This function can GC */
2244 Lisp_Object abspath = Qnil; 2178 Lisp_Object abspath = Qnil;
2245 Lisp_Object handler; 2179 Lisp_Object handler;
2246 int desc;
2247 struct gcpro gcpro1; 2180 struct gcpro gcpro1;
2248 GCPRO1 (abspath); 2181 GCPRO1 (abspath);
2249 2182
2250 CHECK_STRING (filename); 2183 CHECK_STRING (filename);
2251 abspath = Fexpand_file_name (filename, Qnil); 2184 abspath = Fexpand_file_name (filename, Qnil);
2254 call the corresponding file handler. */ 2187 call the corresponding file handler. */
2255 handler = Ffind_file_name_handler (abspath, Qfile_readable_p); 2188 handler = Ffind_file_name_handler (abspath, Qfile_readable_p);
2256 if (!NILP (handler)) 2189 if (!NILP (handler))
2257 RETURN_UNGCPRO (call2 (handler, Qfile_readable_p, abspath)); 2190 RETURN_UNGCPRO (call2 (handler, Qfile_readable_p, abspath));
2258 2191
2259 #ifdef DOS_NT 2192 #ifdef WINDOWSNT
2260 /* Under MS-DOS and Windows, open does not work for directories. */ 2193 /* Under MS-DOS and Windows, open does not work for directories. */
2261 if (access (XSTRING_DATA (abspath), 0) == 0) 2194 if (access (XSTRING_DATA (abspath), 0) == 0)
2262 return Qt; 2195 return Qt;
2263 return Qnil; 2196 return Qnil;
2264 #else /* not DOS_NT */ 2197 #else /* not WINDOWSNT */
2265 desc = interruptible_open ((char *) XSTRING_DATA (abspath), O_RDONLY | OPEN_BINARY, 0); 2198 {
2266 UNGCPRO; 2199 int desc = interruptible_open ((char *) XSTRING_DATA (abspath), O_RDONLY | OPEN_BINARY, 0);
2267 if (desc < 0) 2200 UNGCPRO;
2268 return Qnil; 2201 if (desc < 0)
2269 close (desc); 2202 return Qnil;
2270 return Qt; 2203 close (desc);
2271 #endif /* not DOS_NT */ 2204 return Qt;
2205 }
2206 #endif /* not WINDOWSNT */
2272 } 2207 }
2273 2208
2274 /* Having this before file-symlink-p mysteriously caused it to be forgotten 2209 /* Having this before file-symlink-p mysteriously caused it to be forgotten
2275 on the RT/PC. */ 2210 on the RT/PC. */
2276 DEFUN ("file-writable-p", Ffile_writable_p, 1, 1, 0, /* 2211 DEFUN ("file-writable-p", Ffile_writable_p, 1, 1, 0, /*
2301 2236
2302 2237
2303 GCPRO1 (abspath); 2238 GCPRO1 (abspath);
2304 dir = Ffile_name_directory (abspath); 2239 dir = Ffile_name_directory (abspath);
2305 UNGCPRO; 2240 UNGCPRO;
2306 #ifdef MSDOS
2307 if (!NILP (dir))
2308 {
2309 GCPRO1(dir);
2310 dir = Fdirectory_file_name (dir);
2311 UNGCPRO;
2312 }
2313 #endif /* MSDOS */
2314 return (check_writable (!NILP (dir) ? (char *) XSTRING_DATA (dir) 2241 return (check_writable (!NILP (dir) ? (char *) XSTRING_DATA (dir)
2315 : "") 2242 : "")
2316 ? Qt : Qnil); 2243 ? Qt : Qnil);
2317 } 2244 }
2318 2245
2416 handler = Ffind_file_name_handler (filename, Qfile_accessible_directory_p); 2343 handler = Ffind_file_name_handler (filename, Qfile_accessible_directory_p);
2417 if (!NILP (handler)) 2344 if (!NILP (handler))
2418 return call2 (handler, Qfile_accessible_directory_p, 2345 return call2 (handler, Qfile_accessible_directory_p,
2419 filename); 2346 filename);
2420 2347
2421 #if !defined(DOS_NT) 2348 #if !defined(WINDOWSNT)
2422 if (NILP (Ffile_directory_p (filename))) 2349 if (NILP (Ffile_directory_p (filename)))
2423 return (Qnil); 2350 return (Qnil);
2424 else 2351 else
2425 return Ffile_executable_p (filename); 2352 return Ffile_executable_p (filename);
2426 #else 2353 #else
2437 tem = (NILP (Ffile_directory_p (filename)) 2364 tem = (NILP (Ffile_directory_p (filename))
2438 || NILP (Ffile_executable_p (filename))); 2365 || NILP (Ffile_executable_p (filename)));
2439 UNGCPRO; 2366 UNGCPRO;
2440 return tem ? Qnil : Qt; 2367 return tem ? Qnil : Qt;
2441 } 2368 }
2442 #endif /* !defined(DOS_NT) */ 2369 #endif /* !defined(WINDOWSNT) */
2443 } 2370 }
2444 2371
2445 DEFUN ("file-regular-p", Ffile_regular_p, 1, 1, 0, /* 2372 DEFUN ("file-regular-p", Ffile_regular_p, 1, 1, 0, /*
2446 "Return t if file FILENAME is the name of a regular file. 2373 "Return t if file FILENAME is the name of a regular file.
2447 This is the sort of file that holds an ordinary stream of data bytes. 2374 This is the sort of file that holds an ordinary stream of data bytes.
2627 2554
2628 return (mtime1 > st.st_mtime) ? Qt : Qnil; 2555 return (mtime1 > st.st_mtime) ? Qt : Qnil;
2629 } 2556 }
2630 2557
2631 2558
2632 #ifdef DOS_NT
2633 Lisp_Object Qfind_buffer_file_type;
2634
2635 /* Return 1 if buffer is text, 0 if binary. */
2636 static int
2637 decide_buffer_type (unsigned char * buffer, int nbytes)
2638 {
2639 /* Buffer is binary if we find any LF chars not preceeded by CR or if
2640 the buffer doesn't contain at least 1 line. */
2641 unsigned lines = 0;
2642 unsigned char *p, *q;
2643
2644 for (p = buffer; nbytes > 0 && (q = memchr (p, '\n', nbytes)) != NULL;
2645 p = q + 1 )
2646 {
2647 nbytes -= (q + 1 - p);
2648 lines++;
2649 if (q > buffer && q[-1] != '\r')
2650 return 0;
2651 }
2652
2653 /* If we haven't seen any line endings yet, return -1 (meaning type is
2654 undecided) so we can examine the next bufferful as well. */
2655 return (lines > 0) ? 1 : -1;
2656 }
2657
2658 /* XEmacs addition: like decide_buffer_type(), but working on a XEmacs buffer:
2659 first arg is a byte index position instead of a char pointer;
2660 we check each char sequentially. --marcpa */
2661 static int
2662 buf_decide_buffer_type (struct buffer *buf, Bytind start, int nbytes)
2663 {
2664 /* Buffer is binary if we find any LF chars not preceeded by CR or if
2665 the buffer doesn't contain at least 1 line. */
2666 unsigned lines = 0;
2667 Bytind cur = start;
2668
2669 while (nbytes)
2670 {
2671 if (BI_BUF_FETCH_CHAR(buf, cur) == '\n')
2672 {
2673 lines++;
2674 if (cur != start && BI_BUF_FETCH_CHAR(buf, cur - 1) != '\r')
2675 return 0;
2676 }
2677 nbytes--;
2678 }
2679
2680 /* If we haven't seen any line endings yet, return -1 (meaning type is
2681 undecided) so we can examine the next bufferful as well. */
2682 return (lines > 0) ? 1 : -1;
2683 }
2684 #endif /* DOS_NT */
2685
2686 /* Stack sizes > 2**16 is a good way to elicit compiler bugs */ 2559 /* Stack sizes > 2**16 is a good way to elicit compiler bugs */
2687 /* #define READ_BUF_SIZE (2 << 16) */ 2560 /* #define READ_BUF_SIZE (2 << 16) */
2688 #define READ_BUF_SIZE (1 << 15) 2561 #define READ_BUF_SIZE (1 << 15)
2689 2562
2690 DEFUN ("insert-file-contents-internal", 2563 DEFUN ("insert-file-contents-internal",
2719 Bufbyte read_buf[READ_BUF_SIZE]; 2592 Bufbyte read_buf[READ_BUF_SIZE];
2720 int mc_count; 2593 int mc_count;
2721 struct buffer *buf = current_buffer; 2594 struct buffer *buf = current_buffer;
2722 Lisp_Object curbuf; 2595 Lisp_Object curbuf;
2723 int not_regular = 0; 2596 int not_regular = 0;
2724 #ifdef DOS_NT
2725 int crlf_conversion_required = 0;
2726 unsigned crlf_count = 0;
2727 unsigned lf_count = 0;
2728 #endif
2729 2597
2730 if (buf->base_buffer && ! NILP (visit)) 2598 if (buf->base_buffer && ! NILP (visit))
2731 error ("Cannot do file visiting in an indirect buffer"); 2599 error ("Cannot do file visiting in an indirect buffer");
2732 2600
2733 /* No need to call Fbarf_if_buffer_read_only() here. 2601 /* No need to call Fbarf_if_buffer_read_only() here.
2841 { 2709 {
2842 end = make_int (st.st_size); 2710 end = make_int (st.st_size);
2843 if (XINT (end) != st.st_size) 2711 if (XINT (end) != st.st_size)
2844 error ("Maximum buffer size exceeded"); 2712 error ("Maximum buffer size exceeded");
2845 } 2713 }
2846
2847 #ifdef DOS_NT
2848 /* Permit old behaviour if desired. */
2849 if (NILP (Vinsert_file_contents_allow_replace) && !NILP (replace))
2850 {
2851 replace = Qnil;
2852 /* Surely this was never right! */
2853 /* XSETFASTINT (beg, 0);
2854 XSETFASTINT (end, st.st_size); */
2855 buffer_delete_range (buf, BUF_BEGV(buf), BUF_ZV(buf),
2856 !NILP (visit) ? INSDEL_NO_LOCKING : 0);
2857 }
2858 #endif /* DOS_NT */
2859 } 2714 }
2860 2715
2861 /* If requested, replace the accessible part of the buffer 2716 /* If requested, replace the accessible part of the buffer
2862 with the file contents. Avoid replacing text at the 2717 with the file contents. Avoid replacing text at the
2863 beginning or end of the buffer that matches the file contents; 2718 beginning or end of the buffer that matches the file contents;
2866 /* The replace-mode code currently only works when the assumption 2721 /* The replace-mode code currently only works when the assumption
2867 'one byte == one char' holds true. This fails Mule because 2722 'one byte == one char' holds true. This fails Mule because
2868 files may contain multibyte characters. It holds under Windows NT 2723 files may contain multibyte characters. It holds under Windows NT
2869 provided we convert CRLF into LF. */ 2724 provided we convert CRLF into LF. */
2870 # define FSFMACS_SPEEDY_INSERT 2725 # define FSFMACS_SPEEDY_INSERT
2871 #endif 2726 #endif /* !defined (FILE_CODING) */
2727
2872 #ifndef FSFMACS_SPEEDY_INSERT 2728 #ifndef FSFMACS_SPEEDY_INSERT
2873 if (!NILP (replace)) 2729 if (!NILP (replace))
2874 { 2730 {
2875 buffer_delete_range (buf, BUF_BEG (buf), BUF_Z (buf), 2731 buffer_delete_range (buf, BUF_BEG (buf), BUF_Z (buf),
2876 !NILP (visit) ? INSDEL_NO_LOCKING : 0); 2732 !NILP (visit) ? INSDEL_NO_LOCKING : 0);
2880 { 2736 {
2881 char buffer[1 << 14]; 2737 char buffer[1 << 14];
2882 Bufpos same_at_start = BUF_BEGV (buf); 2738 Bufpos same_at_start = BUF_BEGV (buf);
2883 Bufpos same_at_end = BUF_ZV (buf); 2739 Bufpos same_at_end = BUF_ZV (buf);
2884 int overlap; 2740 int overlap;
2885 #ifdef DOS_NT
2886 /* Syncing with 19.34.6 note: same_at_start_in_file and
2887 same_at_end_in_file are not in XEmacs 20.4.
2888 First try to introduce them as-is and see what happens.
2889 Might be necessary to use constructs like
2890 st.st_size - (BUF_ZV (buf) - same_at_end)
2891 instead.
2892 --marcpa
2893 */
2894 /* Offset into the file where discrepancy begins. */
2895 int same_at_start_in_file = 0;
2896 /* Offset into the file where discrepancy ends. */
2897 int same_at_end_in_file = st.st_size;
2898 /* DOS_NT only: is there a `\r' character left in the buffer? */
2899 int cr_left_in_buffer = 0;
2900 /* DOS_NT only: was `\n' the first character in previous bufferful? */
2901 int last_was_lf = 0;
2902
2903 /* Demacs 1.1.1 91/10/16 HIRANO Satoshi, MW July 1993 */
2904 /* Determine file type (text/binary) from its name.
2905 Note that the buffer_file_type changes here when the file
2906 being inserted is not of the same type as the original buffer. */
2907 current_buffer->buffer_file_type = call1 (Qfind_buffer_file_type, filename);
2908 if (NILP (current_buffer->buffer_file_type))
2909 crlf_conversion_required = 1;
2910 else if (current_buffer->buffer_file_type != Qt)
2911 /* Use heuristic to decide whether file is text or binary (based
2912 on the first bufferful) if buffer-file-type is not nil or t.
2913 If no decision is made (because no line endings were ever
2914 seen) then let buffer-file-type default to nil. */
2915 crlf_conversion_required = -1;
2916 #endif /* DOS_NT */
2917 2741
2918 /* Count how many chars at the start of the file 2742 /* Count how many chars at the start of the file
2919 match the text at the beginning of the buffer. */ 2743 match the text at the beginning of the buffer. */
2920 while (1) 2744 while (1)
2921 { 2745 {
2922 int nread; 2746 int nread;
2923 Bufpos bufpos; 2747 Bufpos bufpos;
2924 #ifdef DOS_NT
2925 if (cr_left_in_buffer)
2926 {
2927 nread = read_allowing_quit (fd, buffer + 1, sizeof(buffer) - 1);
2928 cr_left_in_buffer = 0;
2929 if (nread >= 0)
2930 nread++;
2931 }
2932 else
2933 #endif /* DOS_NT */
2934 nread = read_allowing_quit (fd, buffer, sizeof buffer); 2748 nread = read_allowing_quit (fd, buffer, sizeof buffer);
2935 if (nread < 0) 2749 if (nread < 0)
2936 error ("IO error reading %s: %s", 2750 error ("IO error reading %s: %s",
2937 XSTRING_DATA (filename), strerror (errno)); 2751 XSTRING_DATA (filename), strerror (errno));
2938 else if (nread == 0) 2752 else if (nread == 0)
2939 break; 2753 break;
2940 bufpos = 0; 2754 bufpos = 0;
2941 #ifdef DOS_NT
2942 /* If requested, we do a simple check on the first bufferful
2943 to decide whether the file is binary or text. (If text, we
2944 count LF and CRLF occurences to determine whether the file
2945 was in Unix or DOS format.) */
2946 if (crlf_conversion_required < 0)
2947 {
2948 crlf_conversion_required = decide_buffer_type (buffer, nread);
2949 current_buffer->buffer_file_type =
2950 crlf_conversion_required ? Qnil : Qt;
2951 }
2952
2953 /* DOS_NT text files require that we ignore a `\r' before a `\n'. */
2954 if (crlf_conversion_required > 0)
2955 while (bufpos < nread && same_at_start < BUF_ZV (buf))
2956 {
2957 int filec = buffer[bufpos];
2958 int bufc = BUF_FETCH_CHAR (buf, same_at_start);
2959
2960 if (filec == '\n')
2961 lf_count++;
2962
2963 if (filec == bufc)
2964 same_at_start++, bufpos++, same_at_start_in_file++;
2965 else if (filec == '\r' && bufc == '\n')
2966 {
2967 /* If the `\r' is the last character in this buffer,
2968 it will be examined with the next bufferful. */
2969 if (bufpos == nread)
2970 {
2971 buffer[0] = filec;
2972 cr_left_in_buffer = 1;
2973 }
2974 else if (buffer[bufpos + 1] == bufc)
2975 {
2976 bufpos += 2;
2977 same_at_start_in_file += 2;
2978 same_at_start++;
2979 crlf_count++;
2980 lf_count++;
2981 }
2982 else
2983 break;
2984 }
2985 else
2986 break;
2987 }
2988 else
2989 #endif /* DOS_NT */
2990 while (bufpos < nread && same_at_start < BUF_ZV (buf) 2755 while (bufpos < nread && same_at_start < BUF_ZV (buf)
2991 && BUF_FETCH_CHAR (buf, same_at_start) == buffer[bufpos]) 2756 && BUF_FETCH_CHAR (buf, same_at_start) == buffer[bufpos])
2992 #ifdef DOS_NT
2993 same_at_start_in_file++,
2994 #endif
2995 same_at_start++, bufpos++; 2757 same_at_start++, bufpos++;
2996 /* If we found a discrepancy, stop the scan. 2758 /* If we found a discrepancy, stop the scan.
2997 Otherwise loop around and scan the next bufferful. */ 2759 Otherwise loop around and scan the next bufferful. */
2998 if (bufpos != nread) 2760 if (bufpos != nread)
2999 break; 2761 break;
3000 } 2762 }
3001 /* If the file matches the buffer completely, 2763 /* If the file matches the buffer completely,
3002 there's no need to replace anything. */ 2764 there's no need to replace anything. */
3003 #ifdef DOS_NT
3004 if (same_at_start_in_file == st.st_size)
3005 #else
3006 if (same_at_start - BUF_BEGV (buf) == st.st_size) 2765 if (same_at_start - BUF_BEGV (buf) == st.st_size)
3007 #endif /* DOS_NT */
3008 { 2766 {
3009 close (fd); 2767 close (fd);
3010 unbind_to (speccount, Qnil); 2768 unbind_to (speccount, Qnil);
3011 /* Truncate the buffer to the size of the file. */ 2769 /* Truncate the buffer to the size of the file. */
3012 buffer_delete_range (buf, same_at_start, same_at_end, 2770 buffer_delete_range (buf, same_at_start, same_at_end,
3019 { 2777 {
3020 int total_read, nread; 2778 int total_read, nread;
3021 Bufpos bufpos, curpos, trial; 2779 Bufpos bufpos, curpos, trial;
3022 2780
3023 /* At what file position are we now scanning? */ 2781 /* At what file position are we now scanning? */
3024 #ifdef DOS_NT
3025 curpos = same_at_end_in_file;
3026 #else
3027 curpos = st.st_size - (BUF_ZV (buf) - same_at_end); 2782 curpos = st.st_size - (BUF_ZV (buf) - same_at_end);
3028 #endif /* DOS_NT */
3029 /* If the entire file matches the buffer tail, stop the scan. */ 2783 /* If the entire file matches the buffer tail, stop the scan. */
3030 if (curpos == 0) 2784 if (curpos == 0)
3031 break; 2785 break;
3032 /* How much can we scan in the next step? */ 2786 /* How much can we scan in the next step? */
3033 trial = min (curpos, sizeof buffer); 2787 trial = min (curpos, sizeof buffer);
3044 total_read += nread; 2798 total_read += nread;
3045 } 2799 }
3046 /* Scan this bufferful from the end, comparing with 2800 /* Scan this bufferful from the end, comparing with
3047 the Emacs buffer. */ 2801 the Emacs buffer. */
3048 bufpos = total_read; 2802 bufpos = total_read;
3049 #ifdef DOS_NT
3050 /* DOS_NT text files require that we ignore a `\r' before a `\n'. */
3051 if (crlf_conversion_required)
3052 #endif /* DOS_NT */
3053 /* Compare with same_at_start to avoid counting some buffer text 2803 /* Compare with same_at_start to avoid counting some buffer text
3054 as matching both at the file's beginning and at the end. */ 2804 as matching both at the file's beginning and at the end. */
3055 #if !defined(DOS_NT)
3056 while (bufpos > 0 && same_at_end > same_at_start 2805 while (bufpos > 0 && same_at_end > same_at_start
3057 && BUF_FETCH_CHAR (buf, same_at_end - 1) == 2806 && BUF_FETCH_CHAR (buf, same_at_end - 1) ==
3058 buffer[bufpos - 1]) 2807 buffer[bufpos - 1])
3059 same_at_end--, bufpos--; 2808 same_at_end--, bufpos--;
3060 #else /* DOS_NT */
3061 while (bufpos > 0 && same_at_end > same_at_start
3062 && same_at_end_in_file > same_at_start_in_file)
3063 {
3064 int filec = buffer[bufpos - 1];
3065 int bufc = BUF_FETCH_CHAR (buf, same_at_end - 1);
3066
3067 /* Account for `\n' in previous bufferful. */
3068 if (last_was_lf && filec == '\r')
3069 {
3070 same_at_end_in_file--, bufpos--;
3071 last_was_lf = 0;
3072 crlf_count++;
3073 }
3074 else if (filec == bufc)
3075 {
3076 last_was_lf = 0;
3077 same_at_end--, same_at_end_in_file--, bufpos--;
3078 if (bufc == '\n')
3079 {
3080 lf_count++;
3081 if (bufpos <= 0)
3082 last_was_lf = 1;
3083 else if (same_at_end_in_file <= same_at_start_in_file)
3084 break;
3085 else if (buffer[bufpos - 1] == '\r')
3086 same_at_end_in_file--, bufpos--, crlf_count++;
3087 }
3088 }
3089 else
3090 {
3091 last_was_lf = 0;
3092 break;
3093 }
3094 }
3095 else
3096 while (bufpos > 0 && same_at_end > same_at_start
3097 && same_at_end_in_file > same_at_start_in_file
3098 && BUF_FETCH_CHAR (buf, same_at_end - 1) ==
3099 buffer[bufpos - 1])
3100 same_at_end--, same_at_end_in_file--, bufpos--;
3101 #endif /* !defined(DOS_NT) */
3102 /* If we found a discrepancy, stop the scan. 2809 /* If we found a discrepancy, stop the scan.
3103 Otherwise loop around and scan the preceding bufferful. */ 2810 Otherwise loop around and scan the preceding bufferful. */
3104 if (bufpos != 0) 2811 if (bufpos != 0)
3105 break; 2812 break;
3106 /* If display current starts at beginning of line, 2813 /* If display current starts at beginning of line,
3115 (same_at_end + st.st_size - BUF_ZV (buf)); 2822 (same_at_end + st.st_size - BUF_ZV (buf));
3116 if (overlap > 0) 2823 if (overlap > 0)
3117 same_at_end += overlap; 2824 same_at_end += overlap;
3118 2825
3119 /* Arrange to read only the nonmatching middle part of the file. */ 2826 /* Arrange to read only the nonmatching middle part of the file. */
3120 #ifdef DOS_NT
3121 beg = make_int (same_at_start_in_file);
3122 end = make_int (same_at_end_in_file);
3123 #else
3124 beg = make_int (same_at_start - BUF_BEGV (buf)); 2827 beg = make_int (same_at_start - BUF_BEGV (buf));
3125 end = make_int (st.st_size - (BUF_ZV (buf) - same_at_end)); 2828 end = make_int (st.st_size - (BUF_ZV (buf) - same_at_end));
3126 #endif /* DOS_NT */
3127 2829
3128 buffer_delete_range (buf, same_at_start, same_at_end, 2830 buffer_delete_range (buf, same_at_start, same_at_end,
3129 !NILP (visit) ? INSDEL_NO_LOCKING : 0); 2831 !NILP (visit) ? INSDEL_NO_LOCKING : 0);
3130 /* Insert from the file at the proper position. */ 2832 /* Insert from the file at the proper position. */
3131 BUF_SET_PT (buf, same_at_start); 2833 BUF_SET_PT (buf, same_at_start);
3190 { 2892 {
3191 if (this_len < 0) 2893 if (this_len < 0)
3192 saverrno = errno; 2894 saverrno = errno;
3193 break; 2895 break;
3194 } 2896 }
3195 #ifdef DOS_NT
3196 /* XEmacs (--marcpa) change: FSF does buffer_insert_raw_string_1() first
3197 then checks if conversion is needed, calling lisp
3198 (find-buffer-file-type) which can call a user-function that
3199 might look at the unconverted buffer to decide if
3200 conversion is needed.
3201 I removed the possibility for lisp functions called from
3202 find-buffer-file-type to look at the buffer's content, for
3203 simplicity reasons: it is easier to do the CRLF -> LF
3204 conversion on read_buf than on buffer contents because
3205 BUF_FETCH_CHAR does not return a pointer to an unsigned
3206 char memory location, and because we must cope with bytind
3207 VS bufpos in XEmacs, thus complicating crlf_to_lf().
3208 This decision (of doing Lstream_read(), crlf_to_lf() then
3209 buffer_insert_raw_string_1()) is debatable.
3210 --marcpa
3211 */
3212 /* Following FSF note no longer apply now. See comment above.
3213 --marcpa*/
3214 /* For compatability with earlier versions that did not support the
3215 REPLACE funtionality, we call find-buffer-file-type after inserting
3216 the contents to allow it to inspect the inserted data. (This was
3217 not intentional usage, but proved to be quite useful.) */
3218 if (NILP (replace))
3219 {
3220 /* Demacs 1.1.1 91/10/16 HIRANO Satoshi, MW July 1993 */
3221 /* Determine file type (text/binary) from its name.
3222 Note that the buffer_file_type changes here when the file
3223 being inserted is not of the same type as the original buffer. */
3224 current_buffer->buffer_file_type = call1 (Qfind_buffer_file_type, filename);
3225 if (NILP (current_buffer->buffer_file_type))
3226 crlf_conversion_required = 1;
3227 else if (current_buffer->buffer_file_type != Qt)
3228 /* Use heuristic to decide whether file is text or binary (based
3229 on the first bufferful) if buffer-file-type is not nil or t.
3230 If no decision is made (because no line endings were ever
3231 seen) then let buffer-file-type default to nil. */
3232 crlf_conversion_required = -1;
3233 }
3234
3235 /* If requested, we check the inserted data to decide whether the file
3236 is binary or text. (If text, we count LF and CRLF occurences to
3237 determine whether the file was in Unix or DOS format.) */
3238 if (crlf_conversion_required < 0)
3239 {
3240 crlf_conversion_required =
3241 decide_buffer_type (read_buf, this_len);
3242 current_buffer->buffer_file_type =
3243 crlf_conversion_required ? Qnil : Qt;
3244 }
3245
3246 /* Demacs 1.1.1 91/10/16 HIRANO Satoshi, MW July 1993 */
3247 /* Remove CRs from CR-LFs if the file is deemed to be a text file. */
3248 if (crlf_conversion_required)
3249 {
3250 int reduced_size
3251 = this_len - crlf_to_lf (this_len, read_buf,
3252 &lf_count);
3253 crlf_count += reduced_size;
3254 /* XEmacs (--marcpa) change: No need for this since we havent
3255 inserted in buffer yet. */
3256 #if 0
3257 ZV -= reduced_size;
3258 Z -= reduced_size;
3259 GPT -= reduced_size;
3260 GAP_SIZE += reduced_size;
3261 inserted -= reduced_size;
3262 #endif
3263 this_len -= reduced_size;
3264
3265 /* Change buffer_file_type back to binary if Unix eol format. */
3266 if (crlf_count == 0 && lf_count > 0)
3267 current_buffer->buffer_file_type = Qt;
3268 }
3269
3270 /* Make crlf_count and lf_count available for inspection. */
3271 Fset (intern ("buffer-file-lines"), make_int (lf_count));
3272 Fset (intern ("buffer-file-dos-lines"), make_int (crlf_count));
3273 #endif /* DOS_NT */
3274 2897
3275 cc_inserted = buffer_insert_raw_string_1 (buf, cur_point, read_buf, 2898 cc_inserted = buffer_insert_raw_string_1 (buf, cur_point, read_buf,
3276 this_len, 2899 this_len,
3277 !NILP (visit) 2900 !NILP (visit)
3278 ? INSDEL_NO_LOCKING : 0); 2901 ? INSDEL_NO_LOCKING : 0);
3432 we should signal an error rather than blissfully continuing 3055 we should signal an error rather than blissfully continuing
3433 along. ARGH, this function is going to lose lose lose. We need 3056 along. ARGH, this function is going to lose lose lose. We need
3434 to protect the current_buffer from being destroyed, but the 3057 to protect the current_buffer from being destroyed, but the
3435 multiple return points make this a pain in the butt. */ 3058 multiple return points make this a pain in the butt. */
3436 3059
3437 #ifdef DOS_NT
3438 int buffer_file_type
3439 = NILP (current_buffer->buffer_file_type) ? O_TEXT : O_BINARY;
3440 #endif /* DOS_NT */
3441
3442 #ifdef FILE_CODING 3060 #ifdef FILE_CODING
3443 codesys = Fget_coding_system (codesys); 3061 codesys = Fget_coding_system (codesys);
3444 #endif /* MULE */ 3062 #endif /* MULE */
3445 3063
3446 if (current_buffer->base_buffer && ! NILP (visit)) 3064 if (current_buffer->base_buffer && ! NILP (visit))
3520 } 3138 }
3521 3139
3522 fn = filename; 3140 fn = filename;
3523 desc = -1; 3141 desc = -1;
3524 if (!NILP (append)) 3142 if (!NILP (append))
3525 #ifdef DOS_NT 3143 {
3526 desc = open ((char *) XSTRING_DATA (fn), 3144 desc = open ((char *) XSTRING_DATA (fn), O_WRONLY | OPEN_BINARY, 0);
3527 (O_WRONLY | buffer_file_type), 0); 3145 }
3528 #else /* not DOS_NT */
3529 desc = open ((char *) XSTRING_DATA (fn), O_WRONLY | OPEN_BINARY, 0);
3530 #endif /* not DOS_NT */
3531
3532 if (desc < 0) 3146 if (desc < 0)
3533 { 3147 {
3534 #ifdef DOS_NT
3535 desc = open ((char *) XSTRING_DATA (fn),
3536 (O_WRONLY | O_TRUNC | O_CREAT | buffer_file_type),
3537 (S_IREAD | S_IWRITE));
3538 #else /* not DOS_NT */
3539 desc = open ((char *) XSTRING_DATA (fn), 3148 desc = open ((char *) XSTRING_DATA (fn),
3540 (O_WRONLY | O_TRUNC | O_CREAT | OPEN_BINARY), 3149 (O_WRONLY | O_TRUNC | O_CREAT | OPEN_BINARY),
3541 ((auto_saving) ? auto_save_mode_bits : CREAT_MODE)); 3150 ((auto_saving) ? auto_save_mode_bits : CREAT_MODE));
3542 #endif /* DOS_NT */
3543 } 3151 }
3544 3152
3545 if (desc < 0) 3153 if (desc < 0)
3546 { 3154 {
3547 #ifdef CLASH_DETECTION 3155 #ifdef CLASH_DETECTION
4284 /* Open the auto-save list file, if necessary. 3892 /* Open the auto-save list file, if necessary.
4285 We only do this now so that the file only exists 3893 We only do this now so that the file only exists
4286 if we actually auto-saved any files. */ 3894 if we actually auto-saved any files. */
4287 if (!auto_saved && GC_STRINGP (listfile) && listdesc < 0) 3895 if (!auto_saved && GC_STRINGP (listfile) && listdesc < 0)
4288 { 3896 {
4289 #ifdef DOS_NT
4290 listdesc = open ((char *) XSTRING_DATA (listfile),
4291 O_WRONLY | O_TRUNC | O_CREAT | O_BINARY,
4292 S_IREAD | S_IWRITE);
4293 #else /* not DOS_NT */
4294 listdesc = open ((char *) XSTRING_DATA (listfile), 3897 listdesc = open ((char *) XSTRING_DATA (listfile),
4295 O_WRONLY | O_TRUNC | O_CREAT | OPEN_BINARY, 3898 O_WRONLY | O_TRUNC | O_CREAT | OPEN_BINARY,
4296 CREAT_MODE); 3899 CREAT_MODE);
4297 #endif /* not DOS_NT */
4298 3900
4299 /* Arrange to close that file whether or not we get 3901 /* Arrange to close that file whether or not we get
4300 an error. */ 3902 an error. */
4301 if (listdesc >= 0) 3903 if (listdesc >= 0)
4302 record_unwind_protect (do_auto_save_unwind, 3904 record_unwind_protect (do_auto_save_unwind,
4463 defsymbol (&Qfile_newer_than_file_p, "file-newer-than-file-p"); 4065 defsymbol (&Qfile_newer_than_file_p, "file-newer-than-file-p");
4464 defsymbol (&Qinsert_file_contents, "insert-file-contents"); 4066 defsymbol (&Qinsert_file_contents, "insert-file-contents");
4465 defsymbol (&Qwrite_region, "write-region"); 4067 defsymbol (&Qwrite_region, "write-region");
4466 defsymbol (&Qverify_visited_file_modtime, "verify-visited-file-modtime"); 4068 defsymbol (&Qverify_visited_file_modtime, "verify-visited-file-modtime");
4467 defsymbol (&Qset_visited_file_modtime, "set-visited-file-modtime"); 4069 defsymbol (&Qset_visited_file_modtime, "set-visited-file-modtime");
4468 #ifdef DOS_NT
4469 defsymbol (&Qfind_buffer_file_type, "find-buffer-file-type");
4470 #endif /* DOS_NT */
4471 defsymbol (&Qcar_less_than_car, "car-less-than-car"); /* Vomitous! */ 4070 defsymbol (&Qcar_less_than_car, "car-less-than-car"); /* Vomitous! */
4472 4071
4473 defsymbol (&Qfile_name_handler_alist, "file-name-handler-alist"); 4072 defsymbol (&Qfile_name_handler_alist, "file-name-handler-alist");
4474 defsymbol (&Qauto_save_hook, "auto-save-hook"); 4073 defsymbol (&Qauto_save_hook, "auto-save-hook");
4475 defsymbol (&Qauto_save_error, "auto-save-error"); 4074 defsymbol (&Qauto_save_error, "auto-save-error");
4627 This variable affects the built-in functions only on Windows, 4226 This variable affects the built-in functions only on Windows,
4628 on other platforms, it is initialized so that Lisp code can find out 4227 on other platforms, it is initialized so that Lisp code can find out
4629 what the normal separator is. 4228 what the normal separator is.
4630 */ ); 4229 */ );
4631 Vdirectory_sep_char = make_char('/'); 4230 Vdirectory_sep_char = make_char('/');
4632 4231 }
4633 #ifdef DOS_NT
4634 DEFVAR_LISP ("insert-file-contents-allow-replace", &Vinsert_file_contents_allow_replace /*
4635 *Allow REPLACE option of insert-file-contents to preserve markers.
4636 If non-nil, the REPLACE option works as described, preserving markers.
4637 If nil, the REPLACE option is implemented by deleting the visible region
4638 then inserting the file contents as if REPLACE was nil.
4639
4640 This option is only meaningful on Windows.
4641 */ );
4642 Vinsert_file_contents_allow_replace = Qt;
4643 #endif
4644 }