APPROVE COMMIT
NOTE: This patch has been committed
# HG changeset patch
# User Aidan Kehoe <kehoea(a)parhasard.net>
# Date 1555250453 -3600
#      Sun Apr 14 15:00:53 2019 +0100
# Node ID 900e287bde1f0288186a4db74f7c4138be468deb
# Parent  a975482ad82db38730ffaaf33e0db6092f7cf779
Reduce char->byte conversion costs, #'forward-{char,line},
#'point-at-{eol-bol}
src/ChangeLog addition:
2019-04-14  Aidan Kehoe  <kehoea(a)parhasard.net>
	* cmds.c (Fforward_char):
	Make this usually free in terms of calls to charbpos_to_bytebpos().
	* cmds.c (Fforward_line):
	Avoid needless char-byte conversion in this function.
	* cmds.c (Fpoint_at_bol):
	Ditto.
	* cmds.c (Fpoint_at_eol):
	Ditto.
	* lisp.h:
	Remove the declaration for find_before_next_newline(), no longer
	used.
	* search.c :
	Remove find_before_next_newline(), only called by Fpoint_at_eol(),
	which now includes the (very simple) implementation of f_b_n_n().
diff -r a975482ad82d -r 900e287bde1f src/ChangeLog
--- a/src/ChangeLog	Sun Apr 14 13:23:03 2019 +0100
+++ b/src/ChangeLog	Sun Apr 14 15:00:53 2019 +0100
@@ -1,3 +1,20 @@
+2019-04-14  Aidan Kehoe  <kehoea(a)parhasard.net>
+
+	* cmds.c (Fforward_char):
+	Make this usually free in terms of calls to charbpos_to_bytebpos().
+	* cmds.c (Fforward_line):
+	Avoid needless char-byte conversion in this function.
+	* cmds.c (Fpoint_at_bol):
+	Ditto.
+	* cmds.c (Fpoint_at_eol):
+	Ditto.
+	* lisp.h:
+	Remove the declaration for find_before_next_newline(), no longer
+	used.
+	* search.c :
+	Remove find_before_next_newline(), only called by Fpoint_at_eol(),
+	which now includes the (very simple) implementation of f_b_n_n().
+
 2019-04-14  Aidan Kehoe  <kehoea(a)parhasard.net>
 
 	Get Stephen's last change compiling, fix a clear bug.
diff -r a975482ad82d -r 900e287bde1f src/cmds.c
--- a/src/cmds.c	Sun Apr 14 13:23:03 2019 +0100
+++ b/src/cmds.c	Sun Apr 14 15:00:53 2019 +0100
@@ -76,21 +76,48 @@
      proposed position, then set point.  */
   {
     Charbpos new_point = BUF_PT (buf) + n;
+    Bytebpos bcursor;
 
     if (new_point < BUF_BEGV (buf))
       {
-	BUF_SET_PT (buf, BUF_BEGV (buf));
+	BOTH_BUF_SET_PT (buf, BUF_BEGV (buf), BYTE_BUF_BEGV (buf));
 	Fsignal (Qbeginning_of_buffer, Qnil);
 	return Qnil;
       }
     if (new_point > BUF_ZV (buf))
       {
-	BUF_SET_PT (buf, BUF_ZV (buf));
+	BOTH_BUF_SET_PT (buf, BUF_ZV (buf), BYTE_BUF_ZV (buf));
 	Fsignal (Qend_of_buffer, Qnil);
 	return Qnil;
       }
 
-    BUF_SET_PT (buf, new_point);
+    bcursor = BYTE_BUF_PT (buf);
+
+    if (n >= 0)
+      {
+        while (n != 0 && n <= 16)
+          {
+            bcursor = next_bytebpos (buf, bcursor);
+            n--;
+          }
+      }
+    else
+      {
+        while (n != 0 && n >= -16)
+          {
+            bcursor = prev_bytebpos (buf, bcursor);
+            n++;
+          }
+      }
+
+    if (n == 0) /* We don't need to call charbpos_to_bytebpos(). */
+      {
+        BOTH_BUF_SET_PT (buf, new_point, bcursor);
+      }
+    else
+      {
+        BUF_SET_PT (buf, new_point);
+      }
   }
 
   return Qnil;
@@ -115,8 +142,7 @@
        (count, buffer))
 {
   struct buffer *buf = decode_buffer (buffer, 1);
-  Charbpos pos2 = BUF_PT (buf);
-  Charbpos pos;
+  Bytebpos pos;
   EMACS_INT n, shortage, negp;
 
   if (NILP (count))
@@ -128,14 +154,15 @@
     }
 
   negp = n <= 0;
-  pos = scan_buffer (buf, '\n', pos2, 0, n - negp, &shortage, 1);
+  pos = byte_scan_buffer (buf, '\n', BYTE_BUF_PT (buf), 0, n - negp,
+                          &shortage, 1);
   if (shortage > 0
       && (negp
-	  || (BUF_ZV (buf) > BUF_BEGV (buf)
-	      && pos != pos2
-	      && BUF_FETCH_CHAR (buf, pos - 1) != '\n')))
+	  || (BYTE_BUF_ZV (buf) > BYTE_BUF_BEGV (buf)
+	      && pos != BYTE_BUF_PT (buf)
+	      && byte_beginning_of_line_p (buf, pos))))
     shortage--;
-  BUF_SET_PT (buf, pos);
+  BYTE_BUF_SET_PT (buf, pos);
   return make_fixnum (negp ? - shortage : shortage);
 }
 
@@ -148,23 +175,21 @@
        (count, buffer))
 {
   struct buffer *b = decode_buffer (buffer, 1);
-  REGISTER Charbpos orig, end;
+  EMACS_INT n, shortage, negp;
+  Bytebpos pos;
 
-  buffer = wrap_buffer (b);
   if (NILP (count))
-    count = make_fixnum (0);
+    n = 0;
   else
     {
       CHECK_FIXNUM (count);
-      count = make_fixnum (XFIXNUM (count) - 1);
+      n = XFIXNUM (count) - 1;
     }
 
-  orig = BUF_PT (b);
-  Fforward_line (count, buffer);
-  end = BUF_PT (b);
-  BUF_SET_PT (b, orig);
+  negp = n <= 0;
+  pos = byte_scan_buffer (b, '\n', BYTE_BUF_PT (b), 0, n - negp, &shortage,
1);
 
-  return make_fixnum (end);
+  return make_integer (bytebpos_to_charbpos (b, pos));
 }
 
 DEFUN ("point-at-eol", Fpoint_at_eol, 0, 2, 0, /*
@@ -176,7 +201,8 @@
        (count, buffer))
 {
   struct buffer *buf = decode_buffer (buffer, 1);
-  EMACS_INT n;
+  EMACS_INT n, shortage;
+  Bytebpos pos;
 
   if (NILP (count))
     n = 1;
@@ -186,8 +212,15 @@
       n = XFIXNUM (count);
     }
 
-  return make_fixnum (find_before_next_newline (buf, BUF_PT (buf), 0,
-						n - (n <= 0)));
+  pos = byte_scan_buffer (buf, '\n', BYTE_BUF_PT (buf), 0, n - (n <= 0),
+                          &shortage, 1);
+
+  if (shortage == 0)
+    {
+      pos = prev_bytebpos (buf, pos);
+    }
+
+  return make_integer (bytebpos_to_charbpos (buf, pos));
 }
 
 DEFUN ("delete-char", Fdelete_char, 0, 2, "*p\nP", /*
diff -r a975482ad82d -r 900e287bde1f src/lisp.h
--- a/src/lisp.h	Sun Apr 14 13:23:03 2019 +0100
+++ b/src/lisp.h	Sun Apr 14 15:00:53 2019 +0100
@@ -6017,8 +6017,6 @@
 Bytebpos byte_find_next_newline_no_quit (struct buffer *, Bytebpos, int);
 Bytecount byte_find_next_ichar_in_string (Lisp_Object, Ichar, Bytecount,
 					 EMACS_INT);
-Charbpos find_before_next_newline (struct buffer *, Charbpos, Charbpos,
-				   EMACS_INT);
 struct re_pattern_buffer *compile_pattern (Lisp_Object pattern,
 					   struct re_registers *regp,
 					   Lisp_Object translate,
diff -r a975482ad82d -r 900e287bde1f src/search.c
--- a/src/search.c	Sun Apr 14 13:23:03 2019 +0100
+++ b/src/search.c	Sun Apr 14 15:00:53 2019 +0100
@@ -918,22 +918,6 @@
     }
   return st;
 }
-
-/* Like find_next_newline, but returns position before the newline,
-   not after, and only search up to TO.  This isn't just
-   find_next_newline (...)-1, because you might hit TO.  */
-Charbpos
-find_before_next_newline (struct buffer *buf, Charbpos from, Charbpos to,
-			  EMACS_INT count)
-{
-  EMACS_INT shortage;
-  Charbpos pos = scan_buffer (buf, '\n', from, to, count, &shortage, 1);
-
-  if (shortage == 0)
-    pos--;
-
-  return pos;
-}
 
 /* This function synched with FSF 21.1 */
 static Lisp_Object
-- 
‘As I sat looking up at the Guinness ad, I could never figure out /
How your man stayed up on the surfboard after forty pints of stout’
(C. Moore)