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 }