Mercurial > vim
diff src/ex_cmds2.c @ 13190:9fccd578ce1f v8.0.1469
patch 8.0.1469: when package path is a symlink 'runtimepath' is wrong
commit https://github.com/vim/vim/commit/2374faae111057ee28e8d487f9a52a95855e2206
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun Feb 4 17:47:42 2018 +0100
patch 8.0.1469: when package path is a symlink 'runtimepath' is wrong
Problem: When package path is a symlink adding it to 'runtimepath' happens
at the end.
Solution: Do not resolve symlinks before locating the position in
'runtimepath'. (Ozaki Kiichi, closes #2604)
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Sun, 04 Feb 2018 18:00:06 +0100 |
parents | afd60028f7b7 |
children | ac42c4b11dbc |
line wrap: on
line diff
--- a/src/ex_cmds2.c +++ b/src/ex_cmds2.c @@ -3567,13 +3567,11 @@ source_all_matches(char_u *pat) } } -/* used for "cookie" of add_pack_plugin() */ -static int APP_ADD_DIR; -static int APP_LOAD; -static int APP_BOTH; - - static void -add_pack_plugin(char_u *fname, void *cookie) +/* + * Add the package directory to 'runtimepath'. + */ + static int +add_pack_dir_to_rtp(char_u *fname) { char_u *p4, *p3, *p2, *p1, *p; char_u *insp; @@ -3582,125 +3580,154 @@ add_pack_plugin(char_u *fname, void *coo int keep; size_t oldlen; size_t addlen; - char_u *afterdir; + char_u *afterdir = NULL; size_t afterlen = 0; - char_u *ffname = fix_fname(fname); + char_u *ffname = NULL; size_t fname_len; char_u *buf = NULL; char_u *rtp_ffname; int match; - - if (ffname == NULL) - return; - if (cookie != &APP_LOAD && strstr((char *)p_rtp, (char *)ffname) == NULL) - { - /* directory is not yet in 'runtimepath', add it */ - p4 = p3 = p2 = p1 = get_past_head(ffname); - for (p = p1; *p; MB_PTR_ADV(p)) - if (vim_ispathsep_nocolon(*p)) - { - p4 = p3; p3 = p2; p2 = p1; p1 = p; - } - - /* now we have: - * rtp/pack/name/start/name - * p4 p3 p2 p1 - * - * find the part up to "pack" in 'runtimepath' */ - c = *p4; - *p4 = NUL; - - /* Find "ffname" in "p_rtp", ignoring '/' vs '\' differences. */ - fname_len = STRLEN(ffname); - insp = p_rtp; - buf = alloc(MAXPATHL); - if (buf == NULL) - goto theend; - while (*insp != NUL) + int retval = FAIL; + + p4 = p3 = p2 = p1 = get_past_head(fname); + for (p = p1; *p; MB_PTR_ADV(p)) + if (vim_ispathsep_nocolon(*p)) { - copy_option_part(&insp, buf, MAXPATHL, ","); - add_pathsep(buf); - rtp_ffname = fix_fname(buf); - if (rtp_ffname == NULL) - goto theend; - match = vim_fnamencmp(rtp_ffname, ffname, fname_len) == 0; - vim_free(rtp_ffname); - if (match) - break; + p4 = p3; p3 = p2; p2 = p1; p1 = p; } - if (*insp == NUL) - /* not found, append at the end */ - insp = p_rtp + STRLEN(p_rtp); - else - /* append after the matching directory. */ - --insp; - *p4 = c; - - /* check if rtp/pack/name/start/name/after exists */ - afterdir = concat_fnames(ffname, (char_u *)"after", TRUE); - if (afterdir != NULL && mch_isdir(afterdir)) - afterlen = STRLEN(afterdir) + 1; /* add one for comma */ - - oldlen = STRLEN(p_rtp); - addlen = STRLEN(ffname) + 1; /* add one for comma */ - new_rtp = alloc((int)(oldlen + addlen + afterlen + 1)); - /* add one for NUL */ - if (new_rtp == NULL) + /* now we have: + * rtp/pack/name/start/name + * p4 p3 p2 p1 + * + * find the part up to "pack" in 'runtimepath' */ + c = *++p4; /* append pathsep in order to expand symlink */ + *p4 = NUL; + ffname = fix_fname(fname); + *p4 = c; + if (ffname == NULL) + return FAIL; + + /* Find "ffname" in "p_rtp", ignoring '/' vs '\' differences. */ + fname_len = STRLEN(ffname); + insp = p_rtp; + buf = alloc(MAXPATHL); + if (buf == NULL) + goto theend; + while (*insp != NUL) + { + copy_option_part(&insp, buf, MAXPATHL, ","); + add_pathsep(buf); + rtp_ffname = fix_fname(buf); + if (rtp_ffname == NULL) goto theend; - keep = (int)(insp - p_rtp); - mch_memmove(new_rtp, p_rtp, keep); - new_rtp[keep] = ','; - mch_memmove(new_rtp + keep + 1, ffname, addlen); - if (p_rtp[keep] != NUL) - mch_memmove(new_rtp + keep + addlen, p_rtp + keep, - oldlen - keep + 1); - if (afterlen > 0) - { - STRCAT(new_rtp, ","); - STRCAT(new_rtp, afterdir); - } - set_option_value((char_u *)"rtp", 0L, new_rtp, 0); - vim_free(new_rtp); - vim_free(afterdir); + match = vim_fnamencmp(rtp_ffname, ffname, fname_len) == 0; + vim_free(rtp_ffname); + if (match) + break; } - if (cookie != &APP_ADD_DIR) + if (*insp == NUL) + /* not found, append at the end */ + insp = p_rtp + STRLEN(p_rtp); + else + /* append after the matching directory. */ + --insp; + + /* check if rtp/pack/name/start/name/after exists */ + afterdir = concat_fnames(fname, (char_u *)"after", TRUE); + if (afterdir != NULL && mch_isdir(afterdir)) + afterlen = STRLEN(afterdir) + 1; /* add one for comma */ + + oldlen = STRLEN(p_rtp); + addlen = STRLEN(fname) + 1; /* add one for comma */ + new_rtp = alloc((int)(oldlen + addlen + afterlen + 1)); + /* add one for NUL */ + if (new_rtp == NULL) + goto theend; + keep = (int)(insp - p_rtp); + mch_memmove(new_rtp, p_rtp, keep); + new_rtp[keep] = ','; + mch_memmove(new_rtp + keep + 1, fname, addlen); + if (p_rtp[keep] != NUL) + mch_memmove(new_rtp + keep + addlen, p_rtp + keep, oldlen - keep + 1); + if (afterlen > 0) { - static char *plugpat = "%s/plugin/**/*.vim"; - static char *ftpat = "%s/ftdetect/*.vim"; - int len; - char_u *pat; - - len = (int)STRLEN(ffname) + (int)STRLEN(ftpat); - pat = alloc(len); - if (pat == NULL) - goto theend; - vim_snprintf((char *)pat, len, plugpat, ffname); - source_all_matches(pat); - -#ifdef FEAT_AUTOCMD - { - char_u *cmd = vim_strsave((char_u *)"g:did_load_filetypes"); - - /* If runtime/filetype.vim wasn't loaded yet, the scripts will be - * found when it loads. */ - if (cmd != NULL && eval_to_number(cmd) > 0) - { - do_cmdline_cmd((char_u *)"augroup filetypedetect"); - vim_snprintf((char *)pat, len, ftpat, ffname); - source_all_matches(pat); - do_cmdline_cmd((char_u *)"augroup END"); - } - vim_free(cmd); - } -#endif - vim_free(pat); + STRCAT(new_rtp, ","); + STRCAT(new_rtp, afterdir); } + set_option_value((char_u *)"rtp", 0L, new_rtp, 0); + vim_free(new_rtp); + retval = OK; theend: vim_free(buf); vim_free(ffname); + vim_free(afterdir); + return retval; +} + +/* + * Load scripts in "plugin" and "ftdetect" directories of the package. + */ + static int +load_pack_plugin(char_u *fname) +{ + static char *plugpat = "%s/plugin/**/*.vim"; + static char *ftpat = "%s/ftdetect/*.vim"; + int len; + char_u *ffname = fix_fname(fname); + char_u *pat = NULL; + int retval = FAIL; + + if (ffname == NULL) + return FAIL; + len = (int)STRLEN(ffname) + (int)STRLEN(ftpat); + pat = alloc(len); + if (pat == NULL) + goto theend; + vim_snprintf((char *)pat, len, plugpat, ffname); + source_all_matches(pat); + +#ifdef FEAT_AUTOCMD + { + char_u *cmd = vim_strsave((char_u *)"g:did_load_filetypes"); + + /* If runtime/filetype.vim wasn't loaded yet, the scripts will be + * found when it loads. */ + if (cmd != NULL && eval_to_number(cmd) > 0) + { + do_cmdline_cmd((char_u *)"augroup filetypedetect"); + vim_snprintf((char *)pat, len, ftpat, ffname); + source_all_matches(pat); + do_cmdline_cmd((char_u *)"augroup END"); + } + vim_free(cmd); + } +#endif + vim_free(pat); + retval = OK; + +theend: + vim_free(ffname); + return retval; +} + +/* used for "cookie" of add_pack_plugin() */ +static int APP_ADD_DIR; +static int APP_LOAD; +static int APP_BOTH; + + static void +add_pack_plugin(char_u *fname, void *cookie) +{ + if (cookie != &APP_LOAD && strstr((char *)p_rtp, (char *)fname) == NULL) + /* directory is not yet in 'runtimepath', add it */ + if (add_pack_dir_to_rtp(fname) == FAIL) + return; + + if (cookie != &APP_ADD_DIR) + load_pack_plugin(fname); } /*