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: #include <config.h>
31: #include <ctype.h>
32: #include "lisp.h"
33: #include "buffer.h"
34: #include "charset.h"
35: #include "category.h"
36: #include "keymap.h"
37:
38:
39:
40:
41:
42:
43:
44:
45:
46: static int category_table_version;
47:
48: Lisp_Object Qcategory_table, Qcategoryp, Qcategorysetp, Qcategory_table_p;
49:
50:
51: Lisp_Object Vword_combining_categories, Vword_separating_categories;
52:
53:
54: Lisp_Object _temp_category_set;
55:
56: ^L
57:
58:
59: DEFUN ("make-category-set", Fmake_category_set, Smake_category_set, 1, 1, 0,
60: doc:
61:
62:
63: )
64: (categories)
65: Lisp_Object categories;
66: {
67: Lisp_Object val;
68: int len;
69:
70: CHECK_STRING (categories);
71: val = MAKE_CATEGORY_SET;
72:
73: if (STRING_MULTIBYTE (categories))
74: error ("Multibyte string in `make-category-set'");
75:
76: len = SCHARS (categories);
77: while (--len >= 0)
78: {
79: Lisp_Object category;
80:
81: XSETFASTINT (category, SREF (categories, len));
82: CHECK_CATEGORY (category);
83: SET_CATEGORY_SET (val, category, Qt);
84: }
85: return val;
86: }
87:
88: ^L
89:
90:
91: Lisp_Object check_category_table ();
92:
93: DEFUN ("define-category", Fdefine_category, Sdefine_category, 2, 3, 0,
94: doc:
95:
96:
97:
98: )
99: (category, docstring, table)
100: Lisp_Object category, docstring, table;
101: {
102: CHECK_CATEGORY (category);
103: CHECK_STRING (docstring);
104: table = check_category_table (table);
105:
106: if (!NILP (CATEGORY_DOCSTRING (table, XFASTINT (category))))
107: error ("Category `%c' is already defined", XFASTINT (category));
108: CATEGORY_DOCSTRING (table, XFASTINT (category)) = docstring;
109:
110: return Qnil;
111: }
112:
113: DEFUN ("category-docstring", Fcategory_docstring, Scategory_docstring, 1, 2, 0,
114: doc:
115:
116: )
117: (category, table)
118: Lisp_Object category, table;
119: {
120: CHECK_CATEGORY (category);
121: table = check_category_table (table);
122:
123: return CATEGORY_DOCSTRING (table, XFASTINT (category));
124: }
125:
126: DEFUN ("get-unused-category", Fget_unused_category, Sget_unused_category,
127: 0, 1, 0,
128: doc:
129:
130:
131: )
132: (table)
133: Lisp_Object table;
134: {
135: int i;
136:
137: table = check_category_table (table);
138:
139: for (i = ' '; i <= '~'; i++)
140: if (NILP (CATEGORY_DOCSTRING (table, i)))
141: return make_number (i);
142:
143: return Qnil;
144: }
145:
146: ^L
147:
148:
149: DEFUN ("category-table-p", Fcategory_table_p, Scategory_table_p, 1, 1, 0,
150: doc: )
151: (arg)
152: Lisp_Object arg;
153: {
154: if (CHAR_TABLE_P (arg)
155: && EQ (XCHAR_TABLE (arg)->purpose, Qcategory_table))
156: return Qt;
157: return Qnil;
158: }
159:
160:
161:
162:
163:
164:
165: Lisp_Object
166: check_category_table (table)
167: Lisp_Object table;
168: {
169: if (NILP (table))
170: return current_buffer->category_table;
171: CHECK_TYPE (!NILP (Fcategory_table_p (table)), Qcategory_table_p, table);
172: return table;
173: }
174:
175: DEFUN ("category-table", Fcategory_table, Scategory_table, 0, 0, 0,
176: doc:
177: )
178: ()
179: {
180: return current_buffer->category_table;
181: }
182:
183: DEFUN ("standard-category-table", Fstandard_category_table,
184: Sstandard_category_table, 0, 0, 0,
185: doc:
186: )
187: ()
188: {
189: return Vstandard_category_table;
190: }
191:
192:
193:
194:
195:
196:
197: Lisp_Object
198: copy_category_table (table)
199: Lisp_Object table;
200: {
201: Lisp_Object tmp;
202: int i, to;
203:
204: if (!NILP (XCHAR_TABLE (table)->top))
205: {
206:
207:
208: table = Fcopy_sequence (table);
209:
210:
211: for (i = 0; i < CHAR_TABLE_SINGLE_BYTE_SLOTS; i++)
212: if (!NILP (tmp = XCHAR_TABLE (table)->contents[i]))
213: XCHAR_TABLE (table)->contents[i] = Fcopy_sequence (tmp);
214: to = CHAR_TABLE_ORDINARY_SLOTS;
215:
216:
217:
218: Fset_char_table_extra_slot
219: (table, make_number (0),
220: Fcopy_sequence (Fchar_table_extra_slot (table, make_number (0))));
221: }
222: else
223: {
224: i = 32;
225: to = SUB_CHAR_TABLE_ORDINARY_SLOTS;
226: }
227:
228:
229: if (!NILP (tmp = XCHAR_TABLE (table)->defalt))
230: XCHAR_TABLE (table)->defalt = Fcopy_sequence (tmp);
231:
232:
233:
234: for (; i < to; i++)
235: if (!NILP (tmp = XCHAR_TABLE (table)->contents[i]))
236: XCHAR_TABLE (table)->contents[i]
237: = (SUB_CHAR_TABLE_P (tmp)
238: ? copy_category_table (tmp) : Fcopy_sequence (tmp));
239:
240: return table;
241: }
242:
243: DEFUN ("copy-category-table", Fcopy_category_table, Scopy_category_table,
244: 0, 1, 0,
245: doc:
246: )
247: (table)
248: Lisp_Object table;
249: {
250: if (!NILP (table))
251: check_category_table (table);
252: else
253: table = Vstandard_category_table;
254:
255: return copy_category_table (table);
256: }
257:
258: DEFUN ("make-category-table", Fmake_category_table, Smake_category_table,
259: 0, 0, 0,
260: doc: )
261: ()
262: {
263: Lisp_Object val;
264:
265: val = Fmake_char_table (Qcategory_table, Qnil);
266: XCHAR_TABLE (val)->defalt = MAKE_CATEGORY_SET;
267: Fset_char_table_extra_slot (val, make_number (0),
268: Fmake_vector (make_number (95), Qnil));
269: return val;
270: }
271:
272: DEFUN ("set-category-table", Fset_category_table, Sset_category_table, 1, 1, 0,
273: doc:
274: )
275: (table)
276: Lisp_Object table;
277: {
278: int idx;
279: table = check_category_table (table);
280: current_buffer->category_table = table;
281:
282: idx = PER_BUFFER_VAR_IDX (category_table);
283: SET_PER_BUFFER_VALUE_P (current_buffer, idx, 1);
284: return table;
285: }
286:
287: ^L
288: DEFUN ("char-category-set", Fchar_category_set, Schar_category_set, 1, 1, 0,
289: doc:
290: )
291: (ch)
292: Lisp_Object ch;
293: {
294: CHECK_NUMBER (ch);
295: return CATEGORY_SET (XFASTINT (ch));
296: }
297:
298: DEFUN ("category-set-mnemonics", Fcategory_set_mnemonics,
299: Scategory_set_mnemonics, 1, 1, 0,
300: doc:
301:
302:
303: )
304: (category_set)
305: Lisp_Object category_set;
306: {
307: int i, j;
308: char str[96];
309:
310: CHECK_CATEGORY_SET (category_set);
311:
312: j = 0;
313: for (i = 32; i < 127; i++)
314: if (CATEGORY_MEMBER (i, category_set))
315: str[j++] = i;
316: str[j] = '\0';
317:
318: return build_string (str);
319: }
320:
321:
322:
323:
324:
325: void
326: modify_lower_category_set (table, category, set_value)
327: Lisp_Object table, category, set_value;
328: {
329: Lisp_Object val;
330: int i;
331:
332: val = XCHAR_TABLE (table)->defalt;
333: if (!CATEGORY_SET_P (val))
334: val = MAKE_CATEGORY_SET;
335: SET_CATEGORY_SET (val, category, set_value);
336: XCHAR_TABLE (table)->defalt = val;
337:
338: for (i = 32; i < SUB_CHAR_TABLE_ORDINARY_SLOTS; i++)
339: {
340: val = XCHAR_TABLE (table)->contents[i];
341:
342: if (CATEGORY_SET_P (val))
343: SET_CATEGORY_SET (val, category, set_value);
344: else if (SUB_CHAR_TABLE_P (val))
345: modify_lower_category_set (val, category, set_value);
346: }
347: }
348:
349: void
350: set_category_set (category_set, category, val)
351: Lisp_Object category_set, category, val;
352: {
353: do {
354: int idx = XINT (category) / 8;
355: unsigned char bits = 1 << (XINT (category) % 8);
356:
357: if (NILP (val))
358: XCATEGORY_SET (category_set)->data[idx] &= ~bits;
359: else
360: XCATEGORY_SET (category_set)->data[idx] |= bits;
361: } while (0);
362: }
363:
364: DEFUN ("modify-category-entry", Fmodify_category_entry,
365: Smodify_category_entry, 2, 4, 0,
366: doc:
367:
368:
369:
370: )
371: (character, category, table, reset)
372: Lisp_Object character, category, table, reset;
373: {
374: int c, charset, c1, c2;
375: Lisp_Object set_value;
376: Lisp_Object val, category_set;
377:
378: CHECK_NUMBER (character);
379: c = XINT (character);
380: CHECK_CATEGORY (category);
381: table = check_category_table (table);
382:
383: if (NILP (CATEGORY_DOCSTRING (table, XFASTINT (category))))
384: error ("Undefined category: %c", XFASTINT (category));
385:
386: set_value = NILP (reset) ? Qt : Qnil;
387:
388: if (c < CHAR_TABLE_SINGLE_BYTE_SLOTS)
389: {
390: val = XCHAR_TABLE (table)->contents[c];
391: if (!CATEGORY_SET_P (val))
392: XCHAR_TABLE (table)->contents[c] = (val = MAKE_CATEGORY_SET);
393: SET_CATEGORY_SET (val, category, set_value);
394: return Qnil;
395: }
396:
397: SPLIT_CHAR (c, charset, c1, c2);
398:
399:
400: val = XCHAR_TABLE (table)->contents[charset + 128];
401: if (CATEGORY_SET_P (val))
402: category_set = val;
403: else if (!SUB_CHAR_TABLE_P (val))
404: {
405: category_set = val = MAKE_CATEGORY_SET;
406: XCHAR_TABLE (table)->contents[charset + 128] = category_set;
407: }
408:
409: if (c1 <= 0)
410: {
411:
412: if (SUB_CHAR_TABLE_P (val))
413:
414:
415: modify_lower_category_set (val, category, set_value);
416: else
417: SET_CATEGORY_SET (category_set, category, set_value);
418: return Qnil;
419: }
420:
421:
422: if (!SUB_CHAR_TABLE_P (val))
423: {
424: val = make_sub_char_table (Qnil);
425: XCHAR_TABLE (table)->contents[charset + 128] = val;
426:
427: XCHAR_TABLE (val)->defalt = category_set;
428: }
429: table = val;
430:
431: val = XCHAR_TABLE (table)->contents[c1];
432: if (CATEGORY_SET_P (val))
433: category_set = val;
434: else if (!SUB_CHAR_TABLE_P (val))
435: {
436: category_set = val = Fcopy_sequence (XCHAR_TABLE (table)->defalt);
437: XCHAR_TABLE (table)->contents[c1] = category_set;
438: }
439:
440: if (c2 <= 0)
441: {
442: if (SUB_CHAR_TABLE_P (val))
443:
444:
445: modify_lower_category_set (val, category, set_value);
446: else
447: SET_CATEGORY_SET (category_set, category, set_value);
448: return Qnil;
449: }
450:
451:
452: if (!SUB_CHAR_TABLE_P (val))
453: {
454: val = make_sub_char_table (Qnil);
455: XCHAR_TABLE (table)->contents[c1] = val;
456:
457:
458: XCHAR_TABLE (val)->defalt = category_set;
459: }
460: table = val;
461:
462: val = XCHAR_TABLE (table)->contents[c2];
463: if (CATEGORY_SET_P (val))
464: category_set = val;
465: else if (!SUB_CHAR_TABLE_P (val))
466: {
467: category_set = Fcopy_sequence (XCHAR_TABLE (table)->defalt);
468: XCHAR_TABLE (table)->contents[c2] = category_set;
469: }
470: else
471:
472: error ("Invalid category table");
473:
474: SET_CATEGORY_SET (category_set, category, set_value);
475:
476: return Qnil;
477: }
478: ^L
479:
480:
481:
482:
483:
484: int
485: word_boundary_p (c1, c2)
486: int c1, c2;
487: {
488: Lisp_Object category_set1, category_set2;
489: Lisp_Object tail;
490: int default_result;
491:
492: if (CHAR_CHARSET (c1) == CHAR_CHARSET (c2))
493: {
494: tail = Vword_separating_categories;
495: default_result = 0;
496: }
497: else
498: {
499: tail = Vword_combining_categories;
500: default_result = 1;
501: }
502:
503: category_set1 = CATEGORY_SET (c1);
504: if (NILP (category_set1))
505: return default_result;
506: category_set2 = CATEGORY_SET (c2);
507: if (NILP (category_set2))
508: return default_result;
509:
510: for (; CONSP (tail); tail = XCDR (tail))
511: {
512: Lisp_Object elt = XCAR (tail);
513:
514: if (CONSP (elt)
515: && CATEGORYP (XCAR (elt))
516: && CATEGORYP (XCDR (elt))
517: && CATEGORY_MEMBER (XFASTINT (XCAR (elt)), category_set1)
518: && CATEGORY_MEMBER (XFASTINT (XCDR (elt)), category_set2))
519: return !default_result;
520: }
521: return default_result;
522: }
523:
524: ^L
525: void
526: init_category_once ()
527: {
528:
529: Qcategory_table = intern ("category-table");
530: staticpro (&Qcategory_table);
531:
532:
533:
534:
535: Qchar_table_extra_slots = intern ("char-table-extra-slots");
536:
537:
538:
539: Fput (Qcategory_table, Qchar_table_extra_slots, make_number (2));
540:
541: Vstandard_category_table = Fmake_char_table (Qcategory_table, Qnil);
542:
543: XCHAR_TABLE (Vstandard_category_table)->defalt = MAKE_CATEGORY_SET;
544: Fset_char_table_extra_slot (Vstandard_category_table, make_number (0),
545: Fmake_vector (make_number (95), Qnil));
546: }
547:
548: void
549: syms_of_category ()
550: {
551: Qcategoryp = intern ("categoryp");
552: staticpro (&Qcategoryp);
553: Qcategorysetp = intern ("categorysetp");
554: staticpro (&Qcategorysetp);
555: Qcategory_table_p = intern ("category-table-p");
556: staticpro (&Qcategory_table_p);
557:
558: DEFVAR_LISP ("word-combining-categories", &Vword_combining_categories,
559: doc:
560:
561:
562:
563:
564:
565:
566:
567:
568:
569:
570:
571:
572:
573:
574:
575:
576:
577:
578:
579:
580:
581:
582:
583:
584:
585:
586:
587:
588:
589:
590:
591: );
592:
593: Vword_combining_categories = Qnil;
594:
595: DEFVAR_LISP ("word-separating-categories", &Vword_separating_categories,
596: doc:
597: );
598:
599: Vword_separating_categories = Qnil;
600:
601: defsubr (&Smake_category_set);
602: defsubr (&Sdefine_category);
603: defsubr (&Scategory_docstring);
604: defsubr (&Sget_unused_category);
605: defsubr (&Scategory_table_p);
606: defsubr (&Scategory_table);
607: defsubr (&Sstandard_category_table);
608: defsubr (&Scopy_category_table);