diff options
author | James <89495599+IAKOBVS@users.noreply.github.com> | 2024-06-08 09:12:39 +0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-06-08 10:12:39 +0800 |
commit | 4881211097aba7f5d17700362ec0967e3024f074 (patch) | |
tree | 3afe9a6c2be2f5c801b127d38ae940129deed3d6 | |
parent | da6f68ee6966ebf434eee840b22a4f45e61d77dd (diff) | |
download | rneovim-4881211097aba7f5d17700362ec0967e3024f074.tar.gz rneovim-4881211097aba7f5d17700362ec0967e3024f074.tar.bz2 rneovim-4881211097aba7f5d17700362ec0967e3024f074.zip |
refactor: quadratic behavior in vim_findfile_stopdir (#29232)
Copies characters in-places instead. Related #27827
-rw-r--r-- | src/nvim/file_search.c | 42 |
1 files changed, 27 insertions, 15 deletions
diff --git a/src/nvim/file_search.c b/src/nvim/file_search.c index 51bea3111c..30a80773e3 100644 --- a/src/nvim/file_search.c +++ b/src/nvim/file_search.c @@ -505,24 +505,36 @@ error_return: /// @return the stopdir string. Check that ';' is not escaped. char *vim_findfile_stopdir(char *buf) { - char *r_ptr = buf; - - while (*r_ptr != NUL && *r_ptr != ';') { - if (r_ptr[0] == '\\' && r_ptr[1] == ';') { - // Overwrite the escape char, - // use strlen(r_ptr) to move the trailing NUL. - STRMOVE(r_ptr, r_ptr + 1); - r_ptr++; + for (; *buf != NUL && *buf != ';' && (buf[0] != '\\' || buf[1] != ';'); buf++) {} + char *dst = buf; + if (*buf == ';') { + goto is_semicolon; + } + if (*buf == NUL) { + goto is_nul; + } + 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 == ';') { - *r_ptr = 0; - r_ptr++; - } else if (*r_ptr == NUL) { - r_ptr = NULL; + assert(dst < buf); + *dst = NUL; + if (*buf == ';') { +is_semicolon: + *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. |