aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2024-10-22 13:03:02 +0800
committerGitHub <noreply@github.com>2024-10-22 13:03:02 +0800
commitca7855c5ba7025e512ffbbc060fcf928cc480c91 (patch)
treea502fab4ab227ec35397bbdbd17ceca6b14588ed
parent1b9dafa67ba98e360444832e1fddce1e96acc1d6 (diff)
downloadrneovim-ca7855c5ba7025e512ffbbc060fcf928cc480c91.tar.gz
rneovim-ca7855c5ba7025e512ffbbc060fcf928cc480c91.tar.bz2
rneovim-ca7855c5ba7025e512ffbbc060fcf928cc480c91.zip
vim-patch:9.1.0798: too many strlen() calls in cmdhist.c (#30895)
Problem: too many strlen() calls in cmdhist.c Solution: refactor code and remove strlen() calls (John Marriott) closes: vim/vim#15888 https://github.com/vim/vim/commit/8df07d0ca310a55e1540f7d234b536abee49abd4 Co-authored-by: John Marriott <basilisk@internode.on.net>
-rw-r--r--src/nvim/cmdhist.c47
-rw-r--r--src/nvim/cmdhist.h1
-rw-r--r--src/nvim/ex_cmds.c2
-rw-r--r--src/nvim/ex_getln.c2
-rw-r--r--src/nvim/shada.c3
5 files changed, 25 insertions, 30 deletions
diff --git a/src/nvim/cmdhist.c b/src/nvim/cmdhist.c
index 47a4ffba9e..fc3382f486 100644
--- a/src/nvim/cmdhist.c
+++ b/src/nvim/cmdhist.c
@@ -221,7 +221,7 @@ static int in_history(int type, const char *str, int move_to_front, int sep)
// well.
char *p = history[type][i].hisstr;
if (strcmp(str, p) == 0
- && (type != HIST_SEARCH || sep == p[strlen(p) + 1])) {
+ && (type != HIST_SEARCH || sep == p[history[type][i].hisstrlen + 1])) {
if (!move_to_front) {
return true;
}
@@ -239,6 +239,7 @@ static int in_history(int type, const char *str, int move_to_front, int sep)
AdditionalData *ad = history[type][i].additional_data;
char *const save_hisstr = history[type][i].hisstr;
+ const size_t save_hisstrlen = history[type][i].hisstrlen;
while (i != hisidx[type]) {
if (++i >= hislen) {
i = 0;
@@ -249,6 +250,7 @@ static int in_history(int type, const char *str, int move_to_front, int sep)
xfree(ad);
history[type][i].hisnum = ++hisnum[type];
history[type][i].hisstr = save_hisstr;
+ history[type][i].hisstrlen = save_hisstrlen;
history[type][i].timestamp = os_time();
history[type][i].additional_data = NULL;
return true;
@@ -339,6 +341,7 @@ void add_to_history(int histype, const char *new_entry, size_t new_entrylen, boo
hisptr->timestamp = os_time();
hisptr->additional_data = NULL;
hisptr->hisstr[new_entrylen + 1] = (char)sep;
+ hisptr->hisstrlen = new_entrylen;
hisptr->hisnum = ++hisnum[histype];
if (histype == HIST_SEARCH && in_map) {
@@ -400,19 +403,6 @@ static int calc_hist_idx(int histype, int num)
return -1;
}
-/// Get a history entry by its index.
-///
-/// @param histype may be one of the HIST_ values.
-static char *get_history_entry(int histype, int idx)
-{
- idx = calc_hist_idx(histype, idx);
- if (idx >= 0) {
- return history[histype][idx].hisstr;
- } else {
- return "";
- }
-}
-
/// Clear all entries in a history
///
/// @param[in] histype One of the HIST_ values.
@@ -575,10 +565,15 @@ void f_histget(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
if (argvars[1].v_type == VAR_UNKNOWN) {
idx = get_history_idx(type);
} else {
- idx = (int)tv_get_number_chk(&argvars[1], NULL);
+ idx = (int)tv_get_number_chk(&argvars[1], NULL); // -1 on type error
+ }
+ idx = calc_hist_idx(type, idx);
+ if (idx < 0) {
+ rettv->vval.v_string = xstrnsave("", 0);
+ } else {
+ rettv->vval.v_string = xstrnsave(history[type][idx].hisstr,
+ history[type][idx].hisstrlen);
}
- // -1 on type error
- rettv->vval.v_string = xstrdup(get_history_entry(type, idx));
}
rettv->v_type = VAR_STRING;
}
@@ -591,9 +586,10 @@ void f_histnr(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
? HIST_INVALID
: get_histtype(histname, strlen(histname), false);
if (i != HIST_INVALID) {
- i = get_history_idx(i);
+ rettv->vval.v_number = get_history_idx(i);
+ } else {
+ rettv->vval.v_number = HIST_INVALID;
}
- rettv->vval.v_number = i;
}
/// :history command - print a history
@@ -642,10 +638,8 @@ void ex_history(exarg_T *eap)
}
for (; !got_int && histype1 <= histype2; histype1++) {
- xstrlcpy(IObuff, "\n # ", IOSIZE);
assert(history_names[histype1] != NULL);
- xstrlcat(IObuff, history_names[histype1], IOSIZE);
- xstrlcat(IObuff, " history", IOSIZE);
+ vim_snprintf(IObuff, IOSIZE, "\n # %s history", history_names[histype1]);
msg_puts_title(IObuff);
int idx = hisidx[histype1];
histentry_T *hist = history[histype1];
@@ -666,13 +660,12 @@ void ex_history(exarg_T *eap)
&& hist[i].hisnum >= j && hist[i].hisnum <= k
&& !message_filtered(hist[i].hisstr)) {
msg_putchar('\n');
- snprintf(IObuff, IOSIZE, "%c%6d ", i == idx ? '>' : ' ',
- hist[i].hisnum);
+ int len = snprintf(IObuff, IOSIZE,
+ "%c%6d ", i == idx ? '>' : ' ', hist[i].hisnum);
if (vim_strsize(hist[i].hisstr) > Columns - 10) {
- trunc_string(hist[i].hisstr, IObuff + strlen(IObuff),
- Columns - 10, IOSIZE - (int)strlen(IObuff));
+ trunc_string(hist[i].hisstr, IObuff + len, Columns - 10, IOSIZE - len);
} else {
- xstrlcat(IObuff, hist[i].hisstr, IOSIZE);
+ xstrlcpy(IObuff + len, hist[i].hisstr, (size_t)(IOSIZE - len));
}
msg_outtrans(IObuff, 0);
}
diff --git a/src/nvim/cmdhist.h b/src/nvim/cmdhist.h
index 4df4b09e68..c933982593 100644
--- a/src/nvim/cmdhist.h
+++ b/src/nvim/cmdhist.h
@@ -23,6 +23,7 @@ enum { HIST_COUNT = HIST_DEBUG + 1, }; ///< Number of history tables
typedef struct {
int hisnum; ///< Entry identifier number.
char *hisstr; ///< Actual entry, separator char after the NUL.
+ size_t hisstrlen; ///< Length of hisstr (excluding the NUL).
Timestamp timestamp; ///< Time when entry was added.
AdditionalData *additional_data; ///< Additional entries from ShaDa file.
} histentry_T;
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index d48d25fc22..702dbeac27 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -4434,11 +4434,11 @@ void ex_global(exarg_T *eap)
delim = *cmd; // get the delimiter
cmd++; // skip delimiter if there is one
pat = cmd; // remember start of pattern
- patlen = strlen(pat);
cmd = skip_regexp_ex(cmd, delim, magic_isset(), &eap->arg, NULL, NULL);
if (cmd[0] == delim) { // end delimiter found
*cmd++ = NUL; // replace it with a NUL
}
+ patlen = strlen(pat);
}
char *used_pat;
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index b58a6b16f1..389e935557 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -1789,7 +1789,7 @@ static int command_line_browse_history(CommandLineState *s)
plen = s->lookforlen;
} else {
p = get_histentry(s->histype)[s->hiscnt].hisstr;
- plen = (int)strlen(p);
+ plen = (int)get_histentry(s->histype)[s->hiscnt].hisstrlen;
}
if (s->histype == HIST_SEARCH
diff --git a/src/nvim/shada.c b/src/nvim/shada.c
index 27671771ec..11fe291559 100644
--- a/src/nvim/shada.c
+++ b/src/nvim/shada.c
@@ -658,7 +658,7 @@ static const void *shada_hist_iter(const void *const iter, const uint8_t history
.histtype = history_type,
.string = hist_he.hisstr,
.sep = (char)(history_type == HIST_SEARCH
- ? hist_he.hisstr[strlen(hist_he.hisstr) + 1]
+ ? hist_he.hisstr[hist_he.hisstrlen + 1]
: 0),
}
},
@@ -784,6 +784,7 @@ static inline void hms_to_he_array(const HistoryMergerState *const hms_p,
hist->timestamp = cur_entry->data.timestamp;
hist->hisnum = (int)(hist - hist_array) + 1;
hist->hisstr = cur_entry->data.data.history_item.string;
+ hist->hisstrlen = strlen(cur_entry->data.data.history_item.string);
hist->additional_data = cur_entry->data.additional_data;
hist++;
})