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