xref: /vim-8.2.3635/src/misc2.c (revision 3ad8772e)
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  * misc2.c: Various functions.
12  */
13 #include "vim.h"
14 
15 static char_u	*username = NULL; /* cached result of mch_get_user_name() */
16 
17 static char_u	*ff_expand_buffer = NULL; /* used for expanding filenames */
18 
19 #if defined(FEAT_VIRTUALEDIT) || defined(PROTO)
20 static int coladvance2(pos_T *pos, int addspaces, int finetune, colnr_T wcol);
21 
22 /*
23  * Return TRUE if in the current mode we need to use virtual.
24  */
25     int
26 virtual_active(void)
27 {
28     /* While an operator is being executed we return "virtual_op", because
29      * VIsual_active has already been reset, thus we can't check for "block"
30      * being used. */
31     if (virtual_op != MAYBE)
32 	return virtual_op;
33     return (ve_flags == VE_ALL
34 	    || ((ve_flags & VE_BLOCK) && VIsual_active && VIsual_mode == Ctrl_V)
35 	    || ((ve_flags & VE_INSERT) && (State & INSERT)));
36 }
37 
38 /*
39  * Get the screen position of the cursor.
40  */
41     int
42 getviscol(void)
43 {
44     colnr_T	x;
45 
46     getvvcol(curwin, &curwin->w_cursor, &x, NULL, NULL);
47     return (int)x;
48 }
49 
50 /*
51  * Get the screen position of character col with a coladd in the cursor line.
52  */
53     int
54 getviscol2(colnr_T col, colnr_T coladd)
55 {
56     colnr_T	x;
57     pos_T	pos;
58 
59     pos.lnum = curwin->w_cursor.lnum;
60     pos.col = col;
61     pos.coladd = coladd;
62     getvvcol(curwin, &pos, &x, NULL, NULL);
63     return (int)x;
64 }
65 
66 /*
67  * Go to column "wcol", and add/insert white space as necessary to get the
68  * cursor in that column.
69  * The caller must have saved the cursor line for undo!
70  */
71     int
72 coladvance_force(colnr_T wcol)
73 {
74     int rc = coladvance2(&curwin->w_cursor, TRUE, FALSE, wcol);
75 
76     if (wcol == MAXCOL)
77 	curwin->w_valid &= ~VALID_VIRTCOL;
78     else
79     {
80 	/* Virtcol is valid */
81 	curwin->w_valid |= VALID_VIRTCOL;
82 	curwin->w_virtcol = wcol;
83     }
84     return rc;
85 }
86 #endif
87 
88 /*
89  * Try to advance the Cursor to the specified screen column.
90  * If virtual editing: fine tune the cursor position.
91  * Note that all virtual positions off the end of a line should share
92  * a curwin->w_cursor.col value (n.b. this is equal to STRLEN(line)),
93  * beginning at coladd 0.
94  *
95  * return OK if desired column is reached, FAIL if not
96  */
97     int
98 coladvance(colnr_T wcol)
99 {
100     int rc = getvpos(&curwin->w_cursor, wcol);
101 
102     if (wcol == MAXCOL || rc == FAIL)
103 	curwin->w_valid &= ~VALID_VIRTCOL;
104     else if (*ml_get_cursor() != TAB)
105     {
106 	/* Virtcol is valid when not on a TAB */
107 	curwin->w_valid |= VALID_VIRTCOL;
108 	curwin->w_virtcol = wcol;
109     }
110     return rc;
111 }
112 
113 /*
114  * Return in "pos" the position of the cursor advanced to screen column "wcol".
115  * return OK if desired column is reached, FAIL if not
116  */
117     int
118 getvpos(pos_T *pos, colnr_T wcol)
119 {
120 #ifdef FEAT_VIRTUALEDIT
121     return coladvance2(pos, FALSE, virtual_active(), wcol);
122 }
123 
124     static int
125 coladvance2(
126     pos_T	*pos,
127     int		addspaces,	/* change the text to achieve our goal? */
128     int		finetune,	/* change char offset for the exact column */
129     colnr_T	wcol)		/* column to move to */
130 {
131 #endif
132     int		idx;
133     char_u	*ptr;
134     char_u	*line;
135     colnr_T	col = 0;
136     int		csize = 0;
137     int		one_more;
138 #ifdef FEAT_LINEBREAK
139     int		head = 0;
140 #endif
141 
142     one_more = (State & INSERT)
143 		    || restart_edit != NUL
144 		    || (VIsual_active && *p_sel != 'o')
145 #ifdef FEAT_VIRTUALEDIT
146 		    || ((ve_flags & VE_ONEMORE) && wcol < MAXCOL)
147 #endif
148 		    ;
149     line = ml_get_buf(curbuf, pos->lnum, FALSE);
150 
151     if (wcol >= MAXCOL)
152     {
153 	    idx = (int)STRLEN(line) - 1 + one_more;
154 	    col = wcol;
155 
156 #ifdef FEAT_VIRTUALEDIT
157 	    if ((addspaces || finetune) && !VIsual_active)
158 	    {
159 		curwin->w_curswant = linetabsize(line) + one_more;
160 		if (curwin->w_curswant > 0)
161 		    --curwin->w_curswant;
162 	    }
163 #endif
164     }
165     else
166     {
167 #ifdef FEAT_VIRTUALEDIT
168 	int width = curwin->w_width - win_col_off(curwin);
169 
170 	if (finetune
171 		&& curwin->w_p_wrap
172 		&& curwin->w_width != 0
173 		&& wcol >= (colnr_T)width)
174 	{
175 	    csize = linetabsize(line);
176 	    if (csize > 0)
177 		csize--;
178 
179 	    if (wcol / width > (colnr_T)csize / width
180 		    && ((State & INSERT) == 0 || (int)wcol > csize + 1))
181 	    {
182 		/* In case of line wrapping don't move the cursor beyond the
183 		 * right screen edge.  In Insert mode allow going just beyond
184 		 * the last character (like what happens when typing and
185 		 * reaching the right window edge). */
186 		wcol = (csize / width + 1) * width - 1;
187 	    }
188 	}
189 #endif
190 
191 	ptr = line;
192 	while (col <= wcol && *ptr != NUL)
193 	{
194 	    /* Count a tab for what it's worth (if list mode not on) */
195 #ifdef FEAT_LINEBREAK
196 	    csize = win_lbr_chartabsize(curwin, line, ptr, col, &head);
197 	    MB_PTR_ADV(ptr);
198 #else
199 	    csize = lbr_chartabsize_adv(line, &ptr, col);
200 #endif
201 	    col += csize;
202 	}
203 	idx = (int)(ptr - line);
204 	/*
205 	 * Handle all the special cases.  The virtual_active() check
206 	 * is needed to ensure that a virtual position off the end of
207 	 * a line has the correct indexing.  The one_more comparison
208 	 * replaces an explicit add of one_more later on.
209 	 */
210 	if (col > wcol || (!virtual_active() && one_more == 0))
211 	{
212 	    idx -= 1;
213 # ifdef FEAT_LINEBREAK
214 	    /* Don't count the chars from 'showbreak'. */
215 	    csize -= head;
216 # endif
217 	    col -= csize;
218 	}
219 
220 #ifdef FEAT_VIRTUALEDIT
221 	if (virtual_active()
222 		&& addspaces
223 		&& ((col != wcol && col != wcol + 1) || csize > 1))
224 	{
225 	    /* 'virtualedit' is set: The difference between wcol and col is
226 	     * filled with spaces. */
227 
228 	    if (line[idx] == NUL)
229 	    {
230 		/* Append spaces */
231 		int	correct = wcol - col;
232 		char_u	*newline = alloc(idx + correct + 1);
233 		int	t;
234 
235 		if (newline == NULL)
236 		    return FAIL;
237 
238 		for (t = 0; t < idx; ++t)
239 		    newline[t] = line[t];
240 
241 		for (t = 0; t < correct; ++t)
242 		    newline[t + idx] = ' ';
243 
244 		newline[idx + correct] = NUL;
245 
246 		ml_replace(pos->lnum, newline, FALSE);
247 		changed_bytes(pos->lnum, (colnr_T)idx);
248 		idx += correct;
249 		col = wcol;
250 	    }
251 	    else
252 	    {
253 		/* Break a tab */
254 		int	linelen = (int)STRLEN(line);
255 		int	correct = wcol - col - csize + 1; /* negative!! */
256 		char_u	*newline;
257 		int	t, s = 0;
258 		int	v;
259 
260 		if (-correct > csize)
261 		    return FAIL;
262 
263 		newline = alloc(linelen + csize);
264 		if (newline == NULL)
265 		    return FAIL;
266 
267 		for (t = 0; t < linelen; t++)
268 		{
269 		    if (t != idx)
270 			newline[s++] = line[t];
271 		    else
272 			for (v = 0; v < csize; v++)
273 			    newline[s++] = ' ';
274 		}
275 
276 		newline[linelen + csize - 1] = NUL;
277 
278 		ml_replace(pos->lnum, newline, FALSE);
279 		changed_bytes(pos->lnum, idx);
280 		idx += (csize - 1 + correct);
281 		col += correct;
282 	    }
283 	}
284 #endif
285     }
286 
287     if (idx < 0)
288 	pos->col = 0;
289     else
290 	pos->col = idx;
291 
292 #ifdef FEAT_VIRTUALEDIT
293     pos->coladd = 0;
294 
295     if (finetune)
296     {
297 	if (wcol == MAXCOL)
298 	{
299 	    /* The width of the last character is used to set coladd. */
300 	    if (!one_more)
301 	    {
302 		colnr_T	    scol, ecol;
303 
304 		getvcol(curwin, pos, &scol, NULL, &ecol);
305 		pos->coladd = ecol - scol;
306 	    }
307 	}
308 	else
309 	{
310 	    int b = (int)wcol - (int)col;
311 
312 	    /* The difference between wcol and col is used to set coladd. */
313 	    if (b > 0 && b < (MAXCOL - 2 * curwin->w_width))
314 		pos->coladd = b;
315 
316 	    col += b;
317 	}
318     }
319 #endif
320 
321 #ifdef FEAT_MBYTE
322     /* prevent from moving onto a trail byte */
323     if (has_mbyte)
324 	mb_adjustpos(curbuf, pos);
325 #endif
326 
327     if (col < wcol)
328 	return FAIL;
329     return OK;
330 }
331 
332 /*
333  * Increment the cursor position.  See inc() for return values.
334  */
335     int
336 inc_cursor(void)
337 {
338     return inc(&curwin->w_cursor);
339 }
340 
341 /*
342  * Increment the line pointer "lp" crossing line boundaries as necessary.
343  * Return 1 when going to the next line.
344  * Return 2 when moving forward onto a NUL at the end of the line).
345  * Return -1 when at the end of file.
346  * Return 0 otherwise.
347  */
348     int
349 inc(pos_T *lp)
350 {
351     char_u  *p;
352 
353     /* when searching position may be set to end of a line */
354     if (lp->col != MAXCOL)
355     {
356 	p = ml_get_pos(lp);
357 	if (*p != NUL)	/* still within line, move to next char (may be NUL) */
358 	{
359 #ifdef FEAT_MBYTE
360 	    if (has_mbyte)
361 	    {
362 		int l = (*mb_ptr2len)(p);
363 
364 		lp->col += l;
365 		return ((p[l] != NUL) ? 0 : 2);
366 	    }
367 #endif
368 	    lp->col++;
369 #ifdef FEAT_VIRTUALEDIT
370 	    lp->coladd = 0;
371 #endif
372 	    return ((p[1] != NUL) ? 0 : 2);
373 	}
374     }
375     if (lp->lnum != curbuf->b_ml.ml_line_count)     /* there is a next line */
376     {
377 	lp->col = 0;
378 	lp->lnum++;
379 #ifdef FEAT_VIRTUALEDIT
380 	lp->coladd = 0;
381 #endif
382 	return 1;
383     }
384     return -1;
385 }
386 
387 /*
388  * incl(lp): same as inc(), but skip the NUL at the end of non-empty lines
389  */
390     int
391 incl(pos_T *lp)
392 {
393     int	    r;
394 
395     if ((r = inc(lp)) >= 1 && lp->col)
396 	r = inc(lp);
397     return r;
398 }
399 
400 /*
401  * dec(p)
402  *
403  * Decrement the line pointer 'p' crossing line boundaries as necessary.
404  * Return 1 when crossing a line, -1 when at start of file, 0 otherwise.
405  */
406     int
407 dec_cursor(void)
408 {
409     return dec(&curwin->w_cursor);
410 }
411 
412     int
413 dec(pos_T *lp)
414 {
415     char_u	*p;
416 
417 #ifdef FEAT_VIRTUALEDIT
418     lp->coladd = 0;
419 #endif
420     if (lp->col == MAXCOL)
421     {
422 	/* past end of line */
423 	p = ml_get(lp->lnum);
424 	lp->col = (colnr_T)STRLEN(p);
425 #ifdef FEAT_MBYTE
426 	if (has_mbyte)
427 	    lp->col -= (*mb_head_off)(p, p + lp->col);
428 #endif
429 	return 0;
430     }
431 
432     if (lp->col > 0)
433     {
434 	/* still within line */
435 	lp->col--;
436 #ifdef FEAT_MBYTE
437 	if (has_mbyte)
438 	{
439 	    p = ml_get(lp->lnum);
440 	    lp->col -= (*mb_head_off)(p, p + lp->col);
441 	}
442 #endif
443 	return 0;
444     }
445 
446     if (lp->lnum > 1)
447     {
448 	/* there is a prior line */
449 	lp->lnum--;
450 	p = ml_get(lp->lnum);
451 	lp->col = (colnr_T)STRLEN(p);
452 #ifdef FEAT_MBYTE
453 	if (has_mbyte)
454 	    lp->col -= (*mb_head_off)(p, p + lp->col);
455 #endif
456 	return 1;
457     }
458 
459     /* at start of file */
460     return -1;
461 }
462 
463 /*
464  * decl(lp): same as dec(), but skip the NUL at the end of non-empty lines
465  */
466     int
467 decl(pos_T *lp)
468 {
469     int	    r;
470 
471     if ((r = dec(lp)) == 1 && lp->col)
472 	r = dec(lp);
473     return r;
474 }
475 
476 /*
477  * Get the line number relative to the current cursor position, i.e. the
478  * difference between line number and cursor position. Only look for lines that
479  * can be visible, folded lines don't count.
480  */
481     linenr_T
482 get_cursor_rel_lnum(
483     win_T	*wp,
484     linenr_T	lnum)		    /* line number to get the result for */
485 {
486     linenr_T	cursor = wp->w_cursor.lnum;
487     linenr_T	retval = 0;
488 
489 #ifdef FEAT_FOLDING
490     if (hasAnyFolding(wp))
491     {
492 	if (lnum > cursor)
493 	{
494 	    while (lnum > cursor)
495 	    {
496 		(void)hasFoldingWin(wp, lnum, &lnum, NULL, TRUE, NULL);
497 		/* if lnum and cursor are in the same fold,
498 		 * now lnum <= cursor */
499 		if (lnum > cursor)
500 		    retval++;
501 		lnum--;
502 	    }
503 	}
504 	else if (lnum < cursor)
505 	{
506 	    while (lnum < cursor)
507 	    {
508 		(void)hasFoldingWin(wp, lnum, NULL, &lnum, TRUE, NULL);
509 		/* if lnum and cursor are in the same fold,
510 		 * now lnum >= cursor */
511 		if (lnum < cursor)
512 		    retval--;
513 		lnum++;
514 	    }
515 	}
516 	/* else if (lnum == cursor)
517 	 *     retval = 0;
518 	 */
519     }
520     else
521 #endif
522 	retval = lnum - cursor;
523 
524     return retval;
525 }
526 
527 /*
528  * Make sure "pos.lnum" and "pos.col" are valid in "buf".
529  * This allows for the col to be on the NUL byte.
530  */
531     void
532 check_pos(buf_T *buf, pos_T *pos)
533 {
534     char_u *line;
535     colnr_T len;
536 
537     if (pos->lnum > buf->b_ml.ml_line_count)
538 	pos->lnum = buf->b_ml.ml_line_count;
539 
540     if (pos->col > 0)
541     {
542 	line = ml_get_buf(buf, pos->lnum, FALSE);
543 	len = (colnr_T)STRLEN(line);
544 	if (pos->col > len)
545 	    pos->col = len;
546     }
547 }
548 
549 /*
550  * Make sure curwin->w_cursor.lnum is valid.
551  */
552     void
553 check_cursor_lnum(void)
554 {
555     if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count)
556     {
557 #ifdef FEAT_FOLDING
558 	/* If there is a closed fold at the end of the file, put the cursor in
559 	 * its first line.  Otherwise in the last line. */
560 	if (!hasFolding(curbuf->b_ml.ml_line_count,
561 						&curwin->w_cursor.lnum, NULL))
562 #endif
563 	    curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
564     }
565     if (curwin->w_cursor.lnum <= 0)
566 	curwin->w_cursor.lnum = 1;
567 }
568 
569 /*
570  * Make sure curwin->w_cursor.col is valid.
571  */
572     void
573 check_cursor_col(void)
574 {
575     check_cursor_col_win(curwin);
576 }
577 
578 /*
579  * Make sure win->w_cursor.col is valid.
580  */
581     void
582 check_cursor_col_win(win_T *win)
583 {
584     colnr_T len;
585 #ifdef FEAT_VIRTUALEDIT
586     colnr_T oldcol = win->w_cursor.col;
587     colnr_T oldcoladd = win->w_cursor.col + win->w_cursor.coladd;
588 #endif
589 
590     len = (colnr_T)STRLEN(ml_get_buf(win->w_buffer, win->w_cursor.lnum, FALSE));
591     if (len == 0)
592 	win->w_cursor.col = 0;
593     else if (win->w_cursor.col >= len)
594     {
595 	/* Allow cursor past end-of-line when:
596 	 * - in Insert mode or restarting Insert mode
597 	 * - in Visual mode and 'selection' isn't "old"
598 	 * - 'virtualedit' is set */
599 	if ((State & INSERT) || restart_edit
600 		|| (VIsual_active && *p_sel != 'o')
601 #ifdef FEAT_VIRTUALEDIT
602 		|| (ve_flags & VE_ONEMORE)
603 #endif
604 		|| virtual_active())
605 	    win->w_cursor.col = len;
606 	else
607 	{
608 	    win->w_cursor.col = len - 1;
609 #ifdef FEAT_MBYTE
610 	    /* Move the cursor to the head byte. */
611 	    if (has_mbyte)
612 		mb_adjustpos(win->w_buffer, &win->w_cursor);
613 #endif
614 	}
615     }
616     else if (win->w_cursor.col < 0)
617 	win->w_cursor.col = 0;
618 
619 #ifdef FEAT_VIRTUALEDIT
620     /* If virtual editing is on, we can leave the cursor on the old position,
621      * only we must set it to virtual.  But don't do it when at the end of the
622      * line. */
623     if (oldcol == MAXCOL)
624 	win->w_cursor.coladd = 0;
625     else if (ve_flags == VE_ALL)
626     {
627 	if (oldcoladd > win->w_cursor.col)
628 	{
629 	    win->w_cursor.coladd = oldcoladd - win->w_cursor.col;
630 
631 	    /* Make sure that coladd is not more than the char width.
632 	     * Not for the last character, coladd is then used when the cursor
633 	     * is actually after the last character. */
634 	    if (win->w_cursor.col + 1 < len && win->w_cursor.coladd > 0)
635 	    {
636 		int cs, ce;
637 
638 		getvcol(win, &win->w_cursor, &cs, NULL, &ce);
639 		if (win->w_cursor.coladd > ce - cs)
640 		    win->w_cursor.coladd = ce - cs;
641 	    }
642 	}
643 	else
644 	    /* avoid weird number when there is a miscalculation or overflow */
645 	    win->w_cursor.coladd = 0;
646     }
647 #endif
648 }
649 
650 /*
651  * make sure curwin->w_cursor in on a valid character
652  */
653     void
654 check_cursor(void)
655 {
656     check_cursor_lnum();
657     check_cursor_col();
658 }
659 
660 #if defined(FEAT_TEXTOBJ) || defined(PROTO)
661 /*
662  * Make sure curwin->w_cursor is not on the NUL at the end of the line.
663  * Allow it when in Visual mode and 'selection' is not "old".
664  */
665     void
666 adjust_cursor_col(void)
667 {
668     if (curwin->w_cursor.col > 0
669 	    && (!VIsual_active || *p_sel == 'o')
670 	    && gchar_cursor() == NUL)
671 	--curwin->w_cursor.col;
672 }
673 #endif
674 
675 /*
676  * When curwin->w_leftcol has changed, adjust the cursor position.
677  * Return TRUE if the cursor was moved.
678  */
679     int
680 leftcol_changed(void)
681 {
682     long	lastcol;
683     colnr_T	s, e;
684     int		retval = FALSE;
685 
686     changed_cline_bef_curs();
687     lastcol = curwin->w_leftcol + curwin->w_width - curwin_col_off() - 1;
688     validate_virtcol();
689 
690     /*
691      * If the cursor is right or left of the screen, move it to last or first
692      * character.
693      */
694     if (curwin->w_virtcol > (colnr_T)(lastcol - p_siso))
695     {
696 	retval = TRUE;
697 	coladvance((colnr_T)(lastcol - p_siso));
698     }
699     else if (curwin->w_virtcol < curwin->w_leftcol + p_siso)
700     {
701 	retval = TRUE;
702 	(void)coladvance((colnr_T)(curwin->w_leftcol + p_siso));
703     }
704 
705     /*
706      * If the start of the character under the cursor is not on the screen,
707      * advance the cursor one more char.  If this fails (last char of the
708      * line) adjust the scrolling.
709      */
710     getvvcol(curwin, &curwin->w_cursor, &s, NULL, &e);
711     if (e > (colnr_T)lastcol)
712     {
713 	retval = TRUE;
714 	coladvance(s - 1);
715     }
716     else if (s < curwin->w_leftcol)
717     {
718 	retval = TRUE;
719 	if (coladvance(e + 1) == FAIL)	/* there isn't another character */
720 	{
721 	    curwin->w_leftcol = s;	/* adjust w_leftcol instead */
722 	    changed_cline_bef_curs();
723 	}
724     }
725 
726     if (retval)
727 	curwin->w_set_curswant = TRUE;
728     redraw_later(NOT_VALID);
729     return retval;
730 }
731 
732 /**********************************************************************
733  * Various routines dealing with allocation and deallocation of memory.
734  */
735 
736 #if defined(MEM_PROFILE) || defined(PROTO)
737 
738 # define MEM_SIZES  8200
739 static long_u mem_allocs[MEM_SIZES];
740 static long_u mem_frees[MEM_SIZES];
741 static long_u mem_allocated;
742 static long_u mem_freed;
743 static long_u mem_peak;
744 static long_u num_alloc;
745 static long_u num_freed;
746 
747 static void mem_pre_alloc_s(size_t *sizep);
748 static void mem_pre_alloc_l(long_u *sizep);
749 static void mem_post_alloc(void **pp, size_t size);
750 static void mem_pre_free(void **pp);
751 
752     static void
753 mem_pre_alloc_s(size_t *sizep)
754 {
755     *sizep += sizeof(size_t);
756 }
757 
758     static void
759 mem_pre_alloc_l(long_u *sizep)
760 {
761     *sizep += sizeof(size_t);
762 }
763 
764     static void
765 mem_post_alloc(
766     void **pp,
767     size_t size)
768 {
769     if (*pp == NULL)
770 	return;
771     size -= sizeof(size_t);
772     *(long_u *)*pp = size;
773     if (size <= MEM_SIZES-1)
774 	mem_allocs[size-1]++;
775     else
776 	mem_allocs[MEM_SIZES-1]++;
777     mem_allocated += size;
778     if (mem_allocated - mem_freed > mem_peak)
779 	mem_peak = mem_allocated - mem_freed;
780     num_alloc++;
781     *pp = (void *)((char *)*pp + sizeof(size_t));
782 }
783 
784     static void
785 mem_pre_free(void **pp)
786 {
787     long_u size;
788 
789     *pp = (void *)((char *)*pp - sizeof(size_t));
790     size = *(size_t *)*pp;
791     if (size <= MEM_SIZES-1)
792 	mem_frees[size-1]++;
793     else
794 	mem_frees[MEM_SIZES-1]++;
795     mem_freed += size;
796     num_freed++;
797 }
798 
799 /*
800  * called on exit via atexit()
801  */
802     void
803 vim_mem_profile_dump(void)
804 {
805     int i, j;
806 
807     printf("\r\n");
808     j = 0;
809     for (i = 0; i < MEM_SIZES - 1; i++)
810     {
811 	if (mem_allocs[i] || mem_frees[i])
812 	{
813 	    if (mem_frees[i] > mem_allocs[i])
814 		printf("\r\n%s", _("ERROR: "));
815 	    printf("[%4d / %4lu-%-4lu] ", i + 1, mem_allocs[i], mem_frees[i]);
816 	    j++;
817 	    if (j > 3)
818 	    {
819 		j = 0;
820 		printf("\r\n");
821 	    }
822 	}
823     }
824 
825     i = MEM_SIZES - 1;
826     if (mem_allocs[i])
827     {
828 	printf("\r\n");
829 	if (mem_frees[i] > mem_allocs[i])
830 	    puts(_("ERROR: "));
831 	printf("[>%d / %4lu-%-4lu]", i, mem_allocs[i], mem_frees[i]);
832     }
833 
834     printf(_("\n[bytes] total alloc-freed %lu-%lu, in use %lu, peak use %lu\n"),
835 	    mem_allocated, mem_freed, mem_allocated - mem_freed, mem_peak);
836     printf(_("[calls] total re/malloc()'s %lu, total free()'s %lu\n\n"),
837 	    num_alloc, num_freed);
838 }
839 
840 #endif /* MEM_PROFILE */
841 
842 #ifdef FEAT_EVAL
843 static int alloc_does_fail(long_u size);
844 
845     static int
846 alloc_does_fail(long_u size)
847 {
848     if (alloc_fail_countdown == 0)
849     {
850 	if (--alloc_fail_repeat <= 0)
851 	    alloc_fail_id = 0;
852 	do_outofmem_msg(size);
853 	return TRUE;
854     }
855     --alloc_fail_countdown;
856     return FALSE;
857 }
858 #endif
859 
860 /*
861  * Some memory is reserved for error messages and for being able to
862  * call mf_release_all(), which needs some memory for mf_trans_add().
863  */
864 #define KEEP_ROOM (2 * 8192L)
865 #define KEEP_ROOM_KB (KEEP_ROOM / 1024L)
866 
867 /*
868  * Note: if unsigned is 16 bits we can only allocate up to 64K with alloc().
869  * Use lalloc for larger blocks.
870  */
871     char_u *
872 alloc(unsigned size)
873 {
874     return (lalloc((long_u)size, TRUE));
875 }
876 
877 /*
878  * alloc() with an ID for alloc_fail().
879  */
880     char_u *
881 alloc_id(unsigned size, alloc_id_T id UNUSED)
882 {
883 #ifdef FEAT_EVAL
884     if (alloc_fail_id == id && alloc_does_fail((long_u)size))
885 	return NULL;
886 #endif
887     return (lalloc((long_u)size, TRUE));
888 }
889 
890 /*
891  * Allocate memory and set all bytes to zero.
892  */
893     char_u *
894 alloc_clear(unsigned size)
895 {
896     char_u *p;
897 
898     p = lalloc((long_u)size, TRUE);
899     if (p != NULL)
900 	(void)vim_memset(p, 0, (size_t)size);
901     return p;
902 }
903 
904 /*
905  * alloc() with check for maximum line length
906  */
907     char_u *
908 alloc_check(unsigned size)
909 {
910 #if !defined(UNIX)
911     if (sizeof(int) == 2 && size > 0x7fff)
912     {
913 	/* Don't hide this message */
914 	emsg_silent = 0;
915 	EMSG(_("E340: Line is becoming too long"));
916 	return NULL;
917     }
918 #endif
919     return (lalloc((long_u)size, TRUE));
920 }
921 
922 /*
923  * Allocate memory like lalloc() and set all bytes to zero.
924  */
925     char_u *
926 lalloc_clear(long_u size, int message)
927 {
928     char_u *p;
929 
930     p = (lalloc(size, message));
931     if (p != NULL)
932 	(void)vim_memset(p, 0, (size_t)size);
933     return p;
934 }
935 
936 /*
937  * Low level memory allocation function.
938  * This is used often, KEEP IT FAST!
939  */
940     char_u *
941 lalloc(long_u size, int message)
942 {
943     char_u	*p;		    /* pointer to new storage space */
944     static int	releasing = FALSE;  /* don't do mf_release_all() recursive */
945     int		try_again;
946 #if defined(HAVE_AVAIL_MEM)
947     static long_u allocated = 0;    /* allocated since last avail check */
948 #endif
949 
950     /* Safety check for allocating zero bytes */
951     if (size == 0)
952     {
953 	/* Don't hide this message */
954 	emsg_silent = 0;
955 	IEMSGN(_("E341: Internal error: lalloc(%ld, )"), size);
956 	return NULL;
957     }
958 
959 #ifdef MEM_PROFILE
960     mem_pre_alloc_l(&size);
961 #endif
962 
963     /*
964      * Loop when out of memory: Try to release some memfile blocks and
965      * if some blocks are released call malloc again.
966      */
967     for (;;)
968     {
969 	/*
970 	 * Handle three kind of systems:
971 	 * 1. No check for available memory: Just return.
972 	 * 2. Slow check for available memory: call mch_avail_mem() after
973 	 *    allocating KEEP_ROOM amount of memory.
974 	 * 3. Strict check for available memory: call mch_avail_mem()
975 	 */
976 	if ((p = (char_u *)malloc((size_t)size)) != NULL)
977 	{
978 #ifndef HAVE_AVAIL_MEM
979 	    /* 1. No check for available memory: Just return. */
980 	    goto theend;
981 #else
982 	    /* 2. Slow check for available memory: call mch_avail_mem() after
983 	     *    allocating (KEEP_ROOM / 2) amount of memory. */
984 	    allocated += size;
985 	    if (allocated < KEEP_ROOM / 2)
986 		goto theend;
987 	    allocated = 0;
988 
989 	    /* 3. check for available memory: call mch_avail_mem() */
990 	    if (mch_avail_mem(TRUE) < KEEP_ROOM_KB && !releasing)
991 	    {
992 		free((char *)p);	/* System is low... no go! */
993 		p = NULL;
994 	    }
995 	    else
996 		goto theend;
997 #endif
998 	}
999 	/*
1000 	 * Remember that mf_release_all() is being called to avoid an endless
1001 	 * loop, because mf_release_all() may call alloc() recursively.
1002 	 */
1003 	if (releasing)
1004 	    break;
1005 	releasing = TRUE;
1006 
1007 	clear_sb_text(TRUE);	      /* free any scrollback text */
1008 	try_again = mf_release_all(); /* release as many blocks as possible */
1009 
1010 	releasing = FALSE;
1011 	if (!try_again)
1012 	    break;
1013     }
1014 
1015     if (message && p == NULL)
1016 	do_outofmem_msg(size);
1017 
1018 theend:
1019 #ifdef MEM_PROFILE
1020     mem_post_alloc((void **)&p, (size_t)size);
1021 #endif
1022     return p;
1023 }
1024 
1025 /*
1026  * lalloc() with an ID for alloc_fail().
1027  */
1028     char_u *
1029 lalloc_id(long_u size, int message, alloc_id_T id UNUSED)
1030 {
1031 #ifdef FEAT_EVAL
1032     if (alloc_fail_id == id && alloc_does_fail(size))
1033 	return NULL;
1034 #endif
1035     return (lalloc((long_u)size, message));
1036 }
1037 
1038 #if defined(MEM_PROFILE) || defined(PROTO)
1039 /*
1040  * realloc() with memory profiling.
1041  */
1042     void *
1043 mem_realloc(void *ptr, size_t size)
1044 {
1045     void *p;
1046 
1047     mem_pre_free(&ptr);
1048     mem_pre_alloc_s(&size);
1049 
1050     p = realloc(ptr, size);
1051 
1052     mem_post_alloc(&p, size);
1053 
1054     return p;
1055 }
1056 #endif
1057 
1058 /*
1059 * Avoid repeating the error message many times (they take 1 second each).
1060 * Did_outofmem_msg is reset when a character is read.
1061 */
1062     void
1063 do_outofmem_msg(long_u size)
1064 {
1065     if (!did_outofmem_msg)
1066     {
1067 	/* Don't hide this message */
1068 	emsg_silent = 0;
1069 
1070 	/* Must come first to avoid coming back here when printing the error
1071 	 * message fails, e.g. when setting v:errmsg. */
1072 	did_outofmem_msg = TRUE;
1073 
1074 	EMSGN(_("E342: Out of memory!  (allocating %lu bytes)"), size);
1075     }
1076 }
1077 
1078 #if defined(EXITFREE) || defined(PROTO)
1079 
1080 # if defined(FEAT_SEARCHPATH)
1081 static void free_findfile(void);
1082 # endif
1083 
1084 /*
1085  * Free everything that we allocated.
1086  * Can be used to detect memory leaks, e.g., with ccmalloc.
1087  * NOTE: This is tricky!  Things are freed that functions depend on.  Don't be
1088  * surprised if Vim crashes...
1089  * Some things can't be freed, esp. things local to a library function.
1090  */
1091     void
1092 free_all_mem(void)
1093 {
1094     buf_T	*buf, *nextbuf;
1095 
1096     /* When we cause a crash here it is caught and Vim tries to exit cleanly.
1097      * Don't try freeing everything again. */
1098     if (entered_free_all_mem)
1099 	return;
1100     entered_free_all_mem = TRUE;
1101 
1102 # ifdef FEAT_AUTOCMD
1103     /* Don't want to trigger autocommands from here on. */
1104     block_autocmds();
1105 # endif
1106 
1107     /* Close all tabs and windows.  Reset 'equalalways' to avoid redraws. */
1108     p_ea = FALSE;
1109     if (first_tabpage->tp_next != NULL)
1110 	do_cmdline_cmd((char_u *)"tabonly!");
1111     if (!ONE_WINDOW)
1112 	do_cmdline_cmd((char_u *)"only!");
1113 
1114 # if defined(FEAT_SPELL)
1115     /* Free all spell info. */
1116     spell_free_all();
1117 # endif
1118 
1119 #if defined(FEAT_INS_EXPAND) && defined(FEAT_BEVAL_TERM)
1120     ui_remove_balloon();
1121 # endif
1122 
1123 # if defined(FEAT_USR_CMDS)
1124     /* Clear user commands (before deleting buffers). */
1125     ex_comclear(NULL);
1126 # endif
1127 
1128 # ifdef FEAT_MENU
1129     /* Clear menus. */
1130     do_cmdline_cmd((char_u *)"aunmenu *");
1131 #  ifdef FEAT_MULTI_LANG
1132     do_cmdline_cmd((char_u *)"menutranslate clear");
1133 #  endif
1134 # endif
1135 
1136     /* Clear mappings, abbreviations, breakpoints. */
1137     do_cmdline_cmd((char_u *)"lmapclear");
1138     do_cmdline_cmd((char_u *)"xmapclear");
1139     do_cmdline_cmd((char_u *)"mapclear");
1140     do_cmdline_cmd((char_u *)"mapclear!");
1141     do_cmdline_cmd((char_u *)"abclear");
1142 # if defined(FEAT_EVAL)
1143     do_cmdline_cmd((char_u *)"breakdel *");
1144 # endif
1145 # if defined(FEAT_PROFILE)
1146     do_cmdline_cmd((char_u *)"profdel *");
1147 # endif
1148 # if defined(FEAT_KEYMAP)
1149     do_cmdline_cmd((char_u *)"set keymap=");
1150 #endif
1151 
1152 # ifdef FEAT_TITLE
1153     free_titles();
1154 # endif
1155 # if defined(FEAT_SEARCHPATH)
1156     free_findfile();
1157 # endif
1158 
1159     /* Obviously named calls. */
1160 # if defined(FEAT_AUTOCMD)
1161     free_all_autocmds();
1162 # endif
1163     clear_termcodes();
1164     free_all_marks();
1165     alist_clear(&global_alist);
1166     free_homedir();
1167 # if defined(FEAT_CMDL_COMPL)
1168     free_users();
1169 # endif
1170     free_search_patterns();
1171     free_old_sub();
1172     free_last_insert();
1173     free_prev_shellcmd();
1174     free_regexp_stuff();
1175     free_tag_stuff();
1176     free_cd_dir();
1177 # ifdef FEAT_SIGNS
1178     free_signs();
1179 # endif
1180 # ifdef FEAT_EVAL
1181     set_expr_line(NULL);
1182 # endif
1183 # ifdef FEAT_DIFF
1184     diff_clear(curtab);
1185 # endif
1186     clear_sb_text(TRUE);	      /* free any scrollback text */
1187 
1188     /* Free some global vars. */
1189     vim_free(username);
1190 # ifdef FEAT_CLIPBOARD
1191     vim_regfree(clip_exclude_prog);
1192 # endif
1193     vim_free(last_cmdline);
1194 # ifdef FEAT_CMDHIST
1195     vim_free(new_last_cmdline);
1196 # endif
1197     set_keep_msg(NULL, 0);
1198     vim_free(ff_expand_buffer);
1199 
1200     /* Clear cmdline history. */
1201     p_hi = 0;
1202 # ifdef FEAT_CMDHIST
1203     init_history();
1204 # endif
1205 
1206 #ifdef FEAT_QUICKFIX
1207     {
1208 	win_T	    *win;
1209 	tabpage_T   *tab;
1210 
1211 	qf_free_all(NULL);
1212 	/* Free all location lists */
1213 	FOR_ALL_TAB_WINDOWS(tab, win)
1214 	    qf_free_all(win);
1215     }
1216 #endif
1217 
1218     /* Close all script inputs. */
1219     close_all_scripts();
1220 
1221     /* Destroy all windows.  Must come before freeing buffers. */
1222     win_free_all();
1223 
1224     /* Free all option values.  Must come after closing windows. */
1225     free_all_options();
1226 
1227     /* Free all buffers.  Reset 'autochdir' to avoid accessing things that
1228      * were freed already. */
1229 #ifdef FEAT_AUTOCHDIR
1230     p_acd = FALSE;
1231 #endif
1232     for (buf = firstbuf; buf != NULL; )
1233     {
1234 	bufref_T    bufref;
1235 
1236 	set_bufref(&bufref, buf);
1237 	nextbuf = buf->b_next;
1238 	close_buffer(NULL, buf, DOBUF_WIPE, FALSE);
1239 	if (bufref_valid(&bufref))
1240 	    buf = nextbuf;	/* didn't work, try next one */
1241 	else
1242 	    buf = firstbuf;
1243     }
1244 
1245 #ifdef FEAT_ARABIC
1246     free_cmdline_buf();
1247 #endif
1248 
1249     /* Clear registers. */
1250     clear_registers();
1251     ResetRedobuff();
1252     ResetRedobuff();
1253 
1254 #if defined(FEAT_CLIENTSERVER) && defined(FEAT_X11)
1255     vim_free(serverDelayedStartName);
1256 #endif
1257 
1258     /* highlight info */
1259     free_highlight();
1260 
1261     reset_last_sourcing();
1262 
1263     free_tabpage(first_tabpage);
1264     first_tabpage = NULL;
1265 
1266 # ifdef UNIX
1267     /* Machine-specific free. */
1268     mch_free_mem();
1269 # endif
1270 
1271     /* message history */
1272     for (;;)
1273 	if (delete_first_msg() == FAIL)
1274 	    break;
1275 
1276 # ifdef FEAT_JOB_CHANNEL
1277     channel_free_all();
1278 # endif
1279 #ifdef FEAT_TIMERS
1280     timer_free_all();
1281 #endif
1282 # ifdef FEAT_EVAL
1283     /* must be after channel_free_all() with unrefs partials */
1284     eval_clear();
1285 # endif
1286 # ifdef FEAT_JOB_CHANNEL
1287     /* must be after eval_clear() with unrefs jobs */
1288     job_free_all();
1289 # endif
1290 
1291     free_termoptions();
1292 
1293     /* screenlines (can't display anything now!) */
1294     free_screenlines();
1295 
1296 #if defined(USE_XSMP)
1297     xsmp_close();
1298 #endif
1299 #ifdef FEAT_GUI_GTK
1300     gui_mch_free_all();
1301 #endif
1302     clear_hl_tables();
1303 
1304     vim_free(IObuff);
1305     vim_free(NameBuff);
1306 }
1307 #endif
1308 
1309 /*
1310  * Copy "string" into newly allocated memory.
1311  */
1312     char_u *
1313 vim_strsave(char_u *string)
1314 {
1315     char_u	*p;
1316     unsigned	len;
1317 
1318     len = (unsigned)STRLEN(string) + 1;
1319     p = alloc(len);
1320     if (p != NULL)
1321 	mch_memmove(p, string, (size_t)len);
1322     return p;
1323 }
1324 
1325 /*
1326  * Copy up to "len" bytes of "string" into newly allocated memory and
1327  * terminate with a NUL.
1328  * The allocated memory always has size "len + 1", also when "string" is
1329  * shorter.
1330  */
1331     char_u *
1332 vim_strnsave(char_u *string, int len)
1333 {
1334     char_u	*p;
1335 
1336     p = alloc((unsigned)(len + 1));
1337     if (p != NULL)
1338     {
1339 	STRNCPY(p, string, len);
1340 	p[len] = NUL;
1341     }
1342     return p;
1343 }
1344 
1345 /*
1346  * Same as vim_strsave(), but any characters found in esc_chars are preceded
1347  * by a backslash.
1348  */
1349     char_u *
1350 vim_strsave_escaped(char_u *string, char_u *esc_chars)
1351 {
1352     return vim_strsave_escaped_ext(string, esc_chars, '\\', FALSE);
1353 }
1354 
1355 /*
1356  * Same as vim_strsave_escaped(), but when "bsl" is TRUE also escape
1357  * characters where rem_backslash() would remove the backslash.
1358  * Escape the characters with "cc".
1359  */
1360     char_u *
1361 vim_strsave_escaped_ext(
1362     char_u	*string,
1363     char_u	*esc_chars,
1364     int		cc,
1365     int		bsl)
1366 {
1367     char_u	*p;
1368     char_u	*p2;
1369     char_u	*escaped_string;
1370     unsigned	length;
1371 #ifdef FEAT_MBYTE
1372     int		l;
1373 #endif
1374 
1375     /*
1376      * First count the number of backslashes required.
1377      * Then allocate the memory and insert them.
1378      */
1379     length = 1;				/* count the trailing NUL */
1380     for (p = string; *p; p++)
1381     {
1382 #ifdef FEAT_MBYTE
1383 	if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1)
1384 	{
1385 	    length += l;		/* count a multibyte char */
1386 	    p += l - 1;
1387 	    continue;
1388 	}
1389 #endif
1390 	if (vim_strchr(esc_chars, *p) != NULL || (bsl && rem_backslash(p)))
1391 	    ++length;			/* count a backslash */
1392 	++length;			/* count an ordinary char */
1393     }
1394     escaped_string = alloc(length);
1395     if (escaped_string != NULL)
1396     {
1397 	p2 = escaped_string;
1398 	for (p = string; *p; p++)
1399 	{
1400 #ifdef FEAT_MBYTE
1401 	    if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1)
1402 	    {
1403 		mch_memmove(p2, p, (size_t)l);
1404 		p2 += l;
1405 		p += l - 1;		/* skip multibyte char  */
1406 		continue;
1407 	    }
1408 #endif
1409 	    if (vim_strchr(esc_chars, *p) != NULL || (bsl && rem_backslash(p)))
1410 		*p2++ = cc;
1411 	    *p2++ = *p;
1412 	}
1413 	*p2 = NUL;
1414     }
1415     return escaped_string;
1416 }
1417 
1418 /*
1419  * Return TRUE when 'shell' has "csh" in the tail.
1420  */
1421     int
1422 csh_like_shell(void)
1423 {
1424     return (strstr((char *)gettail(p_sh), "csh") != NULL);
1425 }
1426 
1427 /*
1428  * Escape "string" for use as a shell argument with system().
1429  * This uses single quotes, except when we know we need to use double quotes
1430  * (MS-DOS and MS-Windows without 'shellslash' set).
1431  * Escape a newline, depending on the 'shell' option.
1432  * When "do_special" is TRUE also replace "!", "%", "#" and things starting
1433  * with "<" like "<cfile>".
1434  * When "do_newline" is FALSE do not escape newline unless it is csh shell.
1435  * Returns the result in allocated memory, NULL if we have run out.
1436  */
1437     char_u *
1438 vim_strsave_shellescape(char_u *string, int do_special, int do_newline)
1439 {
1440     unsigned	length;
1441     char_u	*p;
1442     char_u	*d;
1443     char_u	*escaped_string;
1444     int		l;
1445     int		csh_like;
1446 
1447     /* Only csh and similar shells expand '!' within single quotes.  For sh and
1448      * the like we must not put a backslash before it, it will be taken
1449      * literally.  If do_special is set the '!' will be escaped twice.
1450      * Csh also needs to have "\n" escaped twice when do_special is set. */
1451     csh_like = csh_like_shell();
1452 
1453     /* First count the number of extra bytes required. */
1454     length = (unsigned)STRLEN(string) + 3;  /* two quotes and a trailing NUL */
1455     for (p = string; *p != NUL; MB_PTR_ADV(p))
1456     {
1457 # ifdef WIN32
1458 	if (!p_ssl)
1459 	{
1460 	    if (*p == '"')
1461 		++length;		/* " -> "" */
1462 	}
1463 	else
1464 # endif
1465 	if (*p == '\'')
1466 	    length += 3;		/* ' => '\'' */
1467 	if ((*p == '\n' && (csh_like || do_newline))
1468 		|| (*p == '!' && (csh_like || do_special)))
1469 	{
1470 	    ++length;			/* insert backslash */
1471 	    if (csh_like && do_special)
1472 		++length;		/* insert backslash */
1473 	}
1474 	if (do_special && find_cmdline_var(p, &l) >= 0)
1475 	{
1476 	    ++length;			/* insert backslash */
1477 	    p += l - 1;
1478 	}
1479     }
1480 
1481     /* Allocate memory for the result and fill it. */
1482     escaped_string = alloc(length);
1483     if (escaped_string != NULL)
1484     {
1485 	d = escaped_string;
1486 
1487 	/* add opening quote */
1488 # ifdef WIN32
1489 	if (!p_ssl)
1490 	    *d++ = '"';
1491 	else
1492 # endif
1493 	    *d++ = '\'';
1494 
1495 	for (p = string; *p != NUL; )
1496 	{
1497 # ifdef WIN32
1498 	    if (!p_ssl)
1499 	    {
1500 		if (*p == '"')
1501 		{
1502 		    *d++ = '"';
1503 		    *d++ = '"';
1504 		    ++p;
1505 		    continue;
1506 		}
1507 	    }
1508 	    else
1509 # endif
1510 	    if (*p == '\'')
1511 	    {
1512 		*d++ = '\'';
1513 		*d++ = '\\';
1514 		*d++ = '\'';
1515 		*d++ = '\'';
1516 		++p;
1517 		continue;
1518 	    }
1519 	    if ((*p == '\n' && (csh_like || do_newline))
1520 		    || (*p == '!' && (csh_like || do_special)))
1521 	    {
1522 		*d++ = '\\';
1523 		if (csh_like && do_special)
1524 		    *d++ = '\\';
1525 		*d++ = *p++;
1526 		continue;
1527 	    }
1528 	    if (do_special && find_cmdline_var(p, &l) >= 0)
1529 	    {
1530 		*d++ = '\\';		/* insert backslash */
1531 		while (--l >= 0)	/* copy the var */
1532 		    *d++ = *p++;
1533 		continue;
1534 	    }
1535 
1536 	    MB_COPY_CHAR(p, d);
1537 	}
1538 
1539 	/* add terminating quote and finish with a NUL */
1540 # ifdef WIN32
1541 	if (!p_ssl)
1542 	    *d++ = '"';
1543 	else
1544 # endif
1545 	    *d++ = '\'';
1546 	*d = NUL;
1547     }
1548 
1549     return escaped_string;
1550 }
1551 
1552 /*
1553  * Like vim_strsave(), but make all characters uppercase.
1554  * This uses ASCII lower-to-upper case translation, language independent.
1555  */
1556     char_u *
1557 vim_strsave_up(char_u *string)
1558 {
1559     char_u *p1;
1560 
1561     p1 = vim_strsave(string);
1562     vim_strup(p1);
1563     return p1;
1564 }
1565 
1566 /*
1567  * Like vim_strnsave(), but make all characters uppercase.
1568  * This uses ASCII lower-to-upper case translation, language independent.
1569  */
1570     char_u *
1571 vim_strnsave_up(char_u *string, int len)
1572 {
1573     char_u *p1;
1574 
1575     p1 = vim_strnsave(string, len);
1576     vim_strup(p1);
1577     return p1;
1578 }
1579 
1580 /*
1581  * ASCII lower-to-upper case translation, language independent.
1582  */
1583     void
1584 vim_strup(
1585     char_u	*p)
1586 {
1587     char_u  *p2;
1588     int	    c;
1589 
1590     if (p != NULL)
1591     {
1592 	p2 = p;
1593 	while ((c = *p2) != NUL)
1594 #ifdef EBCDIC
1595 	    *p2++ = isalpha(c) ? toupper(c) : c;
1596 #else
1597 	    *p2++ = (c < 'a' || c > 'z') ? c : (c - 0x20);
1598 #endif
1599     }
1600 }
1601 
1602 #if defined(FEAT_EVAL) || defined(FEAT_SPELL) || defined(PROTO)
1603 /*
1604  * Make string "s" all upper-case and return it in allocated memory.
1605  * Handles multi-byte characters as well as possible.
1606  * Returns NULL when out of memory.
1607  */
1608     char_u *
1609 strup_save(char_u *orig)
1610 {
1611     char_u	*p;
1612     char_u	*res;
1613 
1614     res = p = vim_strsave(orig);
1615 
1616     if (res != NULL)
1617 	while (*p != NUL)
1618 	{
1619 # ifdef FEAT_MBYTE
1620 	    int		l;
1621 
1622 	    if (enc_utf8)
1623 	    {
1624 		int	c, uc;
1625 		int	newl;
1626 		char_u	*s;
1627 
1628 		c = utf_ptr2char(p);
1629 		l = utf_ptr2len(p);
1630 		if (c == 0)
1631 		{
1632 		    /* overlong sequence, use only the first byte */
1633 		    c = *p;
1634 		    l = 1;
1635 		}
1636 		uc = utf_toupper(c);
1637 
1638 		/* Reallocate string when byte count changes.  This is rare,
1639 		 * thus it's OK to do another malloc()/free(). */
1640 		newl = utf_char2len(uc);
1641 		if (newl != l)
1642 		{
1643 		    s = alloc((unsigned)STRLEN(res) + 1 + newl - l);
1644 		    if (s == NULL)
1645 		    {
1646 			vim_free(res);
1647 			return NULL;
1648 		    }
1649 		    mch_memmove(s, res, p - res);
1650 		    STRCPY(s + (p - res) + newl, p + l);
1651 		    p = s + (p - res);
1652 		    vim_free(res);
1653 		    res = s;
1654 		}
1655 
1656 		utf_char2bytes(uc, p);
1657 		p += newl;
1658 	    }
1659 	    else if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1)
1660 		p += l;		/* skip multi-byte character */
1661 	    else
1662 # endif
1663 	    {
1664 		*p = TOUPPER_LOC(*p); /* note that toupper() can be a macro */
1665 		p++;
1666 	    }
1667 	}
1668 
1669     return res;
1670 }
1671 
1672 /*
1673  * Make string "s" all lower-case and return it in allocated memory.
1674  * Handles multi-byte characters as well as possible.
1675  * Returns NULL when out of memory.
1676  */
1677     char_u *
1678 strlow_save(char_u *orig)
1679 {
1680     char_u	*p;
1681     char_u	*res;
1682 
1683     res = p = vim_strsave(orig);
1684 
1685     if (res != NULL)
1686 	while (*p != NUL)
1687 	{
1688 # ifdef FEAT_MBYTE
1689 	    int		l;
1690 
1691 	    if (enc_utf8)
1692 	    {
1693 		int	c, lc;
1694 		int	newl;
1695 		char_u	*s;
1696 
1697 		c = utf_ptr2char(p);
1698 		l = utf_ptr2len(p);
1699 		if (c == 0)
1700 		{
1701 		    /* overlong sequence, use only the first byte */
1702 		    c = *p;
1703 		    l = 1;
1704 		}
1705 		lc = utf_tolower(c);
1706 
1707 		/* Reallocate string when byte count changes.  This is rare,
1708 		 * thus it's OK to do another malloc()/free(). */
1709 		newl = utf_char2len(lc);
1710 		if (newl != l)
1711 		{
1712 		    s = alloc((unsigned)STRLEN(res) + 1 + newl - l);
1713 		    if (s == NULL)
1714 		    {
1715 			vim_free(res);
1716 			return NULL;
1717 		    }
1718 		    mch_memmove(s, res, p - res);
1719 		    STRCPY(s + (p - res) + newl, p + l);
1720 		    p = s + (p - res);
1721 		    vim_free(res);
1722 		    res = s;
1723 		}
1724 
1725 		utf_char2bytes(lc, p);
1726 		p += newl;
1727 	    }
1728 	    else if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1)
1729 		p += l;		/* skip multi-byte character */
1730 	    else
1731 # endif
1732 	    {
1733 		*p = TOLOWER_LOC(*p); /* note that tolower() can be a macro */
1734 		p++;
1735 	    }
1736 	}
1737 
1738     return res;
1739 }
1740 #endif
1741 
1742 /*
1743  * delete spaces at the end of a string
1744  */
1745     void
1746 del_trailing_spaces(char_u *ptr)
1747 {
1748     char_u	*q;
1749 
1750     q = ptr + STRLEN(ptr);
1751     while (--q > ptr && VIM_ISWHITE(q[0]) && q[-1] != '\\' && q[-1] != Ctrl_V)
1752 	*q = NUL;
1753 }
1754 
1755 /*
1756  * Like strncpy(), but always terminate the result with one NUL.
1757  * "to" must be "len + 1" long!
1758  */
1759     void
1760 vim_strncpy(char_u *to, char_u *from, size_t len)
1761 {
1762     STRNCPY(to, from, len);
1763     to[len] = NUL;
1764 }
1765 
1766 /*
1767  * Like strcat(), but make sure the result fits in "tosize" bytes and is
1768  * always NUL terminated. "from" and "to" may overlap.
1769  */
1770     void
1771 vim_strcat(char_u *to, char_u *from, size_t tosize)
1772 {
1773     size_t tolen = STRLEN(to);
1774     size_t fromlen = STRLEN(from);
1775 
1776     if (tolen + fromlen + 1 > tosize)
1777     {
1778 	mch_memmove(to + tolen, from, tosize - tolen - 1);
1779 	to[tosize - 1] = NUL;
1780     }
1781     else
1782 	mch_memmove(to + tolen, from, fromlen + 1);
1783 }
1784 
1785 /*
1786  * Isolate one part of a string option where parts are separated with
1787  * "sep_chars".
1788  * The part is copied into "buf[maxlen]".
1789  * "*option" is advanced to the next part.
1790  * The length is returned.
1791  */
1792     int
1793 copy_option_part(
1794     char_u	**option,
1795     char_u	*buf,
1796     int		maxlen,
1797     char	*sep_chars)
1798 {
1799     int	    len = 0;
1800     char_u  *p = *option;
1801 
1802     /* skip '.' at start of option part, for 'suffixes' */
1803     if (*p == '.')
1804 	buf[len++] = *p++;
1805     while (*p != NUL && vim_strchr((char_u *)sep_chars, *p) == NULL)
1806     {
1807 	/*
1808 	 * Skip backslash before a separator character and space.
1809 	 */
1810 	if (p[0] == '\\' && vim_strchr((char_u *)sep_chars, p[1]) != NULL)
1811 	    ++p;
1812 	if (len < maxlen - 1)
1813 	    buf[len++] = *p;
1814 	++p;
1815     }
1816     buf[len] = NUL;
1817 
1818     if (*p != NUL && *p != ',')	/* skip non-standard separator */
1819 	++p;
1820     p = skip_to_option_part(p);	/* p points to next file name */
1821 
1822     *option = p;
1823     return len;
1824 }
1825 
1826 /*
1827  * Replacement for free() that ignores NULL pointers.
1828  * Also skip free() when exiting for sure, this helps when we caught a deadly
1829  * signal that was caused by a crash in free().
1830  * If you want to set NULL after calling this function, you should use
1831  * VIM_CLEAR() instead.
1832  */
1833     void
1834 vim_free(void *x)
1835 {
1836     if (x != NULL && !really_exiting)
1837     {
1838 #ifdef MEM_PROFILE
1839 	mem_pre_free(&x);
1840 #endif
1841 	free(x);
1842     }
1843 }
1844 
1845 #ifndef HAVE_MEMSET
1846     void *
1847 vim_memset(void *ptr, int c, size_t size)
1848 {
1849     char *p = ptr;
1850 
1851     while (size-- > 0)
1852 	*p++ = c;
1853     return ptr;
1854 }
1855 #endif
1856 
1857 #if (!defined(HAVE_STRCASECMP) && !defined(HAVE_STRICMP)) || defined(PROTO)
1858 /*
1859  * Compare two strings, ignoring case, using current locale.
1860  * Doesn't work for multi-byte characters.
1861  * return 0 for match, < 0 for smaller, > 0 for bigger
1862  */
1863     int
1864 vim_stricmp(char *s1, char *s2)
1865 {
1866     int		i;
1867 
1868     for (;;)
1869     {
1870 	i = (int)TOLOWER_LOC(*s1) - (int)TOLOWER_LOC(*s2);
1871 	if (i != 0)
1872 	    return i;			    /* this character different */
1873 	if (*s1 == NUL)
1874 	    break;			    /* strings match until NUL */
1875 	++s1;
1876 	++s2;
1877     }
1878     return 0;				    /* strings match */
1879 }
1880 #endif
1881 
1882 #if (!defined(HAVE_STRNCASECMP) && !defined(HAVE_STRNICMP)) || defined(PROTO)
1883 /*
1884  * Compare two strings, for length "len", ignoring case, using current locale.
1885  * Doesn't work for multi-byte characters.
1886  * return 0 for match, < 0 for smaller, > 0 for bigger
1887  */
1888     int
1889 vim_strnicmp(char *s1, char *s2, size_t len)
1890 {
1891     int		i;
1892 
1893     while (len > 0)
1894     {
1895 	i = (int)TOLOWER_LOC(*s1) - (int)TOLOWER_LOC(*s2);
1896 	if (i != 0)
1897 	    return i;			    /* this character different */
1898 	if (*s1 == NUL)
1899 	    break;			    /* strings match until NUL */
1900 	++s1;
1901 	++s2;
1902 	--len;
1903     }
1904     return 0;				    /* strings match */
1905 }
1906 #endif
1907 
1908 /*
1909  * Version of strchr() and strrchr() that handle unsigned char strings
1910  * with characters from 128 to 255 correctly.  It also doesn't return a
1911  * pointer to the NUL at the end of the string.
1912  */
1913     char_u  *
1914 vim_strchr(char_u *string, int c)
1915 {
1916     char_u	*p;
1917     int		b;
1918 
1919     p = string;
1920 #ifdef FEAT_MBYTE
1921     if (enc_utf8 && c >= 0x80)
1922     {
1923 	while (*p != NUL)
1924 	{
1925 	    int l = utfc_ptr2len(p);
1926 
1927 	    /* Avoid matching an illegal byte here. */
1928 	    if (utf_ptr2char(p) == c && l > 1)
1929 		return p;
1930 	    p += l;
1931 	}
1932 	return NULL;
1933     }
1934     if (enc_dbcs != 0 && c > 255)
1935     {
1936 	int	n2 = c & 0xff;
1937 
1938 	c = ((unsigned)c >> 8) & 0xff;
1939 	while ((b = *p) != NUL)
1940 	{
1941 	    if (b == c && p[1] == n2)
1942 		return p;
1943 	    p += (*mb_ptr2len)(p);
1944 	}
1945 	return NULL;
1946     }
1947     if (has_mbyte)
1948     {
1949 	while ((b = *p) != NUL)
1950 	{
1951 	    if (b == c)
1952 		return p;
1953 	    p += (*mb_ptr2len)(p);
1954 	}
1955 	return NULL;
1956     }
1957 #endif
1958     while ((b = *p) != NUL)
1959     {
1960 	if (b == c)
1961 	    return p;
1962 	++p;
1963     }
1964     return NULL;
1965 }
1966 
1967 /*
1968  * Version of strchr() that only works for bytes and handles unsigned char
1969  * strings with characters above 128 correctly. It also doesn't return a
1970  * pointer to the NUL at the end of the string.
1971  */
1972     char_u  *
1973 vim_strbyte(char_u *string, int c)
1974 {
1975     char_u	*p = string;
1976 
1977     while (*p != NUL)
1978     {
1979 	if (*p == c)
1980 	    return p;
1981 	++p;
1982     }
1983     return NULL;
1984 }
1985 
1986 /*
1987  * Search for last occurrence of "c" in "string".
1988  * Return NULL if not found.
1989  * Does not handle multi-byte char for "c"!
1990  */
1991     char_u  *
1992 vim_strrchr(char_u *string, int c)
1993 {
1994     char_u	*retval = NULL;
1995     char_u	*p = string;
1996 
1997     while (*p)
1998     {
1999 	if (*p == c)
2000 	    retval = p;
2001 	MB_PTR_ADV(p);
2002     }
2003     return retval;
2004 }
2005 
2006 /*
2007  * Vim's version of strpbrk(), in case it's missing.
2008  * Don't generate a prototype for this, causes problems when it's not used.
2009  */
2010 #ifndef PROTO
2011 # ifndef HAVE_STRPBRK
2012 #  ifdef vim_strpbrk
2013 #   undef vim_strpbrk
2014 #  endif
2015     char_u *
2016 vim_strpbrk(char_u *s, char_u *charset)
2017 {
2018     while (*s)
2019     {
2020 	if (vim_strchr(charset, *s) != NULL)
2021 	    return s;
2022 	MB_PTR_ADV(s);
2023     }
2024     return NULL;
2025 }
2026 # endif
2027 #endif
2028 
2029 /*
2030  * Vim has its own isspace() function, because on some machines isspace()
2031  * can't handle characters above 128.
2032  */
2033     int
2034 vim_isspace(int x)
2035 {
2036     return ((x >= 9 && x <= 13) || x == ' ');
2037 }
2038 
2039 /************************************************************************
2040  * Functions for handling growing arrays.
2041  */
2042 
2043 /*
2044  * Clear an allocated growing array.
2045  */
2046     void
2047 ga_clear(garray_T *gap)
2048 {
2049     vim_free(gap->ga_data);
2050     ga_init(gap);
2051 }
2052 
2053 /*
2054  * Clear a growing array that contains a list of strings.
2055  */
2056     void
2057 ga_clear_strings(garray_T *gap)
2058 {
2059     int		i;
2060 
2061     for (i = 0; i < gap->ga_len; ++i)
2062 	vim_free(((char_u **)(gap->ga_data))[i]);
2063     ga_clear(gap);
2064 }
2065 
2066 /*
2067  * Initialize a growing array.	Don't forget to set ga_itemsize and
2068  * ga_growsize!  Or use ga_init2().
2069  */
2070     void
2071 ga_init(garray_T *gap)
2072 {
2073     gap->ga_data = NULL;
2074     gap->ga_maxlen = 0;
2075     gap->ga_len = 0;
2076 }
2077 
2078     void
2079 ga_init2(garray_T *gap, int itemsize, int growsize)
2080 {
2081     ga_init(gap);
2082     gap->ga_itemsize = itemsize;
2083     gap->ga_growsize = growsize;
2084 }
2085 
2086 /*
2087  * Make room in growing array "gap" for at least "n" items.
2088  * Return FAIL for failure, OK otherwise.
2089  */
2090     int
2091 ga_grow(garray_T *gap, int n)
2092 {
2093     size_t	old_len;
2094     size_t	new_len;
2095     char_u	*pp;
2096 
2097     if (gap->ga_maxlen - gap->ga_len < n)
2098     {
2099 	if (n < gap->ga_growsize)
2100 	    n = gap->ga_growsize;
2101 	new_len = gap->ga_itemsize * (gap->ga_len + n);
2102 	pp = (gap->ga_data == NULL)
2103 	      ? alloc((unsigned)new_len) : vim_realloc(gap->ga_data, new_len);
2104 	if (pp == NULL)
2105 	    return FAIL;
2106 	old_len = gap->ga_itemsize * gap->ga_maxlen;
2107 	vim_memset(pp + old_len, 0, new_len - old_len);
2108 	gap->ga_maxlen = gap->ga_len + n;
2109 	gap->ga_data = pp;
2110     }
2111     return OK;
2112 }
2113 
2114 /*
2115  * For a growing array that contains a list of strings: concatenate all the
2116  * strings with a separating "sep".
2117  * Returns NULL when out of memory.
2118  */
2119     char_u *
2120 ga_concat_strings(garray_T *gap, char *sep)
2121 {
2122     int		i;
2123     int		len = 0;
2124     int		sep_len = (int)STRLEN(sep);
2125     char_u	*s;
2126     char_u	*p;
2127 
2128     for (i = 0; i < gap->ga_len; ++i)
2129 	len += (int)STRLEN(((char_u **)(gap->ga_data))[i]) + sep_len;
2130 
2131     s = alloc(len + 1);
2132     if (s != NULL)
2133     {
2134 	*s = NUL;
2135 	p = s;
2136 	for (i = 0; i < gap->ga_len; ++i)
2137 	{
2138 	    if (p != s)
2139 	    {
2140 		STRCPY(p, sep);
2141 		p += sep_len;
2142 	    }
2143 	    STRCPY(p, ((char_u **)(gap->ga_data))[i]);
2144 	    p += STRLEN(p);
2145 	}
2146     }
2147     return s;
2148 }
2149 
2150 #if defined(FEAT_VIMINFO) || defined(FEAT_EVAL) || defined(PROTO)
2151 /*
2152  * Make a copy of string "p" and add it to "gap".
2153  * When out of memory nothing changes.
2154  */
2155     void
2156 ga_add_string(garray_T *gap, char_u *p)
2157 {
2158     char_u *cp = vim_strsave(p);
2159 
2160     if (cp != NULL)
2161     {
2162 	if (ga_grow(gap, 1) == OK)
2163 	    ((char_u **)(gap->ga_data))[gap->ga_len++] = cp;
2164 	else
2165 	    vim_free(cp);
2166     }
2167 }
2168 #endif
2169 
2170 /*
2171  * Concatenate a string to a growarray which contains characters.
2172  * When "s" is NULL does not do anything.
2173  * Note: Does NOT copy the NUL at the end!
2174  */
2175     void
2176 ga_concat(garray_T *gap, char_u *s)
2177 {
2178     int    len;
2179 
2180     if (s == NULL || *s == NUL)
2181 	return;
2182     len = (int)STRLEN(s);
2183     if (ga_grow(gap, len) == OK)
2184     {
2185 	mch_memmove((char *)gap->ga_data + gap->ga_len, s, (size_t)len);
2186 	gap->ga_len += len;
2187     }
2188 }
2189 
2190 /*
2191  * Append one byte to a growarray which contains bytes.
2192  */
2193     void
2194 ga_append(garray_T *gap, int c)
2195 {
2196     if (ga_grow(gap, 1) == OK)
2197     {
2198 	*((char *)gap->ga_data + gap->ga_len) = c;
2199 	++gap->ga_len;
2200     }
2201 }
2202 
2203 #if (defined(UNIX) && !defined(USE_SYSTEM)) || defined(WIN3264) \
2204 	|| defined(PROTO)
2205 /*
2206  * Append the text in "gap" below the cursor line and clear "gap".
2207  */
2208     void
2209 append_ga_line(garray_T *gap)
2210 {
2211     /* Remove trailing CR. */
2212     if (gap->ga_len > 0
2213 	    && !curbuf->b_p_bin
2214 	    && ((char_u *)gap->ga_data)[gap->ga_len - 1] == CAR)
2215 	--gap->ga_len;
2216     ga_append(gap, NUL);
2217     ml_append(curwin->w_cursor.lnum++, gap->ga_data, 0, FALSE);
2218     gap->ga_len = 0;
2219 }
2220 #endif
2221 
2222 /************************************************************************
2223  * functions that use lookup tables for various things, generally to do with
2224  * special key codes.
2225  */
2226 
2227 /*
2228  * Some useful tables.
2229  */
2230 
2231 static struct modmasktable
2232 {
2233     short	mod_mask;	/* Bit-mask for particular key modifier */
2234     short	mod_flag;	/* Bit(s) for particular key modifier */
2235     char_u	name;		/* Single letter name of modifier */
2236 } mod_mask_table[] =
2237 {
2238     {MOD_MASK_ALT,		MOD_MASK_ALT,		(char_u)'M'},
2239     {MOD_MASK_META,		MOD_MASK_META,		(char_u)'T'},
2240     {MOD_MASK_CTRL,		MOD_MASK_CTRL,		(char_u)'C'},
2241     {MOD_MASK_SHIFT,		MOD_MASK_SHIFT,		(char_u)'S'},
2242     {MOD_MASK_MULTI_CLICK,	MOD_MASK_2CLICK,	(char_u)'2'},
2243     {MOD_MASK_MULTI_CLICK,	MOD_MASK_3CLICK,	(char_u)'3'},
2244     {MOD_MASK_MULTI_CLICK,	MOD_MASK_4CLICK,	(char_u)'4'},
2245 #ifdef MACOS_X
2246     {MOD_MASK_CMD,		MOD_MASK_CMD,		(char_u)'D'},
2247 #endif
2248     /* 'A' must be the last one */
2249     {MOD_MASK_ALT,		MOD_MASK_ALT,		(char_u)'A'},
2250     {0, 0, NUL}
2251     /* NOTE: when adding an entry, update MAX_KEY_NAME_LEN! */
2252 };
2253 
2254 /*
2255  * Shifted key terminal codes and their unshifted equivalent.
2256  * Don't add mouse codes here, they are handled separately!
2257  */
2258 #define MOD_KEYS_ENTRY_SIZE 5
2259 
2260 static char_u modifier_keys_table[] =
2261 {
2262 /*  mod mask	    with modifier		without modifier */
2263     MOD_MASK_SHIFT, '&', '9',			'@', '1',	/* begin */
2264     MOD_MASK_SHIFT, '&', '0',			'@', '2',	/* cancel */
2265     MOD_MASK_SHIFT, '*', '1',			'@', '4',	/* command */
2266     MOD_MASK_SHIFT, '*', '2',			'@', '5',	/* copy */
2267     MOD_MASK_SHIFT, '*', '3',			'@', '6',	/* create */
2268     MOD_MASK_SHIFT, '*', '4',			'k', 'D',	/* delete char */
2269     MOD_MASK_SHIFT, '*', '5',			'k', 'L',	/* delete line */
2270     MOD_MASK_SHIFT, '*', '7',			'@', '7',	/* end */
2271     MOD_MASK_CTRL,  KS_EXTRA, (int)KE_C_END,	'@', '7',	/* end */
2272     MOD_MASK_SHIFT, '*', '9',			'@', '9',	/* exit */
2273     MOD_MASK_SHIFT, '*', '0',			'@', '0',	/* find */
2274     MOD_MASK_SHIFT, '#', '1',			'%', '1',	/* help */
2275     MOD_MASK_SHIFT, '#', '2',			'k', 'h',	/* home */
2276     MOD_MASK_CTRL,  KS_EXTRA, (int)KE_C_HOME,	'k', 'h',	/* home */
2277     MOD_MASK_SHIFT, '#', '3',			'k', 'I',	/* insert */
2278     MOD_MASK_SHIFT, '#', '4',			'k', 'l',	/* left arrow */
2279     MOD_MASK_CTRL,  KS_EXTRA, (int)KE_C_LEFT,	'k', 'l',	/* left arrow */
2280     MOD_MASK_SHIFT, '%', 'a',			'%', '3',	/* message */
2281     MOD_MASK_SHIFT, '%', 'b',			'%', '4',	/* move */
2282     MOD_MASK_SHIFT, '%', 'c',			'%', '5',	/* next */
2283     MOD_MASK_SHIFT, '%', 'd',			'%', '7',	/* options */
2284     MOD_MASK_SHIFT, '%', 'e',			'%', '8',	/* previous */
2285     MOD_MASK_SHIFT, '%', 'f',			'%', '9',	/* print */
2286     MOD_MASK_SHIFT, '%', 'g',			'%', '0',	/* redo */
2287     MOD_MASK_SHIFT, '%', 'h',			'&', '3',	/* replace */
2288     MOD_MASK_SHIFT, '%', 'i',			'k', 'r',	/* right arr. */
2289     MOD_MASK_CTRL,  KS_EXTRA, (int)KE_C_RIGHT,	'k', 'r',	/* right arr. */
2290     MOD_MASK_SHIFT, '%', 'j',			'&', '5',	/* resume */
2291     MOD_MASK_SHIFT, '!', '1',			'&', '6',	/* save */
2292     MOD_MASK_SHIFT, '!', '2',			'&', '7',	/* suspend */
2293     MOD_MASK_SHIFT, '!', '3',			'&', '8',	/* undo */
2294     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_UP,	'k', 'u',	/* up arrow */
2295     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_DOWN,	'k', 'd',	/* down arrow */
2296 
2297 								/* vt100 F1 */
2298     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_XF1,	KS_EXTRA, (int)KE_XF1,
2299     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_XF2,	KS_EXTRA, (int)KE_XF2,
2300     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_XF3,	KS_EXTRA, (int)KE_XF3,
2301     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_XF4,	KS_EXTRA, (int)KE_XF4,
2302 
2303     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F1,	'k', '1',	/* F1 */
2304     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F2,	'k', '2',
2305     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F3,	'k', '3',
2306     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F4,	'k', '4',
2307     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F5,	'k', '5',
2308     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F6,	'k', '6',
2309     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F7,	'k', '7',
2310     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F8,	'k', '8',
2311     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F9,	'k', '9',
2312     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F10,	'k', ';',	/* F10 */
2313 
2314     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F11,	'F', '1',
2315     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F12,	'F', '2',
2316     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F13,	'F', '3',
2317     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F14,	'F', '4',
2318     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F15,	'F', '5',
2319     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F16,	'F', '6',
2320     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F17,	'F', '7',
2321     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F18,	'F', '8',
2322     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F19,	'F', '9',
2323     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F20,	'F', 'A',
2324 
2325     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F21,	'F', 'B',
2326     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F22,	'F', 'C',
2327     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F23,	'F', 'D',
2328     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F24,	'F', 'E',
2329     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F25,	'F', 'F',
2330     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F26,	'F', 'G',
2331     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F27,	'F', 'H',
2332     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F28,	'F', 'I',
2333     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F29,	'F', 'J',
2334     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F30,	'F', 'K',
2335 
2336     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F31,	'F', 'L',
2337     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F32,	'F', 'M',
2338     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F33,	'F', 'N',
2339     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F34,	'F', 'O',
2340     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F35,	'F', 'P',
2341     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F36,	'F', 'Q',
2342     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F37,	'F', 'R',
2343 
2344 							    /* TAB pseudo code*/
2345     MOD_MASK_SHIFT, 'k', 'B',			KS_EXTRA, (int)KE_TAB,
2346 
2347     NUL
2348 };
2349 
2350 static struct key_name_entry
2351 {
2352     int	    key;	/* Special key code or ascii value */
2353     char_u  *name;	/* Name of key */
2354 } key_names_table[] =
2355 {
2356     {' ',		(char_u *)"Space"},
2357     {TAB,		(char_u *)"Tab"},
2358     {K_TAB,		(char_u *)"Tab"},
2359     {NL,		(char_u *)"NL"},
2360     {NL,		(char_u *)"NewLine"},	/* Alternative name */
2361     {NL,		(char_u *)"LineFeed"},	/* Alternative name */
2362     {NL,		(char_u *)"LF"},	/* Alternative name */
2363     {CAR,		(char_u *)"CR"},
2364     {CAR,		(char_u *)"Return"},	/* Alternative name */
2365     {CAR,		(char_u *)"Enter"},	/* Alternative name */
2366     {K_BS,		(char_u *)"BS"},
2367     {K_BS,		(char_u *)"BackSpace"},	/* Alternative name */
2368     {ESC,		(char_u *)"Esc"},
2369     {CSI,		(char_u *)"CSI"},
2370     {K_CSI,		(char_u *)"xCSI"},
2371     {'|',		(char_u *)"Bar"},
2372     {'\\',		(char_u *)"Bslash"},
2373     {K_DEL,		(char_u *)"Del"},
2374     {K_DEL,		(char_u *)"Delete"},	/* Alternative name */
2375     {K_KDEL,		(char_u *)"kDel"},
2376     {K_UP,		(char_u *)"Up"},
2377     {K_DOWN,		(char_u *)"Down"},
2378     {K_LEFT,		(char_u *)"Left"},
2379     {K_RIGHT,		(char_u *)"Right"},
2380     {K_XUP,		(char_u *)"xUp"},
2381     {K_XDOWN,		(char_u *)"xDown"},
2382     {K_XLEFT,		(char_u *)"xLeft"},
2383     {K_XRIGHT,		(char_u *)"xRight"},
2384     {K_PS,		(char_u *)"PasteStart"},
2385     {K_PE,		(char_u *)"PasteEnd"},
2386 
2387     {K_F1,		(char_u *)"F1"},
2388     {K_F2,		(char_u *)"F2"},
2389     {K_F3,		(char_u *)"F3"},
2390     {K_F4,		(char_u *)"F4"},
2391     {K_F5,		(char_u *)"F5"},
2392     {K_F6,		(char_u *)"F6"},
2393     {K_F7,		(char_u *)"F7"},
2394     {K_F8,		(char_u *)"F8"},
2395     {K_F9,		(char_u *)"F9"},
2396     {K_F10,		(char_u *)"F10"},
2397 
2398     {K_F11,		(char_u *)"F11"},
2399     {K_F12,		(char_u *)"F12"},
2400     {K_F13,		(char_u *)"F13"},
2401     {K_F14,		(char_u *)"F14"},
2402     {K_F15,		(char_u *)"F15"},
2403     {K_F16,		(char_u *)"F16"},
2404     {K_F17,		(char_u *)"F17"},
2405     {K_F18,		(char_u *)"F18"},
2406     {K_F19,		(char_u *)"F19"},
2407     {K_F20,		(char_u *)"F20"},
2408 
2409     {K_F21,		(char_u *)"F21"},
2410     {K_F22,		(char_u *)"F22"},
2411     {K_F23,		(char_u *)"F23"},
2412     {K_F24,		(char_u *)"F24"},
2413     {K_F25,		(char_u *)"F25"},
2414     {K_F26,		(char_u *)"F26"},
2415     {K_F27,		(char_u *)"F27"},
2416     {K_F28,		(char_u *)"F28"},
2417     {K_F29,		(char_u *)"F29"},
2418     {K_F30,		(char_u *)"F30"},
2419 
2420     {K_F31,		(char_u *)"F31"},
2421     {K_F32,		(char_u *)"F32"},
2422     {K_F33,		(char_u *)"F33"},
2423     {K_F34,		(char_u *)"F34"},
2424     {K_F35,		(char_u *)"F35"},
2425     {K_F36,		(char_u *)"F36"},
2426     {K_F37,		(char_u *)"F37"},
2427 
2428     {K_XF1,		(char_u *)"xF1"},
2429     {K_XF2,		(char_u *)"xF2"},
2430     {K_XF3,		(char_u *)"xF3"},
2431     {K_XF4,		(char_u *)"xF4"},
2432 
2433     {K_HELP,		(char_u *)"Help"},
2434     {K_UNDO,		(char_u *)"Undo"},
2435     {K_INS,		(char_u *)"Insert"},
2436     {K_INS,		(char_u *)"Ins"},	/* Alternative name */
2437     {K_KINS,		(char_u *)"kInsert"},
2438     {K_HOME,		(char_u *)"Home"},
2439     {K_KHOME,		(char_u *)"kHome"},
2440     {K_XHOME,		(char_u *)"xHome"},
2441     {K_ZHOME,		(char_u *)"zHome"},
2442     {K_END,		(char_u *)"End"},
2443     {K_KEND,		(char_u *)"kEnd"},
2444     {K_XEND,		(char_u *)"xEnd"},
2445     {K_ZEND,		(char_u *)"zEnd"},
2446     {K_PAGEUP,		(char_u *)"PageUp"},
2447     {K_PAGEDOWN,	(char_u *)"PageDown"},
2448     {K_KPAGEUP,		(char_u *)"kPageUp"},
2449     {K_KPAGEDOWN,	(char_u *)"kPageDown"},
2450 
2451     {K_KPLUS,		(char_u *)"kPlus"},
2452     {K_KMINUS,		(char_u *)"kMinus"},
2453     {K_KDIVIDE,		(char_u *)"kDivide"},
2454     {K_KMULTIPLY,	(char_u *)"kMultiply"},
2455     {K_KENTER,		(char_u *)"kEnter"},
2456     {K_KPOINT,		(char_u *)"kPoint"},
2457 
2458     {K_K0,		(char_u *)"k0"},
2459     {K_K1,		(char_u *)"k1"},
2460     {K_K2,		(char_u *)"k2"},
2461     {K_K3,		(char_u *)"k3"},
2462     {K_K4,		(char_u *)"k4"},
2463     {K_K5,		(char_u *)"k5"},
2464     {K_K6,		(char_u *)"k6"},
2465     {K_K7,		(char_u *)"k7"},
2466     {K_K8,		(char_u *)"k8"},
2467     {K_K9,		(char_u *)"k9"},
2468 
2469     {'<',		(char_u *)"lt"},
2470 
2471     {K_MOUSE,		(char_u *)"Mouse"},
2472 #ifdef FEAT_MOUSE_NET
2473     {K_NETTERM_MOUSE,	(char_u *)"NetMouse"},
2474 #endif
2475 #ifdef FEAT_MOUSE_DEC
2476     {K_DEC_MOUSE,	(char_u *)"DecMouse"},
2477 #endif
2478 #ifdef FEAT_MOUSE_JSB
2479     {K_JSBTERM_MOUSE,	(char_u *)"JsbMouse"},
2480 #endif
2481 #ifdef FEAT_MOUSE_PTERM
2482     {K_PTERM_MOUSE,	(char_u *)"PtermMouse"},
2483 #endif
2484 #ifdef FEAT_MOUSE_URXVT
2485     {K_URXVT_MOUSE,	(char_u *)"UrxvtMouse"},
2486 #endif
2487 #ifdef FEAT_MOUSE_SGR
2488     {K_SGR_MOUSE,	(char_u *)"SgrMouse"},
2489     {K_SGR_MOUSERELEASE, (char_u *)"SgrMouseRelelase"},
2490 #endif
2491     {K_LEFTMOUSE,	(char_u *)"LeftMouse"},
2492     {K_LEFTMOUSE_NM,	(char_u *)"LeftMouseNM"},
2493     {K_LEFTDRAG,	(char_u *)"LeftDrag"},
2494     {K_LEFTRELEASE,	(char_u *)"LeftRelease"},
2495     {K_LEFTRELEASE_NM,	(char_u *)"LeftReleaseNM"},
2496     {K_MOUSEMOVE,	(char_u *)"MouseMove"},
2497     {K_MIDDLEMOUSE,	(char_u *)"MiddleMouse"},
2498     {K_MIDDLEDRAG,	(char_u *)"MiddleDrag"},
2499     {K_MIDDLERELEASE,	(char_u *)"MiddleRelease"},
2500     {K_RIGHTMOUSE,	(char_u *)"RightMouse"},
2501     {K_RIGHTDRAG,	(char_u *)"RightDrag"},
2502     {K_RIGHTRELEASE,	(char_u *)"RightRelease"},
2503     {K_MOUSEDOWN,	(char_u *)"ScrollWheelUp"},
2504     {K_MOUSEUP,		(char_u *)"ScrollWheelDown"},
2505     {K_MOUSELEFT,	(char_u *)"ScrollWheelRight"},
2506     {K_MOUSERIGHT,	(char_u *)"ScrollWheelLeft"},
2507     {K_MOUSEDOWN,	(char_u *)"MouseDown"}, /* OBSOLETE: Use	  */
2508     {K_MOUSEUP,		(char_u *)"MouseUp"},	/* ScrollWheelXXX instead */
2509     {K_X1MOUSE,		(char_u *)"X1Mouse"},
2510     {K_X1DRAG,		(char_u *)"X1Drag"},
2511     {K_X1RELEASE,		(char_u *)"X1Release"},
2512     {K_X2MOUSE,		(char_u *)"X2Mouse"},
2513     {K_X2DRAG,		(char_u *)"X2Drag"},
2514     {K_X2RELEASE,		(char_u *)"X2Release"},
2515     {K_DROP,		(char_u *)"Drop"},
2516     {K_ZERO,		(char_u *)"Nul"},
2517 #ifdef FEAT_EVAL
2518     {K_SNR,		(char_u *)"SNR"},
2519 #endif
2520     {K_PLUG,		(char_u *)"Plug"},
2521     {K_CURSORHOLD,	(char_u *)"CursorHold"},
2522     {0,			NULL}
2523     /* NOTE: When adding a long name update MAX_KEY_NAME_LEN. */
2524 };
2525 
2526 #define KEY_NAMES_TABLE_LEN (sizeof(key_names_table) / sizeof(struct key_name_entry))
2527 
2528 #ifdef FEAT_MOUSE
2529 static struct mousetable
2530 {
2531     int	    pseudo_code;	/* Code for pseudo mouse event */
2532     int	    button;		/* Which mouse button is it? */
2533     int	    is_click;		/* Is it a mouse button click event? */
2534     int	    is_drag;		/* Is it a mouse drag event? */
2535 } mouse_table[] =
2536 {
2537     {(int)KE_LEFTMOUSE,		MOUSE_LEFT,	TRUE,	FALSE},
2538 #ifdef FEAT_GUI
2539     {(int)KE_LEFTMOUSE_NM,	MOUSE_LEFT,	TRUE,	FALSE},
2540 #endif
2541     {(int)KE_LEFTDRAG,		MOUSE_LEFT,	FALSE,	TRUE},
2542     {(int)KE_LEFTRELEASE,	MOUSE_LEFT,	FALSE,	FALSE},
2543 #ifdef FEAT_GUI
2544     {(int)KE_LEFTRELEASE_NM,	MOUSE_LEFT,	FALSE,	FALSE},
2545 #endif
2546     {(int)KE_MIDDLEMOUSE,	MOUSE_MIDDLE,	TRUE,	FALSE},
2547     {(int)KE_MIDDLEDRAG,	MOUSE_MIDDLE,	FALSE,	TRUE},
2548     {(int)KE_MIDDLERELEASE,	MOUSE_MIDDLE,	FALSE,	FALSE},
2549     {(int)KE_RIGHTMOUSE,	MOUSE_RIGHT,	TRUE,	FALSE},
2550     {(int)KE_RIGHTDRAG,		MOUSE_RIGHT,	FALSE,	TRUE},
2551     {(int)KE_RIGHTRELEASE,	MOUSE_RIGHT,	FALSE,	FALSE},
2552     {(int)KE_X1MOUSE,		MOUSE_X1,	TRUE,	FALSE},
2553     {(int)KE_X1DRAG,		MOUSE_X1,	FALSE,	TRUE},
2554     {(int)KE_X1RELEASE,		MOUSE_X1,	FALSE,	FALSE},
2555     {(int)KE_X2MOUSE,		MOUSE_X2,	TRUE,	FALSE},
2556     {(int)KE_X2DRAG,		MOUSE_X2,	FALSE,	TRUE},
2557     {(int)KE_X2RELEASE,		MOUSE_X2,	FALSE,	FALSE},
2558     /* DRAG without CLICK */
2559     {(int)KE_MOUSEMOVE,		MOUSE_RELEASE,	FALSE,	TRUE},
2560     /* RELEASE without CLICK */
2561     {(int)KE_IGNORE,		MOUSE_RELEASE,	FALSE,	FALSE},
2562     {0,				0,		0,	0},
2563 };
2564 #endif /* FEAT_MOUSE */
2565 
2566 /*
2567  * Return the modifier mask bit (MOD_MASK_*) which corresponds to the given
2568  * modifier name ('S' for Shift, 'C' for Ctrl etc).
2569  */
2570     int
2571 name_to_mod_mask(int c)
2572 {
2573     int	    i;
2574 
2575     c = TOUPPER_ASC(c);
2576     for (i = 0; mod_mask_table[i].mod_mask != 0; i++)
2577 	if (c == mod_mask_table[i].name)
2578 	    return mod_mask_table[i].mod_flag;
2579     return 0;
2580 }
2581 
2582 /*
2583  * Check if if there is a special key code for "key" that includes the
2584  * modifiers specified.
2585  */
2586     int
2587 simplify_key(int key, int *modifiers)
2588 {
2589     int	    i;
2590     int	    key0;
2591     int	    key1;
2592 
2593     if (*modifiers & (MOD_MASK_SHIFT | MOD_MASK_CTRL | MOD_MASK_ALT))
2594     {
2595 	/* TAB is a special case */
2596 	if (key == TAB && (*modifiers & MOD_MASK_SHIFT))
2597 	{
2598 	    *modifiers &= ~MOD_MASK_SHIFT;
2599 	    return K_S_TAB;
2600 	}
2601 	key0 = KEY2TERMCAP0(key);
2602 	key1 = KEY2TERMCAP1(key);
2603 	for (i = 0; modifier_keys_table[i] != NUL; i += MOD_KEYS_ENTRY_SIZE)
2604 	    if (key0 == modifier_keys_table[i + 3]
2605 		    && key1 == modifier_keys_table[i + 4]
2606 		    && (*modifiers & modifier_keys_table[i]))
2607 	    {
2608 		*modifiers &= ~modifier_keys_table[i];
2609 		return TERMCAP2KEY(modifier_keys_table[i + 1],
2610 						   modifier_keys_table[i + 2]);
2611 	    }
2612     }
2613     return key;
2614 }
2615 
2616 /*
2617  * Change <xHome> to <Home>, <xUp> to <Up>, etc.
2618  */
2619     int
2620 handle_x_keys(int key)
2621 {
2622     switch (key)
2623     {
2624 	case K_XUP:	return K_UP;
2625 	case K_XDOWN:	return K_DOWN;
2626 	case K_XLEFT:	return K_LEFT;
2627 	case K_XRIGHT:	return K_RIGHT;
2628 	case K_XHOME:	return K_HOME;
2629 	case K_ZHOME:	return K_HOME;
2630 	case K_XEND:	return K_END;
2631 	case K_ZEND:	return K_END;
2632 	case K_XF1:	return K_F1;
2633 	case K_XF2:	return K_F2;
2634 	case K_XF3:	return K_F3;
2635 	case K_XF4:	return K_F4;
2636 	case K_S_XF1:	return K_S_F1;
2637 	case K_S_XF2:	return K_S_F2;
2638 	case K_S_XF3:	return K_S_F3;
2639 	case K_S_XF4:	return K_S_F4;
2640     }
2641     return key;
2642 }
2643 
2644 /*
2645  * Return a string which contains the name of the given key when the given
2646  * modifiers are down.
2647  */
2648     char_u *
2649 get_special_key_name(int c, int modifiers)
2650 {
2651     static char_u string[MAX_KEY_NAME_LEN + 1];
2652 
2653     int	    i, idx;
2654     int	    table_idx;
2655     char_u  *s;
2656 
2657     string[0] = '<';
2658     idx = 1;
2659 
2660     /* Key that stands for a normal character. */
2661     if (IS_SPECIAL(c) && KEY2TERMCAP0(c) == KS_KEY)
2662 	c = KEY2TERMCAP1(c);
2663 
2664     /*
2665      * Translate shifted special keys into unshifted keys and set modifier.
2666      * Same for CTRL and ALT modifiers.
2667      */
2668     if (IS_SPECIAL(c))
2669     {
2670 	for (i = 0; modifier_keys_table[i] != 0; i += MOD_KEYS_ENTRY_SIZE)
2671 	    if (       KEY2TERMCAP0(c) == (int)modifier_keys_table[i + 1]
2672 		    && (int)KEY2TERMCAP1(c) == (int)modifier_keys_table[i + 2])
2673 	    {
2674 		modifiers |= modifier_keys_table[i];
2675 		c = TERMCAP2KEY(modifier_keys_table[i + 3],
2676 						   modifier_keys_table[i + 4]);
2677 		break;
2678 	    }
2679     }
2680 
2681     /* try to find the key in the special key table */
2682     table_idx = find_special_key_in_table(c);
2683 
2684     /*
2685      * When not a known special key, and not a printable character, try to
2686      * extract modifiers.
2687      */
2688     if (c > 0
2689 #ifdef FEAT_MBYTE
2690 	    && (*mb_char2len)(c) == 1
2691 #endif
2692        )
2693     {
2694 	if (table_idx < 0
2695 		&& (!vim_isprintc(c) || (c & 0x7f) == ' ')
2696 		&& (c & 0x80))
2697 	{
2698 	    c &= 0x7f;
2699 	    modifiers |= MOD_MASK_ALT;
2700 	    /* try again, to find the un-alted key in the special key table */
2701 	    table_idx = find_special_key_in_table(c);
2702 	}
2703 	if (table_idx < 0 && !vim_isprintc(c) && c < ' ')
2704 	{
2705 #ifdef EBCDIC
2706 	    c = CtrlChar(c);
2707 #else
2708 	    c += '@';
2709 #endif
2710 	    modifiers |= MOD_MASK_CTRL;
2711 	}
2712     }
2713 
2714     /* translate the modifier into a string */
2715     for (i = 0; mod_mask_table[i].name != 'A'; i++)
2716 	if ((modifiers & mod_mask_table[i].mod_mask)
2717 						== mod_mask_table[i].mod_flag)
2718 	{
2719 	    string[idx++] = mod_mask_table[i].name;
2720 	    string[idx++] = (char_u)'-';
2721 	}
2722 
2723     if (table_idx < 0)		/* unknown special key, may output t_xx */
2724     {
2725 	if (IS_SPECIAL(c))
2726 	{
2727 	    string[idx++] = 't';
2728 	    string[idx++] = '_';
2729 	    string[idx++] = KEY2TERMCAP0(c);
2730 	    string[idx++] = KEY2TERMCAP1(c);
2731 	}
2732 	/* Not a special key, only modifiers, output directly */
2733 	else
2734 	{
2735 #ifdef FEAT_MBYTE
2736 	    if (has_mbyte && (*mb_char2len)(c) > 1)
2737 		idx += (*mb_char2bytes)(c, string + idx);
2738 	    else
2739 #endif
2740 	    if (vim_isprintc(c))
2741 		string[idx++] = c;
2742 	    else
2743 	    {
2744 		s = transchar(c);
2745 		while (*s)
2746 		    string[idx++] = *s++;
2747 	    }
2748 	}
2749     }
2750     else		/* use name of special key */
2751     {
2752 	size_t len = STRLEN(key_names_table[table_idx].name);
2753 
2754 	if (len + idx + 2 <= MAX_KEY_NAME_LEN)
2755 	{
2756 	    STRCPY(string + idx, key_names_table[table_idx].name);
2757 	    idx += (int)len;
2758 	}
2759     }
2760     string[idx++] = '>';
2761     string[idx] = NUL;
2762     return string;
2763 }
2764 
2765 /*
2766  * Try translating a <> name at (*srcp)[] to dst[].
2767  * Return the number of characters added to dst[], zero for no match.
2768  * If there is a match, srcp is advanced to after the <> name.
2769  * dst[] must be big enough to hold the result (up to six characters)!
2770  */
2771     int
2772 trans_special(
2773     char_u	**srcp,
2774     char_u	*dst,
2775     int		keycode, /* prefer key code, e.g. K_DEL instead of DEL */
2776     int		in_string) /* TRUE when inside a double quoted string */
2777 {
2778     int		modifiers = 0;
2779     int		key;
2780     int		dlen = 0;
2781 
2782     key = find_special_key(srcp, &modifiers, keycode, FALSE, in_string);
2783     if (key == 0)
2784 	return 0;
2785 
2786     /* Put the appropriate modifier in a string */
2787     if (modifiers != 0)
2788     {
2789 	dst[dlen++] = K_SPECIAL;
2790 	dst[dlen++] = KS_MODIFIER;
2791 	dst[dlen++] = modifiers;
2792     }
2793 
2794     if (IS_SPECIAL(key))
2795     {
2796 	dst[dlen++] = K_SPECIAL;
2797 	dst[dlen++] = KEY2TERMCAP0(key);
2798 	dst[dlen++] = KEY2TERMCAP1(key);
2799     }
2800 #ifdef FEAT_MBYTE
2801     else if (has_mbyte && !keycode)
2802 	dlen += (*mb_char2bytes)(key, dst + dlen);
2803 #endif
2804     else if (keycode)
2805 	dlen = (int)(add_char2buf(key, dst + dlen) - dst);
2806     else
2807 	dst[dlen++] = key;
2808 
2809     return dlen;
2810 }
2811 
2812 /*
2813  * Try translating a <> name at (*srcp)[], return the key and modifiers.
2814  * srcp is advanced to after the <> name.
2815  * returns 0 if there is no match.
2816  */
2817     int
2818 find_special_key(
2819     char_u	**srcp,
2820     int		*modp,
2821     int		keycode,     /* prefer key code, e.g. K_DEL instead of DEL */
2822     int		keep_x_key,  /* don't translate xHome to Home key */
2823     int		in_string)   /* TRUE in string, double quote is escaped */
2824 {
2825     char_u	*last_dash;
2826     char_u	*end_of_name;
2827     char_u	*src;
2828     char_u	*bp;
2829     int		modifiers;
2830     int		bit;
2831     int		key;
2832     uvarnumber_T	n;
2833     int		l;
2834 
2835     src = *srcp;
2836     if (src[0] != '<')
2837 	return 0;
2838 
2839     /* Find end of modifier list */
2840     last_dash = src;
2841     for (bp = src + 1; *bp == '-' || vim_isIDc(*bp); bp++)
2842     {
2843 	if (*bp == '-')
2844 	{
2845 	    last_dash = bp;
2846 	    if (bp[1] != NUL)
2847 	    {
2848 #ifdef FEAT_MBYTE
2849 		if (has_mbyte)
2850 		    l = mb_ptr2len(bp + 1);
2851 		else
2852 #endif
2853 		    l = 1;
2854 		/* Anything accepted, like <C-?>.
2855 		 * <C-"> or <M-"> are not special in strings as " is
2856 		 * the string delimiter. With a backslash it works: <M-\"> */
2857 		if (!(in_string && bp[1] == '"') && bp[2] == '>')
2858 		    bp += l;
2859 		else if (in_string && bp[1] == '\\' && bp[2] == '"'
2860 							       && bp[3] == '>')
2861 		    bp += 2;
2862 	    }
2863 	}
2864 	if (bp[0] == 't' && bp[1] == '_' && bp[2] && bp[3])
2865 	    bp += 3;	/* skip t_xx, xx may be '-' or '>' */
2866 	else if (STRNICMP(bp, "char-", 5) == 0)
2867 	{
2868 	    vim_str2nr(bp + 5, NULL, &l, STR2NR_ALL, NULL, NULL, 0);
2869 	    bp += l + 5;
2870 	    break;
2871 	}
2872     }
2873 
2874     if (*bp == '>')	/* found matching '>' */
2875     {
2876 	end_of_name = bp + 1;
2877 
2878 	/* Which modifiers are given? */
2879 	modifiers = 0x0;
2880 	for (bp = src + 1; bp < last_dash; bp++)
2881 	{
2882 	    if (*bp != '-')
2883 	    {
2884 		bit = name_to_mod_mask(*bp);
2885 		if (bit == 0x0)
2886 		    break;	/* Illegal modifier name */
2887 		modifiers |= bit;
2888 	    }
2889 	}
2890 
2891 	/*
2892 	 * Legal modifier name.
2893 	 */
2894 	if (bp >= last_dash)
2895 	{
2896 	    if (STRNICMP(last_dash + 1, "char-", 5) == 0
2897 						 && VIM_ISDIGIT(last_dash[6]))
2898 	    {
2899 		/* <Char-123> or <Char-033> or <Char-0x33> */
2900 		vim_str2nr(last_dash + 6, NULL, NULL, STR2NR_ALL, NULL, &n, 0);
2901 		key = (int)n;
2902 	    }
2903 	    else
2904 	    {
2905 		int off = 1;
2906 
2907 		/* Modifier with single letter, or special key name.  */
2908 		if (in_string && last_dash[1] == '\\' && last_dash[2] == '"')
2909 		    off = 2;
2910 #ifdef FEAT_MBYTE
2911 		if (has_mbyte)
2912 		    l = mb_ptr2len(last_dash + off);
2913 		else
2914 #endif
2915 		    l = 1;
2916 		if (modifiers != 0 && last_dash[l + off] == '>')
2917 		    key = PTR2CHAR(last_dash + off);
2918 		else
2919 		{
2920 		    key = get_special_key_code(last_dash + off);
2921 		    if (!keep_x_key)
2922 			key = handle_x_keys(key);
2923 		}
2924 	    }
2925 
2926 	    /*
2927 	     * get_special_key_code() may return NUL for invalid
2928 	     * special key name.
2929 	     */
2930 	    if (key != NUL)
2931 	    {
2932 		/*
2933 		 * Only use a modifier when there is no special key code that
2934 		 * includes the modifier.
2935 		 */
2936 		key = simplify_key(key, &modifiers);
2937 
2938 		if (!keycode)
2939 		{
2940 		    /* don't want keycode, use single byte code */
2941 		    if (key == K_BS)
2942 			key = BS;
2943 		    else if (key == K_DEL || key == K_KDEL)
2944 			key = DEL;
2945 		}
2946 
2947 		/*
2948 		 * Normal Key with modifier: Try to make a single byte code.
2949 		 */
2950 		if (!IS_SPECIAL(key))
2951 		    key = extract_modifiers(key, &modifiers);
2952 
2953 		*modp = modifiers;
2954 		*srcp = end_of_name;
2955 		return key;
2956 	    }
2957 	}
2958     }
2959     return 0;
2960 }
2961 
2962 /*
2963  * Try to include modifiers in the key.
2964  * Changes "Shift-a" to 'A', "Alt-A" to 0xc0, etc.
2965  */
2966     int
2967 extract_modifiers(int key, int *modp)
2968 {
2969     int	modifiers = *modp;
2970 
2971 #ifdef MACOS_X
2972     /* Command-key really special, no fancynest */
2973     if (!(modifiers & MOD_MASK_CMD))
2974 #endif
2975     if ((modifiers & MOD_MASK_SHIFT) && ASCII_ISALPHA(key))
2976     {
2977 	key = TOUPPER_ASC(key);
2978 	modifiers &= ~MOD_MASK_SHIFT;
2979     }
2980     if ((modifiers & MOD_MASK_CTRL)
2981 #ifdef EBCDIC
2982 	    /* * TODO: EBCDIC Better use:
2983 	     * && (Ctrl_chr(key) || key == '?')
2984 	     * ???  */
2985 	    && strchr("?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_", key)
2986 						       != NULL
2987 #else
2988 	    && ((key >= '?' && key <= '_') || ASCII_ISALPHA(key))
2989 #endif
2990 	    )
2991     {
2992 	key = Ctrl_chr(key);
2993 	modifiers &= ~MOD_MASK_CTRL;
2994 	/* <C-@> is <Nul> */
2995 	if (key == 0)
2996 	    key = K_ZERO;
2997     }
2998 #ifdef MACOS_X
2999     /* Command-key really special, no fancynest */
3000     if (!(modifiers & MOD_MASK_CMD))
3001 #endif
3002     if ((modifiers & MOD_MASK_ALT) && key < 0x80
3003 #ifdef FEAT_MBYTE
3004 	    && !enc_dbcs		/* avoid creating a lead byte */
3005 #endif
3006 	    )
3007     {
3008 	key |= 0x80;
3009 	modifiers &= ~MOD_MASK_ALT;	/* remove the META modifier */
3010     }
3011 
3012     *modp = modifiers;
3013     return key;
3014 }
3015 
3016 /*
3017  * Try to find key "c" in the special key table.
3018  * Return the index when found, -1 when not found.
3019  */
3020     int
3021 find_special_key_in_table(int c)
3022 {
3023     int	    i;
3024 
3025     for (i = 0; key_names_table[i].name != NULL; i++)
3026 	if (c == key_names_table[i].key)
3027 	    break;
3028     if (key_names_table[i].name == NULL)
3029 	i = -1;
3030     return i;
3031 }
3032 
3033 /*
3034  * Find the special key with the given name (the given string does not have to
3035  * end with NUL, the name is assumed to end before the first non-idchar).
3036  * If the name starts with "t_" the next two characters are interpreted as a
3037  * termcap name.
3038  * Return the key code, or 0 if not found.
3039  */
3040     int
3041 get_special_key_code(char_u *name)
3042 {
3043     char_u  *table_name;
3044     char_u  string[3];
3045     int	    i, j;
3046 
3047     /*
3048      * If it's <t_xx> we get the code for xx from the termcap
3049      */
3050     if (name[0] == 't' && name[1] == '_' && name[2] != NUL && name[3] != NUL)
3051     {
3052 	string[0] = name[2];
3053 	string[1] = name[3];
3054 	string[2] = NUL;
3055 	if (add_termcap_entry(string, FALSE) == OK)
3056 	    return TERMCAP2KEY(name[2], name[3]);
3057     }
3058     else
3059 	for (i = 0; key_names_table[i].name != NULL; i++)
3060 	{
3061 	    table_name = key_names_table[i].name;
3062 	    for (j = 0; vim_isIDc(name[j]) && table_name[j] != NUL; j++)
3063 		if (TOLOWER_ASC(table_name[j]) != TOLOWER_ASC(name[j]))
3064 		    break;
3065 	    if (!vim_isIDc(name[j]) && table_name[j] == NUL)
3066 		return key_names_table[i].key;
3067 	}
3068     return 0;
3069 }
3070 
3071 #if defined(FEAT_CMDL_COMPL) || defined(PROTO)
3072     char_u *
3073 get_key_name(int i)
3074 {
3075     if (i >= (int)KEY_NAMES_TABLE_LEN)
3076 	return NULL;
3077     return  key_names_table[i].name;
3078 }
3079 #endif
3080 
3081 #if defined(FEAT_MOUSE) || defined(PROTO)
3082 /*
3083  * Look up the given mouse code to return the relevant information in the other
3084  * arguments.  Return which button is down or was released.
3085  */
3086     int
3087 get_mouse_button(int code, int *is_click, int *is_drag)
3088 {
3089     int	    i;
3090 
3091     for (i = 0; mouse_table[i].pseudo_code; i++)
3092 	if (code == mouse_table[i].pseudo_code)
3093 	{
3094 	    *is_click = mouse_table[i].is_click;
3095 	    *is_drag = mouse_table[i].is_drag;
3096 	    return mouse_table[i].button;
3097 	}
3098     return 0;	    /* Shouldn't get here */
3099 }
3100 
3101 /*
3102  * Return the appropriate pseudo mouse event token (KE_LEFTMOUSE etc) based on
3103  * the given information about which mouse button is down, and whether the
3104  * mouse was clicked, dragged or released.
3105  */
3106     int
3107 get_pseudo_mouse_code(
3108     int	    button,	/* eg MOUSE_LEFT */
3109     int	    is_click,
3110     int	    is_drag)
3111 {
3112     int	    i;
3113 
3114     for (i = 0; mouse_table[i].pseudo_code; i++)
3115 	if (button == mouse_table[i].button
3116 	    && is_click == mouse_table[i].is_click
3117 	    && is_drag == mouse_table[i].is_drag)
3118 	{
3119 #ifdef FEAT_GUI
3120 	    /* Trick: a non mappable left click and release has mouse_col -1
3121 	     * or added MOUSE_COLOFF.  Used for 'mousefocus' in
3122 	     * gui_mouse_moved() */
3123 	    if (mouse_col < 0 || mouse_col > MOUSE_COLOFF)
3124 	    {
3125 		if (mouse_col < 0)
3126 		    mouse_col = 0;
3127 		else
3128 		    mouse_col -= MOUSE_COLOFF;
3129 		if (mouse_table[i].pseudo_code == (int)KE_LEFTMOUSE)
3130 		    return (int)KE_LEFTMOUSE_NM;
3131 		if (mouse_table[i].pseudo_code == (int)KE_LEFTRELEASE)
3132 		    return (int)KE_LEFTRELEASE_NM;
3133 	    }
3134 #endif
3135 	    return mouse_table[i].pseudo_code;
3136 	}
3137     return (int)KE_IGNORE;	    /* not recognized, ignore it */
3138 }
3139 #endif /* FEAT_MOUSE */
3140 
3141 /*
3142  * Return the current end-of-line type: EOL_DOS, EOL_UNIX or EOL_MAC.
3143  */
3144     int
3145 get_fileformat(buf_T *buf)
3146 {
3147     int		c = *buf->b_p_ff;
3148 
3149     if (buf->b_p_bin || c == 'u')
3150 	return EOL_UNIX;
3151     if (c == 'm')
3152 	return EOL_MAC;
3153     return EOL_DOS;
3154 }
3155 
3156 /*
3157  * Like get_fileformat(), but override 'fileformat' with "p" for "++opt=val"
3158  * argument.
3159  */
3160     int
3161 get_fileformat_force(
3162     buf_T	*buf,
3163     exarg_T	*eap)	    /* can be NULL! */
3164 {
3165     int		c;
3166 
3167     if (eap != NULL && eap->force_ff != 0)
3168 	c = eap->cmd[eap->force_ff];
3169     else
3170     {
3171 	if ((eap != NULL && eap->force_bin != 0)
3172 			       ? (eap->force_bin == FORCE_BIN) : buf->b_p_bin)
3173 	    return EOL_UNIX;
3174 	c = *buf->b_p_ff;
3175     }
3176     if (c == 'u')
3177 	return EOL_UNIX;
3178     if (c == 'm')
3179 	return EOL_MAC;
3180     return EOL_DOS;
3181 }
3182 
3183 /*
3184  * Set the current end-of-line type to EOL_DOS, EOL_UNIX or EOL_MAC.
3185  * Sets both 'textmode' and 'fileformat'.
3186  * Note: Does _not_ set global value of 'textmode'!
3187  */
3188     void
3189 set_fileformat(
3190     int		t,
3191     int		opt_flags)	/* OPT_LOCAL and/or OPT_GLOBAL */
3192 {
3193     char	*p = NULL;
3194 
3195     switch (t)
3196     {
3197     case EOL_DOS:
3198 	p = FF_DOS;
3199 	curbuf->b_p_tx = TRUE;
3200 	break;
3201     case EOL_UNIX:
3202 	p = FF_UNIX;
3203 	curbuf->b_p_tx = FALSE;
3204 	break;
3205     case EOL_MAC:
3206 	p = FF_MAC;
3207 	curbuf->b_p_tx = FALSE;
3208 	break;
3209     }
3210     if (p != NULL)
3211 	set_string_option_direct((char_u *)"ff", -1, (char_u *)p,
3212 						     OPT_FREE | opt_flags, 0);
3213 
3214     /* This may cause the buffer to become (un)modified. */
3215     check_status(curbuf);
3216     redraw_tabline = TRUE;
3217 #ifdef FEAT_TITLE
3218     need_maketitle = TRUE;	    /* set window title later */
3219 #endif
3220 }
3221 
3222 /*
3223  * Return the default fileformat from 'fileformats'.
3224  */
3225     int
3226 default_fileformat(void)
3227 {
3228     switch (*p_ffs)
3229     {
3230 	case 'm':   return EOL_MAC;
3231 	case 'd':   return EOL_DOS;
3232     }
3233     return EOL_UNIX;
3234 }
3235 
3236 /*
3237  * Call shell.	Calls mch_call_shell, with 'shellxquote' added.
3238  */
3239     int
3240 call_shell(char_u *cmd, int opt)
3241 {
3242     char_u	*ncmd;
3243     int		retval;
3244 #ifdef FEAT_PROFILE
3245     proftime_T	wait_time;
3246 #endif
3247 
3248     if (p_verbose > 3)
3249     {
3250 	verbose_enter();
3251 	smsg((char_u *)_("Calling shell to execute: \"%s\""),
3252 						    cmd == NULL ? p_sh : cmd);
3253 	out_char('\n');
3254 	cursor_on();
3255 	verbose_leave();
3256     }
3257 
3258 #ifdef FEAT_PROFILE
3259     if (do_profiling == PROF_YES)
3260 	prof_child_enter(&wait_time);
3261 #endif
3262 
3263     if (*p_sh == NUL)
3264     {
3265 	EMSG(_(e_shellempty));
3266 	retval = -1;
3267     }
3268     else
3269     {
3270 #ifdef FEAT_GUI_MSWIN
3271 	/* Don't hide the pointer while executing a shell command. */
3272 	gui_mch_mousehide(FALSE);
3273 #endif
3274 #ifdef FEAT_GUI
3275 	++hold_gui_events;
3276 #endif
3277 	/* The external command may update a tags file, clear cached tags. */
3278 	tag_freematch();
3279 
3280 	if (cmd == NULL || *p_sxq == NUL)
3281 	    retval = mch_call_shell(cmd, opt);
3282 	else
3283 	{
3284 	    char_u *ecmd = cmd;
3285 
3286 	    if (*p_sxe != NUL && STRCMP(p_sxq, "(") == 0)
3287 	    {
3288 		ecmd = vim_strsave_escaped_ext(cmd, p_sxe, '^', FALSE);
3289 		if (ecmd == NULL)
3290 		    ecmd = cmd;
3291 	    }
3292 	    ncmd = alloc((unsigned)(STRLEN(ecmd) + STRLEN(p_sxq) * 2 + 1));
3293 	    if (ncmd != NULL)
3294 	    {
3295 		STRCPY(ncmd, p_sxq);
3296 		STRCAT(ncmd, ecmd);
3297 		/* When 'shellxquote' is ( append ).
3298 		 * When 'shellxquote' is "( append )". */
3299 		STRCAT(ncmd, STRCMP(p_sxq, "(") == 0 ? (char_u *)")"
3300 			   : STRCMP(p_sxq, "\"(") == 0 ? (char_u *)")\""
3301 			   : p_sxq);
3302 		retval = mch_call_shell(ncmd, opt);
3303 		vim_free(ncmd);
3304 	    }
3305 	    else
3306 		retval = -1;
3307 	    if (ecmd != cmd)
3308 		vim_free(ecmd);
3309 	}
3310 #ifdef FEAT_GUI
3311 	--hold_gui_events;
3312 #endif
3313 	/*
3314 	 * Check the window size, in case it changed while executing the
3315 	 * external command.
3316 	 */
3317 	shell_resized_check();
3318     }
3319 
3320 #ifdef FEAT_EVAL
3321     set_vim_var_nr(VV_SHELL_ERROR, (long)retval);
3322 # ifdef FEAT_PROFILE
3323     if (do_profiling == PROF_YES)
3324 	prof_child_exit(&wait_time);
3325 # endif
3326 #endif
3327 
3328     return retval;
3329 }
3330 
3331 /*
3332  * VISUAL, SELECTMODE and OP_PENDING State are never set, they are equal to
3333  * NORMAL State with a condition.  This function returns the real State.
3334  */
3335     int
3336 get_real_state(void)
3337 {
3338     if (State & NORMAL)
3339     {
3340 	if (VIsual_active)
3341 	{
3342 	    if (VIsual_select)
3343 		return SELECTMODE;
3344 	    return VISUAL;
3345 	}
3346 	else if (finish_op)
3347 	    return OP_PENDING;
3348     }
3349     return State;
3350 }
3351 
3352 #if defined(FEAT_MBYTE) || defined(PROTO)
3353 /*
3354  * Return TRUE if "p" points to just after a path separator.
3355  * Takes care of multi-byte characters.
3356  * "b" must point to the start of the file name
3357  */
3358     int
3359 after_pathsep(char_u *b, char_u *p)
3360 {
3361     return p > b && vim_ispathsep(p[-1])
3362 			     && (!has_mbyte || (*mb_head_off)(b, p - 1) == 0);
3363 }
3364 #endif
3365 
3366 /*
3367  * Return TRUE if file names "f1" and "f2" are in the same directory.
3368  * "f1" may be a short name, "f2" must be a full path.
3369  */
3370     int
3371 same_directory(char_u *f1, char_u *f2)
3372 {
3373     char_u	ffname[MAXPATHL];
3374     char_u	*t1;
3375     char_u	*t2;
3376 
3377     /* safety check */
3378     if (f1 == NULL || f2 == NULL)
3379 	return FALSE;
3380 
3381     (void)vim_FullName(f1, ffname, MAXPATHL, FALSE);
3382     t1 = gettail_sep(ffname);
3383     t2 = gettail_sep(f2);
3384     return (t1 - ffname == t2 - f2
3385 	     && pathcmp((char *)ffname, (char *)f2, (int)(t1 - ffname)) == 0);
3386 }
3387 
3388 #if defined(FEAT_SESSION) || defined(MSWIN) || defined(FEAT_GUI_MAC) \
3389 	|| defined(FEAT_GUI_GTK) \
3390 	|| defined(FEAT_SUN_WORKSHOP) || defined(FEAT_NETBEANS_INTG) \
3391 	|| defined(PROTO)
3392 /*
3393  * Change to a file's directory.
3394  * Caller must call shorten_fnames()!
3395  * Return OK or FAIL.
3396  */
3397     int
3398 vim_chdirfile(char_u *fname, char *trigger_autocmd UNUSED)
3399 {
3400     char_u	dir[MAXPATHL];
3401     int		res;
3402 
3403     vim_strncpy(dir, fname, MAXPATHL - 1);
3404     *gettail_sep(dir) = NUL;
3405     res = mch_chdir((char *)dir) == 0 ? OK : FAIL;
3406 #ifdef FEAT_AUTOCMD
3407     if (res == OK && trigger_autocmd != NULL)
3408 	apply_autocmds(EVENT_DIRCHANGED, (char_u *)trigger_autocmd,
3409 							   dir, FALSE, curbuf);
3410 #endif
3411     return res;
3412 }
3413 #endif
3414 
3415 #if defined(STAT_IGNORES_SLASH) || defined(PROTO)
3416 /*
3417  * Check if "name" ends in a slash and is not a directory.
3418  * Used for systems where stat() ignores a trailing slash on a file name.
3419  * The Vim code assumes a trailing slash is only ignored for a directory.
3420  */
3421     static int
3422 illegal_slash(const char *name)
3423 {
3424     if (name[0] == NUL)
3425 	return FALSE;	    /* no file name is not illegal */
3426     if (name[strlen(name) - 1] != '/')
3427 	return FALSE;	    /* no trailing slash */
3428     if (mch_isdir((char_u *)name))
3429 	return FALSE;	    /* trailing slash for a directory */
3430     return TRUE;
3431 }
3432 
3433 /*
3434  * Special implementation of mch_stat() for Solaris.
3435  */
3436     int
3437 vim_stat(const char *name, stat_T *stp)
3438 {
3439     /* On Solaris stat() accepts "file/" as if it was "file".  Return -1 if
3440      * the name ends in "/" and it's not a directory. */
3441     return illegal_slash(name) ? -1 : stat(name, stp);
3442 }
3443 #endif
3444 
3445 #if defined(CURSOR_SHAPE) || defined(PROTO)
3446 
3447 /*
3448  * Handling of cursor and mouse pointer shapes in various modes.
3449  */
3450 
3451 cursorentry_T shape_table[SHAPE_IDX_COUNT] =
3452 {
3453     /* The values will be filled in from the 'guicursor' and 'mouseshape'
3454      * defaults when Vim starts.
3455      * Adjust the SHAPE_IDX_ defines when making changes! */
3456     {0,	0, 0, 700L, 400L, 250L, 0, 0, "n", SHAPE_CURSOR+SHAPE_MOUSE},
3457     {0,	0, 0, 700L, 400L, 250L, 0, 0, "v", SHAPE_CURSOR+SHAPE_MOUSE},
3458     {0,	0, 0, 700L, 400L, 250L, 0, 0, "i", SHAPE_CURSOR+SHAPE_MOUSE},
3459     {0,	0, 0, 700L, 400L, 250L, 0, 0, "r", SHAPE_CURSOR+SHAPE_MOUSE},
3460     {0,	0, 0, 700L, 400L, 250L, 0, 0, "c", SHAPE_CURSOR+SHAPE_MOUSE},
3461     {0,	0, 0, 700L, 400L, 250L, 0, 0, "ci", SHAPE_CURSOR+SHAPE_MOUSE},
3462     {0,	0, 0, 700L, 400L, 250L, 0, 0, "cr", SHAPE_CURSOR+SHAPE_MOUSE},
3463     {0,	0, 0, 700L, 400L, 250L, 0, 0, "o", SHAPE_CURSOR+SHAPE_MOUSE},
3464     {0,	0, 0, 700L, 400L, 250L, 0, 0, "ve", SHAPE_CURSOR+SHAPE_MOUSE},
3465     {0,	0, 0,   0L,   0L,   0L, 0, 0, "e", SHAPE_MOUSE},
3466     {0,	0, 0,   0L,   0L,   0L, 0, 0, "s", SHAPE_MOUSE},
3467     {0,	0, 0,   0L,   0L,   0L, 0, 0, "sd", SHAPE_MOUSE},
3468     {0,	0, 0,   0L,   0L,   0L, 0, 0, "vs", SHAPE_MOUSE},
3469     {0,	0, 0,   0L,   0L,   0L, 0, 0, "vd", SHAPE_MOUSE},
3470     {0,	0, 0,   0L,   0L,   0L, 0, 0, "m", SHAPE_MOUSE},
3471     {0,	0, 0,   0L,   0L,   0L, 0, 0, "ml", SHAPE_MOUSE},
3472     {0,	0, 0, 100L, 100L, 100L, 0, 0, "sm", SHAPE_CURSOR},
3473 };
3474 
3475 #ifdef FEAT_MOUSESHAPE
3476 /*
3477  * Table with names for mouse shapes.  Keep in sync with all the tables for
3478  * mch_set_mouse_shape()!.
3479  */
3480 static char * mshape_names[] =
3481 {
3482     "arrow",	/* default, must be the first one */
3483     "blank",	/* hidden */
3484     "beam",
3485     "updown",
3486     "udsizing",
3487     "leftright",
3488     "lrsizing",
3489     "busy",
3490     "no",
3491     "crosshair",
3492     "hand1",
3493     "hand2",
3494     "pencil",
3495     "question",
3496     "rightup-arrow",
3497     "up-arrow",
3498     NULL
3499 };
3500 #endif
3501 
3502 /*
3503  * Parse the 'guicursor' option ("what" is SHAPE_CURSOR) or 'mouseshape'
3504  * ("what" is SHAPE_MOUSE).
3505  * Returns error message for an illegal option, NULL otherwise.
3506  */
3507     char_u *
3508 parse_shape_opt(int what)
3509 {
3510     char_u	*modep;
3511     char_u	*colonp;
3512     char_u	*commap;
3513     char_u	*slashp;
3514     char_u	*p, *endp;
3515     int		idx = 0;		/* init for GCC */
3516     int		all_idx;
3517     int		len;
3518     int		i;
3519     long	n;
3520     int		found_ve = FALSE;	/* found "ve" flag */
3521     int		round;
3522 
3523     /*
3524      * First round: check for errors; second round: do it for real.
3525      */
3526     for (round = 1; round <= 2; ++round)
3527     {
3528 	/*
3529 	 * Repeat for all comma separated parts.
3530 	 */
3531 #ifdef FEAT_MOUSESHAPE
3532 	if (what == SHAPE_MOUSE)
3533 	    modep = p_mouseshape;
3534 	else
3535 #endif
3536 	    modep = p_guicursor;
3537 	while (*modep != NUL)
3538 	{
3539 	    colonp = vim_strchr(modep, ':');
3540 	    commap = vim_strchr(modep, ',');
3541 
3542 	    if (colonp == NULL || (commap != NULL && commap < colonp))
3543 		return (char_u *)N_("E545: Missing colon");
3544 	    if (colonp == modep)
3545 		return (char_u *)N_("E546: Illegal mode");
3546 
3547 	    /*
3548 	     * Repeat for all mode's before the colon.
3549 	     * For the 'a' mode, we loop to handle all the modes.
3550 	     */
3551 	    all_idx = -1;
3552 	    while (modep < colonp || all_idx >= 0)
3553 	    {
3554 		if (all_idx < 0)
3555 		{
3556 		    /* Find the mode. */
3557 		    if (modep[1] == '-' || modep[1] == ':')
3558 			len = 1;
3559 		    else
3560 			len = 2;
3561 		    if (len == 1 && TOLOWER_ASC(modep[0]) == 'a')
3562 			all_idx = SHAPE_IDX_COUNT - 1;
3563 		    else
3564 		    {
3565 			for (idx = 0; idx < SHAPE_IDX_COUNT; ++idx)
3566 			    if (STRNICMP(modep, shape_table[idx].name, len)
3567 									 == 0)
3568 				break;
3569 			if (idx == SHAPE_IDX_COUNT
3570 				   || (shape_table[idx].used_for & what) == 0)
3571 			    return (char_u *)N_("E546: Illegal mode");
3572 			if (len == 2 && modep[0] == 'v' && modep[1] == 'e')
3573 			    found_ve = TRUE;
3574 		    }
3575 		    modep += len + 1;
3576 		}
3577 
3578 		if (all_idx >= 0)
3579 		    idx = all_idx--;
3580 		else if (round == 2)
3581 		{
3582 #ifdef FEAT_MOUSESHAPE
3583 		    if (what == SHAPE_MOUSE)
3584 		    {
3585 			/* Set the default, for the missing parts */
3586 			shape_table[idx].mshape = 0;
3587 		    }
3588 		    else
3589 #endif
3590 		    {
3591 			/* Set the defaults, for the missing parts */
3592 			shape_table[idx].shape = SHAPE_BLOCK;
3593 			shape_table[idx].blinkwait = 700L;
3594 			shape_table[idx].blinkon = 400L;
3595 			shape_table[idx].blinkoff = 250L;
3596 		    }
3597 		}
3598 
3599 		/* Parse the part after the colon */
3600 		for (p = colonp + 1; *p && *p != ','; )
3601 		{
3602 #ifdef FEAT_MOUSESHAPE
3603 		    if (what == SHAPE_MOUSE)
3604 		    {
3605 			for (i = 0; ; ++i)
3606 			{
3607 			    if (mshape_names[i] == NULL)
3608 			    {
3609 				if (!VIM_ISDIGIT(*p))
3610 				    return (char_u *)N_("E547: Illegal mouseshape");
3611 				if (round == 2)
3612 				    shape_table[idx].mshape =
3613 					      getdigits(&p) + MSHAPE_NUMBERED;
3614 				else
3615 				    (void)getdigits(&p);
3616 				break;
3617 			    }
3618 			    len = (int)STRLEN(mshape_names[i]);
3619 			    if (STRNICMP(p, mshape_names[i], len) == 0)
3620 			    {
3621 				if (round == 2)
3622 				    shape_table[idx].mshape = i;
3623 				p += len;
3624 				break;
3625 			    }
3626 			}
3627 		    }
3628 		    else /* if (what == SHAPE_MOUSE) */
3629 #endif
3630 		    {
3631 			/*
3632 			 * First handle the ones with a number argument.
3633 			 */
3634 			i = *p;
3635 			len = 0;
3636 			if (STRNICMP(p, "ver", 3) == 0)
3637 			    len = 3;
3638 			else if (STRNICMP(p, "hor", 3) == 0)
3639 			    len = 3;
3640 			else if (STRNICMP(p, "blinkwait", 9) == 0)
3641 			    len = 9;
3642 			else if (STRNICMP(p, "blinkon", 7) == 0)
3643 			    len = 7;
3644 			else if (STRNICMP(p, "blinkoff", 8) == 0)
3645 			    len = 8;
3646 			if (len != 0)
3647 			{
3648 			    p += len;
3649 			    if (!VIM_ISDIGIT(*p))
3650 				return (char_u *)N_("E548: digit expected");
3651 			    n = getdigits(&p);
3652 			    if (len == 3)   /* "ver" or "hor" */
3653 			    {
3654 				if (n == 0)
3655 				    return (char_u *)N_("E549: Illegal percentage");
3656 				if (round == 2)
3657 				{
3658 				    if (TOLOWER_ASC(i) == 'v')
3659 					shape_table[idx].shape = SHAPE_VER;
3660 				    else
3661 					shape_table[idx].shape = SHAPE_HOR;
3662 				    shape_table[idx].percentage = n;
3663 				}
3664 			    }
3665 			    else if (round == 2)
3666 			    {
3667 				if (len == 9)
3668 				    shape_table[idx].blinkwait = n;
3669 				else if (len == 7)
3670 				    shape_table[idx].blinkon = n;
3671 				else
3672 				    shape_table[idx].blinkoff = n;
3673 			    }
3674 			}
3675 			else if (STRNICMP(p, "block", 5) == 0)
3676 			{
3677 			    if (round == 2)
3678 				shape_table[idx].shape = SHAPE_BLOCK;
3679 			    p += 5;
3680 			}
3681 			else	/* must be a highlight group name then */
3682 			{
3683 			    endp = vim_strchr(p, '-');
3684 			    if (commap == NULL)		    /* last part */
3685 			    {
3686 				if (endp == NULL)
3687 				    endp = p + STRLEN(p);   /* find end of part */
3688 			    }
3689 			    else if (endp > commap || endp == NULL)
3690 				endp = commap;
3691 			    slashp = vim_strchr(p, '/');
3692 			    if (slashp != NULL && slashp < endp)
3693 			    {
3694 				/* "group/langmap_group" */
3695 				i = syn_check_group(p, (int)(slashp - p));
3696 				p = slashp + 1;
3697 			    }
3698 			    if (round == 2)
3699 			    {
3700 				shape_table[idx].id = syn_check_group(p,
3701 							     (int)(endp - p));
3702 				shape_table[idx].id_lm = shape_table[idx].id;
3703 				if (slashp != NULL && slashp < endp)
3704 				    shape_table[idx].id = i;
3705 			    }
3706 			    p = endp;
3707 			}
3708 		    } /* if (what != SHAPE_MOUSE) */
3709 
3710 		    if (*p == '-')
3711 			++p;
3712 		}
3713 	    }
3714 	    modep = p;
3715 	    if (*modep == ',')
3716 		++modep;
3717 	}
3718     }
3719 
3720     /* If the 's' flag is not given, use the 'v' cursor for 's' */
3721     if (!found_ve)
3722     {
3723 #ifdef FEAT_MOUSESHAPE
3724 	if (what == SHAPE_MOUSE)
3725 	{
3726 	    shape_table[SHAPE_IDX_VE].mshape = shape_table[SHAPE_IDX_V].mshape;
3727 	}
3728 	else
3729 #endif
3730 	{
3731 	    shape_table[SHAPE_IDX_VE].shape = shape_table[SHAPE_IDX_V].shape;
3732 	    shape_table[SHAPE_IDX_VE].percentage =
3733 					 shape_table[SHAPE_IDX_V].percentage;
3734 	    shape_table[SHAPE_IDX_VE].blinkwait =
3735 					  shape_table[SHAPE_IDX_V].blinkwait;
3736 	    shape_table[SHAPE_IDX_VE].blinkon =
3737 					    shape_table[SHAPE_IDX_V].blinkon;
3738 	    shape_table[SHAPE_IDX_VE].blinkoff =
3739 					   shape_table[SHAPE_IDX_V].blinkoff;
3740 	    shape_table[SHAPE_IDX_VE].id = shape_table[SHAPE_IDX_V].id;
3741 	    shape_table[SHAPE_IDX_VE].id_lm = shape_table[SHAPE_IDX_V].id_lm;
3742 	}
3743     }
3744 
3745     return NULL;
3746 }
3747 
3748 # if defined(MCH_CURSOR_SHAPE) || defined(FEAT_GUI) \
3749 	|| defined(FEAT_MOUSESHAPE) || defined(PROTO)
3750 /*
3751  * Return the index into shape_table[] for the current mode.
3752  * When "mouse" is TRUE, consider indexes valid for the mouse pointer.
3753  */
3754     int
3755 get_shape_idx(int mouse)
3756 {
3757 #ifdef FEAT_MOUSESHAPE
3758     if (mouse && (State == HITRETURN || State == ASKMORE))
3759     {
3760 # ifdef FEAT_GUI
3761 	int x, y;
3762 	gui_mch_getmouse(&x, &y);
3763 	if (Y_2_ROW(y) == Rows - 1)
3764 	    return SHAPE_IDX_MOREL;
3765 # endif
3766 	return SHAPE_IDX_MORE;
3767     }
3768     if (mouse && drag_status_line)
3769 	return SHAPE_IDX_SDRAG;
3770     if (mouse && drag_sep_line)
3771 	return SHAPE_IDX_VDRAG;
3772 #endif
3773     if (!mouse && State == SHOWMATCH)
3774 	return SHAPE_IDX_SM;
3775 #ifdef FEAT_VREPLACE
3776     if (State & VREPLACE_FLAG)
3777 	return SHAPE_IDX_R;
3778 #endif
3779     if (State & REPLACE_FLAG)
3780 	return SHAPE_IDX_R;
3781     if (State & INSERT)
3782 	return SHAPE_IDX_I;
3783     if (State & CMDLINE)
3784     {
3785 	if (cmdline_at_end())
3786 	    return SHAPE_IDX_C;
3787 	if (cmdline_overstrike())
3788 	    return SHAPE_IDX_CR;
3789 	return SHAPE_IDX_CI;
3790     }
3791     if (finish_op)
3792 	return SHAPE_IDX_O;
3793     if (VIsual_active)
3794     {
3795 	if (*p_sel == 'e')
3796 	    return SHAPE_IDX_VE;
3797 	else
3798 	    return SHAPE_IDX_V;
3799     }
3800     return SHAPE_IDX_N;
3801 }
3802 #endif
3803 
3804 # if defined(FEAT_MOUSESHAPE) || defined(PROTO)
3805 static int old_mouse_shape = 0;
3806 
3807 /*
3808  * Set the mouse shape:
3809  * If "shape" is -1, use shape depending on the current mode,
3810  * depending on the current state.
3811  * If "shape" is -2, only update the shape when it's CLINE or STATUS (used
3812  * when the mouse moves off the status or command line).
3813  */
3814     void
3815 update_mouseshape(int shape_idx)
3816 {
3817     int new_mouse_shape;
3818 
3819     /* Only works in GUI mode. */
3820     if (!gui.in_use || gui.starting)
3821 	return;
3822 
3823     /* Postpone the updating when more is to come.  Speeds up executing of
3824      * mappings. */
3825     if (shape_idx == -1 && char_avail())
3826     {
3827 	postponed_mouseshape = TRUE;
3828 	return;
3829     }
3830 
3831     /* When ignoring the mouse don't change shape on the statusline. */
3832     if (*p_mouse == NUL
3833 	    && (shape_idx == SHAPE_IDX_CLINE
3834 		|| shape_idx == SHAPE_IDX_STATUS
3835 		|| shape_idx == SHAPE_IDX_VSEP))
3836 	shape_idx = -2;
3837 
3838     if (shape_idx == -2
3839 	    && old_mouse_shape != shape_table[SHAPE_IDX_CLINE].mshape
3840 	    && old_mouse_shape != shape_table[SHAPE_IDX_STATUS].mshape
3841 	    && old_mouse_shape != shape_table[SHAPE_IDX_VSEP].mshape)
3842 	return;
3843     if (shape_idx < 0)
3844 	new_mouse_shape = shape_table[get_shape_idx(TRUE)].mshape;
3845     else
3846 	new_mouse_shape = shape_table[shape_idx].mshape;
3847     if (new_mouse_shape != old_mouse_shape)
3848     {
3849 	mch_set_mouse_shape(new_mouse_shape);
3850 	old_mouse_shape = new_mouse_shape;
3851     }
3852     postponed_mouseshape = FALSE;
3853 }
3854 # endif
3855 
3856 #endif /* CURSOR_SHAPE */
3857 
3858 
3859 /* TODO: make some #ifdef for this */
3860 /*--------[ file searching ]-------------------------------------------------*/
3861 /*
3862  * File searching functions for 'path', 'tags' and 'cdpath' options.
3863  * External visible functions:
3864  * vim_findfile_init()		creates/initialises the search context
3865  * vim_findfile_free_visited()	free list of visited files/dirs of search
3866  *				context
3867  * vim_findfile()		find a file in the search context
3868  * vim_findfile_cleanup()	cleanup/free search context created by
3869  *				vim_findfile_init()
3870  *
3871  * All static functions and variables start with 'ff_'
3872  *
3873  * In general it works like this:
3874  * First you create yourself a search context by calling vim_findfile_init().
3875  * It is possible to give a search context from a previous call to
3876  * vim_findfile_init(), so it can be reused. After this you call vim_findfile()
3877  * until you are satisfied with the result or it returns NULL. On every call it
3878  * returns the next file which matches the conditions given to
3879  * vim_findfile_init(). If it doesn't find a next file it returns NULL.
3880  *
3881  * It is possible to call vim_findfile_init() again to reinitialise your search
3882  * with some new parameters. Don't forget to pass your old search context to
3883  * it, so it can reuse it and especially reuse the list of already visited
3884  * directories. If you want to delete the list of already visited directories
3885  * simply call vim_findfile_free_visited().
3886  *
3887  * When you are done call vim_findfile_cleanup() to free the search context.
3888  *
3889  * The function vim_findfile_init() has a long comment, which describes the
3890  * needed parameters.
3891  *
3892  *
3893  *
3894  * ATTENTION:
3895  * ==========
3896  *	Also we use an allocated search context here, this functions are NOT
3897  *	thread-safe!!!!!
3898  *
3899  *	To minimize parameter passing (or because I'm to lazy), only the
3900  *	external visible functions get a search context as a parameter. This is
3901  *	then assigned to a static global, which is used throughout the local
3902  *	functions.
3903  */
3904 
3905 /*
3906  * type for the directory search stack
3907  */
3908 typedef struct ff_stack
3909 {
3910     struct ff_stack	*ffs_prev;
3911 
3912     /* the fix part (no wildcards) and the part containing the wildcards
3913      * of the search path
3914      */
3915     char_u		*ffs_fix_path;
3916 #ifdef FEAT_PATH_EXTRA
3917     char_u		*ffs_wc_path;
3918 #endif
3919 
3920     /* files/dirs found in the above directory, matched by the first wildcard
3921      * of wc_part
3922      */
3923     char_u		**ffs_filearray;
3924     int			ffs_filearray_size;
3925     char_u		ffs_filearray_cur;   /* needed for partly handled dirs */
3926 
3927     /* to store status of partly handled directories
3928      * 0: we work on this directory for the first time
3929      * 1: this directory was partly searched in an earlier step
3930      */
3931     int			ffs_stage;
3932 
3933     /* How deep are we in the directory tree?
3934      * Counts backward from value of level parameter to vim_findfile_init
3935      */
3936     int			ffs_level;
3937 
3938     /* Did we already expand '**' to an empty string? */
3939     int			ffs_star_star_empty;
3940 } ff_stack_T;
3941 
3942 /*
3943  * type for already visited directories or files.
3944  */
3945 typedef struct ff_visited
3946 {
3947     struct ff_visited	*ffv_next;
3948 
3949 #ifdef FEAT_PATH_EXTRA
3950     /* Visited directories are different if the wildcard string are
3951      * different. So we have to save it.
3952      */
3953     char_u		*ffv_wc_path;
3954 #endif
3955     /* for unix use inode etc for comparison (needed because of links), else
3956      * use filename.
3957      */
3958 #ifdef UNIX
3959     int			ffv_dev_valid;	/* ffv_dev and ffv_ino were set */
3960     dev_t		ffv_dev;	/* device number */
3961     ino_t		ffv_ino;	/* inode number */
3962 #endif
3963     /* The memory for this struct is allocated according to the length of
3964      * ffv_fname.
3965      */
3966     char_u		ffv_fname[1];	/* actually longer */
3967 } ff_visited_T;
3968 
3969 /*
3970  * We might have to manage several visited lists during a search.
3971  * This is especially needed for the tags option. If tags is set to:
3972  *      "./++/tags,./++/TAGS,++/tags"  (replace + with *)
3973  * So we have to do 3 searches:
3974  *   1) search from the current files directory downward for the file "tags"
3975  *   2) search from the current files directory downward for the file "TAGS"
3976  *   3) search from Vims current directory downwards for the file "tags"
3977  * As you can see, the first and the third search are for the same file, so for
3978  * the third search we can use the visited list of the first search. For the
3979  * second search we must start from a empty visited list.
3980  * The struct ff_visited_list_hdr is used to manage a linked list of already
3981  * visited lists.
3982  */
3983 typedef struct ff_visited_list_hdr
3984 {
3985     struct ff_visited_list_hdr	*ffvl_next;
3986 
3987     /* the filename the attached visited list is for */
3988     char_u			*ffvl_filename;
3989 
3990     ff_visited_T		*ffvl_visited_list;
3991 
3992 } ff_visited_list_hdr_T;
3993 
3994 
3995 /*
3996  * '**' can be expanded to several directory levels.
3997  * Set the default maximum depth.
3998  */
3999 #define FF_MAX_STAR_STAR_EXPAND ((char_u)30)
4000 
4001 /*
4002  * The search context:
4003  *   ffsc_stack_ptr:	the stack for the dirs to search
4004  *   ffsc_visited_list: the currently active visited list
4005  *   ffsc_dir_visited_list: the currently active visited list for search dirs
4006  *   ffsc_visited_lists_list: the list of all visited lists
4007  *   ffsc_dir_visited_lists_list: the list of all visited lists for search dirs
4008  *   ffsc_file_to_search:     the file to search for
4009  *   ffsc_start_dir:	the starting directory, if search path was relative
4010  *   ffsc_fix_path:	the fix part of the given path (without wildcards)
4011  *			Needed for upward search.
4012  *   ffsc_wc_path:	the part of the given path containing wildcards
4013  *   ffsc_level:	how many levels of dirs to search downwards
4014  *   ffsc_stopdirs_v:	array of stop directories for upward search
4015  *   ffsc_find_what:	FINDFILE_BOTH, FINDFILE_DIR or FINDFILE_FILE
4016  *   ffsc_tagfile:	searching for tags file, don't use 'suffixesadd'
4017  */
4018 typedef struct ff_search_ctx_T
4019 {
4020      ff_stack_T			*ffsc_stack_ptr;
4021      ff_visited_list_hdr_T	*ffsc_visited_list;
4022      ff_visited_list_hdr_T	*ffsc_dir_visited_list;
4023      ff_visited_list_hdr_T	*ffsc_visited_lists_list;
4024      ff_visited_list_hdr_T	*ffsc_dir_visited_lists_list;
4025      char_u			*ffsc_file_to_search;
4026      char_u			*ffsc_start_dir;
4027      char_u			*ffsc_fix_path;
4028 #ifdef FEAT_PATH_EXTRA
4029      char_u			*ffsc_wc_path;
4030      int			ffsc_level;
4031      char_u			**ffsc_stopdirs_v;
4032 #endif
4033      int			ffsc_find_what;
4034      int			ffsc_tagfile;
4035 } ff_search_ctx_T;
4036 
4037 /* locally needed functions */
4038 #ifdef FEAT_PATH_EXTRA
4039 static int ff_check_visited(ff_visited_T **, char_u *, char_u *);
4040 #else
4041 static int ff_check_visited(ff_visited_T **, char_u *);
4042 #endif
4043 static void vim_findfile_free_visited_list(ff_visited_list_hdr_T **list_headp);
4044 static void ff_free_visited_list(ff_visited_T *vl);
4045 static ff_visited_list_hdr_T* ff_get_visited_list(char_u *, ff_visited_list_hdr_T **list_headp);
4046 #ifdef FEAT_PATH_EXTRA
4047 static int ff_wc_equal(char_u *s1, char_u *s2);
4048 #endif
4049 
4050 static void ff_push(ff_search_ctx_T *search_ctx, ff_stack_T *stack_ptr);
4051 static ff_stack_T *ff_pop(ff_search_ctx_T *search_ctx);
4052 static void ff_clear(ff_search_ctx_T *search_ctx);
4053 static void ff_free_stack_element(ff_stack_T *stack_ptr);
4054 #ifdef FEAT_PATH_EXTRA
4055 static ff_stack_T *ff_create_stack_element(char_u *, char_u *, int, int);
4056 #else
4057 static ff_stack_T *ff_create_stack_element(char_u *, int, int);
4058 #endif
4059 #ifdef FEAT_PATH_EXTRA
4060 static int ff_path_in_stoplist(char_u *, int, char_u **);
4061 #endif
4062 
4063 static char_u e_pathtoolong[] = N_("E854: path too long for completion");
4064 
4065 #if 0
4066 /*
4067  * if someone likes findfirst/findnext, here are the functions
4068  * NOT TESTED!!
4069  */
4070 
4071 static void *ff_fn_search_context = NULL;
4072 
4073     char_u *
4074 vim_findfirst(char_u *path, char_u *filename, int level)
4075 {
4076     ff_fn_search_context =
4077 	vim_findfile_init(path, filename, NULL, level, TRUE, FALSE,
4078 		ff_fn_search_context, rel_fname);
4079     if (NULL == ff_fn_search_context)
4080 	return NULL;
4081     else
4082 	return vim_findnext()
4083 }
4084 
4085     char_u *
4086 vim_findnext(void)
4087 {
4088     char_u *ret = vim_findfile(ff_fn_search_context);
4089 
4090     if (NULL == ret)
4091     {
4092 	vim_findfile_cleanup(ff_fn_search_context);
4093 	ff_fn_search_context = NULL;
4094     }
4095     return ret;
4096 }
4097 #endif
4098 
4099 /*
4100  * Initialization routine for vim_findfile().
4101  *
4102  * Returns the newly allocated search context or NULL if an error occurred.
4103  *
4104  * Don't forget to clean up by calling vim_findfile_cleanup() if you are done
4105  * with the search context.
4106  *
4107  * Find the file 'filename' in the directory 'path'.
4108  * The parameter 'path' may contain wildcards. If so only search 'level'
4109  * directories deep. The parameter 'level' is the absolute maximum and is
4110  * not related to restricts given to the '**' wildcard. If 'level' is 100
4111  * and you use '**200' vim_findfile() will stop after 100 levels.
4112  *
4113  * 'filename' cannot contain wildcards!  It is used as-is, no backslashes to
4114  * escape special characters.
4115  *
4116  * If 'stopdirs' is not NULL and nothing is found downward, the search is
4117  * restarted on the next higher directory level. This is repeated until the
4118  * start-directory of a search is contained in 'stopdirs'. 'stopdirs' has the
4119  * format ";*<dirname>*\(;<dirname>\)*;\=$".
4120  *
4121  * If the 'path' is relative, the starting dir for the search is either VIM's
4122  * current dir or if the path starts with "./" the current files dir.
4123  * If the 'path' is absolute, the starting dir is that part of the path before
4124  * the first wildcard.
4125  *
4126  * Upward search is only done on the starting dir.
4127  *
4128  * If 'free_visited' is TRUE the list of already visited files/directories is
4129  * cleared. Set this to FALSE if you just want to search from another
4130  * directory, but want to be sure that no directory from a previous search is
4131  * searched again. This is useful if you search for a file at different places.
4132  * The list of visited files/dirs can also be cleared with the function
4133  * vim_findfile_free_visited().
4134  *
4135  * Set the parameter 'find_what' to FINDFILE_DIR if you want to search for
4136  * directories only, FINDFILE_FILE for files only, FINDFILE_BOTH for both.
4137  *
4138  * A search context returned by a previous call to vim_findfile_init() can be
4139  * passed in the parameter "search_ctx_arg".  This context is reused and
4140  * reinitialized with the new parameters.  The list of already visited
4141  * directories from this context is only deleted if the parameter
4142  * "free_visited" is true.  Be aware that the passed "search_ctx_arg" is freed
4143  * if the reinitialization fails.
4144  *
4145  * If you don't have a search context from a previous call "search_ctx_arg"
4146  * must be NULL.
4147  *
4148  * This function silently ignores a few errors, vim_findfile() will have
4149  * limited functionality then.
4150  */
4151     void *
4152 vim_findfile_init(
4153     char_u	*path,
4154     char_u	*filename,
4155     char_u	*stopdirs UNUSED,
4156     int		level,
4157     int		free_visited,
4158     int		find_what,
4159     void	*search_ctx_arg,
4160     int		tagfile,	/* expanding names of tags files */
4161     char_u	*rel_fname)	/* file name to use for "." */
4162 {
4163 #ifdef FEAT_PATH_EXTRA
4164     char_u		*wc_part;
4165 #endif
4166     ff_stack_T		*sptr;
4167     ff_search_ctx_T	*search_ctx;
4168 
4169     /* If a search context is given by the caller, reuse it, else allocate a
4170      * new one.
4171      */
4172     if (search_ctx_arg != NULL)
4173 	search_ctx = search_ctx_arg;
4174     else
4175     {
4176 	search_ctx = (ff_search_ctx_T*)alloc((unsigned)sizeof(ff_search_ctx_T));
4177 	if (search_ctx == NULL)
4178 	    goto error_return;
4179 	vim_memset(search_ctx, 0, sizeof(ff_search_ctx_T));
4180     }
4181     search_ctx->ffsc_find_what = find_what;
4182     search_ctx->ffsc_tagfile = tagfile;
4183 
4184     /* clear the search context, but NOT the visited lists */
4185     ff_clear(search_ctx);
4186 
4187     /* clear visited list if wanted */
4188     if (free_visited == TRUE)
4189 	vim_findfile_free_visited(search_ctx);
4190     else
4191     {
4192 	/* Reuse old visited lists. Get the visited list for the given
4193 	 * filename. If no list for the current filename exists, creates a new
4194 	 * one. */
4195 	search_ctx->ffsc_visited_list = ff_get_visited_list(filename,
4196 					&search_ctx->ffsc_visited_lists_list);
4197 	if (search_ctx->ffsc_visited_list == NULL)
4198 	    goto error_return;
4199 	search_ctx->ffsc_dir_visited_list = ff_get_visited_list(filename,
4200 				    &search_ctx->ffsc_dir_visited_lists_list);
4201 	if (search_ctx->ffsc_dir_visited_list == NULL)
4202 	    goto error_return;
4203     }
4204 
4205     if (ff_expand_buffer == NULL)
4206     {
4207 	ff_expand_buffer = (char_u*)alloc(MAXPATHL);
4208 	if (ff_expand_buffer == NULL)
4209 	    goto error_return;
4210     }
4211 
4212     /* Store information on starting dir now if path is relative.
4213      * If path is absolute, we do that later.  */
4214     if (path[0] == '.'
4215 	    && (vim_ispathsep(path[1]) || path[1] == NUL)
4216 	    && (!tagfile || vim_strchr(p_cpo, CPO_DOTTAG) == NULL)
4217 	    && rel_fname != NULL)
4218     {
4219 	int	len = (int)(gettail(rel_fname) - rel_fname);
4220 
4221 	if (!vim_isAbsName(rel_fname) && len + 1 < MAXPATHL)
4222 	{
4223 	    /* Make the start dir an absolute path name. */
4224 	    vim_strncpy(ff_expand_buffer, rel_fname, len);
4225 	    search_ctx->ffsc_start_dir = FullName_save(ff_expand_buffer, FALSE);
4226 	}
4227 	else
4228 	    search_ctx->ffsc_start_dir = vim_strnsave(rel_fname, len);
4229 	if (search_ctx->ffsc_start_dir == NULL)
4230 	    goto error_return;
4231 	if (*++path != NUL)
4232 	    ++path;
4233     }
4234     else if (*path == NUL || !vim_isAbsName(path))
4235     {
4236 #ifdef BACKSLASH_IN_FILENAME
4237 	/* "c:dir" needs "c:" to be expanded, otherwise use current dir */
4238 	if (*path != NUL && path[1] == ':')
4239 	{
4240 	    char_u  drive[3];
4241 
4242 	    drive[0] = path[0];
4243 	    drive[1] = ':';
4244 	    drive[2] = NUL;
4245 	    if (vim_FullName(drive, ff_expand_buffer, MAXPATHL, TRUE) == FAIL)
4246 		goto error_return;
4247 	    path += 2;
4248 	}
4249 	else
4250 #endif
4251 	if (mch_dirname(ff_expand_buffer, MAXPATHL) == FAIL)
4252 	    goto error_return;
4253 
4254 	search_ctx->ffsc_start_dir = vim_strsave(ff_expand_buffer);
4255 	if (search_ctx->ffsc_start_dir == NULL)
4256 	    goto error_return;
4257 
4258 #ifdef BACKSLASH_IN_FILENAME
4259 	/* A path that starts with "/dir" is relative to the drive, not to the
4260 	 * directory (but not for "//machine/dir").  Only use the drive name. */
4261 	if ((*path == '/' || *path == '\\')
4262 		&& path[1] != path[0]
4263 		&& search_ctx->ffsc_start_dir[1] == ':')
4264 	    search_ctx->ffsc_start_dir[2] = NUL;
4265 #endif
4266     }
4267 
4268 #ifdef FEAT_PATH_EXTRA
4269     /*
4270      * If stopdirs are given, split them into an array of pointers.
4271      * If this fails (mem allocation), there is no upward search at all or a
4272      * stop directory is not recognized -> continue silently.
4273      * If stopdirs just contains a ";" or is empty,
4274      * search_ctx->ffsc_stopdirs_v will only contain a  NULL pointer. This
4275      * is handled as unlimited upward search.  See function
4276      * ff_path_in_stoplist() for details.
4277      */
4278     if (stopdirs != NULL)
4279     {
4280 	char_u	*walker = stopdirs;
4281 	int	dircount;
4282 
4283 	while (*walker == ';')
4284 	    walker++;
4285 
4286 	dircount = 1;
4287 	search_ctx->ffsc_stopdirs_v =
4288 				 (char_u **)alloc((unsigned)sizeof(char_u *));
4289 
4290 	if (search_ctx->ffsc_stopdirs_v != NULL)
4291 	{
4292 	    do
4293 	    {
4294 		char_u	*helper;
4295 		void	*ptr;
4296 
4297 		helper = walker;
4298 		ptr = vim_realloc(search_ctx->ffsc_stopdirs_v,
4299 					   (dircount + 1) * sizeof(char_u *));
4300 		if (ptr)
4301 		    search_ctx->ffsc_stopdirs_v = ptr;
4302 		else
4303 		    /* ignore, keep what we have and continue */
4304 		    break;
4305 		walker = vim_strchr(walker, ';');
4306 		if (walker)
4307 		{
4308 		    search_ctx->ffsc_stopdirs_v[dircount-1] =
4309 				 vim_strnsave(helper, (int)(walker - helper));
4310 		    walker++;
4311 		}
4312 		else
4313 		    /* this might be "", which means ascent till top
4314 		     * of directory tree.
4315 		     */
4316 		    search_ctx->ffsc_stopdirs_v[dircount-1] =
4317 							  vim_strsave(helper);
4318 
4319 		dircount++;
4320 
4321 	    } while (walker != NULL);
4322 	    search_ctx->ffsc_stopdirs_v[dircount-1] = NULL;
4323 	}
4324     }
4325 #endif
4326 
4327 #ifdef FEAT_PATH_EXTRA
4328     search_ctx->ffsc_level = level;
4329 
4330     /* split into:
4331      *  -fix path
4332      *  -wildcard_stuff (might be NULL)
4333      */
4334     wc_part = vim_strchr(path, '*');
4335     if (wc_part != NULL)
4336     {
4337 	int	llevel;
4338 	int	len;
4339 	char	*errpt;
4340 
4341 	/* save the fix part of the path */
4342 	search_ctx->ffsc_fix_path = vim_strnsave(path, (int)(wc_part - path));
4343 
4344 	/*
4345 	 * copy wc_path and add restricts to the '**' wildcard.
4346 	 * The octet after a '**' is used as a (binary) counter.
4347 	 * So '**3' is transposed to '**^C' ('^C' is ASCII value 3)
4348 	 * or '**76' is transposed to '**N'( 'N' is ASCII value 76).
4349 	 * For EBCDIC you get different character values.
4350 	 * If no restrict is given after '**' the default is used.
4351 	 * Due to this technique the path looks awful if you print it as a
4352 	 * string.
4353 	 */
4354 	len = 0;
4355 	while (*wc_part != NUL)
4356 	{
4357 	    if (len + 5 >= MAXPATHL)
4358 	    {
4359 		EMSG(_(e_pathtoolong));
4360 		break;
4361 	    }
4362 	    if (STRNCMP(wc_part, "**", 2) == 0)
4363 	    {
4364 		ff_expand_buffer[len++] = *wc_part++;
4365 		ff_expand_buffer[len++] = *wc_part++;
4366 
4367 		llevel = strtol((char *)wc_part, &errpt, 10);
4368 		if ((char_u *)errpt != wc_part && llevel > 0 && llevel < 255)
4369 		    ff_expand_buffer[len++] = llevel;
4370 		else if ((char_u *)errpt != wc_part && llevel == 0)
4371 		    /* restrict is 0 -> remove already added '**' */
4372 		    len -= 2;
4373 		else
4374 		    ff_expand_buffer[len++] = FF_MAX_STAR_STAR_EXPAND;
4375 		wc_part = (char_u *)errpt;
4376 		if (*wc_part != NUL && !vim_ispathsep(*wc_part))
4377 		{
4378 		    EMSG2(_("E343: Invalid path: '**[number]' must be at the end of the path or be followed by '%s'."), PATHSEPSTR);
4379 		    goto error_return;
4380 		}
4381 	    }
4382 	    else
4383 		ff_expand_buffer[len++] = *wc_part++;
4384 	}
4385 	ff_expand_buffer[len] = NUL;
4386 	search_ctx->ffsc_wc_path = vim_strsave(ff_expand_buffer);
4387 
4388 	if (search_ctx->ffsc_wc_path == NULL)
4389 	    goto error_return;
4390     }
4391     else
4392 #endif
4393 	search_ctx->ffsc_fix_path = vim_strsave(path);
4394 
4395     if (search_ctx->ffsc_start_dir == NULL)
4396     {
4397 	/* store the fix part as startdir.
4398 	 * This is needed if the parameter path is fully qualified.
4399 	 */
4400 	search_ctx->ffsc_start_dir = vim_strsave(search_ctx->ffsc_fix_path);
4401 	if (search_ctx->ffsc_start_dir == NULL)
4402 	    goto error_return;
4403 	search_ctx->ffsc_fix_path[0] = NUL;
4404     }
4405 
4406     /* create an absolute path */
4407     if (STRLEN(search_ctx->ffsc_start_dir)
4408 			  + STRLEN(search_ctx->ffsc_fix_path) + 3 >= MAXPATHL)
4409     {
4410 	EMSG(_(e_pathtoolong));
4411 	goto error_return;
4412     }
4413     STRCPY(ff_expand_buffer, search_ctx->ffsc_start_dir);
4414     add_pathsep(ff_expand_buffer);
4415     {
4416 	int    eb_len = (int)STRLEN(ff_expand_buffer);
4417 	char_u *buf = alloc(eb_len
4418 				+ (int)STRLEN(search_ctx->ffsc_fix_path) + 1);
4419 
4420 	STRCPY(buf, ff_expand_buffer);
4421 	STRCPY(buf + eb_len, search_ctx->ffsc_fix_path);
4422 	if (mch_isdir(buf))
4423 	{
4424 	    STRCAT(ff_expand_buffer, search_ctx->ffsc_fix_path);
4425 	    add_pathsep(ff_expand_buffer);
4426 	}
4427 #ifdef FEAT_PATH_EXTRA
4428 	else
4429 	{
4430 	    char_u *p =  gettail(search_ctx->ffsc_fix_path);
4431 	    char_u *wc_path = NULL;
4432 	    char_u *temp = NULL;
4433 	    int    len = 0;
4434 
4435 	    if (p > search_ctx->ffsc_fix_path)
4436 	    {
4437 		len = (int)(p - search_ctx->ffsc_fix_path) - 1;
4438 		STRNCAT(ff_expand_buffer, search_ctx->ffsc_fix_path, len);
4439 		add_pathsep(ff_expand_buffer);
4440 	    }
4441 	    else
4442 		len = (int)STRLEN(search_ctx->ffsc_fix_path);
4443 
4444 	    if (search_ctx->ffsc_wc_path != NULL)
4445 	    {
4446 		wc_path = vim_strsave(search_ctx->ffsc_wc_path);
4447 		temp = alloc((int)(STRLEN(search_ctx->ffsc_wc_path)
4448 				 + STRLEN(search_ctx->ffsc_fix_path + len)
4449 				 + 1));
4450 		if (temp == NULL || wc_path == NULL)
4451 		{
4452 		    vim_free(buf);
4453 		    vim_free(temp);
4454 		    vim_free(wc_path);
4455 		    goto error_return;
4456 		}
4457 
4458 		STRCPY(temp, search_ctx->ffsc_fix_path + len);
4459 		STRCAT(temp, search_ctx->ffsc_wc_path);
4460 		vim_free(search_ctx->ffsc_wc_path);
4461 		vim_free(wc_path);
4462 		search_ctx->ffsc_wc_path = temp;
4463 	    }
4464 	}
4465 #endif
4466 	vim_free(buf);
4467     }
4468 
4469     sptr = ff_create_stack_element(ff_expand_buffer,
4470 #ifdef FEAT_PATH_EXTRA
4471 	    search_ctx->ffsc_wc_path,
4472 #endif
4473 	    level, 0);
4474 
4475     if (sptr == NULL)
4476 	goto error_return;
4477 
4478     ff_push(search_ctx, sptr);
4479 
4480     search_ctx->ffsc_file_to_search = vim_strsave(filename);
4481     if (search_ctx->ffsc_file_to_search == NULL)
4482 	goto error_return;
4483 
4484     return search_ctx;
4485 
4486 error_return:
4487     /*
4488      * We clear the search context now!
4489      * Even when the caller gave us a (perhaps valid) context we free it here,
4490      * as we might have already destroyed it.
4491      */
4492     vim_findfile_cleanup(search_ctx);
4493     return NULL;
4494 }
4495 
4496 #if defined(FEAT_PATH_EXTRA) || defined(PROTO)
4497 /*
4498  * Get the stopdir string.  Check that ';' is not escaped.
4499  */
4500     char_u *
4501 vim_findfile_stopdir(char_u *buf)
4502 {
4503     char_u	*r_ptr = buf;
4504 
4505     while (*r_ptr != NUL && *r_ptr != ';')
4506     {
4507 	if (r_ptr[0] == '\\' && r_ptr[1] == ';')
4508 	{
4509 	    /* Overwrite the escape char,
4510 	     * use STRLEN(r_ptr) to move the trailing '\0'. */
4511 	    STRMOVE(r_ptr, r_ptr + 1);
4512 	    r_ptr++;
4513 	}
4514 	r_ptr++;
4515     }
4516     if (*r_ptr == ';')
4517     {
4518 	*r_ptr = 0;
4519 	r_ptr++;
4520     }
4521     else if (*r_ptr == NUL)
4522 	r_ptr = NULL;
4523     return r_ptr;
4524 }
4525 #endif
4526 
4527 /*
4528  * Clean up the given search context. Can handle a NULL pointer.
4529  */
4530     void
4531 vim_findfile_cleanup(void *ctx)
4532 {
4533     if (ctx == NULL)
4534 	return;
4535 
4536     vim_findfile_free_visited(ctx);
4537     ff_clear(ctx);
4538     vim_free(ctx);
4539 }
4540 
4541 /*
4542  * Find a file in a search context.
4543  * The search context was created with vim_findfile_init() above.
4544  * Return a pointer to an allocated file name or NULL if nothing found.
4545  * To get all matching files call this function until you get NULL.
4546  *
4547  * If the passed search_context is NULL, NULL is returned.
4548  *
4549  * The search algorithm is depth first. To change this replace the
4550  * stack with a list (don't forget to leave partly searched directories on the
4551  * top of the list).
4552  */
4553     char_u *
4554 vim_findfile(void *search_ctx_arg)
4555 {
4556     char_u	*file_path;
4557 #ifdef FEAT_PATH_EXTRA
4558     char_u	*rest_of_wildcards;
4559     char_u	*path_end = NULL;
4560 #endif
4561     ff_stack_T	*stackp;
4562 #if defined(FEAT_SEARCHPATH) || defined(FEAT_PATH_EXTRA)
4563     int		len;
4564 #endif
4565     int		i;
4566     char_u	*p;
4567 #ifdef FEAT_SEARCHPATH
4568     char_u	*suf;
4569 #endif
4570     ff_search_ctx_T *search_ctx;
4571 
4572     if (search_ctx_arg == NULL)
4573 	return NULL;
4574 
4575     search_ctx = (ff_search_ctx_T *)search_ctx_arg;
4576 
4577     /*
4578      * filepath is used as buffer for various actions and as the storage to
4579      * return a found filename.
4580      */
4581     if ((file_path = alloc((int)MAXPATHL)) == NULL)
4582 	return NULL;
4583 
4584 #ifdef FEAT_PATH_EXTRA
4585     /* store the end of the start dir -- needed for upward search */
4586     if (search_ctx->ffsc_start_dir != NULL)
4587 	path_end = &search_ctx->ffsc_start_dir[
4588 					  STRLEN(search_ctx->ffsc_start_dir)];
4589 #endif
4590 
4591 #ifdef FEAT_PATH_EXTRA
4592     /* upward search loop */
4593     for (;;)
4594     {
4595 #endif
4596 	/* downward search loop */
4597 	for (;;)
4598 	{
4599 	    /* check if user user wants to stop the search*/
4600 	    ui_breakcheck();
4601 	    if (got_int)
4602 		break;
4603 
4604 	    /* get directory to work on from stack */
4605 	    stackp = ff_pop(search_ctx);
4606 	    if (stackp == NULL)
4607 		break;
4608 
4609 	    /*
4610 	     * TODO: decide if we leave this test in
4611 	     *
4612 	     * GOOD: don't search a directory(-tree) twice.
4613 	     * BAD:  - check linked list for every new directory entered.
4614 	     *       - check for double files also done below
4615 	     *
4616 	     * Here we check if we already searched this directory.
4617 	     * We already searched a directory if:
4618 	     * 1) The directory is the same.
4619 	     * 2) We would use the same wildcard string.
4620 	     *
4621 	     * Good if you have links on same directory via several ways
4622 	     *  or you have selfreferences in directories (e.g. SuSE Linux 6.3:
4623 	     *  /etc/rc.d/init.d is linked to /etc/rc.d -> endless loop)
4624 	     *
4625 	     * This check is only needed for directories we work on for the
4626 	     * first time (hence stackp->ff_filearray == NULL)
4627 	     */
4628 	    if (stackp->ffs_filearray == NULL
4629 		    && ff_check_visited(&search_ctx->ffsc_dir_visited_list
4630 							  ->ffvl_visited_list,
4631 			stackp->ffs_fix_path
4632 #ifdef FEAT_PATH_EXTRA
4633 			, stackp->ffs_wc_path
4634 #endif
4635 			) == FAIL)
4636 	    {
4637 #ifdef FF_VERBOSE
4638 		if (p_verbose >= 5)
4639 		{
4640 		    verbose_enter_scroll();
4641 		    smsg((char_u *)"Already Searched: %s (%s)",
4642 				   stackp->ffs_fix_path, stackp->ffs_wc_path);
4643 		    /* don't overwrite this either */
4644 		    msg_puts((char_u *)"\n");
4645 		    verbose_leave_scroll();
4646 		}
4647 #endif
4648 		ff_free_stack_element(stackp);
4649 		continue;
4650 	    }
4651 #ifdef FF_VERBOSE
4652 	    else if (p_verbose >= 5)
4653 	    {
4654 		verbose_enter_scroll();
4655 		smsg((char_u *)"Searching: %s (%s)",
4656 				   stackp->ffs_fix_path, stackp->ffs_wc_path);
4657 		/* don't overwrite this either */
4658 		msg_puts((char_u *)"\n");
4659 		verbose_leave_scroll();
4660 	    }
4661 #endif
4662 
4663 	    /* check depth */
4664 	    if (stackp->ffs_level <= 0)
4665 	    {
4666 		ff_free_stack_element(stackp);
4667 		continue;
4668 	    }
4669 
4670 	    file_path[0] = NUL;
4671 
4672 	    /*
4673 	     * If no filearray till now expand wildcards
4674 	     * The function expand_wildcards() can handle an array of paths
4675 	     * and all possible expands are returned in one array. We use this
4676 	     * to handle the expansion of '**' into an empty string.
4677 	     */
4678 	    if (stackp->ffs_filearray == NULL)
4679 	    {
4680 		char_u *dirptrs[2];
4681 
4682 		/* we use filepath to build the path expand_wildcards() should
4683 		 * expand.
4684 		 */
4685 		dirptrs[0] = file_path;
4686 		dirptrs[1] = NULL;
4687 
4688 		/* if we have a start dir copy it in */
4689 		if (!vim_isAbsName(stackp->ffs_fix_path)
4690 						&& search_ctx->ffsc_start_dir)
4691 		{
4692 		    if (STRLEN(search_ctx->ffsc_start_dir) + 1 < MAXPATHL)
4693 		    {
4694 			STRCPY(file_path, search_ctx->ffsc_start_dir);
4695 			add_pathsep(file_path);
4696 		    }
4697 		    else
4698 			goto fail;
4699 		}
4700 
4701 		/* append the fix part of the search path */
4702 		if (STRLEN(file_path) + STRLEN(stackp->ffs_fix_path) + 1 < MAXPATHL)
4703 		{
4704 		    STRCAT(file_path, stackp->ffs_fix_path);
4705 		    add_pathsep(file_path);
4706 		}
4707 		else
4708 		    goto fail;
4709 
4710 #ifdef FEAT_PATH_EXTRA
4711 		rest_of_wildcards = stackp->ffs_wc_path;
4712 		if (*rest_of_wildcards != NUL)
4713 		{
4714 		    len = (int)STRLEN(file_path);
4715 		    if (STRNCMP(rest_of_wildcards, "**", 2) == 0)
4716 		    {
4717 			/* pointer to the restrict byte
4718 			 * The restrict byte is not a character!
4719 			 */
4720 			p = rest_of_wildcards + 2;
4721 
4722 			if (*p > 0)
4723 			{
4724 			    (*p)--;
4725 			    if (len + 1 < MAXPATHL)
4726 				file_path[len++] = '*';
4727 			    else
4728 				goto fail;
4729 			}
4730 
4731 			if (*p == 0)
4732 			{
4733 			    /* remove '**<numb> from wildcards */
4734 			    STRMOVE(rest_of_wildcards, rest_of_wildcards + 3);
4735 			}
4736 			else
4737 			    rest_of_wildcards += 3;
4738 
4739 			if (stackp->ffs_star_star_empty == 0)
4740 			{
4741 			    /* if not done before, expand '**' to empty */
4742 			    stackp->ffs_star_star_empty = 1;
4743 			    dirptrs[1] = stackp->ffs_fix_path;
4744 			}
4745 		    }
4746 
4747 		    /*
4748 		     * Here we copy until the next path separator or the end of
4749 		     * the path. If we stop at a path separator, there is
4750 		     * still something else left. This is handled below by
4751 		     * pushing every directory returned from expand_wildcards()
4752 		     * on the stack again for further search.
4753 		     */
4754 		    while (*rest_of_wildcards
4755 			    && !vim_ispathsep(*rest_of_wildcards))
4756 			if (len + 1 < MAXPATHL)
4757 			    file_path[len++] = *rest_of_wildcards++;
4758 			else
4759 			    goto fail;
4760 
4761 		    file_path[len] = NUL;
4762 		    if (vim_ispathsep(*rest_of_wildcards))
4763 			rest_of_wildcards++;
4764 		}
4765 #endif
4766 
4767 		/*
4768 		 * Expand wildcards like "*" and "$VAR".
4769 		 * If the path is a URL don't try this.
4770 		 */
4771 		if (path_with_url(dirptrs[0]))
4772 		{
4773 		    stackp->ffs_filearray = (char_u **)
4774 					      alloc((unsigned)sizeof(char *));
4775 		    if (stackp->ffs_filearray != NULL
4776 			    && (stackp->ffs_filearray[0]
4777 				= vim_strsave(dirptrs[0])) != NULL)
4778 			stackp->ffs_filearray_size = 1;
4779 		    else
4780 			stackp->ffs_filearray_size = 0;
4781 		}
4782 		else
4783 		    /* Add EW_NOTWILD because the expanded path may contain
4784 		     * wildcard characters that are to be taken literally.
4785 		     * This is a bit of a hack. */
4786 		    expand_wildcards((dirptrs[1] == NULL) ? 1 : 2, dirptrs,
4787 			    &stackp->ffs_filearray_size,
4788 			    &stackp->ffs_filearray,
4789 			    EW_DIR|EW_ADDSLASH|EW_SILENT|EW_NOTWILD);
4790 
4791 		stackp->ffs_filearray_cur = 0;
4792 		stackp->ffs_stage = 0;
4793 	    }
4794 #ifdef FEAT_PATH_EXTRA
4795 	    else
4796 		rest_of_wildcards = &stackp->ffs_wc_path[
4797 						 STRLEN(stackp->ffs_wc_path)];
4798 #endif
4799 
4800 	    if (stackp->ffs_stage == 0)
4801 	    {
4802 		/* this is the first time we work on this directory */
4803 #ifdef FEAT_PATH_EXTRA
4804 		if (*rest_of_wildcards == NUL)
4805 #endif
4806 		{
4807 		    /*
4808 		     * We don't have further wildcards to expand, so we have to
4809 		     * check for the final file now.
4810 		     */
4811 		    for (i = stackp->ffs_filearray_cur;
4812 					  i < stackp->ffs_filearray_size; ++i)
4813 		    {
4814 			if (!path_with_url(stackp->ffs_filearray[i])
4815 				      && !mch_isdir(stackp->ffs_filearray[i]))
4816 			    continue;   /* not a directory */
4817 
4818 			/* prepare the filename to be checked for existence
4819 			 * below */
4820 			if (STRLEN(stackp->ffs_filearray[i]) + 1
4821 				+ STRLEN(search_ctx->ffsc_file_to_search) < MAXPATHL)
4822 			{
4823 			    STRCPY(file_path, stackp->ffs_filearray[i]);
4824 			    add_pathsep(file_path);
4825 			    STRCAT(file_path, search_ctx->ffsc_file_to_search);
4826 			}
4827 			else
4828 			    goto fail;
4829 
4830 			/*
4831 			 * Try without extra suffix and then with suffixes
4832 			 * from 'suffixesadd'.
4833 			 */
4834 #ifdef FEAT_SEARCHPATH
4835 			len = (int)STRLEN(file_path);
4836 			if (search_ctx->ffsc_tagfile)
4837 			    suf = (char_u *)"";
4838 			else
4839 			    suf = curbuf->b_p_sua;
4840 			for (;;)
4841 #endif
4842 			{
4843 			    /* if file exists and we didn't already find it */
4844 			    if ((path_with_url(file_path)
4845 				  || (mch_getperm(file_path) >= 0
4846 				      && (search_ctx->ffsc_find_what
4847 							      == FINDFILE_BOTH
4848 					  || ((search_ctx->ffsc_find_what
4849 							      == FINDFILE_DIR)
4850 						   == mch_isdir(file_path)))))
4851 #ifndef FF_VERBOSE
4852 				    && (ff_check_visited(
4853 					    &search_ctx->ffsc_visited_list->ffvl_visited_list,
4854 					    file_path
4855 #ifdef FEAT_PATH_EXTRA
4856 					    , (char_u *)""
4857 #endif
4858 					    ) == OK)
4859 #endif
4860 			       )
4861 			    {
4862 #ifdef FF_VERBOSE
4863 				if (ff_check_visited(
4864 					    &search_ctx->ffsc_visited_list->ffvl_visited_list,
4865 					    file_path
4866 #ifdef FEAT_PATH_EXTRA
4867 					    , (char_u *)""
4868 #endif
4869 						    ) == FAIL)
4870 				{
4871 				    if (p_verbose >= 5)
4872 				    {
4873 					verbose_enter_scroll();
4874 					smsg((char_u *)"Already: %s",
4875 								   file_path);
4876 					/* don't overwrite this either */
4877 					msg_puts((char_u *)"\n");
4878 					verbose_leave_scroll();
4879 				    }
4880 				    continue;
4881 				}
4882 #endif
4883 
4884 				/* push dir to examine rest of subdirs later */
4885 				stackp->ffs_filearray_cur = i + 1;
4886 				ff_push(search_ctx, stackp);
4887 
4888 				if (!path_with_url(file_path))
4889 				    simplify_filename(file_path);
4890 				if (mch_dirname(ff_expand_buffer, MAXPATHL)
4891 									== OK)
4892 				{
4893 				    p = shorten_fname(file_path,
4894 							    ff_expand_buffer);
4895 				    if (p != NULL)
4896 					STRMOVE(file_path, p);
4897 				}
4898 #ifdef FF_VERBOSE
4899 				if (p_verbose >= 5)
4900 				{
4901 				    verbose_enter_scroll();
4902 				    smsg((char_u *)"HIT: %s", file_path);
4903 				    /* don't overwrite this either */
4904 				    msg_puts((char_u *)"\n");
4905 				    verbose_leave_scroll();
4906 				}
4907 #endif
4908 				return file_path;
4909 			    }
4910 
4911 #ifdef FEAT_SEARCHPATH
4912 			    /* Not found or found already, try next suffix. */
4913 			    if (*suf == NUL)
4914 				break;
4915 			    copy_option_part(&suf, file_path + len,
4916 							 MAXPATHL - len, ",");
4917 #endif
4918 			}
4919 		    }
4920 		}
4921 #ifdef FEAT_PATH_EXTRA
4922 		else
4923 		{
4924 		    /*
4925 		     * still wildcards left, push the directories for further
4926 		     * search
4927 		     */
4928 		    for (i = stackp->ffs_filearray_cur;
4929 					  i < stackp->ffs_filearray_size; ++i)
4930 		    {
4931 			if (!mch_isdir(stackp->ffs_filearray[i]))
4932 			    continue;	/* not a directory */
4933 
4934 			ff_push(search_ctx,
4935 				ff_create_stack_element(
4936 						     stackp->ffs_filearray[i],
4937 						     rest_of_wildcards,
4938 						     stackp->ffs_level - 1, 0));
4939 		    }
4940 		}
4941 #endif
4942 		stackp->ffs_filearray_cur = 0;
4943 		stackp->ffs_stage = 1;
4944 	    }
4945 
4946 #ifdef FEAT_PATH_EXTRA
4947 	    /*
4948 	     * if wildcards contains '**' we have to descent till we reach the
4949 	     * leaves of the directory tree.
4950 	     */
4951 	    if (STRNCMP(stackp->ffs_wc_path, "**", 2) == 0)
4952 	    {
4953 		for (i = stackp->ffs_filearray_cur;
4954 					  i < stackp->ffs_filearray_size; ++i)
4955 		{
4956 		    if (fnamecmp(stackp->ffs_filearray[i],
4957 						   stackp->ffs_fix_path) == 0)
4958 			continue; /* don't repush same directory */
4959 		    if (!mch_isdir(stackp->ffs_filearray[i]))
4960 			continue;   /* not a directory */
4961 		    ff_push(search_ctx,
4962 			    ff_create_stack_element(stackp->ffs_filearray[i],
4963 				stackp->ffs_wc_path, stackp->ffs_level - 1, 1));
4964 		}
4965 	    }
4966 #endif
4967 
4968 	    /* we are done with the current directory */
4969 	    ff_free_stack_element(stackp);
4970 
4971 	}
4972 
4973 #ifdef FEAT_PATH_EXTRA
4974 	/* If we reached this, we didn't find anything downwards.
4975 	 * Let's check if we should do an upward search.
4976 	 */
4977 	if (search_ctx->ffsc_start_dir
4978 		&& search_ctx->ffsc_stopdirs_v != NULL && !got_int)
4979 	{
4980 	    ff_stack_T  *sptr;
4981 
4982 	    /* is the last starting directory in the stop list? */
4983 	    if (ff_path_in_stoplist(search_ctx->ffsc_start_dir,
4984 		       (int)(path_end - search_ctx->ffsc_start_dir),
4985 		       search_ctx->ffsc_stopdirs_v) == TRUE)
4986 		break;
4987 
4988 	    /* cut of last dir */
4989 	    while (path_end > search_ctx->ffsc_start_dir
4990 						  && vim_ispathsep(*path_end))
4991 		path_end--;
4992 	    while (path_end > search_ctx->ffsc_start_dir
4993 					      && !vim_ispathsep(path_end[-1]))
4994 		path_end--;
4995 	    *path_end = 0;
4996 	    path_end--;
4997 
4998 	    if (*search_ctx->ffsc_start_dir == 0)
4999 		break;
5000 
5001 	    if (STRLEN(search_ctx->ffsc_start_dir) + 1
5002 		    + STRLEN(search_ctx->ffsc_fix_path) < MAXPATHL)
5003 	    {
5004 		STRCPY(file_path, search_ctx->ffsc_start_dir);
5005 		add_pathsep(file_path);
5006 		STRCAT(file_path, search_ctx->ffsc_fix_path);
5007 	    }
5008 	    else
5009 		goto fail;
5010 
5011 	    /* create a new stack entry */
5012 	    sptr = ff_create_stack_element(file_path,
5013 		    search_ctx->ffsc_wc_path, search_ctx->ffsc_level, 0);
5014 	    if (sptr == NULL)
5015 		break;
5016 	    ff_push(search_ctx, sptr);
5017 	}
5018 	else
5019 	    break;
5020     }
5021 #endif
5022 
5023 fail:
5024     vim_free(file_path);
5025     return NULL;
5026 }
5027 
5028 /*
5029  * Free the list of lists of visited files and directories
5030  * Can handle it if the passed search_context is NULL;
5031  */
5032     void
5033 vim_findfile_free_visited(void *search_ctx_arg)
5034 {
5035     ff_search_ctx_T *search_ctx;
5036 
5037     if (search_ctx_arg == NULL)
5038 	return;
5039 
5040     search_ctx = (ff_search_ctx_T *)search_ctx_arg;
5041     vim_findfile_free_visited_list(&search_ctx->ffsc_visited_lists_list);
5042     vim_findfile_free_visited_list(&search_ctx->ffsc_dir_visited_lists_list);
5043 }
5044 
5045     static void
5046 vim_findfile_free_visited_list(ff_visited_list_hdr_T **list_headp)
5047 {
5048     ff_visited_list_hdr_T *vp;
5049 
5050     while (*list_headp != NULL)
5051     {
5052 	vp = (*list_headp)->ffvl_next;
5053 	ff_free_visited_list((*list_headp)->ffvl_visited_list);
5054 
5055 	vim_free((*list_headp)->ffvl_filename);
5056 	vim_free(*list_headp);
5057 	*list_headp = vp;
5058     }
5059     *list_headp = NULL;
5060 }
5061 
5062     static void
5063 ff_free_visited_list(ff_visited_T *vl)
5064 {
5065     ff_visited_T *vp;
5066 
5067     while (vl != NULL)
5068     {
5069 	vp = vl->ffv_next;
5070 #ifdef FEAT_PATH_EXTRA
5071 	vim_free(vl->ffv_wc_path);
5072 #endif
5073 	vim_free(vl);
5074 	vl = vp;
5075     }
5076     vl = NULL;
5077 }
5078 
5079 /*
5080  * Returns the already visited list for the given filename. If none is found it
5081  * allocates a new one.
5082  */
5083     static ff_visited_list_hdr_T*
5084 ff_get_visited_list(
5085     char_u			*filename,
5086     ff_visited_list_hdr_T	**list_headp)
5087 {
5088     ff_visited_list_hdr_T  *retptr = NULL;
5089 
5090     /* check if a visited list for the given filename exists */
5091     if (*list_headp != NULL)
5092     {
5093 	retptr = *list_headp;
5094 	while (retptr != NULL)
5095 	{
5096 	    if (fnamecmp(filename, retptr->ffvl_filename) == 0)
5097 	    {
5098 #ifdef FF_VERBOSE
5099 		if (p_verbose >= 5)
5100 		{
5101 		    verbose_enter_scroll();
5102 		    smsg((char_u *)"ff_get_visited_list: FOUND list for %s",
5103 								    filename);
5104 		    /* don't overwrite this either */
5105 		    msg_puts((char_u *)"\n");
5106 		    verbose_leave_scroll();
5107 		}
5108 #endif
5109 		return retptr;
5110 	    }
5111 	    retptr = retptr->ffvl_next;
5112 	}
5113     }
5114 
5115 #ifdef FF_VERBOSE
5116     if (p_verbose >= 5)
5117     {
5118 	verbose_enter_scroll();
5119 	smsg((char_u *)"ff_get_visited_list: new list for %s", filename);
5120 	/* don't overwrite this either */
5121 	msg_puts((char_u *)"\n");
5122 	verbose_leave_scroll();
5123     }
5124 #endif
5125 
5126     /*
5127      * if we reach this we didn't find a list and we have to allocate new list
5128      */
5129     retptr = (ff_visited_list_hdr_T*)alloc((unsigned)sizeof(*retptr));
5130     if (retptr == NULL)
5131 	return NULL;
5132 
5133     retptr->ffvl_visited_list = NULL;
5134     retptr->ffvl_filename = vim_strsave(filename);
5135     if (retptr->ffvl_filename == NULL)
5136     {
5137 	vim_free(retptr);
5138 	return NULL;
5139     }
5140     retptr->ffvl_next = *list_headp;
5141     *list_headp = retptr;
5142 
5143     return retptr;
5144 }
5145 
5146 #ifdef FEAT_PATH_EXTRA
5147 /*
5148  * check if two wildcard paths are equal. Returns TRUE or FALSE.
5149  * They are equal if:
5150  *  - both paths are NULL
5151  *  - they have the same length
5152  *  - char by char comparison is OK
5153  *  - the only differences are in the counters behind a '**', so
5154  *    '**\20' is equal to '**\24'
5155  */
5156     static int
5157 ff_wc_equal(char_u *s1, char_u *s2)
5158 {
5159     int		i, j;
5160     int		c1 = NUL;
5161     int		c2 = NUL;
5162     int		prev1 = NUL;
5163     int		prev2 = NUL;
5164 
5165     if (s1 == s2)
5166 	return TRUE;
5167 
5168     if (s1 == NULL || s2 == NULL)
5169 	return FALSE;
5170 
5171     for (i = 0, j = 0; s1[i] != NUL && s2[j] != NUL;)
5172     {
5173 	c1 = PTR2CHAR(s1 + i);
5174 	c2 = PTR2CHAR(s2 + j);
5175 
5176 	if ((p_fic ? MB_TOLOWER(c1) != MB_TOLOWER(c2) : c1 != c2)
5177 		&& (prev1 != '*' || prev2 != '*'))
5178 	    return FALSE;
5179 	prev2 = prev1;
5180 	prev1 = c1;
5181 
5182 	i += MB_PTR2LEN(s1 + i);
5183 	j += MB_PTR2LEN(s2 + j);
5184     }
5185     return s1[i] == s2[j];
5186 }
5187 #endif
5188 
5189 /*
5190  * maintains the list of already visited files and dirs
5191  * returns FAIL if the given file/dir is already in the list
5192  * returns OK if it is newly added
5193  *
5194  * TODO: What to do on memory allocation problems?
5195  *	 -> return TRUE - Better the file is found several times instead of
5196  *	    never.
5197  */
5198     static int
5199 ff_check_visited(
5200     ff_visited_T	**visited_list,
5201     char_u		*fname
5202 #ifdef FEAT_PATH_EXTRA
5203     , char_u		*wc_path
5204 #endif
5205     )
5206 {
5207     ff_visited_T	*vp;
5208 #ifdef UNIX
5209     stat_T		st;
5210     int			url = FALSE;
5211 #endif
5212 
5213     /* For an URL we only compare the name, otherwise we compare the
5214      * device/inode (unix) or the full path name (not Unix). */
5215     if (path_with_url(fname))
5216     {
5217 	vim_strncpy(ff_expand_buffer, fname, MAXPATHL - 1);
5218 #ifdef UNIX
5219 	url = TRUE;
5220 #endif
5221     }
5222     else
5223     {
5224 	ff_expand_buffer[0] = NUL;
5225 #ifdef UNIX
5226 	if (mch_stat((char *)fname, &st) < 0)
5227 #else
5228 	if (vim_FullName(fname, ff_expand_buffer, MAXPATHL, TRUE) == FAIL)
5229 #endif
5230 	    return FAIL;
5231     }
5232 
5233     /* check against list of already visited files */
5234     for (vp = *visited_list; vp != NULL; vp = vp->ffv_next)
5235     {
5236 	if (
5237 #ifdef UNIX
5238 		!url ? (vp->ffv_dev_valid && vp->ffv_dev == st.st_dev
5239 						  && vp->ffv_ino == st.st_ino)
5240 		     :
5241 #endif
5242 		fnamecmp(vp->ffv_fname, ff_expand_buffer) == 0
5243 	   )
5244 	{
5245 #ifdef FEAT_PATH_EXTRA
5246 	    /* are the wildcard parts equal */
5247 	    if (ff_wc_equal(vp->ffv_wc_path, wc_path) == TRUE)
5248 #endif
5249 		/* already visited */
5250 		return FAIL;
5251 	}
5252     }
5253 
5254     /*
5255      * New file/dir.  Add it to the list of visited files/dirs.
5256      */
5257     vp = (ff_visited_T *)alloc((unsigned)(sizeof(ff_visited_T)
5258 						 + STRLEN(ff_expand_buffer)));
5259 
5260     if (vp != NULL)
5261     {
5262 #ifdef UNIX
5263 	if (!url)
5264 	{
5265 	    vp->ffv_dev_valid = TRUE;
5266 	    vp->ffv_ino = st.st_ino;
5267 	    vp->ffv_dev = st.st_dev;
5268 	    vp->ffv_fname[0] = NUL;
5269 	}
5270 	else
5271 	{
5272 	    vp->ffv_dev_valid = FALSE;
5273 #endif
5274 	    STRCPY(vp->ffv_fname, ff_expand_buffer);
5275 #ifdef UNIX
5276 	}
5277 #endif
5278 #ifdef FEAT_PATH_EXTRA
5279 	if (wc_path != NULL)
5280 	    vp->ffv_wc_path = vim_strsave(wc_path);
5281 	else
5282 	    vp->ffv_wc_path = NULL;
5283 #endif
5284 
5285 	vp->ffv_next = *visited_list;
5286 	*visited_list = vp;
5287     }
5288 
5289     return OK;
5290 }
5291 
5292 /*
5293  * create stack element from given path pieces
5294  */
5295     static ff_stack_T *
5296 ff_create_stack_element(
5297     char_u	*fix_part,
5298 #ifdef FEAT_PATH_EXTRA
5299     char_u	*wc_part,
5300 #endif
5301     int		level,
5302     int		star_star_empty)
5303 {
5304     ff_stack_T	*new;
5305 
5306     new = (ff_stack_T *)alloc((unsigned)sizeof(ff_stack_T));
5307     if (new == NULL)
5308 	return NULL;
5309 
5310     new->ffs_prev	   = NULL;
5311     new->ffs_filearray	   = NULL;
5312     new->ffs_filearray_size = 0;
5313     new->ffs_filearray_cur  = 0;
5314     new->ffs_stage	   = 0;
5315     new->ffs_level	   = level;
5316     new->ffs_star_star_empty = star_star_empty;
5317 
5318     /* the following saves NULL pointer checks in vim_findfile */
5319     if (fix_part == NULL)
5320 	fix_part = (char_u *)"";
5321     new->ffs_fix_path = vim_strsave(fix_part);
5322 
5323 #ifdef FEAT_PATH_EXTRA
5324     if (wc_part == NULL)
5325 	wc_part  = (char_u *)"";
5326     new->ffs_wc_path = vim_strsave(wc_part);
5327 #endif
5328 
5329     if (new->ffs_fix_path == NULL
5330 #ifdef FEAT_PATH_EXTRA
5331 	    || new->ffs_wc_path == NULL
5332 #endif
5333 	    )
5334     {
5335 	ff_free_stack_element(new);
5336 	new = NULL;
5337     }
5338 
5339     return new;
5340 }
5341 
5342 /*
5343  * Push a dir on the directory stack.
5344  */
5345     static void
5346 ff_push(ff_search_ctx_T *search_ctx, ff_stack_T *stack_ptr)
5347 {
5348     /* check for NULL pointer, not to return an error to the user, but
5349      * to prevent a crash */
5350     if (stack_ptr != NULL)
5351     {
5352 	stack_ptr->ffs_prev = search_ctx->ffsc_stack_ptr;
5353 	search_ctx->ffsc_stack_ptr = stack_ptr;
5354     }
5355 }
5356 
5357 /*
5358  * Pop a dir from the directory stack.
5359  * Returns NULL if stack is empty.
5360  */
5361     static ff_stack_T *
5362 ff_pop(ff_search_ctx_T *search_ctx)
5363 {
5364     ff_stack_T  *sptr;
5365 
5366     sptr = search_ctx->ffsc_stack_ptr;
5367     if (search_ctx->ffsc_stack_ptr != NULL)
5368 	search_ctx->ffsc_stack_ptr = search_ctx->ffsc_stack_ptr->ffs_prev;
5369 
5370     return sptr;
5371 }
5372 
5373 /*
5374  * free the given stack element
5375  */
5376     static void
5377 ff_free_stack_element(ff_stack_T *stack_ptr)
5378 {
5379     /* vim_free handles possible NULL pointers */
5380     vim_free(stack_ptr->ffs_fix_path);
5381 #ifdef FEAT_PATH_EXTRA
5382     vim_free(stack_ptr->ffs_wc_path);
5383 #endif
5384 
5385     if (stack_ptr->ffs_filearray != NULL)
5386 	FreeWild(stack_ptr->ffs_filearray_size, stack_ptr->ffs_filearray);
5387 
5388     vim_free(stack_ptr);
5389 }
5390 
5391 /*
5392  * Clear the search context, but NOT the visited list.
5393  */
5394     static void
5395 ff_clear(ff_search_ctx_T *search_ctx)
5396 {
5397     ff_stack_T   *sptr;
5398 
5399     /* clear up stack */
5400     while ((sptr = ff_pop(search_ctx)) != NULL)
5401 	ff_free_stack_element(sptr);
5402 
5403     vim_free(search_ctx->ffsc_file_to_search);
5404     vim_free(search_ctx->ffsc_start_dir);
5405     vim_free(search_ctx->ffsc_fix_path);
5406 #ifdef FEAT_PATH_EXTRA
5407     vim_free(search_ctx->ffsc_wc_path);
5408 #endif
5409 
5410 #ifdef FEAT_PATH_EXTRA
5411     if (search_ctx->ffsc_stopdirs_v != NULL)
5412     {
5413 	int  i = 0;
5414 
5415 	while (search_ctx->ffsc_stopdirs_v[i] != NULL)
5416 	{
5417 	    vim_free(search_ctx->ffsc_stopdirs_v[i]);
5418 	    i++;
5419 	}
5420 	vim_free(search_ctx->ffsc_stopdirs_v);
5421     }
5422     search_ctx->ffsc_stopdirs_v = NULL;
5423 #endif
5424 
5425     /* reset everything */
5426     search_ctx->ffsc_file_to_search = NULL;
5427     search_ctx->ffsc_start_dir = NULL;
5428     search_ctx->ffsc_fix_path = NULL;
5429 #ifdef FEAT_PATH_EXTRA
5430     search_ctx->ffsc_wc_path = NULL;
5431     search_ctx->ffsc_level = 0;
5432 #endif
5433 }
5434 
5435 #ifdef FEAT_PATH_EXTRA
5436 /*
5437  * check if the given path is in the stopdirs
5438  * returns TRUE if yes else FALSE
5439  */
5440     static int
5441 ff_path_in_stoplist(char_u *path, int path_len, char_u **stopdirs_v)
5442 {
5443     int		i = 0;
5444 
5445     /* eat up trailing path separators, except the first */
5446     while (path_len > 1 && vim_ispathsep(path[path_len - 1]))
5447 	path_len--;
5448 
5449     /* if no path consider it as match */
5450     if (path_len == 0)
5451 	return TRUE;
5452 
5453     for (i = 0; stopdirs_v[i] != NULL; i++)
5454     {
5455 	if ((int)STRLEN(stopdirs_v[i]) > path_len)
5456 	{
5457 	    /* match for parent directory. So '/home' also matches
5458 	     * '/home/rks'. Check for PATHSEP in stopdirs_v[i], else
5459 	     * '/home/r' would also match '/home/rks'
5460 	     */
5461 	    if (fnamencmp(stopdirs_v[i], path, path_len) == 0
5462 		    && vim_ispathsep(stopdirs_v[i][path_len]))
5463 		return TRUE;
5464 	}
5465 	else
5466 	{
5467 	    if (fnamecmp(stopdirs_v[i], path) == 0)
5468 		return TRUE;
5469 	}
5470     }
5471     return FALSE;
5472 }
5473 #endif
5474 
5475 #if defined(FEAT_SEARCHPATH) || defined(PROTO)
5476 /*
5477  * Find the file name "ptr[len]" in the path.  Also finds directory names.
5478  *
5479  * On the first call set the parameter 'first' to TRUE to initialize
5480  * the search.  For repeating calls to FALSE.
5481  *
5482  * Repeating calls will return other files called 'ptr[len]' from the path.
5483  *
5484  * Only on the first call 'ptr' and 'len' are used.  For repeating calls they
5485  * don't need valid values.
5486  *
5487  * If nothing found on the first call the option FNAME_MESS will issue the
5488  * message:
5489  *	    'Can't find file "<file>" in path'
5490  * On repeating calls:
5491  *	    'No more file "<file>" found in path'
5492  *
5493  * options:
5494  * FNAME_MESS	    give error message when not found
5495  *
5496  * Uses NameBuff[]!
5497  *
5498  * Returns an allocated string for the file name.  NULL for error.
5499  *
5500  */
5501     char_u *
5502 find_file_in_path(
5503     char_u	*ptr,		/* file name */
5504     int		len,		/* length of file name */
5505     int		options,
5506     int		first,		/* use count'th matching file name */
5507     char_u	*rel_fname)	/* file name searching relative to */
5508 {
5509     return find_file_in_path_option(ptr, len, options, first,
5510 	    *curbuf->b_p_path == NUL ? p_path : curbuf->b_p_path,
5511 	    FINDFILE_BOTH, rel_fname, curbuf->b_p_sua);
5512 }
5513 
5514 static char_u	*ff_file_to_find = NULL;
5515 static void	*fdip_search_ctx = NULL;
5516 
5517 #if defined(EXITFREE)
5518     static void
5519 free_findfile(void)
5520 {
5521     vim_free(ff_file_to_find);
5522     vim_findfile_cleanup(fdip_search_ctx);
5523 }
5524 #endif
5525 
5526 /*
5527  * Find the directory name "ptr[len]" in the path.
5528  *
5529  * options:
5530  * FNAME_MESS	    give error message when not found
5531  * FNAME_UNESC	    unescape backslashes.
5532  *
5533  * Uses NameBuff[]!
5534  *
5535  * Returns an allocated string for the file name.  NULL for error.
5536  */
5537     char_u *
5538 find_directory_in_path(
5539     char_u	*ptr,		/* file name */
5540     int		len,		/* length of file name */
5541     int		options,
5542     char_u	*rel_fname)	/* file name searching relative to */
5543 {
5544     return find_file_in_path_option(ptr, len, options, TRUE, p_cdpath,
5545 				       FINDFILE_DIR, rel_fname, (char_u *)"");
5546 }
5547 
5548     char_u *
5549 find_file_in_path_option(
5550     char_u	*ptr,		/* file name */
5551     int		len,		/* length of file name */
5552     int		options,
5553     int		first,		/* use count'th matching file name */
5554     char_u	*path_option,	/* p_path or p_cdpath */
5555     int		find_what,	/* FINDFILE_FILE, _DIR or _BOTH */
5556     char_u	*rel_fname,	/* file name we are looking relative to. */
5557     char_u	*suffixes)	/* list of suffixes, 'suffixesadd' option */
5558 {
5559     static char_u	*dir;
5560     static int		did_findfile_init = FALSE;
5561     char_u		save_char;
5562     char_u		*file_name = NULL;
5563     char_u		*buf = NULL;
5564     int			rel_to_curdir;
5565 #ifdef AMIGA
5566     struct Process	*proc = (struct Process *)FindTask(0L);
5567     APTR		save_winptr = proc->pr_WindowPtr;
5568 
5569     /* Avoid a requester here for a volume that doesn't exist. */
5570     proc->pr_WindowPtr = (APTR)-1L;
5571 #endif
5572 
5573     if (first == TRUE)
5574     {
5575 	/* copy file name into NameBuff, expanding environment variables */
5576 	save_char = ptr[len];
5577 	ptr[len] = NUL;
5578 	expand_env_esc(ptr, NameBuff, MAXPATHL, FALSE, TRUE, NULL);
5579 	ptr[len] = save_char;
5580 
5581 	vim_free(ff_file_to_find);
5582 	ff_file_to_find = vim_strsave(NameBuff);
5583 	if (ff_file_to_find == NULL)	/* out of memory */
5584 	{
5585 	    file_name = NULL;
5586 	    goto theend;
5587 	}
5588 	if (options & FNAME_UNESC)
5589 	{
5590 	    /* Change all "\ " to " ". */
5591 	    for (ptr = ff_file_to_find; *ptr != NUL; ++ptr)
5592 		if (ptr[0] == '\\' && ptr[1] == ' ')
5593 		    mch_memmove(ptr, ptr + 1, STRLEN(ptr));
5594 	}
5595     }
5596 
5597     rel_to_curdir = (ff_file_to_find[0] == '.'
5598 		    && (ff_file_to_find[1] == NUL
5599 			|| vim_ispathsep(ff_file_to_find[1])
5600 			|| (ff_file_to_find[1] == '.'
5601 			    && (ff_file_to_find[2] == NUL
5602 				|| vim_ispathsep(ff_file_to_find[2])))));
5603     if (vim_isAbsName(ff_file_to_find)
5604 	    /* "..", "../path", "." and "./path": don't use the path_option */
5605 	    || rel_to_curdir
5606 #if defined(MSWIN)
5607 	    /* handle "\tmp" as absolute path */
5608 	    || vim_ispathsep(ff_file_to_find[0])
5609 	    /* handle "c:name" as absolute path */
5610 	    || (ff_file_to_find[0] != NUL && ff_file_to_find[1] == ':')
5611 #endif
5612 #ifdef AMIGA
5613 	    /* handle ":tmp" as absolute path */
5614 	    || ff_file_to_find[0] == ':'
5615 #endif
5616        )
5617     {
5618 	/*
5619 	 * Absolute path, no need to use "path_option".
5620 	 * If this is not a first call, return NULL.  We already returned a
5621 	 * filename on the first call.
5622 	 */
5623 	if (first == TRUE)
5624 	{
5625 	    int		l;
5626 	    int		run;
5627 
5628 	    if (path_with_url(ff_file_to_find))
5629 	    {
5630 		file_name = vim_strsave(ff_file_to_find);
5631 		goto theend;
5632 	    }
5633 
5634 	    /* When FNAME_REL flag given first use the directory of the file.
5635 	     * Otherwise or when this fails use the current directory. */
5636 	    for (run = 1; run <= 2; ++run)
5637 	    {
5638 		l = (int)STRLEN(ff_file_to_find);
5639 		if (run == 1
5640 			&& rel_to_curdir
5641 			&& (options & FNAME_REL)
5642 			&& rel_fname != NULL
5643 			&& STRLEN(rel_fname) + l < MAXPATHL)
5644 		{
5645 		    STRCPY(NameBuff, rel_fname);
5646 		    STRCPY(gettail(NameBuff), ff_file_to_find);
5647 		    l = (int)STRLEN(NameBuff);
5648 		}
5649 		else
5650 		{
5651 		    STRCPY(NameBuff, ff_file_to_find);
5652 		    run = 2;
5653 		}
5654 
5655 		/* When the file doesn't exist, try adding parts of
5656 		 * 'suffixesadd'. */
5657 		buf = suffixes;
5658 		for (;;)
5659 		{
5660 		    if (mch_getperm(NameBuff) >= 0
5661 			     && (find_what == FINDFILE_BOTH
5662 				 || ((find_what == FINDFILE_DIR)
5663 						    == mch_isdir(NameBuff))))
5664 		    {
5665 			file_name = vim_strsave(NameBuff);
5666 			goto theend;
5667 		    }
5668 		    if (*buf == NUL)
5669 			break;
5670 		    copy_option_part(&buf, NameBuff + l, MAXPATHL - l, ",");
5671 		}
5672 	    }
5673 	}
5674     }
5675     else
5676     {
5677 	/*
5678 	 * Loop over all paths in the 'path' or 'cdpath' option.
5679 	 * When "first" is set, first setup to the start of the option.
5680 	 * Otherwise continue to find the next match.
5681 	 */
5682 	if (first == TRUE)
5683 	{
5684 	    /* vim_findfile_free_visited can handle a possible NULL pointer */
5685 	    vim_findfile_free_visited(fdip_search_ctx);
5686 	    dir = path_option;
5687 	    did_findfile_init = FALSE;
5688 	}
5689 
5690 	for (;;)
5691 	{
5692 	    if (did_findfile_init)
5693 	    {
5694 		file_name = vim_findfile(fdip_search_ctx);
5695 		if (file_name != NULL)
5696 		    break;
5697 
5698 		did_findfile_init = FALSE;
5699 	    }
5700 	    else
5701 	    {
5702 		char_u  *r_ptr;
5703 
5704 		if (dir == NULL || *dir == NUL)
5705 		{
5706 		    /* We searched all paths of the option, now we can
5707 		     * free the search context. */
5708 		    vim_findfile_cleanup(fdip_search_ctx);
5709 		    fdip_search_ctx = NULL;
5710 		    break;
5711 		}
5712 
5713 		if ((buf = alloc((int)(MAXPATHL))) == NULL)
5714 		    break;
5715 
5716 		/* copy next path */
5717 		buf[0] = 0;
5718 		copy_option_part(&dir, buf, MAXPATHL, " ,");
5719 
5720 #ifdef FEAT_PATH_EXTRA
5721 		/* get the stopdir string */
5722 		r_ptr = vim_findfile_stopdir(buf);
5723 #else
5724 		r_ptr = NULL;
5725 #endif
5726 		fdip_search_ctx = vim_findfile_init(buf, ff_file_to_find,
5727 					    r_ptr, 100, FALSE, find_what,
5728 					   fdip_search_ctx, FALSE, rel_fname);
5729 		if (fdip_search_ctx != NULL)
5730 		    did_findfile_init = TRUE;
5731 		vim_free(buf);
5732 	    }
5733 	}
5734     }
5735     if (file_name == NULL && (options & FNAME_MESS))
5736     {
5737 	if (first == TRUE)
5738 	{
5739 	    if (find_what == FINDFILE_DIR)
5740 		EMSG2(_("E344: Can't find directory \"%s\" in cdpath"),
5741 			ff_file_to_find);
5742 	    else
5743 		EMSG2(_("E345: Can't find file \"%s\" in path"),
5744 			ff_file_to_find);
5745 	}
5746 	else
5747 	{
5748 	    if (find_what == FINDFILE_DIR)
5749 		EMSG2(_("E346: No more directory \"%s\" found in cdpath"),
5750 			ff_file_to_find);
5751 	    else
5752 		EMSG2(_("E347: No more file \"%s\" found in path"),
5753 			ff_file_to_find);
5754 	}
5755     }
5756 
5757 theend:
5758 #ifdef AMIGA
5759     proc->pr_WindowPtr = save_winptr;
5760 #endif
5761     return file_name;
5762 }
5763 
5764 #endif /* FEAT_SEARCHPATH */
5765 
5766 /*
5767  * Change directory to "new_dir".  If FEAT_SEARCHPATH is defined, search
5768  * 'cdpath' for relative directory names, otherwise just mch_chdir().
5769  */
5770     int
5771 vim_chdir(char_u *new_dir)
5772 {
5773 #ifndef FEAT_SEARCHPATH
5774     return mch_chdir((char *)new_dir);
5775 #else
5776     char_u	*dir_name;
5777     int		r;
5778 
5779     dir_name = find_directory_in_path(new_dir, (int)STRLEN(new_dir),
5780 						FNAME_MESS, curbuf->b_ffname);
5781     if (dir_name == NULL)
5782 	return -1;
5783     r = mch_chdir((char *)dir_name);
5784     vim_free(dir_name);
5785     return r;
5786 #endif
5787 }
5788 
5789 /*
5790  * Get user name from machine-specific function.
5791  * Returns the user name in "buf[len]".
5792  * Some systems are quite slow in obtaining the user name (Windows NT), thus
5793  * cache the result.
5794  * Returns OK or FAIL.
5795  */
5796     int
5797 get_user_name(char_u *buf, int len)
5798 {
5799     if (username == NULL)
5800     {
5801 	if (mch_get_user_name(buf, len) == FAIL)
5802 	    return FAIL;
5803 	username = vim_strsave(buf);
5804     }
5805     else
5806 	vim_strncpy(buf, username, len - 1);
5807     return OK;
5808 }
5809 
5810 #ifndef HAVE_QSORT
5811 /*
5812  * Our own qsort(), for systems that don't have it.
5813  * It's simple and slow.  From the K&R C book.
5814  */
5815     void
5816 qsort(
5817     void	*base,
5818     size_t	elm_count,
5819     size_t	elm_size,
5820     int (*cmp)(const void *, const void *))
5821 {
5822     char_u	*buf;
5823     char_u	*p1;
5824     char_u	*p2;
5825     int		i, j;
5826     int		gap;
5827 
5828     buf = alloc((unsigned)elm_size);
5829     if (buf == NULL)
5830 	return;
5831 
5832     for (gap = elm_count / 2; gap > 0; gap /= 2)
5833 	for (i = gap; i < elm_count; ++i)
5834 	    for (j = i - gap; j >= 0; j -= gap)
5835 	    {
5836 		/* Compare the elements. */
5837 		p1 = (char_u *)base + j * elm_size;
5838 		p2 = (char_u *)base + (j + gap) * elm_size;
5839 		if ((*cmp)((void *)p1, (void *)p2) <= 0)
5840 		    break;
5841 		/* Exchange the elements. */
5842 		mch_memmove(buf, p1, elm_size);
5843 		mch_memmove(p1, p2, elm_size);
5844 		mch_memmove(p2, buf, elm_size);
5845 	    }
5846 
5847     vim_free(buf);
5848 }
5849 #endif
5850 
5851 /*
5852  * Sort an array of strings.
5853  */
5854 static int
5855 #ifdef __BORLANDC__
5856 _RTLENTRYF
5857 #endif
5858 sort_compare(const void *s1, const void *s2);
5859 
5860     static int
5861 #ifdef __BORLANDC__
5862 _RTLENTRYF
5863 #endif
5864 sort_compare(const void *s1, const void *s2)
5865 {
5866     return STRCMP(*(char **)s1, *(char **)s2);
5867 }
5868 
5869     void
5870 sort_strings(
5871     char_u	**files,
5872     int		count)
5873 {
5874     qsort((void *)files, (size_t)count, sizeof(char_u *), sort_compare);
5875 }
5876 
5877 #if !defined(NO_EXPANDPATH) || defined(PROTO)
5878 /*
5879  * Compare path "p[]" to "q[]".
5880  * If "maxlen" >= 0 compare "p[maxlen]" to "q[maxlen]"
5881  * Return value like strcmp(p, q), but consider path separators.
5882  */
5883     int
5884 pathcmp(const char *p, const char *q, int maxlen)
5885 {
5886     int		i, j;
5887     int		c1, c2;
5888     const char	*s = NULL;
5889 
5890     for (i = 0, j = 0; maxlen < 0 || (i < maxlen && j < maxlen);)
5891     {
5892 	c1 = PTR2CHAR((char_u *)p + i);
5893 	c2 = PTR2CHAR((char_u *)q + j);
5894 
5895 	/* End of "p": check if "q" also ends or just has a slash. */
5896 	if (c1 == NUL)
5897 	{
5898 	    if (c2 == NUL)  /* full match */
5899 		return 0;
5900 	    s = q;
5901 	    i = j;
5902 	    break;
5903 	}
5904 
5905 	/* End of "q": check if "p" just has a slash. */
5906 	if (c2 == NUL)
5907 	{
5908 	    s = p;
5909 	    break;
5910 	}
5911 
5912 	if ((p_fic ? MB_TOUPPER(c1) != MB_TOUPPER(c2) : c1 != c2)
5913 #ifdef BACKSLASH_IN_FILENAME
5914 		/* consider '/' and '\\' to be equal */
5915 		&& !((c1 == '/' && c2 == '\\')
5916 		    || (c1 == '\\' && c2 == '/'))
5917 #endif
5918 		)
5919 	{
5920 	    if (vim_ispathsep(c1))
5921 		return -1;
5922 	    if (vim_ispathsep(c2))
5923 		return 1;
5924 	    return p_fic ? MB_TOUPPER(c1) - MB_TOUPPER(c2)
5925 		    : c1 - c2;  /* no match */
5926 	}
5927 
5928 	i += MB_PTR2LEN((char_u *)p + i);
5929 	j += MB_PTR2LEN((char_u *)q + j);
5930     }
5931     if (s == NULL)	/* "i" or "j" ran into "maxlen" */
5932 	return 0;
5933 
5934     c1 = PTR2CHAR((char_u *)s + i);
5935     c2 = PTR2CHAR((char_u *)s + i + MB_PTR2LEN((char_u *)s + i));
5936     /* ignore a trailing slash, but not "//" or ":/" */
5937     if (c2 == NUL
5938 	    && i > 0
5939 	    && !after_pathsep((char_u *)s, (char_u *)s + i)
5940 #ifdef BACKSLASH_IN_FILENAME
5941 	    && (c1 == '/' || c1 == '\\')
5942 #else
5943 	    && c1 == '/'
5944 #endif
5945        )
5946 	return 0;   /* match with trailing slash */
5947     if (s == q)
5948 	return -1;	    /* no match */
5949     return 1;
5950 }
5951 #endif
5952 
5953 /*
5954  * The putenv() implementation below comes from the "screen" program.
5955  * Included with permission from Juergen Weigert.
5956  * See pty.c for the copyright notice.
5957  */
5958 
5959 /*
5960  *  putenv  --	put value into environment
5961  *
5962  *  Usage:  i = putenv (string)
5963  *    int i;
5964  *    char  *string;
5965  *
5966  *  where string is of the form <name>=<value>.
5967  *  Putenv returns 0 normally, -1 on error (not enough core for malloc).
5968  *
5969  *  Putenv may need to add a new name into the environment, or to
5970  *  associate a value longer than the current value with a particular
5971  *  name.  So, to make life simpler, putenv() copies your entire
5972  *  environment into the heap (i.e. malloc()) from the stack
5973  *  (i.e. where it resides when your process is initiated) the first
5974  *  time you call it.
5975  *
5976  *  (history removed, not very interesting.  See the "screen" sources.)
5977  */
5978 
5979 #if !defined(HAVE_SETENV) && !defined(HAVE_PUTENV)
5980 
5981 #define EXTRASIZE 5		/* increment to add to env. size */
5982 
5983 static int  envsize = -1;	/* current size of environment */
5984 extern char **environ;		/* the global which is your env. */
5985 
5986 static int  findenv(char *name); /* look for a name in the env. */
5987 static int  newenv(void);	/* copy env. from stack to heap */
5988 static int  moreenv(void);	/* incr. size of env. */
5989 
5990     int
5991 putenv(const char *string)
5992 {
5993     int	    i;
5994     char    *p;
5995 
5996     if (envsize < 0)
5997     {				/* first time putenv called */
5998 	if (newenv() < 0)	/* copy env. to heap */
5999 	    return -1;
6000     }
6001 
6002     i = findenv((char *)string); /* look for name in environment */
6003 
6004     if (i < 0)
6005     {				/* name must be added */
6006 	for (i = 0; environ[i]; i++);
6007 	if (i >= (envsize - 1))
6008 	{			/* need new slot */
6009 	    if (moreenv() < 0)
6010 		return -1;
6011 	}
6012 	p = (char *)alloc((unsigned)(strlen(string) + 1));
6013 	if (p == NULL)		/* not enough core */
6014 	    return -1;
6015 	environ[i + 1] = 0;	/* new end of env. */
6016     }
6017     else
6018     {				/* name already in env. */
6019 	p = vim_realloc(environ[i], strlen(string) + 1);
6020 	if (p == NULL)
6021 	    return -1;
6022     }
6023     sprintf(p, "%s", string);	/* copy into env. */
6024     environ[i] = p;
6025 
6026     return 0;
6027 }
6028 
6029     static int
6030 findenv(char *name)
6031 {
6032     char    *namechar, *envchar;
6033     int	    i, found;
6034 
6035     found = 0;
6036     for (i = 0; environ[i] && !found; i++)
6037     {
6038 	envchar = environ[i];
6039 	namechar = name;
6040 	while (*namechar && *namechar != '=' && (*namechar == *envchar))
6041 	{
6042 	    namechar++;
6043 	    envchar++;
6044 	}
6045 	found = ((*namechar == '\0' || *namechar == '=') && *envchar == '=');
6046     }
6047     return found ? i - 1 : -1;
6048 }
6049 
6050     static int
6051 newenv(void)
6052 {
6053     char    **env, *elem;
6054     int	    i, esize;
6055 
6056     for (i = 0; environ[i]; i++)
6057 	;
6058 
6059     esize = i + EXTRASIZE + 1;
6060     env = (char **)alloc((unsigned)(esize * sizeof (elem)));
6061     if (env == NULL)
6062 	return -1;
6063 
6064     for (i = 0; environ[i]; i++)
6065     {
6066 	elem = (char *)alloc((unsigned)(strlen(environ[i]) + 1));
6067 	if (elem == NULL)
6068 	    return -1;
6069 	env[i] = elem;
6070 	strcpy(elem, environ[i]);
6071     }
6072 
6073     env[i] = 0;
6074     environ = env;
6075     envsize = esize;
6076     return 0;
6077 }
6078 
6079     static int
6080 moreenv(void)
6081 {
6082     int	    esize;
6083     char    **env;
6084 
6085     esize = envsize + EXTRASIZE;
6086     env = (char **)vim_realloc((char *)environ, esize * sizeof (*env));
6087     if (env == 0)
6088 	return -1;
6089     environ = env;
6090     envsize = esize;
6091     return 0;
6092 }
6093 
6094 # ifdef USE_VIMPTY_GETENV
6095 /*
6096  * Used for mch_getenv() for Mac.
6097  */
6098     char_u *
6099 vimpty_getenv(const char_u *string)
6100 {
6101     int i;
6102     char_u *p;
6103 
6104     if (envsize < 0)
6105 	return NULL;
6106 
6107     i = findenv((char *)string);
6108 
6109     if (i < 0)
6110 	return NULL;
6111 
6112     p = vim_strchr((char_u *)environ[i], '=');
6113     return (p + 1);
6114 }
6115 # endif
6116 
6117 #endif /* !defined(HAVE_SETENV) && !defined(HAVE_PUTENV) */
6118 
6119 #if defined(FEAT_EVAL) || defined(FEAT_SPELL) || defined(PROTO)
6120 /*
6121  * Return 0 for not writable, 1 for writable file, 2 for a dir which we have
6122  * rights to write into.
6123  */
6124     int
6125 filewritable(char_u *fname)
6126 {
6127     int		retval = 0;
6128 #if defined(UNIX) || defined(VMS)
6129     int		perm = 0;
6130 #endif
6131 
6132 #if defined(UNIX) || defined(VMS)
6133     perm = mch_getperm(fname);
6134 #endif
6135     if (
6136 # ifdef WIN3264
6137 	    mch_writable(fname) &&
6138 # else
6139 # if defined(UNIX) || defined(VMS)
6140 	    (perm & 0222) &&
6141 #  endif
6142 # endif
6143 	    mch_access((char *)fname, W_OK) == 0
6144        )
6145     {
6146 	++retval;
6147 	if (mch_isdir(fname))
6148 	    ++retval;
6149     }
6150     return retval;
6151 }
6152 #endif
6153 
6154 #if defined(FEAT_SPELL) || defined(FEAT_PERSISTENT_UNDO) || defined(PROTO)
6155 /*
6156  * Read 2 bytes from "fd" and turn them into an int, MSB first.
6157  */
6158     int
6159 get2c(FILE *fd)
6160 {
6161     int		n;
6162 
6163     n = getc(fd);
6164     n = (n << 8) + getc(fd);
6165     return n;
6166 }
6167 
6168 /*
6169  * Read 3 bytes from "fd" and turn them into an int, MSB first.
6170  */
6171     int
6172 get3c(FILE *fd)
6173 {
6174     int		n;
6175 
6176     n = getc(fd);
6177     n = (n << 8) + getc(fd);
6178     n = (n << 8) + getc(fd);
6179     return n;
6180 }
6181 
6182 /*
6183  * Read 4 bytes from "fd" and turn them into an int, MSB first.
6184  */
6185     int
6186 get4c(FILE *fd)
6187 {
6188     /* Use unsigned rather than int otherwise result is undefined
6189      * when left-shift sets the MSB. */
6190     unsigned	n;
6191 
6192     n = (unsigned)getc(fd);
6193     n = (n << 8) + (unsigned)getc(fd);
6194     n = (n << 8) + (unsigned)getc(fd);
6195     n = (n << 8) + (unsigned)getc(fd);
6196     return (int)n;
6197 }
6198 
6199 /*
6200  * Read 8 bytes from "fd" and turn them into a time_T, MSB first.
6201  */
6202     time_T
6203 get8ctime(FILE *fd)
6204 {
6205     time_T	n = 0;
6206     int		i;
6207 
6208     for (i = 0; i < 8; ++i)
6209 	n = (n << 8) + getc(fd);
6210     return n;
6211 }
6212 
6213 /*
6214  * Read a string of length "cnt" from "fd" into allocated memory.
6215  * Returns NULL when out of memory or unable to read that many bytes.
6216  */
6217     char_u *
6218 read_string(FILE *fd, int cnt)
6219 {
6220     char_u	*str;
6221     int		i;
6222     int		c;
6223 
6224     /* allocate memory */
6225     str = alloc((unsigned)cnt + 1);
6226     if (str != NULL)
6227     {
6228 	/* Read the string.  Quit when running into the EOF. */
6229 	for (i = 0; i < cnt; ++i)
6230 	{
6231 	    c = getc(fd);
6232 	    if (c == EOF)
6233 	    {
6234 		vim_free(str);
6235 		return NULL;
6236 	    }
6237 	    str[i] = c;
6238 	}
6239 	str[i] = NUL;
6240     }
6241     return str;
6242 }
6243 
6244 /*
6245  * Write a number to file "fd", MSB first, in "len" bytes.
6246  */
6247     int
6248 put_bytes(FILE *fd, long_u nr, int len)
6249 {
6250     int	    i;
6251 
6252     for (i = len - 1; i >= 0; --i)
6253 	if (putc((int)(nr >> (i * 8)), fd) == EOF)
6254 	    return FAIL;
6255     return OK;
6256 }
6257 
6258 #ifdef _MSC_VER
6259 # if (_MSC_VER <= 1200)
6260 /* This line is required for VC6 without the service pack.  Also see the
6261  * matching #pragma below. */
6262  #  pragma optimize("", off)
6263 # endif
6264 #endif
6265 
6266 /*
6267  * Write time_T to file "fd" in 8 bytes.
6268  * Returns FAIL when the write failed.
6269  */
6270     int
6271 put_time(FILE *fd, time_T the_time)
6272 {
6273     char_u	buf[8];
6274 
6275     time_to_bytes(the_time, buf);
6276     return fwrite(buf, (size_t)8, (size_t)1, fd) == 1 ? OK : FAIL;
6277 }
6278 
6279 /*
6280  * Write time_T to "buf[8]".
6281  */
6282     void
6283 time_to_bytes(time_T the_time, char_u *buf)
6284 {
6285     int		c;
6286     int		i;
6287     int		bi = 0;
6288     time_T	wtime = the_time;
6289 
6290     /* time_T can be up to 8 bytes in size, more than long_u, thus we
6291      * can't use put_bytes() here.
6292      * Another problem is that ">>" may do an arithmetic shift that keeps the
6293      * sign.  This happens for large values of wtime.  A cast to long_u may
6294      * truncate if time_T is 8 bytes.  So only use a cast when it is 4 bytes,
6295      * it's safe to assume that long_u is 4 bytes or more and when using 8
6296      * bytes the top bit won't be set. */
6297     for (i = 7; i >= 0; --i)
6298     {
6299 	if (i + 1 > (int)sizeof(time_T))
6300 	    /* ">>" doesn't work well when shifting more bits than avail */
6301 	    buf[bi++] = 0;
6302 	else
6303 	{
6304 #if defined(SIZEOF_TIME_T) && SIZEOF_TIME_T > 4
6305 	    c = (int)(wtime >> (i * 8));
6306 #else
6307 	    c = (int)((long_u)wtime >> (i * 8));
6308 #endif
6309 	    buf[bi++] = c;
6310 	}
6311     }
6312 }
6313 
6314 #ifdef _MSC_VER
6315 # if (_MSC_VER <= 1200)
6316  #  pragma optimize("", on)
6317 # endif
6318 #endif
6319 
6320 #endif
6321 
6322 #if (defined(FEAT_MBYTE) && defined(FEAT_QUICKFIX)) \
6323 	|| defined(FEAT_SPELL) || defined(PROTO)
6324 /*
6325  * Return TRUE if string "s" contains a non-ASCII character (128 or higher).
6326  * When "s" is NULL FALSE is returned.
6327  */
6328     int
6329 has_non_ascii(char_u *s)
6330 {
6331     char_u	*p;
6332 
6333     if (s != NULL)
6334 	for (p = s; *p != NUL; ++p)
6335 	    if (*p >= 128)
6336 		return TRUE;
6337     return FALSE;
6338 }
6339 #endif
6340 
6341 #if defined(MESSAGE_QUEUE) || defined(PROTO)
6342 /*
6343  * Process messages that have been queued for netbeans or clientserver.
6344  * Also check if any jobs have ended.
6345  * These functions can call arbitrary vimscript and should only be called when
6346  * it is safe to do so.
6347  */
6348     void
6349 parse_queued_messages(void)
6350 {
6351     win_T *old_curwin = curwin;
6352 
6353     /* For Win32 mch_breakcheck() does not check for input, do it here. */
6354 # if defined(WIN32) && defined(FEAT_JOB_CHANNEL)
6355     channel_handle_events(FALSE);
6356 # endif
6357 
6358 # ifdef FEAT_NETBEANS_INTG
6359     /* Process the queued netbeans messages. */
6360     netbeans_parse_messages();
6361 # endif
6362 # ifdef FEAT_JOB_CHANNEL
6363     /* Write any buffer lines still to be written. */
6364     channel_write_any_lines();
6365 
6366     /* Process the messages queued on channels. */
6367     channel_parse_messages();
6368 # endif
6369 # if defined(FEAT_CLIENTSERVER) && defined(FEAT_X11)
6370     /* Process the queued clientserver messages. */
6371     server_parse_messages();
6372 # endif
6373 # ifdef FEAT_JOB_CHANNEL
6374     /* Check if any jobs have ended. */
6375     job_check_ended();
6376 # endif
6377 
6378     /* If the current window changed we need to bail out of the waiting loop.
6379      * E.g. when a job exit callback closes the terminal window. */
6380     if (curwin != old_curwin)
6381 	ins_char_typebuf(K_IGNORE);
6382 }
6383 #endif
6384 
6385 #ifndef PROTO  /* proto is defined in vim.h */
6386 # ifdef ELAPSED_TIMEVAL
6387 /*
6388  * Return time in msec since "start_tv".
6389  */
6390     long
6391 elapsed(struct timeval *start_tv)
6392 {
6393     struct timeval  now_tv;
6394 
6395     gettimeofday(&now_tv, NULL);
6396     return (now_tv.tv_sec - start_tv->tv_sec) * 1000L
6397 	 + (now_tv.tv_usec - start_tv->tv_usec) / 1000L;
6398 }
6399 # endif
6400 
6401 # ifdef ELAPSED_TICKCOUNT
6402 /*
6403  * Return time in msec since "start_tick".
6404  */
6405     long
6406 elapsed(DWORD start_tick)
6407 {
6408     DWORD	now = GetTickCount();
6409 
6410     return (long)now - (long)start_tick;
6411 }
6412 # endif
6413 #endif
6414