This source file includes following definitions.
- bset_category_table
- hash_get_category_set
- set_category_set
- DEFUN
- DEFUN
- DEFUN
- check_category_table
- DEFUN
- DEFUN
- copy_category_entry
- copy_category_table
- DEFUN
- DEFUN
- DEFUN
- char_category_set
- DEFUN
- DEFUN
- word_boundary_p
- init_category_once
- syms_of_category
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 #include <config.h>
32
33 #include "lisp.h"
34 #include "character.h"
35 #include "buffer.h"
36 #include "category.h"
37
38
39 static void
40 bset_category_table (struct buffer *b, Lisp_Object val)
41 {
42 b->category_table_ = val;
43 }
44
45
46
47
48 static Lisp_Object
49 hash_get_category_set (Lisp_Object table, Lisp_Object category_set)
50 {
51 if (NILP (XCHAR_TABLE (table)->extras[1]))
52 set_char_table_extras
53 (table, 1,
54 make_hash_table (hashtest_equal, DEFAULT_HASH_SIZE,
55 DEFAULT_REHASH_SIZE, DEFAULT_REHASH_THRESHOLD,
56 Qnil, false));
57 struct Lisp_Hash_Table *h = XHASH_TABLE (XCHAR_TABLE (table)->extras[1]);
58 Lisp_Object hash;
59 ptrdiff_t i = hash_lookup (h, category_set, &hash);
60 if (i >= 0)
61 return HASH_KEY (h, i);
62 hash_put (h, category_set, Qnil, hash);
63 return category_set;
64 }
65
66
67
68 static void
69 set_category_set (Lisp_Object category_set, EMACS_INT category, bool val)
70 {
71 bool_vector_set (category_set, category, val);
72 }
73
74 DEFUN ("make-category-set", Fmake_category_set, Smake_category_set, 1, 1, 0,
75 doc:
76
77
78 )
79 (Lisp_Object categories)
80 {
81 Lisp_Object val;
82 ptrdiff_t len;
83
84 CHECK_STRING (categories);
85 val = MAKE_CATEGORY_SET;
86
87 if (STRING_MULTIBYTE (categories))
88 error ("Multibyte string in `make-category-set'");
89
90 len = SCHARS (categories);
91 while (--len >= 0)
92 {
93 unsigned char cat = SREF (categories, len);
94 Lisp_Object category = make_fixnum (cat);
95
96 CHECK_CATEGORY (category);
97 set_category_set (val, cat, 1);
98 }
99 return val;
100 }
101
102
103
104
105 static Lisp_Object check_category_table (Lisp_Object table);
106
107 DEFUN ("define-category", Fdefine_category, Sdefine_category, 2, 3, 0,
108 doc:
109
110
111
112
113
114 )
115 (Lisp_Object category, Lisp_Object docstring, Lisp_Object table)
116 {
117 CHECK_CATEGORY (category);
118 CHECK_STRING (docstring);
119 table = check_category_table (table);
120
121 if (!NILP (CATEGORY_DOCSTRING (table, XFIXNAT (category))))
122 error ("Category `%c' is already defined", (int) XFIXNAT (category));
123 if (!NILP (Vpurify_flag))
124 docstring = Fpurecopy (docstring);
125 SET_CATEGORY_DOCSTRING (table, XFIXNAT (category), docstring);
126
127 return Qnil;
128 }
129
130 DEFUN ("category-docstring", Fcategory_docstring, Scategory_docstring, 1, 2, 0,
131 doc:
132
133 )
134 (Lisp_Object category, Lisp_Object table)
135 {
136 CHECK_CATEGORY (category);
137 table = check_category_table (table);
138
139 return CATEGORY_DOCSTRING (table, XFIXNAT (category));
140 }
141
142 DEFUN ("get-unused-category", Fget_unused_category, Sget_unused_category,
143 0, 1, 0,
144 doc:
145
146
147 )
148 (Lisp_Object table)
149 {
150 int i;
151
152 table = check_category_table (table);
153
154 for (i = ' '; i <= '~'; i++)
155 if (NILP (CATEGORY_DOCSTRING (table, i)))
156 return make_fixnum (i);
157
158 return Qnil;
159 }
160
161
162
163
164 DEFUN ("category-table-p", Fcategory_table_p, Scategory_table_p, 1, 1, 0,
165 doc: )
166 (Lisp_Object arg)
167 {
168 if (CHAR_TABLE_P (arg)
169 && EQ (XCHAR_TABLE (arg)->purpose, Qcategory_table))
170 return Qt;
171 return Qnil;
172 }
173
174
175
176
177
178
179 static Lisp_Object
180 check_category_table (Lisp_Object table)
181 {
182 if (NILP (table))
183 return BVAR (current_buffer, category_table);
184 CHECK_TYPE (!NILP (Fcategory_table_p (table)), Qcategory_table_p, table);
185 return table;
186 }
187
188 DEFUN ("category-table", Fcategory_table, Scategory_table, 0, 0, 0,
189 doc:
190 )
191 (void)
192 {
193 return BVAR (current_buffer, category_table);
194 }
195
196 DEFUN ("standard-category-table", Fstandard_category_table,
197 Sstandard_category_table, 0, 0, 0,
198 doc:
199 )
200 (void)
201 {
202 return Vstandard_category_table;
203 }
204
205
206 static void
207 copy_category_entry (Lisp_Object table, Lisp_Object c, Lisp_Object val)
208 {
209 val = Fcopy_sequence (val);
210 if (CONSP (c))
211 char_table_set_range (table, XFIXNUM (XCAR (c)), XFIXNUM (XCDR (c)), val);
212 else
213 char_table_set (table, XFIXNUM (c), val);
214 }
215
216
217
218
219
220
221 static Lisp_Object
222 copy_category_table (Lisp_Object table)
223 {
224 table = copy_char_table (table);
225
226 if (! NILP (XCHAR_TABLE (table)->defalt))
227 set_char_table_defalt (table,
228 Fcopy_sequence (XCHAR_TABLE (table)->defalt));
229 set_char_table_extras
230 (table, 0, Fcopy_sequence (XCHAR_TABLE (table)->extras[0]));
231 map_char_table (copy_category_entry, Qnil, table, table);
232
233 return table;
234 }
235
236 DEFUN ("copy-category-table", Fcopy_category_table, Scopy_category_table,
237 0, 1, 0,
238 doc:
239 )
240 (Lisp_Object table)
241 {
242 if (!NILP (table))
243 check_category_table (table);
244 else
245 table = Vstandard_category_table;
246
247 return copy_category_table (table);
248 }
249
250 DEFUN ("make-category-table", Fmake_category_table, Smake_category_table,
251 0, 0, 0,
252 doc: )
253 (void)
254 {
255 Lisp_Object val;
256 int i;
257
258 val = Fmake_char_table (Qcategory_table, Qnil);
259 set_char_table_defalt (val, MAKE_CATEGORY_SET);
260 for (i = 0; i < (1 << CHARTAB_SIZE_BITS_0); i++)
261 set_char_table_contents (val, i, MAKE_CATEGORY_SET);
262 Fset_char_table_extra_slot (val, make_fixnum (0), make_nil_vector (95));
263 return val;
264 }
265
266 DEFUN ("set-category-table", Fset_category_table, Sset_category_table, 1, 1, 0,
267 doc:
268 )
269 (Lisp_Object table)
270 {
271 int idx;
272 table = check_category_table (table);
273 bset_category_table (current_buffer, table);
274
275 idx = PER_BUFFER_VAR_IDX (category_table);
276 SET_PER_BUFFER_VALUE_P (current_buffer, idx, 1);
277 return table;
278 }
279
280
281 Lisp_Object
282 char_category_set (int c)
283 {
284 return CHAR_TABLE_REF (BVAR (current_buffer, category_table), c);
285 }
286
287 DEFUN ("char-category-set", Fchar_category_set, Schar_category_set, 1, 1, 0,
288 doc:
289 )
290 (Lisp_Object ch)
291 {
292 CHECK_CHARACTER (ch);
293 return CATEGORY_SET (XFIXNAT (ch));
294 }
295
296 DEFUN ("category-set-mnemonics", Fcategory_set_mnemonics,
297 Scategory_set_mnemonics, 1, 1, 0,
298 doc:
299
300
301 )
302 (Lisp_Object category_set)
303 {
304 int i, j;
305 char str[96];
306
307 CHECK_CATEGORY_SET (category_set);
308
309 j = 0;
310 for (i = 32; i < 127; i++)
311 if (CATEGORY_MEMBER (i, category_set))
312 str[j++] = i;
313 str[j] = '\0';
314
315 return build_string (str);
316 }
317
318 DEFUN ("modify-category-entry", Fmodify_category_entry,
319 Smodify_category_entry, 2, 4, 0,
320 doc:
321
322
323
324
325
326
327
328 )
329 (Lisp_Object character, Lisp_Object category, Lisp_Object table, Lisp_Object reset)
330 {
331 bool set_value;
332 Lisp_Object category_set;
333 int start, end;
334 int from, to;
335
336 if (FIXNUMP (character))
337 {
338 CHECK_CHARACTER (character);
339 start = end = XFIXNAT (character);
340 }
341 else
342 {
343 CHECK_CONS (character);
344 CHECK_CHARACTER_CAR (character);
345 CHECK_CHARACTER_CDR (character);
346 start = XFIXNAT (XCAR (character));
347 end = XFIXNAT (XCDR (character));
348 }
349
350 CHECK_CATEGORY (category);
351 table = check_category_table (table);
352
353 if (NILP (CATEGORY_DOCSTRING (table, XFIXNAT (category))))
354 error ("Undefined category: %c", (int) XFIXNAT (category));
355
356 set_value = NILP (reset);
357
358 while (start <= end)
359 {
360 from = start, to = end;
361 category_set = char_table_ref_and_range (table, start, &from, &to);
362 if (CATEGORY_MEMBER (XFIXNAT (category), category_set) != NILP (reset))
363 {
364 category_set = Fcopy_sequence (category_set);
365 set_category_set (category_set, XFIXNAT (category), set_value);
366 category_set = hash_get_category_set (table, category_set);
367 char_table_set_range (table, start, to, category_set);
368 }
369 start = to + 1;
370 }
371
372 return Qnil;
373 }
374
375
376
377
378
379
380 bool
381 word_boundary_p (int c1, int c2)
382 {
383 Lisp_Object category_set1, category_set2;
384 Lisp_Object tail;
385 bool default_result;
386
387 if (EQ (CHAR_TABLE_REF (Vchar_script_table, c1),
388 CHAR_TABLE_REF (Vchar_script_table, c2)))
389 {
390 tail = Vword_separating_categories;
391 default_result = 0;
392 }
393 else
394 {
395 tail = Vword_combining_categories;
396 default_result = 1;
397 }
398
399 category_set1 = CATEGORY_SET (c1);
400 if (NILP (category_set1))
401 return default_result;
402 category_set2 = CATEGORY_SET (c2);
403 if (NILP (category_set2))
404 return default_result;
405
406 for (; CONSP (tail); tail = XCDR (tail))
407 {
408 Lisp_Object elt = XCAR (tail);
409
410 if (CONSP (elt)
411 && (NILP (XCAR (elt))
412 || (CATEGORYP (XCAR (elt))
413 && CATEGORY_MEMBER (XFIXNAT (XCAR (elt)), category_set1)
414 && ! CATEGORY_MEMBER (XFIXNAT (XCAR (elt)), category_set2)))
415 && (NILP (XCDR (elt))
416 || (CATEGORYP (XCDR (elt))
417 && ! CATEGORY_MEMBER (XFIXNAT (XCDR (elt)), category_set1)
418 && CATEGORY_MEMBER (XFIXNAT (XCDR (elt)), category_set2))))
419 return !default_result;
420 }
421 return default_result;
422 }
423
424
425 void
426 init_category_once (void)
427 {
428
429 DEFSYM (Qcategory_table, "category-table");
430 Fput (Qcategory_table, Qchar_table_extra_slots, make_fixnum (2));
431
432 Vstandard_category_table = Fmake_char_table (Qcategory_table, Qnil);
433
434 set_char_table_defalt (Vstandard_category_table, MAKE_CATEGORY_SET);
435 Fset_char_table_extra_slot (Vstandard_category_table, make_fixnum (0),
436 make_nil_vector (95));
437 }
438
439 void
440 syms_of_category (void)
441 {
442 DEFSYM (Qcategoryp, "categoryp");
443 DEFSYM (Qcategorysetp, "categorysetp");
444 DEFSYM (Qcategory_table_p, "category-table-p");
445
446 DEFVAR_LISP ("word-combining-categories", Vword_combining_categories,
447 doc:
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480 );
481
482 Vword_combining_categories = Qnil;
483
484 DEFVAR_LISP ("word-separating-categories", Vword_separating_categories,
485 doc:
486 );
487
488 Vword_separating_categories = Qnil;
489
490 defsubr (&Smake_category_set);
491 defsubr (&Sdefine_category);
492 defsubr (&Scategory_docstring);
493 defsubr (&Sget_unused_category);
494 defsubr (&Scategory_table_p);
495 defsubr (&Scategory_table);
496 defsubr (&Sstandard_category_table);
497 defsubr (&Scopy_category_table);
498 defsubr (&Smake_category_table);
499 defsubr (&Sset_category_table);
500 defsubr (&Schar_category_set);
501 defsubr (&Scategory_set_mnemonics);
502 defsubr (&Smodify_category_entry);
503 }