emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] master 2c87dab 4/6: Split up casify_region function (bug#2


From: Michal Nazarewicz
Subject: [Emacs-diffs] master 2c87dab 4/6: Split up casify_region function (bug#24603)
Date: Thu, 6 Apr 2017 14:55:32 -0400 (EDT)

branch: master
commit 2c87dabd0460cce83d2345b4ddff159969674fef
Author: Michal Nazarewicz <address@hidden>
Commit: Michal Nazarewicz <address@hidden>

    Split up casify_region function  (bug#24603)
    
    No functional changes at this time but splitting casify_region into
    a function dealing with multibyte and another dealing with unibyte
    buffers will make future code changes slightly easier.
    
    * src/casefiddle.c (casify_region): Move most of the code into two
    new functions:
    (do_casify_multibyte_region, do_casify_unibyte_region): new functions.
---
 src/casefiddle.c | 159 ++++++++++++++++++++++++++++++-------------------------
 1 file changed, 86 insertions(+), 73 deletions(-)

diff --git a/src/casefiddle.c b/src/casefiddle.c
index a83469c..b1a5f8e 100644
--- a/src/casefiddle.c
+++ b/src/casefiddle.c
@@ -231,102 +231,115 @@ The argument object is not altered--the value is a 
copy.  */)
   return casify_object (CASE_CAPITALIZE_UP, obj);
 }
 
-/* flag is CASE_UP, CASE_DOWN or CASE_CAPITALIZE or CASE_CAPITALIZE_UP.
-   b and e specify range of buffer to operate on. */
-
-static void
-casify_region (enum case_action flag, Lisp_Object b, Lisp_Object e)
+/* Based on CTX, case region in a unibyte buffer from POS to *ENDP.  Return
+   first position that has changed and save last position in *ENDP.  If no
+   characters were changed, return -1 and *ENDP is unspecified. */
+static ptrdiff_t
+do_casify_unibyte_region (struct casing_context *ctx,
+                         ptrdiff_t pos, ptrdiff_t *endp)
 {
-  bool multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
-  ptrdiff_t start, end;
-  ptrdiff_t start_byte;
+  ptrdiff_t first = -1, last = -1;  /* Position of first and last changes. */
+  ptrdiff_t end = *endp;
+  int ch, cased;
 
-  /* Position of first and last changes.  */
-  ptrdiff_t first = -1, last;
+  for (; pos < end; ++pos)
+    {
+      ch = FETCH_BYTE (pos);
+      MAKE_CHAR_MULTIBYTE (ch);
 
-  ptrdiff_t opoint = PT;
-  ptrdiff_t opoint_byte = PT_BYTE;
+      cased = case_character (ctx, ch);
+      if (cased == ch)
+       continue;
 
-  struct casing_context ctx;
+      last = pos;
+      if (first < 0)
+       first = pos;
 
-  if (EQ (b, e))
-    /* Not modifying because nothing marked */
-    return;
+      MAKE_CHAR_UNIBYTE (cased);
+      FETCH_BYTE (pos) = cased;
+    }
 
-  validate_region (&b, &e);
-  start = XFASTINT (b);
-  end = XFASTINT (e);
-  modify_text (start, end);
-  record_change (start, end - start);
-  start_byte = CHAR_TO_BYTE (start);
+  *endp = last + 1;
+  return first;
+}
 
-  prepare_casing_context (&ctx, flag, true);
+/* Based on CTX, case region in a multibyte buffer from POS to *ENDP.  Return
+   first position that has changed and save last position in *ENDP.  If no
+   characters were changed, return -1 and *ENDP is unspecified. */
+static ptrdiff_t
+do_casify_multibyte_region (struct casing_context *ctx,
+                           ptrdiff_t pos, ptrdiff_t *endp)
+{
+  ptrdiff_t first = -1, last = -1;  /* Position of first and last changes. */
+  ptrdiff_t pos_byte = CHAR_TO_BYTE (pos), end = *endp;
+  ptrdiff_t opoint = PT;
+  int ch, cased, len;
 
-  while (start < end)
+  while (pos < end)
     {
-      int ch, cased, len;
-
-      if (multibyte)
-       {
-         ch = FETCH_MULTIBYTE_CHAR (start_byte);
-         len = CHAR_BYTES (ch);
-       }
-      else
-       {
-         ch = FETCH_BYTE (start_byte);
-         MAKE_CHAR_MULTIBYTE (ch);
-         len = 1;
-       }
-      cased = case_character (&ctx, ch);
-      if (ch != cased)
+      ch = STRING_CHAR_AND_LENGTH (BYTE_POS_ADDR (pos_byte), len);
+      cased = case_character (ctx, ch);
+      if (cased != ch)
        {
-         last = start;
+         last = pos;
          if (first < 0)
-           first = start;
+           first = pos;
 
-         if (! multibyte)
-           {
-             MAKE_CHAR_UNIBYTE (cased);
-             FETCH_BYTE (start_byte) = cased;
-           }
-         else if (ASCII_CHAR_P (cased) && ASCII_CHAR_P (ch))
-           FETCH_BYTE (start_byte) = cased;
+         if (ASCII_CHAR_P (cased) && ASCII_CHAR_P (ch))
+           FETCH_BYTE (pos_byte) = cased;
          else
            {
-             int tolen = CHAR_BYTES (cased);
-             int j;
              unsigned char str[MAX_MULTIBYTE_LENGTH];
-
-             CHAR_STRING (cased, str);
-             if (len == tolen)
-               {
-                 /* Length is unchanged.  */
-                 for (j = 0; j < len; ++j)
-                   FETCH_BYTE (start_byte + j) = str[j];
-               }
+             int totlen = CHAR_STRING (cased, str);
+             if (len == totlen)
+               memcpy (BYTE_POS_ADDR (pos_byte), str, len);
              else
-               {
-                 /* Replace one character with the other,
-                    keeping text properties the same.  */
-                 replace_range_2 (start, start_byte,
-                                  start + 1, start_byte + len,
-                                  (char *) str, 1, tolen,
-                                  0);
-                 len = tolen;
-               }
+               /* Replace one character with the other(s), keeping text
+                  properties the same.  */
+               replace_range_2 (pos, pos_byte, pos + 1, pos_byte + len,
+                                (char *) str, 9, totlen, 0);
+             len = totlen;
            }
        }
-      start++;
-      start_byte += len;
+      pos++;
+      pos_byte += len;
     }
 
   if (PT != opoint)
-    TEMP_SET_PT_BOTH (opoint, opoint_byte);
+    TEMP_SET_PT_BOTH (opoint, CHAR_TO_BYTE (opoint));
+
+  *endp = last;
+  return first;
+}
+
+/* flag is CASE_UP, CASE_DOWN or CASE_CAPITALIZE or CASE_CAPITALIZE_UP.
+   b and e specify range of buffer to operate on. */
+static void
+casify_region (enum case_action flag, Lisp_Object b, Lisp_Object e)
+{
+  struct casing_context ctx;
+  ptrdiff_t start, end;
+
+  if (EQ (b, e))
+    /* Not modifying because nothing marked */
+    return;
+
+  validate_region (&b, &e);
+  start = XFASTINT (b);
+  end = XFASTINT (e);
+  modify_text (start, end);
+  record_change (start, end - start);
+  prepare_casing_context (&ctx, flag, true);
+
+  if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
+    start = do_casify_unibyte_region (&ctx, start, &end);
+  else
+    start = do_casify_multibyte_region (&ctx, start, &end);
 
-  if (first >= 0)
+  if (start >= 0)
     {
-      signal_after_change (first, last + 1 - first, last + 1 - first);
-      update_compositions (first, last + 1, CHECK_ALL);
+      signal_after_change (start, end + 1 - start, end + 1 - start);
+      update_compositions (start, end + 1, CHECK_ALL);
     }
 }
 



reply via email to

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