diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/main.c | 1 | ||||
-rw-r--r-- | src/nvim/os/stdpaths.c | 6 | ||||
-rw-r--r-- | src/nvim/path.c | 56 |
3 files changed, 52 insertions, 11 deletions
diff --git a/src/nvim/main.c b/src/nvim/main.c index 0e250de8ca..6186d2e7e7 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -1895,6 +1895,7 @@ static void source_startup_scripts(mparm_T *parmp) (void)do_source((char_u *)EXRC_FILE, FALSE, DOSO_NONE); } } + xfree(user_vimrc); if (secure == 2) need_wait_return = TRUE; secure = 0; diff --git a/src/nvim/os/stdpaths.c b/src/nvim/os/stdpaths.c index 86daa7257a..9d93f25a7e 100644 --- a/src/nvim/os/stdpaths.c +++ b/src/nvim/os/stdpaths.c @@ -59,7 +59,7 @@ static char *get_xdg_home(const XDGVarType idx) { char *dir = stdpaths_get_xdg_var(idx); if (dir) { - dir = concat_fnames(dir, "nvim", true); + dir = concat_fnames_realloc(dir, "nvim", true); } return dir; } @@ -77,13 +77,13 @@ static void create_dir(const char *dir, int mode, const char *suffix) char *stdpaths_user_conf_subpath(const char *fname) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL { - return concat_fnames(get_xdg_home(kXDGConfigHome), fname, true); + return concat_fnames_realloc(get_xdg_home(kXDGConfigHome), fname, true); } char *stdpaths_user_data_subpath(const char *fname) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL { - char *dir = concat_fnames(get_xdg_home(kXDGDataHome), fname, true); + char *dir = concat_fnames_realloc(get_xdg_home(kXDGDataHome), fname, true); if (!os_isdir((char_u *)dir)) { create_dir(dir, 0755, fname); } diff --git a/src/nvim/path.c b/src/nvim/path.c index a9d1d052d4..a0bba450cd 100644 --- a/src/nvim/path.c +++ b/src/nvim/path.c @@ -329,6 +329,31 @@ int vim_fnamencmp(char_u *x, char_u *y, size_t len) #endif } +/// Append fname2 to fname1 +/// +/// @param[in] fname1 First fname to append to. +/// @param[in] len1 Length of fname1. +/// @param[in] fname2 Secord part of the file name. +/// @param[in] len2 Length of fname2. +/// @param[in] sep If true and fname1 does not end with a path separator, +/// add a path separator before fname2. +/// +/// @return fname1 +static inline char *do_concat_fnames(char *fname1, const size_t len1, + const char *fname2, const size_t len2, + const bool sep) + FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET +{ + if (sep && *fname1 && !after_pathsep(fname1, fname1 + len1)) { + fname1[len1] = PATHSEP; + memmove(fname1 + len1 + 1, fname2, len2 + 1); + } else { + memmove(fname1 + len1, fname2, len2 + 1); + } + + return fname1; +} + /// Concatenate file names fname1 and fname2 into allocated memory. /// /// Only add a '/' or '\\' when 'sep' is true and it is necessary. @@ -341,15 +366,30 @@ int vim_fnamencmp(char_u *x, char_u *y, size_t len) char *concat_fnames(const char *fname1, const char *fname2, bool sep) FUNC_ATTR_NONNULL_ARG(1, 2) FUNC_ATTR_NONNULL_RET { - char *dest = xmalloc(strlen(fname1) + strlen(fname2) + 3); - - strcpy(dest, fname1); - if (sep) { - add_pathsep(dest); - } - strcat(dest, fname2); + const size_t len1 = strlen(fname1); + const size_t len2 = strlen(fname2); + char *dest = xmalloc(len1 + len2 + 3); + memmove(dest, fname1, len1 + 1); + return do_concat_fnames(dest, len1, fname2, len2, sep); +} - return dest; +/// Concatenate file names fname1 and fname2 +/// +/// Like concat_fnames(), but in place of allocating new memory it reallocates +/// fname1. For this reason fname1 must be allocated with xmalloc. +/// +/// @param fname1 is the first part of the path or filename +/// @param fname2 is the second half of the path or filename +/// @param sep is a flag to indicate a path separator should be added +/// if necessary +/// @return [allocated] Concatenation of fname1 and fname2. +char *concat_fnames_realloc(char *fname1, const char *fname2, bool sep) + FUNC_ATTR_NONNULL_ARG(1, 2) FUNC_ATTR_NONNULL_RET +{ + const size_t len1 = strlen(fname1); + const size_t len2 = strlen(fname2); + return do_concat_fnames(xrealloc(fname1, len1 + len2 + 3), len1, + fname2, len2, sep); } /* |