+/* Offset to add to a non-ASCII value when inserting it. */
+int nonascii_insert_offset;
+
+/* Translation table for converting non-ASCII unibyte characters
+ to multibyte codes, or nil. */
+Lisp_Object Vnonascii_translation_table;
+
+/* List of all possible generic characters. */
+Lisp_Object Vgeneric_character_list;
+
+#define min(X, Y) ((X) < (Y) ? (X) : (Y))
+#define max(X, Y) ((X) > (Y) ? (X) : (Y))
+\f
+void
+invalid_character (c)
+ int c;
+{
+ error ("Invalid character: 0%o, %d, 0x%x", c, c, c);
+}
+
+/* Parse string STR of length LENGTH and fetch information of a
+ character at STR. Set BYTES to the byte length the character
+ occupies, CHARSET, C1, C2 to proper values of the character. */
+
+#define SPLIT_MULTIBYTE_SEQ(str, length, bytes, charset, c1, c2) \
+ do { \
+ (c1) = *(str); \
+ (bytes) = BYTES_BY_CHAR_HEAD (c1); \
+ if ((bytes) == 1) \
+ (charset) = ASCII_BYTE_P (c1) ? CHARSET_ASCII : CHARSET_8_BIT_GRAPHIC; \
+ else if ((bytes) == 2) \
+ { \
+ if ((c1) == LEADING_CODE_8_BIT_CONTROL) \
+ (charset) = CHARSET_8_BIT_CONTROL, (c1) = (str)[1] - 0x20; \
+ else \
+ (charset) = (c1), (c1) = (str)[1] & 0x7F; \
+ } \
+ else if ((bytes) == 3) \
+ { \
+ if ((c1) < LEADING_CODE_PRIVATE_11) \
+ (charset) = (c1), (c1) = (str)[1] & 0x7F, (c2) = (str)[2] & 0x7F; \
+ else \
+ (charset) = (str)[1], (c1) = (str)[2] & 0x7F; \
+ } \
+ else \
+ (charset) = (str)[1], (c1) = (str)[2] & 0x7F, (c2) = (str)[3] & 0x7F; \
+ } while (0)
+
+/* 1 if CHARSET, C1, and C2 compose a valid character, else 0. */
+#define CHAR_COMPONENTS_VALID_P(charset, c1, c2) \
+ ((charset) == CHARSET_ASCII \
+ ? ((c1) >= 0 && (c1) <= 0x7F) \
+ : ((charset) == CHARSET_8_BIT_CONTROL \
+ ? ((c1) >= 0x80 && (c1) <= 0x9F) \
+ : ((charset) == CHARSET_8_BIT_GRAPHIC \
+ ? ((c1) >= 0x80 && (c1) <= 0xFF) \
+ : (CHARSET_DIMENSION (charset) == 1 \
+ ? ((c1) >= 0x20 && (c1) <= 0x7F) \
+ : ((c1) >= 0x20 && (c1) <= 0x7F \
+ && (c2) >= 0x20 && (c2) <= 0x7F)))))
+
+/* Store multi-byte form of the character C in STR. The caller should
+ allocate at least 4-byte area at STR in advance. Returns the
+ length of the multi-byte form. If C is an invalid character code,