From c2dd07448ff1b2922e8ea14f909a9cbde481e5fc Mon Sep 17 00:00:00 2001 From: Keerthan Jaic Date: Tue, 4 Aug 2015 21:41:38 -0400 Subject: option,main: Partial support of XDG base directory specification - Add functions that are able to query XDG. - Replace defaults for - &runtimepath. Does not follow #78. - &viewdir. - &undodir. - &directory. - &backupdir. Does not follow #78. - vimrc location. - Remove user vimrc file line from :version message. --- src/nvim/main.c | 23 ++--------- src/nvim/option.c | 15 ++++++++ src/nvim/options.lua | 10 ++--- src/nvim/os/os.h | 1 + src/nvim/os/stdpaths.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++++ src/nvim/os/unix_defs.h | 29 -------------- src/nvim/os/win_defs.h | 1 - src/nvim/version.c | 15 -------- 8 files changed, 125 insertions(+), 69 deletions(-) create mode 100644 src/nvim/os/stdpaths.c (limited to 'src') diff --git a/src/nvim/main.c b/src/nvim/main.c index d865260295..c1a8d3ad75 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -1840,16 +1840,9 @@ static void source_startup_scripts(mparm_T *parmp) * - second user exrc file ($VIM/.exrc for Dos) * The first that exists is used, the rest is ignored. */ + char_u *user_vimrc = (char_u *)get_from_user_conf("init.vim"); if (process_env("VIMINIT", true) != OK) { - if (do_source((char_u *)USR_VIMRC_FILE, TRUE, DOSO_VIMRC) == FAIL -#ifdef USR_VIMRC_FILE2 - && do_source((char_u *)USR_VIMRC_FILE2, TRUE, - DOSO_VIMRC) == FAIL -#endif -#ifdef USR_VIMRC_FILE3 - && do_source((char_u *)USR_VIMRC_FILE3, TRUE, - DOSO_VIMRC) == FAIL -#endif + if (do_source(user_vimrc, true, DOSO_VIMRC) == FAIL && process_env("EXINIT", FALSE) == FAIL && do_source((char_u *)USR_EXRC_FILE, FALSE, DOSO_NONE) == FAIL) { #ifdef USR_EXRC_FILE2 @@ -1875,16 +1868,8 @@ static void source_startup_scripts(mparm_T *parmp) secure = p_secure; i = FAIL; - if (path_full_compare((char_u *)USR_VIMRC_FILE, - (char_u *)VIMRC_FILE, FALSE) != kEqualFiles -#ifdef USR_VIMRC_FILE2 - && path_full_compare((char_u *)USR_VIMRC_FILE2, - (char_u *)VIMRC_FILE, FALSE) != kEqualFiles -#endif -#ifdef USR_VIMRC_FILE3 - && path_full_compare((char_u *)USR_VIMRC_FILE3, - (char_u *)VIMRC_FILE, FALSE) != kEqualFiles -#endif + if (path_full_compare(user_vimrc, + (char_u *)VIMRC_FILE, false) != kEqualFiles #ifdef SYS_VIMRC_FILE && path_full_compare((char_u *)SYS_VIMRC_FILE, (char_u *)VIMRC_FILE, FALSE) != kEqualFiles diff --git a/src/nvim/option.c b/src/nvim/option.c index a578f2bb01..c419e58f7e 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -301,6 +301,15 @@ static char *(p_cot_values[]) = {"menu", "menuone", "longest", "preview", # include "option.c.generated.h" #endif +static void set_runtimepath_default(void) +{ + garray_T rtp_ga; + ga_init(&rtp_ga, (int)sizeof(const char *), 1); + GA_APPEND(const char *, &rtp_ga, get_user_conf_dir()); + GA_APPEND(const char *, &rtp_ga, concat_fnames(get_user_conf_dir(), "after", true)); + set_string_default("runtimepath", ga_concat_strings(&rtp_ga)); +} + /* * Initialize the options, first part. * @@ -437,6 +446,12 @@ void set_init_1(void) "system('lpr' . (&printdevice == '' ? '' : ' -P' . &printdevice) . ' ' . v:fname_in) . delete(v:fname_in) + v:shell_error" ); + set_string_default("viewdir", (char_u *)get_from_user_data("view")); + set_string_default("backupdir", (char_u *)get_from_user_data("backup")); + set_string_default("directory", (char_u *)get_from_user_data("swap")); + set_string_default("undodir", (char_u *)get_from_user_data("undo")); + set_runtimepath_default(); + /* * Set all the options (except the terminal options) to their default * value. Also set the global value for local options. diff --git a/src/nvim/options.lua b/src/nvim/options.lua index 842b0a7c82..633eabab60 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -176,7 +176,7 @@ return { vi_def=true, expand=true, varname='p_bdir', - defaults={if_true={vi=macros('DFLT_BDIR')}} + defaults={if_true={vi=''}} }, { full_name='backupext', abbreviation='bex', @@ -627,7 +627,7 @@ return { vi_def=true, expand=true, varname='p_dir', - defaults={if_true={vi=macros('DFLT_DIR')}} + defaults={if_true={vi=''}} }, { full_name='display', abbreviation='dy', @@ -1916,7 +1916,7 @@ return { vi_def=true, expand=true, varname='p_rtp', - defaults={if_true={vi=macros('DFLT_RUNTIMEPATH')}} + defaults={if_true={vi=''}} }, { full_name='scroll', abbreviation='scr', @@ -2524,7 +2524,7 @@ return { vi_def=true, expand=true, varname='p_udir', - defaults={if_true={vi="."}} + defaults={if_true={vi=''}} }, { full_name='undofile', abbreviation='udf', @@ -2585,7 +2585,7 @@ return { vi_def=true, expand=true, varname='p_vdir', - defaults={if_true={vi=macros('DFLT_VDIR')}} + defaults={if_true={vi=''}} }, { full_name='viewoptions', abbreviation='vop', diff --git a/src/nvim/os/os.h b/src/nvim/os/os.h index 69bd1ff4fd..198f9ae897 100644 --- a/src/nvim/os/os.h +++ b/src/nvim/os/os.h @@ -12,6 +12,7 @@ # include "os/mem.h.generated.h" # include "os/env.h.generated.h" # include "os/users.h.generated.h" +# include "os/stdpaths.h.generated.h" #endif #endif // NVIM_OS_OS_H diff --git a/src/nvim/os/stdpaths.c b/src/nvim/os/stdpaths.c new file mode 100644 index 0000000000..230e760d7d --- /dev/null +++ b/src/nvim/os/stdpaths.c @@ -0,0 +1,100 @@ +#include "nvim/os/os.h" +#include "nvim/strings.h" +#include "nvim/path.h" +#include "nvim/garray.h" + +typedef enum { + kXDGConfigHome, + kXDGDataHome, + kXDGCacheHome, + kXDGRuntimeDir, + kXDGConfigDirs, + kXDGDataDirs, +} XDGDirType; + +static const char *xdg_env_vars[] = { + [kXDGConfigHome] = "XDG_CONFIG_HOME", + [kXDGDataHome] = "XDG_DATA_HOME", + [kXDGCacheHome] = "XDG_CACHE_HOME", + [kXDGRuntimeDir] = "XDG_RUNTIME_DIR", + [kXDGConfigDirs] = "XDG_CONFIG_DIRS", + [kXDGDataDirs] = "XDG_DATA_DIRS", +}; + +static const char *const xdg_defaults[] = { + // Windows, Apple stuff are just shims right now +#ifdef WIN32 + // Windows +#elif APPLE + // Apple (this includes iOS, which we might need to handle differently) + [kXDGConfigHome] = "~/Library/Preferences", + [kXDGDataHome] = "~/Library/Application Support", + [kXDGCacheHome] = "~/Library/Caches", + [kXDGRuntimeDir] = "~/Library/Application Support", + [kXDGConfigDirs] = "/Library/Application Support", + [kXDGDataDirs] = "/Library/Application Support", +#else + // Linux, BSD, CYGWIN + [kXDGConfigHome] = "~/.config", + [kXDGDataHome] = "~/.local/share", + [kXDGCacheHome] = "~/.cache", + [kXDGRuntimeDir] = "", + [kXDGConfigDirs] = "/etc/xdg/", + [kXDGDataDirs] = "/usr/local/share/:/usr/share/", +}; +#endif + +static const char *get_xdg(XDGDirType idx) +{ + const char *env = xdg_env_vars[idx]; + const char *fallback = xdg_defaults[idx]; + + const char *ret = os_getenv(env); + if (!ret && fallback) { + ret = (const char *)expand_env_save((char_u *)fallback); + } + + return ret; +} + +static const char *get_xdg_home(XDGDirType idx) +{ + const char *dir = get_xdg(idx); + if (dir) { + dir = (const char *)concat_fnames(dir, "nvim", true); + } + return dir; +} + +static void create_dir(const char *dir, int mode, const char *suffix) +{ + char *failed; + if (!os_mkdir_recurse(dir, mode, &failed)) { + // TODO: Create a folder in $TMPDIR instead + DLOG("Create dir failed"); + } +} + +const char *get_user_conf_dir(void) +{ + return get_xdg_home(kXDGConfigHome); +} + +const char *get_from_user_conf(const char * fname) +{ + return (const char *)concat_fnames(get_user_conf_dir(), fname, true); +} + +const char *get_user_data_dir(void) +{ + return get_xdg_home(kXDGDataHome); +} + +const char *get_from_user_data(const char * fname) +{ + const char *dir = (const char *)concat_fnames(get_user_data_dir(), fname, true); + if (!os_isdir((char_u *)dir)) { + create_dir(dir, 0755, fname); + } + return dir; +} diff --git a/src/nvim/os/unix_defs.h b/src/nvim/os/unix_defs.h index 949973bf40..83c6752ff7 100644 --- a/src/nvim/os/unix_defs.h +++ b/src/nvim/os/unix_defs.h @@ -31,12 +31,6 @@ #ifndef USR_EXRC_FILE # define USR_EXRC_FILE "~/.exrc" #endif -#ifndef USR_VIMRC_FILE -# define USR_VIMRC_FILE "~/.nvimrc" -#endif -#ifndef USR_VIMRC_FILE2 -# define USR_VIMRC_FILE2 "~/.nvim/nvimrc" -#endif #ifndef EXRC_FILE # define EXRC_FILE ".exrc" #endif @@ -47,27 +41,4 @@ # define SHADA_FILE "~/.nvim/shada/main.shada" #endif -// Default for 'backupdir'. -#ifndef DFLT_BDIR -# define DFLT_BDIR ".,~/tmp,~/" -#endif - -// Default for 'directory'. -#ifndef DFLT_DIR -# define DFLT_DIR ".,~/tmp,/var/tmp,/tmp" -#endif - -// Default for 'viewdir'. -#ifndef DFLT_VDIR -# define DFLT_VDIR "~/.nvim/view" -#endif - -#ifdef RUNTIME_GLOBAL -# define DFLT_RUNTIMEPATH "~/.nvim," RUNTIME_GLOBAL ",$VIMRUNTIME," \ - RUNTIME_GLOBAL "/after,~/.nvim/after" -#else -# define DFLT_RUNTIMEPATH \ - "~/.nvim,$VIM/vimfiles,$VIMRUNTIME,$VIM/vimfiles/after,~/.nvim/after" -#endif - #endif // NVIM_OS_UNIX_DEFS_H diff --git a/src/nvim/os/win_defs.h b/src/nvim/os/win_defs.h index b7ec50a109..62889a7d2f 100644 --- a/src/nvim/os/win_defs.h +++ b/src/nvim/os/win_defs.h @@ -8,7 +8,6 @@ // Defines needed to fix the build on Windows: // - USR_EXRC_FILE -// - USR_VIMRC_FILE // - SHADA_FILE // - DFLT_DIR // - DFLT_BDIR diff --git a/src/nvim/version.c b/src/nvim/version.c index 961c017bd5..9cfda96c16 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -1067,21 +1067,6 @@ void list_version(void) version_msg(SYS_VIMRC_FILE); version_msg("\"\n"); #endif // ifdef SYS_VIMRC_FILE -#ifdef USR_VIMRC_FILE - version_msg(_(" user vimrc file: \"")); - version_msg(USR_VIMRC_FILE); - version_msg("\"\n"); -#endif // ifdef USR_VIMRC_FILE -#ifdef USR_VIMRC_FILE2 - version_msg(_(" 2nd user vimrc file: \"")); - version_msg(USR_VIMRC_FILE2); - version_msg("\"\n"); -#endif // ifdef USR_VIMRC_FILE2 -#ifdef USR_VIMRC_FILE3 - version_msg(_(" 3rd user vimrc file: \"")); - version_msg(USR_VIMRC_FILE3); - version_msg("\"\n"); -#endif // ifdef USR_VIMRC_FILE3 #ifdef USR_EXRC_FILE version_msg(_(" user exrc file: \"")); version_msg(USR_EXRC_FILE); -- cgit From 674629be0c8bc02d79d263b1b795ab125e1341e0 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 1 Aug 2015 01:51:19 +0300 Subject: os/env: Add functions that can iterate over colon-separated variables --- src/nvim/os/env.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) (limited to 'src') diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c index 7be8a868bd..bdf406af5e 100644 --- a/src/nvim/os/env.c +++ b/src/nvim/os/env.c @@ -415,6 +415,74 @@ static char *remove_tail(char *p, char *pend, char *name) return pend; } +/// Iterate over colon-separated list +/// +/// @note Environment variables must not be modified during iteration. +/// +/// @param[in] val Value of the environment variable to iterate over. +/// @param[in] iter Pointer used for iteration. Must be NULL on first +/// iteration. +/// @param[out] dir Location where pointer to the start of the current +/// directory name should be saved. May be set to NULL. +/// @param[out] len Location where current directory length should be saved. +/// +/// @return Next iter argument value or NULL when iteration should stop. +const void *vim_colon_env_iter(const char *const val, + const void *const iter, + const char **const dir, + size_t *const len) + FUNC_ATTR_NONNULL_ARG(1,3,4) FUNC_ATTR_WARN_UNUSED_RESULT +{ + const char *varval = (const char *) iter; + if (varval == NULL) { + varval = val; + } + *dir = varval; + const char *const dirend = strchr(varval, ':'); + if (dirend == NULL) { + *len = strlen(varval); + return NULL; + } else { + *len = (size_t) (dirend - varval); + return dirend + 1; + } +} + +/// Iterate over colon-separated list in reverse order +/// +/// @note Environment variables must not be modified during iteration. +/// +/// @param[in] val Value of the environment variable to iterate over. +/// @param[in] iter Pointer used for iteration. Must be NULL on first +/// iteration. +/// @param[out] dir Location where pointer to the start of the current +/// directory name should be saved. May be set to NULL. +/// @param[out] len Location where current directory length should be saved. +/// +/// @return Next iter argument value or NULL when iteration should stop. +const void *vim_colon_env_iter_rev(const char *const val, + const void *const iter, + const char **const dir, + size_t *const len) + FUNC_ATTR_NONNULL_ARG(1,3,4) FUNC_ATTR_WARN_UNUSED_RESULT +{ + const char *varend = (const char *) iter; + if (varend == NULL) { + varend = val + strlen(val) - 1; + } + const size_t varlen = (size_t) (varend - val) + 1; + const char *const colon = xmemrchr(val, ':', varlen); + if (colon == NULL) { + *len = varlen; + *dir = val; + return NULL; + } else { + *dir = colon + 1; + *len = (size_t) (varend - colon); + return colon - 1; + } +} + /// Vim's version of getenv(). /// Special handling of $HOME, $VIM and $VIMRUNTIME, allowing the user to /// override the vim runtime directory at runtime. Also does ACP to 'enc' -- cgit From 76e2788d87f8474055536efbbc4827ddf290bc89 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 1 Aug 2015 03:04:28 +0300 Subject: option: Use different default value for &runtimepath --- src/nvim/option.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++--- src/nvim/os/win_defs.h | 1 - 2 files changed, 81 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/nvim/option.c b/src/nvim/option.c index c419e58f7e..5d614e4367 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -301,13 +301,87 @@ static char *(p_cot_values[]) = {"menu", "menuone", "longest", "preview", # include "option.c.generated.h" #endif +/// Set &runtimepath to default value static void set_runtimepath_default(void) { - garray_T rtp_ga; - ga_init(&rtp_ga, (int)sizeof(const char *), 1); - GA_APPEND(const char *, &rtp_ga, get_user_conf_dir()); - GA_APPEND(const char *, &rtp_ga, concat_fnames(get_user_conf_dir(), "after", true)); - set_string_default("runtimepath", ga_concat_strings(&rtp_ga)); + size_t rtp_size = 0; + char *const data_home = vim_getenv("XDG_DATA_HOME"); + char *const config_home = vim_getenv("XDG_CONFIG_HOME"); + char *const vimruntime = vim_getenv("VIMRUNTIME"); + char *const data_dirs = vim_getenv("XDG_DATA_DIRS"); + char *const config_dirs = vim_getenv("XDG_CONFIG_DIRS"); + assert(data_home != NULL); + assert(config_home != NULL); + assert(vimruntime != NULL); + assert(data_dirs != NULL); + assert(config_dirs != NULL); +#define NVIM_SIZE (sizeof("/nvim") - 1) +#define AFTER_SIZE (sizeof("/after") - 1) + const size_t data_len = strlen(data_home); + const size_t config_len = strlen(config_home); + const size_t vimruntime_len = strlen(vimruntime); + rtp_size += ((data_len + NVIM_SIZE) * 2 + AFTER_SIZE) + 2; + rtp_size += ((config_len + NVIM_SIZE) * 2 + AFTER_SIZE) + 2; + rtp_size += vimruntime_len; +#define COMPUTE_COLON_LEN(rtp_size, val) \ + do { \ + const void *iter = NULL; \ + do { \ + size_t dir_len; \ + const char *dir; \ + iter = vim_colon_env_iter(val, iter, &dir, &dir_len); \ + if (dir != NULL && dir_len > 0) { \ + rtp_size += ((dir_len + NVIM_SIZE) * 2 + AFTER_SIZE) + 2; \ + } \ + } while (iter != NULL); \ + } while (0) + COMPUTE_COLON_LEN(rtp_size, data_dirs); + COMPUTE_COLON_LEN(rtp_size, config_dirs); +#undef COMPUTE_COLON_LEN + char *const rtp = xmallocz(rtp_size); + char *rtp_cur = rtp; +#define ADD_STRING(tgt, src, len) \ + do { memmove(tgt, src, len); tgt += len; } while (0) +#define ADD_STATIC_STRING(tgt, str) \ + ADD_STRING(tgt, str, sizeof(str) - 1) +#define ADD_COLON_DIRS(tgt, val, suffix, revsuffix) \ + do { \ + const void *iter = NULL; \ + do { \ + size_t dir_len; \ + const char *dir; \ + iter = vim_colon_env_iter##revsuffix(val, iter, &dir, &dir_len); \ + if (dir != NULL && dir_len > 0) { \ + ADD_STRING(rtp_cur, dir, dir_len); \ + ADD_STATIC_STRING(rtp_cur, "/nvim" suffix ","); \ + } \ + } while (iter != NULL); \ + } while (0) + ADD_STRING(rtp_cur, config_home, config_len); + ADD_STATIC_STRING(rtp_cur, "/nvim,"); + ADD_STRING(rtp_cur, data_home, data_len); + ADD_STATIC_STRING(rtp_cur, "/nvim,"); + ADD_COLON_DIRS(rtp_cur, config_dirs, "", ); + ADD_COLON_DIRS(rtp_cur, data_dirs, "", ); + ADD_STRING(rtp_cur, vimruntime, vimruntime_len); + *rtp_cur++ = ','; + ADD_COLON_DIRS(rtp_cur, data_dirs, "/after", _rev); + ADD_COLON_DIRS(rtp_cur, config_dirs, "/after", _rev); + ADD_STRING(rtp_cur, data_home, data_len); + ADD_STATIC_STRING(rtp_cur, "/nvim/after,"); + ADD_STRING(rtp_cur, config_home, config_len); + ADD_STATIC_STRING(rtp_cur, "/nvim/after"); +#undef ADD_COLON_DIRS +#undef ADD_STATIC_STRING +#undef ADD_STRING +#undef NVIM_SIZE +#undef AFTER_SIZE + set_string_default("runtimepath", (char_u *)rtp); + xfree(data_dirs); + xfree(config_dirs); + xfree(data_home); + xfree(config_home); + xfree(vimruntime); } /* @@ -450,6 +524,8 @@ void set_init_1(void) set_string_default("backupdir", (char_u *)get_from_user_data("backup")); set_string_default("directory", (char_u *)get_from_user_data("swap")); set_string_default("undodir", (char_u *)get_from_user_data("undo")); + // Set default for &runtimepath. All necessary expansions are performed in + // this function. set_runtimepath_default(); /* diff --git a/src/nvim/os/win_defs.h b/src/nvim/os/win_defs.h index 62889a7d2f..427e6a8481 100644 --- a/src/nvim/os/win_defs.h +++ b/src/nvim/os/win_defs.h @@ -12,7 +12,6 @@ // - DFLT_DIR // - DFLT_BDIR // - DFLT_VDIR -// - DFLT_RUNTIMEPATH // - EXRC_FILE // - VIMRC_FILE // - SYNTAX_FNAME -- cgit From efb6045a00d6da77aea51547dcd8f01754b5179c Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 1 Aug 2015 03:14:58 +0300 Subject: option: Add /site subdirectory to data directories --- src/nvim/option.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/nvim/option.c b/src/nvim/option.c index 5d614e4367..e038205101 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -316,14 +316,15 @@ static void set_runtimepath_default(void) assert(data_dirs != NULL); assert(config_dirs != NULL); #define NVIM_SIZE (sizeof("/nvim") - 1) +#define SITE_SIZE (sizeof("/site") - 1) #define AFTER_SIZE (sizeof("/after") - 1) const size_t data_len = strlen(data_home); const size_t config_len = strlen(config_home); const size_t vimruntime_len = strlen(vimruntime); - rtp_size += ((data_len + NVIM_SIZE) * 2 + AFTER_SIZE) + 2; + rtp_size += ((data_len + NVIM_SIZE + SITE_SIZE) * 2 + AFTER_SIZE) + 2; rtp_size += ((config_len + NVIM_SIZE) * 2 + AFTER_SIZE) + 2; rtp_size += vimruntime_len; -#define COMPUTE_COLON_LEN(rtp_size, val) \ +#define COMPUTE_COLON_LEN(rtp_size, additional_size, val) \ do { \ const void *iter = NULL; \ do { \ @@ -331,12 +332,13 @@ static void set_runtimepath_default(void) const char *dir; \ iter = vim_colon_env_iter(val, iter, &dir, &dir_len); \ if (dir != NULL && dir_len > 0) { \ - rtp_size += ((dir_len + NVIM_SIZE) * 2 + AFTER_SIZE) + 2; \ + rtp_size += ((dir_len + NVIM_SIZE + additional_size) * 2 \ + + AFTER_SIZE) + 2; \ } \ } while (iter != NULL); \ } while (0) - COMPUTE_COLON_LEN(rtp_size, data_dirs); - COMPUTE_COLON_LEN(rtp_size, config_dirs); + COMPUTE_COLON_LEN(rtp_size, SITE_SIZE, data_dirs); + COMPUTE_COLON_LEN(rtp_size, 0, config_dirs); #undef COMPUTE_COLON_LEN char *const rtp = xmallocz(rtp_size); char *rtp_cur = rtp; @@ -360,21 +362,22 @@ static void set_runtimepath_default(void) ADD_STRING(rtp_cur, config_home, config_len); ADD_STATIC_STRING(rtp_cur, "/nvim,"); ADD_STRING(rtp_cur, data_home, data_len); - ADD_STATIC_STRING(rtp_cur, "/nvim,"); + ADD_STATIC_STRING(rtp_cur, "/nvim/site,"); ADD_COLON_DIRS(rtp_cur, config_dirs, "", ); - ADD_COLON_DIRS(rtp_cur, data_dirs, "", ); + ADD_COLON_DIRS(rtp_cur, data_dirs, "/site", ); ADD_STRING(rtp_cur, vimruntime, vimruntime_len); *rtp_cur++ = ','; - ADD_COLON_DIRS(rtp_cur, data_dirs, "/after", _rev); + ADD_COLON_DIRS(rtp_cur, data_dirs, "/site/after", _rev); ADD_COLON_DIRS(rtp_cur, config_dirs, "/after", _rev); ADD_STRING(rtp_cur, data_home, data_len); - ADD_STATIC_STRING(rtp_cur, "/nvim/after,"); + ADD_STATIC_STRING(rtp_cur, "/nvim/site/after,"); ADD_STRING(rtp_cur, config_home, config_len); ADD_STATIC_STRING(rtp_cur, "/nvim/after"); #undef ADD_COLON_DIRS #undef ADD_STATIC_STRING #undef ADD_STRING #undef NVIM_SIZE +#undef SITE_SIZE #undef AFTER_SIZE set_string_default("runtimepath", (char_u *)rtp); xfree(data_dirs); -- cgit From ee95f818a66d8d46ebb237260d6edcb20b10ac61 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 1 Aug 2015 16:32:44 +0300 Subject: option: Move all data directories after all config directories --- src/nvim/option.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/option.c b/src/nvim/option.c index e038205101..2e17708f93 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -361,16 +361,16 @@ static void set_runtimepath_default(void) } while (0) ADD_STRING(rtp_cur, config_home, config_len); ADD_STATIC_STRING(rtp_cur, "/nvim,"); + ADD_COLON_DIRS(rtp_cur, config_dirs, "", ); ADD_STRING(rtp_cur, data_home, data_len); ADD_STATIC_STRING(rtp_cur, "/nvim/site,"); - ADD_COLON_DIRS(rtp_cur, config_dirs, "", ); ADD_COLON_DIRS(rtp_cur, data_dirs, "/site", ); ADD_STRING(rtp_cur, vimruntime, vimruntime_len); *rtp_cur++ = ','; ADD_COLON_DIRS(rtp_cur, data_dirs, "/site/after", _rev); - ADD_COLON_DIRS(rtp_cur, config_dirs, "/after", _rev); ADD_STRING(rtp_cur, data_home, data_len); ADD_STATIC_STRING(rtp_cur, "/nvim/site/after,"); + ADD_COLON_DIRS(rtp_cur, config_dirs, "/after", _rev); ADD_STRING(rtp_cur, config_home, config_len); ADD_STATIC_STRING(rtp_cur, "/nvim/after"); #undef ADD_COLON_DIRS -- cgit From ab2944f46cbe53d66ae7edf7b21eaf9bec4e7b22 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 1 Aug 2015 18:53:39 +0300 Subject: option: Prepare for all environment variables being NULL. --- src/nvim/option.c | 108 +++++++++++++++++++++++++++++++++--------------------- 1 file changed, 67 insertions(+), 41 deletions(-) (limited to 'src') diff --git a/src/nvim/option.c b/src/nvim/option.c index 2e17708f93..ae1c083f00 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -310,36 +310,47 @@ static void set_runtimepath_default(void) char *const vimruntime = vim_getenv("VIMRUNTIME"); char *const data_dirs = vim_getenv("XDG_DATA_DIRS"); char *const config_dirs = vim_getenv("XDG_CONFIG_DIRS"); - assert(data_home != NULL); - assert(config_home != NULL); - assert(vimruntime != NULL); - assert(data_dirs != NULL); - assert(config_dirs != NULL); #define NVIM_SIZE (sizeof("/nvim") - 1) #define SITE_SIZE (sizeof("/site") - 1) #define AFTER_SIZE (sizeof("/after") - 1) - const size_t data_len = strlen(data_home); - const size_t config_len = strlen(config_home); - const size_t vimruntime_len = strlen(vimruntime); - rtp_size += ((data_len + NVIM_SIZE + SITE_SIZE) * 2 + AFTER_SIZE) + 2; - rtp_size += ((config_len + NVIM_SIZE) * 2 + AFTER_SIZE) + 2; - rtp_size += vimruntime_len; + size_t data_len; + size_t config_len; + size_t vimruntime_len; + if (data_home != NULL) { + data_len = strlen(data_home); + rtp_size += ((data_len + NVIM_SIZE + SITE_SIZE) * 2 + AFTER_SIZE) + 2; + } + if (config_home != NULL) { + config_len = strlen(config_home); + rtp_size += ((config_len + NVIM_SIZE) * 2 + AFTER_SIZE) + 2; + } + if (vimruntime != NULL) { + vimruntime_len = strlen(vimruntime); + rtp_size += vimruntime_len + 1; + } #define COMPUTE_COLON_LEN(rtp_size, additional_size, val) \ do { \ - const void *iter = NULL; \ - do { \ - size_t dir_len; \ - const char *dir; \ - iter = vim_colon_env_iter(val, iter, &dir, &dir_len); \ - if (dir != NULL && dir_len > 0) { \ - rtp_size += ((dir_len + NVIM_SIZE + additional_size) * 2 \ - + AFTER_SIZE) + 2; \ - } \ - } while (iter != NULL); \ + if (val != NULL) { \ + const void *iter = NULL; \ + do { \ + size_t dir_len; \ + const char *dir; \ + iter = vim_colon_env_iter(val, iter, &dir, &dir_len); \ + if (dir != NULL && dir_len > 0) { \ + rtp_size += ((dir_len + NVIM_SIZE + additional_size) * 2 \ + + AFTER_SIZE) + 2; \ + } \ + } while (iter != NULL); \ + } \ } while (0) COMPUTE_COLON_LEN(rtp_size, SITE_SIZE, data_dirs); COMPUTE_COLON_LEN(rtp_size, 0, config_dirs); #undef COMPUTE_COLON_LEN + if (rtp_size == 0) { + return; + } + // All additions were including comma. + rtp_size--; char *const rtp = xmallocz(rtp_size); char *rtp_cur = rtp; #define ADD_STRING(tgt, src, len) \ @@ -348,31 +359,46 @@ static void set_runtimepath_default(void) ADD_STRING(tgt, str, sizeof(str) - 1) #define ADD_COLON_DIRS(tgt, val, suffix, revsuffix) \ do { \ - const void *iter = NULL; \ - do { \ - size_t dir_len; \ - const char *dir; \ - iter = vim_colon_env_iter##revsuffix(val, iter, &dir, &dir_len); \ - if (dir != NULL && dir_len > 0) { \ - ADD_STRING(rtp_cur, dir, dir_len); \ - ADD_STATIC_STRING(rtp_cur, "/nvim" suffix ","); \ - } \ - } while (iter != NULL); \ + if (val != NULL) { \ + const void *iter = NULL; \ + do { \ + size_t dir_len; \ + const char *dir; \ + iter = vim_colon_env_iter##revsuffix(val, iter, &dir, &dir_len); \ + if (dir != NULL && dir_len > 0) { \ + ADD_STRING(rtp_cur, dir, dir_len); \ + ADD_STATIC_STRING(rtp_cur, "/nvim" suffix ","); \ + } \ + } while (iter != NULL); \ + } \ } while (0) - ADD_STRING(rtp_cur, config_home, config_len); - ADD_STATIC_STRING(rtp_cur, "/nvim,"); + if (config_home != NULL) { + ADD_STRING(rtp_cur, config_home, config_len); + ADD_STATIC_STRING(rtp_cur, "/nvim,"); + } ADD_COLON_DIRS(rtp_cur, config_dirs, "", ); - ADD_STRING(rtp_cur, data_home, data_len); - ADD_STATIC_STRING(rtp_cur, "/nvim/site,"); + if (data_home != NULL) { + ADD_STRING(rtp_cur, data_home, data_len); + ADD_STATIC_STRING(rtp_cur, "/nvim/site,"); + } ADD_COLON_DIRS(rtp_cur, data_dirs, "/site", ); - ADD_STRING(rtp_cur, vimruntime, vimruntime_len); - *rtp_cur++ = ','; + if (vimruntime != NULL) { + ADD_STRING(rtp_cur, vimruntime, vimruntime_len); + *rtp_cur++ = ','; + } ADD_COLON_DIRS(rtp_cur, data_dirs, "/site/after", _rev); - ADD_STRING(rtp_cur, data_home, data_len); - ADD_STATIC_STRING(rtp_cur, "/nvim/site/after,"); + if (data_home != NULL) { + ADD_STRING(rtp_cur, data_home, data_len); + ADD_STATIC_STRING(rtp_cur, "/nvim/site/after,"); + } ADD_COLON_DIRS(rtp_cur, config_dirs, "/after", _rev); - ADD_STRING(rtp_cur, config_home, config_len); - ADD_STATIC_STRING(rtp_cur, "/nvim/after"); + if (config_home != NULL) { + ADD_STRING(rtp_cur, config_home, config_len); + ADD_STATIC_STRING(rtp_cur, "/nvim/after"); + } else { + // Strip trailing comma. + rtp[rtp_size - 1] = NUL; + } #undef ADD_COLON_DIRS #undef ADD_STATIC_STRING #undef ADD_STRING -- cgit From 8e2c0fdba5cf8d7c0fe00ddda1ebe702e405d918 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 2 Aug 2015 09:35:37 +0300 Subject: option: Append with escaped commas --- src/nvim/option.c | 46 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/nvim/option.c b/src/nvim/option.c index ae1c083f00..97dc88833c 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -301,6 +301,33 @@ static char *(p_cot_values[]) = {"menu", "menuone", "longest", "preview", # include "option.c.generated.h" #endif +/// Count commas in the given string +static size_t count_commas(const char *const s, size_t len) + FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT +{ + size_t ret = 0; + for (size_t i = 0; i < len; i++) { + if (s[i] == ',') { + ret++; + } + } + return ret; +} + +/// Append string with escaped commas +static char *strcpy_comma_escaped(char *dest, const char *src, const size_t len) + FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT +{ + size_t shift = 0; + for (size_t i = 0; i < len; i++) { + if (src[i] == ',') { + dest[i + shift++] = '\\'; + } + dest[i + shift] = src[i]; + } + return &dest[len + shift]; +} + /// Set &runtimepath to default value static void set_runtimepath_default(void) { @@ -318,15 +345,17 @@ static void set_runtimepath_default(void) size_t vimruntime_len; if (data_home != NULL) { data_len = strlen(data_home); - rtp_size += ((data_len + NVIM_SIZE + SITE_SIZE) * 2 + AFTER_SIZE) + 2; + rtp_size += ((data_len + count_commas(data_home, data_len) + + NVIM_SIZE + SITE_SIZE) * 2 + AFTER_SIZE) + 2; } if (config_home != NULL) { config_len = strlen(config_home); - rtp_size += ((config_len + NVIM_SIZE) * 2 + AFTER_SIZE) + 2; + rtp_size += ((config_len + count_commas(config_home, config_len) + + NVIM_SIZE) * 2 + AFTER_SIZE) + 2; } if (vimruntime != NULL) { vimruntime_len = strlen(vimruntime); - rtp_size += vimruntime_len + 1; + rtp_size += vimruntime_len + count_commas(vimruntime, vimruntime_len) + 1; } #define COMPUTE_COLON_LEN(rtp_size, additional_size, val) \ do { \ @@ -337,7 +366,8 @@ static void set_runtimepath_default(void) const char *dir; \ iter = vim_colon_env_iter(val, iter, &dir, &dir_len); \ if (dir != NULL && dir_len > 0) { \ - rtp_size += ((dir_len + NVIM_SIZE + additional_size) * 2 \ + rtp_size += ((dir_len + count_commas(dir, dir_len) \ + + NVIM_SIZE + additional_size) * 2 \ + AFTER_SIZE) + 2; \ } \ } while (iter != NULL); \ @@ -354,9 +384,9 @@ static void set_runtimepath_default(void) char *const rtp = xmallocz(rtp_size); char *rtp_cur = rtp; #define ADD_STRING(tgt, src, len) \ - do { memmove(tgt, src, len); tgt += len; } while (0) -#define ADD_STATIC_STRING(tgt, str) \ - ADD_STRING(tgt, str, sizeof(str) - 1) + tgt = strcpy_comma_escaped(tgt, src, len) +#define ADD_STATIC_STRING(tgt, src) \ + do { memmove(tgt, src, sizeof(src) - 1); tgt += sizeof(src) - 1; } while (0) #define ADD_COLON_DIRS(tgt, val, suffix, revsuffix) \ do { \ if (val != NULL) { \ @@ -397,7 +427,7 @@ static void set_runtimepath_default(void) ADD_STATIC_STRING(rtp_cur, "/nvim/after"); } else { // Strip trailing comma. - rtp[rtp_size - 1] = NUL; + rtp[rtp_size] = NUL; } #undef ADD_COLON_DIRS #undef ADD_STATIC_STRING -- cgit From 1db5a807b203634de608f68e76387fcf0a7857d7 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 17 Oct 2015 14:17:16 +0300 Subject: stdpaths: Fix some issues, specifically - Remove/add includes - Do not pretend that returns are const - Add function attributes - Allocate memory always in get_xdg --- src/nvim/os/stdpaths.c | 45 ++++++++++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/nvim/os/stdpaths.c b/src/nvim/os/stdpaths.c index 230e760d7d..e8cfba8b3a 100644 --- a/src/nvim/os/stdpaths.c +++ b/src/nvim/os/stdpaths.c @@ -1,7 +1,8 @@ +#include + #include "nvim/os/os.h" -#include "nvim/strings.h" #include "nvim/path.h" -#include "nvim/garray.h" +#include "nvim/memory.h" typedef enum { kXDGConfigHome, @@ -44,29 +45,35 @@ static const char *const xdg_defaults[] = { }; #endif -static const char *get_xdg(XDGDirType idx) +static char *get_xdg(const XDGDirType idx) + FUNC_ATTR_WARN_UNUSED_RESULT { - const char *env = xdg_env_vars[idx]; - const char *fallback = xdg_defaults[idx]; + const char *const env = xdg_env_vars[idx]; + const char *const fallback = xdg_defaults[idx]; - const char *ret = os_getenv(env); - if (!ret && fallback) { - ret = (const char *)expand_env_save((char_u *)fallback); + const char *const env_val = os_getenv(env); + char *ret = NULL; + if (env_val != NULL) { + ret = xstrdup(env_val); + } else if (fallback) { + ret = (char *) expand_env_save((char_u *)fallback); } return ret; } -static const char *get_xdg_home(XDGDirType idx) +static char *get_xdg_home(XDGDirType idx) + FUNC_ATTR_WARN_UNUSED_RESULT { - const char *dir = get_xdg(idx); + char *dir = get_xdg(idx); if (dir) { - dir = (const char *)concat_fnames(dir, "nvim", true); + dir = concat_fnames(dir, "nvim", true); } return dir; } static void create_dir(const char *dir, int mode, const char *suffix) + FUNC_ATTR_NONNULL_ALL { char *failed; if (!os_mkdir_recurse(dir, mode, &failed)) { @@ -75,24 +82,28 @@ static void create_dir(const char *dir, int mode, const char *suffix) } } -const char *get_user_conf_dir(void) +char *get_user_conf_dir(void) + FUNC_ATTR_WARN_UNUSED_RESULT { return get_xdg_home(kXDGConfigHome); } -const char *get_from_user_conf(const char * fname) +char *get_from_user_conf(const char *fname) + FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL { - return (const char *)concat_fnames(get_user_conf_dir(), fname, true); + return concat_fnames(get_user_conf_dir(), fname, true); } -const char *get_user_data_dir(void) +char *get_user_data_dir(void) + FUNC_ATTR_WARN_UNUSED_RESULT { return get_xdg_home(kXDGDataHome); } -const char *get_from_user_data(const char * fname) +char *get_from_user_data(const char *fname) + FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL { - const char *dir = (const char *)concat_fnames(get_user_data_dir(), fname, true); + char *dir = concat_fnames(get_user_data_dir(), fname, true); if (!os_isdir((char_u *)dir)) { create_dir(dir, 0755, fname); } -- cgit From 120ec8c2eab21dc44baa0c4814cb004fd3db6e54 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 17 Oct 2015 14:37:13 +0300 Subject: stdpaths: Remove useless functions get_user_*_dir --- src/nvim/os/stdpaths.c | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/nvim/os/stdpaths.c b/src/nvim/os/stdpaths.c index e8cfba8b3a..0380c9ea37 100644 --- a/src/nvim/os/stdpaths.c +++ b/src/nvim/os/stdpaths.c @@ -11,7 +11,7 @@ typedef enum { kXDGRuntimeDir, kXDGConfigDirs, kXDGDataDirs, -} XDGDirType; +} XDGVarType; static const char *xdg_env_vars[] = { [kXDGConfigHome] = "XDG_CONFIG_HOME", @@ -45,7 +45,7 @@ static const char *const xdg_defaults[] = { }; #endif -static char *get_xdg(const XDGDirType idx) +static char *get_xdg(const XDGVarType idx) FUNC_ATTR_WARN_UNUSED_RESULT { const char *const env = xdg_env_vars[idx]; @@ -62,7 +62,7 @@ static char *get_xdg(const XDGDirType idx) return ret; } -static char *get_xdg_home(XDGDirType idx) +static char *get_xdg_home(const XDGVarType idx) FUNC_ATTR_WARN_UNUSED_RESULT { char *dir = get_xdg(idx); @@ -82,28 +82,16 @@ static void create_dir(const char *dir, int mode, const char *suffix) } } -char *get_user_conf_dir(void) - FUNC_ATTR_WARN_UNUSED_RESULT -{ - return get_xdg_home(kXDGConfigHome); -} - char *get_from_user_conf(const char *fname) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL { - return concat_fnames(get_user_conf_dir(), fname, true); -} - -char *get_user_data_dir(void) - FUNC_ATTR_WARN_UNUSED_RESULT -{ - return get_xdg_home(kXDGDataHome); + return concat_fnames(get_xdg_home(kXDGConfigHome), fname, true); } char *get_from_user_data(const char *fname) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL { - char *dir = concat_fnames(get_user_data_dir(), fname, true); + char *dir = concat_fnames(get_xdg_home(kXDGDataHome), fname, true); if (!os_isdir((char_u *)dir)) { create_dir(dir, 0755, fname); } -- cgit From afb0f2f9b14f0ebcb5c53a47338a6a4359019e38 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 17 Oct 2015 14:40:27 +0300 Subject: stdpaths: Rename export functions so that they have common prefix --- src/nvim/main.c | 2 +- src/nvim/option.c | 11 ++++++----- src/nvim/os/stdpaths.c | 4 ++-- 3 files changed, 9 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/nvim/main.c b/src/nvim/main.c index c1a8d3ad75..0e250de8ca 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -1840,7 +1840,7 @@ static void source_startup_scripts(mparm_T *parmp) * - second user exrc file ($VIM/.exrc for Dos) * The first that exists is used, the rest is ignored. */ - char_u *user_vimrc = (char_u *)get_from_user_conf("init.vim"); + char_u *user_vimrc = (char_u *)stdpaths_user_conf_subpath("init.vim"); if (process_env("VIMINIT", true) != OK) { if (do_source(user_vimrc, true, DOSO_VIMRC) == FAIL && process_env("EXINIT", FALSE) == FAIL diff --git a/src/nvim/option.c b/src/nvim/option.c index 97dc88833c..c2236114d6 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -579,11 +579,12 @@ void set_init_1(void) "system('lpr' . (&printdevice == '' ? '' : ' -P' . &printdevice) . ' ' . v:fname_in) . delete(v:fname_in) + v:shell_error" ); - set_string_default("viewdir", (char_u *)get_from_user_data("view")); - set_string_default("backupdir", (char_u *)get_from_user_data("backup")); - set_string_default("directory", (char_u *)get_from_user_data("swap")); - set_string_default("undodir", (char_u *)get_from_user_data("undo")); - // Set default for &runtimepath. All necessary expansions are performed in + set_string_default("viewdir", (char_u *)stdpaths_user_data_subpath("view")); + set_string_default("backupdir", + (char_u *)stdpaths_user_data_subpath("backup")); + set_string_default("directory", (char_u *)stdpaths_user_data_subpath("swap")); + set_string_default("undodir", (char_u *)stdpaths_user_data_subpath("undo")); + // Set default for &runtimepath. All necessary expansions are performed in // this function. set_runtimepath_default(); diff --git a/src/nvim/os/stdpaths.c b/src/nvim/os/stdpaths.c index 0380c9ea37..b8ce400276 100644 --- a/src/nvim/os/stdpaths.c +++ b/src/nvim/os/stdpaths.c @@ -82,13 +82,13 @@ static void create_dir(const char *dir, int mode, const char *suffix) } } -char *get_from_user_conf(const char *fname) +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); } -char *get_from_user_data(const char *fname) +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); -- cgit From be91bc1e1a110da938201eab9b43736e64a7392e Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 17 Oct 2015 14:45:53 +0300 Subject: stdpaths: Export get_xdg function (renamed) and use it for runtimepath --- src/nvim/option.c | 8 ++++---- src/nvim/os/os.h | 1 + src/nvim/os/stdpaths.c | 14 +++----------- src/nvim/os/stdpaths_defs.h | 13 +++++++++++++ 4 files changed, 21 insertions(+), 15 deletions(-) create mode 100644 src/nvim/os/stdpaths_defs.h (limited to 'src') diff --git a/src/nvim/option.c b/src/nvim/option.c index c2236114d6..b879580ff1 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -332,11 +332,11 @@ static char *strcpy_comma_escaped(char *dest, const char *src, const size_t len) static void set_runtimepath_default(void) { size_t rtp_size = 0; - char *const data_home = vim_getenv("XDG_DATA_HOME"); - char *const config_home = vim_getenv("XDG_CONFIG_HOME"); + char *const data_home = stdpaths_get_xdg_var(kXDGDataHome); + char *const config_home = stdpaths_get_xdg_var(kXDGConfigHome); char *const vimruntime = vim_getenv("VIMRUNTIME"); - char *const data_dirs = vim_getenv("XDG_DATA_DIRS"); - char *const config_dirs = vim_getenv("XDG_CONFIG_DIRS"); + char *const data_dirs = stdpaths_get_xdg_var(kXDGDataDirs); + char *const config_dirs = stdpaths_get_xdg_var(kXDGConfigDirs); #define NVIM_SIZE (sizeof("/nvim") - 1) #define SITE_SIZE (sizeof("/site") - 1) #define AFTER_SIZE (sizeof("/after") - 1) diff --git a/src/nvim/os/os.h b/src/nvim/os/os.h index 198f9ae897..3e89e5a94a 100644 --- a/src/nvim/os/os.h +++ b/src/nvim/os/os.h @@ -5,6 +5,7 @@ #include #include "nvim/os/fs_defs.h" +#include "nvim/os/stdpaths_defs.h" #include "nvim/vim.h" #ifdef INCLUDE_GENERATED_DECLARATIONS diff --git a/src/nvim/os/stdpaths.c b/src/nvim/os/stdpaths.c index b8ce400276..86daa7257a 100644 --- a/src/nvim/os/stdpaths.c +++ b/src/nvim/os/stdpaths.c @@ -1,18 +1,10 @@ #include +#include "nvim/os/stdpaths_defs.h" #include "nvim/os/os.h" #include "nvim/path.h" #include "nvim/memory.h" -typedef enum { - kXDGConfigHome, - kXDGDataHome, - kXDGCacheHome, - kXDGRuntimeDir, - kXDGConfigDirs, - kXDGDataDirs, -} XDGVarType; - static const char *xdg_env_vars[] = { [kXDGConfigHome] = "XDG_CONFIG_HOME", [kXDGDataHome] = "XDG_DATA_HOME", @@ -45,7 +37,7 @@ static const char *const xdg_defaults[] = { }; #endif -static char *get_xdg(const XDGVarType idx) +char *stdpaths_get_xdg_var(const XDGVarType idx) FUNC_ATTR_WARN_UNUSED_RESULT { const char *const env = xdg_env_vars[idx]; @@ -65,7 +57,7 @@ static char *get_xdg(const XDGVarType idx) static char *get_xdg_home(const XDGVarType idx) FUNC_ATTR_WARN_UNUSED_RESULT { - char *dir = get_xdg(idx); + char *dir = stdpaths_get_xdg_var(idx); if (dir) { dir = concat_fnames(dir, "nvim", true); } diff --git a/src/nvim/os/stdpaths_defs.h b/src/nvim/os/stdpaths_defs.h new file mode 100644 index 0000000000..3b882cd582 --- /dev/null +++ b/src/nvim/os/stdpaths_defs.h @@ -0,0 +1,13 @@ +#ifndef NVIM_OS_STDPATHS_DEFS_H +#define NVIM_OS_STDPATHS_DEFS_H + +typedef enum { + kXDGConfigHome, + kXDGDataHome, + kXDGCacheHome, + kXDGRuntimeDir, + kXDGConfigDirs, + kXDGDataDirs, +} XDGVarType; + +#endif // NVIM_OS_STDPATHS_DEFS_H -- cgit From 642a07ce2770428e5114200b4292f5a76bb90fa2 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 17 Oct 2015 15:04:44 +0300 Subject: option: Remove some memory leaks --- src/nvim/option.c | 72 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 38 insertions(+), 34 deletions(-) (limited to 'src') diff --git a/src/nvim/option.c b/src/nvim/option.c index b879580ff1..7000fc4067 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -435,7 +435,7 @@ static void set_runtimepath_default(void) #undef NVIM_SIZE #undef SITE_SIZE #undef AFTER_SIZE - set_string_default("runtimepath", (char_u *)rtp); + set_string_default("runtimepath", rtp, true); xfree(data_dirs); xfree(config_dirs); xfree(data_home); @@ -450,7 +450,6 @@ static void set_runtimepath_default(void) */ void set_init_1(void) { - char_u *p; int opt_idx; langmap_init(); @@ -462,8 +461,12 @@ void set_init_1(void) * Find default value for 'shell' option. * Don't use it if it is empty. */ - if ((p = (char_u *)os_getenv("SHELL")) != NULL) - set_string_default("sh", p); + { + const char *shell = os_getenv("SHELL"); + if (shell != NULL) { + set_string_default("sh", (char *) shell, false); + } + } /* * Set the default for 'backupskip' to include environment variables for @@ -481,17 +484,18 @@ void set_init_1(void) ga_init(&ga, 1, 100); for (size_t n = 0; n < ARRAY_SIZE(names); ++n) { bool mustfree = true; + char *p; # ifdef UNIX if (*names[n] == NUL) { - p = (char_u *)"/tmp"; + p = "/tmp"; mustfree = false; } else # endif - p = (char_u *)vim_getenv(names[n]); + p = vim_getenv(names[n]); if (p != NULL && *p != NUL) { // First time count the NUL, otherwise count the ','. - len = (int)STRLEN(p) + 3; + len = (int)strlen(p) + 3; ga_grow(&ga, len); if (!GA_EMPTY(&ga)) STRCAT(ga.ga_data, ","); @@ -505,8 +509,7 @@ void set_init_1(void) } } if (ga.ga_data != NULL) { - set_string_default("bsk", ga.ga_data); - xfree(ga.ga_data); + set_string_default("bsk", ga.ga_data, true); } } @@ -567,23 +570,17 @@ void set_init_1(void) #if defined(MSWIN) || defined(MAC) /* Set print encoding on platforms that don't default to latin1 */ - set_string_default("penc", - (char_u *)"hp-roman8" - ); + set_string_default("penc", "hp-roman8", false); #endif /* 'printexpr' must be allocated to be able to evaluate it. */ - set_string_default( - "pexpr", - (char_u *) - "system('lpr' . (&printdevice == '' ? '' : ' -P' . &printdevice) . ' ' . v:fname_in) . delete(v:fname_in) + v:shell_error" - ); - - set_string_default("viewdir", (char_u *)stdpaths_user_data_subpath("view")); - set_string_default("backupdir", - (char_u *)stdpaths_user_data_subpath("backup")); - set_string_default("directory", (char_u *)stdpaths_user_data_subpath("swap")); - set_string_default("undodir", (char_u *)stdpaths_user_data_subpath("undo")); + set_string_default("pexpr", "system('lpr' . (&printdevice == '' ? '' : ' -P' . &printdevice) . ' ' . v:fname_in) . delete(v:fname_in) + v:shell_error", false); + + + set_string_default("viewdir", stdpaths_user_data_subpath("view"), true); + set_string_default("backupdir", stdpaths_user_data_subpath("backup"), true); + set_string_default("directory", stdpaths_user_data_subpath("swap"), true); + set_string_default("undodir", stdpaths_user_data_subpath("undo"), true); // Set default for &runtimepath. All necessary expansions are performed in // this function. set_runtimepath_default(); @@ -629,14 +626,16 @@ void set_init_1(void) * default. */ for (opt_idx = 0; options[opt_idx].fullname; opt_idx++) { + char *p; if ((options[opt_idx].flags & P_GETTEXT) - && options[opt_idx].var != NULL) - p = (char_u *)_(*(char **)options[opt_idx].var); - else - p = option_expand(opt_idx, NULL); + && options[opt_idx].var != NULL) { + p = _(*(char **)options[opt_idx].var); + } else { + p = (char *) option_expand(opt_idx, NULL); + } if (p != NULL) { - p = vim_strsave(p); - *(char_u **)options[opt_idx].var = p; + p = xstrdup(p); + *(char **)options[opt_idx].var = p; /* VIMEXP * Defaults for all expanded options are currently the same for Vi * and Vim. When this changes, add some code here! Also need to @@ -644,7 +643,7 @@ void set_init_1(void) */ if (options[opt_idx].flags & P_DEF_ALLOCED) xfree(options[opt_idx].def_val[VI_DEFAULT]); - options[opt_idx].def_val[VI_DEFAULT] = p; + options[opt_idx].def_val[VI_DEFAULT] = (char_u *) p; options[opt_idx].flags |= P_DEF_ALLOCED; } } @@ -673,14 +672,14 @@ void set_init_1(void) (void)set_chars_option(&p_lcs); /* enc_locale() will try to find the encoding of the current locale. */ - p = enc_locale(); + char_u *p = enc_locale(); if (p != NULL) { char_u *save_enc; /* Try setting 'encoding' and check if the value is valid. * If not, go back to the default "utf-8". */ save_enc = p_enc; - p_enc = p; + p_enc = (char_u *) p; if (STRCMP(p_enc, "gb18030") == 0) { /* We don't support "gb18030", but "cp936" is a good substitute * for practical purposes, thus use that. It's not an alias to @@ -825,7 +824,9 @@ set_options_default ( /// /// @param name The name of the option /// @param val The value of the option -void set_string_default(const char *name, const char_u *val) +/// @param allocated If true, do not copy default as it was already allocated. +static void set_string_default(const char *name, char *val, bool allocated) + FUNC_ATTR_NONNULL_ALL { int opt_idx = findoption((char_u *)name); if (opt_idx >= 0) { @@ -833,7 +834,10 @@ void set_string_default(const char *name, const char_u *val) xfree(options[opt_idx].def_val[VI_DEFAULT]); } - options[opt_idx].def_val[VI_DEFAULT] = (char_u *) xstrdup((char *) val); + options[opt_idx].def_val[VI_DEFAULT] = (char_u *) ( + allocated + ? (char_u *) val + : (char_u *) xstrdup(val)); options[opt_idx].flags |= P_DEF_ALLOCED; } } -- cgit From 0a59c969cc2850940f0791ce2944fa7f4ee3de02 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 17 Oct 2015 15:09:50 +0300 Subject: option: Use proper printexpr --- src/nvim/option.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nvim/option.c b/src/nvim/option.c index 7000fc4067..13ac1503d5 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -570,12 +570,25 @@ void set_init_1(void) #if defined(MSWIN) || defined(MAC) /* Set print encoding on platforms that don't default to latin1 */ - set_string_default("penc", "hp-roman8", false); + set_string_default("printencoding", "hp-roman8", false); #endif - /* 'printexpr' must be allocated to be able to evaluate it. */ - set_string_default("pexpr", "system('lpr' . (&printdevice == '' ? '' : ' -P' . &printdevice) . ' ' . v:fname_in) . delete(v:fname_in) + v:shell_error", false); - + // 'printexpr' must be allocated to be able to evaluate it. + set_string_default("printexpr", +#ifdef UNIX + "system(['lpr'] " + "+ (empty(&printdevice)?[]:['-P', &printdevice]) " + "+ [v:fname_in])" + ". delete(v:fname_in)" + "+ v:shell_error", +#elif defined(MSWIN) + "system(['copy', v:fname_in, " + "empty(&printdevice)?'LPT1':&printdevice])" + ". delete(v:fname_in)", +#else + "", +#endif + false); set_string_default("viewdir", stdpaths_user_data_subpath("view"), true); set_string_default("backupdir", stdpaths_user_data_subpath("backup"), true); -- cgit From 502a20a8feb80e7e12eb34231975257b915e3115 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 17 Oct 2015 15:32:11 +0300 Subject: stdpaths,main: Remove all remaining memory leaks --- src/nvim/main.c | 1 + src/nvim/os/stdpaths.c | 6 +++--- src/nvim/path.c | 56 ++++++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 52 insertions(+), 11 deletions(-) (limited to 'src') 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); } /* -- cgit From 2e750973e936a04d9effea88f78f03a5a07ab282 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 17 Oct 2015 15:41:05 +0300 Subject: shada: Move shada file to a new location --- src/nvim/main.c | 2 +- src/nvim/os/unix_defs.h | 3 --- src/nvim/os/win_defs.h | 1 - src/nvim/shada.c | 18 ++++++++++++++++-- 4 files changed, 17 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/nvim/main.c b/src/nvim/main.c index 6186d2e7e7..90d469b203 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -2028,7 +2028,7 @@ static void usage(void) mch_msg(_(" -r, -L List swap files and exit\n")); mch_msg(_(" -r Recover crashed session\n")); mch_msg(_(" -u Use instead of the default\n")); - mch_msg(_(" -i Use instead of the default " SHADA_FILE "\n")); // NOLINT(whitespace/line_length) + mch_msg(_(" -i Use instead of the default\n")); mch_msg(_(" --noplugin Don't load plugin scripts\n")); mch_msg(_(" -o[N] Open N windows (default: one for each file)\n")); mch_msg(_(" -O[N] Like -o but split vertically\n")); diff --git a/src/nvim/os/unix_defs.h b/src/nvim/os/unix_defs.h index 83c6752ff7..82a434cdf1 100644 --- a/src/nvim/os/unix_defs.h +++ b/src/nvim/os/unix_defs.h @@ -37,8 +37,5 @@ #ifndef VIMRC_FILE # define VIMRC_FILE ".nvimrc" #endif -#ifndef SHADA_FILE -# define SHADA_FILE "~/.nvim/shada/main.shada" -#endif #endif // NVIM_OS_UNIX_DEFS_H diff --git a/src/nvim/os/win_defs.h b/src/nvim/os/win_defs.h index 427e6a8481..585def7dd0 100644 --- a/src/nvim/os/win_defs.h +++ b/src/nvim/os/win_defs.h @@ -8,7 +8,6 @@ // Defines needed to fix the build on Windows: // - USR_EXRC_FILE -// - SHADA_FILE // - DFLT_DIR // - DFLT_BDIR // - DFLT_VDIR diff --git a/src/nvim/shada.c b/src/nvim/shada.c index 523f8db6f0..6fd13a88b7 100644 --- a/src/nvim/shada.c +++ b/src/nvim/shada.c @@ -1583,6 +1583,20 @@ shada_read_main_cycle_end: kh_dealloc(strset, &oldfiles_set); } +/// Default shada file location: cached path +static char *default_shada_file = NULL; + +/// Get the default ShaDa file +static const char *shada_get_default_file(void) + FUNC_ATTR_WARN_UNUSED_RESULT +{ + if (default_shada_file == NULL) { + char *shada_dir = stdpaths_user_data_subpath("shada"); + default_shada_file = concat_fnames_realloc(shada_dir, "main.shada", true); + } + return default_shada_file; +} + /// Get the ShaDa file name to use /// /// If "file" is given and not empty, use it (has already been expanded by @@ -1608,11 +1622,11 @@ static char *shada_filename(const char *file) if (STRCMP("$VIM", NameBuff) != 0) { // $VIM was expanded file = SHADA_FILE2; } else { - file = SHADA_FILE; + file = shada_get_default_file(); } } else { #endif - file = SHADA_FILE; + file = shada_get_default_file(); #ifdef SHADA_FILE2 } #endif -- cgit From a06a8bad6080e605c25124446c7441cee8911234 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 17 Oct 2015 15:48:38 +0300 Subject: stdpaths: Give proper error message in case directory creation failed --- src/nvim/os/stdpaths.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/nvim/os/stdpaths.c b/src/nvim/os/stdpaths.c index 9d93f25a7e..e242cd3d69 100644 --- a/src/nvim/os/stdpaths.c +++ b/src/nvim/os/stdpaths.c @@ -64,13 +64,15 @@ static char *get_xdg_home(const XDGVarType idx) return dir; } -static void create_dir(const char *dir, int mode, const char *suffix) +static void create_dir(const char *dir, int mode) FUNC_ATTR_NONNULL_ALL { char *failed; - if (!os_mkdir_recurse(dir, mode, &failed)) { - // TODO: Create a folder in $TMPDIR instead - DLOG("Create dir failed"); + int err; + if ((err = os_mkdir_recurse(dir, mode, &failed)) != 0) { + EMSG3(_("E920: Failed to create data directory %s: %s"), failed, + os_strerror(-err)); + xfree(failed); } } @@ -85,7 +87,7 @@ char *stdpaths_user_data_subpath(const char *fname) { char *dir = concat_fnames_realloc(get_xdg_home(kXDGDataHome), fname, true); if (!os_isdir((char_u *)dir)) { - create_dir(dir, 0755, fname); + create_dir(dir, 0755); } return dir; } -- cgit From a1b0f4073deb7f50e1b7137174bcb9914c97078f Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 17 Oct 2015 15:51:31 +0300 Subject: stdpaths: Do NOT create data directories This is none of option.c business to create *possibly unneeded* **default** directories **before** user specified where he actually wants to place the files. --- src/nvim/os/stdpaths.c | 18 +----------------- src/nvim/path.c | 7 ++++--- 2 files changed, 5 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/nvim/os/stdpaths.c b/src/nvim/os/stdpaths.c index e242cd3d69..167a53c985 100644 --- a/src/nvim/os/stdpaths.c +++ b/src/nvim/os/stdpaths.c @@ -64,18 +64,6 @@ static char *get_xdg_home(const XDGVarType idx) return dir; } -static void create_dir(const char *dir, int mode) - FUNC_ATTR_NONNULL_ALL -{ - char *failed; - int err; - if ((err = os_mkdir_recurse(dir, mode, &failed)) != 0) { - EMSG3(_("E920: Failed to create data directory %s: %s"), failed, - os_strerror(-err)); - xfree(failed); - } -} - char *stdpaths_user_conf_subpath(const char *fname) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL { @@ -85,9 +73,5 @@ char *stdpaths_user_conf_subpath(const char *fname) char *stdpaths_user_data_subpath(const char *fname) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL { - char *dir = concat_fnames_realloc(get_xdg_home(kXDGDataHome), fname, true); - if (!os_isdir((char_u *)dir)) { - create_dir(dir, 0755); - } - return dir; + return concat_fnames_realloc(get_xdg_home(kXDGDataHome), fname, true); } diff --git a/src/nvim/path.c b/src/nvim/path.c index a0bba450cd..e30f6b08d9 100644 --- a/src/nvim/path.c +++ b/src/nvim/path.c @@ -364,7 +364,7 @@ static inline char *do_concat_fnames(char *fname1, const size_t len1, /// if necessary /// @return [allocated] Concatenation of fname1 and fname2. char *concat_fnames(const char *fname1, const char *fname2, bool sep) - FUNC_ATTR_NONNULL_ARG(1, 2) FUNC_ATTR_NONNULL_RET + FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET { const size_t len1 = strlen(fname1); const size_t len2 = strlen(fname2); @@ -376,7 +376,8 @@ char *concat_fnames(const char *fname1, const char *fname2, bool sep) /// 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. +/// fname1. For this reason fname1 must be allocated with xmalloc, and can no +/// longer be used after running concat_fnames_realloc. /// /// @param fname1 is the first part of the path or filename /// @param fname2 is the second half of the path or filename @@ -384,7 +385,7 @@ char *concat_fnames(const char *fname1, const char *fname2, bool sep) /// 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 + FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET { const size_t len1 = strlen(fname1); const size_t len2 = strlen(fname2); -- cgit From 1cdc3298cfb8389b2bc3203da16abc74abb0a0c0 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 17 Oct 2015 17:25:53 +0300 Subject: documentation: Update documentation Note about ~/.local/share/nvim/site used in one usr_\* file: this one talks about user-local installation of third-party plugins, and ~/.local/share/nvim/site is the proper place for them. Most other files talk about user own configuration and this is ~/.config. --- src/nvim/main.c | 54 +++++++++++++++++++++++------------------------------- src/nvim/option.c | 2 +- 2 files changed, 24 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/nvim/main.c b/src/nvim/main.c index 90d469b203..7f7194cc38 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -287,8 +287,8 @@ int main(int argc, char **argv) * Set the default values for the options that use Rows and Columns. */ win_init_size(); - /* Set the 'diff' option now, so that it can be checked for in a .vimrc - * file. There is no buffer yet though. */ + // Set the 'diff' option now, so that it can be checked for in a vimrc + // file. There is no buffer yet though. if (params.diff_mode) diff_win_options(firstwin, FALSE); @@ -345,7 +345,7 @@ int main(int argc, char **argv) */ load_plugins(); - /* Decide about window layout for diff mode after reading vimrc. */ + // Decide about window layout for diff mode after reading vimrc. set_window_layout(¶ms); /* @@ -358,10 +358,8 @@ int main(int argc, char **argv) mch_exit(0); } - /* - * Set a few option defaults after reading .vimrc files: - * 'title' and 'icon', Unix: 'shellpipe' and 'shellredir'. - */ + // Set a few option defaults after reading vimrc files: + // 'title' and 'icon', Unix: 'shellpipe' and 'shellredir'. set_init_3(); TIME_MSG("inits 3"); @@ -1551,8 +1549,8 @@ static void create_windows(mparm_T *parmp) if (parmp->window_count == 0) parmp->window_count = GARGCOUNT; if (parmp->window_count > 1) { - /* Don't change the windows if there was a command in .vimrc that - * already split some windows */ + // Don't change the windows if there was a command in vimrc that + // already split some windows if (parmp->window_layout == 0) parmp->window_layout = WIN_HOR; if (parmp->window_layout == WIN_TABS) { @@ -1574,14 +1572,11 @@ static void create_windows(mparm_T *parmp) getout(1); do_modelines(0); /* do modelines */ } else { - /* - * Open a buffer for windows that don't have one yet. - * Commands in the .vimrc might have loaded a file or split the window. - * Watch out for autocommands that delete a window. - */ - /* - * Don't execute Win/Buf Enter/Leave autocommands here - */ + // Open a buffer for windows that don't have one yet. + // Commands in the vimrc might have loaded a file or split the window. + // Watch out for autocommands that delete a window. + // + // Don't execute Win/Buf Enter/Leave autocommands here ++autocmd_no_enter; ++autocmd_no_leave; dorewind = TRUE; @@ -1691,8 +1686,8 @@ static void edit_buffers(mparm_T *parmp) } advance = TRUE; - /* Only open the file if there is no file in this window yet (that can - * happen when .vimrc contains ":sall"). */ + // Only open the file if there is no file in this window yet (that can + // happen when vimrc contains ":sall"). if (curbuf == firstwin->w_buffer || curbuf->b_ffname == NULL) { curwin->w_arg_idx = arg_idx; /* Edit file from arg list, if there is one. When "Quit" selected @@ -1830,16 +1825,13 @@ static void source_startup_scripts(mparm_T *parmp) (void)do_source((char_u *)SYS_VIMRC_FILE, FALSE, DOSO_NONE); #endif - /* - * Try to read initialization commands from the following places: - * - environment variable VIMINIT - * - user vimrc file (~/.vimrc) - * - second user vimrc file ($VIM/.vimrc for Dos) - * - environment variable EXINIT - * - user exrc file (~/.exrc) - * - second user exrc file ($VIM/.exrc for Dos) - * The first that exists is used, the rest is ignored. - */ + // Try to read initialization commands from the following places: + // - environment variable VIMINIT + // - user vimrc file (~/.config/nvim/init.vim) + // - environment variable EXINIT + // - user exrc file (~/.exrc) + // - second user exrc file ($VIM/.exrc for Dos) + // The first that exists is used, the rest is ignored. char_u *user_vimrc = (char_u *)stdpaths_user_conf_subpath("init.vim"); if (process_env("VIMINIT", true) != OK) { if (do_source(user_vimrc, true, DOSO_VIMRC) == FAIL @@ -1856,13 +1848,13 @@ static void source_startup_scripts(mparm_T *parmp) * directory. This is only done if the 'exrc' option is set. * Because of security reasons we disallow shell and write commands * now, except for unix if the file is owned by the user or 'secure' - * option has been reset in environment of global ".exrc" or ".vimrc". + * option has been reset in environment of global "exrc" or "vimrc". * Only do this if VIMRC_FILE is not the same as USR_VIMRC_FILE or * SYS_VIMRC_FILE. */ if (p_exrc) { #if defined(UNIX) - /* If ".vimrc" file is not owned by user, set 'secure' mode. */ + // If vimrc file is not owned by user, set 'secure' mode. if (!file_owned(VIMRC_FILE)) #endif secure = p_secure; diff --git a/src/nvim/option.c b/src/nvim/option.c index 13ac1503d5..b4b0ff0c43 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -6116,7 +6116,7 @@ static void paste_option_changed(void) old_p_paste = p_paste; } -/// vimrc_found() - Called when a ".vimrc" or "VIMINIT" has been found. +/// vimrc_found() - Called when a vimrc or "VIMINIT" has been found. /// /// Set the values for options that didn't get set yet to the Vim defaults. /// When "fname" is not NULL, use it to set $"envname" when it wasn't set yet. -- cgit From 86a6ff7b9d2c669ea711ba53432300c017f8a3b1 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 17 Oct 2015 19:31:31 +0300 Subject: option: Move macros to functions, use PATHSEP in place of / --- src/nvim/option.c | 247 +++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 170 insertions(+), 77 deletions(-) (limited to 'src') diff --git a/src/nvim/option.c b/src/nvim/option.c index b4b0ff0c43..a449deb014 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -328,6 +328,146 @@ static char *strcpy_comma_escaped(char *dest, const char *src, const size_t len) return &dest[len + shift]; } +/// Compute length of a colon-separated value, doubled and with some suffixes +/// +/// @param[in] val Colon-separated array value. +/// @param[in] common_suf_len Length of the common suffix which is appended to +/// each item in the array, twice. +/// @param[in] single_suf_len Length of the suffix which is appended to each +/// item in the array once. +/// +/// @return Length of the comma-separated string array that contains each item +/// in the original array twice with suffixes with given length +/// (common_suf is present after each new item, single_suf is present +/// after half of the new items) and with commas after each item, commas +/// inside the values are escaped. +static inline size_t compute_double_colon_len(const char *const val, + const size_t common_suf_len, + const size_t single_suf_len) + FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_PURE +{ + if (val == NULL) { + return 0; + } + size_t ret = 0; + const void *iter = NULL; + do { + size_t dir_len; + const char *dir; + iter = vim_colon_env_iter(val, iter, &dir, &dir_len); + if (dir != NULL && dir_len > 0) { + ret += ((dir_len + count_commas(dir, dir_len) + common_suf_len + 1) * 2 + + single_suf_len); + } + } while (iter != NULL); + return ret; +} + +#define NVIM_SIZE (sizeof("nvim") - 1) + +/// Add directories to a comma-separated array from a colon-separated one +/// +/// Commas are escaped in process. To each item PATHSEP "nvim" is appended in +/// addition to suf1 and suf2. +/// +/// @param[in,out] dest Destination comma-separated array. +/// @param[in] val Source colon-separated array. +/// @param[in] suf1 If not NULL, suffix appended to destination. Prior to it +/// directory separator is appended. Suffix must not contain +/// commas. +/// @param[in] len1 Length of the suf1. +/// @param[in] suf2 If not NULL, another suffix appended to destination. Again +/// with directory separator behind. Suffix must not contain +/// commas. +/// @param[in] len2 Length of the suf2. +/// @param[in] forward If true, iterate over val in forward direction. +/// Otherwise in reverse. +/// +/// @return (dest + appended_characters_length) +static inline char *add_colon_dirs(char *dest, const char *const val, + const char *const suf1, const size_t len1, + const char *const suf2, const size_t len2, + const bool forward) + FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_RET FUNC_ATTR_NONNULL_ARG(1) +{ + if (val == NULL) { + return dest; + } + const void *iter = NULL; + do { + size_t dir_len; + const char *dir; + iter = (forward ? vim_colon_env_iter : vim_colon_env_iter_rev)( + val, iter, &dir, &dir_len); + if (dir != NULL && dir_len > 0) { + dest = strcpy_comma_escaped(dest, dir, dir_len); + *dest++ = PATHSEP; + memmove(dest, "nvim", NVIM_SIZE); + dest += NVIM_SIZE; + if (suf1 != NULL) { + *dest++ = PATHSEP; + memmove(dest, suf1, len1); + dest += len1; + if (suf2 != NULL) { + *dest++ = PATHSEP; + memmove(dest, suf2, len2); + dest += len2; + } + } + *dest++ = ','; + } + } while (iter != NULL); + return dest; +} + +/// Add directory to a comma-separated list of directories +/// +/// In the added directory comma is escaped. +/// +/// @param[in,out] dest Destination comma-separated array. +/// @param[in] dir Directory to append. +/// @param[in] append_nvim If true, append "nvim" as the very first suffix. +/// @param[in] suf1 If not NULL, suffix appended to destination. Prior to it +/// directory separator is appended. Suffix must not contain +/// commas. +/// @param[in] len1 Length of the suf1. +/// @param[in] suf2 If not NULL, another suffix appended to destination. Again +/// with directory separator behind. Suffix must not contain +/// commas. +/// @param[in] len2 Length of the suf2. +/// @param[in] forward If true, iterate over val in forward direction. +/// Otherwise in reverse. +/// +/// @return (dest + appended_characters_length) +static inline char *add_dir(char *dest, const char *const dir, + const size_t dir_len, const bool append_nvim, + const char *const suf1, const size_t len1, + const char *const suf2, const size_t len2) + FUNC_ATTR_NONNULL_RET FUNC_ATTR_NONNULL_ARG(1) FUNC_ATTR_WARN_UNUSED_RESULT +{ + if (dir == NULL) { + return dest; + } + dest = strcpy_comma_escaped(dest, dir, dir_len); + if (append_nvim) { + *dest++ = PATHSEP; + memmove(dest, "nvim", NVIM_SIZE); + dest += NVIM_SIZE; + if (suf1 != NULL) { + *dest++ = PATHSEP; + memmove(dest, suf1, len1); + dest += len1; + if (suf2 != NULL) { + *dest++ = PATHSEP; + memmove(dest, suf2, len2); + dest += len2; + } + } + } + *dest++ = ','; + return dest; +} + /// Set &runtimepath to default value static void set_runtimepath_default(void) { @@ -337,102 +477,53 @@ static void set_runtimepath_default(void) char *const vimruntime = vim_getenv("VIMRUNTIME"); char *const data_dirs = stdpaths_get_xdg_var(kXDGDataDirs); char *const config_dirs = stdpaths_get_xdg_var(kXDGConfigDirs); -#define NVIM_SIZE (sizeof("/nvim") - 1) -#define SITE_SIZE (sizeof("/site") - 1) -#define AFTER_SIZE (sizeof("/after") - 1) +#define SITE_SIZE (sizeof("site") - 1) +#define AFTER_SIZE (sizeof("after") - 1) size_t data_len; size_t config_len; size_t vimruntime_len; if (data_home != NULL) { data_len = strlen(data_home); rtp_size += ((data_len + count_commas(data_home, data_len) - + NVIM_SIZE + SITE_SIZE) * 2 + AFTER_SIZE) + 2; + + NVIM_SIZE + 1 + SITE_SIZE + 1 + 1) * 2 + AFTER_SIZE + 1); } if (config_home != NULL) { config_len = strlen(config_home); rtp_size += ((config_len + count_commas(config_home, config_len) - + NVIM_SIZE) * 2 + AFTER_SIZE) + 2; + + NVIM_SIZE + 1 + 1) * 2 + AFTER_SIZE + 1); } if (vimruntime != NULL) { vimruntime_len = strlen(vimruntime); rtp_size += vimruntime_len + count_commas(vimruntime, vimruntime_len) + 1; } -#define COMPUTE_COLON_LEN(rtp_size, additional_size, val) \ - do { \ - if (val != NULL) { \ - const void *iter = NULL; \ - do { \ - size_t dir_len; \ - const char *dir; \ - iter = vim_colon_env_iter(val, iter, &dir, &dir_len); \ - if (dir != NULL && dir_len > 0) { \ - rtp_size += ((dir_len + count_commas(dir, dir_len) \ - + NVIM_SIZE + additional_size) * 2 \ - + AFTER_SIZE) + 2; \ - } \ - } while (iter != NULL); \ - } \ - } while (0) - COMPUTE_COLON_LEN(rtp_size, SITE_SIZE, data_dirs); - COMPUTE_COLON_LEN(rtp_size, 0, config_dirs); -#undef COMPUTE_COLON_LEN + rtp_size += compute_double_colon_len(data_dirs, NVIM_SIZE + 1 + SITE_SIZE + 1, + AFTER_SIZE + 1); + rtp_size += compute_double_colon_len(config_dirs, NVIM_SIZE + 1, + AFTER_SIZE + 1); if (rtp_size == 0) { return; } - // All additions were including comma. - rtp_size--; - char *const rtp = xmallocz(rtp_size); + char *const rtp = xmalloc(rtp_size); char *rtp_cur = rtp; -#define ADD_STRING(tgt, src, len) \ - tgt = strcpy_comma_escaped(tgt, src, len) -#define ADD_STATIC_STRING(tgt, src) \ - do { memmove(tgt, src, sizeof(src) - 1); tgt += sizeof(src) - 1; } while (0) -#define ADD_COLON_DIRS(tgt, val, suffix, revsuffix) \ - do { \ - if (val != NULL) { \ - const void *iter = NULL; \ - do { \ - size_t dir_len; \ - const char *dir; \ - iter = vim_colon_env_iter##revsuffix(val, iter, &dir, &dir_len); \ - if (dir != NULL && dir_len > 0) { \ - ADD_STRING(rtp_cur, dir, dir_len); \ - ADD_STATIC_STRING(rtp_cur, "/nvim" suffix ","); \ - } \ - } while (iter != NULL); \ - } \ - } while (0) - if (config_home != NULL) { - ADD_STRING(rtp_cur, config_home, config_len); - ADD_STATIC_STRING(rtp_cur, "/nvim,"); - } - ADD_COLON_DIRS(rtp_cur, config_dirs, "", ); - if (data_home != NULL) { - ADD_STRING(rtp_cur, data_home, data_len); - ADD_STATIC_STRING(rtp_cur, "/nvim/site,"); - } - ADD_COLON_DIRS(rtp_cur, data_dirs, "/site", ); - if (vimruntime != NULL) { - ADD_STRING(rtp_cur, vimruntime, vimruntime_len); - *rtp_cur++ = ','; - } - ADD_COLON_DIRS(rtp_cur, data_dirs, "/site/after", _rev); - if (data_home != NULL) { - ADD_STRING(rtp_cur, data_home, data_len); - ADD_STATIC_STRING(rtp_cur, "/nvim/site/after,"); - } - ADD_COLON_DIRS(rtp_cur, config_dirs, "/after", _rev); - if (config_home != NULL) { - ADD_STRING(rtp_cur, config_home, config_len); - ADD_STATIC_STRING(rtp_cur, "/nvim/after"); - } else { - // Strip trailing comma. - rtp[rtp_size] = NUL; - } -#undef ADD_COLON_DIRS -#undef ADD_STATIC_STRING -#undef ADD_STRING -#undef NVIM_SIZE + rtp_cur = add_dir(rtp_cur, config_home, config_len, true, NULL, 0, NULL, 0); + rtp_cur = add_colon_dirs(rtp_cur, config_dirs, NULL, 0, NULL, 0, true); + rtp_cur = add_dir(rtp_cur, data_home, data_len, true, "site", SITE_SIZE, + NULL, 0); + rtp_cur = add_colon_dirs(rtp_cur, data_dirs, "site", SITE_SIZE, NULL, 0, + true); + rtp_cur = add_dir(rtp_cur, vimruntime, vimruntime_len, false, NULL, 0, + NULL, 0); + rtp_cur = add_colon_dirs(rtp_cur, data_dirs, "site", SITE_SIZE, + "after", AFTER_SIZE, false); + rtp_cur = add_dir(rtp_cur, data_home, data_len, true, "site", SITE_SIZE, + "after", AFTER_SIZE); + rtp_cur = add_colon_dirs(rtp_cur, config_dirs, "after", AFTER_SIZE, NULL, 0, + false); + rtp_cur = add_dir(rtp_cur, config_home, config_len, true, + "after", AFTER_SIZE, NULL, 0); + // Strip trailing comma. + rtp_cur[-1] = NUL; + assert((size_t) (rtp_cur - rtp) == rtp_size); #undef SITE_SIZE #undef AFTER_SIZE set_string_default("runtimepath", rtp, true); @@ -443,6 +534,8 @@ static void set_runtimepath_default(void) xfree(vimruntime); } +#undef NVIM_SIZE + /* * Initialize the options, first part. * -- cgit From d1ed658c4470d1f15ce668253cd87340610c555f Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 17 Oct 2015 19:37:43 +0300 Subject: option: Do not add unneeded path separator, protect against zero len --- src/nvim/option.c | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/nvim/option.c b/src/nvim/option.c index a449deb014..54c934ef7c 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -346,7 +346,7 @@ static inline size_t compute_double_colon_len(const char *const val, const size_t single_suf_len) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_PURE { - if (val == NULL) { + if (val == NULL && *val) { return 0; } size_t ret = 0; @@ -356,7 +356,8 @@ static inline size_t compute_double_colon_len(const char *const val, const char *dir; iter = vim_colon_env_iter(val, iter, &dir, &dir_len); if (dir != NULL && dir_len > 0) { - ret += ((dir_len + count_commas(dir, dir_len) + common_suf_len + 1) * 2 + ret += ((dir_len + count_commas(dir, dir_len) + common_suf_len + + !after_pathsep(dir, dir + dir_len)) * 2 + single_suf_len); } } while (iter != NULL); @@ -390,7 +391,7 @@ static inline char *add_colon_dirs(char *dest, const char *const val, const bool forward) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_RET FUNC_ATTR_NONNULL_ARG(1) { - if (val == NULL) { + if (val == NULL && *val) { return dest; } const void *iter = NULL; @@ -401,7 +402,9 @@ static inline char *add_colon_dirs(char *dest, const char *const val, val, iter, &dir, &dir_len); if (dir != NULL && dir_len > 0) { dest = strcpy_comma_escaped(dest, dir, dir_len); - *dest++ = PATHSEP; + if (!after_pathsep(dest - 1, dest)) { + *dest++ = PATHSEP; + } memmove(dest, "nvim", NVIM_SIZE); dest += NVIM_SIZE; if (suf1 != NULL) { @@ -445,12 +448,14 @@ static inline char *add_dir(char *dest, const char *const dir, const char *const suf2, const size_t len2) FUNC_ATTR_NONNULL_RET FUNC_ATTR_NONNULL_ARG(1) FUNC_ATTR_WARN_UNUSED_RESULT { - if (dir == NULL) { + if (dir == NULL && dir_len != 0) { return dest; } dest = strcpy_comma_escaped(dest, dir, dir_len); if (append_nvim) { - *dest++ = PATHSEP; + if (!after_pathsep(dest - 1, dest)) { + *dest++ = PATHSEP; + } memmove(dest, "nvim", NVIM_SIZE); dest += NVIM_SIZE; if (suf1 != NULL) { @@ -484,17 +489,27 @@ static void set_runtimepath_default(void) size_t vimruntime_len; if (data_home != NULL) { data_len = strlen(data_home); - rtp_size += ((data_len + count_commas(data_home, data_len) - + NVIM_SIZE + 1 + SITE_SIZE + 1 + 1) * 2 + AFTER_SIZE + 1); + if (data_len != 0) { + rtp_size += ((data_len + count_commas(data_home, data_len) + + NVIM_SIZE + 1 + SITE_SIZE + 1 + + !after_pathsep(data_home, data_home + data_len)) * 2 + + AFTER_SIZE + 1); + } } if (config_home != NULL) { config_len = strlen(config_home); - rtp_size += ((config_len + count_commas(config_home, config_len) - + NVIM_SIZE + 1 + 1) * 2 + AFTER_SIZE + 1); + if (config_len != 0) { + rtp_size += ((config_len + count_commas(config_home, config_len) + + NVIM_SIZE + 1 + + !after_pathsep(config_home, config_home + config_len)) * 2 + + AFTER_SIZE + 1); + } } if (vimruntime != NULL) { vimruntime_len = strlen(vimruntime); - rtp_size += vimruntime_len + count_commas(vimruntime, vimruntime_len) + 1; + if (vimruntime_len != 0) { + rtp_size += vimruntime_len + count_commas(vimruntime, vimruntime_len) + 1; + } } rtp_size += compute_double_colon_len(data_dirs, NVIM_SIZE + 1 + SITE_SIZE + 1, AFTER_SIZE + 1); -- cgit From 2018389871c8c973005601a63a2b6c97fa5417e2 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 17 Oct 2015 19:39:04 +0300 Subject: option: Remove new trailing spaces --- src/nvim/option.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/nvim/option.c b/src/nvim/option.c index 54c934ef7c..9fa8a6539e 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -331,15 +331,15 @@ static char *strcpy_comma_escaped(char *dest, const char *src, const size_t len) /// Compute length of a colon-separated value, doubled and with some suffixes /// /// @param[in] val Colon-separated array value. -/// @param[in] common_suf_len Length of the common suffix which is appended to +/// @param[in] common_suf_len Length of the common suffix which is appended to /// each item in the array, twice. -/// @param[in] single_suf_len Length of the suffix which is appended to each +/// @param[in] single_suf_len Length of the suffix which is appended to each /// item in the array once. /// -/// @return Length of the comma-separated string array that contains each item -/// in the original array twice with suffixes with given length -/// (common_suf is present after each new item, single_suf is present -/// after half of the new items) and with commas after each item, commas +/// @return Length of the comma-separated string array that contains each item +/// in the original array twice with suffixes with given length +/// (common_suf is present after each new item, single_suf is present +/// after half of the new items) and with commas after each item, commas /// inside the values are escaped. static inline size_t compute_double_colon_len(const char *const val, const size_t common_suf_len, @@ -368,20 +368,20 @@ static inline size_t compute_double_colon_len(const char *const val, /// Add directories to a comma-separated array from a colon-separated one /// -/// Commas are escaped in process. To each item PATHSEP "nvim" is appended in +/// Commas are escaped in process. To each item PATHSEP "nvim" is appended in /// addition to suf1 and suf2. /// /// @param[in,out] dest Destination comma-separated array. /// @param[in] val Source colon-separated array. -/// @param[in] suf1 If not NULL, suffix appended to destination. Prior to it -/// directory separator is appended. Suffix must not contain +/// @param[in] suf1 If not NULL, suffix appended to destination. Prior to it +/// directory separator is appended. Suffix must not contain /// commas. /// @param[in] len1 Length of the suf1. -/// @param[in] suf2 If not NULL, another suffix appended to destination. Again -/// with directory separator behind. Suffix must not contain +/// @param[in] suf2 If not NULL, another suffix appended to destination. Again +/// with directory separator behind. Suffix must not contain /// commas. /// @param[in] len2 Length of the suf2. -/// @param[in] forward If true, iterate over val in forward direction. +/// @param[in] forward If true, iterate over val in forward direction. /// Otherwise in reverse. /// /// @return (dest + appended_characters_length) @@ -430,15 +430,15 @@ static inline char *add_colon_dirs(char *dest, const char *const val, /// @param[in,out] dest Destination comma-separated array. /// @param[in] dir Directory to append. /// @param[in] append_nvim If true, append "nvim" as the very first suffix. -/// @param[in] suf1 If not NULL, suffix appended to destination. Prior to it -/// directory separator is appended. Suffix must not contain +/// @param[in] suf1 If not NULL, suffix appended to destination. Prior to it +/// directory separator is appended. Suffix must not contain /// commas. /// @param[in] len1 Length of the suf1. -/// @param[in] suf2 If not NULL, another suffix appended to destination. Again -/// with directory separator behind. Suffix must not contain +/// @param[in] suf2 If not NULL, another suffix appended to destination. Again +/// with directory separator behind. Suffix must not contain /// commas. /// @param[in] len2 Length of the suf2. -/// @param[in] forward If true, iterate over val in forward direction. +/// @param[in] forward If true, iterate over val in forward direction. /// Otherwise in reverse. /// /// @return (dest + appended_characters_length) -- cgit From 89a10b3e7cadc5d088217380de7ed1af70ed8b31 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 17 Oct 2015 19:41:03 +0300 Subject: main,os/env: Fix lint errors --- src/nvim/main.c | 6 +++--- src/nvim/os/env.c | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/nvim/main.c b/src/nvim/main.c index 7f7194cc38..48e0f48ea6 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -1835,10 +1835,10 @@ static void source_startup_scripts(mparm_T *parmp) char_u *user_vimrc = (char_u *)stdpaths_user_conf_subpath("init.vim"); if (process_env("VIMINIT", true) != OK) { if (do_source(user_vimrc, true, DOSO_VIMRC) == FAIL - && process_env("EXINIT", FALSE) == FAIL - && do_source((char_u *)USR_EXRC_FILE, FALSE, DOSO_NONE) == FAIL) { + && process_env("EXINIT", false) == FAIL + && do_source((char_u *)USR_EXRC_FILE, false, DOSO_NONE) == FAIL) { #ifdef USR_EXRC_FILE2 - (void)do_source((char_u *)USR_EXRC_FILE2, FALSE, DOSO_NONE); + (void)do_source((char_u *)USR_EXRC_FILE2, false, DOSO_NONE); #endif } } diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c index bdf406af5e..bf6db97fcf 100644 --- a/src/nvim/os/env.c +++ b/src/nvim/os/env.c @@ -431,7 +431,7 @@ const void *vim_colon_env_iter(const char *const val, const void *const iter, const char **const dir, size_t *const len) - FUNC_ATTR_NONNULL_ARG(1,3,4) FUNC_ATTR_WARN_UNUSED_RESULT + FUNC_ATTR_NONNULL_ARG(1, 3, 4) FUNC_ATTR_WARN_UNUSED_RESULT { const char *varval = (const char *) iter; if (varval == NULL) { @@ -464,7 +464,7 @@ const void *vim_colon_env_iter_rev(const char *const val, const void *const iter, const char **const dir, size_t *const len) - FUNC_ATTR_NONNULL_ARG(1,3,4) FUNC_ATTR_WARN_UNUSED_RESULT + FUNC_ATTR_NONNULL_ARG(1, 3, 4) FUNC_ATTR_WARN_UNUSED_RESULT { const char *varend = (const char *) iter; if (varend == NULL) { -- cgit From aadaa1fed4d471fc2e286b0ffa151c006482389e Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 17 Oct 2015 21:30:52 +0300 Subject: stdpaths: Add documentation --- src/nvim/os/stdpaths.c | 24 ++++++++++++++++++++++++ src/nvim/os/stdpaths_defs.h | 13 +++++++------ 2 files changed, 31 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/nvim/os/stdpaths.c b/src/nvim/os/stdpaths.c index 167a53c985..0ed7aec2a6 100644 --- a/src/nvim/os/stdpaths.c +++ b/src/nvim/os/stdpaths.c @@ -5,6 +5,7 @@ #include "nvim/path.h" #include "nvim/memory.h" +/// Names of the environment variables, mapped to XDGVarType values static const char *xdg_env_vars[] = { [kXDGConfigHome] = "XDG_CONFIG_HOME", [kXDGDataHome] = "XDG_DATA_HOME", @@ -14,6 +15,9 @@ static const char *xdg_env_vars[] = { [kXDGDataDirs] = "XDG_DATA_DIRS", }; +/// Defaults for XDGVarType values +/// +/// Used in case environment variables contain nothing. Need to be expanded. static const char *const xdg_defaults[] = { // Windows, Apple stuff are just shims right now #ifdef WIN32 @@ -37,6 +41,11 @@ static const char *const xdg_defaults[] = { }; #endif +/// Return XDG variable value +/// +/// @param[in] idx XDG variable to use. +/// +/// @return [allocated] variable value. char *stdpaths_get_xdg_var(const XDGVarType idx) FUNC_ATTR_WARN_UNUSED_RESULT { @@ -54,6 +63,11 @@ char *stdpaths_get_xdg_var(const XDGVarType idx) return ret; } +/// Return nvim-specific XDG directory subpath +/// +/// @param[in] idx XDG directory to use. +/// +/// @return [allocated] `{xdg_directory}/nvim` static char *get_xdg_home(const XDGVarType idx) FUNC_ATTR_WARN_UNUSED_RESULT { @@ -64,12 +78,22 @@ static char *get_xdg_home(const XDGVarType idx) return dir; } +/// Return subpath of $XDG_CONFIG_HOME +/// +/// @param[in] fname New component of the path. +/// +/// @return [allocated] `$XDG_CONFIG_HOME/nvim/{fname}` char *stdpaths_user_conf_subpath(const char *fname) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL { return concat_fnames_realloc(get_xdg_home(kXDGConfigHome), fname, true); } +/// Return subpath of $XDG_DATA_HOME +/// +/// @param[in] fname New component of the path. +/// +/// @return [allocated] `$XDG_DATA_HOME/nvim/{fname}` char *stdpaths_user_data_subpath(const char *fname) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL { diff --git a/src/nvim/os/stdpaths_defs.h b/src/nvim/os/stdpaths_defs.h index 3b882cd582..1433e0bc62 100644 --- a/src/nvim/os/stdpaths_defs.h +++ b/src/nvim/os/stdpaths_defs.h @@ -1,13 +1,14 @@ #ifndef NVIM_OS_STDPATHS_DEFS_H #define NVIM_OS_STDPATHS_DEFS_H +/// List of possible XDG variables typedef enum { - kXDGConfigHome, - kXDGDataHome, - kXDGCacheHome, - kXDGRuntimeDir, - kXDGConfigDirs, - kXDGDataDirs, + kXDGConfigHome, ///< XDG_CONFIG_HOME + kXDGDataHome, ///< XDG_DATA_HOME + kXDGCacheHome, ///< XDG_CACHE_HOME + kXDGRuntimeDir, ///< XDG_RUNTIME_DIR + kXDGConfigDirs, ///< XDG_CONFIG_DIRS + kXDGDataDirs, ///< XDG_DATA_DIRS } XDGVarType; #endif // NVIM_OS_STDPATHS_DEFS_H -- cgit From a82a059921f36fb580026ef4cc31f64c110d07b7 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 17 Oct 2015 21:46:30 +0300 Subject: option: Add `//` to the end of default `&directory` --- src/nvim/option.c | 9 +++++---- src/nvim/os/stdpaths.c | 13 +++++++++++-- src/nvim/shada.c | 2 +- 3 files changed, 17 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/nvim/option.c b/src/nvim/option.c index 9fa8a6539e..9089947803 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -698,10 +698,11 @@ void set_init_1(void) #endif false); - set_string_default("viewdir", stdpaths_user_data_subpath("view"), true); - set_string_default("backupdir", stdpaths_user_data_subpath("backup"), true); - set_string_default("directory", stdpaths_user_data_subpath("swap"), true); - set_string_default("undodir", stdpaths_user_data_subpath("undo"), true); + set_string_default("viewdir", stdpaths_user_data_subpath("view", 0), true); + set_string_default("backupdir", stdpaths_user_data_subpath("backup", 0), + true); + set_string_default("directory", stdpaths_user_data_subpath("swap", 2), true); + set_string_default("undodir", stdpaths_user_data_subpath("undo", 0), true); // Set default for &runtimepath. All necessary expansions are performed in // this function. set_runtimepath_default(); diff --git a/src/nvim/os/stdpaths.c b/src/nvim/os/stdpaths.c index 0ed7aec2a6..d4bff65312 100644 --- a/src/nvim/os/stdpaths.c +++ b/src/nvim/os/stdpaths.c @@ -92,10 +92,19 @@ char *stdpaths_user_conf_subpath(const char *fname) /// Return subpath of $XDG_DATA_HOME /// /// @param[in] fname New component of the path. +/// @param[in] trailing_pathseps Amount of trailing path separators to add. /// /// @return [allocated] `$XDG_DATA_HOME/nvim/{fname}` -char *stdpaths_user_data_subpath(const char *fname) +char *stdpaths_user_data_subpath(const char *fname, + const size_t trailing_pathseps) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL { - return concat_fnames_realloc(get_xdg_home(kXDGDataHome), fname, true); + char *ret = concat_fnames_realloc(get_xdg_home(kXDGDataHome), fname, true); + if (trailing_pathseps) { + const size_t len = strlen(ret); + ret = xrealloc(ret, len + trailing_pathseps + 1); + memset(ret + len, PATHSEP, trailing_pathseps); + ret[len + trailing_pathseps] = NUL; + } + return ret; } diff --git a/src/nvim/shada.c b/src/nvim/shada.c index 6fd13a88b7..d6cbba4b12 100644 --- a/src/nvim/shada.c +++ b/src/nvim/shada.c @@ -1591,7 +1591,7 @@ static const char *shada_get_default_file(void) FUNC_ATTR_WARN_UNUSED_RESULT { if (default_shada_file == NULL) { - char *shada_dir = stdpaths_user_data_subpath("shada"); + char *shada_dir = stdpaths_user_data_subpath("shada", 0); default_shada_file = concat_fnames_realloc(shada_dir, "main.shada", true); } return default_shada_file; -- cgit From afcc842881d2569c11da26a75057062ba4f124e7 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 17 Oct 2015 21:53:16 +0300 Subject: main,version: Remove USR_EXRC_FILE* --- src/nvim/main.c | 17 +++-------------- src/nvim/os/unix_defs.h | 3 --- src/nvim/os/win_defs.h | 1 - src/nvim/version.c | 10 ---------- 4 files changed, 3 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/nvim/main.c b/src/nvim/main.c index 48e0f48ea6..3c1d59567b 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -1834,12 +1834,8 @@ static void source_startup_scripts(mparm_T *parmp) // The first that exists is used, the rest is ignored. char_u *user_vimrc = (char_u *)stdpaths_user_conf_subpath("init.vim"); if (process_env("VIMINIT", true) != OK) { - if (do_source(user_vimrc, true, DOSO_VIMRC) == FAIL - && process_env("EXINIT", false) == FAIL - && do_source((char_u *)USR_EXRC_FILE, false, DOSO_NONE) == FAIL) { -#ifdef USR_EXRC_FILE2 - (void)do_source((char_u *)USR_EXRC_FILE2, false, DOSO_NONE); -#endif + if (do_source(user_vimrc, true, DOSO_VIMRC) == FAIL) { + process_env("EXINIT", false); } } @@ -1877,14 +1873,7 @@ static void source_startup_scripts(mparm_T *parmp) else secure = 0; #endif - if ( path_full_compare((char_u *)USR_EXRC_FILE, - (char_u *)EXRC_FILE, FALSE) != kEqualFiles -#ifdef USR_EXRC_FILE2 - && path_full_compare((char_u *)USR_EXRC_FILE2, - (char_u *)EXRC_FILE, FALSE) != kEqualFiles -#endif - ) - (void)do_source((char_u *)EXRC_FILE, FALSE, DOSO_NONE); + (void) do_source((char_u *)EXRC_FILE, FALSE, DOSO_NONE); } } xfree(user_vimrc); diff --git a/src/nvim/os/unix_defs.h b/src/nvim/os/unix_defs.h index 82a434cdf1..e1c3060999 100644 --- a/src/nvim/os/unix_defs.h +++ b/src/nvim/os/unix_defs.h @@ -28,9 +28,6 @@ #ifndef SYNTAX_FNAME # define SYNTAX_FNAME "$VIMRUNTIME/syntax/%s.vim" #endif -#ifndef USR_EXRC_FILE -# define USR_EXRC_FILE "~/.exrc" -#endif #ifndef EXRC_FILE # define EXRC_FILE ".exrc" #endif diff --git a/src/nvim/os/win_defs.h b/src/nvim/os/win_defs.h index 585def7dd0..d614582250 100644 --- a/src/nvim/os/win_defs.h +++ b/src/nvim/os/win_defs.h @@ -7,7 +7,6 @@ #define TEMP_FILE_PATH_MAXLEN _MAX_PATH // Defines needed to fix the build on Windows: -// - USR_EXRC_FILE // - DFLT_DIR // - DFLT_BDIR // - DFLT_VDIR diff --git a/src/nvim/version.c b/src/nvim/version.c index 9cfda96c16..3b80336817 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -1067,16 +1067,6 @@ void list_version(void) version_msg(SYS_VIMRC_FILE); version_msg("\"\n"); #endif // ifdef SYS_VIMRC_FILE -#ifdef USR_EXRC_FILE - version_msg(_(" user exrc file: \"")); - version_msg(USR_EXRC_FILE); - version_msg("\"\n"); -#endif // ifdef USR_EXRC_FILE -#ifdef USR_EXRC_FILE2 - version_msg(_(" 2nd user exrc file: \"")); - version_msg(USR_EXRC_FILE2); - version_msg("\"\n"); -#endif // ifdef USR_EXRC_FILE2 #ifdef HAVE_PATHDEF if (*default_vim_dir != NUL) { -- cgit From fee3c320484f8444b6b078bdff6777a7aac31c89 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 17 Oct 2015 21:56:27 +0300 Subject: stdpaths: Remove Apple defaults, use \*nix ones instead --- src/nvim/os/stdpaths.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/nvim/os/stdpaths.c b/src/nvim/os/stdpaths.c index d4bff65312..520836b983 100644 --- a/src/nvim/os/stdpaths.c +++ b/src/nvim/os/stdpaths.c @@ -22,24 +22,16 @@ static const char *const xdg_defaults[] = { // Windows, Apple stuff are just shims right now #ifdef WIN32 // Windows -#elif APPLE - // Apple (this includes iOS, which we might need to handle differently) - [kXDGConfigHome] = "~/Library/Preferences", - [kXDGDataHome] = "~/Library/Application Support", - [kXDGCacheHome] = "~/Library/Caches", - [kXDGRuntimeDir] = "~/Library/Application Support", - [kXDGConfigDirs] = "/Library/Application Support", - [kXDGDataDirs] = "/Library/Application Support", #else - // Linux, BSD, CYGWIN + // Linux, BSD, CYGWIN, Apple [kXDGConfigHome] = "~/.config", [kXDGDataHome] = "~/.local/share", [kXDGCacheHome] = "~/.cache", [kXDGRuntimeDir] = "", [kXDGConfigDirs] = "/etc/xdg/", [kXDGDataDirs] = "/usr/local/share/:/usr/share/", -}; #endif +}; /// Return XDG variable value /// -- cgit From 8642bad122dd8b79983d42fbdf12524db9236aa2 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 17 Oct 2015 22:12:21 +0300 Subject: shada: Remove SHADA_FILE2 --- src/nvim/shada.c | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) (limited to 'src') diff --git a/src/nvim/shada.c b/src/nvim/shada.c index d6cbba4b12..bb79c183e6 100644 --- a/src/nvim/shada.c +++ b/src/nvim/shada.c @@ -1614,22 +1614,7 @@ static char *shada_filename(const char *file) file = used_shada_file; } else { if ((file = find_shada_parameter('n')) == NULL || *file == NUL) { -#ifdef SHADA_FILE2 - // don't use $HOME when not defined (turned into "c:/"!). - if (os_getenv((char_u *)"HOME") == NULL) { - // don't use $VIM when not available. - expand_env((char_u *)"$VIM", NameBuff, MAXPATHL); - if (STRCMP("$VIM", NameBuff) != 0) { // $VIM was expanded - file = SHADA_FILE2; - } else { - file = shada_get_default_file(); - } - } else { -#endif - file = shada_get_default_file(); -#ifdef SHADA_FILE2 - } -#endif + file = shada_get_default_file(); } // XXX It used to be one level lower, so that whatever is in // `used_shada_file` was expanded. I intentionally moved it here -- cgit From d2e07c8307af8a1ab37e68746a8ba600ee372948 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 17 Oct 2015 23:18:04 +0300 Subject: stdpaths: Add missing include --- src/nvim/os/stdpaths.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/nvim/os/stdpaths.c b/src/nvim/os/stdpaths.c index 520836b983..6e5e37ec08 100644 --- a/src/nvim/os/stdpaths.c +++ b/src/nvim/os/stdpaths.c @@ -4,6 +4,7 @@ #include "nvim/os/os.h" #include "nvim/path.h" #include "nvim/memory.h" +#include "nvim/ascii.h" /// Names of the environment variables, mapped to XDGVarType values static const char *xdg_env_vars[] = { -- cgit From 181c377697b8d4ef8234d3881466837ebae43f69 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 18 Oct 2015 00:24:23 +0300 Subject: stdpaths: Add Windows-specific directories --- src/nvim/os/stdpaths.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/nvim/os/stdpaths.c b/src/nvim/os/stdpaths.c index 6e5e37ec08..ef20fe0883 100644 --- a/src/nvim/os/stdpaths.c +++ b/src/nvim/os/stdpaths.c @@ -23,6 +23,12 @@ static const char *const xdg_defaults[] = { // Windows, Apple stuff are just shims right now #ifdef WIN32 // Windows + [kXDGConfigHome] = "$LOCALAPPDATA\\nvim\\config", + [kXDGDataHome] = "$LOCALAPPDATA\\nvim\\data", + [kXDGCacheHome] = "$LOCALAPPDATA\\nvim\\cache", + [kXDGRuntimeDir] = "", + [kXDGConfigDirs] = NULL, + [kXDGDataDirs] = NULL, #else // Linux, BSD, CYGWIN, Apple [kXDGConfigHome] = "~/.config", -- cgit From 25bb9c9f7d467563f90e1c492f62132ac23ab97b Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 18 Oct 2015 00:29:54 +0300 Subject: option: Silence “may be used unitialized” errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/nvim/option.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/nvim/option.c b/src/nvim/option.c index 9089947803..ab170facf6 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -484,9 +484,9 @@ static void set_runtimepath_default(void) char *const config_dirs = stdpaths_get_xdg_var(kXDGConfigDirs); #define SITE_SIZE (sizeof("site") - 1) #define AFTER_SIZE (sizeof("after") - 1) - size_t data_len; - size_t config_len; - size_t vimruntime_len; + size_t data_len = 0; + size_t config_len = 0; + size_t vimruntime_len = 0; if (data_home != NULL) { data_len = strlen(data_home); if (data_len != 0) { -- cgit From 198ba323b89fbfb5ea254ec7595a5c58ba7d2aa4 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 18 Oct 2015 00:35:30 +0300 Subject: stdpaths: Remove outdated comment --- src/nvim/os/stdpaths.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/nvim/os/stdpaths.c b/src/nvim/os/stdpaths.c index ef20fe0883..ce374828f9 100644 --- a/src/nvim/os/stdpaths.c +++ b/src/nvim/os/stdpaths.c @@ -20,7 +20,6 @@ static const char *xdg_env_vars[] = { /// /// Used in case environment variables contain nothing. Need to be expanded. static const char *const xdg_defaults[] = { - // Windows, Apple stuff are just shims right now #ifdef WIN32 // Windows [kXDGConfigHome] = "$LOCALAPPDATA\\nvim\\config", -- cgit From 030c608b7dee6662a9771a3acadb069b5eaab218 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 18 Oct 2015 13:32:45 +0300 Subject: option: Use memcnt for counting commas --- src/nvim/option.c | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/nvim/option.c b/src/nvim/option.c index ab170facf6..a4cfe45f10 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -301,19 +301,6 @@ static char *(p_cot_values[]) = {"menu", "menuone", "longest", "preview", # include "option.c.generated.h" #endif -/// Count commas in the given string -static size_t count_commas(const char *const s, size_t len) - FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT -{ - size_t ret = 0; - for (size_t i = 0; i < len; i++) { - if (s[i] == ',') { - ret++; - } - } - return ret; -} - /// Append string with escaped commas static char *strcpy_comma_escaped(char *dest, const char *src, const size_t len) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT @@ -356,7 +343,7 @@ static inline size_t compute_double_colon_len(const char *const val, const char *dir; iter = vim_colon_env_iter(val, iter, &dir, &dir_len); if (dir != NULL && dir_len > 0) { - ret += ((dir_len + count_commas(dir, dir_len) + common_suf_len + ret += ((dir_len + memcnt(dir, ',', dir_len) + common_suf_len + !after_pathsep(dir, dir + dir_len)) * 2 + single_suf_len); } @@ -490,7 +477,7 @@ static void set_runtimepath_default(void) if (data_home != NULL) { data_len = strlen(data_home); if (data_len != 0) { - rtp_size += ((data_len + count_commas(data_home, data_len) + rtp_size += ((data_len + memcnt(data_home, ',', data_len) + NVIM_SIZE + 1 + SITE_SIZE + 1 + !after_pathsep(data_home, data_home + data_len)) * 2 + AFTER_SIZE + 1); @@ -499,7 +486,7 @@ static void set_runtimepath_default(void) if (config_home != NULL) { config_len = strlen(config_home); if (config_len != 0) { - rtp_size += ((config_len + count_commas(config_home, config_len) + rtp_size += ((config_len + memcnt(config_home, ',', config_len) + NVIM_SIZE + 1 + !after_pathsep(config_home, config_home + config_len)) * 2 + AFTER_SIZE + 1); @@ -508,7 +495,7 @@ static void set_runtimepath_default(void) if (vimruntime != NULL) { vimruntime_len = strlen(vimruntime); if (vimruntime_len != 0) { - rtp_size += vimruntime_len + count_commas(vimruntime, vimruntime_len) + 1; + rtp_size += vimruntime_len + memcnt(vimruntime, ',', vimruntime_len) + 1; } } rtp_size += compute_double_colon_len(data_dirs, NVIM_SIZE + 1 + SITE_SIZE + 1, -- cgit From fefcc01cc1da9540767a2c0b14ebb532a51dd412 Mon Sep 17 00:00:00 2001 From: ZyX Date: Mon, 19 Oct 2015 15:25:49 +0300 Subject: os/fs: Allow os_mkdir_recurse directory name to end with /// --- src/nvim/os/fs.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c index 522e49950c..05f0f53c63 100644 --- a/src/nvim/os/fs.c +++ b/src/nvim/os/fs.c @@ -366,11 +366,17 @@ int os_mkdir_recurse(const char *const dir, int32_t mode, } while (e != real_end) { if (e > past_head) { - *e = '/'; + *e = PATHSEP; } else { *past_head = past_head_save; } - e += strlen(e); + const size_t component_len = strlen(e); + e += component_len; + if (e == real_end + && memcnt(e - component_len, PATHSEP, component_len) == component_len) { + // Path ends with something like "////". Ignore this. + break; + } int ret; if ((ret = os_mkdir(curdir, mode)) != 0) { *failed_dir = curdir; -- cgit From a8e18d9b5a74c8d061f383e0da7a88813db59502 Mon Sep 17 00:00:00 2001 From: ZyX Date: Mon, 19 Oct 2015 15:27:53 +0300 Subject: memline: Automatically create swap file directory for last directory --- src/nvim/memline.c | 129 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 79 insertions(+), 50 deletions(-) (limited to 'src') diff --git a/src/nvim/memline.c b/src/nvim/memline.c index d90e91be5d..2ff7cb3e19 100644 --- a/src/nvim/memline.c +++ b/src/nvim/memline.c @@ -406,10 +406,12 @@ void ml_setname(buf_T *buf) * Try all directories in the 'directory' option. */ dirp = p_dir; + bool found_existing_dir = false; for (;; ) { if (*dirp == NUL) /* tried all directories, fail */ break; - fname = findswapname(buf, &dirp, mfp->mf_fname); + fname = (char_u *)findswapname(buf, (char **)&dirp, (char *)mfp->mf_fname, + &found_existing_dir); /* alloc's fname */ if (dirp == NULL) /* out of memory */ break; @@ -504,13 +506,15 @@ void ml_open_file(buf_T *buf) * Try all directories in 'directory' option. */ dirp = p_dir; + bool found_existing_dir = false; for (;; ) { if (*dirp == NUL) break; - /* There is a small chance that between choosing the swap file name - * and creating it, another Vim creates the file. In that case the - * creation will fail and we will use another directory. */ - fname = findswapname(buf, &dirp, NULL); /* allocates fname */ + // There is a small chance that between choosing the swap file name + // and creating it, another Vim creates the file. In that case the + // creation will fail and we will use another directory. + fname = (char_u *)findswapname(buf, (char **)&dirp, NULL, + &found_existing_dir); if (dirp == NULL) break; /* out of memory */ if (fname == NULL) @@ -3222,45 +3226,56 @@ static int do_swapexists(buf_T *buf, char_u *fname) return 0; } -/* - * Find out what name to use for the swap file for buffer 'buf'. - * - * Several names are tried to find one that does not exist - * Returns the name in allocated memory or NULL. - * When out of memory "dirp" is set to NULL. - * - * Note: If BASENAMELEN is not correct, you will get error messages for - * not being able to open the swap or undo file - * Note: May trigger SwapExists autocmd, pointers may change! - */ -static char_u * -findswapname ( - buf_T *buf, - char_u **dirp, /* pointer to list of directories */ - char_u *old_fname /* don't give warning for this file name */ -) +/// Find out what name to use for the swap file for buffer 'buf'. +/// +/// Several names are tried to find one that does not exist. Last directory in +/// option is automatically created. +/// +/// @note If BASENAMELEN is not correct, you will get error messages for +/// not being able to open the swap or undo file. +/// @note May trigger SwapExists autocmd, pointers may change! +/// +/// @param[in] buf Buffer for which swap file names needs to be found. +/// @param[in,out] dirp Pointer to a list of directories. When out of memory, +/// is set to NULL. Is advanced to the next directory in +/// the list otherwise. +/// @param[in] old_fname Allowed existing swap file name. Except for this +/// case, name of the non-existing file is used. +/// @param[in,out] found_existing_dir If points to true, then new directory +/// for swap file is not created. At first +/// findswapname() call this argument must +/// point to false. This parameter may only +/// be set to true by this function, it is +/// never set to false. +/// +/// @return [allocated] Name of the swap file. +static char *findswapname(buf_T *buf, char **dirp, char *old_fname, + bool *found_existing_dir) + FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ARG(1, 2, 4) { - char_u *fname; - int n; - char_u *dir_name; - char_u *buf_fname = buf->b_fname; + char *fname; + size_t n; + char *dir_name; + char *buf_fname = (char *) buf->b_fname; /* * Isolate a directory name from *dirp and put it in dir_name. * First allocate some memory to put the directory name in. */ - dir_name = xmalloc(STRLEN(*dirp) + 1); - (void)copy_option_part(dirp, dir_name, 31000, ","); + const size_t dir_len = strlen(*dirp); + dir_name = xmalloc(dir_len + 1); + (void)copy_option_part((char_u **) dirp, (char_u *) dir_name, dir_len, ","); /* * we try different names until we find one that does not exist yet */ - fname = makeswapname(buf_fname, buf->b_ffname, buf, dir_name); + fname = (char *)makeswapname((char_u *)buf_fname, buf->b_ffname, buf, + (char_u *)dir_name); for (;; ) { if (fname == NULL) /* must be out of memory */ break; - if ((n = (int)STRLEN(fname)) == 0) { /* safety check */ + if ((n = strlen(fname)) == 0) { /* safety check */ xfree(fname); fname = NULL; break; @@ -3269,7 +3284,7 @@ findswapname ( // Extra security check: When a swap file is a symbolic link, this // is most likely a symlink attack. FileInfo file_info; - bool file_or_link_found = os_fileinfo_link((char *)fname, &file_info); + bool file_or_link_found = os_fileinfo_link(fname, &file_info); if (!file_or_link_found) { break; } @@ -3300,7 +3315,7 @@ findswapname ( * Try to read block 0 from the swap file to get the original * file name (and inode number). */ - fd = os_open((char *)fname, O_RDONLY, 0); + fd = os_open(fname, O_RDONLY, 0); if (fd >= 0) { if (read_eintr(fd, &b0, sizeof(b0)) == sizeof(b0)) { /* @@ -3311,7 +3326,7 @@ findswapname ( if (b0.b0_flags & B0_SAME_DIR) { if (fnamecmp(path_tail(buf->b_ffname), path_tail(b0.b0_fname)) != 0 - || !same_directory(fname, buf->b_ffname)) { + || !same_directory((char_u *) fname, buf->b_ffname)) { /* Symlinks may point to the same file even * when the name differs, need to check the * inode too. */ @@ -3351,12 +3366,12 @@ findswapname ( * user anyway. */ if (swap_exists_action != SEA_NONE - && has_autocmd(EVENT_SWAPEXISTS, buf_fname, buf)) - choice = do_swapexists(buf, fname); + && has_autocmd(EVENT_SWAPEXISTS, (char_u *) buf_fname, buf)) + choice = do_swapexists(buf, (char_u *) fname); if (choice == 0) { /* Show info about the existing swap file. */ - attention_message(buf, fname); + attention_message(buf, (char_u *) fname); /* We don't want a 'q' typed at the more-prompt * interrupt loading a file. */ @@ -3364,20 +3379,21 @@ findswapname ( } if (swap_exists_action != SEA_NONE && choice == 0) { - char_u *name; - - name = xmalloc(STRLEN(fname) - + STRLEN(_("Swap file \"")) - + STRLEN(_("\" already exists!")) + 5); - STRCPY(name, _("Swap file \"")); - home_replace(NULL, fname, name + STRLEN(name), - 1000, TRUE); - STRCAT(name, _("\" already exists!")); + char *name; + + const size_t fname_len = strlen(fname); + name = xmalloc(fname_len + + strlen(_("Swap file \"")) + + strlen(_("\" already exists!")) + 5); + strcpy(name, _("Swap file \"")); + home_replace(NULL, (char_u *) fname, (char_u *)&name[strlen(name)], + fname_len, true); + strcat(name, _("\" already exists!")); choice = do_dialog(VIM_WARNING, (char_u *)_("VIM - ATTENTION"), - name == NULL - ? (char_u *)_("Swap file already exists!") - : name, + (char_u *)(name == NULL + ? _("Swap file already exists!") + : name), # if defined(UNIX) process_still_running ? (char_u *)_( @@ -3409,7 +3425,7 @@ findswapname ( swap_exists_action = SEA_RECOVER; break; case 4: - os_remove((char *)fname); + os_remove(fname); break; case 5: swap_exists_action = SEA_QUIT; @@ -3421,7 +3437,7 @@ findswapname ( } /* If the file was deleted this fname can be used. */ - if (!os_file_exists(fname)) + if (!os_file_exists((char_u *) fname)) break; } else { @@ -3454,6 +3470,19 @@ findswapname ( --fname[n - 1]; /* ".swo", ".swn", etc. */ } + if (os_isdir((char_u *) dir_name)) { + *found_existing_dir = true; + } else if (!*found_existing_dir && **dirp == NUL) { + int ret; + char *failed_dir; + if ((ret = os_mkdir_recurse(dir_name, 0755, &failed_dir)) != 0) { + EMSG3(_("E303: Unable to create directory \"%s\" for swap file, " + "recovery impossible: %s"), + failed_dir, os_strerror(ret)); + xfree(failed_dir); + } + } + xfree(dir_name); return fname; } -- cgit From ca6235c20f4ac53cdc9f87857b6221a2841fe10e Mon Sep 17 00:00:00 2001 From: ZyX Date: Mon, 19 Oct 2015 15:32:06 +0300 Subject: *: Fix linter errors --- src/nvim/main.c | 2 +- src/nvim/memline.c | 4 ++-- src/nvim/path.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nvim/main.c b/src/nvim/main.c index 3c1d59567b..c10db29d1f 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -1873,7 +1873,7 @@ static void source_startup_scripts(mparm_T *parmp) else secure = 0; #endif - (void) do_source((char_u *)EXRC_FILE, FALSE, DOSO_NONE); + (void) do_source((char_u *)EXRC_FILE, false, DOSO_NONE); } } xfree(user_vimrc); diff --git a/src/nvim/memline.c b/src/nvim/memline.c index 2ff7cb3e19..aa3e0e0b1c 100644 --- a/src/nvim/memline.c +++ b/src/nvim/memline.c @@ -3385,10 +3385,10 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname, name = xmalloc(fname_len + strlen(_("Swap file \"")) + strlen(_("\" already exists!")) + 5); - strcpy(name, _("Swap file \"")); + STRCPY(name, _("Swap file \"")); home_replace(NULL, (char_u *) fname, (char_u *)&name[strlen(name)], fname_len, true); - strcat(name, _("\" already exists!")); + STRCAT(name, _("\" already exists!")); choice = do_dialog(VIM_WARNING, (char_u *)_("VIM - ATTENTION"), (char_u *)(name == NULL diff --git a/src/nvim/path.c b/src/nvim/path.c index e30f6b08d9..eaca85ed40 100644 --- a/src/nvim/path.c +++ b/src/nvim/path.c @@ -376,7 +376,7 @@ char *concat_fnames(const char *fname1, const char *fname2, bool sep) /// 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, and can no +/// fname1. For this reason fname1 must be allocated with xmalloc, and can no /// longer be used after running concat_fnames_realloc. /// /// @param fname1 is the first part of the path or filename -- cgit From 95979afc47f33ddde158cf699c1112a7be5cfc47 Mon Sep 17 00:00:00 2001 From: ZyX Date: Fri, 23 Oct 2015 17:04:26 +0300 Subject: oldtests: Also set `.` as default directories for old tests --- src/nvim/testdir/unix.vim | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/nvim/testdir/unix.vim b/src/nvim/testdir/unix.vim index aa1f6a92bc..a7daacf8cf 100644 --- a/src/nvim/testdir/unix.vim +++ b/src/nvim/testdir/unix.vim @@ -4,3 +4,6 @@ set shell=sh " Don't depend on system locale, always use utf-8 set encoding=utf-8 + +" Use safer defaults for various directories +set backupdir=. directory=. undodir=. viewdir=. -- cgit From 2b437e7102fddcd48215909816aae5ece01af48a Mon Sep 17 00:00:00 2001 From: ZyX Date: Fri, 23 Oct 2015 17:43:35 +0300 Subject: main: Check init.vim files also in other XDG directories --- src/nvim/main.c | 146 ++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 89 insertions(+), 57 deletions(-) (limited to 'src') diff --git a/src/nvim/main.c b/src/nvim/main.c index c10db29d1f..60a242fae3 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -1796,89 +1796,121 @@ static void exe_commands(mparm_T *parmp) TIME_MSG("executing command arguments"); } -/* - * Source startup scripts. - */ -static void source_startup_scripts(mparm_T *parmp) +/// Source vimrc or do other user initialization +/// +/// Does one of the following things, stops after whichever succeeds: +/// +/// 1. Execution of VIMINIT environment variable. +/// 2. Sourcing user vimrc file ($XDG_CONFIG_HOME/nvim/init.vim). +/// 3. Sourcing other vimrc files ($XDG_CONFIG_DIRS[1]/nvim/init.vim, …). +/// 4. Execution of EXINIT environment variable. +/// +/// @return True if it is needed to attempt to source exrc file according to +/// 'exrc' option definition. +static bool do_user_initialization(void) + FUNC_ATTR_WARN_UNUSED_RESULT { - int i; + bool do_exrc = p_exrc; + if (process_env("VIMINIT", true) == OK) { + return do_exrc; + } + char_u *user_vimrc = (char_u *)stdpaths_user_conf_subpath("init.vim"); + if (do_source(user_vimrc, true, DOSO_VIMRC) != FAIL) { + if (do_exrc) { + do_exrc = (path_full_compare((char_u *)VIMRC_FILE, user_vimrc, false) + != kEqualFiles); + } + xfree(user_vimrc); + return do_exrc; + } + xfree(user_vimrc); + char *const config_dirs = stdpaths_get_xdg_var(kXDGConfigDirs); + if (config_dirs != NULL) { + const void *iter = NULL; + do { + const char *dir; + size_t dir_len; + iter = vim_colon_env_iter(config_dirs, iter, &dir, &dir_len); + if (dir == NULL || dir_len == 0) { + break; + } + const char path_tail[] = { 'n', 'v', 'i', 'm', PATHSEP, + 'i', 'n', 'i', 't', '.', 'v', 'i', 'm', NUL }; + char *vimrc = xmalloc(dir_len + sizeof(path_tail) + 1); + memmove(vimrc, dir, dir_len); + vimrc[dir_len] = PATHSEP; + memmove(vimrc + dir_len + 1, path_tail, sizeof(path_tail)); + if (do_source((char_u *) vimrc, true, DOSO_VIMRC) != FAIL) { + if (do_exrc) { + do_exrc = (path_full_compare((char_u *)VIMRC_FILE, (char_u *)vimrc, + false) != kEqualFiles); + } + xfree(vimrc); + xfree(config_dirs); + return do_exrc; + } + xfree(vimrc); + } while (iter != NULL); + xfree(config_dirs); + } + if (process_env("EXINIT", false) == OK) { + return do_exrc; + } + return do_exrc; +} - /* - * If -u argument given, use only the initializations from that file and - * nothing else. - */ +/// Source startup scripts +/// +/// @param[in] +static void source_startup_scripts(const mparm_T *const parmp) + FUNC_ATTR_NONNULL_ALL +{ + // If -u argument given, use only the initializations from that file and + // nothing else. if (parmp->use_vimrc != NULL) { if (strcmp(parmp->use_vimrc, "NONE") == 0 || strcmp(parmp->use_vimrc, "NORC") == 0) { if (parmp->use_vimrc[2] == 'N') - p_lpl = FALSE; // don't load plugins either + p_lpl = false; // don't load plugins either } else { if (do_source((char_u *)parmp->use_vimrc, FALSE, DOSO_NONE) != OK) EMSG2(_("E282: Cannot read from \"%s\""), parmp->use_vimrc); } } else if (!silent_mode) { - - /* - * Get system wide defaults, if the file name is defined. - */ #ifdef SYS_VIMRC_FILE - (void)do_source((char_u *)SYS_VIMRC_FILE, FALSE, DOSO_NONE); + // Get system wide defaults, if the file name is defined. + (void) do_source((char_u *)SYS_VIMRC_FILE, false, DOSO_NONE); #endif - // Try to read initialization commands from the following places: - // - environment variable VIMINIT - // - user vimrc file (~/.config/nvim/init.vim) - // - environment variable EXINIT - // - user exrc file (~/.exrc) - // - second user exrc file ($VIM/.exrc for Dos) - // The first that exists is used, the rest is ignored. - char_u *user_vimrc = (char_u *)stdpaths_user_conf_subpath("init.vim"); - if (process_env("VIMINIT", true) != OK) { - if (do_source(user_vimrc, true, DOSO_VIMRC) == FAIL) { - process_env("EXINIT", false); - } - } - - /* - * Read initialization commands from ".vimrc" or ".exrc" in current - * directory. This is only done if the 'exrc' option is set. - * Because of security reasons we disallow shell and write commands - * now, except for unix if the file is owned by the user or 'secure' - * option has been reset in environment of global "exrc" or "vimrc". - * Only do this if VIMRC_FILE is not the same as USR_VIMRC_FILE or - * SYS_VIMRC_FILE. - */ - if (p_exrc) { + if (do_user_initialization()) { + // Read initialization commands from ".vimrc" or ".exrc" in current + // directory. This is only done if the 'exrc' option is set. + // Because of security reasons we disallow shell and write commands + // now, except for unix if the file is owned by the user or 'secure' + // option has been reset in environment of global "exrc" or "vimrc". + // Only do this if VIMRC_FILE is not the same as vimrc file sourced in + // do_user_initialization. #if defined(UNIX) // If vimrc file is not owned by user, set 'secure' mode. if (!file_owned(VIMRC_FILE)) #endif secure = p_secure; - i = FAIL; - if (path_full_compare(user_vimrc, - (char_u *)VIMRC_FILE, false) != kEqualFiles -#ifdef SYS_VIMRC_FILE - && path_full_compare((char_u *)SYS_VIMRC_FILE, - (char_u *)VIMRC_FILE, FALSE) != kEqualFiles -#endif - ) - i = do_source((char_u *)VIMRC_FILE, TRUE, DOSO_VIMRC); - - if (i == FAIL) { + if (do_source((char_u *)VIMRC_FILE, true, DOSO_VIMRC) == FAIL) { #if defined(UNIX) - /* if ".exrc" is not owned by user set 'secure' mode */ - if (!file_owned(EXRC_FILE)) + // if ".exrc" is not owned by user set 'secure' mode + if (!file_owned(EXRC_FILE)) { secure = p_secure; - else + } else { secure = 0; + } #endif - (void) do_source((char_u *)EXRC_FILE, false, DOSO_NONE); + (void)do_source((char_u *)EXRC_FILE, false, DOSO_NONE); } } - xfree(user_vimrc); - if (secure == 2) - need_wait_return = TRUE; + if (secure == 2) { + need_wait_return = true; + } secure = 0; } did_source_startup_scripts = true; -- cgit From 157af47202c41b3d987d45be3542e74456f06470 Mon Sep 17 00:00:00 2001 From: ZyX Date: Fri, 23 Oct 2015 17:45:59 +0300 Subject: os/unix_defs: Rename default system vimrc file to sysinit.vim This way all standard Vim file paths have .vim extension. VIMRC_FILE constant used for &exrc option was not touched. --- src/nvim/os/unix_defs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/os/unix_defs.h b/src/nvim/os/unix_defs.h index e1c3060999..b1511d4b56 100644 --- a/src/nvim/os/unix_defs.h +++ b/src/nvim/os/unix_defs.h @@ -20,7 +20,7 @@ // Unix system-dependent file names #ifndef SYS_VIMRC_FILE -# define SYS_VIMRC_FILE "$VIM/nvimrc" +# define SYS_VIMRC_FILE "$VIM/sysinit.vim" #endif #ifndef DFLT_HELPFILE # define DFLT_HELPFILE "$VIMRUNTIME/doc/help.txt" -- cgit