mirror of
https://github.com/neovim/neovim.git
synced 2025-10-16 14:56:08 +00:00
vim-patch:9.1.0766: too many strlen() calls in ex_getln.c (#30715)
Problem: too many strlen() calls in ex_getln.c
Solution: refactor the code to reduce the number of strlen() calls
(John Marriott)
closes: vim/vim#15809
ccf8907570
Co-authored-by: John Marriott <basilisk@internode.on.net>
This commit is contained in:
@@ -125,6 +125,7 @@ typedef struct {
|
|||||||
bool gotesc; // true when <ESC> just typed
|
bool gotesc; // true when <ESC> just typed
|
||||||
int do_abbr; // when true check for abbr.
|
int do_abbr; // when true check for abbr.
|
||||||
char *lookfor; // string to match
|
char *lookfor; // string to match
|
||||||
|
int lookforlen;
|
||||||
int hiscnt; // current history line in use
|
int hiscnt; // current history line in use
|
||||||
int save_hiscnt; // history line before attempting
|
int save_hiscnt; // history line before attempting
|
||||||
// to jump to next match
|
// to jump to next match
|
||||||
@@ -385,7 +386,7 @@ static bool do_incsearch_highlighting(int firstc, int *search_delim, incsearch_s
|
|||||||
if (!use_last_pat) {
|
if (!use_last_pat) {
|
||||||
char c = *end;
|
char c = *end;
|
||||||
*end = NUL;
|
*end = NUL;
|
||||||
bool empty = empty_pattern_magic(p, strlen(p), magic);
|
bool empty = empty_pattern_magic(p, (size_t)(end - p), magic);
|
||||||
*end = c;
|
*end = c;
|
||||||
if (empty) {
|
if (empty) {
|
||||||
goto theend;
|
goto theend;
|
||||||
@@ -538,7 +539,8 @@ static void may_do_incsearch_highlighting(int firstc, int count, incsearch_state
|
|||||||
if (!use_last_pat) {
|
if (!use_last_pat) {
|
||||||
next_char = ccline.cmdbuff[skiplen + patlen];
|
next_char = ccline.cmdbuff[skiplen + patlen];
|
||||||
ccline.cmdbuff[skiplen + patlen] = NUL;
|
ccline.cmdbuff[skiplen + patlen] = NUL;
|
||||||
if (empty_pattern(ccline.cmdbuff + skiplen, search_delim) && !no_hlsearch) {
|
if (empty_pattern(ccline.cmdbuff + skiplen, (size_t)patlen, search_delim)
|
||||||
|
&& !no_hlsearch) {
|
||||||
redraw_all_later(UPD_SOME_VALID);
|
redraw_all_later(UPD_SOME_VALID);
|
||||||
set_no_hlsearch(true);
|
set_no_hlsearch(true);
|
||||||
}
|
}
|
||||||
@@ -900,12 +902,11 @@ static uint8_t *command_line_enter(int firstc, int count, int indent, bool clear
|
|||||||
&& ccline.cmdlen
|
&& ccline.cmdlen
|
||||||
&& s->firstc != NUL
|
&& s->firstc != NUL
|
||||||
&& (s->some_key_typed || s->histype == HIST_SEARCH)) {
|
&& (s->some_key_typed || s->histype == HIST_SEARCH)) {
|
||||||
size_t cmdbufflen = strlen(ccline.cmdbuff);
|
add_to_history(s->histype, ccline.cmdbuff, (size_t)ccline.cmdlen, true,
|
||||||
add_to_history(s->histype, ccline.cmdbuff, cmdbufflen, true,
|
|
||||||
s->histype == HIST_SEARCH ? s->firstc : NUL);
|
s->histype == HIST_SEARCH ? s->firstc : NUL);
|
||||||
if (s->firstc == ':') {
|
if (s->firstc == ':') {
|
||||||
xfree(new_last_cmdline);
|
xfree(new_last_cmdline);
|
||||||
new_last_cmdline = xstrnsave(ccline.cmdbuff, cmdbufflen);
|
new_last_cmdline = xstrnsave(ccline.cmdbuff, (size_t)ccline.cmdlen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1262,6 +1263,7 @@ static int command_line_execute(VimState *state, int key)
|
|||||||
&& s->c != K_LEFT && s->c != K_RIGHT
|
&& s->c != K_LEFT && s->c != K_RIGHT
|
||||||
&& (s->xpc.xp_numfiles > 0 || (s->c != Ctrl_P && s->c != Ctrl_N))) {
|
&& (s->xpc.xp_numfiles > 0 || (s->c != Ctrl_P && s->c != Ctrl_N))) {
|
||||||
XFREE_CLEAR(s->lookfor);
|
XFREE_CLEAR(s->lookfor);
|
||||||
|
s->lookforlen = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// When there are matching completions to select <S-Tab> works like
|
// When there are matching completions to select <S-Tab> works like
|
||||||
@@ -1440,7 +1442,7 @@ static int may_do_command_line_next_incsearch(int firstc, int count, incsearch_s
|
|||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
skiplen = 0;
|
skiplen = 0;
|
||||||
patlen = (int)strlen(pat);
|
patlen = (int)last_search_pattern_len();
|
||||||
} else {
|
} else {
|
||||||
pat = ccline.cmdbuff + skiplen;
|
pat = ccline.cmdbuff + skiplen;
|
||||||
}
|
}
|
||||||
@@ -1574,7 +1576,8 @@ static int command_line_erase_chars(CommandLineState *s)
|
|||||||
return CMDLINE_NOT_CHANGED;
|
return CMDLINE_NOT_CHANGED;
|
||||||
}
|
}
|
||||||
|
|
||||||
XFREE_CLEAR(ccline.cmdbuff); // no commandline to return
|
dealloc_cmdbuff(); // no commandline to return
|
||||||
|
|
||||||
if (!cmd_silent && !ui_has(kUICmdline)) {
|
if (!cmd_silent && !ui_has(kUICmdline)) {
|
||||||
msg_col = 0;
|
msg_col = 0;
|
||||||
msg_putchar(' '); // delete ':'
|
msg_putchar(' '); // delete ':'
|
||||||
@@ -1702,7 +1705,6 @@ static void command_line_left_right_mouse(CommandLineState *s)
|
|||||||
|
|
||||||
static void command_line_next_histidx(CommandLineState *s, bool next_match)
|
static void command_line_next_histidx(CommandLineState *s, bool next_match)
|
||||||
{
|
{
|
||||||
int j = (int)strlen(s->lookfor);
|
|
||||||
while (true) {
|
while (true) {
|
||||||
// one step backwards
|
// one step backwards
|
||||||
if (!next_match) {
|
if (!next_match) {
|
||||||
@@ -1746,7 +1748,7 @@ static void command_line_next_histidx(CommandLineState *s, bool next_match)
|
|||||||
if ((s->c != K_UP && s->c != K_DOWN)
|
if ((s->c != K_UP && s->c != K_DOWN)
|
||||||
|| s->hiscnt == s->save_hiscnt
|
|| s->hiscnt == s->save_hiscnt
|
||||||
|| strncmp(get_histentry(s->histype)[s->hiscnt].hisstr,
|
|| strncmp(get_histentry(s->histype)[s->hiscnt].hisstr,
|
||||||
s->lookfor, (size_t)j) == 0) {
|
s->lookfor, (size_t)s->lookforlen) == 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1765,30 +1767,34 @@ static int command_line_browse_history(CommandLineState *s)
|
|||||||
|
|
||||||
// save current command string so it can be restored later
|
// save current command string so it can be restored later
|
||||||
if (s->lookfor == NULL) {
|
if (s->lookfor == NULL) {
|
||||||
s->lookfor = xstrdup(ccline.cmdbuff);
|
s->lookfor = xstrnsave(ccline.cmdbuff, (size_t)ccline.cmdlen);
|
||||||
s->lookfor[ccline.cmdpos] = NUL;
|
s->lookfor[ccline.cmdpos] = NUL;
|
||||||
|
s->lookforlen = ccline.cmdpos;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool next_match = (s->c == K_DOWN || s->c == K_S_DOWN || s->c == Ctrl_N
|
bool next_match = (s->c == K_DOWN || s->c == K_S_DOWN || s->c == Ctrl_N
|
||||||
|| s->c == K_PAGEDOWN || s->c == K_KPAGEDOWN);
|
|| s->c == K_PAGEDOWN || s->c == K_KPAGEDOWN);
|
||||||
command_line_next_histidx(s, next_match);
|
command_line_next_histidx(s, next_match);
|
||||||
|
|
||||||
if (s->hiscnt != s->save_hiscnt) {
|
if (s->hiscnt != s->save_hiscnt) { // jumped to other entry
|
||||||
// jumped to other entry
|
|
||||||
char *p;
|
char *p;
|
||||||
|
int plen;
|
||||||
int old_firstc;
|
int old_firstc;
|
||||||
|
|
||||||
XFREE_CLEAR(ccline.cmdbuff);
|
dealloc_cmdbuff();
|
||||||
|
|
||||||
s->xpc.xp_context = EXPAND_NOTHING;
|
s->xpc.xp_context = EXPAND_NOTHING;
|
||||||
if (s->hiscnt == get_hislen()) {
|
if (s->hiscnt == get_hislen()) {
|
||||||
p = s->lookfor; // back to the old one
|
p = s->lookfor; // back to the old one
|
||||||
|
plen = s->lookforlen;
|
||||||
} else {
|
} else {
|
||||||
p = get_histentry(s->histype)[s->hiscnt].hisstr;
|
p = get_histentry(s->histype)[s->hiscnt].hisstr;
|
||||||
|
plen = (int)strlen(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s->histype == HIST_SEARCH
|
if (s->histype == HIST_SEARCH
|
||||||
&& p != s->lookfor
|
&& p != s->lookfor
|
||||||
&& (old_firstc = (uint8_t)p[strlen(p) + 1]) != s->firstc) {
|
&& (old_firstc = (uint8_t)p[plen + 1]) != s->firstc) {
|
||||||
int len = 0;
|
int len = 0;
|
||||||
// Correct for the separator character used when
|
// Correct for the separator character used when
|
||||||
// adding the history entry vs the one used now.
|
// adding the history entry vs the one used now.
|
||||||
@@ -1827,12 +1833,13 @@ static int command_line_browse_history(CommandLineState *s)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ccline.cmdbuff[len] = NUL;
|
ccline.cmdbuff[len] = NUL;
|
||||||
|
ccline.cmdpos = ccline.cmdlen = len;
|
||||||
} else {
|
} else {
|
||||||
alloc_cmdbuff((int)strlen(p));
|
alloc_cmdbuff(plen);
|
||||||
STRCPY(ccline.cmdbuff, p);
|
STRCPY(ccline.cmdbuff, p);
|
||||||
|
ccline.cmdpos = ccline.cmdlen = plen;
|
||||||
}
|
}
|
||||||
|
|
||||||
ccline.cmdpos = ccline.cmdlen = (int)strlen(ccline.cmdbuff);
|
|
||||||
redrawcmd();
|
redrawcmd();
|
||||||
return CMDLINE_CHANGED;
|
return CMDLINE_CHANGED;
|
||||||
}
|
}
|
||||||
@@ -2201,18 +2208,17 @@ static int command_line_not_changed(CommandLineState *s)
|
|||||||
|
|
||||||
/// Guess that the pattern matches everything. Only finds specific cases, such
|
/// Guess that the pattern matches everything. Only finds specific cases, such
|
||||||
/// as a trailing \|, which can happen while typing a pattern.
|
/// as a trailing \|, which can happen while typing a pattern.
|
||||||
static bool empty_pattern(char *p, int delim)
|
static bool empty_pattern(char *p, size_t len, int delim)
|
||||||
{
|
{
|
||||||
size_t n = strlen(p);
|
|
||||||
magic_T magic_val = MAGIC_ON;
|
magic_T magic_val = MAGIC_ON;
|
||||||
|
|
||||||
if (n > 0) {
|
if (len > 0) {
|
||||||
skip_regexp_ex(p, delim, magic_isset(), NULL, NULL, &magic_val);
|
skip_regexp_ex(p, delim, magic_isset(), NULL, NULL, &magic_val);
|
||||||
} else {
|
} else {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return empty_pattern_magic(p, n, magic_val);
|
return empty_pattern_magic(p, len, magic_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool empty_pattern_magic(char *p, size_t len, magic_T magic_val)
|
static bool empty_pattern_magic(char *p, size_t len, magic_T magic_val)
|
||||||
@@ -2225,11 +2231,9 @@ static bool empty_pattern_magic(char *p, size_t len, magic_T magic_val)
|
|||||||
|
|
||||||
// true, if the pattern is empty, or the pattern ends with \| and magic is
|
// true, if the pattern is empty, or the pattern ends with \| and magic is
|
||||||
// set (or it ends with '|' and very magic is set)
|
// set (or it ends with '|' and very magic is set)
|
||||||
return len == 0 || (len > 1
|
return len == 0 || (len > 1 && p[len - 1] == '|'
|
||||||
&& ((p[len - 2] == '\\'
|
&& ((p[len - 2] == '\\' && magic_val == MAGIC_ON)
|
||||||
&& p[len - 1] == '|' && magic_val == MAGIC_ON)
|
|| (p[len - 2] != '\\' && magic_val == MAGIC_ALL)));
|
||||||
|| (p[len - 2] != '\\'
|
|
||||||
&& p[len - 1] == '|' && magic_val == MAGIC_ALL)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
handle_T cmdpreview_get_bufnr(void)
|
handle_T cmdpreview_get_bufnr(void)
|
||||||
@@ -2710,7 +2714,7 @@ static int command_line_changed(CommandLineState *s)
|
|||||||
/// Abandon the command line.
|
/// Abandon the command line.
|
||||||
static void abandon_cmdline(void)
|
static void abandon_cmdline(void)
|
||||||
{
|
{
|
||||||
XFREE_CLEAR(ccline.cmdbuff);
|
dealloc_cmdbuff();
|
||||||
ccline.redraw_state = kCmdRedrawNone;
|
ccline.redraw_state = kCmdRedrawNone;
|
||||||
if (msg_scrolled == 0) {
|
if (msg_scrolled == 0) {
|
||||||
compute_cmdrow();
|
compute_cmdrow();
|
||||||
@@ -3000,8 +3004,15 @@ bool cmdline_at_end(void)
|
|||||||
return (ccline.cmdpos >= ccline.cmdlen);
|
return (ccline.cmdpos >= ccline.cmdlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate a new command line buffer.
|
/// Deallocate a command line buffer, updating the buffer size and length.
|
||||||
// Assigns the new buffer to ccline.cmdbuff and ccline.cmdbufflen.
|
static void dealloc_cmdbuff(void)
|
||||||
|
{
|
||||||
|
XFREE_CLEAR(ccline.cmdbuff);
|
||||||
|
ccline.cmdlen = ccline.cmdbufflen = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Allocate a new command line buffer.
|
||||||
|
/// Assigns the new buffer to ccline.cmdbuff and ccline.cmdbufflen.
|
||||||
static void alloc_cmdbuff(int len)
|
static void alloc_cmdbuff(int len)
|
||||||
{
|
{
|
||||||
// give some extra space to avoid having to allocate all the time
|
// give some extra space to avoid having to allocate all the time
|
||||||
@@ -3023,6 +3034,7 @@ void realloc_cmdbuff(int len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
char *p = ccline.cmdbuff;
|
char *p = ccline.cmdbuff;
|
||||||
|
|
||||||
alloc_cmdbuff(len); // will get some more
|
alloc_cmdbuff(len); // will get some more
|
||||||
// There isn't always a NUL after the command, but it may need to be
|
// There isn't always a NUL after the command, but it may need to be
|
||||||
// there, thus copy up to the NUL and add a NUL.
|
// there, thus copy up to the NUL and add a NUL.
|
||||||
@@ -4509,17 +4521,20 @@ static int open_cmdwin(void)
|
|||||||
cmdwin_result = Ctrl_C;
|
cmdwin_result = Ctrl_C;
|
||||||
}
|
}
|
||||||
// Set the new command line from the cmdline buffer.
|
// Set the new command line from the cmdline buffer.
|
||||||
xfree(ccline.cmdbuff);
|
dealloc_cmdbuff();
|
||||||
|
|
||||||
if (cmdwin_result == K_XF1 || cmdwin_result == K_XF2) { // :qa[!] typed
|
if (cmdwin_result == K_XF1 || cmdwin_result == K_XF2) { // :qa[!] typed
|
||||||
const char *p = (cmdwin_result == K_XF2) ? "qa" : "qa!";
|
const char *p = (cmdwin_result == K_XF2) ? "qa" : "qa!";
|
||||||
|
size_t plen = (cmdwin_result == K_XF2) ? 2 : 3;
|
||||||
|
|
||||||
if (histtype == HIST_CMD) {
|
if (histtype == HIST_CMD) {
|
||||||
// Execute the command directly.
|
// Execute the command directly.
|
||||||
ccline.cmdbuff = xstrdup(p);
|
ccline.cmdbuff = xmemdupz(p, plen);
|
||||||
|
ccline.cmdlen = (int)plen;
|
||||||
|
ccline.cmdbufflen = (int)plen + 1;
|
||||||
cmdwin_result = CAR;
|
cmdwin_result = CAR;
|
||||||
} else {
|
} else {
|
||||||
// First need to cancel what we were doing.
|
// First need to cancel what we were doing.
|
||||||
ccline.cmdbuff = NULL;
|
|
||||||
stuffcharReadbuff(':');
|
stuffcharReadbuff(':');
|
||||||
stuffReadbuff(p);
|
stuffReadbuff(p);
|
||||||
stuffcharReadbuff(CAR);
|
stuffcharReadbuff(CAR);
|
||||||
@@ -4529,17 +4544,18 @@ static int open_cmdwin(void)
|
|||||||
// and don't modify the cmd window.
|
// and don't modify the cmd window.
|
||||||
ccline.cmdbuff = NULL;
|
ccline.cmdbuff = NULL;
|
||||||
} else {
|
} else {
|
||||||
ccline.cmdbuff = xstrdup(get_cursor_line_ptr());
|
ccline.cmdlen = get_cursor_line_len();
|
||||||
|
ccline.cmdbufflen = ccline.cmdlen + 1;
|
||||||
|
ccline.cmdbuff = xstrnsave(get_cursor_line_ptr(), (size_t)ccline.cmdlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ccline.cmdbuff == NULL) {
|
if (ccline.cmdbuff == NULL) {
|
||||||
ccline.cmdbuff = xstrdup("");
|
ccline.cmdbuff = xmemdupz("", 0);
|
||||||
ccline.cmdlen = 0;
|
ccline.cmdlen = 0;
|
||||||
ccline.cmdbufflen = 1;
|
ccline.cmdbufflen = 1;
|
||||||
ccline.cmdpos = 0;
|
ccline.cmdpos = 0;
|
||||||
cmdwin_result = Ctrl_C;
|
cmdwin_result = Ctrl_C;
|
||||||
} else {
|
} else {
|
||||||
ccline.cmdlen = (int)strlen(ccline.cmdbuff);
|
|
||||||
ccline.cmdbufflen = ccline.cmdlen + 1;
|
|
||||||
ccline.cmdpos = curwin->w_cursor.col;
|
ccline.cmdpos = curwin->w_cursor.col;
|
||||||
// If the cursor is on the last character, it probably should be after it.
|
// If the cursor is on the last character, it probably should be after it.
|
||||||
if (ccline.cmdpos == ccline.cmdlen - 1 || ccline.cmdpos > ccline.cmdlen) {
|
if (ccline.cmdpos == ccline.cmdlen - 1 || ccline.cmdpos > ccline.cmdlen) {
|
||||||
|
@@ -380,6 +380,11 @@ char *last_search_pattern(void)
|
|||||||
return spats[RE_SEARCH].pat;
|
return spats[RE_SEARCH].pat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t last_search_pattern_len(void)
|
||||||
|
{
|
||||||
|
return spats[RE_SEARCH].patlen;
|
||||||
|
}
|
||||||
|
|
||||||
/// Return true when case should be ignored for search pattern "pat".
|
/// Return true when case should be ignored for search pattern "pat".
|
||||||
/// Uses the 'ignorecase' and 'smartcase' options.
|
/// Uses the 'ignorecase' and 'smartcase' options.
|
||||||
int ignorecase(char *pat)
|
int ignorecase(char *pat)
|
||||||
|
Reference in New Issue
Block a user