]> code.delx.au - gnu-emacs/blobdiff - src/character.c
Add a note how to use `tramp-own-remote-path'
[gnu-emacs] / src / character.c
index ad78f512f43b57355143ede329bcbd4c808a0686..9f60aa718d573c7fa3e1040e3fe32bac07a54a07 100644 (file)
@@ -1,6 +1,6 @@
 /* Basic character support.
 
-Copyright (C) 2001-2015 Free Software Foundation, Inc.
+Copyright (C) 2001-2016 Free Software Foundation, Inc.
 Copyright (C) 1995, 1997, 1998, 2001 Electrotechnical Laboratory, JAPAN.
   Licensed to the Free Software Foundation.
 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
@@ -11,8 +11,8 @@ 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
@@ -25,29 +25,18 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 /* At first, see the document in `character.h' to understand the code
    in this file.  */
 
-#ifdef emacs
 #include <config.h>
-#endif
 
 #include <stdio.h>
 
-#ifdef emacs
-
 #include <sys/types.h>
 #include <intprops.h>
 #include "lisp.h"
 #include "character.h"
 #include "buffer.h"
-#include "charset.h"
 #include "composite.h"
 #include "disptab.h"
 
-#else  /* not emacs */
-
-#include "mulelib.h"
-
-#endif /* emacs */
-
 /* Char-table of information about which character to unify to which
    Unicode character.  Mainly used by the macro MAYBE_UNIFY_CHAR.  */
 Lisp_Object Vchar_unify_table;
@@ -303,9 +292,8 @@ char_width (int c, struct Lisp_Char_Table *dp)
            if (CHARACTERP (ch))
              {
                int w = CHAR_WIDTH (XFASTINT (ch));
-               if (INT_ADD_OVERFLOW (width, w))
+               if (INT_ADD_WRAPV (width, w, &width))
                  string_overflow ();
-               width += w;
              }
          }
     }
@@ -350,20 +338,16 @@ c_string_width (const unsigned char *str, ptrdiff_t len, int precision,
       int c = STRING_CHAR_AND_LENGTH (str + i_byte, bytes);
       ptrdiff_t thiswidth = char_width (c, dp);
 
-      if (precision <= 0)
-       {
-         if (INT_ADD_OVERFLOW (width, thiswidth))
-           string_overflow ();
-       }
-      else if (precision - width < thiswidth)
+      if (0 < precision && precision - width < thiswidth)
        {
          *nchars = i;
          *nbytes = i_byte;
          return width;
        }
+      if (INT_ADD_WRAPV (thiswidth, width, &width))
+       string_overflow ();
       i++;
       i_byte += bytes;
-      width += thiswidth;
   }
 
   if (precision > 0)
@@ -437,22 +421,16 @@ lisp_string_width (Lisp_Object string, ptrdiff_t precision,
          thiswidth = char_width (c, dp);
        }
 
-      if (precision <= 0)
-       {
-#ifdef emacs
-         if (INT_ADD_OVERFLOW (width, thiswidth))
-           string_overflow ();
-#endif
-       }
-      else if (precision - width < thiswidth)
+      if (0 < precision && precision - width < thiswidth)
        {
          *nchars = i;
          *nbytes = i_byte;
          return width;
        }
+      if (INT_ADD_WRAPV (thiswidth, width, &width))
+       string_overflow ();
       i += chars;
       i_byte += bytes;
-      width += thiswidth;
     }
 
   if (precision > 0)
@@ -658,9 +636,8 @@ count_size_as_multibyte (const unsigned char *str, ptrdiff_t len)
   for (bytes = 0; str < endp; str++)
     {
       int n = *str < 0x80 ? 1 : 2;
-      if (INT_ADD_OVERFLOW (bytes, n))
+      if (INT_ADD_WRAPV (bytes, n, &bytes))
         string_overflow ();
-      bytes += n;
     }
   return bytes;
 }
@@ -796,6 +773,7 @@ string_escape_byte8 (Lisp_Object string)
   ptrdiff_t nbytes = SBYTES (string);
   bool multibyte = STRING_MULTIBYTE (string);
   ptrdiff_t byte8_count;
+  ptrdiff_t thrice_byte8_count, uninit_nchars, uninit_nbytes;
   const unsigned char *src, *src_end;
   unsigned char *dst;
   Lisp_Object val;
@@ -809,23 +787,23 @@ string_escape_byte8 (Lisp_Object string)
   if (byte8_count == 0)
     return string;
 
+  if (INT_MULTIPLY_WRAPV (byte8_count, 3, &thrice_byte8_count))
+    string_overflow ();
+
   if (multibyte)
     {
-      if ((MOST_POSITIVE_FIXNUM - nchars) / 3 < byte8_count
-         || (STRING_BYTES_BOUND - nbytes) / 2 < byte8_count)
-       string_overflow ();
-
       /* Convert 2-byte sequence of byte8 chars to 4-byte octal.  */
-      val = make_uninit_multibyte_string (nchars + byte8_count * 3,
-                                         nbytes + byte8_count * 2);
+      if (INT_ADD_WRAPV (nchars, thrice_byte8_count, &uninit_nchars)
+         || INT_ADD_WRAPV (nbytes, 2 * byte8_count, &uninit_nbytes))
+       string_overflow ();
+      val = make_uninit_multibyte_string (uninit_nchars, uninit_nbytes);
     }
   else
     {
-      if ((STRING_BYTES_BOUND - nbytes) / 3 < byte8_count)
-       string_overflow ();
-
       /* Convert 1-byte sequence of byte8 chars to 4-byte octal.  */
-      val = make_uninit_string (nbytes + byte8_count * 3);
+      if (INT_ADD_WRAPV (thrice_byte8_count, nbytes, &uninit_nbytes))
+       string_overflow ();
+      val = make_uninit_string (uninit_nbytes);
     }
 
   src = SDATA (string);
@@ -841,7 +819,7 @@ string_escape_byte8 (Lisp_Object string)
          {
            c = STRING_CHAR_ADVANCE (src);
            c = CHAR_TO_BYTE8 (c);
-           dst += sprintf ((char *) dst, "\\%03o", c);
+           dst += sprintf ((char *) dst, "\\%03o", c + 0u);
          }
        else
          while (len--) *dst++ = *src++;
@@ -851,7 +829,7 @@ string_escape_byte8 (Lisp_Object string)
       {
        c = *src++;
        if (c >= 0x80)
-         dst += sprintf ((char *) dst, "\\%03o", c);
+         dst += sprintf ((char *) dst, "\\%03o", c + 0u);
        else
          *dst++ = c;
       }
@@ -982,10 +960,7 @@ character is not ASCII nor 8-bit character, an error is signaled.  */)
   return make_number (c);
 }
 
-#ifdef emacs
-
-/* Return 'true' if C is an alphabetic character as defined by its
-   Unicode properties.  */
+/* Return true if C is an alphabetic character.  */
 bool
 alphabeticp (int c)
 {
@@ -1008,8 +983,7 @@ alphabeticp (int c)
          || gen_cat == UNICODE_CATEGORY_Nl);
 }
 
-/* Return 'true' if C is an decimal-number character as defined by its
-   Unicode properties.  */
+/* Return true if C is a decimal-number character.  */
 bool
 decimalnump (int c)
 {
@@ -1022,6 +996,39 @@ decimalnump (int c)
   return gen_cat == UNICODE_CATEGORY_Nd;
 }
 
+/* Return true if C is a graphic character.  */
+bool
+graphicp (int c)
+{
+  Lisp_Object category = CHAR_TABLE_REF (Vunicode_category_table, c);
+  if (! INTEGERP (category))
+    return false;
+  EMACS_INT gen_cat = XINT (category);
+
+  /* See UTS #18.  */
+  return (!(gen_cat == UNICODE_CATEGORY_Zs /* space separator */
+           || gen_cat == UNICODE_CATEGORY_Zl /* line separator */
+           || gen_cat == UNICODE_CATEGORY_Zp /* paragraph separator */
+           || gen_cat == UNICODE_CATEGORY_Cc /* control */
+           || gen_cat == UNICODE_CATEGORY_Cs /* surrogate */
+           || gen_cat == UNICODE_CATEGORY_Cn)); /* unassigned */
+}
+
+/* Return true if C is a printable character.  */
+bool
+printablep (int c)
+{
+  Lisp_Object category = CHAR_TABLE_REF (Vunicode_category_table, c);
+  if (! INTEGERP (category))
+    return false;
+  EMACS_INT gen_cat = XINT (category);
+
+  /* See UTS #18.  */
+  return (!(gen_cat == UNICODE_CATEGORY_Cc /* control */
+           || gen_cat == UNICODE_CATEGORY_Cs /* surrogate */
+           || gen_cat == UNICODE_CATEGORY_Cn)); /* unassigned */
+}
+
 void
 syms_of_character (void)
 {
@@ -1101,5 +1108,3 @@ See The Unicode Standard for the meaning of those values.  */);
   /* The correct char-table is setup in characters.el.  */
   Vunicode_category_table = Qnil;
 }
-
-#endif /* emacs */