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