diff options
Diffstat (limited to 'src/nvim/os/env.c')
-rw-r--r-- | src/nvim/os/env.c | 64 |
1 files changed, 43 insertions, 21 deletions
diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c index 8620c79069..5b1cb01976 100644 --- a/src/nvim/os/env.c +++ b/src/nvim/os/env.c @@ -13,9 +13,9 @@ #include "nvim/buffer_defs.h" #include "nvim/charset.h" #include "nvim/cmdexpand.h" +#include "nvim/cmdexpand_defs.h" #include "nvim/eval.h" -#include "nvim/func_attr.h" -#include "nvim/gettext.h" +#include "nvim/gettext_defs.h" #include "nvim/globals.h" #include "nvim/log.h" #include "nvim/macros_defs.h" @@ -25,8 +25,10 @@ #include "nvim/option_vars.h" #include "nvim/os/fs.h" #include "nvim/os/os.h" +#include "nvim/os/os_defs.h" #include "nvim/path.h" #include "nvim/strings.h" +#include "nvim/types_defs.h" #include "nvim/version.h" #include "nvim/vim_defs.h" @@ -46,6 +48,10 @@ # include <sys/utsname.h> #endif +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "os/env.c.generated.h" +#endif + // Because `uv_os_getenv` requires allocating, we must manage a map to maintain // the behavior of `os_getenv`. static PMap(cstr_t) envmap = MAP_INIT; @@ -55,8 +61,7 @@ static PMap(cstr_t) envmap = MAP_INIT; const char *os_getenv(const char *name) FUNC_ATTR_NONNULL_ALL { - char *e; - size_t size = 64; + char *e = NULL; if (name[0] == '\0') { return NULL; } @@ -72,23 +77,31 @@ const char *os_getenv(const char *name) } pmap_del2(&envmap, name); } - e = xmalloc(size); - r = uv_os_getenv(name, e, &size); +#define INIT_SIZE 64 + size_t size = INIT_SIZE; + char buf[INIT_SIZE]; + r = uv_os_getenv(name, buf, &size); if (r == UV_ENOBUFS) { - e = xrealloc(e, size); + e = xmalloc(size); r = uv_os_getenv(name, e, &size); - } - if (r != 0 || size == 0 || e[0] == '\0') { - xfree(e); + if (r != 0 || size == 0 || e[0] == '\0') { + XFREE_CLEAR(e); + goto end; + } + } else if (r != 0 || size == 0 || buf[0] == '\0') { e = NULL; goto end; + } else { + // NB: `size` param of uv_os_getenv() includes the NUL-terminator, + // except when it does not include the NUL-terminator. + e = xmemdupz(buf, size); } pmap_put(cstr_t)(&envmap, xstrdup(name), e); end: if (r != 0 && r != UV_ENOENT && r != UV_UNKNOWN) { ELOG("uv_os_getenv(%s) failed: %d %s", name, r, uv_err_name(r)); } - return (e == NULL || size == 0 || e[0] == '\0') ? NULL : e; + return e; } /// Returns true if environment variable `name` is defined (even if empty). @@ -507,6 +520,17 @@ void free_homedir(void) xfree(homedir); } +void free_envmap(void) +{ + cstr_t name; + ptr_t e; + map_foreach(&envmap, name, e, { + xfree((char *)name); + xfree(e); + }); + map_destroy(cstr_t, &envmap); +} + #endif /// Call expand_env() and store the result in an allocated string. @@ -562,6 +586,9 @@ void expand_env_esc(char *restrict srcp, char *restrict dst, int dstlen, bool es bool copy_char; bool mustfree; // var was allocated, need to free it later bool at_start = true; // at start of a name +#if defined(BACKSLASH_IN_FILENAME) + char *const save_dst = dst; +#endif int prefix_len = (prefix == NULL) ? 0 : (int)strlen(prefix); @@ -572,7 +599,7 @@ void expand_env_esc(char *restrict srcp, char *restrict dst, int dstlen, bool es if (src[0] == '`' && src[1] == '=') { var = src; src += 2; - (void)skip_expr(&src, NULL); + skip_expr(&src, NULL); if (*src == '`') { src++; } @@ -604,7 +631,7 @@ void expand_env_esc(char *restrict srcp, char *restrict dst, int dstlen, bool es while (c-- > 0 && *tail != NUL && *tail != '}') { *var++ = *tail++; } - } else // NOLINT + } else #endif { while (c-- > 0 && *tail != NUL && vim_isIDc((uint8_t)(*tail))) { @@ -702,7 +729,7 @@ void expand_env_esc(char *restrict srcp, char *restrict dst, int dstlen, bool es // with it, skip a character if (after_pathsep(dst, dst + c) #if defined(BACKSLASH_IN_FILENAME) - && dst[-1] != ':' + && (dst == save_dst || dst[-1] != ':') #endif && vim_ispathsep(*tail)) { tail++; @@ -904,10 +931,7 @@ char *vim_getenv(const char *name) // Don't do this when default_vimruntime_dir is non-empty. char *vim_path = NULL; if (vimruntime -#ifdef HAVE_PATHDEF - && *default_vimruntime_dir == NUL -#endif - ) { + && *default_vimruntime_dir == NUL) { kos_env_path = os_getenv("VIM"); if (kos_env_path != NULL) { vim_path = vim_version_dir(kos_env_path); @@ -966,7 +990,6 @@ char *vim_getenv(const char *name) assert(vim_path != exe_name); } -#ifdef HAVE_PATHDEF // When there is a pathdef.c file we can use default_vim_dir and // default_vimruntime_dir if (vim_path == NULL) { @@ -980,7 +1003,6 @@ char *vim_getenv(const char *name) } } } -#endif // Set the environment variable, so that the new value can be found fast // next time, and others can also use it (e.g. Perl). @@ -1051,7 +1073,7 @@ size_t home_replace(const buf_T *const buf, const char *src, char *const dst, si size_t usedlen = 0; size_t flen = strlen(homedir_env_mod); char *fbuf = NULL; - (void)modify_fname(":p", false, &usedlen, &homedir_env_mod, &fbuf, &flen); + modify_fname(":p", false, &usedlen, &homedir_env_mod, &fbuf, &flen); flen = strlen(homedir_env_mod); assert(homedir_env_mod != homedir_env); if (vim_ispathsep(homedir_env_mod[flen - 1])) { |