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.