#ifndef EMACS_CHARACTER_H
#define EMACS_CHARACTER_H
+#include <verify.h>
+
/* character code 1st byte byte sequence
-------------- -------- -------------
0-7F 00..7F 0xxxxxxx
#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) \
} 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) \
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
*(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)
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. */
#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. */
#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) \
: (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 *);
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);
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);
#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 */