diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog.bidi | 10 | ||||
| -rw-r--r-- | src/bidi.c | 30 |
2 files changed, 39 insertions, 1 deletions
diff --git a/src/ChangeLog.bidi b/src/ChangeLog.bidi index 9d2d643ae57..eab5642cb14 100644 --- a/src/ChangeLog.bidi +++ b/src/ChangeLog.bidi | |||
| @@ -1,3 +1,13 @@ | |||
| 1 | 2009-08-22 Eli Zaretskii <eliz@gnu.org> | ||
| 2 | |||
| 3 | * bidi.c (bidi_initialize): staticpro bidi_char_table. | ||
| 4 | (bidi_check_type): New function. | ||
| 5 | (bidi_cache_iterator_state, bidi_remember_char) | ||
| 6 | (bidi_resolve_explicit_1, bidi_resolve_explicit) | ||
| 7 | (bidi_resolve_weak, bidi_resolve_neutral) | ||
| 8 | (bidi_level_of_next_char): Use it to validate the bidi type | ||
| 9 | assigned to the iterator. | ||
| 10 | |||
| 1 | 2009-08-15 Eli Zaretskii <eliz@gnu.org> | 11 | 2009-08-15 Eli Zaretskii <eliz@gnu.org> |
| 2 | 12 | ||
| 3 | * bidi.c (bidi_initialize): Fix initialization of bidi_type_table. | 13 | * bidi.c (bidi_initialize): Fix initialization of bidi_type_table. |
diff --git a/src/bidi.c b/src/bidi.c index 46382b2b66c..697909ae8be 100644 --- a/src/bidi.c +++ b/src/bidi.c | |||
| @@ -19,7 +19,9 @@ along with GNU Emacs; see the file COPYING. If not, write to | |||
| 19 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | 19 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
| 20 | Boston, MA 02110-1301, USA. */ | 20 | Boston, MA 02110-1301, USA. */ |
| 21 | 21 | ||
| 22 | /* A sequential implementation of the Unicode Bidirectional algorithm, | 22 | /* Written by Eli Zaretskii <eliz@gnu.org>. |
| 23 | |||
| 24 | A sequential implementation of the Unicode Bidirectional algorithm, | ||
| 23 | as per UAX#9, a part of the Unicode Standard. | 25 | as per UAX#9, a part of the Unicode Standard. |
| 24 | 26 | ||
| 25 | Unlike the reference and most other implementations, this one is | 27 | Unlike the reference and most other implementations, this one is |
| @@ -447,6 +449,7 @@ bidi_initialize () | |||
| 447 | int i; | 449 | int i; |
| 448 | 450 | ||
| 449 | bidi_type_table = Fmake_char_table (Qnil, make_number (STRONG_L)); | 451 | bidi_type_table = Fmake_char_table (Qnil, make_number (STRONG_L)); |
| 452 | staticpro (&bidi_type_table); | ||
| 450 | 453 | ||
| 451 | for (i = 0; i < sizeof bidi_type / sizeof bidi_type[0]; i++) | 454 | for (i = 0; i < sizeof bidi_type / sizeof bidi_type[0]; i++) |
| 452 | char_table_set_range (bidi_type_table, bidi_type[i].from, | 455 | char_table_set_range (bidi_type_table, bidi_type[i].from, |
| @@ -472,6 +475,13 @@ bidi_get_type (int ch) | |||
| 472 | return (bidi_type_t) XINT (CHAR_TABLE_REF (bidi_type_table, ch)); | 475 | return (bidi_type_t) XINT (CHAR_TABLE_REF (bidi_type_table, ch)); |
| 473 | } | 476 | } |
| 474 | 477 | ||
| 478 | void | ||
| 479 | bidi_check_type (bidi_type_t type) | ||
| 480 | { | ||
| 481 | if (type < UNKNOWN_BT || type > NEUTRAL_ON) | ||
| 482 | abort (); | ||
| 483 | } | ||
| 484 | |||
| 475 | /* Given a bidi TYPE of a character, return its category. */ | 485 | /* Given a bidi TYPE of a character, return its category. */ |
| 476 | bidi_category_t | 486 | bidi_category_t |
| 477 | bidi_get_category (bidi_type_t type) | 487 | bidi_get_category (bidi_type_t type) |
| @@ -688,7 +698,9 @@ bidi_cache_iterator_state (struct bidi_it *bidi_it, int resolved) | |||
| 688 | /* Copy only the members which could have changed, to avoid | 698 | /* Copy only the members which could have changed, to avoid |
| 689 | costly copying of the entire struct. */ | 699 | costly copying of the entire struct. */ |
| 690 | bidi_cache[idx].type = bidi_it->type; | 700 | bidi_cache[idx].type = bidi_it->type; |
| 701 | bidi_check_type (bidi_it->type); | ||
| 691 | bidi_cache[idx].orig_type = bidi_it->orig_type; | 702 | bidi_cache[idx].orig_type = bidi_it->orig_type; |
| 703 | bidi_check_type (bidi_it->orig_type); | ||
| 692 | if (resolved) | 704 | if (resolved) |
| 693 | bidi_cache[idx].resolved_level = bidi_it->resolved_level; | 705 | bidi_cache[idx].resolved_level = bidi_it->resolved_level; |
| 694 | else | 706 | else |
| @@ -923,8 +935,11 @@ bidi_remember_char (struct bidi_saved_info *saved_info, | |||
| 923 | saved_info->charpos = bidi_it->charpos; | 935 | saved_info->charpos = bidi_it->charpos; |
| 924 | saved_info->bytepos = bidi_it->bytepos; | 936 | saved_info->bytepos = bidi_it->bytepos; |
| 925 | saved_info->type = bidi_it->type; | 937 | saved_info->type = bidi_it->type; |
| 938 | bidi_check_type (bidi_it->type); | ||
| 926 | saved_info->orig_type = bidi_it->orig_type; | 939 | saved_info->orig_type = bidi_it->orig_type; |
| 940 | bidi_check_type (bidi_it->orig_type); | ||
| 927 | saved_info->pristine_type = bidi_it->pristine_type; | 941 | saved_info->pristine_type = bidi_it->pristine_type; |
| 942 | bidi_check_type (bidi_it->pristine_type); | ||
| 928 | } | 943 | } |
| 929 | 944 | ||
| 930 | /* Resolve the type of a neutral character according to the type of | 945 | /* Resolve the type of a neutral character according to the type of |
| @@ -988,6 +1003,7 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it) | |||
| 988 | 1003 | ||
| 989 | type = bidi_get_type (curchar); | 1004 | type = bidi_get_type (curchar); |
| 990 | bidi_it->pristine_type = type; | 1005 | bidi_it->pristine_type = type; |
| 1006 | bidi_check_type (bidi_it->pristine_type); | ||
| 991 | 1007 | ||
| 992 | if (type != PDF) | 1008 | if (type != PDF) |
| 993 | bidi_it->prev_was_pdf = 0; | 1009 | bidi_it->prev_was_pdf = 0; |
| @@ -999,6 +1015,7 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it) | |||
| 999 | case RLE: /* X2 */ | 1015 | case RLE: /* X2 */ |
| 1000 | case RLO: /* X4 */ | 1016 | case RLO: /* X4 */ |
| 1001 | bidi_it->orig_type = type; | 1017 | bidi_it->orig_type = type; |
| 1018 | bidi_check_type (bidi_it->orig_type); | ||
| 1002 | type = WEAK_BN; /* X9/Retaining */ | 1019 | type = WEAK_BN; /* X9/Retaining */ |
| 1003 | if (bidi_it->ignore_bn_limit <= 0) | 1020 | if (bidi_it->ignore_bn_limit <= 0) |
| 1004 | { | 1021 | { |
| @@ -1031,6 +1048,7 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it) | |||
| 1031 | case LRE: /* X3 */ | 1048 | case LRE: /* X3 */ |
| 1032 | case LRO: /* X5 */ | 1049 | case LRO: /* X5 */ |
| 1033 | bidi_it->orig_type = type; | 1050 | bidi_it->orig_type = type; |
| 1051 | bidi_check_type (bidi_it->orig_type); | ||
| 1034 | type = WEAK_BN; /* X9/Retaining */ | 1052 | type = WEAK_BN; /* X9/Retaining */ |
| 1035 | if (bidi_it->ignore_bn_limit <= 0) | 1053 | if (bidi_it->ignore_bn_limit <= 0) |
| 1036 | { | 1054 | { |
| @@ -1065,6 +1083,7 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it) | |||
| 1065 | break; | 1083 | break; |
| 1066 | case PDF: /* X7 */ | 1084 | case PDF: /* X7 */ |
| 1067 | bidi_it->orig_type = type; | 1085 | bidi_it->orig_type = type; |
| 1086 | bidi_check_type (bidi_it->orig_type); | ||
| 1068 | type = WEAK_BN; /* X9/Retaining */ | 1087 | type = WEAK_BN; /* X9/Retaining */ |
| 1069 | if (bidi_it->ignore_bn_limit <= 0) | 1088 | if (bidi_it->ignore_bn_limit <= 0) |
| 1070 | { | 1089 | { |
| @@ -1094,6 +1113,7 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it) | |||
| 1094 | } | 1113 | } |
| 1095 | 1114 | ||
| 1096 | bidi_it->type = type; | 1115 | bidi_it->type = type; |
| 1116 | bidi_check_type (bidi_it->type); | ||
| 1097 | 1117 | ||
| 1098 | return new_level; | 1118 | return new_level; |
| 1099 | } | 1119 | } |
| @@ -1168,6 +1188,7 @@ bidi_resolve_explicit (struct bidi_it *bidi_it) | |||
| 1168 | { | 1188 | { |
| 1169 | bidi_set_paragraph_end (bidi_it); | 1189 | bidi_set_paragraph_end (bidi_it); |
| 1170 | bidi_it->orig_type = bidi_it->type; /* needed below and in L1 */ | 1190 | bidi_it->orig_type = bidi_it->type; /* needed below and in L1 */ |
| 1191 | bidi_check_type (bidi_it->orig_type); | ||
| 1171 | } | 1192 | } |
| 1172 | 1193 | ||
| 1173 | return new_level; | 1194 | return new_level; |
| @@ -1208,6 +1229,7 @@ bidi_resolve_weak (struct bidi_it *bidi_it) | |||
| 1208 | else if (type == NEUTRAL_S || type == NEUTRAL_WS | 1229 | else if (type == NEUTRAL_S || type == NEUTRAL_WS |
| 1209 | || type == WEAK_BN || type == STRONG_AL) | 1230 | || type == WEAK_BN || type == STRONG_AL) |
| 1210 | bidi_it->orig_type = type; /* needed in L1 */ | 1231 | bidi_it->orig_type = type; /* needed in L1 */ |
| 1232 | bidi_check_type (bidi_it->orig_type); | ||
| 1211 | 1233 | ||
| 1212 | /* Level and directional override status are already recorded in | 1234 | /* Level and directional override status are already recorded in |
| 1213 | bidi_it, and do not need any change; see X6. */ | 1235 | bidi_it, and do not need any change; see X6. */ |
| @@ -1344,6 +1366,7 @@ bidi_resolve_weak (struct bidi_it *bidi_it) | |||
| 1344 | them for the L1 clause. */ | 1366 | them for the L1 clause. */ |
| 1345 | if (bidi_it->orig_type == UNKNOWN_BT) | 1367 | if (bidi_it->orig_type == UNKNOWN_BT) |
| 1346 | bidi_it->orig_type = type; | 1368 | bidi_it->orig_type = type; |
| 1369 | bidi_check_type (bidi_it->orig_type); | ||
| 1347 | 1370 | ||
| 1348 | if (type == WEAK_EN) /* W7 */ | 1371 | if (type == WEAK_EN) /* W7 */ |
| 1349 | { | 1372 | { |
| @@ -1353,6 +1376,7 @@ bidi_resolve_weak (struct bidi_it *bidi_it) | |||
| 1353 | } | 1376 | } |
| 1354 | 1377 | ||
| 1355 | bidi_it->type = type; | 1378 | bidi_it->type = type; |
| 1379 | bidi_check_type (bidi_it->type); | ||
| 1356 | return type; | 1380 | return type; |
| 1357 | } | 1381 | } |
| 1358 | 1382 | ||
| @@ -1454,6 +1478,7 @@ bidi_resolve_neutral (struct bidi_it *bidi_it) | |||
| 1454 | { | 1478 | { |
| 1455 | next_type = bidi_it->prev_for_neutral.type; | 1479 | next_type = bidi_it->prev_for_neutral.type; |
| 1456 | saved_it.next_for_neutral.type = next_type; | 1480 | saved_it.next_for_neutral.type = next_type; |
| 1481 | bidi_check_type (next_type); | ||
| 1457 | } | 1482 | } |
| 1458 | else | 1483 | else |
| 1459 | { | 1484 | { |
| @@ -1469,6 +1494,7 @@ bidi_resolve_neutral (struct bidi_it *bidi_it) | |||
| 1469 | type = bidi_resolve_neutral_1 (saved_it.prev_for_neutral.type, | 1494 | type = bidi_resolve_neutral_1 (saved_it.prev_for_neutral.type, |
| 1470 | next_type, current_level); | 1495 | next_type, current_level); |
| 1471 | saved_it.type = type; | 1496 | saved_it.type = type; |
| 1497 | bidi_check_type (type); | ||
| 1472 | bidi_copy_it (bidi_it, &saved_it); | 1498 | bidi_copy_it (bidi_it, &saved_it); |
| 1473 | } | 1499 | } |
| 1474 | } | 1500 | } |
| @@ -1601,6 +1627,7 @@ bidi_level_of_next_char (struct bidi_it *bidi_it) | |||
| 1601 | || type == WEAK_AN)) | 1627 | || type == WEAK_AN)) |
| 1602 | abort (); | 1628 | abort (); |
| 1603 | bidi_it->type = type; | 1629 | bidi_it->type = type; |
| 1630 | bidi_check_type (bidi_it->type); | ||
| 1604 | 1631 | ||
| 1605 | /* For L1 below, we need to know, for each WS character, whether | 1632 | /* For L1 below, we need to know, for each WS character, whether |
| 1606 | it belongs to a sequence of WS characters preceeding a newline | 1633 | it belongs to a sequence of WS characters preceeding a newline |
| @@ -1627,6 +1654,7 @@ bidi_level_of_next_char (struct bidi_it *bidi_it) | |||
| 1627 | } while (chtype == NEUTRAL_WS || chtype == WEAK_BN | 1654 | } while (chtype == NEUTRAL_WS || chtype == WEAK_BN |
| 1628 | || bidi_explicit_dir_char (ch)); /* L1/Retaining */ | 1655 | || bidi_explicit_dir_char (ch)); /* L1/Retaining */ |
| 1629 | bidi_it->next_for_ws.type = chtype; | 1656 | bidi_it->next_for_ws.type = chtype; |
| 1657 | bidi_check_type (bidi_it->next_for_ws.type); | ||
| 1630 | bidi_it->next_for_ws.charpos = cpos; | 1658 | bidi_it->next_for_ws.charpos = cpos; |
| 1631 | bidi_it->next_for_ws.bytepos = bpos; | 1659 | bidi_it->next_for_ws.bytepos = bpos; |
| 1632 | } | 1660 | } |