1 /* Functions to handle multilingual characters.
2 Copyright (C) 1992, 1995 Free Software Foundation, Inc.
3 Copyright (C) 1995 Sun Microsystems, Inc.
4 Copyright (C) 1999,2000,2001,2002,2003,2004,2008,2009 MORIOKA Tomohiko
6 This file is part of XEmacs.
8 XEmacs is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 2, or (at your option) any
13 XEmacs is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License
19 along with XEmacs; see the file COPYING. If not, write to
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
23 /* Rewritten by Ben Wing <ben@xemacs.org>. */
25 /* Rewritten by MORIOKA Tomohiko <tomo@m17n.org> for XEmacs CHISE. */
44 /* The various pre-defined charsets. */
46 Lisp_Object Vcharset_ascii;
47 Lisp_Object Vcharset_control_1;
48 Lisp_Object Vcharset_latin_iso8859_1;
49 Lisp_Object Vcharset_latin_iso8859_2;
50 Lisp_Object Vcharset_latin_iso8859_3;
51 Lisp_Object Vcharset_latin_iso8859_4;
52 Lisp_Object Vcharset_thai_tis620;
53 Lisp_Object Vcharset_greek_iso8859_7;
54 Lisp_Object Vcharset_arabic_iso8859_6;
55 Lisp_Object Vcharset_hebrew_iso8859_8;
56 Lisp_Object Vcharset_katakana_jisx0201;
57 Lisp_Object Vcharset_latin_jisx0201;
58 Lisp_Object Vcharset_cyrillic_iso8859_5;
59 Lisp_Object Vcharset_latin_iso8859_9;
60 /* Lisp_Object Vcharset_japanese_jisx0208_1978; */
61 Lisp_Object Vcharset_chinese_gb2312;
62 Lisp_Object Vcharset_chinese_gb12345;
63 Lisp_Object Vcharset_japanese_jisx0208;
64 Lisp_Object Vcharset_japanese_jisx0208_1990;
65 Lisp_Object Vcharset_korean_ksc5601;
66 Lisp_Object Vcharset_japanese_jisx0212;
67 Lisp_Object Vcharset_chinese_cns11643_1;
68 Lisp_Object Vcharset_chinese_cns11643_2;
70 Lisp_Object Vcharset_system_char_id;
71 Lisp_Object Vcharset_ucs;
72 Lisp_Object Vcharset_ucs_bmp;
73 Lisp_Object Vcharset_ucs_smp;
74 Lisp_Object Vcharset_ucs_sip;
75 Lisp_Object Vcharset_latin_viscii;
76 Lisp_Object Vcharset_latin_tcvn5712;
77 Lisp_Object Vcharset_latin_viscii_lower;
78 Lisp_Object Vcharset_latin_viscii_upper;
79 Lisp_Object Vcharset_jis_x0208;
80 Lisp_Object Vcharset_chinese_big5;
81 Lisp_Object Vcharset_ethiopic_ucs;
83 Lisp_Object Vcharset_chinese_big5_1;
84 Lisp_Object Vcharset_chinese_big5_2;
86 #ifdef ENABLE_COMPOSITE_CHARS
87 Lisp_Object Vcharset_composite;
89 /* Hash tables for composite chars. One maps string representing
90 composed chars to their equivalent chars; one goes the
92 Lisp_Object Vcomposite_char_char2string_hash_table;
93 Lisp_Object Vcomposite_char_string2char_hash_table;
95 static int composite_char_row_next;
96 static int composite_char_col_next;
98 #endif /* ENABLE_COMPOSITE_CHARS */
100 struct charset_lookup *chlook;
102 static const struct lrecord_description charset_lookup_description_1[] = {
103 { XD_LISP_OBJECT_ARRAY, offsetof (struct charset_lookup, charset_by_leading_byte),
105 NUM_LEADING_BYTES+4*128
112 static const struct struct_description charset_lookup_description = {
113 sizeof (struct charset_lookup),
114 charset_lookup_description_1
118 /* Table of number of bytes in the string representation of a character
119 indexed by the first byte of that representation.
121 rep_bytes_by_first_byte(c) is more efficient than the equivalent
122 canonical computation:
124 XCHARSET_REP_BYTES (CHARSET_BY_LEADING_BYTE (c)) */
126 const Bytecount rep_bytes_by_first_byte[0xA0] =
127 { /* 0x00 - 0x7f are for straight ASCII */
128 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
129 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
130 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
131 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
132 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
133 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
134 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
135 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
136 /* 0x80 - 0x8f are for Dimension-1 official charsets */
138 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3,
140 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
142 /* 0x90 - 0x9d are for Dimension-2 official charsets */
143 /* 0x9e is for Dimension-1 private charsets */
144 /* 0x9f is for Dimension-2 private charsets */
145 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4
151 int decoding_table_check_elements (Lisp_Object v, int dim, int ccs_len);
153 decoding_table_check_elements (Lisp_Object v, int dim, int ccs_len)
157 if (XVECTOR_LENGTH (v) > ccs_len)
160 for (i = 0; i < XVECTOR_LENGTH (v); i++)
162 Lisp_Object c = XVECTOR_DATA(v)[i];
164 if (!NILP (c) && !CHARP (c))
168 int ret = decoding_table_check_elements (c, dim - 1, ccs_len);
180 decoding_table_put_char (Lisp_Object ccs,
181 int code_point, Lisp_Object character)
184 Lisp_Object table1 = XCHARSET_DECODING_TABLE (ccs);
185 int dim = XCHARSET_DIMENSION (ccs);
188 XCHARSET_DECODING_TABLE (ccs)
189 = put_ccs_octet_table (table1, ccs, code_point, character);
193 = get_ccs_octet_table (table1, ccs, (unsigned char)(code_point >> 8));
195 table2 = put_ccs_octet_table (table2, ccs,
196 (unsigned char)code_point, character);
197 XCHARSET_DECODING_TABLE (ccs)
198 = put_ccs_octet_table (table1, ccs,
199 (unsigned char)(code_point >> 8), table2);
204 = get_ccs_octet_table (table1, ccs, (unsigned char)(code_point >> 16));
206 = get_ccs_octet_table (table2, ccs, (unsigned char)(code_point >> 8));
208 table3 = put_ccs_octet_table (table3, ccs,
209 (unsigned char)code_point, character);
210 table2 = put_ccs_octet_table (table2, ccs,
211 (unsigned char)(code_point >> 8), table3);
212 XCHARSET_DECODING_TABLE (ccs)
213 = put_ccs_octet_table (table1, ccs,
214 (unsigned char)(code_point >> 16), table2);
216 else /* if (dim == 4) */
219 = get_ccs_octet_table (table1, ccs, (unsigned char)(code_point >> 24));
221 = get_ccs_octet_table (table2, ccs, (unsigned char)(code_point >> 16));
223 = get_ccs_octet_table (table3, ccs, (unsigned char)(code_point >> 8));
225 table4 = put_ccs_octet_table (table4, ccs,
226 (unsigned char)code_point, character);
227 table3 = put_ccs_octet_table (table3, ccs,
228 (unsigned char)(code_point >> 8), table4);
229 table2 = put_ccs_octet_table (table2, ccs,
230 (unsigned char)(code_point >> 16), table3);
231 XCHARSET_DECODING_TABLE (ccs)
232 = put_ccs_octet_table (table1, ccs,
233 (unsigned char)(code_point >> 24), table2);
236 Lisp_Object v = XCHARSET_DECODING_TABLE (ccs);
237 int dim = XCHARSET_DIMENSION (ccs);
238 int byte_offset = XCHARSET_BYTE_OFFSET (ccs);
241 int ccs_len = XVECTOR_LENGTH (v);
246 i = ((code_point >> (8 * dim)) & 255) - byte_offset;
247 nv = XVECTOR_DATA(v)[i];
252 if (EQ (nv, character))
255 nv = (XVECTOR_DATA(v)[i] = make_vector (ccs_len, Qnil));
262 XVECTOR_DATA(v)[i] = character;
267 put_char_ccs_code_point (Lisp_Object character,
268 Lisp_Object ccs, Lisp_Object value)
270 if ( !( EQ (XCHARSET_NAME (ccs), Qrep_ucs)
271 && INTP (value) && (XINT (value) < 0xF0000)
272 && XCHAR (character) == XINT (value) )
275 Lisp_Object v = XCHARSET_DECODING_TABLE (ccs);
279 { /* obsolete representation: value must be a list of bytes */
280 Lisp_Object ret = Fcar (value);
284 signal_simple_error ("Invalid value for coded-charset", value);
285 code_point = XINT (ret);
286 if (XCHARSET_GRAPHIC (ccs) == 1)
294 signal_simple_error ("Invalid value for coded-charset",
298 signal_simple_error ("Invalid value for coded-charset",
301 if (XCHARSET_GRAPHIC (ccs) == 1)
303 code_point = (code_point << 8) | j;
306 value = make_int (code_point);
308 else if (INTP (value))
310 code_point = XINT (value);
311 if (XCHARSET_GRAPHIC (ccs) == 1)
313 code_point &= 0x7F7F7F7F;
314 value = make_int (code_point);
318 signal_simple_error ("Invalid value for coded-charset", value);
322 Lisp_Object cpos = Fget_char_attribute (character, ccs, Qnil);
325 decoding_table_remove_char (ccs, XINT (cpos));
328 decoding_table_put_char (ccs, code_point, character);
334 remove_char_ccs (Lisp_Object character, Lisp_Object ccs)
336 Lisp_Object decoding_table = XCHARSET_DECODING_TABLE (ccs);
337 Lisp_Object encoding_table = XCHARSET_ENCODING_TABLE (ccs);
339 if (VECTORP (decoding_table))
341 Lisp_Object cpos = Fget_char_attribute (character, ccs, Qnil);
345 decoding_table_remove_char (ccs, XINT (cpos));
348 if (CHAR_TABLEP (encoding_table))
350 put_char_id_table (XCHAR_TABLE(encoding_table), character, Qunbound);
358 int leading_code_private_11;
361 Lisp_Object Qcharsetp;
363 /* Qdoc_string, Qdimension, Qchars defined in general.c */
364 Lisp_Object Qregistry, Qfinal, Qgraphic;
365 Lisp_Object Qdirection;
366 Lisp_Object Qreverse_direction_charset;
367 Lisp_Object Qleading_byte;
368 Lisp_Object Qshort_name, Qlong_name;
371 Lisp_Object Qto_iso_ir;
372 Lisp_Object Qpartial;
373 Lisp_Object Qmin_code, Qmax_code, Qcode_offset;
374 Lisp_Object Qmother, Qconversion, Q94x60, Q94x94x60, Qbig5_1, Qbig5_2;
391 /* Qrep_jis_x0208_1978, */
409 Qvietnamese_viscii_lower,
410 Qvietnamese_viscii_upper,
420 Lisp_Object Ql2r, Qr2l;
422 Lisp_Object Vcharset_hash_table;
424 /* Composite characters are characters constructed by overstriking two
425 or more regular characters.
427 1) The old Mule implementation involves storing composite characters
428 in a buffer as a tag followed by all of the actual characters
429 used to make up the composite character. I think this is a bad
430 idea; it greatly complicates code that wants to handle strings
431 one character at a time because it has to deal with the possibility
432 of great big ungainly characters. It's much more reasonable to
433 simply store an index into a table of composite characters.
435 2) The current implementation only allows for 16,384 separate
436 composite characters over the lifetime of the XEmacs process.
437 This could become a potential problem if the user
438 edited lots of different files that use composite characters.
439 Due to FSF bogosity, increasing the number of allowable
440 composite characters under Mule would decrease the number
441 of possible faces that can exist. Mule already has shrunk
442 this to 2048, and further shrinkage would become uncomfortable.
443 No such problems exist in XEmacs.
445 Composite characters could be represented as 0x80 C1 C2 C3,
446 where each C[1-3] is in the range 0xA0 - 0xFF. This allows
447 for slightly under 2^20 (one million) composite characters
448 over the XEmacs process lifetime, and you only need to
449 increase the size of a Mule character from 19 to 21 bits.
450 Or you could use 0x80 C1 C2 C3 C4, allowing for about
451 85 million (slightly over 2^26) composite characters. */
454 /************************************************************************/
455 /* Basic Emchar functions */
456 /************************************************************************/
458 /* Convert a non-ASCII Mule character C into a one-character Mule-encoded
459 string in STR. Returns the number of bytes stored.
460 Do not call this directly. Use the macro set_charptr_emchar() instead.
464 non_ascii_set_charptr_emchar (Bufbyte *str, Emchar c)
479 else if ( c <= 0x7ff )
481 *p++ = (c >> 6) | 0xc0;
482 *p++ = (c & 0x3f) | 0x80;
484 else if ( c <= 0xffff )
486 *p++ = (c >> 12) | 0xe0;
487 *p++ = ((c >> 6) & 0x3f) | 0x80;
488 *p++ = (c & 0x3f) | 0x80;
490 else if ( c <= 0x1fffff )
492 *p++ = (c >> 18) | 0xf0;
493 *p++ = ((c >> 12) & 0x3f) | 0x80;
494 *p++ = ((c >> 6) & 0x3f) | 0x80;
495 *p++ = (c & 0x3f) | 0x80;
497 else if ( c <= 0x3ffffff )
499 *p++ = (c >> 24) | 0xf8;
500 *p++ = ((c >> 18) & 0x3f) | 0x80;
501 *p++ = ((c >> 12) & 0x3f) | 0x80;
502 *p++ = ((c >> 6) & 0x3f) | 0x80;
503 *p++ = (c & 0x3f) | 0x80;
507 *p++ = (c >> 30) | 0xfc;
508 *p++ = ((c >> 24) & 0x3f) | 0x80;
509 *p++ = ((c >> 18) & 0x3f) | 0x80;
510 *p++ = ((c >> 12) & 0x3f) | 0x80;
511 *p++ = ((c >> 6) & 0x3f) | 0x80;
512 *p++ = (c & 0x3f) | 0x80;
515 BREAKUP_CHAR (c, charset, c1, c2);
516 lb = CHAR_LEADING_BYTE (c);
517 if (LEADING_BYTE_PRIVATE_P (lb))
518 *p++ = PRIVATE_LEADING_BYTE_PREFIX (lb);
520 if (EQ (charset, Vcharset_control_1))
529 /* Return the first character from a Mule-encoded string in STR,
530 assuming it's non-ASCII. Do not call this directly.
531 Use the macro charptr_emchar() instead. */
534 non_ascii_charptr_emchar (const Bufbyte *str)
547 else if ( b >= 0xf8 )
552 else if ( b >= 0xf0 )
557 else if ( b >= 0xe0 )
562 else if ( b >= 0xc0 )
572 for( ; len > 0; len-- )
575 ch = ( ch << 6 ) | ( b & 0x3f );
579 Bufbyte i0 = *str, i1, i2 = 0;
582 if (i0 == LEADING_BYTE_CONTROL_1)
583 return (Emchar) (*++str - 0x20);
585 if (LEADING_BYTE_PREFIX_P (i0))
590 charset = CHARSET_BY_LEADING_BYTE (i0);
591 if (XCHARSET_DIMENSION (charset) == 2)
594 return MAKE_CHAR (charset, i1, i2);
598 /* Return whether CH is a valid Emchar, assuming it's non-ASCII.
599 Do not call this directly. Use the macro valid_char_p() instead. */
603 non_ascii_valid_char_p (Emchar ch)
607 /* Must have only lowest 19 bits set */
611 f1 = CHAR_FIELD1 (ch);
612 f2 = CHAR_FIELD2 (ch);
613 f3 = CHAR_FIELD3 (ch);
619 if (f2 < MIN_CHAR_FIELD2_OFFICIAL ||
620 (f2 > MAX_CHAR_FIELD2_OFFICIAL && f2 < MIN_CHAR_FIELD2_PRIVATE) ||
621 f2 > MAX_CHAR_FIELD2_PRIVATE)
626 if (f3 != 0x20 && f3 != 0x7F && !(f2 >= MIN_CHAR_FIELD2_PRIVATE &&
627 f2 <= MAX_CHAR_FIELD2_PRIVATE))
631 NOTE: This takes advantage of the fact that
632 FIELD2_TO_OFFICIAL_LEADING_BYTE and
633 FIELD2_TO_PRIVATE_LEADING_BYTE are the same.
635 charset = CHARSET_BY_LEADING_BYTE (f2 + FIELD2_TO_OFFICIAL_LEADING_BYTE);
636 if (EQ (charset, Qnil))
638 return (XCHARSET_CHARS (charset) == 96);
644 if (f1 < MIN_CHAR_FIELD1_OFFICIAL ||
645 (f1 > MAX_CHAR_FIELD1_OFFICIAL && f1 < MIN_CHAR_FIELD1_PRIVATE) ||
646 f1 > MAX_CHAR_FIELD1_PRIVATE)
648 if (f2 < 0x20 || f3 < 0x20)
651 #ifdef ENABLE_COMPOSITE_CHARS
652 if (f1 + FIELD1_TO_OFFICIAL_LEADING_BYTE == LEADING_BYTE_COMPOSITE)
654 if (UNBOUNDP (Fgethash (make_int (ch),
655 Vcomposite_char_char2string_hash_table,
660 #endif /* ENABLE_COMPOSITE_CHARS */
662 if (f2 != 0x20 && f2 != 0x7F && f3 != 0x20 && f3 != 0x7F
663 && !(f1 >= MIN_CHAR_FIELD1_PRIVATE && f1 <= MAX_CHAR_FIELD1_PRIVATE))
666 if (f1 <= MAX_CHAR_FIELD1_OFFICIAL)
668 CHARSET_BY_LEADING_BYTE (f1 + FIELD1_TO_OFFICIAL_LEADING_BYTE);
671 CHARSET_BY_LEADING_BYTE (f1 + FIELD1_TO_PRIVATE_LEADING_BYTE);
673 if (EQ (charset, Qnil))
675 return (XCHARSET_CHARS (charset) == 96);
681 /************************************************************************/
682 /* Basic string functions */
683 /************************************************************************/
685 /* Copy the character pointed to by SRC into DST. Do not call this
686 directly. Use the macro charptr_copy_char() instead.
687 Return the number of bytes copied. */
690 non_ascii_charptr_copy_char (const Bufbyte *src, Bufbyte *dst)
692 unsigned int bytes = REP_BYTES_BY_FIRST_BYTE (*src);
694 for (i = bytes; i; i--, dst++, src++)
700 /************************************************************************/
701 /* streams of Emchars */
702 /************************************************************************/
704 /* Treat a stream as a stream of Emchar's rather than a stream of bytes.
705 The functions below are not meant to be called directly; use
706 the macros in insdel.h. */
709 Lstream_get_emchar_1 (Lstream *stream, int ch)
711 Bufbyte str[MAX_EMCHAR_LEN];
712 Bufbyte *strptr = str;
715 str[0] = (Bufbyte) ch;
717 for (bytes = REP_BYTES_BY_FIRST_BYTE (ch) - 1; bytes; bytes--)
719 int c = Lstream_getc (stream);
720 bufpos_checking_assert (c >= 0);
721 *++strptr = (Bufbyte) c;
723 return charptr_emchar (str);
727 Lstream_fput_emchar (Lstream *stream, Emchar ch)
729 Bufbyte str[MAX_EMCHAR_LEN];
730 Bytecount len = set_charptr_emchar (str, ch);
731 return Lstream_write (stream, str, len);
735 Lstream_funget_emchar (Lstream *stream, Emchar ch)
737 Bufbyte str[MAX_EMCHAR_LEN];
738 Bytecount len = set_charptr_emchar (str, ch);
739 Lstream_unread (stream, str, len);
743 /************************************************************************/
745 /************************************************************************/
748 mark_charset (Lisp_Object obj)
750 Lisp_Charset *cs = XCHARSET (obj);
752 mark_object (cs->short_name);
753 mark_object (cs->long_name);
754 mark_object (cs->doc_string);
755 mark_object (cs->registry);
756 mark_object (cs->ccl_program);
758 mark_object (cs->decoding_table);
759 mark_object (cs->mother);
765 print_charset (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
767 Lisp_Charset *cs = XCHARSET (obj);
771 error ("printing unreadable object #<charset %s 0x%x>",
772 string_data (XSYMBOL (CHARSET_NAME (cs))->name),
775 write_c_string ("#<charset ", printcharfun);
776 print_internal (CHARSET_NAME (cs), printcharfun, 0);
777 write_c_string (" ", printcharfun);
778 print_internal (CHARSET_SHORT_NAME (cs), printcharfun, 1);
779 write_c_string (" ", printcharfun);
780 print_internal (CHARSET_LONG_NAME (cs), printcharfun, 1);
781 write_c_string (" ", printcharfun);
782 print_internal (CHARSET_DOC_STRING (cs), printcharfun, 1);
783 sprintf (buf, " %d^%d %s cols=%d g%d final='%c' reg=",
785 CHARSET_DIMENSION (cs),
786 CHARSET_DIRECTION (cs) == CHARSET_LEFT_TO_RIGHT ? "l2r" : "r2l",
787 CHARSET_COLUMNS (cs),
788 CHARSET_GRAPHIC (cs),
790 write_c_string (buf, printcharfun);
791 print_internal (CHARSET_REGISTRY (cs), printcharfun, 0);
792 sprintf (buf, " 0x%x>", cs->header.uid);
793 write_c_string (buf, printcharfun);
796 static const struct lrecord_description charset_description[] = {
797 { XD_LISP_OBJECT, offsetof (Lisp_Charset, name) },
798 { XD_LISP_OBJECT, offsetof (Lisp_Charset, doc_string) },
799 { XD_LISP_OBJECT, offsetof (Lisp_Charset, registry) },
800 { XD_LISP_OBJECT, offsetof (Lisp_Charset, short_name) },
801 { XD_LISP_OBJECT, offsetof (Lisp_Charset, long_name) },
802 { XD_LISP_OBJECT, offsetof (Lisp_Charset, reverse_direction_charset) },
803 { XD_LISP_OBJECT, offsetof (Lisp_Charset, ccl_program) },
805 { XD_LISP_OBJECT, offsetof (Lisp_Charset, decoding_table) },
806 { XD_LISP_OBJECT, offsetof (Lisp_Charset, mother) },
811 DEFINE_LRECORD_IMPLEMENTATION ("charset", charset,
812 mark_charset, print_charset, 0, 0, 0,
816 /* Make a new charset. */
817 /* #### SJT Should generic properties be allowed? */
819 make_charset (Charset_ID id, Lisp_Object name,
820 unsigned short chars, unsigned char dimension,
821 unsigned char columns, unsigned char graphic,
822 Bufbyte final, unsigned char direction, Lisp_Object short_name,
823 Lisp_Object long_name, Lisp_Object doc,
826 Lisp_Object decoding_table,
827 Emchar min_code, Emchar max_code,
828 Emchar code_offset, unsigned char byte_offset,
829 Lisp_Object mother, unsigned char conversion,
833 Lisp_Charset *cs = alloc_lcrecord_type (Lisp_Charset, &lrecord_charset);
837 XSETCHARSET (obj, cs);
839 CHARSET_ID (cs) = id;
840 CHARSET_NAME (cs) = name;
841 CHARSET_SHORT_NAME (cs) = short_name;
842 CHARSET_LONG_NAME (cs) = long_name;
843 CHARSET_CHARS (cs) = chars;
844 CHARSET_DIMENSION (cs) = dimension;
845 CHARSET_DIRECTION (cs) = direction;
846 CHARSET_COLUMNS (cs) = columns;
847 CHARSET_GRAPHIC (cs) = graphic;
848 CHARSET_FINAL (cs) = final;
849 CHARSET_DOC_STRING (cs) = doc;
850 CHARSET_REGISTRY (cs) = reg;
851 CHARSET_CCL_PROGRAM (cs) = Qnil;
852 CHARSET_REVERSE_DIRECTION_CHARSET (cs) = Qnil;
854 CHARSET_ISO_IR (cs) = iso_ir;
855 CHARSET_DECODING_TABLE(cs) = Qunbound;
856 CHARSET_MIN_CODE (cs) = min_code;
857 CHARSET_MAX_CODE (cs) = max_code;
858 CHARSET_CODE_OFFSET (cs) = code_offset;
859 CHARSET_BYTE_OFFSET (cs) = byte_offset;
860 CHARSET_MOTHER (cs) = mother;
861 CHARSET_CONVERSION (cs) = conversion;
865 if (id == LEADING_BYTE_ASCII)
866 CHARSET_REP_BYTES (cs) = 1;
868 CHARSET_REP_BYTES (cs) = CHARSET_DIMENSION (cs) + 1;
870 CHARSET_REP_BYTES (cs) = CHARSET_DIMENSION (cs) + 2;
875 /* some charsets do not have final characters. This includes
876 ASCII, Control-1, Composite, and the two faux private
878 unsigned char iso2022_type
879 = (dimension == 1 ? 0 : 2) + (chars == 94 ? 0 : 1);
881 if ( ( !partial ) && ( code_offset == 0 ) )
883 assert (NILP (chlook->charset_by_attributes[iso2022_type][final]));
884 chlook->charset_by_attributes[iso2022_type][final] = obj;
888 (chlook->charset_by_attributes[iso2022_type][final][direction]));
889 chlook->charset_by_attributes[iso2022_type][final][direction] = obj;
893 assert (NILP (chlook->charset_by_leading_byte[id - MIN_LEADING_BYTE]));
894 chlook->charset_by_leading_byte[id - MIN_LEADING_BYTE] = obj;
896 /* Some charsets are "faux" and don't have names or really exist at
897 all except in the leading-byte table. */
899 Fputhash (name, obj, Vcharset_hash_table);
904 get_unallocated_leading_byte (int dimension)
909 if (chlook->next_allocated_leading_byte > MAX_LEADING_BYTE_PRIVATE)
912 lb = chlook->next_allocated_leading_byte++;
916 if (chlook->next_allocated_1_byte_leading_byte >
917 MAX_LEADING_BYTE_PRIVATE_1)
920 lb = chlook->next_allocated_1_byte_leading_byte++;
924 /* awfully fragile, but correct */
925 #if MAX_LEADING_BYTE_PRIVATE_2 == 255
926 if (chlook->next_allocated_2_byte_leading_byte == 0)
928 if (chlook->next_allocated_2_byte_leading_byte >
929 MAX_LEADING_BYTE_PRIVATE_2)
933 lb = chlook->next_allocated_2_byte_leading_byte++;
939 ("No more character sets free for this dimension",
940 make_int (dimension));
946 /* Number of Big5 characters which have the same code in 1st byte. */
948 #define BIG5_SAME_ROW (0xFF - 0xA1 + 0x7F - 0x40)
951 decode_ccs_conversion (int conv_type, int code_point)
953 if ( conv_type == CONVERSION_IDENTICAL )
957 if ( conv_type == CONVERSION_94x60 )
959 int row = code_point >> 8;
960 int cell = code_point & 255;
964 else if (row < 16 + 32 + 30)
965 return (row - (16 + 32)) * 94 + cell - 33;
966 else if (row < 18 + 32 + 30)
968 else if (row < 18 + 32 + 60)
969 return (row - (18 + 32)) * 94 + cell - 33;
971 else if ( conv_type == CONVERSION_94x94x60 )
973 int plane = code_point >> 16;
974 int row = (code_point >> 8) & 255;
975 int cell = code_point & 255;
979 else if (row < 16 + 32 + 30)
981 (plane - 33) * 94 * 60
982 + (row - (16 + 32)) * 94
984 else if (row < 18 + 32 + 30)
986 else if (row < 18 + 32 + 60)
988 (plane - 33) * 94 * 60
989 + (row - (18 + 32)) * 94
992 else if ( conv_type == CONVERSION_BIG5_1 )
995 = (((code_point >> 8) & 0x7F) - 33) * 94
996 + (( code_point & 0x7F) - 33);
997 unsigned char b1 = I / (0xFF - 0xA1 + 0x7F - 0x40) + 0xA1;
998 unsigned char b2 = I % (0xFF - 0xA1 + 0x7F - 0x40);
1000 b2 += b2 < 0x3F ? 0x40 : 0x62;
1001 return (b1 << 8) | b2;
1003 else if ( conv_type == CONVERSION_BIG5_2 )
1006 = (((code_point >> 8) & 0x7F) - 33) * 94
1007 + (( code_point & 0x7F) - 33)
1008 + BIG5_SAME_ROW * (0xC9 - 0xA1);
1009 unsigned char b1 = I / (0xFF - 0xA1 + 0x7F - 0x40) + 0xA1;
1010 unsigned char b2 = I % (0xFF - 0xA1 + 0x7F - 0x40);
1012 b2 += b2 < 0x3F ? 0x40 : 0x62;
1013 return (b1 << 8) | b2;
1019 decode_defined_char (Lisp_Object ccs, int code_point, int without_inheritance)
1021 int dim = XCHARSET_DIMENSION (ccs);
1022 Lisp_Object decoding_table = XCHARSET_DECODING_TABLE (ccs);
1023 Emchar char_id = -1;
1030 = get_ccs_octet_table (decoding_table, ccs,
1031 (code_point >> (dim * 8)) & 255);
1033 if (CHARP (decoding_table))
1034 return XCHAR (decoding_table);
1036 if (EQ (decoding_table, Qunloaded))
1038 char_id = load_char_decoding_entry_maybe (ccs, code_point);
1040 #endif /* HAVE_CHISE */
1043 else if ( !without_inheritance
1044 && CHARSETP (mother = XCHARSET_MOTHER (ccs)) )
1047 = decode_ccs_conversion (XCHARSET_CONVERSION (ccs), code_point);
1051 code += XCHARSET_CODE_OFFSET(ccs);
1052 if ( EQ (mother, Vcharset_ucs) )
1053 return DECODE_CHAR (mother, code, without_inheritance);
1055 return decode_defined_char (mother, code,
1056 without_inheritance);
1063 decode_builtin_char (Lisp_Object charset, int code_point)
1065 Lisp_Object mother = XCHARSET_MOTHER (charset);
1068 if ( XCHARSET_MAX_CODE (charset) > 0 )
1070 if ( CHARSETP (mother) )
1073 = decode_ccs_conversion (XCHARSET_CONVERSION (charset),
1078 decode_builtin_char (mother,
1079 code + XCHARSET_CODE_OFFSET(charset));
1086 = (XCHARSET_DIMENSION (charset) == 1
1088 code_point - XCHARSET_BYTE_OFFSET (charset)
1090 ((code_point >> 8) - XCHARSET_BYTE_OFFSET (charset))
1091 * XCHARSET_CHARS (charset)
1092 + (code_point & 0xFF) - XCHARSET_BYTE_OFFSET (charset))
1093 + XCHARSET_CODE_OFFSET (charset);
1094 if ((cid < XCHARSET_MIN_CODE (charset))
1095 || (XCHARSET_MAX_CODE (charset) < cid))
1100 else if ((final = XCHARSET_FINAL (charset)) >= '0')
1102 if (XCHARSET_DIMENSION (charset) == 1)
1104 switch (XCHARSET_CHARS (charset))
1108 + (final - '0') * 94 + ((code_point & 0x7F) - 33);
1111 + (final - '0') * 96 + ((code_point & 0x7F) - 32);
1119 switch (XCHARSET_CHARS (charset))
1122 return MIN_CHAR_94x94
1123 + (final - '0') * 94 * 94
1124 + (((code_point >> 8) & 0x7F) - 33) * 94
1125 + ((code_point & 0x7F) - 33);
1127 return MIN_CHAR_96x96
1128 + (final - '0') * 96 * 96
1129 + (((code_point >> 8) & 0x7F) - 32) * 96
1130 + ((code_point & 0x7F) - 32);
1142 charset_code_point (Lisp_Object charset, Emchar ch, int defined_only)
1144 Lisp_Object encoding_table = XCHARSET_ENCODING_TABLE (charset);
1147 if ( CHAR_TABLEP (encoding_table)
1148 && INTP (ret = get_char_id_table (XCHAR_TABLE(encoding_table),
1153 Lisp_Object mother = XCHARSET_MOTHER (charset);
1154 int min = XCHARSET_MIN_CODE (charset);
1155 int max = XCHARSET_MAX_CODE (charset);
1158 if ( CHARSETP (mother) )
1160 if (XCHARSET_FINAL (charset) >= '0')
1161 code = charset_code_point (mother, ch, 1);
1163 code = charset_code_point (mother, ch, defined_only);
1165 else if (defined_only)
1167 else if ( ((max == 0) && CHARSETP (mother)
1168 && (XCHARSET_FINAL (charset) == 0))
1169 || ((min <= ch) && (ch <= max)) )
1171 if ( ((max == 0) && CHARSETP (mother) && (code >= 0))
1172 || ((min <= code) && (code <= max)) )
1174 int d = code - XCHARSET_CODE_OFFSET (charset);
1176 if ( XCHARSET_CONVERSION (charset) == CONVERSION_IDENTICAL )
1178 else if ( XCHARSET_CONVERSION (charset) == CONVERSION_94 )
1180 else if ( XCHARSET_CONVERSION (charset) == CONVERSION_96 )
1182 else if ( XCHARSET_CONVERSION (charset) == CONVERSION_94x60 )
1185 int cell = d % 94 + 33;
1191 return (row << 8) | cell;
1193 else if ( XCHARSET_CONVERSION (charset) == CONVERSION_BIG5_1 )
1195 int B1 = d >> 8, B2 = d & 0xFF;
1197 = (B1 - 0xA1) * BIG5_SAME_ROW + B2
1198 - (B2 < 0x7F ? 0x40 : 0x62);
1202 return ((I / 94 + 33) << 8) | (I % 94 + 33);
1205 else if ( XCHARSET_CONVERSION (charset) == CONVERSION_BIG5_2 )
1207 int B1 = d >> 8, B2 = d & 0xFF;
1209 = (B1 - 0xA1) * BIG5_SAME_ROW + B2
1210 - (B2 < 0x7F ? 0x40 : 0x62);
1214 I -= (BIG5_SAME_ROW) * (0xC9 - 0xA1);
1215 return ((I / 94 + 33) << 8) | (I % 94 + 33);
1218 else if ( XCHARSET_CONVERSION (charset) == CONVERSION_94x94 )
1219 return ((d / 94 + 33) << 8) | (d % 94 + 33);
1220 else if ( XCHARSET_CONVERSION (charset) == CONVERSION_96x96 )
1221 return ((d / 96 + 32) << 8) | (d % 96 + 32);
1222 else if ( XCHARSET_CONVERSION (charset) == CONVERSION_94x94x60 )
1224 int plane = d / (94 * 60) + 33;
1225 int row = (d % (94 * 60)) / 94;
1226 int cell = d % 94 + 33;
1232 return (plane << 16) | (row << 8) | cell;
1234 else if ( XCHARSET_CONVERSION (charset) == CONVERSION_94x94x94 )
1236 ( (d / (94 * 94) + 33) << 16)
1237 | ((d / 94 % 94 + 33) << 8)
1239 else if ( XCHARSET_CONVERSION (charset) == CONVERSION_96x96x96 )
1241 ( (d / (96 * 96) + 32) << 16)
1242 | ((d / 96 % 96 + 32) << 8)
1244 else if ( XCHARSET_CONVERSION (charset) == CONVERSION_94x94x94x94 )
1246 ( (d / (94 * 94 * 94) + 33) << 24)
1247 | ((d / (94 * 94) % 94 + 33) << 16)
1248 | ((d / 94 % 94 + 33) << 8)
1250 else if ( XCHARSET_CONVERSION (charset) == CONVERSION_96x96x96x96 )
1252 ( (d / (96 * 96 * 96) + 32) << 24)
1253 | ((d / (96 * 96) % 96 + 32) << 16)
1254 | ((d / 96 % 96 + 32) << 8)
1258 printf ("Unknown CCS-conversion %d is specified!",
1259 XCHARSET_CONVERSION (charset));
1263 else if (defined_only)
1265 else if ( ( XCHARSET_FINAL (charset) >= '0' ) &&
1266 ( XCHARSET_MIN_CODE (charset) == 0 )
1268 (XCHARSET_CODE_OFFSET (charset) == 0) ||
1269 (XCHARSET_CODE_OFFSET (charset)
1270 == XCHARSET_MIN_CODE (charset))
1275 if (XCHARSET_DIMENSION (charset) == 1)
1277 if (XCHARSET_CHARS (charset) == 94)
1279 if (((d = ch - (MIN_CHAR_94
1280 + (XCHARSET_FINAL (charset) - '0') * 94))
1285 else if (XCHARSET_CHARS (charset) == 96)
1287 if (((d = ch - (MIN_CHAR_96
1288 + (XCHARSET_FINAL (charset) - '0') * 96))
1296 else if (XCHARSET_DIMENSION (charset) == 2)
1298 if (XCHARSET_CHARS (charset) == 94)
1300 if (((d = ch - (MIN_CHAR_94x94
1302 (XCHARSET_FINAL (charset) - '0') * 94 * 94))
1305 return (((d / 94) + 33) << 8) | (d % 94 + 33);
1307 else if (XCHARSET_CHARS (charset) == 96)
1309 if (((d = ch - (MIN_CHAR_96x96
1311 (XCHARSET_FINAL (charset) - '0') * 96 * 96))
1314 return (((d / 96) + 32) << 8) | (d % 96 + 32);
1325 encode_char_2 (Emchar ch, Lisp_Object* charset)
1327 Lisp_Object charsets = Vdefault_coded_charset_priority_list;
1330 while (!NILP (charsets))
1332 *charset = Ffind_charset (Fcar (charsets));
1333 if ( !NILP (*charset)
1334 && (XCHARSET_DIMENSION (*charset) <= 2) )
1336 code_point = charset_code_point (*charset, ch, 0);
1337 if (code_point >= 0)
1340 if ( !NILP (Vdisplay_coded_charset_priority_use_inheritance) &&
1341 NILP (Vdisplay_coded_charset_priority_use_hierarchy_order) )
1343 code_point = encode_char_2_search_children (ch, charset);
1344 if (code_point >= 0)
1348 charsets = Fcdr (charsets);
1351 if ( !NILP (Vdisplay_coded_charset_priority_use_inheritance) &&
1352 !NILP (Vdisplay_coded_charset_priority_use_hierarchy_order) )
1354 charsets = Vdefault_coded_charset_priority_list;
1355 while (!NILP (charsets))
1357 *charset = Ffind_charset (Fcar (charsets));
1358 if ( !NILP (*charset)
1359 && (XCHARSET_DIMENSION (*charset) <= 2) )
1361 code_point = encode_char_2_search_children (ch, charset);
1362 if (code_point >= 0)
1365 charsets = Fcdr (charsets);
1369 /* otherwise --- maybe for bootstrap */
1370 return encode_builtin_char_1 (ch, charset);
1374 encode_builtin_char_1 (Emchar c, Lisp_Object* charset)
1376 if (c <= MAX_CHAR_BASIC_LATIN)
1378 *charset = Vcharset_ascii;
1383 *charset = Vcharset_control_1;
1388 *charset = Vcharset_latin_iso8859_1;
1392 else if ((MIN_CHAR_HEBREW <= c) && (c <= MAX_CHAR_HEBREW))
1394 *charset = Vcharset_hebrew_iso8859_8;
1395 return c - MIN_CHAR_HEBREW + 0x20;
1398 else if ((MIN_CHAR_THAI <= c) && (c <= MAX_CHAR_THAI))
1400 *charset = Vcharset_thai_tis620;
1401 return c - MIN_CHAR_THAI + 0x20;
1404 else if ((MIN_CHAR_HALFWIDTH_KATAKANA <= c)
1405 && (c <= MAX_CHAR_HALFWIDTH_KATAKANA))
1407 return list2 (Vcharset_katakana_jisx0201,
1408 make_int (c - MIN_CHAR_HALFWIDTH_KATAKANA + 33));
1411 else if (c <= MAX_CHAR_BMP)
1413 *charset = Vcharset_ucs_bmp;
1416 else if (c <= MAX_CHAR_SMP)
1418 *charset = Vcharset_ucs_smp;
1419 return c - MIN_CHAR_SMP;
1421 else if (c <= MAX_CHAR_SIP)
1423 *charset = Vcharset_ucs_sip;
1424 return c - MIN_CHAR_SIP;
1426 else if (c < MIN_CHAR_94)
1428 *charset = Vcharset_ucs;
1431 else if (c <= MAX_CHAR_94)
1433 *charset = CHARSET_BY_ATTRIBUTES (94, 1,
1434 ((c - MIN_CHAR_94) / 94) + '0',
1435 CHARSET_LEFT_TO_RIGHT);
1436 if (!NILP (*charset))
1437 return ((c - MIN_CHAR_94) % 94) + 33;
1440 *charset = Vcharset_ucs;
1444 else if (c <= MAX_CHAR_96)
1446 *charset = CHARSET_BY_ATTRIBUTES (96, 1,
1447 ((c - MIN_CHAR_96) / 96) + '0',
1448 CHARSET_LEFT_TO_RIGHT);
1449 if (!NILP (*charset))
1450 return ((c - MIN_CHAR_96) % 96) + 32;
1453 *charset = Vcharset_ucs;
1457 else if (c <= MAX_CHAR_94x94)
1460 = CHARSET_BY_ATTRIBUTES (94, 2,
1461 ((c - MIN_CHAR_94x94) / (94 * 94)) + '0',
1462 CHARSET_LEFT_TO_RIGHT);
1463 if (!NILP (*charset))
1464 return (((((c - MIN_CHAR_94x94) / 94) % 94) + 33) << 8)
1465 | (((c - MIN_CHAR_94x94) % 94) + 33);
1468 *charset = Vcharset_ucs;
1472 else if (c <= MAX_CHAR_96x96)
1475 = CHARSET_BY_ATTRIBUTES (96, 2,
1476 ((c - MIN_CHAR_96x96) / (96 * 96)) + '0',
1477 CHARSET_LEFT_TO_RIGHT);
1478 if (!NILP (*charset))
1479 return ((((c - MIN_CHAR_96x96) / 96) % 96) + 32) << 8
1480 | (((c - MIN_CHAR_96x96) % 96) + 32);
1483 *charset = Vcharset_ucs;
1489 *charset = Vcharset_ucs;
1494 Lisp_Object Vdefault_coded_charset_priority_list;
1495 Lisp_Object Vdisplay_coded_charset_priority_use_inheritance;
1496 Lisp_Object Vdisplay_coded_charset_priority_use_hierarchy_order;
1500 /************************************************************************/
1501 /* Basic charset Lisp functions */
1502 /************************************************************************/
1504 DEFUN ("charsetp", Fcharsetp, 1, 1, 0, /*
1505 Return non-nil if OBJECT is a charset.
1509 return CHARSETP (object) ? Qt : Qnil;
1512 DEFUN ("find-charset", Ffind_charset, 1, 1, 0, /*
1513 Retrieve the charset of the given name.
1514 If CHARSET-OR-NAME is a charset object, it is simply returned.
1515 Otherwise, CHARSET-OR-NAME should be a symbol. If there is no such charset,
1516 nil is returned. Otherwise the associated charset object is returned.
1520 if (CHARSETP (charset_or_name))
1521 return charset_or_name;
1523 CHECK_SYMBOL (charset_or_name);
1524 return Fgethash (charset_or_name, Vcharset_hash_table, Qnil);
1527 DEFUN ("get-charset", Fget_charset, 1, 1, 0, /*
1528 Retrieve the charset of the given name.
1529 Same as `find-charset' except an error is signalled if there is no such
1530 charset instead of returning nil.
1534 Lisp_Object charset = Ffind_charset (name);
1537 signal_simple_error ("No such charset", name);
1541 /* We store the charsets in hash tables with the names as the key and the
1542 actual charset object as the value. Occasionally we need to use them
1543 in a list format. These routines provide us with that. */
1544 struct charset_list_closure
1546 Lisp_Object *charset_list;
1550 add_charset_to_list_mapper (Lisp_Object key, Lisp_Object value,
1551 void *charset_list_closure)
1553 /* This function can GC */
1554 struct charset_list_closure *chcl =
1555 (struct charset_list_closure*) charset_list_closure;
1556 Lisp_Object *charset_list = chcl->charset_list;
1558 *charset_list = Fcons (key /* XCHARSET_NAME (value) */, *charset_list);
1562 DEFUN ("charset-list", Fcharset_list, 0, 0, 0, /*
1563 Return a list of the names of all defined charsets.
1567 Lisp_Object charset_list = Qnil;
1568 struct gcpro gcpro1;
1569 struct charset_list_closure charset_list_closure;
1571 GCPRO1 (charset_list);
1572 charset_list_closure.charset_list = &charset_list;
1573 elisp_maphash (add_charset_to_list_mapper, Vcharset_hash_table,
1574 &charset_list_closure);
1577 return charset_list;
1580 DEFUN ("charset-name", Fcharset_name, 1, 1, 0, /*
1581 Return the name of charset CHARSET.
1585 return XCHARSET_NAME (Fget_charset (charset));
1588 /* #### SJT Should generic properties be allowed? */
1589 DEFUN ("make-charset", Fmake_charset, 3, 3, 0, /*
1590 Define a new character set.
1591 This function is for use with Mule support.
1592 NAME is a symbol, the name by which the character set is normally referred.
1593 DOC-STRING is a string describing the character set.
1594 PROPS is a property list, describing the specific nature of the
1595 character set. Recognized properties are:
1597 'short-name Short version of the charset name (ex: Latin-1)
1598 'long-name Long version of the charset name (ex: ISO8859-1 (Latin-1))
1599 'registry A regular expression matching the font registry field for
1601 'dimension Number of octets used to index a character in this charset.
1602 Either 1 or 2. Defaults to 1.
1603 If UTF-2000 feature is enabled, 3 or 4 are also available.
1604 'columns Number of columns used to display a character in this charset.
1605 Only used in TTY mode. (Under X, the actual width of a
1606 character can be derived from the font used to display the
1607 characters.) If unspecified, defaults to the dimension
1608 (this is almost always the correct value).
1609 'chars Number of characters in each dimension (94 or 96).
1610 Defaults to 94. Note that if the dimension is 2, the
1611 character set thus described is 94x94 or 96x96.
1612 If UTF-2000 feature is enabled, 128 or 256 are also available.
1613 'final Final byte of ISO 2022 escape sequence. Must be
1614 supplied. Each combination of (DIMENSION, CHARS) defines a
1615 separate namespace for final bytes. Note that ISO
1616 2022 restricts the final byte to the range
1617 0x30 - 0x7E if dimension == 1, and 0x30 - 0x5F if
1618 dimension == 2. Note also that final bytes in the range
1619 0x30 - 0x3F are reserved for user-defined (not official)
1621 'graphic 0 (use left half of font on output) or 1 (use right half
1622 of font on output). Defaults to 0. For example, for
1623 a font whose registry is ISO8859-1, the left half
1624 (octets 0x20 - 0x7F) is the `ascii' character set, while
1625 the right half (octets 0xA0 - 0xFF) is the `latin-1'
1626 character set. With 'graphic set to 0, the octets
1627 will have their high bit cleared; with it set to 1,
1628 the octets will have their high bit set.
1629 'direction 'l2r (left-to-right) or 'r2l (right-to-left).
1631 'ccl-program A compiled CCL program used to convert a character in
1632 this charset into an index into the font. This is in
1633 addition to the 'graphic property. The CCL program
1634 is passed the octets of the character, with the high
1635 bit cleared and set depending upon whether the value
1636 of the 'graphic property is 0 or 1.
1637 'iso-ir ISO-IR number (for representative coded-charset).
1638 '=>iso-ir [UTF-2000 only] Corresponding ISO-IR number.
1639 'mother [UTF-2000 only] Base coded-charset.
1640 'code-min [UTF-2000 only] Minimum code-point of a base coded-charset.
1641 'code-max [UTF-2000 only] Maximum code-point of a base coded-charset.
1642 'code-offset [UTF-2000 only] Offset for a code-point of a base
1644 'conversion [UTF-2000 only] Conversion for a code-point of a base
1645 coded-charset (94x60, 94x94x60, big5-1 or big5-2).
1646 'partial [UTF-2000 only] If t, specify as a partial coded-charset.
1648 (name, doc_string, props))
1650 int id = 0, dimension = 1, chars = 94, graphic = 0, final = 0, columns = -1;
1652 int direction = CHARSET_LEFT_TO_RIGHT;
1653 Lisp_Object registry = Qnil;
1654 Lisp_Object charset;
1655 Lisp_Object ccl_program = Qnil;
1656 Lisp_Object short_name = Qnil, long_name = Qnil;
1657 Lisp_Object mother = Qnil;
1659 int min_code = 0, max_code = 0, code_offset = 0;
1660 int byte_offset = -1;
1663 CHECK_SYMBOL (name);
1664 if (!NILP (doc_string))
1665 CHECK_STRING (doc_string);
1667 charset = Ffind_charset (name);
1668 if (!NILP (charset))
1669 signal_simple_error ("Cannot redefine existing charset", name);
1672 EXTERNAL_PROPERTY_LIST_LOOP_3 (keyword, value, props)
1674 if (EQ (keyword, Qshort_name))
1676 CHECK_STRING (value);
1680 else if (EQ (keyword, Qlong_name))
1682 CHECK_STRING (value);
1686 else if (EQ (keyword, Qiso_ir))
1690 iso_ir = XINT (value);
1696 else if (EQ (keyword, Qto_iso_ir))
1699 iso_ir = XINT (value);
1703 else if (EQ (keyword, Qdimension))
1706 dimension = XINT (value);
1707 if (dimension < 1 ||
1714 signal_simple_error ("Invalid value for 'dimension", value);
1717 else if (EQ (keyword, Qchars))
1720 chars = XINT (value);
1721 if (chars != 94 && chars != 96
1723 && chars != 128 && chars != 256
1726 signal_simple_error ("Invalid value for 'chars", value);
1729 else if (EQ (keyword, Qcolumns))
1732 columns = XINT (value);
1733 if (columns != 1 && columns != 2)
1734 signal_simple_error ("Invalid value for 'columns", value);
1737 else if (EQ (keyword, Qgraphic))
1740 graphic = XINT (value);
1748 signal_simple_error ("Invalid value for 'graphic", value);
1751 else if (EQ (keyword, Qregistry))
1753 CHECK_STRING (value);
1757 else if (EQ (keyword, Qdirection))
1759 if (EQ (value, Ql2r))
1760 direction = CHARSET_LEFT_TO_RIGHT;
1761 else if (EQ (value, Qr2l))
1762 direction = CHARSET_RIGHT_TO_LEFT;
1764 signal_simple_error ("Invalid value for 'direction", value);
1767 else if (EQ (keyword, Qfinal))
1769 CHECK_CHAR_COERCE_INT (value);
1770 final = XCHAR (value);
1771 if (final < '0' || final > '~')
1772 signal_simple_error ("Invalid value for 'final", value);
1776 else if (EQ (keyword, Qpartial))
1778 partial = !NILP (value);
1781 else if (EQ (keyword, Qmother))
1783 mother = Fget_charset (value);
1786 else if (EQ (keyword, Qmin_code))
1789 min_code = XUINT (value);
1792 else if (EQ (keyword, Qmax_code))
1795 max_code = XUINT (value);
1798 else if (EQ (keyword, Qcode_offset))
1801 code_offset = XUINT (value);
1804 else if (EQ (keyword, Qconversion))
1806 if (EQ (value, Q94x60))
1807 conversion = CONVERSION_94x60;
1808 else if (EQ (value, Q94x94x60))
1809 conversion = CONVERSION_94x94x60;
1810 else if (EQ (value, Qbig5_1))
1811 conversion = CONVERSION_BIG5_1;
1812 else if (EQ (value, Qbig5_2))
1813 conversion = CONVERSION_BIG5_2;
1815 signal_simple_error ("Unrecognized conversion", value);
1819 else if (EQ (keyword, Qccl_program))
1821 struct ccl_program test_ccl;
1823 if (setup_ccl_program (&test_ccl, value) < 0)
1824 signal_simple_error ("Invalid value for 'ccl-program", value);
1825 ccl_program = value;
1829 signal_simple_error ("Unrecognized property", keyword);
1835 error ("'final must be specified");
1837 if (dimension == 2 && final > 0x5F)
1839 ("Final must be in the range 0x30 - 0x5F for dimension == 2",
1842 if (!NILP (CHARSET_BY_ATTRIBUTES (chars, dimension, final,
1843 CHARSET_LEFT_TO_RIGHT)) ||
1844 !NILP (CHARSET_BY_ATTRIBUTES (chars, dimension, final,
1845 CHARSET_RIGHT_TO_LEFT)))
1847 ("Character set already defined for this DIMENSION/CHARS/FINAL combo");
1850 id = get_unallocated_leading_byte (dimension);
1852 if (NILP (doc_string))
1853 doc_string = build_string ("");
1855 if (NILP (registry))
1856 registry = build_string ("");
1858 if (NILP (short_name))
1859 XSETSTRING (short_name, XSYMBOL (name)->name);
1861 if (NILP (long_name))
1862 long_name = doc_string;
1865 columns = dimension;
1867 if (byte_offset < 0)
1871 else if (chars == 96)
1877 charset = make_charset (id, name, chars, dimension, columns, graphic,
1878 final, direction, short_name, long_name,
1879 doc_string, registry, iso_ir,
1880 Qnil, min_code, max_code, code_offset, byte_offset,
1881 mother, conversion, partial);
1882 if (!NILP (ccl_program))
1883 XCHARSET_CCL_PROGRAM (charset) = ccl_program;
1887 DEFUN ("make-reverse-direction-charset", Fmake_reverse_direction_charset,
1889 Make a charset equivalent to CHARSET but which goes in the opposite direction.
1890 NEW-NAME is the name of the new charset. Return the new charset.
1892 (charset, new_name))
1894 Lisp_Object new_charset = Qnil;
1895 int id, chars, dimension, columns, graphic, final;
1897 Lisp_Object registry, doc_string, short_name, long_name;
1900 charset = Fget_charset (charset);
1901 if (!NILP (XCHARSET_REVERSE_DIRECTION_CHARSET (charset)))
1902 signal_simple_error ("Charset already has reverse-direction charset",
1905 CHECK_SYMBOL (new_name);
1906 if (!NILP (Ffind_charset (new_name)))
1907 signal_simple_error ("Cannot redefine existing charset", new_name);
1909 cs = XCHARSET (charset);
1911 chars = CHARSET_CHARS (cs);
1912 dimension = CHARSET_DIMENSION (cs);
1913 columns = CHARSET_COLUMNS (cs);
1914 id = get_unallocated_leading_byte (dimension);
1916 graphic = CHARSET_GRAPHIC (cs);
1917 final = CHARSET_FINAL (cs);
1918 direction = CHARSET_RIGHT_TO_LEFT;
1919 if (CHARSET_DIRECTION (cs) == CHARSET_RIGHT_TO_LEFT)
1920 direction = CHARSET_LEFT_TO_RIGHT;
1921 doc_string = CHARSET_DOC_STRING (cs);
1922 short_name = CHARSET_SHORT_NAME (cs);
1923 long_name = CHARSET_LONG_NAME (cs);
1924 registry = CHARSET_REGISTRY (cs);
1926 new_charset = make_charset (id, new_name, chars, dimension, columns,
1927 graphic, final, direction, short_name, long_name,
1928 doc_string, registry,
1931 CHARSET_DECODING_TABLE(cs),
1932 CHARSET_MIN_CODE(cs),
1933 CHARSET_MAX_CODE(cs),
1934 CHARSET_CODE_OFFSET(cs),
1935 CHARSET_BYTE_OFFSET(cs),
1937 CHARSET_CONVERSION (cs)
1939 Qnil, 0, 0, 0, 0, Qnil, 0
1943 CHARSET_REVERSE_DIRECTION_CHARSET (cs) = new_charset;
1944 XCHARSET_REVERSE_DIRECTION_CHARSET (new_charset) = charset;
1949 DEFUN ("define-charset-alias", Fdefine_charset_alias, 2, 2, 0, /*
1950 Define symbol ALIAS as an alias for CHARSET.
1954 CHECK_SYMBOL (alias);
1955 charset = Fget_charset (charset);
1956 return Fputhash (alias, charset, Vcharset_hash_table);
1959 /* #### Reverse direction charsets not yet implemented. */
1961 DEFUN ("charset-reverse-direction-charset", Fcharset_reverse_direction_charset,
1963 Return the reverse-direction charset parallel to CHARSET, if any.
1964 This is the charset with the same properties (in particular, the same
1965 dimension, number of characters per dimension, and final byte) as
1966 CHARSET but whose characters are displayed in the opposite direction.
1970 charset = Fget_charset (charset);
1971 return XCHARSET_REVERSE_DIRECTION_CHARSET (charset);
1975 DEFUN ("charset-from-attributes", Fcharset_from_attributes, 3, 4, 0, /*
1976 Return a charset with the given DIMENSION, CHARS, FINAL, and DIRECTION.
1977 If DIRECTION is omitted, both directions will be checked (left-to-right
1978 will be returned if character sets exist for both directions).
1980 (dimension, chars, final, direction))
1982 int dm, ch, fi, di = -1;
1983 Lisp_Object obj = Qnil;
1985 CHECK_INT (dimension);
1986 dm = XINT (dimension);
1987 if (dm < 1 || dm > 2)
1988 signal_simple_error ("Invalid value for DIMENSION", dimension);
1992 if (ch != 94 && ch != 96)
1993 signal_simple_error ("Invalid value for CHARS", chars);
1995 CHECK_CHAR_COERCE_INT (final);
1997 if (fi < '0' || fi > '~')
1998 signal_simple_error ("Invalid value for FINAL", final);
2000 if (EQ (direction, Ql2r))
2001 di = CHARSET_LEFT_TO_RIGHT;
2002 else if (EQ (direction, Qr2l))
2003 di = CHARSET_RIGHT_TO_LEFT;
2004 else if (!NILP (direction))
2005 signal_simple_error ("Invalid value for DIRECTION", direction);
2007 if (dm == 2 && fi > 0x5F)
2009 ("Final must be in the range 0x30 - 0x5F for dimension == 2", final);
2013 obj = CHARSET_BY_ATTRIBUTES (ch, dm, fi, CHARSET_LEFT_TO_RIGHT);
2015 obj = CHARSET_BY_ATTRIBUTES (ch, dm, fi, CHARSET_RIGHT_TO_LEFT);
2018 obj = CHARSET_BY_ATTRIBUTES (ch, dm, fi, di);
2021 return XCHARSET_NAME (obj);
2025 DEFUN ("charset-short-name", Fcharset_short_name, 1, 1, 0, /*
2026 Return short name of CHARSET.
2030 return XCHARSET_SHORT_NAME (Fget_charset (charset));
2033 DEFUN ("charset-long-name", Fcharset_long_name, 1, 1, 0, /*
2034 Return long name of CHARSET.
2038 return XCHARSET_LONG_NAME (Fget_charset (charset));
2041 DEFUN ("charset-description", Fcharset_description, 1, 1, 0, /*
2042 Return description of CHARSET.
2046 return XCHARSET_DOC_STRING (Fget_charset (charset));
2049 DEFUN ("charset-dimension", Fcharset_dimension, 1, 1, 0, /*
2050 Return dimension of CHARSET.
2054 return make_int (XCHARSET_DIMENSION (Fget_charset (charset)));
2057 DEFUN ("charset-property", Fcharset_property, 2, 2, 0, /*
2058 Return property PROP of CHARSET, a charset object or symbol naming a charset.
2059 Recognized properties are those listed in `make-charset', as well as
2060 'name and 'doc-string.
2066 charset = Fget_charset (charset);
2067 cs = XCHARSET (charset);
2069 CHECK_SYMBOL (prop);
2070 if (EQ (prop, Qname)) return CHARSET_NAME (cs);
2071 if (EQ (prop, Qshort_name)) return CHARSET_SHORT_NAME (cs);
2072 if (EQ (prop, Qlong_name)) return CHARSET_LONG_NAME (cs);
2073 if (EQ (prop, Qdoc_string)) return CHARSET_DOC_STRING (cs);
2074 if (EQ (prop, Qdimension)) return make_int (CHARSET_DIMENSION (cs));
2075 if (EQ (prop, Qcolumns)) return make_int (CHARSET_COLUMNS (cs));
2076 if (EQ (prop, Qgraphic)) return make_int (CHARSET_GRAPHIC (cs));
2077 if (EQ (prop, Qfinal)) return CHARSET_FINAL (cs) == 0 ?
2078 Qnil : make_char (CHARSET_FINAL (cs));
2079 if (EQ (prop, Qchars)) return make_int (CHARSET_CHARS (cs));
2080 if (EQ (prop, Qregistry)) return CHARSET_REGISTRY (cs);
2081 if (EQ (prop, Qccl_program)) return CHARSET_CCL_PROGRAM (cs);
2082 if (EQ (prop, Qdirection))
2083 return CHARSET_DIRECTION (cs) == CHARSET_LEFT_TO_RIGHT ? Ql2r : Qr2l;
2084 if (EQ (prop, Qreverse_direction_charset))
2086 Lisp_Object obj = CHARSET_REVERSE_DIRECTION_CHARSET (cs);
2087 /* #### Is this translation OK? If so, error checking sufficient? */
2088 return CHARSETP (obj) ? XCHARSET_NAME (obj) : obj;
2091 if (EQ (prop, Qiso_ir)||
2092 EQ (prop, Qto_iso_ir))
2094 if ( CHARSET_ISO_IR (cs) > 0 )
2095 return make_int (CHARSET_ISO_IR (cs));
2099 if (EQ (prop, Qmother))
2100 return CHARSET_MOTHER (cs);
2101 if (EQ (prop, Qmin_code))
2102 return make_int (CHARSET_MIN_CODE (cs));
2103 if (EQ (prop, Qmax_code))
2104 return make_int (CHARSET_MAX_CODE (cs));
2106 signal_simple_error ("Unrecognized charset property name", prop);
2107 return Qnil; /* not reached */
2110 DEFUN ("charset-id", Fcharset_id, 1, 1, 0, /*
2111 Return charset identification number of CHARSET.
2115 return make_int(XCHARSET_LEADING_BYTE (Fget_charset (charset)));
2118 /* #### We need to figure out which properties we really want to
2121 DEFUN ("set-charset-ccl-program", Fset_charset_ccl_program, 2, 2, 0, /*
2122 Set the 'ccl-program property of CHARSET to CCL-PROGRAM.
2124 (charset, ccl_program))
2126 struct ccl_program test_ccl;
2128 charset = Fget_charset (charset);
2129 if (setup_ccl_program (&test_ccl, ccl_program) < 0)
2130 signal_simple_error ("Invalid ccl-program", ccl_program);
2131 XCHARSET_CCL_PROGRAM (charset) = ccl_program;
2136 invalidate_charset_font_caches (Lisp_Object charset)
2138 /* Invalidate font cache entries for charset on all devices. */
2139 Lisp_Object devcons, concons, hash_table;
2140 DEVICE_LOOP_NO_BREAK (devcons, concons)
2142 struct device *d = XDEVICE (XCAR (devcons));
2143 hash_table = Fgethash (charset, d->charset_font_cache, Qunbound);
2144 if (!UNBOUNDP (hash_table))
2145 Fclrhash (hash_table);
2149 DEFUN ("set-charset-registry", Fset_charset_registry, 2, 2, 0, /*
2150 Set the 'registry property of CHARSET to REGISTRY.
2152 (charset, registry))
2154 charset = Fget_charset (charset);
2155 CHECK_STRING (registry);
2156 XCHARSET_REGISTRY (charset) = registry;
2157 invalidate_charset_font_caches (charset);
2158 face_property_was_changed (Vdefault_face, Qfont, Qglobal);
2163 DEFUN ("charset-mapping-table", Fcharset_mapping_table, 1, 1, 0, /*
2164 Return mapping-table of CHARSET.
2168 return XCHARSET_DECODING_TABLE (Fget_charset (charset));
2171 DEFUN ("set-charset-mapping-table", Fset_charset_mapping_table, 2, 2, 0, /*
2172 Set mapping-table of CHARSET to TABLE.
2176 struct Lisp_Charset *cs;
2180 charset = Fget_charset (charset);
2181 cs = XCHARSET (charset);
2185 CHARSET_DECODING_TABLE(cs) = Qnil;
2188 else if (VECTORP (table))
2190 int ccs_len = CHARSET_BYTE_SIZE (cs);
2191 int ret = decoding_table_check_elements (table,
2192 CHARSET_DIMENSION (cs),
2197 signal_simple_error ("Too big table", table);
2199 signal_simple_error ("Invalid element is found", table);
2201 signal_simple_error ("Something wrong", table);
2203 CHARSET_DECODING_TABLE(cs) = Qnil;
2206 signal_error (Qwrong_type_argument,
2207 list2 (build_translated_string ("vector-or-nil-p"),
2210 byte_offset = CHARSET_BYTE_OFFSET (cs);
2211 switch (CHARSET_DIMENSION (cs))
2214 for (i = 0; i < XVECTOR_LENGTH (table); i++)
2216 Lisp_Object c = XVECTOR_DATA(table)[i];
2219 Fput_char_attribute (c, XCHARSET_NAME (charset),
2220 make_int (i + byte_offset));
2224 for (i = 0; i < XVECTOR_LENGTH (table); i++)
2226 Lisp_Object v = XVECTOR_DATA(table)[i];
2232 for (j = 0; j < XVECTOR_LENGTH (v); j++)
2234 Lisp_Object c = XVECTOR_DATA(v)[j];
2238 (c, XCHARSET_NAME (charset),
2239 make_int ( ( (i + byte_offset) << 8 )
2245 Fput_char_attribute (v, XCHARSET_NAME (charset),
2246 make_int (i + byte_offset));
2254 DEFUN ("save-charset-mapping-table", Fsave_charset_mapping_table, 1, 1, 0, /*
2255 Save mapping-table of CHARSET.
2259 struct Lisp_Charset *cs;
2260 int byte_min, byte_max;
2261 #ifdef HAVE_LIBCHISE
2263 #else /* HAVE_LIBCHISE */
2265 Lisp_Object db_file;
2266 #endif /* not HAVE_LIBCHISE */
2268 charset = Fget_charset (charset);
2269 cs = XCHARSET (charset);
2271 #ifdef HAVE_LIBCHISE
2272 if ( open_chise_data_source_maybe () )
2276 = chise_ds_get_ccs (default_chise_data_source,
2277 XSTRING_DATA (Fsymbol_name (XCHARSET_NAME(charset))));
2280 printf ("Can't open decoding-table %s\n",
2281 XSTRING_DATA (Fsymbol_name (XCHARSET_NAME(charset))));
2284 #else /* HAVE_LIBCHISE */
2285 db_file = char_attribute_system_db_file (CHARSET_NAME (cs),
2286 Qsystem_char_id, 1);
2287 db = Fopen_database (db_file, Qnil, Qnil, build_string ("w+"), Qnil);
2288 #endif /* not HAVE_LIBCHISE */
2290 byte_min = CHARSET_BYTE_OFFSET (cs);
2291 byte_max = byte_min + CHARSET_BYTE_SIZE (cs);
2292 switch (CHARSET_DIMENSION (cs))
2296 Lisp_Object table_c = XCHARSET_DECODING_TABLE (charset);
2299 for (cell = byte_min; cell < byte_max; cell++)
2301 Lisp_Object c = get_ccs_octet_table (table_c, charset, cell);
2305 #ifdef HAVE_LIBCHISE
2306 chise_ccs_set_decoded_char (dt_ccs, cell, XCHAR (c));
2307 #else /* HAVE_LIBCHISE */
2308 Fput_database (Fprin1_to_string (make_int (cell), Qnil),
2309 Fprin1_to_string (c, Qnil),
2311 #endif /* not HAVE_LIBCHISE */
2318 Lisp_Object table_r = XCHARSET_DECODING_TABLE (charset);
2321 for (row = byte_min; row < byte_max; row++)
2323 Lisp_Object table_c = get_ccs_octet_table (table_r, charset, row);
2326 for (cell = byte_min; cell < byte_max; cell++)
2328 Lisp_Object c = get_ccs_octet_table (table_c, charset, cell);
2332 #ifdef HAVE_LIBCHISE
2333 chise_ccs_set_decoded_char
2335 (row << 8) | cell, XCHAR (c));
2336 #else /* HAVE_LIBCHISE */
2337 Fput_database (Fprin1_to_string (make_int ((row << 8)
2340 Fprin1_to_string (c, Qnil),
2342 #endif /* not HAVE_LIBCHISE */
2350 Lisp_Object table_p = XCHARSET_DECODING_TABLE (charset);
2353 for (plane = byte_min; plane < byte_max; plane++)
2356 = get_ccs_octet_table (table_p, charset, plane);
2359 for (row = byte_min; row < byte_max; row++)
2362 = get_ccs_octet_table (table_r, charset, row);
2365 for (cell = byte_min; cell < byte_max; cell++)
2367 Lisp_Object c = get_ccs_octet_table (table_c, charset,
2372 #ifdef HAVE_LIBCHISE
2373 chise_ccs_set_decoded_char
2378 #else /* HAVE_LIBCHISE */
2379 Fput_database (Fprin1_to_string
2380 (make_int ((plane << 16)
2384 Fprin1_to_string (c, Qnil),
2386 #endif /* not HAVE_LIBCHISE */
2395 Lisp_Object table_g = XCHARSET_DECODING_TABLE (charset);
2398 for (group = byte_min; group < byte_max; group++)
2401 = get_ccs_octet_table (table_g, charset, group);
2404 for (plane = byte_min; plane < byte_max; plane++)
2407 = get_ccs_octet_table (table_p, charset, plane);
2410 for (row = byte_min; row < byte_max; row++)
2413 = get_ccs_octet_table (table_r, charset, row);
2416 for (cell = byte_min; cell < byte_max; cell++)
2419 = get_ccs_octet_table (table_c, charset, cell);
2423 #ifdef HAVE_LIBCHISE
2424 chise_ccs_set_decoded_char
2430 #else /* HAVE_LIBCHISE */
2431 Fput_database (Fprin1_to_string
2432 (make_int (( group << 24)
2437 Fprin1_to_string (c, Qnil),
2439 #endif /* not HAVE_LIBCHISE */
2447 #ifdef HAVE_LIBCHISE
2448 chise_ccs_sync (dt_ccs);
2450 #else /* HAVE_LIBCHISE */
2451 return Fclose_database (db);
2452 #endif /* not HAVE_LIBCHISE */
2455 DEFUN ("reset-charset-mapping-table", Freset_charset_mapping_table, 1, 1, 0, /*
2456 Reset mapping-table of CCS with database file.
2460 #ifdef HAVE_LIBCHISE
2461 CHISE_CCS chise_ccs;
2463 Lisp_Object db_file;
2466 ccs = Fget_charset (ccs);
2468 #ifdef HAVE_LIBCHISE
2469 if ( open_chise_data_source_maybe () )
2472 chise_ccs = chise_ds_get_ccs (default_chise_data_source,
2473 XSTRING_DATA (Fsymbol_name
2474 (XCHARSET_NAME(ccs))));
2475 if (chise_ccs == NULL)
2478 db_file = char_attribute_system_db_file (XCHARSET_NAME(ccs),
2479 Qsystem_char_id, 0);
2483 #ifdef HAVE_LIBCHISE
2484 chise_ccs_setup_db (chise_ccs, 0) == 0
2486 !NILP (Ffile_exists_p (db_file))
2490 XCHARSET_DECODING_TABLE(ccs) = Qunloaded;
2497 load_char_decoding_entry_maybe (Lisp_Object ccs, int code_point)
2499 #ifdef HAVE_LIBCHISE
2500 CHISE_Char_ID char_id;
2502 if ( open_chise_data_source_maybe () )
2506 = chise_ds_decode_char (default_chise_data_source,
2507 XSTRING_DATA(Fsymbol_name (XCHARSET_NAME(ccs))),
2510 decoding_table_put_char (ccs, code_point, make_char (char_id));
2512 decoding_table_put_char (ccs, code_point, Qnil);
2514 /* chise_ccst_close (dt_ccs); */
2516 #else /* HAVE_LIBCHISE */
2519 = char_attribute_system_db_file (XCHARSET_NAME(ccs), Qsystem_char_id,
2522 db = Fopen_database (db_file, Qnil, Qnil, build_string ("r"), Qnil);
2526 = Fget_database (Fprin1_to_string (make_int (code_point), Qnil),
2533 decoding_table_put_char (ccs, code_point, ret);
2534 Fclose_database (db);
2538 decoding_table_put_char (ccs, code_point, Qnil);
2539 Fclose_database (db);
2542 #endif /* not HAVE_LIBCHISE */
2545 #ifdef HAVE_LIBCHISE
2546 DEFUN ("save-charset-properties", Fsave_charset_properties, 1, 1, 0, /*
2547 Save properties of CHARSET.
2551 struct Lisp_Charset *cs;
2552 CHISE_Property property;
2554 unsigned char* feature_name;
2556 ccs = Fget_charset (charset);
2557 cs = XCHARSET (ccs);
2559 if ( open_chise_data_source_maybe () )
2562 if ( SYMBOLP (charset) && !EQ (charset, XCHARSET_NAME (ccs)) )
2564 property = chise_ds_get_property (default_chise_data_source,
2566 feature_name = XSTRING_DATA (Fsymbol_name (charset));
2567 chise_feature_set_property_value
2568 (chise_ds_get_feature (default_chise_data_source, feature_name),
2569 property, XSTRING_DATA (Fprin1_to_string (CHARSET_NAME (cs),
2571 chise_property_sync (property);
2573 charset = XCHARSET_NAME (ccs);
2574 feature_name = XSTRING_DATA (Fsymbol_name (charset));
2576 property = chise_ds_get_property (default_chise_data_source,
2578 chise_feature_set_property_value
2579 (chise_ds_get_feature (default_chise_data_source, feature_name),
2580 property, XSTRING_DATA (Fprin1_to_string
2581 (CHARSET_DOC_STRING (cs), Qnil)));
2582 chise_property_sync (property);
2584 property = chise_ds_get_property (default_chise_data_source, "type");
2585 chise_feature_set_property_value
2586 (chise_ds_get_feature (default_chise_data_source, feature_name),
2588 chise_property_sync (property);
2590 property = chise_ds_get_property (default_chise_data_source, "chars");
2591 chise_feature_set_property_value
2592 (chise_ds_get_feature (default_chise_data_source, feature_name),
2593 property, XSTRING_DATA (Fprin1_to_string (make_int
2594 (CHARSET_CHARS (cs)),
2596 chise_property_sync (property);
2598 property = chise_ds_get_property (default_chise_data_source, "dimension");
2599 chise_feature_set_property_value
2600 (chise_ds_get_feature (default_chise_data_source, feature_name),
2601 property, XSTRING_DATA (Fprin1_to_string (make_int
2602 (CHARSET_DIMENSION (cs)),
2604 chise_property_sync (property);
2606 if ( CHARSET_FINAL (cs) != 0 )
2608 property = chise_ds_get_property (default_chise_data_source,
2610 chise_feature_set_property_value
2611 (chise_ds_get_feature (default_chise_data_source, feature_name),
2612 property, XSTRING_DATA (Fprin1_to_string (make_int
2613 (CHARSET_FINAL (cs)),
2615 chise_property_sync (property);
2618 if ( !NILP (CHARSET_MOTHER (cs)) )
2620 Lisp_Object mother = CHARSET_MOTHER (cs);
2622 if ( CHARSETP (mother) )
2623 mother = XCHARSET_NAME (mother);
2625 property = chise_ds_get_property (default_chise_data_source,
2627 chise_feature_set_property_value
2628 (chise_ds_get_feature (default_chise_data_source, feature_name),
2629 property, XSTRING_DATA (Fprin1_to_string (mother, Qnil)));
2630 chise_property_sync (property);
2633 if ( CHARSET_MAX_CODE (cs) != 0 )
2637 property = chise_ds_get_property (default_chise_data_source,
2639 if ( CHARSET_MIN_CODE (cs) == 0 )
2640 chise_feature_set_property_value
2641 (chise_ds_get_feature (default_chise_data_source, feature_name),
2645 sprintf (str, "#x%X", CHARSET_MIN_CODE (cs));
2646 chise_feature_set_property_value
2647 (chise_ds_get_feature (default_chise_data_source, feature_name),
2650 chise_property_sync (property);
2652 property = chise_ds_get_property (default_chise_data_source,
2654 sprintf (str, "#x%X", CHARSET_MAX_CODE (cs));
2655 chise_feature_set_property_value
2656 (chise_ds_get_feature (default_chise_data_source, feature_name),
2658 chise_property_sync (property);
2660 property = chise_ds_get_property (default_chise_data_source,
2661 "mother-code-offset");
2662 if ( CHARSET_CODE_OFFSET (cs) == 0 )
2663 chise_feature_set_property_value
2664 (chise_ds_get_feature (default_chise_data_source, feature_name),
2668 sprintf (str, "#x%X", CHARSET_CODE_OFFSET (cs));
2669 chise_feature_set_property_value
2670 (chise_ds_get_feature (default_chise_data_source, feature_name),
2673 chise_property_sync (property);
2675 property = chise_ds_get_property (default_chise_data_source,
2676 "mother-code-conversion");
2677 if ( CHARSET_CONVERSION (cs) == CONVERSION_IDENTICAL )
2678 chise_feature_set_property_value
2679 (chise_ds_get_feature (default_chise_data_source, feature_name),
2680 property, "identical");
2683 Lisp_Object sym = Qnil;
2685 if ( CHARSET_CONVERSION (cs) == CONVERSION_94x60 )
2687 else if ( CHARSET_CONVERSION (cs) == CONVERSION_94x94x60 )
2689 else if ( CHARSET_CONVERSION (cs) == CONVERSION_BIG5_1 )
2691 else if ( CHARSET_CONVERSION (cs) == CONVERSION_BIG5_2 )
2694 chise_feature_set_property_value
2695 (chise_ds_get_feature (default_chise_data_source, feature_name),
2696 property, XSTRING_DATA (Fprin1_to_string (sym, Qnil)));
2698 chise_feature_set_property_value
2699 (chise_ds_get_feature (default_chise_data_source, feature_name),
2700 property, "unknown");
2702 chise_property_sync (property);
2706 #endif /* HAVE_LIBCHISE */
2708 #endif /* HAVE_CHISE */
2709 #endif /* UTF2000 */
2712 /************************************************************************/
2713 /* Lisp primitives for working with characters */
2714 /************************************************************************/
2717 DEFUN ("decode-char", Fdecode_char, 2, 4, 0, /*
2718 Make a character from CHARSET and code-point CODE.
2719 If DEFINED_ONLY is non-nil, builtin character is not returned.
2720 If WITHOUT_INHERITANCE is non-nil, inherited character is not returned.
2721 If corresponding character is not found, nil is returned.
2723 (charset, code, defined_only, without_inheritance))
2727 charset = Fget_charset (charset);
2730 if ( (XCHARSET_GRAPHIC (charset) == 0) ||
2731 (XCHARSET_GRAPHIC (charset) == 1) )
2733 if (NILP (defined_only))
2734 c = DECODE_CHAR (charset, c, !NILP (without_inheritance));
2736 c = decode_defined_char (charset, c, !NILP (without_inheritance));
2737 return c >= 0 ? make_char (c) : Qnil;
2740 DEFUN ("decode-builtin-char", Fdecode_builtin_char, 2, 2, 0, /*
2741 Make a builtin character from CHARSET and code-point CODE.
2748 charset = Fget_charset (charset);
2750 if (EQ (charset, Vcharset_latin_viscii))
2752 Lisp_Object chr = Fdecode_char (charset, code, Qnil, Qnil);
2758 (ret = Fget_char_attribute (chr,
2759 Vcharset_latin_viscii_lower,
2762 charset = Vcharset_latin_viscii_lower;
2766 (ret = Fget_char_attribute (chr,
2767 Vcharset_latin_viscii_upper,
2770 charset = Vcharset_latin_viscii_upper;
2777 if (XCHARSET_GRAPHIC (charset) == 1)
2780 ch = decode_builtin_char (charset, c);
2782 ch >= 0 ? make_char (ch) : Fdecode_char (charset, code, Qnil, Qnil);
2786 DEFUN ("make-char", Fmake_char, 2, 3, 0, /*
2787 Make a character from CHARSET and octets ARG1 and ARG2.
2788 ARG2 is required only for characters from two-dimensional charsets.
2789 For example, (make-char 'latin-iso8859-2 185) will return the Latin 2
2790 character s with caron.
2792 (charset, arg1, arg2))
2796 int lowlim, highlim;
2798 charset = Fget_charset (charset);
2799 cs = XCHARSET (charset);
2801 if (EQ (charset, Vcharset_ascii)) lowlim = 0, highlim = 127;
2802 else if (EQ (charset, Vcharset_control_1)) lowlim = 0, highlim = 31;
2804 else if (CHARSET_CHARS (cs) == 256) lowlim = 0, highlim = 255;
2806 else if (CHARSET_CHARS (cs) == 94) lowlim = 33, highlim = 126;
2807 else /* CHARSET_CHARS (cs) == 96) */ lowlim = 32, highlim = 127;
2810 /* It is useful (and safe, according to Olivier Galibert) to strip
2811 the 8th bit off ARG1 and ARG2 because it allows programmers to
2812 write (make-char 'latin-iso8859-2 CODE) where code is the actual
2813 Latin 2 code of the character. */
2821 if (a1 < lowlim || a1 > highlim)
2822 args_out_of_range_3 (arg1, make_int (lowlim), make_int (highlim));
2824 if (CHARSET_DIMENSION (cs) == 1)
2828 ("Charset is of dimension one; second octet must be nil", arg2);
2829 return make_char (MAKE_CHAR (charset, a1, 0));
2838 a2 = XINT (arg2) & 0x7f;
2840 if (a2 < lowlim || a2 > highlim)
2841 args_out_of_range_3 (arg2, make_int (lowlim), make_int (highlim));
2843 return make_char (MAKE_CHAR (charset, a1, a2));
2846 DEFUN ("char-charset", Fchar_charset, 1, 1, 0, /*
2847 Return the character set of CHARACTER.
2851 CHECK_CHAR_COERCE_INT (character);
2853 return XCHARSET_NAME (CHAR_CHARSET (XCHAR (character)));
2856 DEFUN ("char-octet", Fchar_octet, 1, 2, 0, /*
2857 Return the octet numbered N (should be 0 or 1) of CHARACTER.
2858 N defaults to 0 if omitted.
2862 Lisp_Object charset;
2865 CHECK_CHAR_COERCE_INT (character);
2867 BREAKUP_CHAR (XCHAR (character), charset, octet0, octet1);
2869 if (NILP (n) || EQ (n, Qzero))
2870 return make_int (octet0);
2871 else if (EQ (n, make_int (1)))
2872 return make_int (octet1);
2874 signal_simple_error ("Octet number must be 0 or 1", n);
2878 DEFUN ("encode-char", Fencode_char, 2, 3, 0, /*
2879 Return code-point of CHARACTER in specified CHARSET.
2881 (character, charset, defined_only))
2885 CHECK_CHAR_COERCE_INT (character);
2886 charset = Fget_charset (charset);
2887 code_point = charset_code_point (charset, XCHAR (character),
2888 !NILP (defined_only));
2889 if (code_point >= 0)
2890 return make_int (code_point);
2896 DEFUN ("split-char", Fsplit_char, 1, 1, 0, /*
2897 Return list of charset and one or two position-codes of CHARACTER.
2901 /* This function can GC */
2902 struct gcpro gcpro1, gcpro2;
2903 Lisp_Object charset = Qnil;
2904 Lisp_Object rc = Qnil;
2912 GCPRO2 (charset, rc);
2913 CHECK_CHAR_COERCE_INT (character);
2916 code_point = ENCODE_CHAR (XCHAR (character), charset);
2917 dimension = XCHARSET_DIMENSION (charset);
2918 while (dimension > 0)
2920 rc = Fcons (make_int (code_point & 255), rc);
2924 rc = Fcons (XCHARSET_NAME (charset), rc);
2926 BREAKUP_CHAR (XCHAR (character), charset, c1, c2);
2928 if (XCHARSET_DIMENSION (Fget_charset (charset)) == 2)
2930 rc = list3 (XCHARSET_NAME (charset), make_int (c1), make_int (c2));
2934 rc = list2 (XCHARSET_NAME (charset), make_int (c1));
2943 #ifdef ENABLE_COMPOSITE_CHARS
2944 /************************************************************************/
2945 /* composite character functions */
2946 /************************************************************************/
2949 lookup_composite_char (Bufbyte *str, int len)
2951 Lisp_Object lispstr = make_string (str, len);
2952 Lisp_Object ch = Fgethash (lispstr,
2953 Vcomposite_char_string2char_hash_table,
2959 if (composite_char_row_next >= 128)
2960 signal_simple_error ("No more composite chars available", lispstr);
2961 emch = MAKE_CHAR (Vcharset_composite, composite_char_row_next,
2962 composite_char_col_next);
2963 Fputhash (make_char (emch), lispstr,
2964 Vcomposite_char_char2string_hash_table);
2965 Fputhash (lispstr, make_char (emch),
2966 Vcomposite_char_string2char_hash_table);
2967 composite_char_col_next++;
2968 if (composite_char_col_next >= 128)
2970 composite_char_col_next = 32;
2971 composite_char_row_next++;
2980 composite_char_string (Emchar ch)
2982 Lisp_Object str = Fgethash (make_char (ch),
2983 Vcomposite_char_char2string_hash_table,
2985 assert (!UNBOUNDP (str));
2989 xxDEFUN ("make-composite-char", Fmake_composite_char, 1, 1, 0, /*
2990 Convert a string into a single composite character.
2991 The character is the result of overstriking all the characters in
2996 CHECK_STRING (string);
2997 return make_char (lookup_composite_char (XSTRING_DATA (string),
2998 XSTRING_LENGTH (string)));
3001 xxDEFUN ("composite-char-string", Fcomposite_char_string, 1, 1, 0, /*
3002 Return a string of the characters comprising a composite character.
3010 if (CHAR_LEADING_BYTE (emch) != LEADING_BYTE_COMPOSITE)
3011 signal_simple_error ("Must be composite char", ch);
3012 return composite_char_string (emch);
3014 #endif /* ENABLE_COMPOSITE_CHARS */
3017 /************************************************************************/
3018 /* initialization */
3019 /************************************************************************/
3022 syms_of_mule_charset (void)
3024 INIT_LRECORD_IMPLEMENTATION (charset);
3026 DEFSUBR (Fcharsetp);
3027 DEFSUBR (Ffind_charset);
3028 DEFSUBR (Fget_charset);
3029 DEFSUBR (Fcharset_list);
3030 DEFSUBR (Fcharset_name);
3031 DEFSUBR (Fmake_charset);
3032 DEFSUBR (Fmake_reverse_direction_charset);
3033 /* DEFSUBR (Freverse_direction_charset); */
3034 DEFSUBR (Fdefine_charset_alias);
3035 DEFSUBR (Fcharset_from_attributes);
3036 DEFSUBR (Fcharset_short_name);
3037 DEFSUBR (Fcharset_long_name);
3038 DEFSUBR (Fcharset_description);
3039 DEFSUBR (Fcharset_dimension);
3040 DEFSUBR (Fcharset_property);
3041 DEFSUBR (Fcharset_id);
3042 DEFSUBR (Fset_charset_ccl_program);
3043 DEFSUBR (Fset_charset_registry);
3046 DEFSUBR (Fcharset_mapping_table);
3047 DEFSUBR (Fset_charset_mapping_table);
3049 DEFSUBR (Fsave_charset_mapping_table);
3050 DEFSUBR (Freset_charset_mapping_table);
3051 #ifdef HAVE_LIBCHISE
3052 DEFSUBR (Fsave_charset_properties);
3053 #endif /* HAVE_LIBCHISE */
3054 #endif /* HAVE_CHISE */
3055 DEFSUBR (Fdecode_char);
3056 DEFSUBR (Fdecode_builtin_char);
3057 DEFSUBR (Fencode_char);
3060 DEFSUBR (Fmake_char);
3061 DEFSUBR (Fchar_charset);
3062 DEFSUBR (Fchar_octet);
3063 DEFSUBR (Fsplit_char);
3065 #ifdef ENABLE_COMPOSITE_CHARS
3066 DEFSUBR (Fmake_composite_char);
3067 DEFSUBR (Fcomposite_char_string);
3070 defsymbol (&Qcharsetp, "charsetp");
3071 defsymbol (&Qregistry, "registry");
3072 defsymbol (&Qfinal, "final");
3073 defsymbol (&Qgraphic, "graphic");
3074 defsymbol (&Qdirection, "direction");
3075 defsymbol (&Qreverse_direction_charset, "reverse-direction-charset");
3076 defsymbol (&Qshort_name, "short-name");
3077 defsymbol (&Qlong_name, "long-name");
3078 defsymbol (&Qiso_ir, "iso-ir");
3080 defsymbol (&Qto_iso_ir, "=>iso-ir");
3081 defsymbol (&Qpartial, "partial");
3082 defsymbol (&Qmother, "mother");
3083 defsymbol (&Qmin_code, "min-code");
3084 defsymbol (&Qmax_code, "max-code");
3085 defsymbol (&Qcode_offset, "code-offset");
3086 defsymbol (&Qconversion, "conversion");
3087 defsymbol (&Q94x60, "94x60");
3088 defsymbol (&Q94x94x60, "94x94x60");
3089 defsymbol (&Qbig5_1, "big5-1");
3090 defsymbol (&Qbig5_2, "big5-2");
3093 defsymbol (&Ql2r, "l2r");
3094 defsymbol (&Qr2l, "r2l");
3096 /* Charsets, compatible with FSF 20.3
3097 Naming convention is Script-Charset[-Edition] */
3098 defsymbol (&Qascii, "ascii");
3099 defsymbol (&Qcontrol_1, "control-1");
3100 defsymbol (&Qlatin_iso8859_1, "latin-iso8859-1");
3101 defsymbol (&Qlatin_iso8859_2, "latin-iso8859-2");
3102 defsymbol (&Qlatin_iso8859_3, "latin-iso8859-3");
3103 defsymbol (&Qlatin_iso8859_4, "latin-iso8859-4");
3104 defsymbol (&Qthai_tis620, "thai-tis620");
3105 defsymbol (&Qgreek_iso8859_7, "greek-iso8859-7");
3106 defsymbol (&Qarabic_iso8859_6, "arabic-iso8859-6");
3107 defsymbol (&Qhebrew_iso8859_8, "hebrew-iso8859-8");
3108 defsymbol (&Qkatakana_jisx0201, "katakana-jisx0201");
3109 defsymbol (&Qlatin_jisx0201, "latin-jisx0201");
3110 defsymbol (&Qcyrillic_iso8859_5, "cyrillic-iso8859-5");
3111 defsymbol (&Qlatin_iso8859_9, "latin-iso8859-9");
3112 /* defsymbol (&Qrep_jis_x0208_1978, "=jis-x0208@1978"); */
3113 defsymbol (&Qrep_gb2312, "=gb2312");
3114 defsymbol (&Qrep_gb12345, "=gb12345");
3115 defsymbol (&Qrep_jis_x0208_1983, "=jis-x0208@1983");
3116 defsymbol (&Qrep_ks_x1001, "=ks-x1001");
3117 defsymbol (&Qrep_jis_x0212, "=jis-x0212");
3118 defsymbol (&Qrep_cns11643_1, "=cns11643-1");
3119 defsymbol (&Qrep_cns11643_2, "=cns11643-2");
3121 defsymbol (&Qsystem_char_id, "system-char-id");
3122 defsymbol (&Qrep_ucs, "=ucs");
3123 defsymbol (&Qucs, "ucs");
3124 defsymbol (&Qucs_bmp, "ucs-bmp");
3125 defsymbol (&Qucs_smp, "ucs-smp");
3126 defsymbol (&Qucs_sip, "ucs-sip");
3127 defsymbol (&Qlatin_viscii, "latin-viscii");
3128 defsymbol (&Qlatin_tcvn5712, "latin-tcvn5712");
3129 defsymbol (&Qlatin_viscii_lower, "latin-viscii-lower");
3130 defsymbol (&Qlatin_viscii_upper, "latin-viscii-upper");
3131 defsymbol (&Qvietnamese_viscii_lower, "vietnamese-viscii-lower");
3132 defsymbol (&Qvietnamese_viscii_upper, "vietnamese-viscii-upper");
3133 defsymbol (&Qrep_jis_x0208, "=jis-x0208");
3134 defsymbol (&Qrep_jis_x0208_1990, "=jis-x0208@1990");
3135 defsymbol (&Qrep_big5, "=big5");
3136 defsymbol (&Qethiopic_ucs, "ethiopic-ucs");
3138 defsymbol (&Qchinese_big5_1, "chinese-big5-1");
3139 defsymbol (&Qchinese_big5_2, "chinese-big5-2");
3141 defsymbol (&Qcomposite, "composite");
3145 vars_of_mule_charset (void)
3152 chlook = xnew_and_zero (struct charset_lookup); /* zero for Purify. */
3153 dump_add_root_struct_ptr (&chlook, &charset_lookup_description);
3155 /* Table of charsets indexed by leading byte. */
3156 for (i = 0; i < countof (chlook->charset_by_leading_byte); i++)
3157 chlook->charset_by_leading_byte[i] = Qnil;
3160 /* Table of charsets indexed by type/final-byte. */
3161 for (i = 0; i < countof (chlook->charset_by_attributes); i++)
3162 for (j = 0; j < countof (chlook->charset_by_attributes[0]); j++)
3163 chlook->charset_by_attributes[i][j] = Qnil;
3165 /* Table of charsets indexed by type/final-byte/direction. */
3166 for (i = 0; i < countof (chlook->charset_by_attributes); i++)
3167 for (j = 0; j < countof (chlook->charset_by_attributes[0]); j++)
3168 for (k = 0; k < countof (chlook->charset_by_attributes[0][0]); k++)
3169 chlook->charset_by_attributes[i][j][k] = Qnil;
3173 chlook->next_allocated_leading_byte = MIN_LEADING_BYTE_PRIVATE;
3175 chlook->next_allocated_1_byte_leading_byte = MIN_LEADING_BYTE_PRIVATE_1;
3176 chlook->next_allocated_2_byte_leading_byte = MIN_LEADING_BYTE_PRIVATE_2;
3180 leading_code_private_11 = PRE_LEADING_BYTE_PRIVATE_1;
3181 DEFVAR_INT ("leading-code-private-11", &leading_code_private_11 /*
3182 Leading-code of private TYPE9N charset of column-width 1.
3184 leading_code_private_11 = PRE_LEADING_BYTE_PRIVATE_1;
3188 Vdefault_coded_charset_priority_list = Qnil;
3189 DEFVAR_LISP ("default-coded-charset-priority-list",
3190 &Vdefault_coded_charset_priority_list /*
3191 Default order of preferred coded-character-sets.
3193 Vdisplay_coded_charset_priority_use_inheritance = Qt;
3194 DEFVAR_LISP ("display-coded-charset-priority-use-inheritance",
3195 &Vdisplay_coded_charset_priority_use_inheritance /*
3196 If non-nil, use character inheritance.
3198 Vdisplay_coded_charset_priority_use_hierarchy_order = Qt;
3199 DEFVAR_LISP ("display-coded-charset-priority-use-hierarchy-order",
3200 &Vdisplay_coded_charset_priority_use_hierarchy_order /*
3201 If non-nil, prefer nearest character in hierarchy order.
3207 complex_vars_of_mule_charset (void)
3209 staticpro (&Vcharset_hash_table);
3210 Vcharset_hash_table =
3211 make_lisp_hash_table (50, HASH_TABLE_NON_WEAK, HASH_TABLE_EQ);
3213 /* Predefined character sets. We store them into variables for
3217 staticpro (&Vcharset_system_char_id);
3218 Vcharset_system_char_id =
3219 make_charset (LEADING_BYTE_SYSTEM_CHAR_ID, Qsystem_char_id, 256, 4,
3220 1, 2, 0, CHARSET_LEFT_TO_RIGHT,
3221 build_string ("SCID"),
3222 build_string ("CHAR-ID"),
3223 build_string ("System char-id"),
3226 Qnil, 0, 0x7FFFFFFF, 0, 0, Qnil, CONVERSION_IDENTICAL,
3228 staticpro (&Vcharset_ucs);
3230 make_charset (LEADING_BYTE_UCS, Qrep_ucs, 256, 4,
3231 1, 2, 0, CHARSET_LEFT_TO_RIGHT,
3232 build_string ("UCS"),
3233 build_string ("UCS"),
3234 build_string ("ISO/IEC 10646"),
3237 Qnil, 0, 0xEFFFF, 0, 0, Qnil, CONVERSION_IDENTICAL,
3239 staticpro (&Vcharset_ucs_bmp);
3241 make_charset (LEADING_BYTE_UCS_BMP, Qucs_bmp, 256, 2,
3242 1, 2, 0, CHARSET_LEFT_TO_RIGHT,
3243 build_string ("BMP"),
3244 build_string ("UCS-BMP"),
3245 build_string ("ISO/IEC 10646 Group 0 Plane 0 (BMP)"),
3247 ("\\(ISO10646\\(\\.[0-9]+\\)?-[01]\\|UCS00-0\\|UNICODE[23]?-0\\)"),
3248 - LEADING_BYTE_UCS_BMP,
3249 Qnil, 0, 0xFFFF, 0, 0, Qnil, CONVERSION_IDENTICAL,
3251 staticpro (&Vcharset_ucs_smp);
3253 make_charset (LEADING_BYTE_UCS_SMP, Qucs_smp, 256, 2,
3254 1, 2, 0, CHARSET_LEFT_TO_RIGHT,
3255 build_string ("SMP"),
3256 build_string ("UCS-SMP"),
3257 build_string ("ISO/IEC 10646 Group 0 Plane 1 (SMP)"),
3258 build_string ("UCS00-1"),
3260 Qnil, MIN_CHAR_SMP, MAX_CHAR_SMP,
3261 MIN_CHAR_SMP, 0, Qnil, CONVERSION_IDENTICAL,
3263 staticpro (&Vcharset_ucs_sip);
3265 make_charset (LEADING_BYTE_UCS_SIP, Qucs_sip, 256, 2,
3266 2, 2, 0, CHARSET_LEFT_TO_RIGHT,
3267 build_string ("SIP"),
3268 build_string ("UCS-SIP"),
3269 build_string ("ISO/IEC 10646 Group 0 Plane 2 (SIP)"),
3270 build_string ("\\(ISO10646.*-2\\|UCS00-2\\)"),
3272 Qnil, MIN_CHAR_SIP, MAX_CHAR_SIP,
3273 MIN_CHAR_SIP, 0, Qnil, CONVERSION_IDENTICAL,
3276 # define MIN_CHAR_THAI 0
3277 # define MAX_CHAR_THAI 0
3278 /* # define MIN_CHAR_HEBREW 0 */
3279 /* # define MAX_CHAR_HEBREW 0 */
3280 # define MIN_CHAR_HALFWIDTH_KATAKANA 0
3281 # define MAX_CHAR_HALFWIDTH_KATAKANA 0
3283 staticpro (&Vcharset_ascii);
3285 make_charset (LEADING_BYTE_ASCII, Qascii, 94, 1,
3286 1, 0, 'B', CHARSET_LEFT_TO_RIGHT,
3287 build_string ("ASCII"),
3288 build_string ("ASCII)"),
3289 build_string ("ASCII (ISO646 IRV)"),
3290 build_string ("\\(iso8859-[0-9]*\\|-ascii\\)"),
3291 - LEADING_BYTE_ASCII,
3292 Qnil, 0, 0x7F, 0, 0, Qnil, CONVERSION_IDENTICAL,
3294 staticpro (&Vcharset_control_1);
3295 Vcharset_control_1 =
3296 make_charset (LEADING_BYTE_CONTROL_1, Qcontrol_1, 94, 1,
3297 1, 1, 0, CHARSET_LEFT_TO_RIGHT,
3298 build_string ("C1"),
3299 build_string ("Control characters"),
3300 build_string ("Control characters 128-191"),
3302 - LEADING_BYTE_CONTROL_1,
3303 Qnil, 0x80, 0x9F, 0x80, 0, Qnil, CONVERSION_IDENTICAL,
3305 staticpro (&Vcharset_latin_iso8859_1);
3306 Vcharset_latin_iso8859_1 =
3307 make_charset (LEADING_BYTE_LATIN_ISO8859_1, Qlatin_iso8859_1, 96, 1,
3308 1, 1, 'A', CHARSET_LEFT_TO_RIGHT,
3309 build_string ("Latin-1"),
3310 build_string ("ISO8859-1 (Latin-1)"),
3311 build_string ("ISO8859-1 (Latin-1)"),
3312 build_string ("iso8859-1"),
3313 - LEADING_BYTE_LATIN_ISO8859_1,
3314 Qnil, 0, 0, 0, 32, Qnil, CONVERSION_IDENTICAL,
3316 staticpro (&Vcharset_latin_iso8859_2);
3317 Vcharset_latin_iso8859_2 =
3318 make_charset (LEADING_BYTE_LATIN_ISO8859_2, Qlatin_iso8859_2, 96, 1,
3319 1, 1, 'B', CHARSET_LEFT_TO_RIGHT,
3320 build_string ("Latin-2"),
3321 build_string ("ISO8859-2 (Latin-2)"),
3322 build_string ("ISO8859-2 (Latin-2)"),
3323 build_string ("iso8859-2"),
3324 - LEADING_BYTE_LATIN_ISO8859_2,
3325 Qnil, 0, 0, 0, 32, Qnil, CONVERSION_IDENTICAL,
3327 staticpro (&Vcharset_latin_iso8859_3);
3328 Vcharset_latin_iso8859_3 =
3329 make_charset (LEADING_BYTE_LATIN_ISO8859_3, Qlatin_iso8859_3, 96, 1,
3330 1, 1, 'C', CHARSET_LEFT_TO_RIGHT,
3331 build_string ("Latin-3"),
3332 build_string ("ISO8859-3 (Latin-3)"),
3333 build_string ("ISO8859-3 (Latin-3)"),
3334 build_string ("iso8859-3"),
3335 - LEADING_BYTE_LATIN_ISO8859_3,
3336 Qnil, 0, 0, 0, 32, Qnil, CONVERSION_IDENTICAL,
3338 staticpro (&Vcharset_latin_iso8859_4);
3339 Vcharset_latin_iso8859_4 =
3340 make_charset (LEADING_BYTE_LATIN_ISO8859_4, Qlatin_iso8859_4, 96, 1,
3341 1, 1, 'D', CHARSET_LEFT_TO_RIGHT,
3342 build_string ("Latin-4"),
3343 build_string ("ISO8859-4 (Latin-4)"),
3344 build_string ("ISO8859-4 (Latin-4)"),
3345 build_string ("iso8859-4"),
3346 - LEADING_BYTE_LATIN_ISO8859_4,
3347 Qnil, 0, 0, 0, 32, Qnil, CONVERSION_IDENTICAL,
3349 staticpro (&Vcharset_thai_tis620);
3350 Vcharset_thai_tis620 =
3351 make_charset (LEADING_BYTE_THAI_TIS620, Qthai_tis620, 96, 1,
3352 1, 1, 'T', CHARSET_LEFT_TO_RIGHT,
3353 build_string ("TIS620"),
3354 build_string ("TIS620 (Thai)"),
3355 build_string ("TIS620.2529 (Thai)"),
3356 build_string ("tis620"),
3357 - LEADING_BYTE_THAI_TIS620,
3358 Qnil, 0, 0, 0, 32, Qnil, CONVERSION_IDENTICAL,
3360 staticpro (&Vcharset_greek_iso8859_7);
3361 Vcharset_greek_iso8859_7 =
3362 make_charset (LEADING_BYTE_GREEK_ISO8859_7, Qgreek_iso8859_7, 96, 1,
3363 1, 1, 'F', CHARSET_LEFT_TO_RIGHT,
3364 build_string ("ISO8859-7"),
3365 build_string ("ISO8859-7 (Greek)"),
3366 build_string ("ISO8859-7 (Greek)"),
3367 build_string ("iso8859-7"),
3368 - LEADING_BYTE_GREEK_ISO8859_7,
3369 Qnil, 0, 0, 0, 32, Qnil, CONVERSION_IDENTICAL,
3371 staticpro (&Vcharset_arabic_iso8859_6);
3372 Vcharset_arabic_iso8859_6 =
3373 make_charset (LEADING_BYTE_ARABIC_ISO8859_6, Qarabic_iso8859_6, 96, 1,
3374 1, 1, 'G', CHARSET_RIGHT_TO_LEFT,
3375 build_string ("ISO8859-6"),
3376 build_string ("ISO8859-6 (Arabic)"),
3377 build_string ("ISO8859-6 (Arabic)"),
3378 build_string ("iso8859-6"),
3379 - LEADING_BYTE_ARABIC_ISO8859_6,
3380 Qnil, 0, 0, 0, 32, Qnil, CONVERSION_IDENTICAL,
3382 staticpro (&Vcharset_hebrew_iso8859_8);
3383 Vcharset_hebrew_iso8859_8 =
3384 make_charset (LEADING_BYTE_HEBREW_ISO8859_8, Qhebrew_iso8859_8, 96, 1,
3385 1, 1, 'H', CHARSET_RIGHT_TO_LEFT,
3386 build_string ("ISO8859-8"),
3387 build_string ("ISO8859-8 (Hebrew)"),
3388 build_string ("ISO8859-8 (Hebrew)"),
3389 build_string ("iso8859-8"),
3390 - LEADING_BYTE_HEBREW_ISO8859_8,
3392 0 /* MIN_CHAR_HEBREW */,
3393 0 /* MAX_CHAR_HEBREW */, 0, 32,
3394 Qnil, CONVERSION_IDENTICAL,
3396 staticpro (&Vcharset_katakana_jisx0201);
3397 Vcharset_katakana_jisx0201 =
3398 make_charset (LEADING_BYTE_KATAKANA_JISX0201, Qkatakana_jisx0201, 94, 1,
3399 1, 1, 'I', CHARSET_LEFT_TO_RIGHT,
3400 build_string ("JISX0201 Kana"),
3401 build_string ("JISX0201.1976 (Japanese Kana)"),
3402 build_string ("JISX0201.1976 Japanese Kana"),
3403 build_string ("jisx0201\\.1976"),
3404 - LEADING_BYTE_KATAKANA_JISX0201,
3405 Qnil, 0, 0, 0, 33, Qnil, CONVERSION_IDENTICAL,
3407 staticpro (&Vcharset_latin_jisx0201);
3408 Vcharset_latin_jisx0201 =
3409 make_charset (LEADING_BYTE_LATIN_JISX0201, Qlatin_jisx0201, 94, 1,
3410 1, 0, 'J', CHARSET_LEFT_TO_RIGHT,
3411 build_string ("JISX0201 Roman"),
3412 build_string ("JISX0201.1976 (Japanese Roman)"),
3413 build_string ("JISX0201.1976 Japanese Roman"),
3414 build_string ("jisx0201\\.1976"),
3415 - LEADING_BYTE_LATIN_JISX0201,
3416 Qnil, 0, 0, 0, 33, Qnil, CONVERSION_IDENTICAL,
3418 staticpro (&Vcharset_cyrillic_iso8859_5);
3419 Vcharset_cyrillic_iso8859_5 =
3420 make_charset (LEADING_BYTE_CYRILLIC_ISO8859_5, Qcyrillic_iso8859_5, 96, 1,
3421 1, 1, 'L', CHARSET_LEFT_TO_RIGHT,
3422 build_string ("ISO8859-5"),
3423 build_string ("ISO8859-5 (Cyrillic)"),
3424 build_string ("ISO8859-5 (Cyrillic)"),
3425 build_string ("iso8859-5"),
3426 - LEADING_BYTE_CYRILLIC_ISO8859_5,
3427 Qnil, 0, 0, 0, 32, Qnil, CONVERSION_IDENTICAL,
3429 staticpro (&Vcharset_latin_iso8859_9);
3430 Vcharset_latin_iso8859_9 =
3431 make_charset (LEADING_BYTE_LATIN_ISO8859_9, Qlatin_iso8859_9, 96, 1,
3432 1, 1, 'M', CHARSET_LEFT_TO_RIGHT,
3433 build_string ("Latin-5"),
3434 build_string ("ISO8859-9 (Latin-5)"),
3435 build_string ("ISO8859-9 (Latin-5)"),
3436 build_string ("iso8859-9"),
3437 - LEADING_BYTE_LATIN_ISO8859_9,
3438 Qnil, 0, 0, 0, 32, Qnil, CONVERSION_IDENTICAL,
3441 staticpro (&Vcharset_jis_x0208);
3442 Vcharset_jis_x0208 =
3443 make_charset (LEADING_BYTE_JIS_X0208,
3444 Qrep_jis_x0208, 94, 2,
3445 2, 0, 'B', CHARSET_LEFT_TO_RIGHT,
3446 build_string ("JIS X0208"),
3447 build_string ("JIS X0208 Common"),
3448 build_string ("JIS X0208 Common part"),
3449 build_string ("jisx0208\\.1990"),
3450 - LEADING_BYTE_JAPANESE_JISX0208_1978,
3452 MIN_CHAR_JIS_X0208_1990,
3453 MAX_CHAR_JIS_X0208_1990, MIN_CHAR_JIS_X0208_1990, 33,
3454 Qnil, CONVERSION_94x94,
3458 staticpro (&Vcharset_japanese_jisx0208_1978);
3459 Vcharset_japanese_jisx0208_1978 =
3460 make_charset (LEADING_BYTE_JAPANESE_JISX0208_1978,
3461 Qrep_jis_x0208_1978, 94, 2,
3462 2, 0, '@', CHARSET_LEFT_TO_RIGHT,
3463 build_string ("JIS X0208:1978"),
3464 build_string ("JIS X0208:1978 (Japanese)"),
3466 ("JIS X0208:1978 Japanese Kanji (so called \"old JIS\")"),
3467 build_string ("\\(jisx0208\\|jisc6226\\)\\.1978"),
3468 - LEADING_BYTE_JAPANESE_JISX0208_1978,
3475 CONVERSION_IDENTICAL,
3478 staticpro (&Vcharset_chinese_gb2312);
3479 Vcharset_chinese_gb2312 =
3480 make_charset (LEADING_BYTE_CHINESE_GB2312, Qrep_gb2312, 94, 2,
3481 2, 0, 'A', CHARSET_LEFT_TO_RIGHT,
3482 build_string ("GB2312"),
3483 build_string ("GB2312)"),
3484 build_string ("GB2312 Chinese simplified"),
3485 build_string ("gb2312"),
3486 - LEADING_BYTE_CHINESE_GB2312,
3487 Qnil, 0, 0, 0, 33, Qnil, CONVERSION_IDENTICAL,
3489 staticpro (&Vcharset_chinese_gb12345);
3490 Vcharset_chinese_gb12345 =
3491 make_charset (LEADING_BYTE_CHINESE_GB12345, Qrep_gb12345, 94, 2,
3492 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3493 build_string ("G1"),
3494 build_string ("GB 12345)"),
3495 build_string ("GB 12345-1990"),
3496 build_string ("GB12345\\(\\.1990\\)?-0"),
3498 Qnil, 0, 0, 0, 33, Qnil, CONVERSION_IDENTICAL,
3500 staticpro (&Vcharset_japanese_jisx0208);
3501 Vcharset_japanese_jisx0208 =
3502 make_charset (LEADING_BYTE_JAPANESE_JISX0208, Qrep_jis_x0208_1983, 94, 2,
3503 2, 0, 'B', CHARSET_LEFT_TO_RIGHT,
3504 build_string ("JISX0208"),
3505 build_string ("JIS X0208:1983 (Japanese)"),
3506 build_string ("JIS X0208:1983 Japanese Kanji"),
3507 build_string ("jisx0208\\.1983"),
3508 - LEADING_BYTE_JAPANESE_JISX0208,
3515 CONVERSION_IDENTICAL,
3518 staticpro (&Vcharset_japanese_jisx0208_1990);
3519 Vcharset_japanese_jisx0208_1990 =
3520 make_charset (LEADING_BYTE_JAPANESE_JISX0208_1990,
3521 Qrep_jis_x0208_1990, 94, 2,
3522 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3523 build_string ("JISX0208-1990"),
3524 build_string ("JIS X0208:1990 (Japanese)"),
3525 build_string ("JIS X0208:1990 Japanese Kanji"),
3526 build_string ("jisx0208\\.1990"),
3527 - LEADING_BYTE_JAPANESE_JISX0208_1990,
3529 0x2121 /* MIN_CHAR_JIS_X0208_1990 */,
3530 0x7426 /* MAX_CHAR_JIS_X0208_1990 */,
3531 0 /* MIN_CHAR_JIS_X0208_1990 */, 33,
3532 Vcharset_jis_x0208 /* Qnil */,
3533 CONVERSION_IDENTICAL /* CONVERSION_94x94 */,
3536 staticpro (&Vcharset_korean_ksc5601);
3537 Vcharset_korean_ksc5601 =
3538 make_charset (LEADING_BYTE_KOREAN_KSC5601, Qrep_ks_x1001, 94, 2,
3539 2, 0, 'C', CHARSET_LEFT_TO_RIGHT,
3540 build_string ("KSC5601"),
3541 build_string ("KSC5601 (Korean"),
3542 build_string ("KSC5601 Korean Hangul and Hanja"),
3543 build_string ("ksc5601"),
3544 - LEADING_BYTE_KOREAN_KSC5601,
3545 Qnil, 0, 0, 0, 33, Qnil, CONVERSION_IDENTICAL,
3547 staticpro (&Vcharset_japanese_jisx0212);
3548 Vcharset_japanese_jisx0212 =
3549 make_charset (LEADING_BYTE_JAPANESE_JISX0212, Qrep_jis_x0212, 94, 2,
3550 2, 0, 'D', CHARSET_LEFT_TO_RIGHT,
3551 build_string ("JISX0212"),
3552 build_string ("JISX0212 (Japanese)"),
3553 build_string ("JISX0212 Japanese Supplement"),
3554 build_string ("jisx0212"),
3555 - LEADING_BYTE_JAPANESE_JISX0212,
3556 Qnil, 0, 0, 0, 33, Qnil, CONVERSION_IDENTICAL,
3559 #define CHINESE_CNS_PLANE_RE(n) "cns11643[.-]\\(.*[.-]\\)?" n "$"
3560 staticpro (&Vcharset_chinese_cns11643_1);
3561 Vcharset_chinese_cns11643_1 =
3562 make_charset (LEADING_BYTE_CHINESE_CNS11643_1, Qrep_cns11643_1, 94, 2,
3563 2, 0, 'G', CHARSET_LEFT_TO_RIGHT,
3564 build_string ("CNS11643-1"),
3565 build_string ("CNS11643-1 (Chinese traditional)"),
3567 ("CNS 11643 Plane 1 Chinese traditional"),
3568 build_string (CHINESE_CNS_PLANE_RE("1")),
3569 - LEADING_BYTE_CHINESE_CNS11643_1,
3570 Qnil, 0, 0, 0, 33, Qnil, CONVERSION_IDENTICAL,
3572 staticpro (&Vcharset_chinese_cns11643_2);
3573 Vcharset_chinese_cns11643_2 =
3574 make_charset (LEADING_BYTE_CHINESE_CNS11643_2, Qrep_cns11643_2, 94, 2,
3575 2, 0, 'H', CHARSET_LEFT_TO_RIGHT,
3576 build_string ("CNS11643-2"),
3577 build_string ("CNS11643-2 (Chinese traditional)"),
3579 ("CNS 11643 Plane 2 Chinese traditional"),
3580 build_string (CHINESE_CNS_PLANE_RE("2")),
3581 - LEADING_BYTE_CHINESE_CNS11643_2,
3582 Qnil, 0, 0, 0, 33, Qnil, CONVERSION_IDENTICAL,
3585 staticpro (&Vcharset_latin_tcvn5712);
3586 Vcharset_latin_tcvn5712 =
3587 make_charset (LEADING_BYTE_LATIN_TCVN5712, Qlatin_tcvn5712, 96, 1,
3588 1, 1, 'Z', CHARSET_LEFT_TO_RIGHT,
3589 build_string ("TCVN 5712"),
3590 build_string ("TCVN 5712 (VSCII-2)"),
3591 build_string ("Vietnamese TCVN 5712:1983 (VSCII-2)"),
3592 build_string ("tcvn5712\\(\\.1993\\)?-1"),
3593 - LEADING_BYTE_LATIN_TCVN5712,
3594 Qnil, 0, 0, 0, 32, Qnil, CONVERSION_IDENTICAL,
3596 staticpro (&Vcharset_latin_viscii_lower);
3597 Vcharset_latin_viscii_lower =
3598 make_charset (LEADING_BYTE_LATIN_VISCII_LOWER, Qlatin_viscii_lower, 96, 1,
3599 1, 1, '1', CHARSET_LEFT_TO_RIGHT,
3600 build_string ("VISCII lower"),
3601 build_string ("VISCII lower (Vietnamese)"),
3602 build_string ("VISCII lower (Vietnamese)"),
3603 build_string ("MULEVISCII-LOWER"),
3605 Qnil, 0, 0, 0, 32, Qnil, CONVERSION_IDENTICAL,
3607 staticpro (&Vcharset_latin_viscii_upper);
3608 Vcharset_latin_viscii_upper =
3609 make_charset (LEADING_BYTE_LATIN_VISCII_UPPER, Qlatin_viscii_upper, 96, 1,
3610 1, 1, '2', CHARSET_LEFT_TO_RIGHT,
3611 build_string ("VISCII upper"),
3612 build_string ("VISCII upper (Vietnamese)"),
3613 build_string ("VISCII upper (Vietnamese)"),
3614 build_string ("MULEVISCII-UPPER"),
3616 Qnil, 0, 0, 0, 32, Qnil, CONVERSION_IDENTICAL,
3618 staticpro (&Vcharset_latin_viscii);
3619 Vcharset_latin_viscii =
3620 make_charset (LEADING_BYTE_LATIN_VISCII, Qlatin_viscii, 256, 1,
3621 1, 2, 0, CHARSET_LEFT_TO_RIGHT,
3622 build_string ("VISCII"),
3623 build_string ("VISCII 1.1 (Vietnamese)"),
3624 build_string ("VISCII 1.1 (Vietnamese)"),
3625 build_string ("VISCII1\\.1"),
3627 Qnil, 0, 0, 0, 0, Qnil, CONVERSION_IDENTICAL,
3629 staticpro (&Vcharset_chinese_big5);
3630 Vcharset_chinese_big5 =
3631 make_charset (LEADING_BYTE_CHINESE_BIG5, Qrep_big5, 256, 2,
3632 2, 2, 0, CHARSET_LEFT_TO_RIGHT,
3633 build_string ("Big5"),
3634 build_string ("Big5"),
3635 build_string ("Big5 Chinese traditional"),
3636 build_string ("big5-0"),
3639 MIN_CHAR_BIG5_CDP, MAX_CHAR_BIG5_CDP,
3640 MIN_CHAR_BIG5_CDP, 0, Qnil, CONVERSION_IDENTICAL,
3643 staticpro (&Vcharset_ethiopic_ucs);
3644 Vcharset_ethiopic_ucs =
3645 make_charset (LEADING_BYTE_ETHIOPIC_UCS, Qethiopic_ucs, 256, 2,
3646 2, 2, 0, CHARSET_LEFT_TO_RIGHT,
3647 build_string ("Ethiopic (UCS)"),
3648 build_string ("Ethiopic (UCS)"),
3649 build_string ("Ethiopic of UCS"),
3650 build_string ("Ethiopic-Unicode"),
3652 Qnil, 0x1200, 0x137F, 0, 0,
3653 Qnil, CONVERSION_IDENTICAL,
3656 staticpro (&Vcharset_chinese_big5_1);
3657 Vcharset_chinese_big5_1 =
3658 make_charset (LEADING_BYTE_CHINESE_BIG5_1, Qchinese_big5_1, 94, 2,
3659 2, 0, '0', CHARSET_LEFT_TO_RIGHT,
3660 build_string ("Big5"),
3661 build_string ("Big5 (Level-1)"),
3663 ("Big5 Level-1 Chinese traditional"),
3664 build_string ("big5"),
3666 Qnil, 0, 0, 0, 33, /* Qnil, CONVERSION_IDENTICAL */
3667 Vcharset_chinese_big5, CONVERSION_BIG5_1,
3669 staticpro (&Vcharset_chinese_big5_2);
3670 Vcharset_chinese_big5_2 =
3671 make_charset (LEADING_BYTE_CHINESE_BIG5_2, Qchinese_big5_2, 94, 2,
3672 2, 0, '1', CHARSET_LEFT_TO_RIGHT,
3673 build_string ("Big5"),
3674 build_string ("Big5 (Level-2)"),
3676 ("Big5 Level-2 Chinese traditional"),
3677 build_string ("big5"),
3679 Qnil, 0, 0, 0, 33, /* Qnil, CONVERSION_IDENTICAL */
3680 Vcharset_chinese_big5, CONVERSION_BIG5_2,
3683 #ifdef ENABLE_COMPOSITE_CHARS
3684 /* #### For simplicity, we put composite chars into a 96x96 charset.
3685 This is going to lead to problems because you can run out of
3686 room, esp. as we don't yet recycle numbers. */
3687 staticpro (&Vcharset_composite);
3688 Vcharset_composite =
3689 make_charset (LEADING_BYTE_COMPOSITE, Qcomposite, 96, 2,
3690 2, 0, 0, CHARSET_LEFT_TO_RIGHT,
3691 build_string ("Composite"),
3692 build_string ("Composite characters"),
3693 build_string ("Composite characters"),
3696 /* #### not dumped properly */
3697 composite_char_row_next = 32;
3698 composite_char_col_next = 32;
3700 Vcomposite_char_string2char_hash_table =
3701 make_lisp_hash_table (500, HASH_TABLE_NON_WEAK, HASH_TABLE_EQUAL);
3702 Vcomposite_char_char2string_hash_table =
3703 make_lisp_hash_table (500, HASH_TABLE_NON_WEAK, HASH_TABLE_EQ);
3704 staticpro (&Vcomposite_char_string2char_hash_table);
3705 staticpro (&Vcomposite_char_char2string_hash_table);
3706 #endif /* ENABLE_COMPOSITE_CHARS */