/* File IO for GNU Emacs.
- Copyright (C) 1985,86,87,88,93,94,95,96 Free Software Foundation, Inc.
+ Copyright (C) 1985,86,87,88,93,94,95,96,1997 Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include <fcntl.h>
#endif
+#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
extern int minibuf_level;
+extern int minibuffer_auto_raise;
+
/* These variables describe handlers that have "already" had a chance
to handle the current operation.
}
DEFUN ("file-directory-p", Ffile_directory_p, Sfile_directory_p, 1, 1, 0,
- "Return t if file FILENAME is the name of a directory as a file.\n\
-A directory name spec may be given instead; then the value is t\n\
-if the directory so specified exists and really is a directory.")
+ "Return t if FILENAME names an existing directory.")
(filename)
Lisp_Object filename;
{
When REPLACE is non-nil, the value is the number of characters actually read,\n\
which is often less than the number of characters to be read.\n\
This does code conversion according to the value of\n\
- `coding-system-for-read' or `coding-system-alist', and sets the variable\n\
- `last-coding-system-used' to the coding system actually used.")
+ `coding-system-for-read' or `file-coding-system-alist',\n\
+ and sets the variable `last-coding-system-used' to the coding system\n\
+ actually used.")
(filename, visit, beg, end, replace)
Lisp_Object filename, visit, beg, end, replace;
{
/* Decide the coding-system of the file. */
{
- Lisp_Object val = Vcoding_system_for_read;
- if (NILP (current_buffer->enable_multibyte_characters))
- val = Qnil;
- else if (NILP (val))
+ Lisp_Object val;
+
+ if (!NILP (Vcoding_system_for_read))
+ val = Vcoding_system_for_read;
+ else if (NILP (current_buffer->enable_multibyte_characters))
+ val = Qemacs_mule;
+ else
{
Lisp_Object args[6], coding_systems;
args[0] = Qinsert_file_contents, args[1] = filename, args[2] = visit,
args[3] = beg, args[4] = end, args[5] = replace;
- coding_systems = Ffind_coding_system (6, args);
+ coding_systems = Ffind_operation_coding_system (6, args);
val = CONSP (coding_systems) ? XCONS (coding_systems)->car : Qnil;
}
setup_coding_system (Fcheck_coding_system (val), &coding);
}
+#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.type == coding_type_no_conversion)
+ current_buffer->buffer_file_type = Qt;
+ else
+ current_buffer->buffer_file_type = Qnil;
+#endif
+
fd = -1;
#ifndef APOLLO
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_CONVERSION (&coding)
- || (coding.type == coding_type_automatic
- && ! CODING_REQUIRE_EOL_CONVERSION (&coding))
- || (coding.eol_type == CODING_EOL_AUTOMATIC
- && ! CODING_REQUIRE_TEXT_CONVERSION (&coding))))
+ && CODING_MAY_REQUIRE_NO_CONVERSION (&coding))
{
int same_at_start = BEGV;
int same_at_end = ZV;
else if (nread == 0)
break;
- if (coding.type == coding_type_automatic)
+ if (coding.type == coding_type_undecided)
detect_coding (&coding, buffer, nread);
- if (CODING_REQUIRE_TEXT_CONVERSION (&coding))
+ if (coding.type != coding_type_undecided
+ && coding.type != coding_type_no_conversion
+ && coding.type != coding_type_emacs_mule)
/* We found that the file should be decoded somehow.
Let's give up here. */
{
break;
}
- if (coding.eol_type == CODING_EOL_AUTOMATIC)
+ if (coding.eol_type == CODING_EOL_UNDECIDED)
detect_eol (&coding, buffer, nread);
- if (CODING_REQUIRE_EOL_CONVERSION (&coding))
+ if (coding.eol_type != CODING_EOL_UNDECIDED
+ && coding.eol_type != CODING_EOL_LF)
/* We found that the format of eol should be decoded.
Let's give up here. */
{
we cannot use this method; giveup and try the other. */
if (same_at_end > same_at_start
&& FETCH_BYTE (same_at_end - 1) >= 0200
- && ! NILP (current_buffer->enable_multibyte_characters))
+ && ! NILP (current_buffer->enable_multibyte_characters)
+ && ! CODING_REQUIRE_NO_CONVERSION (&coding))
giveup_match_end = 1;
break;
}
{
/* We win! We can handle REPLACE the optimized way. */
+ /* Extends the end of non-matching text area to multibyte
+ character boundary. */
+ if (! NILP (current_buffer->enable_multibyte_characters))
+ while (same_at_end < ZV && ! CHAR_HEAD_P (POS_ADDR (same_at_end)))
+ same_at_end++;
+
/* Don't try to reuse the same piece of text twice. */
overlap = same_at_start - BEGV - (same_at_end + st.st_size - ZV);
if (overlap > 0)
how_much += this;
- if (CODING_REQUIRE_CONVERSION (&coding))
+ if (! CODING_REQUIRE_NO_CONVERSION (&coding))
{
int require, produced, consumed;
if (inserted + require + 2 * (total - how_much) > bufsize)
{
bufsize = inserted + require + 2 * (total - how_much);
- conversion_buffer = (unsigned char *) realloc (conversion_buffer, bufsize);
+ conversion_buffer = (unsigned char *) xrealloc (conversion_buffer, bufsize);
}
/* Convert this batch with results in CONVERSION_BUFFER. */
total = READ_BUF_SIZE;
if (NILP (visit) && total > 0)
- prepare_to_modify_buffer (PT, PT);
+ prepare_to_modify_buffer (PT, PT, NULL);
move_gap (PT);
if (GAP_SIZE < total)
{
/* try is reserved in some compilers (Microsoft C) */
int trytry = min (total - how_much, READ_BUF_SIZE - unprocessed);
- char *destination = (CODING_REQUIRE_CONVERSION (&coding)
- ? read_buf + unprocessed
- : (char *) (POS_ADDR (PT + inserted - 1) + 1));
+ char *destination = (CODING_REQUIRE_NO_CONVERSION (&coding)
+ ? (char *) (POS_ADDR (PT + inserted - 1) + 1)
+ : read_buf + unprocessed);
int this;
/* Allow quitting out of the actual I/O. */
if (! not_regular)
how_much += this;
- if (CODING_REQUIRE_CONVERSION (&coding))
+ if (! CODING_REQUIRE_NO_CONVERSION (&coding))
{
int require, produced, consumed;
}
\f
static Lisp_Object build_annotations ();
+extern Lisp_Object Ffile_locked_p ();
/* If build_annotations switched buffers, switch back to BUF.
Kill the temporary buffer that was selected in the meantime.
return Qnil;
}
-DEFUN ("write-region", Fwrite_region, Swrite_region, 3, 7,
- "r\nFWrite region to file: \ni\ni\ni\nZCoding system: ",
+DEFUN ("write-region", Fwrite_region, Swrite_region, 3, 6,
+ "r\nFWrite region to file: ",
"Write current region into specified file.\n\
When called from a program, takes three arguments:\n\
START, END and FILENAME. START and END are buffer positions.\n\
that means do not print the \"Wrote file\" message.\n\
The optional sixth arg LOCKNAME, if non-nil, specifies the name to\n\
use for locking and unlocking, overriding FILENAME and VISIT.\n\
-The optional seventh arg CODING-SYSTEM, if non-nil, specifies the coding\n\
- system to be used for encoding characters. For interactive use,\n\
- you can specify it by giving a prefix argument. If no coding system\n\
- is specified, the current region is encoded according to the value of\n\
- `coding-system-for-write' or `coding-system-alist'. The variable\n\
- `last-coding-system-used' is set the coding system actually used.\n\
Kludgy feature: if START is a string, then that string is written\n\
to the file, instead of any buffer contents, and END is ignored.")
- (start, end, filename, append, visit, lockname, coding_system_symbol)
+ (start, end, filename, append, visit, lockname)
Lisp_Object start, end, filename, append, visit, lockname;
- Lisp_Object coding_system_symbol;
{
register int desc;
int failure;
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
struct buffer *given_buffer;
#ifdef DOS_NT
- int buffer_file_type
- = NILP (current_buffer->buffer_file_type) ? O_TEXT : O_BINARY;
+ int buffer_file_type = O_BINARY;
#endif /* DOS_NT */
struct coding_system coding;
if (!NILP (start) && !STRINGP (start))
validate_region (&start, &end);
- GCPRO5 (start, filename, visit, lockname, coding_system_symbol);
+ GCPRO4 (start, filename, visit, lockname);
/* Decide the coding-system to be encoded to. */
{
Lisp_Object val;
- if (auto_saving || NILP (current_buffer->enable_multibyte_characters))
+ if (auto_saving)
val = Qnil;
- else if (!NILP (coding_system_symbol))
- val = coding_system_symbol;
else if (!NILP (Vcoding_system_for_write))
val = Vcoding_system_for_write;
- else if (!NILP (Flocal_variable_if_set_p (Qbuffer_file_coding_system,
- Qnil)))
- val = Fsymbol_value (Qbuffer_file_coding_system);
+ else if (NILP (current_buffer->enable_multibyte_characters))
+ val = (NILP (Flocal_variable_p (Qbuffer_file_coding_system, Qnil))
+ ? Qnil
+ : Fsymbol_value (Qbuffer_file_coding_system));
else
{
Lisp_Object args[7], coding_systems;
args[0] = Qwrite_region, args[1] = start, args[2] = end,
args[3] = filename, args[4] = append, args[5] = visit,
args[6] = lockname;
- coding_systems = Ffind_coding_system (7, args);
- val = (CONSP (coding_systems)
+ coding_systems = Ffind_operation_coding_system (7, args);
+ val = (CONSP (coding_systems) && !NILP (XCONS (coding_systems)->cdr)
? XCONS (coding_systems)->cdr
- : Fsymbol_value (Qbuffer_file_coding_system));
+ : current_buffer->buffer_file_coding_system);
}
setup_coding_system (Fcheck_coding_system (val), &coding);
if (!STRINGP (start) && !NILP (current_buffer->selective_display))
coding.selective = 1;
-#ifdef DOS_NT
- if (!NILP (current_buffer->buffer_file_type))
- coding.eol_type = CODING_EOL_LF;
-#endif /* DOS_NT */
}
filename = Fexpand_file_name (filename, Qnil);
annotations = build_annotations (start, end, coding.pre_write_conversion);
if (current_buffer != given_buffer)
{
- start = BEGV;
- end = ZV;
+ XSETFASTINT (start, BEGV);
+ XSETFASTINT (end, ZV);
}
#ifdef CLASH_DETECTION
/* If we've locked this file for some other buffer,
query before proceeding. */
if (!visiting && EQ (Ffile_locked_p (lockname), Qt))
- call2 (intern ("ask-user-about-lock"), fn, Vuser_login_name);
+ call2 (intern ("ask-user-about-lock"), filename, Vuser_login_name);
lock_file (lockname);
}
save_errno = errno;
}
- if (coding.require_flushing)
+ if (coding.require_flushing && !coding.last_block)
{
/* We have to flush out a data. */
coding.last_block = 1;
been dealt with by this function. */
if (current_buffer != given_buffer)
{
- start = BEGV;
- end = ZV;
+ XSETFASTINT (start, BEGV);
+ XSETFASTINT (end, ZV);
annotations = Qnil;
}
Flength (res); /* Check basic validity of return value */
original_buffer);
if (current_buffer != given_buffer)
{
- start = BEGV;
- end = ZV;
+ XSETFASTINT (start, BEGV);
+ XSETFASTINT (end, ZV);
annotations = Qnil;
}
Flength (res);
return
Fwrite_region (Qnil, Qnil,
current_buffer->auto_save_file_name,
- Qnil, Qlambda, Qnil, Qnil);
+ Qnil, Qlambda, Qnil);
}
static Lisp_Object
-do_auto_save_unwind (desc) /* used as unwind-protect function */
- Lisp_Object desc;
+do_auto_save_unwind (stream) /* used as unwind-protect function */
+ Lisp_Object stream;
{
auto_saving = 0;
- if (XINT (desc) >= 0)
- close (XINT (desc));
+ if (!NILP (stream))
+ fclose ((FILE *) (XFASTINT (XCONS (stream)->car) << 16
+ | XFASTINT (XCONS (stream)->cdr)));
+ return Qnil;
+}
+
+static Lisp_Object
+do_auto_save_unwind_1 (value) /* used as unwind-protect function */
+ Lisp_Object value;
+{
+ minibuffer_auto_raise = XINT (value);
return Qnil;
}
int omessage_length = echo_area_glyphs_length;
int do_handled_files;
Lisp_Object oquit;
- int listdesc;
+ FILE *stream;
+ Lisp_Object lispstream;
int count = specpdl_ptr - specpdl;
int *ptr;
+ int orig_minibuffer_auto_raise = minibuffer_auto_raise;
/* Ordinarily don't quit within this function,
but don't make it impossible to quit (in case we get hung in I/O). */
{
Lisp_Object listfile;
listfile = Fexpand_file_name (Vauto_save_list_file_name, Qnil);
-#ifdef DOS_NT
- listdesc = open (XSTRING (listfile)->data,
- O_WRONLY | O_TRUNC | O_CREAT | O_TEXT,
- S_IREAD | S_IWRITE);
-#else /* not DOS_NT */
- listdesc = creat (XSTRING (listfile)->data, 0666);
-#endif /* not DOS_NT */
+ stream = fopen (XSTRING (listfile)->data, "w");
+
+ /* Arrange to close that file whether or not we get an error.
+ Also reset auto_saving to 0. */
+ lispstream = Fcons (Qnil, Qnil);
+ XSETFASTINT (XCONS (lispstream)->car, (EMACS_UINT)stream >> 16);
+ XSETFASTINT (XCONS (lispstream)->cdr, (EMACS_UINT)stream & 0xffff);
}
else
- listdesc = -1;
-
- /* Arrange to close that file whether or not we get an error.
- Also reset auto_saving to 0. */
- record_unwind_protect (do_auto_save_unwind, make_number (listdesc));
+ {
+ stream = NULL;
+ lispstream = Qnil;
+ }
+ record_unwind_protect (do_auto_save_unwind, lispstream);
+ record_unwind_protect (do_auto_save_unwind_1,
+ make_number (minibuffer_auto_raise));
+ minibuffer_auto_raise = 0;
auto_saving = 1;
/* First, save all files which don't have handlers. If Emacs is
in the special file that lists them. For each of these buffers,
Record visited name (if any) and auto save name. */
if (STRINGP (b->auto_save_file_name)
- && listdesc >= 0 && do_handled_files == 0)
+ && stream != NULL && do_handled_files == 0)
{
if (!NILP (b->filename))
{
- write (listdesc, XSTRING (b->filename)->data,
- XSTRING (b->filename)->size);
+ fwrite (XSTRING (b->filename)->data, 1,
+ XSTRING (b->filename)->size, stream);
}
- write (listdesc, "\n", 1);
- write (listdesc, XSTRING (b->auto_save_file_name)->data,
- XSTRING (b->auto_save_file_name)->size);
- write (listdesc, "\n", 1);
+ putc ('\n', stream);
+ fwrite (XSTRING (b->auto_save_file_name)->data, 1,
+ XSTRING (b->auto_save_file_name)->size, stream);
+ putc ('\n', stream);
}
if (!NILP (current_only)
&& NILP (no_message))
{
/* It has shrunk too much; turn off auto-saving here. */
+ minibuffer_auto_raise = orig_minibuffer_auto_raise;
message ("Buffer %s has shrunk a lot; auto save turned off there",
XSTRING (b->name)->data);
+ minibuffer_auto_raise = 0;
/* Turn off auto-saving until there's a real save,
and prevent any more warnings. */
XSETINT (b->save_length, -1);
{
if (omessage)
{
- sit_for (1, 0, 0, 0);
+ sit_for (1, 0, 0, 0, 0);
message2 (omessage, omessage_length);
}
else
else if (STRINGP (initial))
{
insdef = initial;
- insdef1 = Fcons (double_dollars (insdef), 0);
+ insdef1 = Fcons (double_dollars (insdef), make_number (0));
}
else
insdef = Qnil, insdef1 = Qnil;
val = Fcompleting_read (prompt, intern ("read-file-name-internal"),
dir, mustmatch, insdef1,
Qfile_name_history, default_filename);
+ /* If Fcompleting_read returned the default string itself
+ (rather than a new string with the same contents),
+ it has to mean that the user typed RET with the minibuffer empty.
+ In that case, we really want to return ""
+ so that commands such as set-visited-file-name can distinguish. */
+ if (EQ (val, default_filename))
+ val = build_string ("");
#ifdef VMS
unbind_to (count, Qnil);
This variable affects the built-in functions only on Windows,\n\
on other platforms, it is initialized so that Lisp code can find out\n\
what the normal separator is.");
- Vdirectory_sep_char = '/';
+ XSETFASTINT (Vdirectory_sep_char, '/');
DEFVAR_LISP ("file-name-handler-alist", &Vfile_name_handler_alist,
"*Alist of elements (REGEXP . HANDLER) for file names handled specially.\n\