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