Switch to recommended form of GPLv3 permissions notice.
[bpt/emacs.git] / src / category.c
CommitLineData
4ed46869 1/* GNU Emacs routines to deal with category tables.
8cabe764 2 Copyright (C) 1998, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
429ab54e 3 Free Software Foundation, Inc.
7976eda0 4 Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
8cabe764 5 2005, 2006, 2007, 2008
ce03bf76
KH
6 National Institute of Advanced Industrial Science and Technology (AIST)
7 Registration Number H14PRO021
8f924df7 8 Copyright (C) 2003
ea012abd
KH
9 National Institute of Advanced Industrial Science and Technology (AIST)
10 Registration Number H13PRO009
4ed46869
KH
11
12This file is part of GNU Emacs.
13
9ec0b715 14GNU Emacs is free software: you can redistribute it and/or modify
4ed46869 15it under the terms of the GNU General Public License as published by
9ec0b715
GM
16the Free Software Foundation, either version 3 of the License, or
17(at your option) any later version.
4ed46869
KH
18
19GNU Emacs is distributed in the hope that it will be useful,
20but WITHOUT ANY WARRANTY; without even the implied warranty of
21MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22GNU General Public License for more details.
23
24You should have received a copy of the GNU General Public License
9ec0b715 25along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
4ed46869
KH
26
27
28/* Here we handle three objects: category, category set, and category
29 table. Read comments in the file category.h to understand them. */
30
31#include <config.h>
32#include <ctype.h>
33#include "lisp.h"
34#include "buffer.h"
ea012abd 35#include "character.h"
4ed46869
KH
36#include "charset.h"
37#include "category.h"
e35f6ff7 38#include "keymap.h"
4ed46869
KH
39
40/* The version number of the latest category table. Each category
41 table has a unique version number. It is assigned a new number
42 also when it is modified. When a regular expression is compiled
43 into the struct re_pattern_buffer, the version number of the
44 category table (of the current buffer) at that moment is also
45 embedded in the structure.
46
47 For the moment, we are not using this feature. */
48static int category_table_version;
49
50Lisp_Object Qcategory_table, Qcategoryp, Qcategorysetp, Qcategory_table_p;
51
52/* Variables to determine word boundary. */
53Lisp_Object Vword_combining_categories, Vword_separating_categories;
54
55/* Temporary internal variable used in macro CHAR_HAS_CATEGORY. */
56Lisp_Object _temp_category_set;
57
58\f
59/* Category set staff. */
60
61DEFUN ("make-category-set", Fmake_category_set, Smake_category_set, 1, 1, 0,
fdb82f93
PJ
62 doc: /* Return a newly created category-set which contains CATEGORIES.
63CATEGORIES is a string of category mnemonics.
64The value is a bool-vector which has t at the indices corresponding to
65those categories. */)
66 (categories)
4ed46869
KH
67 Lisp_Object categories;
68{
69 Lisp_Object val;
70 int len;
71
b7826503 72 CHECK_STRING (categories);
4ed46869
KH
73 val = MAKE_CATEGORY_SET;
74
115afec3 75 if (STRING_MULTIBYTE (categories))
95030461 76 error ("Multibyte string in `make-category-set'");
115afec3 77
d5db4077 78 len = SCHARS (categories);
4ed46869
KH
79 while (--len >= 0)
80 {
15c60737 81 Lisp_Object category;
4ed46869 82
d5db4077 83 XSETFASTINT (category, SREF (categories, len));
b7826503 84 CHECK_CATEGORY (category);
4ed46869
KH
85 SET_CATEGORY_SET (val, category, Qt);
86 }
87 return val;
88}
89
90\f
91/* Category staff. */
92
93Lisp_Object check_category_table ();
94
95DEFUN ("define-category", Fdefine_category, Sdefine_category, 2, 3, 0,
839966f3
KH
96 doc: /* Define CATEGORY as a category which is described by DOCSTRING.
97CATEGORY should be an ASCII printing character in the range ` ' to `~'.
98DOCSTRING is the documentation string of the category.
fdb82f93 99The category is defined only in category table TABLE, which defaults to
839966f3 100the current buffer's category table. */)
fdb82f93 101 (category, docstring, table)
4ed46869
KH
102 Lisp_Object category, docstring, table;
103{
b7826503
PJ
104 CHECK_CATEGORY (category);
105 CHECK_STRING (docstring);
4ed46869
KH
106 table = check_category_table (table);
107
108 if (!NILP (CATEGORY_DOCSTRING (table, XFASTINT (category))))
109 error ("Category `%c' is already defined", XFASTINT (category));
110 CATEGORY_DOCSTRING (table, XFASTINT (category)) = docstring;
111
112 return Qnil;
113}
114
115DEFUN ("category-docstring", Fcategory_docstring, Scategory_docstring, 1, 2, 0,
839966f3
KH
116 doc: /* Return the documentation string of CATEGORY, as defined in TABLE.
117TABLE should be a category table and defaults to the current buffer's
118category table. */)
fdb82f93 119 (category, table)
4ed46869
KH
120 Lisp_Object category, table;
121{
b7826503 122 CHECK_CATEGORY (category);
4ed46869
KH
123 table = check_category_table (table);
124
125 return CATEGORY_DOCSTRING (table, XFASTINT (category));
126}
127
128DEFUN ("get-unused-category", Fget_unused_category, Sget_unused_category,
129 0, 1, 0,
839966f3 130 doc: /* Return a category which is not yet defined in TABLE.
0b6694a5 131If no category remains available, return nil.
839966f3 132The optional argument TABLE specifies which category table to modify;
0b6694a5 133it defaults to the current buffer's category table. */)
fdb82f93 134 (table)
4ed46869
KH
135 Lisp_Object table;
136{
137 int i;
4ed46869
KH
138
139 table = check_category_table (table);
140
141 for (i = ' '; i <= '~'; i++)
142 if (NILP (CATEGORY_DOCSTRING (table, i)))
143 return make_number (i);
144
145 return Qnil;
146}
147
148\f
149/* Category-table staff. */
150
151DEFUN ("category-table-p", Fcategory_table_p, Scategory_table_p, 1, 1, 0,
fdb82f93
PJ
152 doc: /* Return t if ARG is a category table. */)
153 (arg)
4ed46869
KH
154 Lisp_Object arg;
155{
156 if (CHAR_TABLE_P (arg)
ed8ec86d 157 && EQ (XCHAR_TABLE (arg)->purpose, Qcategory_table))
4ed46869
KH
158 return Qt;
159 return Qnil;
160}
161
162/* If TABLE is nil, return the current category table. If TABLE is
163 not nil, check the validity of TABLE as a category table. If
164 valid, return TABLE itself, but if not valid, signal an error of
165 wrong-type-argument. */
166
167Lisp_Object
168check_category_table (table)
169 Lisp_Object table;
170{
4ed46869
KH
171 if (NILP (table))
172 return current_buffer->category_table;
88674269 173 CHECK_TYPE (!NILP (Fcategory_table_p (table)), Qcategory_table_p, table);
4ed46869 174 return table;
177c0ea7 175}
4ed46869
KH
176
177DEFUN ("category-table", Fcategory_table, Scategory_table, 0, 0, 0,
fdb82f93
PJ
178 doc: /* Return the current category table.
179This is the one specified by the current buffer. */)
180 ()
4ed46869
KH
181{
182 return current_buffer->category_table;
183}
184
185DEFUN ("standard-category-table", Fstandard_category_table,
186 Sstandard_category_table, 0, 0, 0,
fdb82f93
PJ
187 doc: /* Return the standard category table.
188This is the one used for new buffers. */)
189 ()
4ed46869
KH
190{
191 return Vstandard_category_table;
192}
193
ea012abd
KH
194
195static void
8f924df7
KH
196copy_category_entry (table, c, val)
197 Lisp_Object table, c, val;
ea012abd 198{
f4b670ef 199 val = Fcopy_sequence (val);
8f924df7
KH
200 if (CONSP (c))
201 char_table_set_range (table, XINT (XCAR (c)), XINT (XCDR (c)), val);
f4b670ef 202 else
8f924df7 203 char_table_set (table, XINT (c), val);
ea012abd
KH
204}
205
4ed46869
KH
206/* Return a copy of category table TABLE. We can't simply use the
207 function copy-sequence because no contents should be shared between
ed8ec86d 208 the original and the copy. This function is called recursively by
9da95d53 209 binding TABLE to a sub char table. */
4ed46869
KH
210
211Lisp_Object
ed8ec86d 212copy_category_table (table)
4ed46869
KH
213 Lisp_Object table;
214{
ea012abd 215 table = copy_char_table (table);
4ed46869 216
ea012abd
KH
217 if (! NILP (XCHAR_TABLE (table)->defalt))
218 XCHAR_TABLE (table)->defalt
219 = Fcopy_sequence (XCHAR_TABLE (table)->defalt);
220 XCHAR_TABLE (table)->extras[0]
221 = Fcopy_sequence (XCHAR_TABLE (table)->extras[0]);
8f924df7 222 map_char_table (copy_category_entry, Qnil, table, table);
ed8ec86d 223
4ed46869
KH
224 return table;
225}
226
227DEFUN ("copy-category-table", Fcopy_category_table, Scopy_category_table,
228 0, 1, 0,
fdb82f93
PJ
229 doc: /* Construct a new category table and return it.
230It is a copy of the TABLE, which defaults to the standard category table. */)
231 (table)
4ed46869
KH
232 Lisp_Object table;
233{
234 if (!NILP (table))
235 check_category_table (table);
236 else
237 table = Vstandard_category_table;
238
9da95d53 239 return copy_category_table (table);
4ed46869
KH
240}
241
70414a3d
KH
242DEFUN ("make-category-table", Fmake_category_table, Smake_category_table,
243 0, 0, 0,
fdb82f93
PJ
244 doc: /* Construct a new and empty category table and return it. */)
245 ()
70414a3d
KH
246{
247 Lisp_Object val;
ea012abd 248 int i;
70414a3d
KH
249
250 val = Fmake_char_table (Qcategory_table, Qnil);
251 XCHAR_TABLE (val)->defalt = MAKE_CATEGORY_SET;
8f924df7 252 for (i = 0; i < (1 << CHARTAB_SIZE_BITS_0); i++)
ea012abd 253 XCHAR_TABLE (val)->contents[i] = MAKE_CATEGORY_SET;
70414a3d
KH
254 Fset_char_table_extra_slot (val, make_number (0),
255 Fmake_vector (make_number (95), Qnil));
256 return val;
257}
258
4ed46869 259DEFUN ("set-category-table", Fset_category_table, Sset_category_table, 1, 1, 0,
839966f3
KH
260 doc: /* Specify TABLE as the category table for the current buffer.
261Return TABLE. */)
fdb82f93 262 (table)
4ed46869
KH
263 Lisp_Object table;
264{
6f598a6d 265 int idx;
4ed46869
KH
266 table = check_category_table (table);
267 current_buffer->category_table = table;
268 /* Indicate that this buffer now has a specified category table. */
f6cd0527
GM
269 idx = PER_BUFFER_VAR_IDX (category_table);
270 SET_PER_BUFFER_VALUE_P (current_buffer, idx, 1);
4ed46869
KH
271 return table;
272}
273
274\f
ea012abd
KH
275Lisp_Object
276char_category_set (c)
277 int c;
278{
279 return CHAR_TABLE_REF (current_buffer->category_table, c);
280}
281
4ed46869 282DEFUN ("char-category-set", Fchar_category_set, Schar_category_set, 1, 1, 0,
a2c2f196
JB
283 doc: /* Return the category set of CHAR.
284usage: (char-category-set CHAR) */)
fdb82f93 285 (ch)
4ed46869
KH
286 Lisp_Object ch;
287{
b7826503 288 CHECK_NUMBER (ch);
4ed46869
KH
289 return CATEGORY_SET (XFASTINT (ch));
290}
291
292DEFUN ("category-set-mnemonics", Fcategory_set_mnemonics,
293 Scategory_set_mnemonics, 1, 1, 0,
fdb82f93
PJ
294 doc: /* Return a string containing mnemonics of the categories in CATEGORY-SET.
295CATEGORY-SET is a bool-vector, and the categories \"in\" it are those
839966f3 296that are indexes where t occurs in the bool-vector.
fdb82f93
PJ
297The return value is a string containing those same categories. */)
298 (category_set)
4ed46869
KH
299 Lisp_Object category_set;
300{
301 int i, j;
302 char str[96];
303
b7826503 304 CHECK_CATEGORY_SET (category_set);
4ed46869
KH
305
306 j = 0;
307 for (i = 32; i < 127; i++)
308 if (CATEGORY_MEMBER (i, category_set))
309 str[j++] = i;
310 str[j] = '\0';
311
312 return build_string (str);
313}
314
4ed46869
KH
315void
316set_category_set (category_set, category, val)
317 Lisp_Object category_set, category, val;
318{
319 do {
320 int idx = XINT (category) / 8;
321 unsigned char bits = 1 << (XINT (category) % 8);
322
323 if (NILP (val))
324 XCATEGORY_SET (category_set)->data[idx] &= ~bits;
325 else
326 XCATEGORY_SET (category_set)->data[idx] |= bits;
327 } while (0);
328}
329
330DEFUN ("modify-category-entry", Fmodify_category_entry,
331 Smodify_category_entry, 2, 4, 0,
fdb82f93
PJ
332 doc: /* Modify the category set of CHARACTER by adding CATEGORY to it.
333The category is changed only for table TABLE, which defaults to
8f7e5042
DL
334the current buffer's category table.
335CHARACTER can be either a single character or a cons representing the
336lower and upper ends of an inclusive character range to modify.
fdb82f93
PJ
337If optional fourth argument RESET is non-nil,
338then delete CATEGORY from the category set instead of adding it. */)
339 (character, category, table, reset)
ea4943bf 340 Lisp_Object character, category, table, reset;
4ed46869 341{
4ed46869 342 Lisp_Object set_value; /* Actual value to be set in category sets. */
8f7e5042 343 Lisp_Object category_set;
ea012abd
KH
344 int start, end;
345 int from, to;
4ed46869 346
ea012abd 347 if (INTEGERP (character))
4ed46869 348 {
ea012abd
KH
349 CHECK_CHARACTER (character);
350 start = end = XFASTINT (character);
4ed46869 351 }
ea012abd 352 else
4ed46869 353 {
ea012abd 354 CHECK_CONS (character);
8f924df7
KH
355 CHECK_CHARACTER_CAR (character);
356 CHECK_CHARACTER_CDR (character);
ea012abd
KH
357 start = XFASTINT (XCAR (character));
358 end = XFASTINT (XCDR (character));
4ed46869 359 }
4ed46869 360
b7826503 361 CHECK_CATEGORY (category);
4ed46869 362 table = check_category_table (table);
4ed46869 363
4ed46869
KH
364 if (NILP (CATEGORY_DOCSTRING (table, XFASTINT (category))))
365 error ("Undefined category: %c", XFASTINT (category));
4ed46869 366
4ed46869 367 set_value = NILP (reset) ? Qt : Qnil;
4ed46869 368
ea012abd 369 while (start <= end)
4ed46869 370 {
ea012abd 371 category_set = char_table_ref_and_range (table, start, &from, &to);
0b261f59 372 if (CATEGORY_MEMBER (XFASTINT (category), category_set) != NILP (reset))
ea012abd 373 {
d8887a31
KH
374 category_set = Fcopy_sequence (category_set);
375 SET_CATEGORY_SET (category_set, category, set_value);
ea012abd
KH
376 if (to > end)
377 char_table_set_range (table, start, end, category_set);
378 else
379 char_table_set_range (table, start, to, category_set);
380 }
ea012abd 381 start = to + 1;
4ed46869 382 }
4ed46869
KH
383
384 return Qnil;
385}
386\f
4ed46869
KH
387/* Return 1 if there is a word boundary between two word-constituent
388 characters C1 and C2 if they appear in this order, else return 0.
389 Use the macro WORD_BOUNDARY_P instead of calling this function
390 directly. */
391
392int
393word_boundary_p (c1, c2)
394 int c1, c2;
395{
396 Lisp_Object category_set1, category_set2;
397 Lisp_Object tail;
398 int default_result;
399
400 if (CHAR_CHARSET (c1) == CHAR_CHARSET (c2))
401 {
402 tail = Vword_separating_categories;
403 default_result = 0;
404 }
405 else
406 {
407 tail = Vword_combining_categories;
408 default_result = 1;
409 }
410
411 category_set1 = CATEGORY_SET (c1);
412 if (NILP (category_set1))
413 return default_result;
414 category_set2 = CATEGORY_SET (c2);
415 if (NILP (category_set2))
416 return default_result;
417
03699b14 418 for (; CONSP (tail); tail = XCDR (tail))
4ed46869 419 {
03699b14 420 Lisp_Object elt = XCAR (tail);
4ed46869
KH
421
422 if (CONSP (elt)
03699b14
KR
423 && CATEGORYP (XCAR (elt))
424 && CATEGORYP (XCDR (elt))
425 && CATEGORY_MEMBER (XFASTINT (XCAR (elt)), category_set1)
426 && CATEGORY_MEMBER (XFASTINT (XCDR (elt)), category_set2))
4ed46869
KH
427 return !default_result;
428 }
429 return default_result;
430}
431
432\f
dfcf069d 433void
4ed46869
KH
434init_category_once ()
435{
436 /* This has to be done here, before we call Fmake_char_table. */
437 Qcategory_table = intern ("category-table");
438 staticpro (&Qcategory_table);
439
440 /* Intern this now in case it isn't already done.
441 Setting this variable twice is harmless.
442 But don't staticpro it here--that is done in alloc.c. */
443 Qchar_table_extra_slots = intern ("char-table-extra-slots");
444
445 /* Now we are ready to set up this property, so we can
446 create category tables. */
447 Fput (Qcategory_table, Qchar_table_extra_slots, make_number (2));
448
449 Vstandard_category_table = Fmake_char_table (Qcategory_table, Qnil);
177c0ea7 450 /* Set a category set which contains nothing to the default. */
4ed46869 451 XCHAR_TABLE (Vstandard_category_table)->defalt = MAKE_CATEGORY_SET;
9da95d53 452 Fset_char_table_extra_slot (Vstandard_category_table, make_number (0),
4ed46869
KH
453 Fmake_vector (make_number (95), Qnil));
454}
455
dfcf069d 456void
4ed46869
KH
457syms_of_category ()
458{
459 Qcategoryp = intern ("categoryp");
460 staticpro (&Qcategoryp);
461 Qcategorysetp = intern ("categorysetp");
462 staticpro (&Qcategorysetp);
463 Qcategory_table_p = intern ("category-table-p");
464 staticpro (&Qcategory_table_p);
465
466 DEFVAR_LISP ("word-combining-categories", &Vword_combining_categories,
fdb82f93
PJ
467 doc: /* List of pair (cons) of categories to determine word boundary.
468
469Emacs treats a sequence of word constituent characters as a single
e0f24100 470word (i.e. finds no word boundary between them) only if they belong to
fdb82f93
PJ
471the same charset. But, exceptions are allowed in the following cases.
472
473\(1) The case that characters are in different charsets is controlled
474by the variable `word-combining-categories'.
475
476Emacs finds no word boundary between characters of different charsets
477if they have categories matching some element of this list.
478
479More precisely, if an element of this list is a cons of category CAT1
480and CAT2, and a multibyte character C1 which has CAT1 is followed by
481C2 which has CAT2, there's no word boundary between C1 and C2.
482
483For instance, to tell that ASCII characters and Latin-1 characters can
484form a single word, the element `(?l . ?l)' should be in this list
485because both characters have the category `l' (Latin characters).
486
487\(2) The case that character are in the same charset is controlled by
488the variable `word-separating-categories'.
489
490Emacs find a word boundary between characters of the same charset
491if they have categories matching some element of this list.
492
493More precisely, if an element of this list is a cons of category CAT1
494and CAT2, and a multibyte character C1 which has CAT1 is followed by
495C2 which has CAT2, there's a word boundary between C1 and C2.
496
497For instance, to tell that there's a word boundary between Japanese
498Hiragana and Japanese Kanji (both are in the same charset), the
499element `(?H . ?C) should be in this list. */);
4ed46869
KH
500
501 Vword_combining_categories = Qnil;
502
503 DEFVAR_LISP ("word-separating-categories", &Vword_separating_categories,
fdb82f93
PJ
504 doc: /* List of pair (cons) of categories to determine word boundary.
505See the documentation of the variable `word-combining-categories'. */);
4ed46869
KH
506
507 Vword_separating_categories = Qnil;
508
509 defsubr (&Smake_category_set);
510 defsubr (&Sdefine_category);
511 defsubr (&Scategory_docstring);
512 defsubr (&Sget_unused_category);
513 defsubr (&Scategory_table_p);
514 defsubr (&Scategory_table);
515 defsubr (&Sstandard_category_table);
516 defsubr (&Scopy_category_table);
70414a3d 517 defsubr (&Smake_category_table);
4ed46869
KH
518 defsubr (&Sset_category_table);
519 defsubr (&Schar_category_set);
520 defsubr (&Scategory_set_mnemonics);
521 defsubr (&Smodify_category_entry);
4ed46869
KH
522
523 category_table_version = 0;
524}
839966f3
KH
525
526/* arch-tag: 74ebf524-121b-4d9c-bd68-07f8d708b211
527 (do not change this comment) */