diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/buffer.c | 2 | ||||
-rw-r--r-- | src/eval.c | 2 | ||||
-rw-r--r-- | src/ex_getln.c | 2 | ||||
-rw-r--r-- | src/fileio.c | 2 | ||||
-rw-r--r-- | src/memline.c | 2 | ||||
-rw-r--r-- | src/misc1.c | 6 | ||||
-rw-r--r-- | src/os/fs.c | 163 | ||||
-rw-r--r-- | src/os/os.h | 4 | ||||
-rw-r--r-- | src/os_unix.c | 2 | ||||
-rw-r--r-- | src/syntax.c | 2 | ||||
-rw-r--r-- | src/window.c | 4 |
11 files changed, 112 insertions, 79 deletions
diff --git a/src/buffer.c b/src/buffer.c index 1c1c0dc6d9..4a13e4bcc9 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -2418,7 +2418,7 @@ void buflist_altfpos(win_T *win) /* * Return TRUE if 'ffname' is not the same file as current file. - * Fname must have a full path (expanded by mch_FullName()). + * Fname must have a full path (expanded by mch_full_name()). */ int otherfile(char_u *ffname) { diff --git a/src/eval.c b/src/eval.c index 08496e05bd..4eee644536 100644 --- a/src/eval.c +++ b/src/eval.c @@ -12467,7 +12467,7 @@ static void f_resolve(typval_T *argvars, typval_T *rettv) q[-1] = NUL; q = gettail(p); } - if (q > p && !mch_isFullName(buf)) { + if (q > p && !mch_is_full_name(buf)) { /* symlink is relative to directory of argument */ cpy = alloc((unsigned)(STRLEN(p) + STRLEN(buf) + 1)); if (cpy != NULL) { diff --git a/src/ex_getln.c b/src/ex_getln.c index dabe2e49e2..53f30471f5 100644 --- a/src/ex_getln.c +++ b/src/ex_getln.c @@ -3944,7 +3944,7 @@ expand_shellcmd ( flags |= EW_FILE | EW_EXEC; /* For an absolute name we don't use $PATH. */ - if (mch_isFullName(pat)) + if (mch_is_full_name(pat)) path = (char_u *)" "; else if ((pat[0] == '.' && (vim_ispathsep(pat[1]) || (pat[1] == '.' && vim_ispathsep(pat[2]))))) diff --git a/src/fileio.c b/src/fileio.c index 54631ad34a..4613c7cf1a 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -4769,7 +4769,7 @@ void shorten_fnames(int force) && !path_with_url(buf->b_fname) && (force || buf->b_sfname == NULL - || mch_isFullName(buf->b_sfname))) { + || mch_is_full_name(buf->b_sfname))) { vim_free(buf->b_sfname); buf->b_sfname = NULL; p = shorten_fname(buf->b_ffname, dirname); diff --git a/src/memline.c b/src/memline.c index 7ccd39b9fc..6fb29c2ddb 100644 --- a/src/memline.c +++ b/src/memline.c @@ -3381,7 +3381,7 @@ int resolve_symlink(char_u *fname, char_u *buf) * portion of the filename (if any) and the path the symlink * points to. */ - if (mch_isFullName(buf)) + if (mch_is_full_name(buf)) STRCPY(tmp, buf); else { char_u *tail; diff --git a/src/misc1.c b/src/misc1.c index 0fca08188b..770e870069 100644 --- a/src/misc1.c +++ b/src/misc1.c @@ -7945,7 +7945,7 @@ static void expand_path_option(char_u *curdir, garray_T *gap) else if (path_with_url(buf)) /* URL can't be used here */ continue; - else if (!mch_isFullName(buf)) { + else if (!mch_is_full_name(buf)) { /* Expand relative path to their full path equivalent */ len = (int)STRLEN(curdir); if (len + (int)STRLEN(buf) + 3 > MAXPATHL) @@ -8086,7 +8086,7 @@ static void uniquefy_paths(garray_T *gap, char_u *pattern) break; } - if (mch_isFullName(path)) { + if (mch_is_full_name(path)) { /* * Last resort: shorten relative to curdir if possible. * 'possible' means: @@ -8375,7 +8375,7 @@ gen_expand_wildcards ( */ if (mch_has_exp_wildcard(p)) { if ((flags & EW_PATH) - && !mch_isFullName(p) + && !mch_is_full_name(p) && !(p[0] == '.' && (vim_ispathsep(p[1]) || (p[1] == '.' && vim_ispathsep(p[2])))) diff --git a/src/os/fs.c b/src/os/fs.c index bc9a495984..0b83ca319e 100644 --- a/src/os/fs.c +++ b/src/os/fs.c @@ -1,4 +1,4 @@ -/* vi:set ts=8 sts=4 sw=4: +/* vi:set ts=2 sts=2 sw=2: * * VIM - Vi IMproved by Bram Moolenaar * @@ -33,96 +33,129 @@ int mch_chdir(char *path) { int mch_dirname(char_u *buf, int len) { int errno; - if ((errno = uv_cwd((char *)buf, len)) != 0) { + if ((errno = uv_cwd((char *) buf, len)) != 0) { STRCPY(buf, uv_strerror(errno)); return FAIL; } return OK; } -/* - * Get absolute file name into "buf[len]". +/* + * Get the absolute name of the given relative directory. * + * parameter directory: Directory name, relative to current directory. * return FAIL for failure, OK for success */ -int mch_FullName( - char_u *fname, - char_u *buf, - int len, - int force /* also expand when already absolute path */ - ) +int mch_full_dir_name(char *directory, char *buffer, int len) { - int l; - char_u olddir[MAXPATHL]; - char_u *p; int retval = OK; + if(0 == STRLEN(directory)) { + return mch_dirname((char_u *) buffer, len); + } + char old_dir[MAXPATHL]; - /* expand it if forced or not an absolute path */ - if (force || !mch_isFullName(fname)) { - /* - * If the file name has a path, change to that directory for a moment, - * and then do the getwd() (and get back to where we were). - * This will get the correct path name with "../" things. - */ - if ((p = vim_strrchr(fname, '/')) != NULL) { + /* Get current directory name. */ + if (FAIL == mch_dirname((char_u *) old_dir, MAXPATHL)) { + return FAIL; + } - /* Only change directory when we are sure we can return to where - * we are now. After doing "su" chdir(".") might not work. */ - if ((mch_dirname(olddir, MAXPATHL) == FAIL - || mch_chdir((char *)olddir) != 0)) { - p = NULL; /* can't get current dir: don't chdir */ - retval = FAIL; - } else { - /* The directory is copied into buf[], to be able to remove - * the file name without changing it (could be a string in - * read-only memory) */ - if (p - fname >= len) - retval = FAIL; - else { - vim_strncpy(buf, fname, p - fname); - if (mch_chdir((char *)buf)) - retval = FAIL; - else - fname = p + 1; - *buf = NUL; - } - } - } - if (mch_dirname(buf, len) == FAIL) { - retval = FAIL; - *buf = NUL; - } - if (p != NULL) { - l = mch_chdir((char *)olddir); - if (l != 0) - EMSG(_(e_prev_dir)); - } + /* We have to get back to the current dir at the end, check if that works. */ + if (0 != mch_chdir(old_dir)) { + return FAIL; + } - l = STRLEN(buf); - if (l >= len - 1) - retval = FAIL; /* no space for trailing "/" */ - else if (l > 0 && buf[l - 1] != '/' && *fname != NUL - && STRCMP(fname, ".") != 0) - STRCAT(buf, "/"); + if (0 != mch_chdir(directory)) { + retval = FAIL; } - /* Catch file names which are too long. */ - if (retval == FAIL || (int)(STRLEN(buf) + STRLEN(fname)) >= len) - return FAIL; + if ((FAIL == retval) || (FAIL == mch_dirname((char_u *) buffer, len))) { + retval = FAIL; + } + + if (0 != mch_chdir(old_dir)) { + /* That shouldn't happen, since we've tested if it works. */ + retval = FAIL; + EMSG(_(e_prev_dir)); + } + return retval; +} + +/* + * Append to_append to path with a slash in between. + */ +int append_path(char *path, char *to_append, int max_len) +{ + int current_length = STRLEN(path); + int to_append_length = STRLEN(to_append); + + /* Do not append empty strings. */ + if (0 == to_append_length) + return OK; + + /* Do not append a dot. */ + if (STRCMP(to_append, ".") == 0) + return OK; - /* Do not append ".", "/dir/." is equal to "/dir". */ - if (STRCMP(fname, ".") != 0) - STRCAT(buf, fname); + /* Glue both paths with a slash. */ + if (current_length > 0 && path[current_length-1] != '/') { + current_length += 1; /* Count the trailing slash. */ + if (current_length > max_len) + return FAIL; + + STRCAT(path, "/"); + } + + /* +1 for the NUL at the end. */ + if (current_length + to_append_length +1 > max_len) { + return FAIL; + } + + STRCAT(path, to_append); return OK; } /* + * Get absolute file name into "buf[len]". + * + * parameter force: Also expand when the given path in fname is already + * absolute. + * + * return FAIL for failure, OK for success + */ +int mch_full_name(char_u *fname, char_u *buf, int len, int force) +{ + char_u *p; + *buf = NUL; + + char relative_directory[len]; + char *end_of_path = (char *) fname; + + /* expand it if forced or not an absolute path */ + if (force || !mch_is_full_name(fname)) { + if ((p = vim_strrchr(fname, '/')) != NULL) { + + STRNCPY(relative_directory, fname, p-fname); + relative_directory[p-fname] = NUL; + end_of_path = (char *) (p + 1); + } else { + relative_directory[0] = NUL; + end_of_path = (char *) fname; + } + + if (FAIL == mch_full_dir_name(relative_directory, (char *) buf, len)) { + return FAIL; + } + } + return append_path((char *) buf, (char *) end_of_path, len); +} + +/* * Return TRUE if "fname" does not depend on the current directory. */ -int mch_isFullName(char_u *fname) +int mch_is_full_name(char_u *fname) { return *fname == '/' || *fname == '~'; } diff --git a/src/os/os.h b/src/os/os.h index 9cf2116091..1ef311b32c 100644 --- a/src/os/os.h +++ b/src/os/os.h @@ -6,7 +6,7 @@ long_u mch_total_mem(int special); int mch_chdir(char *path); int mch_dirname(char_u *buf, int len); -int mch_FullName (char_u *fname, char_u *buf, int len, int force); -int mch_isFullName (char_u *fname); +int mch_full_name (char_u *fname, char_u *buf, int len, int force); +int mch_is_full_name (char_u *fname); #endif diff --git a/src/os_unix.c b/src/os_unix.c index 80832024c9..003e45c2a0 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -1364,7 +1364,7 @@ int mch_can_exe(char_u *name) int retval; /* If it's an absolute or relative path don't need to use $PATH. */ - if (mch_isFullName(name) || (name[0] == '.' && (name[1] == '/' + if (mch_is_full_name(name) || (name[0] == '.' && (name[1] == '/' || (name[1] == '.' && name[2] == '/')))) return executable_file(name); diff --git a/src/syntax.c b/src/syntax.c index fb3285729f..ba33f16e23 100644 --- a/src/syntax.c +++ b/src/syntax.c @@ -4187,7 +4187,7 @@ static void syn_cmd_include(exarg_T *eap, int syncing) */ eap->argt |= (XFILE | NOSPC); separate_nextcmd(eap); - if (*eap->arg == '<' || *eap->arg == '$' || mch_isFullName(eap->arg)) { + if (*eap->arg == '<' || *eap->arg == '$' || mch_is_full_name(eap->arg)) { /* For an absolute path, "$VIM/..." or "<sfile>.." we ":source" the * file. Need to expand the file name first. In other cases * ":runtime!" is used. */ diff --git a/src/window.c b/src/window.c index cd96365902..16acf013ab 100644 --- a/src/window.c +++ b/src/window.c @@ -5065,7 +5065,7 @@ int path_with_url(char_u *fname) */ int vim_isAbsName(char_u *name) { - return path_with_url(name) != 0 || mch_isFullName(name); + return path_with_url(name) != 0 || mch_is_full_name(name); } /* @@ -5090,7 +5090,7 @@ vim_FullName ( url = path_with_url(fname); if (!url) - retval = mch_FullName(fname, buf, len, force); + retval = mch_full_name(fname, buf, len, force); if (url || retval == FAIL) { /* something failed; use the file name (truncate when too long) */ vim_strncpy(buf, fname, len - 1); |