| To: vim-dev@vim.org |
| Subject: Patch 7.1.304 |
| 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 7.1.304 |
| Problem: Shortpath_for_invalid_fname() does not work correctly and is |
| unnecessary complex. |
| Solution: Clean up shortpath_for_invalid_fname(). (mostly by Yegappan |
| Lakshmanan) |
| Files: src/eval.c |
| |
| |
| |
| |
| |
| *** 21068,21075 **** |
| 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. |
| */ |
| static int |
| get_short_pathname(fnamep, bufp, fnamelen) |
| --- 21476,21487 ---- |
| static int shortpath_for_partial __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen)); |
| |
| /* |
| ! * 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,21112 **** |
| char_u **bufp; |
| int *fnamelen; |
| { |
| ! 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 |
| ! */ |
| newbuf = vim_strnsave(*fnamep, l); |
| if (newbuf == NULL) |
| ! return 0; |
| |
| vim_free(*bufp); |
| *fnamep = *bufp = newbuf; |
| |
| ! l = GetShortPathName(*fnamep,*fnamep,l+1); |
| ! |
| ! /* Really should always succeed, as the buffer is big enough */ |
| } |
| |
| *fnamelen = l; |
| ! return 1; |
| } |
| |
| /* |
| ! * Create a short path name. Returns the length of the buffer it needs. |
| ! * Doesn't copy over the end of the buffer passed in. |
| */ |
| static int |
| shortpath_for_invalid_fname(fname, bufp, fnamelen) |
| --- 21489,21532 ---- |
| char_u **bufp; |
| int *fnamelen; |
| { |
| ! 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. */ |
| newbuf = vim_strnsave(*fnamep, l); |
| if (newbuf == NULL) |
| ! return FAIL; |
| |
| vim_free(*bufp); |
| *fnamep = *bufp = newbuf; |
| |
| ! /* Really should always succeed, as the buffer is big enough. */ |
| ! l = GetShortPathName(*fnamep, *fnamep, l+1); |
| } |
| |
| *fnamelen = l; |
| ! return OK; |
| } |
| |
| /* |
| ! * 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,21198 **** |
| char_u **bufp; |
| int *fnamelen; |
| { |
| ! char_u *s, *p, *pbuf2, *pbuf3; |
| char_u ch; |
| ! int len, len2, plen, slen; |
| |
| /* Make a copy */ |
| ! len2 = *fnamelen; |
| ! pbuf2 = vim_strnsave(*fname, len2); |
| ! pbuf3 = NULL; |
| ! |
| ! s = pbuf2 + len2 - 1; /* Find the end */ |
| ! slen = 1; |
| ! plen = len2; |
| ! |
| ! if (after_pathsep(pbuf2, s + 1)) |
| ! { |
| ! --s; |
| ! ++slen; |
| ! --plen; |
| ! } |
| |
| ! do |
| { |
| ! /* Go back one path-separator */ |
| ! while (s > pbuf2 && !after_pathsep(pbuf2, s + 1)) |
| ! { |
| ! --s; |
| ! ++slen; |
| ! --plen; |
| ! } |
| ! if (s <= pbuf2) |
| ! break; |
| |
| ! /* Remember the character that is about to be splatted */ |
| ! ch = *s; |
| ! *s = 0; /* get_short_pathname requires a null-terminated string */ |
| ! |
| ! /* 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); |
| |
| ! if (plen > 0) |
| { |
| ! /* Remember the length of the new string. */ |
| ! *fnamelen = len = plen + slen; |
| vim_free(*bufp); |
| ! if (len > len2) |
| { |
| ! /* 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); |
| if (*fname == NULL) |
| ! return -1; |
| } |
| else |
| { |
| ! /* Transfer pbuf2 to being the main buffer (it's big enough) */ |
| ! *fname = *bufp = pbuf2; |
| ! if (p != pbuf2) |
| ! strncpy(*fname, p, plen); |
| ! pbuf2 = NULL; |
| ! } |
| ! /* Concat the next bit */ |
| ! strncpy(*fname + plen, s, slen); |
| ! (*fname)[len] = '\0'; |
| } |
| ! vim_free(pbuf3); |
| ! vim_free(pbuf2); |
| ! return 0; |
| } |
| |
| /* |
| * Get a pathname for a partial path. |
| */ |
| static int |
| shortpath_for_partial(fnamep, bufp, fnamelen) |
| --- 21534,21639 ---- |
| char_u **bufp; |
| int *fnamelen; |
| { |
| ! char_u *short_fname, *save_fname, *pbuf_unused; |
| ! char_u *endp, *save_endp; |
| char_u ch; |
| ! int old_len, len; |
| ! int new_len, sfx_len; |
| ! int retval = OK; |
| |
| /* Make a copy */ |
| ! old_len = *fnamelen; |
| ! save_fname = vim_strnsave(*fname, old_len); |
| ! pbuf_unused = NULL; |
| ! short_fname = NULL; |
| |
| ! endp = save_fname + old_len - 1; /* Find the end of the copy */ |
| ! save_endp = endp; |
| ! |
| ! /* |
| ! * Try shortening the supplied path till it succeeds by removing one |
| ! * directory at a time from the tail of the path. |
| ! */ |
| ! len = 0; |
| ! for (;;) |
| { |
| ! /* 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 */ |
| |
| ! /* |
| ! * 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) |
| { |
| ! retval = FAIL; |
| ! goto theend; |
| } |
| ! *endp = ch; /* preserve the string */ |
| ! |
| ! if (len > 0) |
| ! break; /* successfully shortened the path */ |
| |
| ! /* failed to shorten the path. Skip the path separator */ |
| ! --endp; |
| ! } |
| ! |
| ! if (len > 0) |
| { |
| ! /* |
| ! * 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 (new_len > old_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) |
| ! { |
| ! retval = FAIL; |
| ! goto theend; |
| ! } |
| } |
| else |
| { |
| ! /* 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 not-shortened part of the path */ |
| ! vim_strncpy(*fname + len, endp, sfx_len); |
| ! (*fname)[new_len] = NUL; |
| } |
| ! |
| ! 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,21229 **** |
| |
| len = tflen = (int)STRLEN(tfname); |
| |
| ! if (!get_short_pathname(&tfname, &pbuf, &len)) |
| ! return -1; |
| |
| if (len == 0) |
| { |
| --- 21663,21670 ---- |
| |
| len = tflen = (int)STRLEN(tfname); |
| |
| ! if (get_short_pathname(&tfname, &pbuf, &len) == FAIL) |
| ! return FAIL; |
| |
| if (len == 0) |
| { |
| |
| *** 21232,21239 **** |
| * 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; |
| } |
| |
| /* Count the paths backward to find the beginning of the desired string. */ |
| --- 21673,21680 ---- |
| * there's not a lot of point in guessing what it might be. |
| */ |
| len = tflen; |
| ! if (shortpath_for_invalid_fname(&tfname, &pbuf, &len) == FAIL) |
| ! return FAIL; |
| } |
| |
| /* Count the paths backward to find the beginning of the desired string. */ |
| |
| *** 21257,21263 **** |
| if (p >= tfname) |
| *p = '~'; |
| else |
| ! return -1; |
| } |
| else |
| ++p; |
| --- 21698,21704 ---- |
| if (p >= tfname) |
| *p = '~'; |
| else |
| ! return FAIL; |
| } |
| else |
| ++p; |
| |
| *** 21268,21274 **** |
| *bufp = pbuf; |
| *fnamep = p; |
| |
| ! return 0; |
| } |
| #endif /* WIN3264 */ |
| |
| --- 21709,21715 ---- |
| *bufp = pbuf; |
| *fnamep = p; |
| |
| ! return OK; |
| } |
| #endif /* WIN3264 */ |
| |
| |
| *** 21276,21282 **** |
| * 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. |
| * When there is an error, *fnamep is set to NULL. |
| */ |
| int |
| --- 21717,21723 ---- |
| * 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 or -1 for failure. |
| * When there is an error, *fnamep is set to NULL. |
| */ |
| int |
| |
| *** 21488,21494 **** |
| */ |
| if (!has_fullname && !vim_isAbsName(*fnamep)) |
| { |
| ! if (shortpath_for_partial(fnamep, bufp, fnamelen) == -1) |
| return -1; |
| } |
| else |
| --- 21929,21935 ---- |
| */ |
| if (!has_fullname && !vim_isAbsName(*fnamep)) |
| { |
| ! if (shortpath_for_partial(fnamep, bufp, fnamelen) == FAIL) |
| return -1; |
| } |
| else |
| |
| *** 21498,21504 **** |
| /* Simple case, already have the full-name |
| * Nearly always shorter, so try first time. */ |
| l = *fnamelen; |
| ! if (!get_short_pathname(fnamep, bufp, &l)) |
| return -1; |
| |
| if (l == 0) |
| --- 21939,21945 ---- |
| /* Simple case, already have the full-name |
| * Nearly always shorter, so try first time. */ |
| l = *fnamelen; |
| ! if (get_short_pathname(fnamep, bufp, &l) == FAIL) |
| return -1; |
| |
| if (l == 0) |
| |
| *** 21506,21512 **** |
| /* Couldn't find the filename.. search the paths. |
| */ |
| l = *fnamelen; |
| ! if (shortpath_for_invalid_fname(fnamep, bufp, &l ) == -1) |
| return -1; |
| } |
| *fnamelen = l; |
| --- 21947,21953 ---- |
| /* Couldn't find the filename.. search the paths. |
| */ |
| l = *fnamelen; |
| ! if (shortpath_for_invalid_fname(fnamep, bufp, &l) == FAIL) |
| return -1; |
| } |
| *fnamelen = l; |
| |
| |
| |
| *** 668,669 **** |
| --- 673,676 ---- |
| { /* Add new patch number below this line */ |
| + /**/ |
| + 304, |
| /**/ |
| |
| -- |
| "The future's already arrived - it's just not evenly distributed yet." |
| -- William Gibson |
| |
| /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ |
| /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ |
| \\\ download, build and distribute -- http://www.A-A-P.org /// |
| \\\ help me help AIDS victims -- http://ICCF-Holland.org /// |