Fix an off by one error in c-guess-basic-syntax CASE 5B.1.
[bpt/emacs.git] / src / character.h
index 7a75ac1..5ae6cb8 100644 (file)
@@ -23,6 +23,8 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #ifndef EMACS_CHARACTER_H
 #define EMACS_CHARACTER_H
 
+#include <verify.h>
+
 /* character code      1st byte   byte sequence
    --------------      --------   -------------
         0-7F           00..7F     0xxxxxxx
@@ -102,13 +104,13 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #define make_char(c) make_number (c)
 
 /* Nonzero iff C is an ASCII byte.  */
-#define ASCII_BYTE_P(c) ((unsigned) (c) < 0x80)
+#define ASCII_BYTE_P(c) UNSIGNED_CMP (c, <, 0x80)
 
 /* Nonzero iff X is a character.  */
 #define CHARACTERP(x) (NATNUMP (x) && XFASTINT (x) <= MAX_CHAR)
 
-/* Nonzero iff C is valid as a character code.  GENERICP is not used.  */
-#define CHAR_VALID_P(c, genericp) ((unsigned) (c) <= MAX_CHAR)
+/* Nonzero iff C is valid as a character code.  */
+#define CHAR_VALID_P(c) UNSIGNED_CMP (c, <=, MAX_CHAR)
 
 /* Check if Lisp object X is a character or not.  */
 #define CHECK_CHARACTER(x) \
@@ -129,7 +131,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
   } while (0)
 
 /* Nonzero iff C is a character of code less than 0x100.  */
-#define SINGLE_BYTE_CHAR_P(c) ((unsigned) (c) < 0x100)
+#define SINGLE_BYTE_CHAR_P(c) UNSIGNED_CMP (c, <, 0x100)
 
 /* Nonzero if character C has a printable glyph.  */
 #define CHAR_PRINTABLE_P(c)    \
@@ -161,19 +163,19 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
    Returns the length of the multibyte form.  */
 
 #define CHAR_STRING(c, p)                      \
-  ((unsigned) (c) <= MAX_1_BYTE_CHAR           \
+  (UNSIGNED_CMP (c, <=, MAX_1_BYTE_CHAR)       \
    ? ((p)[0] = (c),                            \
       1)                                       \
-   : (unsigned) (c) <= MAX_2_BYTE_CHAR         \
+   : UNSIGNED_CMP (c, <=, MAX_2_BYTE_CHAR)     \
    ? ((p)[0] = (0xC0 | ((c) >> 6)),            \
       (p)[1] = (0x80 | ((c) & 0x3F)),          \
       2)                                       \
-   : (unsigned) (c) <= MAX_3_BYTE_CHAR         \
+   : UNSIGNED_CMP (c, <=, MAX_3_BYTE_CHAR)     \
    ? ((p)[0] = (0xE0 | ((c) >> 12)),           \
       (p)[1] = (0x80 | (((c) >> 6) & 0x3F)),   \
       (p)[2] = (0x80 | ((c) & 0x3F)),          \
       3)                                       \
-   : char_string ((unsigned) c, p))
+   : verify_expr (sizeof (c) <= sizeof (unsigned), char_string (c, p)))
 
 /* Store multibyte form of byte B in P.  The caller should allocate at
    least MAX_MULTIBYTE_LENGTH bytes area at P in advance.  Returns the
@@ -201,7 +203,10 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
        *(p)++ = (0x80 | (((c) >> 6) & 0x3F)),  \
        *(p)++ = (0x80 | ((c) & 0x3F));         \
     else                                       \
-      (p) += char_string ((c), (p));           \
+      {                                                \
+       verify (sizeof (c) <= sizeof (unsigned));       \
+       (p) += char_string (c, p);              \
+      }                                                \
   } while (0)
 
 
@@ -544,13 +549,23 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
        Lisp_Object val;                                \
        val = CHAR_TABLE_REF (Vchar_unify_table, c);    \
        if (INTEGERP (val))                             \
-         c = XINT (val);                               \
+         c = XFASTINT (val);                           \
        else if (! NILP (val))                          \
          c = maybe_unify_char (c, val);                \
       }                                                        \
   } while (0)
 
 
+/* Return a non-outlandish value for the tab width.  */
+
+#define SANE_TAB_WIDTH(buf) \
+  sanitize_tab_width (XFASTINT (BVAR (buf, tab_width)))
+static inline int
+sanitize_tab_width (EMACS_INT width)
+{
+  return 0 < width && width <= 1000 ? width : 8;
+}
+
 /* Return the width of ASCII character C.  The width is measured by
    how many columns C will occupy on the screen when displayed in the
    current buffer.  */
@@ -558,12 +573,20 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #define ASCII_CHAR_WIDTH(c)                                            \
   (c < 0x20                                                            \
    ? (c == '\t'                                                                \
-      ? XFASTINT (BVAR (current_buffer, tab_width))                            \
+      ? SANE_TAB_WIDTH (current_buffer)                                        \
       : (c == '\n' ? 0 : (NILP (BVAR (current_buffer, ctl_arrow)) ? 4 : 2)))   \
    : (c < 0x7f                                                         \
       ? 1                                                              \
       : ((NILP (BVAR (current_buffer, ctl_arrow)) ? 4 : 2))))
 
+/* Return a non-outlandish value for a character width.  */
+
+static inline int
+sanitize_char_width (EMACS_INT width)
+{
+  return 0 <= width && width <= 1000 ? width : 1000;
+}
+
 /* Return the width of character C.  The width is measured by how many
    columns C will occupy on the screen when displayed in the current
    buffer.  */
@@ -571,9 +594,9 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #define CHAR_WIDTH(c)          \
   (ASCII_CHAR_P (c)            \
    ? ASCII_CHAR_WIDTH (c)      \
-   : XINT (CHAR_TABLE_REF (Vchar_width_table, c)))
+   : sanitize_char_width (XINT (CHAR_TABLE_REF (Vchar_width_table, c))))
 
-/* If C is a variation selector, return the index numnber of the
+/* If C is a variation selector, return the index of the
    variation selector (1..256).  Otherwise, return 0.  */
 
 #define CHAR_VARIATION_SELECTOR_P(c)           \
@@ -592,6 +615,45 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
    : (c) <= 0xDFFF ? 2                 \
    : 0)
 
+/* Data type for Unicode general category.
+
+   The order of members must be in sync with the 8th element of the
+   member of unidata-prop-alist (in admin/unidata/unidata-getn.el) for
+   Unicode character property `general-category'.  */
+
+typedef enum {
+  UNICODE_CATEGORY_UNKNOWN = 0,
+  UNICODE_CATEGORY_Lu,
+  UNICODE_CATEGORY_Ll,
+  UNICODE_CATEGORY_Lt,
+  UNICODE_CATEGORY_Lm,
+  UNICODE_CATEGORY_Lo,
+  UNICODE_CATEGORY_Mn,
+  UNICODE_CATEGORY_Mc,
+  UNICODE_CATEGORY_Me,
+  UNICODE_CATEGORY_Nd,
+  UNICODE_CATEGORY_Nl,
+  UNICODE_CATEGORY_No,
+  UNICODE_CATEGORY_Pc,
+  UNICODE_CATEGORY_Pd,
+  UNICODE_CATEGORY_Ps,
+  UNICODE_CATEGORY_Pe,
+  UNICODE_CATEGORY_Pi,
+  UNICODE_CATEGORY_Pf,
+  UNICODE_CATEGORY_Po,
+  UNICODE_CATEGORY_Sm,
+  UNICODE_CATEGORY_Sc,
+  UNICODE_CATEGORY_Sk,
+  UNICODE_CATEGORY_So,
+  UNICODE_CATEGORY_Zs,
+  UNICODE_CATEGORY_Zl,
+  UNICODE_CATEGORY_Zp,
+  UNICODE_CATEGORY_Cc,
+  UNICODE_CATEGORY_Cf,
+  UNICODE_CATEGORY_Cs,
+  UNICODE_CATEGORY_Co,
+  UNICODE_CATEGORY_Cn
+} unicode_category_t;
 
 extern int char_resolve_modifier_mask (int);
 extern int char_string (unsigned, unsigned char *);
@@ -602,7 +664,7 @@ extern int translate_char (Lisp_Object, int c);
 extern int char_printable_p (int c);
 extern void parse_str_as_multibyte (const unsigned char *,
                                    EMACS_INT, EMACS_INT *, EMACS_INT *);
-extern EMACS_INT parse_str_to_multibyte (const unsigned char *, EMACS_INT);
+extern EMACS_INT count_size_as_multibyte (const unsigned char *, EMACS_INT);
 extern EMACS_INT str_as_multibyte (unsigned char *, EMACS_INT, EMACS_INT,
                             EMACS_INT *);
 extern EMACS_INT str_to_multibyte (unsigned char *, EMACS_INT, EMACS_INT);
@@ -612,10 +674,10 @@ extern EMACS_INT str_to_unibyte (const unsigned char *, unsigned char *,
 extern EMACS_INT strwidth (const char *, EMACS_INT);
 extern EMACS_INT c_string_width (const unsigned char *, EMACS_INT, int,
                                 EMACS_INT *, EMACS_INT *);
-extern EMACS_INT lisp_string_width (Lisp_Object, int,
+extern EMACS_INT lisp_string_width (Lisp_Object, EMACS_INT,
                                    EMACS_INT *, EMACS_INT *);
 
-extern Lisp_Object Qcharacterp, Qauto_fill_chars;
+extern Lisp_Object Qcharacterp;
 extern Lisp_Object Vchar_unify_table;
 extern Lisp_Object string_escape_byte8 (Lisp_Object);
 
@@ -623,7 +685,4 @@ extern Lisp_Object string_escape_byte8 (Lisp_Object);
 #define GET_TRANSLATION_TABLE(id) \
   (XCDR(XVECTOR(Vtranslation_table_vector)->contents[(id)]))
 
-#define DEFSYM(sym, name)      \
-  do { (sym) = intern_c_string ((name)); staticpro (&(sym)); } while (0)
-
 #endif /* EMACS_CHARACTER_H */