emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] trunk r115063: * search.c (find_newline): Rewrite to prefe


From: Paul Eggert
Subject: [Emacs-diffs] trunk r115063: * search.c (find_newline): Rewrite to prefer offsets to pointers.
Date: Mon, 11 Nov 2013 16:37:57 +0000
User-agent: Bazaar (2.6b2)

------------------------------------------------------------
revno: 115063
revision-id: address@hidden
parent: address@hidden
committer: Paul Eggert <address@hidden>
branch nick: trunk
timestamp: Mon 2013-11-11 08:37:54 -0800
message:
  * search.c (find_newline): Rewrite to prefer offsets to pointers.
  
  This avoids undefined behavior when subtracting pointers into
  different aways.  On my platform it also makes the code a tad
  smaller and presumably faster.
modified:
  src/ChangeLog                  changelog-20091113204419-o5vbwnq5f7feedwu-1438
  src/search.c                   search.c-20091113204419-o5vbwnq5f7feedwu-473
=== modified file 'src/ChangeLog'
--- a/src/ChangeLog     2013-11-11 05:18:53 +0000
+++ b/src/ChangeLog     2013-11-11 16:37:54 +0000
@@ -1,3 +1,10 @@
+2013-11-11  Paul Eggert  <address@hidden>
+
+       * search.c (find_newline): Rewrite to prefer offsets to pointers.
+       This avoids undefined behavior when subtracting pointers into
+       different aways.  On my platform it also makes the code a tad
+       smaller and presumably faster.
+
 2013-11-11  Stefan Monnier  <address@hidden>
 
        * keyboard.c (command_loop_1): Use region-extract-function.

=== modified file 'src/search.c'
--- a/src/search.c      2013-11-09 21:24:10 +0000
+++ b/src/search.c      2013-11-11 16:37:54 +0000
@@ -720,58 +720,45 @@
 
         {
           /* The termination address of the dumb loop.  */
-          register unsigned char *ceiling_addr
-           = BYTE_POS_ADDR (ceiling_byte) + 1;
-          register unsigned char *cursor
-           = BYTE_POS_ADDR (start_byte);
-          unsigned char *base = cursor;
-
-          while (cursor < ceiling_addr)
-            {
+         unsigned char *lim_addr = BYTE_POS_ADDR (ceiling_byte) + 1;
+         ptrdiff_t lim_byte = ceiling_byte + 1;
+
+         /* Nonpositive offsets (relative to LIM_ADDR and LIM_BYTE)
+            of the base, the cursor, and the next line.  */
+         ptrdiff_t base = start_byte - lim_byte;
+         ptrdiff_t cursor, next;
+
+         for (cursor = base; cursor < 0; cursor = next)
+           {
               /* The dumb loop.  */
-             unsigned char *nl = memchr (cursor, '\n', ceiling_addr - cursor);
+             unsigned char *nl = memchr (lim_addr + cursor, '\n', - cursor);
+             next = nl ? nl - lim_addr : 0;
 
               /* If we're looking for newlines, cache the fact that
-                 the region from start to cursor is free of them. */
+                 this line's region is free of them. */
               if (newline_cache)
                {
-                 unsigned char *low = cursor;
-                 unsigned char *lim = nl ? nl : ceiling_addr;
                  know_region_cache (current_buffer, newline_cache,
-                                    BYTE_TO_CHAR (low - base + start_byte),
-                                    BYTE_TO_CHAR (lim - base + start_byte));
+                                    BYTE_TO_CHAR (lim_byte + cursor),
+                                    BYTE_TO_CHAR (lim_byte + next));
+                 /* know_region_cache can relocate buffer text.  */
+                 lim_addr = BYTE_POS_ADDR (ceiling_byte) + 1;
                }
 
               if (! nl)
                break;
+             next++;
 
              if (--count == 0)
                {
                  immediate_quit = 0;
                  if (bytepos)
-                   *bytepos = nl + 1 - base + start_byte;
-                 return BYTE_TO_CHAR (nl + 1 - base + start_byte);
-               }
-             if (newline_cache)
-               {
-                 /* The call to know_region_cache could have
-                    allocated memory and caused relocation of buffer
-                    text.  If it did, adjust pointers into buffer
-                    text.  */
-                 ptrdiff_t offset = BYTE_POS_ADDR (start_byte) - base;
-
-                 if (offset != 0)
-                   {
-                     cursor += offset;
-                     base += offset;
-                     ceiling_addr += offset;
-                     nl += offset;
-                   }
-               }
-             cursor = nl + 1;
+                   *bytepos = lim_byte + next;
+                 return BYTE_TO_CHAR (lim_byte + next);
+               }
             }
 
-         start_byte += ceiling_addr - base;
+         start_byte = lim_byte;
          start = BYTE_TO_CHAR (start_byte);
         }
       }
@@ -810,24 +797,28 @@
 
         {
           /* The termination address of the dumb loop.  */
-          register unsigned char *ceiling_addr = BYTE_POS_ADDR (ceiling_byte);
-          register unsigned char *cursor = BYTE_POS_ADDR (start_byte - 1);
-          unsigned char *base = cursor;
-
-          while (cursor >= ceiling_addr)
+         unsigned char *ceiling_addr = BYTE_POS_ADDR (ceiling_byte);
+
+         /* Offsets (relative to CEILING_ADDR and CEILING_BYTE) of
+            the base, the cursor, and the previous line.  These
+            offsets are at least -1.  */
+         ptrdiff_t base = start_byte - ceiling_byte;
+         ptrdiff_t cursor, prev;
+
+         for (cursor = base; 0 < cursor; cursor = prev)
             {
-             unsigned char *nl = memrchr (ceiling_addr, '\n',
-                                          cursor + 1 - ceiling_addr);
+             unsigned char *nl = memrchr (ceiling_addr, '\n', cursor);
+             prev = nl ? nl - ceiling_addr : -1;
 
               /* If we're looking for newlines, cache the fact that
-                 the region from after the cursor to start is free of them.  */
+                 this line's region is free of them. */
               if (newline_cache)
                {
-                 unsigned char *low = nl ? nl : ceiling_addr - 1;
-                 unsigned char *lim = cursor;
                  know_region_cache (current_buffer, newline_cache,
-                                    BYTE_TO_CHAR (low - base + start_byte),
-                                    BYTE_TO_CHAR (lim - base + start_byte));
+                                    BYTE_TO_CHAR (ceiling_byte + prev + 1),
+                                    BYTE_TO_CHAR (ceiling_byte + cursor));
+                 /* know_region_cache can relocate buffer text.  */
+                 ceiling_addr = BYTE_POS_ADDR (ceiling_byte);
                }
 
               if (! nl)
@@ -837,25 +828,12 @@
                {
                  immediate_quit = 0;
                  if (bytepos)
-                   *bytepos = nl - base + start_byte;
-                 return BYTE_TO_CHAR (nl - base + start_byte);
-               }
-             if (newline_cache)
-               {
-                 ptrdiff_t offset = BYTE_POS_ADDR (start_byte - 1) - base;
-
-                 if (offset != 0)
-                   {
-                     cursor += offset;
-                     base += offset;
-                     ceiling_addr += offset;
-                     nl += offset;
-                   }
-               }
-             cursor = nl - 1;
+                   *bytepos = ceiling_byte + prev + 1;
+                 return BYTE_TO_CHAR (ceiling_byte + prev + 1);
+               }
             }
 
-         start_byte += ceiling_addr - 1 - base;
+         start_byte = ceiling_byte;
          start = BYTE_TO_CHAR (start_byte);
         }
       }


reply via email to

[Prev in Thread] Current Thread [Next in Thread]