xref: /vim-8.2.3635/src/tag.c (revision ed37d9b3)
1 /* vi:set ts=8 sts=4 sw=4 noet:
2  *
3  * VIM - Vi IMproved	by Bram Moolenaar
4  *
5  * Do ":help uganda"  in Vim to read copying and usage conditions.
6  * Do ":help credits" in Vim to see a list of people who contributed.
7  * See README.txt for an overview of the Vim source code.
8  */
9 
10 /*
11  * Code to handle tags and the tag stack
12  */
13 
14 #include "vim.h"
15 
16 /*
17  * Structure to hold pointers to various items in a tag line.
18  */
19 typedef struct tag_pointers
20 {
21     // filled in by parse_tag_line():
22     char_u	*tagname;	// start of tag name (skip "file:")
23     char_u	*tagname_end;	// char after tag name
24     char_u	*fname;		// first char of file name
25     char_u	*fname_end;	// char after file name
26     char_u	*command;	// first char of command
27     // filled in by parse_match():
28     char_u	*command_end;	// first char after command
29     char_u	*tag_fname;	// file name of the tags file. This is used
30 				// when 'tr' is set.
31 #ifdef FEAT_EMACS_TAGS
32     int		is_etag;	// TRUE for emacs tag
33 #endif
34     char_u	*tagkind;	// "kind:" value
35     char_u	*tagkind_end;	// end of tagkind
36     char_u	*user_data;	// user_data string
37     char_u	*user_data_end;	// end of user_data
38     linenr_T	tagline;	// "line:" value
39 } tagptrs_T;
40 
41 /*
42  * The matching tags are first stored in one of the hash tables.  In
43  * which one depends on the priority of the match.
44  * ht_match[] is used to find duplicates, ga_match[] to keep them in sequence.
45  * At the end, all the matches from ga_match[] are concatenated, to make a list
46  * sorted on priority.
47  */
48 #define MT_ST_CUR	0		// static match in current file
49 #define MT_GL_CUR	1		// global match in current file
50 #define MT_GL_OTH	2		// global match in other file
51 #define MT_ST_OTH	3		// static match in other file
52 #define MT_IC_OFF	4		// add for icase match
53 #define MT_RE_OFF	8		// add for regexp match
54 #define MT_MASK		7		// mask for printing priority
55 #define MT_COUNT	16
56 
57 static char	*mt_names[MT_COUNT/2] =
58 		{"FSC", "F C", "F  ", "FS ", " SC", "  C", "   ", " S "};
59 
60 #define NOTAGFILE	99		// return value for jumpto_tag
61 static char_u	*nofile_fname = NULL;	// fname for NOTAGFILE error
62 
63 static void taglen_advance(int l);
64 
65 static int jumpto_tag(char_u *lbuf, int forceit, int keep_help);
66 #ifdef FEAT_EMACS_TAGS
67 static int parse_tag_line(char_u *lbuf, int is_etag, tagptrs_T *tagp);
68 #else
69 static int parse_tag_line(char_u *lbuf, tagptrs_T *tagp);
70 #endif
71 static int test_for_static(tagptrs_T *);
72 static int parse_match(char_u *lbuf, tagptrs_T *tagp);
73 static char_u *tag_full_fname(tagptrs_T *tagp);
74 static char_u *expand_tag_fname(char_u *fname, char_u *tag_fname, int expand);
75 #ifdef FEAT_EMACS_TAGS
76 static int test_for_current(int, char_u *, char_u *, char_u *, char_u *);
77 #else
78 static int test_for_current(char_u *, char_u *, char_u *, char_u *);
79 #endif
80 static int find_extra(char_u **pp);
81 static void print_tag_list(int new_tag, int use_tagstack, int num_matches, char_u **matches);
82 #if defined(FEAT_QUICKFIX) && defined(FEAT_EVAL)
83 static int add_llist_tags(char_u *tag, int num_matches, char_u **matches);
84 #endif
85 static void tagstack_clear_entry(taggy_T *item);
86 
87 static char_u *bottommsg = (char_u *)N_("E555: at bottom of tag stack");
88 static char_u *topmsg = (char_u *)N_("E556: at top of tag stack");
89 #ifdef FEAT_EVAL
90 static char_u *recurmsg = (char_u *)N_("E986: cannot modify the tag stack within tagfunc");
91 static char_u *tfu_inv_ret_msg = (char_u *)N_("E987: invalid return value from tagfunc");
92 #endif
93 
94 static char_u	*tagmatchname = NULL;	// name of last used tag
95 
96 #if defined(FEAT_QUICKFIX)
97 /*
98  * Tag for preview window is remembered separately, to avoid messing up the
99  * normal tagstack.
100  */
101 static taggy_T ptag_entry = {NULL, {{0, 0, 0}, 0}, 0, 0, NULL};
102 #endif
103 
104 #ifdef FEAT_EVAL
105 static int  tfu_in_use = FALSE;	    // disallow recursive call of tagfunc
106 #endif
107 
108 // Used instead of NUL to separate tag fields in the growarrays.
109 #define TAG_SEP 0x02
110 
111 /*
112  * Jump to tag; handling of tag commands and tag stack
113  *
114  * *tag != NUL: ":tag {tag}", jump to new tag, add to tag stack
115  *
116  * type == DT_TAG:	":tag [tag]", jump to newer position or same tag again
117  * type == DT_HELP:	like DT_TAG, but don't use regexp.
118  * type == DT_POP:	":pop" or CTRL-T, jump to old position
119  * type == DT_NEXT:	jump to next match of same tag
120  * type == DT_PREV:	jump to previous match of same tag
121  * type == DT_FIRST:	jump to first match of same tag
122  * type == DT_LAST:	jump to last match of same tag
123  * type == DT_SELECT:	":tselect [tag]", select tag from a list of all matches
124  * type == DT_JUMP:	":tjump [tag]", jump to tag or select tag from a list
125  * type == DT_CSCOPE:	use cscope to find the tag
126  * type == DT_LTAG:	use location list for displaying tag matches
127  * type == DT_FREE:	free cached matches
128  *
129  * for cscope, returns TRUE if we jumped to tag or aborted, FALSE otherwise
130  */
131     int
132 do_tag(
133     char_u	*tag,		// tag (pattern) to jump to
134     int		type,
135     int		count,
136     int		forceit,	// :ta with !
137     int		verbose)	// print "tag not found" message
138 {
139     taggy_T	*tagstack = curwin->w_tagstack;
140     int		tagstackidx = curwin->w_tagstackidx;
141     int		tagstacklen = curwin->w_tagstacklen;
142     int		cur_match = 0;
143     int		cur_fnum = curbuf->b_fnum;
144     int		oldtagstackidx = tagstackidx;
145     int		prevtagstackidx = tagstackidx;
146     int		prev_num_matches;
147     int		new_tag = FALSE;
148     int		i;
149     int		ic;
150     int		no_regexp = FALSE;
151     int		error_cur_match = 0;
152     int		save_pos = FALSE;
153     fmark_T	saved_fmark;
154 #ifdef FEAT_CSCOPE
155     int		jumped_to_tag = FALSE;
156 #endif
157     int		new_num_matches;
158     char_u	**new_matches;
159     int		use_tagstack;
160     int		skip_msg = FALSE;
161     char_u	*buf_ffname = curbuf->b_ffname;	    // name to use for
162 						    // priority computation
163     int         use_tfu = 1;
164 
165     // remember the matches for the last used tag
166     static int		num_matches = 0;
167     static int		max_num_matches = 0;  // limit used for match search
168     static char_u	**matches = NULL;
169     static int		flags;
170 
171 #ifdef FEAT_EVAL
172     if (tfu_in_use)
173     {
174 	emsg(_(recurmsg));
175 	return FALSE;
176     }
177 #endif
178 
179 #ifdef EXITFREE
180     if (type == DT_FREE)
181     {
182 	// remove the list of matches
183 	FreeWild(num_matches, matches);
184 # ifdef FEAT_CSCOPE
185 	cs_free_tags();
186 # endif
187 	num_matches = 0;
188 	return FALSE;
189     }
190 #endif
191 
192     if (type == DT_HELP)
193     {
194 	type = DT_TAG;
195 	no_regexp = TRUE;
196 	use_tfu = 0;
197     }
198 
199     prev_num_matches = num_matches;
200     free_string_option(nofile_fname);
201     nofile_fname = NULL;
202 
203     CLEAR_POS(&saved_fmark.mark);	// shutup gcc 4.0
204     saved_fmark.fnum = 0;
205 
206     /*
207      * Don't add a tag to the tagstack if 'tagstack' has been reset.
208      */
209     if ((!p_tgst && *tag != NUL))
210     {
211 	use_tagstack = FALSE;
212 	new_tag = TRUE;
213 #if defined(FEAT_QUICKFIX)
214 	if (g_do_tagpreview != 0)
215 	{
216 	    tagstack_clear_entry(&ptag_entry);
217 	    if ((ptag_entry.tagname = vim_strsave(tag)) == NULL)
218 		goto end_do_tag;
219 	}
220 #endif
221     }
222     else
223     {
224 #if defined(FEAT_QUICKFIX)
225 	if (g_do_tagpreview != 0)
226 	    use_tagstack = FALSE;
227 	else
228 #endif
229 	    use_tagstack = TRUE;
230 
231 	// new pattern, add to the tag stack
232 	if (*tag != NUL
233 		&& (type == DT_TAG || type == DT_SELECT || type == DT_JUMP
234 #ifdef FEAT_QUICKFIX
235 		    || type == DT_LTAG
236 #endif
237 #ifdef FEAT_CSCOPE
238 		    || type == DT_CSCOPE
239 #endif
240 		    ))
241 	{
242 #if defined(FEAT_QUICKFIX)
243 	    if (g_do_tagpreview != 0)
244 	    {
245 		if (ptag_entry.tagname != NULL
246 			&& STRCMP(ptag_entry.tagname, tag) == 0)
247 		{
248 		    // Jumping to same tag: keep the current match, so that
249 		    // the CursorHold autocommand example works.
250 		    cur_match = ptag_entry.cur_match;
251 		    cur_fnum = ptag_entry.cur_fnum;
252 		}
253 		else
254 		{
255 		    tagstack_clear_entry(&ptag_entry);
256 		    if ((ptag_entry.tagname = vim_strsave(tag)) == NULL)
257 			goto end_do_tag;
258 		}
259 	    }
260 	    else
261 #endif
262 	    {
263 		/*
264 		 * If the last used entry is not at the top, delete all tag
265 		 * stack entries above it.
266 		 */
267 		while (tagstackidx < tagstacklen)
268 		    tagstack_clear_entry(&tagstack[--tagstacklen]);
269 
270 		// if the tagstack is full: remove oldest entry
271 		if (++tagstacklen > TAGSTACKSIZE)
272 		{
273 		    tagstacklen = TAGSTACKSIZE;
274 		    tagstack_clear_entry(&tagstack[0]);
275 		    for (i = 1; i < tagstacklen; ++i)
276 			tagstack[i - 1] = tagstack[i];
277 		    --tagstackidx;
278 		}
279 
280 		/*
281 		 * put the tag name in the tag stack
282 		 */
283 		if ((tagstack[tagstackidx].tagname = vim_strsave(tag)) == NULL)
284 		{
285 		    curwin->w_tagstacklen = tagstacklen - 1;
286 		    goto end_do_tag;
287 		}
288 		curwin->w_tagstacklen = tagstacklen;
289 
290 		save_pos = TRUE;	// save the cursor position below
291 	    }
292 
293 	    new_tag = TRUE;
294 	}
295 	else
296 	{
297 	    if (
298 #if defined(FEAT_QUICKFIX)
299 		    g_do_tagpreview != 0 ? ptag_entry.tagname == NULL :
300 #endif
301 		    tagstacklen == 0)
302 	    {
303 		// empty stack
304 		emsg(_(e_tagstack));
305 		goto end_do_tag;
306 	    }
307 
308 	    if (type == DT_POP)		// go to older position
309 	    {
310 #ifdef FEAT_FOLDING
311 		int	old_KeyTyped = KeyTyped;
312 #endif
313 		if ((tagstackidx -= count) < 0)
314 		{
315 		    emsg(_(bottommsg));
316 		    if (tagstackidx + count == 0)
317 		    {
318 			// We did [num]^T from the bottom of the stack
319 			tagstackidx = 0;
320 			goto end_do_tag;
321 		    }
322 		    // We weren't at the bottom of the stack, so jump all the
323 		    // way to the bottom now.
324 		    tagstackidx = 0;
325 		}
326 		else if (tagstackidx >= tagstacklen)    // count == 0?
327 		{
328 		    emsg(_(topmsg));
329 		    goto end_do_tag;
330 		}
331 
332 		// Make a copy of the fmark, autocommands may invalidate the
333 		// tagstack before it's used.
334 		saved_fmark = tagstack[tagstackidx].fmark;
335 		if (saved_fmark.fnum != curbuf->b_fnum)
336 		{
337 		    /*
338 		     * Jump to other file. If this fails (e.g. because the
339 		     * file was changed) keep original position in tag stack.
340 		     */
341 		    if (buflist_getfile(saved_fmark.fnum, saved_fmark.mark.lnum,
342 					       GETF_SETMARK, forceit) == FAIL)
343 		    {
344 			tagstackidx = oldtagstackidx;  // back to old posn
345 			goto end_do_tag;
346 		    }
347 		    // An BufReadPost autocommand may jump to the '" mark, but
348 		    // we don't what that here.
349 		    curwin->w_cursor.lnum = saved_fmark.mark.lnum;
350 		}
351 		else
352 		{
353 		    setpcmark();
354 		    curwin->w_cursor.lnum = saved_fmark.mark.lnum;
355 		}
356 		curwin->w_cursor.col = saved_fmark.mark.col;
357 		curwin->w_set_curswant = TRUE;
358 		check_cursor();
359 #ifdef FEAT_FOLDING
360 		if ((fdo_flags & FDO_TAG) && old_KeyTyped)
361 		    foldOpenCursor();
362 #endif
363 
364 		// remove the old list of matches
365 		FreeWild(num_matches, matches);
366 #ifdef FEAT_CSCOPE
367 		cs_free_tags();
368 #endif
369 		num_matches = 0;
370 		tag_freematch();
371 		goto end_do_tag;
372 	    }
373 
374 	    if (type == DT_TAG
375 #if defined(FEAT_QUICKFIX)
376 		    || type == DT_LTAG
377 #endif
378 	       )
379 	    {
380 #if defined(FEAT_QUICKFIX)
381 		if (g_do_tagpreview != 0)
382 		{
383 		    cur_match = ptag_entry.cur_match;
384 		    cur_fnum = ptag_entry.cur_fnum;
385 		}
386 		else
387 #endif
388 		{
389 		    // ":tag" (no argument): go to newer pattern
390 		    save_pos = TRUE;	// save the cursor position below
391 		    if ((tagstackidx += count - 1) >= tagstacklen)
392 		    {
393 			/*
394 			 * Beyond the last one, just give an error message and
395 			 * go to the last one.  Don't store the cursor
396 			 * position.
397 			 */
398 			tagstackidx = tagstacklen - 1;
399 			emsg(_(topmsg));
400 			save_pos = FALSE;
401 		    }
402 		    else if (tagstackidx < 0)	// must have been count == 0
403 		    {
404 			emsg(_(bottommsg));
405 			tagstackidx = 0;
406 			goto end_do_tag;
407 		    }
408 		    cur_match = tagstack[tagstackidx].cur_match;
409 		    cur_fnum = tagstack[tagstackidx].cur_fnum;
410 		}
411 		new_tag = TRUE;
412 	    }
413 	    else				// go to other matching tag
414 	    {
415 		// Save index for when selection is cancelled.
416 		prevtagstackidx = tagstackidx;
417 
418 #if defined(FEAT_QUICKFIX)
419 		if (g_do_tagpreview != 0)
420 		{
421 		    cur_match = ptag_entry.cur_match;
422 		    cur_fnum = ptag_entry.cur_fnum;
423 		}
424 		else
425 #endif
426 		{
427 		    if (--tagstackidx < 0)
428 			tagstackidx = 0;
429 		    cur_match = tagstack[tagstackidx].cur_match;
430 		    cur_fnum = tagstack[tagstackidx].cur_fnum;
431 		}
432 		switch (type)
433 		{
434 		    case DT_FIRST: cur_match = count - 1; break;
435 		    case DT_SELECT:
436 		    case DT_JUMP:
437 #ifdef FEAT_CSCOPE
438 		    case DT_CSCOPE:
439 #endif
440 		    case DT_LAST:  cur_match = MAXCOL - 1; break;
441 		    case DT_NEXT:  cur_match += count; break;
442 		    case DT_PREV:  cur_match -= count; break;
443 		}
444 		if (cur_match >= MAXCOL)
445 		    cur_match = MAXCOL - 1;
446 		else if (cur_match < 0)
447 		{
448 		    emsg(_("E425: Cannot go before first matching tag"));
449 		    skip_msg = TRUE;
450 		    cur_match = 0;
451 		    cur_fnum = curbuf->b_fnum;
452 		}
453 	    }
454 	}
455 
456 #if defined(FEAT_QUICKFIX)
457 	if (g_do_tagpreview != 0)
458 	{
459 	    if (type != DT_SELECT && type != DT_JUMP)
460 	    {
461 		ptag_entry.cur_match = cur_match;
462 		ptag_entry.cur_fnum = cur_fnum;
463 	    }
464 	}
465 	else
466 #endif
467 	{
468 	    /*
469 	     * For ":tag [arg]" or ":tselect" remember position before the jump.
470 	     */
471 	    saved_fmark = tagstack[tagstackidx].fmark;
472 	    if (save_pos)
473 	    {
474 		tagstack[tagstackidx].fmark.mark = curwin->w_cursor;
475 		tagstack[tagstackidx].fmark.fnum = curbuf->b_fnum;
476 	    }
477 
478 	    // Curwin will change in the call to jumpto_tag() if ":stag" was
479 	    // used or an autocommand jumps to another window; store value of
480 	    // tagstackidx now.
481 	    curwin->w_tagstackidx = tagstackidx;
482 	    if (type != DT_SELECT && type != DT_JUMP)
483 	    {
484 		curwin->w_tagstack[tagstackidx].cur_match = cur_match;
485 		curwin->w_tagstack[tagstackidx].cur_fnum = cur_fnum;
486 	    }
487 	}
488     }
489 
490     // When not using the current buffer get the name of buffer "cur_fnum".
491     // Makes sure that the tag order doesn't change when using a remembered
492     // position for "cur_match".
493     if (cur_fnum != curbuf->b_fnum)
494     {
495 	buf_T *buf = buflist_findnr(cur_fnum);
496 
497 	if (buf != NULL)
498 	    buf_ffname = buf->b_ffname;
499     }
500 
501     /*
502      * Repeat searching for tags, when a file has not been found.
503      */
504     for (;;)
505     {
506 	int	other_name;
507 	char_u	*name;
508 
509 	/*
510 	 * When desired match not found yet, try to find it (and others).
511 	 */
512 	if (use_tagstack)
513 	    name = tagstack[tagstackidx].tagname;
514 #if defined(FEAT_QUICKFIX)
515 	else if (g_do_tagpreview != 0)
516 	    name = ptag_entry.tagname;
517 #endif
518 	else
519 	    name = tag;
520 	other_name = (tagmatchname == NULL || STRCMP(tagmatchname, name) != 0);
521 	if (new_tag
522 		|| (cur_match >= num_matches && max_num_matches != MAXCOL)
523 		|| other_name)
524 	{
525 	    if (other_name)
526 	    {
527 		vim_free(tagmatchname);
528 		tagmatchname = vim_strsave(name);
529 	    }
530 
531 	    if (type == DT_SELECT || type == DT_JUMP
532 #if defined(FEAT_QUICKFIX)
533 		|| type == DT_LTAG
534 #endif
535 		)
536 		cur_match = MAXCOL - 1;
537 	    if (type == DT_TAG)
538 		max_num_matches = MAXCOL;
539 	    else
540 		max_num_matches = cur_match + 1;
541 
542 	    // when the argument starts with '/', use it as a regexp
543 	    if (!no_regexp && *name == '/')
544 	    {
545 		flags = TAG_REGEXP;
546 		++name;
547 	    }
548 	    else
549 		flags = TAG_NOIC;
550 
551 #ifdef FEAT_CSCOPE
552 	    if (type == DT_CSCOPE)
553 		flags = TAG_CSCOPE;
554 #endif
555 	    if (verbose)
556 		flags |= TAG_VERBOSE;
557 
558 	    if (!use_tfu)
559 		flags |= TAG_NO_TAGFUNC;
560 
561 	    if (find_tags(name, &new_num_matches, &new_matches, flags,
562 					    max_num_matches, buf_ffname) == OK
563 		    && new_num_matches < max_num_matches)
564 		max_num_matches = MAXCOL; // If less than max_num_matches
565 					  // found: all matches found.
566 
567 	    // If there already were some matches for the same name, move them
568 	    // to the start.  Avoids that the order changes when using
569 	    // ":tnext" and jumping to another file.
570 	    if (!new_tag && !other_name)
571 	    {
572 		int	    j, k;
573 		int	    idx = 0;
574 		tagptrs_T   tagp, tagp2;
575 
576 		// Find the position of each old match in the new list.  Need
577 		// to use parse_match() to find the tag line.
578 		for (j = 0; j < num_matches; ++j)
579 		{
580 		    parse_match(matches[j], &tagp);
581 		    for (i = idx; i < new_num_matches; ++i)
582 		    {
583 			parse_match(new_matches[i], &tagp2);
584 			if (STRCMP(tagp.tagname, tagp2.tagname) == 0)
585 			{
586 			    char_u *p = new_matches[i];
587 			    for (k = i; k > idx; --k)
588 				new_matches[k] = new_matches[k - 1];
589 			    new_matches[idx++] = p;
590 			    break;
591 			}
592 		    }
593 		}
594 	    }
595 	    FreeWild(num_matches, matches);
596 	    num_matches = new_num_matches;
597 	    matches = new_matches;
598 	}
599 
600 	if (num_matches <= 0)
601 	{
602 	    if (verbose)
603 		semsg(_("E426: tag not found: %s"), name);
604 #if defined(FEAT_QUICKFIX)
605 	    g_do_tagpreview = 0;
606 #endif
607 	}
608 	else
609 	{
610 	    int ask_for_selection = FALSE;
611 
612 #ifdef FEAT_CSCOPE
613 	    if (type == DT_CSCOPE && num_matches > 1)
614 	    {
615 		cs_print_tags();
616 		ask_for_selection = TRUE;
617 	    }
618 	    else
619 #endif
620 	    if (type == DT_TAG && *tag != NUL)
621 		// If a count is supplied to the ":tag <name>" command, then
622 		// jump to count'th matching tag.
623 		cur_match = count > 0 ? count - 1 : 0;
624 	    else if (type == DT_SELECT || (type == DT_JUMP && num_matches > 1))
625 	    {
626 		print_tag_list(new_tag, use_tagstack, num_matches, matches);
627 		ask_for_selection = TRUE;
628 	    }
629 #if defined(FEAT_QUICKFIX) && defined(FEAT_EVAL)
630 	    else if (type == DT_LTAG)
631 	    {
632 		if (add_llist_tags(tag, num_matches, matches) == FAIL)
633 		    goto end_do_tag;
634 		cur_match = 0;		// Jump to the first tag
635 	    }
636 #endif
637 
638 	    if (ask_for_selection == TRUE)
639 	    {
640 		/*
641 		 * Ask to select a tag from the list.
642 		 */
643 		i = prompt_for_number(NULL);
644 		if (i <= 0 || i > num_matches || got_int)
645 		{
646 		    // no valid choice: don't change anything
647 		    if (use_tagstack)
648 		    {
649 			tagstack[tagstackidx].fmark = saved_fmark;
650 			tagstackidx = prevtagstackidx;
651 		    }
652 #ifdef FEAT_CSCOPE
653 		    cs_free_tags();
654 		    jumped_to_tag = TRUE;
655 #endif
656 		    break;
657 		}
658 		cur_match = i - 1;
659 	    }
660 
661 	    if (cur_match >= num_matches)
662 	    {
663 		// Avoid giving this error when a file wasn't found and we're
664 		// looking for a match in another file, which wasn't found.
665 		// There will be an emsg("file doesn't exist") below then.
666 		if ((type == DT_NEXT || type == DT_FIRST)
667 						      && nofile_fname == NULL)
668 		{
669 		    if (num_matches == 1)
670 			emsg(_("E427: There is only one matching tag"));
671 		    else
672 			emsg(_("E428: Cannot go beyond last matching tag"));
673 		    skip_msg = TRUE;
674 		}
675 		cur_match = num_matches - 1;
676 	    }
677 	    if (use_tagstack)
678 	    {
679 		tagptrs_T   tagp;
680 
681 		tagstack[tagstackidx].cur_match = cur_match;
682 		tagstack[tagstackidx].cur_fnum = cur_fnum;
683 
684 		// store user-provided data originating from tagfunc
685 		if (use_tfu && parse_match(matches[cur_match], &tagp) == OK
686 			&& tagp.user_data)
687 		{
688 		    VIM_CLEAR(tagstack[tagstackidx].user_data);
689 		    tagstack[tagstackidx].user_data = vim_strnsave(
690 			    tagp.user_data, tagp.user_data_end - tagp.user_data);
691 		}
692 
693 		++tagstackidx;
694 	    }
695 #if defined(FEAT_QUICKFIX)
696 	    else if (g_do_tagpreview != 0)
697 	    {
698 		ptag_entry.cur_match = cur_match;
699 		ptag_entry.cur_fnum = cur_fnum;
700 	    }
701 #endif
702 
703 	    /*
704 	     * Only when going to try the next match, report that the previous
705 	     * file didn't exist.  Otherwise an emsg() is given below.
706 	     */
707 	    if (nofile_fname != NULL && error_cur_match != cur_match)
708 		smsg(_("File \"%s\" does not exist"), nofile_fname);
709 
710 
711 	    ic = (matches[cur_match][0] & MT_IC_OFF);
712 	    if (type != DT_TAG && type != DT_SELECT && type != DT_JUMP
713 #ifdef FEAT_CSCOPE
714 		&& type != DT_CSCOPE
715 #endif
716 		&& (num_matches > 1 || ic)
717 		&& !skip_msg)
718 	    {
719 		// Give an indication of the number of matching tags
720 		sprintf((char *)IObuff, _("tag %d of %d%s"),
721 				cur_match + 1,
722 				num_matches,
723 				max_num_matches != MAXCOL ? _(" or more") : "");
724 		if (ic)
725 		    STRCAT(IObuff, _("  Using tag with different case!"));
726 		if ((num_matches > prev_num_matches || new_tag)
727 							   && num_matches > 1)
728 		{
729 		    if (ic)
730 			msg_attr((char *)IObuff, HL_ATTR(HLF_W));
731 		    else
732 			msg((char *)IObuff);
733 		    msg_scroll = TRUE;	// don't overwrite this message
734 		}
735 		else
736 		    give_warning(IObuff, ic);
737 		if (ic && !msg_scrolled && msg_silent == 0)
738 		{
739 		    out_flush();
740 		    ui_delay(1007L, TRUE);
741 		}
742 	    }
743 
744 #if defined(FEAT_EVAL)
745 	    // Let the SwapExists event know what tag we are jumping to.
746 	    vim_snprintf((char *)IObuff, IOSIZE, ":ta %s\r", name);
747 	    set_vim_var_string(VV_SWAPCOMMAND, IObuff, -1);
748 #endif
749 
750 	    /*
751 	     * Jump to the desired match.
752 	     */
753 	    i = jumpto_tag(matches[cur_match], forceit, type != DT_CSCOPE);
754 
755 #if defined(FEAT_EVAL)
756 	    set_vim_var_string(VV_SWAPCOMMAND, NULL, -1);
757 #endif
758 
759 	    if (i == NOTAGFILE)
760 	    {
761 		// File not found: try again with another matching tag
762 		if ((type == DT_PREV && cur_match > 0)
763 			|| ((type == DT_TAG || type == DT_NEXT
764 							  || type == DT_FIRST)
765 			    && (max_num_matches != MAXCOL
766 					     || cur_match < num_matches - 1)))
767 		{
768 		    error_cur_match = cur_match;
769 		    if (use_tagstack)
770 			--tagstackidx;
771 		    if (type == DT_PREV)
772 			--cur_match;
773 		    else
774 		    {
775 			type = DT_NEXT;
776 			++cur_match;
777 		    }
778 		    continue;
779 		}
780 		semsg(_("E429: File \"%s\" does not exist"), nofile_fname);
781 	    }
782 	    else
783 	    {
784 		// We may have jumped to another window, check that
785 		// tagstackidx is still valid.
786 		if (use_tagstack && tagstackidx > curwin->w_tagstacklen)
787 		    tagstackidx = curwin->w_tagstackidx;
788 #ifdef FEAT_CSCOPE
789 		jumped_to_tag = TRUE;
790 #endif
791 	    }
792 	}
793 	break;
794     }
795 
796 end_do_tag:
797     // Only store the new index when using the tagstack and it's valid.
798     if (use_tagstack && tagstackidx <= curwin->w_tagstacklen)
799 	curwin->w_tagstackidx = tagstackidx;
800     postponed_split = 0;	// don't split next time
801 # ifdef FEAT_QUICKFIX
802     g_do_tagpreview = 0;	// don't do tag preview next time
803 # endif
804 
805 #ifdef FEAT_CSCOPE
806     return jumped_to_tag;
807 #else
808     return FALSE;
809 #endif
810 }
811 
812 /*
813  * List all the matching tags.
814  */
815     static void
816 print_tag_list(
817     int		new_tag,
818     int		use_tagstack,
819     int		num_matches,
820     char_u	**matches)
821 {
822     taggy_T	*tagstack = curwin->w_tagstack;
823     int		tagstackidx = curwin->w_tagstackidx;
824     int		i;
825     char_u	*p;
826     char_u	*command_end;
827     tagptrs_T	tagp;
828     int		taglen;
829     int		attr;
830 
831     /*
832      * Assume that the first match indicates how long the tags can
833      * be, and align the file names to that.
834      */
835     parse_match(matches[0], &tagp);
836     taglen = (int)(tagp.tagname_end - tagp.tagname + 2);
837     if (taglen < 18)
838 	taglen = 18;
839     if (taglen > Columns - 25)
840 	taglen = MAXCOL;
841     if (msg_col == 0)
842 	msg_didout = FALSE;	// overwrite previous message
843     msg_start();
844     msg_puts_attr(_("  # pri kind tag"), HL_ATTR(HLF_T));
845     msg_clr_eos();
846     taglen_advance(taglen);
847     msg_puts_attr(_("file\n"), HL_ATTR(HLF_T));
848 
849     for (i = 0; i < num_matches && !got_int; ++i)
850     {
851 	parse_match(matches[i], &tagp);
852 	if (!new_tag && (
853 #if defined(FEAT_QUICKFIX)
854 		    (g_do_tagpreview != 0
855 		     && i == ptag_entry.cur_match) ||
856 #endif
857 		    (use_tagstack
858 		     && i == tagstack[tagstackidx].cur_match)))
859 	    *IObuff = '>';
860 	else
861 	    *IObuff = ' ';
862 	vim_snprintf((char *)IObuff + 1, IOSIZE - 1,
863 		"%2d %s ", i + 1,
864 			       mt_names[matches[i][0] & MT_MASK]);
865 	msg_puts((char *)IObuff);
866 	if (tagp.tagkind != NULL)
867 	    msg_outtrans_len(tagp.tagkind,
868 			  (int)(tagp.tagkind_end - tagp.tagkind));
869 	msg_advance(13);
870 	msg_outtrans_len_attr(tagp.tagname,
871 			   (int)(tagp.tagname_end - tagp.tagname),
872 						  HL_ATTR(HLF_T));
873 	msg_putchar(' ');
874 	taglen_advance(taglen);
875 
876 	// Find out the actual file name. If it is long, truncate
877 	// it and put "..." in the middle
878 	p = tag_full_fname(&tagp);
879 	if (p != NULL)
880 	{
881 	    msg_outtrans_long_attr(p, HL_ATTR(HLF_D));
882 	    vim_free(p);
883 	}
884 	if (msg_col > 0)
885 	    msg_putchar('\n');
886 	if (got_int)
887 	    break;
888 	msg_advance(15);
889 
890 	// print any extra fields
891 	command_end = tagp.command_end;
892 	if (command_end != NULL)
893 	{
894 	    p = command_end + 3;
895 	    while (*p && *p != '\r' && *p != '\n')
896 	    {
897 		while (*p == TAB)
898 		    ++p;
899 
900 		// skip "file:" without a value (static tag)
901 		if (STRNCMP(p, "file:", 5) == 0
902 					     && vim_isspace(p[5]))
903 		{
904 		    p += 5;
905 		    continue;
906 		}
907 		// skip "kind:<kind>" and "<kind>"
908 		if (p == tagp.tagkind
909 			|| (p + 5 == tagp.tagkind
910 				&& STRNCMP(p, "kind:", 5) == 0))
911 		{
912 		    p = tagp.tagkind_end;
913 		    continue;
914 		}
915 		// print all other extra fields
916 		attr = HL_ATTR(HLF_CM);
917 		while (*p && *p != '\r' && *p != '\n')
918 		{
919 		    if (msg_col + ptr2cells(p) >= Columns)
920 		    {
921 			msg_putchar('\n');
922 			if (got_int)
923 			    break;
924 			msg_advance(15);
925 		    }
926 		    p = msg_outtrans_one(p, attr);
927 		    if (*p == TAB)
928 		    {
929 			msg_puts_attr(" ", attr);
930 			break;
931 		    }
932 		    if (*p == ':')
933 			attr = 0;
934 		}
935 	    }
936 	    if (msg_col > 15)
937 	    {
938 		msg_putchar('\n');
939 		if (got_int)
940 		    break;
941 		msg_advance(15);
942 	    }
943 	}
944 	else
945 	{
946 	    for (p = tagp.command;
947 			      *p && *p != '\r' && *p != '\n'; ++p)
948 		;
949 	    command_end = p;
950 	}
951 
952 	// Put the info (in several lines) at column 15.
953 	// Don't display "/^" and "?^".
954 	p = tagp.command;
955 	if (*p == '/' || *p == '?')
956 	{
957 	    ++p;
958 	    if (*p == '^')
959 		++p;
960 	}
961 	// Remove leading whitespace from pattern
962 	while (p != command_end && vim_isspace(*p))
963 	    ++p;
964 
965 	while (p != command_end)
966 	{
967 	    if (msg_col + (*p == TAB ? 1 : ptr2cells(p)) > Columns)
968 		msg_putchar('\n');
969 	    if (got_int)
970 		break;
971 	    msg_advance(15);
972 
973 	    // skip backslash used for escaping a command char or
974 	    // a backslash
975 	    if (*p == '\\' && (*(p + 1) == *tagp.command
976 			    || *(p + 1) == '\\'))
977 		++p;
978 
979 	    if (*p == TAB)
980 	    {
981 		msg_putchar(' ');
982 		++p;
983 	    }
984 	    else
985 		p = msg_outtrans_one(p, 0);
986 
987 	    // don't display the "$/;\"" and "$?;\""
988 	    if (p == command_end - 2 && *p == '$'
989 				     && *(p + 1) == *tagp.command)
990 		break;
991 	    // don't display matching '/' or '?'
992 	    if (p == command_end - 1 && *p == *tagp.command
993 				     && (*p == '/' || *p == '?'))
994 		break;
995 	}
996 	if (msg_col)
997 	    msg_putchar('\n');
998 	ui_breakcheck();
999     }
1000     if (got_int)
1001 	got_int = FALSE;	// only stop the listing
1002 }
1003 
1004 #if defined(FEAT_QUICKFIX) && defined(FEAT_EVAL)
1005 /*
1006  * Add the matching tags to the location list for the current
1007  * window.
1008  */
1009     static int
1010 add_llist_tags(
1011     char_u	*tag,
1012     int		num_matches,
1013     char_u	**matches)
1014 {
1015     list_T	*list;
1016     char_u	tag_name[128 + 1];
1017     char_u	*fname;
1018     char_u	*cmd;
1019     int		i;
1020     char_u	*p;
1021     tagptrs_T	tagp;
1022 
1023     fname = alloc(MAXPATHL + 1);
1024     cmd = alloc(CMDBUFFSIZE + 1);
1025     list = list_alloc();
1026     if (list == NULL || fname == NULL || cmd == NULL)
1027     {
1028 	vim_free(cmd);
1029 	vim_free(fname);
1030 	if (list != NULL)
1031 	    list_free(list);
1032 	return FAIL;
1033     }
1034 
1035     for (i = 0; i < num_matches; ++i)
1036     {
1037 	int	    len, cmd_len;
1038 	long    lnum;
1039 	dict_T  *dict;
1040 
1041 	parse_match(matches[i], &tagp);
1042 
1043 	// Save the tag name
1044 	len = (int)(tagp.tagname_end - tagp.tagname);
1045 	if (len > 128)
1046 	    len = 128;
1047 	vim_strncpy(tag_name, tagp.tagname, len);
1048 	tag_name[len] = NUL;
1049 
1050 	// Save the tag file name
1051 	p = tag_full_fname(&tagp);
1052 	if (p == NULL)
1053 	    continue;
1054 	vim_strncpy(fname, p, MAXPATHL);
1055 	vim_free(p);
1056 
1057 	// Get the line number or the search pattern used to locate
1058 	// the tag.
1059 	lnum = 0;
1060 	if (isdigit(*tagp.command))
1061 	    // Line number is used to locate the tag
1062 	    lnum = atol((char *)tagp.command);
1063 	else
1064 	{
1065 	    char_u *cmd_start, *cmd_end;
1066 
1067 	    // Search pattern is used to locate the tag
1068 
1069 	    // Locate the end of the command
1070 	    cmd_start = tagp.command;
1071 	    cmd_end = tagp.command_end;
1072 	    if (cmd_end == NULL)
1073 	    {
1074 		for (p = tagp.command;
1075 		     *p && *p != '\r' && *p != '\n'; ++p)
1076 		    ;
1077 		cmd_end = p;
1078 	    }
1079 
1080 	    // Now, cmd_end points to the character after the
1081 	    // command. Adjust it to point to the last
1082 	    // character of the command.
1083 	    cmd_end--;
1084 
1085 	    // Skip the '/' and '?' characters at the
1086 	    // beginning and end of the search pattern.
1087 	    if (*cmd_start == '/' || *cmd_start == '?')
1088 		cmd_start++;
1089 
1090 	    if (*cmd_end == '/' || *cmd_end == '?')
1091 		cmd_end--;
1092 
1093 	    len = 0;
1094 	    cmd[0] = NUL;
1095 
1096 	    // If "^" is present in the tag search pattern, then
1097 	    // copy it first.
1098 	    if (*cmd_start == '^')
1099 	    {
1100 		STRCPY(cmd, "^");
1101 		cmd_start++;
1102 		len++;
1103 	    }
1104 
1105 	    // Precede the tag pattern with \V to make it very
1106 	    // nomagic.
1107 	    STRCAT(cmd, "\\V");
1108 	    len += 2;
1109 
1110 	    cmd_len = (int)(cmd_end - cmd_start + 1);
1111 	    if (cmd_len > (CMDBUFFSIZE - 5))
1112 		cmd_len = CMDBUFFSIZE - 5;
1113 	    STRNCAT(cmd, cmd_start, cmd_len);
1114 	    len += cmd_len;
1115 
1116 	    if (cmd[len - 1] == '$')
1117 	    {
1118 		// Replace '$' at the end of the search pattern
1119 		// with '\$'
1120 		cmd[len - 1] = '\\';
1121 		cmd[len] = '$';
1122 		len++;
1123 	    }
1124 
1125 	    cmd[len] = NUL;
1126 	}
1127 
1128 	if ((dict = dict_alloc()) == NULL)
1129 	    continue;
1130 	if (list_append_dict(list, dict) == FAIL)
1131 	{
1132 	    vim_free(dict);
1133 	    continue;
1134 	}
1135 
1136 	dict_add_string(dict, "text", tag_name);
1137 	dict_add_string(dict, "filename", fname);
1138 	dict_add_number(dict, "lnum", lnum);
1139 	if (lnum == 0)
1140 	    dict_add_string(dict, "pattern", cmd);
1141     }
1142 
1143     vim_snprintf((char *)IObuff, IOSIZE, "ltag %s", tag);
1144     set_errorlist(curwin, list, ' ', IObuff, NULL);
1145 
1146     list_free(list);
1147     vim_free(fname);
1148     vim_free(cmd);
1149 
1150     return OK;
1151 }
1152 #endif
1153 
1154 /*
1155  * Free cached tags.
1156  */
1157     void
1158 tag_freematch(void)
1159 {
1160     VIM_CLEAR(tagmatchname);
1161 }
1162 
1163     static void
1164 taglen_advance(int l)
1165 {
1166     if (l == MAXCOL)
1167     {
1168 	msg_putchar('\n');
1169 	msg_advance(24);
1170     }
1171     else
1172 	msg_advance(13 + l);
1173 }
1174 
1175 /*
1176  * Print the tag stack
1177  */
1178     void
1179 do_tags(exarg_T *eap UNUSED)
1180 {
1181     int		i;
1182     char_u	*name;
1183     taggy_T	*tagstack = curwin->w_tagstack;
1184     int		tagstackidx = curwin->w_tagstackidx;
1185     int		tagstacklen = curwin->w_tagstacklen;
1186 
1187     // Highlight title
1188     msg_puts_title(_("\n  # TO tag         FROM line  in file/text"));
1189     for (i = 0; i < tagstacklen; ++i)
1190     {
1191 	if (tagstack[i].tagname != NULL)
1192 	{
1193 	    name = fm_getname(&(tagstack[i].fmark), 30);
1194 	    if (name == NULL)	    // file name not available
1195 		continue;
1196 
1197 	    msg_putchar('\n');
1198 	    vim_snprintf((char *)IObuff, IOSIZE, "%c%2d %2d %-15s %5ld  ",
1199 		i == tagstackidx ? '>' : ' ',
1200 		i + 1,
1201 		tagstack[i].cur_match + 1,
1202 		tagstack[i].tagname,
1203 		tagstack[i].fmark.mark.lnum);
1204 	    msg_outtrans(IObuff);
1205 	    msg_outtrans_attr(name, tagstack[i].fmark.fnum == curbuf->b_fnum
1206 							? HL_ATTR(HLF_D) : 0);
1207 	    vim_free(name);
1208 	}
1209 	out_flush();		    // show one line at a time
1210     }
1211     if (tagstackidx == tagstacklen)	// idx at top of stack
1212 	msg_puts("\n>");
1213 }
1214 
1215 #ifdef FEAT_TAG_BINS
1216 /*
1217  * Compare two strings, for length "len", ignoring case the ASCII way.
1218  * return 0 for match, < 0 for smaller, > 0 for bigger
1219  * Make sure case is folded to uppercase in comparison (like for 'sort -f')
1220  */
1221     static int
1222 tag_strnicmp(char_u *s1, char_u *s2, size_t len)
1223 {
1224     int		i;
1225 
1226     while (len > 0)
1227     {
1228 	i = (int)TOUPPER_ASC(*s1) - (int)TOUPPER_ASC(*s2);
1229 	if (i != 0)
1230 	    return i;			// this character different
1231 	if (*s1 == NUL)
1232 	    break;			// strings match until NUL
1233 	++s1;
1234 	++s2;
1235 	--len;
1236     }
1237     return 0;				// strings match
1238 }
1239 #endif
1240 
1241 /*
1242  * Structure to hold info about the tag pattern being used.
1243  */
1244 typedef struct
1245 {
1246     char_u	*pat;		// the pattern
1247     int		len;		// length of pat[]
1248     char_u	*head;		// start of pattern head
1249     int		headlen;	// length of head[]
1250     regmatch_T	regmatch;	// regexp program, may be NULL
1251 } pat_T;
1252 
1253 /*
1254  * Extract info from the tag search pattern "pats->pat".
1255  */
1256     static void
1257 prepare_pats(pat_T *pats, int has_re)
1258 {
1259     pats->head = pats->pat;
1260     pats->headlen = pats->len;
1261     if (has_re)
1262     {
1263 	// When the pattern starts with '^' or "\\<", binary searching can be
1264 	// used (much faster).
1265 	if (pats->pat[0] == '^')
1266 	    pats->head = pats->pat + 1;
1267 	else if (pats->pat[0] == '\\' && pats->pat[1] == '<')
1268 	    pats->head = pats->pat + 2;
1269 	if (pats->head == pats->pat)
1270 	    pats->headlen = 0;
1271 	else
1272 	    for (pats->headlen = 0; pats->head[pats->headlen] != NUL;
1273 							      ++pats->headlen)
1274 		if (vim_strchr((char_u *)(p_magic ? ".[~*\\$" : "\\$"),
1275 					   pats->head[pats->headlen]) != NULL)
1276 		    break;
1277 	if (p_tl != 0 && pats->headlen > p_tl)	// adjust for 'taglength'
1278 	    pats->headlen = p_tl;
1279     }
1280 
1281     if (has_re)
1282 	pats->regmatch.regprog = vim_regcomp(pats->pat, p_magic ? RE_MAGIC : 0);
1283     else
1284 	pats->regmatch.regprog = NULL;
1285 }
1286 
1287 #ifdef FEAT_EVAL
1288 /*
1289  * Call the user-defined function to generate a list of tags used by
1290  * find_tags().
1291  *
1292  * Return OK if at least 1 tag has been successfully found,
1293  * NOTDONE if the function returns v:null, and FAIL otherwise.
1294  */
1295     static int
1296 find_tagfunc_tags(
1297     char_u	*pat,		// pattern supplied to the user-defined function
1298     garray_T	*ga,		// the tags will be placed here
1299     int		*match_count,	// here the number of tags found will be placed
1300     int		flags,		// flags from find_tags (TAG_*)
1301     char_u	*buf_ffname)	// name of buffer for priority
1302 {
1303     pos_T       save_pos;
1304     list_T      *taglist;
1305     listitem_T  *item;
1306     int         ntags = 0;
1307     int         result = FAIL;
1308     typval_T	args[4];
1309     typval_T	rettv;
1310     char_u      flagString[3];
1311     dict_T	*d;
1312     taggy_T	*tag = &curwin->w_tagstack[curwin->w_tagstackidx];
1313 
1314     if (*curbuf->b_p_tfu == NUL)
1315 	return FAIL;
1316 
1317     args[0].v_type = VAR_STRING;
1318     args[0].vval.v_string = pat;
1319     args[1].v_type = VAR_STRING;
1320     args[1].vval.v_string = flagString;
1321 
1322     // create 'info' dict argument
1323     if ((d = dict_alloc_lock(VAR_FIXED)) == NULL)
1324 	return FAIL;
1325     if (tag->user_data != NULL)
1326 	dict_add_string(d, "user_data", tag->user_data);
1327     if (buf_ffname != NULL)
1328 	dict_add_string(d, "buf_ffname", buf_ffname);
1329 
1330     ++d->dv_refcount;
1331     args[2].v_type = VAR_DICT;
1332     args[2].vval.v_dict = d;
1333 
1334     args[3].v_type = VAR_UNKNOWN;
1335 
1336     vim_snprintf((char *)flagString, sizeof(flagString),
1337 		 "%s%s",
1338 		 g_tag_at_cursor      ? "c": "",
1339 		 flags & TAG_INS_COMP ? "i": "");
1340 
1341     save_pos = curwin->w_cursor;
1342     result = call_vim_function(curbuf->b_p_tfu, 3, args, &rettv);
1343     curwin->w_cursor = save_pos;	// restore the cursor position
1344     --d->dv_refcount;
1345 
1346     if (result == FAIL)
1347 	return FAIL;
1348     if (rettv.v_type == VAR_SPECIAL && rettv.vval.v_number == VVAL_NULL)
1349     {
1350 	clear_tv(&rettv);
1351 	return NOTDONE;
1352     }
1353     if (rettv.v_type != VAR_LIST || !rettv.vval.v_list)
1354     {
1355 	clear_tv(&rettv);
1356 	emsg(_(tfu_inv_ret_msg));
1357 	return FAIL;
1358     }
1359     taglist = rettv.vval.v_list;
1360 
1361     FOR_ALL_LIST_ITEMS(taglist, item)
1362     {
1363 	char_u		*mfp;
1364 	char_u		*res_name, *res_fname, *res_cmd, *res_kind;
1365 	int		len;
1366 	dict_iterator_T	iter;
1367 	char_u		*dict_key;
1368 	typval_T	*tv;
1369 	int		has_extra = 0;
1370 	int		name_only = flags & TAG_NAMES;
1371 
1372 	if (item->li_tv.v_type != VAR_DICT)
1373 	{
1374 	    emsg(_(tfu_inv_ret_msg));
1375 	    break;
1376 	}
1377 
1378 #ifdef FEAT_EMACS_TAGS
1379 	len = 3;
1380 #else
1381 	len = 2;
1382 #endif
1383 	res_name = NULL;
1384 	res_fname = NULL;
1385 	res_cmd = NULL;
1386 	res_kind = NULL;
1387 
1388 	dict_iterate_start(&item->li_tv, &iter);
1389 	while (NULL != (dict_key = dict_iterate_next(&iter, &tv)))
1390 	{
1391 	    if (tv->v_type != VAR_STRING || tv->vval.v_string == NULL)
1392 		continue;
1393 
1394 	    len += (int)STRLEN(tv->vval.v_string) + 1;   // Space for "\tVALUE"
1395 	    if (!STRCMP(dict_key, "name"))
1396 	    {
1397 		res_name = tv->vval.v_string;
1398 		continue;
1399 	    }
1400 	    if (!STRCMP(dict_key, "filename"))
1401 	    {
1402 		res_fname = tv->vval.v_string;
1403 		continue;
1404 	    }
1405 	    if (!STRCMP(dict_key, "cmd"))
1406 	    {
1407 		res_cmd = tv->vval.v_string;
1408 		continue;
1409 	    }
1410 	    has_extra = 1;
1411 	    if (!STRCMP(dict_key, "kind"))
1412 	    {
1413 		res_kind = tv->vval.v_string;
1414 		continue;
1415 	    }
1416 	    // Other elements will be stored as "\tKEY:VALUE"
1417 	    // Allocate space for the key and the colon
1418 	    len += (int)STRLEN(dict_key) + 1;
1419 	}
1420 
1421 	if (has_extra)
1422 	    len += 2;	// need space for ;"
1423 
1424 	if (!res_name || !res_fname || !res_cmd)
1425 	{
1426 	    emsg(_(tfu_inv_ret_msg));
1427 	    break;
1428 	}
1429 
1430 	if (name_only)
1431 	    mfp = vim_strsave(res_name);
1432 	else
1433 	    mfp = alloc(sizeof(char_u) + len + 1);
1434 
1435 	if (mfp == NULL)
1436 	    continue;
1437 
1438 	if (!name_only)
1439 	{
1440 	    char_u *p = mfp;
1441 
1442 	    *p++ = MT_GL_OTH + 1;   // mtt
1443 	    *p++ = TAG_SEP;	    // no tag file name
1444 #ifdef FEAT_EMACS_TAGS
1445 	    *p++ = TAG_SEP;
1446 #endif
1447 
1448 	    STRCPY(p, res_name);
1449 	    p += STRLEN(p);
1450 
1451 	    *p++ = TAB;
1452 	    STRCPY(p, res_fname);
1453 	    p += STRLEN(p);
1454 
1455 	    *p++ = TAB;
1456 	    STRCPY(p, res_cmd);
1457 	    p += STRLEN(p);
1458 
1459 	    if (has_extra)
1460 	    {
1461 		STRCPY(p, ";\"");
1462 		p += STRLEN(p);
1463 
1464 		if (res_kind)
1465 		{
1466 		    *p++ = TAB;
1467 		    STRCPY(p, res_kind);
1468 		    p += STRLEN(p);
1469 		}
1470 
1471 		dict_iterate_start(&item->li_tv, &iter);
1472 		while (NULL != (dict_key = dict_iterate_next(&iter, &tv)))
1473 		{
1474 		    if (tv->v_type != VAR_STRING || tv->vval.v_string == NULL)
1475 			continue;
1476 
1477 		    if (!STRCMP(dict_key, "name"))
1478 			continue;
1479 		    if (!STRCMP(dict_key, "filename"))
1480 			continue;
1481 		    if (!STRCMP(dict_key, "cmd"))
1482 			continue;
1483 		    if (!STRCMP(dict_key, "kind"))
1484 			continue;
1485 
1486 		    *p++ = TAB;
1487 		    STRCPY(p, dict_key);
1488 		    p += STRLEN(p);
1489 		    STRCPY(p, ":");
1490 		    p += STRLEN(p);
1491 		    STRCPY(p, tv->vval.v_string);
1492 		    p += STRLEN(p);
1493 		}
1494 	    }
1495 	}
1496 
1497 	// Add all matches because tagfunc should do filtering.
1498 	if (ga_grow(ga, 1) == OK)
1499 	{
1500 	    ((char_u **)(ga->ga_data))[ga->ga_len++] = mfp;
1501 	    ++ntags;
1502 	    result = OK;
1503 	}
1504 	else
1505 	{
1506 	    vim_free(mfp);
1507 	    break;
1508 	}
1509     }
1510 
1511     clear_tv(&rettv);
1512 
1513     *match_count = ntags;
1514     return result;
1515 }
1516 #endif
1517 
1518 /*
1519  * find_tags() - search for tags in tags files
1520  *
1521  * Return FAIL if search completely failed (*num_matches will be 0, *matchesp
1522  * will be NULL), OK otherwise.
1523  *
1524  * There is a priority in which type of tag is recognized.
1525  *
1526  *  6.	A static or global tag with a full matching tag for the current file.
1527  *  5.	A global tag with a full matching tag for another file.
1528  *  4.	A static tag with a full matching tag for another file.
1529  *  3.	A static or global tag with an ignore-case matching tag for the
1530  *	current file.
1531  *  2.	A global tag with an ignore-case matching tag for another file.
1532  *  1.	A static tag with an ignore-case matching tag for another file.
1533  *
1534  * Tags in an emacs-style tags file are always global.
1535  *
1536  * flags:
1537  * TAG_HELP	  only search for help tags
1538  * TAG_NAMES	  only return name of tag
1539  * TAG_REGEXP	  use "pat" as a regexp
1540  * TAG_NOIC	  don't always ignore case
1541  * TAG_KEEP_LANG  keep language
1542  * TAG_CSCOPE	  use cscope results for tags
1543  * TAG_NO_TAGFUNC do not call the 'tagfunc' function
1544  */
1545     int
1546 find_tags(
1547     char_u	*pat,			// pattern to search for
1548     int		*num_matches,		// return: number of matches found
1549     char_u	***matchesp,		// return: array of matches found
1550     int		flags,
1551     int		mincount,		//  MAXCOL: find all matches
1552 					// other: minimal number of matches
1553     char_u	*buf_ffname)		// name of buffer for priority
1554 {
1555     FILE       *fp;
1556     char_u     *lbuf;			// line buffer
1557     int		lbuf_size = LSIZE;	// length of lbuf
1558     char_u     *tag_fname;		// name of tag file
1559     tagname_T	tn;			// info for get_tagfname()
1560     int		first_file;		// trying first tag file
1561     tagptrs_T	tagp;
1562     int		did_open = FALSE;	// did open a tag file
1563     int		stop_searching = FALSE;	// stop when match found or error
1564     int		retval = FAIL;		// return value
1565     int		is_static;		// current tag line is static
1566     int		is_current;		// file name matches
1567     int		eof = FALSE;		// found end-of-file
1568     char_u	*p;
1569     char_u	*s;
1570     int		i;
1571 #ifdef FEAT_TAG_BINS
1572     int		tag_file_sorted = NUL;	// !_TAG_FILE_SORTED value
1573     struct tag_search_info	// Binary search file offsets
1574     {
1575 	off_T	low_offset;	// offset for first char of first line that
1576 				// could match
1577 	off_T	high_offset;	// offset of char after last line that could
1578 				// match
1579 	off_T	curr_offset;	// Current file offset in search range
1580 	off_T	curr_offset_used; // curr_offset used when skipping back
1581 	off_T	match_offset;	// Where the binary search found a tag
1582 	int	low_char;	// first char at low_offset
1583 	int	high_char;	// first char at high_offset
1584     } search_info;
1585     off_T	filesize;
1586     int		tagcmp;
1587     off_T	offset;
1588     int		round;
1589 #endif
1590     enum
1591     {
1592 	TS_START,		// at start of file
1593 	TS_LINEAR		// linear searching forward, till EOF
1594 #ifdef FEAT_TAG_BINS
1595 	, TS_BINARY,		// binary searching
1596 	TS_SKIP_BACK,		// skipping backwards
1597 	TS_STEP_FORWARD		// stepping forwards
1598 #endif
1599     }	state;			// Current search state
1600 
1601     int		cmplen;
1602     int		match;		// matches
1603     int		match_no_ic = 0;// matches with rm_ic == FALSE
1604     int		match_re;	// match with regexp
1605     int		matchoff = 0;
1606     int		save_emsg_off;
1607 
1608 #ifdef FEAT_EMACS_TAGS
1609     /*
1610      * Stack for included emacs-tags file.
1611      * It has a fixed size, to truncate cyclic includes. jw
1612      */
1613 # define INCSTACK_SIZE 42
1614     struct
1615     {
1616 	FILE	*fp;
1617 	char_u	*etag_fname;
1618     } incstack[INCSTACK_SIZE];
1619 
1620     int		incstack_idx = 0;	// index in incstack
1621     char_u     *ebuf;			// additional buffer for etag fname
1622     int		is_etag;		// current file is emaces style
1623 #endif
1624 
1625     char_u	*mfp;
1626     garray_T	ga_match[MT_COUNT];	// stores matches in sequence
1627     hashtab_T	ht_match[MT_COUNT];	// stores matches by key
1628     hash_T	hash = 0;
1629     int		match_count = 0;		// number of matches found
1630     char_u	**matches;
1631     int		mtt;
1632     int		help_save;
1633 #ifdef FEAT_MULTI_LANG
1634     int		help_pri = 0;
1635     char_u	*help_lang_find = NULL;		// lang to be found
1636     char_u	help_lang[3];			// lang of current tags file
1637     char_u	*saved_pat = NULL;		// copy of pat[]
1638     int		is_txt = FALSE;			// flag of file extension
1639 #endif
1640 
1641     pat_T	orgpat;			// holds unconverted pattern info
1642     vimconv_T	vimconv;
1643 
1644 #ifdef FEAT_TAG_BINS
1645     int		findall = (mincount == MAXCOL || mincount == TAG_MANY);
1646 						// find all matching tags
1647     int		sort_error = FALSE;		// tags file not sorted
1648     int		linear;				// do a linear search
1649     int		sortic = FALSE;			// tag file sorted in nocase
1650 #endif
1651     int		line_error = FALSE;		// syntax error
1652     int		has_re = (flags & TAG_REGEXP);	// regexp used
1653     int		help_only = (flags & TAG_HELP);
1654     int		name_only = (flags & TAG_NAMES);
1655     int		noic = (flags & TAG_NOIC);
1656     int		get_it_again = FALSE;
1657 #ifdef FEAT_CSCOPE
1658     int		use_cscope = (flags & TAG_CSCOPE);
1659 #endif
1660     int		verbose = (flags & TAG_VERBOSE);
1661 #ifdef FEAT_EVAL
1662     int         use_tfu = ((flags & TAG_NO_TAGFUNC) == 0);
1663 #endif
1664     int		save_p_ic = p_ic;
1665 
1666     /*
1667      * Change the value of 'ignorecase' according to 'tagcase' for the
1668      * duration of this function.
1669      */
1670     switch (curbuf->b_tc_flags ? curbuf->b_tc_flags : tc_flags)
1671     {
1672 	case TC_FOLLOWIC:		 break;
1673 	case TC_IGNORE:    p_ic = TRUE;  break;
1674 	case TC_MATCH:     p_ic = FALSE; break;
1675 	case TC_FOLLOWSCS: p_ic = ignorecase(pat); break;
1676 	case TC_SMART:     p_ic = ignorecase_opt(pat, TRUE, TRUE); break;
1677     }
1678 
1679     help_save = curbuf->b_help;
1680     orgpat.pat = pat;
1681     vimconv.vc_type = CONV_NONE;
1682 
1683     /*
1684      * Allocate memory for the buffers that are used
1685      */
1686     lbuf = alloc(lbuf_size);
1687     tag_fname = alloc(MAXPATHL + 1);
1688 #ifdef FEAT_EMACS_TAGS
1689     ebuf = alloc(LSIZE);
1690 #endif
1691     for (mtt = 0; mtt < MT_COUNT; ++mtt)
1692     {
1693 	ga_init2(&ga_match[mtt], (int)sizeof(char_u *), 100);
1694 	hash_init(&ht_match[mtt]);
1695     }
1696 
1697     // check for out of memory situation
1698     if (lbuf == NULL || tag_fname == NULL
1699 #ifdef FEAT_EMACS_TAGS
1700 					 || ebuf == NULL
1701 #endif
1702 							)
1703 	goto findtag_end;
1704 
1705 #ifdef FEAT_CSCOPE
1706     STRCPY(tag_fname, "from cscope");		// for error messages
1707 #endif
1708 
1709     /*
1710      * Initialize a few variables
1711      */
1712     if (help_only)				// want tags from help file
1713 	curbuf->b_help = TRUE;			// will be restored later
1714 #ifdef FEAT_CSCOPE
1715     else if (use_cscope)
1716     {
1717 	// Make sure we don't mix help and cscope, confuses Coverity.
1718 	help_only = FALSE;
1719 	curbuf->b_help = FALSE;
1720     }
1721 #endif
1722 
1723     orgpat.len = (int)STRLEN(pat);
1724 #ifdef FEAT_MULTI_LANG
1725     if (curbuf->b_help)
1726     {
1727 	// When "@ab" is specified use only the "ab" language, otherwise
1728 	// search all languages.
1729 	if (orgpat.len > 3 && pat[orgpat.len - 3] == '@'
1730 					  && ASCII_ISALPHA(pat[orgpat.len - 2])
1731 					 && ASCII_ISALPHA(pat[orgpat.len - 1]))
1732 	{
1733 	    saved_pat = vim_strnsave(pat, orgpat.len - 3);
1734 	    if (saved_pat != NULL)
1735 	    {
1736 		help_lang_find = &pat[orgpat.len - 2];
1737 		orgpat.pat = saved_pat;
1738 		orgpat.len -= 3;
1739 	    }
1740 	}
1741     }
1742 #endif
1743     if (p_tl != 0 && orgpat.len > p_tl)		// adjust for 'taglength'
1744 	orgpat.len = p_tl;
1745 
1746     save_emsg_off = emsg_off;
1747     emsg_off = TRUE;  // don't want error for invalid RE here
1748     prepare_pats(&orgpat, has_re);
1749     emsg_off = save_emsg_off;
1750     if (has_re && orgpat.regmatch.regprog == NULL)
1751 	goto findtag_end;
1752 
1753 #ifdef FEAT_TAG_BINS
1754     // This is only to avoid a compiler warning for using search_info
1755     // uninitialised.
1756     CLEAR_FIELD(search_info);
1757 #endif
1758 
1759 #ifdef FEAT_EVAL
1760     if (*curbuf->b_p_tfu != NUL && use_tfu && !tfu_in_use)
1761     {
1762 	tfu_in_use = TRUE;
1763 	retval = find_tagfunc_tags(pat, &ga_match[0], &match_count,
1764 							   flags, buf_ffname);
1765 	tfu_in_use = FALSE;
1766 	if (retval != NOTDONE)
1767 	    goto findtag_end;
1768     }
1769 #endif
1770 
1771     /*
1772      * When finding a specified number of matches, first try with matching
1773      * case, so binary search can be used, and try ignore-case matches in a
1774      * second loop.
1775      * When finding all matches, 'tagbsearch' is off, or there is no fixed
1776      * string to look for, ignore case right away to avoid going though the
1777      * tags files twice.
1778      * When the tag file is case-fold sorted, it is either one or the other.
1779      * Only ignore case when TAG_NOIC not used or 'ignorecase' set.
1780      */
1781 #ifdef FEAT_MULTI_LANG
1782     // Set a flag if the file extension is .txt
1783     if ((flags & TAG_KEEP_LANG)
1784 	    && help_lang_find == NULL
1785 	    && curbuf->b_fname != NULL
1786 	    && (i = (int)STRLEN(curbuf->b_fname)) > 4
1787 	    && STRICMP(curbuf->b_fname + i - 4, ".txt") == 0)
1788 	is_txt = TRUE;
1789 #endif
1790 #ifdef FEAT_TAG_BINS
1791     orgpat.regmatch.rm_ic = ((p_ic || !noic)
1792 				&& (findall || orgpat.headlen == 0 || !p_tbs));
1793     for (round = 1; round <= 2; ++round)
1794     {
1795       linear = (orgpat.headlen == 0 || !p_tbs || round == 2);
1796 #else
1797       orgpat.regmatch.rm_ic = (p_ic || !noic);
1798 #endif
1799 
1800       /*
1801        * Try tag file names from tags option one by one.
1802        */
1803       for (first_file = TRUE;
1804 #ifdef FEAT_CSCOPE
1805 	    use_cscope ||
1806 #endif
1807 		get_tagfname(&tn, first_file, tag_fname) == OK;
1808 							   first_file = FALSE)
1809       {
1810 	/*
1811 	 * A file that doesn't exist is silently ignored.  Only when not a
1812 	 * single file is found, an error message is given (further on).
1813 	 */
1814 #ifdef FEAT_CSCOPE
1815 	if (use_cscope)
1816 	    fp = NULL;	    // avoid GCC warning
1817 	else
1818 #endif
1819 	{
1820 #ifdef FEAT_MULTI_LANG
1821 	    if (curbuf->b_help)
1822 	    {
1823 		// Keep en if the file extension is .txt
1824 		if (is_txt)
1825 		    STRCPY(help_lang, "en");
1826 		else
1827 		{
1828 		    // Prefer help tags according to 'helplang'.  Put the
1829 		    // two-letter language name in help_lang[].
1830 		    i = (int)STRLEN(tag_fname);
1831 		    if (i > 3 && tag_fname[i - 3] == '-')
1832 			STRCPY(help_lang, tag_fname + i - 2);
1833 		    else
1834 			STRCPY(help_lang, "en");
1835 		}
1836 		// When searching for a specific language skip tags files
1837 		// for other languages.
1838 		if (help_lang_find != NULL
1839 				   && STRICMP(help_lang, help_lang_find) != 0)
1840 		    continue;
1841 
1842 		// For CTRL-] in a help file prefer a match with the same
1843 		// language.
1844 		if ((flags & TAG_KEEP_LANG)
1845 			&& help_lang_find == NULL
1846 			&& curbuf->b_fname != NULL
1847 			&& (i = (int)STRLEN(curbuf->b_fname)) > 4
1848 			&& curbuf->b_fname[i - 1] == 'x'
1849 			&& curbuf->b_fname[i - 4] == '.'
1850 			&& STRNICMP(curbuf->b_fname + i - 3, help_lang, 2) == 0)
1851 		    help_pri = 0;
1852 		else
1853 		{
1854 		    help_pri = 1;
1855 		    for (s = p_hlg; *s != NUL; ++s)
1856 		    {
1857 			if (STRNICMP(s, help_lang, 2) == 0)
1858 			    break;
1859 			++help_pri;
1860 			if ((s = vim_strchr(s, ',')) == NULL)
1861 			    break;
1862 		    }
1863 		    if (s == NULL || *s == NUL)
1864 		    {
1865 			// Language not in 'helplang': use last, prefer English,
1866 			// unless found already.
1867 			++help_pri;
1868 			if (STRICMP(help_lang, "en") != 0)
1869 			    ++help_pri;
1870 		    }
1871 		}
1872 	    }
1873 #endif
1874 
1875 	    if ((fp = mch_fopen((char *)tag_fname, "r")) == NULL)
1876 		continue;
1877 
1878 	    if (p_verbose >= 5)
1879 	    {
1880 		verbose_enter();
1881 		smsg(_("Searching tags file %s"), tag_fname);
1882 		verbose_leave();
1883 	    }
1884 	}
1885 	did_open = TRUE;    // remember that we found at least one file
1886 
1887 	state = TS_START;   // we're at the start of the file
1888 #ifdef FEAT_EMACS_TAGS
1889 	is_etag = 0;	    // default is: not emacs style
1890 #endif
1891 
1892 	/*
1893 	 * Read and parse the lines in the file one by one
1894 	 */
1895 	for (;;)
1896 	{
1897 #ifdef FEAT_TAG_BINS
1898 	    // check for CTRL-C typed, more often when jumping around
1899 	    if (state == TS_BINARY || state == TS_SKIP_BACK)
1900 		line_breakcheck();
1901 	    else
1902 #endif
1903 		fast_breakcheck();
1904 	    if ((flags & TAG_INS_COMP))	// Double brackets for gcc
1905 		ins_compl_check_keys(30, FALSE);
1906 	    if (got_int || ins_compl_interrupted())
1907 	    {
1908 		stop_searching = TRUE;
1909 		break;
1910 	    }
1911 	    // When mincount is TAG_MANY, stop when enough matches have been
1912 	    // found (for completion).
1913 	    if (mincount == TAG_MANY && match_count >= TAG_MANY)
1914 	    {
1915 		stop_searching = TRUE;
1916 		retval = OK;
1917 		break;
1918 	    }
1919 	    if (get_it_again)
1920 		goto line_read_in;
1921 #ifdef FEAT_TAG_BINS
1922 	    /*
1923 	     * For binary search: compute the next offset to use.
1924 	     */
1925 	    if (state == TS_BINARY)
1926 	    {
1927 		offset = search_info.low_offset + ((search_info.high_offset
1928 					       - search_info.low_offset) / 2);
1929 		if (offset == search_info.curr_offset)
1930 		    break;	// End the binary search without a match.
1931 		else
1932 		    search_info.curr_offset = offset;
1933 	    }
1934 
1935 	    /*
1936 	     * Skipping back (after a match during binary search).
1937 	     */
1938 	    else if (state == TS_SKIP_BACK)
1939 	    {
1940 		search_info.curr_offset -= lbuf_size * 2;
1941 		if (search_info.curr_offset < 0)
1942 		{
1943 		    search_info.curr_offset = 0;
1944 		    rewind(fp);
1945 		    state = TS_STEP_FORWARD;
1946 		}
1947 	    }
1948 
1949 	    /*
1950 	     * When jumping around in the file, first read a line to find the
1951 	     * start of the next line.
1952 	     */
1953 	    if (state == TS_BINARY || state == TS_SKIP_BACK)
1954 	    {
1955 		// Adjust the search file offset to the correct position
1956 		search_info.curr_offset_used = search_info.curr_offset;
1957 		vim_fseek(fp, search_info.curr_offset, SEEK_SET);
1958 		eof = vim_fgets(lbuf, lbuf_size, fp);
1959 		if (!eof && search_info.curr_offset != 0)
1960 		{
1961 		    // The explicit cast is to work around a bug in gcc 3.4.2
1962 		    // (repeated below).
1963 		    search_info.curr_offset = vim_ftell(fp);
1964 		    if (search_info.curr_offset == search_info.high_offset)
1965 		    {
1966 			// oops, gone a bit too far; try from low offset
1967 			vim_fseek(fp, search_info.low_offset, SEEK_SET);
1968 			search_info.curr_offset = search_info.low_offset;
1969 		    }
1970 		    eof = vim_fgets(lbuf, lbuf_size, fp);
1971 		}
1972 		// skip empty and blank lines
1973 		while (!eof && vim_isblankline(lbuf))
1974 		{
1975 		    search_info.curr_offset = vim_ftell(fp);
1976 		    eof = vim_fgets(lbuf, lbuf_size, fp);
1977 		}
1978 		if (eof)
1979 		{
1980 		    // Hit end of file.  Skip backwards.
1981 		    state = TS_SKIP_BACK;
1982 		    search_info.match_offset = vim_ftell(fp);
1983 		    search_info.curr_offset = search_info.curr_offset_used;
1984 		    continue;
1985 		}
1986 	    }
1987 
1988 	    /*
1989 	     * Not jumping around in the file: Read the next line.
1990 	     */
1991 	    else
1992 #endif
1993 	    {
1994 		// skip empty and blank lines
1995 		do
1996 		{
1997 #ifdef FEAT_CSCOPE
1998 		    if (use_cscope)
1999 			eof = cs_fgets(lbuf, lbuf_size);
2000 		    else
2001 #endif
2002 			eof = vim_fgets(lbuf, lbuf_size, fp);
2003 		} while (!eof && vim_isblankline(lbuf));
2004 
2005 		if (eof)
2006 		{
2007 #ifdef FEAT_EMACS_TAGS
2008 		    if (incstack_idx)	// this was an included file
2009 		    {
2010 			--incstack_idx;
2011 			fclose(fp);	// end of this file ...
2012 			fp = incstack[incstack_idx].fp;
2013 			STRCPY(tag_fname, incstack[incstack_idx].etag_fname);
2014 			vim_free(incstack[incstack_idx].etag_fname);
2015 			is_etag = 1;	// (only etags can include)
2016 			continue;	// ... continue with parent file
2017 		    }
2018 		    else
2019 #endif
2020 			break;			    // end of file
2021 		}
2022 	    }
2023 line_read_in:
2024 
2025 	    if (vimconv.vc_type != CONV_NONE)
2026 	    {
2027 		char_u	*conv_line;
2028 		int	len;
2029 
2030 		// Convert every line.  Converting the pattern from 'enc' to
2031 		// the tags file encoding doesn't work, because characters are
2032 		// not recognized.
2033 		conv_line = string_convert(&vimconv, lbuf, NULL);
2034 		if (conv_line != NULL)
2035 		{
2036 		    // Copy or swap lbuf and conv_line.
2037 		    len = (int)STRLEN(conv_line) + 1;
2038 		    if (len > lbuf_size)
2039 		    {
2040 			vim_free(lbuf);
2041 			lbuf = conv_line;
2042 			lbuf_size = len;
2043 		    }
2044 		    else
2045 		    {
2046 			STRCPY(lbuf, conv_line);
2047 			vim_free(conv_line);
2048 		    }
2049 		}
2050 	    }
2051 
2052 
2053 #ifdef FEAT_EMACS_TAGS
2054 	    /*
2055 	     * Emacs tags line with CTRL-L: New file name on next line.
2056 	     * The file name is followed by a ','.
2057 	     * Remember etag file name in ebuf.
2058 	     */
2059 	    if (*lbuf == Ctrl_L
2060 # ifdef FEAT_CSCOPE
2061 				&& !use_cscope
2062 # endif
2063 				)
2064 	    {
2065 		is_etag = 1;		// in case at the start
2066 		state = TS_LINEAR;
2067 		if (!vim_fgets(ebuf, LSIZE, fp))
2068 		{
2069 		    for (p = ebuf; *p && *p != ','; p++)
2070 			;
2071 		    *p = NUL;
2072 
2073 		    /*
2074 		     * atoi(p+1) is the number of bytes before the next ^L
2075 		     * unless it is an include statement.
2076 		     */
2077 		    if (STRNCMP(p + 1, "include", 7) == 0
2078 					      && incstack_idx < INCSTACK_SIZE)
2079 		    {
2080 			// Save current "fp" and "tag_fname" in the stack.
2081 			if ((incstack[incstack_idx].etag_fname =
2082 					      vim_strsave(tag_fname)) != NULL)
2083 			{
2084 			    char_u *fullpath_ebuf;
2085 
2086 			    incstack[incstack_idx].fp = fp;
2087 			    fp = NULL;
2088 
2089 			    // Figure out "tag_fname" and "fp" to use for
2090 			    // included file.
2091 			    fullpath_ebuf = expand_tag_fname(ebuf,
2092 							    tag_fname, FALSE);
2093 			    if (fullpath_ebuf != NULL)
2094 			    {
2095 				fp = mch_fopen((char *)fullpath_ebuf, "r");
2096 				if (fp != NULL)
2097 				{
2098 				    if (STRLEN(fullpath_ebuf) > LSIZE)
2099 					  semsg(_("E430: Tag file path truncated for %s\n"), ebuf);
2100 				    vim_strncpy(tag_fname, fullpath_ebuf,
2101 								    MAXPATHL);
2102 				    ++incstack_idx;
2103 				    is_etag = 0; // we can include anything
2104 				}
2105 				vim_free(fullpath_ebuf);
2106 			    }
2107 			    if (fp == NULL)
2108 			    {
2109 				// Can't open the included file, skip it and
2110 				// restore old value of "fp".
2111 				fp = incstack[incstack_idx].fp;
2112 				vim_free(incstack[incstack_idx].etag_fname);
2113 			    }
2114 			}
2115 		    }
2116 		}
2117 		continue;
2118 	    }
2119 #endif
2120 
2121 	    /*
2122 	     * When still at the start of the file, check for Emacs tags file
2123 	     * format, and for "not sorted" flag.
2124 	     */
2125 	    if (state == TS_START)
2126 	    {
2127 		// The header ends when the line sorts below "!_TAG_".  When
2128 		// case is folded lower case letters sort before "_".
2129 		if (STRNCMP(lbuf, "!_TAG_", 6) <= 0
2130 				|| (lbuf[0] == '!' && ASCII_ISLOWER(lbuf[1])))
2131 		{
2132 		    if (STRNCMP(lbuf, "!_TAG_", 6) != 0)
2133 			// Non-header item before the header, e.g. "!" itself.
2134 			goto parse_line;
2135 
2136 		    /*
2137 		     * Read header line.
2138 		     */
2139 #ifdef FEAT_TAG_BINS
2140 		    if (STRNCMP(lbuf, "!_TAG_FILE_SORTED\t", 18) == 0)
2141 			tag_file_sorted = lbuf[18];
2142 #endif
2143 		    if (STRNCMP(lbuf, "!_TAG_FILE_ENCODING\t", 20) == 0)
2144 		    {
2145 			// Prepare to convert every line from the specified
2146 			// encoding to 'encoding'.
2147 			for (p = lbuf + 20; *p > ' ' && *p < 127; ++p)
2148 			    ;
2149 			*p = NUL;
2150 			convert_setup(&vimconv, lbuf + 20, p_enc);
2151 		    }
2152 
2153 		    // Read the next line.  Unrecognized flags are ignored.
2154 		    continue;
2155 		}
2156 
2157 		// Headers ends.
2158 
2159 #ifdef FEAT_TAG_BINS
2160 		/*
2161 		 * When there is no tag head, or ignoring case, need to do a
2162 		 * linear search.
2163 		 * When no "!_TAG_" is found, default to binary search.  If
2164 		 * the tag file isn't sorted, the second loop will find it.
2165 		 * When "!_TAG_FILE_SORTED" found: start binary search if
2166 		 * flag set.
2167 		 * For cscope, it's always linear.
2168 		 */
2169 # ifdef FEAT_CSCOPE
2170 		if (linear || use_cscope)
2171 # else
2172 		if (linear)
2173 # endif
2174 		    state = TS_LINEAR;
2175 		else if (tag_file_sorted == NUL)
2176 		    state = TS_BINARY;
2177 		else if (tag_file_sorted == '1')
2178 			state = TS_BINARY;
2179 		else if (tag_file_sorted == '2')
2180 		{
2181 		    state = TS_BINARY;
2182 		    sortic = TRUE;
2183 		    orgpat.regmatch.rm_ic = (p_ic || !noic);
2184 		}
2185 		else
2186 		    state = TS_LINEAR;
2187 
2188 		if (state == TS_BINARY && orgpat.regmatch.rm_ic && !sortic)
2189 		{
2190 		    // Binary search won't work for ignoring case, use linear
2191 		    // search.
2192 		    linear = TRUE;
2193 		    state = TS_LINEAR;
2194 		}
2195 #else
2196 		state = TS_LINEAR;
2197 #endif
2198 
2199 #ifdef FEAT_TAG_BINS
2200 		// When starting a binary search, get the size of the file and
2201 		// compute the first offset.
2202 		if (state == TS_BINARY)
2203 		{
2204 		    if (vim_fseek(fp, 0L, SEEK_END) != 0)
2205 			// can't seek, don't use binary search
2206 			state = TS_LINEAR;
2207 		    else
2208 		    {
2209 			// Get the tag file size (don't use mch_fstat(), it's
2210 			// not portable).  Don't use lseek(), it doesn't work
2211 			// properly on MacOS Catalina.
2212 			filesize = vim_ftell(fp);
2213 			vim_fseek(fp, 0L, SEEK_SET);
2214 
2215 			// Calculate the first read offset in the file.  Start
2216 			// the search in the middle of the file.
2217 			search_info.low_offset = 0;
2218 			search_info.low_char = 0;
2219 			search_info.high_offset = filesize;
2220 			search_info.curr_offset = 0;
2221 			search_info.high_char = 0xff;
2222 		    }
2223 		    continue;
2224 		}
2225 #endif
2226 	    }
2227 
2228 parse_line:
2229 	    // When the line is too long the NUL will not be in the
2230 	    // last-but-one byte (see vim_fgets()).
2231 	    // Has been reported for Mozilla JS with extremely long names.
2232 	    // In that case we need to increase lbuf_size.
2233 	    if (lbuf[lbuf_size - 2] != NUL
2234 #ifdef FEAT_CSCOPE
2235 					     && !use_cscope
2236 #endif
2237 					     )
2238 	    {
2239 		lbuf_size *= 2;
2240 		vim_free(lbuf);
2241 		lbuf = alloc(lbuf_size);
2242 		if (lbuf == NULL)
2243 		    goto findtag_end;
2244 #ifdef FEAT_TAG_BINS
2245 		// this will try the same thing again, make sure the offset is
2246 		// different
2247 		search_info.curr_offset = 0;
2248 #endif
2249 		continue;
2250 	    }
2251 
2252 	    /*
2253 	     * Figure out where the different strings are in this line.
2254 	     * For "normal" tags: Do a quick check if the tag matches.
2255 	     * This speeds up tag searching a lot!
2256 	     */
2257 	    if (orgpat.headlen
2258 #ifdef FEAT_EMACS_TAGS
2259 			    && !is_etag
2260 #endif
2261 					)
2262 	    {
2263 		CLEAR_FIELD(tagp);
2264 		tagp.tagname = lbuf;
2265 		tagp.tagname_end = vim_strchr(lbuf, TAB);
2266 		if (tagp.tagname_end == NULL)
2267 		{
2268 		    // Corrupted tag line.
2269 		    line_error = TRUE;
2270 		    break;
2271 		}
2272 
2273 		/*
2274 		 * Skip this line if the length of the tag is different and
2275 		 * there is no regexp, or the tag is too short.
2276 		 */
2277 		cmplen = (int)(tagp.tagname_end - tagp.tagname);
2278 		if (p_tl != 0 && cmplen > p_tl)	    // adjust for 'taglength'
2279 		    cmplen = p_tl;
2280 		if (has_re && orgpat.headlen < cmplen)
2281 		    cmplen = orgpat.headlen;
2282 		else if (state == TS_LINEAR && orgpat.headlen != cmplen)
2283 		    continue;
2284 
2285 #ifdef FEAT_TAG_BINS
2286 		if (state == TS_BINARY)
2287 		{
2288 		    /*
2289 		     * Simplistic check for unsorted tags file.
2290 		     */
2291 		    i = (int)tagp.tagname[0];
2292 		    if (sortic)
2293 			i = (int)TOUPPER_ASC(tagp.tagname[0]);
2294 		    if (i < search_info.low_char || i > search_info.high_char)
2295 			sort_error = TRUE;
2296 
2297 		    /*
2298 		     * Compare the current tag with the searched tag.
2299 		     */
2300 		    if (sortic)
2301 			tagcmp = tag_strnicmp(tagp.tagname, orgpat.head,
2302 							      (size_t)cmplen);
2303 		    else
2304 			tagcmp = STRNCMP(tagp.tagname, orgpat.head, cmplen);
2305 
2306 		    /*
2307 		     * A match with a shorter tag means to search forward.
2308 		     * A match with a longer tag means to search backward.
2309 		     */
2310 		    if (tagcmp == 0)
2311 		    {
2312 			if (cmplen < orgpat.headlen)
2313 			    tagcmp = -1;
2314 			else if (cmplen > orgpat.headlen)
2315 			    tagcmp = 1;
2316 		    }
2317 
2318 		    if (tagcmp == 0)
2319 		    {
2320 			// We've located the tag, now skip back and search
2321 			// forward until the first matching tag is found.
2322 			state = TS_SKIP_BACK;
2323 			search_info.match_offset = search_info.curr_offset;
2324 			continue;
2325 		    }
2326 		    if (tagcmp < 0)
2327 		    {
2328 			search_info.curr_offset = vim_ftell(fp);
2329 			if (search_info.curr_offset < search_info.high_offset)
2330 			{
2331 			    search_info.low_offset = search_info.curr_offset;
2332 			    if (sortic)
2333 				search_info.low_char =
2334 						 TOUPPER_ASC(tagp.tagname[0]);
2335 			    else
2336 				search_info.low_char = tagp.tagname[0];
2337 			    continue;
2338 			}
2339 		    }
2340 		    if (tagcmp > 0
2341 			&& search_info.curr_offset != search_info.high_offset)
2342 		    {
2343 			search_info.high_offset = search_info.curr_offset;
2344 			if (sortic)
2345 			    search_info.high_char =
2346 						 TOUPPER_ASC(tagp.tagname[0]);
2347 			else
2348 			    search_info.high_char = tagp.tagname[0];
2349 			continue;
2350 		    }
2351 
2352 		    // No match yet and are at the end of the binary search.
2353 		    break;
2354 		}
2355 		else if (state == TS_SKIP_BACK)
2356 		{
2357 		    if (MB_STRNICMP(tagp.tagname, orgpat.head, cmplen) != 0)
2358 			state = TS_STEP_FORWARD;
2359 		    else
2360 			// Have to skip back more.  Restore the curr_offset
2361 			// used, otherwise we get stuck at a long line.
2362 			search_info.curr_offset = search_info.curr_offset_used;
2363 		    continue;
2364 		}
2365 		else if (state == TS_STEP_FORWARD)
2366 		{
2367 		    if (MB_STRNICMP(tagp.tagname, orgpat.head, cmplen) != 0)
2368 		    {
2369 			if ((off_T)vim_ftell(fp) > search_info.match_offset)
2370 			    break;	// past last match
2371 			else
2372 			    continue;	// before first match
2373 		    }
2374 		}
2375 		else
2376 #endif
2377 		    // skip this match if it can't match
2378 		    if (MB_STRNICMP(tagp.tagname, orgpat.head, cmplen) != 0)
2379 		    continue;
2380 
2381 		/*
2382 		 * Can be a matching tag, isolate the file name and command.
2383 		 */
2384 		tagp.fname = tagp.tagname_end + 1;
2385 		tagp.fname_end = vim_strchr(tagp.fname, TAB);
2386 		tagp.command = tagp.fname_end + 1;
2387 		if (tagp.fname_end == NULL)
2388 		    i = FAIL;
2389 		else
2390 		    i = OK;
2391 	    }
2392 	    else
2393 		i = parse_tag_line(lbuf,
2394 #ifdef FEAT_EMACS_TAGS
2395 				       is_etag,
2396 #endif
2397 					       &tagp);
2398 	    if (i == FAIL)
2399 	    {
2400 		line_error = TRUE;
2401 		break;
2402 	    }
2403 
2404 #ifdef FEAT_EMACS_TAGS
2405 	    if (is_etag)
2406 		tagp.fname = ebuf;
2407 #endif
2408 	    /*
2409 	     * First try matching with the pattern literally (also when it is
2410 	     * a regexp).
2411 	     */
2412 	    cmplen = (int)(tagp.tagname_end - tagp.tagname);
2413 	    if (p_tl != 0 && cmplen > p_tl)	    // adjust for 'taglength'
2414 		cmplen = p_tl;
2415 	    // if tag length does not match, don't try comparing
2416 	    if (orgpat.len != cmplen)
2417 		match = FALSE;
2418 	    else
2419 	    {
2420 		if (orgpat.regmatch.rm_ic)
2421 		{
2422 		    match = (MB_STRNICMP(tagp.tagname, orgpat.pat, cmplen) == 0);
2423 		    if (match)
2424 			match_no_ic = (STRNCMP(tagp.tagname, orgpat.pat,
2425 								cmplen) == 0);
2426 		}
2427 		else
2428 		    match = (STRNCMP(tagp.tagname, orgpat.pat, cmplen) == 0);
2429 	    }
2430 
2431 	    /*
2432 	     * Has a regexp: Also find tags matching regexp.
2433 	     */
2434 	    match_re = FALSE;
2435 	    if (!match && orgpat.regmatch.regprog != NULL)
2436 	    {
2437 		int	cc;
2438 
2439 		cc = *tagp.tagname_end;
2440 		*tagp.tagname_end = NUL;
2441 		match = vim_regexec(&orgpat.regmatch, tagp.tagname, (colnr_T)0);
2442 		if (match)
2443 		{
2444 		    matchoff = (int)(orgpat.regmatch.startp[0] - tagp.tagname);
2445 		    if (orgpat.regmatch.rm_ic)
2446 		    {
2447 			orgpat.regmatch.rm_ic = FALSE;
2448 			match_no_ic = vim_regexec(&orgpat.regmatch, tagp.tagname,
2449 								  (colnr_T)0);
2450 			orgpat.regmatch.rm_ic = TRUE;
2451 		    }
2452 		}
2453 		*tagp.tagname_end = cc;
2454 		match_re = TRUE;
2455 	    }
2456 
2457 	    /*
2458 	     * If a match is found, add it to ht_match[] and ga_match[].
2459 	     */
2460 	    if (match)
2461 	    {
2462 		int len = 0;
2463 
2464 #ifdef FEAT_CSCOPE
2465 		if (use_cscope)
2466 		{
2467 		    // Don't change the ordering, always use the same table.
2468 		    mtt = MT_GL_OTH;
2469 		}
2470 		else
2471 #endif
2472 		{
2473 		    // Decide in which array to store this match.
2474 		    is_current = test_for_current(
2475 #ifdef FEAT_EMACS_TAGS
2476 			    is_etag,
2477 #endif
2478 				     tagp.fname, tagp.fname_end, tag_fname,
2479 				     buf_ffname);
2480 #ifdef FEAT_EMACS_TAGS
2481 		    is_static = FALSE;
2482 		    if (!is_etag)	// emacs tags are never static
2483 #endif
2484 			is_static = test_for_static(&tagp);
2485 
2486 		    // decide in which of the sixteen tables to store this
2487 		    // match
2488 		    if (is_static)
2489 		    {
2490 			if (is_current)
2491 			    mtt = MT_ST_CUR;
2492 			else
2493 			    mtt = MT_ST_OTH;
2494 		    }
2495 		    else
2496 		    {
2497 			if (is_current)
2498 			    mtt = MT_GL_CUR;
2499 			else
2500 			    mtt = MT_GL_OTH;
2501 		    }
2502 		    if (orgpat.regmatch.rm_ic && !match_no_ic)
2503 			mtt += MT_IC_OFF;
2504 		    if (match_re)
2505 			mtt += MT_RE_OFF;
2506 		}
2507 
2508 		/*
2509 		 * Add the found match in ht_match[mtt] and ga_match[mtt].
2510 		 * Store the info we need later, which depends on the kind of
2511 		 * tags we are dealing with.
2512 		 */
2513 		if (help_only)
2514 		{
2515 #ifdef FEAT_MULTI_LANG
2516 # define ML_EXTRA 3
2517 #else
2518 # define ML_EXTRA 0
2519 #endif
2520 		    /*
2521 		     * Append the help-heuristic number after the tagname, for
2522 		     * sorting it later.  The heuristic is ignored for
2523 		     * detecting duplicates.
2524 		     * The format is {tagname}@{lang}NUL{heuristic}NUL
2525 		     */
2526 		    *tagp.tagname_end = NUL;
2527 		    len = (int)(tagp.tagname_end - tagp.tagname);
2528 		    mfp = alloc(sizeof(char_u) + len + 10 + ML_EXTRA + 1);
2529 		    if (mfp != NULL)
2530 		    {
2531 			int heuristic;
2532 
2533 			p = mfp;
2534 			STRCPY(p, tagp.tagname);
2535 #ifdef FEAT_MULTI_LANG
2536 			p[len] = '@';
2537 			STRCPY(p + len + 1, help_lang);
2538 #endif
2539 
2540 			heuristic = help_heuristic(tagp.tagname,
2541 				    match_re ? matchoff : 0, !match_no_ic);
2542 #ifdef FEAT_MULTI_LANG
2543 			heuristic += help_pri;
2544 #endif
2545 			sprintf((char *)p + len + 1 + ML_EXTRA, "%06d",
2546 							       heuristic);
2547 		    }
2548 		    *tagp.tagname_end = TAB;
2549 		}
2550 		else if (name_only)
2551 		{
2552 		    if (get_it_again)
2553 		    {
2554 			char_u *temp_end = tagp.command;
2555 
2556 			if (*temp_end == '/')
2557 			    while (*temp_end && *temp_end != '\r'
2558 				    && *temp_end != '\n'
2559 				    && *temp_end != '$')
2560 				temp_end++;
2561 
2562 			if (tagp.command + 2 < temp_end)
2563 			{
2564 			    len = (int)(temp_end - tagp.command - 2);
2565 			    mfp = alloc(len + 2);
2566 			    if (mfp != NULL)
2567 				vim_strncpy(mfp, tagp.command + 2, len);
2568 			}
2569 			else
2570 			    mfp = NULL;
2571 			get_it_again = FALSE;
2572 		    }
2573 		    else
2574 		    {
2575 			len = (int)(tagp.tagname_end - tagp.tagname);
2576 			mfp = alloc(sizeof(char_u) + len + 1);
2577 			if (mfp != NULL)
2578 			    vim_strncpy(mfp, tagp.tagname, len);
2579 
2580 			// if wanted, re-read line to get long form too
2581 			if (State & INSERT)
2582 			    get_it_again = p_sft;
2583 		    }
2584 		}
2585 		else
2586 		{
2587 		    size_t tag_fname_len = STRLEN(tag_fname);
2588 #ifdef FEAT_EMACS_TAGS
2589 		    size_t ebuf_len = 0;
2590 #endif
2591 
2592 		    // Save the tag in a buffer.
2593 		    // Use 0x02 to separate fields (Can't use NUL because the
2594 		    // hash key is terminated by NUL, or Ctrl_A because that is
2595 		    // part of some Emacs tag files -- see parse_tag_line).
2596 		    // Emacs tag: <mtt><tag_fname><0x02><ebuf><0x02><lbuf><NUL>
2597 		    // other tag: <mtt><tag_fname><0x02><0x02><lbuf><NUL>
2598 		    // without Emacs tags: <mtt><tag_fname><0x02><lbuf><NUL>
2599 		    // Here <mtt> is the "mtt" value plus 1 to avoid NUL.
2600 		    len = (int)tag_fname_len + (int)STRLEN(lbuf) + 3;
2601 #ifdef FEAT_EMACS_TAGS
2602 		    if (is_etag)
2603 		    {
2604 			ebuf_len = STRLEN(ebuf);
2605 			len += (int)ebuf_len + 1;
2606 		    }
2607 		    else
2608 			++len;
2609 #endif
2610 		    mfp = alloc(sizeof(char_u) + len + 1);
2611 		    if (mfp != NULL)
2612 		    {
2613 			p = mfp;
2614 			p[0] = mtt + 1;
2615 			STRCPY(p + 1, tag_fname);
2616 #ifdef BACKSLASH_IN_FILENAME
2617 			// Ignore differences in slashes, avoid adding
2618 			// both path/file and path\file.
2619 			slash_adjust(p + 1);
2620 #endif
2621 			p[tag_fname_len + 1] = TAG_SEP;
2622 			s = p + 1 + tag_fname_len + 1;
2623 #ifdef FEAT_EMACS_TAGS
2624 			if (is_etag)
2625 			{
2626 			    STRCPY(s, ebuf);
2627 			    s[ebuf_len] = TAG_SEP;
2628 			    s += ebuf_len + 1;
2629 			}
2630 			else
2631 			    *s++ = TAG_SEP;
2632 #endif
2633 			STRCPY(s, lbuf);
2634 		    }
2635 		}
2636 
2637 		if (mfp != NULL)
2638 		{
2639 		    hashitem_T	*hi;
2640 
2641 		    /*
2642 		     * Don't add identical matches.
2643 		     * Add all cscope tags, because they are all listed.
2644 		     * "mfp" is used as a hash key, there is a NUL byte to end
2645 		     * the part that matters for comparing, more bytes may
2646 		     * follow after it.  E.g. help tags store the priority
2647 		     * after the NUL.
2648 		     */
2649 #ifdef FEAT_CSCOPE
2650 		    if (use_cscope)
2651 			hash++;
2652 		    else
2653 #endif
2654 			hash = hash_hash(mfp);
2655 		    hi = hash_lookup(&ht_match[mtt], mfp, hash);
2656 		    if (HASHITEM_EMPTY(hi))
2657 		    {
2658 			if (hash_add_item(&ht_match[mtt], hi, mfp, hash)
2659 								       == FAIL
2660 				       || ga_grow(&ga_match[mtt], 1) != OK)
2661 			{
2662 			    // Out of memory! Just forget about the rest.
2663 			    retval = OK;
2664 			    stop_searching = TRUE;
2665 			    break;
2666 			}
2667 			else
2668 			{
2669 			    ((char_u **)(ga_match[mtt].ga_data))
2670 						[ga_match[mtt].ga_len++] = mfp;
2671 			    ++match_count;
2672 			}
2673 		    }
2674 		    else
2675 			// duplicate tag, drop it
2676 			vim_free(mfp);
2677 		}
2678 	    }
2679 #ifdef FEAT_CSCOPE
2680 	    if (use_cscope && eof)
2681 		break;
2682 #endif
2683 	} // forever
2684 
2685 	if (line_error)
2686 	{
2687 	    semsg(_("E431: Format error in tags file \"%s\""), tag_fname);
2688 #ifdef FEAT_CSCOPE
2689 	    if (!use_cscope)
2690 #endif
2691 		semsg(_("Before byte %ld"), (long)vim_ftell(fp));
2692 	    stop_searching = TRUE;
2693 	    line_error = FALSE;
2694 	}
2695 
2696 #ifdef FEAT_CSCOPE
2697 	if (!use_cscope)
2698 #endif
2699 	    fclose(fp);
2700 #ifdef FEAT_EMACS_TAGS
2701 	while (incstack_idx)
2702 	{
2703 	    --incstack_idx;
2704 	    fclose(incstack[incstack_idx].fp);
2705 	    vim_free(incstack[incstack_idx].etag_fname);
2706 	}
2707 #endif
2708 	if (vimconv.vc_type != CONV_NONE)
2709 	    convert_setup(&vimconv, NULL, NULL);
2710 
2711 #ifdef FEAT_TAG_BINS
2712 	tag_file_sorted = NUL;
2713 	if (sort_error)
2714 	{
2715 	    semsg(_("E432: Tags file not sorted: %s"), tag_fname);
2716 	    sort_error = FALSE;
2717 	}
2718 #endif
2719 
2720 	/*
2721 	 * Stop searching if sufficient tags have been found.
2722 	 */
2723 	if (match_count >= mincount)
2724 	{
2725 	    retval = OK;
2726 	    stop_searching = TRUE;
2727 	}
2728 
2729 #ifdef FEAT_CSCOPE
2730 	if (stop_searching || use_cscope)
2731 #else
2732 	if (stop_searching)
2733 #endif
2734 	    break;
2735 
2736       } // end of for-each-file loop
2737 
2738 #ifdef FEAT_CSCOPE
2739 	if (!use_cscope)
2740 #endif
2741 	    tagname_free(&tn);
2742 
2743 #ifdef FEAT_TAG_BINS
2744       // stop searching when already did a linear search, or when TAG_NOIC
2745       // used, and 'ignorecase' not set or already did case-ignore search
2746       if (stop_searching || linear || (!p_ic && noic) || orgpat.regmatch.rm_ic)
2747 	  break;
2748 # ifdef FEAT_CSCOPE
2749       if (use_cscope)
2750 	  break;
2751 # endif
2752       orgpat.regmatch.rm_ic = TRUE;	// try another time while ignoring case
2753     }
2754 #endif
2755 
2756     if (!stop_searching)
2757     {
2758 	if (!did_open && verbose)	// never opened any tags file
2759 	    emsg(_("E433: No tags file"));
2760 	retval = OK;		// It's OK even when no tag found
2761     }
2762 
2763 findtag_end:
2764     vim_free(lbuf);
2765     vim_regfree(orgpat.regmatch.regprog);
2766     vim_free(tag_fname);
2767 #ifdef FEAT_EMACS_TAGS
2768     vim_free(ebuf);
2769 #endif
2770 
2771     /*
2772      * Move the matches from the ga_match[] arrays into one list of
2773      * matches.  When retval == FAIL, free the matches.
2774      */
2775     if (retval == FAIL)
2776 	match_count = 0;
2777 
2778     if (match_count > 0)
2779 	matches = ALLOC_MULT(char_u *, match_count);
2780     else
2781 	matches = NULL;
2782     match_count = 0;
2783     for (mtt = 0; mtt < MT_COUNT; ++mtt)
2784     {
2785 	for (i = 0; i < ga_match[mtt].ga_len; ++i)
2786 	{
2787 	    mfp = ((char_u **)(ga_match[mtt].ga_data))[i];
2788 	    if (matches == NULL)
2789 		vim_free(mfp);
2790 	    else
2791 	    {
2792 		if (!name_only)
2793 		{
2794 		    // Change mtt back to zero-based.
2795 		    *mfp = *mfp - 1;
2796 
2797 		    // change the TAG_SEP back to NUL
2798 		    for (p = mfp + 1; *p != NUL; ++p)
2799 			if (*p == TAG_SEP)
2800 			    *p = NUL;
2801 		}
2802 		matches[match_count++] = (char_u *)mfp;
2803 	    }
2804 	}
2805 
2806 	ga_clear(&ga_match[mtt]);
2807 	hash_clear(&ht_match[mtt]);
2808     }
2809 
2810     *matchesp = matches;
2811     *num_matches = match_count;
2812 
2813     curbuf->b_help = help_save;
2814 #ifdef FEAT_MULTI_LANG
2815     vim_free(saved_pat);
2816 #endif
2817 
2818     p_ic = save_p_ic;
2819 
2820     return retval;
2821 }
2822 
2823 static garray_T tag_fnames = GA_EMPTY;
2824 
2825 /*
2826  * Callback function for finding all "tags" and "tags-??" files in
2827  * 'runtimepath' doc directories.
2828  */
2829     static void
2830 found_tagfile_cb(char_u *fname, void *cookie UNUSED)
2831 {
2832     if (ga_grow(&tag_fnames, 1) == OK)
2833     {
2834 	char_u	*tag_fname = vim_strsave(fname);
2835 
2836 #ifdef BACKSLASH_IN_FILENAME
2837 	slash_adjust(tag_fname);
2838 #endif
2839 	simplify_filename(tag_fname);
2840 	((char_u **)(tag_fnames.ga_data))[tag_fnames.ga_len++] = tag_fname;
2841     }
2842 }
2843 
2844 #if defined(EXITFREE) || defined(PROTO)
2845     void
2846 free_tag_stuff(void)
2847 {
2848     ga_clear_strings(&tag_fnames);
2849     if (curwin != NULL)
2850 	do_tag(NULL, DT_FREE, 0, 0, 0);
2851     tag_freematch();
2852 
2853 # if defined(FEAT_QUICKFIX)
2854     tagstack_clear_entry(&ptag_entry);
2855 # endif
2856 }
2857 #endif
2858 
2859 /*
2860  * Get the next name of a tag file from the tag file list.
2861  * For help files, use "tags" file only.
2862  *
2863  * Return FAIL if no more tag file names, OK otherwise.
2864  */
2865     int
2866 get_tagfname(
2867     tagname_T	*tnp,	// holds status info
2868     int		first,	// TRUE when first file name is wanted
2869     char_u	*buf)	// pointer to buffer of MAXPATHL chars
2870 {
2871     char_u		*fname = NULL;
2872     char_u		*r_ptr;
2873     int			i;
2874 
2875     if (first)
2876 	CLEAR_POINTER(tnp);
2877 
2878     if (curbuf->b_help)
2879     {
2880 	/*
2881 	 * For help files it's done in a completely different way:
2882 	 * Find "doc/tags" and "doc/tags-??" in all directories in
2883 	 * 'runtimepath'.
2884 	 */
2885 	if (first)
2886 	{
2887 	    ga_clear_strings(&tag_fnames);
2888 	    ga_init2(&tag_fnames, (int)sizeof(char_u *), 10);
2889 	    do_in_runtimepath((char_u *)
2890 #ifdef FEAT_MULTI_LANG
2891 # ifdef VMS
2892 		    // Functions decc$to_vms() and decc$translate_vms() crash
2893 		    // on some VMS systems with wildcards "??".  Seems ECO
2894 		    // patches do fix the problem in C RTL, but we can't use
2895 		    // an #ifdef for that.
2896 		    "doc/tags doc/tags-*"
2897 # else
2898 		    "doc/tags doc/tags-??"
2899 # endif
2900 #else
2901 		    "doc/tags"
2902 #endif
2903 					   , DIP_ALL, found_tagfile_cb, NULL);
2904 	}
2905 
2906 	if (tnp->tn_hf_idx >= tag_fnames.ga_len)
2907 	{
2908 	    // Not found in 'runtimepath', use 'helpfile', if it exists and
2909 	    // wasn't used yet, replacing "help.txt" with "tags".
2910 	    if (tnp->tn_hf_idx > tag_fnames.ga_len || *p_hf == NUL)
2911 		return FAIL;
2912 	    ++tnp->tn_hf_idx;
2913 	    STRCPY(buf, p_hf);
2914 	    STRCPY(gettail(buf), "tags");
2915 #ifdef BACKSLASH_IN_FILENAME
2916 	    slash_adjust(buf);
2917 #endif
2918 	    simplify_filename(buf);
2919 
2920 	    for (i = 0; i < tag_fnames.ga_len; ++i)
2921 		if (STRCMP(buf, ((char_u **)(tag_fnames.ga_data))[i]) == 0)
2922 		    return FAIL; // avoid duplicate file names
2923 	}
2924 	else
2925 	    vim_strncpy(buf, ((char_u **)(tag_fnames.ga_data))[
2926 					     tnp->tn_hf_idx++], MAXPATHL - 1);
2927 	return OK;
2928     }
2929 
2930     if (first)
2931     {
2932 	// Init.  We make a copy of 'tags', because autocommands may change
2933 	// the value without notifying us.
2934 	tnp->tn_tags = vim_strsave((*curbuf->b_p_tags != NUL)
2935 						 ? curbuf->b_p_tags : p_tags);
2936 	if (tnp->tn_tags == NULL)
2937 	    return FAIL;
2938 	tnp->tn_np = tnp->tn_tags;
2939     }
2940 
2941     /*
2942      * Loop until we have found a file name that can be used.
2943      * There are two states:
2944      * tnp->tn_did_filefind_init == FALSE: setup for next part in 'tags'.
2945      * tnp->tn_did_filefind_init == TRUE: find next file in this part.
2946      */
2947     for (;;)
2948     {
2949 	if (tnp->tn_did_filefind_init)
2950 	{
2951 	    fname = vim_findfile(tnp->tn_search_ctx);
2952 	    if (fname != NULL)
2953 		break;
2954 
2955 	    tnp->tn_did_filefind_init = FALSE;
2956 	}
2957 	else
2958 	{
2959 	    char_u  *filename = NULL;
2960 
2961 	    // Stop when used all parts of 'tags'.
2962 	    if (*tnp->tn_np == NUL)
2963 	    {
2964 		vim_findfile_cleanup(tnp->tn_search_ctx);
2965 		tnp->tn_search_ctx = NULL;
2966 		return FAIL;
2967 	    }
2968 
2969 	    /*
2970 	     * Copy next file name into buf.
2971 	     */
2972 	    buf[0] = NUL;
2973 	    (void)copy_option_part(&tnp->tn_np, buf, MAXPATHL - 1, " ,");
2974 
2975 #ifdef FEAT_PATH_EXTRA
2976 	    r_ptr = vim_findfile_stopdir(buf);
2977 #else
2978 	    r_ptr = NULL;
2979 #endif
2980 	    // move the filename one char forward and truncate the
2981 	    // filepath with a NUL
2982 	    filename = gettail(buf);
2983 	    STRMOVE(filename + 1, filename);
2984 	    *filename++ = NUL;
2985 
2986 	    tnp->tn_search_ctx = vim_findfile_init(buf, filename,
2987 		    r_ptr, 100,
2988 		    FALSE,	   // don't free visited list
2989 		    FINDFILE_FILE, // we search for a file
2990 		    tnp->tn_search_ctx, TRUE, curbuf->b_ffname);
2991 	    if (tnp->tn_search_ctx != NULL)
2992 		tnp->tn_did_filefind_init = TRUE;
2993 	}
2994     }
2995 
2996     STRCPY(buf, fname);
2997     vim_free(fname);
2998     return OK;
2999 }
3000 
3001 /*
3002  * Free the contents of a tagname_T that was filled by get_tagfname().
3003  */
3004     void
3005 tagname_free(tagname_T *tnp)
3006 {
3007     vim_free(tnp->tn_tags);
3008     vim_findfile_cleanup(tnp->tn_search_ctx);
3009     tnp->tn_search_ctx = NULL;
3010     ga_clear_strings(&tag_fnames);
3011 }
3012 
3013 /*
3014  * Parse one line from the tags file. Find start/end of tag name, start/end of
3015  * file name and start of search pattern.
3016  *
3017  * If is_etag is TRUE, tagp->fname and tagp->fname_end are not set.
3018  *
3019  * Return FAIL if there is a format error in this line, OK otherwise.
3020  */
3021     static int
3022 parse_tag_line(
3023     char_u	*lbuf,		// line to be parsed
3024 #ifdef FEAT_EMACS_TAGS
3025     int		is_etag,
3026 #endif
3027     tagptrs_T	*tagp)
3028 {
3029     char_u	*p;
3030 
3031 #ifdef FEAT_EMACS_TAGS
3032     char_u	*p_7f;
3033 
3034     if (is_etag)
3035     {
3036 	/*
3037 	 * There are two formats for an emacs tag line:
3038 	 * 1:  struct EnvBase ^?EnvBase^A139,4627
3039 	 * 2: #define	ARPB_WILD_WORLD ^?153,5194
3040 	 */
3041 	p_7f = vim_strchr(lbuf, 0x7f);
3042 	if (p_7f == NULL)
3043 	{
3044 etag_fail:
3045 	    if (vim_strchr(lbuf, '\n') == NULL)
3046 	    {
3047 		// Truncated line.  Ignore it.
3048 		if (p_verbose >= 5)
3049 		{
3050 		    verbose_enter();
3051 		    msg(_("Ignoring long line in tags file"));
3052 		    verbose_leave();
3053 		}
3054 		tagp->command = lbuf;
3055 		tagp->tagname = lbuf;
3056 		tagp->tagname_end = lbuf;
3057 		return OK;
3058 	    }
3059 	    return FAIL;
3060 	}
3061 
3062 	// Find ^A.  If not found the line number is after the 0x7f
3063 	p = vim_strchr(p_7f, Ctrl_A);
3064 	if (p == NULL)
3065 	    p = p_7f + 1;
3066 	else
3067 	    ++p;
3068 
3069 	if (!VIM_ISDIGIT(*p))	    // check for start of line number
3070 	    goto etag_fail;
3071 	tagp->command = p;
3072 
3073 
3074 	if (p[-1] == Ctrl_A)	    // first format: explicit tagname given
3075 	{
3076 	    tagp->tagname = p_7f + 1;
3077 	    tagp->tagname_end = p - 1;
3078 	}
3079 	else			    // second format: isolate tagname
3080 	{
3081 	    // find end of tagname
3082 	    for (p = p_7f - 1; !vim_iswordc(*p); --p)
3083 		if (p == lbuf)
3084 		    goto etag_fail;
3085 	    tagp->tagname_end = p + 1;
3086 	    while (p >= lbuf && vim_iswordc(*p))
3087 		--p;
3088 	    tagp->tagname = p + 1;
3089 	}
3090     }
3091     else	// not an Emacs tag
3092     {
3093 #endif
3094 	// Isolate the tagname, from lbuf up to the first white
3095 	tagp->tagname = lbuf;
3096 	p = vim_strchr(lbuf, TAB);
3097 	if (p == NULL)
3098 	    return FAIL;
3099 	tagp->tagname_end = p;
3100 
3101 	// Isolate file name, from first to second white space
3102 	if (*p != NUL)
3103 	    ++p;
3104 	tagp->fname = p;
3105 	p = vim_strchr(p, TAB);
3106 	if (p == NULL)
3107 	    return FAIL;
3108 	tagp->fname_end = p;
3109 
3110 	// find start of search command, after second white space
3111 	if (*p != NUL)
3112 	    ++p;
3113 	if (*p == NUL)
3114 	    return FAIL;
3115 	tagp->command = p;
3116 #ifdef FEAT_EMACS_TAGS
3117     }
3118 #endif
3119 
3120     return OK;
3121 }
3122 
3123 /*
3124  * Check if tagname is a static tag
3125  *
3126  * Static tags produced by the older ctags program have the format:
3127  *	'file:tag  file  /pattern'.
3128  * This is only recognized when both occurrence of 'file' are the same, to
3129  * avoid recognizing "string::string" or ":exit".
3130  *
3131  * Static tags produced by the new ctags program have the format:
3132  *	'tag  file  /pattern/;"<Tab>file:'	    "
3133  *
3134  * Return TRUE if it is a static tag and adjust *tagname to the real tag.
3135  * Return FALSE if it is not a static tag.
3136  */
3137     static int
3138 test_for_static(tagptrs_T *tagp)
3139 {
3140     char_u	*p;
3141 
3142     /*
3143      * Check for new style static tag ":...<Tab>file:[<Tab>...]"
3144      */
3145     p = tagp->command;
3146     while ((p = vim_strchr(p, '\t')) != NULL)
3147     {
3148 	++p;
3149 	if (STRNCMP(p, "file:", 5) == 0)
3150 	    return TRUE;
3151     }
3152 
3153     return FALSE;
3154 }
3155 
3156 /*
3157  * Returns the length of a matching tag line.
3158  */
3159     static size_t
3160 matching_line_len(char_u *lbuf)
3161 {
3162     char_u	*p = lbuf + 1;
3163 
3164     // does the same thing as parse_match()
3165     p += STRLEN(p) + 1;
3166 #ifdef FEAT_EMACS_TAGS
3167     p += STRLEN(p) + 1;
3168 #endif
3169     return (p - lbuf) + STRLEN(p);
3170 }
3171 
3172 /*
3173  * Parse a line from a matching tag.  Does not change the line itself.
3174  *
3175  * The line that we get looks like this:
3176  * Emacs tag: <mtt><tag_fname><NUL><ebuf><NUL><lbuf>
3177  * other tag: <mtt><tag_fname><NUL><NUL><lbuf>
3178  * without Emacs tags: <mtt><tag_fname><NUL><lbuf>
3179  *
3180  * Return OK or FAIL.
3181  */
3182     static int
3183 parse_match(
3184     char_u	*lbuf,	    // input: matching line
3185     tagptrs_T	*tagp)	    // output: pointers into the line
3186 {
3187     int		retval;
3188     char_u	*p;
3189     char_u	*pc, *pt;
3190 
3191     tagp->tag_fname = lbuf + 1;
3192     lbuf += STRLEN(tagp->tag_fname) + 2;
3193 #ifdef FEAT_EMACS_TAGS
3194     if (*lbuf)
3195     {
3196 	tagp->is_etag = TRUE;
3197 	tagp->fname = lbuf;
3198 	lbuf += STRLEN(lbuf);
3199 	tagp->fname_end = lbuf++;
3200     }
3201     else
3202     {
3203 	tagp->is_etag = FALSE;
3204 	++lbuf;
3205     }
3206 #endif
3207 
3208     // Find search pattern and the file name for non-etags.
3209     retval = parse_tag_line(lbuf,
3210 #ifdef FEAT_EMACS_TAGS
3211 			tagp->is_etag,
3212 #endif
3213 			tagp);
3214 
3215     tagp->tagkind = NULL;
3216     tagp->user_data = NULL;
3217     tagp->tagline = 0;
3218     tagp->command_end = NULL;
3219 
3220     if (retval == OK)
3221     {
3222 	// Try to find a kind field: "kind:<kind>" or just "<kind>"
3223 	p = tagp->command;
3224 	if (find_extra(&p) == OK)
3225 	{
3226 	    if (p > tagp->command && p[-1] == '|')
3227 		tagp->command_end = p - 1;  // drop trailing bar
3228 	    else
3229 		tagp->command_end = p;
3230 	    p += 2;	// skip ";\""
3231 	    if (*p++ == TAB)
3232 		// Accept ASCII alphabetic kind characters and any multi-byte
3233 		// character.
3234 		while (ASCII_ISALPHA(*p) || mb_ptr2len(p) > 1)
3235 		{
3236 		    if (STRNCMP(p, "kind:", 5) == 0)
3237 			tagp->tagkind = p + 5;
3238 		    else if (STRNCMP(p, "user_data:", 10) == 0)
3239 			tagp->user_data = p + 10;
3240 		    else if (STRNCMP(p, "line:", 5) == 0)
3241 			tagp->tagline = atoi((char *)p + 5);
3242 		    if (tagp->tagkind != NULL && tagp->user_data != NULL)
3243 			break;
3244 		    pc = vim_strchr(p, ':');
3245 		    pt = vim_strchr(p, '\t');
3246 		    if (pc == NULL || (pt != NULL && pc > pt))
3247 			tagp->tagkind = p;
3248 		    if (pt == NULL)
3249 			break;
3250 		    p = pt;
3251 		    MB_PTR_ADV(p);
3252 		}
3253 	}
3254 	if (tagp->tagkind != NULL)
3255 	{
3256 	    for (p = tagp->tagkind;
3257 			    *p && *p != '\t' && *p != '\r' && *p != '\n'; MB_PTR_ADV(p))
3258 		;
3259 	    tagp->tagkind_end = p;
3260 	}
3261 	if (tagp->user_data != NULL)
3262 	{
3263 	    for (p = tagp->user_data;
3264 			    *p && *p != '\t' && *p != '\r' && *p != '\n'; MB_PTR_ADV(p))
3265 		;
3266 	    tagp->user_data_end = p;
3267 	}
3268     }
3269     return retval;
3270 }
3271 
3272 /*
3273  * Find out the actual file name of a tag.  Concatenate the tags file name
3274  * with the matching tag file name.
3275  * Returns an allocated string or NULL (out of memory).
3276  */
3277     static char_u *
3278 tag_full_fname(tagptrs_T *tagp)
3279 {
3280     char_u	*fullname;
3281     int		c;
3282 
3283 #ifdef FEAT_EMACS_TAGS
3284     if (tagp->is_etag)
3285 	c = 0;	    // to shut up GCC
3286     else
3287 #endif
3288     {
3289 	c = *tagp->fname_end;
3290 	*tagp->fname_end = NUL;
3291     }
3292     fullname = expand_tag_fname(tagp->fname, tagp->tag_fname, FALSE);
3293 
3294 #ifdef FEAT_EMACS_TAGS
3295     if (!tagp->is_etag)
3296 #endif
3297 	*tagp->fname_end = c;
3298 
3299     return fullname;
3300 }
3301 
3302 /*
3303  * Jump to a tag that has been found in one of the tag files
3304  *
3305  * returns OK for success, NOTAGFILE when file not found, FAIL otherwise.
3306  */
3307     static int
3308 jumpto_tag(
3309     char_u	*lbuf_arg,	// line from the tags file for this tag
3310     int		forceit,	// :ta with !
3311     int		keep_help)	// keep help flag (FALSE for cscope)
3312 {
3313     int		save_secure;
3314     int		save_magic;
3315     int		save_p_ws, save_p_scs, save_p_ic;
3316     linenr_T	save_lnum;
3317     char_u	*str;
3318     char_u	*pbuf;			// search pattern buffer
3319     char_u	*pbuf_end;
3320     char_u	*tofree_fname = NULL;
3321     char_u	*fname;
3322     tagptrs_T	tagp;
3323     int		retval = FAIL;
3324     int		getfile_result = GETFILE_UNUSED;
3325     int		search_options;
3326 #ifdef FEAT_SEARCH_EXTRA
3327     int		save_no_hlsearch;
3328 #endif
3329 #if defined(FEAT_QUICKFIX)
3330     win_T	*curwin_save = NULL;
3331 #endif
3332     char_u	*full_fname = NULL;
3333 #ifdef FEAT_FOLDING
3334     int		old_KeyTyped = KeyTyped;    // getting the file may reset it
3335 #endif
3336     size_t	len;
3337     char_u	*lbuf;
3338 
3339     // Make a copy of the line, it can become invalid when an autocommand calls
3340     // back here recursively.
3341     len = matching_line_len(lbuf_arg) + 1;
3342     lbuf = alloc(len);
3343     if (lbuf != NULL)
3344 	mch_memmove(lbuf, lbuf_arg, len);
3345 
3346     pbuf = alloc(LSIZE);
3347 
3348     // parse the match line into the tagp structure
3349     if (pbuf == NULL || lbuf == NULL || parse_match(lbuf, &tagp) == FAIL)
3350     {
3351 	tagp.fname_end = NULL;
3352 	goto erret;
3353     }
3354 
3355     // truncate the file name, so it can be used as a string
3356     *tagp.fname_end = NUL;
3357     fname = tagp.fname;
3358 
3359     // copy the command to pbuf[], remove trailing CR/NL
3360     str = tagp.command;
3361     for (pbuf_end = pbuf; *str && *str != '\n' && *str != '\r'; )
3362     {
3363 #ifdef FEAT_EMACS_TAGS
3364 	if (tagp.is_etag && *str == ',')// stop at ',' after line number
3365 	    break;
3366 #endif
3367 	*pbuf_end++ = *str++;
3368 	if (pbuf_end - pbuf + 1 >= LSIZE)
3369 	    break;
3370     }
3371     *pbuf_end = NUL;
3372 
3373 #ifdef FEAT_EMACS_TAGS
3374     if (!tagp.is_etag)
3375 #endif
3376     {
3377 	/*
3378 	 * Remove the "<Tab>fieldname:value" stuff; we don't need it here.
3379 	 */
3380 	str = pbuf;
3381 	if (find_extra(&str) == OK)
3382 	{
3383 	    pbuf_end = str;
3384 	    *pbuf_end = NUL;
3385 	}
3386     }
3387 
3388     /*
3389      * Expand file name, when needed (for environment variables).
3390      * If 'tagrelative' option set, may change file name.
3391      */
3392     fname = expand_tag_fname(fname, tagp.tag_fname, TRUE);
3393     if (fname == NULL)
3394 	goto erret;
3395     tofree_fname = fname;	// free() it later
3396 
3397     /*
3398      * Check if the file with the tag exists before abandoning the current
3399      * file.  Also accept a file name for which there is a matching BufReadCmd
3400      * autocommand event (e.g., http://sys/file).
3401      */
3402     if (mch_getperm(fname) < 0 && !has_autocmd(EVENT_BUFREADCMD, fname, NULL))
3403     {
3404 	retval = NOTAGFILE;
3405 	vim_free(nofile_fname);
3406 	nofile_fname = vim_strsave(fname);
3407 	if (nofile_fname == NULL)
3408 	    nofile_fname = empty_option;
3409 	goto erret;
3410     }
3411 
3412     ++RedrawingDisabled;
3413 
3414 #ifdef FEAT_GUI
3415     need_mouse_correct = TRUE;
3416 #endif
3417 
3418 #if defined(FEAT_QUICKFIX)
3419     if (g_do_tagpreview != 0)
3420     {
3421 	postponed_split = 0;	// don't split again below
3422 	curwin_save = curwin;	// Save current window
3423 
3424 	/*
3425 	 * If we are reusing a window, we may change dir when
3426 	 * entering it (autocommands) so turn the tag filename
3427 	 * into a fullpath
3428 	 */
3429 	if (!curwin->w_p_pvw)
3430 	{
3431 	    full_fname = FullName_save(fname, FALSE);
3432 	    fname = full_fname;
3433 
3434 	    /*
3435 	     * Make the preview window the current window.
3436 	     * Open a preview window when needed.
3437 	     */
3438 	    prepare_tagpreview(TRUE, TRUE, FALSE);
3439 	}
3440     }
3441 
3442     // If it was a CTRL-W CTRL-] command split window now.  For ":tab tag"
3443     // open a new tab page.
3444     if (postponed_split && (swb_flags & (SWB_USEOPEN | SWB_USETAB)))
3445     {
3446 	buf_T *existing_buf = buflist_findname_exp(fname);
3447 
3448 	if (existing_buf != NULL)
3449 	{
3450 	    win_T *wp = NULL;
3451 
3452 	    if (swb_flags & SWB_USEOPEN)
3453 		wp = buf_jump_open_win(existing_buf);
3454 
3455 	    // If 'switchbuf' contains "usetab": jump to first window in any tab
3456 	    // page containing "existing_buf" if one exists
3457 	    if (wp == NULL && (swb_flags & SWB_USETAB))
3458 		wp = buf_jump_open_tab(existing_buf);
3459 	    // We've switched to the buffer, the usual loading of the file must
3460 	    // be skipped.
3461 	    if (wp != NULL)
3462 		getfile_result = GETFILE_SAME_FILE;
3463 	}
3464     }
3465     if (getfile_result == GETFILE_UNUSED
3466 				       && (postponed_split || cmdmod.tab != 0))
3467     {
3468 	if (win_split(postponed_split > 0 ? postponed_split : 0,
3469 						postponed_split_flags) == FAIL)
3470 	{
3471 	    --RedrawingDisabled;
3472 	    goto erret;
3473 	}
3474 	RESET_BINDING(curwin);
3475     }
3476 #endif
3477 
3478     if (keep_help)
3479     {
3480 	// A :ta from a help file will keep the b_help flag set.  For ":ptag"
3481 	// we need to use the flag from the window where we came from.
3482 #if defined(FEAT_QUICKFIX)
3483 	if (g_do_tagpreview != 0)
3484 	    keep_help_flag = bt_help(curwin_save->w_buffer);
3485 	else
3486 #endif
3487 	    keep_help_flag = curbuf->b_help;
3488     }
3489 
3490     if (getfile_result == GETFILE_UNUSED)
3491 	// Careful: getfile() may trigger autocommands and call jumpto_tag()
3492 	// recursively.
3493 	getfile_result = getfile(0, fname, NULL, TRUE, (linenr_T)0, forceit);
3494     keep_help_flag = FALSE;
3495 
3496     if (GETFILE_SUCCESS(getfile_result))	// got to the right file
3497     {
3498 	curwin->w_set_curswant = TRUE;
3499 	postponed_split = 0;
3500 
3501 	save_secure = secure;
3502 	secure = 1;
3503 #ifdef HAVE_SANDBOX
3504 	++sandbox;
3505 #endif
3506 	save_magic = p_magic;
3507 	p_magic = FALSE;	// always execute with 'nomagic'
3508 #ifdef FEAT_SEARCH_EXTRA
3509 	// Save value of no_hlsearch, jumping to a tag is not a real search
3510 	save_no_hlsearch = no_hlsearch;
3511 #endif
3512 
3513 	/*
3514 	 * If 'cpoptions' contains 't', store the search pattern for the "n"
3515 	 * command.  If 'cpoptions' does not contain 't', the search pattern
3516 	 * is not stored.
3517 	 */
3518 	if (vim_strchr(p_cpo, CPO_TAGPAT) != NULL)
3519 	    search_options = 0;
3520 	else
3521 	    search_options = SEARCH_KEEP;
3522 
3523 	/*
3524 	 * If the command is a search, try here.
3525 	 *
3526 	 * Reset 'smartcase' for the search, since the search pattern was not
3527 	 * typed by the user.
3528 	 * Only use do_search() when there is a full search command, without
3529 	 * anything following.
3530 	 */
3531 	str = pbuf;
3532 	if (pbuf[0] == '/' || pbuf[0] == '?')
3533 	    str = skip_regexp(pbuf + 1, pbuf[0], FALSE) + 1;
3534 	if (str > pbuf_end - 1)	// search command with nothing following
3535 	{
3536 	    save_p_ws = p_ws;
3537 	    save_p_ic = p_ic;
3538 	    save_p_scs = p_scs;
3539 	    p_ws = TRUE;	// need 'wrapscan' for backward searches
3540 	    p_ic = FALSE;	// don't ignore case now
3541 	    p_scs = FALSE;
3542 	    save_lnum = curwin->w_cursor.lnum;
3543 	    if (tagp.tagline > 0)
3544 		// start search before line from "line:" field
3545 		curwin->w_cursor.lnum = tagp.tagline - 1;
3546 	    else
3547 		// start search before first line
3548 		curwin->w_cursor.lnum = 0;
3549 	    if (do_search(NULL, pbuf[0], pbuf[0], pbuf + 1, (long)1,
3550 							 search_options, NULL))
3551 		retval = OK;
3552 	    else
3553 	    {
3554 		int	found = 1;
3555 		int	cc;
3556 
3557 		/*
3558 		 * try again, ignore case now
3559 		 */
3560 		p_ic = TRUE;
3561 		if (!do_search(NULL, pbuf[0], pbuf[0], pbuf + 1, (long)1,
3562 							 search_options, NULL))
3563 		{
3564 		    /*
3565 		     * Failed to find pattern, take a guess: "^func  ("
3566 		     */
3567 		    found = 2;
3568 		    (void)test_for_static(&tagp);
3569 		    cc = *tagp.tagname_end;
3570 		    *tagp.tagname_end = NUL;
3571 		    sprintf((char *)pbuf, "^%s\\s\\*(", tagp.tagname);
3572 		    if (!do_search(NULL, '/', '/', pbuf, (long)1,
3573 							 search_options, NULL))
3574 		    {
3575 			// Guess again: "^char * \<func  ("
3576 			sprintf((char *)pbuf, "^\\[#a-zA-Z_]\\.\\*\\<%s\\s\\*(",
3577 								tagp.tagname);
3578 			if (!do_search(NULL, '/', '/', pbuf, (long)1,
3579 							 search_options, NULL))
3580 			    found = 0;
3581 		    }
3582 		    *tagp.tagname_end = cc;
3583 		}
3584 		if (found == 0)
3585 		{
3586 		    emsg(_("E434: Can't find tag pattern"));
3587 		    curwin->w_cursor.lnum = save_lnum;
3588 		}
3589 		else
3590 		{
3591 		    /*
3592 		     * Only give a message when really guessed, not when 'ic'
3593 		     * is set and match found while ignoring case.
3594 		     */
3595 		    if (found == 2 || !save_p_ic)
3596 		    {
3597 			msg(_("E435: Couldn't find tag, just guessing!"));
3598 			if (!msg_scrolled && msg_silent == 0)
3599 			{
3600 			    out_flush();
3601 			    ui_delay(1010L, TRUE);
3602 			}
3603 		    }
3604 		    retval = OK;
3605 		}
3606 	    }
3607 	    p_ws = save_p_ws;
3608 	    p_ic = save_p_ic;
3609 	    p_scs = save_p_scs;
3610 
3611 	    // A search command may have positioned the cursor beyond the end
3612 	    // of the line.  May need to correct that here.
3613 	    check_cursor();
3614 	}
3615 	else
3616 	{
3617 	    curwin->w_cursor.lnum = 1;		// start command in line 1
3618 	    do_cmdline_cmd(pbuf);
3619 	    retval = OK;
3620 	}
3621 
3622 	/*
3623 	 * When the command has done something that is not allowed make sure
3624 	 * the error message can be seen.
3625 	 */
3626 	if (secure == 2)
3627 	    wait_return(TRUE);
3628 	secure = save_secure;
3629 	p_magic = save_magic;
3630 #ifdef HAVE_SANDBOX
3631 	--sandbox;
3632 #endif
3633 #ifdef FEAT_SEARCH_EXTRA
3634 	// restore no_hlsearch when keeping the old search pattern
3635 	if (search_options)
3636 	    set_no_hlsearch(save_no_hlsearch);
3637 #endif
3638 
3639 	// Return OK if jumped to another file (at least we found the file!).
3640 	if (getfile_result == GETFILE_OPEN_OTHER)
3641 	    retval = OK;
3642 
3643 	if (retval == OK)
3644 	{
3645 	    /*
3646 	     * For a help buffer: Put the cursor line at the top of the window,
3647 	     * the help subject will be below it.
3648 	     */
3649 	    if (curbuf->b_help)
3650 		set_topline(curwin, curwin->w_cursor.lnum);
3651 #ifdef FEAT_FOLDING
3652 	    if ((fdo_flags & FDO_TAG) && old_KeyTyped)
3653 		foldOpenCursor();
3654 #endif
3655 	}
3656 
3657 #if defined(FEAT_QUICKFIX)
3658 	if (g_do_tagpreview != 0
3659 			   && curwin != curwin_save && win_valid(curwin_save))
3660 	{
3661 	    // Return cursor to where we were
3662 	    validate_cursor();
3663 	    redraw_later(VALID);
3664 	    win_enter(curwin_save, TRUE);
3665 	}
3666 #endif
3667 
3668 	--RedrawingDisabled;
3669     }
3670     else
3671     {
3672 	--RedrawingDisabled;
3673 	got_int = FALSE;  // don't want entering window to fail
3674 
3675 	if (postponed_split)		// close the window
3676 	{
3677 	    win_close(curwin, FALSE);
3678 	    postponed_split = 0;
3679 	}
3680 #if defined(FEAT_QUICKFIX) && defined(FEAT_PROP_POPUP)
3681 	else if (WIN_IS_POPUP(curwin))
3682 	{
3683 	    win_T   *wp = curwin;
3684 
3685 	    if (win_valid(curwin_save))
3686 		win_enter(curwin_save, TRUE);
3687 	    popup_close(wp->w_id, FALSE);
3688 	}
3689 #endif
3690     }
3691 #if defined(FEAT_QUICKFIX) && defined(FEAT_PROP_POPUP)
3692     if (WIN_IS_POPUP(curwin))
3693 	// something went wrong, still in popup, but it can't have focus
3694 	win_enter(firstwin, TRUE);
3695 #endif
3696 
3697 erret:
3698 #if defined(FEAT_QUICKFIX)
3699     g_do_tagpreview = 0; // For next time
3700 #endif
3701     vim_free(lbuf);
3702     vim_free(pbuf);
3703     vim_free(tofree_fname);
3704     vim_free(full_fname);
3705 
3706     return retval;
3707 }
3708 
3709 /*
3710  * If "expand" is TRUE, expand wildcards in fname.
3711  * If 'tagrelative' option set, change fname (name of file containing tag)
3712  * according to tag_fname (name of tag file containing fname).
3713  * Returns a pointer to allocated memory (or NULL when out of memory).
3714  */
3715     static char_u *
3716 expand_tag_fname(char_u *fname, char_u *tag_fname, int expand)
3717 {
3718     char_u	*p;
3719     char_u	*retval;
3720     char_u	*expanded_fname = NULL;
3721     expand_T	xpc;
3722 
3723     /*
3724      * Expand file name (for environment variables) when needed.
3725      */
3726     if (expand && mch_has_wildcard(fname))
3727     {
3728 	ExpandInit(&xpc);
3729 	xpc.xp_context = EXPAND_FILES;
3730 	expanded_fname = ExpandOne(&xpc, (char_u *)fname, NULL,
3731 			    WILD_LIST_NOTFOUND|WILD_SILENT, WILD_EXPAND_FREE);
3732 	if (expanded_fname != NULL)
3733 	    fname = expanded_fname;
3734     }
3735 
3736     if ((p_tr || curbuf->b_help)
3737 	    && !vim_isAbsName(fname)
3738 	    && (p = gettail(tag_fname)) != tag_fname)
3739     {
3740 	retval = alloc(MAXPATHL);
3741 	if (retval != NULL)
3742 	{
3743 	    STRCPY(retval, tag_fname);
3744 	    vim_strncpy(retval + (p - tag_fname), fname,
3745 					      MAXPATHL - (p - tag_fname) - 1);
3746 	    /*
3747 	     * Translate names like "src/a/../b/file.c" into "src/b/file.c".
3748 	     */
3749 	    simplify_filename(retval);
3750 	}
3751     }
3752     else
3753 	retval = vim_strsave(fname);
3754 
3755     vim_free(expanded_fname);
3756 
3757     return retval;
3758 }
3759 
3760 /*
3761  * Check if we have a tag for the buffer with name "buf_ffname".
3762  * This is a bit slow, because of the full path compare in fullpathcmp().
3763  * Return TRUE if tag for file "fname" if tag file "tag_fname" is for current
3764  * file.
3765  */
3766     static int
3767 test_for_current(
3768 #ifdef FEAT_EMACS_TAGS
3769     int	    is_etag,
3770 #endif
3771     char_u  *fname,
3772     char_u  *fname_end,
3773     char_u  *tag_fname,
3774     char_u  *buf_ffname)
3775 {
3776     int	    c;
3777     int	    retval = FALSE;
3778     char_u  *fullname;
3779 
3780     if (buf_ffname != NULL)	// if the buffer has a name
3781     {
3782 #ifdef FEAT_EMACS_TAGS
3783 	if (is_etag)
3784 	    c = 0;	    // to shut up GCC
3785 	else
3786 #endif
3787 	{
3788 	    c = *fname_end;
3789 	    *fname_end = NUL;
3790 	}
3791 	fullname = expand_tag_fname(fname, tag_fname, TRUE);
3792 	if (fullname != NULL)
3793 	{
3794 	    retval = (fullpathcmp(fullname, buf_ffname, TRUE, TRUE) & FPC_SAME);
3795 	    vim_free(fullname);
3796 	}
3797 #ifdef FEAT_EMACS_TAGS
3798 	if (!is_etag)
3799 #endif
3800 	    *fname_end = c;
3801     }
3802 
3803     return retval;
3804 }
3805 
3806 /*
3807  * Find the end of the tagaddress.
3808  * Return OK if ";\"" is following, FAIL otherwise.
3809  */
3810     static int
3811 find_extra(char_u **pp)
3812 {
3813     char_u	*str = *pp;
3814     char_u	first_char = **pp;
3815 
3816     // Repeat for addresses separated with ';'
3817     for (;;)
3818     {
3819 	if (VIM_ISDIGIT(*str))
3820 	    str = skipdigits(str);
3821 	else if (*str == '/' || *str == '?')
3822 	{
3823 	    str = skip_regexp(str + 1, *str, FALSE);
3824 	    if (*str != first_char)
3825 		str = NULL;
3826 	    else
3827 		++str;
3828 	}
3829 	else
3830 	{
3831 	    // not a line number or search string, look for terminator.
3832 	    str = (char_u *)strstr((char *)str, "|;\"");
3833 	    if (str != NULL)
3834 	    {
3835 		++str;
3836 		break;
3837 	    }
3838 
3839 	}
3840 	if (str == NULL || *str != ';'
3841 		  || !(VIM_ISDIGIT(str[1]) || str[1] == '/' || str[1] == '?'))
3842 	    break;
3843 	++str;	// skip ';'
3844 	first_char = *str;
3845     }
3846 
3847     if (str != NULL && STRNCMP(str, ";\"", 2) == 0)
3848     {
3849 	*pp = str;
3850 	return OK;
3851     }
3852     return FAIL;
3853 }
3854 
3855 /*
3856  * Free a single entry in a tag stack
3857  */
3858     static void
3859 tagstack_clear_entry(taggy_T *item)
3860 {
3861     VIM_CLEAR(item->tagname);
3862     VIM_CLEAR(item->user_data);
3863 }
3864 
3865     int
3866 expand_tags(
3867     int		tagnames,	// expand tag names
3868     char_u	*pat,
3869     int		*num_file,
3870     char_u	***file)
3871 {
3872     int		i;
3873     int		c;
3874     int		tagnmflag;
3875     char_u      tagnm[100];
3876     tagptrs_T	t_p;
3877     int		ret;
3878 
3879     if (tagnames)
3880 	tagnmflag = TAG_NAMES;
3881     else
3882 	tagnmflag = 0;
3883     if (pat[0] == '/')
3884 	ret = find_tags(pat + 1, num_file, file,
3885 		TAG_REGEXP | tagnmflag | TAG_VERBOSE | TAG_NO_TAGFUNC,
3886 		TAG_MANY, curbuf->b_ffname);
3887     else
3888 	ret = find_tags(pat, num_file, file,
3889 	      TAG_REGEXP | tagnmflag | TAG_VERBOSE | TAG_NO_TAGFUNC | TAG_NOIC,
3890 		TAG_MANY, curbuf->b_ffname);
3891     if (ret == OK && !tagnames)
3892     {
3893 	 // Reorganize the tags for display and matching as strings of:
3894 	 // "<tagname>\0<kind>\0<filename>\0"
3895 	 for (i = 0; i < *num_file; i++)
3896 	 {
3897 	     parse_match((*file)[i], &t_p);
3898 	     c = (int)(t_p.tagname_end - t_p.tagname);
3899 	     mch_memmove(tagnm, t_p.tagname, (size_t)c);
3900 	     tagnm[c++] = 0;
3901 	     tagnm[c++] = (t_p.tagkind != NULL && *t_p.tagkind)
3902 							 ? *t_p.tagkind : 'f';
3903 	     tagnm[c++] = 0;
3904 	     mch_memmove((*file)[i] + c, t_p.fname, t_p.fname_end - t_p.fname);
3905 	     (*file)[i][c + (t_p.fname_end - t_p.fname)] = 0;
3906 	     mch_memmove((*file)[i], tagnm, (size_t)c);
3907 	}
3908     }
3909     return ret;
3910 }
3911 
3912 #if defined(FEAT_EVAL) || defined(PROTO)
3913 /*
3914  * Add a tag field to the dictionary "dict".
3915  * Return OK or FAIL.
3916  */
3917     static int
3918 add_tag_field(
3919     dict_T  *dict,
3920     char    *field_name,
3921     char_u  *start,		// start of the value
3922     char_u  *end)		// after the value; can be NULL
3923 {
3924     char_u	*buf;
3925     int		len = 0;
3926     int		retval;
3927 
3928     // check that the field name doesn't exist yet
3929     if (dict_find(dict, (char_u *)field_name, -1) != NULL)
3930     {
3931 	if (p_verbose > 0)
3932 	{
3933 	    verbose_enter();
3934 	    smsg(_("Duplicate field name: %s"), field_name);
3935 	    verbose_leave();
3936 	}
3937 	return FAIL;
3938     }
3939     buf = alloc(MAXPATHL);
3940     if (buf == NULL)
3941 	return FAIL;
3942     if (start != NULL)
3943     {
3944 	if (end == NULL)
3945 	{
3946 	    end = start + STRLEN(start);
3947 	    while (end > start && (end[-1] == '\r' || end[-1] == '\n'))
3948 		--end;
3949 	}
3950 	len = (int)(end - start);
3951 	if (len > MAXPATHL - 1)
3952 	    len = MAXPATHL - 1;
3953 	vim_strncpy(buf, start, len);
3954     }
3955     buf[len] = NUL;
3956     retval = dict_add_string(dict, field_name, buf);
3957     vim_free(buf);
3958     return retval;
3959 }
3960 
3961 /*
3962  * Add the tags matching the specified pattern "pat" to the list "list"
3963  * as a dictionary. Use "buf_fname" for priority, unless NULL.
3964  */
3965     int
3966 get_tags(list_T *list, char_u *pat, char_u *buf_fname)
3967 {
3968     int		num_matches, i, ret;
3969     char_u	**matches, *p;
3970     char_u	*full_fname;
3971     dict_T	*dict;
3972     tagptrs_T	tp;
3973     long	is_static;
3974 
3975     ret = find_tags(pat, &num_matches, &matches,
3976 				TAG_REGEXP | TAG_NOIC, (int)MAXCOL, buf_fname);
3977     if (ret == OK && num_matches > 0)
3978     {
3979 	for (i = 0; i < num_matches; ++i)
3980 	{
3981 	    parse_match(matches[i], &tp);
3982 	    is_static = test_for_static(&tp);
3983 
3984 	    // Skip pseudo-tag lines.
3985 	    if (STRNCMP(tp.tagname, "!_TAG_", 6) == 0)
3986 	    {
3987 		vim_free(matches[i]);
3988 		continue;
3989 	    }
3990 
3991 	    if ((dict = dict_alloc()) == NULL)
3992 		ret = FAIL;
3993 	    if (list_append_dict(list, dict) == FAIL)
3994 		ret = FAIL;
3995 
3996 	    full_fname = tag_full_fname(&tp);
3997 	    if (add_tag_field(dict, "name", tp.tagname, tp.tagname_end) == FAIL
3998 		    || add_tag_field(dict, "filename", full_fname,
3999 							 NULL) == FAIL
4000 		    || add_tag_field(dict, "cmd", tp.command,
4001 						       tp.command_end) == FAIL
4002 		    || add_tag_field(dict, "kind", tp.tagkind,
4003 						      tp.tagkind_end) == FAIL
4004 		    || dict_add_number(dict, "static", is_static) == FAIL)
4005 		ret = FAIL;
4006 
4007 	    vim_free(full_fname);
4008 
4009 	    if (tp.command_end != NULL)
4010 	    {
4011 		for (p = tp.command_end + 3;
4012 			  *p != NUL && *p != '\n' && *p != '\r'; MB_PTR_ADV(p))
4013 		{
4014 		    if (p == tp.tagkind || (p + 5 == tp.tagkind
4015 					      && STRNCMP(p, "kind:", 5) == 0))
4016 			// skip "kind:<kind>" and "<kind>"
4017 			p = tp.tagkind_end - 1;
4018 		    else if (STRNCMP(p, "file:", 5) == 0)
4019 			// skip "file:" (static tag)
4020 			p += 4;
4021 		    else if (!VIM_ISWHITE(*p))
4022 		    {
4023 			char_u	*s, *n;
4024 			int	len;
4025 
4026 			// Add extra field as a dict entry.  Fields are
4027 			// separated by Tabs.
4028 			n = p;
4029 			while (*p != NUL && *p >= ' ' && *p < 127 && *p != ':')
4030 			    ++p;
4031 			len = (int)(p - n);
4032 			if (*p == ':' && len > 0)
4033 			{
4034 			    s = ++p;
4035 			    while (*p != NUL && *p >= ' ')
4036 				++p;
4037 			    n[len] = NUL;
4038 			    if (add_tag_field(dict, (char *)n, s, p) == FAIL)
4039 				ret = FAIL;
4040 			    n[len] = ':';
4041 			}
4042 			else
4043 			    // Skip field without colon.
4044 			    while (*p != NUL && *p >= ' ')
4045 				++p;
4046 			if (*p == NUL)
4047 			    break;
4048 		    }
4049 		}
4050 	    }
4051 
4052 	    vim_free(matches[i]);
4053 	}
4054 	vim_free(matches);
4055     }
4056     return ret;
4057 }
4058 
4059 /*
4060  * Return information about 'tag' in dict 'retdict'.
4061  */
4062     static void
4063 get_tag_details(taggy_T *tag, dict_T *retdict)
4064 {
4065     list_T	*pos;
4066     fmark_T	*fmark;
4067 
4068     dict_add_string(retdict, "tagname", tag->tagname);
4069     dict_add_number(retdict, "matchnr", tag->cur_match + 1);
4070     dict_add_number(retdict, "bufnr", tag->cur_fnum);
4071     if (tag->user_data)
4072 	dict_add_string(retdict, "user_data", tag->user_data);
4073 
4074     if ((pos = list_alloc_id(aid_tagstack_from)) == NULL)
4075 	return;
4076     dict_add_list(retdict, "from", pos);
4077 
4078     fmark = &tag->fmark;
4079     list_append_number(pos,
4080 			(varnumber_T)(fmark->fnum != -1 ? fmark->fnum : 0));
4081     list_append_number(pos, (varnumber_T)fmark->mark.lnum);
4082     list_append_number(pos, (varnumber_T)(fmark->mark.col == MAXCOL ?
4083 					MAXCOL : fmark->mark.col + 1));
4084     list_append_number(pos, (varnumber_T)fmark->mark.coladd);
4085 }
4086 
4087 /*
4088  * Return the tag stack entries of the specified window 'wp' in dictionary
4089  * 'retdict'.
4090  */
4091     void
4092 get_tagstack(win_T *wp, dict_T *retdict)
4093 {
4094     list_T	*l;
4095     int		i;
4096     dict_T	*d;
4097 
4098     dict_add_number(retdict, "length", wp->w_tagstacklen);
4099     dict_add_number(retdict, "curidx", wp->w_tagstackidx + 1);
4100     l = list_alloc_id(aid_tagstack_items);
4101     if (l == NULL)
4102 	return;
4103     dict_add_list(retdict, "items", l);
4104 
4105     for (i = 0; i < wp->w_tagstacklen; i++)
4106     {
4107 	if ((d = dict_alloc_id(aid_tagstack_details)) == NULL)
4108 	    return;
4109 	list_append_dict(l, d);
4110 
4111 	get_tag_details(&wp->w_tagstack[i], d);
4112     }
4113 }
4114 
4115 /*
4116  * Free all the entries in the tag stack of the specified window
4117  */
4118     static void
4119 tagstack_clear(win_T *wp)
4120 {
4121     int i;
4122 
4123     // Free the current tag stack
4124     for (i = 0; i < wp->w_tagstacklen; ++i)
4125 	tagstack_clear_entry(&wp->w_tagstack[i]);
4126     wp->w_tagstacklen = 0;
4127     wp->w_tagstackidx = 0;
4128 }
4129 
4130 /*
4131  * Remove the oldest entry from the tag stack and shift the rest of
4132  * the entries to free up the top of the stack.
4133  */
4134     static void
4135 tagstack_shift(win_T *wp)
4136 {
4137     taggy_T	*tagstack = wp->w_tagstack;
4138     int		i;
4139 
4140     tagstack_clear_entry(&tagstack[0]);
4141     for (i = 1; i < wp->w_tagstacklen; ++i)
4142 	tagstack[i - 1] = tagstack[i];
4143     wp->w_tagstacklen--;
4144 }
4145 
4146 /*
4147  * Push a new item to the tag stack
4148  */
4149     static void
4150 tagstack_push_item(
4151 	win_T	*wp,
4152 	char_u	*tagname,
4153 	int	cur_fnum,
4154 	int	cur_match,
4155 	pos_T	mark,
4156 	int	fnum,
4157 	char_u  *user_data)
4158 {
4159     taggy_T	*tagstack = wp->w_tagstack;
4160     int		idx = wp->w_tagstacklen;	// top of the stack
4161 
4162     // if the tagstack is full: remove the oldest entry
4163     if (idx >= TAGSTACKSIZE)
4164     {
4165 	tagstack_shift(wp);
4166 	idx = TAGSTACKSIZE - 1;
4167     }
4168 
4169     wp->w_tagstacklen++;
4170     tagstack[idx].tagname = tagname;
4171     tagstack[idx].cur_fnum = cur_fnum;
4172     tagstack[idx].cur_match = cur_match;
4173     if (tagstack[idx].cur_match < 0)
4174 	tagstack[idx].cur_match = 0;
4175     tagstack[idx].fmark.mark = mark;
4176     tagstack[idx].fmark.fnum = fnum;
4177     tagstack[idx].user_data = user_data;
4178 }
4179 
4180 /*
4181  * Add a list of items to the tag stack in the specified window
4182  */
4183     static void
4184 tagstack_push_items(win_T *wp, list_T *l)
4185 {
4186     listitem_T	*li;
4187     dictitem_T	*di;
4188     dict_T	*itemdict;
4189     char_u	*tagname;
4190     pos_T	mark;
4191     int		fnum;
4192 
4193     // Add one entry at a time to the tag stack
4194     FOR_ALL_LIST_ITEMS(l, li)
4195     {
4196 	if (li->li_tv.v_type != VAR_DICT || li->li_tv.vval.v_dict == NULL)
4197 	    continue;				// Skip non-dict items
4198 	itemdict = li->li_tv.vval.v_dict;
4199 
4200 	// parse 'from' for the cursor position before the tag jump
4201 	if ((di = dict_find(itemdict, (char_u *)"from", -1)) == NULL)
4202 	    continue;
4203 	if (list2fpos(&di->di_tv, &mark, &fnum, NULL) != OK)
4204 	    continue;
4205 	if ((tagname =
4206 		dict_get_string(itemdict, (char_u *)"tagname", TRUE)) == NULL)
4207 	    continue;
4208 
4209 	if (mark.col > 0)
4210 	    mark.col--;
4211 	tagstack_push_item(wp, tagname,
4212 		(int)dict_get_number(itemdict, (char_u *)"bufnr"),
4213 		(int)dict_get_number(itemdict, (char_u *)"matchnr") - 1,
4214 		mark, fnum,
4215 		dict_get_string(itemdict, (char_u *)"user_data", TRUE));
4216     }
4217 }
4218 
4219 /*
4220  * Set the current index in the tag stack. Valid values are between 0
4221  * and the stack length (inclusive).
4222  */
4223     static void
4224 tagstack_set_curidx(win_T *wp, int curidx)
4225 {
4226     wp->w_tagstackidx = curidx;
4227     if (wp->w_tagstackidx < 0)			// sanity check
4228 	wp->w_tagstackidx = 0;
4229     if (wp->w_tagstackidx > wp->w_tagstacklen)
4230 	wp->w_tagstackidx = wp->w_tagstacklen;
4231 }
4232 
4233 /*
4234  * Set the tag stack entries of the specified window.
4235  * 'action' is set to one of:
4236  *	'a' for append
4237  *	'r' for replace
4238  *	't' for truncate
4239  */
4240     int
4241 set_tagstack(win_T *wp, dict_T *d, int action)
4242 {
4243     dictitem_T	*di;
4244     list_T	*l = NULL;
4245 
4246 #ifdef FEAT_EVAL
4247     // not allowed to alter the tag stack entries from inside tagfunc
4248     if (tfu_in_use)
4249     {
4250 	emsg(_(recurmsg));
4251 	return FAIL;
4252     }
4253 #endif
4254 
4255     if ((di = dict_find(d, (char_u *)"items", -1)) != NULL)
4256     {
4257 	if (di->di_tv.v_type != VAR_LIST)
4258 	{
4259 	    emsg(_(e_listreq));
4260 	    return FAIL;
4261 	}
4262 	l = di->di_tv.vval.v_list;
4263     }
4264 
4265     if ((di = dict_find(d, (char_u *)"curidx", -1)) != NULL)
4266 	tagstack_set_curidx(wp, (int)tv_get_number(&di->di_tv) - 1);
4267 
4268     if (action == 't')		    // truncate the stack
4269     {
4270 	taggy_T	*tagstack = wp->w_tagstack;
4271 	int	tagstackidx = wp->w_tagstackidx;
4272 	int	tagstacklen = wp->w_tagstacklen;
4273 
4274 	// delete all the tag stack entries above the current entry
4275 	while (tagstackidx < tagstacklen)
4276 	    tagstack_clear_entry(&tagstack[--tagstacklen]);
4277 	wp->w_tagstacklen = tagstacklen;
4278     }
4279 
4280     if (l != NULL)
4281     {
4282 	if (action == 'r')		// replace the stack
4283 	    tagstack_clear(wp);
4284 
4285 	tagstack_push_items(wp, l);
4286 	// set the current index after the last entry
4287 	wp->w_tagstackidx = wp->w_tagstacklen;
4288     }
4289 
4290     return OK;
4291 }
4292 #endif
4293