428
+ − 1 /* XEmacs routines to deal with char tables.
+ − 2 Copyright (C) 1992, 1995 Free Software Foundation, Inc.
+ − 3 Copyright (C) 1995 Sun Microsystems, Inc.
+ − 4 Copyright (C) 1995, 1996 Ben Wing.
+ − 5 Copyright (C) 1995, 1997, 1999 Electrotechnical Laboratory, JAPAN.
+ − 6 Licensed to the Free Software Foundation.
+ − 7
+ − 8 This file is part of XEmacs.
+ − 9
+ − 10 XEmacs is free software; you can redistribute it and/or modify it
+ − 11 under the terms of the GNU General Public License as published by the
+ − 12 Free Software Foundation; either version 2, or (at your option) any
+ − 13 later version.
+ − 14
+ − 15 XEmacs is distributed in the hope that it will be useful, but WITHOUT
+ − 16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ − 17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ − 18 for more details.
+ − 19
+ − 20 You should have received a copy of the GNU General Public License
+ − 21 along with XEmacs; see the file COPYING. If not, write to
+ − 22 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ − 23 Boston, MA 02111-1307, USA. */
+ − 24
+ − 25 /* Synched up with: Mule 2.3. Not synched with FSF.
+ − 26
+ − 27 This file was written independently of the FSF implementation,
+ − 28 and is not compatible. */
+ − 29
+ − 30 /* Authorship:
+ − 31
+ − 32 Ben Wing: wrote, for 19.13 (Mule). Some category table stuff
+ − 33 loosely based on the original Mule.
+ − 34 Jareth Hein: fixed a couple of bugs in the implementation, and
+ − 35 added regex support for categories with check_category_at
+ − 36 */
+ − 37
+ − 38 #include <config.h>
+ − 39 #include "lisp.h"
+ − 40
+ − 41 #include "buffer.h"
+ − 42 #include "chartab.h"
+ − 43 #include "syntax.h"
+ − 44
+ − 45 Lisp_Object Qchar_tablep, Qchar_table;
+ − 46
+ − 47 Lisp_Object Vall_syntax_tables;
+ − 48
+ − 49 #ifdef MULE
+ − 50 Lisp_Object Qcategory_table_p;
+ − 51 Lisp_Object Qcategory_designator_p;
+ − 52 Lisp_Object Qcategory_table_value_p;
+ − 53
+ − 54 Lisp_Object Vstandard_category_table;
+ − 55
+ − 56 /* Variables to determine word boundary. */
+ − 57 Lisp_Object Vword_combining_categories, Vword_separating_categories;
+ − 58 #endif /* MULE */
+ − 59
+ − 60
+ − 61 /* A char table maps from ranges of characters to values.
+ − 62
+ − 63 Implementing a general data structure that maps from arbitrary
+ − 64 ranges of numbers to values is tricky to do efficiently. As it
+ − 65 happens, it should suffice (and is usually more convenient, anyway)
+ − 66 when dealing with characters to restrict the sorts of ranges that
+ − 67 can be assigned values, as follows:
+ − 68
+ − 69 1) All characters.
+ − 70 2) All characters in a charset.
+ − 71 3) All characters in a particular row of a charset, where a "row"
+ − 72 means all characters with the same first byte.
+ − 73 4) A particular character in a charset.
+ − 74
+ − 75 We use char tables to generalize the 256-element vectors now
+ − 76 littering the Emacs code.
+ − 77
+ − 78 Possible uses (all should be converted at some point):
+ − 79
+ − 80 1) category tables
+ − 81 2) syntax tables
+ − 82 3) display tables
+ − 83 4) case tables
+ − 84 5) keyboard-translate-table?
+ − 85
+ − 86 We provide an
+ − 87 abstract type to generalize the Emacs vectors and Mule
+ − 88 vectors-of-vectors goo.
+ − 89 */
+ − 90
+ − 91 /************************************************************************/
+ − 92 /* Char Table object */
+ − 93 /************************************************************************/
+ − 94
+ − 95 #ifdef MULE
+ − 96
+ − 97 static Lisp_Object
+ − 98 mark_char_table_entry (Lisp_Object obj)
+ − 99 {
440
+ − 100 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (obj);
428
+ − 101 int i;
+ − 102
+ − 103 for (i = 0; i < 96; i++)
+ − 104 {
+ − 105 mark_object (cte->level2[i]);
+ − 106 }
+ − 107 return Qnil;
+ − 108 }
+ − 109
+ − 110 static int
+ − 111 char_table_entry_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
+ − 112 {
440
+ − 113 Lisp_Char_Table_Entry *cte1 = XCHAR_TABLE_ENTRY (obj1);
+ − 114 Lisp_Char_Table_Entry *cte2 = XCHAR_TABLE_ENTRY (obj2);
428
+ − 115 int i;
+ − 116
+ − 117 for (i = 0; i < 96; i++)
+ − 118 if (!internal_equal (cte1->level2[i], cte2->level2[i], depth + 1))
+ − 119 return 0;
+ − 120
+ − 121 return 1;
+ − 122 }
+ − 123
665
+ − 124 static Hashcode
428
+ − 125 char_table_entry_hash (Lisp_Object obj, int depth)
+ − 126 {
440
+ − 127 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (obj);
428
+ − 128
+ − 129 return internal_array_hash (cte->level2, 96, depth);
+ − 130 }
+ − 131
+ − 132 static const struct lrecord_description char_table_entry_description[] = {
440
+ − 133 { XD_LISP_OBJECT_ARRAY, offsetof (Lisp_Char_Table_Entry, level2), 96 },
428
+ − 134 { XD_END }
+ − 135 };
+ − 136
+ − 137 DEFINE_LRECORD_IMPLEMENTATION ("char-table-entry", char_table_entry,
+ − 138 mark_char_table_entry, internal_object_printer,
+ − 139 0, char_table_entry_equal,
+ − 140 char_table_entry_hash,
+ − 141 char_table_entry_description,
440
+ − 142 Lisp_Char_Table_Entry);
428
+ − 143 #endif /* MULE */
+ − 144
+ − 145 static Lisp_Object
+ − 146 mark_char_table (Lisp_Object obj)
+ − 147 {
440
+ − 148 Lisp_Char_Table *ct = XCHAR_TABLE (obj);
428
+ − 149 int i;
+ − 150
+ − 151 for (i = 0; i < NUM_ASCII_CHARS; i++)
+ − 152 mark_object (ct->ascii[i]);
+ − 153 #ifdef MULE
+ − 154 for (i = 0; i < NUM_LEADING_BYTES; i++)
+ − 155 mark_object (ct->level1[i]);
+ − 156 #endif
+ − 157 return ct->mirror_table;
+ − 158 }
+ − 159
+ − 160 /* WARNING: All functions of this nature need to be written extremely
+ − 161 carefully to avoid crashes during GC. Cf. prune_specifiers()
+ − 162 and prune_weak_hash_tables(). */
+ − 163
+ − 164 void
+ − 165 prune_syntax_tables (void)
+ − 166 {
+ − 167 Lisp_Object rest, prev = Qnil;
+ − 168
+ − 169 for (rest = Vall_syntax_tables;
+ − 170 !NILP (rest);
+ − 171 rest = XCHAR_TABLE (rest)->next_table)
+ − 172 {
+ − 173 if (! marked_p (rest))
+ − 174 {
+ − 175 /* This table is garbage. Remove it from the list. */
+ − 176 if (NILP (prev))
+ − 177 Vall_syntax_tables = XCHAR_TABLE (rest)->next_table;
+ − 178 else
+ − 179 XCHAR_TABLE (prev)->next_table =
+ − 180 XCHAR_TABLE (rest)->next_table;
+ − 181 }
+ − 182 }
+ − 183 }
+ − 184
+ − 185 static Lisp_Object
+ − 186 char_table_type_to_symbol (enum char_table_type type)
+ − 187 {
+ − 188 switch (type)
+ − 189 {
+ − 190 default: abort();
+ − 191 case CHAR_TABLE_TYPE_GENERIC: return Qgeneric;
+ − 192 case CHAR_TABLE_TYPE_SYNTAX: return Qsyntax;
+ − 193 case CHAR_TABLE_TYPE_DISPLAY: return Qdisplay;
+ − 194 case CHAR_TABLE_TYPE_CHAR: return Qchar;
+ − 195 #ifdef MULE
+ − 196 case CHAR_TABLE_TYPE_CATEGORY: return Qcategory;
+ − 197 #endif
+ − 198 }
+ − 199 }
+ − 200
+ − 201 static enum char_table_type
+ − 202 symbol_to_char_table_type (Lisp_Object symbol)
+ − 203 {
+ − 204 CHECK_SYMBOL (symbol);
+ − 205
+ − 206 if (EQ (symbol, Qgeneric)) return CHAR_TABLE_TYPE_GENERIC;
+ − 207 if (EQ (symbol, Qsyntax)) return CHAR_TABLE_TYPE_SYNTAX;
+ − 208 if (EQ (symbol, Qdisplay)) return CHAR_TABLE_TYPE_DISPLAY;
+ − 209 if (EQ (symbol, Qchar)) return CHAR_TABLE_TYPE_CHAR;
+ − 210 #ifdef MULE
+ − 211 if (EQ (symbol, Qcategory)) return CHAR_TABLE_TYPE_CATEGORY;
+ − 212 #endif
+ − 213
563
+ − 214 invalid_constant ("Unrecognized char table type", symbol);
428
+ − 215 return CHAR_TABLE_TYPE_GENERIC; /* not reached */
+ − 216 }
+ − 217
+ − 218 static void
+ − 219 print_chartab_range (Emchar first, Emchar last, Lisp_Object val,
+ − 220 Lisp_Object printcharfun)
+ − 221 {
+ − 222 if (first != last)
+ − 223 {
+ − 224 write_c_string (" (", printcharfun);
+ − 225 print_internal (make_char (first), printcharfun, 0);
+ − 226 write_c_string (" ", printcharfun);
+ − 227 print_internal (make_char (last), printcharfun, 0);
+ − 228 write_c_string (") ", printcharfun);
+ − 229 }
+ − 230 else
+ − 231 {
+ − 232 write_c_string (" ", printcharfun);
+ − 233 print_internal (make_char (first), printcharfun, 0);
+ − 234 write_c_string (" ", printcharfun);
+ − 235 }
+ − 236 print_internal (val, printcharfun, 1);
+ − 237 }
+ − 238
+ − 239 #ifdef MULE
+ − 240
+ − 241 static void
+ − 242 print_chartab_charset_row (Lisp_Object charset,
+ − 243 int row,
440
+ − 244 Lisp_Char_Table_Entry *cte,
428
+ − 245 Lisp_Object printcharfun)
+ − 246 {
+ − 247 int i;
+ − 248 Lisp_Object cat = Qunbound;
+ − 249 int first = -1;
+ − 250
+ − 251 for (i = 32; i < 128; i++)
+ − 252 {
+ − 253 Lisp_Object pam = cte->level2[i - 32];
+ − 254
+ − 255 if (first == -1)
+ − 256 {
+ − 257 first = i;
+ − 258 cat = pam;
+ − 259 continue;
+ − 260 }
+ − 261
+ − 262 if (!EQ (cat, pam))
+ − 263 {
+ − 264 if (row == -1)
+ − 265 print_chartab_range (MAKE_CHAR (charset, first, 0),
+ − 266 MAKE_CHAR (charset, i - 1, 0),
+ − 267 cat, printcharfun);
+ − 268 else
+ − 269 print_chartab_range (MAKE_CHAR (charset, row, first),
+ − 270 MAKE_CHAR (charset, row, i - 1),
+ − 271 cat, printcharfun);
+ − 272 first = -1;
+ − 273 i--;
+ − 274 }
+ − 275 }
+ − 276
+ − 277 if (first != -1)
+ − 278 {
+ − 279 if (row == -1)
+ − 280 print_chartab_range (MAKE_CHAR (charset, first, 0),
+ − 281 MAKE_CHAR (charset, i - 1, 0),
+ − 282 cat, printcharfun);
+ − 283 else
+ − 284 print_chartab_range (MAKE_CHAR (charset, row, first),
+ − 285 MAKE_CHAR (charset, row, i - 1),
+ − 286 cat, printcharfun);
+ − 287 }
+ − 288 }
+ − 289
+ − 290 static void
+ − 291 print_chartab_two_byte_charset (Lisp_Object charset,
440
+ − 292 Lisp_Char_Table_Entry *cte,
428
+ − 293 Lisp_Object printcharfun)
+ − 294 {
+ − 295 int i;
+ − 296
+ − 297 for (i = 32; i < 128; i++)
+ − 298 {
+ − 299 Lisp_Object jen = cte->level2[i - 32];
+ − 300
+ − 301 if (!CHAR_TABLE_ENTRYP (jen))
+ − 302 {
+ − 303 char buf[100];
+ − 304
+ − 305 write_c_string (" [", printcharfun);
+ − 306 print_internal (XCHARSET_NAME (charset), printcharfun, 0);
+ − 307 sprintf (buf, " %d] ", i);
+ − 308 write_c_string (buf, printcharfun);
+ − 309 print_internal (jen, printcharfun, 0);
+ − 310 }
+ − 311 else
+ − 312 print_chartab_charset_row (charset, i, XCHAR_TABLE_ENTRY (jen),
+ − 313 printcharfun);
+ − 314 }
+ − 315 }
+ − 316
+ − 317 #endif /* MULE */
+ − 318
+ − 319 static void
+ − 320 print_char_table (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
+ − 321 {
440
+ − 322 Lisp_Char_Table *ct = XCHAR_TABLE (obj);
428
+ − 323 char buf[200];
+ − 324
+ − 325 sprintf (buf, "#s(char-table type %s data (",
+ − 326 string_data (symbol_name (XSYMBOL
+ − 327 (char_table_type_to_symbol (ct->type)))));
+ − 328 write_c_string (buf, printcharfun);
+ − 329
+ − 330 /* Now write out the ASCII/Control-1 stuff. */
+ − 331 {
+ − 332 int i;
+ − 333 int first = -1;
+ − 334 Lisp_Object val = Qunbound;
+ − 335
+ − 336 for (i = 0; i < NUM_ASCII_CHARS; i++)
+ − 337 {
+ − 338 if (first == -1)
+ − 339 {
+ − 340 first = i;
+ − 341 val = ct->ascii[i];
+ − 342 continue;
+ − 343 }
+ − 344
+ − 345 if (!EQ (ct->ascii[i], val))
+ − 346 {
+ − 347 print_chartab_range (first, i - 1, val, printcharfun);
+ − 348 first = -1;
+ − 349 i--;
+ − 350 }
+ − 351 }
+ − 352
+ − 353 if (first != -1)
+ − 354 print_chartab_range (first, i - 1, val, printcharfun);
+ − 355 }
+ − 356
+ − 357 #ifdef MULE
+ − 358 {
+ − 359 int i;
+ − 360
+ − 361 for (i = MIN_LEADING_BYTE; i < MIN_LEADING_BYTE + NUM_LEADING_BYTES;
+ − 362 i++)
+ − 363 {
+ − 364 Lisp_Object ann = ct->level1[i - MIN_LEADING_BYTE];
+ − 365 Lisp_Object charset = CHARSET_BY_LEADING_BYTE (i);
+ − 366
+ − 367 if (!CHARSETP (charset) || i == LEADING_BYTE_ASCII
+ − 368 || i == LEADING_BYTE_CONTROL_1)
+ − 369 continue;
+ − 370 if (!CHAR_TABLE_ENTRYP (ann))
+ − 371 {
+ − 372 write_c_string (" ", printcharfun);
+ − 373 print_internal (XCHARSET_NAME (charset),
+ − 374 printcharfun, 0);
+ − 375 write_c_string (" ", printcharfun);
+ − 376 print_internal (ann, printcharfun, 0);
+ − 377 }
+ − 378 else
+ − 379 {
440
+ − 380 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (ann);
428
+ − 381 if (XCHARSET_DIMENSION (charset) == 1)
+ − 382 print_chartab_charset_row (charset, -1, cte, printcharfun);
+ − 383 else
+ − 384 print_chartab_two_byte_charset (charset, cte, printcharfun);
+ − 385 }
+ − 386 }
+ − 387 }
+ − 388 #endif /* MULE */
+ − 389
+ − 390 write_c_string ("))", printcharfun);
+ − 391 }
+ − 392
+ − 393 static int
+ − 394 char_table_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
+ − 395 {
440
+ − 396 Lisp_Char_Table *ct1 = XCHAR_TABLE (obj1);
+ − 397 Lisp_Char_Table *ct2 = XCHAR_TABLE (obj2);
428
+ − 398 int i;
+ − 399
+ − 400 if (CHAR_TABLE_TYPE (ct1) != CHAR_TABLE_TYPE (ct2))
+ − 401 return 0;
+ − 402
+ − 403 for (i = 0; i < NUM_ASCII_CHARS; i++)
+ − 404 if (!internal_equal (ct1->ascii[i], ct2->ascii[i], depth + 1))
+ − 405 return 0;
+ − 406
+ − 407 #ifdef MULE
+ − 408 for (i = 0; i < NUM_LEADING_BYTES; i++)
+ − 409 if (!internal_equal (ct1->level1[i], ct2->level1[i], depth + 1))
+ − 410 return 0;
+ − 411 #endif /* MULE */
+ − 412
+ − 413 return 1;
+ − 414 }
+ − 415
665
+ − 416 static Hashcode
428
+ − 417 char_table_hash (Lisp_Object obj, int depth)
+ − 418 {
440
+ − 419 Lisp_Char_Table *ct = XCHAR_TABLE (obj);
665
+ − 420 Hashcode hashval = internal_array_hash (ct->ascii, NUM_ASCII_CHARS,
647
+ − 421 depth);
428
+ − 422 #ifdef MULE
+ − 423 hashval = HASH2 (hashval,
+ − 424 internal_array_hash (ct->level1, NUM_LEADING_BYTES, depth));
+ − 425 #endif /* MULE */
+ − 426 return hashval;
+ − 427 }
+ − 428
+ − 429 static const struct lrecord_description char_table_description[] = {
440
+ − 430 { XD_LISP_OBJECT_ARRAY, offsetof (Lisp_Char_Table, ascii), NUM_ASCII_CHARS },
428
+ − 431 #ifdef MULE
440
+ − 432 { XD_LISP_OBJECT_ARRAY, offsetof (Lisp_Char_Table, level1), NUM_LEADING_BYTES },
428
+ − 433 #endif
440
+ − 434 { XD_LISP_OBJECT, offsetof (Lisp_Char_Table, mirror_table) },
+ − 435 { XD_LO_LINK, offsetof (Lisp_Char_Table, next_table) },
428
+ − 436 { XD_END }
+ − 437 };
+ − 438
+ − 439 DEFINE_LRECORD_IMPLEMENTATION ("char-table", char_table,
+ − 440 mark_char_table, print_char_table, 0,
+ − 441 char_table_equal, char_table_hash,
+ − 442 char_table_description,
440
+ − 443 Lisp_Char_Table);
428
+ − 444
+ − 445 DEFUN ("char-table-p", Fchar_table_p, 1, 1, 0, /*
+ − 446 Return non-nil if OBJECT is a char table.
+ − 447
+ − 448 A char table is a table that maps characters (or ranges of characters)
+ − 449 to values. Char tables are specialized for characters, only allowing
+ − 450 particular sorts of ranges to be assigned values. Although this
+ − 451 loses in generality, it makes for extremely fast (constant-time)
+ − 452 lookups, and thus is feasible for applications that do an extremely
+ − 453 large number of lookups (e.g. scanning a buffer for a character in
+ − 454 a particular syntax, where a lookup in the syntax table must occur
+ − 455 once per character).
+ − 456
+ − 457 When Mule support exists, the types of ranges that can be assigned
+ − 458 values are
+ − 459
+ − 460 -- all characters
+ − 461 -- an entire charset
+ − 462 -- a single row in a two-octet charset
+ − 463 -- a single character
+ − 464
+ − 465 When Mule support is not present, the types of ranges that can be
+ − 466 assigned values are
+ − 467
+ − 468 -- all characters
+ − 469 -- a single character
+ − 470
444
+ − 471 To create a char table, use `make-char-table'.
+ − 472 To modify a char table, use `put-char-table' or `remove-char-table'.
+ − 473 To retrieve the value for a particular character, use `get-char-table'.
+ − 474 See also `map-char-table', `clear-char-table', `copy-char-table',
+ − 475 `valid-char-table-type-p', `char-table-type-list',
+ − 476 `valid-char-table-value-p', and `check-char-table-value'.
428
+ − 477 */
+ − 478 (object))
+ − 479 {
+ − 480 return CHAR_TABLEP (object) ? Qt : Qnil;
+ − 481 }
+ − 482
+ − 483 DEFUN ("char-table-type-list", Fchar_table_type_list, 0, 0, 0, /*
+ − 484 Return a list of the recognized char table types.
+ − 485 See `valid-char-table-type-p'.
+ − 486 */
+ − 487 ())
+ − 488 {
+ − 489 #ifdef MULE
+ − 490 return list5 (Qchar, Qcategory, Qdisplay, Qgeneric, Qsyntax);
+ − 491 #else
+ − 492 return list4 (Qchar, Qdisplay, Qgeneric, Qsyntax);
+ − 493 #endif
+ − 494 }
+ − 495
+ − 496 DEFUN ("valid-char-table-type-p", Fvalid_char_table_type_p, 1, 1, 0, /*
+ − 497 Return t if TYPE if a recognized char table type.
+ − 498
+ − 499 Each char table type is used for a different purpose and allows different
+ − 500 sorts of values. The different char table types are
+ − 501
+ − 502 `category'
+ − 503 Used for category tables, which specify the regexp categories
+ − 504 that a character is in. The valid values are nil or a
+ − 505 bit vector of 95 elements. Higher-level Lisp functions are
+ − 506 provided for working with category tables. Currently categories
+ − 507 and category tables only exist when Mule support is present.
+ − 508 `char'
+ − 509 A generalized char table, for mapping from one character to
+ − 510 another. Used for case tables, syntax matching tables,
+ − 511 `keyboard-translate-table', etc. The valid values are characters.
+ − 512 `generic'
+ − 513 An even more generalized char table, for mapping from a
+ − 514 character to anything.
+ − 515 `display'
+ − 516 Used for display tables, which specify how a particular character
+ − 517 is to appear when displayed. #### Not yet implemented.
+ − 518 `syntax'
+ − 519 Used for syntax tables, which specify the syntax of a particular
+ − 520 character. Higher-level Lisp functions are provided for
+ − 521 working with syntax tables. The valid values are integers.
+ − 522
+ − 523 */
+ − 524 (type))
+ − 525 {
+ − 526 return (EQ (type, Qchar) ||
+ − 527 #ifdef MULE
+ − 528 EQ (type, Qcategory) ||
+ − 529 #endif
+ − 530 EQ (type, Qdisplay) ||
+ − 531 EQ (type, Qgeneric) ||
+ − 532 EQ (type, Qsyntax)) ? Qt : Qnil;
+ − 533 }
+ − 534
+ − 535 DEFUN ("char-table-type", Fchar_table_type, 1, 1, 0, /*
444
+ − 536 Return the type of CHAR-TABLE.
428
+ − 537 See `valid-char-table-type-p'.
+ − 538 */
444
+ − 539 (char_table))
428
+ − 540 {
444
+ − 541 CHECK_CHAR_TABLE (char_table);
+ − 542 return char_table_type_to_symbol (XCHAR_TABLE (char_table)->type);
428
+ − 543 }
+ − 544
+ − 545 void
440
+ − 546 fill_char_table (Lisp_Char_Table *ct, Lisp_Object value)
428
+ − 547 {
+ − 548 int i;
+ − 549
+ − 550 for (i = 0; i < NUM_ASCII_CHARS; i++)
+ − 551 ct->ascii[i] = value;
+ − 552 #ifdef MULE
+ − 553 for (i = 0; i < NUM_LEADING_BYTES; i++)
+ − 554 ct->level1[i] = value;
+ − 555 #endif /* MULE */
+ − 556
+ − 557 if (ct->type == CHAR_TABLE_TYPE_SYNTAX)
+ − 558 update_syntax_table (ct);
+ − 559 }
+ − 560
+ − 561 DEFUN ("reset-char-table", Freset_char_table, 1, 1, 0, /*
444
+ − 562 Reset CHAR-TABLE to its default state.
428
+ − 563 */
444
+ − 564 (char_table))
428
+ − 565 {
440
+ − 566 Lisp_Char_Table *ct;
428
+ − 567
444
+ − 568 CHECK_CHAR_TABLE (char_table);
+ − 569 ct = XCHAR_TABLE (char_table);
428
+ − 570
+ − 571 switch (ct->type)
+ − 572 {
+ − 573 case CHAR_TABLE_TYPE_CHAR:
+ − 574 fill_char_table (ct, make_char (0));
+ − 575 break;
+ − 576 case CHAR_TABLE_TYPE_DISPLAY:
+ − 577 case CHAR_TABLE_TYPE_GENERIC:
+ − 578 #ifdef MULE
+ − 579 case CHAR_TABLE_TYPE_CATEGORY:
+ − 580 #endif /* MULE */
+ − 581 fill_char_table (ct, Qnil);
+ − 582 break;
+ − 583
+ − 584 case CHAR_TABLE_TYPE_SYNTAX:
+ − 585 fill_char_table (ct, make_int (Sinherit));
+ − 586 break;
+ − 587
+ − 588 default:
+ − 589 abort ();
+ − 590 }
+ − 591
+ − 592 return Qnil;
+ − 593 }
+ − 594
+ − 595 DEFUN ("make-char-table", Fmake_char_table, 1, 1, 0, /*
+ − 596 Return a new, empty char table of type TYPE.
+ − 597 Currently recognized types are 'char, 'category, 'display, 'generic,
+ − 598 and 'syntax. See `valid-char-table-type-p'.
+ − 599 */
+ − 600 (type))
+ − 601 {
440
+ − 602 Lisp_Char_Table *ct;
428
+ − 603 Lisp_Object obj;
+ − 604 enum char_table_type ty = symbol_to_char_table_type (type);
+ − 605
440
+ − 606 ct = alloc_lcrecord_type (Lisp_Char_Table, &lrecord_char_table);
428
+ − 607 ct->type = ty;
+ − 608 if (ty == CHAR_TABLE_TYPE_SYNTAX)
+ − 609 {
+ − 610 ct->mirror_table = Fmake_char_table (Qgeneric);
+ − 611 fill_char_table (XCHAR_TABLE (ct->mirror_table),
+ − 612 make_int (Spunct));
+ − 613 }
+ − 614 else
+ − 615 ct->mirror_table = Qnil;
+ − 616 ct->next_table = Qnil;
+ − 617 XSETCHAR_TABLE (obj, ct);
+ − 618 if (ty == CHAR_TABLE_TYPE_SYNTAX)
+ − 619 {
+ − 620 ct->next_table = Vall_syntax_tables;
+ − 621 Vall_syntax_tables = obj;
+ − 622 }
+ − 623 Freset_char_table (obj);
+ − 624 return obj;
+ − 625 }
+ − 626
+ − 627 #ifdef MULE
+ − 628
+ − 629 static Lisp_Object
+ − 630 make_char_table_entry (Lisp_Object initval)
+ − 631 {
+ − 632 Lisp_Object obj;
+ − 633 int i;
440
+ − 634 Lisp_Char_Table_Entry *cte =
+ − 635 alloc_lcrecord_type (Lisp_Char_Table_Entry, &lrecord_char_table_entry);
428
+ − 636
+ − 637 for (i = 0; i < 96; i++)
+ − 638 cte->level2[i] = initval;
+ − 639
+ − 640 XSETCHAR_TABLE_ENTRY (obj, cte);
+ − 641 return obj;
+ − 642 }
+ − 643
+ − 644 static Lisp_Object
+ − 645 copy_char_table_entry (Lisp_Object entry)
+ − 646 {
440
+ − 647 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (entry);
428
+ − 648 Lisp_Object obj;
+ − 649 int i;
440
+ − 650 Lisp_Char_Table_Entry *ctenew =
+ − 651 alloc_lcrecord_type (Lisp_Char_Table_Entry, &lrecord_char_table_entry);
428
+ − 652
+ − 653 for (i = 0; i < 96; i++)
+ − 654 {
+ − 655 Lisp_Object new = cte->level2[i];
+ − 656 if (CHAR_TABLE_ENTRYP (new))
+ − 657 ctenew->level2[i] = copy_char_table_entry (new);
+ − 658 else
+ − 659 ctenew->level2[i] = new;
+ − 660 }
+ − 661
+ − 662 XSETCHAR_TABLE_ENTRY (obj, ctenew);
+ − 663 return obj;
+ − 664 }
+ − 665
+ − 666 #endif /* MULE */
+ − 667
+ − 668 DEFUN ("copy-char-table", Fcopy_char_table, 1, 1, 0, /*
444
+ − 669 Return a new char table which is a copy of CHAR-TABLE.
428
+ − 670 It will contain the same values for the same characters and ranges
444
+ − 671 as CHAR-TABLE. The values will not themselves be copied.
428
+ − 672 */
444
+ − 673 (char_table))
428
+ − 674 {
440
+ − 675 Lisp_Char_Table *ct, *ctnew;
428
+ − 676 Lisp_Object obj;
+ − 677 int i;
+ − 678
444
+ − 679 CHECK_CHAR_TABLE (char_table);
+ − 680 ct = XCHAR_TABLE (char_table);
440
+ − 681 ctnew = alloc_lcrecord_type (Lisp_Char_Table, &lrecord_char_table);
428
+ − 682 ctnew->type = ct->type;
+ − 683
+ − 684 for (i = 0; i < NUM_ASCII_CHARS; i++)
+ − 685 {
+ − 686 Lisp_Object new = ct->ascii[i];
+ − 687 #ifdef MULE
+ − 688 assert (! (CHAR_TABLE_ENTRYP (new)));
+ − 689 #endif /* MULE */
+ − 690 ctnew->ascii[i] = new;
+ − 691 }
+ − 692
+ − 693 #ifdef MULE
+ − 694
+ − 695 for (i = 0; i < NUM_LEADING_BYTES; i++)
+ − 696 {
+ − 697 Lisp_Object new = ct->level1[i];
+ − 698 if (CHAR_TABLE_ENTRYP (new))
+ − 699 ctnew->level1[i] = copy_char_table_entry (new);
+ − 700 else
+ − 701 ctnew->level1[i] = new;
+ − 702 }
+ − 703
+ − 704 #endif /* MULE */
+ − 705
+ − 706 if (CHAR_TABLEP (ct->mirror_table))
+ − 707 ctnew->mirror_table = Fcopy_char_table (ct->mirror_table);
+ − 708 else
+ − 709 ctnew->mirror_table = ct->mirror_table;
+ − 710 ctnew->next_table = Qnil;
+ − 711 XSETCHAR_TABLE (obj, ctnew);
+ − 712 if (ctnew->type == CHAR_TABLE_TYPE_SYNTAX)
+ − 713 {
+ − 714 ctnew->next_table = Vall_syntax_tables;
+ − 715 Vall_syntax_tables = obj;
+ − 716 }
+ − 717 return obj;
+ − 718 }
+ − 719
+ − 720 static void
+ − 721 decode_char_table_range (Lisp_Object range, struct chartab_range *outrange)
+ − 722 {
+ − 723 if (EQ (range, Qt))
+ − 724 outrange->type = CHARTAB_RANGE_ALL;
+ − 725 else if (CHAR_OR_CHAR_INTP (range))
+ − 726 {
+ − 727 outrange->type = CHARTAB_RANGE_CHAR;
+ − 728 outrange->ch = XCHAR_OR_CHAR_INT (range);
+ − 729 }
+ − 730 #ifndef MULE
+ − 731 else
563
+ − 732 sferror ("Range must be t or a character", range);
428
+ − 733 #else /* MULE */
+ − 734 else if (VECTORP (range))
+ − 735 {
440
+ − 736 Lisp_Vector *vec = XVECTOR (range);
428
+ − 737 Lisp_Object *elts = vector_data (vec);
+ − 738 if (vector_length (vec) != 2)
563
+ − 739 sferror ("Length of charset row vector must be 2",
428
+ − 740 range);
+ − 741 outrange->type = CHARTAB_RANGE_ROW;
+ − 742 outrange->charset = Fget_charset (elts[0]);
+ − 743 CHECK_INT (elts[1]);
+ − 744 outrange->row = XINT (elts[1]);
+ − 745 switch (XCHARSET_TYPE (outrange->charset))
+ − 746 {
+ − 747 case CHARSET_TYPE_94:
+ − 748 case CHARSET_TYPE_96:
563
+ − 749 sferror ("Charset in row vector must be multi-byte",
428
+ − 750 outrange->charset);
+ − 751 case CHARSET_TYPE_94X94:
+ − 752 check_int_range (outrange->row, 33, 126);
+ − 753 break;
+ − 754 case CHARSET_TYPE_96X96:
+ − 755 check_int_range (outrange->row, 32, 127);
+ − 756 break;
+ − 757 default:
+ − 758 abort ();
+ − 759 }
+ − 760 }
+ − 761 else
+ − 762 {
+ − 763 if (!CHARSETP (range) && !SYMBOLP (range))
563
+ − 764 sferror
428
+ − 765 ("Char table range must be t, charset, char, or vector", range);
+ − 766 outrange->type = CHARTAB_RANGE_CHARSET;
+ − 767 outrange->charset = Fget_charset (range);
+ − 768 }
+ − 769 #endif /* MULE */
+ − 770 }
+ − 771
+ − 772 #ifdef MULE
+ − 773
+ − 774 /* called from CHAR_TABLE_VALUE(). */
+ − 775 Lisp_Object
440
+ − 776 get_non_ascii_char_table_value (Lisp_Char_Table *ct, int leading_byte,
428
+ − 777 Emchar c)
+ − 778 {
+ − 779 Lisp_Object val;
+ − 780 Lisp_Object charset = CHARSET_BY_LEADING_BYTE (leading_byte);
+ − 781 int byte1, byte2;
+ − 782
+ − 783 BREAKUP_CHAR_1_UNSAFE (c, charset, byte1, byte2);
+ − 784 val = ct->level1[leading_byte - MIN_LEADING_BYTE];
+ − 785 if (CHAR_TABLE_ENTRYP (val))
+ − 786 {
440
+ − 787 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (val);
428
+ − 788 val = cte->level2[byte1 - 32];
+ − 789 if (CHAR_TABLE_ENTRYP (val))
+ − 790 {
+ − 791 cte = XCHAR_TABLE_ENTRY (val);
+ − 792 assert (byte2 >= 32);
+ − 793 val = cte->level2[byte2 - 32];
+ − 794 assert (!CHAR_TABLE_ENTRYP (val));
+ − 795 }
+ − 796 }
+ − 797
+ − 798 return val;
+ − 799 }
+ − 800
+ − 801 #endif /* MULE */
+ − 802
+ − 803 Lisp_Object
440
+ − 804 get_char_table (Emchar ch, Lisp_Char_Table *ct)
428
+ − 805 {
+ − 806 #ifdef MULE
+ − 807 {
+ − 808 Lisp_Object charset;
+ − 809 int byte1, byte2;
+ − 810 Lisp_Object val;
+ − 811
+ − 812 BREAKUP_CHAR (ch, charset, byte1, byte2);
+ − 813
+ − 814 if (EQ (charset, Vcharset_ascii))
+ − 815 val = ct->ascii[byte1];
+ − 816 else if (EQ (charset, Vcharset_control_1))
+ − 817 val = ct->ascii[byte1 + 128];
+ − 818 else
+ − 819 {
+ − 820 int lb = XCHARSET_LEADING_BYTE (charset) - MIN_LEADING_BYTE;
+ − 821 val = ct->level1[lb];
+ − 822 if (CHAR_TABLE_ENTRYP (val))
+ − 823 {
440
+ − 824 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (val);
428
+ − 825 val = cte->level2[byte1 - 32];
+ − 826 if (CHAR_TABLE_ENTRYP (val))
+ − 827 {
+ − 828 cte = XCHAR_TABLE_ENTRY (val);
+ − 829 assert (byte2 >= 32);
+ − 830 val = cte->level2[byte2 - 32];
+ − 831 assert (!CHAR_TABLE_ENTRYP (val));
+ − 832 }
+ − 833 }
+ − 834 }
+ − 835
+ − 836 return val;
+ − 837 }
+ − 838 #else /* not MULE */
+ − 839 return ct->ascii[(unsigned char)ch];
+ − 840 #endif /* not MULE */
+ − 841 }
+ − 842
+ − 843
+ − 844 DEFUN ("get-char-table", Fget_char_table, 2, 2, 0, /*
444
+ − 845 Find value for CHARACTER in CHAR-TABLE.
428
+ − 846 */
444
+ − 847 (character, char_table))
428
+ − 848 {
444
+ − 849 CHECK_CHAR_TABLE (char_table);
+ − 850 CHECK_CHAR_COERCE_INT (character);
428
+ − 851
444
+ − 852 return get_char_table (XCHAR (character), XCHAR_TABLE (char_table));
428
+ − 853 }
+ − 854
+ − 855 DEFUN ("get-range-char-table", Fget_range_char_table, 2, 3, 0, /*
444
+ − 856 Find value for a range in CHAR-TABLE.
428
+ − 857 If there is more than one value, return MULTI (defaults to nil).
+ − 858 */
444
+ − 859 (range, char_table, multi))
428
+ − 860 {
440
+ − 861 Lisp_Char_Table *ct;
428
+ − 862 struct chartab_range rainj;
+ − 863
+ − 864 if (CHAR_OR_CHAR_INTP (range))
444
+ − 865 return Fget_char_table (range, char_table);
+ − 866 CHECK_CHAR_TABLE (char_table);
+ − 867 ct = XCHAR_TABLE (char_table);
428
+ − 868
+ − 869 decode_char_table_range (range, &rainj);
+ − 870 switch (rainj.type)
+ − 871 {
+ − 872 case CHARTAB_RANGE_ALL:
+ − 873 {
+ − 874 int i;
+ − 875 Lisp_Object first = ct->ascii[0];
+ − 876
+ − 877 for (i = 1; i < NUM_ASCII_CHARS; i++)
+ − 878 if (!EQ (first, ct->ascii[i]))
+ − 879 return multi;
+ − 880
+ − 881 #ifdef MULE
+ − 882 for (i = MIN_LEADING_BYTE; i < MIN_LEADING_BYTE + NUM_LEADING_BYTES;
+ − 883 i++)
+ − 884 {
+ − 885 if (!CHARSETP (CHARSET_BY_LEADING_BYTE (i))
+ − 886 || i == LEADING_BYTE_ASCII
+ − 887 || i == LEADING_BYTE_CONTROL_1)
+ − 888 continue;
+ − 889 if (!EQ (first, ct->level1[i - MIN_LEADING_BYTE]))
+ − 890 return multi;
+ − 891 }
+ − 892 #endif /* MULE */
+ − 893
+ − 894 return first;
+ − 895 }
+ − 896
+ − 897 #ifdef MULE
+ − 898 case CHARTAB_RANGE_CHARSET:
+ − 899 if (EQ (rainj.charset, Vcharset_ascii))
+ − 900 {
+ − 901 int i;
+ − 902 Lisp_Object first = ct->ascii[0];
+ − 903
+ − 904 for (i = 1; i < 128; i++)
+ − 905 if (!EQ (first, ct->ascii[i]))
+ − 906 return multi;
+ − 907 return first;
+ − 908 }
+ − 909
+ − 910 if (EQ (rainj.charset, Vcharset_control_1))
+ − 911 {
+ − 912 int i;
+ − 913 Lisp_Object first = ct->ascii[128];
+ − 914
+ − 915 for (i = 129; i < 160; i++)
+ − 916 if (!EQ (first, ct->ascii[i]))
+ − 917 return multi;
+ − 918 return first;
+ − 919 }
+ − 920
+ − 921 {
+ − 922 Lisp_Object val = ct->level1[XCHARSET_LEADING_BYTE (rainj.charset) -
+ − 923 MIN_LEADING_BYTE];
+ − 924 if (CHAR_TABLE_ENTRYP (val))
+ − 925 return multi;
+ − 926 return val;
+ − 927 }
+ − 928
+ − 929 case CHARTAB_RANGE_ROW:
+ − 930 {
+ − 931 Lisp_Object val = ct->level1[XCHARSET_LEADING_BYTE (rainj.charset) -
+ − 932 MIN_LEADING_BYTE];
+ − 933 if (!CHAR_TABLE_ENTRYP (val))
+ − 934 return val;
+ − 935 val = XCHAR_TABLE_ENTRY (val)->level2[rainj.row - 32];
+ − 936 if (CHAR_TABLE_ENTRYP (val))
+ − 937 return multi;
+ − 938 return val;
+ − 939 }
+ − 940 #endif /* not MULE */
+ − 941
+ − 942 default:
+ − 943 abort ();
+ − 944 }
+ − 945
+ − 946 return Qnil; /* not reached */
+ − 947 }
+ − 948
+ − 949 static int
+ − 950 check_valid_char_table_value (Lisp_Object value, enum char_table_type type,
578
+ − 951 Error_Behavior errb)
428
+ − 952 {
+ − 953 switch (type)
+ − 954 {
+ − 955 case CHAR_TABLE_TYPE_SYNTAX:
+ − 956 if (!ERRB_EQ (errb, ERROR_ME))
+ − 957 return INTP (value) || (CONSP (value) && INTP (XCAR (value))
+ − 958 && CHAR_OR_CHAR_INTP (XCDR (value)));
+ − 959 if (CONSP (value))
+ − 960 {
+ − 961 Lisp_Object cdr = XCDR (value);
+ − 962 CHECK_INT (XCAR (value));
+ − 963 CHECK_CHAR_COERCE_INT (cdr);
+ − 964 }
+ − 965 else
+ − 966 CHECK_INT (value);
+ − 967 break;
+ − 968
+ − 969 #ifdef MULE
+ − 970 case CHAR_TABLE_TYPE_CATEGORY:
+ − 971 if (!ERRB_EQ (errb, ERROR_ME))
+ − 972 return CATEGORY_TABLE_VALUEP (value);
+ − 973 CHECK_CATEGORY_TABLE_VALUE (value);
+ − 974 break;
+ − 975 #endif /* MULE */
+ − 976
+ − 977 case CHAR_TABLE_TYPE_GENERIC:
+ − 978 return 1;
+ − 979
+ − 980 case CHAR_TABLE_TYPE_DISPLAY:
+ − 981 /* #### fix this */
563
+ − 982 maybe_signal_error (Qunimplemented,
+ − 983 "Display char tables not yet implemented",
+ − 984 value, Qchar_table, errb);
428
+ − 985 return 0;
+ − 986
+ − 987 case CHAR_TABLE_TYPE_CHAR:
+ − 988 if (!ERRB_EQ (errb, ERROR_ME))
+ − 989 return CHAR_OR_CHAR_INTP (value);
+ − 990 CHECK_CHAR_COERCE_INT (value);
+ − 991 break;
+ − 992
+ − 993 default:
+ − 994 abort ();
+ − 995 }
+ − 996
+ − 997 return 0; /* not reached */
+ − 998 }
+ − 999
+ − 1000 static Lisp_Object
+ − 1001 canonicalize_char_table_value (Lisp_Object value, enum char_table_type type)
+ − 1002 {
+ − 1003 switch (type)
+ − 1004 {
+ − 1005 case CHAR_TABLE_TYPE_SYNTAX:
+ − 1006 if (CONSP (value))
+ − 1007 {
+ − 1008 Lisp_Object car = XCAR (value);
+ − 1009 Lisp_Object cdr = XCDR (value);
+ − 1010 CHECK_CHAR_COERCE_INT (cdr);
+ − 1011 return Fcons (car, cdr);
+ − 1012 }
+ − 1013 break;
+ − 1014 case CHAR_TABLE_TYPE_CHAR:
+ − 1015 CHECK_CHAR_COERCE_INT (value);
+ − 1016 break;
+ − 1017 default:
+ − 1018 break;
+ − 1019 }
+ − 1020 return value;
+ − 1021 }
+ − 1022
+ − 1023 DEFUN ("valid-char-table-value-p", Fvalid_char_table_value_p, 2, 2, 0, /*
+ − 1024 Return non-nil if VALUE is a valid value for CHAR-TABLE-TYPE.
+ − 1025 */
+ − 1026 (value, char_table_type))
+ − 1027 {
+ − 1028 enum char_table_type type = symbol_to_char_table_type (char_table_type);
+ − 1029
+ − 1030 return check_valid_char_table_value (value, type, ERROR_ME_NOT) ? Qt : Qnil;
+ − 1031 }
+ − 1032
+ − 1033 DEFUN ("check-valid-char-table-value", Fcheck_valid_char_table_value, 2, 2, 0, /*
+ − 1034 Signal an error if VALUE is not a valid value for CHAR-TABLE-TYPE.
+ − 1035 */
+ − 1036 (value, char_table_type))
+ − 1037 {
+ − 1038 enum char_table_type type = symbol_to_char_table_type (char_table_type);
+ − 1039
+ − 1040 check_valid_char_table_value (value, type, ERROR_ME);
+ − 1041 return Qnil;
+ − 1042 }
+ − 1043
+ − 1044 /* Assign VAL to all characters in RANGE in char table CT. */
+ − 1045
+ − 1046 void
440
+ − 1047 put_char_table (Lisp_Char_Table *ct, struct chartab_range *range,
428
+ − 1048 Lisp_Object val)
+ − 1049 {
+ − 1050 switch (range->type)
+ − 1051 {
+ − 1052 case CHARTAB_RANGE_ALL:
+ − 1053 fill_char_table (ct, val);
+ − 1054 return; /* avoid the duplicate call to update_syntax_table() below,
+ − 1055 since fill_char_table() also did that. */
+ − 1056
+ − 1057 #ifdef MULE
+ − 1058 case CHARTAB_RANGE_CHARSET:
+ − 1059 if (EQ (range->charset, Vcharset_ascii))
+ − 1060 {
+ − 1061 int i;
+ − 1062 for (i = 0; i < 128; i++)
+ − 1063 ct->ascii[i] = val;
+ − 1064 }
+ − 1065 else if (EQ (range->charset, Vcharset_control_1))
+ − 1066 {
+ − 1067 int i;
+ − 1068 for (i = 128; i < 160; i++)
+ − 1069 ct->ascii[i] = val;
+ − 1070 }
+ − 1071 else
+ − 1072 {
+ − 1073 int lb = XCHARSET_LEADING_BYTE (range->charset) - MIN_LEADING_BYTE;
+ − 1074 ct->level1[lb] = val;
+ − 1075 }
+ − 1076 break;
+ − 1077
+ − 1078 case CHARTAB_RANGE_ROW:
+ − 1079 {
440
+ − 1080 Lisp_Char_Table_Entry *cte;
428
+ − 1081 int lb = XCHARSET_LEADING_BYTE (range->charset) - MIN_LEADING_BYTE;
+ − 1082 /* make sure that there is a separate entry for the row. */
+ − 1083 if (!CHAR_TABLE_ENTRYP (ct->level1[lb]))
+ − 1084 ct->level1[lb] = make_char_table_entry (ct->level1[lb]);
+ − 1085 cte = XCHAR_TABLE_ENTRY (ct->level1[lb]);
+ − 1086 cte->level2[range->row - 32] = val;
+ − 1087 }
+ − 1088 break;
+ − 1089 #endif /* MULE */
+ − 1090
+ − 1091 case CHARTAB_RANGE_CHAR:
+ − 1092 #ifdef MULE
+ − 1093 {
+ − 1094 Lisp_Object charset;
+ − 1095 int byte1, byte2;
+ − 1096
+ − 1097 BREAKUP_CHAR (range->ch, charset, byte1, byte2);
+ − 1098 if (EQ (charset, Vcharset_ascii))
+ − 1099 ct->ascii[byte1] = val;
+ − 1100 else if (EQ (charset, Vcharset_control_1))
+ − 1101 ct->ascii[byte1 + 128] = val;
+ − 1102 else
+ − 1103 {
440
+ − 1104 Lisp_Char_Table_Entry *cte;
428
+ − 1105 int lb = XCHARSET_LEADING_BYTE (charset) - MIN_LEADING_BYTE;
+ − 1106 /* make sure that there is a separate entry for the row. */
+ − 1107 if (!CHAR_TABLE_ENTRYP (ct->level1[lb]))
+ − 1108 ct->level1[lb] = make_char_table_entry (ct->level1[lb]);
+ − 1109 cte = XCHAR_TABLE_ENTRY (ct->level1[lb]);
+ − 1110 /* now CTE is a char table entry for the charset;
+ − 1111 each entry is for a single row (or character of
+ − 1112 a one-octet charset). */
+ − 1113 if (XCHARSET_DIMENSION (charset) == 1)
+ − 1114 cte->level2[byte1 - 32] = val;
+ − 1115 else
+ − 1116 {
+ − 1117 /* assigning to one character in a two-octet charset. */
+ − 1118 /* make sure that the charset row contains a separate
+ − 1119 entry for each character. */
+ − 1120 if (!CHAR_TABLE_ENTRYP (cte->level2[byte1 - 32]))
+ − 1121 cte->level2[byte1 - 32] =
+ − 1122 make_char_table_entry (cte->level2[byte1 - 32]);
+ − 1123 cte = XCHAR_TABLE_ENTRY (cte->level2[byte1 - 32]);
+ − 1124 cte->level2[byte2 - 32] = val;
+ − 1125 }
+ − 1126 }
+ − 1127 }
+ − 1128 #else /* not MULE */
+ − 1129 ct->ascii[(unsigned char) (range->ch)] = val;
+ − 1130 break;
+ − 1131 #endif /* not MULE */
+ − 1132 }
+ − 1133
+ − 1134 if (ct->type == CHAR_TABLE_TYPE_SYNTAX)
+ − 1135 update_syntax_table (ct);
+ − 1136 }
+ − 1137
+ − 1138 DEFUN ("put-char-table", Fput_char_table, 3, 3, 0, /*
444
+ − 1139 Set the value for chars in RANGE to be VALUE in CHAR-TABLE.
428
+ − 1140
+ − 1141 RANGE specifies one or more characters to be affected and should be
+ − 1142 one of the following:
+ − 1143
+ − 1144 -- t (all characters are affected)
+ − 1145 -- A charset (only allowed when Mule support is present)
+ − 1146 -- A vector of two elements: a two-octet charset and a row number
+ − 1147 (only allowed when Mule support is present)
+ − 1148 -- A single character
+ − 1149
444
+ − 1150 VALUE must be a value appropriate for the type of CHAR-TABLE.
428
+ − 1151 See `valid-char-table-type-p'.
+ − 1152 */
444
+ − 1153 (range, value, char_table))
428
+ − 1154 {
440
+ − 1155 Lisp_Char_Table *ct;
428
+ − 1156 struct chartab_range rainj;
+ − 1157
444
+ − 1158 CHECK_CHAR_TABLE (char_table);
+ − 1159 ct = XCHAR_TABLE (char_table);
+ − 1160 check_valid_char_table_value (value, ct->type, ERROR_ME);
428
+ − 1161 decode_char_table_range (range, &rainj);
444
+ − 1162 value = canonicalize_char_table_value (value, ct->type);
+ − 1163 put_char_table (ct, &rainj, value);
428
+ − 1164 return Qnil;
+ − 1165 }
+ − 1166
+ − 1167 /* Map FN over the ASCII chars in CT. */
+ − 1168
+ − 1169 static int
440
+ − 1170 map_over_charset_ascii (Lisp_Char_Table *ct,
428
+ − 1171 int (*fn) (struct chartab_range *range,
+ − 1172 Lisp_Object val, void *arg),
+ − 1173 void *arg)
+ − 1174 {
+ − 1175 struct chartab_range rainj;
+ − 1176 int i, retval;
+ − 1177 int start = 0;
+ − 1178 #ifdef MULE
+ − 1179 int stop = 128;
+ − 1180 #else
+ − 1181 int stop = 256;
+ − 1182 #endif
+ − 1183
+ − 1184 rainj.type = CHARTAB_RANGE_CHAR;
+ − 1185
+ − 1186 for (i = start, retval = 0; i < stop && retval == 0; i++)
+ − 1187 {
+ − 1188 rainj.ch = (Emchar) i;
+ − 1189 retval = (fn) (&rainj, ct->ascii[i], arg);
+ − 1190 }
+ − 1191
+ − 1192 return retval;
+ − 1193 }
+ − 1194
+ − 1195 #ifdef MULE
+ − 1196
+ − 1197 /* Map FN over the Control-1 chars in CT. */
+ − 1198
+ − 1199 static int
440
+ − 1200 map_over_charset_control_1 (Lisp_Char_Table *ct,
428
+ − 1201 int (*fn) (struct chartab_range *range,
+ − 1202 Lisp_Object val, void *arg),
+ − 1203 void *arg)
+ − 1204 {
+ − 1205 struct chartab_range rainj;
+ − 1206 int i, retval;
+ − 1207 int start = 128;
+ − 1208 int stop = start + 32;
+ − 1209
+ − 1210 rainj.type = CHARTAB_RANGE_CHAR;
+ − 1211
+ − 1212 for (i = start, retval = 0; i < stop && retval == 0; i++)
+ − 1213 {
+ − 1214 rainj.ch = (Emchar) (i);
+ − 1215 retval = (fn) (&rainj, ct->ascii[i], arg);
+ − 1216 }
+ − 1217
+ − 1218 return retval;
+ − 1219 }
+ − 1220
+ − 1221 /* Map FN over the row ROW of two-byte charset CHARSET.
+ − 1222 There must be a separate value for that row in the char table.
+ − 1223 CTE specifies the char table entry for CHARSET. */
+ − 1224
+ − 1225 static int
440
+ − 1226 map_over_charset_row (Lisp_Char_Table_Entry *cte,
428
+ − 1227 Lisp_Object charset, int row,
+ − 1228 int (*fn) (struct chartab_range *range,
+ − 1229 Lisp_Object val, void *arg),
+ − 1230 void *arg)
+ − 1231 {
+ − 1232 Lisp_Object val = cte->level2[row - 32];
+ − 1233
+ − 1234 if (!CHAR_TABLE_ENTRYP (val))
+ − 1235 {
+ − 1236 struct chartab_range rainj;
+ − 1237
+ − 1238 rainj.type = CHARTAB_RANGE_ROW;
+ − 1239 rainj.charset = charset;
+ − 1240 rainj.row = row;
+ − 1241 return (fn) (&rainj, val, arg);
+ − 1242 }
+ − 1243 else
+ − 1244 {
+ − 1245 struct chartab_range rainj;
+ − 1246 int i, retval;
+ − 1247 int charset94_p = (XCHARSET_CHARS (charset) == 94);
+ − 1248 int start = charset94_p ? 33 : 32;
+ − 1249 int stop = charset94_p ? 127 : 128;
+ − 1250
+ − 1251 cte = XCHAR_TABLE_ENTRY (val);
+ − 1252
+ − 1253 rainj.type = CHARTAB_RANGE_CHAR;
+ − 1254
+ − 1255 for (i = start, retval = 0; i < stop && retval == 0; i++)
+ − 1256 {
+ − 1257 rainj.ch = MAKE_CHAR (charset, row, i);
+ − 1258 retval = (fn) (&rainj, cte->level2[i - 32], arg);
+ − 1259 }
+ − 1260 return retval;
+ − 1261 }
+ − 1262 }
+ − 1263
+ − 1264
+ − 1265 static int
440
+ − 1266 map_over_other_charset (Lisp_Char_Table *ct, int lb,
428
+ − 1267 int (*fn) (struct chartab_range *range,
+ − 1268 Lisp_Object val, void *arg),
+ − 1269 void *arg)
+ − 1270 {
+ − 1271 Lisp_Object val = ct->level1[lb - MIN_LEADING_BYTE];
+ − 1272 Lisp_Object charset = CHARSET_BY_LEADING_BYTE (lb);
+ − 1273
+ − 1274 if (!CHARSETP (charset)
+ − 1275 || lb == LEADING_BYTE_ASCII
+ − 1276 || lb == LEADING_BYTE_CONTROL_1)
+ − 1277 return 0;
+ − 1278
+ − 1279 if (!CHAR_TABLE_ENTRYP (val))
+ − 1280 {
+ − 1281 struct chartab_range rainj;
+ − 1282
+ − 1283 rainj.type = CHARTAB_RANGE_CHARSET;
+ − 1284 rainj.charset = charset;
+ − 1285 return (fn) (&rainj, val, arg);
+ − 1286 }
+ − 1287
+ − 1288 {
440
+ − 1289 Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (val);
428
+ − 1290 int charset94_p = (XCHARSET_CHARS (charset) == 94);
+ − 1291 int start = charset94_p ? 33 : 32;
+ − 1292 int stop = charset94_p ? 127 : 128;
+ − 1293 int i, retval;
+ − 1294
+ − 1295 if (XCHARSET_DIMENSION (charset) == 1)
+ − 1296 {
+ − 1297 struct chartab_range rainj;
+ − 1298 rainj.type = CHARTAB_RANGE_CHAR;
+ − 1299
+ − 1300 for (i = start, retval = 0; i < stop && retval == 0; i++)
+ − 1301 {
+ − 1302 rainj.ch = MAKE_CHAR (charset, i, 0);
+ − 1303 retval = (fn) (&rainj, cte->level2[i - 32], arg);
+ − 1304 }
+ − 1305 }
+ − 1306 else
+ − 1307 {
+ − 1308 for (i = start, retval = 0; i < stop && retval == 0; i++)
+ − 1309 retval = map_over_charset_row (cte, charset, i, fn, arg);
+ − 1310 }
+ − 1311
+ − 1312 return retval;
+ − 1313 }
+ − 1314 }
+ − 1315
+ − 1316 #endif /* MULE */
+ − 1317
+ − 1318 /* Map FN (with client data ARG) over range RANGE in char table CT.
+ − 1319 Mapping stops the first time FN returns non-zero, and that value
+ − 1320 becomes the return value of map_char_table(). */
+ − 1321
+ − 1322 int
440
+ − 1323 map_char_table (Lisp_Char_Table *ct,
428
+ − 1324 struct chartab_range *range,
+ − 1325 int (*fn) (struct chartab_range *range,
+ − 1326 Lisp_Object val, void *arg),
+ − 1327 void *arg)
+ − 1328 {
+ − 1329 switch (range->type)
+ − 1330 {
+ − 1331 case CHARTAB_RANGE_ALL:
+ − 1332 {
+ − 1333 int retval;
+ − 1334
+ − 1335 retval = map_over_charset_ascii (ct, fn, arg);
+ − 1336 if (retval)
+ − 1337 return retval;
+ − 1338 #ifdef MULE
+ − 1339 retval = map_over_charset_control_1 (ct, fn, arg);
+ − 1340 if (retval)
+ − 1341 return retval;
+ − 1342 {
+ − 1343 int i;
+ − 1344 int start = MIN_LEADING_BYTE;
+ − 1345 int stop = start + NUM_LEADING_BYTES;
+ − 1346
+ − 1347 for (i = start, retval = 0; i < stop && retval == 0; i++)
+ − 1348 {
+ − 1349 retval = map_over_other_charset (ct, i, fn, arg);
+ − 1350 }
+ − 1351 }
+ − 1352 #endif /* MULE */
+ − 1353 return retval;
+ − 1354 }
+ − 1355
+ − 1356 #ifdef MULE
+ − 1357 case CHARTAB_RANGE_CHARSET:
+ − 1358 return map_over_other_charset (ct,
+ − 1359 XCHARSET_LEADING_BYTE (range->charset),
+ − 1360 fn, arg);
+ − 1361
+ − 1362 case CHARTAB_RANGE_ROW:
+ − 1363 {
+ − 1364 Lisp_Object val = ct->level1[XCHARSET_LEADING_BYTE (range->charset) - MIN_LEADING_BYTE];
+ − 1365 if (!CHAR_TABLE_ENTRYP (val))
+ − 1366 {
+ − 1367 struct chartab_range rainj;
+ − 1368
+ − 1369 rainj.type = CHARTAB_RANGE_ROW;
+ − 1370 rainj.charset = range->charset;
+ − 1371 rainj.row = range->row;
+ − 1372 return (fn) (&rainj, val, arg);
+ − 1373 }
+ − 1374 else
+ − 1375 return map_over_charset_row (XCHAR_TABLE_ENTRY (val),
+ − 1376 range->charset, range->row,
+ − 1377 fn, arg);
+ − 1378 }
+ − 1379 #endif /* MULE */
+ − 1380
+ − 1381 case CHARTAB_RANGE_CHAR:
+ − 1382 {
+ − 1383 Emchar ch = range->ch;
+ − 1384 Lisp_Object val = CHAR_TABLE_VALUE_UNSAFE (ct, ch);
+ − 1385 struct chartab_range rainj;
+ − 1386
+ − 1387 rainj.type = CHARTAB_RANGE_CHAR;
+ − 1388 rainj.ch = ch;
+ − 1389 return (fn) (&rainj, val, arg);
+ − 1390 }
+ − 1391
+ − 1392 default:
+ − 1393 abort ();
+ − 1394 }
+ − 1395
+ − 1396 return 0;
+ − 1397 }
+ − 1398
+ − 1399 struct slow_map_char_table_arg
+ − 1400 {
+ − 1401 Lisp_Object function;
+ − 1402 Lisp_Object retval;
+ − 1403 };
+ − 1404
+ − 1405 static int
+ − 1406 slow_map_char_table_fun (struct chartab_range *range,
+ − 1407 Lisp_Object val, void *arg)
+ − 1408 {
+ − 1409 Lisp_Object ranjarg = Qnil;
+ − 1410 struct slow_map_char_table_arg *closure =
+ − 1411 (struct slow_map_char_table_arg *) arg;
+ − 1412
+ − 1413 switch (range->type)
+ − 1414 {
+ − 1415 case CHARTAB_RANGE_ALL:
+ − 1416 ranjarg = Qt;
+ − 1417 break;
+ − 1418
+ − 1419 #ifdef MULE
+ − 1420 case CHARTAB_RANGE_CHARSET:
+ − 1421 ranjarg = XCHARSET_NAME (range->charset);
+ − 1422 break;
+ − 1423
+ − 1424 case CHARTAB_RANGE_ROW:
+ − 1425 ranjarg = vector2 (XCHARSET_NAME (range->charset),
+ − 1426 make_int (range->row));
+ − 1427 break;
+ − 1428 #endif /* MULE */
+ − 1429 case CHARTAB_RANGE_CHAR:
+ − 1430 ranjarg = make_char (range->ch);
+ − 1431 break;
+ − 1432 default:
+ − 1433 abort ();
+ − 1434 }
+ − 1435
+ − 1436 closure->retval = call2 (closure->function, ranjarg, val);
+ − 1437 return !NILP (closure->retval);
+ − 1438 }
+ − 1439
+ − 1440 DEFUN ("map-char-table", Fmap_char_table, 2, 3, 0, /*
444
+ − 1441 Map FUNCTION over entries in CHAR-TABLE, calling it with two args,
428
+ − 1442 each key and value in the table.
+ − 1443
+ − 1444 RANGE specifies a subrange to map over and is in the same format as
+ − 1445 the RANGE argument to `put-range-table'. If omitted or t, it defaults to
+ − 1446 the entire table.
+ − 1447 */
444
+ − 1448 (function, char_table, range))
428
+ − 1449 {
440
+ − 1450 Lisp_Char_Table *ct;
428
+ − 1451 struct slow_map_char_table_arg slarg;
+ − 1452 struct gcpro gcpro1, gcpro2;
+ − 1453 struct chartab_range rainj;
+ − 1454
444
+ − 1455 CHECK_CHAR_TABLE (char_table);
+ − 1456 ct = XCHAR_TABLE (char_table);
428
+ − 1457 if (NILP (range))
+ − 1458 range = Qt;
+ − 1459 decode_char_table_range (range, &rainj);
+ − 1460 slarg.function = function;
+ − 1461 slarg.retval = Qnil;
+ − 1462 GCPRO2 (slarg.function, slarg.retval);
+ − 1463 map_char_table (ct, &rainj, slow_map_char_table_fun, &slarg);
+ − 1464 UNGCPRO;
+ − 1465
+ − 1466 return slarg.retval;
+ − 1467 }
+ − 1468
+ − 1469
+ − 1470
+ − 1471 /************************************************************************/
+ − 1472 /* Char table read syntax */
+ − 1473 /************************************************************************/
+ − 1474
+ − 1475 static int
+ − 1476 chartab_type_validate (Lisp_Object keyword, Lisp_Object value,
578
+ − 1477 Error_Behavior errb)
428
+ − 1478 {
+ − 1479 /* #### should deal with ERRB */
+ − 1480 symbol_to_char_table_type (value);
+ − 1481 return 1;
+ − 1482 }
+ − 1483
+ − 1484 static int
+ − 1485 chartab_data_validate (Lisp_Object keyword, Lisp_Object value,
578
+ − 1486 Error_Behavior errb)
428
+ − 1487 {
+ − 1488 Lisp_Object rest;
+ − 1489
+ − 1490 /* #### should deal with ERRB */
+ − 1491 EXTERNAL_LIST_LOOP (rest, value)
+ − 1492 {
+ − 1493 Lisp_Object range = XCAR (rest);
+ − 1494 struct chartab_range dummy;
+ − 1495
+ − 1496 rest = XCDR (rest);
+ − 1497 if (!CONSP (rest))
563
+ − 1498 signal_error (Qlist_formation_error, "Invalid list format", value);
428
+ − 1499 if (CONSP (range))
+ − 1500 {
+ − 1501 if (!CONSP (XCDR (range))
+ − 1502 || !NILP (XCDR (XCDR (range))))
563
+ − 1503 sferror ("Invalid range format", range);
428
+ − 1504 decode_char_table_range (XCAR (range), &dummy);
+ − 1505 decode_char_table_range (XCAR (XCDR (range)), &dummy);
+ − 1506 }
+ − 1507 else
+ − 1508 decode_char_table_range (range, &dummy);
+ − 1509 }
+ − 1510
+ − 1511 return 1;
+ − 1512 }
+ − 1513
+ − 1514 static Lisp_Object
+ − 1515 chartab_instantiate (Lisp_Object data)
+ − 1516 {
+ − 1517 Lisp_Object chartab;
+ − 1518 Lisp_Object type = Qgeneric;
+ − 1519 Lisp_Object dataval = Qnil;
+ − 1520
+ − 1521 while (!NILP (data))
+ − 1522 {
+ − 1523 Lisp_Object keyw = Fcar (data);
+ − 1524 Lisp_Object valw;
+ − 1525
+ − 1526 data = Fcdr (data);
+ − 1527 valw = Fcar (data);
+ − 1528 data = Fcdr (data);
+ − 1529 if (EQ (keyw, Qtype))
+ − 1530 type = valw;
+ − 1531 else if (EQ (keyw, Qdata))
+ − 1532 dataval = valw;
+ − 1533 }
+ − 1534
+ − 1535 chartab = Fmake_char_table (type);
+ − 1536
+ − 1537 data = dataval;
+ − 1538 while (!NILP (data))
+ − 1539 {
+ − 1540 Lisp_Object range = Fcar (data);
+ − 1541 Lisp_Object val = Fcar (Fcdr (data));
+ − 1542
+ − 1543 data = Fcdr (Fcdr (data));
+ − 1544 if (CONSP (range))
+ − 1545 {
+ − 1546 if (CHAR_OR_CHAR_INTP (XCAR (range)))
+ − 1547 {
+ − 1548 Emchar first = XCHAR_OR_CHAR_INT (Fcar (range));
+ − 1549 Emchar last = XCHAR_OR_CHAR_INT (Fcar (Fcdr (range)));
+ − 1550 Emchar i;
+ − 1551
+ − 1552 for (i = first; i <= last; i++)
+ − 1553 Fput_char_table (make_char (i), val, chartab);
+ − 1554 }
+ − 1555 else
+ − 1556 abort ();
+ − 1557 }
+ − 1558 else
+ − 1559 Fput_char_table (range, val, chartab);
+ − 1560 }
+ − 1561
+ − 1562 return chartab;
+ − 1563 }
+ − 1564
+ − 1565 #ifdef MULE
+ − 1566
+ − 1567
+ − 1568 /************************************************************************/
+ − 1569 /* Category Tables, specifically */
+ − 1570 /************************************************************************/
+ − 1571
+ − 1572 DEFUN ("category-table-p", Fcategory_table_p, 1, 1, 0, /*
444
+ − 1573 Return t if OBJECT is a category table.
428
+ − 1574 A category table is a type of char table used for keeping track of
+ − 1575 categories. Categories are used for classifying characters for use
+ − 1576 in regexps -- you can refer to a category rather than having to use
+ − 1577 a complicated [] expression (and category lookups are significantly
+ − 1578 faster).
+ − 1579
+ − 1580 There are 95 different categories available, one for each printable
+ − 1581 character (including space) in the ASCII charset. Each category
+ − 1582 is designated by one such character, called a "category designator".
+ − 1583 They are specified in a regexp using the syntax "\\cX", where X is
+ − 1584 a category designator.
+ − 1585
+ − 1586 A category table specifies, for each character, the categories that
+ − 1587 the character is in. Note that a character can be in more than one
+ − 1588 category. More specifically, a category table maps from a character
+ − 1589 to either the value nil (meaning the character is in no categories)
+ − 1590 or a 95-element bit vector, specifying for each of the 95 categories
+ − 1591 whether the character is in that category.
+ − 1592
+ − 1593 Special Lisp functions are provided that abstract this, so you do not
+ − 1594 have to directly manipulate bit vectors.
+ − 1595 */
444
+ − 1596 (object))
428
+ − 1597 {
444
+ − 1598 return (CHAR_TABLEP (object) &&
+ − 1599 XCHAR_TABLE_TYPE (object) == CHAR_TABLE_TYPE_CATEGORY) ?
428
+ − 1600 Qt : Qnil;
+ − 1601 }
+ − 1602
+ − 1603 static Lisp_Object
444
+ − 1604 check_category_table (Lisp_Object object, Lisp_Object default_)
428
+ − 1605 {
444
+ − 1606 if (NILP (object))
+ − 1607 object = default_;
+ − 1608 while (NILP (Fcategory_table_p (object)))
+ − 1609 object = wrong_type_argument (Qcategory_table_p, object);
+ − 1610 return object;
428
+ − 1611 }
+ − 1612
+ − 1613 int
+ − 1614 check_category_char (Emchar ch, Lisp_Object table,
647
+ − 1615 int designator, int not_p)
428
+ − 1616 {
+ − 1617 REGISTER Lisp_Object temp;
440
+ − 1618 Lisp_Char_Table *ctbl;
428
+ − 1619 #ifdef ERROR_CHECK_TYPECHECK
+ − 1620 if (NILP (Fcategory_table_p (table)))
563
+ − 1621 wtaerror ("Expected category table", table);
428
+ − 1622 #endif
+ − 1623 ctbl = XCHAR_TABLE (table);
+ − 1624 temp = get_char_table (ch, ctbl);
+ − 1625 if (NILP (temp))
458
+ − 1626 return not_p;
428
+ − 1627
+ − 1628 designator -= ' ';
458
+ − 1629 return bit_vector_bit (XBIT_VECTOR (temp), designator) ? !not_p : not_p;
428
+ − 1630 }
+ − 1631
+ − 1632 DEFUN ("check-category-at", Fcheck_category_at, 2, 4, 0, /*
444
+ − 1633 Return t if category of the character at POSITION includes DESIGNATOR.
+ − 1634 Optional third arg BUFFER specifies which buffer to use, and defaults
+ − 1635 to the current buffer.
+ − 1636 Optional fourth arg CATEGORY-TABLE specifies the category table to
+ − 1637 use, and defaults to BUFFER's category table.
428
+ − 1638 */
444
+ − 1639 (position, designator, buffer, category_table))
428
+ − 1640 {
+ − 1641 Lisp_Object ctbl;
+ − 1642 Emchar ch;
647
+ − 1643 int des;
428
+ − 1644 struct buffer *buf = decode_buffer (buffer, 0);
+ − 1645
444
+ − 1646 CHECK_INT (position);
428
+ − 1647 CHECK_CATEGORY_DESIGNATOR (designator);
+ − 1648 des = XCHAR (designator);
+ − 1649 ctbl = check_category_table (category_table, Vstandard_category_table);
444
+ − 1650 ch = BUF_FETCH_CHAR (buf, XINT (position));
428
+ − 1651 return check_category_char (ch, ctbl, des, 0) ? Qt : Qnil;
+ − 1652 }
+ − 1653
+ − 1654 DEFUN ("char-in-category-p", Fchar_in_category_p, 2, 3, 0, /*
444
+ − 1655 Return t if category of CHARACTER includes DESIGNATOR, else nil.
+ − 1656 Optional third arg CATEGORY-TABLE specifies the category table to use,
+ − 1657 and defaults to the standard category table.
428
+ − 1658 */
444
+ − 1659 (character, designator, category_table))
428
+ − 1660 {
+ − 1661 Lisp_Object ctbl;
+ − 1662 Emchar ch;
647
+ − 1663 int des;
428
+ − 1664
+ − 1665 CHECK_CATEGORY_DESIGNATOR (designator);
+ − 1666 des = XCHAR (designator);
444
+ − 1667 CHECK_CHAR (character);
+ − 1668 ch = XCHAR (character);
428
+ − 1669 ctbl = check_category_table (category_table, Vstandard_category_table);
+ − 1670 return check_category_char (ch, ctbl, des, 0) ? Qt : Qnil;
+ − 1671 }
+ − 1672
+ − 1673 DEFUN ("category-table", Fcategory_table, 0, 1, 0, /*
444
+ − 1674 Return BUFFER's current category table.
+ − 1675 BUFFER defaults to the current buffer.
428
+ − 1676 */
+ − 1677 (buffer))
+ − 1678 {
+ − 1679 return decode_buffer (buffer, 0)->category_table;
+ − 1680 }
+ − 1681
+ − 1682 DEFUN ("standard-category-table", Fstandard_category_table, 0, 0, 0, /*
+ − 1683 Return the standard category table.
+ − 1684 This is the one used for new buffers.
+ − 1685 */
+ − 1686 ())
+ − 1687 {
+ − 1688 return Vstandard_category_table;
+ − 1689 }
+ − 1690
+ − 1691 DEFUN ("copy-category-table", Fcopy_category_table, 0, 1, 0, /*
444
+ − 1692 Return a new category table which is a copy of CATEGORY-TABLE.
+ − 1693 CATEGORY-TABLE defaults to the standard category table.
428
+ − 1694 */
444
+ − 1695 (category_table))
428
+ − 1696 {
+ − 1697 if (NILP (Vstandard_category_table))
+ − 1698 return Fmake_char_table (Qcategory);
+ − 1699
444
+ − 1700 category_table =
+ − 1701 check_category_table (category_table, Vstandard_category_table);
+ − 1702 return Fcopy_char_table (category_table);
428
+ − 1703 }
+ − 1704
+ − 1705 DEFUN ("set-category-table", Fset_category_table, 1, 2, 0, /*
444
+ − 1706 Select CATEGORY-TABLE as the new category table for BUFFER.
428
+ − 1707 BUFFER defaults to the current buffer if omitted.
+ − 1708 */
444
+ − 1709 (category_table, buffer))
428
+ − 1710 {
+ − 1711 struct buffer *buf = decode_buffer (buffer, 0);
444
+ − 1712 category_table = check_category_table (category_table, Qnil);
+ − 1713 buf->category_table = category_table;
428
+ − 1714 /* Indicate that this buffer now has a specified category table. */
+ − 1715 buf->local_var_flags |= XINT (buffer_local_flags.category_table);
444
+ − 1716 return category_table;
428
+ − 1717 }
+ − 1718
+ − 1719 DEFUN ("category-designator-p", Fcategory_designator_p, 1, 1, 0, /*
444
+ − 1720 Return t if OBJECT is a category designator (a char in the range ' ' to '~').
428
+ − 1721 */
444
+ − 1722 (object))
428
+ − 1723 {
444
+ − 1724 return CATEGORY_DESIGNATORP (object) ? Qt : Qnil;
428
+ − 1725 }
+ − 1726
+ − 1727 DEFUN ("category-table-value-p", Fcategory_table_value_p, 1, 1, 0, /*
444
+ − 1728 Return t if OBJECT is a category table value.
428
+ − 1729 Valid values are nil or a bit vector of size 95.
+ − 1730 */
444
+ − 1731 (object))
428
+ − 1732 {
444
+ − 1733 return CATEGORY_TABLE_VALUEP (object) ? Qt : Qnil;
428
+ − 1734 }
+ − 1735
+ − 1736
+ − 1737 #define CATEGORYP(x) \
+ − 1738 (CHARP (x) && XCHAR (x) >= 0x20 && XCHAR (x) <= 0x7E)
+ − 1739
+ − 1740 #define CATEGORY_SET(c) \
+ − 1741 (get_char_table(c, XCHAR_TABLE(current_buffer->category_table)))
+ − 1742
+ − 1743 /* Return 1 if CATEGORY_SET contains CATEGORY, else return 0.
+ − 1744 The faster version of `!NILP (Faref (category_set, category))'. */
+ − 1745 #define CATEGORY_MEMBER(category, category_set) \
+ − 1746 (bit_vector_bit(XBIT_VECTOR (category_set), category - 32))
+ − 1747
+ − 1748 /* Return 1 if there is a word boundary between two word-constituent
+ − 1749 characters C1 and C2 if they appear in this order, else return 0.
+ − 1750 Use the macro WORD_BOUNDARY_P instead of calling this function
+ − 1751 directly. */
+ − 1752
+ − 1753 int word_boundary_p (Emchar c1, Emchar c2);
+ − 1754 int
+ − 1755 word_boundary_p (Emchar c1, Emchar c2)
+ − 1756 {
+ − 1757 Lisp_Object category_set1, category_set2;
+ − 1758 Lisp_Object tail;
+ − 1759 int default_result;
+ − 1760
+ − 1761 #if 0
+ − 1762 if (COMPOSITE_CHAR_P (c1))
+ − 1763 c1 = cmpchar_component (c1, 0, 1);
+ − 1764 if (COMPOSITE_CHAR_P (c2))
+ − 1765 c2 = cmpchar_component (c2, 0, 1);
+ − 1766 #endif
+ − 1767
+ − 1768 if (EQ (CHAR_CHARSET (c1), CHAR_CHARSET (c2)))
+ − 1769 {
+ − 1770 tail = Vword_separating_categories;
+ − 1771 default_result = 0;
+ − 1772 }
+ − 1773 else
+ − 1774 {
+ − 1775 tail = Vword_combining_categories;
+ − 1776 default_result = 1;
+ − 1777 }
+ − 1778
+ − 1779 category_set1 = CATEGORY_SET (c1);
+ − 1780 if (NILP (category_set1))
+ − 1781 return default_result;
+ − 1782 category_set2 = CATEGORY_SET (c2);
+ − 1783 if (NILP (category_set2))
+ − 1784 return default_result;
+ − 1785
+ − 1786 for (; CONSP (tail); tail = XCONS (tail)->cdr)
+ − 1787 {
+ − 1788 Lisp_Object elt = XCONS(tail)->car;
+ − 1789
+ − 1790 if (CONSP (elt)
+ − 1791 && CATEGORYP (XCONS (elt)->car)
+ − 1792 && CATEGORYP (XCONS (elt)->cdr)
+ − 1793 && CATEGORY_MEMBER (XCHAR (XCONS (elt)->car), category_set1)
+ − 1794 && CATEGORY_MEMBER (XCHAR (XCONS (elt)->cdr), category_set2))
+ − 1795 return !default_result;
+ − 1796 }
+ − 1797 return default_result;
+ − 1798 }
+ − 1799 #endif /* MULE */
+ − 1800
+ − 1801
+ − 1802 void
+ − 1803 syms_of_chartab (void)
+ − 1804 {
442
+ − 1805 INIT_LRECORD_IMPLEMENTATION (char_table);
+ − 1806
428
+ − 1807 #ifdef MULE
442
+ − 1808 INIT_LRECORD_IMPLEMENTATION (char_table_entry);
+ − 1809
563
+ − 1810 DEFSYMBOL (Qcategory_table_p);
+ − 1811 DEFSYMBOL (Qcategory_designator_p);
+ − 1812 DEFSYMBOL (Qcategory_table_value_p);
428
+ − 1813 #endif /* MULE */
+ − 1814
563
+ − 1815 DEFSYMBOL (Qchar_table);
+ − 1816 DEFSYMBOL_MULTIWORD_PREDICATE (Qchar_tablep);
428
+ − 1817
+ − 1818 DEFSUBR (Fchar_table_p);
+ − 1819 DEFSUBR (Fchar_table_type_list);
+ − 1820 DEFSUBR (Fvalid_char_table_type_p);
+ − 1821 DEFSUBR (Fchar_table_type);
+ − 1822 DEFSUBR (Freset_char_table);
+ − 1823 DEFSUBR (Fmake_char_table);
+ − 1824 DEFSUBR (Fcopy_char_table);
+ − 1825 DEFSUBR (Fget_char_table);
+ − 1826 DEFSUBR (Fget_range_char_table);
+ − 1827 DEFSUBR (Fvalid_char_table_value_p);
+ − 1828 DEFSUBR (Fcheck_valid_char_table_value);
+ − 1829 DEFSUBR (Fput_char_table);
+ − 1830 DEFSUBR (Fmap_char_table);
+ − 1831
+ − 1832 #ifdef MULE
+ − 1833 DEFSUBR (Fcategory_table_p);
+ − 1834 DEFSUBR (Fcategory_table);
+ − 1835 DEFSUBR (Fstandard_category_table);
+ − 1836 DEFSUBR (Fcopy_category_table);
+ − 1837 DEFSUBR (Fset_category_table);
+ − 1838 DEFSUBR (Fcheck_category_at);
+ − 1839 DEFSUBR (Fchar_in_category_p);
+ − 1840 DEFSUBR (Fcategory_designator_p);
+ − 1841 DEFSUBR (Fcategory_table_value_p);
+ − 1842 #endif /* MULE */
+ − 1843
+ − 1844 }
+ − 1845
+ − 1846 void
+ − 1847 vars_of_chartab (void)
+ − 1848 {
+ − 1849 /* DO NOT staticpro this. It works just like Vweak_hash_tables. */
+ − 1850 Vall_syntax_tables = Qnil;
452
+ − 1851 dump_add_weak_object_chain (&Vall_syntax_tables);
428
+ − 1852 }
+ − 1853
+ − 1854 void
+ − 1855 structure_type_create_chartab (void)
+ − 1856 {
+ − 1857 struct structure_type *st;
+ − 1858
+ − 1859 st = define_structure_type (Qchar_table, 0, chartab_instantiate);
+ − 1860
+ − 1861 define_structure_type_keyword (st, Qtype, chartab_type_validate);
+ − 1862 define_structure_type_keyword (st, Qdata, chartab_data_validate);
+ − 1863 }
+ − 1864
+ − 1865 void
+ − 1866 complex_vars_of_chartab (void)
+ − 1867 {
+ − 1868 #ifdef MULE
+ − 1869 /* Set this now, so first buffer creation can refer to it. */
+ − 1870 /* Make it nil before calling copy-category-table
+ − 1871 so that copy-category-table will know not to try to copy from garbage */
+ − 1872 Vstandard_category_table = Qnil;
+ − 1873 Vstandard_category_table = Fcopy_category_table (Qnil);
+ − 1874 staticpro (&Vstandard_category_table);
+ − 1875
+ − 1876 DEFVAR_LISP ("word-combining-categories", &Vword_combining_categories /*
+ − 1877 List of pair (cons) of categories to determine word boundary.
+ − 1878
+ − 1879 Emacs treats a sequence of word constituent characters as a single
+ − 1880 word (i.e. finds no word boundary between them) iff they belongs to
+ − 1881 the same charset. But, exceptions are allowed in the following cases.
+ − 1882
444
+ − 1883 \(1) The case that characters are in different charsets is controlled
428
+ − 1884 by the variable `word-combining-categories'.
+ − 1885
+ − 1886 Emacs finds no word boundary between characters of different charsets
+ − 1887 if they have categories matching some element of this list.
+ − 1888
+ − 1889 More precisely, if an element of this list is a cons of category CAT1
+ − 1890 and CAT2, and a multibyte character C1 which has CAT1 is followed by
+ − 1891 C2 which has CAT2, there's no word boundary between C1 and C2.
+ − 1892
+ − 1893 For instance, to tell that ASCII characters and Latin-1 characters can
+ − 1894 form a single word, the element `(?l . ?l)' should be in this list
+ − 1895 because both characters have the category `l' (Latin characters).
+ − 1896
444
+ − 1897 \(2) The case that character are in the same charset is controlled by
428
+ − 1898 the variable `word-separating-categories'.
+ − 1899
+ − 1900 Emacs find a word boundary between characters of the same charset
+ − 1901 if they have categories matching some element of this list.
+ − 1902
+ − 1903 More precisely, if an element of this list is a cons of category CAT1
+ − 1904 and CAT2, and a multibyte character C1 which has CAT1 is followed by
+ − 1905 C2 which has CAT2, there's a word boundary between C1 and C2.
+ − 1906
+ − 1907 For instance, to tell that there's a word boundary between Japanese
+ − 1908 Hiragana and Japanese Kanji (both are in the same charset), the
+ − 1909 element `(?H . ?C) should be in this list.
+ − 1910 */ );
+ − 1911
+ − 1912 Vword_combining_categories = Qnil;
+ − 1913
+ − 1914 DEFVAR_LISP ("word-separating-categories", &Vword_separating_categories /*
+ − 1915 List of pair (cons) of categories to determine word boundary.
+ − 1916 See the documentation of the variable `word-combining-categories'.
+ − 1917 */ );
+ − 1918
+ − 1919 Vword_separating_categories = Qnil;
+ − 1920 #endif /* MULE */
+ − 1921 }