summaryrefslogtreecommitdiffstats
path: root/src/eval.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2008-05-29 19:47:13 +0000
committerBram Moolenaar <Bram@vim.org>2008-05-29 19:47:13 +0000
commitbcebfb6925372a6d67b8a04e92a19aca8ac03016 (patch)
tree69a154f4f0b35714eb7b67d0e0938e4d9f0b4303 /src/eval.c
parent59fb5aaacb7da181a33bcc2012b9c9c91b1ed9ec (diff)
updated for version 7.1-304v7.1.304
Diffstat (limited to 'src/eval.c')
-rw-r--r--src/eval.c187
1 files changed, 110 insertions, 77 deletions
diff --git a/src/eval.c b/src/eval.c
index 34263544cb..1ad9cec1ef 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -21068,8 +21068,12 @@ static int shortpath_for_invalid_fname __ARGS((char_u **fname, char_u **bufp, in
static int shortpath_for_partial __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen));
/*
- * Get the short pathname of a file.
- * Returns 1 on success. *fnamelen is 0 for nonexistent path.
+ * Get the short path (8.3) for the filename in "fnamep".
+ * Only works for a valid file name.
+ * When the path gets longer "fnamep" is changed and the allocated buffer
+ * is put in "bufp".
+ * *fnamelen is the length of "fnamep" and set to 0 for a nonexistent path.
+ * Returns OK on success, FAIL on failure.
*/
static int
get_short_pathname(fnamep, bufp, fnamelen)
@@ -21077,36 +21081,44 @@ get_short_pathname(fnamep, bufp, fnamelen)
char_u **bufp;
int *fnamelen;
{
- int l,len;
+ int l, len;
char_u *newbuf;
len = *fnamelen;
-
l = GetShortPathName(*fnamep, *fnamep, len);
if (l > len - 1)
{
/* If that doesn't work (not enough space), then save the string
- * and try again with a new buffer big enough
- */
+ * and try again with a new buffer big enough. */
newbuf = vim_strnsave(*fnamep, l);
if (newbuf == NULL)
- return 0;
+ return FAIL;
vim_free(*bufp);
*fnamep = *bufp = newbuf;
- l = GetShortPathName(*fnamep,*fnamep,l+1);
-
- /* Really should always succeed, as the buffer is big enough */
+ /* Really should always succeed, as the buffer is big enough. */
+ l = GetShortPathName(*fnamep, *fnamep, l+1);
}
*fnamelen = l;
- return 1;
+ return OK;
}
/*
- * Create a short path name. Returns the length of the buffer it needs.
- * Doesn't copy over the end of the buffer passed in.
+ * Get the short path (8.3) for the filename in "fname". The converted
+ * path is returned in "bufp".
+ *
+ * Some of the directories specified in "fname" may not exist. This function
+ * will shorten the existing directories at the beginning of the path and then
+ * append the remaining non-existing path.
+ *
+ * fname - Pointer to the filename to shorten. On return, contains the
+ * pointer to the shortened pathname
+ * bufp - Pointer to an allocated buffer for the filename.
+ * fnamelen - Length of the filename pointed to by fname
+ *
+ * Returns OK on success (or nothing done) and FAIL on failure (out of memory).
*/
static int
shortpath_for_invalid_fname(fname, bufp, fnamelen)
@@ -21114,85 +21126,106 @@ shortpath_for_invalid_fname(fname, bufp, fnamelen)
char_u **bufp;
int *fnamelen;
{
- char_u *s, *p, *pbuf2, *pbuf3;
+ char_u *short_fname, *save_fname, *pbuf_unused;
+ char_u *endp, *save_endp;
char_u ch;
- int len, len2, plen, slen;
+ int old_len, len;
+ int new_len, sfx_len;
+ int retval = OK;
/* Make a copy */
- len2 = *fnamelen;
- pbuf2 = vim_strnsave(*fname, len2);
- pbuf3 = NULL;
+ old_len = *fnamelen;
+ save_fname = vim_strnsave(*fname, old_len);
+ pbuf_unused = NULL;
+ short_fname = NULL;
- s = pbuf2 + len2 - 1; /* Find the end */
- slen = 1;
- plen = len2;
+ endp = save_fname + old_len - 1; /* Find the end of the copy */
+ save_endp = endp;
- if (after_pathsep(pbuf2, s + 1))
+ /*
+ * Try shortening the supplied path till it succeeds by removing one
+ * directory at a time from the tail of the path.
+ */
+ len = 0;
+ for (;;)
{
- --s;
- ++slen;
- --plen;
- }
+ /* go back one path-separator */
+ while (endp > save_fname && !after_pathsep(save_fname, endp + 1))
+ --endp;
+ if (endp <= save_fname)
+ break; /* processed the complete path */
- do
- {
- /* Go back one path-separator */
- while (s > pbuf2 && !after_pathsep(pbuf2, s + 1))
+ /*
+ * Replace the path separator with a NUL and try to shorten the
+ * resulting path.
+ */
+ ch = *endp;
+ *endp = 0;
+ short_fname = save_fname;
+ len = STRLEN(short_fname) + 1;
+ if (get_short_pathname(&short_fname, &pbuf_unused, &len) == FAIL)
{
- --s;
- ++slen;
- --plen;
+ retval = FAIL;
+ goto theend;
}
- if (s <= pbuf2)
- break;
+ *endp = ch; /* preserve the string */
- /* Remember the character that is about to be splatted */
- ch = *s;
- *s = 0; /* get_short_pathname requires a null-terminated string */
+ if (len > 0)
+ break; /* successfully shortened the path */
- /* Try it in situ */
- p = pbuf2;
- if (!get_short_pathname(&p, &pbuf3, &plen))
- {
- vim_free(pbuf2);
- return -1;
- }
- *s = ch; /* Preserve the string */
- } while (plen == 0);
+ /* failed to shorten the path. Skip the path separator */
+ --endp;
+ }
- if (plen > 0)
+ if (len > 0)
{
- /* Remember the length of the new string. */
- *fnamelen = len = plen + slen;
+ /*
+ * Succeeded in shortening the path. Now concatenate the shortened
+ * path with the remaining path at the tail.
+ */
+
+ /* Compute the length of the new path. */
+ sfx_len = (int)(save_endp - endp) + 1;
+ new_len = len + sfx_len;
+
+ *fnamelen = new_len;
vim_free(*bufp);
- if (len > len2)
+ if (new_len > old_len)
{
- /* If there's not enough space in the currently allocated string,
- * then copy it to a buffer big enough.
- */
- *fname= *bufp = vim_strnsave(p, len);
+ /* There is not enough space in the currently allocated string,
+ * copy it to a buffer big enough. */
+ *fname = *bufp = vim_strnsave(short_fname, new_len);
if (*fname == NULL)
- return -1;
+ {
+ retval = FAIL;
+ goto theend;
+ }
}
else
{
- /* Transfer pbuf2 to being the main buffer (it's big enough) */
- *fname = *bufp = pbuf2;
- if (p != pbuf2)
- strncpy(*fname, p, plen);
- pbuf2 = NULL;
+ /* Transfer short_fname to the main buffer (it's big enough),
+ * unless get_short_pathname() did its work in-place. */
+ *fname = *bufp = save_fname;
+ if (short_fname != save_fname)
+ vim_strncpy(save_fname, short_fname, len);
+ save_fname = NULL;
}
- /* Concat the next bit */
- strncpy(*fname + plen, s, slen);
- (*fname)[len] = '\0';
+
+ /* concat the not-shortened part of the path */
+ vim_strncpy(*fname + len, endp, sfx_len);
+ (*fname)[new_len] = NUL;
}
- vim_free(pbuf3);
- vim_free(pbuf2);
- return 0;
+
+theend:
+ vim_free(pbuf_unused);
+ vim_free(save_fname);
+
+ return retval;
}
/*
* Get a pathname for a partial path.
+ * Returns OK for success, FAIL for failure.
*/
static int
shortpath_for_partial(fnamep, bufp, fnamelen)
@@ -21222,8 +21255,8 @@ shortpath_for_partial(fnamep, bufp, fnamelen)
len = tflen = (int)STRLEN(tfname);
- if (!get_short_pathname(&tfname, &pbuf, &len))
- return -1;
+ if (get_short_pathname(&tfname, &pbuf, &len) == FAIL)
+ return FAIL;
if (len == 0)
{
@@ -21232,8 +21265,8 @@ shortpath_for_partial(fnamep, bufp, fnamelen)
* there's not a lot of point in guessing what it might be.
*/
len = tflen;
- if (shortpath_for_invalid_fname(&tfname, &pbuf, &len) == -1)
- return -1;
+ if (shortpath_for_invalid_fname(&tfname, &pbuf, &len) == FAIL)
+ return FAIL;
}
/* Count the paths backward to find the beginning of the desired string. */
@@ -21257,7 +21290,7 @@ shortpath_for_partial(fnamep, bufp, fnamelen)
if (p >= tfname)
*p = '~';
else
- return -1;
+ return FAIL;
}
else
++p;
@@ -21268,7 +21301,7 @@ shortpath_for_partial(fnamep, bufp, fnamelen)
*bufp = pbuf;
*fnamep = p;
- return 0;
+ return OK;
}
#endif /* WIN3264 */
@@ -21276,7 +21309,7 @@ shortpath_for_partial(fnamep, bufp, fnamelen)
* Adjust a filename, according to a string of modifiers.
* *fnamep must be NUL terminated when called. When returning, the length is
* determined by *fnamelen.
- * Returns valid flags.
+ * Returns VALID_ flags or -1 for failure.
* When there is an error, *fnamep is set to NULL.
*/
int
@@ -21488,7 +21521,7 @@ repeat:
*/
if (!has_fullname && !vim_isAbsName(*fnamep))
{
- if (shortpath_for_partial(fnamep, bufp, fnamelen) == -1)
+ if (shortpath_for_partial(fnamep, bufp, fnamelen) == FAIL)
return -1;
}
else
@@ -21498,7 +21531,7 @@ repeat:
/* Simple case, already have the full-name
* Nearly always shorter, so try first time. */
l = *fnamelen;
- if (!get_short_pathname(fnamep, bufp, &l))
+ if (get_short_pathname(fnamep, bufp, &l) == FAIL)
return -1;
if (l == 0)
@@ -21506,7 +21539,7 @@ repeat:
/* Couldn't find the filename.. search the paths.
*/
l = *fnamelen;
- if (shortpath_for_invalid_fname(fnamep, bufp, &l ) == -1)
+ if (shortpath_for_invalid_fname(fnamep, bufp, &l) == FAIL)
return -1;
}
*fnamelen = l;