{
#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);
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;
/* 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)
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",
{
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;
}
}
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
/* 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
}