refactor: quadratic behavior in vim_findfile_stopdir (#29232)

Copies characters in-places instead. Related #27827
This commit is contained in:
James 2024-06-08 09:12:39 +07:00 committed by GitHub
parent da6f68ee69
commit 4881211097
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -505,24 +505,36 @@ error_return:
/// @return the stopdir string. Check that ';' is not escaped. /// @return the stopdir string. Check that ';' is not escaped.
char *vim_findfile_stopdir(char *buf) char *vim_findfile_stopdir(char *buf)
{ {
char *r_ptr = buf; for (; *buf != NUL && *buf != ';' && (buf[0] != '\\' || buf[1] != ';'); buf++) {}
char *dst = buf;
while (*r_ptr != NUL && *r_ptr != ';') { if (*buf == ';') {
if (r_ptr[0] == '\\' && r_ptr[1] == ';') { goto is_semicolon;
// Overwrite the escape char, }
// use strlen(r_ptr) to move the trailing NUL. if (*buf == NUL) {
STRMOVE(r_ptr, r_ptr + 1); goto is_nul;
r_ptr++; }
goto start;
while (*buf != NUL && *buf != ';') {
if (buf[0] == '\\' && buf[1] == ';') {
start:
// Overwrite the escape char.
*dst++ = ';';
buf += 2;
} else {
*dst++ = *buf++;
} }
r_ptr++;
} }
if (*r_ptr == ';') { assert(dst < buf);
*r_ptr = 0; *dst = NUL;
r_ptr++; if (*buf == ';') {
} else if (*r_ptr == NUL) { is_semicolon:
r_ptr = NULL; *buf = NUL;
buf++;
} else { // if (*buf == NUL)
is_nul:
buf = NULL;
} }
return r_ptr; return buf;
} }
/// Clean up the given search context. Can handle a NULL pointer. /// Clean up the given search context. Can handle a NULL pointer.