]>
Commit | Line | Data |
---|---|---|
04f0bc09 AF |
1 | To: vim-dev@vim.org |
2 | Subject: Patch 6.2.064 | |
3 | Fcc: outbox | |
4 | From: Bram Moolenaar <Bram@moolenaar.net> | |
5 | Mime-Version: 1.0 | |
6 | Content-Type: text/plain; charset=ISO-8859-1 | |
7 | Content-Transfer-Encoding: 8bit | |
8 | ------------ | |
9 | ||
10 | Patch 6.2.064 | |
11 | Problem: resolve() only handles one symbolic link, need to repeat it to | |
12 | resolve all of them. Then need to simplify the file name. | |
13 | Solution: Make resolve() resolve all symbolic links and simplify the result. | |
14 | Add simplify() to just simplify a file name. Fix that test49 | |
15 | doesn't work if /tmp is a symbolic link. (Servatius Brandt) | |
16 | Files: runtime/doc/eval.txt, src/eval.c, src/tag.c, | |
17 | src/testdir/test49.vim | |
18 | ||
19 | ||
20 | *** ../vim-6.2.063/runtime/doc/eval.txt Sun Jun 1 14:45:23 2003 | |
21 | --- runtime/doc/eval.txt Thu Aug 7 19:31:16 2003 | |
22 | *************** | |
23 | *** 1,4 **** | |
24 | ! *eval.txt* For Vim version 6.2. Last change: 2003 Jun 01 | |
25 | ||
26 | ||
27 | VIM REFERENCE MANUAL by Bram Moolenaar | |
28 | --- 1,4 ---- | |
29 | ! *eval.txt* For Vim version 6.2. Last change: 2003 Aug 07 | |
30 | ||
31 | ||
32 | VIM REFERENCE MANUAL by Bram Moolenaar | |
33 | *************** | |
34 | *** 885,890 **** | |
35 | --- 887,893 ---- | |
36 | setline( {lnum}, {line}) Number set line {lnum} to {line} | |
37 | setreg( {n}, {v}[, {opt}]) Number set register to value and type | |
38 | setwinvar( {nr}, {varname}, {val}) set {varname} in window {nr} to {val} | |
39 | + simplify( {filename}) String simplify filename as much as possible | |
40 | strftime( {format}[, {time}]) String time in specified format | |
41 | stridx( {haystack}, {needle}) Number first index of {needle} in {haystack} | |
42 | strlen( {expr}) Number length of the String {expr} | |
43 | *************** | |
44 | *** 2104,2116 **** | |
45 | successfully, and non-zero when the renaming failed. | |
46 | This function is not available in the |sandbox|. | |
47 | ||
48 | ! resolve({filename}) *resolve()* | |
49 | On MS-Windows, when {filename} is a shortcut (a .lnk file), | |
50 | ! returns the path the shortcut points to. | |
51 | ! On Unix, when {filename} is a symbolic link, returns the path | |
52 | ! the symlink points to. This only happens once, the returned | |
53 | ! path could be a symlink again. | |
54 | ! Otherwise {filename} is returned. | |
55 | ||
56 | search({pattern} [, {flags}]) *search()* | |
57 | Search for regexp pattern {pattern}. The search starts at the | |
58 | --- 2112,2129 ---- | |
59 | successfully, and non-zero when the renaming failed. | |
60 | This function is not available in the |sandbox|. | |
61 | ||
62 | ! resolve({filename}) *resolve()* *E655* | |
63 | On MS-Windows, when {filename} is a shortcut (a .lnk file), | |
64 | ! returns the path the shortcut points to in a simplified form. | |
65 | ! On Unix, repeat resolving symbolic links in all path | |
66 | ! components of {filename} and return the simplified result. | |
67 | ! To cope with link cycles, resolving of symbolic links is | |
68 | ! stopped after 100 iterations. | |
69 | ! On other systems, return the simplified {filename}. | |
70 | ! The simplification step is done as by |simplify()|. | |
71 | ! resolve() keeps a leading path component specifying the | |
72 | ! current directory (provided the result is still a relative | |
73 | ! path name) and also keeps a trailing path separator. | |
74 | ||
75 | search({pattern} [, {flags}]) *search()* | |
76 | Search for regexp pattern {pattern}. The search starts at the | |
77 | *************** | |
78 | *** 2302,2307 **** | |
79 | --- 2315,2335 ---- | |
80 | :call setwinvar(2, "myvar", "foobar") | |
81 | < This function is not available in the |sandbox|. | |
82 | ||
83 | + simplify({filename}) *simplify()* | |
84 | + Simplify the file name as much as possible without changing | |
85 | + the meaning. Shortcuts (on MS-Windows) or symbolic links (on | |
86 | + Unix) are not resolved. If the first path component in | |
87 | + {filename} designates the current directory, this will be | |
88 | + valid for the result as well. A trailing path separator is | |
89 | + not removed either. | |
90 | + Example: > | |
91 | + simplify("./dir/.././/file/") == "./file/" | |
92 | + < Note: The combination "dir/.." is only removed if "dir" is | |
93 | + a searchable directory or does not exist. On Unix, it is also | |
94 | + removed when "dir" is a symbolic link within the same | |
95 | + directory. In order to resolve all the involved symbolic | |
96 | + links before simplifying the path name, use |resolve()|. | |
97 | + | |
98 | strftime({format} [, {time}]) *strftime()* | |
99 | The result is a String, which is a formatted date and time, as | |
100 | specified by the {format} string. The given {time} is used, | |
101 | *** ../vim-6.2.063/src/eval.c Sun Aug 10 22:24:37 2003 | |
102 | --- src/eval.c Thu Jul 31 19:47:34 2003 | |
103 | *************** | |
104 | *** 318,323 **** | |
105 | --- 318,324 ---- | |
106 | static void f_serverlist __ARGS((VAR argvars, VAR retvar)); | |
107 | static void f_setline __ARGS((VAR argvars, VAR retvar)); | |
108 | static void f_setreg __ARGS((VAR argvars, VAR retvar)); | |
109 | + static void f_simplify __ARGS((VAR argvars, VAR retvar)); | |
110 | static void find_some_match __ARGS((VAR argvars, VAR retvar, int start)); | |
111 | static void f_strftime __ARGS((VAR argvars, VAR retvar)); | |
112 | static void f_stridx __ARGS((VAR argvars, VAR retvar)); | |
113 | *************** | |
114 | *** 2812,2817 **** | |
115 | --- 2813,2819 ---- | |
116 | {"setline", 2, 2, f_setline}, | |
117 | {"setreg", 2, 3, f_setreg}, | |
118 | {"setwinvar", 3, 3, f_setwinvar}, | |
119 | + {"simplify", 1, 1, f_simplify}, | |
120 | #ifdef HAVE_STRFTIME | |
121 | {"strftime", 1, 2, f_strftime}, | |
122 | #endif | |
123 | *************** | |
124 | *** 5808,5813 **** | |
125 | --- 5810,5816 ---- | |
126 | VAR retvar; | |
127 | { | |
128 | char_u *p; | |
129 | + int limit = 100; | |
130 | ||
131 | p = get_var_string(&argvars[0]); | |
132 | #ifdef FEAT_SHORTCUT | |
133 | *************** | |
134 | *** 5826,5858 **** | |
135 | char_u buf[MAXPATHL + 1]; | |
136 | char_u *cpy; | |
137 | int len; | |
138 | ||
139 | ! len = readlink((char *)p, (char *)buf, MAXPATHL); | |
140 | ! if (len > 0) | |
141 | { | |
142 | ! buf[len] = NUL; | |
143 | ! if (gettail(p) > p && !mch_isFullName(buf)) | |
144 | { | |
145 | ! /* symlink is relative to directory of argument */ | |
146 | ! cpy = alloc((unsigned)(STRLEN(p) + STRLEN(buf) + 1)); | |
147 | ! if (cpy != NULL) | |
148 | { | |
149 | ! STRCPY(cpy, p); | |
150 | ! STRCPY(gettail(cpy), buf); | |
151 | ! retvar->var_val.var_string = cpy; | |
152 | ! p = NULL; | |
153 | } | |
154 | } | |
155 | else | |
156 | ! p = buf; | |
157 | } | |
158 | ! if (p != NULL) | |
159 | ! retvar->var_val.var_string = vim_strsave(p); | |
160 | } | |
161 | # else | |
162 | retvar->var_val.var_string = vim_strsave(p); | |
163 | # endif | |
164 | #endif | |
165 | retvar->var_type = VAR_STRING; | |
166 | } | |
167 | ||
168 | --- 5829,6020 ---- | |
169 | char_u buf[MAXPATHL + 1]; | |
170 | char_u *cpy; | |
171 | int len; | |
172 | + char_u *remain = NULL; | |
173 | + char_u *q; | |
174 | + int is_relative_to_current = FALSE; | |
175 | + int has_trailing_pathsep = FALSE; | |
176 | ||
177 | ! p = vim_strsave(p); | |
178 | ! | |
179 | ! if (p[0] == '.' && (vim_ispathsep(p[1]) | |
180 | ! || (p[1] == '.' && (vim_ispathsep(p[2]))))) | |
181 | ! is_relative_to_current = TRUE; | |
182 | ! | |
183 | ! len = STRLEN(p); | |
184 | ! if (len > 0 && vim_ispathsep(p[len-1])) | |
185 | ! has_trailing_pathsep = TRUE; | |
186 | ! | |
187 | ! q = getnextcomp(p); | |
188 | ! if (*q != NUL) | |
189 | ! { | |
190 | ! /* Separate the first path component in "p", and keep the | |
191 | ! * remainder (beginning with the path separator). */ | |
192 | ! remain = vim_strsave(q - 1); | |
193 | ! q[-1] = NUL; | |
194 | ! } | |
195 | ! | |
196 | ! for(;;) | |
197 | { | |
198 | ! for (;;) | |
199 | { | |
200 | ! len = readlink((char *)p, (char *)buf, MAXPATHL); | |
201 | ! if (len <= 0) | |
202 | ! break; | |
203 | ! buf[len] = NUL; | |
204 | ! | |
205 | ! if (limit-- == 0) | |
206 | ! { | |
207 | ! vim_free(p); | |
208 | ! vim_free(remain); | |
209 | ! EMSG(_("E655: Too much symbolic links (cycle?)")); | |
210 | ! retvar->var_val.var_string = NULL; | |
211 | ! goto fail; | |
212 | ! } | |
213 | ! | |
214 | ! /* Ensure that the result will have a trailing path separator | |
215 | ! * if the argument has one. */ | |
216 | ! if (remain == NULL && has_trailing_pathsep) | |
217 | ! add_pathsep(buf); | |
218 | ! | |
219 | ! /* Separate the first path component in the link value and | |
220 | ! * concatenate the remainders. */ | |
221 | ! q = getnextcomp(vim_ispathsep(*buf) ? buf + 1 : buf); | |
222 | ! if (*q != NUL) | |
223 | ! { | |
224 | ! if (remain == NULL) | |
225 | ! remain = vim_strsave(q - 1); | |
226 | ! else | |
227 | ! { | |
228 | ! cpy = vim_strnsave(q-1, STRLEN(q-1)+STRLEN(remain)); | |
229 | ! if (cpy != NULL) | |
230 | ! { | |
231 | ! STRCAT(cpy, remain); | |
232 | ! vim_free(remain); | |
233 | ! remain = cpy; | |
234 | ! } | |
235 | ! } | |
236 | ! q[-1] = NUL; | |
237 | ! } | |
238 | ! | |
239 | ! q = gettail(p); | |
240 | ! if (q > p && *q == NUL) | |
241 | ! { | |
242 | ! /* Ignore trailing path separator. */ | |
243 | ! q[-1] = NUL; | |
244 | ! q = gettail(p); | |
245 | ! } | |
246 | ! if (q > p && !mch_isFullName(buf)) | |
247 | ! { | |
248 | ! /* symlink is relative to directory of argument */ | |
249 | ! cpy = alloc((unsigned)(STRLEN(p) + STRLEN(buf) + 1)); | |
250 | ! if (cpy != NULL) | |
251 | ! { | |
252 | ! STRCPY(cpy, p); | |
253 | ! STRCPY(gettail(cpy), buf); | |
254 | ! vim_free(p); | |
255 | ! p = cpy; | |
256 | ! } | |
257 | ! } | |
258 | ! else | |
259 | { | |
260 | ! vim_free(p); | |
261 | ! p = vim_strsave(buf); | |
262 | } | |
263 | } | |
264 | + | |
265 | + if (remain == NULL) | |
266 | + break; | |
267 | + | |
268 | + /* Append the first path component of "remain" to "p". */ | |
269 | + q = getnextcomp(remain + 1); | |
270 | + len = q - remain - (*q != NUL); | |
271 | + cpy = vim_strnsave(p, STRLEN(p) + len); | |
272 | + if (cpy != NULL) | |
273 | + { | |
274 | + STRNCAT(cpy, remain, len); | |
275 | + vim_free(p); | |
276 | + p = cpy; | |
277 | + } | |
278 | + /* Shorten "remain". */ | |
279 | + if (*q != NUL) | |
280 | + STRCPY(remain, q - 1); | |
281 | else | |
282 | ! { | |
283 | ! vim_free(remain); | |
284 | ! remain = NULL; | |
285 | ! } | |
286 | } | |
287 | ! | |
288 | ! /* If the result is a relative path name, make it explicitly relative to | |
289 | ! * the current directory if and only if the argument had this form. */ | |
290 | ! if (!vim_ispathsep(*p)) | |
291 | ! { | |
292 | ! if (is_relative_to_current | |
293 | ! && *p != NUL | |
294 | ! && !(p[0] == '.' | |
295 | ! && (p[1] == NUL | |
296 | ! || vim_ispathsep(p[1]) | |
297 | ! || (p[1] == '.' | |
298 | ! && (p[2] == NUL | |
299 | ! || vim_ispathsep(p[2])))))) | |
300 | ! { | |
301 | ! /* Prepend "./". */ | |
302 | ! cpy = vim_strnsave((char_u *)"./", 2 + STRLEN(p)); | |
303 | ! if (cpy != NULL) | |
304 | ! { | |
305 | ! STRCAT(cpy, p); | |
306 | ! vim_free(p); | |
307 | ! p = cpy; | |
308 | ! } | |
309 | ! } | |
310 | ! else if (!is_relative_to_current) | |
311 | ! { | |
312 | ! /* Strip leading "./". */ | |
313 | ! q = p; | |
314 | ! while (q[0] == '.' && vim_ispathsep(q[1])) | |
315 | ! q += 2; | |
316 | ! if (q > p) | |
317 | ! mch_memmove(p, p + 2, STRLEN(p + 2) + (size_t)1); | |
318 | ! } | |
319 | ! } | |
320 | ! | |
321 | ! /* Ensure that the result will have no trailing path separator | |
322 | ! * if the argument had none. But keep "/" or "//". */ | |
323 | ! if (!has_trailing_pathsep) | |
324 | ! { | |
325 | ! q = p + STRLEN(p); | |
326 | ! while ((q > p + 2 || (q == p + 2 && !vim_ispathsep(*p))) | |
327 | ! && vim_ispathsep(q[-1])) | |
328 | ! --q; | |
329 | ! *q = NUL; | |
330 | ! } | |
331 | ! | |
332 | ! retvar->var_val.var_string = p; | |
333 | } | |
334 | # else | |
335 | retvar->var_val.var_string = vim_strsave(p); | |
336 | # endif | |
337 | #endif | |
338 | + | |
339 | + simplify_filename(retvar->var_val.var_string); | |
340 | + | |
341 | + fail: | |
342 | + retvar->var_type = VAR_STRING; | |
343 | + } | |
344 | + | |
345 | + /* | |
346 | + * "simplify()" function | |
347 | + */ | |
348 | + static void | |
349 | + f_simplify(argvars, retvar) | |
350 | + VAR argvars; | |
351 | + VAR retvar; | |
352 | + { | |
353 | + char_u *p; | |
354 | + | |
355 | + p = get_var_string(&argvars[0]); | |
356 | + retvar->var_val.var_string = vim_strsave(p); | |
357 | + simplify_filename(retvar->var_val.var_string); /* simplify in place */ | |
358 | retvar->var_type = VAR_STRING; | |
359 | } | |
360 | ||
361 | *** ../vim-6.2.063/src/tag.c Sun Aug 10 22:24:37 2003 | |
362 | --- src/tag.c Thu Jul 31 18:27:34 2003 | |
363 | *************** | |
364 | *** 2864,2875 **** | |
365 | #ifndef AMIGA /* Amiga doesn't have "..", it uses "/" */ | |
366 | int components = 0; | |
367 | char_u *p, *tail, *start; | |
368 | ! #ifdef UNIX | |
369 | ! char_u *orig = vim_strsave(filename); | |
370 | ! | |
371 | ! if (orig == NULL) | |
372 | ! return; | |
373 | ! #endif | |
374 | ||
375 | p = filename; | |
376 | #ifdef BACKSLASH_IN_FILENAME | |
377 | --- 2864,2871 ---- | |
378 | #ifndef AMIGA /* Amiga doesn't have "..", it uses "/" */ | |
379 | int components = 0; | |
380 | char_u *p, *tail, *start; | |
381 | ! int stripping_disabled = FALSE; | |
382 | ! int relative = TRUE; | |
383 | ||
384 | p = filename; | |
385 | #ifdef BACKSLASH_IN_FILENAME | |
386 | *************** | |
387 | *** 2877,2889 **** | |
388 | p += 2; | |
389 | #endif | |
390 | ||
391 | ! while (vim_ispathsep(*p)) | |
392 | ! ++p; | |
393 | ! start = p; /* remember start after "c:/" or "/" or "//" */ | |
394 | ||
395 | do | |
396 | { | |
397 | ! /* At this point "p" is pointing to the char following a "/". */ | |
398 | #ifdef VMS | |
399 | /* VMS allows device:[path] - don't strip the [ in directory */ | |
400 | if ((*p == '[' || *p == '<') && p > filename && p[-1] == ':') | |
401 | --- 2873,2891 ---- | |
402 | p += 2; | |
403 | #endif | |
404 | ||
405 | ! if (vim_ispathsep(*p)) | |
406 | ! { | |
407 | ! relative = FALSE; | |
408 | ! do | |
409 | ! ++p; | |
410 | ! while (vim_ispathsep(*p)); | |
411 | ! } | |
412 | ! start = p; /* remember start after "c:/" or "/" or "///" */ | |
413 | ||
414 | do | |
415 | { | |
416 | ! /* At this point "p" is pointing to the char following a single "/" | |
417 | ! * or "p" is at the "start" of the (absolute or relative) path name. */ | |
418 | #ifdef VMS | |
419 | /* VMS allows device:[path] - don't strip the [ in directory */ | |
420 | if ((*p == '[' || *p == '<') && p > filename && p[-1] == ':') | |
421 | *************** | |
422 | *** 2898,2952 **** | |
423 | /* ":: composition: vms host/passwd component */ | |
424 | ++components; | |
425 | p = getnextcomp(p + 2); | |
426 | - | |
427 | } | |
428 | else | |
429 | #endif | |
430 | if (vim_ispathsep(*p)) | |
431 | movetail(p, p + 1); /* remove duplicate "/" */ | |
432 | ! else if (p[0] == '.' && vim_ispathsep(p[1])) | |
433 | ! movetail(p, p + 2); /* strip "./" */ | |
434 | ! else if (p[0] == '.' && p[1] == '.' && vim_ispathsep(p[2])) | |
435 | { | |
436 | if (components > 0) /* strip one preceding component */ | |
437 | { | |
438 | ! tail = p + 3; /* skip to after "../" or "..///" */ | |
439 | ! while (vim_ispathsep(*tail)) | |
440 | ! ++tail; | |
441 | ! --p; | |
442 | ! /* skip back to after previous '/' */ | |
443 | ! while (p > start && !vim_ispathsep(p[-1])) | |
444 | ! --p; | |
445 | ! /* skip back to after first '/' in a row */ | |
446 | ! while (p - 1 > start && vim_ispathsep(p[-2])) | |
447 | --p; | |
448 | ! movetail(p, tail); /* strip previous component */ | |
449 | ! --components; | |
450 | } | |
451 | - else /* leading "../" */ | |
452 | - p += 3; /* skip to char after "/" */ | |
453 | } | |
454 | else | |
455 | { | |
456 | ++components; /* simple path component */ | |
457 | p = getnextcomp(p); | |
458 | } | |
459 | ! } while (p != NULL && *p != NUL); | |
460 | ! | |
461 | ! #ifdef UNIX | |
462 | ! /* Check that the new file name is really the same file. This will not be | |
463 | ! * the case when using symbolic links: "dir/link/../name" != "dir/name". */ | |
464 | ! { | |
465 | ! struct stat orig_st, new_st; | |
466 | ! | |
467 | ! if ( mch_stat((char *)orig, &orig_st) < 0 | |
468 | ! || mch_stat((char *)filename, &new_st) < 0 | |
469 | ! || orig_st.st_ino != new_st.st_ino | |
470 | ! || orig_st.st_dev != new_st.st_dev) | |
471 | ! STRCPY(filename, orig); | |
472 | ! vim_free(orig); | |
473 | ! } | |
474 | ! #endif | |
475 | #endif /* !AMIGA */ | |
476 | } | |
477 | ||
478 | --- 2900,3064 ---- | |
479 | /* ":: composition: vms host/passwd component */ | |
480 | ++components; | |
481 | p = getnextcomp(p + 2); | |
482 | } | |
483 | else | |
484 | #endif | |
485 | if (vim_ispathsep(*p)) | |
486 | movetail(p, p + 1); /* remove duplicate "/" */ | |
487 | ! else if (p[0] == '.' && (vim_ispathsep(p[1]) || p[1] == NUL)) | |
488 | ! { | |
489 | ! if (p == start && relative) | |
490 | ! p += 1 + (p[1] != NUL); /* keep single "." or leading "./" */ | |
491 | ! else | |
492 | ! { | |
493 | ! /* Strip "./" or ".///". If we are at the end of the file name | |
494 | ! * and there is no trailing path separator, either strip "/." if | |
495 | ! * we are after "start", or strip "." if we are at the beginning | |
496 | ! * of an absolute path name . */ | |
497 | ! tail = p + 1; | |
498 | ! if (p[1] != NUL) | |
499 | ! while (vim_ispathsep(*tail)) | |
500 | ! ++tail; | |
501 | ! else if (p > start) | |
502 | ! --p; /* strip preceding path separator */ | |
503 | ! movetail(p, tail); | |
504 | ! } | |
505 | ! } | |
506 | ! else if (p[0] == '.' && p[1] == '.' && | |
507 | ! (vim_ispathsep(p[2]) || p[2] == NUL)) | |
508 | { | |
509 | + /* Skip to after ".." or "../" or "..///". */ | |
510 | + tail = p + 2; | |
511 | + while (vim_ispathsep(*tail)) | |
512 | + ++tail; | |
513 | + | |
514 | if (components > 0) /* strip one preceding component */ | |
515 | { | |
516 | ! int do_strip = FALSE; | |
517 | ! char_u saved_char; | |
518 | ! struct stat st, new_st; | |
519 | ! | |
520 | ! /* Don't strip for an erroneous file name. */ | |
521 | ! if (!stripping_disabled) | |
522 | ! { | |
523 | ! /* If the preceding component does not exist in the file | |
524 | ! * system, we strip it. On Unix, we don't accept a symbolic | |
525 | ! * link that refers to a non-existent file. */ | |
526 | ! saved_char = p[-1]; | |
527 | ! p[-1] = NUL; | |
528 | ! #ifdef UNIX | |
529 | ! if (mch_lstat((char *)filename, &st) < 0) | |
530 | ! #else | |
531 | ! if (mch_stat((char *)filename, &st) < 0) | |
532 | ! #endif | |
533 | ! do_strip = TRUE; | |
534 | ! p[-1] = saved_char; | |
535 | ! | |
536 | --p; | |
537 | ! /* Skip back to after previous '/'. */ | |
538 | ! while (p > start && !vim_ispathsep(p[-1])) | |
539 | ! --p; | |
540 | ! | |
541 | ! if (!do_strip) | |
542 | ! { | |
543 | ! /* If the component exists in the file system, check | |
544 | ! * that stripping it won't change the meaning of the | |
545 | ! * file name. First get information about the | |
546 | ! * unstripped file name. This may fail if the component | |
547 | ! * to strip is not a searchable directory (but a regular | |
548 | ! * file, for instance), since the trailing "/.." cannot | |
549 | ! * be applied then. We don't strip it then since we | |
550 | ! * don't want to replace an erroneous file name by | |
551 | ! * a valid one, and we disable stripping of later | |
552 | ! * components. */ | |
553 | ! saved_char = *tail; | |
554 | ! *tail = NUL; | |
555 | ! if (mch_stat((char *)filename, &st) >= 0) | |
556 | ! do_strip = TRUE; | |
557 | ! else | |
558 | ! stripping_disabled = TRUE; | |
559 | ! *tail = saved_char; | |
560 | ! #ifdef UNIX | |
561 | ! if (do_strip) | |
562 | ! { | |
563 | ! /* On Unix, the check for the unstripped file name | |
564 | ! * above works also for a symbolic link pointing to | |
565 | ! * a searchable directory. But then the parent of | |
566 | ! * the directory pointed to by the link must be the | |
567 | ! * same as the stripped file name. (The latter | |
568 | ! * exists in the file system since it is the | |
569 | ! * component's parent directory.) */ | |
570 | ! if (p == start && relative) | |
571 | ! (void)mch_stat(".", &new_st); | |
572 | ! else | |
573 | ! { | |
574 | ! saved_char = *p; | |
575 | ! *p = NUL; | |
576 | ! (void)mch_stat((char *)filename, &new_st); | |
577 | ! *p = saved_char; | |
578 | ! } | |
579 | ! | |
580 | ! if (new_st.st_ino != st.st_ino || | |
581 | ! new_st.st_dev != st.st_dev) | |
582 | ! { | |
583 | ! do_strip = FALSE; | |
584 | ! /* We don't disable stripping of later | |
585 | ! * components since the unstripped path name is | |
586 | ! * still valid. */ | |
587 | ! } | |
588 | ! } | |
589 | ! #endif | |
590 | ! } | |
591 | ! } | |
592 | ! | |
593 | ! if (!do_strip) | |
594 | ! { | |
595 | ! /* Skip the ".." or "../" and reset the counter for the | |
596 | ! * components that might be stripped later on. */ | |
597 | ! p = tail; | |
598 | ! components = 0; | |
599 | ! } | |
600 | ! else | |
601 | ! { | |
602 | ! /* Strip previous component. If the result would get empty | |
603 | ! * and there is no trailing path separator, leave a single | |
604 | ! * "." instead. If we are at the end of the file name and | |
605 | ! * there is no trailing path separator and a preceding | |
606 | ! * component is left after stripping, strip its trailing | |
607 | ! * path separator as well. */ | |
608 | ! if (p == start && relative && tail[-1] == '.') | |
609 | ! { | |
610 | ! *p++ = '.'; | |
611 | ! *p = NUL; | |
612 | ! } | |
613 | ! else | |
614 | ! { | |
615 | ! if (p > start && tail[-1] == '.') | |
616 | ! --p; | |
617 | ! movetail(p, tail); /* strip previous component */ | |
618 | ! } | |
619 | ! | |
620 | ! --components; | |
621 | ! } | |
622 | ! } | |
623 | ! else if (p == start && !relative) /* leading "/.." or "/../" */ | |
624 | ! movetail(p, tail); /* strip ".." or "../" */ | |
625 | ! else | |
626 | ! { | |
627 | ! if (p == start + 2 && p[-2] == '.') /* leading "./../" */ | |
628 | ! { | |
629 | ! movetail(p - 2, p); /* strip leading "./" */ | |
630 | ! tail -= 2; | |
631 | ! } | |
632 | ! p = tail; /* skip to char after ".." or "../" */ | |
633 | } | |
634 | } | |
635 | else | |
636 | { | |
637 | ++components; /* simple path component */ | |
638 | p = getnextcomp(p); | |
639 | } | |
640 | ! } while (*p != NUL); | |
641 | #endif /* !AMIGA */ | |
642 | } | |
643 | ||
644 | *** ../vim-6.2.063/src/testdir/test49.vim Fri May 30 21:45:31 2003 | |
645 | --- src/testdir/test49.vim Thu Jul 31 18:25:02 2003 | |
646 | *************** | |
647 | *** 1,6 **** | |
648 | " Vim script language tests | |
649 | " Author: Servatius Brandt <Servatius.Brandt@fujitsu-siemens.com> | |
650 | ! " Last Change: 2003 May 30 | |
651 | ||
652 | "------------------------------------------------------------------------------- | |
653 | " Test environment {{{1 | |
654 | --- 1,6 ---- | |
655 | " Vim script language tests | |
656 | " Author: Servatius Brandt <Servatius.Brandt@fujitsu-siemens.com> | |
657 | ! " Last Change: 2003 Jul 30 | |
658 | ||
659 | "------------------------------------------------------------------------------- | |
660 | " Test environment {{{1 | |
661 | *************** | |
662 | *** 5076,5082 **** | |
663 | Xpath 1048576 " X: 1048576 | |
664 | let exception = v:exception | |
665 | let throwpoint = v:throwpoint | |
666 | ! call CHECK(7, "autsch", scriptT, '\<6\>') | |
667 | finally | |
668 | Xpath 2097152 " X: 2097152 | |
669 | let exception = v:exception | |
670 | --- 5076,5085 ---- | |
671 | Xpath 1048576 " X: 1048576 | |
672 | let exception = v:exception | |
673 | let throwpoint = v:throwpoint | |
674 | ! " Symbolic links in tempname()s are not resolved, whereas resolving | |
675 | ! " is done for v:throwpoint. Resolve the temporary file name for | |
676 | ! " scriptT, so that it can be matched against v:throwpoint. | |
677 | ! call CHECK(7, "autsch", resolve(scriptT), '\<6\>') | |
678 | finally | |
679 | Xpath 2097152 " X: 2097152 | |
680 | let exception = v:exception | |
681 | *************** | |
682 | *** 5091,5097 **** | |
683 | Xpath 8388608 " X: 8388608 | |
684 | let exception = v:exception | |
685 | let throwpoint = v:throwpoint | |
686 | ! call CHECK(9, "brrrr", scriptT, '\<8\>') | |
687 | finally | |
688 | Xpath 16777216 " X: 16777216 | |
689 | let exception = v:exception | |
690 | --- 5094,5101 ---- | |
691 | Xpath 8388608 " X: 8388608 | |
692 | let exception = v:exception | |
693 | let throwpoint = v:throwpoint | |
694 | ! " Resolve scriptT for matching it against v:throwpoint. | |
695 | ! call CHECK(9, "brrrr", resolve(scriptT), '\<8\>') | |
696 | finally | |
697 | Xpath 16777216 " X: 16777216 | |
698 | let exception = v:exception | |
699 | *** ../vim-6.2.063/src/version.c Sun Aug 10 22:24:37 2003 | |
700 | --- src/version.c Sun Aug 10 22:26:34 2003 | |
701 | *************** | |
702 | *** 632,633 **** | |
703 | --- 632,635 ---- | |
704 | { /* Add new patch number below this line */ | |
705 | + /**/ | |
706 | + 64, | |
707 | /**/ | |
708 | ||
709 | -- | |
710 | From "know your smileys": | |
711 | :-{} Too much lipstick | |
712 | ||
713 | /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ | |
714 | /// Creator of Vim - Vi IMproved -- http://www.Vim.org \\\ | |
715 | \\\ Project leader for A-A-P -- http://www.A-A-P.org /// | |
716 | \\\ Help AIDS victims, buy here: http://ICCF-Holland.org/click1.html /// |