patch 9.0.0181: textprop test with line2byte() fails on MS-Windows

Problem:    Textprop test with line2byte() fails on MS-Windows.
Solution:   Fix updating chuncks in ml_delete_int().
This commit is contained in:
Bram Moolenaar
2022-08-09 21:37:55 +01:00
parent ef257e7bd1
commit e5a0e8c1d7
3 changed files with 33 additions and 30 deletions

View File

@ -3313,7 +3313,7 @@ ml_append_int(
(long)text_len (long)text_len
# else # else
(long)len (long)len
#endif # endif
, ML_CHNK_ADDLINE); , ML_CHNK_ADDLINE);
#endif #endif
@ -3667,7 +3667,7 @@ ml_delete_int(buf_T *buf, linenr_T lnum, int flags)
int ret = FAIL; int ret = FAIL;
#ifdef FEAT_PROP_POPUP #ifdef FEAT_PROP_POPUP
char_u *textprop_save = NULL; char_u *textprop_save = NULL;
int textprop_save_len = 0; long textprop_len = 0;
#endif #endif
if (lowest_marked && lowest_marked > lnum) if (lowest_marked && lowest_marked > lnum)
@ -3723,18 +3723,17 @@ ml_delete_int(buf_T *buf, linenr_T lnum, int flags)
netbeans_removed(buf, lnum, 0, line_size); netbeans_removed(buf, lnum, 0, line_size);
#endif #endif
#ifdef FEAT_PROP_POPUP #ifdef FEAT_PROP_POPUP
// If there are text properties, make a copy, so that we can update // If there are text properties compute their byte length.
// properties in preceding and following lines. // if needed make a copy, so that we can update properties in preceding and
if (buf->b_has_textprop && !(flags & (ML_DEL_UNDO | ML_DEL_NOPROP))) // following lines.
if (buf->b_has_textprop)
{ {
size_t textlen = STRLEN((char_u *)dp + line_start) + 1; size_t textlen = STRLEN((char_u *)dp + line_start) + 1;
if ((long)textlen < line_size) textprop_len = line_size - (long)textlen;
{ if (!(flags & (ML_DEL_UNDO | ML_DEL_NOPROP)) && textprop_len > 0)
textprop_save_len = line_size - (int)textlen;
textprop_save = vim_memsave((char_u *)dp + line_start + textlen, textprop_save = vim_memsave((char_u *)dp + line_start + textlen,
textprop_save_len); textprop_len);
}
} }
#endif #endif
@ -3820,9 +3819,9 @@ ml_delete_int(buf_T *buf, linenr_T lnum, int flags)
#ifdef FEAT_BYTEOFF #ifdef FEAT_BYTEOFF
ml_updatechunk(buf, lnum, line_size ml_updatechunk(buf, lnum, line_size
# ifdef FEAT_PROP_POPUP # ifdef FEAT_PROP_POPUP
- textprop_save_len - textprop_len
# endif # endif
, ML_CHNK_DELLINE); , ML_CHNK_DELLINE);
#endif #endif
ret = OK; ret = OK;
@ -3833,10 +3832,10 @@ theend:
// Adjust text properties in the line above and below. // Adjust text properties in the line above and below.
if (lnum > 1) if (lnum > 1)
adjust_text_props_for_delete(buf, lnum - 1, textprop_save, adjust_text_props_for_delete(buf, lnum - 1, textprop_save,
textprop_save_len, TRUE); (int)textprop_len, TRUE);
if (lnum <= buf->b_ml.ml_line_count) if (lnum <= buf->b_ml.ml_line_count)
adjust_text_props_for_delete(buf, lnum, textprop_save, adjust_text_props_for_delete(buf, lnum, textprop_save,
textprop_save_len, FALSE); (int)textprop_len, FALSE);
} }
vim_free(textprop_save); vim_free(textprop_save);
#endif #endif
@ -5684,7 +5683,8 @@ ml_updatechunk(
// the text prop info would also be counted. Go over the // the text prop info would also be counted. Go over the
// lines. // lines.
for (i = end_idx; i < idx; ++i) for (i = end_idx; i < idx; ++i)
size += (int)STRLEN((char_u *)dp + (dp->db_index[i] & DB_INDEX_MASK)) + 1; size += (int)STRLEN((char_u *)dp
+ (dp->db_index[i] & DB_INDEX_MASK)) + 1;
} }
else else
#endif #endif
@ -5693,7 +5693,8 @@ ml_updatechunk(
text_end = dp->db_txt_end; text_end = dp->db_txt_end;
else else
text_end = ((dp->db_index[idx - 1]) & DB_INDEX_MASK); text_end = ((dp->db_index[idx - 1]) & DB_INDEX_MASK);
size += text_end - ((dp->db_index[end_idx]) & DB_INDEX_MASK); size += text_end
- ((dp->db_index[end_idx]) & DB_INDEX_MASK);
} }
} }
buf->b_ml.ml_chunksize[curix].mlcs_numlines = linecnt; buf->b_ml.ml_chunksize[curix].mlcs_numlines = linecnt;
@ -5749,9 +5750,9 @@ ml_updatechunk(
{ {
curchnk->mlcs_numlines--; curchnk->mlcs_numlines--;
ml_upd_lastbuf = NULL; // Force recalc of curix & curline ml_upd_lastbuf = NULL; // Force recalc of curix & curline
if (curix < (buf->b_ml.ml_usedchunks - 1) if (curix < buf->b_ml.ml_usedchunks - 1
&& (curchnk->mlcs_numlines + curchnk[1].mlcs_numlines) && curchnk->mlcs_numlines + curchnk[1].mlcs_numlines
<= MLCS_MINL) <= MLCS_MINL)
{ {
curix++; curix++;
curchnk = buf->b_ml.ml_chunksize + curix; curchnk = buf->b_ml.ml_chunksize + curix;
@ -5764,8 +5765,8 @@ ml_updatechunk(
return; return;
} }
else if (curix == 0 || (curchnk->mlcs_numlines > 10 else if (curix == 0 || (curchnk->mlcs_numlines > 10
&& (curchnk->mlcs_numlines + curchnk[-1].mlcs_numlines) && curchnk->mlcs_numlines + curchnk[-1].mlcs_numlines
> MLCS_MINL)) > MLCS_MINL))
{ {
return; return;
} }
@ -5775,12 +5776,10 @@ ml_updatechunk(
curchnk[-1].mlcs_totalsize += curchnk->mlcs_totalsize; curchnk[-1].mlcs_totalsize += curchnk->mlcs_totalsize;
buf->b_ml.ml_usedchunks--; buf->b_ml.ml_usedchunks--;
if (curix < buf->b_ml.ml_usedchunks) if (curix < buf->b_ml.ml_usedchunks)
{
mch_memmove(buf->b_ml.ml_chunksize + curix, mch_memmove(buf->b_ml.ml_chunksize + curix,
buf->b_ml.ml_chunksize + curix + 1, buf->b_ml.ml_chunksize + curix + 1,
(buf->b_ml.ml_usedchunks - curix) * (buf->b_ml.ml_usedchunks - curix) *
sizeof(chunksize_T)); sizeof(chunksize_T));
}
return; return;
} }
ml_upd_lastbuf = buf; ml_upd_lastbuf = buf;

View File

@ -922,20 +922,22 @@ func Run_test_with_line2byte(add_props)
if a:add_props if a:add_props
call prop_type_add('textprop', #{highlight: 'Search'}) call prop_type_add('textprop', #{highlight: 'Search'})
endif endif
" Add a text prop to every fourth line and then change every fifth line so
" that it causes a data block split a few times.
for nr in range(1, 1000) for nr in range(1, 1000)
call setline(nr, 'some longer text here') call setline(nr, 'some longer text here')
if a:add_props && nr % 17 == 0 if a:add_props && nr % 4 == 0
call prop_add(nr, 13, #{type: 'textprop', length: 4}) call prop_add(nr, 13, #{type: 'textprop', length: 4})
endif endif
endfor endfor
call assert_equal(21935, line2byte(998)) let expected = 22 * 997 + 1
for nr in range(1, 1000, 7) call assert_equal(expected, line2byte(998))
for nr in range(1, 1000, 5)
exe nr .. "s/longer/much more/" exe nr .. "s/longer/much more/"
let expected += 3
call assert_equal(expected, line2byte(998), 'line ' .. nr)
endfor endfor
" FIXME: somehow this fails on MS-Windows
if !(a:add_props && has('win32'))
call assert_equal(22364, line2byte(998))
endif
if a:add_props if a:add_props
call prop_type_delete('textprop') call prop_type_delete('textprop')

View File

@ -735,6 +735,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
181,
/**/ /**/
180, 180,
/**/ /**/