vim-patch:partial:9.2.0193: using copy_option_part() can be improved (#38369)

Problem:  using copy_option_part() can be improved
Solution: Refactor and use the return value of copy_option_part() to
          avoid strlen() calls (John Marriott).

In addition, this commit includes the following changes:

memline.c:
- In recover_names():
  - Replace calls to vim_strsave() with vim_strnsave() for the literal
    strings
  - Use a string_T to store local variable dir_name.

bufwrite.c:
- In buf_write()
  - move variable wp to where it is used.

help.c:
- In fix_help_buffer():
  - replace call to add_pathsep() with after_pathsep()

optionstr.c:
- In export_myvimdir():
  - use a string_T to store local variable buf
  - replace call to add_pathsep() with after_pathsep()

scriptfile.c:
- In do_in_path():
  - use a string_T to store local variable buf
  - measure the lengths of prefix and name once before the while loop
  - replace call to add_pathsep() with after_pathsep()
  - move some variables closer to where they are used

spellfile.c:
- In init_spellfile():
  - use a string_T to store local variable buf

closes: vim/vim#19725

a74e5fc5b9

Co-authored-by: John Marriott <basilisk@internode.on.net>
This commit is contained in:
zeertzjq
2026-03-19 18:31:11 +08:00
committed by GitHub
parent 7d6b6b2d14
commit 4c48f19e51
5 changed files with 36 additions and 37 deletions

View File

@@ -1242,6 +1242,7 @@ bool open_line(int dir, int flags, int second_line_indent, bool *did_do_comment)
char *lead_repl = NULL; // replaces comment leader
int lead_repl_len = 0; // length of *lead_repl
char lead_middle[COM_MAX_LEN]; // middle-comment string
int lead_middle_len; // length of the lead_middle
char lead_end[COM_MAX_LEN]; // end-comment string
char *comment_end = NULL; // where lead_end has been found
int extra_space = false; // append extra space
@@ -1276,7 +1277,7 @@ bool open_line(int dir, int flags, int second_line_indent, bool *did_do_comment)
}
p++;
}
copy_option_part(&p, lead_middle, COM_MAX_LEN, ",");
lead_middle_len = (int)copy_option_part(&p, lead_middle, COM_MAX_LEN, ",");
while (*p && p[-1] != ':') { // find end of end flags
// Check whether we allow automatic ending of comments
@@ -1307,7 +1308,7 @@ bool open_line(int dir, int flags, int second_line_indent, bool *did_do_comment)
if (lead_len > 0) {
if (current_flag == COM_START) {
lead_repl = lead_middle;
lead_repl_len = (int)strlen(lead_middle);
lead_repl_len = lead_middle_len;
}
// If we have hit RETURN immediately after the start

View File

@@ -2057,6 +2057,7 @@ int get_c_indent(void)
char lead_start[COM_MAX_LEN]; // start-comment string
char lead_middle[COM_MAX_LEN]; // middle-comment string
char lead_end[COM_MAX_LEN]; // end-comment string
int lead_end_len;
char *p;
int start_align = 0;
int start_off = 0;
@@ -2089,20 +2090,20 @@ int get_c_indent(void)
if (*p == ':') {
p++;
}
(void)copy_option_part(&p, lead_end, COM_MAX_LEN, ",");
lead_end_len = (int)copy_option_part(&p, lead_end, COM_MAX_LEN, ",");
if (what == COM_START) {
STRCPY(lead_start, lead_end);
lead_start_len = (int)strlen(lead_start);
lead_start_len = lead_end_len;
start_off = off;
start_align = align;
} else if (what == COM_MIDDLE) {
STRCPY(lead_middle, lead_end);
lead_middle_len = (int)strlen(lead_middle);
lead_middle_len = lead_end_len;
} else if (what == COM_END) {
// If our line starts with the middle comment string, line it
// up with the comment opener per the 'comments' option.
if (strncmp(theline, lead_middle, (size_t)lead_middle_len) == 0
&& strncmp(theline, lead_end, strlen(lead_end)) != 0) {
&& strncmp(theline, lead_end, (size_t)lead_end_len) != 0) {
done = true;
if (curwin->w_cursor.lnum > 1) {
// If the start comment string matches in the previous
@@ -2133,7 +2134,7 @@ int get_c_indent(void)
// If our line starts with the end comment string, line it up
// with the middle comment
if (strncmp(theline, lead_middle, (size_t)lead_middle_len) != 0
&& strncmp(theline, lead_end, strlen(lead_end)) == 0) {
&& strncmp(theline, lead_end, (size_t)lead_end_len) == 0) {
amount = get_indent_lnum(curwin->w_cursor.lnum - 1);
// XXX
if (off != 0) {

View File

@@ -1305,42 +1305,42 @@ int recover_names(char *fname, bool do_list, list_T *ret_list, int nr, char **fn
// Do the loop for every directory in 'directory'.
// First allocate some memory to put the directory name in.
char *dir_name = xmalloc(strlen(p_dir) + 1);
String dir_name;
dir_name.data = xmalloc(strlen(p_dir) + 1);
char *dirp = p_dir;
while (*dirp) {
// Isolate a directory name from *dirp and put it in dir_name (we know
// it is large enough, so use 31000 for length).
// Advance dirp to next directory name.
copy_option_part(&dirp, dir_name, 31000, ",");
dir_name.size = copy_option_part(&dirp, dir_name.data, 31000, ",");
if (dir_name[0] == '.' && dir_name[1] == NUL) { // check current dir
if (dir_name.data[0] == '.' && dir_name.data[1] == NUL) { // check current dir
if (fname == NULL) {
names[0] = xstrdup("*.sw?");
names[0] = xmemdupz(S_LEN("*.sw?"));
// For Unix names starting with a dot are special. MS-Windows
// supports this too, on some file systems.
names[1] = xstrdup(".*.sw?");
names[2] = xstrdup(".sw?");
names[1] = xmemdupz(S_LEN(".*.sw?"));
names[2] = xmemdupz(S_LEN(".sw?"));
num_names = 3;
} else {
num_names = recov_file_names(names, fname_res, true);
}
} else { // check directory dir_name
if (fname == NULL) {
names[0] = concat_fnames(dir_name, "*.sw?", true);
names[0] = concat_fnames(dir_name.data, "*.sw?", true);
// For Unix names starting with a dot are special. MS-Windows
// supports this too, on some file systems.
names[1] = concat_fnames(dir_name, ".*.sw?", true);
names[2] = concat_fnames(dir_name, ".sw?", true);
names[1] = concat_fnames(dir_name.data, ".*.sw?", true);
names[2] = concat_fnames(dir_name.data, ".sw?", true);
num_names = 3;
} else {
int len = (int)strlen(dir_name);
p = dir_name + len;
if (after_pathsep(dir_name, p) && len > 1 && p[-1] == p[-2]) {
p = dir_name.data + dir_name.size;
if (after_pathsep(dir_name.data, p) && dir_name.size > 1 && p[-1] == p[-2]) {
// Ends with '//', Use Full path for swap name
tail = make_percent_swname(dir_name, p, fname_res);
tail = make_percent_swname(dir_name.data, p, fname_res);
} else {
tail = path_tail(fname_res);
tail = concat_fnames(dir_name, tail, true);
tail = concat_fnames(dir_name.data, tail, true);
}
num_names = recov_file_names(names, tail, false);
xfree(tail);
@@ -1401,7 +1401,7 @@ int recover_names(char *fname, bool do_list, list_T *ret_list, int nr, char **fn
dirp = ""; // stop searching
}
} else if (do_list) {
if (dir_name[0] == '.' && dir_name[1] == NUL) {
if (dir_name.data[0] == '.' && dir_name.data[1] == NUL) {
if (fname == NULL) {
msg_puts(_(" In current directory:\n"));
} else {
@@ -1409,7 +1409,7 @@ int recover_names(char *fname, bool do_list, list_T *ret_list, int nr, char **fn
}
} else {
msg_puts(_(" In directory "));
msg_home_replace(dir_name);
msg_home_replace(dir_name.data);
msg_puts(":\n");
}
@@ -1433,7 +1433,7 @@ int recover_names(char *fname, bool do_list, list_T *ret_list, int nr, char **fn
ui_flush();
} else if (ret_list != NULL) {
for (int i = 0; i < num_files; i++) {
char *name = concat_fnames(dir_name, files[i], true);
char *name = concat_fnames(dir_name.data, files[i], true);
tv_list_append_allocated_string(ret_list, name);
}
} else {
@@ -1447,7 +1447,7 @@ int recover_names(char *fname, bool do_list, list_T *ret_list, int nr, char **fn
FreeWild(num_files, files);
}
}
xfree(dir_name);
xfree(dir_name.data);
return file_count;
}

View File

@@ -455,8 +455,7 @@ int do_in_path(const char *path, const char *prefix, char *name, int flags,
char *rtp = rtp_copy;
while (*rtp != NUL && (do_all || !did_one)) {
// Copy the path from 'runtimepath' to buf[].
copy_option_part(&rtp, buf, MAXPATHL, ",");
size_t buflen = strlen(buf);
size_t buflen = copy_option_part(&rtp, buf, MAXPATHL, ",");
// Skip after or non-after directories.
if (flags & (DIP_NOAFTER | DIP_AFTER)) {
@@ -840,9 +839,9 @@ static RuntimeSearchPath runtime_search_path_build(void)
static char buf[MAXPATHL];
for (char *entry = p_pp; *entry != NUL;) {
char *cur_entry = entry;
copy_option_part(&entry, buf, MAXPATHL, ",");
size_t buflen = copy_option_part(&entry, buf, MAXPATHL, ",");
String the_entry = { .data = cur_entry, .size = strlen(buf) };
String the_entry = { .data = cur_entry, .size = buflen };
kv_push(pack_entries, the_entry);
map_put(String, int)(&pack_used, the_entry, 0);
@@ -851,8 +850,7 @@ static RuntimeSearchPath runtime_search_path_build(void)
char *rtp_entry;
for (rtp_entry = p_rtp; *rtp_entry != NUL;) {
char *cur_entry = rtp_entry;
copy_option_part(&rtp_entry, buf, MAXPATHL, ",");
size_t buflen = strlen(buf);
size_t buflen = copy_option_part(&rtp_entry, buf, MAXPATHL, ",");
if (path_is_after(buf, buflen)) {
rtp_entry = cur_entry;
@@ -895,9 +893,9 @@ static RuntimeSearchPath runtime_search_path_build(void)
// "after" dirs in rtp
for (; *rtp_entry != NUL;) {
char *cur_entry = rtp_entry;
copy_option_part(&rtp_entry, buf, MAXPATHL, ",");
size_t buflen = copy_option_part(&rtp_entry, buf, MAXPATHL, ",");
size_t pos_in_rtp = (size_t)(cur_entry - p_rtp);
expand_rtp_entry(&search_path, &rtp_used, buf, path_is_after(buf, strlen(buf)), pos_in_rtp);
expand_rtp_entry(&search_path, &rtp_used, buf, path_is_after(buf, buflen), pos_in_rtp);
}
// strings are not owned

View File

@@ -1955,9 +1955,8 @@ char *parse_spelllang(win_T *wp)
// Loop over comma separated language names.
for (char *splp = spl_copy; *splp != NUL;) {
// Get one language name.
copy_option_part(&splp, lang, MAXWLEN, ",");
int len = (int)copy_option_part(&splp, lang, MAXWLEN, ",");
char *region = NULL;
int len = (int)strlen(lang);
if (!valid_spelllang(lang)) {
continue;
@@ -2089,8 +2088,8 @@ char *parse_spelllang(win_T *wp)
int_wordlist_spl(spf_name);
} else {
// One entry in 'spellfile'.
copy_option_part(&spf, spf_name, MAXPATHL - 4, ",");
strcat(spf_name, ".spl");
int len = (int)copy_option_part(&spf, spf_name, MAXPATHL - 4, ",");
STRCPY(spf_name + len, ".spl");
int c;
// If it was already found above then skip it.