Mercurial > emacs
comparison src/category.c @ 89483:2f877ed80fa6
*** empty log message ***
author | Kenichi Handa <handa@m17n.org> |
---|---|
date | Mon, 08 Sep 2003 12:53:41 +0000 |
parents | 375f2633d815 9320c2f4f351 |
children | 51677cb10ced |
comparison
equal
deleted
inserted
replaced
88123:375f2633d815 | 89483:2f877ed80fa6 |
---|---|
1 /* GNU Emacs routines to deal with category tables. | 1 /* GNU Emacs routines to deal with category tables. |
2 Copyright (C) 1995, 1997 Electrotechnical Laboratory, JAPAN. | 2 Copyright (C) 1995, 1997 Electrotechnical Laboratory, JAPAN. |
3 Licensed to the Free Software Foundation. | 3 Licensed to the Free Software Foundation. |
4 Copyright (C) 2003 | |
5 National Institute of Advanced Industrial Science and Technology (AIST) | |
6 Registration Number H13PRO009 | |
4 | 7 |
5 This file is part of GNU Emacs. | 8 This file is part of GNU Emacs. |
6 | 9 |
7 GNU Emacs is free software; you can redistribute it and/or modify | 10 GNU Emacs is free software; you can redistribute it and/or modify |
8 it under the terms of the GNU General Public License as published by | 11 it under the terms of the GNU General Public License as published by |
25 | 28 |
26 #include <config.h> | 29 #include <config.h> |
27 #include <ctype.h> | 30 #include <ctype.h> |
28 #include "lisp.h" | 31 #include "lisp.h" |
29 #include "buffer.h" | 32 #include "buffer.h" |
33 #include "character.h" | |
30 #include "charset.h" | 34 #include "charset.h" |
31 #include "category.h" | 35 #include "category.h" |
32 #include "keymap.h" | 36 #include "keymap.h" |
33 | 37 |
34 /* The version number of the latest category table. Each category | 38 /* The version number of the latest category table. Each category |
184 () | 188 () |
185 { | 189 { |
186 return Vstandard_category_table; | 190 return Vstandard_category_table; |
187 } | 191 } |
188 | 192 |
193 | |
194 static void | |
195 copy_category_entry (table, c, val) | |
196 Lisp_Object table, c, val; | |
197 { | |
198 val = Fcopy_sequence (val); | |
199 if (CONSP (c)) | |
200 char_table_set_range (table, XINT (XCAR (c)), XINT (XCDR (c)), val); | |
201 else | |
202 char_table_set (table, XINT (c), val); | |
203 } | |
204 | |
189 /* Return a copy of category table TABLE. We can't simply use the | 205 /* Return a copy of category table TABLE. We can't simply use the |
190 function copy-sequence because no contents should be shared between | 206 function copy-sequence because no contents should be shared between |
191 the original and the copy. This function is called recursively by | 207 the original and the copy. This function is called recursively by |
192 binding TABLE to a sub char table. */ | 208 binding TABLE to a sub char table. */ |
193 | 209 |
194 Lisp_Object | 210 Lisp_Object |
195 copy_category_table (table) | 211 copy_category_table (table) |
196 Lisp_Object table; | 212 Lisp_Object table; |
197 { | 213 { |
198 Lisp_Object tmp; | 214 table = copy_char_table (table); |
199 int i, to; | 215 |
200 | 216 if (! NILP (XCHAR_TABLE (table)->defalt)) |
201 if (!NILP (XCHAR_TABLE (table)->top)) | 217 XCHAR_TABLE (table)->defalt |
202 { | 218 = Fcopy_sequence (XCHAR_TABLE (table)->defalt); |
203 /* TABLE is a top level char table. | 219 XCHAR_TABLE (table)->extras[0] |
204 At first, make a copy of tree structure of the table. */ | 220 = Fcopy_sequence (XCHAR_TABLE (table)->extras[0]); |
205 table = Fcopy_sequence (table); | 221 map_char_table (copy_category_entry, Qnil, table, table); |
206 | |
207 /* Then, copy elements for single byte characters one by one. */ | |
208 for (i = 0; i < CHAR_TABLE_SINGLE_BYTE_SLOTS; i++) | |
209 if (!NILP (tmp = XCHAR_TABLE (table)->contents[i])) | |
210 XCHAR_TABLE (table)->contents[i] = Fcopy_sequence (tmp); | |
211 to = CHAR_TABLE_ORDINARY_SLOTS; | |
212 | |
213 /* Also copy the first (and sole) extra slot. It is a vector | |
214 containing docstring of each category. */ | |
215 Fset_char_table_extra_slot | |
216 (table, make_number (0), | |
217 Fcopy_sequence (Fchar_table_extra_slot (table, make_number (0)))); | |
218 } | |
219 else | |
220 { | |
221 i = 32; | |
222 to = SUB_CHAR_TABLE_ORDINARY_SLOTS; | |
223 } | |
224 | |
225 /* If the table has non-nil default value, copy it. */ | |
226 if (!NILP (tmp = XCHAR_TABLE (table)->defalt)) | |
227 XCHAR_TABLE (table)->defalt = Fcopy_sequence (tmp); | |
228 | |
229 /* At last, copy the remaining elements while paying attention to a | |
230 sub char table. */ | |
231 for (; i < to; i++) | |
232 if (!NILP (tmp = XCHAR_TABLE (table)->contents[i])) | |
233 XCHAR_TABLE (table)->contents[i] | |
234 = (SUB_CHAR_TABLE_P (tmp) | |
235 ? copy_category_table (tmp) : Fcopy_sequence (tmp)); | |
236 | 222 |
237 return table; | 223 return table; |
238 } | 224 } |
239 | 225 |
240 DEFUN ("copy-category-table", Fcopy_category_table, Scopy_category_table, | 226 DEFUN ("copy-category-table", Fcopy_category_table, Scopy_category_table, |
256 0, 0, 0, | 242 0, 0, 0, |
257 doc: /* Construct a new and empty category table and return it. */) | 243 doc: /* Construct a new and empty category table and return it. */) |
258 () | 244 () |
259 { | 245 { |
260 Lisp_Object val; | 246 Lisp_Object val; |
247 int i; | |
261 | 248 |
262 val = Fmake_char_table (Qcategory_table, Qnil); | 249 val = Fmake_char_table (Qcategory_table, Qnil); |
263 XCHAR_TABLE (val)->defalt = MAKE_CATEGORY_SET; | 250 XCHAR_TABLE (val)->defalt = MAKE_CATEGORY_SET; |
251 for (i = 0; i < (1 << CHARTAB_SIZE_BITS_0); i++) | |
252 XCHAR_TABLE (val)->contents[i] = MAKE_CATEGORY_SET; | |
264 Fset_char_table_extra_slot (val, make_number (0), | 253 Fset_char_table_extra_slot (val, make_number (0), |
265 Fmake_vector (make_number (95), Qnil)); | 254 Fmake_vector (make_number (95), Qnil)); |
266 return val; | 255 return val; |
267 } | 256 } |
268 | 257 |
279 SET_PER_BUFFER_VALUE_P (current_buffer, idx, 1); | 268 SET_PER_BUFFER_VALUE_P (current_buffer, idx, 1); |
280 return table; | 269 return table; |
281 } | 270 } |
282 | 271 |
283 | 272 |
273 Lisp_Object | |
274 char_category_set (c) | |
275 int c; | |
276 { | |
277 return CHAR_TABLE_REF (current_buffer->category_table, c); | |
278 } | |
279 | |
284 DEFUN ("char-category-set", Fchar_category_set, Schar_category_set, 1, 1, 0, | 280 DEFUN ("char-category-set", Fchar_category_set, Schar_category_set, 1, 1, 0, |
285 doc: /* Return the category set of CHAR. */) | 281 doc: /* Return the category set of CHAR. */) |
286 (ch) | 282 (ch) |
287 Lisp_Object ch; | 283 Lisp_Object ch; |
288 { | 284 { |
311 str[j] = '\0'; | 307 str[j] = '\0'; |
312 | 308 |
313 return build_string (str); | 309 return build_string (str); |
314 } | 310 } |
315 | 311 |
316 /* Modify all category sets stored under sub char-table TABLE so that | |
317 they contain (SET_VALUE is t) or don't contain (SET_VALUE is nil) | |
318 CATEGORY. */ | |
319 | |
320 void | |
321 modify_lower_category_set (table, category, set_value) | |
322 Lisp_Object table, category, set_value; | |
323 { | |
324 Lisp_Object val; | |
325 int i; | |
326 | |
327 val = XCHAR_TABLE (table)->defalt; | |
328 if (!CATEGORY_SET_P (val)) | |
329 val = MAKE_CATEGORY_SET; | |
330 SET_CATEGORY_SET (val, category, set_value); | |
331 XCHAR_TABLE (table)->defalt = val; | |
332 | |
333 for (i = 32; i < SUB_CHAR_TABLE_ORDINARY_SLOTS; i++) | |
334 { | |
335 val = XCHAR_TABLE (table)->contents[i]; | |
336 | |
337 if (CATEGORY_SET_P (val)) | |
338 SET_CATEGORY_SET (val, category, set_value); | |
339 else if (SUB_CHAR_TABLE_P (val)) | |
340 modify_lower_category_set (val, category, set_value); | |
341 } | |
342 } | |
343 | |
344 void | 312 void |
345 set_category_set (category_set, category, val) | 313 set_category_set (category_set, category, val) |
346 Lisp_Object category_set, category, val; | 314 Lisp_Object category_set, category, val; |
347 { | 315 { |
348 do { | 316 do { |
358 | 326 |
359 DEFUN ("modify-category-entry", Fmodify_category_entry, | 327 DEFUN ("modify-category-entry", Fmodify_category_entry, |
360 Smodify_category_entry, 2, 4, 0, | 328 Smodify_category_entry, 2, 4, 0, |
361 doc: /* Modify the category set of CHARACTER by adding CATEGORY to it. | 329 doc: /* Modify the category set of CHARACTER by adding CATEGORY to it. |
362 The category is changed only for table TABLE, which defaults to | 330 The category is changed only for table TABLE, which defaults to |
363 the current buffer's category table. | 331 the current buffer's category table. |
332 CHARACTER can be either a single character or a cons representing the | |
333 lower and upper ends of an inclusive character range to modify. | |
364 If optional fourth argument RESET is non-nil, | 334 If optional fourth argument RESET is non-nil, |
365 then delete CATEGORY from the category set instead of adding it. */) | 335 then delete CATEGORY from the category set instead of adding it. */) |
366 (character, category, table, reset) | 336 (character, category, table, reset) |
367 Lisp_Object character, category, table, reset; | 337 Lisp_Object character, category, table, reset; |
368 { | 338 { |
369 int c, charset, c1, c2; | |
370 Lisp_Object set_value; /* Actual value to be set in category sets. */ | 339 Lisp_Object set_value; /* Actual value to be set in category sets. */ |
371 Lisp_Object val, category_set; | 340 Lisp_Object category_set; |
372 | 341 int start, end; |
373 CHECK_NUMBER (character); | 342 int from, to; |
374 c = XINT (character); | 343 |
344 if (INTEGERP (character)) | |
345 { | |
346 CHECK_CHARACTER (character); | |
347 start = end = XFASTINT (character); | |
348 } | |
349 else | |
350 { | |
351 CHECK_CONS (character); | |
352 CHECK_CHARACTER_CAR (character); | |
353 CHECK_CHARACTER_CDR (character); | |
354 start = XFASTINT (XCAR (character)); | |
355 end = XFASTINT (XCDR (character)); | |
356 } | |
357 | |
375 CHECK_CATEGORY (category); | 358 CHECK_CATEGORY (category); |
376 table = check_category_table (table); | 359 table = check_category_table (table); |
377 | 360 |
378 if (NILP (CATEGORY_DOCSTRING (table, XFASTINT (category)))) | 361 if (NILP (CATEGORY_DOCSTRING (table, XFASTINT (category)))) |
379 error ("Undefined category: %c", XFASTINT (category)); | 362 error ("Undefined category: %c", XFASTINT (category)); |
380 | 363 |
381 set_value = NILP (reset) ? Qt : Qnil; | 364 set_value = NILP (reset) ? Qt : Qnil; |
382 | 365 |
383 if (c < CHAR_TABLE_SINGLE_BYTE_SLOTS) | 366 while (start <= end) |
384 { | 367 { |
385 val = XCHAR_TABLE (table)->contents[c]; | 368 category_set = char_table_ref_and_range (table, start, &from, &to); |
386 if (!CATEGORY_SET_P (val)) | 369 if (CATEGORY_MEMBER (XFASTINT (category), category_set) != NILP (reset)) |
387 XCHAR_TABLE (table)->contents[c] = (val = MAKE_CATEGORY_SET); | 370 { |
388 SET_CATEGORY_SET (val, category, set_value); | 371 category_set = Fcopy_sequence (category_set); |
389 return Qnil; | 372 SET_CATEGORY_SET (category_set, category, set_value); |
390 } | 373 if (to > end) |
391 | 374 char_table_set_range (table, start, end, category_set); |
392 SPLIT_CHAR (c, charset, c1, c2); | 375 else |
393 | 376 char_table_set_range (table, start, to, category_set); |
394 /* The top level table. */ | 377 } |
395 val = XCHAR_TABLE (table)->contents[charset + 128]; | 378 start = to + 1; |
396 if (CATEGORY_SET_P (val)) | 379 } |
397 category_set = val; | |
398 else if (!SUB_CHAR_TABLE_P (val)) | |
399 { | |
400 category_set = val = MAKE_CATEGORY_SET; | |
401 XCHAR_TABLE (table)->contents[charset + 128] = category_set; | |
402 } | |
403 | |
404 if (c1 <= 0) | |
405 { | |
406 /* Only a charset is specified. */ | |
407 if (SUB_CHAR_TABLE_P (val)) | |
408 /* All characters in CHARSET should be the same as for having | |
409 CATEGORY or not. */ | |
410 modify_lower_category_set (val, category, set_value); | |
411 else | |
412 SET_CATEGORY_SET (category_set, category, set_value); | |
413 return Qnil; | |
414 } | |
415 | |
416 /* The second level table. */ | |
417 if (!SUB_CHAR_TABLE_P (val)) | |
418 { | |
419 val = make_sub_char_table (Qnil); | |
420 XCHAR_TABLE (table)->contents[charset + 128] = val; | |
421 /* We must set default category set of CHARSET in `defalt' slot. */ | |
422 XCHAR_TABLE (val)->defalt = category_set; | |
423 } | |
424 table = val; | |
425 | |
426 val = XCHAR_TABLE (table)->contents[c1]; | |
427 if (CATEGORY_SET_P (val)) | |
428 category_set = val; | |
429 else if (!SUB_CHAR_TABLE_P (val)) | |
430 { | |
431 category_set = val = Fcopy_sequence (XCHAR_TABLE (table)->defalt); | |
432 XCHAR_TABLE (table)->contents[c1] = category_set; | |
433 } | |
434 | |
435 if (c2 <= 0) | |
436 { | |
437 if (SUB_CHAR_TABLE_P (val)) | |
438 /* All characters in C1 group of CHARSET should be the same as | |
439 for CATEGORY. */ | |
440 modify_lower_category_set (val, category, set_value); | |
441 else | |
442 SET_CATEGORY_SET (category_set, category, set_value); | |
443 return Qnil; | |
444 } | |
445 | |
446 /* The third (bottom) level table. */ | |
447 if (!SUB_CHAR_TABLE_P (val)) | |
448 { | |
449 val = make_sub_char_table (Qnil); | |
450 XCHAR_TABLE (table)->contents[c1] = val; | |
451 /* We must set default category set of CHARSET and C1 in | |
452 `defalt' slot. */ | |
453 XCHAR_TABLE (val)->defalt = category_set; | |
454 } | |
455 table = val; | |
456 | |
457 val = XCHAR_TABLE (table)->contents[c2]; | |
458 if (CATEGORY_SET_P (val)) | |
459 category_set = val; | |
460 else if (!SUB_CHAR_TABLE_P (val)) | |
461 { | |
462 category_set = Fcopy_sequence (XCHAR_TABLE (table)->defalt); | |
463 XCHAR_TABLE (table)->contents[c2] = category_set; | |
464 } | |
465 else | |
466 /* This should never happen. */ | |
467 error ("Invalid category table"); | |
468 | |
469 SET_CATEGORY_SET (category_set, category, set_value); | |
470 | 380 |
471 return Qnil; | 381 return Qnil; |
472 } | 382 } |
473 | 383 |
474 /* Return 1 if there is a word boundary between two word-constituent | 384 /* Return 1 if there is a word boundary between two word-constituent |