mirror of
https://github.com/neovim/neovim.git
synced 2026-03-31 04:42:03 +00:00
vim-patch:partial:9.2.0068: Inefficient use of list_append_string() (#38083)
Problem: Inefficient use of list_append_string()
Solution: Pass string length to list_append_string() where it is known
(John Marriott).
closes: vim/vim#19491
455d62e38a
N/A patches:
vim-patch:9.2.0063: memory leak in type_name_list_or_dict()
vim-patch:9.2.0065: memory leak in invoke_sync_listeners()
vim-patch:9.2.0066: memory leak in build_drop_cmd()
vim-patch:9.2.0067: memory leak in dict_extend_func()
Co-authored-by: John Marriott <basilisk@internode.on.net>
This commit is contained in:
@@ -209,7 +209,7 @@ void set_clipboard(int name, yankreg_T *reg)
|
||||
list_T *const lines = tv_list_alloc((ptrdiff_t)reg->y_size + (reg->y_type != kMTCharWise));
|
||||
|
||||
for (size_t i = 0; i < reg->y_size; i++) {
|
||||
tv_list_append_string(lines, reg->y_array[i].data, -1);
|
||||
tv_list_append_string(lines, reg->y_array[i].data, (int)reg->y_array[i].size);
|
||||
}
|
||||
|
||||
char regtype;
|
||||
|
||||
@@ -611,12 +611,16 @@ static void get_buffer_lines(buf_T *buf, linenr_T start, linenr_T end, bool retl
|
||||
}
|
||||
tv_list_alloc_ret(rettv, end - start + 1);
|
||||
while (start <= end) {
|
||||
tv_list_append_string(rettv->vval.v_list, ml_get_buf(buf, start++), -1);
|
||||
tv_list_append_string(rettv->vval.v_list,
|
||||
ml_get_buf(buf, start), (int)ml_get_buf_len(buf, start));
|
||||
start++;
|
||||
}
|
||||
} else {
|
||||
rettv->v_type = VAR_STRING;
|
||||
rettv->vval.v_string = ((start >= 1 && start <= buf->b_ml.ml_line_count)
|
||||
? xstrdup(ml_get_buf(buf, start)) : NULL);
|
||||
rettv->vval.v_string =
|
||||
start >= 1 && start <= buf->b_ml.ml_line_count
|
||||
? xstrnsave(ml_get_buf(buf, start), (size_t)ml_get_buf_len(buf, start))
|
||||
: NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2161,17 +2161,19 @@ static void f_getpos(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
}
|
||||
|
||||
/// Convert from block_def to string
|
||||
static char *block_def2str(struct block_def *bd)
|
||||
static String block_def2str(struct block_def *bd)
|
||||
{
|
||||
size_t size = (size_t)bd->startspaces + (size_t)bd->endspaces + (size_t)bd->textlen;
|
||||
char *ret = xmalloc(size + 1);
|
||||
char *p = ret;
|
||||
memset(p, ' ', (size_t)bd->startspaces);
|
||||
p += bd->startspaces;
|
||||
memmove(p, bd->textstart, (size_t)bd->textlen);
|
||||
p += bd->textlen;
|
||||
memset(p, ' ', (size_t)bd->endspaces);
|
||||
*(p + bd->endspaces) = NUL;
|
||||
String ret = { .data = xmalloc(size + 1) };
|
||||
|
||||
memset(ret.data, ' ', (size_t)bd->startspaces);
|
||||
ret.size += (size_t)bd->startspaces;
|
||||
memmove(ret.data + ret.size, bd->textstart, (size_t)bd->textlen);
|
||||
ret.size += (size_t)bd->textlen;
|
||||
memset(ret.data + ret.size, ' ', (size_t)bd->endspaces);
|
||||
ret.size += (size_t)bd->endspaces;
|
||||
ret.data[ret.size] = NUL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -2326,24 +2328,22 @@ static void f_getregion(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
}
|
||||
|
||||
for (linenr_T lnum = p1.lnum; lnum <= p2.lnum; lnum++) {
|
||||
char *akt = NULL;
|
||||
String akt = STRING_INIT;
|
||||
|
||||
if (region_type == kMTLineWise) {
|
||||
akt = xstrdup(ml_get(lnum));
|
||||
} else if (region_type == kMTBlockWise) {
|
||||
if (region_type == kMTBlockWise) {
|
||||
struct block_def bd;
|
||||
block_prep(&oa, &bd, lnum, false);
|
||||
akt = block_def2str(&bd);
|
||||
} else if (p1.lnum < lnum && lnum < p2.lnum) {
|
||||
akt = xstrdup(ml_get(lnum));
|
||||
} else if (region_type == kMTLineWise || (p1.lnum < lnum && lnum < p2.lnum)) {
|
||||
akt = cbuf_to_string(ml_get(lnum), (size_t)ml_get_len(lnum));
|
||||
} else {
|
||||
struct block_def bd;
|
||||
charwise_block_prep(p1, p2, &bd, lnum, inclusive);
|
||||
akt = block_def2str(&bd);
|
||||
}
|
||||
|
||||
assert(akt != NULL);
|
||||
tv_list_append_allocated_string(rettv->vval.v_list, akt);
|
||||
assert(akt.data != NULL);
|
||||
tv_list_append_allocated_string(rettv->vval.v_list, akt.data);
|
||||
}
|
||||
|
||||
// getregionpos() may change curbuf and virtual_op
|
||||
@@ -6949,12 +6949,18 @@ static void f_spellbadword(typval_T *argvars, typval_T *rettv, EvalFuncData fptr
|
||||
assert(len <= INT_MAX);
|
||||
tv_list_alloc_ret(rettv, 2);
|
||||
tv_list_append_string(rettv->vval.v_list, word, (ssize_t)len);
|
||||
tv_list_append_string(rettv->vval.v_list,
|
||||
(attr == HLF_SPB
|
||||
? "bad" : (attr == HLF_SPR
|
||||
? "rare" : (attr == HLF_SPL
|
||||
? "local" : (attr == HLF_SPC
|
||||
? "caps" : NULL)))), -1);
|
||||
switch (attr) {
|
||||
case HLF_SPB:
|
||||
tv_list_append_string(rettv->vval.v_list, S_LEN("bad")); break;
|
||||
case HLF_SPR:
|
||||
tv_list_append_string(rettv->vval.v_list, S_LEN("rare")); break;
|
||||
case HLF_SPL:
|
||||
tv_list_append_string(rettv->vval.v_list, S_LEN("local")); break;
|
||||
case HLF_SPC:
|
||||
tv_list_append_string(rettv->vval.v_list, S_LEN("caps")); break;
|
||||
default:
|
||||
tv_list_append_string(rettv->vval.v_list, NULL, -1); break;
|
||||
}
|
||||
}
|
||||
|
||||
/// "spellsuggest()" function
|
||||
|
||||
@@ -238,11 +238,15 @@ static void get_framelayout(const frame_T *fr, list_T *l, bool outer)
|
||||
|
||||
if (fr->fr_layout == FR_LEAF) {
|
||||
if (fr->fr_win != NULL) {
|
||||
tv_list_append_string(fr_list, "leaf", -1);
|
||||
tv_list_append_string(fr_list, S_LEN("leaf"));
|
||||
tv_list_append_number(fr_list, fr->fr_win->handle);
|
||||
}
|
||||
} else {
|
||||
tv_list_append_string(fr_list, fr->fr_layout == FR_ROW ? "row" : "col", -1);
|
||||
if (fr->fr_layout == FR_ROW) {
|
||||
tv_list_append_string(fr_list, S_LEN("row"));
|
||||
} else {
|
||||
tv_list_append_string(fr_list, S_LEN("col"));
|
||||
}
|
||||
|
||||
list_T *const win_list = tv_list_alloc(kListLenUnknown);
|
||||
tv_list_append_list(fr_list, win_list);
|
||||
|
||||
@@ -1215,7 +1215,7 @@ void do_autocmd_textyankpost(oparg_T *oap, yankreg_T *reg)
|
||||
// The yanked text contents.
|
||||
list_T *const list = tv_list_alloc((ptrdiff_t)reg->y_size);
|
||||
for (size_t i = 0; i < reg->y_size; i++) {
|
||||
tv_list_append_string(list, reg->y_array[i].data, -1);
|
||||
tv_list_append_string(list, reg->y_array[i].data, (int)reg->y_array[i].size);
|
||||
}
|
||||
tv_list_set_lock(list, VAR_FIXED);
|
||||
tv_dict_add_list(dict, S_LEN("regcontents"), list);
|
||||
@@ -2344,7 +2344,7 @@ void *get_reg_contents(int regname, int flags)
|
||||
if (flags & kGRegList) {
|
||||
list_T *const list = tv_list_alloc((ptrdiff_t)reg->y_size);
|
||||
for (size_t i = 0; i < reg->y_size; i++) {
|
||||
tv_list_append_string(list, reg->y_array[i].data, -1);
|
||||
tv_list_append_string(list, reg->y_array[i].data, (int)reg->y_array[i].size);
|
||||
}
|
||||
|
||||
return list;
|
||||
|
||||
Reference in New Issue
Block a user