]> git.pld-linux.org Git - packages/vim.git/blob - 7.1.256
- new
[packages/vim.git] / 7.1.256
1 To: vim-dev@vim.org
2 Subject: Patch 7.1.256
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 7.1.256
11 Problem:    findfile() also returns directories.
12 Solution:   Cleanup the code for finding files and directories in a list of
13             directories.  Remove the ugly global ff_search_ctx.
14 Files:      src/eval.c, src/misc2.c, src/vim.h, src/tag.c
15
16
17 *** ../vim-7.1.255/src/eval.c   Wed Feb 13 12:41:30 2008
18 --- src/eval.c  Wed Feb 20 11:08:21 2008
19 ***************
20 *** 9203,9215 ****
21       rettv->vval.v_number = filewritable(get_tv_string(&argvars[0]));
22   }
23   
24 ! static void findfilendir __ARGS((typval_T *argvars, typval_T *rettv, int dir));
25   
26       static void
27 ! findfilendir(argvars, rettv, dir)
28       typval_T  *argvars;
29       typval_T  *rettv;
30 !     int               dir;
31   {
32   #ifdef FEAT_SEARCHPATH
33       char_u    *fname;
34 --- 9205,9217 ----
35       rettv->vval.v_number = filewritable(get_tv_string(&argvars[0]));
36   }
37   
38 ! static void findfilendir __ARGS((typval_T *argvars, typval_T *rettv, int find_what));
39   
40       static void
41 ! findfilendir(argvars, rettv, find_what)
42       typval_T  *argvars;
43       typval_T  *rettv;
44 !     int               find_what;
45   {
46   #ifdef FEAT_SEARCHPATH
47       char_u    *fname;
48 ***************
49 *** 9254,9261 ****
50                 vim_free(fresult);
51             fresult = find_file_in_path_option(first ? fname : NULL,
52                                                first ? (int)STRLEN(fname) : 0,
53 !                                       0, first, path, dir, curbuf->b_ffname,
54 !                                       dir ? (char_u *)"" : curbuf->b_p_sua);
55             first = FALSE;
56   
57             if (fresult != NULL && rettv->v_type == VAR_LIST)
58 --- 9256,9266 ----
59                 vim_free(fresult);
60             fresult = find_file_in_path_option(first ? fname : NULL,
61                                                first ? (int)STRLEN(fname) : 0,
62 !                                       0, first, path,
63 !                                       find_what,
64 !                                       curbuf->b_ffname,
65 !                                       find_what == FINDFILE_DIR
66 !                                           ? (char_u *)"" : curbuf->b_p_sua);
67             first = FALSE;
68   
69             if (fresult != NULL && rettv->v_type == VAR_LIST)
70 ***************
71 *** 9445,9451 ****
72       typval_T  *argvars;
73       typval_T  *rettv;
74   {
75 !     findfilendir(argvars, rettv, TRUE);
76   }
77   
78   /*
79 --- 9450,9456 ----
80       typval_T  *argvars;
81       typval_T  *rettv;
82   {
83 !     findfilendir(argvars, rettv, FINDFILE_DIR);
84   }
85   
86   /*
87 ***************
88 *** 9456,9462 ****
89       typval_T  *argvars;
90       typval_T  *rettv;
91   {
92 !     findfilendir(argvars, rettv, FALSE);
93   }
94   
95   /*
96 --- 9461,9467 ----
97       typval_T  *argvars;
98       typval_T  *rettv;
99   {
100 !     findfilendir(argvars, rettv, FINDFILE_FILE);
101   }
102   
103   /*
104 *** ../vim-7.1.255/src/misc2.c  Fri Jan  4 21:25:01 2008
105 --- src/misc2.c Wed Feb 13 17:19:21 2008
106 ***************
107 *** 3777,3785 ****
108       char_u            ffs_filearray_cur;   /* needed for partly handled dirs */
109   
110       /* to store status of partly handled directories
111 !      * 0: we work the on this directory for the first time
112        * 1: this directory was partly searched in an earlier step
113 !     */
114       int                       ffs_stage;
115   
116       /* How deep are we in the directory tree?
117 --- 3778,3786 ----
118       char_u            ffs_filearray_cur;   /* needed for partly handled dirs */
119   
120       /* to store status of partly handled directories
121 !      * 0: we work on this directory for the first time
122        * 1: this directory was partly searched in an earlier step
123 !      */
124       int                       ffs_stage;
125   
126       /* How deep are we in the directory tree?
127 ***************
128 *** 3848,3853 ****
129 --- 3849,3855 ----
130    * Set the default maximum depth.
131    */
132   #define FF_MAX_STAR_STAR_EXPAND ((char_u)30)
133
134   /*
135    * The search context:
136    *   ffsc_stack_ptr:  the stack for the dirs to search
137 ***************
138 *** 3862,3868 ****
139    *   ffsc_wc_path:    the part of the given path containing wildcards
140    *   ffsc_level:      how many levels of dirs to search downwards
141    *   ffsc_stopdirs_v: array of stop directories for upward search
142 !  *   ffsc_need_dir:   TRUE if we search for a directory
143    */
144   typedef struct ff_search_ctx_T
145   {
146 --- 3864,3870 ----
147    *   ffsc_wc_path:    the part of the given path containing wildcards
148    *   ffsc_level:      how many levels of dirs to search downwards
149    *   ffsc_stopdirs_v: array of stop directories for upward search
150 !  *   ffsc_find_what:  FINDFILE_BOTH, FINDFILE_DIR or FINDFILE_FILE
151    */
152   typedef struct ff_search_ctx_T
153   {
154 ***************
155 *** 3879,3889 ****
156        int                      ffsc_level;
157        char_u                   **ffsc_stopdirs_v;
158   #endif
159 !      int                      ffsc_need_dir;
160   } ff_search_ctx_T;
161   
162 - static ff_search_ctx_T *ff_search_ctx = NULL;
163
164   /* locally needed functions */
165   #ifdef FEAT_PATH_EXTRA
166   static int ff_check_visited __ARGS((ff_visited_T **, char_u *, char_u *));
167 --- 3881,3889 ----
168        int                      ffsc_level;
169        char_u                   **ffsc_stopdirs_v;
170   #endif
171 !      int                      ffsc_find_what;
172   } ff_search_ctx_T;
173   
174   /* locally needed functions */
175   #ifdef FEAT_PATH_EXTRA
176   static int ff_check_visited __ARGS((ff_visited_T **, char_u *, char_u *));
177 ***************
178 *** 3897,3906 ****
179   static int ff_wc_equal __ARGS((char_u *s1, char_u *s2));
180   #endif
181   
182 ! static void ff_push __ARGS((ff_stack_T *));
183 ! static ff_stack_T * ff_pop __ARGS((void));
184 ! static void ff_clear __ARGS((void));
185 ! static void ff_free_stack_element __ARGS((ff_stack_T *));
186   #ifdef FEAT_PATH_EXTRA
187   static ff_stack_T *ff_create_stack_element __ARGS((char_u *, char_u *, int, int));
188   #else
189 --- 3897,3906 ----
190   static int ff_wc_equal __ARGS((char_u *s1, char_u *s2));
191   #endif
192   
193 ! static void ff_push __ARGS((ff_search_ctx_T *search_ctx, ff_stack_T *stack_ptr));
194 ! static ff_stack_T *ff_pop __ARGS((ff_search_ctx_T *search_ctx));
195 ! static void ff_clear __ARGS((ff_search_ctx_T *search_ctx));
196 ! static void ff_free_stack_element __ARGS((ff_stack_T *stack_ptr));
197   #ifdef FEAT_PATH_EXTRA
198   static ff_stack_T *ff_create_stack_element __ARGS((char_u *, char_u *, int, int));
199   #else
200 ***************
201 *** 3961,3966 ****
202 --- 3961,3969 ----
203    * not related to restricts given to the '**' wildcard. If 'level' is 100
204    * and you use '**200' vim_findfile() will stop after 100 levels.
205    *
206 +  * 'filename' cannot contain wildcards!  It is used as-is, no backslashes to
207 +  * escape special characters.
208 +  *
209    * If 'stopdirs' is not NULL and nothing is found downward, the search is
210    * restarted on the next higher directory level. This is repeated until the
211    * start-directory of a search is contained in 'stopdirs'. 'stopdirs' has the
212 ***************
213 *** 3980,4053 ****
214    * The list of visited files/dirs can also be cleared with the function
215    * vim_findfile_free_visited().
216    *
217 !  * Set the parameter 'need_dir' to TRUE if you want to search for a directory
218 !  * instead of a file.
219    *
220    * A search context returned by a previous call to vim_findfile_init() can be
221 !  * passed in the parameter 'search_ctx'. This context is than reused and
222 !  * reinitialized with the new parameters. The list of already viseted
223    * directories from this context is only deleted if the parameter
224 !  * 'free_visited' is true. Be aware that the passed search_context is freed if
225 !  * the reinitialization fails.
226    *
227 !  * If you don't have a search context from a previous call 'search_ctx' must be
228 !  * NULL.
229    *
230    * This function silently ignores a few errors, vim_findfile() will have
231    * limited functionality then.
232    */
233   /*ARGSUSED*/
234       void *
235 ! vim_findfile_init(path, filename, stopdirs, level, free_visited, need_dir,
236 !                                               search_ctx, tagfile, rel_fname)
237       char_u    *path;
238       char_u    *filename;
239       char_u    *stopdirs;
240       int               level;
241       int               free_visited;
242 !     int               need_dir;
243 !     void      *search_ctx;
244       int               tagfile;
245       char_u    *rel_fname;     /* file name to use for "." */
246   {
247   #ifdef FEAT_PATH_EXTRA
248 !     char_u    *wc_part;
249   #endif
250 !     ff_stack_T        *sptr;
251   
252       /* If a search context is given by the caller, reuse it, else allocate a
253        * new one.
254        */
255 !     if (search_ctx != NULL)
256 !       ff_search_ctx = search_ctx;
257       else
258       {
259 !       ff_search_ctx = (ff_search_ctx_T*)alloc(
260 !                                          (unsigned)sizeof(ff_search_ctx_T));
261 !       if (ff_search_ctx == NULL)
262             goto error_return;
263 !       memset(ff_search_ctx, 0, sizeof(ff_search_ctx_T));
264       }
265   
266       /* clear the search context, but NOT the visited lists */
267 !     ff_clear();
268   
269       /* clear visited list if wanted */
270       if (free_visited == TRUE)
271 !       vim_findfile_free_visited(ff_search_ctx);
272       else
273       {
274         /* Reuse old visited lists. Get the visited list for the given
275          * filename. If no list for the current filename exists, creates a new
276 !        * one.
277 !        */
278 !       ff_search_ctx->ffsc_visited_list = ff_get_visited_list(filename,
279 !                                    &ff_search_ctx->ffsc_visited_lists_list);
280 !       if (ff_search_ctx->ffsc_visited_list == NULL)
281             goto error_return;
282 !       ff_search_ctx->ffsc_dir_visited_list = ff_get_visited_list(filename,
283 !                                &ff_search_ctx->ffsc_dir_visited_lists_list);
284 !       if (ff_search_ctx->ffsc_dir_visited_list == NULL)
285             goto error_return;
286       }
287   
288 --- 3983,4056 ----
289    * The list of visited files/dirs can also be cleared with the function
290    * vim_findfile_free_visited().
291    *
292 !  * Set the parameter 'find_what' to FINDFILE_DIR if you want to search for
293 !  * directories only, FINDFILE_FILE for files only, FINDFILE_BOTH for both.
294    *
295    * A search context returned by a previous call to vim_findfile_init() can be
296 !  * passed in the parameter "search_ctx_arg".  This context is reused and
297 !  * reinitialized with the new parameters.  The list of already visited
298    * directories from this context is only deleted if the parameter
299 !  * "free_visited" is true.  Be aware that the passed "search_ctx_arg" is freed
300 !  * if the reinitialization fails.
301    *
302 !  * If you don't have a search context from a previous call "search_ctx_arg"
303 !  * must be NULL.
304    *
305    * This function silently ignores a few errors, vim_findfile() will have
306    * limited functionality then.
307    */
308   /*ARGSUSED*/
309       void *
310 ! vim_findfile_init(path, filename, stopdirs, level, free_visited, find_what,
311 !                                          search_ctx_arg, tagfile, rel_fname)
312       char_u    *path;
313       char_u    *filename;
314       char_u    *stopdirs;
315       int               level;
316       int               free_visited;
317 !     int               find_what;
318 !     void      *search_ctx_arg;
319       int               tagfile;
320       char_u    *rel_fname;     /* file name to use for "." */
321   {
322   #ifdef FEAT_PATH_EXTRA
323 !     char_u            *wc_part;
324   #endif
325 !     ff_stack_T                *sptr;
326 !     ff_search_ctx_T   *search_ctx;
327   
328       /* If a search context is given by the caller, reuse it, else allocate a
329        * new one.
330        */
331 !     if (search_ctx_arg != NULL)
332 !       search_ctx = search_ctx_arg;
333       else
334       {
335 !       search_ctx = (ff_search_ctx_T*)alloc((unsigned)sizeof(ff_search_ctx_T));
336 !       if (search_ctx == NULL)
337             goto error_return;
338 !       memset(search_ctx, 0, sizeof(ff_search_ctx_T));
339       }
340 +     search_ctx->ffsc_find_what = find_what;
341   
342       /* clear the search context, but NOT the visited lists */
343 !     ff_clear(search_ctx);
344   
345       /* clear visited list if wanted */
346       if (free_visited == TRUE)
347 !       vim_findfile_free_visited(search_ctx);
348       else
349       {
350         /* Reuse old visited lists. Get the visited list for the given
351          * filename. If no list for the current filename exists, creates a new
352 !        * one. */
353 !       search_ctx->ffsc_visited_list = ff_get_visited_list(filename,
354 !                                       &search_ctx->ffsc_visited_lists_list);
355 !       if (search_ctx->ffsc_visited_list == NULL)
356             goto error_return;
357 !       search_ctx->ffsc_dir_visited_list = ff_get_visited_list(filename,
358 !                                   &search_ctx->ffsc_dir_visited_lists_list);
359 !       if (search_ctx->ffsc_dir_visited_list == NULL)
360             goto error_return;
361       }
362   
363 ***************
364 *** 4071,4082 ****
365         {
366             /* Make the start dir an absolute path name. */
367             vim_strncpy(ff_expand_buffer, rel_fname, len);
368 !           ff_search_ctx->ffsc_start_dir = FullName_save(ff_expand_buffer,
369 !                                                                      FALSE);
370         }
371         else
372 !           ff_search_ctx->ffsc_start_dir = vim_strnsave(rel_fname, len);
373 !       if (ff_search_ctx->ffsc_start_dir == NULL)
374             goto error_return;
375         if (*++path != NUL)
376             ++path;
377 --- 4074,4084 ----
378         {
379             /* Make the start dir an absolute path name. */
380             vim_strncpy(ff_expand_buffer, rel_fname, len);
381 !           search_ctx->ffsc_start_dir = FullName_save(ff_expand_buffer, FALSE);
382         }
383         else
384 !           search_ctx->ffsc_start_dir = vim_strnsave(rel_fname, len);
385 !       if (search_ctx->ffsc_start_dir == NULL)
386             goto error_return;
387         if (*++path != NUL)
388             ++path;
389 ***************
390 *** 4101,4108 ****
391         if (mch_dirname(ff_expand_buffer, MAXPATHL) == FAIL)
392             goto error_return;
393   
394 !       ff_search_ctx->ffsc_start_dir = vim_strsave(ff_expand_buffer);
395 !       if (ff_search_ctx->ffsc_start_dir == NULL)
396             goto error_return;
397   
398   #ifdef BACKSLASH_IN_FILENAME
399 --- 4103,4110 ----
400         if (mch_dirname(ff_expand_buffer, MAXPATHL) == FAIL)
401             goto error_return;
402   
403 !       search_ctx->ffsc_start_dir = vim_strsave(ff_expand_buffer);
404 !       if (search_ctx->ffsc_start_dir == NULL)
405             goto error_return;
406   
407   #ifdef BACKSLASH_IN_FILENAME
408 ***************
409 *** 4110,4117 ****
410          * directory (but not for "//machine/dir").  Only use the drive name. */
411         if ((*path == '/' || *path == '\\')
412                 && path[1] != path[0]
413 !               && ff_search_ctx->ffsc_start_dir[1] == ':')
414 !           ff_search_ctx->ffsc_start_dir[2] = NUL;
415   #endif
416       }
417   
418 --- 4112,4119 ----
419          * directory (but not for "//machine/dir").  Only use the drive name. */
420         if ((*path == '/' || *path == '\\')
421                 && path[1] != path[0]
422 !               && search_ctx->ffsc_start_dir[1] == ':')
423 !           search_ctx->ffsc_start_dir[2] = NUL;
424   #endif
425       }
426   
427 ***************
428 *** 4121,4127 ****
429        * If this fails (mem allocation), there is no upward search at all or a
430        * stop directory is not recognized -> continue silently.
431        * If stopdirs just contains a ";" or is empty,
432 !      * ff_search_ctx->ffsc_stopdirs_v will only contain a  NULL pointer. This
433        * is handled as unlimited upward search.  See function
434        * ff_path_in_stoplist() for details.
435        */
436 --- 4123,4129 ----
437        * If this fails (mem allocation), there is no upward search at all or a
438        * stop directory is not recognized -> continue silently.
439        * If stopdirs just contains a ";" or is empty,
440 !      * search_ctx->ffsc_stopdirs_v will only contain a  NULL pointer. This
441        * is handled as unlimited upward search.  See function
442        * ff_path_in_stoplist() for details.
443        */
444 ***************
445 *** 4134,4143 ****
446             walker++;
447   
448         dircount = 1;
449 !       ff_search_ctx->ffsc_stopdirs_v =
450 !           (char_u **)alloc((unsigned)sizeof(char_u *));
451   
452 !       if (ff_search_ctx->ffsc_stopdirs_v != NULL)
453         {
454             do
455             {
456 --- 4136,4145 ----
457             walker++;
458   
459         dircount = 1;
460 !       search_ctx->ffsc_stopdirs_v =
461 !                                (char_u **)alloc((unsigned)sizeof(char_u *));
462   
463 !       if (search_ctx->ffsc_stopdirs_v != NULL)
464         {
465             do
466             {
467 ***************
468 *** 4145,4181 ****
469                 void    *ptr;
470   
471                 helper = walker;
472 !               ptr = vim_realloc(ff_search_ctx->ffsc_stopdirs_v,
473                                            (dircount + 1) * sizeof(char_u *));
474                 if (ptr)
475 !                   ff_search_ctx->ffsc_stopdirs_v = ptr;
476                 else
477                     /* ignore, keep what we have and continue */
478                     break;
479                 walker = vim_strchr(walker, ';');
480                 if (walker)
481                 {
482 !                   ff_search_ctx->ffsc_stopdirs_v[dircount-1] =
483 !                       vim_strnsave(helper, (int)(walker - helper));
484                     walker++;
485                 }
486                 else
487                     /* this might be "", which means ascent till top
488                      * of directory tree.
489                      */
490 !                   ff_search_ctx->ffsc_stopdirs_v[dircount-1] =
491 !                       vim_strsave(helper);
492   
493                 dircount++;
494   
495             } while (walker != NULL);
496 !           ff_search_ctx->ffsc_stopdirs_v[dircount-1] = NULL;
497         }
498       }
499   #endif
500   
501   #ifdef FEAT_PATH_EXTRA
502 !     ff_search_ctx->ffsc_level = level;
503   
504       /* split into:
505        *  -fix path
506 --- 4147,4183 ----
507                 void    *ptr;
508   
509                 helper = walker;
510 !               ptr = vim_realloc(search_ctx->ffsc_stopdirs_v,
511                                            (dircount + 1) * sizeof(char_u *));
512                 if (ptr)
513 !                   search_ctx->ffsc_stopdirs_v = ptr;
514                 else
515                     /* ignore, keep what we have and continue */
516                     break;
517                 walker = vim_strchr(walker, ';');
518                 if (walker)
519                 {
520 !                   search_ctx->ffsc_stopdirs_v[dircount-1] =
521 !                                vim_strnsave(helper, (int)(walker - helper));
522                     walker++;
523                 }
524                 else
525                     /* this might be "", which means ascent till top
526                      * of directory tree.
527                      */
528 !                   search_ctx->ffsc_stopdirs_v[dircount-1] =
529 !                                                         vim_strsave(helper);
530   
531                 dircount++;
532   
533             } while (walker != NULL);
534 !           search_ctx->ffsc_stopdirs_v[dircount-1] = NULL;
535         }
536       }
537   #endif
538   
539   #ifdef FEAT_PATH_EXTRA
540 !     search_ctx->ffsc_level = level;
541   
542       /* split into:
543        *  -fix path
544 ***************
545 *** 4189,4196 ****
546         char    *errpt;
547   
548         /* save the fix part of the path */
549 !       ff_search_ctx->ffsc_fix_path = vim_strnsave(path,
550 !                                                      (int)(wc_part - path));
551   
552         /*
553          * copy wc_path and add restricts to the '**' wildcard.
554 --- 4191,4197 ----
555         char    *errpt;
556   
557         /* save the fix part of the path */
558 !       search_ctx->ffsc_fix_path = vim_strnsave(path, (int)(wc_part - path));
559   
560         /*
561          * copy wc_path and add restricts to the '**' wildcard.
562 ***************
563 *** 4229,4275 ****
564                 ff_expand_buffer[len++] = *wc_part++;
565         }
566         ff_expand_buffer[len] = NUL;
567 !       ff_search_ctx->ffsc_wc_path = vim_strsave(ff_expand_buffer);
568   
569 !       if (ff_search_ctx->ffsc_wc_path == NULL)
570             goto error_return;
571       }
572       else
573   #endif
574 !       ff_search_ctx->ffsc_fix_path = vim_strsave(path);
575   
576 !     if (ff_search_ctx->ffsc_start_dir == NULL)
577       {
578         /* store the fix part as startdir.
579          * This is needed if the parameter path is fully qualified.
580          */
581 !       ff_search_ctx->ffsc_start_dir = vim_strsave(ff_search_ctx->ffsc_fix_path);
582 !       if (ff_search_ctx->ffsc_start_dir)
583 !           ff_search_ctx->ffsc_fix_path[0] = NUL;
584       }
585   
586       /* create an absolute path */
587 !     STRCPY(ff_expand_buffer, ff_search_ctx->ffsc_start_dir);
588       add_pathsep(ff_expand_buffer);
589 !     STRCAT(ff_expand_buffer, ff_search_ctx->ffsc_fix_path);
590       add_pathsep(ff_expand_buffer);
591   
592       sptr = ff_create_stack_element(ff_expand_buffer,
593   #ifdef FEAT_PATH_EXTRA
594 !           ff_search_ctx->ffsc_wc_path,
595   #endif
596             level, 0);
597   
598       if (sptr == NULL)
599         goto error_return;
600   
601 !     ff_push(sptr);
602   
603 !     ff_search_ctx->ffsc_file_to_search = vim_strsave(filename);
604 !     if (ff_search_ctx->ffsc_file_to_search == NULL)
605         goto error_return;
606   
607 !     return ff_search_ctx;
608   
609   error_return:
610       /*
611 --- 4230,4276 ----
612                 ff_expand_buffer[len++] = *wc_part++;
613         }
614         ff_expand_buffer[len] = NUL;
615 !       search_ctx->ffsc_wc_path = vim_strsave(ff_expand_buffer);
616   
617 !       if (search_ctx->ffsc_wc_path == NULL)
618             goto error_return;
619       }
620       else
621   #endif
622 !       search_ctx->ffsc_fix_path = vim_strsave(path);
623   
624 !     if (search_ctx->ffsc_start_dir == NULL)
625       {
626         /* store the fix part as startdir.
627          * This is needed if the parameter path is fully qualified.
628          */
629 !       search_ctx->ffsc_start_dir = vim_strsave(search_ctx->ffsc_fix_path);
630 !       if (search_ctx->ffsc_start_dir)
631 !           search_ctx->ffsc_fix_path[0] = NUL;
632       }
633   
634       /* create an absolute path */
635 !     STRCPY(ff_expand_buffer, search_ctx->ffsc_start_dir);
636       add_pathsep(ff_expand_buffer);
637 !     STRCAT(ff_expand_buffer, search_ctx->ffsc_fix_path);
638       add_pathsep(ff_expand_buffer);
639   
640       sptr = ff_create_stack_element(ff_expand_buffer,
641   #ifdef FEAT_PATH_EXTRA
642 !           search_ctx->ffsc_wc_path,
643   #endif
644             level, 0);
645   
646       if (sptr == NULL)
647         goto error_return;
648   
649 !     ff_push(search_ctx, sptr);
650   
651 !     search_ctx->ffsc_file_to_search = vim_strsave(filename);
652 !     if (search_ctx->ffsc_file_to_search == NULL)
653         goto error_return;
654   
655 !     return search_ctx;
656   
657   error_return:
658       /*
659 ***************
660 *** 4277,4283 ****
661        * Even when the caller gave us a (perhaps valid) context we free it here,
662        * as we might have already destroyed it.
663        */
664 !     vim_findfile_cleanup(ff_search_ctx);
665       return NULL;
666   }
667   
668 --- 4278,4284 ----
669        * Even when the caller gave us a (perhaps valid) context we free it here,
670        * as we might have already destroyed it.
671        */
672 !     vim_findfile_cleanup(search_ctx);
673       return NULL;
674   }
675   
676 ***************
677 *** 4314,4320 ****
678   }
679   #endif
680   
681 ! /* Clean up the given search context. Can handle a NULL pointer */
682       void
683   vim_findfile_cleanup(ctx)
684       void      *ctx;
685 --- 4315,4323 ----
686   }
687   #endif
688   
689 ! /*
690 !  * Clean up the given search context. Can handle a NULL pointer.
691 !  */
692       void
693   vim_findfile_cleanup(ctx)
694       void      *ctx;
695 ***************
696 *** 4322,4333 ****
697       if (ctx == NULL)
698         return;
699   
700 -     ff_search_ctx = ctx;
701
702       vim_findfile_free_visited(ctx);
703 !     ff_clear();
704       vim_free(ctx);
705 -     ff_search_ctx = NULL;
706   }
707   
708   /*
709 --- 4325,4333 ----
710       if (ctx == NULL)
711         return;
712   
713       vim_findfile_free_visited(ctx);
714 !     ff_clear(ctx);
715       vim_free(ctx);
716   }
717   
718   /*
719 ***************
720 *** 4343,4357 ****
721    * top of the list).
722    */
723       char_u *
724 ! vim_findfile(search_ctx)
725 !     void      *search_ctx;
726   {
727       char_u    *file_path;
728   #ifdef FEAT_PATH_EXTRA
729       char_u    *rest_of_wildcards;
730       char_u    *path_end = NULL;
731   #endif
732 !     ff_stack_T        *ctx;
733   #if defined(FEAT_SEARCHPATH) || defined(FEAT_PATH_EXTRA)
734       int               len;
735   #endif
736 --- 4343,4357 ----
737    * top of the list).
738    */
739       char_u *
740 ! vim_findfile(search_ctx_arg)
741 !     void      *search_ctx_arg;
742   {
743       char_u    *file_path;
744   #ifdef FEAT_PATH_EXTRA
745       char_u    *rest_of_wildcards;
746       char_u    *path_end = NULL;
747   #endif
748 !     ff_stack_T        *stackp;
749   #if defined(FEAT_SEARCHPATH) || defined(FEAT_PATH_EXTRA)
750       int               len;
751   #endif
752 ***************
753 *** 4360,4370 ****
754   #ifdef FEAT_SEARCHPATH
755       char_u    *suf;
756   #endif
757   
758 !     if (search_ctx == NULL)
759         return NULL;
760   
761 !     ff_search_ctx = (ff_search_ctx_T*)search_ctx;
762   
763       /*
764        * filepath is used as buffer for various actions and as the storage to
765 --- 4360,4371 ----
766   #ifdef FEAT_SEARCHPATH
767       char_u    *suf;
768   #endif
769 +     ff_search_ctx_T *search_ctx;
770   
771 !     if (search_ctx_arg == NULL)
772         return NULL;
773   
774 !     search_ctx = (ff_search_ctx_T *)search_ctx_arg;
775   
776       /*
777        * filepath is used as buffer for various actions and as the storage to
778 ***************
779 *** 4375,4382 ****
780   
781   #ifdef FEAT_PATH_EXTRA
782       /* store the end of the start dir -- needed for upward search */
783 !     if (ff_search_ctx->ffsc_start_dir != NULL)
784 !       path_end = &ff_search_ctx->ffsc_start_dir[STRLEN(ff_search_ctx->ffsc_start_dir)];
785   #endif
786   
787   #ifdef FEAT_PATH_EXTRA
788 --- 4376,4384 ----
789   
790   #ifdef FEAT_PATH_EXTRA
791       /* store the end of the start dir -- needed for upward search */
792 !     if (search_ctx->ffsc_start_dir != NULL)
793 !       path_end = &search_ctx->ffsc_start_dir[
794 !                                         STRLEN(search_ctx->ffsc_start_dir)];
795   #endif
796   
797   #ifdef FEAT_PATH_EXTRA
798 ***************
799 *** 4393,4400 ****
800                 break;
801   
802             /* get directory to work on from stack */
803 !           ctx = ff_pop();
804 !           if (ctx == NULL)
805                 break;
806   
807             /*
808 --- 4395,4402 ----
809                 break;
810   
811             /* get directory to work on from stack */
812 !           stackp = ff_pop(search_ctx);
813 !           if (stackp == NULL)
814                 break;
815   
816             /*
817 ***************
818 *** 4414,4427 ****
819              *  /etc/rc.d/init.d is linked to /etc/rc.d -> endless loop)
820              *
821              * This check is only needed for directories we work on for the
822 !            * first time (hence ctx->ff_filearray == NULL)
823              */
824 !           if (ctx->ffs_filearray == NULL
825 !                   && ff_check_visited(&ff_search_ctx->ffsc_dir_visited_list
826                                                           ->ffvl_visited_list,
827 !                       ctx->ffs_fix_path
828   #ifdef FEAT_PATH_EXTRA
829 !                       , ctx->ffs_wc_path
830   #endif
831                         ) == FAIL)
832             {
833 --- 4416,4429 ----
834              *  /etc/rc.d/init.d is linked to /etc/rc.d -> endless loop)
835              *
836              * This check is only needed for directories we work on for the
837 !            * first time (hence stackp->ff_filearray == NULL)
838              */
839 !           if (stackp->ffs_filearray == NULL
840 !                   && ff_check_visited(&search_ctx->ffsc_dir_visited_list
841                                                           ->ffvl_visited_list,
842 !                       stackp->ffs_fix_path
843   #ifdef FEAT_PATH_EXTRA
844 !                       , stackp->ffs_wc_path
845   #endif
846                         ) == FAIL)
847             {
848 ***************
849 *** 4430,4442 ****
850                 {
851                     verbose_enter_scroll();
852                     smsg((char_u *)"Already Searched: %s (%s)",
853 !                                          ctx->ffs_fix_path, ctx->ffs_wc_path);
854                     /* don't overwrite this either */
855                     msg_puts((char_u *)"\n");
856                     verbose_leave_scroll();
857                 }
858   #endif
859 !               ff_free_stack_element(ctx);
860                 continue;
861             }
862   #ifdef FF_VERBOSE
863 --- 4432,4444 ----
864                 {
865                     verbose_enter_scroll();
866                     smsg((char_u *)"Already Searched: %s (%s)",
867 !                                  stackp->ffs_fix_path, stackp->ffs_wc_path);
868                     /* don't overwrite this either */
869                     msg_puts((char_u *)"\n");
870                     verbose_leave_scroll();
871                 }
872   #endif
873 !               ff_free_stack_element(stackp);
874                 continue;
875             }
876   #ifdef FF_VERBOSE
877 ***************
878 *** 4444,4450 ****
879             {
880                 verbose_enter_scroll();
881                 smsg((char_u *)"Searching: %s (%s)",
882 !                                        ctx->ffs_fix_path, ctx->ffs_wc_path);
883                 /* don't overwrite this either */
884                 msg_puts((char_u *)"\n");
885                 verbose_leave_scroll();
886 --- 4446,4452 ----
887             {
888                 verbose_enter_scroll();
889                 smsg((char_u *)"Searching: %s (%s)",
890 !                                  stackp->ffs_fix_path, stackp->ffs_wc_path);
891                 /* don't overwrite this either */
892                 msg_puts((char_u *)"\n");
893                 verbose_leave_scroll();
894 ***************
895 *** 4452,4460 ****
896   #endif
897   
898             /* check depth */
899 !           if (ctx->ffs_level <= 0)
900             {
901 !               ff_free_stack_element(ctx);
902                 continue;
903             }
904   
905 --- 4454,4462 ----
906   #endif
907   
908             /* check depth */
909 !           if (stackp->ffs_level <= 0)
910             {
911 !               ff_free_stack_element(stackp);
912                 continue;
913             }
914   
915 ***************
916 *** 4466,4472 ****
917              * and all possible expands are returned in one array. We use this
918              * to handle the expansion of '**' into an empty string.
919              */
920 !           if (ctx->ffs_filearray == NULL)
921             {
922                 char_u *dirptrs[2];
923   
924 --- 4468,4474 ----
925              * and all possible expands are returned in one array. We use this
926              * to handle the expansion of '**' into an empty string.
927              */
928 !           if (stackp->ffs_filearray == NULL)
929             {
930                 char_u *dirptrs[2];
931   
932 ***************
933 *** 4477,4495 ****
934                 dirptrs[1] = NULL;
935   
936                 /* if we have a start dir copy it in */
937 !               if (!vim_isAbsName(ctx->ffs_fix_path)
938 !                       && ff_search_ctx->ffsc_start_dir)
939                 {
940 !                   STRCPY(file_path, ff_search_ctx->ffsc_start_dir);
941                     add_pathsep(file_path);
942                 }
943   
944                 /* append the fix part of the search path */
945 !               STRCAT(file_path, ctx->ffs_fix_path);
946                 add_pathsep(file_path);
947   
948   #ifdef FEAT_PATH_EXTRA
949 !               rest_of_wildcards = ctx->ffs_wc_path;
950                 if (*rest_of_wildcards != NUL)
951                 {
952                     len = (int)STRLEN(file_path);
953 --- 4479,4497 ----
954                 dirptrs[1] = NULL;
955   
956                 /* if we have a start dir copy it in */
957 !               if (!vim_isAbsName(stackp->ffs_fix_path)
958 !                                               && search_ctx->ffsc_start_dir)
959                 {
960 !                   STRCPY(file_path, search_ctx->ffsc_start_dir);
961                     add_pathsep(file_path);
962                 }
963   
964                 /* append the fix part of the search path */
965 !               STRCAT(file_path, stackp->ffs_fix_path);
966                 add_pathsep(file_path);
967   
968   #ifdef FEAT_PATH_EXTRA
969 !               rest_of_wildcards = stackp->ffs_wc_path;
970                 if (*rest_of_wildcards != NUL)
971                 {
972                     len = (int)STRLEN(file_path);
973 ***************
974 *** 4516,4526 ****
975                         else
976                             rest_of_wildcards += 3;
977   
978 !                       if (ctx->ffs_star_star_empty == 0)
979                         {
980                             /* if not done before, expand '**' to empty */
981 !                           ctx->ffs_star_star_empty = 1;
982 !                           dirptrs[1] = ctx->ffs_fix_path;
983                         }
984                     }
985   
986 --- 4518,4528 ----
987                         else
988                             rest_of_wildcards += 3;
989   
990 !                       if (stackp->ffs_star_star_empty == 0)
991                         {
992                             /* if not done before, expand '**' to empty */
993 !                           stackp->ffs_star_star_empty = 1;
994 !                           dirptrs[1] = stackp->ffs_fix_path;
995                         }
996                     }
997   
998 ***************
999 *** 4547,4576 ****
1000                  */
1001                 if (path_with_url(dirptrs[0]))
1002                 {
1003 !                   ctx->ffs_filearray = (char_u **)
1004                                               alloc((unsigned)sizeof(char *));
1005 !                   if (ctx->ffs_filearray != NULL
1006 !                           && (ctx->ffs_filearray[0]
1007                                 = vim_strsave(dirptrs[0])) != NULL)
1008 !                       ctx->ffs_filearray_size = 1;
1009                     else
1010 !                       ctx->ffs_filearray_size = 0;
1011                 }
1012                 else
1013                     expand_wildcards((dirptrs[1] == NULL) ? 1 : 2, dirptrs,
1014 !                           &ctx->ffs_filearray_size,
1015 !                           &ctx->ffs_filearray,
1016                             EW_DIR|EW_ADDSLASH|EW_SILENT);
1017   
1018 !               ctx->ffs_filearray_cur = 0;
1019 !               ctx->ffs_stage = 0;
1020             }
1021   #ifdef FEAT_PATH_EXTRA
1022             else
1023 !               rest_of_wildcards = &ctx->ffs_wc_path[STRLEN(ctx->ffs_wc_path)];
1024   #endif
1025   
1026 !           if (ctx->ffs_stage == 0)
1027             {
1028                 /* this is the first time we work on this directory */
1029   #ifdef FEAT_PATH_EXTRA
1030 --- 4549,4579 ----
1031                  */
1032                 if (path_with_url(dirptrs[0]))
1033                 {
1034 !                   stackp->ffs_filearray = (char_u **)
1035                                               alloc((unsigned)sizeof(char *));
1036 !                   if (stackp->ffs_filearray != NULL
1037 !                           && (stackp->ffs_filearray[0]
1038                                 = vim_strsave(dirptrs[0])) != NULL)
1039 !                       stackp->ffs_filearray_size = 1;
1040                     else
1041 !                       stackp->ffs_filearray_size = 0;
1042                 }
1043                 else
1044                     expand_wildcards((dirptrs[1] == NULL) ? 1 : 2, dirptrs,
1045 !                           &stackp->ffs_filearray_size,
1046 !                           &stackp->ffs_filearray,
1047                             EW_DIR|EW_ADDSLASH|EW_SILENT);
1048   
1049 !               stackp->ffs_filearray_cur = 0;
1050 !               stackp->ffs_stage = 0;
1051             }
1052   #ifdef FEAT_PATH_EXTRA
1053             else
1054 !               rest_of_wildcards = &stackp->ffs_wc_path[
1055 !                                                STRLEN(stackp->ffs_wc_path)];
1056   #endif
1057   
1058 !           if (stackp->ffs_stage == 0)
1059             {
1060                 /* this is the first time we work on this directory */
1061   #ifdef FEAT_PATH_EXTRA
1062 ***************
1063 *** 4581,4598 ****
1064                      * we don't have further wildcards to expand, so we have to
1065                      * check for the final file now
1066                      */
1067 !                   for (i = ctx->ffs_filearray_cur;
1068 !                                            i < ctx->ffs_filearray_size; ++i)
1069                     {
1070 !                       if (!path_with_url(ctx->ffs_filearray[i])
1071 !                                        && !mch_isdir(ctx->ffs_filearray[i]))
1072                             continue;   /* not a directory */
1073   
1074                         /* prepare the filename to be checked for existance
1075                          * below */
1076 !                       STRCPY(file_path, ctx->ffs_filearray[i]);
1077                         add_pathsep(file_path);
1078 !                       STRCAT(file_path, ff_search_ctx->ffsc_file_to_search);
1079   
1080                         /*
1081                          * Try without extra suffix and then with suffixes
1082 --- 4584,4601 ----
1083                      * we don't have further wildcards to expand, so we have to
1084                      * check for the final file now
1085                      */
1086 !                   for (i = stackp->ffs_filearray_cur;
1087 !                                         i < stackp->ffs_filearray_size; ++i)
1088                     {
1089 !                       if (!path_with_url(stackp->ffs_filearray[i])
1090 !                                     && !mch_isdir(stackp->ffs_filearray[i]))
1091                             continue;   /* not a directory */
1092   
1093                         /* prepare the filename to be checked for existance
1094                          * below */
1095 !                       STRCPY(file_path, stackp->ffs_filearray[i]);
1096                         add_pathsep(file_path);
1097 !                       STRCAT(file_path, search_ctx->ffsc_file_to_search);
1098   
1099                         /*
1100                          * Try without extra suffix and then with suffixes
1101 ***************
1102 *** 4606,4617 ****
1103                         {
1104                             /* if file exists and we didn't already find it */
1105                             if ((path_with_url(file_path)
1106 !                                       || (mch_getperm(file_path) >= 0
1107 !                                           && (!ff_search_ctx->ffsc_need_dir
1108 !                                               || mch_isdir(file_path))))
1109   #ifndef FF_VERBOSE
1110                                     && (ff_check_visited(
1111 !                                           &ff_search_ctx->ffsc_visited_list->ffvl_visited_list,
1112                                             file_path
1113   #ifdef FEAT_PATH_EXTRA
1114                                             , (char_u *)""
1115 --- 4609,4623 ----
1116                         {
1117                             /* if file exists and we didn't already find it */
1118                             if ((path_with_url(file_path)
1119 !                                 || (mch_getperm(file_path) >= 0
1120 !                                     && (search_ctx->ffsc_find_what
1121 !                                                             == FINDFILE_BOTH
1122 !                                         || ((search_ctx->ffsc_find_what
1123 !                                                             == FINDFILE_DIR)
1124 !                                                  == mch_isdir(file_path)))))
1125   #ifndef FF_VERBOSE
1126                                     && (ff_check_visited(
1127 !                                           &search_ctx->ffsc_visited_list->ffvl_visited_list,
1128                                             file_path
1129   #ifdef FEAT_PATH_EXTRA
1130                                             , (char_u *)""
1131 ***************
1132 *** 4622,4628 ****
1133                             {
1134   #ifdef FF_VERBOSE
1135                                 if (ff_check_visited(
1136 !                                           &ff_search_ctx->ffsc_visited_list->ffvl_visited_list,
1137                                             file_path
1138   #ifdef FEAT_PATH_EXTRA
1139                                             , (char_u *)""
1140 --- 4628,4634 ----
1141                             {
1142   #ifdef FF_VERBOSE
1143                                 if (ff_check_visited(
1144 !                                           &search_ctx->ffsc_visited_list->ffvl_visited_list,
1145                                             file_path
1146   #ifdef FEAT_PATH_EXTRA
1147                                             , (char_u *)""
1148 ***************
1149 *** 4643,4650 ****
1150   #endif
1151   
1152                                 /* push dir to examine rest of subdirs later */
1153 !                               ctx->ffs_filearray_cur = i + 1;
1154 !                               ff_push(ctx);
1155   
1156                                 simplify_filename(file_path);
1157                                 if (mch_dirname(ff_expand_buffer, MAXPATHL)
1158 --- 4649,4656 ----
1159   #endif
1160   
1161                                 /* push dir to examine rest of subdirs later */
1162 !                               stackp->ffs_filearray_cur = i + 1;
1163 !                               ff_push(search_ctx, stackp);
1164   
1165                                 simplify_filename(file_path);
1166                                 if (mch_dirname(ff_expand_buffer, MAXPATHL)
1167 ***************
1168 *** 4686,4704 ****
1169                      * still wildcards left, push the directories for further
1170                      * search
1171                      */
1172 !                   for (i = ctx->ffs_filearray_cur;
1173 !                                            i < ctx->ffs_filearray_size; ++i)
1174                     {
1175 !                       if (!mch_isdir(ctx->ffs_filearray[i]))
1176                             continue;   /* not a directory */
1177   
1178 !                       ff_push(ff_create_stack_element(ctx->ffs_filearray[i],
1179 !                                     rest_of_wildcards, ctx->ffs_level - 1, 0));
1180                     }
1181                 }
1182   #endif
1183 !               ctx->ffs_filearray_cur = 0;
1184 !               ctx->ffs_stage = 1;
1185             }
1186   
1187   #ifdef FEAT_PATH_EXTRA
1188 --- 4692,4713 ----
1189                      * still wildcards left, push the directories for further
1190                      * search
1191                      */
1192 !                   for (i = stackp->ffs_filearray_cur;
1193 !                                         i < stackp->ffs_filearray_size; ++i)
1194                     {
1195 !                       if (!mch_isdir(stackp->ffs_filearray[i]))
1196                             continue;   /* not a directory */
1197   
1198 !                       ff_push(search_ctx,
1199 !                               ff_create_stack_element(
1200 !                                                    stackp->ffs_filearray[i],
1201 !                                                    rest_of_wildcards,
1202 !                                                    stackp->ffs_level - 1, 0));
1203                     }
1204                 }
1205   #endif
1206 !               stackp->ffs_filearray_cur = 0;
1207 !               stackp->ffs_stage = 1;
1208             }
1209   
1210   #ifdef FEAT_PATH_EXTRA
1211 ***************
1212 *** 4706,4728 ****
1213              * if wildcards contains '**' we have to descent till we reach the
1214              * leaves of the directory tree.
1215              */
1216 !           if (STRNCMP(ctx->ffs_wc_path, "**", 2) == 0)
1217             {
1218 !               for (i = ctx->ffs_filearray_cur;
1219 !                                            i < ctx->ffs_filearray_size; ++i)
1220                 {
1221 !                   if (fnamecmp(ctx->ffs_filearray[i], ctx->ffs_fix_path) == 0)
1222                         continue; /* don't repush same directory */
1223 !                   if (!mch_isdir(ctx->ffs_filearray[i]))
1224                         continue;   /* not a directory */
1225 !                   ff_push(ff_create_stack_element(ctx->ffs_filearray[i],
1226 !                               ctx->ffs_wc_path, ctx->ffs_level - 1, 1));
1227                 }
1228             }
1229   #endif
1230   
1231             /* we are done with the current directory */
1232 !           ff_free_stack_element(ctx);
1233   
1234         }
1235   
1236 --- 4715,4739 ----
1237              * if wildcards contains '**' we have to descent till we reach the
1238              * leaves of the directory tree.
1239              */
1240 !           if (STRNCMP(stackp->ffs_wc_path, "**", 2) == 0)
1241             {
1242 !               for (i = stackp->ffs_filearray_cur;
1243 !                                         i < stackp->ffs_filearray_size; ++i)
1244                 {
1245 !                   if (fnamecmp(stackp->ffs_filearray[i],
1246 !                                                  stackp->ffs_fix_path) == 0)
1247                         continue; /* don't repush same directory */
1248 !                   if (!mch_isdir(stackp->ffs_filearray[i]))
1249                         continue;   /* not a directory */
1250 !                   ff_push(search_ctx,
1251 !                           ff_create_stack_element(stackp->ffs_filearray[i],
1252 !                               stackp->ffs_wc_path, stackp->ffs_level - 1, 1));
1253                 }
1254             }
1255   #endif
1256   
1257             /* we are done with the current directory */
1258 !           ff_free_stack_element(stackp);
1259   
1260         }
1261   
1262 ***************
1263 *** 4730,4769 ****
1264         /* If we reached this, we didn't find anything downwards.
1265          * Let's check if we should do an upward search.
1266          */
1267 !       if (ff_search_ctx->ffsc_start_dir
1268 !               && ff_search_ctx->ffsc_stopdirs_v != NULL && !got_int)
1269         {
1270             ff_stack_T  *sptr;
1271   
1272             /* is the last starting directory in the stop list? */
1273 !           if (ff_path_in_stoplist(ff_search_ctx->ffsc_start_dir,
1274 !                      (int)(path_end - ff_search_ctx->ffsc_start_dir),
1275 !                      ff_search_ctx->ffsc_stopdirs_v) == TRUE)
1276                 break;
1277   
1278             /* cut of last dir */
1279 !           while (path_end > ff_search_ctx->ffsc_start_dir
1280 !                   && vim_ispathsep(*path_end))
1281                 path_end--;
1282 !           while (path_end > ff_search_ctx->ffsc_start_dir
1283 !                   && !vim_ispathsep(path_end[-1]))
1284                 path_end--;
1285             *path_end = 0;
1286             path_end--;
1287   
1288 !           if (*ff_search_ctx->ffsc_start_dir == 0)
1289                 break;
1290   
1291 !           STRCPY(file_path, ff_search_ctx->ffsc_start_dir);
1292             add_pathsep(file_path);
1293 !           STRCAT(file_path, ff_search_ctx->ffsc_fix_path);
1294   
1295             /* create a new stack entry */
1296             sptr = ff_create_stack_element(file_path,
1297 !                   ff_search_ctx->ffsc_wc_path, ff_search_ctx->ffsc_level, 0);
1298             if (sptr == NULL)
1299                 break;
1300 !           ff_push(sptr);
1301         }
1302         else
1303             break;
1304 --- 4741,4780 ----
1305         /* If we reached this, we didn't find anything downwards.
1306          * Let's check if we should do an upward search.
1307          */
1308 !       if (search_ctx->ffsc_start_dir
1309 !               && search_ctx->ffsc_stopdirs_v != NULL && !got_int)
1310         {
1311             ff_stack_T  *sptr;
1312   
1313             /* is the last starting directory in the stop list? */
1314 !           if (ff_path_in_stoplist(search_ctx->ffsc_start_dir,
1315 !                      (int)(path_end - search_ctx->ffsc_start_dir),
1316 !                      search_ctx->ffsc_stopdirs_v) == TRUE)
1317                 break;
1318   
1319             /* cut of last dir */
1320 !           while (path_end > search_ctx->ffsc_start_dir
1321 !                                                 && vim_ispathsep(*path_end))
1322                 path_end--;
1323 !           while (path_end > search_ctx->ffsc_start_dir
1324 !                                             && !vim_ispathsep(path_end[-1]))
1325                 path_end--;
1326             *path_end = 0;
1327             path_end--;
1328   
1329 !           if (*search_ctx->ffsc_start_dir == 0)
1330                 break;
1331   
1332 !           STRCPY(file_path, search_ctx->ffsc_start_dir);
1333             add_pathsep(file_path);
1334 !           STRCAT(file_path, search_ctx->ffsc_fix_path);
1335   
1336             /* create a new stack entry */
1337             sptr = ff_create_stack_element(file_path,
1338 !                   search_ctx->ffsc_wc_path, search_ctx->ffsc_level, 0);
1339             if (sptr == NULL)
1340                 break;
1341 !           ff_push(search_ctx, sptr);
1342         }
1343         else
1344             break;
1345 ***************
1346 *** 4779,4794 ****
1347    * Can handle it if the passed search_context is NULL;
1348    */
1349       void
1350 ! vim_findfile_free_visited(search_ctx)
1351 !     void      *search_ctx;
1352   {
1353 !     if (search_ctx == NULL)
1354 !       return;
1355   
1356 !     ff_search_ctx = (ff_search_ctx_T *)search_ctx;
1357   
1358 !     vim_findfile_free_visited_list(&ff_search_ctx->ffsc_visited_lists_list);
1359 !     vim_findfile_free_visited_list(&ff_search_ctx->ffsc_dir_visited_lists_list);
1360   }
1361   
1362       static void
1363 --- 4790,4806 ----
1364    * Can handle it if the passed search_context is NULL;
1365    */
1366       void
1367 ! vim_findfile_free_visited(search_ctx_arg)
1368 !     void      *search_ctx_arg;
1369   {
1370 !     ff_search_ctx_T *search_ctx;
1371   
1372 !     if (search_ctx_arg == NULL)
1373 !       return;
1374   
1375 !     search_ctx = (ff_search_ctx_T *)search_ctx_arg;
1376 !     vim_findfile_free_visited_list(&search_ctx->ffsc_visited_lists_list);
1377 !     vim_findfile_free_visited_list(&search_ctx->ffsc_dir_visited_lists_list);
1378   }
1379   
1380       static void
1381 ***************
1382 *** 5103,5135 ****
1383   }
1384   
1385   /*
1386 !  * push a dir on the directory stack
1387    */
1388       static void
1389 ! ff_push(ctx)
1390 !     ff_stack_T *ctx;
1391   {
1392       /* check for NULL pointer, not to return an error to the user, but
1393        * to prevent a crash */
1394 !     if (ctx != NULL)
1395       {
1396 !       ctx->ffs_prev   = ff_search_ctx->ffsc_stack_ptr;
1397 !       ff_search_ctx->ffsc_stack_ptr = ctx;
1398       }
1399   }
1400   
1401   /*
1402 !  * pop a dir from the directory stack
1403 !  * returns NULL if stack is empty
1404    */
1405       static ff_stack_T *
1406 ! ff_pop()
1407   {
1408       ff_stack_T  *sptr;
1409   
1410 !     sptr = ff_search_ctx->ffsc_stack_ptr;
1411 !     if (ff_search_ctx->ffsc_stack_ptr != NULL)
1412 !       ff_search_ctx->ffsc_stack_ptr = ff_search_ctx->ffsc_stack_ptr->ffs_prev;
1413   
1414       return sptr;
1415   }
1416 --- 5115,5149 ----
1417   }
1418   
1419   /*
1420 !  * Push a dir on the directory stack.
1421    */
1422       static void
1423 ! ff_push(search_ctx, stack_ptr)
1424 !     ff_search_ctx_T *search_ctx;
1425 !     ff_stack_T            *stack_ptr;
1426   {
1427       /* check for NULL pointer, not to return an error to the user, but
1428        * to prevent a crash */
1429 !     if (stack_ptr != NULL)
1430       {
1431 !       stack_ptr->ffs_prev = search_ctx->ffsc_stack_ptr;
1432 !       search_ctx->ffsc_stack_ptr = stack_ptr;
1433       }
1434   }
1435   
1436   /*
1437 !  * Pop a dir from the directory stack.
1438 !  * Returns NULL if stack is empty.
1439    */
1440       static ff_stack_T *
1441 ! ff_pop(search_ctx)
1442 !     ff_search_ctx_T *search_ctx;
1443   {
1444       ff_stack_T  *sptr;
1445   
1446 !     sptr = search_ctx->ffsc_stack_ptr;
1447 !     if (search_ctx->ffsc_stack_ptr != NULL)
1448 !       search_ctx->ffsc_stack_ptr = search_ctx->ffsc_stack_ptr->ffs_prev;
1449   
1450       return sptr;
1451   }
1452 ***************
1453 *** 5138,5199 ****
1454    * free the given stack element
1455    */
1456       static void
1457 ! ff_free_stack_element(ctx)
1458 !     ff_stack_T  *ctx;
1459   {
1460       /* vim_free handles possible NULL pointers */
1461 !     vim_free(ctx->ffs_fix_path);
1462   #ifdef FEAT_PATH_EXTRA
1463 !     vim_free(ctx->ffs_wc_path);
1464   #endif
1465   
1466 !     if (ctx->ffs_filearray != NULL)
1467 !       FreeWild(ctx->ffs_filearray_size, ctx->ffs_filearray);
1468   
1469 !     vim_free(ctx);
1470   }
1471   
1472   /*
1473 !  * clear the search context
1474    */
1475       static void
1476 ! ff_clear()
1477   {
1478       ff_stack_T   *sptr;
1479   
1480       /* clear up stack */
1481 !     while ((sptr = ff_pop()) != NULL)
1482         ff_free_stack_element(sptr);
1483   
1484 !     vim_free(ff_search_ctx->ffsc_file_to_search);
1485 !     vim_free(ff_search_ctx->ffsc_start_dir);
1486 !     vim_free(ff_search_ctx->ffsc_fix_path);
1487   #ifdef FEAT_PATH_EXTRA
1488 !     vim_free(ff_search_ctx->ffsc_wc_path);
1489   #endif
1490   
1491   #ifdef FEAT_PATH_EXTRA
1492 !     if (ff_search_ctx->ffsc_stopdirs_v != NULL)
1493       {
1494         int  i = 0;
1495   
1496 !       while (ff_search_ctx->ffsc_stopdirs_v[i] != NULL)
1497         {
1498 !           vim_free(ff_search_ctx->ffsc_stopdirs_v[i]);
1499             i++;
1500         }
1501 !       vim_free(ff_search_ctx->ffsc_stopdirs_v);
1502       }
1503 !     ff_search_ctx->ffsc_stopdirs_v = NULL;
1504   #endif
1505   
1506       /* reset everything */
1507 !     ff_search_ctx->ffsc_file_to_search        = NULL;
1508 !     ff_search_ctx->ffsc_start_dir     = NULL;
1509 !     ff_search_ctx->ffsc_fix_path      = NULL;
1510   #ifdef FEAT_PATH_EXTRA
1511 !     ff_search_ctx->ffsc_wc_path               = NULL;
1512 !     ff_search_ctx->ffsc_level         = 0;
1513   #endif
1514   }
1515   
1516 --- 5152,5214 ----
1517    * free the given stack element
1518    */
1519       static void
1520 ! ff_free_stack_element(stack_ptr)
1521 !     ff_stack_T  *stack_ptr;
1522   {
1523       /* vim_free handles possible NULL pointers */
1524 !     vim_free(stack_ptr->ffs_fix_path);
1525   #ifdef FEAT_PATH_EXTRA
1526 !     vim_free(stack_ptr->ffs_wc_path);
1527   #endif
1528   
1529 !     if (stack_ptr->ffs_filearray != NULL)
1530 !       FreeWild(stack_ptr->ffs_filearray_size, stack_ptr->ffs_filearray);
1531   
1532 !     vim_free(stack_ptr);
1533   }
1534   
1535   /*
1536 !  * Clear the search context, but NOT the visited list.
1537    */
1538       static void
1539 ! ff_clear(search_ctx)
1540 !     ff_search_ctx_T *search_ctx;
1541   {
1542       ff_stack_T   *sptr;
1543   
1544       /* clear up stack */
1545 !     while ((sptr = ff_pop(search_ctx)) != NULL)
1546         ff_free_stack_element(sptr);
1547   
1548 !     vim_free(search_ctx->ffsc_file_to_search);
1549 !     vim_free(search_ctx->ffsc_start_dir);
1550 !     vim_free(search_ctx->ffsc_fix_path);
1551   #ifdef FEAT_PATH_EXTRA
1552 !     vim_free(search_ctx->ffsc_wc_path);
1553   #endif
1554   
1555   #ifdef FEAT_PATH_EXTRA
1556 !     if (search_ctx->ffsc_stopdirs_v != NULL)
1557       {
1558         int  i = 0;
1559   
1560 !       while (search_ctx->ffsc_stopdirs_v[i] != NULL)
1561         {
1562 !           vim_free(search_ctx->ffsc_stopdirs_v[i]);
1563             i++;
1564         }
1565 !       vim_free(search_ctx->ffsc_stopdirs_v);
1566       }
1567 !     search_ctx->ffsc_stopdirs_v = NULL;
1568   #endif
1569   
1570       /* reset everything */
1571 !     search_ctx->ffsc_file_to_search = NULL;
1572 !     search_ctx->ffsc_start_dir = NULL;
1573 !     search_ctx->ffsc_fix_path = NULL;
1574   #ifdef FEAT_PATH_EXTRA
1575 !     search_ctx->ffsc_wc_path = NULL;
1576 !     search_ctx->ffsc_level = 0;
1577   #endif
1578   }
1579   
1580 ***************
1581 *** 5242,5248 ****
1582   
1583   #if defined(FEAT_SEARCHPATH) || defined(PROTO)
1584   /*
1585 !  * Find the file name "ptr[len]" in the path.
1586    *
1587    * On the first call set the parameter 'first' to TRUE to initialize
1588    * the search.  For repeating calls to FALSE.
1589 --- 5257,5263 ----
1590   
1591   #if defined(FEAT_SEARCHPATH) || defined(PROTO)
1592   /*
1593 !  * Find the file name "ptr[len]" in the path.  Also finds directory names.
1594    *
1595    * On the first call set the parameter 'first' to TRUE to initialize
1596    * the search.  For repeating calls to FALSE.
1597 ***************
1598 *** 5276,5282 ****
1599   {
1600       return find_file_in_path_option(ptr, len, options, first,
1601             *curbuf->b_p_path == NUL ? p_path : curbuf->b_p_path,
1602 !           FALSE, rel_fname, curbuf->b_p_sua);
1603   }
1604   
1605   static char_u *ff_file_to_find = NULL;
1606 --- 5291,5297 ----
1607   {
1608       return find_file_in_path_option(ptr, len, options, first,
1609             *curbuf->b_p_path == NUL ? p_path : curbuf->b_p_path,
1610 !           FINDFILE_BOTH, rel_fname, curbuf->b_p_sua);
1611   }
1612   
1613   static char_u *ff_file_to_find = NULL;
1614 ***************
1615 *** 5309,5325 ****
1616       char_u    *rel_fname;     /* file name searching relative to */
1617   {
1618       return find_file_in_path_option(ptr, len, options, TRUE, p_cdpath,
1619 !                                              TRUE, rel_fname, (char_u *)"");
1620   }
1621   
1622       char_u *
1623 ! find_file_in_path_option(ptr, len, options, first, path_option, need_dir, rel_fname, suffixes)
1624       char_u    *ptr;           /* file name */
1625       int               len;            /* length of file name */
1626       int               options;
1627       int               first;          /* use count'th matching file name */
1628       char_u    *path_option;   /* p_path or p_cdpath */
1629 !     int               need_dir;       /* looking for directory name */
1630       char_u    *rel_fname;     /* file name we are looking relative to. */
1631       char_u    *suffixes;      /* list of suffixes, 'suffixesadd' option */
1632   {
1633 --- 5324,5340 ----
1634       char_u    *rel_fname;     /* file name searching relative to */
1635   {
1636       return find_file_in_path_option(ptr, len, options, TRUE, p_cdpath,
1637 !                                      FINDFILE_DIR, rel_fname, (char_u *)"");
1638   }
1639   
1640       char_u *
1641 ! find_file_in_path_option(ptr, len, options, first, path_option, find_what, rel_fname, suffixes)
1642       char_u    *ptr;           /* file name */
1643       int               len;            /* length of file name */
1644       int               options;
1645       int               first;          /* use count'th matching file name */
1646       char_u    *path_option;   /* p_path or p_cdpath */
1647 !     int               find_what;      /* FINDFILE_FILE, _DIR or _BOTH */
1648       char_u    *rel_fname;     /* file name we are looking relative to. */
1649       char_u    *suffixes;      /* list of suffixes, 'suffixesadd' option */
1650   {
1651 ***************
1652 *** 5421,5432 ****
1653   #ifdef DJGPP
1654                             /* "C:" by itself will fail for mch_getperm(),
1655                              * assume it's always valid. */
1656 !                           (need_dir && NameBuff[0] != NUL
1657                                   && NameBuff[1] == ':'
1658                                   && NameBuff[2] == NUL) ||
1659   #endif
1660                             (mch_getperm(NameBuff) >= 0
1661 !                                      && (!need_dir || mch_isdir(NameBuff))))
1662                     {
1663                         file_name = vim_strsave(NameBuff);
1664                         goto theend;
1665 --- 5436,5449 ----
1666   #ifdef DJGPP
1667                             /* "C:" by itself will fail for mch_getperm(),
1668                              * assume it's always valid. */
1669 !                           (find_what != FINDFILE_FILE && NameBuff[0] != NUL
1670                                   && NameBuff[1] == ':'
1671                                   && NameBuff[2] == NUL) ||
1672   #endif
1673                             (mch_getperm(NameBuff) >= 0
1674 !                            && (find_what == FINDFILE_BOTH
1675 !                                || ((find_what == FINDFILE_DIR)
1676 !                                                   == mch_isdir(NameBuff)))))
1677                     {
1678                         file_name = vim_strsave(NameBuff);
1679                         goto theend;
1680 ***************
1681 *** 5457,5465 ****
1682         {
1683             if (did_findfile_init)
1684             {
1685 -               ff_search_ctx->ffsc_need_dir = need_dir;
1686                 file_name = vim_findfile(fdip_search_ctx);
1687 -               ff_search_ctx->ffsc_need_dir = FALSE;
1688                 if (file_name != NULL)
1689                     break;
1690   
1691 --- 5474,5480 ----
1692 ***************
1693 *** 5492,5498 ****
1694                 r_ptr = NULL;
1695   #endif
1696                 fdip_search_ctx = vim_findfile_init(buf, ff_file_to_find,
1697 !                                           r_ptr, 100, FALSE, TRUE,
1698                                            fdip_search_ctx, FALSE, rel_fname);
1699                 if (fdip_search_ctx != NULL)
1700                     did_findfile_init = TRUE;
1701 --- 5507,5513 ----
1702                 r_ptr = NULL;
1703   #endif
1704                 fdip_search_ctx = vim_findfile_init(buf, ff_file_to_find,
1705 !                                           r_ptr, 100, FALSE, find_what,
1706                                            fdip_search_ctx, FALSE, rel_fname);
1707                 if (fdip_search_ctx != NULL)
1708                     did_findfile_init = TRUE;
1709 ***************
1710 *** 5504,5510 ****
1711       {
1712         if (first == TRUE)
1713         {
1714 !           if (need_dir)
1715                 EMSG2(_("E344: Can't find directory \"%s\" in cdpath"),
1716                         ff_file_to_find);
1717             else
1718 --- 5519,5525 ----
1719       {
1720         if (first == TRUE)
1721         {
1722 !           if (find_what == FINDFILE_DIR)
1723                 EMSG2(_("E344: Can't find directory \"%s\" in cdpath"),
1724                         ff_file_to_find);
1725             else
1726 ***************
1727 *** 5513,5519 ****
1728         }
1729         else
1730         {
1731 !           if (need_dir)
1732                 EMSG2(_("E346: No more directory \"%s\" found in cdpath"),
1733                         ff_file_to_find);
1734             else
1735 --- 5528,5534 ----
1736         }
1737         else
1738         {
1739 !           if (find_what == FINDFILE_DIR)
1740                 EMSG2(_("E346: No more directory \"%s\" found in cdpath"),
1741                         ff_file_to_find);
1742             else
1743 *** ../vim-7.1.255/src/vim.h    Sat Jan 19 15:55:51 2008
1744 --- src/vim.h   Tue Jan 22 22:35:16 2008
1745 ***************
1746 *** 721,726 ****
1747 --- 721,731 ----
1748   /* Note: mostly EW_NOTFOUND and EW_SILENT are mutually exclusive: EW_NOTFOUND
1749    * is used when executing commands and EW_SILENT for interactive expanding. */
1750   
1751 + /* Flags for find_file_*() functions. */
1752 + #define FINDFILE_FILE 0       /* only files */
1753 + #define FINDFILE_DIR  1       /* only directories */
1754 + #define FINDFILE_BOTH 2       /* files and directories */
1755
1756   #ifdef FEAT_VERTSPLIT
1757   # define W_WINCOL(wp) (wp->w_wincol)
1758   # define W_WIDTH(wp)  (wp->w_width)
1759 *** ../vim-7.1.255/src/tag.c    Sat Jan 19 15:55:51 2008
1760 --- src/tag.c   Wed Feb 13 18:02:32 2008
1761 ***************
1762 *** 2669,2676 ****
1763   
1764             tnp->tn_search_ctx = vim_findfile_init(buf, filename,
1765                     r_ptr, 100,
1766 !                   FALSE, /* don't free visited list */
1767 !                   FALSE, /* we search for a file */
1768                     tnp->tn_search_ctx, TRUE, curbuf->b_ffname);
1769             if (tnp->tn_search_ctx != NULL)
1770                 tnp->tn_did_filefind_init = TRUE;
1771 --- 2669,2676 ----
1772   
1773             tnp->tn_search_ctx = vim_findfile_init(buf, filename,
1774                     r_ptr, 100,
1775 !                   FALSE,         /* don't free visited list */
1776 !                   FINDFILE_FILE, /* we search for a file */
1777                     tnp->tn_search_ctx, TRUE, curbuf->b_ffname);
1778             if (tnp->tn_search_ctx != NULL)
1779                 tnp->tn_did_filefind_init = TRUE;
1780 ***************
1781 *** 2691,2696 ****
1782 --- 2691,2697 ----
1783   {
1784       vim_free(tnp->tn_tags);
1785       vim_findfile_cleanup(tnp->tn_search_ctx);
1786 +     tnp->tn_search_ctx = NULL;
1787       ga_clear_strings(&tag_fnames);
1788   }
1789   
1790 *** ../vim-7.1.255/src/version.c        Wed Feb 20 11:27:59 2008
1791 --- src/version.c       Wed Feb 20 12:09:54 2008
1792 ***************
1793 *** 668,669 ****
1794 --- 668,671 ----
1795   {   /* Add new patch number below this line */
1796 + /**/
1797 +     256,
1798   /**/
1799
1800 -- 
1801 hundred-and-one symptoms of being an internet addict:
1802 38. You wake up at 3 a.m. to go to the bathroom and stop and check your e-mail
1803     on the way back to bed.
1804
1805  /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
1806 ///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
1807 \\\        download, build and distribute -- http://www.A-A-P.org        ///
1808  \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///
This page took 0.159342 seconds and 3 git commands to generate.