2 new commits in XEmacs:
https://bitbucket.org/xemacs/xemacs/commits/f45199815d5d/
Changeset: f45199815d5d
User: kehoea
Date: 2018-04-07 20:40:47+00:00
Summary: Handle bignum START, END values as appropriate,
#'insert-file-contents-internal
src/ChangeLog addition:
2018-04-07 Aidan Kehoe <kehoea(a)parhasard.net>
* fileio.c (Fsubstitute_in_file_name): Fixup some whitespace here.
* fileio.c (Finsert_file_contents_internal):
Handle bignum values for START, END. Error if the difference
between START and END means the relevant buffer would become too
big to handle.
* insdel.c (buffer_insert_string_1):
Check the new buffer size in terms of characters, not bytes.
* lstream.c (make_filedesc_stream_1):
* lstream.c (make_filedesc_input_stream):
* lstream.c (make_filedesc_output_stream):
* lstream.h:
Use the OFF_T type for the OFFSET argument to these functions,
Bytecount for the COUNT argument, as has long been the most
reasonable approach.
Affected #: 5 files
diff -r 3e52d0a8ca3d -r f45199815d5d src/ChangeLog
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,20 @@
+2018-04-07 Aidan Kehoe <kehoea(a)parhasard.net>
+
+ * fileio.c (Fsubstitute_in_file_name): Fixup some whitespace here.
+ * fileio.c (Finsert_file_contents_internal):
+ Handle bignum values for START, END. Error if the difference
+ between START and END means the relevant buffer would become too
+ big to handle.
+ * insdel.c (buffer_insert_string_1):
+ Check the new buffer size in terms of characters, not bytes.
+ * lstream.c (make_filedesc_stream_1):
+ * lstream.c (make_filedesc_input_stream):
+ * lstream.c (make_filedesc_output_stream):
+ * lstream.h:
+ Use the OFF_T type for the OFFSET argument to these functions,
+ Bytecount for the COUNT argument, as has long been the most
+ reasonable approach.
+
2018-04-06 Aidan Kehoe <kehoea(a)parhasard.net>
* process-unix.c:
diff -r 3e52d0a8ca3d -r f45199815d5d src/fileio.c
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -1495,10 +1495,7 @@
(filename))
{
/* This function can GC. GC checked 2000-07-28 ben. */
- Ibyte *nm;
-
- Ibyte *s, *p, *o, *x, *endp, *got;
- Ibyte *target = 0;
+ Ibyte *nm, *s, *p, *o, *x, *endp, *got, *target = 0;
int total = 0;
int substituted = 0, seen_braces;
Ibyte *xnm;
@@ -2897,17 +2894,17 @@
int speccount;
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
Lisp_Object val;
- int total;
+ Bytecount total;
Ibyte *read_buf = alloca_ibytes (READ_BUF_SIZE);
int mc_count;
struct buffer *buf = current_buffer;
Lisp_Object curbuf;
- int not_regular = 0;
- int do_speedy_insert =
+ Boolint not_regular = 0, do_speedy_insert =
coding_system_is_binary (Fget_coding_system (codesys));
if (buf->base_buffer && ! NILP (visit))
- invalid_operation ("Cannot do file visiting in an indirect buffer",
Qunbound);
+ invalid_operation ("Cannot do file visiting in an indirect buffer",
+ Qunbound);
/* No need to call Fbarf_if_buffer_read_only() here.
That's called in begin_multiple_change() or wherever. */
@@ -2977,12 +2974,12 @@
#endif /* S_IFREG */
if (!NILP (start))
- CHECK_FIXNUM (start);
+ CHECK_NATNUM (start);
else
start = Qzero;
if (!NILP (end))
- CHECK_FIXNUM (end);
+ CHECK_NATNUM (end);
if (fd < 0)
{
@@ -2997,20 +2994,21 @@
record_unwind_protect (close_file_unwind, make_fixnum (fd));
- /* Supposedly happens on VMS. */
- if (st.st_size < 0)
- signal_error (Qfile_error, "File size is negative", Qunbound);
-
if (NILP (end))
{
if (!not_regular)
{
- end = make_fixnum (st.st_size);
- if (XFIXNUM (end) != st.st_size)
- out_of_memory ("Maximum buffer size exceeded", Qunbound);
+ end = make_integer (st.st_size);
+ CHECK_NATNUM (end);
}
}
+ /* Supposedly happens on VMS. */
+ if (NILP (end) && st.st_size < 0)
+ {
+ signal_error (Qfile_error, "File size is negative", Qunbound);
+ }
+
/* If requested, replace the accessible part of the buffer
with the file contents. Avoid replacing text at the
beginning or end of the buffer that matches the file contents;
@@ -3097,8 +3095,8 @@
match the text at the end of the buffer. */
while (1)
{
- int total_read, nread;
- Charcount charbpos, curpos, trial;
+ Bytecount total_read, nread;
+ OFF_T charbpos, curpos, trial;
/* At what file position are we now scanning? */
curpos = st.st_size - (BUF_ZV (buf) - same_at_end);
@@ -3146,8 +3144,8 @@
same_at_end += overlap;
/* Arrange to read only the nonmatching middle part of the file. */
- start = make_fixnum (same_at_start - BUF_BEGV (buf));
- end = make_fixnum (st.st_size - (BUF_ZV (buf) - same_at_end));
+ start = make_integer (same_at_start - BYTE_BUF_BEGV (buf));
+ end = make_integer (st.st_size - (BYTE_BUF_ZV (buf) - same_at_end));
buffer_delete_range (buf, same_at_start, same_at_end,
!NILP (visit) ? INSDEL_NO_LOCKING : 0);
@@ -3158,24 +3156,75 @@
if (!not_regular)
{
- total = XFIXNUM (end) - XFIXNUM (start);
+ Lisp_Object args[] = { end, start };
+ Lisp_Object diff = Fminus (countof (args), args);
/* Make sure point-max won't overflow after this insertion. */
- if (total != XFIXNUM (make_fixnum (total)))
- out_of_memory ("Maximum buffer size exceeded", Qunbound);
+ if (FIXNUMP (diff))
+ {
+ total = XREALFIXNUM (diff);
+ }
+#ifdef HAVE_BIGNUM
+ else if (bignum_fits_emacs_int_p (XBIGNUM_DATA (diff)))
+ {
+ total = bignum_to_emacs_int (XBIGNUM_DATA (diff));
+ }
+#endif
+ else
+ {
+ /* Doesn't fit in an EMACS_INT, which means doesn't fit in a
+ Bytecount, which means we should error. */
+ goto unreasonably_large;
+ }
+
+ if ((total > ((Bytecount) (~((EMACS_UINT) 0) >> 1))))
+ {
+ unreasonably_large:
+ out_of_memory ("Maximum buffer byte size exceeded",
+ diff);
+ }
}
else
/* For a special file, all we can do is guess. The value of -1
will make the stream functions read as much as possible. */
total = -1;
- if (XFIXNUM (start) != 0
+ if (!(EQ (start, Qzero))
/* why was this here? asked jwz. The reason is that the replace-mode
connivings above will normally put the file pointer other than
where it should be. */
|| (!NILP (replace) && do_speedy_insert))
{
- if (lseek (fd, XFIXNUM (start), 0) < 0)
+ OFF_T starting;
+
+ if (FIXNUMP (start))
+ {
+ starting = XREALFIXNUM (start);
+ }
+#ifdef HAVE_BIGNUM
+ else if (bignum_fits_emacs_int_p (XBIGNUM_DATA (start)))
+ {
+ starting = bignum_to_emacs_int (XBIGNUM_DATA (start));
+ }
+ else if (sizeof (starting) == sizeof (long long)
+ && bignum_fits_llong_p (XBIGNUM_DATA (start)))
+ {
+ starting = bignum_to_llong (XBIGNUM_DATA (start));
+ }
+ else if (sizeof (starting) == sizeof (unsigned long long)
+ && bignum_fits_ullong_p (XBIGNUM_DATA (start)))
+ {
+ starting = bignum_to_ullong (XBIGNUM_DATA (start));
+ }
+#endif
+ else
+ {
+ signal_error (Qunimplemented,
+ "File offset not supported in this XEmacs",
+ start);
+ }
+
+ if (lseek (fd, starting, 0) < 0)
report_file_error ("Setting file position", filename);
}
diff -r 3e52d0a8ca3d -r f45199815d5d src/insdel.c
--- a/src/insdel.c
+++ b/src/insdel.c
@@ -1079,10 +1079,6 @@
is a string. */
#endif
- /* Make sure that point-max won't exceed the size of an emacs int. */
- if ((length + BUF_Z (buf)) > MOST_POSITIVE_FIXNUM)
- out_of_memory ("Maximum buffer size exceeded", Qunbound);
-
/* theoretically not necessary -- caller should GCPRO.
#### buffer_insert_from_buffer_1() doesn't! */
GCPRO1 (reloc);
@@ -1129,6 +1125,12 @@
#endif /* ERROR_CHECK_TEXT */
}
+ /* Make sure that point-max won't exceed the size of an emacs int. */
+ if ((MOST_POSITIVE_FIXNUM - 1) - BUF_Z (buf) < cclen)
+ {
+ out_of_memory ("Maximum buffer size exceeded", Qunbound);
+ }
+
/* &&#### Here we check if the text can't fit into the format of the
buffer,
and if so convert it to another format (either default or 32-bit-fixed,
according to some flag; if no flag, use default). */
diff -r 3e52d0a8ca3d -r f45199815d5d src/lstream.c
--- a/src/lstream.c
+++ b/src/lstream.c
@@ -1232,7 +1232,7 @@
should start at. COUNT is the number of bytes to be read (it is
ignored when writing); -1 for unlimited. */
static Lisp_Object
-make_filedesc_stream_1 (int filedesc, int offset, int count, int flags,
+make_filedesc_stream_1 (int filedesc, OFF_T offset, Bytecount count, int flags,
tls_state_t *state)
{
Lstream *lstr = Lstream_new (lstream_filedesc,
@@ -1271,16 +1271,16 @@
*/
Lisp_Object
-make_filedesc_input_stream (int filedesc, int offset, int count, int flags,
- tls_state_t *state)
+make_filedesc_input_stream (int filedesc, OFF_T offset, Bytecount count,
+ int flags, tls_state_t *state)
{
return make_filedesc_stream_1 (filedesc, offset, count,
flags | LSTR_READ, state);
}
Lisp_Object
-make_filedesc_output_stream (int filedesc, int offset, int count, int flags,
- tls_state_t *state)
+make_filedesc_output_stream (int filedesc, OFF_T offset, Bytecount count,
+ int flags, tls_state_t *state)
{
return make_filedesc_stream_1 (filedesc, offset, count,
flags | LSTR_WRITE, state);
diff -r 3e52d0a8ca3d -r f45199815d5d src/lstream.h
--- a/src/lstream.h
+++ b/src/lstream.h
@@ -507,10 +507,12 @@
Lisp_Object make_stdio_input_stream (FILE *stream, int flags);
Lisp_Object make_stdio_output_stream (FILE *stream, int flags);
-Lisp_Object make_filedesc_input_stream (int filedesc, int offset, int count,
- int flags, tls_state_t *state);
-Lisp_Object make_filedesc_output_stream (int filedesc, int offset, int count,
- int flags, tls_state_t *state);
+Lisp_Object make_filedesc_input_stream (int filedesc, OFF_T offset,
+ Bytecount count, int flags,
+ tls_state_t *state);
+Lisp_Object make_filedesc_output_stream (int filedesc, OFF_T offset,
+ Bytecount count, int flags,
+ tls_state_t *state);
void filedesc_stream_set_pty_flushing (Lstream *stream,
int pty_max_bytes,
Ibyte eof_char);
https://bitbucket.org/xemacs/xemacs/commits/f101d3bd2814/
Changeset: f101d3bd2814
User: kehoea
Date: 2018-04-10 07:03:42+00:00
Summary: Interpret a numeric APPEND as a position for lseek(),
#'write-region-internal
src/ChangeLog addition:
2018-04-10 Aidan Kehoe <kehoea(a)parhasard.net>
* fileio.c (lisp_to_off_t): New function.
Decode a Lisp_Object into an OFF_T. Accept floats as well as
integers, as does GNU (they have more need to, because they don't
have bignums)
* fileio.c (Finsert_file_contents_internal):
Use it here.
* fileio.c (Fwrite_region_internal):
Interpret a numeric APPEND argument as specifying a byte offset in
the output file to seek to before writing.
lisp/ChangeLog addition:
2018-04-10 Aidan Kehoe <kehoea(a)parhasard.net>
* code-files.el (write-region):
Document that APPEND can now be a numeric offset, indicating a
point to seek to.
Affected #: 4 files
diff -r f45199815d5d -r f101d3bd2814 lisp/ChangeLog
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,9 @@
+2018-04-10 Aidan Kehoe <kehoea(a)parhasard.net>
+
+ * code-files.el (write-region):
+ Document that APPEND can now be a numeric offset, indicating a
+ point to seek to.
+
2018-02-18 Aidan Kehoe <kehoea(a)parhasard.net>
* simple.el (no-case-regexp-p):
diff -r f45199815d5d -r f101d3bd2814 lisp/code-files.el
--- a/lisp/code-files.el
+++ b/lisp/code-files.el
@@ -597,8 +597,8 @@
When called from a program, takes three required arguments:
START, END and FILENAME. START and END are buffer positions.
-APPEND, if non-nil, means append to existing file contents (if any), else
- the file's existing contents are replaced by the specified region.
+APPEND, if non-nil, means append to existing file contents (if any). If it is
+a byte file offset, seek to that point before writing.
VISIT, if non-nil, should be a string naming a file. The buffer is marked
as visiting VISIT. VISIT is also the file name to lock
and unlock for clash detection.
diff -r f45199815d5d -r f101d3bd2814 src/ChangeLog
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,15 @@
+2018-04-10 Aidan Kehoe <kehoea(a)parhasard.net>
+
+ * fileio.c (lisp_to_off_t): New function.
+ Decode a Lisp_Object into an OFF_T. Accept floats as well as
+ integers, as does GNU (they have more need to, because they don't
+ have bignums)
+ * fileio.c (Finsert_file_contents_internal):
+ Use it here.
+ * fileio.c (Fwrite_region_internal):
+ Interpret a numeric APPEND argument as specifying a byte offset in
+ the output file to seek to before writing.
+
2018-04-07 Aidan Kehoe <kehoea(a)parhasard.net>
* fileio.c (Fsubstitute_in_file_name): Fixup some whitespace here.
diff -r f45199815d5d -r f101d3bd2814 src/fileio.c
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -167,6 +167,54 @@
return build_extstring (ret, Qstrerror_encoding);
}
+static OFF_T
+lisp_to_off_t (Lisp_Object offset)
+{
+ OFF_T result;
+ double v;
+
+ if (FIXNUMP (offset))
+ {
+ type_checking_assert (FIXNUM_VALBITS <=
+ (sizeof (OFF_T) * BITS_PER_CHAR));
+ return XREALFIXNUM (offset);
+ }
+#ifdef HAVE_BIGNUM
+ if (BIGNUMP (offset))
+ {
+ if (bignum_fits_emacs_int_p (XBIGNUM_DATA (offset)))
+ {
+ type_checking_assert (BITS_PER_EMACS_INT <=
+ (sizeof (OFF_T) * BITS_PER_CHAR));
+ return bignum_to_emacs_int (XBIGNUM_DATA (offset));
+ }
+ else if (sizeof (OFF_T) == sizeof (long long)
+ && bignum_fits_llong_p (XBIGNUM_DATA (offset)))
+ {
+ return bignum_to_llong (XBIGNUM_DATA (offset));
+ }
+ else if (sizeof (OFF_T) == sizeof (unsigned long long)
+ && (OFF_T)(-1) != -1
+ && bignum_fits_ullong_p (XBIGNUM_DATA (offset)))
+ {
+ return bignum_to_ullong (XBIGNUM_DATA (offset));
+ }
+ }
+#endif
+
+ v = extract_float (offset);
+ result = v;
+
+ if (result == v) /* Value bits preserved? */
+ {
+ return result;
+ }
+
+ wtaerror ("Offset not supported", offset);
+ RETURN_NOT_REACHED (-1);
+}
+
+
static Lisp_Object
close_file_unwind (Lisp_Object fd)
{
@@ -2973,13 +3021,14 @@
}
#endif /* S_IFREG */
- if (!NILP (start))
- CHECK_NATNUM (start);
- else
- start = Qzero;
-
- if (!NILP (end))
- CHECK_NATNUM (end);
+ if (NILP (start))
+ {
+ start = Qzero;
+ }
+ else if (lisp_to_off_t (start) < 0)
+ {
+ start = wrong_type_argument (Qnatnump, start);
+ }
if (fd < 0)
{
@@ -3146,7 +3195,6 @@
/* Arrange to read only the nonmatching middle part of the file. */
start = make_integer (same_at_start - BYTE_BUF_BEGV (buf));
end = make_integer (st.st_size - (BYTE_BUF_ZV (buf) - same_at_end));
-
buffer_delete_range (buf, same_at_start, same_at_end,
!NILP (visit) ? INSDEL_NO_LOCKING : 0);
/* Insert from the file at the proper position. */
@@ -3159,29 +3207,17 @@
Lisp_Object args[] = { end, start };
Lisp_Object diff = Fminus (countof (args), args);
- /* Make sure point-max won't overflow after this insertion. */
- if (FIXNUMP (diff))
- {
- total = XREALFIXNUM (diff);
- }
-#ifdef HAVE_BIGNUM
- else if (bignum_fits_emacs_int_p (XBIGNUM_DATA (diff)))
+ total = lisp_to_off_t (diff);
+
+ if (total < 0)
{
- total = bignum_to_emacs_int (XBIGNUM_DATA (diff));
+ dead_wrong_type_argument (Qnatnump, make_integer (total));
}
-#endif
- else
- {
- /* Doesn't fit in an EMACS_INT, which means doesn't fit in a
- Bytecount, which means we should error. */
- goto unreasonably_large;
- }
-
+
+ /* Make sure point-max won't overflow after this insertion. */
if ((total > ((Bytecount) (~((EMACS_UINT) 0) >> 1))))
{
- unreasonably_large:
- out_of_memory ("Maximum buffer byte size exceeded",
- diff);
+ out_of_memory ("Maximum buffer byte size exceeded", diff);
}
}
else
@@ -3197,32 +3233,10 @@
{
OFF_T starting;
- if (FIXNUMP (start))
- {
- starting = XREALFIXNUM (start);
- }
-#ifdef HAVE_BIGNUM
- else if (bignum_fits_emacs_int_p (XBIGNUM_DATA (start)))
- {
- starting = bignum_to_emacs_int (XBIGNUM_DATA (start));
- }
- else if (sizeof (starting) == sizeof (long long)
- && bignum_fits_llong_p (XBIGNUM_DATA (start)))
+ if (NUMBERP (start))
{
- starting = bignum_to_llong (XBIGNUM_DATA (start));
- }
- else if (sizeof (starting) == sizeof (unsigned long long)
- && bignum_fits_ullong_p (XBIGNUM_DATA (start)))
- {
- starting = bignum_to_ullong (XBIGNUM_DATA (start));
+ starting = lisp_to_off_t (start);
}
-#endif
- else
- {
- signal_error (Qunimplemented,
- "File offset not supported in this XEmacs",
- start);
- }
if (lseek (fd, starting, 0) < 0)
report_file_error ("Setting file position", filename);
@@ -3424,6 +3438,7 @@
Lisp_Object annotations = Qnil;
struct buffer *given_buffer;
Charbpos start1, end1;
+ OFF_T offset = 0;
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
struct gcpro ngcpro1, ngcpro2;
Lisp_Object curbuf = wrap_buffer (current_buffer);
@@ -3555,13 +3570,24 @@
if (!NILP (append))
{
- if (lseek (desc, 0, 2) < 0)
+ int whence = SEEK_END;
+ if (NUMBERP (append))
+ {
+ whence = SEEK_SET;
+ offset = lisp_to_off_t (append);
+ if (offset < 0)
+ {
+ dead_wrong_type_argument (Qnatnump, append);
+ }
+ }
+
+ if (lseek (desc, offset, whence) < 0)
{
#ifdef CLASH_DETECTION
if (!auto_saving) unlock_file (lockname);
#endif /* CLASH_DETECTION */
- report_file_error ("Lseek error",
- filename);
+ report_error_with_errno (Qfile_error, "Lseek error",
+ list2 (filename, make_integer (offset)));
}
}
Repository URL:
https://bitbucket.org/xemacs/xemacs/
--
This is a commit notification from
bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.