]> code.delx.au - gnu-emacs/blobdiff - src/casefiddle.c
Ibuffer: Mark locked buffers
[gnu-emacs] / src / casefiddle.c
index 5a40790f87f7f84a8381d24eb6d868d0a5c91968..6114a6f7857a83efa236ccfe22ef12745d075a86 100644 (file)
@@ -1,14 +1,14 @@
 /* GNU Emacs case conversion functions.
 
-Copyright (C) 1985, 1994, 1997-1999, 2001-2013 Free Software Foundation,
+Copyright (C) 1985, 1994, 1997-1999, 2001-2016 Free Software Foundation,
 Inc.
 
 This file is part of GNU Emacs.
 
 GNU Emacs is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
+the Free Software Foundation, either version 3 of the License, or (at
+your option) any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -30,8 +30,6 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "keymap.h"
 
 enum case_action {CASE_UP, CASE_DOWN, CASE_CAPITALIZE, CASE_CAPITALIZE_UP};
-
-Lisp_Object Qidentity;
 \f
 static Lisp_Object
 casify_object (enum case_action flag, Lisp_Object obj)
@@ -102,7 +100,7 @@ casify_object (enum case_action flag, Lisp_Object obj)
            inword = (SYNTAX (c) == Sword);
          if (c != c1)
            {
-                 MAKE_CHAR_UNIBYTE (c);
+             MAKE_CHAR_UNIBYTE (c);
              /* If the char can't be converted to a valid byte, just don't
                 change it.  */
              if (c >= 0 && c < 256)
@@ -116,15 +114,15 @@ casify_object (enum case_action flag, Lisp_Object obj)
       ptrdiff_t i, i_byte, size = SCHARS (obj);
       int len;
       USE_SAFE_ALLOCA;
-      ptrdiff_t o_size = (size < STRING_BYTES_BOUND / MAX_MULTIBYTE_LENGTH
-                         ? size * MAX_MULTIBYTE_LENGTH
-                         : STRING_BYTES_BOUND);
+      ptrdiff_t o_size;
+      if (INT_MULTIPLY_WRAPV (size, MAX_MULTIBYTE_LENGTH, &o_size))
+       o_size = PTRDIFF_MAX;
       unsigned char *dst = SAFE_ALLOCA (o_size);
       unsigned char *o = dst;
 
       for (i = i_byte = 0; i < size; i++, i_byte += len)
        {
-         if (o_size - (o - dst) < MAX_MULTIBYTE_LENGTH)
+         if (o_size - MAX_MULTIBYTE_LENGTH < o - dst)
            string_overflow ();
          c = STRING_CHAR_AND_LENGTH (SDATA (obj) + i_byte, len);
          if (inword && flag != CASE_CAPITALIZE_UP)
@@ -198,7 +196,7 @@ casify_region (enum case_action flag, Lisp_Object b, Lisp_Object e)
   ptrdiff_t start_byte;
 
   /* Position of first and last changes.  */
-  ptrdiff_t first = -1, last IF_LINT (= 0);
+  ptrdiff_t first = -1, last;
 
   ptrdiff_t opoint = PT;
   ptrdiff_t opoint_byte = PT_BYTE;
@@ -296,26 +294,58 @@ casify_region (enum case_action flag, Lisp_Object b, Lisp_Object e)
     }
 }
 
-DEFUN ("upcase-region", Fupcase_region, Supcase_region, 2, 2, "r",
+DEFUN ("upcase-region", Fupcase_region, Supcase_region, 2, 3,
+       "(list (region-beginning) (region-end) (region-noncontiguous-p))",
        doc: /* Convert the region to upper case.  In programs, wants two arguments.
 These arguments specify the starting and ending character numbers of
 the region to operate on.  When used as a command, the text between
 point and the mark is operated on.
 See also `capitalize-region'.  */)
-  (Lisp_Object beg, Lisp_Object end)
+  (Lisp_Object beg, Lisp_Object end, Lisp_Object region_noncontiguous_p)
 {
-  casify_region (CASE_UP, beg, end);
+  Lisp_Object bounds = Qnil;
+
+  if (!NILP (region_noncontiguous_p))
+    {
+      bounds = call1 (Fsymbol_value (intern ("region-extract-function")),
+                     intern ("bounds"));
+
+      while (CONSP (bounds))
+       {
+         casify_region (CASE_UP, XCAR (XCAR (bounds)), XCDR (XCAR (bounds)));
+         bounds = XCDR (bounds);
+       }
+    }
+  else
+    casify_region (CASE_UP, beg, end);
+
   return Qnil;
 }
 
-DEFUN ("downcase-region", Fdowncase_region, Sdowncase_region, 2, 2, "r",
+DEFUN ("downcase-region", Fdowncase_region, Sdowncase_region, 2, 3,
+       "(list (region-beginning) (region-end) (region-noncontiguous-p))",
        doc: /* Convert the region to lower case.  In programs, wants two arguments.
 These arguments specify the starting and ending character numbers of
 the region to operate on.  When used as a command, the text between
 point and the mark is operated on.  */)
-  (Lisp_Object beg, Lisp_Object end)
+  (Lisp_Object beg, Lisp_Object end, Lisp_Object region_noncontiguous_p)
 {
-  casify_region (CASE_DOWN, beg, end);
+  Lisp_Object bounds = Qnil;
+
+  if (!NILP (region_noncontiguous_p))
+    {
+      bounds = call1 (Fsymbol_value (intern ("region-extract-function")),
+                     intern ("bounds"));
+
+      while (CONSP (bounds))
+       {
+         casify_region (CASE_DOWN, XCAR (XCAR (bounds)), XCDR (XCAR (bounds)));
+         bounds = XCDR (bounds);
+       }
+    }
+  else
+    casify_region (CASE_DOWN, beg, end);
+
   return Qnil;
 }
 
@@ -365,7 +395,11 @@ operate_on_word (Lisp_Object arg, ptrdiff_t *newpoint)
 }
 
 DEFUN ("upcase-word", Fupcase_word, Supcase_word, 1, 1, "p",
-       doc: /* Convert following word (or ARG words) to upper case, moving over.
+       doc: /* Convert to upper case from point to end of word, moving over.
+
+If point is in the middle of a word, the part of that word before point
+is ignored when moving forward.
+
 With negative argument, convert previous words but do not move.
 See also `capitalize-word'.  */)
   (Lisp_Object arg)
@@ -380,7 +414,11 @@ See also `capitalize-word'.  */)
 }
 
 DEFUN ("downcase-word", Fdowncase_word, Sdowncase_word, 1, 1, "p",
-       doc: /* Convert following word (or ARG words) to lower case, moving over.
+       doc: /* Convert to lower case from point to end of word, moving over.
+
+If point is in the middle of a word, the part of that word before point
+is ignored when moving forward.
+
 With negative argument, convert previous words but do not move.  */)
   (Lisp_Object arg)
 {
@@ -394,9 +432,14 @@ With negative argument, convert previous words but do not move.  */)
 }
 
 DEFUN ("capitalize-word", Fcapitalize_word, Scapitalize_word, 1, 1, "p",
-       doc: /* Capitalize the following word (or ARG words), moving over.
+       doc: /* Capitalize from point to the end of word, moving over.
+With numerical argument ARG, capitalize the next ARG-1 words as well.
 This gives the word(s) a first character in upper case
 and the rest lower case.
+
+If point is in the middle of a word, the part of that word before point
+is ignored when moving forward.
+
 With negative argument, capitalize previous words but do not move.  */)
   (Lisp_Object arg)
 {