Allow floating-point file offsets.
Problem reported by Vitalie Spinu in <http://lists.gnu.org/archive/html/emacs-devel/2013-01/msg00411.html>. * doc/lispref/files.texi (Reading from Files, Writing to Files): Say that file offsets can be numbers, not just integers. * src/fileio.c (emacs_lseek): Remove. (file_offset): New function. (Finsert_file_contents, Fwrite_region): Use it.
This commit is contained in:
parent
73c1421878
commit
b3fbb3956c
4 changed files with 47 additions and 37 deletions
|
@ -1,3 +1,9 @@
|
|||
2013-01-19 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
Allow floating-point file offsets.
|
||||
* files.texi (Reading from Files, Writing to Files):
|
||||
Say that file offsets can be numbers, not just integers.
|
||||
|
||||
2013-01-09 Glenn Morris <rgm@gnu.org>
|
||||
|
||||
* commands.texi (Interactive Codes):
|
||||
|
|
|
@ -533,9 +533,9 @@ is visiting the file @var{filename}: these include the buffer's visited
|
|||
file name and its last save file modtime. This feature is used by
|
||||
@code{find-file-noselect} and you probably should not use it yourself.
|
||||
|
||||
If @var{beg} and @var{end} are non-@code{nil}, they should be integers
|
||||
specifying the portion of the file to insert. In this case, @var{visit}
|
||||
must be @code{nil}. For example,
|
||||
If @var{beg} and @var{end} are non-@code{nil}, they should be numbers
|
||||
that are byte offsets specifying the portion of the file to insert.
|
||||
In this case, @var{visit} must be @code{nil}. For example,
|
||||
|
||||
@example
|
||||
(insert-file-contents filename nil 0 500)
|
||||
|
@ -605,8 +605,8 @@ that string, rather than text from the buffer. @var{end} is ignored in
|
|||
this case.
|
||||
|
||||
If @var{append} is non-@code{nil}, then the specified text is appended
|
||||
to the existing file contents (if any). If @var{append} is an
|
||||
integer, @code{write-region} seeks to that byte offset from the start
|
||||
to the existing file contents (if any). If @var{append} is a
|
||||
number, @code{write-region} seeks to that byte offset from the start
|
||||
of the file and writes the data from there.
|
||||
|
||||
If @var{mustbenew} is non-@code{nil}, then @code{write-region} asks
|
||||
|
|
|
@ -1,3 +1,12 @@
|
|||
2013-01-19 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
Allow floating-point file offsets.
|
||||
Problem reported by Vitalie Spinu in
|
||||
<http://lists.gnu.org/archive/html/emacs-devel/2013-01/msg00411.html>.
|
||||
* fileio.c (emacs_lseek): Remove.
|
||||
(file_offset): New function.
|
||||
(Finsert_file_contents, Fwrite_region): Use it.
|
||||
|
||||
2013-01-19 Chong Yidong <cyd@gnu.org>
|
||||
|
||||
* emacs.c (Fkill_emacs): Set waiting_for_input to 0 to avoid
|
||||
|
|
59
src/fileio.c
59
src/fileio.c
|
@ -3443,19 +3443,25 @@ read_contents_quit (Lisp_Object ignore)
|
|||
return Qnil;
|
||||
}
|
||||
|
||||
/* Reposition FD to OFFSET, based on WHENCE. This acts like lseek
|
||||
except that it also tests for OFFSET being out of lseek's range. */
|
||||
/* Return the file offset that VAL represents, checking for type
|
||||
errors and overflow. */
|
||||
static off_t
|
||||
emacs_lseek (int fd, EMACS_INT offset, int whence)
|
||||
file_offset (Lisp_Object val)
|
||||
{
|
||||
/* Use "&" rather than "&&" to suppress a bogus GCC warning; see
|
||||
<http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43772>. */
|
||||
if (! ((offset >= TYPE_MINIMUM (off_t)) & (offset <= TYPE_MAXIMUM (off_t))))
|
||||
if (RANGED_INTEGERP (0, val, TYPE_MAXIMUM (off_t)))
|
||||
return XINT (val);
|
||||
|
||||
if (FLOATP (val))
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
double v = XFLOAT_DATA (val);
|
||||
if (0 <= v
|
||||
&& (sizeof (off_t) < sizeof v
|
||||
? v <= TYPE_MAXIMUM (off_t)
|
||||
: v < TYPE_MAXIMUM (off_t)))
|
||||
return v;
|
||||
}
|
||||
return lseek (fd, offset, whence);
|
||||
|
||||
wrong_type_argument (intern ("file-offset"), val);
|
||||
}
|
||||
|
||||
/* Return a special time value indicating the error number ERRNUM. */
|
||||
|
@ -3606,20 +3612,12 @@ by calling `format-decode', which see. */)
|
|||
}
|
||||
|
||||
if (!NILP (beg))
|
||||
{
|
||||
if (! RANGED_INTEGERP (0, beg, TYPE_MAXIMUM (off_t)))
|
||||
wrong_type_argument (intern ("file-offset"), beg);
|
||||
beg_offset = XFASTINT (beg);
|
||||
}
|
||||
beg_offset = file_offset (beg);
|
||||
else
|
||||
beg_offset = 0;
|
||||
|
||||
if (!NILP (end))
|
||||
{
|
||||
if (! RANGED_INTEGERP (0, end, TYPE_MAXIMUM (off_t)))
|
||||
wrong_type_argument (intern ("file-offset"), end);
|
||||
end_offset = XFASTINT (end);
|
||||
}
|
||||
end_offset = file_offset (end);
|
||||
else
|
||||
{
|
||||
if (not_regular)
|
||||
|
@ -4714,7 +4712,7 @@ If START is a string, then output that string to the file
|
|||
instead of any buffer contents; END is ignored.
|
||||
|
||||
Optional fourth argument APPEND if non-nil means
|
||||
append to existing file contents (if any). If it is an integer,
|
||||
append to existing file contents (if any). If it is a number,
|
||||
seek to that offset in the file before writing.
|
||||
Optional fifth argument VISIT, if t or a string, means
|
||||
set the last-save-file-modtime of buffer to this file's modtime
|
||||
|
@ -4743,6 +4741,7 @@ This calls `write-region-annotate-functions' at the start, and
|
|||
(Lisp_Object start, Lisp_Object end, Lisp_Object filename, Lisp_Object append, Lisp_Object visit, Lisp_Object lockname, Lisp_Object mustbenew)
|
||||
{
|
||||
int desc;
|
||||
off_t offset;
|
||||
bool ok;
|
||||
int save_errno = 0;
|
||||
const char *fn;
|
||||
|
@ -4864,13 +4863,14 @@ This calls `write-region-annotate-functions' at the start, and
|
|||
encoded_filename = ENCODE_FILE (filename);
|
||||
|
||||
fn = SSDATA (encoded_filename);
|
||||
offset = 0;
|
||||
desc = -1;
|
||||
if (!NILP (append))
|
||||
#ifdef DOS_NT
|
||||
desc = emacs_open (fn, O_WRONLY | O_BINARY, 0);
|
||||
#else /* not DOS_NT */
|
||||
desc = emacs_open (fn, O_WRONLY, 0);
|
||||
#endif /* not DOS_NT */
|
||||
{
|
||||
if (NUMBERP (append))
|
||||
offset = file_offset (append);
|
||||
desc = emacs_open (fn, O_WRONLY | O_BINARY, 0);
|
||||
}
|
||||
|
||||
if (desc < 0 && (NILP (append) || errno == ENOENT))
|
||||
#ifdef DOS_NT
|
||||
|
@ -4897,14 +4897,9 @@ This calls `write-region-annotate-functions' at the start, and
|
|||
|
||||
record_unwind_protect (close_file_unwind, make_number (desc));
|
||||
|
||||
if (!NILP (append) && !NILP (Ffile_regular_p (filename)))
|
||||
if (!NILP (append))
|
||||
{
|
||||
off_t ret;
|
||||
|
||||
if (NUMBERP (append))
|
||||
ret = emacs_lseek (desc, XINT (append), SEEK_CUR);
|
||||
else
|
||||
ret = lseek (desc, 0, SEEK_END);
|
||||
off_t ret = lseek (desc, offset, NUMBERP (append) ? SEEK_SET : SEEK_END);
|
||||
if (ret < 0)
|
||||
{
|
||||
#ifdef CLASH_DETECTION
|
||||
|
|
Loading…
Add table
Reference in a new issue