+Lisp_Object
+case_table_char (Lisp_Object ch, Lisp_Object table)
+{
+ Lisp_Object ct_char;
+ ct_char = get_char_table (XCHAR (ch), XCHAR_TABLE (table));
+ if (NILP (ct_char))
+ return ch;
+ else
+ return ct_char;
+}
+
+DEFUN ("get-case-table", Fget_case_table, 3, 3, 0, /*
+Return CHAR-CASE version of CHARACTER in CASE-TABLE.
+
+CHAR-CASE is either downcase or upcase.
+*/
+ (char_case, character, case_table))
+{
+ CHECK_CHAR (character);
+ CHECK_CASE_TABLE (case_table);
+ if (EQ (char_case, Qdowncase))
+ return case_table_char (character, XCASE_TABLE_DOWNCASE (case_table));
+ else if (EQ (char_case, Qupcase))
+ return case_table_char (character, XCASE_TABLE_UPCASE (case_table));
+ else
+ signal_simple_error ("Char case must be downcase or upcase", char_case);
+
+ return Qnil; /* Not reached. */
+}
+
+DEFUN ("put-case-table", Fput_case_table, 4, 4, 0, /*
+Set CHAR-CASE version of CHARACTER to be VALUE in CASE-TABLE.
+
+CHAR-CASE is either downcase or upcase.
+See also `put-case-table-pair'.
+*/
+ (char_case, character, value, case_table))
+{
+ CHECK_CHAR (character);
+ CHECK_CHAR (value);
+
+ if (EQ (char_case, Qdowncase))
+ {
+ Fput_char_table (character, value, XCASE_TABLE_DOWNCASE (case_table));
+ /* This one is not at all intuitive. */
+ Fput_char_table (character, value, XCASE_TABLE_UPCASE (case_table));
+ Fput_char_table (character, value, XCASE_TABLE_CANON (case_table));
+ Fput_char_table (value, value, XCASE_TABLE_CANON (case_table));
+ Fput_char_table (value, character, XCASE_TABLE_EQV (case_table));
+ Fput_char_table (character, value, XCASE_TABLE_EQV (case_table));
+ }
+ else if (EQ (char_case, Qupcase))
+ {
+ Fput_char_table (character, value, XCASE_TABLE_UPCASE (case_table));
+ Fput_char_table (character, character, XCASE_TABLE_DOWNCASE (case_table));
+ Fput_char_table (character, character, XCASE_TABLE_CANON (case_table));
+ Fput_char_table (value, character, XCASE_TABLE_CANON (case_table));
+ Fput_char_table (value, character, XCASE_TABLE_EQV (case_table));
+ Fput_char_table (character, value, XCASE_TABLE_EQV (case_table));
+ }
+ else
+ signal_simple_error ("Char case must be downcase or upcase", char_case);
+
+ return Qnil;
+}
+
+DEFUN ("put-case-table-pair", Fput_case_table_pair, 3, 3, 0, /*
+Make UC and LC a pair of inter-case-converting letters in CASE-TABLE.
+UC is an uppercase character and LC is a downcase character.
+*/
+ (uc, lc, case_table))
+{
+ CHECK_CHAR (uc);
+ CHECK_CHAR (lc);
+ CHECK_CASE_TABLE (case_table);
+
+ Fput_char_table (lc, lc, XCASE_TABLE_DOWNCASE (case_table));
+ Fput_char_table (uc, lc, XCASE_TABLE_UPCASE (case_table));
+ Fput_char_table (uc, lc, XCASE_TABLE_DOWNCASE (case_table));
+ Fput_char_table (lc, uc, XCASE_TABLE_UPCASE (case_table));
+
+ Fput_char_table (lc, lc, XCASE_TABLE_CANON (case_table));
+ Fput_char_table (uc, lc, XCASE_TABLE_CANON (case_table));
+ Fput_char_table (uc, lc, XCASE_TABLE_EQV (case_table));
+ Fput_char_table (lc, uc, XCASE_TABLE_EQV (case_table));
+ return Qnil;
+}
+
+DEFUN ("copy-case-table", Fcopy_case_table, 1, 1, 0, /*
+Return a new case table which is a copy of CASE-TABLE
+*/
+ (case_table))
+{
+ Lisp_Object new_obj;
+ CHECK_CASE_TABLE (case_table);
+
+ new_obj = allocate_case_table ();
+ XSET_CASE_TABLE_DOWNCASE
+ (new_obj, Fcopy_char_table (XCASE_TABLE_DOWNCASE (case_table)));
+ XSET_CASE_TABLE_UPCASE
+ (new_obj, Fcopy_char_table (XCASE_TABLE_UPCASE (case_table)));
+ XSET_CASE_TABLE_CANON
+ (new_obj, Fcopy_char_table (XCASE_TABLE_CANON (case_table)));
+ XSET_CASE_TABLE_EQV
+ (new_obj, Fcopy_char_table (XCASE_TABLE_EQV (case_table)));
+ return new_obj;