diff options
Diffstat (limited to 'src/bidi.c')
| -rw-r--r-- | src/bidi.c | 42 |
1 files changed, 25 insertions, 17 deletions
diff --git a/src/bidi.c b/src/bidi.c index 6f3d749ef22..c6bea62f67b 100644 --- a/src/bidi.c +++ b/src/bidi.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Low-level bidirectional buffer/string-scanning functions for GNU Emacs. | 1 | /* Low-level bidirectional buffer/string-scanning functions for GNU Emacs. |
| 2 | Copyright (C) 2000-2001, 2004-2005, 2009-2012 | 2 | Copyright (C) 2000-2001, 2004-2005, 2009-2013 Free Software |
| 3 | Free Software Foundation, Inc. | 3 | Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 6 | 6 | ||
| @@ -910,7 +910,7 @@ bidi_char_at_pos (ptrdiff_t bytepos, const unsigned char *s, bool unibyte) | |||
| 910 | return STRING_CHAR (s); | 910 | return STRING_CHAR (s); |
| 911 | } | 911 | } |
| 912 | 912 | ||
| 913 | /* Fetch and return the character at BYTEPOS/CHARPOS. If that | 913 | /* Fetch and return the character at CHARPOS/BYTEPOS. If that |
| 914 | character is covered by a display string, treat the entire run of | 914 | character is covered by a display string, treat the entire run of |
| 915 | covered characters as a single character, either u+2029 or u+FFFC, | 915 | covered characters as a single character, either u+2029 or u+FFFC, |
| 916 | and return their combined length in CH_LEN and NCHARS. DISP_POS | 916 | and return their combined length in CH_LEN and NCHARS. DISP_POS |
| @@ -925,7 +925,7 @@ bidi_char_at_pos (ptrdiff_t bytepos, const unsigned char *s, bool unibyte) | |||
| 925 | string to iterate, or NULL if iterating over a buffer or a Lisp | 925 | string to iterate, or NULL if iterating over a buffer or a Lisp |
| 926 | string; in the latter case, STRING->lstring is the Lisp string. */ | 926 | string; in the latter case, STRING->lstring is the Lisp string. */ |
| 927 | static int | 927 | static int |
| 928 | bidi_fetch_char (ptrdiff_t bytepos, ptrdiff_t charpos, ptrdiff_t *disp_pos, | 928 | bidi_fetch_char (ptrdiff_t charpos, ptrdiff_t bytepos, ptrdiff_t *disp_pos, |
| 929 | int *disp_prop, struct bidi_string_data *string, | 929 | int *disp_prop, struct bidi_string_data *string, |
| 930 | bool frame_window_p, ptrdiff_t *ch_len, ptrdiff_t *nchars) | 930 | bool frame_window_p, ptrdiff_t *ch_len, ptrdiff_t *nchars) |
| 931 | { | 931 | { |
| @@ -1109,8 +1109,8 @@ bidi_find_paragraph_start (ptrdiff_t pos, ptrdiff_t pos_byte) | |||
| 1109 | display string? And what if a display string covering some | 1109 | display string? And what if a display string covering some |
| 1110 | of the text over which we scan back includes | 1110 | of the text over which we scan back includes |
| 1111 | paragraph_start_re? */ | 1111 | paragraph_start_re? */ |
| 1112 | pos = find_next_newline_no_quit (pos - 1, -1); | 1112 | DEC_BOTH (pos, pos_byte); |
| 1113 | pos_byte = CHAR_TO_BYTE (pos); | 1113 | pos = find_newline_no_quit (pos, pos_byte, -1, &pos_byte); |
| 1114 | } | 1114 | } |
| 1115 | if (n >= MAX_PARAGRAPH_SEARCH) | 1115 | if (n >= MAX_PARAGRAPH_SEARCH) |
| 1116 | pos_byte = BEGV_BYTE; | 1116 | pos_byte = BEGV_BYTE; |
| @@ -1223,7 +1223,7 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, bool no_default_p) | |||
| 1223 | bytepos = pstartbyte; | 1223 | bytepos = pstartbyte; |
| 1224 | if (!string_p) | 1224 | if (!string_p) |
| 1225 | pos = BYTE_TO_CHAR (bytepos); | 1225 | pos = BYTE_TO_CHAR (bytepos); |
| 1226 | ch = bidi_fetch_char (bytepos, pos, &disp_pos, &disp_prop, | 1226 | ch = bidi_fetch_char (pos, bytepos, &disp_pos, &disp_prop, |
| 1227 | &bidi_it->string, | 1227 | &bidi_it->string, |
| 1228 | bidi_it->frame_window_p, &ch_len, &nchars); | 1228 | bidi_it->frame_window_p, &ch_len, &nchars); |
| 1229 | type = bidi_get_type (ch, NEUTRAL_DIR); | 1229 | type = bidi_get_type (ch, NEUTRAL_DIR); |
| @@ -1251,7 +1251,7 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, bool no_default_p) | |||
| 1251 | && bidi_at_paragraph_end (pos, bytepos) >= -1) | 1251 | && bidi_at_paragraph_end (pos, bytepos) >= -1) |
| 1252 | break; | 1252 | break; |
| 1253 | /* Fetch next character and advance to get past it. */ | 1253 | /* Fetch next character and advance to get past it. */ |
| 1254 | ch = bidi_fetch_char (bytepos, pos, &disp_pos, | 1254 | ch = bidi_fetch_char (pos, bytepos, &disp_pos, |
| 1255 | &disp_prop, &bidi_it->string, | 1255 | &disp_prop, &bidi_it->string, |
| 1256 | bidi_it->frame_window_p, &ch_len, &nchars); | 1256 | bidi_it->frame_window_p, &ch_len, &nchars); |
| 1257 | pos += nchars; | 1257 | pos += nchars; |
| @@ -1282,8 +1282,7 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, bool no_default_p) | |||
| 1282 | /* FXIME: What if p is covered by a display | 1282 | /* FXIME: What if p is covered by a display |
| 1283 | string? See also a FIXME inside | 1283 | string? See also a FIXME inside |
| 1284 | bidi_find_paragraph_start. */ | 1284 | bidi_find_paragraph_start. */ |
| 1285 | p--; | 1285 | DEC_BOTH (p, pbyte); |
| 1286 | pbyte = CHAR_TO_BYTE (p); | ||
| 1287 | prevpbyte = bidi_find_paragraph_start (p, pbyte); | 1286 | prevpbyte = bidi_find_paragraph_start (p, pbyte); |
| 1288 | } | 1287 | } |
| 1289 | pstartbyte = prevpbyte; | 1288 | pstartbyte = prevpbyte; |
| @@ -1356,15 +1355,19 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it) | |||
| 1356 | : bidi_it->string.s); | 1355 | : bidi_it->string.s); |
| 1357 | 1356 | ||
| 1358 | if (bidi_it->charpos < 0) | 1357 | if (bidi_it->charpos < 0) |
| 1359 | bidi_it->charpos = 0; | 1358 | bidi_it->charpos = bidi_it->bytepos = 0; |
| 1360 | bidi_it->bytepos = bidi_count_bytes (p, 0, 0, bidi_it->charpos, | 1359 | eassert (bidi_it->bytepos == bidi_count_bytes (p, 0, 0, |
| 1361 | bidi_it->string.unibyte); | 1360 | bidi_it->charpos, |
| 1361 | bidi_it->string.unibyte)); | ||
| 1362 | } | 1362 | } |
| 1363 | else | 1363 | else |
| 1364 | { | 1364 | { |
| 1365 | if (bidi_it->charpos < BEGV) | 1365 | if (bidi_it->charpos < BEGV) |
| 1366 | bidi_it->charpos = BEGV; | 1366 | { |
| 1367 | bidi_it->bytepos = CHAR_TO_BYTE (bidi_it->charpos); | 1367 | bidi_it->charpos = BEGV; |
| 1368 | bidi_it->bytepos = BEGV_BYTE; | ||
| 1369 | } | ||
| 1370 | eassert (bidi_it->bytepos == CHAR_TO_BYTE (bidi_it->charpos)); | ||
| 1368 | } | 1371 | } |
| 1369 | } | 1372 | } |
| 1370 | /* Don't move at end of buffer/string. */ | 1373 | /* Don't move at end of buffer/string. */ |
| @@ -1397,7 +1400,7 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it) | |||
| 1397 | /* Fetch the character at BYTEPOS. If it is covered by a | 1400 | /* Fetch the character at BYTEPOS. If it is covered by a |
| 1398 | display string, treat the entire run of covered characters as | 1401 | display string, treat the entire run of covered characters as |
| 1399 | a single character u+FFFC. */ | 1402 | a single character u+FFFC. */ |
| 1400 | curchar = bidi_fetch_char (bidi_it->bytepos, bidi_it->charpos, | 1403 | curchar = bidi_fetch_char (bidi_it->charpos, bidi_it->bytepos, |
| 1401 | &bidi_it->disp_pos, &bidi_it->disp_prop, | 1404 | &bidi_it->disp_pos, &bidi_it->disp_prop, |
| 1402 | &bidi_it->string, bidi_it->frame_window_p, | 1405 | &bidi_it->string, bidi_it->frame_window_p, |
| 1403 | &bidi_it->ch_len, &bidi_it->nchars); | 1406 | &bidi_it->ch_len, &bidi_it->nchars); |
| @@ -1973,6 +1976,7 @@ bidi_resolve_neutral (struct bidi_it *bidi_it) | |||
| 1973 | next_type = STRONG_R; | 1976 | next_type = STRONG_R; |
| 1974 | break; | 1977 | break; |
| 1975 | case WEAK_BN: | 1978 | case WEAK_BN: |
| 1979 | case NEUTRAL_ON: /* W6/Retaining */ | ||
| 1976 | if (!bidi_explicit_dir_char (bidi_it->ch)) | 1980 | if (!bidi_explicit_dir_char (bidi_it->ch)) |
| 1977 | emacs_abort (); /* can't happen: BNs are skipped */ | 1981 | emacs_abort (); /* can't happen: BNs are skipped */ |
| 1978 | /* FALLTHROUGH */ | 1982 | /* FALLTHROUGH */ |
| @@ -2189,7 +2193,7 @@ bidi_level_of_next_char (struct bidi_it *bidi_it) | |||
| 2189 | if (bidi_it->nchars <= 0) | 2193 | if (bidi_it->nchars <= 0) |
| 2190 | emacs_abort (); | 2194 | emacs_abort (); |
| 2191 | do { | 2195 | do { |
| 2192 | ch = bidi_fetch_char (bpos += clen, cpos += nc, &disp_pos, &dpp, &bs, | 2196 | ch = bidi_fetch_char (cpos += nc, bpos += clen, &disp_pos, &dpp, &bs, |
| 2193 | fwp, &clen, &nc); | 2197 | fwp, &clen, &nc); |
| 2194 | if (ch == '\n' || ch == BIDI_EOB) | 2198 | if (ch == '\n' || ch == BIDI_EOB) |
| 2195 | chtype = NEUTRAL_B; | 2199 | chtype = NEUTRAL_B; |
| @@ -2391,6 +2395,10 @@ bidi_move_to_visually_next (struct bidi_it *bidi_it) | |||
| 2391 | next_level = bidi_peek_at_next_level (bidi_it); | 2395 | next_level = bidi_peek_at_next_level (bidi_it); |
| 2392 | while (next_level != expected_next_level) | 2396 | while (next_level != expected_next_level) |
| 2393 | { | 2397 | { |
| 2398 | /* If next_level is -1, it means we have an unresolved level | ||
| 2399 | in the cache, which at this point should not happen. If | ||
| 2400 | it does, we will infloop. */ | ||
| 2401 | eassert (next_level >= 0); | ||
| 2394 | expected_next_level += incr; | 2402 | expected_next_level += incr; |
| 2395 | level_to_search += incr; | 2403 | level_to_search += incr; |
| 2396 | bidi_find_other_level_edge (bidi_it, level_to_search, !ascending); | 2404 | bidi_find_other_level_edge (bidi_it, level_to_search, !ascending); |