+/* A char table is a kind of vectorlike, with contents are like a
+ vector but with a few other slots. For some purposes, it makes
+ sense to handle a chartable with type struct Lisp_Vector. An
+ element of a char table can be any Lisp objects, but if it is a sub
+ char-table, we treat it a table that contains information of a
+ group of characters of the same charsets or a specific character of
+ a charset. A sub char-table has the same structure as a char table
+ except for that the former omits several slots at the tail. A sub
+ char table appears only in an element of a char table, and there's
+ no way to access it directly from Emacs Lisp program. */
+
+/* This is the number of slots that apply to characters or character
+ sets. The first 128 are for ASCII, the next 128 are for 8-bit
+ European characters, and the last 128 are for multibyte characters.
+ The first 256 are indexed by the code itself, but the last 128 are
+ indexed by (charset-id + 128). */
+#define CHAR_TABLE_ORDINARY_SLOTS 384
+
+/* This is the number of slots that apply to characters of ASCII and
+ 8-bit Europeans only. */
+#define CHAR_TABLE_SINGLE_BYTE_SLOTS 256
+
+/* This is the number of slots that every char table must have. This
+ counts the ordinary slots and the top, defalt, parent, and purpose
+ slots. */
+#define CHAR_TABLE_STANDARD_SLOTS (CHAR_TABLE_ORDINARY_SLOTS + 4)
+
+/* This is the number of slots that apply to position-code-1 and
+ position-code-2 of a multibyte character at the 2nd and 3rd level
+ sub char tables respectively. */
+#define SUB_CHAR_TABLE_ORDINARY_SLOTS 128
+
+/* This is the number of slots that every sub char table must have.
+ This counts the ordinary slots and the top and defalt slot. */
+#define SUB_CHAR_TABLE_STANDARD_SLOTS (SUB_CHAR_TABLE_ORDINARY_SLOTS + 2)
+
+/* Return the number of "extra" slots in the char table CT. */
+
+#define CHAR_TABLE_EXTRA_SLOTS(CT) \
+ (((CT)->size & PSEUDOVECTOR_SIZE_MASK) - CHAR_TABLE_STANDARD_SLOTS)
+
+/* Almost equivalent to Faref (CT, IDX) with optimization for ASCII
+ and 8-bit Europeans characters. For these characters, do not check
+ validity of CT. Do not follow parent. */
+#define CHAR_TABLE_REF(CT, IDX) \
+ ((IDX) < CHAR_TABLE_SINGLE_BYTE_SLOTS \
+ ? (!NILP (XCHAR_TABLE (CT)->contents[IDX]) \
+ ? XCHAR_TABLE (CT)->contents[IDX] \
+ : XCHAR_TABLE (CT)->defalt) \
+ : Faref (CT, make_number (IDX)))
+
+/* Equivalent to Faset (CT, IDX, VAL) with optimization for ASCII and
+ 8-bit Europeans characters. Do not check validity of CT. */
+#define CHAR_TABLE_SET(CT, IDX, VAL) \
+ do { \
+ if (XFASTINT (IDX) < CHAR_TABLE_SINGLE_BYTE_SLOTS) \
+ XCHAR_TABLE (CT)->contents[XFASTINT (IDX)] = VAL; \
+ else \
+ Faset (CT, IDX, VAL); \
+ } while (0)
+
+struct Lisp_Char_Table
+ {
+ /* This is the vector's size field, which also holds the
+ pseudovector type information. It holds the size, too.
+ The size counts the top, defalt, purpose, and parent slots.
+ The last three are not counted if this is a sub char table. */
+ EMACS_INT size;
+ struct Lisp_Vector *next;
+ /* This holds a flag to tell if this is a top level char table (t)
+ or a sub char table (nil). */
+ Lisp_Object top;
+ /* This holds a default value,
+ which is used whenever the value for a specific character is nil. */
+ Lisp_Object defalt;
+ /* This holds an actual value of each element. A sub char table
+ has only SUB_CHAR_TABLE_ORDINARY_SLOTS number of elements. */
+ Lisp_Object contents[CHAR_TABLE_ORDINARY_SLOTS];
+
+ /* A sub char table doesn't has the following slots. */
+
+ /* This points to another char table, which we inherit from
+ when the value for a specific character is nil.
+ The `defalt' slot takes precedence over this. */
+ Lisp_Object parent;
+ /* This should be a symbol which says what kind of use
+ this char-table is meant for.
+ Typically now the values can be `syntax-table' and `display-table'. */
+ Lisp_Object purpose;
+ /* These hold additional data. */
+ Lisp_Object extras[1];
+ };
+
+/* A boolvector is a kind of vectorlike, with contents are like a string. */
+struct Lisp_Bool_Vector
+ {
+ /* This is the vector's size field. It doesn't have the real size,
+ just the subtype information. */
+ EMACS_INT vector_size;
+ struct Lisp_Vector *next;
+ /* This is the size in bits. */
+ EMACS_INT size;
+ /* This contains the actual bits, packed into bytes. */
+ unsigned char data[1];
+ };
+