]> git.pld-linux.org Git - packages/vim.git/blame - 6.2.064
- manpaged md5 fix
[packages/vim.git] / 6.2.064
CommitLineData
04f0bc09
AF
1To: vim-dev@vim.org
2Subject: Patch 6.2.064
3Fcc: outbox
4From: Bram Moolenaar <Bram@moolenaar.net>
5Mime-Version: 1.0
6Content-Type: text/plain; charset=ISO-8859-1
7Content-Transfer-Encoding: 8bit
8------------
9
10Patch 6.2.064
11Problem: resolve() only handles one symbolic link, need to repeat it to
12 resolve all of them. Then need to simplify the file name.
13Solution: 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)
16Files: 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--
710From "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 ///
This page took 0.104434 seconds and 4 git commands to generate.