4 From: Bram Moolenaar <Bram@moolenaar.net>
6 Content-Type: text/plain; charset=ISO-8859-1
7 Content-Transfer-Encoding: 8bit
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
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
21 rettv->vval.v_number = filewritable(get_tv_string(&argvars[0]));
24 ! static void findfilendir __ARGS((typval_T *argvars, typval_T *rettv, int dir));
27 ! findfilendir(argvars, rettv, dir)
32 #ifdef FEAT_SEARCHPATH
35 rettv->vval.v_number = filewritable(get_tv_string(&argvars[0]));
38 ! static void findfilendir __ARGS((typval_T *argvars, typval_T *rettv, int find_what));
41 ! findfilendir(argvars, rettv, find_what)
46 #ifdef FEAT_SEARCHPATH
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);
57 if (fresult != NULL && rettv->v_type == VAR_LIST)
60 fresult = find_file_in_path_option(first ? fname : NULL,
61 first ? (int)STRLEN(fname) : 0,
65 ! find_what == FINDFILE_DIR
66 ! ? (char_u *)"" : curbuf->b_p_sua);
69 if (fresult != NULL && rettv->v_type == VAR_LIST)
75 ! findfilendir(argvars, rettv, TRUE);
83 ! findfilendir(argvars, rettv, FINDFILE_DIR);
92 ! findfilendir(argvars, rettv, FALSE);
100 ! findfilendir(argvars, rettv, FINDFILE_FILE);
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
108 char_u ffs_filearray_cur; /* needed for partly handled dirs */
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
116 /* How deep are we in the directory tree?
118 char_u ffs_filearray_cur; /* needed for partly handled dirs */
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
126 /* How deep are we in the directory tree?
130 * Set the default maximum depth.
132 #define FF_MAX_STAR_STAR_EXPAND ((char_u)30)
135 * The search context:
136 * ffsc_stack_ptr: the stack for the dirs to search
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
144 typedef struct ff_search_ctx_T
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
152 typedef struct ff_search_ctx_T
157 char_u **ffsc_stopdirs_v;
162 - static ff_search_ctx_T *ff_search_ctx = NULL;
164 /* locally needed functions */
165 #ifdef FEAT_PATH_EXTRA
166 static int ff_check_visited __ARGS((ff_visited_T **, char_u *, char_u *));
169 char_u **ffsc_stopdirs_v;
171 ! int ffsc_find_what;
174 /* locally needed functions */
175 #ifdef FEAT_PATH_EXTRA
176 static int ff_check_visited __ARGS((ff_visited_T **, char_u *, char_u *));
179 static int ff_wc_equal __ARGS((char_u *s1, char_u *s2));
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));
190 static int ff_wc_equal __ARGS((char_u *s1, char_u *s2));
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));
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.
206 + * 'filename' cannot contain wildcards! It is used as-is, no backslashes to
207 + * escape special characters.
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
214 * The list of visited files/dirs can also be cleared with the function
215 * vim_findfile_free_visited().
217 ! * Set the parameter 'need_dir' to TRUE if you want to search for a directory
218 ! * instead of a file.
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.
227 ! * If you don't have a search context from a previous call 'search_ctx' must be
230 * This function silently ignores a few errors, vim_findfile() will have
231 * limited functionality then.
235 ! vim_findfile_init(path, filename, stopdirs, level, free_visited, need_dir,
236 ! search_ctx, tagfile, rel_fname)
245 char_u *rel_fname; /* file name to use for "." */
247 #ifdef FEAT_PATH_EXTRA
252 /* If a search context is given by the caller, reuse it, else allocate a
255 ! if (search_ctx != NULL)
256 ! ff_search_ctx = search_ctx;
259 ! ff_search_ctx = (ff_search_ctx_T*)alloc(
260 ! (unsigned)sizeof(ff_search_ctx_T));
261 ! if (ff_search_ctx == NULL)
263 ! memset(ff_search_ctx, 0, sizeof(ff_search_ctx_T));
266 /* clear the search context, but NOT the visited lists */
269 /* clear visited list if wanted */
270 if (free_visited == TRUE)
271 ! vim_findfile_free_visited(ff_search_ctx);
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
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)
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)
289 * The list of visited files/dirs can also be cleared with the function
290 * vim_findfile_free_visited().
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.
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.
302 ! * If you don't have a search context from a previous call "search_ctx_arg"
305 * This function silently ignores a few errors, vim_findfile() will have
306 * limited functionality then.
310 ! vim_findfile_init(path, filename, stopdirs, level, free_visited, find_what,
311 ! search_ctx_arg, tagfile, rel_fname)
318 ! void *search_ctx_arg;
320 char_u *rel_fname; /* file name to use for "." */
322 #ifdef FEAT_PATH_EXTRA
326 ! ff_search_ctx_T *search_ctx;
328 /* If a search context is given by the caller, reuse it, else allocate a
331 ! if (search_ctx_arg != NULL)
332 ! search_ctx = search_ctx_arg;
335 ! search_ctx = (ff_search_ctx_T*)alloc((unsigned)sizeof(ff_search_ctx_T));
336 ! if (search_ctx == NULL)
338 ! memset(search_ctx, 0, sizeof(ff_search_ctx_T));
340 + search_ctx->ffsc_find_what = find_what;
342 /* clear the search context, but NOT the visited lists */
343 ! ff_clear(search_ctx);
345 /* clear visited list if wanted */
346 if (free_visited == TRUE)
347 ! vim_findfile_free_visited(search_ctx);
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
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)
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)
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,
372 ! ff_search_ctx->ffsc_start_dir = vim_strnsave(rel_fname, len);
373 ! if (ff_search_ctx->ffsc_start_dir == NULL)
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);
384 ! search_ctx->ffsc_start_dir = vim_strnsave(rel_fname, len);
385 ! if (search_ctx->ffsc_start_dir == NULL)
391 if (mch_dirname(ff_expand_buffer, MAXPATHL) == FAIL)
394 ! ff_search_ctx->ffsc_start_dir = vim_strsave(ff_expand_buffer);
395 ! if (ff_search_ctx->ffsc_start_dir == NULL)
398 #ifdef BACKSLASH_IN_FILENAME
400 if (mch_dirname(ff_expand_buffer, MAXPATHL) == FAIL)
403 ! search_ctx->ffsc_start_dir = vim_strsave(ff_expand_buffer);
404 ! if (search_ctx->ffsc_start_dir == NULL)
407 #ifdef BACKSLASH_IN_FILENAME
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;
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;
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.
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.
449 ! ff_search_ctx->ffsc_stopdirs_v =
450 ! (char_u **)alloc((unsigned)sizeof(char_u *));
452 ! if (ff_search_ctx->ffsc_stopdirs_v != NULL)
460 ! search_ctx->ffsc_stopdirs_v =
461 ! (char_u **)alloc((unsigned)sizeof(char_u *));
463 ! if (search_ctx->ffsc_stopdirs_v != NULL)
472 ! ptr = vim_realloc(ff_search_ctx->ffsc_stopdirs_v,
473 (dircount + 1) * sizeof(char_u *));
475 ! ff_search_ctx->ffsc_stopdirs_v = ptr;
477 /* ignore, keep what we have and continue */
479 walker = vim_strchr(walker, ';');
482 ! ff_search_ctx->ffsc_stopdirs_v[dircount-1] =
483 ! vim_strnsave(helper, (int)(walker - helper));
487 /* this might be "", which means ascent till top
490 ! ff_search_ctx->ffsc_stopdirs_v[dircount-1] =
491 ! vim_strsave(helper);
495 } while (walker != NULL);
496 ! ff_search_ctx->ffsc_stopdirs_v[dircount-1] = NULL;
501 #ifdef FEAT_PATH_EXTRA
502 ! ff_search_ctx->ffsc_level = level;
510 ! ptr = vim_realloc(search_ctx->ffsc_stopdirs_v,
511 (dircount + 1) * sizeof(char_u *));
513 ! search_ctx->ffsc_stopdirs_v = ptr;
515 /* ignore, keep what we have and continue */
517 walker = vim_strchr(walker, ';');
520 ! search_ctx->ffsc_stopdirs_v[dircount-1] =
521 ! vim_strnsave(helper, (int)(walker - helper));
525 /* this might be "", which means ascent till top
528 ! search_ctx->ffsc_stopdirs_v[dircount-1] =
529 ! vim_strsave(helper);
533 } while (walker != NULL);
534 ! search_ctx->ffsc_stopdirs_v[dircount-1] = NULL;
539 #ifdef FEAT_PATH_EXTRA
540 ! search_ctx->ffsc_level = level;
548 /* save the fix part of the path */
549 ! ff_search_ctx->ffsc_fix_path = vim_strnsave(path,
550 ! (int)(wc_part - path));
553 * copy wc_path and add restricts to the '**' wildcard.
557 /* save the fix part of the path */
558 ! search_ctx->ffsc_fix_path = vim_strnsave(path, (int)(wc_part - path));
561 * copy wc_path and add restricts to the '**' wildcard.
564 ff_expand_buffer[len++] = *wc_part++;
566 ff_expand_buffer[len] = NUL;
567 ! ff_search_ctx->ffsc_wc_path = vim_strsave(ff_expand_buffer);
569 ! if (ff_search_ctx->ffsc_wc_path == NULL)
574 ! ff_search_ctx->ffsc_fix_path = vim_strsave(path);
576 ! if (ff_search_ctx->ffsc_start_dir == NULL)
578 /* store the fix part as startdir.
579 * This is needed if the parameter path is fully qualified.
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;
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);
592 sptr = ff_create_stack_element(ff_expand_buffer,
593 #ifdef FEAT_PATH_EXTRA
594 ! ff_search_ctx->ffsc_wc_path,
603 ! ff_search_ctx->ffsc_file_to_search = vim_strsave(filename);
604 ! if (ff_search_ctx->ffsc_file_to_search == NULL)
607 ! return ff_search_ctx;
612 ff_expand_buffer[len++] = *wc_part++;
614 ff_expand_buffer[len] = NUL;
615 ! search_ctx->ffsc_wc_path = vim_strsave(ff_expand_buffer);
617 ! if (search_ctx->ffsc_wc_path == NULL)
622 ! search_ctx->ffsc_fix_path = vim_strsave(path);
624 ! if (search_ctx->ffsc_start_dir == NULL)
626 /* store the fix part as startdir.
627 * This is needed if the parameter path is fully qualified.
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;
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);
640 sptr = ff_create_stack_element(ff_expand_buffer,
641 #ifdef FEAT_PATH_EXTRA
642 ! search_ctx->ffsc_wc_path,
649 ! ff_push(search_ctx, sptr);
651 ! search_ctx->ffsc_file_to_search = vim_strsave(filename);
652 ! if (search_ctx->ffsc_file_to_search == NULL)
661 * Even when the caller gave us a (perhaps valid) context we free it here,
662 * as we might have already destroyed it.
664 ! vim_findfile_cleanup(ff_search_ctx);
669 * Even when the caller gave us a (perhaps valid) context we free it here,
670 * as we might have already destroyed it.
672 ! vim_findfile_cleanup(search_ctx);
681 ! /* Clean up the given search context. Can handle a NULL pointer */
683 vim_findfile_cleanup(ctx)
690 ! * Clean up the given search context. Can handle a NULL pointer.
693 vim_findfile_cleanup(ctx)
700 - ff_search_ctx = ctx;
702 vim_findfile_free_visited(ctx);
705 - ff_search_ctx = NULL;
713 vim_findfile_free_visited(ctx);
724 ! vim_findfile(search_ctx)
728 #ifdef FEAT_PATH_EXTRA
729 char_u *rest_of_wildcards;
730 char_u *path_end = NULL;
733 #if defined(FEAT_SEARCHPATH) || defined(FEAT_PATH_EXTRA)
740 ! vim_findfile(search_ctx_arg)
741 ! void *search_ctx_arg;
744 #ifdef FEAT_PATH_EXTRA
745 char_u *rest_of_wildcards;
746 char_u *path_end = NULL;
748 ! ff_stack_T *stackp;
749 #if defined(FEAT_SEARCHPATH) || defined(FEAT_PATH_EXTRA)
754 #ifdef FEAT_SEARCHPATH
758 ! if (search_ctx == NULL)
761 ! ff_search_ctx = (ff_search_ctx_T*)search_ctx;
764 * filepath is used as buffer for various actions and as the storage to
766 #ifdef FEAT_SEARCHPATH
769 + ff_search_ctx_T *search_ctx;
771 ! if (search_ctx_arg == NULL)
774 ! search_ctx = (ff_search_ctx_T *)search_ctx_arg;
777 * filepath is used as buffer for various actions and as the storage to
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)];
787 #ifdef FEAT_PATH_EXTRA
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)];
797 #ifdef FEAT_PATH_EXTRA
802 /* get directory to work on from stack */
811 /* get directory to work on from stack */
812 ! stackp = ff_pop(search_ctx);
813 ! if (stackp == NULL)
819 * /etc/rc.d/init.d is linked to /etc/rc.d -> endless loop)
821 * This check is only needed for directories we work on for the
822 ! * first time (hence ctx->ff_filearray == NULL)
824 ! if (ctx->ffs_filearray == NULL
825 ! && ff_check_visited(&ff_search_ctx->ffsc_dir_visited_list
828 #ifdef FEAT_PATH_EXTRA
834 * /etc/rc.d/init.d is linked to /etc/rc.d -> endless loop)
836 * This check is only needed for directories we work on for the
837 ! * first time (hence stackp->ff_filearray == NULL)
839 ! if (stackp->ffs_filearray == NULL
840 ! && ff_check_visited(&search_ctx->ffsc_dir_visited_list
842 ! stackp->ffs_fix_path
843 #ifdef FEAT_PATH_EXTRA
844 ! , stackp->ffs_wc_path
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();
859 ! ff_free_stack_element(ctx);
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();
873 ! ff_free_stack_element(stackp);
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();
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();
899 ! if (ctx->ffs_level <= 0)
901 ! ff_free_stack_element(ctx);
909 ! if (stackp->ffs_level <= 0)
911 ! ff_free_stack_element(stackp);
917 * and all possible expands are returned in one array. We use this
918 * to handle the expansion of '**' into an empty string.
920 ! if (ctx->ffs_filearray == NULL)
925 * and all possible expands are returned in one array. We use this
926 * to handle the expansion of '**' into an empty string.
928 ! if (stackp->ffs_filearray == NULL)
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)
940 ! STRCPY(file_path, ff_search_ctx->ffsc_start_dir);
941 add_pathsep(file_path);
944 /* append the fix part of the search path */
945 ! STRCAT(file_path, ctx->ffs_fix_path);
946 add_pathsep(file_path);
948 #ifdef FEAT_PATH_EXTRA
949 ! rest_of_wildcards = ctx->ffs_wc_path;
950 if (*rest_of_wildcards != NUL)
952 len = (int)STRLEN(file_path);
956 /* if we have a start dir copy it in */
957 ! if (!vim_isAbsName(stackp->ffs_fix_path)
958 ! && search_ctx->ffsc_start_dir)
960 ! STRCPY(file_path, search_ctx->ffsc_start_dir);
961 add_pathsep(file_path);
964 /* append the fix part of the search path */
965 ! STRCAT(file_path, stackp->ffs_fix_path);
966 add_pathsep(file_path);
968 #ifdef FEAT_PATH_EXTRA
969 ! rest_of_wildcards = stackp->ffs_wc_path;
970 if (*rest_of_wildcards != NUL)
972 len = (int)STRLEN(file_path);
976 rest_of_wildcards += 3;
978 ! if (ctx->ffs_star_star_empty == 0)
980 /* if not done before, expand '**' to empty */
981 ! ctx->ffs_star_star_empty = 1;
982 ! dirptrs[1] = ctx->ffs_fix_path;
988 rest_of_wildcards += 3;
990 ! if (stackp->ffs_star_star_empty == 0)
992 /* if not done before, expand '**' to empty */
993 ! stackp->ffs_star_star_empty = 1;
994 ! dirptrs[1] = stackp->ffs_fix_path;
1001 if (path_with_url(dirptrs[0]))
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;
1010 ! ctx->ffs_filearray_size = 0;
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);
1018 ! ctx->ffs_filearray_cur = 0;
1019 ! ctx->ffs_stage = 0;
1021 #ifdef FEAT_PATH_EXTRA
1023 ! rest_of_wildcards = &ctx->ffs_wc_path[STRLEN(ctx->ffs_wc_path)];
1026 ! if (ctx->ffs_stage == 0)
1028 /* this is the first time we work on this directory */
1029 #ifdef FEAT_PATH_EXTRA
1032 if (path_with_url(dirptrs[0]))
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;
1041 ! stackp->ffs_filearray_size = 0;
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);
1049 ! stackp->ffs_filearray_cur = 0;
1050 ! stackp->ffs_stage = 0;
1052 #ifdef FEAT_PATH_EXTRA
1054 ! rest_of_wildcards = &stackp->ffs_wc_path[
1055 ! STRLEN(stackp->ffs_wc_path)];
1058 ! if (stackp->ffs_stage == 0)
1060 /* this is the first time we work on this directory */
1061 #ifdef FEAT_PATH_EXTRA
1064 * we don't have further wildcards to expand, so we have to
1065 * check for the final file now
1067 ! for (i = ctx->ffs_filearray_cur;
1068 ! i < ctx->ffs_filearray_size; ++i)
1070 ! if (!path_with_url(ctx->ffs_filearray[i])
1071 ! && !mch_isdir(ctx->ffs_filearray[i]))
1072 continue; /* not a directory */
1074 /* prepare the filename to be checked for existance
1076 ! STRCPY(file_path, ctx->ffs_filearray[i]);
1077 add_pathsep(file_path);
1078 ! STRCAT(file_path, ff_search_ctx->ffsc_file_to_search);
1081 * Try without extra suffix and then with suffixes
1083 * we don't have further wildcards to expand, so we have to
1084 * check for the final file now
1086 ! for (i = stackp->ffs_filearray_cur;
1087 ! i < stackp->ffs_filearray_size; ++i)
1089 ! if (!path_with_url(stackp->ffs_filearray[i])
1090 ! && !mch_isdir(stackp->ffs_filearray[i]))
1091 continue; /* not a directory */
1093 /* prepare the filename to be checked for existance
1095 ! STRCPY(file_path, stackp->ffs_filearray[i]);
1096 add_pathsep(file_path);
1097 ! STRCAT(file_path, search_ctx->ffsc_file_to_search);
1100 * Try without extra suffix and then with suffixes
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))))
1110 && (ff_check_visited(
1111 ! &ff_search_ctx->ffsc_visited_list->ffvl_visited_list,
1113 #ifdef FEAT_PATH_EXTRA
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
1122 ! || ((search_ctx->ffsc_find_what
1124 ! == mch_isdir(file_path)))))
1126 && (ff_check_visited(
1127 ! &search_ctx->ffsc_visited_list->ffvl_visited_list,
1129 #ifdef FEAT_PATH_EXTRA
1135 if (ff_check_visited(
1136 ! &ff_search_ctx->ffsc_visited_list->ffvl_visited_list,
1138 #ifdef FEAT_PATH_EXTRA
1143 if (ff_check_visited(
1144 ! &search_ctx->ffsc_visited_list->ffvl_visited_list,
1146 #ifdef FEAT_PATH_EXTRA
1152 /* push dir to examine rest of subdirs later */
1153 ! ctx->ffs_filearray_cur = i + 1;
1156 simplify_filename(file_path);
1157 if (mch_dirname(ff_expand_buffer, MAXPATHL)
1161 /* push dir to examine rest of subdirs later */
1162 ! stackp->ffs_filearray_cur = i + 1;
1163 ! ff_push(search_ctx, stackp);
1165 simplify_filename(file_path);
1166 if (mch_dirname(ff_expand_buffer, MAXPATHL)
1169 * still wildcards left, push the directories for further
1172 ! for (i = ctx->ffs_filearray_cur;
1173 ! i < ctx->ffs_filearray_size; ++i)
1175 ! if (!mch_isdir(ctx->ffs_filearray[i]))
1176 continue; /* not a directory */
1178 ! ff_push(ff_create_stack_element(ctx->ffs_filearray[i],
1179 ! rest_of_wildcards, ctx->ffs_level - 1, 0));
1183 ! ctx->ffs_filearray_cur = 0;
1184 ! ctx->ffs_stage = 1;
1187 #ifdef FEAT_PATH_EXTRA
1189 * still wildcards left, push the directories for further
1192 ! for (i = stackp->ffs_filearray_cur;
1193 ! i < stackp->ffs_filearray_size; ++i)
1195 ! if (!mch_isdir(stackp->ffs_filearray[i]))
1196 continue; /* not a directory */
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));
1206 ! stackp->ffs_filearray_cur = 0;
1207 ! stackp->ffs_stage = 1;
1210 #ifdef FEAT_PATH_EXTRA
1213 * if wildcards contains '**' we have to descent till we reach the
1214 * leaves of the directory tree.
1216 ! if (STRNCMP(ctx->ffs_wc_path, "**", 2) == 0)
1218 ! for (i = ctx->ffs_filearray_cur;
1219 ! i < ctx->ffs_filearray_size; ++i)
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));
1231 /* we are done with the current directory */
1232 ! ff_free_stack_element(ctx);
1237 * if wildcards contains '**' we have to descent till we reach the
1238 * leaves of the directory tree.
1240 ! if (STRNCMP(stackp->ffs_wc_path, "**", 2) == 0)
1242 ! for (i = stackp->ffs_filearray_cur;
1243 ! i < stackp->ffs_filearray_size; ++i)
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));
1257 /* we are done with the current directory */
1258 ! ff_free_stack_element(stackp);
1264 /* If we reached this, we didn't find anything downwards.
1265 * Let's check if we should do an upward search.
1267 ! if (ff_search_ctx->ffsc_start_dir
1268 ! && ff_search_ctx->ffsc_stopdirs_v != NULL && !got_int)
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)
1278 /* cut of last dir */
1279 ! while (path_end > ff_search_ctx->ffsc_start_dir
1280 ! && vim_ispathsep(*path_end))
1282 ! while (path_end > ff_search_ctx->ffsc_start_dir
1283 ! && !vim_ispathsep(path_end[-1]))
1288 ! if (*ff_search_ctx->ffsc_start_dir == 0)
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);
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);
1305 /* If we reached this, we didn't find anything downwards.
1306 * Let's check if we should do an upward search.
1308 ! if (search_ctx->ffsc_start_dir
1309 ! && search_ctx->ffsc_stopdirs_v != NULL && !got_int)
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)
1319 /* cut of last dir */
1320 ! while (path_end > search_ctx->ffsc_start_dir
1321 ! && vim_ispathsep(*path_end))
1323 ! while (path_end > search_ctx->ffsc_start_dir
1324 ! && !vim_ispathsep(path_end[-1]))
1329 ! if (*search_ctx->ffsc_start_dir == 0)
1332 ! STRCPY(file_path, search_ctx->ffsc_start_dir);
1333 add_pathsep(file_path);
1334 ! STRCAT(file_path, search_ctx->ffsc_fix_path);
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);
1341 ! ff_push(search_ctx, sptr);
1347 * Can handle it if the passed search_context is NULL;
1350 ! vim_findfile_free_visited(search_ctx)
1353 ! if (search_ctx == NULL)
1356 ! ff_search_ctx = (ff_search_ctx_T *)search_ctx;
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);
1364 * Can handle it if the passed search_context is NULL;
1367 ! vim_findfile_free_visited(search_ctx_arg)
1368 ! void *search_ctx_arg;
1370 ! ff_search_ctx_T *search_ctx;
1372 ! if (search_ctx_arg == NULL)
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);
1386 ! * push a dir on the directory stack
1392 /* check for NULL pointer, not to return an error to the user, but
1393 * to prevent a crash */
1396 ! ctx->ffs_prev = ff_search_ctx->ffsc_stack_ptr;
1397 ! ff_search_ctx->ffsc_stack_ptr = ctx;
1402 ! * pop a dir from the directory stack
1403 ! * returns NULL if stack is empty
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;
1420 ! * Push a dir on the directory stack.
1423 ! ff_push(search_ctx, stack_ptr)
1424 ! ff_search_ctx_T *search_ctx;
1425 ! ff_stack_T *stack_ptr;
1427 /* check for NULL pointer, not to return an error to the user, but
1428 * to prevent a crash */
1429 ! if (stack_ptr != NULL)
1431 ! stack_ptr->ffs_prev = search_ctx->ffsc_stack_ptr;
1432 ! search_ctx->ffsc_stack_ptr = stack_ptr;
1437 ! * Pop a dir from the directory stack.
1438 ! * Returns NULL if stack is empty.
1441 ! ff_pop(search_ctx)
1442 ! ff_search_ctx_T *search_ctx;
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;
1454 * free the given stack element
1457 ! ff_free_stack_element(ctx)
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);
1466 ! if (ctx->ffs_filearray != NULL)
1467 ! FreeWild(ctx->ffs_filearray_size, ctx->ffs_filearray);
1473 ! * clear the search context
1480 /* clear up stack */
1481 ! while ((sptr = ff_pop()) != NULL)
1482 ff_free_stack_element(sptr);
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);
1491 #ifdef FEAT_PATH_EXTRA
1492 ! if (ff_search_ctx->ffsc_stopdirs_v != NULL)
1496 ! while (ff_search_ctx->ffsc_stopdirs_v[i] != NULL)
1498 ! vim_free(ff_search_ctx->ffsc_stopdirs_v[i]);
1501 ! vim_free(ff_search_ctx->ffsc_stopdirs_v);
1503 ! ff_search_ctx->ffsc_stopdirs_v = NULL;
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;
1517 * free the given stack element
1520 ! ff_free_stack_element(stack_ptr)
1521 ! ff_stack_T *stack_ptr;
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);
1529 ! if (stack_ptr->ffs_filearray != NULL)
1530 ! FreeWild(stack_ptr->ffs_filearray_size, stack_ptr->ffs_filearray);
1532 ! vim_free(stack_ptr);
1536 ! * Clear the search context, but NOT the visited list.
1539 ! ff_clear(search_ctx)
1540 ! ff_search_ctx_T *search_ctx;
1544 /* clear up stack */
1545 ! while ((sptr = ff_pop(search_ctx)) != NULL)
1546 ff_free_stack_element(sptr);
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);
1555 #ifdef FEAT_PATH_EXTRA
1556 ! if (search_ctx->ffsc_stopdirs_v != NULL)
1560 ! while (search_ctx->ffsc_stopdirs_v[i] != NULL)
1562 ! vim_free(search_ctx->ffsc_stopdirs_v[i]);
1565 ! vim_free(search_ctx->ffsc_stopdirs_v);
1567 ! search_ctx->ffsc_stopdirs_v = NULL;
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;
1583 #if defined(FEAT_SEARCHPATH) || defined(PROTO)
1585 ! * Find the file name "ptr[len]" in the path.
1587 * On the first call set the parameter 'first' to TRUE to initialize
1588 * the search. For repeating calls to FALSE.
1591 #if defined(FEAT_SEARCHPATH) || defined(PROTO)
1593 ! * Find the file name "ptr[len]" in the path. Also finds directory names.
1595 * On the first call set the parameter 'first' to TRUE to initialize
1596 * the search. For repeating calls to FALSE.
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);
1605 static char_u *ff_file_to_find = NULL;
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);
1613 static char_u *ff_file_to_find = NULL;
1616 char_u *rel_fname; /* file name searching relative to */
1618 return find_file_in_path_option(ptr, len, options, TRUE, p_cdpath,
1619 ! TRUE, rel_fname, (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 */
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 */
1634 char_u *rel_fname; /* file name searching relative to */
1636 return find_file_in_path_option(ptr, len, options, TRUE, p_cdpath,
1637 ! FINDFILE_DIR, rel_fname, (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 */
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 */
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) ||
1660 (mch_getperm(NameBuff) >= 0
1661 ! && (!need_dir || mch_isdir(NameBuff))))
1663 file_name = vim_strsave(NameBuff);
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) ||
1673 (mch_getperm(NameBuff) >= 0
1674 ! && (find_what == FINDFILE_BOTH
1675 ! || ((find_what == FINDFILE_DIR)
1676 ! == mch_isdir(NameBuff)))))
1678 file_name = vim_strsave(NameBuff);
1683 if (did_findfile_init)
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)
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;
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;
1715 EMSG2(_("E344: Can't find directory \"%s\" in cdpath"),
1722 ! if (find_what == FINDFILE_DIR)
1723 EMSG2(_("E344: Can't find directory \"%s\" in cdpath"),
1732 EMSG2(_("E346: No more directory \"%s\" found in cdpath"),
1739 ! if (find_what == FINDFILE_DIR)
1740 EMSG2(_("E346: No more directory \"%s\" found in cdpath"),
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
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. */
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 */
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
1764 tnp->tn_search_ctx = vim_findfile_init(buf, filename,
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;
1773 tnp->tn_search_ctx = vim_findfile_init(buf, filename,
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;
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);
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
1795 { /* Add new patch number below this line */
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.
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 ///