Mercurial > vim
comparison src/eval.c @ 1591:c19f6b8d0393 v7.1.304
updated for version 7.1-304
author | vimboss |
---|---|
date | Thu, 29 May 2008 19:47:13 +0000 |
parents | fe7db192c7cc |
children | 1324b7b755f3 |
comparison
equal
deleted
inserted
replaced
1590:fe3ec5ea62f7 | 1591:c19f6b8d0393 |
---|---|
21066 static int get_short_pathname __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen)); | 21066 static int get_short_pathname __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen)); |
21067 static int shortpath_for_invalid_fname __ARGS((char_u **fname, char_u **bufp, int *fnamelen)); | 21067 static int shortpath_for_invalid_fname __ARGS((char_u **fname, char_u **bufp, int *fnamelen)); |
21068 static int shortpath_for_partial __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen)); | 21068 static int shortpath_for_partial __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen)); |
21069 | 21069 |
21070 /* | 21070 /* |
21071 * Get the short pathname of a file. | 21071 * Get the short path (8.3) for the filename in "fnamep". |
21072 * Returns 1 on success. *fnamelen is 0 for nonexistent path. | 21072 * Only works for a valid file name. |
21073 * When the path gets longer "fnamep" is changed and the allocated buffer | |
21074 * is put in "bufp". | |
21075 * *fnamelen is the length of "fnamep" and set to 0 for a nonexistent path. | |
21076 * Returns OK on success, FAIL on failure. | |
21073 */ | 21077 */ |
21074 static int | 21078 static int |
21075 get_short_pathname(fnamep, bufp, fnamelen) | 21079 get_short_pathname(fnamep, bufp, fnamelen) |
21076 char_u **fnamep; | 21080 char_u **fnamep; |
21077 char_u **bufp; | 21081 char_u **bufp; |
21078 int *fnamelen; | 21082 int *fnamelen; |
21079 { | 21083 { |
21080 int l,len; | 21084 int l, len; |
21081 char_u *newbuf; | 21085 char_u *newbuf; |
21082 | 21086 |
21083 len = *fnamelen; | 21087 len = *fnamelen; |
21084 | |
21085 l = GetShortPathName(*fnamep, *fnamep, len); | 21088 l = GetShortPathName(*fnamep, *fnamep, len); |
21086 if (l > len - 1) | 21089 if (l > len - 1) |
21087 { | 21090 { |
21088 /* If that doesn't work (not enough space), then save the string | 21091 /* If that doesn't work (not enough space), then save the string |
21089 * and try again with a new buffer big enough | 21092 * and try again with a new buffer big enough. */ |
21090 */ | |
21091 newbuf = vim_strnsave(*fnamep, l); | 21093 newbuf = vim_strnsave(*fnamep, l); |
21092 if (newbuf == NULL) | 21094 if (newbuf == NULL) |
21093 return 0; | 21095 return FAIL; |
21094 | 21096 |
21095 vim_free(*bufp); | 21097 vim_free(*bufp); |
21096 *fnamep = *bufp = newbuf; | 21098 *fnamep = *bufp = newbuf; |
21097 | 21099 |
21098 l = GetShortPathName(*fnamep,*fnamep,l+1); | 21100 /* Really should always succeed, as the buffer is big enough. */ |
21099 | 21101 l = GetShortPathName(*fnamep, *fnamep, l+1); |
21100 /* Really should always succeed, as the buffer is big enough */ | |
21101 } | 21102 } |
21102 | 21103 |
21103 *fnamelen = l; | 21104 *fnamelen = l; |
21104 return 1; | 21105 return OK; |
21105 } | 21106 } |
21106 | 21107 |
21107 /* | 21108 /* |
21108 * Create a short path name. Returns the length of the buffer it needs. | 21109 * Get the short path (8.3) for the filename in "fname". The converted |
21109 * Doesn't copy over the end of the buffer passed in. | 21110 * path is returned in "bufp". |
21111 * | |
21112 * Some of the directories specified in "fname" may not exist. This function | |
21113 * will shorten the existing directories at the beginning of the path and then | |
21114 * append the remaining non-existing path. | |
21115 * | |
21116 * fname - Pointer to the filename to shorten. On return, contains the | |
21117 * pointer to the shortened pathname | |
21118 * bufp - Pointer to an allocated buffer for the filename. | |
21119 * fnamelen - Length of the filename pointed to by fname | |
21120 * | |
21121 * Returns OK on success (or nothing done) and FAIL on failure (out of memory). | |
21110 */ | 21122 */ |
21111 static int | 21123 static int |
21112 shortpath_for_invalid_fname(fname, bufp, fnamelen) | 21124 shortpath_for_invalid_fname(fname, bufp, fnamelen) |
21113 char_u **fname; | 21125 char_u **fname; |
21114 char_u **bufp; | 21126 char_u **bufp; |
21115 int *fnamelen; | 21127 int *fnamelen; |
21116 { | 21128 { |
21117 char_u *s, *p, *pbuf2, *pbuf3; | 21129 char_u *short_fname, *save_fname, *pbuf_unused; |
21130 char_u *endp, *save_endp; | |
21118 char_u ch; | 21131 char_u ch; |
21119 int len, len2, plen, slen; | 21132 int old_len, len; |
21133 int new_len, sfx_len; | |
21134 int retval = OK; | |
21120 | 21135 |
21121 /* Make a copy */ | 21136 /* Make a copy */ |
21122 len2 = *fnamelen; | 21137 old_len = *fnamelen; |
21123 pbuf2 = vim_strnsave(*fname, len2); | 21138 save_fname = vim_strnsave(*fname, old_len); |
21124 pbuf3 = NULL; | 21139 pbuf_unused = NULL; |
21125 | 21140 short_fname = NULL; |
21126 s = pbuf2 + len2 - 1; /* Find the end */ | 21141 |
21127 slen = 1; | 21142 endp = save_fname + old_len - 1; /* Find the end of the copy */ |
21128 plen = len2; | 21143 save_endp = endp; |
21129 | 21144 |
21130 if (after_pathsep(pbuf2, s + 1)) | 21145 /* |
21131 { | 21146 * Try shortening the supplied path till it succeeds by removing one |
21132 --s; | 21147 * directory at a time from the tail of the path. |
21133 ++slen; | 21148 */ |
21134 --plen; | 21149 len = 0; |
21135 } | 21150 for (;;) |
21136 | 21151 { |
21137 do | 21152 /* go back one path-separator */ |
21138 { | 21153 while (endp > save_fname && !after_pathsep(save_fname, endp + 1)) |
21139 /* Go back one path-separator */ | 21154 --endp; |
21140 while (s > pbuf2 && !after_pathsep(pbuf2, s + 1)) | 21155 if (endp <= save_fname) |
21141 { | 21156 break; /* processed the complete path */ |
21142 --s; | 21157 |
21143 ++slen; | 21158 /* |
21144 --plen; | 21159 * Replace the path separator with a NUL and try to shorten the |
21145 } | 21160 * resulting path. |
21146 if (s <= pbuf2) | 21161 */ |
21147 break; | 21162 ch = *endp; |
21148 | 21163 *endp = 0; |
21149 /* Remember the character that is about to be splatted */ | 21164 short_fname = save_fname; |
21150 ch = *s; | 21165 len = STRLEN(short_fname) + 1; |
21151 *s = 0; /* get_short_pathname requires a null-terminated string */ | 21166 if (get_short_pathname(&short_fname, &pbuf_unused, &len) == FAIL) |
21152 | 21167 { |
21153 /* Try it in situ */ | 21168 retval = FAIL; |
21154 p = pbuf2; | 21169 goto theend; |
21155 if (!get_short_pathname(&p, &pbuf3, &plen)) | 21170 } |
21156 { | 21171 *endp = ch; /* preserve the string */ |
21157 vim_free(pbuf2); | 21172 |
21158 return -1; | 21173 if (len > 0) |
21159 } | 21174 break; /* successfully shortened the path */ |
21160 *s = ch; /* Preserve the string */ | 21175 |
21161 } while (plen == 0); | 21176 /* failed to shorten the path. Skip the path separator */ |
21162 | 21177 --endp; |
21163 if (plen > 0) | 21178 } |
21164 { | 21179 |
21165 /* Remember the length of the new string. */ | 21180 if (len > 0) |
21166 *fnamelen = len = plen + slen; | 21181 { |
21182 /* | |
21183 * Succeeded in shortening the path. Now concatenate the shortened | |
21184 * path with the remaining path at the tail. | |
21185 */ | |
21186 | |
21187 /* Compute the length of the new path. */ | |
21188 sfx_len = (int)(save_endp - endp) + 1; | |
21189 new_len = len + sfx_len; | |
21190 | |
21191 *fnamelen = new_len; | |
21167 vim_free(*bufp); | 21192 vim_free(*bufp); |
21168 if (len > len2) | 21193 if (new_len > old_len) |
21169 { | 21194 { |
21170 /* If there's not enough space in the currently allocated string, | 21195 /* There is not enough space in the currently allocated string, |
21171 * then copy it to a buffer big enough. | 21196 * copy it to a buffer big enough. */ |
21172 */ | 21197 *fname = *bufp = vim_strnsave(short_fname, new_len); |
21173 *fname= *bufp = vim_strnsave(p, len); | |
21174 if (*fname == NULL) | 21198 if (*fname == NULL) |
21175 return -1; | 21199 { |
21200 retval = FAIL; | |
21201 goto theend; | |
21202 } | |
21176 } | 21203 } |
21177 else | 21204 else |
21178 { | 21205 { |
21179 /* Transfer pbuf2 to being the main buffer (it's big enough) */ | 21206 /* Transfer short_fname to the main buffer (it's big enough), |
21180 *fname = *bufp = pbuf2; | 21207 * unless get_short_pathname() did its work in-place. */ |
21181 if (p != pbuf2) | 21208 *fname = *bufp = save_fname; |
21182 strncpy(*fname, p, plen); | 21209 if (short_fname != save_fname) |
21183 pbuf2 = NULL; | 21210 vim_strncpy(save_fname, short_fname, len); |
21184 } | 21211 save_fname = NULL; |
21185 /* Concat the next bit */ | 21212 } |
21186 strncpy(*fname + plen, s, slen); | 21213 |
21187 (*fname)[len] = '\0'; | 21214 /* concat the not-shortened part of the path */ |
21188 } | 21215 vim_strncpy(*fname + len, endp, sfx_len); |
21189 vim_free(pbuf3); | 21216 (*fname)[new_len] = NUL; |
21190 vim_free(pbuf2); | 21217 } |
21191 return 0; | 21218 |
21219 theend: | |
21220 vim_free(pbuf_unused); | |
21221 vim_free(save_fname); | |
21222 | |
21223 return retval; | |
21192 } | 21224 } |
21193 | 21225 |
21194 /* | 21226 /* |
21195 * Get a pathname for a partial path. | 21227 * Get a pathname for a partial path. |
21228 * Returns OK for success, FAIL for failure. | |
21196 */ | 21229 */ |
21197 static int | 21230 static int |
21198 shortpath_for_partial(fnamep, bufp, fnamelen) | 21231 shortpath_for_partial(fnamep, bufp, fnamelen) |
21199 char_u **fnamep; | 21232 char_u **fnamep; |
21200 char_u **bufp; | 21233 char_u **bufp; |
21220 else | 21253 else |
21221 pbuf = tfname = FullName_save(*fnamep, FALSE); | 21254 pbuf = tfname = FullName_save(*fnamep, FALSE); |
21222 | 21255 |
21223 len = tflen = (int)STRLEN(tfname); | 21256 len = tflen = (int)STRLEN(tfname); |
21224 | 21257 |
21225 if (!get_short_pathname(&tfname, &pbuf, &len)) | 21258 if (get_short_pathname(&tfname, &pbuf, &len) == FAIL) |
21226 return -1; | 21259 return FAIL; |
21227 | 21260 |
21228 if (len == 0) | 21261 if (len == 0) |
21229 { | 21262 { |
21230 /* Don't have a valid filename, so shorten the rest of the | 21263 /* Don't have a valid filename, so shorten the rest of the |
21231 * path if we can. This CAN give us invalid 8.3 filenames, but | 21264 * path if we can. This CAN give us invalid 8.3 filenames, but |
21232 * there's not a lot of point in guessing what it might be. | 21265 * there's not a lot of point in guessing what it might be. |
21233 */ | 21266 */ |
21234 len = tflen; | 21267 len = tflen; |
21235 if (shortpath_for_invalid_fname(&tfname, &pbuf, &len) == -1) | 21268 if (shortpath_for_invalid_fname(&tfname, &pbuf, &len) == FAIL) |
21236 return -1; | 21269 return FAIL; |
21237 } | 21270 } |
21238 | 21271 |
21239 /* Count the paths backward to find the beginning of the desired string. */ | 21272 /* Count the paths backward to find the beginning of the desired string. */ |
21240 for (p = tfname + len - 1; p >= tfname; --p) | 21273 for (p = tfname + len - 1; p >= tfname; --p) |
21241 { | 21274 { |
21255 { | 21288 { |
21256 --p; | 21289 --p; |
21257 if (p >= tfname) | 21290 if (p >= tfname) |
21258 *p = '~'; | 21291 *p = '~'; |
21259 else | 21292 else |
21260 return -1; | 21293 return FAIL; |
21261 } | 21294 } |
21262 else | 21295 else |
21263 ++p; | 21296 ++p; |
21264 | 21297 |
21265 /* Copy in the string - p indexes into tfname - allocated at pbuf */ | 21298 /* Copy in the string - p indexes into tfname - allocated at pbuf */ |
21266 vim_free(*bufp); | 21299 vim_free(*bufp); |
21267 *fnamelen = (int)STRLEN(p); | 21300 *fnamelen = (int)STRLEN(p); |
21268 *bufp = pbuf; | 21301 *bufp = pbuf; |
21269 *fnamep = p; | 21302 *fnamep = p; |
21270 | 21303 |
21271 return 0; | 21304 return OK; |
21272 } | 21305 } |
21273 #endif /* WIN3264 */ | 21306 #endif /* WIN3264 */ |
21274 | 21307 |
21275 /* | 21308 /* |
21276 * Adjust a filename, according to a string of modifiers. | 21309 * Adjust a filename, according to a string of modifiers. |
21277 * *fnamep must be NUL terminated when called. When returning, the length is | 21310 * *fnamep must be NUL terminated when called. When returning, the length is |
21278 * determined by *fnamelen. | 21311 * determined by *fnamelen. |
21279 * Returns valid flags. | 21312 * Returns VALID_ flags or -1 for failure. |
21280 * When there is an error, *fnamep is set to NULL. | 21313 * When there is an error, *fnamep is set to NULL. |
21281 */ | 21314 */ |
21282 int | 21315 int |
21283 modify_fname(src, usedlen, fnamep, bufp, fnamelen) | 21316 modify_fname(src, usedlen, fnamep, bufp, fnamelen) |
21284 char_u *src; /* string with modifiers */ | 21317 char_u *src; /* string with modifiers */ |
21486 /* Split into two implementations - makes it easier. First is where | 21519 /* Split into two implementations - makes it easier. First is where |
21487 * there isn't a full name already, second is where there is. | 21520 * there isn't a full name already, second is where there is. |
21488 */ | 21521 */ |
21489 if (!has_fullname && !vim_isAbsName(*fnamep)) | 21522 if (!has_fullname && !vim_isAbsName(*fnamep)) |
21490 { | 21523 { |
21491 if (shortpath_for_partial(fnamep, bufp, fnamelen) == -1) | 21524 if (shortpath_for_partial(fnamep, bufp, fnamelen) == FAIL) |
21492 return -1; | 21525 return -1; |
21493 } | 21526 } |
21494 else | 21527 else |
21495 { | 21528 { |
21496 int l; | 21529 int l; |
21497 | 21530 |
21498 /* Simple case, already have the full-name | 21531 /* Simple case, already have the full-name |
21499 * Nearly always shorter, so try first time. */ | 21532 * Nearly always shorter, so try first time. */ |
21500 l = *fnamelen; | 21533 l = *fnamelen; |
21501 if (!get_short_pathname(fnamep, bufp, &l)) | 21534 if (get_short_pathname(fnamep, bufp, &l) == FAIL) |
21502 return -1; | 21535 return -1; |
21503 | 21536 |
21504 if (l == 0) | 21537 if (l == 0) |
21505 { | 21538 { |
21506 /* Couldn't find the filename.. search the paths. | 21539 /* Couldn't find the filename.. search the paths. |
21507 */ | 21540 */ |
21508 l = *fnamelen; | 21541 l = *fnamelen; |
21509 if (shortpath_for_invalid_fname(fnamep, bufp, &l ) == -1) | 21542 if (shortpath_for_invalid_fname(fnamep, bufp, &l) == FAIL) |
21510 return -1; | 21543 return -1; |
21511 } | 21544 } |
21512 *fnamelen = l; | 21545 *fnamelen = l; |
21513 } | 21546 } |
21514 } | 21547 } |