X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/f4ac86afc5b2297b76649cc2aad4df678ded8e3d..f5321b5c8a5fe2e79344f79f790283ae3a13c2a8:/src/fileio.c?ds=sidebyside diff --git a/src/fileio.c b/src/fileio.c index 59d587ae1d..aef7a01e0a 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -50,15 +50,6 @@ Boston, MA 02111-1307, USA. */ #include #endif -#ifdef MSDOS -#include "msdos.h" -#include -#if __DJGPP__ >= 2 -#include -#include -#endif -#endif - #include #ifdef VMS @@ -104,6 +95,15 @@ extern char *strerror (); #include #endif /* not WINDOWSNT */ +#ifdef MSDOS +#include "msdos.h" +#include +#if __DJGPP__ >= 2 +#include +#include +#endif +#endif + #ifdef DOS_NT #define CORRECT_DIR_SEPS(s) \ do { if ('/' == DIRECTORY_SEP) dostounix_filename (s); \ @@ -375,7 +375,7 @@ on VMS, perhaps instead a string ending in `:', `]' or `>'.") #ifdef DOS_NT beg = strcpy (alloca (strlen (beg) + 1), beg); #endif - p = beg + XSTRING (filename)->size_byte; + p = beg + STRING_BYTES (XSTRING (filename)); while (p != beg && !IS_DIRECTORY_SEP (p[-1]) #ifdef VMS @@ -432,7 +432,7 @@ or the entire name if it contains no slash.") return call2 (handler, Qfile_name_nondirectory, filename); beg = XSTRING (filename)->data; - end = p = beg + XSTRING (filename)->size_byte; + end = p = beg + STRING_BYTES (XSTRING (filename)); while (p != beg && !IS_DIRECTORY_SEP (p[-1]) #ifdef VMS @@ -484,8 +484,9 @@ file_name_as_directory (out, in) if (size < 0) { - out[0] = '/'; - out[1] = 0; + out[0] = '.'; + out[1] = '/'; + out[2] = 0; return out; } @@ -585,7 +586,7 @@ On VMS, converts \"[X]FOO.DIR\" to \"[X.FOO]\", etc.") if (!NILP (handler)) return call2 (handler, Qfile_name_as_directory, file); - buf = (char *) alloca (XSTRING (file)->size_byte + 10); + buf = (char *) alloca (STRING_BYTES (XSTRING (file)) + 10); return build_string (file_name_as_directory (buf, XSTRING (file)->data)); } @@ -599,6 +600,7 @@ On VMS, converts \"[X]FOO.DIR\" to \"[X.FOO]\", etc.") * Value is nonzero if the string output is different from the input. */ +int directory_file_name (src, dst) char *src, *dst; { @@ -780,37 +782,126 @@ it returns a file name such as \"[X]Y.DIR.1\".") /* 20 extra chars is insufficient for VMS, since we might perform a logical name translation. an equivalence string can be up to 255 chars long, so grab that much extra space... - sss */ - buf = (char *) alloca (XSTRING (directory)->size_byte + 20 + 255); + buf = (char *) alloca (STRING_BYTES (XSTRING (directory)) + 20 + 255); #else - buf = (char *) alloca (XSTRING (directory)->size_byte + 20); + buf = (char *) alloca (STRING_BYTES (XSTRING (directory)) + 20); #endif directory_file_name (XSTRING (directory)->data, buf); return build_string (buf); } +static char make_temp_name_tbl[64] = +{ + 'A','B','C','D','E','F','G','H', + 'I','J','K','L','M','N','O','P', + 'Q','R','S','T','U','V','W','X', + 'Y','Z','a','b','c','d','e','f', + 'g','h','i','j','k','l','m','n', + 'o','p','q','r','s','t','u','v', + 'w','x','y','z','0','1','2','3', + '4','5','6','7','8','9','-','_' +}; +static unsigned make_temp_name_count, make_temp_name_count_initialized_p; + DEFUN ("make-temp-name", Fmake_temp_name, Smake_temp_name, 1, 1, 0, "Generate temporary file name (string) starting with PREFIX (a string).\n\ The Emacs process number forms part of the result,\n\ so there is no danger of generating a name being used by another process.\n\ +\n\ In addition, this function makes an attempt to choose a name\n\ -which has no existing file.") +which has no existing file. To make this work,\n\ +PREFIX should be an absolute file name.") (prefix) Lisp_Object prefix; { Lisp_Object val; -#ifdef MSDOS - /* Don't use too many characters of the restricted 8+3 DOS - filename space. */ - val = concat2 (prefix, build_string ("a.XXX")); + int len; + int pid; + unsigned char *p, *data; + char pidbuf[20]; + int pidlen; + + CHECK_STRING (prefix, 0); + + /* VAL is created by adding 6 characters to PREFIX. The first + three are the PID of this process, in base 64, and the second + three are incremented if the file already exists. This ensures + 262144 unique file names per PID per PREFIX. */ + + pid = (int) getpid (); + +#ifdef HAVE_LONG_FILE_NAMES + sprintf (pidbuf, "%d", pid); + pidlen = strlen (pidbuf); #else - val = concat2 (prefix, build_string ("XXXXXX")); + pidbuf[0] = make_temp_name_tbl[pid & 63], pid >>= 6; + pidbuf[1] = make_temp_name_tbl[pid & 63], pid >>= 6; + pidbuf[2] = make_temp_name_tbl[pid & 63], pid >>= 6; + pidlen = 3; #endif - mktemp (XSTRING (val)->data); -#ifdef DOS_NT - CORRECT_DIR_SEPS (XSTRING (val)->data); -#endif - return val; + + len = XSTRING (prefix)->size; + val = make_uninit_string (len + 3 + pidlen); + data = XSTRING (val)->data; + bcopy(XSTRING (prefix)->data, data, len); + p = data + len; + + bcopy (pidbuf, p, pidlen); + p += pidlen; + + /* Here we try to minimize useless stat'ing when this function is + invoked many times successively with the same PREFIX. We achieve + this by initializing count to a random value, and incrementing it + afterwards. + + We don't want make-temp-name to be called while dumping, + because then make_temp_name_count_initialized_p would get set + and then make_temp_name_count would not be set when Emacs starts. */ + + if (!make_temp_name_count_initialized_p) + { + make_temp_name_count = (unsigned) time (NULL); + make_temp_name_count_initialized_p = 1; + } + + while (1) + { + struct stat ignored; + unsigned num = make_temp_name_count; + + p[0] = make_temp_name_tbl[num & 63], num >>= 6; + p[1] = make_temp_name_tbl[num & 63], num >>= 6; + p[2] = make_temp_name_tbl[num & 63], num >>= 6; + + /* Poor man's congruential RN generator. Replace with + ++make_temp_name_count for debugging. */ + make_temp_name_count += 25229; + make_temp_name_count %= 225307; + + if (stat (data, &ignored) < 0) + { + /* We want to return only if errno is ENOENT. */ + if (errno == ENOENT) + return val; + else + /* The error here is dubious, but there is little else we + can do. The alternatives are to return nil, which is + as bad as (and in many cases worse than) throwing the + error, or to ignore the error, which will likely result + in looping through 225307 stat's, which is not only + dog-slow, but also useless since it will fallback to + the errow below, anyway. */ + report_file_error ("Cannot create temporary name for prefix `%s'", + Fcons (prefix, Qnil)); + /* not reached */ + } + } + + error ("Cannot create temporary name for prefix `%s'", + XSTRING (prefix)->data); + return Qnil; } + DEFUN ("expand-file-name", Fexpand_file_name, Sexpand_file_name, 1, 2, 0, "Convert filename NAME to absolute, and canonicalize it.\n\ @@ -844,6 +935,7 @@ See also the function `substitute-in-file-name'.") #ifdef DOS_NT int drive = 0; int collapse_newdir = 1; + int is_escaped = 0; #endif /* DOS_NT */ int length; Lisp_Object handler; @@ -887,7 +979,7 @@ See also the function `substitute-in-file-name'.") is needed at all) without requiring it to be expanded now. */ #ifdef DOS_NT /* Detect MSDOS file names with drive specifiers. */ - && ! (IS_DRIVE (o[0]) && (IS_DEVICE_SEP (o[1]) && IS_DIRECTORY_SEP (o[2]))) + && ! (IS_DRIVE (o[0]) && IS_DEVICE_SEP (o[1]) && IS_DIRECTORY_SEP (o[2])) #ifdef WINDOWSNT /* Detect Windows file names in UNC format. */ && ! (IS_DIRECTORY_SEP (o[0]) && IS_DIRECTORY_SEP (o[1])) @@ -921,33 +1013,21 @@ See also the function `substitute-in-file-name'.") a local copy to modify, even if there ends up being no change. */ nm = strcpy (alloca (strlen (nm) + 1), nm); + /* Note if special escape prefix is present, but remove for now. */ + if (nm[0] == '/' && nm[1] == ':') + { + is_escaped = 1; + nm += 2; + } + /* Find and remove drive specifier if present; this makes nm absolute - even if the rest of the name appears to be relative. */ - { - unsigned char *colon = rindex (nm, ':'); - - if (colon) - /* Only recognize colon as part of drive specifier if there is a - single alphabetic character preceeding the colon (and if the - character before the drive letter, if present, is a directory - separator); this is to support the remote system syntax used by - ange-ftp, and the "po:username" syntax for POP mailboxes. */ - look_again: - if (nm == colon) - nm++; - else if (IS_DRIVE (colon[-1]) - && (colon == nm + 1 || IS_DIRECTORY_SEP (colon[-2]))) - { - drive = colon[-1]; - nm = colon + 1; - } - else - { - while (--colon >= nm) - if (colon[0] == ':') - goto look_again; - } - } + even if the rest of the name appears to be relative. Only look for + drive specifier at the beginning. */ + if (IS_DRIVE (nm[0]) && IS_DEVICE_SEP (nm[1])) + { + drive = nm[0]; + nm += 2; + } #ifdef WINDOWSNT /* If we see "c://somedir", we want to strip the first slash after the @@ -972,10 +1052,10 @@ See also the function `substitute-in-file-name'.") if ( IS_DIRECTORY_SEP (nm[0]) #ifdef MSDOS - && drive + && drive && !is_escaped #endif #ifdef WINDOWSNT - && (drive || IS_DIRECTORY_SEP (nm[1])) + && (drive || IS_DIRECTORY_SEP (nm[1])) && !is_escaped #endif #ifdef VMS || index (nm, ':') @@ -1221,6 +1301,14 @@ See also the function `substitute-in-file-name'.") && !newdir) { newdir = XSTRING (default_directory)->data; +#ifdef DOS_NT + /* Note if special escape prefix is present, but remove for now. */ + if (newdir[0] == '/' && newdir[1] == ':') + { + is_escaped = 1; + newdir += 2; + } +#endif } #ifdef DOS_NT @@ -1296,9 +1384,9 @@ See also the function `substitute-in-file-name'.") if (newdir) { /* Get rid of any slash at the end of newdir, unless newdir is - just // (an incomplete UNC name). */ + just / or // (an incomplete UNC name). */ length = strlen (newdir); - if (length > 0 && IS_DIRECTORY_SEP (newdir[length - 1]) + if (length > 1 && IS_DIRECTORY_SEP (newdir[length - 1]) #ifdef WINDOWSNT && !(length == 2 && IS_DIRECTORY_SEP (newdir[0])) #endif @@ -1317,10 +1405,11 @@ See also the function `substitute-in-file-name'.") /* Now concatenate the directory and name to new space in the stack frame */ tlen += strlen (nm) + 1; #ifdef DOS_NT - /* Add reserved space for drive name. (The Microsoft x86 compiler + /* Reserve space for drive specifier and escape prefix, since either + or both may need to be inserted. (The Microsoft x86 compiler produces incorrect code if the following two lines are combined.) */ - target = (unsigned char *) alloca (tlen + 2); - target += 2; + target = (unsigned char *) alloca (tlen + 4); + target += 4; #else /* not DOS_NT */ target = (unsigned char *) alloca (tlen); #endif /* not DOS_NT */ @@ -1330,7 +1419,18 @@ See also the function `substitute-in-file-name'.") { #ifndef VMS if (nm[0] == 0 || IS_DIRECTORY_SEP (nm[0])) - strcpy (target, newdir); + { +#ifdef WINDOWSNT + /* If newdir is effectively "C:/", then the drive letter will have + been stripped and newdir will be "/". Concatenating with an + absolute directory in nm produces "//", which will then be + incorrectly treated as a network share. Ignore newdir in + this case (keeping the drive letter). */ + if (!(drive && nm[0] && IS_DIRECTORY_SEP (newdir[0]) + && newdir[1] == '\0')) +#endif + strcpy (target, newdir); + } else #endif file_name_as_directory (target, newdir); @@ -1439,6 +1539,13 @@ See also the function `substitute-in-file-name'.") target[0] = DRIVE_LETTER (drive); target[1] = ':'; } + /* Reinsert the escape prefix if required. */ + if (is_escaped) + { + target -= 2; + target[0] = '/'; + target[1] = ':'; + } CORRECT_DIR_SEPS (target); #endif /* DOS_NT */ @@ -1805,7 +1912,7 @@ duplicates what `expand-file-name' does.") CORRECT_DIR_SEPS (nm); substituted = (strcmp (nm, XSTRING (filename)->data) != 0); #endif - endp = nm + XSTRING (filename)->size_byte; + endp = nm + STRING_BYTES (XSTRING (filename)); /* If /~ or // appears, discard everything through first slash. */ @@ -1898,7 +2005,7 @@ duplicates what `expand-file-name' does.") /* If substitution required, recopy the string and do it */ /* Make space in stack frame for the new copy */ - xnm = (unsigned char *) alloca (XSTRING (filename)->size_byte + total + 1); + xnm = (unsigned char *) alloca (STRING_BYTES (XSTRING (filename)) + total + 1); x = xnm; /* Copy the rest of the name through, replacing $ constructs with values */ @@ -2017,7 +2124,7 @@ expand_and_dir_to_file (filename, defdir) absname = Fexpand_file_name (filename, defdir); #ifdef VMS { - register int c = XSTRING (absname)->data[XSTRING (absname)->size_byte - 1]; + register int c = XSTRING (absname)->data[STRING_BYTES (XSTRING (absname)) - 1]; if (c == ':' || c == ']' || c == '>') absname = Fdirectory_file_name (absname); } @@ -2025,8 +2132,8 @@ expand_and_dir_to_file (filename, defdir) /* Remove final slash, if any (unless this is the root dir). stat behaves differently depending! */ if (XSTRING (absname)->size > 1 - && IS_DIRECTORY_SEP (XSTRING (absname)->data[XSTRING (absname)->size_byte - 1]) - && !IS_DEVICE_SEP (XSTRING (absname)->data[XSTRING (absname)->size_byte-2])) + && IS_DIRECTORY_SEP (XSTRING (absname)->data[STRING_BYTES (XSTRING (absname)) - 1]) + && !IS_DEVICE_SEP (XSTRING (absname)->data[STRING_BYTES (XSTRING (absname))-2])) /* We cannot take shortcuts; they might be wrong for magic file names. */ absname = Fdirectory_file_name (absname); #endif @@ -2041,30 +2148,39 @@ expand_and_dir_to_file (filename, defdir) *STATPTR is used to store the stat information if the file exists. If the file does not exist, STATPTR->st_mode is set to 0. - If STATPTR is null, we don't store into it. */ + If STATPTR is null, we don't store into it. + + If QUICK is nonzero, we ask for y or n, not yes or no. */ void -barf_or_query_if_file_exists (absname, querystring, interactive, statptr) +barf_or_query_if_file_exists (absname, querystring, interactive, statptr, quick) Lisp_Object absname; unsigned char *querystring; int interactive; struct stat *statptr; + int quick; { - register Lisp_Object tem; + register Lisp_Object tem, encoded_filename; struct stat statbuf; struct gcpro gcpro1; + encoded_filename = ENCODE_FILE (absname); + /* stat is a good way to tell whether the file exists, regardless of what access permissions it has. */ - if (stat (XSTRING (absname)->data, &statbuf) >= 0) + if (stat (XSTRING (encoded_filename)->data, &statbuf) >= 0) { if (! interactive) Fsignal (Qfile_already_exists, Fcons (build_string ("File already exists"), Fcons (absname, Qnil))); GCPRO1 (absname); - tem = do_yes_or_no_p (format1 ("File %s already exists; %s anyway? ", - XSTRING (absname)->data, querystring)); + tem = format1 ("File %s already exists; %s anyway? ", + XSTRING (absname)->data, querystring); + if (quick) + tem = Fy_or_n_p (tem); + else + tem = do_yes_or_no_p (tem); UNGCPRO; if (NILP (tem)) Fsignal (Qfile_already_exists, @@ -2127,7 +2243,7 @@ A prefix arg makes KEEP-TIME non-nil.") if (NILP (ok_if_already_exists) || INTEGERP (ok_if_already_exists)) barf_or_query_if_file_exists (encoded_newname, "copy to it", - INTEGERP (ok_if_already_exists), &out_st); + INTEGERP (ok_if_already_exists), &out_st, 0); else if (stat (XSTRING (encoded_newname)->data, &out_st) < 0) out_st.st_mode = 0; @@ -2141,7 +2257,7 @@ A prefix arg makes KEEP-TIME non-nil.") copyable by us. */ input_file_statable_p = (fstat (ifd, &st) >= 0); -#if !defined (MSDOS) || __DJGPP__ > 1 +#if !defined (DOS_NT) || __DJGPP__ > 1 if (out_st.st_mode != 0 && st.st_dev == out_st.st_dev && st.st_ino == out_st.st_ino) { @@ -2365,7 +2481,7 @@ This is what happens in interactive use with M-x.") if (NILP (ok_if_already_exists) || INTEGERP (ok_if_already_exists)) barf_or_query_if_file_exists (encoded_newname, "rename to it", - INTEGERP (ok_if_already_exists), 0); + INTEGERP (ok_if_already_exists), 0, 0); #ifndef BSD4_1 if (0 > rename (XSTRING (encoded_file)->data, XSTRING (encoded_newname)->data)) #else @@ -2440,7 +2556,7 @@ This is what happens in interactive use with M-x.") if (NILP (ok_if_already_exists) || INTEGERP (ok_if_already_exists)) barf_or_query_if_file_exists (encoded_newname, "make it a new name", - INTEGERP (ok_if_already_exists), 0); + INTEGERP (ok_if_already_exists), 0, 0); unlink (XSTRING (newname)->data); if (0 > link (XSTRING (encoded_file)->data, XSTRING (encoded_newname)->data)) @@ -2507,7 +2623,7 @@ This happens for interactive use with M-x.") if (NILP (ok_if_already_exists) || INTEGERP (ok_if_already_exists)) barf_or_query_if_file_exists (encoded_linkname, "make it a link", - INTEGERP (ok_if_already_exists), 0); + INTEGERP (ok_if_already_exists), 0, 0); if (0 > symlink (XSTRING (encoded_filename)->data, XSTRING (encoded_linkname)->data)) { @@ -3154,7 +3270,7 @@ This does code conversion according to the value of\n\ Lisp_Object p; int total; int not_regular = 0; - char read_buf[READ_BUF_SIZE]; + unsigned char read_buf[READ_BUF_SIZE]; struct coding_system coding; unsigned char buffer[1 << 14]; int replace_handled = 0; @@ -3263,25 +3379,39 @@ This does code conversion according to the value of\n\ /* Decide the coding-system of the file. */ { - Lisp_Object val = Qnil; + Lisp_Object val; + val = Qnil; if (!NILP (Vcoding_system_for_read)) val = Vcoding_system_for_read; - else + else if (! NILP (replace)) + /* In REPLACE mode, we can use the same coding system + that was used to visit the file. */ + val = current_buffer->buffer_file_coding_system; + else if (! not_regular) { + /* Don't try looking inside a file for a coding system specification + if it is not seekable. */ if (! NILP (Vset_auto_coding_function)) { /* Find a coding system specified in the heading two lines or in the tailing several lines of the file. We assume that the 1K-byte and 3K-byte for heading and tailing respectively are sufficient fot this purpose. */ - int how_many, nread; + int nread; + int beginning_of_end, end_of_beginning; if (st.st_size <= (1024 * 4)) - nread = read (fd, read_buf, 1024 * 4); + { + nread = read (fd, read_buf, 1024 * 4); + end_of_beginning = nread; + beginning_of_end = 0; + } else { nread = read (fd, read_buf, 1024); + end_of_beginning = nread; + beginning_of_end = nread; if (nread >= 0) { if (lseek (fd, st.st_size - (1024 * 3), 0) < 0) @@ -3290,17 +3420,83 @@ This does code conversion according to the value of\n\ nread += read (fd, read_buf + nread, 1024 * 3); } } - + if (nread < 0) error ("IO error reading %s: %s", XSTRING (orig_filename)->data, strerror (errno)); else if (nread > 0) { + int i; + int possible_spec = 0; + unsigned char *p, *p1; Lisp_Object tem; - /* Always make this a unibyte string - because we have not yet decoded it. */ - tem = make_unibyte_string (read_buf, nread); - val = call1 (Vset_auto_coding_function, tem); + unsigned char *copy = (unsigned char *) alloca (nread + 1); + + /* Make a copy of the contents of read_buf in COPY, + and convert it to lower case so we can compare + more efficiently. */ + bcopy (read_buf, copy, nread); + for (i = 0; i < nread; i++) + copy[i] = DOWNCASE (copy[i]); + /* Ensure various comparisons fail at end of data. */ + copy[nread] = 0; + + /* Now test quickly whether the file contains a -*- line. */ + p = copy; + while (*p != '\n' && p - copy < end_of_beginning) + p++; + if (copy[0] == '#' && copy[1] == '!') + while (*p != '\n' && p - copy < end_of_beginning) + p++; + p1 = copy; + while (p - p1 >= 3) + { + if (p1[0] == '-' && p1[1] == '*' && p1[2] == '-') + { + while (p - p1 >= 7) + { + if (! bcmp ("coding:", p1, 7)) + { + possible_spec = 1; + goto win; + } + p1++; + } + break; + } + p1++; + } + + /* Test quickly whether the file + contains a local variables list. */ + p = ©[nread - 1]; + p1 = ©[beginning_of_end]; + while (p > p1) + { + if (p[0] == '\n' && p[1] == '\f') + break; + p--; + } + p1 = ©[nread]; + while (p1 - p >= 16) + { + if (! bcmp ("local variables:", p, 16)) + { + possible_spec = 1; + break; + } + p++; + } + win: + + if (possible_spec) + { + /* Always make this a unibyte string + because we have not yet decoded it. */ + tem = make_unibyte_string (read_buf, nread); + val = call1 (Vset_auto_coding_function, tem); + } + /* Rewind the file for the actual read done later. */ if (lseek (fd, 0, 0) < 0) report_file_error ("Setting file position", @@ -3311,10 +3507,11 @@ This does code conversion according to the value of\n\ { Lisp_Object args[6], coding_systems; - args[0] = Qinsert_file_contents, args[1] = orig_filename, - args[2] = visit, args[3] = beg, args[4] = end, args[5] = replace; + args[0] = Qinsert_file_contents, args[1] = orig_filename; + args[2] = visit, args[3] = beg, args[4] = end, args[5] = replace; coding_systems = Ffind_operation_coding_system (6, args); - if (CONSP (coding_systems)) val = XCONS (coding_systems)->car; + if (CONSP (coding_systems)) + val = XCONS (coding_systems)->car; } } @@ -3348,7 +3545,9 @@ This does code conversion according to the value of\n\ But if we discover the need for conversion, we give up on this method and let the following if-statement handle the replace job. */ if (!NILP (replace) - && ! CODING_REQUIRE_DECODING (&coding)) + && ! CODING_REQUIRE_DECODING (&coding) + && (coding.eol_type == CODING_EOL_UNDECIDED + || coding.eol_type == CODING_EOL_LF)) { /* same_at_start and same_at_end count bytes, because file access counts bytes @@ -3664,7 +3863,14 @@ This does code conversion according to the value of\n\ we are taking from the file. */ inserted -= (Z_BYTE - same_at_end) + (same_at_start - BEG_BYTE); del_range_byte (same_at_start, same_at_end, 0); - SET_PT_BOTH (GPT, GPT_BYTE); + if (same_at_end != same_at_start) + SET_PT_BOTH (GPT, GPT_BYTE); + else + { + /* Insert from the file at the proper position. */ + temp = BYTE_TO_CHAR (same_at_start); + SET_PT_BOTH (temp, same_at_start); + } insert_1 (conversion_buffer + same_at_start - BEG_BYTE, inserted, 0, 0, 0); @@ -3786,30 +3992,26 @@ This does code conversion according to the value of\n\ /* There's a possibility that we must combine bytes at the head (resp. the tail) of the just inserted text with the bytes before (resp. after) the gap to form a single - character. Thus, we, at first, rewind the adjusted - character positions (GPT, ZV, Z), then adjust them again. */ - GAP_SIZE += inserted; - GPT_BYTE -= inserted; - ZV_BYTE -= inserted; - Z_BYTE -= inserted; - GPT -= inserted; - ZV -= inserted; - Z -= inserted; - - inserted = multibyte_chars_in_text (GPT_ADDR, inserted); - adjust_after_replace (PT, PT_BYTE, PT, PT_BYTE, - inserted, inserted_byte, 0); + character. */ + inserted = multibyte_chars_in_text (GPT_ADDR - inserted, inserted); + adjust_after_insert (PT, PT_BYTE, + PT + inserted_byte, PT_BYTE + inserted_byte, + inserted); } + else + adjust_after_insert (PT, PT_BYTE, PT + inserted, PT_BYTE + inserted, + inserted); #ifdef DOS_NT /* Use the conversion type to determine buffer-file-type (find-buffer-file-type is now used to help determine the conversion). */ - if (coding.eol_type != CODING_EOL_UNDECIDED - && coding.eol_type != CODING_EOL_LF) - current_buffer->buffer_file_type = Qnil; - else + if ((coding.eol_type == CODING_EOL_UNDECIDED + || coding.eol_type == CODING_EOL_LF) + && ! CODING_REQUIRE_DECODING (&coding)) current_buffer->buffer_file_type = Qt; + else + current_buffer->buffer_file_type = Qnil; #endif } @@ -4023,7 +4225,7 @@ to the file, instead of any buffer contents, and END is ignored.") ? XCONS (coding_systems)->cdr : current_buffer->buffer_file_coding_system); /* Confirm that VAL can surely encode the current region. */ - if (Ffboundp (Vselect_safe_coding_system_function)) + if (!NILP (Ffboundp (Vselect_safe_coding_system_function))) val = call3 (Vselect_safe_coding_system_function, start, end, val); } setup_coding_system (Fcheck_coding_system (val), &coding); @@ -4038,7 +4240,7 @@ to the file, instead of any buffer contents, and END is ignored.") filename = Fexpand_file_name (filename, Qnil); if (! NILP (confirm)) - barf_or_query_if_file_exists (filename, "overwrite", 1, 0); + barf_or_query_if_file_exists (filename, "overwrite", 1, 0, 1); if (STRINGP (visit)) visit_file = Fexpand_file_name (visit, Qnil); @@ -4240,7 +4442,7 @@ to the file, instead of any buffer contents, and END is ignored.") if (STRINGP (start)) { failure = 0 > a_write (desc, XSTRING (start)->data, - XSTRING (start)->size_byte, 0, &annotations, + STRING_BYTES (XSTRING (start)), 0, &annotations, &coding); save_errno = errno; } @@ -4510,12 +4712,13 @@ a_write (desc, addr, nbytes, bytepos, annot, coding) tem = Fcdr (Fcar (*annot)); if (STRINGP (tem)) { - if (0 > e_write (desc, XSTRING (tem)->data, XSTRING (tem)->size_byte, + if (0 > e_write (desc, XSTRING (tem)->data, STRING_BYTES (XSTRING (tem)), coding)) return -1; } *annot = Fcdr (*annot); } + return 0; } #ifndef WRITE_BUF_SIZE @@ -4793,11 +4996,11 @@ A non-nil CURRENT-ONLY argument means save only current buffer.") if (!NILP (b->filename)) { fwrite (XSTRING (b->filename)->data, 1, - XSTRING (b->filename)->size_byte, stream); + STRING_BYTES (XSTRING (b->filename)), stream); } putc ('\n', stream); fwrite (XSTRING (b->auto_save_file_name)->data, 1, - XSTRING (b->auto_save_file_name)->size_byte, stream); + STRING_BYTES (XSTRING (b->auto_save_file_name)), stream); putc ('\n', stream); } @@ -4931,7 +5134,7 @@ double_dollars (val) register int n; int osize, count; - osize = XSTRING (val)->size_byte; + osize = STRING_BYTES (XSTRING (val)); /* Count the number of $ characters. */ for (n = osize, count = 0, old = XSTRING (val)->data; n > 0; n--) @@ -5072,7 +5275,7 @@ DIR defaults to current buffer's directory default.") && IS_DIRECTORY_SEP (XSTRING (dir)->data[strlen (homedir)])) { dir = make_string (XSTRING (dir)->data + strlen (homedir) - 1, - XSTRING (dir)->size_byte - strlen (homedir) + 1); + STRING_BYTES (XSTRING (dir)) - strlen (homedir) + 1); XSTRING (dir)->data[0] = '~'; } @@ -5166,6 +5369,7 @@ DIR defaults to current buffer's directory default.") return val; } +void syms_of_fileio () { Qexpand_file_name = intern ("expand-file-name");