home *** CD-ROM | disk | FTP | other *** search
- To: vim-dev@vim.org
- Subject: Patch 6.2.064
- Fcc: outbox
- From: Bram Moolenaar <Bram@moolenaar.net>
- Mime-Version: 1.0
- Content-Type: text/plain; charset=ISO-8859-1
- Content-Transfer-Encoding: 8bit
- ------------
-
- Patch 6.2.064
- Problem: resolve() only handles one symbolic link, need to repeat it to
- resolve all of them. Then need to simplify the file name.
- Solution: Make resolve() resolve all symbolic links and simplify the result.
- Add simplify() to just simplify a file name. Fix that test49
- doesn't work if /tmp is a symbolic link. (Servatius Brandt)
- Files: runtime/doc/eval.txt, src/eval.c, src/tag.c,
- src/testdir/test49.vim
-
-
- *** ../vim-6.2.063/runtime/doc/eval.txt Sun Jun 1 14:45:23 2003
- --- runtime/doc/eval.txt Thu Aug 7 19:31:16 2003
- ***************
- *** 1,4 ****
- ! *eval.txt* For Vim version 6.2. Last change: 2003 Jun 01
-
-
- VIM REFERENCE MANUAL by Bram Moolenaar
- --- 1,4 ----
- ! *eval.txt* For Vim version 6.2. Last change: 2003 Aug 07
-
-
- VIM REFERENCE MANUAL by Bram Moolenaar
- ***************
- *** 885,890 ****
- --- 887,893 ----
- setline( {lnum}, {line}) Number set line {lnum} to {line}
- setreg( {n}, {v}[, {opt}]) Number set register to value and type
- setwinvar( {nr}, {varname}, {val}) set {varname} in window {nr} to {val}
- + simplify( {filename}) String simplify filename as much as possible
- strftime( {format}[, {time}]) String time in specified format
- stridx( {haystack}, {needle}) Number first index of {needle} in {haystack}
- strlen( {expr}) Number length of the String {expr}
- ***************
- *** 2104,2116 ****
- successfully, and non-zero when the renaming failed.
- This function is not available in the |sandbox|.
-
- ! resolve({filename}) *resolve()*
- On MS-Windows, when {filename} is a shortcut (a .lnk file),
- ! returns the path the shortcut points to.
- ! On Unix, when {filename} is a symbolic link, returns the path
- ! the symlink points to. This only happens once, the returned
- ! path could be a symlink again.
- ! Otherwise {filename} is returned.
-
- search({pattern} [, {flags}]) *search()*
- Search for regexp pattern {pattern}. The search starts at the
- --- 2112,2129 ----
- successfully, and non-zero when the renaming failed.
- This function is not available in the |sandbox|.
-
- ! resolve({filename}) *resolve()* *E655*
- On MS-Windows, when {filename} is a shortcut (a .lnk file),
- ! returns the path the shortcut points to in a simplified form.
- ! On Unix, repeat resolving symbolic links in all path
- ! components of {filename} and return the simplified result.
- ! To cope with link cycles, resolving of symbolic links is
- ! stopped after 100 iterations.
- ! On other systems, return the simplified {filename}.
- ! The simplification step is done as by |simplify()|.
- ! resolve() keeps a leading path component specifying the
- ! current directory (provided the result is still a relative
- ! path name) and also keeps a trailing path separator.
-
- search({pattern} [, {flags}]) *search()*
- Search for regexp pattern {pattern}. The search starts at the
- ***************
- *** 2302,2307 ****
- --- 2315,2335 ----
- :call setwinvar(2, "myvar", "foobar")
- < This function is not available in the |sandbox|.
-
- + simplify({filename}) *simplify()*
- + Simplify the file name as much as possible without changing
- + the meaning. Shortcuts (on MS-Windows) or symbolic links (on
- + Unix) are not resolved. If the first path component in
- + {filename} designates the current directory, this will be
- + valid for the result as well. A trailing path separator is
- + not removed either.
- + Example: >
- + simplify("./dir/.././/file/") == "./file/"
- + < Note: The combination "dir/.." is only removed if "dir" is
- + a searchable directory or does not exist. On Unix, it is also
- + removed when "dir" is a symbolic link within the same
- + directory. In order to resolve all the involved symbolic
- + links before simplifying the path name, use |resolve()|.
- +
- strftime({format} [, {time}]) *strftime()*
- The result is a String, which is a formatted date and time, as
- specified by the {format} string. The given {time} is used,
- *** ../vim-6.2.063/src/eval.c Sun Aug 10 22:24:37 2003
- --- src/eval.c Thu Jul 31 19:47:34 2003
- ***************
- *** 318,323 ****
- --- 318,324 ----
- static void f_serverlist __ARGS((VAR argvars, VAR retvar));
- static void f_setline __ARGS((VAR argvars, VAR retvar));
- static void f_setreg __ARGS((VAR argvars, VAR retvar));
- + static void f_simplify __ARGS((VAR argvars, VAR retvar));
- static void find_some_match __ARGS((VAR argvars, VAR retvar, int start));
- static void f_strftime __ARGS((VAR argvars, VAR retvar));
- static void f_stridx __ARGS((VAR argvars, VAR retvar));
- ***************
- *** 2812,2817 ****
- --- 2813,2819 ----
- {"setline", 2, 2, f_setline},
- {"setreg", 2, 3, f_setreg},
- {"setwinvar", 3, 3, f_setwinvar},
- + {"simplify", 1, 1, f_simplify},
- #ifdef HAVE_STRFTIME
- {"strftime", 1, 2, f_strftime},
- #endif
- ***************
- *** 5808,5813 ****
- --- 5810,5816 ----
- VAR retvar;
- {
- char_u *p;
- + int limit = 100;
-
- p = get_var_string(&argvars[0]);
- #ifdef FEAT_SHORTCUT
- ***************
- *** 5826,5858 ****
- char_u buf[MAXPATHL + 1];
- char_u *cpy;
- int len;
-
- ! len = readlink((char *)p, (char *)buf, MAXPATHL);
- ! if (len > 0)
- {
- ! buf[len] = NUL;
- ! if (gettail(p) > p && !mch_isFullName(buf))
- {
- ! /* symlink is relative to directory of argument */
- ! cpy = alloc((unsigned)(STRLEN(p) + STRLEN(buf) + 1));
- ! if (cpy != NULL)
- {
- ! STRCPY(cpy, p);
- ! STRCPY(gettail(cpy), buf);
- ! retvar->var_val.var_string = cpy;
- ! p = NULL;
- }
- }
- else
- ! p = buf;
- }
- ! if (p != NULL)
- ! retvar->var_val.var_string = vim_strsave(p);
- }
- # else
- retvar->var_val.var_string = vim_strsave(p);
- # endif
- #endif
- retvar->var_type = VAR_STRING;
- }
-
- --- 5829,6020 ----
- char_u buf[MAXPATHL + 1];
- char_u *cpy;
- int len;
- + char_u *remain = NULL;
- + char_u *q;
- + int is_relative_to_current = FALSE;
- + int has_trailing_pathsep = FALSE;
-
- ! p = vim_strsave(p);
- !
- ! if (p[0] == '.' && (vim_ispathsep(p[1])
- ! || (p[1] == '.' && (vim_ispathsep(p[2])))))
- ! is_relative_to_current = TRUE;
- !
- ! len = STRLEN(p);
- ! if (len > 0 && vim_ispathsep(p[len-1]))
- ! has_trailing_pathsep = TRUE;
- !
- ! q = getnextcomp(p);
- ! if (*q != NUL)
- ! {
- ! /* Separate the first path component in "p", and keep the
- ! * remainder (beginning with the path separator). */
- ! remain = vim_strsave(q - 1);
- ! q[-1] = NUL;
- ! }
- !
- ! for(;;)
- {
- ! for (;;)
- {
- ! len = readlink((char *)p, (char *)buf, MAXPATHL);
- ! if (len <= 0)
- ! break;
- ! buf[len] = NUL;
- !
- ! if (limit-- == 0)
- ! {
- ! vim_free(p);
- ! vim_free(remain);
- ! EMSG(_("E655: Too much symbolic links (cycle?)"));
- ! retvar->var_val.var_string = NULL;
- ! goto fail;
- ! }
- !
- ! /* Ensure that the result will have a trailing path separator
- ! * if the argument has one. */
- ! if (remain == NULL && has_trailing_pathsep)
- ! add_pathsep(buf);
- !
- ! /* Separate the first path component in the link value and
- ! * concatenate the remainders. */
- ! q = getnextcomp(vim_ispathsep(*buf) ? buf + 1 : buf);
- ! if (*q != NUL)
- ! {
- ! if (remain == NULL)
- ! remain = vim_strsave(q - 1);
- ! else
- ! {
- ! cpy = vim_strnsave(q-1, STRLEN(q-1)+STRLEN(remain));
- ! if (cpy != NULL)
- ! {
- ! STRCAT(cpy, remain);
- ! vim_free(remain);
- ! remain = cpy;
- ! }
- ! }
- ! q[-1] = NUL;
- ! }
- !
- ! q = gettail(p);
- ! if (q > p && *q == NUL)
- ! {
- ! /* Ignore trailing path separator. */
- ! q[-1] = NUL;
- ! q = gettail(p);
- ! }
- ! if (q > p && !mch_isFullName(buf))
- ! {
- ! /* symlink is relative to directory of argument */
- ! cpy = alloc((unsigned)(STRLEN(p) + STRLEN(buf) + 1));
- ! if (cpy != NULL)
- ! {
- ! STRCPY(cpy, p);
- ! STRCPY(gettail(cpy), buf);
- ! vim_free(p);
- ! p = cpy;
- ! }
- ! }
- ! else
- {
- ! vim_free(p);
- ! p = vim_strsave(buf);
- }
- }
- +
- + if (remain == NULL)
- + break;
- +
- + /* Append the first path component of "remain" to "p". */
- + q = getnextcomp(remain + 1);
- + len = q - remain - (*q != NUL);
- + cpy = vim_strnsave(p, STRLEN(p) + len);
- + if (cpy != NULL)
- + {
- + STRNCAT(cpy, remain, len);
- + vim_free(p);
- + p = cpy;
- + }
- + /* Shorten "remain". */
- + if (*q != NUL)
- + STRCPY(remain, q - 1);
- else
- ! {
- ! vim_free(remain);
- ! remain = NULL;
- ! }
- }
- !
- ! /* If the result is a relative path name, make it explicitly relative to
- ! * the current directory if and only if the argument had this form. */
- ! if (!vim_ispathsep(*p))
- ! {
- ! if (is_relative_to_current
- ! && *p != NUL
- ! && !(p[0] == '.'
- ! && (p[1] == NUL
- ! || vim_ispathsep(p[1])
- ! || (p[1] == '.'
- ! && (p[2] == NUL
- ! || vim_ispathsep(p[2]))))))
- ! {
- ! /* Prepend "./". */
- ! cpy = vim_strnsave((char_u *)"./", 2 + STRLEN(p));
- ! if (cpy != NULL)
- ! {
- ! STRCAT(cpy, p);
- ! vim_free(p);
- ! p = cpy;
- ! }
- ! }
- ! else if (!is_relative_to_current)
- ! {
- ! /* Strip leading "./". */
- ! q = p;
- ! while (q[0] == '.' && vim_ispathsep(q[1]))
- ! q += 2;
- ! if (q > p)
- ! mch_memmove(p, p + 2, STRLEN(p + 2) + (size_t)1);
- ! }
- ! }
- !
- ! /* Ensure that the result will have no trailing path separator
- ! * if the argument had none. But keep "/" or "//". */
- ! if (!has_trailing_pathsep)
- ! {
- ! q = p + STRLEN(p);
- ! while ((q > p + 2 || (q == p + 2 && !vim_ispathsep(*p)))
- ! && vim_ispathsep(q[-1]))
- ! --q;
- ! *q = NUL;
- ! }
- !
- ! retvar->var_val.var_string = p;
- }
- # else
- retvar->var_val.var_string = vim_strsave(p);
- # endif
- #endif
- +
- + simplify_filename(retvar->var_val.var_string);
- +
- + fail:
- + retvar->var_type = VAR_STRING;
- + }
- +
- + /*
- + * "simplify()" function
- + */
- + static void
- + f_simplify(argvars, retvar)
- + VAR argvars;
- + VAR retvar;
- + {
- + char_u *p;
- +
- + p = get_var_string(&argvars[0]);
- + retvar->var_val.var_string = vim_strsave(p);
- + simplify_filename(retvar->var_val.var_string); /* simplify in place */
- retvar->var_type = VAR_STRING;
- }
-
- *** ../vim-6.2.063/src/tag.c Sun Aug 10 22:24:37 2003
- --- src/tag.c Thu Jul 31 18:27:34 2003
- ***************
- *** 2864,2875 ****
- #ifndef AMIGA /* Amiga doesn't have "..", it uses "/" */
- int components = 0;
- char_u *p, *tail, *start;
- ! #ifdef UNIX
- ! char_u *orig = vim_strsave(filename);
- !
- ! if (orig == NULL)
- ! return;
- ! #endif
-
- p = filename;
- #ifdef BACKSLASH_IN_FILENAME
- --- 2864,2871 ----
- #ifndef AMIGA /* Amiga doesn't have "..", it uses "/" */
- int components = 0;
- char_u *p, *tail, *start;
- ! int stripping_disabled = FALSE;
- ! int relative = TRUE;
-
- p = filename;
- #ifdef BACKSLASH_IN_FILENAME
- ***************
- *** 2877,2889 ****
- p += 2;
- #endif
-
- ! while (vim_ispathsep(*p))
- ! ++p;
- ! start = p; /* remember start after "c:/" or "/" or "//" */
-
- do
- {
- ! /* At this point "p" is pointing to the char following a "/". */
- #ifdef VMS
- /* VMS allows device:[path] - don't strip the [ in directory */
- if ((*p == '[' || *p == '<') && p > filename && p[-1] == ':')
- --- 2873,2891 ----
- p += 2;
- #endif
-
- ! if (vim_ispathsep(*p))
- ! {
- ! relative = FALSE;
- ! do
- ! ++p;
- ! while (vim_ispathsep(*p));
- ! }
- ! start = p; /* remember start after "c:/" or "/" or "///" */
-
- do
- {
- ! /* At this point "p" is pointing to the char following a single "/"
- ! * or "p" is at the "start" of the (absolute or relative) path name. */
- #ifdef VMS
- /* VMS allows device:[path] - don't strip the [ in directory */
- if ((*p == '[' || *p == '<') && p > filename && p[-1] == ':')
- ***************
- *** 2898,2952 ****
- /* ":: composition: vms host/passwd component */
- ++components;
- p = getnextcomp(p + 2);
- -
- }
- else
- #endif
- if (vim_ispathsep(*p))
- movetail(p, p + 1); /* remove duplicate "/" */
- ! else if (p[0] == '.' && vim_ispathsep(p[1]))
- ! movetail(p, p + 2); /* strip "./" */
- ! else if (p[0] == '.' && p[1] == '.' && vim_ispathsep(p[2]))
- {
- if (components > 0) /* strip one preceding component */
- {
- ! tail = p + 3; /* skip to after "../" or "..///" */
- ! while (vim_ispathsep(*tail))
- ! ++tail;
- ! --p;
- ! /* skip back to after previous '/' */
- ! while (p > start && !vim_ispathsep(p[-1]))
- ! --p;
- ! /* skip back to after first '/' in a row */
- ! while (p - 1 > start && vim_ispathsep(p[-2]))
- --p;
- ! movetail(p, tail); /* strip previous component */
- ! --components;
- }
- - else /* leading "../" */
- - p += 3; /* skip to char after "/" */
- }
- else
- {
- ++components; /* simple path component */
- p = getnextcomp(p);
- }
- ! } while (p != NULL && *p != NUL);
- !
- ! #ifdef UNIX
- ! /* Check that the new file name is really the same file. This will not be
- ! * the case when using symbolic links: "dir/link/../name" != "dir/name". */
- ! {
- ! struct stat orig_st, new_st;
- !
- ! if ( mch_stat((char *)orig, &orig_st) < 0
- ! || mch_stat((char *)filename, &new_st) < 0
- ! || orig_st.st_ino != new_st.st_ino
- ! || orig_st.st_dev != new_st.st_dev)
- ! STRCPY(filename, orig);
- ! vim_free(orig);
- ! }
- ! #endif
- #endif /* !AMIGA */
- }
-
- --- 2900,3064 ----
- /* ":: composition: vms host/passwd component */
- ++components;
- p = getnextcomp(p + 2);
- }
- else
- #endif
- if (vim_ispathsep(*p))
- movetail(p, p + 1); /* remove duplicate "/" */
- ! else if (p[0] == '.' && (vim_ispathsep(p[1]) || p[1] == NUL))
- ! {
- ! if (p == start && relative)
- ! p += 1 + (p[1] != NUL); /* keep single "." or leading "./" */
- ! else
- ! {
- ! /* Strip "./" or ".///". If we are at the end of the file name
- ! * and there is no trailing path separator, either strip "/." if
- ! * we are after "start", or strip "." if we are at the beginning
- ! * of an absolute path name . */
- ! tail = p + 1;
- ! if (p[1] != NUL)
- ! while (vim_ispathsep(*tail))
- ! ++tail;
- ! else if (p > start)
- ! --p; /* strip preceding path separator */
- ! movetail(p, tail);
- ! }
- ! }
- ! else if (p[0] == '.' && p[1] == '.' &&
- ! (vim_ispathsep(p[2]) || p[2] == NUL))
- {
- + /* Skip to after ".." or "../" or "..///". */
- + tail = p + 2;
- + while (vim_ispathsep(*tail))
- + ++tail;
- +
- if (components > 0) /* strip one preceding component */
- {
- ! int do_strip = FALSE;
- ! char_u saved_char;
- ! struct stat st, new_st;
- !
- ! /* Don't strip for an erroneous file name. */
- ! if (!stripping_disabled)
- ! {
- ! /* If the preceding component does not exist in the file
- ! * system, we strip it. On Unix, we don't accept a symbolic
- ! * link that refers to a non-existent file. */
- ! saved_char = p[-1];
- ! p[-1] = NUL;
- ! #ifdef UNIX
- ! if (mch_lstat((char *)filename, &st) < 0)
- ! #else
- ! if (mch_stat((char *)filename, &st) < 0)
- ! #endif
- ! do_strip = TRUE;
- ! p[-1] = saved_char;
- !
- --p;
- ! /* Skip back to after previous '/'. */
- ! while (p > start && !vim_ispathsep(p[-1]))
- ! --p;
- !
- ! if (!do_strip)
- ! {
- ! /* If the component exists in the file system, check
- ! * that stripping it won't change the meaning of the
- ! * file name. First get information about the
- ! * unstripped file name. This may fail if the component
- ! * to strip is not a searchable directory (but a regular
- ! * file, for instance), since the trailing "/.." cannot
- ! * be applied then. We don't strip it then since we
- ! * don't want to replace an erroneous file name by
- ! * a valid one, and we disable stripping of later
- ! * components. */
- ! saved_char = *tail;
- ! *tail = NUL;
- ! if (mch_stat((char *)filename, &st) >= 0)
- ! do_strip = TRUE;
- ! else
- ! stripping_disabled = TRUE;
- ! *tail = saved_char;
- ! #ifdef UNIX
- ! if (do_strip)
- ! {
- ! /* On Unix, the check for the unstripped file name
- ! * above works also for a symbolic link pointing to
- ! * a searchable directory. But then the parent of
- ! * the directory pointed to by the link must be the
- ! * same as the stripped file name. (The latter
- ! * exists in the file system since it is the
- ! * component's parent directory.) */
- ! if (p == start && relative)
- ! (void)mch_stat(".", &new_st);
- ! else
- ! {
- ! saved_char = *p;
- ! *p = NUL;
- ! (void)mch_stat((char *)filename, &new_st);
- ! *p = saved_char;
- ! }
- !
- ! if (new_st.st_ino != st.st_ino ||
- ! new_st.st_dev != st.st_dev)
- ! {
- ! do_strip = FALSE;
- ! /* We don't disable stripping of later
- ! * components since the unstripped path name is
- ! * still valid. */
- ! }
- ! }
- ! #endif
- ! }
- ! }
- !
- ! if (!do_strip)
- ! {
- ! /* Skip the ".." or "../" and reset the counter for the
- ! * components that might be stripped later on. */
- ! p = tail;
- ! components = 0;
- ! }
- ! else
- ! {
- ! /* Strip previous component. If the result would get empty
- ! * and there is no trailing path separator, leave a single
- ! * "." instead. If we are at the end of the file name and
- ! * there is no trailing path separator and a preceding
- ! * component is left after stripping, strip its trailing
- ! * path separator as well. */
- ! if (p == start && relative && tail[-1] == '.')
- ! {
- ! *p++ = '.';
- ! *p = NUL;
- ! }
- ! else
- ! {
- ! if (p > start && tail[-1] == '.')
- ! --p;
- ! movetail(p, tail); /* strip previous component */
- ! }
- !
- ! --components;
- ! }
- ! }
- ! else if (p == start && !relative) /* leading "/.." or "/../" */
- ! movetail(p, tail); /* strip ".." or "../" */
- ! else
- ! {
- ! if (p == start + 2 && p[-2] == '.') /* leading "./../" */
- ! {
- ! movetail(p - 2, p); /* strip leading "./" */
- ! tail -= 2;
- ! }
- ! p = tail; /* skip to char after ".." or "../" */
- }
- }
- else
- {
- ++components; /* simple path component */
- p = getnextcomp(p);
- }
- ! } while (*p != NUL);
- #endif /* !AMIGA */
- }
-
- *** ../vim-6.2.063/src/testdir/test49.vim Fri May 30 21:45:31 2003
- --- src/testdir/test49.vim Thu Jul 31 18:25:02 2003
- ***************
- *** 1,6 ****
- " Vim script language tests
- " Author: Servatius Brandt <Servatius.Brandt@fujitsu-siemens.com>
- ! " Last Change: 2003 May 30
-
- "-------------------------------------------------------------------------------
- " Test environment {{{1
- --- 1,6 ----
- " Vim script language tests
- " Author: Servatius Brandt <Servatius.Brandt@fujitsu-siemens.com>
- ! " Last Change: 2003 Jul 30
-
- "-------------------------------------------------------------------------------
- " Test environment {{{1
- ***************
- *** 5076,5082 ****
- Xpath 1048576 " X: 1048576
- let exception = v:exception
- let throwpoint = v:throwpoint
- ! call CHECK(7, "autsch", scriptT, '\<6\>')
- finally
- Xpath 2097152 " X: 2097152
- let exception = v:exception
- --- 5076,5085 ----
- Xpath 1048576 " X: 1048576
- let exception = v:exception
- let throwpoint = v:throwpoint
- ! " Symbolic links in tempname()s are not resolved, whereas resolving
- ! " is done for v:throwpoint. Resolve the temporary file name for
- ! " scriptT, so that it can be matched against v:throwpoint.
- ! call CHECK(7, "autsch", resolve(scriptT), '\<6\>')
- finally
- Xpath 2097152 " X: 2097152
- let exception = v:exception
- ***************
- *** 5091,5097 ****
- Xpath 8388608 " X: 8388608
- let exception = v:exception
- let throwpoint = v:throwpoint
- ! call CHECK(9, "brrrr", scriptT, '\<8\>')
- finally
- Xpath 16777216 " X: 16777216
- let exception = v:exception
- --- 5094,5101 ----
- Xpath 8388608 " X: 8388608
- let exception = v:exception
- let throwpoint = v:throwpoint
- ! " Resolve scriptT for matching it against v:throwpoint.
- ! call CHECK(9, "brrrr", resolve(scriptT), '\<8\>')
- finally
- Xpath 16777216 " X: 16777216
- let exception = v:exception
- *** ../vim-6.2.063/src/version.c Sun Aug 10 22:24:37 2003
- --- src/version.c Sun Aug 10 22:26:34 2003
- ***************
- *** 632,633 ****
- --- 632,635 ----
- { /* Add new patch number below this line */
- + /**/
- + 64,
- /**/
-
- --
- From "know your smileys":
- :-{} Too much lipstick
-
- /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\
- /// Creator of Vim - Vi IMproved -- http://www.Vim.org \\\
- \\\ Project leader for A-A-P -- http://www.A-A-P.org ///
- \\\ Help AIDS victims, buy here: http://ICCF-Holland.org/click1.html ///
-