Staticpro bidi_char_table, add type checking where bidi type is assigned.
bidi.c (bidi_initialize): staticpro bidi_char_table.
(bidi_check_type): New function.
(bidi_cache_iterator_state, bidi_remember_char)
(bidi_resolve_explicit_1, bidi_resolve_explicit)
(bidi_resolve_weak, bidi_resolve_neutral)
(bidi_level_of_next_char): Use it to validate the bidi type
assigned to the iterator.
+2009-08-22 Eli Zaretskii <eliz@gnu.org>
+
+ * bidi.c (bidi_initialize): staticpro bidi_char_table.
+ (bidi_check_type): New function.
+ (bidi_cache_iterator_state, bidi_remember_char)
+ (bidi_resolve_explicit_1, bidi_resolve_explicit)
+ (bidi_resolve_weak, bidi_resolve_neutral)
+ (bidi_level_of_next_char): Use it to validate the bidi type
+ assigned to the iterator.
+
2009-08-15 Eli Zaretskii <eliz@gnu.org>
* bidi.c (bidi_initialize): Fix initialization of bidi_type_table.
2009-08-15 Eli Zaretskii <eliz@gnu.org>
* bidi.c (bidi_initialize): Fix initialization of bidi_type_table.
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA. */
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA. */
-/* A sequential implementation of the Unicode Bidirectional algorithm,
+/* Written by Eli Zaretskii <eliz@gnu.org>.
+
+ A sequential implementation of the Unicode Bidirectional algorithm,
as per UAX#9, a part of the Unicode Standard.
Unlike the reference and most other implementations, this one is
as per UAX#9, a part of the Unicode Standard.
Unlike the reference and most other implementations, this one is
int i;
bidi_type_table = Fmake_char_table (Qnil, make_number (STRONG_L));
int i;
bidi_type_table = Fmake_char_table (Qnil, make_number (STRONG_L));
+ staticpro (&bidi_type_table);
for (i = 0; i < sizeof bidi_type / sizeof bidi_type[0]; i++)
char_table_set_range (bidi_type_table, bidi_type[i].from,
for (i = 0; i < sizeof bidi_type / sizeof bidi_type[0]; i++)
char_table_set_range (bidi_type_table, bidi_type[i].from,
return (bidi_type_t) XINT (CHAR_TABLE_REF (bidi_type_table, ch));
}
return (bidi_type_t) XINT (CHAR_TABLE_REF (bidi_type_table, ch));
}
+void
+bidi_check_type (bidi_type_t type)
+{
+ if (type < UNKNOWN_BT || type > NEUTRAL_ON)
+ abort ();
+}
+
/* Given a bidi TYPE of a character, return its category. */
bidi_category_t
bidi_get_category (bidi_type_t type)
/* Given a bidi TYPE of a character, return its category. */
bidi_category_t
bidi_get_category (bidi_type_t type)
/* Copy only the members which could have changed, to avoid
costly copying of the entire struct. */
bidi_cache[idx].type = bidi_it->type;
/* Copy only the members which could have changed, to avoid
costly copying of the entire struct. */
bidi_cache[idx].type = bidi_it->type;
+ bidi_check_type (bidi_it->type);
bidi_cache[idx].orig_type = bidi_it->orig_type;
bidi_cache[idx].orig_type = bidi_it->orig_type;
+ bidi_check_type (bidi_it->orig_type);
if (resolved)
bidi_cache[idx].resolved_level = bidi_it->resolved_level;
else
if (resolved)
bidi_cache[idx].resolved_level = bidi_it->resolved_level;
else
saved_info->charpos = bidi_it->charpos;
saved_info->bytepos = bidi_it->bytepos;
saved_info->type = bidi_it->type;
saved_info->charpos = bidi_it->charpos;
saved_info->bytepos = bidi_it->bytepos;
saved_info->type = bidi_it->type;
+ bidi_check_type (bidi_it->type);
saved_info->orig_type = bidi_it->orig_type;
saved_info->orig_type = bidi_it->orig_type;
+ bidi_check_type (bidi_it->orig_type);
saved_info->pristine_type = bidi_it->pristine_type;
saved_info->pristine_type = bidi_it->pristine_type;
+ bidi_check_type (bidi_it->pristine_type);
}
/* Resolve the type of a neutral character according to the type of
}
/* Resolve the type of a neutral character according to the type of
type = bidi_get_type (curchar);
bidi_it->pristine_type = type;
type = bidi_get_type (curchar);
bidi_it->pristine_type = type;
+ bidi_check_type (bidi_it->pristine_type);
if (type != PDF)
bidi_it->prev_was_pdf = 0;
if (type != PDF)
bidi_it->prev_was_pdf = 0;
case RLE: /* X2 */
case RLO: /* X4 */
bidi_it->orig_type = type;
case RLE: /* X2 */
case RLO: /* X4 */
bidi_it->orig_type = type;
+ bidi_check_type (bidi_it->orig_type);
type = WEAK_BN; /* X9/Retaining */
if (bidi_it->ignore_bn_limit <= 0)
{
type = WEAK_BN; /* X9/Retaining */
if (bidi_it->ignore_bn_limit <= 0)
{
case LRE: /* X3 */
case LRO: /* X5 */
bidi_it->orig_type = type;
case LRE: /* X3 */
case LRO: /* X5 */
bidi_it->orig_type = type;
+ bidi_check_type (bidi_it->orig_type);
type = WEAK_BN; /* X9/Retaining */
if (bidi_it->ignore_bn_limit <= 0)
{
type = WEAK_BN; /* X9/Retaining */
if (bidi_it->ignore_bn_limit <= 0)
{
break;
case PDF: /* X7 */
bidi_it->orig_type = type;
break;
case PDF: /* X7 */
bidi_it->orig_type = type;
+ bidi_check_type (bidi_it->orig_type);
type = WEAK_BN; /* X9/Retaining */
if (bidi_it->ignore_bn_limit <= 0)
{
type = WEAK_BN; /* X9/Retaining */
if (bidi_it->ignore_bn_limit <= 0)
{
+ bidi_check_type (bidi_it->type);
{
bidi_set_paragraph_end (bidi_it);
bidi_it->orig_type = bidi_it->type; /* needed below and in L1 */
{
bidi_set_paragraph_end (bidi_it);
bidi_it->orig_type = bidi_it->type; /* needed below and in L1 */
+ bidi_check_type (bidi_it->orig_type);
else if (type == NEUTRAL_S || type == NEUTRAL_WS
|| type == WEAK_BN || type == STRONG_AL)
bidi_it->orig_type = type; /* needed in L1 */
else if (type == NEUTRAL_S || type == NEUTRAL_WS
|| type == WEAK_BN || type == STRONG_AL)
bidi_it->orig_type = type; /* needed in L1 */
+ bidi_check_type (bidi_it->orig_type);
/* Level and directional override status are already recorded in
bidi_it, and do not need any change; see X6. */
/* Level and directional override status are already recorded in
bidi_it, and do not need any change; see X6. */
them for the L1 clause. */
if (bidi_it->orig_type == UNKNOWN_BT)
bidi_it->orig_type = type;
them for the L1 clause. */
if (bidi_it->orig_type == UNKNOWN_BT)
bidi_it->orig_type = type;
+ bidi_check_type (bidi_it->orig_type);
if (type == WEAK_EN) /* W7 */
{
if (type == WEAK_EN) /* W7 */
{
+ bidi_check_type (bidi_it->type);
{
next_type = bidi_it->prev_for_neutral.type;
saved_it.next_for_neutral.type = next_type;
{
next_type = bidi_it->prev_for_neutral.type;
saved_it.next_for_neutral.type = next_type;
+ bidi_check_type (next_type);
type = bidi_resolve_neutral_1 (saved_it.prev_for_neutral.type,
next_type, current_level);
saved_it.type = type;
type = bidi_resolve_neutral_1 (saved_it.prev_for_neutral.type,
next_type, current_level);
saved_it.type = type;
+ bidi_check_type (type);
bidi_copy_it (bidi_it, &saved_it);
}
}
bidi_copy_it (bidi_it, &saved_it);
}
}
|| type == WEAK_AN))
abort ();
bidi_it->type = type;
|| type == WEAK_AN))
abort ();
bidi_it->type = type;
+ bidi_check_type (bidi_it->type);
/* For L1 below, we need to know, for each WS character, whether
it belongs to a sequence of WS characters preceeding a newline
/* For L1 below, we need to know, for each WS character, whether
it belongs to a sequence of WS characters preceeding a newline
} while (chtype == NEUTRAL_WS || chtype == WEAK_BN
|| bidi_explicit_dir_char (ch)); /* L1/Retaining */
bidi_it->next_for_ws.type = chtype;
} while (chtype == NEUTRAL_WS || chtype == WEAK_BN
|| bidi_explicit_dir_char (ch)); /* L1/Retaining */
bidi_it->next_for_ws.type = chtype;
+ bidi_check_type (bidi_it->next_for_ws.type);
bidi_it->next_for_ws.charpos = cpos;
bidi_it->next_for_ws.bytepos = bpos;
}
bidi_it->next_for_ws.charpos = cpos;
bidi_it->next_for_ws.bytepos = bpos;
}