patch 9.2.0031: Inefficient use of ga_concat()

Problem:  Inefficient use of ga_concat()
Solution: Use ga_concat_len() when the length is already known to avoid
          use of strlen() (John Marriott).

closes: #19422

Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
Signed-off-by: John Marriott <basilisk@internode.on.net>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
John Marriott
2026-02-19 17:25:27 +00:00
committed by Christian Brabandt
parent a04ae0210b
commit ed202035b1
6 changed files with 181 additions and 139 deletions
+31 -28
View File
@@ -674,12 +674,16 @@ build_drop_cmd(
int i;
char_u *inicmd = NULL;
char_u *p;
char_u *cdp;
string_T cdp;
char_u *cwd;
// reset wildignore temporarily
const char *wig[] =
{ "<CR><C-\\><C-N>:let g:_wig=&wig|set wig=",
"<C-\\><C-N>:let &wig=g:_wig|unlet g:_wig<CR>"};
# define STRING_INIT(s) \
{(char_u *)(s), STRLEN_LITERAL(s)}
const string_T wig[] = {
STRING_INIT("<CR><C-\\><C-N>:let g:_wig=&wig|set wig="),
STRING_INIT("<C-\\><C-N>:let &wig=g:_wig|unlet g:_wig<CR>")
};
# undef STRING_INIT
if (filec > 0 && filev[0][0] == '+')
{
@@ -700,7 +704,7 @@ build_drop_cmd(
vim_free(cwd);
return NULL;
}
cdp = vim_strsave_escaped_ext(cwd,
cdp.string = vim_strsave_escaped_ext(cwd,
# ifdef BACKSLASH_IN_FILENAME
(char_u *)"", // rem_backslash() will tell what chars to escape
# else
@@ -708,20 +712,20 @@ build_drop_cmd(
# endif
'\\', TRUE);
vim_free(cwd);
if (cdp == NULL)
if (cdp.string == NULL)
return NULL;
cdp.length = STRLEN(cdp.string);
ga_init2(&ga, 1, 100);
ga_concat(&ga, (char_u *)"<C-\\><C-N>:cd ");
ga_concat(&ga, cdp);
GA_CONCAT_LITERAL(&ga, "<C-\\><C-N>:cd ");
ga_concat_len(&ga, cdp.string, cdp.length);
// reset wildignorecase temporarily
ga_concat(&ga, (char_u *)wig[0]);
ga_concat_len(&ga, wig[0].string, wig[0].length);
// Call inputsave() so that a prompt for an encryption key works.
ga_concat(&ga, (char_u *)
"<CR><C-\\><C-N>:if exists('*inputsave')|call inputsave()|endif|");
GA_CONCAT_LITERAL(&ga, "<CR><C-\\><C-N>:if exists('*inputsave')|call inputsave()|endif|");
if (tabs)
ga_concat(&ga, (char_u *)"tab ");
ga_concat(&ga, (char_u *)"drop");
GA_CONCAT_LITERAL(&ga, "tab ");
GA_CONCAT_LITERAL(&ga, "drop");
for (i = 0; i < filec; i++)
{
// On Unix the shell has already expanded the wildcards, don't want to
@@ -739,16 +743,15 @@ build_drop_cmd(
vim_free(ga.ga_data);
return NULL;
}
ga_concat(&ga, (char_u *)" ");
GA_CONCAT_LITERAL(&ga, " ");
ga_concat(&ga, p);
vim_free(p);
}
ga_concat(&ga, (char_u *)
"|if exists('*inputrestore')|call inputrestore()|endif<CR>");
GA_CONCAT_LITERAL(&ga, "|if exists('*inputrestore')|call inputrestore()|endif<CR>");
// The :drop commands goes to Insert mode when 'insertmode' is set, use
// CTRL-\ CTRL-N again.
ga_concat(&ga, (char_u *)"<C-\\><C-N>");
GA_CONCAT_LITERAL(&ga, "<C-\\><C-N>");
// Switch back to the correct current directory (prior to temporary path
// switch) unless 'autochdir' is set, in which case it will already be
@@ -761,34 +764,34 @@ build_drop_cmd(
// cd -
// endif
// endif
ga_concat(&ga, (char_u *)":if !exists('+acd')||!&acd|if haslocaldir()|");
GA_CONCAT_LITERAL(&ga, ":if !exists('+acd')||!&acd|if haslocaldir()|");
# ifdef MSWIN
// in case :set shellslash is set, need to normalize the directory separators
// '/' is not valid in a filename so replacing '/' by '\\' should be safe
ga_concat(&ga, (char_u *)"cd -|lcd -|elseif getcwd()->tr('/','\\') ==# '");
GA_CONCAT_LITERAL(&ga, "cd -|lcd -|elseif getcwd()->tr('/','\\') ==# '");
# else
ga_concat(&ga, (char_u *)"cd -|lcd -|elseif getcwd() ==# '");
GA_CONCAT_LITERAL(&ga, "cd -|lcd -|elseif getcwd() ==# '");
# endif
ga_concat(&ga, cdp);
ga_concat(&ga, (char_u *)"'|cd -|endif|endif<CR>");
vim_free(cdp);
ga_concat_len(&ga, cdp.string, cdp.length);
GA_CONCAT_LITERAL(&ga, "'|cd -|endif|endif<CR>");
vim_free(cdp.string);
// reset wildignorecase
ga_concat(&ga, (char_u *)wig[1]);
ga_concat_len(&ga, wig[1].string, wig[1].length);
if (sendReply)
ga_concat(&ga, (char_u *)":call SetupRemoteReplies()<CR>");
ga_concat(&ga, (char_u *)":");
GA_CONCAT_LITERAL(&ga, ":call SetupRemoteReplies()<CR>");
GA_CONCAT_LITERAL(&ga, ":");
if (inicmd != NULL)
{
// Can't use <CR> after "inicmd", because a "startinsert" would cause
// the following commands to be inserted as text. Use a "|",
// hopefully "inicmd" does allow this...
ga_concat(&ga, inicmd);
ga_concat(&ga, (char_u *)"|");
GA_CONCAT_LITERAL(&ga, "|");
}
// Bring the window to the foreground, goto Insert mode when 'im' set and
// clear command line.
ga_concat(&ga, (char_u *)"cal foreground()|if &im|star|en|redr|f<CR>");
GA_CONCAT_LITERAL(&ga, "cal foreground()|if &im|star|en|redr|f<CR>");
ga_append(&ga, NUL);
return ga.ga_data;
}
+51 -34
View File
@@ -96,6 +96,7 @@ json_encode_lsp_msg(typval_T *val)
{
garray_T ga;
garray_T lspga;
size_t IObufflen;
ga_init2(&ga, 1, 4000);
if (json_encode_gap(&ga, val, 0) == FAIL)
@@ -104,10 +105,10 @@ json_encode_lsp_msg(typval_T *val)
ga_init2(&lspga, 1, 4000);
// Header according to LSP specification.
vim_snprintf((char *)IObuff, IOSIZE,
IObufflen = vim_snprintf_safelen((char *)IObuff, IOSIZE,
"Content-Length: %u\r\n\r\n",
ga.ga_len - 1);
ga_concat(&lspga, IObuff);
ga_concat_len(&lspga, IObuff, IObufflen);
ga_concat_len(&lspga, ga.ga_data, ga.ga_len);
ga_clear(&ga);
return lspga.ga_data;
@@ -145,7 +146,7 @@ write_string(garray_T *gap, char_u *str)
if (res == NULL)
{
ga_concat(gap, (char_u *)"\"\"");
GA_CONCAT_LITERAL(gap, "\"\"");
return;
}
@@ -199,16 +200,21 @@ write_string(garray_T *gap, char_u *str)
ga_append(gap, c);
break;
default:
vim_snprintf((char *)numbuf, NUMBUFLEN, "\\u%04lx",
(long)c);
ga_concat(gap, numbuf);
{
size_t numbuflen;
numbuflen = vim_snprintf_safelen((char *)numbuf,
sizeof(numbuf), "\\u%04lx", (long)c);
ga_concat_len(gap, numbuf, numbuflen);
}
}
res += 1;
}
else
{
int l = utf_ptr2len(res);
int l = utf_ptr2len(res);
size_t numbuflen;
if (l > 1)
{
@@ -222,8 +228,9 @@ write_string(garray_T *gap, char_u *str)
ga_concat_len(gap, from, res - from);
from = res + 1;
numbuf[utf_char2bytes(0xFFFD, numbuf)] = NUL;
ga_concat(gap, numbuf);
numbuflen = utf_char2bytes(0xFFFD, numbuf);
numbuf[numbuflen] = NUL;
ga_concat_len(gap, numbuf, numbuflen);
res += l;
}
@@ -276,8 +283,8 @@ json_encode_item(garray_T *gap, typval_T *val, int copyID, int options)
case VAR_BOOL:
switch ((long)val->vval.v_number)
{
case VVAL_FALSE: ga_concat(gap, (char_u *)"false"); break;
case VVAL_TRUE: ga_concat(gap, (char_u *)"true"); break;
case VVAL_FALSE: GA_CONCAT_LITERAL(gap, "false"); break;
case VVAL_TRUE: GA_CONCAT_LITERAL(gap, "true"); break;
}
break;
@@ -289,14 +296,18 @@ json_encode_item(garray_T *gap, typval_T *val, int copyID, int options)
// empty item
break;
// FALLTHROUGH
case VVAL_NULL: ga_concat(gap, (char_u *)"null"); break;
case VVAL_NULL: GA_CONCAT_LITERAL(gap, "null"); break;
}
break;
case VAR_NUMBER:
vim_snprintf((char *)numbuf, NUMBUFLEN, "%lld",
(varnumber_T)val->vval.v_number);
ga_concat(gap, numbuf);
{
size_t numbuflen;
numbuflen = vim_snprintf_safelen((char *)numbuf, sizeof(numbuf),
"%lld", (varnumber_T)val->vval.v_number);
ga_concat_len(gap, numbuf, numbuflen);
}
break;
case VAR_STRING:
@@ -318,17 +329,19 @@ json_encode_item(garray_T *gap, typval_T *val, int copyID, int options)
case VAR_BLOB:
b = val->vval.v_blob;
if (b == NULL || b->bv_ga.ga_len == 0)
ga_concat(gap, (char_u *)"[]");
GA_CONCAT_LITERAL(gap, "[]");
else
{
ga_append(gap, '[');
for (i = 0; i < b->bv_ga.ga_len; i++)
{
size_t numbuflen;
if (i > 0)
ga_concat(gap, (char_u *)",");
vim_snprintf((char *)numbuf, NUMBUFLEN, "%d",
blob_get(b, i));
ga_concat(gap, numbuf);
GA_CONCAT_LITERAL(gap, ",");
numbuflen = vim_snprintf_safelen((char *)numbuf, sizeof(numbuf),
"%d", blob_get(b, i));
ga_concat_len(gap, numbuf, numbuflen);
}
ga_append(gap, ']');
}
@@ -337,11 +350,11 @@ json_encode_item(garray_T *gap, typval_T *val, int copyID, int options)
case VAR_LIST:
l = val->vval.v_list;
if (l == NULL)
ga_concat(gap, (char_u *)"[]");
GA_CONCAT_LITERAL(gap, "[]");
else
{
if (l->lv_copyID == copyID)
ga_concat(gap, (char_u *)"[]");
GA_CONCAT_LITERAL(gap, "[]");
else
{
listitem_T *li;
@@ -373,11 +386,11 @@ json_encode_item(garray_T *gap, typval_T *val, int copyID, int options)
case VAR_TUPLE:
tuple = val->vval.v_tuple;
if (tuple == NULL)
ga_concat(gap, (char_u *)"[]");
GA_CONCAT_LITERAL(gap, "[]");
else
{
if (tuple->tv_copyID == copyID)
ga_concat(gap, (char_u *)"[]");
GA_CONCAT_LITERAL(gap, "[]");
else
{
int len = TUPLE_LEN(tuple);
@@ -409,11 +422,11 @@ json_encode_item(garray_T *gap, typval_T *val, int copyID, int options)
case VAR_DICT:
d = val->vval.v_dict;
if (d == NULL)
ga_concat(gap, (char_u *)"{}");
GA_CONCAT_LITERAL(gap, "{}");
else
{
if (d->dv_copyID == copyID)
ga_concat(gap, (char_u *)"{}");
GA_CONCAT_LITERAL(gap, "{}");
else
{
int first = TRUE;
@@ -451,20 +464,22 @@ json_encode_item(garray_T *gap, typval_T *val, int copyID, int options)
case VAR_FLOAT:
#if defined(HAVE_MATH_H)
if (isnan(val->vval.v_float))
ga_concat(gap, (char_u *)"NaN");
GA_CONCAT_LITERAL(gap, "NaN");
else if (isinf(val->vval.v_float))
{
if (val->vval.v_float < 0.0)
ga_concat(gap, (char_u *)"-Infinity");
GA_CONCAT_LITERAL(gap, "-Infinity");
else
ga_concat(gap, (char_u *)"Infinity");
GA_CONCAT_LITERAL(gap, "Infinity");
}
else
#endif
{
vim_snprintf((char *)numbuf, NUMBUFLEN, "%g",
val->vval.v_float);
ga_concat(gap, numbuf);
size_t numbuflen;
numbuflen = vim_snprintf_safelen((char *)numbuf, sizeof(numbuf),
"%g", val->vval.v_float);
ga_concat_len(gap, numbuf, numbuflen);
}
break;
case VAR_UNKNOWN:
@@ -612,9 +627,11 @@ json_decode_string(js_read_T *reader, typval_T *res, int quote)
if (res != NULL)
{
char_u buf[NUMBUFLEN];
size_t buflen;
buf[utf_char2bytes((int)nr, buf)] = NUL;
ga_concat(&ga, buf);
buflen = utf_char2bytes((int)nr, buf);
buf[buflen] = NUL;
ga_concat_len(&ga, buf, buflen);
}
break;
default:
+23 -17
View File
@@ -1466,7 +1466,7 @@ list2string(typval_T *tv, int copyID, int restore_copyID)
}
typedef struct join_S {
char_u *s;
string_T s;
char_u *tofree;
} join_T;
@@ -1482,37 +1482,39 @@ list_join_inner(
{
int i;
join_T *p;
int len;
int sumlen = 0;
int first = TRUE;
char_u *tofree;
char_u numbuf[NUMBUFLEN];
listitem_T *item;
char_u *s;
string_T s;
size_t seplen;
// Stringify each item in the list.
CHECK_LIST_MATERIALIZE(l);
for (item = l->lv_first; item != NULL && !got_int; item = item->li_next)
{
s = echo_string_core(&item->li_tv, &tofree, numbuf, copyID,
s.string = echo_string_core(&item->li_tv, &tofree, numbuf, copyID,
echo_style, restore_copyID, !echo_style);
if (s == NULL)
if (s.string == NULL)
return FAIL;
len = (int)STRLEN(s);
sumlen += len;
s.length = STRLEN(s.string);
sumlen += (int)s.length;
(void)ga_grow(join_gap, 1);
p = ((join_T *)join_gap->ga_data) + (join_gap->ga_len++);
if (tofree != NULL || s != numbuf)
if (tofree != NULL || s.string != numbuf)
{
p->s = s;
p->s.string = s.string;
p->s.length = s.length;
p->tofree = tofree;
}
else
{
p->s = vim_strnsave(s, len);
p->tofree = p->s;
p->s.string = vim_strnsave(s.string, s.length);
p->s.length = s.length;
p->tofree = p->s.string;
}
line_breakcheck();
@@ -1522,8 +1524,9 @@ list_join_inner(
// Allocate result buffer with its total size, avoid re-allocation and
// multiple copy operations. Add 2 for a tailing ']' and NUL.
seplen = STRLEN(sep);
if (join_gap->ga_len >= 2)
sumlen += (int)STRLEN(sep) * (join_gap->ga_len - 1);
sumlen += (int)seplen * (join_gap->ga_len - 1);
if (ga_grow(gap, sumlen + 2) == FAIL)
return FAIL;
@@ -1532,11 +1535,11 @@ list_join_inner(
if (first)
first = FALSE;
else
ga_concat(gap, sep);
ga_concat_len(gap, sep, seplen);
p = ((join_T *)join_gap->ga_data) + i;
if (p->s != NULL)
ga_concat(gap, p->s);
if (p->s.string != NULL)
ga_concat_len(gap, p->s.string, p->s.length);
line_breakcheck();
}
@@ -1836,8 +1839,11 @@ f_list2str(typval_T *argvars, typval_T *rettv)
FOR_ALL_LIST_ITEMS(l, li)
{
buf[(*char2bytes)(tv_get_number(&li->li_tv), buf)] = NUL;
ga_concat(&ga, buf);
size_t buflen;
buflen = (size_t)(*char2bytes)(tv_get_number(&li->li_tv), buf);
buf[buflen] = NUL;
ga_concat_len(&ga, buf, buflen);
}
ga_append(&ga, NUL);
}
+1
View File
@@ -424,6 +424,7 @@
#define GA_GROW_FAILS(gap, n) unlikely((((gap)->ga_maxlen - (gap)->ga_len < (n)) ? ga_grow_inner((gap), (n)) : OK) == FAIL)
// Inlined version of ga_grow() with optimized condition that it succeeds.
#define GA_GROW_OK(gap, n) likely((((gap)->ga_maxlen - (gap)->ga_len < (n)) ? ga_grow_inner((gap), (n)) : OK) == OK)
#define GA_CONCAT_LITERAL(gap, s) ga_concat_len((gap), (char_u *)(s), STRLEN_LITERAL(s))
#ifndef MIN
# define MIN(a, b) ((a) < (b) ? (a) : (b))
+73 -60
View File
@@ -21,7 +21,6 @@
static void
prepare_assert_error(garray_T *gap)
{
char buf[NUMBUFLEN];
char_u *sname = estack_sfile(ESTACK_NONE);
ga_init2(gap, 1, 100);
@@ -29,15 +28,18 @@ prepare_assert_error(garray_T *gap)
{
ga_concat(gap, sname);
if (SOURCING_LNUM > 0)
ga_concat(gap, (char_u *)" ");
GA_CONCAT_LITERAL(gap, " ");
}
if (SOURCING_LNUM > 0)
{
sprintf(buf, "line %ld", (long)SOURCING_LNUM);
ga_concat(gap, (char_u *)buf);
char buf[NUMBUFLEN];
size_t buflen;
buflen = vim_snprintf_safelen(buf, sizeof(buf), "line %ld", (long)SOURCING_LNUM);
ga_concat_len(gap, (char_u *)buf, buflen);
}
if (sname != NULL || SOURCING_LNUM > 0)
ga_concat(gap, (char_u *)": ");
GA_CONCAT_LITERAL(gap, ": ");
vim_free(sname);
}
@@ -54,28 +56,31 @@ ga_concat_esc(garray_T *gap, char_u *p, int clen)
{
mch_memmove(buf, p, clen);
buf[clen] = NUL;
ga_concat(gap, buf);
ga_concat_len(gap, buf, clen);
return;
}
switch (*p)
{
case BS: ga_concat(gap, (char_u *)"\\b"); break;
case ESC: ga_concat(gap, (char_u *)"\\e"); break;
case FF: ga_concat(gap, (char_u *)"\\f"); break;
case NL: ga_concat(gap, (char_u *)"\\n"); break;
case TAB: ga_concat(gap, (char_u *)"\\t"); break;
case CAR: ga_concat(gap, (char_u *)"\\r"); break;
case '\\': ga_concat(gap, (char_u *)"\\\\"); break;
case BS: GA_CONCAT_LITERAL(gap, "\\b"); break;
case ESC: GA_CONCAT_LITERAL(gap, "\\e"); break;
case FF: GA_CONCAT_LITERAL(gap, "\\f"); break;
case NL: GA_CONCAT_LITERAL(gap, "\\n"); break;
case TAB: GA_CONCAT_LITERAL(gap, "\\t"); break;
case CAR: GA_CONCAT_LITERAL(gap, "\\r"); break;
case '\\': GA_CONCAT_LITERAL(gap, "\\\\"); break;
default:
if (*p < ' ' || *p == 0x7f)
{
vim_snprintf((char *)buf, NUMBUFLEN, "\\x%02x", *p);
ga_concat(gap, buf);
}
else
ga_append(gap, *p);
break;
if (*p < ' ' || *p == 0x7f)
{
size_t buflen;
buflen = vim_snprintf_safelen((char *)buf, sizeof(buf),
"\\x%02x", *p);
ga_concat_len(gap, buf, buflen);
}
else
ga_append(gap, *p);
break;
}
}
@@ -91,11 +96,12 @@ ga_concat_shorten_esc(garray_T *gap, char_u *str)
int c;
int clen;
char_u buf[NUMBUFLEN];
size_t buflen;
int same_len;
if (str == NULL)
{
ga_concat(gap, (char_u *)"NULL");
GA_CONCAT_LITERAL(gap, "NULL");
return;
}
@@ -112,12 +118,13 @@ ga_concat_shorten_esc(garray_T *gap, char_u *str)
}
if (same_len > 20)
{
ga_concat(gap, (char_u *)"\\[");
GA_CONCAT_LITERAL(gap, "\\[");
ga_concat_esc(gap, p, clen);
ga_concat(gap, (char_u *)" occurs ");
vim_snprintf((char *)buf, NUMBUFLEN, "%d", same_len);
ga_concat(gap, buf);
ga_concat(gap, (char_u *)" times]");
GA_CONCAT_LITERAL(gap, " occurs ");
buflen = vim_snprintf_safelen((char *)buf, sizeof(buf),
"%d", same_len);
ga_concat_len(gap, buf, buflen);
GA_CONCAT_LITERAL(gap, " times]");
p = s;
}
else
@@ -154,15 +161,15 @@ fill_assert_error(
{
ga_concat(gap, echo_string(opt_msg_tv, &tofree, numbuf, 0));
vim_free(tofree);
ga_concat(gap, (char_u *)": ");
GA_CONCAT_LITERAL(gap, ": ");
}
if (atype == ASSERT_MATCH || atype == ASSERT_NOTMATCH)
ga_concat(gap, (char_u *)"Pattern ");
GA_CONCAT_LITERAL(gap, "Pattern ");
else if (atype == ASSERT_NOTEQUAL)
ga_concat(gap, (char_u *)"Expected not equal to ");
GA_CONCAT_LITERAL(gap, "Expected not equal to ");
else
ga_concat(gap, (char_u *)"Expected ");
GA_CONCAT_LITERAL(gap, "Expected ");
if (exp_str == NULL)
{
// When comparing dictionaries, drop the items that are equal, so that
@@ -227,29 +234,30 @@ fill_assert_error(
else
{
if (atype == ASSERT_FAILS)
ga_concat(gap, (char_u *)"'");
GA_CONCAT_LITERAL(gap, "'");
ga_concat_shorten_esc(gap, exp_str);
if (atype == ASSERT_FAILS)
ga_concat(gap, (char_u *)"'");
GA_CONCAT_LITERAL(gap, "'");
}
if (atype != ASSERT_NOTEQUAL)
{
if (atype == ASSERT_MATCH)
ga_concat(gap, (char_u *)" does not match ");
GA_CONCAT_LITERAL(gap, " does not match ");
else if (atype == ASSERT_NOTMATCH)
ga_concat(gap, (char_u *)" does match ");
GA_CONCAT_LITERAL(gap, " does match ");
else
ga_concat(gap, (char_u *)" but got ");
GA_CONCAT_LITERAL(gap, " but got ");
ga_concat_shorten_esc(gap, tv2string(got_tv, &tofree, numbuf, 0));
vim_free(tofree);
if (omitted != 0)
{
char buf[100];
char buf[100];
size_t buflen;
vim_snprintf(buf, 100, " - %d equal item%s omitted",
omitted, omitted == 1 ? "" : "s");
ga_concat(gap, (char_u *)buf);
buflen = vim_snprintf_safelen(buf, sizeof(buf),
" - %d equal item%s omitted", omitted, omitted == 1 ? "" : "s");
ga_concat_len(gap, (char_u *)buf, buflen);
}
}
@@ -368,9 +376,9 @@ assert_beeps(typval_T *argvars, int no_beep)
{
prepare_assert_error(&ga);
if (no_beep)
ga_concat(&ga, (char_u *)"command did beep: ");
GA_CONCAT_LITERAL(&ga, "command did beep: ");
else
ga_concat(&ga, (char_u *)"command did not beep: ");
GA_CONCAT_LITERAL(&ga, "command did not beep: ");
ga_concat(&ga, cmd);
assert_error(&ga);
ga_clear(&ga);
@@ -427,16 +435,18 @@ assert_equalfile(typval_T *argvars)
char line1[200];
char line2[200];
int lineidx = 0;
size_t IObufflen;
if (fname1 == NULL || fname2 == NULL)
return 0;
IObuff[0] = NUL;
IObufflen = 0;
fd1 = mch_fopen((char *)fname1, READBIN);
if (fd1 == NULL)
{
vim_snprintf((char *)IObuff, IOSIZE, (char *)e_cant_read_file_str,
fname1);
IObufflen = vim_snprintf_safelen((char *)IObuff, IOSIZE,
(char *)e_cant_read_file_str, fname1);
}
else
{
@@ -444,8 +454,8 @@ assert_equalfile(typval_T *argvars)
if (fd2 == NULL)
{
fclose(fd1);
vim_snprintf((char *)IObuff, IOSIZE, (char *)e_cant_read_file_str,
fname2);
IObufflen = vim_snprintf_safelen((char *)IObuff, IOSIZE,
(char *)e_cant_read_file_str, fname2);
}
else
{
@@ -460,12 +470,16 @@ assert_equalfile(typval_T *argvars)
if (c1 == EOF)
{
if (c2 != EOF)
{
STRCPY(IObuff, "first file is shorter");
IObufflen = 21;
}
break;
}
else if (c2 == EOF)
{
STRCPY(IObuff, "second file is shorter");
IObufflen = 22;
break;
}
else
@@ -475,9 +489,8 @@ assert_equalfile(typval_T *argvars)
++lineidx;
if (c1 != c2)
{
vim_snprintf((char *)IObuff, IOSIZE,
"difference at byte %ld, line %ld",
count, linecount);
IObufflen = vim_snprintf_safelen((char *)IObuff, IOSIZE,
"difference at byte %ld, line %ld", count, linecount);
break;
}
}
@@ -499,7 +512,7 @@ assert_equalfile(typval_T *argvars)
}
}
if (IObuff[0] != NUL)
if (IObufflen > 0)
{
garray_T ga;
prepare_assert_error(&ga);
@@ -510,21 +523,21 @@ assert_equalfile(typval_T *argvars)
ga_concat(&ga, echo_string(&argvars[2], &tofree, numbuf, 0));
vim_free(tofree);
ga_concat(&ga, (char_u *)": ");
GA_CONCAT_LITERAL(&ga, ": ");
}
ga_concat(&ga, IObuff);
ga_concat_len(&ga, IObuff, IObufflen);
if (lineidx > 0)
{
line1[lineidx] = NUL;
line2[lineidx] = NUL;
ga_concat(&ga, (char_u *)" after \"");
ga_concat(&ga, (char_u *)line1);
GA_CONCAT_LITERAL(&ga, " after \"");
ga_concat_len(&ga, (char_u *)line1, lineidx);
if (STRCMP(line1, line2) != 0)
{
ga_concat(&ga, (char_u *)"\" vs \"");
ga_concat(&ga, (char_u *)line2);
GA_CONCAT_LITERAL(&ga, "\" vs \"");
ga_concat_len(&ga, (char_u *)line2, lineidx);
}
ga_concat(&ga, (char_u *)"\"");
GA_CONCAT_LITERAL(&ga, "\"");
}
assert_error(&ga);
ga_clear(&ga);
@@ -576,7 +589,7 @@ f_assert_exception(typval_T *argvars, typval_T *rettv)
if (*get_vim_var_str(VV_EXCEPTION) == NUL)
{
prepare_assert_error(&ga);
ga_concat(&ga, (char_u *)"v:exception is not set");
GA_CONCAT_LITERAL(&ga, "v:exception is not set");
assert_error(&ga);
ga_clear(&ga);
rettv->vval.v_number = 1;
@@ -630,7 +643,7 @@ f_assert_fails(typval_T *argvars, typval_T *rettv)
if (called_emsg == called_emsg_before)
{
prepare_assert_error(&ga);
ga_concat(&ga, (char_u *)"command did not fail: ");
GA_CONCAT_LITERAL(&ga, "command did not fail: ");
assert_append_cmd_or_arg(&ga, argvars, cmd);
assert_error(&ga);
ga_clear(&ga);
@@ -749,7 +762,7 @@ f_assert_fails(typval_T *argvars, typval_T *rettv)
}
fill_assert_error(&ga, &argvars[2], expected_str,
&argvars[error_found_index], &actual_tv, ASSERT_FAILS);
ga_concat(&ga, (char_u *)": ");
GA_CONCAT_LITERAL(&ga, ": ");
assert_append_cmd_or_arg(&ga, argvars, cmd);
assert_error(&ga);
ga_clear(&ga);
+2
View File
@@ -734,6 +734,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
31,
/**/
30,
/**/