/* 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_undecided
- && ! CODING_REQUIRE_EOL_CONVERSION (&coding))
- || (coding.eol_type == CODING_EOL_UNDECIDED
- && ! CODING_REQUIRE_TEXT_CONVERSION (&coding))))
+ && CODING_MAY_REQUIRE_NO_CONVERSION (&coding))
{
int same_at_start = BEGV;
int same_at_end = ZV;
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. */
{
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;
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.
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;
{
Lisp_Object val;
- if (auto_saving || NILP (current_buffer->enable_multibyte_characters))
+ if (auto_saving)
val = Qnil;
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
: 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);
/* 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;
}
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);
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\