diff options
author | zeertzjq <zeertzjq@outlook.com> | 2024-10-22 13:03:02 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-10-22 13:03:02 +0800 |
commit | ca7855c5ba7025e512ffbbc060fcf928cc480c91 (patch) | |
tree | a502fab4ab227ec35397bbdbd17ceca6b14588ed | |
parent | 1b9dafa67ba98e360444832e1fddce1e96acc1d6 (diff) | |
download | rneovim-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.c | 47 | ||||
-rw-r--r-- | src/nvim/cmdhist.h | 1 | ||||
-rw-r--r-- | src/nvim/ex_cmds.c | 2 | ||||
-rw-r--r-- | src/nvim/ex_getln.c | 2 | ||||
-rw-r--r-- | src/nvim/shada.c | 3 |
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++; }) |