/* Low-level bidirectional buffer/string-scanning functions for GNU Emacs.
- Copyright (C) 2000-2001, 2004-2005, 2009-2012
- Free Software Foundation, Inc.
+ Copyright (C) 2000-2001, 2004-2005, 2009-2013 Free Software
+ Foundation, Inc.
This file is part of GNU Emacs.
return STRING_CHAR (s);
}
-/* Fetch and return the character at BYTEPOS/CHARPOS. If that
+/* Fetch and return the character at CHARPOS/BYTEPOS. If that
character is covered by a display string, treat the entire run of
covered characters as a single character, either u+2029 or u+FFFC,
and return their combined length in CH_LEN and NCHARS. DISP_POS
string to iterate, or NULL if iterating over a buffer or a Lisp
string; in the latter case, STRING->lstring is the Lisp string. */
static int
-bidi_fetch_char (ptrdiff_t bytepos, ptrdiff_t charpos, ptrdiff_t *disp_pos,
+bidi_fetch_char (ptrdiff_t charpos, ptrdiff_t bytepos, ptrdiff_t *disp_pos,
int *disp_prop, struct bidi_string_data *string,
bool frame_window_p, ptrdiff_t *ch_len, ptrdiff_t *nchars)
{
display string? And what if a display string covering some
of the text over which we scan back includes
paragraph_start_re? */
- pos = find_next_newline_no_quit (pos - 1, -1);
- pos_byte = CHAR_TO_BYTE (pos);
+ DEC_BOTH (pos, pos_byte);
+ pos = find_newline_no_quit (pos, pos_byte, -1, &pos_byte);
}
if (n >= MAX_PARAGRAPH_SEARCH)
pos_byte = BEGV_BYTE;
bytepos = pstartbyte;
if (!string_p)
pos = BYTE_TO_CHAR (bytepos);
- ch = bidi_fetch_char (bytepos, pos, &disp_pos, &disp_prop,
+ ch = bidi_fetch_char (pos, bytepos, &disp_pos, &disp_prop,
&bidi_it->string,
bidi_it->frame_window_p, &ch_len, &nchars);
type = bidi_get_type (ch, NEUTRAL_DIR);
&& bidi_at_paragraph_end (pos, bytepos) >= -1)
break;
/* Fetch next character and advance to get past it. */
- ch = bidi_fetch_char (bytepos, pos, &disp_pos,
+ ch = bidi_fetch_char (pos, bytepos, &disp_pos,
&disp_prop, &bidi_it->string,
bidi_it->frame_window_p, &ch_len, &nchars);
pos += nchars;
/* FXIME: What if p is covered by a display
string? See also a FIXME inside
bidi_find_paragraph_start. */
- p--;
- pbyte = CHAR_TO_BYTE (p);
+ DEC_BOTH (p, pbyte);
prevpbyte = bidi_find_paragraph_start (p, pbyte);
}
pstartbyte = prevpbyte;
: bidi_it->string.s);
if (bidi_it->charpos < 0)
- bidi_it->charpos = 0;
- bidi_it->bytepos = bidi_count_bytes (p, 0, 0, bidi_it->charpos,
- bidi_it->string.unibyte);
+ bidi_it->charpos = bidi_it->bytepos = 0;
+ eassert (bidi_it->bytepos == bidi_count_bytes (p, 0, 0,
+ bidi_it->charpos,
+ bidi_it->string.unibyte));
}
else
{
if (bidi_it->charpos < BEGV)
- bidi_it->charpos = BEGV;
- bidi_it->bytepos = CHAR_TO_BYTE (bidi_it->charpos);
+ {
+ bidi_it->charpos = BEGV;
+ bidi_it->bytepos = BEGV_BYTE;
+ }
+ eassert (bidi_it->bytepos == CHAR_TO_BYTE (bidi_it->charpos));
}
}
/* Don't move at end of buffer/string. */
/* Fetch the character at BYTEPOS. If it is covered by a
display string, treat the entire run of covered characters as
a single character u+FFFC. */
- curchar = bidi_fetch_char (bidi_it->bytepos, bidi_it->charpos,
+ curchar = bidi_fetch_char (bidi_it->charpos, bidi_it->bytepos,
&bidi_it->disp_pos, &bidi_it->disp_prop,
&bidi_it->string, bidi_it->frame_window_p,
&bidi_it->ch_len, &bidi_it->nchars);
next_type = STRONG_R;
break;
case WEAK_BN:
+ case NEUTRAL_ON: /* W6/Retaining */
if (!bidi_explicit_dir_char (bidi_it->ch))
emacs_abort (); /* can't happen: BNs are skipped */
/* FALLTHROUGH */
if (bidi_it->nchars <= 0)
emacs_abort ();
do {
- ch = bidi_fetch_char (bpos += clen, cpos += nc, &disp_pos, &dpp, &bs,
+ ch = bidi_fetch_char (cpos += nc, bpos += clen, &disp_pos, &dpp, &bs,
fwp, &clen, &nc);
if (ch == '\n' || ch == BIDI_EOB)
chtype = NEUTRAL_B;
next_level = bidi_peek_at_next_level (bidi_it);
while (next_level != expected_next_level)
{
+ /* If next_level is -1, it means we have an unresolved level
+ in the cache, which at this point should not happen. If
+ it does, we will infloop. */
+ eassert (next_level >= 0);
expected_next_level += incr;
level_to_search += incr;
bidi_find_other_level_edge (bidi_it, level_to_search, !ascending);