xref: /vim-8.2.3635/src/misc2.c (revision 83cd0156)
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 int coladvance2(pos_T *pos, int addspaces, int finetune, colnr_T wcol);
18 
19 /*
20  * Return TRUE if in the current mode we need to use virtual.
21  */
22     int
23 virtual_active(void)
24 {
25     unsigned int cur_ve_flags = get_ve_flags();
26 
27     // While an operator is being executed we return "virtual_op", because
28     // VIsual_active has already been reset, thus we can't check for "block"
29     // being used.
30     if (virtual_op != MAYBE)
31 	return virtual_op;
32     return (cur_ve_flags == VE_ALL
33 	    || ((cur_ve_flags & VE_BLOCK) && VIsual_active && VIsual_mode == Ctrl_V)
34 	    || ((cur_ve_flags & VE_INSERT) && (State & INSERT)));
35 }
36 
37 /*
38  * Get the screen position of the cursor.
39  */
40     int
41 getviscol(void)
42 {
43     colnr_T	x;
44 
45     getvvcol(curwin, &curwin->w_cursor, &x, NULL, NULL);
46     return (int)x;
47 }
48 
49 /*
50  * Go to column "wcol", and add/insert white space as necessary to get the
51  * cursor in that column.
52  * The caller must have saved the cursor line for undo!
53  */
54     int
55 coladvance_force(colnr_T wcol)
56 {
57     int rc = coladvance2(&curwin->w_cursor, TRUE, FALSE, wcol);
58 
59     if (wcol == MAXCOL)
60 	curwin->w_valid &= ~VALID_VIRTCOL;
61     else
62     {
63 	// Virtcol is valid
64 	curwin->w_valid |= VALID_VIRTCOL;
65 	curwin->w_virtcol = wcol;
66     }
67     return rc;
68 }
69 
70 /*
71  * Get the screen position of character col with a coladd in the cursor line.
72  */
73     int
74 getviscol2(colnr_T col, colnr_T coladd UNUSED)
75 {
76     colnr_T	x;
77     pos_T	pos;
78 
79     pos.lnum = curwin->w_cursor.lnum;
80     pos.col = col;
81     pos.coladd = coladd;
82     getvvcol(curwin, &pos, &x, NULL, NULL);
83     return (int)x;
84 }
85 
86 /*
87  * Try to advance the Cursor to the specified screen column.
88  * If virtual editing: fine tune the cursor position.
89  * Note that all virtual positions off the end of a line should share
90  * a curwin->w_cursor.col value (n.b. this is equal to STRLEN(line)),
91  * beginning at coladd 0.
92  *
93  * return OK if desired column is reached, FAIL if not
94  */
95     int
96 coladvance(colnr_T wcol)
97 {
98     int rc = getvpos(&curwin->w_cursor, wcol);
99 
100     if (wcol == MAXCOL || rc == FAIL)
101 	curwin->w_valid &= ~VALID_VIRTCOL;
102     else if (*ml_get_cursor() != TAB)
103     {
104 	// Virtcol is valid when not on a TAB
105 	curwin->w_valid |= VALID_VIRTCOL;
106 	curwin->w_virtcol = wcol;
107     }
108     return rc;
109 }
110 
111 /*
112  * Return in "pos" the position of the cursor advanced to screen column "wcol".
113  * return OK if desired column is reached, FAIL if not
114  */
115     int
116 getvpos(pos_T *pos, colnr_T wcol)
117 {
118     return coladvance2(pos, FALSE, virtual_active(), wcol);
119 }
120 
121     static int
122 coladvance2(
123     pos_T	*pos,
124     int		addspaces,	// change the text to achieve our goal?
125     int		finetune,	// change char offset for the exact column
126     colnr_T	wcol_arg)	// column to move to (can be negative)
127 {
128     colnr_T	wcol = wcol_arg;
129     int		idx;
130     char_u	*ptr;
131     char_u	*line;
132     colnr_T	col = 0;
133     int		csize = 0;
134     int		one_more;
135 #ifdef FEAT_LINEBREAK
136     int		head = 0;
137 #endif
138 
139     one_more = (State & INSERT)
140 		    || restart_edit != NUL
141 		    || (VIsual_active && *p_sel != 'o')
142 		    || ((get_ve_flags() & VE_ONEMORE) && wcol < MAXCOL);
143     line = ml_get_buf(curbuf, pos->lnum, FALSE);
144 
145     if (wcol >= MAXCOL)
146     {
147 	    idx = (int)STRLEN(line) - 1 + one_more;
148 	    col = wcol;
149 
150 	    if ((addspaces || finetune) && !VIsual_active)
151 	    {
152 		curwin->w_curswant = linetabsize(line) + one_more;
153 		if (curwin->w_curswant > 0)
154 		    --curwin->w_curswant;
155 	    }
156     }
157     else
158     {
159 	int width = curwin->w_width - win_col_off(curwin);
160 
161 	if (finetune
162 		&& curwin->w_p_wrap
163 		&& curwin->w_width != 0
164 		&& wcol >= (colnr_T)width)
165 	{
166 	    csize = linetabsize(line);
167 	    if (csize > 0)
168 		csize--;
169 
170 	    if (wcol / width > (colnr_T)csize / width
171 		    && ((State & INSERT) == 0 || (int)wcol > csize + 1))
172 	    {
173 		// In case of line wrapping don't move the cursor beyond the
174 		// right screen edge.  In Insert mode allow going just beyond
175 		// the last character (like what happens when typing and
176 		// reaching the right window edge).
177 		wcol = (csize / width + 1) * width - 1;
178 	    }
179 	}
180 
181 	ptr = line;
182 	while (col <= wcol && *ptr != NUL)
183 	{
184 	    // Count a tab for what it's worth (if list mode not on)
185 #ifdef FEAT_LINEBREAK
186 	    csize = win_lbr_chartabsize(curwin, line, ptr, col, &head);
187 	    MB_PTR_ADV(ptr);
188 #else
189 	    csize = lbr_chartabsize_adv(line, &ptr, col);
190 #endif
191 	    col += csize;
192 	}
193 	idx = (int)(ptr - line);
194 	/*
195 	 * Handle all the special cases.  The virtual_active() check
196 	 * is needed to ensure that a virtual position off the end of
197 	 * a line has the correct indexing.  The one_more comparison
198 	 * replaces an explicit add of one_more later on.
199 	 */
200 	if (col > wcol || (!virtual_active() && one_more == 0))
201 	{
202 	    idx -= 1;
203 # ifdef FEAT_LINEBREAK
204 	    // Don't count the chars from 'showbreak'.
205 	    csize -= head;
206 # endif
207 	    col -= csize;
208 	}
209 
210 	if (virtual_active()
211 		&& addspaces
212 		&& wcol >= 0
213 		&& ((col != wcol && col != wcol + 1) || csize > 1))
214 	{
215 	    // 'virtualedit' is set: The difference between wcol and col is
216 	    // filled with spaces.
217 
218 	    if (line[idx] == NUL)
219 	    {
220 		// Append spaces
221 		int	correct = wcol - col;
222 		char_u	*newline = alloc(idx + correct + 1);
223 		int	t;
224 
225 		if (newline == NULL)
226 		    return FAIL;
227 
228 		for (t = 0; t < idx; ++t)
229 		    newline[t] = line[t];
230 
231 		for (t = 0; t < correct; ++t)
232 		    newline[t + idx] = ' ';
233 
234 		newline[idx + correct] = NUL;
235 
236 		ml_replace(pos->lnum, newline, FALSE);
237 		changed_bytes(pos->lnum, (colnr_T)idx);
238 		idx += correct;
239 		col = wcol;
240 	    }
241 	    else
242 	    {
243 		// Break a tab
244 		int	linelen = (int)STRLEN(line);
245 		int	correct = wcol - col - csize + 1; // negative!!
246 		char_u	*newline;
247 		int	t, s = 0;
248 		int	v;
249 
250 		if (-correct > csize)
251 		    return FAIL;
252 
253 		newline = alloc(linelen + csize);
254 		if (newline == NULL)
255 		    return FAIL;
256 
257 		for (t = 0; t < linelen; t++)
258 		{
259 		    if (t != idx)
260 			newline[s++] = line[t];
261 		    else
262 			for (v = 0; v < csize; v++)
263 			    newline[s++] = ' ';
264 		}
265 
266 		newline[linelen + csize - 1] = NUL;
267 
268 		ml_replace(pos->lnum, newline, FALSE);
269 		changed_bytes(pos->lnum, idx);
270 		idx += (csize - 1 + correct);
271 		col += correct;
272 	    }
273 	}
274     }
275 
276     if (idx < 0)
277 	pos->col = 0;
278     else
279 	pos->col = idx;
280 
281     pos->coladd = 0;
282 
283     if (finetune)
284     {
285 	if (wcol == MAXCOL)
286 	{
287 	    // The width of the last character is used to set coladd.
288 	    if (!one_more)
289 	    {
290 		colnr_T	    scol, ecol;
291 
292 		getvcol(curwin, pos, &scol, NULL, &ecol);
293 		pos->coladd = ecol - scol;
294 	    }
295 	}
296 	else
297 	{
298 	    int b = (int)wcol - (int)col;
299 
300 	    // The difference between wcol and col is used to set coladd.
301 	    if (b > 0 && b < (MAXCOL - 2 * curwin->w_width))
302 		pos->coladd = b;
303 
304 	    col += b;
305 	}
306     }
307 
308     // prevent from moving onto a trail byte
309     if (has_mbyte)
310 	mb_adjustpos(curbuf, pos);
311 
312     if (wcol < 0 || col < wcol)
313 	return FAIL;
314     return OK;
315 }
316 
317 /*
318  * Increment the cursor position.  See inc() for return values.
319  */
320     int
321 inc_cursor(void)
322 {
323     return inc(&curwin->w_cursor);
324 }
325 
326 /*
327  * Increment the line pointer "lp" crossing line boundaries as necessary.
328  * Return 1 when going to the next line.
329  * Return 2 when moving forward onto a NUL at the end of the line).
330  * Return -1 when at the end of file.
331  * Return 0 otherwise.
332  */
333     int
334 inc(pos_T *lp)
335 {
336     char_u  *p;
337 
338     // when searching position may be set to end of a line
339     if (lp->col != MAXCOL)
340     {
341 	p = ml_get_pos(lp);
342 	if (*p != NUL)	// still within line, move to next char (may be NUL)
343 	{
344 	    if (has_mbyte)
345 	    {
346 		int l = (*mb_ptr2len)(p);
347 
348 		lp->col += l;
349 		return ((p[l] != NUL) ? 0 : 2);
350 	    }
351 	    lp->col++;
352 	    lp->coladd = 0;
353 	    return ((p[1] != NUL) ? 0 : 2);
354 	}
355     }
356     if (lp->lnum != curbuf->b_ml.ml_line_count)     // there is a next line
357     {
358 	lp->col = 0;
359 	lp->lnum++;
360 	lp->coladd = 0;
361 	return 1;
362     }
363     return -1;
364 }
365 
366 /*
367  * incl(lp): same as inc(), but skip the NUL at the end of non-empty lines
368  */
369     int
370 incl(pos_T *lp)
371 {
372     int	    r;
373 
374     if ((r = inc(lp)) >= 1 && lp->col)
375 	r = inc(lp);
376     return r;
377 }
378 
379 /*
380  * dec(p)
381  *
382  * Decrement the line pointer 'p' crossing line boundaries as necessary.
383  * Return 1 when crossing a line, -1 when at start of file, 0 otherwise.
384  */
385     int
386 dec_cursor(void)
387 {
388     return dec(&curwin->w_cursor);
389 }
390 
391     int
392 dec(pos_T *lp)
393 {
394     char_u	*p;
395 
396     lp->coladd = 0;
397     if (lp->col == MAXCOL)
398     {
399 	// past end of line
400 	p = ml_get(lp->lnum);
401 	lp->col = (colnr_T)STRLEN(p);
402 	if (has_mbyte)
403 	    lp->col -= (*mb_head_off)(p, p + lp->col);
404 	return 0;
405     }
406 
407     if (lp->col > 0)
408     {
409 	// still within line
410 	lp->col--;
411 	if (has_mbyte)
412 	{
413 	    p = ml_get(lp->lnum);
414 	    lp->col -= (*mb_head_off)(p, p + lp->col);
415 	}
416 	return 0;
417     }
418 
419     if (lp->lnum > 1)
420     {
421 	// there is a prior line
422 	lp->lnum--;
423 	p = ml_get(lp->lnum);
424 	lp->col = (colnr_T)STRLEN(p);
425 	if (has_mbyte)
426 	    lp->col -= (*mb_head_off)(p, p + lp->col);
427 	return 1;
428     }
429 
430     // at start of file
431     return -1;
432 }
433 
434 /*
435  * decl(lp): same as dec(), but skip the NUL at the end of non-empty lines
436  */
437     int
438 decl(pos_T *lp)
439 {
440     int	    r;
441 
442     if ((r = dec(lp)) == 1 && lp->col)
443 	r = dec(lp);
444     return r;
445 }
446 
447 /*
448  * Get the line number relative to the current cursor position, i.e. the
449  * difference between line number and cursor position. Only look for lines that
450  * can be visible, folded lines don't count.
451  */
452     linenr_T
453 get_cursor_rel_lnum(
454     win_T	*wp,
455     linenr_T	lnum)		    // line number to get the result for
456 {
457     linenr_T	cursor = wp->w_cursor.lnum;
458     linenr_T	retval = 0;
459 
460 #ifdef FEAT_FOLDING
461     if (hasAnyFolding(wp))
462     {
463 	if (lnum > cursor)
464 	{
465 	    while (lnum > cursor)
466 	    {
467 		(void)hasFoldingWin(wp, lnum, &lnum, NULL, TRUE, NULL);
468 		// if lnum and cursor are in the same fold,
469 		// now lnum <= cursor
470 		if (lnum > cursor)
471 		    retval++;
472 		lnum--;
473 	    }
474 	}
475 	else if (lnum < cursor)
476 	{
477 	    while (lnum < cursor)
478 	    {
479 		(void)hasFoldingWin(wp, lnum, NULL, &lnum, TRUE, NULL);
480 		// if lnum and cursor are in the same fold,
481 		// now lnum >= cursor
482 		if (lnum < cursor)
483 		    retval--;
484 		lnum++;
485 	    }
486 	}
487 	// else if (lnum == cursor)
488 	//     retval = 0;
489     }
490     else
491 #endif
492 	retval = lnum - cursor;
493 
494     return retval;
495 }
496 
497 /*
498  * Make sure "pos.lnum" and "pos.col" are valid in "buf".
499  * This allows for the col to be on the NUL byte.
500  */
501     void
502 check_pos(buf_T *buf, pos_T *pos)
503 {
504     char_u *line;
505     colnr_T len;
506 
507     if (pos->lnum > buf->b_ml.ml_line_count)
508 	pos->lnum = buf->b_ml.ml_line_count;
509 
510     if (pos->col > 0)
511     {
512 	line = ml_get_buf(buf, pos->lnum, FALSE);
513 	len = (colnr_T)STRLEN(line);
514 	if (pos->col > len)
515 	    pos->col = len;
516     }
517 }
518 
519 /*
520  * Make sure curwin->w_cursor.lnum is valid.
521  */
522     void
523 check_cursor_lnum(void)
524 {
525     if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count)
526     {
527 #ifdef FEAT_FOLDING
528 	// If there is a closed fold at the end of the file, put the cursor in
529 	// its first line.  Otherwise in the last line.
530 	if (!hasFolding(curbuf->b_ml.ml_line_count,
531 						&curwin->w_cursor.lnum, NULL))
532 #endif
533 	    curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
534     }
535     if (curwin->w_cursor.lnum <= 0)
536 	curwin->w_cursor.lnum = 1;
537 }
538 
539 /*
540  * Make sure curwin->w_cursor.col is valid.
541  */
542     void
543 check_cursor_col(void)
544 {
545     check_cursor_col_win(curwin);
546 }
547 
548 /*
549  * Make sure win->w_cursor.col is valid.
550  */
551     void
552 check_cursor_col_win(win_T *win)
553 {
554     colnr_T      len;
555     colnr_T      oldcol = win->w_cursor.col;
556     colnr_T      oldcoladd = win->w_cursor.col + win->w_cursor.coladd;
557     unsigned int cur_ve_flags = get_ve_flags();
558 
559     len = (colnr_T)STRLEN(ml_get_buf(win->w_buffer, win->w_cursor.lnum, FALSE));
560     if (len == 0)
561 	win->w_cursor.col = 0;
562     else if (win->w_cursor.col >= len)
563     {
564 	// Allow cursor past end-of-line when:
565 	// - in Insert mode or restarting Insert mode
566 	// - in Visual mode and 'selection' isn't "old"
567 	// - 'virtualedit' is set
568 	if ((State & INSERT) || restart_edit
569 		|| (VIsual_active && *p_sel != 'o')
570 		|| (cur_ve_flags & VE_ONEMORE)
571 		|| virtual_active())
572 	    win->w_cursor.col = len;
573 	else
574 	{
575 	    win->w_cursor.col = len - 1;
576 	    // Move the cursor to the head byte.
577 	    if (has_mbyte)
578 		mb_adjustpos(win->w_buffer, &win->w_cursor);
579 	}
580     }
581     else if (win->w_cursor.col < 0)
582 	win->w_cursor.col = 0;
583 
584     // If virtual editing is on, we can leave the cursor on the old position,
585     // only we must set it to virtual.  But don't do it when at the end of the
586     // line.
587     if (oldcol == MAXCOL)
588 	win->w_cursor.coladd = 0;
589     else if (cur_ve_flags == VE_ALL)
590     {
591 	if (oldcoladd > win->w_cursor.col)
592 	{
593 	    win->w_cursor.coladd = oldcoladd - win->w_cursor.col;
594 
595 	    // Make sure that coladd is not more than the char width.
596 	    // Not for the last character, coladd is then used when the cursor
597 	    // is actually after the last character.
598 	    if (win->w_cursor.col + 1 < len && win->w_cursor.coladd > 0)
599 	    {
600 		int cs, ce;
601 
602 		getvcol(win, &win->w_cursor, &cs, NULL, &ce);
603 		if (win->w_cursor.coladd > ce - cs)
604 		    win->w_cursor.coladd = ce - cs;
605 	    }
606 	}
607 	else
608 	    // avoid weird number when there is a miscalculation or overflow
609 	    win->w_cursor.coladd = 0;
610     }
611 }
612 
613 /*
614  * make sure curwin->w_cursor in on a valid character
615  */
616     void
617 check_cursor(void)
618 {
619     check_cursor_lnum();
620     check_cursor_col();
621 }
622 
623 #if defined(FEAT_TEXTOBJ) || defined(PROTO)
624 /*
625  * Make sure curwin->w_cursor is not on the NUL at the end of the line.
626  * Allow it when in Visual mode and 'selection' is not "old".
627  */
628     void
629 adjust_cursor_col(void)
630 {
631     if (curwin->w_cursor.col > 0
632 	    && (!VIsual_active || *p_sel == 'o')
633 	    && gchar_cursor() == NUL)
634 	--curwin->w_cursor.col;
635 }
636 #endif
637 
638 /*
639  * When curwin->w_leftcol has changed, adjust the cursor position.
640  * Return TRUE if the cursor was moved.
641  */
642     int
643 leftcol_changed(void)
644 {
645     long	lastcol;
646     colnr_T	s, e;
647     int		retval = FALSE;
648     long        siso = get_sidescrolloff_value();
649 
650     changed_cline_bef_curs();
651     lastcol = curwin->w_leftcol + curwin->w_width - curwin_col_off() - 1;
652     validate_virtcol();
653 
654     /*
655      * If the cursor is right or left of the screen, move it to last or first
656      * character.
657      */
658     if (curwin->w_virtcol > (colnr_T)(lastcol - siso))
659     {
660 	retval = TRUE;
661 	coladvance((colnr_T)(lastcol - siso));
662     }
663     else if (curwin->w_virtcol < curwin->w_leftcol + siso)
664     {
665 	retval = TRUE;
666 	(void)coladvance((colnr_T)(curwin->w_leftcol + siso));
667     }
668 
669     /*
670      * If the start of the character under the cursor is not on the screen,
671      * advance the cursor one more char.  If this fails (last char of the
672      * line) adjust the scrolling.
673      */
674     getvvcol(curwin, &curwin->w_cursor, &s, NULL, &e);
675     if (e > (colnr_T)lastcol)
676     {
677 	retval = TRUE;
678 	coladvance(s - 1);
679     }
680     else if (s < curwin->w_leftcol)
681     {
682 	retval = TRUE;
683 	if (coladvance(e + 1) == FAIL)	// there isn't another character
684 	{
685 	    curwin->w_leftcol = s;	// adjust w_leftcol instead
686 	    changed_cline_bef_curs();
687 	}
688     }
689 
690     if (retval)
691 	curwin->w_set_curswant = TRUE;
692     redraw_later(NOT_VALID);
693     return retval;
694 }
695 
696 /**********************************************************************
697  * Various routines dealing with allocation and deallocation of memory.
698  */
699 
700 #if defined(MEM_PROFILE) || defined(PROTO)
701 
702 # define MEM_SIZES  8200
703 static long_u mem_allocs[MEM_SIZES];
704 static long_u mem_frees[MEM_SIZES];
705 static long_u mem_allocated;
706 static long_u mem_freed;
707 static long_u mem_peak;
708 static long_u num_alloc;
709 static long_u num_freed;
710 
711     static void
712 mem_pre_alloc_s(size_t *sizep)
713 {
714     *sizep += sizeof(size_t);
715 }
716 
717     static void
718 mem_pre_alloc_l(size_t *sizep)
719 {
720     *sizep += sizeof(size_t);
721 }
722 
723     static void
724 mem_post_alloc(
725     void **pp,
726     size_t size)
727 {
728     if (*pp == NULL)
729 	return;
730     size -= sizeof(size_t);
731     *(long_u *)*pp = size;
732     if (size <= MEM_SIZES-1)
733 	mem_allocs[size-1]++;
734     else
735 	mem_allocs[MEM_SIZES-1]++;
736     mem_allocated += size;
737     if (mem_allocated - mem_freed > mem_peak)
738 	mem_peak = mem_allocated - mem_freed;
739     num_alloc++;
740     *pp = (void *)((char *)*pp + sizeof(size_t));
741 }
742 
743     static void
744 mem_pre_free(void **pp)
745 {
746     long_u size;
747 
748     *pp = (void *)((char *)*pp - sizeof(size_t));
749     size = *(size_t *)*pp;
750     if (size <= MEM_SIZES-1)
751 	mem_frees[size-1]++;
752     else
753 	mem_frees[MEM_SIZES-1]++;
754     mem_freed += size;
755     num_freed++;
756 }
757 
758 /*
759  * called on exit via atexit()
760  */
761     void
762 vim_mem_profile_dump(void)
763 {
764     int i, j;
765 
766     printf("\r\n");
767     j = 0;
768     for (i = 0; i < MEM_SIZES - 1; i++)
769     {
770 	if (mem_allocs[i] || mem_frees[i])
771 	{
772 	    if (mem_frees[i] > mem_allocs[i])
773 		printf("\r\n%s", _("ERROR: "));
774 	    printf("[%4d / %4lu-%-4lu] ", i + 1, mem_allocs[i], mem_frees[i]);
775 	    j++;
776 	    if (j > 3)
777 	    {
778 		j = 0;
779 		printf("\r\n");
780 	    }
781 	}
782     }
783 
784     i = MEM_SIZES - 1;
785     if (mem_allocs[i])
786     {
787 	printf("\r\n");
788 	if (mem_frees[i] > mem_allocs[i])
789 	    puts(_("ERROR: "));
790 	printf("[>%d / %4lu-%-4lu]", i, mem_allocs[i], mem_frees[i]);
791     }
792 
793     printf(_("\n[bytes] total alloc-freed %lu-%lu, in use %lu, peak use %lu\n"),
794 	    mem_allocated, mem_freed, mem_allocated - mem_freed, mem_peak);
795     printf(_("[calls] total re/malloc()'s %lu, total free()'s %lu\n\n"),
796 	    num_alloc, num_freed);
797 }
798 
799 #endif // MEM_PROFILE
800 
801 #ifdef FEAT_EVAL
802     int
803 alloc_does_fail(size_t size)
804 {
805     if (alloc_fail_countdown == 0)
806     {
807 	if (--alloc_fail_repeat <= 0)
808 	    alloc_fail_id = 0;
809 	do_outofmem_msg(size);
810 	return TRUE;
811     }
812     --alloc_fail_countdown;
813     return FALSE;
814 }
815 #endif
816 
817 /*
818  * Some memory is reserved for error messages and for being able to
819  * call mf_release_all(), which needs some memory for mf_trans_add().
820  */
821 #define KEEP_ROOM (2 * 8192L)
822 #define KEEP_ROOM_KB (KEEP_ROOM / 1024L)
823 
824 /*
825  * The normal way to allocate memory.  This handles an out-of-memory situation
826  * as well as possible, still returns NULL when we're completely out.
827  */
828     void *
829 alloc(size_t size)
830 {
831     return lalloc(size, TRUE);
832 }
833 
834 /*
835  * alloc() with an ID for alloc_fail().
836  */
837     void *
838 alloc_id(size_t size, alloc_id_T id UNUSED)
839 {
840 #ifdef FEAT_EVAL
841     if (alloc_fail_id == id && alloc_does_fail(size))
842 	return NULL;
843 #endif
844     return lalloc(size, TRUE);
845 }
846 
847 /*
848  * Allocate memory and set all bytes to zero.
849  */
850     void *
851 alloc_clear(size_t size)
852 {
853     void *p;
854 
855     p = lalloc(size, TRUE);
856     if (p != NULL)
857 	(void)vim_memset(p, 0, size);
858     return p;
859 }
860 
861 /*
862  * Same as alloc_clear() but with allocation id for testing
863  */
864     void *
865 alloc_clear_id(size_t size, alloc_id_T id UNUSED)
866 {
867 #ifdef FEAT_EVAL
868     if (alloc_fail_id == id && alloc_does_fail(size))
869 	return NULL;
870 #endif
871     return alloc_clear(size);
872 }
873 
874 /*
875  * Allocate memory like lalloc() and set all bytes to zero.
876  */
877     void *
878 lalloc_clear(size_t size, int message)
879 {
880     void *p;
881 
882     p = lalloc(size, message);
883     if (p != NULL)
884 	(void)vim_memset(p, 0, size);
885     return p;
886 }
887 
888 /*
889  * Low level memory allocation function.
890  * This is used often, KEEP IT FAST!
891  */
892     void *
893 lalloc(size_t size, int message)
894 {
895     void	*p;		    // pointer to new storage space
896     static int	releasing = FALSE;  // don't do mf_release_all() recursive
897     int		try_again;
898 #if defined(HAVE_AVAIL_MEM)
899     static size_t allocated = 0;    // allocated since last avail check
900 #endif
901 
902     // Safety check for allocating zero bytes
903     if (size == 0)
904     {
905 	// Don't hide this message
906 	emsg_silent = 0;
907 	iemsg(_("E341: Internal error: lalloc(0, )"));
908 	return NULL;
909     }
910 
911 #ifdef MEM_PROFILE
912     mem_pre_alloc_l(&size);
913 #endif
914 
915     /*
916      * Loop when out of memory: Try to release some memfile blocks and
917      * if some blocks are released call malloc again.
918      */
919     for (;;)
920     {
921 	/*
922 	 * Handle three kind of systems:
923 	 * 1. No check for available memory: Just return.
924 	 * 2. Slow check for available memory: call mch_avail_mem() after
925 	 *    allocating KEEP_ROOM amount of memory.
926 	 * 3. Strict check for available memory: call mch_avail_mem()
927 	 */
928 	if ((p = malloc(size)) != NULL)
929 	{
930 #ifndef HAVE_AVAIL_MEM
931 	    // 1. No check for available memory: Just return.
932 	    goto theend;
933 #else
934 	    // 2. Slow check for available memory: call mch_avail_mem() after
935 	    //    allocating (KEEP_ROOM / 2) amount of memory.
936 	    allocated += size;
937 	    if (allocated < KEEP_ROOM / 2)
938 		goto theend;
939 	    allocated = 0;
940 
941 	    // 3. check for available memory: call mch_avail_mem()
942 	    if (mch_avail_mem(TRUE) < KEEP_ROOM_KB && !releasing)
943 	    {
944 		free(p);	// System is low... no go!
945 		p = NULL;
946 	    }
947 	    else
948 		goto theend;
949 #endif
950 	}
951 	/*
952 	 * Remember that mf_release_all() is being called to avoid an endless
953 	 * loop, because mf_release_all() may call alloc() recursively.
954 	 */
955 	if (releasing)
956 	    break;
957 	releasing = TRUE;
958 
959 	clear_sb_text(TRUE);	      // free any scrollback text
960 	try_again = mf_release_all(); // release as many blocks as possible
961 
962 	releasing = FALSE;
963 	if (!try_again)
964 	    break;
965     }
966 
967     if (message && p == NULL)
968 	do_outofmem_msg(size);
969 
970 theend:
971 #ifdef MEM_PROFILE
972     mem_post_alloc(&p, size);
973 #endif
974     return p;
975 }
976 
977 /*
978  * lalloc() with an ID for alloc_fail().
979  */
980 #if defined(FEAT_SIGNS) || defined(PROTO)
981     void *
982 lalloc_id(size_t size, int message, alloc_id_T id UNUSED)
983 {
984 #ifdef FEAT_EVAL
985     if (alloc_fail_id == id && alloc_does_fail(size))
986 	return NULL;
987 #endif
988     return (lalloc(size, message));
989 }
990 #endif
991 
992 #if defined(MEM_PROFILE) || defined(PROTO)
993 /*
994  * realloc() with memory profiling.
995  */
996     void *
997 mem_realloc(void *ptr, size_t size)
998 {
999     void *p;
1000 
1001     mem_pre_free(&ptr);
1002     mem_pre_alloc_s(&size);
1003 
1004     p = realloc(ptr, size);
1005 
1006     mem_post_alloc(&p, size);
1007 
1008     return p;
1009 }
1010 #endif
1011 
1012 /*
1013 * Avoid repeating the error message many times (they take 1 second each).
1014 * Did_outofmem_msg is reset when a character is read.
1015 */
1016     void
1017 do_outofmem_msg(size_t size)
1018 {
1019     if (!did_outofmem_msg)
1020     {
1021 	// Don't hide this message
1022 	emsg_silent = 0;
1023 
1024 	// Must come first to avoid coming back here when printing the error
1025 	// message fails, e.g. when setting v:errmsg.
1026 	did_outofmem_msg = TRUE;
1027 
1028 	semsg(_("E342: Out of memory!  (allocating %lu bytes)"), (long_u)size);
1029 
1030 	if (starting == NO_SCREEN)
1031 	    // Not even finished with initializations and already out of
1032 	    // memory?  Then nothing is going to work, exit.
1033 	    mch_exit(123);
1034     }
1035 }
1036 
1037 #if defined(EXITFREE) || defined(PROTO)
1038 
1039 /*
1040  * Free everything that we allocated.
1041  * Can be used to detect memory leaks, e.g., with ccmalloc.
1042  * NOTE: This is tricky!  Things are freed that functions depend on.  Don't be
1043  * surprised if Vim crashes...
1044  * Some things can't be freed, esp. things local to a library function.
1045  */
1046     void
1047 free_all_mem(void)
1048 {
1049     buf_T	*buf, *nextbuf;
1050 
1051     // When we cause a crash here it is caught and Vim tries to exit cleanly.
1052     // Don't try freeing everything again.
1053     if (entered_free_all_mem)
1054 	return;
1055     entered_free_all_mem = TRUE;
1056     // Don't want to trigger autocommands from here on.
1057     block_autocmds();
1058 
1059     // Close all tabs and windows.  Reset 'equalalways' to avoid redraws.
1060     p_ea = FALSE;
1061     if (first_tabpage != NULL && first_tabpage->tp_next != NULL)
1062 	do_cmdline_cmd((char_u *)"tabonly!");
1063     if (!ONE_WINDOW)
1064 	do_cmdline_cmd((char_u *)"only!");
1065 
1066 # if defined(FEAT_SPELL)
1067     // Free all spell info.
1068     spell_free_all();
1069 # endif
1070 
1071 # if defined(FEAT_BEVAL_TERM)
1072     ui_remove_balloon();
1073 # endif
1074 # ifdef FEAT_PROP_POPUP
1075     if (curwin != NULL)
1076 	close_all_popups(TRUE);
1077 # endif
1078 
1079     // Clear user commands (before deleting buffers).
1080     ex_comclear(NULL);
1081 
1082     // When exiting from mainerr_arg_missing curbuf has not been initialized,
1083     // and not much else.
1084     if (curbuf != NULL)
1085     {
1086 # ifdef FEAT_MENU
1087 	// Clear menus.
1088 	do_cmdline_cmd((char_u *)"aunmenu *");
1089 #  ifdef FEAT_MULTI_LANG
1090 	do_cmdline_cmd((char_u *)"menutranslate clear");
1091 #  endif
1092 # endif
1093 	// Clear mappings, abbreviations, breakpoints.
1094 	do_cmdline_cmd((char_u *)"lmapclear");
1095 	do_cmdline_cmd((char_u *)"xmapclear");
1096 	do_cmdline_cmd((char_u *)"mapclear");
1097 	do_cmdline_cmd((char_u *)"mapclear!");
1098 	do_cmdline_cmd((char_u *)"abclear");
1099 # if defined(FEAT_EVAL)
1100 	do_cmdline_cmd((char_u *)"breakdel *");
1101 # endif
1102 # if defined(FEAT_PROFILE)
1103 	do_cmdline_cmd((char_u *)"profdel *");
1104 # endif
1105 # if defined(FEAT_KEYMAP)
1106 	do_cmdline_cmd((char_u *)"set keymap=");
1107 # endif
1108     }
1109 
1110 # ifdef FEAT_TITLE
1111     free_titles();
1112 # endif
1113 # if defined(FEAT_SEARCHPATH)
1114     free_findfile();
1115 # endif
1116 
1117     // Obviously named calls.
1118     free_all_autocmds();
1119     clear_termcodes();
1120     free_all_marks();
1121     alist_clear(&global_alist);
1122     free_homedir();
1123     free_users();
1124     free_search_patterns();
1125     free_old_sub();
1126     free_last_insert();
1127     free_insexpand_stuff();
1128     free_prev_shellcmd();
1129     free_regexp_stuff();
1130     free_tag_stuff();
1131     free_cd_dir();
1132 # ifdef FEAT_SIGNS
1133     free_signs();
1134 # endif
1135 # ifdef FEAT_EVAL
1136     set_expr_line(NULL, NULL);
1137 # endif
1138 # ifdef FEAT_DIFF
1139     if (curtab != NULL)
1140 	diff_clear(curtab);
1141 # endif
1142     clear_sb_text(TRUE);	      // free any scrollback text
1143 
1144     // Free some global vars.
1145     vim_free(username);
1146 # ifdef FEAT_CLIPBOARD
1147     vim_regfree(clip_exclude_prog);
1148 # endif
1149     vim_free(last_cmdline);
1150     vim_free(new_last_cmdline);
1151     set_keep_msg(NULL, 0);
1152 
1153     // Clear cmdline history.
1154     p_hi = 0;
1155     init_history();
1156 # ifdef FEAT_PROP_POPUP
1157     clear_global_prop_types();
1158 # endif
1159 
1160 # ifdef FEAT_QUICKFIX
1161     {
1162 	win_T	    *win;
1163 	tabpage_T   *tab;
1164 
1165 	qf_free_all(NULL);
1166 	// Free all location lists
1167 	FOR_ALL_TAB_WINDOWS(tab, win)
1168 	    qf_free_all(win);
1169     }
1170 # endif
1171 
1172     // Close all script inputs.
1173     close_all_scripts();
1174 
1175     if (curwin != NULL)
1176 	// Destroy all windows.  Must come before freeing buffers.
1177 	win_free_all();
1178 
1179     // Free all option values.  Must come after closing windows.
1180     free_all_options();
1181 
1182     // Free all buffers.  Reset 'autochdir' to avoid accessing things that
1183     // were freed already.
1184 # ifdef FEAT_AUTOCHDIR
1185     p_acd = FALSE;
1186 # endif
1187     for (buf = firstbuf; buf != NULL; )
1188     {
1189 	bufref_T    bufref;
1190 
1191 	set_bufref(&bufref, buf);
1192 	nextbuf = buf->b_next;
1193 	close_buffer(NULL, buf, DOBUF_WIPE, FALSE, FALSE);
1194 	if (bufref_valid(&bufref))
1195 	    buf = nextbuf;	// didn't work, try next one
1196 	else
1197 	    buf = firstbuf;
1198     }
1199 
1200 # ifdef FEAT_ARABIC
1201     free_arshape_buf();
1202 # endif
1203 
1204     // Clear registers.
1205     clear_registers();
1206     ResetRedobuff();
1207     ResetRedobuff();
1208 
1209 # if defined(FEAT_CLIENTSERVER) && defined(FEAT_X11)
1210     vim_free(serverDelayedStartName);
1211 # endif
1212 
1213     // highlight info
1214     free_highlight();
1215 
1216     reset_last_sourcing();
1217 
1218     if (first_tabpage != NULL)
1219     {
1220 	free_tabpage(first_tabpage);
1221 	first_tabpage = NULL;
1222     }
1223 
1224 # ifdef UNIX
1225     // Machine-specific free.
1226     mch_free_mem();
1227 # endif
1228 
1229     // message history
1230     for (;;)
1231 	if (delete_first_msg() == FAIL)
1232 	    break;
1233 
1234 # ifdef FEAT_JOB_CHANNEL
1235     channel_free_all();
1236 # endif
1237 # ifdef FEAT_TIMERS
1238     timer_free_all();
1239 # endif
1240 # ifdef FEAT_EVAL
1241     // must be after channel_free_all() with unrefs partials
1242     eval_clear();
1243 # endif
1244 # ifdef FEAT_JOB_CHANNEL
1245     // must be after eval_clear() with unrefs jobs
1246     job_free_all();
1247 # endif
1248 
1249     free_termoptions();
1250 
1251     // screenlines (can't display anything now!)
1252     free_screenlines();
1253 
1254 # if defined(FEAT_SOUND)
1255     sound_free();
1256 # endif
1257 # if defined(USE_XSMP)
1258     xsmp_close();
1259 # endif
1260 # ifdef FEAT_GUI_GTK
1261     gui_mch_free_all();
1262 # endif
1263     clear_hl_tables();
1264 
1265     vim_free(IObuff);
1266     vim_free(NameBuff);
1267 # ifdef FEAT_QUICKFIX
1268     check_quickfix_busy();
1269 # endif
1270 }
1271 #endif
1272 
1273 /*
1274  * Copy "p[len]" into allocated memory, ignoring NUL characters.
1275  * Returns NULL when out of memory.
1276  */
1277     char_u *
1278 vim_memsave(char_u *p, size_t len)
1279 {
1280     char_u *ret = alloc(len);
1281 
1282     if (ret != NULL)
1283 	mch_memmove(ret, p, len);
1284     return ret;
1285 }
1286 
1287 /*
1288  * Isolate one part of a string option where parts are separated with
1289  * "sep_chars".
1290  * The part is copied into "buf[maxlen]".
1291  * "*option" is advanced to the next part.
1292  * The length is returned.
1293  */
1294     int
1295 copy_option_part(
1296     char_u	**option,
1297     char_u	*buf,
1298     int		maxlen,
1299     char	*sep_chars)
1300 {
1301     int	    len = 0;
1302     char_u  *p = *option;
1303 
1304     // skip '.' at start of option part, for 'suffixes'
1305     if (*p == '.')
1306 	buf[len++] = *p++;
1307     while (*p != NUL && vim_strchr((char_u *)sep_chars, *p) == NULL)
1308     {
1309 	/*
1310 	 * Skip backslash before a separator character and space.
1311 	 */
1312 	if (p[0] == '\\' && vim_strchr((char_u *)sep_chars, p[1]) != NULL)
1313 	    ++p;
1314 	if (len < maxlen - 1)
1315 	    buf[len++] = *p;
1316 	++p;
1317     }
1318     buf[len] = NUL;
1319 
1320     if (*p != NUL && *p != ',')	// skip non-standard separator
1321 	++p;
1322     p = skip_to_option_part(p);	// p points to next file name
1323 
1324     *option = p;
1325     return len;
1326 }
1327 
1328 /*
1329  * Replacement for free() that ignores NULL pointers.
1330  * Also skip free() when exiting for sure, this helps when we caught a deadly
1331  * signal that was caused by a crash in free().
1332  * If you want to set NULL after calling this function, you should use
1333  * VIM_CLEAR() instead.
1334  */
1335     void
1336 vim_free(void *x)
1337 {
1338     if (x != NULL && !really_exiting)
1339     {
1340 #ifdef MEM_PROFILE
1341 	mem_pre_free(&x);
1342 #endif
1343 	free(x);
1344     }
1345 }
1346 
1347 #ifndef HAVE_MEMSET
1348     void *
1349 vim_memset(void *ptr, int c, size_t size)
1350 {
1351     char *p = ptr;
1352 
1353     while (size-- > 0)
1354 	*p++ = c;
1355     return ptr;
1356 }
1357 #endif
1358 
1359 /*
1360  * Vim has its own isspace() function, because on some machines isspace()
1361  * can't handle characters above 128.
1362  */
1363     int
1364 vim_isspace(int x)
1365 {
1366     return ((x >= 9 && x <= 13) || x == ' ');
1367 }
1368 
1369 /************************************************************************
1370  * Functions for handling growing arrays.
1371  */
1372 
1373 /*
1374  * Clear an allocated growing array.
1375  */
1376     void
1377 ga_clear(garray_T *gap)
1378 {
1379     vim_free(gap->ga_data);
1380     ga_init(gap);
1381 }
1382 
1383 /*
1384  * Clear a growing array that contains a list of strings.
1385  */
1386     void
1387 ga_clear_strings(garray_T *gap)
1388 {
1389     int		i;
1390 
1391     if (gap->ga_data != NULL)
1392 	for (i = 0; i < gap->ga_len; ++i)
1393 	    vim_free(((char_u **)(gap->ga_data))[i]);
1394     ga_clear(gap);
1395 }
1396 
1397 /*
1398  * Copy a growing array that contains a list of strings.
1399  */
1400     int
1401 ga_copy_strings(garray_T *from, garray_T *to)
1402 {
1403     int		i;
1404 
1405     ga_init2(to, sizeof(char_u *), 1);
1406     if (ga_grow(to, from->ga_len) == FAIL)
1407 	return FAIL;
1408 
1409     for (i = 0; i < from->ga_len; ++i)
1410     {
1411 	char_u *orig = ((char_u **)from->ga_data)[i];
1412 	char_u *copy;
1413 
1414 	if (orig == NULL)
1415 	    copy = NULL;
1416 	else
1417 	{
1418 	    copy = vim_strsave(orig);
1419 	    if (copy == NULL)
1420 	    {
1421 		to->ga_len = i;
1422 		ga_clear_strings(to);
1423 		return FAIL;
1424 	    }
1425 	}
1426 	((char_u **)to->ga_data)[i] = copy;
1427     }
1428     to->ga_len = from->ga_len;
1429     return OK;
1430 }
1431 
1432 /*
1433  * Initialize a growing array.	Don't forget to set ga_itemsize and
1434  * ga_growsize!  Or use ga_init2().
1435  */
1436     void
1437 ga_init(garray_T *gap)
1438 {
1439     gap->ga_data = NULL;
1440     gap->ga_maxlen = 0;
1441     gap->ga_len = 0;
1442 }
1443 
1444     void
1445 ga_init2(garray_T *gap, int itemsize, int growsize)
1446 {
1447     ga_init(gap);
1448     gap->ga_itemsize = itemsize;
1449     gap->ga_growsize = growsize;
1450 }
1451 
1452 /*
1453  * Make room in growing array "gap" for at least "n" items.
1454  * Return FAIL for failure, OK otherwise.
1455  */
1456     int
1457 ga_grow(garray_T *gap, int n)
1458 {
1459     if (gap->ga_maxlen - gap->ga_len < n)
1460 	return ga_grow_inner(gap, n);
1461     return OK;
1462 }
1463 
1464     int
1465 ga_grow_inner(garray_T *gap, int n)
1466 {
1467     size_t	old_len;
1468     size_t	new_len;
1469     char_u	*pp;
1470 
1471     if (n < gap->ga_growsize)
1472 	n = gap->ga_growsize;
1473 
1474     // A linear growth is very inefficient when the array grows big.  This
1475     // is a compromise between allocating memory that won't be used and too
1476     // many copy operations. A factor of 1.5 seems reasonable.
1477     if (n < gap->ga_len / 2)
1478 	n = gap->ga_len / 2;
1479 
1480     new_len = gap->ga_itemsize * (gap->ga_len + n);
1481     pp = vim_realloc(gap->ga_data, new_len);
1482     if (pp == NULL)
1483 	return FAIL;
1484     old_len = gap->ga_itemsize * gap->ga_maxlen;
1485     vim_memset(pp + old_len, 0, new_len - old_len);
1486     gap->ga_maxlen = gap->ga_len + n;
1487     gap->ga_data = pp;
1488     return OK;
1489 }
1490 
1491 /*
1492  * For a growing array that contains a list of strings: concatenate all the
1493  * strings with a separating "sep".
1494  * Returns NULL when out of memory.
1495  */
1496     char_u *
1497 ga_concat_strings(garray_T *gap, char *sep)
1498 {
1499     int		i;
1500     int		len = 0;
1501     int		sep_len = (int)STRLEN(sep);
1502     char_u	*s;
1503     char_u	*p;
1504 
1505     for (i = 0; i < gap->ga_len; ++i)
1506 	len += (int)STRLEN(((char_u **)(gap->ga_data))[i]) + sep_len;
1507 
1508     s = alloc(len + 1);
1509     if (s != NULL)
1510     {
1511 	*s = NUL;
1512 	p = s;
1513 	for (i = 0; i < gap->ga_len; ++i)
1514 	{
1515 	    if (p != s)
1516 	    {
1517 		STRCPY(p, sep);
1518 		p += sep_len;
1519 	    }
1520 	    STRCPY(p, ((char_u **)(gap->ga_data))[i]);
1521 	    p += STRLEN(p);
1522 	}
1523     }
1524     return s;
1525 }
1526 
1527 /*
1528  * Make a copy of string "p" and add it to "gap".
1529  * When out of memory nothing changes and FAIL is returned.
1530  */
1531     int
1532 ga_add_string(garray_T *gap, char_u *p)
1533 {
1534     char_u *cp = vim_strsave(p);
1535 
1536     if (cp == NULL)
1537 	return FAIL;
1538 
1539     if (ga_grow(gap, 1) == FAIL)
1540     {
1541 	vim_free(cp);
1542 	return FAIL;
1543     }
1544     ((char_u **)(gap->ga_data))[gap->ga_len++] = cp;
1545     return OK;
1546 }
1547 
1548 /*
1549  * Concatenate a string to a growarray which contains bytes.
1550  * When "s" is NULL does not do anything.
1551  * Note: Does NOT copy the NUL at the end!
1552  */
1553     void
1554 ga_concat(garray_T *gap, char_u *s)
1555 {
1556     int    len;
1557 
1558     if (s == NULL || *s == NUL)
1559 	return;
1560     len = (int)STRLEN(s);
1561     if (ga_grow(gap, len) == OK)
1562     {
1563 	mch_memmove((char *)gap->ga_data + gap->ga_len, s, (size_t)len);
1564 	gap->ga_len += len;
1565     }
1566 }
1567 
1568 /*
1569  * Append one byte to a growarray which contains bytes.
1570  */
1571     void
1572 ga_append(garray_T *gap, int c)
1573 {
1574     if (ga_grow(gap, 1) == OK)
1575     {
1576 	*((char *)gap->ga_data + gap->ga_len) = c;
1577 	++gap->ga_len;
1578     }
1579 }
1580 
1581 #if (defined(UNIX) && !defined(USE_SYSTEM)) || defined(MSWIN) \
1582 	|| defined(PROTO)
1583 /*
1584  * Append the text in "gap" below the cursor line and clear "gap".
1585  */
1586     void
1587 append_ga_line(garray_T *gap)
1588 {
1589     // Remove trailing CR.
1590     if (gap->ga_len > 0
1591 	    && !curbuf->b_p_bin
1592 	    && ((char_u *)gap->ga_data)[gap->ga_len - 1] == CAR)
1593 	--gap->ga_len;
1594     ga_append(gap, NUL);
1595     ml_append(curwin->w_cursor.lnum++, gap->ga_data, 0, FALSE);
1596     gap->ga_len = 0;
1597 }
1598 #endif
1599 
1600 /************************************************************************
1601  * functions that use lookup tables for various things, generally to do with
1602  * special key codes.
1603  */
1604 
1605 /*
1606  * Some useful tables.
1607  */
1608 
1609 static struct modmasktable
1610 {
1611     short	mod_mask;	// Bit-mask for particular key modifier
1612     short	mod_flag;	// Bit(s) for particular key modifier
1613     char_u	name;		// Single letter name of modifier
1614 } mod_mask_table[] =
1615 {
1616     {MOD_MASK_ALT,		MOD_MASK_ALT,		(char_u)'M'},
1617     {MOD_MASK_META,		MOD_MASK_META,		(char_u)'T'},
1618     {MOD_MASK_CTRL,		MOD_MASK_CTRL,		(char_u)'C'},
1619     {MOD_MASK_SHIFT,		MOD_MASK_SHIFT,		(char_u)'S'},
1620     {MOD_MASK_MULTI_CLICK,	MOD_MASK_2CLICK,	(char_u)'2'},
1621     {MOD_MASK_MULTI_CLICK,	MOD_MASK_3CLICK,	(char_u)'3'},
1622     {MOD_MASK_MULTI_CLICK,	MOD_MASK_4CLICK,	(char_u)'4'},
1623 #ifdef MACOS_X
1624     {MOD_MASK_CMD,		MOD_MASK_CMD,		(char_u)'D'},
1625 #endif
1626     // 'A' must be the last one
1627     {MOD_MASK_ALT,		MOD_MASK_ALT,		(char_u)'A'},
1628     {0, 0, NUL}
1629     // NOTE: when adding an entry, update MAX_KEY_NAME_LEN!
1630 };
1631 
1632 /*
1633  * Shifted key terminal codes and their unshifted equivalent.
1634  * Don't add mouse codes here, they are handled separately!
1635  */
1636 #define MOD_KEYS_ENTRY_SIZE 5
1637 
1638 static char_u modifier_keys_table[] =
1639 {
1640 //  mod mask	    with modifier		without modifier
1641     MOD_MASK_SHIFT, '&', '9',			'@', '1',	// begin
1642     MOD_MASK_SHIFT, '&', '0',			'@', '2',	// cancel
1643     MOD_MASK_SHIFT, '*', '1',			'@', '4',	// command
1644     MOD_MASK_SHIFT, '*', '2',			'@', '5',	// copy
1645     MOD_MASK_SHIFT, '*', '3',			'@', '6',	// create
1646     MOD_MASK_SHIFT, '*', '4',			'k', 'D',	// delete char
1647     MOD_MASK_SHIFT, '*', '5',			'k', 'L',	// delete line
1648     MOD_MASK_SHIFT, '*', '7',			'@', '7',	// end
1649     MOD_MASK_CTRL,  KS_EXTRA, (int)KE_C_END,	'@', '7',	// end
1650     MOD_MASK_SHIFT, '*', '9',			'@', '9',	// exit
1651     MOD_MASK_SHIFT, '*', '0',			'@', '0',	// find
1652     MOD_MASK_SHIFT, '#', '1',			'%', '1',	// help
1653     MOD_MASK_SHIFT, '#', '2',			'k', 'h',	// home
1654     MOD_MASK_CTRL,  KS_EXTRA, (int)KE_C_HOME,	'k', 'h',	// home
1655     MOD_MASK_SHIFT, '#', '3',			'k', 'I',	// insert
1656     MOD_MASK_SHIFT, '#', '4',			'k', 'l',	// left arrow
1657     MOD_MASK_CTRL,  KS_EXTRA, (int)KE_C_LEFT,	'k', 'l',	// left arrow
1658     MOD_MASK_SHIFT, '%', 'a',			'%', '3',	// message
1659     MOD_MASK_SHIFT, '%', 'b',			'%', '4',	// move
1660     MOD_MASK_SHIFT, '%', 'c',			'%', '5',	// next
1661     MOD_MASK_SHIFT, '%', 'd',			'%', '7',	// options
1662     MOD_MASK_SHIFT, '%', 'e',			'%', '8',	// previous
1663     MOD_MASK_SHIFT, '%', 'f',			'%', '9',	// print
1664     MOD_MASK_SHIFT, '%', 'g',			'%', '0',	// redo
1665     MOD_MASK_SHIFT, '%', 'h',			'&', '3',	// replace
1666     MOD_MASK_SHIFT, '%', 'i',			'k', 'r',	// right arr.
1667     MOD_MASK_CTRL,  KS_EXTRA, (int)KE_C_RIGHT,	'k', 'r',	// right arr.
1668     MOD_MASK_SHIFT, '%', 'j',			'&', '5',	// resume
1669     MOD_MASK_SHIFT, '!', '1',			'&', '6',	// save
1670     MOD_MASK_SHIFT, '!', '2',			'&', '7',	// suspend
1671     MOD_MASK_SHIFT, '!', '3',			'&', '8',	// undo
1672     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_UP,	'k', 'u',	// up arrow
1673     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_DOWN,	'k', 'd',	// down arrow
1674 
1675 								// vt100 F1
1676     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_XF1,	KS_EXTRA, (int)KE_XF1,
1677     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_XF2,	KS_EXTRA, (int)KE_XF2,
1678     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_XF3,	KS_EXTRA, (int)KE_XF3,
1679     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_XF4,	KS_EXTRA, (int)KE_XF4,
1680 
1681     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F1,	'k', '1',	// F1
1682     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F2,	'k', '2',
1683     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F3,	'k', '3',
1684     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F4,	'k', '4',
1685     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F5,	'k', '5',
1686     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F6,	'k', '6',
1687     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F7,	'k', '7',
1688     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F8,	'k', '8',
1689     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F9,	'k', '9',
1690     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F10,	'k', ';',	// F10
1691 
1692     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F11,	'F', '1',
1693     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F12,	'F', '2',
1694     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F13,	'F', '3',
1695     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F14,	'F', '4',
1696     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F15,	'F', '5',
1697     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F16,	'F', '6',
1698     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F17,	'F', '7',
1699     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F18,	'F', '8',
1700     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F19,	'F', '9',
1701     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F20,	'F', 'A',
1702 
1703     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F21,	'F', 'B',
1704     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F22,	'F', 'C',
1705     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F23,	'F', 'D',
1706     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F24,	'F', 'E',
1707     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F25,	'F', 'F',
1708     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F26,	'F', 'G',
1709     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F27,	'F', 'H',
1710     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F28,	'F', 'I',
1711     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F29,	'F', 'J',
1712     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F30,	'F', 'K',
1713 
1714     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F31,	'F', 'L',
1715     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F32,	'F', 'M',
1716     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F33,	'F', 'N',
1717     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F34,	'F', 'O',
1718     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F35,	'F', 'P',
1719     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F36,	'F', 'Q',
1720     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F37,	'F', 'R',
1721 
1722 							    // TAB pseudo code
1723     MOD_MASK_SHIFT, 'k', 'B',			KS_EXTRA, (int)KE_TAB,
1724 
1725     NUL
1726 };
1727 
1728 static struct key_name_entry
1729 {
1730     int	    key;	// Special key code or ascii value
1731     char_u  *name;	// Name of key
1732 } key_names_table[] =
1733 {
1734     {' ',		(char_u *)"Space"},
1735     {TAB,		(char_u *)"Tab"},
1736     {K_TAB,		(char_u *)"Tab"},
1737     {NL,		(char_u *)"NL"},
1738     {NL,		(char_u *)"NewLine"},	// Alternative name
1739     {NL,		(char_u *)"LineFeed"},	// Alternative name
1740     {NL,		(char_u *)"LF"},	// Alternative name
1741     {CAR,		(char_u *)"CR"},
1742     {CAR,		(char_u *)"Return"},	// Alternative name
1743     {CAR,		(char_u *)"Enter"},	// Alternative name
1744     {K_BS,		(char_u *)"BS"},
1745     {K_BS,		(char_u *)"BackSpace"},	// Alternative name
1746     {ESC,		(char_u *)"Esc"},
1747     {CSI,		(char_u *)"CSI"},
1748     {K_CSI,		(char_u *)"xCSI"},
1749     {'|',		(char_u *)"Bar"},
1750     {'\\',		(char_u *)"Bslash"},
1751     {K_DEL,		(char_u *)"Del"},
1752     {K_DEL,		(char_u *)"Delete"},	// Alternative name
1753     {K_KDEL,		(char_u *)"kDel"},
1754     {K_UP,		(char_u *)"Up"},
1755     {K_DOWN,		(char_u *)"Down"},
1756     {K_LEFT,		(char_u *)"Left"},
1757     {K_RIGHT,		(char_u *)"Right"},
1758     {K_XUP,		(char_u *)"xUp"},
1759     {K_XDOWN,		(char_u *)"xDown"},
1760     {K_XLEFT,		(char_u *)"xLeft"},
1761     {K_XRIGHT,		(char_u *)"xRight"},
1762     {K_PS,		(char_u *)"PasteStart"},
1763     {K_PE,		(char_u *)"PasteEnd"},
1764 
1765     {K_F1,		(char_u *)"F1"},
1766     {K_F2,		(char_u *)"F2"},
1767     {K_F3,		(char_u *)"F3"},
1768     {K_F4,		(char_u *)"F4"},
1769     {K_F5,		(char_u *)"F5"},
1770     {K_F6,		(char_u *)"F6"},
1771     {K_F7,		(char_u *)"F7"},
1772     {K_F8,		(char_u *)"F8"},
1773     {K_F9,		(char_u *)"F9"},
1774     {K_F10,		(char_u *)"F10"},
1775 
1776     {K_F11,		(char_u *)"F11"},
1777     {K_F12,		(char_u *)"F12"},
1778     {K_F13,		(char_u *)"F13"},
1779     {K_F14,		(char_u *)"F14"},
1780     {K_F15,		(char_u *)"F15"},
1781     {K_F16,		(char_u *)"F16"},
1782     {K_F17,		(char_u *)"F17"},
1783     {K_F18,		(char_u *)"F18"},
1784     {K_F19,		(char_u *)"F19"},
1785     {K_F20,		(char_u *)"F20"},
1786 
1787     {K_F21,		(char_u *)"F21"},
1788     {K_F22,		(char_u *)"F22"},
1789     {K_F23,		(char_u *)"F23"},
1790     {K_F24,		(char_u *)"F24"},
1791     {K_F25,		(char_u *)"F25"},
1792     {K_F26,		(char_u *)"F26"},
1793     {K_F27,		(char_u *)"F27"},
1794     {K_F28,		(char_u *)"F28"},
1795     {K_F29,		(char_u *)"F29"},
1796     {K_F30,		(char_u *)"F30"},
1797 
1798     {K_F31,		(char_u *)"F31"},
1799     {K_F32,		(char_u *)"F32"},
1800     {K_F33,		(char_u *)"F33"},
1801     {K_F34,		(char_u *)"F34"},
1802     {K_F35,		(char_u *)"F35"},
1803     {K_F36,		(char_u *)"F36"},
1804     {K_F37,		(char_u *)"F37"},
1805 
1806     {K_XF1,		(char_u *)"xF1"},
1807     {K_XF2,		(char_u *)"xF2"},
1808     {K_XF3,		(char_u *)"xF3"},
1809     {K_XF4,		(char_u *)"xF4"},
1810 
1811     {K_HELP,		(char_u *)"Help"},
1812     {K_UNDO,		(char_u *)"Undo"},
1813     {K_INS,		(char_u *)"Insert"},
1814     {K_INS,		(char_u *)"Ins"},	// Alternative name
1815     {K_KINS,		(char_u *)"kInsert"},
1816     {K_HOME,		(char_u *)"Home"},
1817     {K_KHOME,		(char_u *)"kHome"},
1818     {K_XHOME,		(char_u *)"xHome"},
1819     {K_ZHOME,		(char_u *)"zHome"},
1820     {K_END,		(char_u *)"End"},
1821     {K_KEND,		(char_u *)"kEnd"},
1822     {K_XEND,		(char_u *)"xEnd"},
1823     {K_ZEND,		(char_u *)"zEnd"},
1824     {K_PAGEUP,		(char_u *)"PageUp"},
1825     {K_PAGEDOWN,	(char_u *)"PageDown"},
1826     {K_KPAGEUP,		(char_u *)"kPageUp"},
1827     {K_KPAGEDOWN,	(char_u *)"kPageDown"},
1828 
1829     {K_KPLUS,		(char_u *)"kPlus"},
1830     {K_KMINUS,		(char_u *)"kMinus"},
1831     {K_KDIVIDE,		(char_u *)"kDivide"},
1832     {K_KMULTIPLY,	(char_u *)"kMultiply"},
1833     {K_KENTER,		(char_u *)"kEnter"},
1834     {K_KPOINT,		(char_u *)"kPoint"},
1835 
1836     {K_K0,		(char_u *)"k0"},
1837     {K_K1,		(char_u *)"k1"},
1838     {K_K2,		(char_u *)"k2"},
1839     {K_K3,		(char_u *)"k3"},
1840     {K_K4,		(char_u *)"k4"},
1841     {K_K5,		(char_u *)"k5"},
1842     {K_K6,		(char_u *)"k6"},
1843     {K_K7,		(char_u *)"k7"},
1844     {K_K8,		(char_u *)"k8"},
1845     {K_K9,		(char_u *)"k9"},
1846 
1847     {'<',		(char_u *)"lt"},
1848 
1849     {K_MOUSE,		(char_u *)"Mouse"},
1850 #ifdef FEAT_MOUSE_NET
1851     {K_NETTERM_MOUSE,	(char_u *)"NetMouse"},
1852 #endif
1853 #ifdef FEAT_MOUSE_DEC
1854     {K_DEC_MOUSE,	(char_u *)"DecMouse"},
1855 #endif
1856 #ifdef FEAT_MOUSE_JSB
1857     {K_JSBTERM_MOUSE,	(char_u *)"JsbMouse"},
1858 #endif
1859 #ifdef FEAT_MOUSE_PTERM
1860     {K_PTERM_MOUSE,	(char_u *)"PtermMouse"},
1861 #endif
1862 #ifdef FEAT_MOUSE_URXVT
1863     {K_URXVT_MOUSE,	(char_u *)"UrxvtMouse"},
1864 #endif
1865     {K_SGR_MOUSE,	(char_u *)"SgrMouse"},
1866     {K_SGR_MOUSERELEASE, (char_u *)"SgrMouseRelease"},
1867     {K_LEFTMOUSE,	(char_u *)"LeftMouse"},
1868     {K_LEFTMOUSE_NM,	(char_u *)"LeftMouseNM"},
1869     {K_LEFTDRAG,	(char_u *)"LeftDrag"},
1870     {K_LEFTRELEASE,	(char_u *)"LeftRelease"},
1871     {K_LEFTRELEASE_NM,	(char_u *)"LeftReleaseNM"},
1872     {K_MOUSEMOVE,	(char_u *)"MouseMove"},
1873     {K_MIDDLEMOUSE,	(char_u *)"MiddleMouse"},
1874     {K_MIDDLEDRAG,	(char_u *)"MiddleDrag"},
1875     {K_MIDDLERELEASE,	(char_u *)"MiddleRelease"},
1876     {K_RIGHTMOUSE,	(char_u *)"RightMouse"},
1877     {K_RIGHTDRAG,	(char_u *)"RightDrag"},
1878     {K_RIGHTRELEASE,	(char_u *)"RightRelease"},
1879     {K_MOUSEDOWN,	(char_u *)"ScrollWheelUp"},
1880     {K_MOUSEUP,		(char_u *)"ScrollWheelDown"},
1881     {K_MOUSELEFT,	(char_u *)"ScrollWheelRight"},
1882     {K_MOUSERIGHT,	(char_u *)"ScrollWheelLeft"},
1883     {K_MOUSEDOWN,	(char_u *)"MouseDown"}, // OBSOLETE: Use
1884     {K_MOUSEUP,		(char_u *)"MouseUp"},	// ScrollWheelXXX instead
1885     {K_X1MOUSE,		(char_u *)"X1Mouse"},
1886     {K_X1DRAG,		(char_u *)"X1Drag"},
1887     {K_X1RELEASE,		(char_u *)"X1Release"},
1888     {K_X2MOUSE,		(char_u *)"X2Mouse"},
1889     {K_X2DRAG,		(char_u *)"X2Drag"},
1890     {K_X2RELEASE,		(char_u *)"X2Release"},
1891     {K_DROP,		(char_u *)"Drop"},
1892     {K_ZERO,		(char_u *)"Nul"},
1893 #ifdef FEAT_EVAL
1894     {K_SNR,		(char_u *)"SNR"},
1895 #endif
1896     {K_PLUG,		(char_u *)"Plug"},
1897     {K_CURSORHOLD,	(char_u *)"CursorHold"},
1898     {K_IGNORE,		(char_u *)"Ignore"},
1899     {K_COMMAND,		(char_u *)"Cmd"},
1900     {K_FOCUSGAINED,	(char_u *)"FocusGained"},
1901     {K_FOCUSLOST,	(char_u *)"FocusLost"},
1902     {0,			NULL}
1903     // NOTE: When adding a long name update MAX_KEY_NAME_LEN.
1904 };
1905 
1906 #define KEY_NAMES_TABLE_LEN ARRAY_LENGTH(key_names_table)
1907 
1908 /*
1909  * Return the modifier mask bit (MOD_MASK_*) which corresponds to the given
1910  * modifier name ('S' for Shift, 'C' for Ctrl etc).
1911  */
1912     static int
1913 name_to_mod_mask(int c)
1914 {
1915     int	    i;
1916 
1917     c = TOUPPER_ASC(c);
1918     for (i = 0; mod_mask_table[i].mod_mask != 0; i++)
1919 	if (c == mod_mask_table[i].name)
1920 	    return mod_mask_table[i].mod_flag;
1921     return 0;
1922 }
1923 
1924 /*
1925  * Check if if there is a special key code for "key" that includes the
1926  * modifiers specified.
1927  */
1928     int
1929 simplify_key(int key, int *modifiers)
1930 {
1931     int	    i;
1932     int	    key0;
1933     int	    key1;
1934 
1935     if (*modifiers & (MOD_MASK_SHIFT | MOD_MASK_CTRL | MOD_MASK_ALT))
1936     {
1937 	// TAB is a special case
1938 	if (key == TAB && (*modifiers & MOD_MASK_SHIFT))
1939 	{
1940 	    *modifiers &= ~MOD_MASK_SHIFT;
1941 	    return K_S_TAB;
1942 	}
1943 	key0 = KEY2TERMCAP0(key);
1944 	key1 = KEY2TERMCAP1(key);
1945 	for (i = 0; modifier_keys_table[i] != NUL; i += MOD_KEYS_ENTRY_SIZE)
1946 	    if (key0 == modifier_keys_table[i + 3]
1947 		    && key1 == modifier_keys_table[i + 4]
1948 		    && (*modifiers & modifier_keys_table[i]))
1949 	    {
1950 		*modifiers &= ~modifier_keys_table[i];
1951 		return TERMCAP2KEY(modifier_keys_table[i + 1],
1952 						   modifier_keys_table[i + 2]);
1953 	    }
1954     }
1955     return key;
1956 }
1957 
1958 /*
1959  * Change <xHome> to <Home>, <xUp> to <Up>, etc.
1960  */
1961     int
1962 handle_x_keys(int key)
1963 {
1964     switch (key)
1965     {
1966 	case K_XUP:	return K_UP;
1967 	case K_XDOWN:	return K_DOWN;
1968 	case K_XLEFT:	return K_LEFT;
1969 	case K_XRIGHT:	return K_RIGHT;
1970 	case K_XHOME:	return K_HOME;
1971 	case K_ZHOME:	return K_HOME;
1972 	case K_XEND:	return K_END;
1973 	case K_ZEND:	return K_END;
1974 	case K_XF1:	return K_F1;
1975 	case K_XF2:	return K_F2;
1976 	case K_XF3:	return K_F3;
1977 	case K_XF4:	return K_F4;
1978 	case K_S_XF1:	return K_S_F1;
1979 	case K_S_XF2:	return K_S_F2;
1980 	case K_S_XF3:	return K_S_F3;
1981 	case K_S_XF4:	return K_S_F4;
1982     }
1983     return key;
1984 }
1985 
1986 /*
1987  * Return a string which contains the name of the given key when the given
1988  * modifiers are down.
1989  */
1990     char_u *
1991 get_special_key_name(int c, int modifiers)
1992 {
1993     static char_u string[MAX_KEY_NAME_LEN + 1];
1994 
1995     int	    i, idx;
1996     int	    table_idx;
1997     char_u  *s;
1998 
1999     string[0] = '<';
2000     idx = 1;
2001 
2002     // Key that stands for a normal character.
2003     if (IS_SPECIAL(c) && KEY2TERMCAP0(c) == KS_KEY)
2004 	c = KEY2TERMCAP1(c);
2005 
2006     /*
2007      * Translate shifted special keys into unshifted keys and set modifier.
2008      * Same for CTRL and ALT modifiers.
2009      */
2010     if (IS_SPECIAL(c))
2011     {
2012 	for (i = 0; modifier_keys_table[i] != 0; i += MOD_KEYS_ENTRY_SIZE)
2013 	    if (       KEY2TERMCAP0(c) == (int)modifier_keys_table[i + 1]
2014 		    && (int)KEY2TERMCAP1(c) == (int)modifier_keys_table[i + 2])
2015 	    {
2016 		modifiers |= modifier_keys_table[i];
2017 		c = TERMCAP2KEY(modifier_keys_table[i + 3],
2018 						   modifier_keys_table[i + 4]);
2019 		break;
2020 	    }
2021     }
2022 
2023     // try to find the key in the special key table
2024     table_idx = find_special_key_in_table(c);
2025 
2026     /*
2027      * When not a known special key, and not a printable character, try to
2028      * extract modifiers.
2029      */
2030     if (c > 0 && (*mb_char2len)(c) == 1)
2031     {
2032 	if (table_idx < 0
2033 		&& (!vim_isprintc(c) || (c & 0x7f) == ' ')
2034 		&& (c & 0x80))
2035 	{
2036 	    c &= 0x7f;
2037 	    modifiers |= MOD_MASK_ALT;
2038 	    // try again, to find the un-alted key in the special key table
2039 	    table_idx = find_special_key_in_table(c);
2040 	}
2041 	if (table_idx < 0 && !vim_isprintc(c) && c < ' ')
2042 	{
2043 #ifdef EBCDIC
2044 	    c = CtrlChar(c);
2045 #else
2046 	    c += '@';
2047 #endif
2048 	    modifiers |= MOD_MASK_CTRL;
2049 	}
2050     }
2051 
2052     // translate the modifier into a string
2053     for (i = 0; mod_mask_table[i].name != 'A'; i++)
2054 	if ((modifiers & mod_mask_table[i].mod_mask)
2055 						== mod_mask_table[i].mod_flag)
2056 	{
2057 	    string[idx++] = mod_mask_table[i].name;
2058 	    string[idx++] = (char_u)'-';
2059 	}
2060 
2061     if (table_idx < 0)		// unknown special key, may output t_xx
2062     {
2063 	if (IS_SPECIAL(c))
2064 	{
2065 	    string[idx++] = 't';
2066 	    string[idx++] = '_';
2067 	    string[idx++] = KEY2TERMCAP0(c);
2068 	    string[idx++] = KEY2TERMCAP1(c);
2069 	}
2070 	// Not a special key, only modifiers, output directly
2071 	else
2072 	{
2073 	    if (has_mbyte && (*mb_char2len)(c) > 1)
2074 		idx += (*mb_char2bytes)(c, string + idx);
2075 	    else if (vim_isprintc(c))
2076 		string[idx++] = c;
2077 	    else
2078 	    {
2079 		s = transchar(c);
2080 		while (*s)
2081 		    string[idx++] = *s++;
2082 	    }
2083 	}
2084     }
2085     else		// use name of special key
2086     {
2087 	size_t len = STRLEN(key_names_table[table_idx].name);
2088 
2089 	if (len + idx + 2 <= MAX_KEY_NAME_LEN)
2090 	{
2091 	    STRCPY(string + idx, key_names_table[table_idx].name);
2092 	    idx += (int)len;
2093 	}
2094     }
2095     string[idx++] = '>';
2096     string[idx] = NUL;
2097     return string;
2098 }
2099 
2100 /*
2101  * Try translating a <> name at (*srcp)[] to dst[].
2102  * Return the number of characters added to dst[], zero for no match.
2103  * If there is a match, srcp is advanced to after the <> name.
2104  * dst[] must be big enough to hold the result (up to six characters)!
2105  */
2106     int
2107 trans_special(
2108     char_u	**srcp,
2109     char_u	*dst,
2110     int		flags,		// FSK_ values
2111     int		*did_simplify)  // FSK_SIMPLIFY and found <C-H> or <A-x>
2112 {
2113     int		modifiers = 0;
2114     int		key;
2115 
2116     key = find_special_key(srcp, &modifiers, flags, did_simplify);
2117     if (key == 0)
2118 	return 0;
2119 
2120     return special_to_buf(key, modifiers, flags & FSK_KEYCODE, dst);
2121 }
2122 
2123 /*
2124  * Put the character sequence for "key" with "modifiers" into "dst" and return
2125  * the resulting length.
2126  * When "keycode" is TRUE prefer key code, e.g. K_DEL instead of DEL.
2127  * The sequence is not NUL terminated.
2128  * This is how characters in a string are encoded.
2129  */
2130     int
2131 special_to_buf(int key, int modifiers, int keycode, char_u *dst)
2132 {
2133     int		dlen = 0;
2134 
2135     // Put the appropriate modifier in a string
2136     if (modifiers != 0)
2137     {
2138 	dst[dlen++] = K_SPECIAL;
2139 	dst[dlen++] = KS_MODIFIER;
2140 	dst[dlen++] = modifiers;
2141     }
2142 
2143     if (IS_SPECIAL(key))
2144     {
2145 	dst[dlen++] = K_SPECIAL;
2146 	dst[dlen++] = KEY2TERMCAP0(key);
2147 	dst[dlen++] = KEY2TERMCAP1(key);
2148     }
2149     else if (has_mbyte && !keycode)
2150 	dlen += (*mb_char2bytes)(key, dst + dlen);
2151     else if (keycode)
2152 	dlen = (int)(add_char2buf(key, dst + dlen) - dst);
2153     else
2154 	dst[dlen++] = key;
2155 
2156     return dlen;
2157 }
2158 
2159 /*
2160  * Try translating a <> name at (*srcp)[], return the key and modifiers.
2161  * srcp is advanced to after the <> name.
2162  * returns 0 if there is no match.
2163  */
2164     int
2165 find_special_key(
2166     char_u	**srcp,
2167     int		*modp,
2168     int		flags,		// FSK_ values
2169     int		*did_simplify)  // found <C-H> or <A-x>
2170 {
2171     char_u	*last_dash;
2172     char_u	*end_of_name;
2173     char_u	*src;
2174     char_u	*bp;
2175     int		in_string = flags & FSK_IN_STRING;
2176     int		modifiers;
2177     int		bit;
2178     int		key;
2179     uvarnumber_T	n;
2180     int		l;
2181 
2182     src = *srcp;
2183     if (src[0] != '<')
2184 	return 0;
2185     if (src[1] == '*')	    // <*xxx>: do not simplify
2186 	++src;
2187 
2188     // Find end of modifier list
2189     last_dash = src;
2190     for (bp = src + 1; *bp == '-' || vim_isNormalIDc(*bp); bp++)
2191     {
2192 	if (*bp == '-')
2193 	{
2194 	    last_dash = bp;
2195 	    if (bp[1] != NUL)
2196 	    {
2197 		if (has_mbyte)
2198 		    l = mb_ptr2len(bp + 1);
2199 		else
2200 		    l = 1;
2201 		// Anything accepted, like <C-?>.
2202 		// <C-"> or <M-"> are not special in strings as " is
2203 		// the string delimiter. With a backslash it works: <M-\">
2204 		if (!(in_string && bp[1] == '"') && bp[l + 1] == '>')
2205 		    bp += l;
2206 		else if (in_string && bp[1] == '\\' && bp[2] == '"'
2207 							   && bp[3] == '>')
2208 		    bp += 2;
2209 	    }
2210 	}
2211 	if (bp[0] == 't' && bp[1] == '_' && bp[2] && bp[3])
2212 	    bp += 3;	// skip t_xx, xx may be '-' or '>'
2213 	else if (STRNICMP(bp, "char-", 5) == 0)
2214 	{
2215 	    vim_str2nr(bp + 5, NULL, &l, STR2NR_ALL, NULL, NULL, 0, TRUE);
2216 	    if (l == 0)
2217 	    {
2218 		emsg(_(e_invarg));
2219 		return 0;
2220 	    }
2221 	    bp += l + 5;
2222 	    break;
2223 	}
2224     }
2225 
2226     if (*bp == '>')	// found matching '>'
2227     {
2228 	end_of_name = bp + 1;
2229 
2230 	// Which modifiers are given?
2231 	modifiers = 0x0;
2232 	for (bp = src + 1; bp < last_dash; bp++)
2233 	{
2234 	    if (*bp != '-')
2235 	    {
2236 		bit = name_to_mod_mask(*bp);
2237 		if (bit == 0x0)
2238 		    break;	// Illegal modifier name
2239 		modifiers |= bit;
2240 	    }
2241 	}
2242 
2243 	/*
2244 	 * Legal modifier name.
2245 	 */
2246 	if (bp >= last_dash)
2247 	{
2248 	    if (STRNICMP(last_dash + 1, "char-", 5) == 0
2249 						 && VIM_ISDIGIT(last_dash[6]))
2250 	    {
2251 		// <Char-123> or <Char-033> or <Char-0x33>
2252 		vim_str2nr(last_dash + 6, NULL, &l, STR2NR_ALL, NULL,
2253 								  &n, 0, TRUE);
2254 		if (l == 0)
2255 		{
2256 		    emsg(_(e_invarg));
2257 		    return 0;
2258 		}
2259 		key = (int)n;
2260 	    }
2261 	    else
2262 	    {
2263 		int off = 1;
2264 
2265 		// Modifier with single letter, or special key name.
2266 		if (in_string && last_dash[1] == '\\' && last_dash[2] == '"')
2267 		    off = 2;
2268 		if (has_mbyte)
2269 		    l = mb_ptr2len(last_dash + off);
2270 		else
2271 		    l = 1;
2272 		if (modifiers != 0 && last_dash[l + off] == '>')
2273 		    key = PTR2CHAR(last_dash + off);
2274 		else
2275 		{
2276 		    key = get_special_key_code(last_dash + off);
2277 		    if (!(flags & FSK_KEEP_X_KEY))
2278 			key = handle_x_keys(key);
2279 		}
2280 	    }
2281 
2282 	    /*
2283 	     * get_special_key_code() may return NUL for invalid
2284 	     * special key name.
2285 	     */
2286 	    if (key != NUL)
2287 	    {
2288 		/*
2289 		 * Only use a modifier when there is no special key code that
2290 		 * includes the modifier.
2291 		 */
2292 		key = simplify_key(key, &modifiers);
2293 
2294 		if (!(flags & FSK_KEYCODE))
2295 		{
2296 		    // don't want keycode, use single byte code
2297 		    if (key == K_BS)
2298 			key = BS;
2299 		    else if (key == K_DEL || key == K_KDEL)
2300 			key = DEL;
2301 		}
2302 
2303 		// Normal Key with modifier: Try to make a single byte code.
2304 		if (!IS_SPECIAL(key))
2305 		    key = extract_modifiers(key, &modifiers,
2306 					   flags & FSK_SIMPLIFY, did_simplify);
2307 
2308 		*modp = modifiers;
2309 		*srcp = end_of_name;
2310 		return key;
2311 	    }
2312 	}
2313     }
2314     return 0;
2315 }
2316 
2317 
2318 /*
2319  * Some keys are used with Ctrl without Shift and are still expected to be
2320  * mapped as if Shift was pressed:
2321  * CTRL-2 is CTRL-@
2322  * CTRL-6 is CTRL-^
2323  * CTRL-- is CTRL-_
2324  * Also, <C-H> and <C-h> mean the same thing, always use "H".
2325  * Returns the possibly adjusted key.
2326  */
2327     int
2328 may_adjust_key_for_ctrl(int modifiers, int key)
2329 {
2330     if (modifiers & MOD_MASK_CTRL)
2331     {
2332 	if (ASCII_ISALPHA(key))
2333 	    return TOUPPER_ASC(key);
2334 	if (key == '2')
2335 	    return '@';
2336 	if (key == '6')
2337 	    return '^';
2338 	if (key == '-')
2339 	    return '_';
2340     }
2341     return key;
2342 }
2343 
2344 /*
2345  * Some keys already have Shift included, pass them as normal keys.
2346  * When Ctrl is also used <C-H> and <C-S-H> are different, but <C-S-{> should
2347  * be <C-{>.  Same for <C-S-}> and <C-S-|>.
2348  * Also for <A-S-a> and <M-S-a>.
2349  * This includes all printable ASCII characters except numbers and a-z.
2350  */
2351     int
2352 may_remove_shift_modifier(int modifiers, int key)
2353 {
2354     if ((modifiers == MOD_MASK_SHIFT
2355 		|| modifiers == (MOD_MASK_SHIFT | MOD_MASK_ALT)
2356 		|| modifiers == (MOD_MASK_SHIFT | MOD_MASK_META))
2357 	    && ((key >= '!' && key <= '/')
2358 		|| (key >= ':' && key <= 'Z')
2359 		|| (key >= '[' && key <= '`')
2360 		|| (key >= '{' && key <= '~')))
2361 	return modifiers & ~MOD_MASK_SHIFT;
2362 
2363     if (modifiers == (MOD_MASK_SHIFT | MOD_MASK_CTRL)
2364 		&& (key == '{' || key == '}' || key == '|'))
2365 	return modifiers & ~MOD_MASK_SHIFT;
2366 
2367     return modifiers;
2368 }
2369 
2370 /*
2371  * Try to include modifiers in the key.
2372  * Changes "Shift-a" to 'A', "Alt-A" to 0xc0, etc.
2373  * When "simplify" is FALSE don't do Ctrl and Alt.
2374  * When "simplify" is TRUE and Ctrl or Alt is removed from modifiers set
2375  * "did_simplify" when it's not NULL.
2376  */
2377     int
2378 extract_modifiers(int key, int *modp, int simplify, int *did_simplify)
2379 {
2380     int	modifiers = *modp;
2381 
2382 #ifdef MACOS_X
2383     // Command-key really special, no fancynest
2384     if (!(modifiers & MOD_MASK_CMD))
2385 #endif
2386     if ((modifiers & MOD_MASK_SHIFT) && ASCII_ISALPHA(key))
2387     {
2388 	key = TOUPPER_ASC(key);
2389 	// With <C-S-a> we keep the shift modifier.
2390 	// With <S-a>, <A-S-a> and <S-A> we don't keep the shift modifier.
2391 	if (simplify || modifiers == MOD_MASK_SHIFT
2392 		|| modifiers == (MOD_MASK_SHIFT | MOD_MASK_ALT)
2393 		|| modifiers == (MOD_MASK_SHIFT | MOD_MASK_META))
2394 	    modifiers &= ~MOD_MASK_SHIFT;
2395     }
2396 
2397     // <C-H> and <C-h> mean the same thing, always use "H"
2398     if ((modifiers & MOD_MASK_CTRL) && ASCII_ISALPHA(key))
2399 	key = TOUPPER_ASC(key);
2400 
2401     if (simplify && (modifiers & MOD_MASK_CTRL)
2402 #ifdef EBCDIC
2403 	    // TODO: EBCDIC Better use:
2404 	    // && (Ctrl_chr(key) || key == '?')
2405 	    // ???
2406 	    && strchr("?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_", key)
2407 						       != NULL
2408 #else
2409 	    && ((key >= '?' && key <= '_') || ASCII_ISALPHA(key))
2410 #endif
2411 	    )
2412     {
2413 	key = Ctrl_chr(key);
2414 	modifiers &= ~MOD_MASK_CTRL;
2415 	// <C-@> is <Nul>
2416 	if (key == 0)
2417 	    key = K_ZERO;
2418 	if (did_simplify != NULL)
2419 	    *did_simplify = TRUE;
2420     }
2421 
2422 #ifdef MACOS_X
2423     // Command-key really special, no fancynest
2424     if (!(modifiers & MOD_MASK_CMD))
2425 #endif
2426     if (simplify && (modifiers & MOD_MASK_ALT) && key < 0x80
2427 	    && !enc_dbcs)		// avoid creating a lead byte
2428     {
2429 	key |= 0x80;
2430 	modifiers &= ~MOD_MASK_ALT;	// remove the META modifier
2431 	if (did_simplify != NULL)
2432 	    *did_simplify = TRUE;
2433     }
2434 
2435     *modp = modifiers;
2436     return key;
2437 }
2438 
2439 /*
2440  * Try to find key "c" in the special key table.
2441  * Return the index when found, -1 when not found.
2442  */
2443     int
2444 find_special_key_in_table(int c)
2445 {
2446     int	    i;
2447 
2448     for (i = 0; key_names_table[i].name != NULL; i++)
2449 	if (c == key_names_table[i].key)
2450 	    break;
2451     if (key_names_table[i].name == NULL)
2452 	i = -1;
2453     return i;
2454 }
2455 
2456 /*
2457  * Find the special key with the given name (the given string does not have to
2458  * end with NUL, the name is assumed to end before the first non-idchar).
2459  * If the name starts with "t_" the next two characters are interpreted as a
2460  * termcap name.
2461  * Return the key code, or 0 if not found.
2462  */
2463     int
2464 get_special_key_code(char_u *name)
2465 {
2466     char_u  *table_name;
2467     char_u  string[3];
2468     int	    i, j;
2469 
2470     /*
2471      * If it's <t_xx> we get the code for xx from the termcap
2472      */
2473     if (name[0] == 't' && name[1] == '_' && name[2] != NUL && name[3] != NUL)
2474     {
2475 	string[0] = name[2];
2476 	string[1] = name[3];
2477 	string[2] = NUL;
2478 	if (add_termcap_entry(string, FALSE) == OK)
2479 	    return TERMCAP2KEY(name[2], name[3]);
2480     }
2481     else
2482 	for (i = 0; key_names_table[i].name != NULL; i++)
2483 	{
2484 	    table_name = key_names_table[i].name;
2485 	    for (j = 0; vim_isNormalIDc(name[j]) && table_name[j] != NUL; j++)
2486 		if (TOLOWER_ASC(table_name[j]) != TOLOWER_ASC(name[j]))
2487 		    break;
2488 	    if (!vim_isNormalIDc(name[j]) && table_name[j] == NUL)
2489 		return key_names_table[i].key;
2490 	}
2491     return 0;
2492 }
2493 
2494     char_u *
2495 get_key_name(int i)
2496 {
2497     if (i >= (int)KEY_NAMES_TABLE_LEN)
2498 	return NULL;
2499     return  key_names_table[i].name;
2500 }
2501 
2502 /*
2503  * Return the current end-of-line type: EOL_DOS, EOL_UNIX or EOL_MAC.
2504  */
2505     int
2506 get_fileformat(buf_T *buf)
2507 {
2508     int		c = *buf->b_p_ff;
2509 
2510     if (buf->b_p_bin || c == 'u')
2511 	return EOL_UNIX;
2512     if (c == 'm')
2513 	return EOL_MAC;
2514     return EOL_DOS;
2515 }
2516 
2517 /*
2518  * Like get_fileformat(), but override 'fileformat' with "p" for "++opt=val"
2519  * argument.
2520  */
2521     int
2522 get_fileformat_force(
2523     buf_T	*buf,
2524     exarg_T	*eap)	    // can be NULL!
2525 {
2526     int		c;
2527 
2528     if (eap != NULL && eap->force_ff != 0)
2529 	c = eap->force_ff;
2530     else
2531     {
2532 	if ((eap != NULL && eap->force_bin != 0)
2533 			       ? (eap->force_bin == FORCE_BIN) : buf->b_p_bin)
2534 	    return EOL_UNIX;
2535 	c = *buf->b_p_ff;
2536     }
2537     if (c == 'u')
2538 	return EOL_UNIX;
2539     if (c == 'm')
2540 	return EOL_MAC;
2541     return EOL_DOS;
2542 }
2543 
2544 /*
2545  * Set the current end-of-line type to EOL_DOS, EOL_UNIX or EOL_MAC.
2546  * Sets both 'textmode' and 'fileformat'.
2547  * Note: Does _not_ set global value of 'textmode'!
2548  */
2549     void
2550 set_fileformat(
2551     int		t,
2552     int		opt_flags)	// OPT_LOCAL and/or OPT_GLOBAL
2553 {
2554     char	*p = NULL;
2555 
2556     switch (t)
2557     {
2558     case EOL_DOS:
2559 	p = FF_DOS;
2560 	curbuf->b_p_tx = TRUE;
2561 	break;
2562     case EOL_UNIX:
2563 	p = FF_UNIX;
2564 	curbuf->b_p_tx = FALSE;
2565 	break;
2566     case EOL_MAC:
2567 	p = FF_MAC;
2568 	curbuf->b_p_tx = FALSE;
2569 	break;
2570     }
2571     if (p != NULL)
2572 	set_string_option_direct((char_u *)"ff", -1, (char_u *)p,
2573 						     OPT_FREE | opt_flags, 0);
2574 
2575     // This may cause the buffer to become (un)modified.
2576     check_status(curbuf);
2577     redraw_tabline = TRUE;
2578 #ifdef FEAT_TITLE
2579     need_maketitle = TRUE;	    // set window title later
2580 #endif
2581 }
2582 
2583 /*
2584  * Return the default fileformat from 'fileformats'.
2585  */
2586     int
2587 default_fileformat(void)
2588 {
2589     switch (*p_ffs)
2590     {
2591 	case 'm':   return EOL_MAC;
2592 	case 'd':   return EOL_DOS;
2593     }
2594     return EOL_UNIX;
2595 }
2596 
2597 /*
2598  * Call shell.	Calls mch_call_shell, with 'shellxquote' added.
2599  */
2600     int
2601 call_shell(char_u *cmd, int opt)
2602 {
2603     char_u	*ncmd;
2604     int		retval;
2605 #ifdef FEAT_PROFILE
2606     proftime_T	wait_time;
2607 #endif
2608 
2609     if (p_verbose > 3)
2610     {
2611 	verbose_enter();
2612 	smsg(_("Calling shell to execute: \"%s\""), cmd == NULL ? p_sh : cmd);
2613 	out_char('\n');
2614 	cursor_on();
2615 	verbose_leave();
2616     }
2617 
2618 #ifdef FEAT_PROFILE
2619     if (do_profiling == PROF_YES)
2620 	prof_child_enter(&wait_time);
2621 #endif
2622 
2623     if (*p_sh == NUL)
2624     {
2625 	emsg(_(e_shellempty));
2626 	retval = -1;
2627     }
2628     else
2629     {
2630 #ifdef FEAT_GUI_MSWIN
2631 	// Don't hide the pointer while executing a shell command.
2632 	gui_mch_mousehide(FALSE);
2633 #endif
2634 #ifdef FEAT_GUI
2635 	++hold_gui_events;
2636 #endif
2637 	// The external command may update a tags file, clear cached tags.
2638 	tag_freematch();
2639 
2640 	if (cmd == NULL || *p_sxq == NUL)
2641 	    retval = mch_call_shell(cmd, opt);
2642 	else
2643 	{
2644 	    char_u *ecmd = cmd;
2645 
2646 	    if (*p_sxe != NUL && *p_sxq == '(')
2647 	    {
2648 		ecmd = vim_strsave_escaped_ext(cmd, p_sxe, '^', FALSE);
2649 		if (ecmd == NULL)
2650 		    ecmd = cmd;
2651 	    }
2652 	    ncmd = alloc(STRLEN(ecmd) + STRLEN(p_sxq) * 2 + 1);
2653 	    if (ncmd != NULL)
2654 	    {
2655 		STRCPY(ncmd, p_sxq);
2656 		STRCAT(ncmd, ecmd);
2657 		// When 'shellxquote' is ( append ).
2658 		// When 'shellxquote' is "( append )".
2659 		STRCAT(ncmd, *p_sxq == '(' ? (char_u *)")"
2660 		    : *p_sxq == '"' && *(p_sxq+1) == '(' ? (char_u *)")\""
2661 		    : p_sxq);
2662 		retval = mch_call_shell(ncmd, opt);
2663 		vim_free(ncmd);
2664 	    }
2665 	    else
2666 		retval = -1;
2667 	    if (ecmd != cmd)
2668 		vim_free(ecmd);
2669 	}
2670 #ifdef FEAT_GUI
2671 	--hold_gui_events;
2672 #endif
2673 	/*
2674 	 * Check the window size, in case it changed while executing the
2675 	 * external command.
2676 	 */
2677 	shell_resized_check();
2678     }
2679 
2680 #ifdef FEAT_EVAL
2681     set_vim_var_nr(VV_SHELL_ERROR, (long)retval);
2682 # ifdef FEAT_PROFILE
2683     if (do_profiling == PROF_YES)
2684 	prof_child_exit(&wait_time);
2685 # endif
2686 #endif
2687 
2688     return retval;
2689 }
2690 
2691 /*
2692  * VISUAL, SELECTMODE and OP_PENDING State are never set, they are equal to
2693  * NORMAL State with a condition.  This function returns the real State.
2694  */
2695     int
2696 get_real_state(void)
2697 {
2698     if (State & NORMAL)
2699     {
2700 	if (VIsual_active)
2701 	{
2702 	    if (VIsual_select)
2703 		return SELECTMODE;
2704 	    return VISUAL;
2705 	}
2706 	else if (finish_op)
2707 	    return OP_PENDING;
2708     }
2709     return State;
2710 }
2711 
2712 /*
2713  * Return TRUE if "p" points to just after a path separator.
2714  * Takes care of multi-byte characters.
2715  * "b" must point to the start of the file name
2716  */
2717     int
2718 after_pathsep(char_u *b, char_u *p)
2719 {
2720     return p > b && vim_ispathsep(p[-1])
2721 			     && (!has_mbyte || (*mb_head_off)(b, p - 1) == 0);
2722 }
2723 
2724 /*
2725  * Return TRUE if file names "f1" and "f2" are in the same directory.
2726  * "f1" may be a short name, "f2" must be a full path.
2727  */
2728     int
2729 same_directory(char_u *f1, char_u *f2)
2730 {
2731     char_u	ffname[MAXPATHL];
2732     char_u	*t1;
2733     char_u	*t2;
2734 
2735     // safety check
2736     if (f1 == NULL || f2 == NULL)
2737 	return FALSE;
2738 
2739     (void)vim_FullName(f1, ffname, MAXPATHL, FALSE);
2740     t1 = gettail_sep(ffname);
2741     t2 = gettail_sep(f2);
2742     return (t1 - ffname == t2 - f2
2743 	     && pathcmp((char *)ffname, (char *)f2, (int)(t1 - ffname)) == 0);
2744 }
2745 
2746 #if defined(FEAT_SESSION) || defined(FEAT_AUTOCHDIR) \
2747 	|| defined(MSWIN) || defined(FEAT_GUI_GTK) \
2748 	|| defined(FEAT_NETBEANS_INTG) \
2749 	|| defined(PROTO)
2750 /*
2751  * Change to a file's directory.
2752  * Caller must call shorten_fnames()!
2753  * Return OK or FAIL.
2754  */
2755     int
2756 vim_chdirfile(char_u *fname, char *trigger_autocmd)
2757 {
2758     char_u	old_dir[MAXPATHL];
2759     char_u	new_dir[MAXPATHL];
2760     int		res;
2761 
2762     if (mch_dirname(old_dir, MAXPATHL) != OK)
2763 	*old_dir = NUL;
2764 
2765     vim_strncpy(new_dir, fname, MAXPATHL - 1);
2766     *gettail_sep(new_dir) = NUL;
2767 
2768     if (pathcmp((char *)old_dir, (char *)new_dir, -1) == 0)
2769 	// nothing to do
2770 	res = OK;
2771     else
2772     {
2773 	res = mch_chdir((char *)new_dir) == 0 ? OK : FAIL;
2774 
2775 	if (res == OK && trigger_autocmd != NULL)
2776 	    apply_autocmds(EVENT_DIRCHANGED, (char_u *)trigger_autocmd,
2777 						       new_dir, FALSE, curbuf);
2778     }
2779     return res;
2780 }
2781 #endif
2782 
2783 #if defined(STAT_IGNORES_SLASH) || defined(PROTO)
2784 /*
2785  * Check if "name" ends in a slash and is not a directory.
2786  * Used for systems where stat() ignores a trailing slash on a file name.
2787  * The Vim code assumes a trailing slash is only ignored for a directory.
2788  */
2789     static int
2790 illegal_slash(const char *name)
2791 {
2792     if (name[0] == NUL)
2793 	return FALSE;	    // no file name is not illegal
2794     if (name[strlen(name) - 1] != '/')
2795 	return FALSE;	    // no trailing slash
2796     if (mch_isdir((char_u *)name))
2797 	return FALSE;	    // trailing slash for a directory
2798     return TRUE;
2799 }
2800 
2801 /*
2802  * Special implementation of mch_stat() for Solaris.
2803  */
2804     int
2805 vim_stat(const char *name, stat_T *stp)
2806 {
2807     // On Solaris stat() accepts "file/" as if it was "file".  Return -1 if
2808     // the name ends in "/" and it's not a directory.
2809     return illegal_slash(name) ? -1 : stat(name, stp);
2810 }
2811 #endif
2812 
2813 #if defined(CURSOR_SHAPE) || defined(PROTO)
2814 
2815 /*
2816  * Handling of cursor and mouse pointer shapes in various modes.
2817  */
2818 
2819 cursorentry_T shape_table[SHAPE_IDX_COUNT] =
2820 {
2821     // The values will be filled in from the 'guicursor' and 'mouseshape'
2822     // defaults when Vim starts.
2823     // Adjust the SHAPE_IDX_ defines when making changes!
2824     {0,	0, 0, 700L, 400L, 250L, 0, 0, "n", SHAPE_CURSOR+SHAPE_MOUSE},
2825     {0,	0, 0, 700L, 400L, 250L, 0, 0, "v", SHAPE_CURSOR+SHAPE_MOUSE},
2826     {0,	0, 0, 700L, 400L, 250L, 0, 0, "i", SHAPE_CURSOR+SHAPE_MOUSE},
2827     {0,	0, 0, 700L, 400L, 250L, 0, 0, "r", SHAPE_CURSOR+SHAPE_MOUSE},
2828     {0,	0, 0, 700L, 400L, 250L, 0, 0, "c", SHAPE_CURSOR+SHAPE_MOUSE},
2829     {0,	0, 0, 700L, 400L, 250L, 0, 0, "ci", SHAPE_CURSOR+SHAPE_MOUSE},
2830     {0,	0, 0, 700L, 400L, 250L, 0, 0, "cr", SHAPE_CURSOR+SHAPE_MOUSE},
2831     {0,	0, 0, 700L, 400L, 250L, 0, 0, "o", SHAPE_CURSOR+SHAPE_MOUSE},
2832     {0,	0, 0, 700L, 400L, 250L, 0, 0, "ve", SHAPE_CURSOR+SHAPE_MOUSE},
2833     {0,	0, 0,   0L,   0L,   0L, 0, 0, "e", SHAPE_MOUSE},
2834     {0,	0, 0,   0L,   0L,   0L, 0, 0, "s", SHAPE_MOUSE},
2835     {0,	0, 0,   0L,   0L,   0L, 0, 0, "sd", SHAPE_MOUSE},
2836     {0,	0, 0,   0L,   0L,   0L, 0, 0, "vs", SHAPE_MOUSE},
2837     {0,	0, 0,   0L,   0L,   0L, 0, 0, "vd", SHAPE_MOUSE},
2838     {0,	0, 0,   0L,   0L,   0L, 0, 0, "m", SHAPE_MOUSE},
2839     {0,	0, 0,   0L,   0L,   0L, 0, 0, "ml", SHAPE_MOUSE},
2840     {0,	0, 0, 100L, 100L, 100L, 0, 0, "sm", SHAPE_CURSOR},
2841 };
2842 
2843 #ifdef FEAT_MOUSESHAPE
2844 /*
2845  * Table with names for mouse shapes.  Keep in sync with all the tables for
2846  * mch_set_mouse_shape()!.
2847  */
2848 static char * mshape_names[] =
2849 {
2850     "arrow",	// default, must be the first one
2851     "blank",	// hidden
2852     "beam",
2853     "updown",
2854     "udsizing",
2855     "leftright",
2856     "lrsizing",
2857     "busy",
2858     "no",
2859     "crosshair",
2860     "hand1",
2861     "hand2",
2862     "pencil",
2863     "question",
2864     "rightup-arrow",
2865     "up-arrow",
2866     NULL
2867 };
2868 #endif
2869 
2870 /*
2871  * Parse the 'guicursor' option ("what" is SHAPE_CURSOR) or 'mouseshape'
2872  * ("what" is SHAPE_MOUSE).
2873  * Returns error message for an illegal option, NULL otherwise.
2874  */
2875     char *
2876 parse_shape_opt(int what)
2877 {
2878     char_u	*modep;
2879     char_u	*colonp;
2880     char_u	*commap;
2881     char_u	*slashp;
2882     char_u	*p, *endp;
2883     int		idx = 0;		// init for GCC
2884     int		all_idx;
2885     int		len;
2886     int		i;
2887     long	n;
2888     int		found_ve = FALSE;	// found "ve" flag
2889     int		round;
2890 
2891     /*
2892      * First round: check for errors; second round: do it for real.
2893      */
2894     for (round = 1; round <= 2; ++round)
2895     {
2896 	/*
2897 	 * Repeat for all comma separated parts.
2898 	 */
2899 #ifdef FEAT_MOUSESHAPE
2900 	if (what == SHAPE_MOUSE)
2901 	    modep = p_mouseshape;
2902 	else
2903 #endif
2904 	    modep = p_guicursor;
2905 	while (*modep != NUL)
2906 	{
2907 	    colonp = vim_strchr(modep, ':');
2908 	    commap = vim_strchr(modep, ',');
2909 
2910 	    if (colonp == NULL || (commap != NULL && commap < colonp))
2911 		return N_("E545: Missing colon");
2912 	    if (colonp == modep)
2913 		return N_("E546: Illegal mode");
2914 
2915 	    /*
2916 	     * Repeat for all mode's before the colon.
2917 	     * For the 'a' mode, we loop to handle all the modes.
2918 	     */
2919 	    all_idx = -1;
2920 	    while (modep < colonp || all_idx >= 0)
2921 	    {
2922 		if (all_idx < 0)
2923 		{
2924 		    // Find the mode.
2925 		    if (modep[1] == '-' || modep[1] == ':')
2926 			len = 1;
2927 		    else
2928 			len = 2;
2929 		    if (len == 1 && TOLOWER_ASC(modep[0]) == 'a')
2930 			all_idx = SHAPE_IDX_COUNT - 1;
2931 		    else
2932 		    {
2933 			for (idx = 0; idx < SHAPE_IDX_COUNT; ++idx)
2934 			    if (STRNICMP(modep, shape_table[idx].name, len)
2935 									 == 0)
2936 				break;
2937 			if (idx == SHAPE_IDX_COUNT
2938 				   || (shape_table[idx].used_for & what) == 0)
2939 			    return N_("E546: Illegal mode");
2940 			if (len == 2 && modep[0] == 'v' && modep[1] == 'e')
2941 			    found_ve = TRUE;
2942 		    }
2943 		    modep += len + 1;
2944 		}
2945 
2946 		if (all_idx >= 0)
2947 		    idx = all_idx--;
2948 		else if (round == 2)
2949 		{
2950 #ifdef FEAT_MOUSESHAPE
2951 		    if (what == SHAPE_MOUSE)
2952 		    {
2953 			// Set the default, for the missing parts
2954 			shape_table[idx].mshape = 0;
2955 		    }
2956 		    else
2957 #endif
2958 		    {
2959 			// Set the defaults, for the missing parts
2960 			shape_table[idx].shape = SHAPE_BLOCK;
2961 			shape_table[idx].blinkwait = 700L;
2962 			shape_table[idx].blinkon = 400L;
2963 			shape_table[idx].blinkoff = 250L;
2964 		    }
2965 		}
2966 
2967 		// Parse the part after the colon
2968 		for (p = colonp + 1; *p && *p != ','; )
2969 		{
2970 #ifdef FEAT_MOUSESHAPE
2971 		    if (what == SHAPE_MOUSE)
2972 		    {
2973 			for (i = 0; ; ++i)
2974 			{
2975 			    if (mshape_names[i] == NULL)
2976 			    {
2977 				if (!VIM_ISDIGIT(*p))
2978 				    return N_("E547: Illegal mouseshape");
2979 				if (round == 2)
2980 				    shape_table[idx].mshape =
2981 					      getdigits(&p) + MSHAPE_NUMBERED;
2982 				else
2983 				    (void)getdigits(&p);
2984 				break;
2985 			    }
2986 			    len = (int)STRLEN(mshape_names[i]);
2987 			    if (STRNICMP(p, mshape_names[i], len) == 0)
2988 			    {
2989 				if (round == 2)
2990 				    shape_table[idx].mshape = i;
2991 				p += len;
2992 				break;
2993 			    }
2994 			}
2995 		    }
2996 		    else // if (what == SHAPE_MOUSE)
2997 #endif
2998 		    {
2999 			/*
3000 			 * First handle the ones with a number argument.
3001 			 */
3002 			i = *p;
3003 			len = 0;
3004 			if (STRNICMP(p, "ver", 3) == 0)
3005 			    len = 3;
3006 			else if (STRNICMP(p, "hor", 3) == 0)
3007 			    len = 3;
3008 			else if (STRNICMP(p, "blinkwait", 9) == 0)
3009 			    len = 9;
3010 			else if (STRNICMP(p, "blinkon", 7) == 0)
3011 			    len = 7;
3012 			else if (STRNICMP(p, "blinkoff", 8) == 0)
3013 			    len = 8;
3014 			if (len != 0)
3015 			{
3016 			    p += len;
3017 			    if (!VIM_ISDIGIT(*p))
3018 				return N_("E548: digit expected");
3019 			    n = getdigits(&p);
3020 			    if (len == 3)   // "ver" or "hor"
3021 			    {
3022 				if (n == 0)
3023 				    return N_("E549: Illegal percentage");
3024 				if (round == 2)
3025 				{
3026 				    if (TOLOWER_ASC(i) == 'v')
3027 					shape_table[idx].shape = SHAPE_VER;
3028 				    else
3029 					shape_table[idx].shape = SHAPE_HOR;
3030 				    shape_table[idx].percentage = n;
3031 				}
3032 			    }
3033 			    else if (round == 2)
3034 			    {
3035 				if (len == 9)
3036 				    shape_table[idx].blinkwait = n;
3037 				else if (len == 7)
3038 				    shape_table[idx].blinkon = n;
3039 				else
3040 				    shape_table[idx].blinkoff = n;
3041 			    }
3042 			}
3043 			else if (STRNICMP(p, "block", 5) == 0)
3044 			{
3045 			    if (round == 2)
3046 				shape_table[idx].shape = SHAPE_BLOCK;
3047 			    p += 5;
3048 			}
3049 			else	// must be a highlight group name then
3050 			{
3051 			    endp = vim_strchr(p, '-');
3052 			    if (commap == NULL)		    // last part
3053 			    {
3054 				if (endp == NULL)
3055 				    endp = p + STRLEN(p);   // find end of part
3056 			    }
3057 			    else if (endp > commap || endp == NULL)
3058 				endp = commap;
3059 			    slashp = vim_strchr(p, '/');
3060 			    if (slashp != NULL && slashp < endp)
3061 			    {
3062 				// "group/langmap_group"
3063 				i = syn_check_group(p, (int)(slashp - p));
3064 				p = slashp + 1;
3065 			    }
3066 			    if (round == 2)
3067 			    {
3068 				shape_table[idx].id = syn_check_group(p,
3069 							     (int)(endp - p));
3070 				shape_table[idx].id_lm = shape_table[idx].id;
3071 				if (slashp != NULL && slashp < endp)
3072 				    shape_table[idx].id = i;
3073 			    }
3074 			    p = endp;
3075 			}
3076 		    } // if (what != SHAPE_MOUSE)
3077 
3078 		    if (*p == '-')
3079 			++p;
3080 		}
3081 	    }
3082 	    modep = p;
3083 	    if (*modep == ',')
3084 		++modep;
3085 	}
3086     }
3087 
3088     // If the 's' flag is not given, use the 'v' cursor for 's'
3089     if (!found_ve)
3090     {
3091 #ifdef FEAT_MOUSESHAPE
3092 	if (what == SHAPE_MOUSE)
3093 	{
3094 	    shape_table[SHAPE_IDX_VE].mshape = shape_table[SHAPE_IDX_V].mshape;
3095 	}
3096 	else
3097 #endif
3098 	{
3099 	    shape_table[SHAPE_IDX_VE].shape = shape_table[SHAPE_IDX_V].shape;
3100 	    shape_table[SHAPE_IDX_VE].percentage =
3101 					 shape_table[SHAPE_IDX_V].percentage;
3102 	    shape_table[SHAPE_IDX_VE].blinkwait =
3103 					  shape_table[SHAPE_IDX_V].blinkwait;
3104 	    shape_table[SHAPE_IDX_VE].blinkon =
3105 					    shape_table[SHAPE_IDX_V].blinkon;
3106 	    shape_table[SHAPE_IDX_VE].blinkoff =
3107 					   shape_table[SHAPE_IDX_V].blinkoff;
3108 	    shape_table[SHAPE_IDX_VE].id = shape_table[SHAPE_IDX_V].id;
3109 	    shape_table[SHAPE_IDX_VE].id_lm = shape_table[SHAPE_IDX_V].id_lm;
3110 	}
3111     }
3112 
3113     return NULL;
3114 }
3115 
3116 # if defined(MCH_CURSOR_SHAPE) || defined(FEAT_GUI) \
3117 	|| defined(FEAT_MOUSESHAPE) || defined(PROTO)
3118 /*
3119  * Return the index into shape_table[] for the current mode.
3120  * When "mouse" is TRUE, consider indexes valid for the mouse pointer.
3121  */
3122     int
3123 get_shape_idx(int mouse)
3124 {
3125 #ifdef FEAT_MOUSESHAPE
3126     if (mouse && (State == HITRETURN || State == ASKMORE))
3127     {
3128 # ifdef FEAT_GUI
3129 	int x, y;
3130 	gui_mch_getmouse(&x, &y);
3131 	if (Y_2_ROW(y) == Rows - 1)
3132 	    return SHAPE_IDX_MOREL;
3133 # endif
3134 	return SHAPE_IDX_MORE;
3135     }
3136     if (mouse && drag_status_line)
3137 	return SHAPE_IDX_SDRAG;
3138     if (mouse && drag_sep_line)
3139 	return SHAPE_IDX_VDRAG;
3140 #endif
3141     if (!mouse && State == SHOWMATCH)
3142 	return SHAPE_IDX_SM;
3143     if (State & VREPLACE_FLAG)
3144 	return SHAPE_IDX_R;
3145     if (State & REPLACE_FLAG)
3146 	return SHAPE_IDX_R;
3147     if (State & INSERT)
3148 	return SHAPE_IDX_I;
3149     if (State & CMDLINE)
3150     {
3151 	if (cmdline_at_end())
3152 	    return SHAPE_IDX_C;
3153 	if (cmdline_overstrike())
3154 	    return SHAPE_IDX_CR;
3155 	return SHAPE_IDX_CI;
3156     }
3157     if (finish_op)
3158 	return SHAPE_IDX_O;
3159     if (VIsual_active)
3160     {
3161 	if (*p_sel == 'e')
3162 	    return SHAPE_IDX_VE;
3163 	else
3164 	    return SHAPE_IDX_V;
3165     }
3166     return SHAPE_IDX_N;
3167 }
3168 #endif
3169 
3170 # if defined(FEAT_MOUSESHAPE) || defined(PROTO)
3171 static int old_mouse_shape = 0;
3172 
3173 /*
3174  * Set the mouse shape:
3175  * If "shape" is -1, use shape depending on the current mode,
3176  * depending on the current state.
3177  * If "shape" is -2, only update the shape when it's CLINE or STATUS (used
3178  * when the mouse moves off the status or command line).
3179  */
3180     void
3181 update_mouseshape(int shape_idx)
3182 {
3183     int new_mouse_shape;
3184 
3185     // Only works in GUI mode.
3186     if (!gui.in_use || gui.starting)
3187 	return;
3188 
3189     // Postpone the updating when more is to come.  Speeds up executing of
3190     // mappings.
3191     if (shape_idx == -1 && char_avail())
3192     {
3193 	postponed_mouseshape = TRUE;
3194 	return;
3195     }
3196 
3197     // When ignoring the mouse don't change shape on the statusline.
3198     if (*p_mouse == NUL
3199 	    && (shape_idx == SHAPE_IDX_CLINE
3200 		|| shape_idx == SHAPE_IDX_STATUS
3201 		|| shape_idx == SHAPE_IDX_VSEP))
3202 	shape_idx = -2;
3203 
3204     if (shape_idx == -2
3205 	    && old_mouse_shape != shape_table[SHAPE_IDX_CLINE].mshape
3206 	    && old_mouse_shape != shape_table[SHAPE_IDX_STATUS].mshape
3207 	    && old_mouse_shape != shape_table[SHAPE_IDX_VSEP].mshape)
3208 	return;
3209     if (shape_idx < 0)
3210 	new_mouse_shape = shape_table[get_shape_idx(TRUE)].mshape;
3211     else
3212 	new_mouse_shape = shape_table[shape_idx].mshape;
3213     if (new_mouse_shape != old_mouse_shape)
3214     {
3215 	mch_set_mouse_shape(new_mouse_shape);
3216 	old_mouse_shape = new_mouse_shape;
3217     }
3218     postponed_mouseshape = FALSE;
3219 }
3220 # endif
3221 
3222 #endif // CURSOR_SHAPE
3223 
3224 
3225 /*
3226  * Change directory to "new_dir".  If FEAT_SEARCHPATH is defined, search
3227  * 'cdpath' for relative directory names, otherwise just mch_chdir().
3228  */
3229     int
3230 vim_chdir(char_u *new_dir)
3231 {
3232 #ifndef FEAT_SEARCHPATH
3233     return mch_chdir((char *)new_dir);
3234 #else
3235     char_u	*dir_name;
3236     int		r;
3237 
3238     dir_name = find_directory_in_path(new_dir, (int)STRLEN(new_dir),
3239 						FNAME_MESS, curbuf->b_ffname);
3240     if (dir_name == NULL)
3241 	return -1;
3242     r = mch_chdir((char *)dir_name);
3243     vim_free(dir_name);
3244     return r;
3245 #endif
3246 }
3247 
3248 /*
3249  * Get user name from machine-specific function.
3250  * Returns the user name in "buf[len]".
3251  * Some systems are quite slow in obtaining the user name (Windows NT), thus
3252  * cache the result.
3253  * Returns OK or FAIL.
3254  */
3255     int
3256 get_user_name(char_u *buf, int len)
3257 {
3258     if (username == NULL)
3259     {
3260 	if (mch_get_user_name(buf, len) == FAIL)
3261 	    return FAIL;
3262 	username = vim_strsave(buf);
3263     }
3264     else
3265 	vim_strncpy(buf, username, len - 1);
3266     return OK;
3267 }
3268 
3269 #ifndef HAVE_QSORT
3270 /*
3271  * Our own qsort(), for systems that don't have it.
3272  * It's simple and slow.  From the K&R C book.
3273  */
3274     void
3275 qsort(
3276     void	*base,
3277     size_t	elm_count,
3278     size_t	elm_size,
3279     int (*cmp)(const void *, const void *))
3280 {
3281     char_u	*buf;
3282     char_u	*p1;
3283     char_u	*p2;
3284     int		i, j;
3285     int		gap;
3286 
3287     buf = alloc(elm_size);
3288     if (buf == NULL)
3289 	return;
3290 
3291     for (gap = elm_count / 2; gap > 0; gap /= 2)
3292 	for (i = gap; i < elm_count; ++i)
3293 	    for (j = i - gap; j >= 0; j -= gap)
3294 	    {
3295 		// Compare the elements.
3296 		p1 = (char_u *)base + j * elm_size;
3297 		p2 = (char_u *)base + (j + gap) * elm_size;
3298 		if ((*cmp)((void *)p1, (void *)p2) <= 0)
3299 		    break;
3300 		// Exchange the elements.
3301 		mch_memmove(buf, p1, elm_size);
3302 		mch_memmove(p1, p2, elm_size);
3303 		mch_memmove(p2, buf, elm_size);
3304 	    }
3305 
3306     vim_free(buf);
3307 }
3308 #endif
3309 
3310 /*
3311  * The putenv() implementation below comes from the "screen" program.
3312  * Included with permission from Juergen Weigert.
3313  * See pty.c for the copyright notice.
3314  */
3315 
3316 /*
3317  *  putenv  --	put value into environment
3318  *
3319  *  Usage:  i = putenv (string)
3320  *    int i;
3321  *    char  *string;
3322  *
3323  *  where string is of the form <name>=<value>.
3324  *  Putenv returns 0 normally, -1 on error (not enough core for malloc).
3325  *
3326  *  Putenv may need to add a new name into the environment, or to
3327  *  associate a value longer than the current value with a particular
3328  *  name.  So, to make life simpler, putenv() copies your entire
3329  *  environment into the heap (i.e. malloc()) from the stack
3330  *  (i.e. where it resides when your process is initiated) the first
3331  *  time you call it.
3332  *
3333  *  (history removed, not very interesting.  See the "screen" sources.)
3334  */
3335 
3336 #if !defined(HAVE_SETENV) && !defined(HAVE_PUTENV)
3337 
3338 #define EXTRASIZE 5		// increment to add to env. size
3339 
3340 static int  envsize = -1;	// current size of environment
3341 extern char **environ;		// the global which is your env.
3342 
3343 static int  findenv(char *name); // look for a name in the env.
3344 static int  newenv(void);	// copy env. from stack to heap
3345 static int  moreenv(void);	// incr. size of env.
3346 
3347     int
3348 putenv(const char *string)
3349 {
3350     int	    i;
3351     char    *p;
3352 
3353     if (envsize < 0)
3354     {				// first time putenv called
3355 	if (newenv() < 0)	// copy env. to heap
3356 	    return -1;
3357     }
3358 
3359     i = findenv((char *)string); // look for name in environment
3360 
3361     if (i < 0)
3362     {				// name must be added
3363 	for (i = 0; environ[i]; i++);
3364 	if (i >= (envsize - 1))
3365 	{			// need new slot
3366 	    if (moreenv() < 0)
3367 		return -1;
3368 	}
3369 	p = alloc(strlen(string) + 1);
3370 	if (p == NULL)		// not enough core
3371 	    return -1;
3372 	environ[i + 1] = 0;	// new end of env.
3373     }
3374     else
3375     {				// name already in env.
3376 	p = vim_realloc(environ[i], strlen(string) + 1);
3377 	if (p == NULL)
3378 	    return -1;
3379     }
3380     sprintf(p, "%s", string);	// copy into env.
3381     environ[i] = p;
3382 
3383     return 0;
3384 }
3385 
3386     static int
3387 findenv(char *name)
3388 {
3389     char    *namechar, *envchar;
3390     int	    i, found;
3391 
3392     found = 0;
3393     for (i = 0; environ[i] && !found; i++)
3394     {
3395 	envchar = environ[i];
3396 	namechar = name;
3397 	while (*namechar && *namechar != '=' && (*namechar == *envchar))
3398 	{
3399 	    namechar++;
3400 	    envchar++;
3401 	}
3402 	found = ((*namechar == '\0' || *namechar == '=') && *envchar == '=');
3403     }
3404     return found ? i - 1 : -1;
3405 }
3406 
3407     static int
3408 newenv(void)
3409 {
3410     char    **env, *elem;
3411     int	    i, esize;
3412 
3413     for (i = 0; environ[i]; i++)
3414 	;
3415 
3416     esize = i + EXTRASIZE + 1;
3417     env = ALLOC_MULT(char *, esize);
3418     if (env == NULL)
3419 	return -1;
3420 
3421     for (i = 0; environ[i]; i++)
3422     {
3423 	elem = alloc(strlen(environ[i]) + 1);
3424 	if (elem == NULL)
3425 	    return -1;
3426 	env[i] = elem;
3427 	strcpy(elem, environ[i]);
3428     }
3429 
3430     env[i] = 0;
3431     environ = env;
3432     envsize = esize;
3433     return 0;
3434 }
3435 
3436     static int
3437 moreenv(void)
3438 {
3439     int	    esize;
3440     char    **env;
3441 
3442     esize = envsize + EXTRASIZE;
3443     env = vim_realloc((char *)environ, esize * sizeof (*env));
3444     if (env == 0)
3445 	return -1;
3446     environ = env;
3447     envsize = esize;
3448     return 0;
3449 }
3450 
3451 # ifdef USE_VIMPTY_GETENV
3452 /*
3453  * Used for mch_getenv() for Mac.
3454  */
3455     char_u *
3456 vimpty_getenv(const char_u *string)
3457 {
3458     int i;
3459     char_u *p;
3460 
3461     if (envsize < 0)
3462 	return NULL;
3463 
3464     i = findenv((char *)string);
3465 
3466     if (i < 0)
3467 	return NULL;
3468 
3469     p = vim_strchr((char_u *)environ[i], '=');
3470     return (p + 1);
3471 }
3472 # endif
3473 
3474 #endif // !defined(HAVE_SETENV) && !defined(HAVE_PUTENV)
3475 
3476 #if defined(FEAT_EVAL) || defined(FEAT_SPELL) || defined(PROTO)
3477 /*
3478  * Return 0 for not writable, 1 for writable file, 2 for a dir which we have
3479  * rights to write into.
3480  */
3481     int
3482 filewritable(char_u *fname)
3483 {
3484     int		retval = 0;
3485 #if defined(UNIX) || defined(VMS)
3486     int		perm = 0;
3487 #endif
3488 
3489 #if defined(UNIX) || defined(VMS)
3490     perm = mch_getperm(fname);
3491 #endif
3492     if (
3493 # ifdef MSWIN
3494 	    mch_writable(fname) &&
3495 # else
3496 # if defined(UNIX) || defined(VMS)
3497 	    (perm & 0222) &&
3498 #  endif
3499 # endif
3500 	    mch_access((char *)fname, W_OK) == 0
3501        )
3502     {
3503 	++retval;
3504 	if (mch_isdir(fname))
3505 	    ++retval;
3506     }
3507     return retval;
3508 }
3509 #endif
3510 
3511 #if defined(FEAT_SPELL) || defined(FEAT_PERSISTENT_UNDO) || defined(PROTO)
3512 /*
3513  * Read 2 bytes from "fd" and turn them into an int, MSB first.
3514  * Returns -1 when encountering EOF.
3515  */
3516     int
3517 get2c(FILE *fd)
3518 {
3519     int		c, n;
3520 
3521     n = getc(fd);
3522     if (n == EOF) return -1;
3523     c = getc(fd);
3524     if (c == EOF) return -1;
3525     return (n << 8) + c;
3526 }
3527 
3528 /*
3529  * Read 3 bytes from "fd" and turn them into an int, MSB first.
3530  * Returns -1 when encountering EOF.
3531  */
3532     int
3533 get3c(FILE *fd)
3534 {
3535     int		c, n;
3536 
3537     n = getc(fd);
3538     if (n == EOF) return -1;
3539     c = getc(fd);
3540     if (c == EOF) return -1;
3541     n = (n << 8) + c;
3542     c = getc(fd);
3543     if (c == EOF) return -1;
3544     return (n << 8) + c;
3545 }
3546 
3547 /*
3548  * Read 4 bytes from "fd" and turn them into an int, MSB first.
3549  * Returns -1 when encountering EOF.
3550  */
3551     int
3552 get4c(FILE *fd)
3553 {
3554     int		c;
3555     // Use unsigned rather than int otherwise result is undefined
3556     // when left-shift sets the MSB.
3557     unsigned	n;
3558 
3559     c = getc(fd);
3560     if (c == EOF) return -1;
3561     n = (unsigned)c;
3562     c = getc(fd);
3563     if (c == EOF) return -1;
3564     n = (n << 8) + (unsigned)c;
3565     c = getc(fd);
3566     if (c == EOF) return -1;
3567     n = (n << 8) + (unsigned)c;
3568     c = getc(fd);
3569     if (c == EOF) return -1;
3570     n = (n << 8) + (unsigned)c;
3571     return (int)n;
3572 }
3573 
3574 /*
3575  * Read a string of length "cnt" from "fd" into allocated memory.
3576  * Returns NULL when out of memory or unable to read that many bytes.
3577  */
3578     char_u *
3579 read_string(FILE *fd, int cnt)
3580 {
3581     char_u	*str;
3582     int		i;
3583     int		c;
3584 
3585     // allocate memory
3586     str = alloc(cnt + 1);
3587     if (str != NULL)
3588     {
3589 	// Read the string.  Quit when running into the EOF.
3590 	for (i = 0; i < cnt; ++i)
3591 	{
3592 	    c = getc(fd);
3593 	    if (c == EOF)
3594 	    {
3595 		vim_free(str);
3596 		return NULL;
3597 	    }
3598 	    str[i] = c;
3599 	}
3600 	str[i] = NUL;
3601     }
3602     return str;
3603 }
3604 
3605 /*
3606  * Write a number to file "fd", MSB first, in "len" bytes.
3607  */
3608     int
3609 put_bytes(FILE *fd, long_u nr, int len)
3610 {
3611     int	    i;
3612 
3613     for (i = len - 1; i >= 0; --i)
3614 	if (putc((int)(nr >> (i * 8)), fd) == EOF)
3615 	    return FAIL;
3616     return OK;
3617 }
3618 
3619 #endif
3620 
3621 #ifndef PROTO  // proto is defined in vim.h
3622 # ifdef ELAPSED_TIMEVAL
3623 /*
3624  * Return time in msec since "start_tv".
3625  */
3626     long
3627 elapsed(struct timeval *start_tv)
3628 {
3629     struct timeval  now_tv;
3630 
3631     gettimeofday(&now_tv, NULL);
3632     return (now_tv.tv_sec - start_tv->tv_sec) * 1000L
3633 	 + (now_tv.tv_usec - start_tv->tv_usec) / 1000L;
3634 }
3635 # endif
3636 
3637 # ifdef ELAPSED_TICKCOUNT
3638 /*
3639  * Return time in msec since "start_tick".
3640  */
3641     long
3642 elapsed(DWORD start_tick)
3643 {
3644     DWORD	now = GetTickCount();
3645 
3646     return (long)now - (long)start_tick;
3647 }
3648 # endif
3649 #endif
3650 
3651 #if defined(FEAT_JOB_CHANNEL) \
3652 	|| (defined(UNIX) && (!defined(USE_SYSTEM) \
3653 	|| (defined(FEAT_GUI) && defined(FEAT_TERMINAL)))) \
3654 	|| defined(PROTO)
3655 /*
3656  * Parse "cmd" and put the white-separated parts in "argv".
3657  * "argv" is an allocated array with "argc" entries and room for 4 more.
3658  * Returns FAIL when out of memory.
3659  */
3660     int
3661 mch_parse_cmd(char_u *cmd, int use_shcf, char ***argv, int *argc)
3662 {
3663     int		i;
3664     char_u	*p, *d;
3665     int		inquote;
3666 
3667     /*
3668      * Do this loop twice:
3669      * 1: find number of arguments
3670      * 2: separate them and build argv[]
3671      */
3672     for (i = 1; i <= 2; ++i)
3673     {
3674 	p = skipwhite(cmd);
3675 	inquote = FALSE;
3676 	*argc = 0;
3677 	while (*p != NUL)
3678 	{
3679 	    if (i == 2)
3680 		(*argv)[*argc] = (char *)p;
3681 	    ++*argc;
3682 	    d = p;
3683 	    while (*p != NUL && (inquote || (*p != ' ' && *p != TAB)))
3684 	    {
3685 		if (p[0] == '"')
3686 		    // quotes surrounding an argument and are dropped
3687 		    inquote = !inquote;
3688 		else
3689 		{
3690 		    if (rem_backslash(p))
3691 		    {
3692 			// First pass: skip over "\ " and "\"".
3693 			// Second pass: Remove the backslash.
3694 			++p;
3695 		    }
3696 		    if (i == 2)
3697 			*d++ = *p;
3698 		}
3699 		++p;
3700 	    }
3701 	    if (*p == NUL)
3702 	    {
3703 		if (i == 2)
3704 		    *d++ = NUL;
3705 		break;
3706 	    }
3707 	    if (i == 2)
3708 		*d++ = NUL;
3709 	    p = skipwhite(p + 1);
3710 	}
3711 	if (*argv == NULL)
3712 	{
3713 	    if (use_shcf)
3714 	    {
3715 		// Account for possible multiple args in p_shcf.
3716 		p = p_shcf;
3717 		for (;;)
3718 		{
3719 		    p = skiptowhite(p);
3720 		    if (*p == NUL)
3721 			break;
3722 		    ++*argc;
3723 		    p = skipwhite(p);
3724 		}
3725 	    }
3726 
3727 	    *argv = ALLOC_MULT(char *, *argc + 4);
3728 	    if (*argv == NULL)	    // out of memory
3729 		return FAIL;
3730 	}
3731     }
3732     return OK;
3733 }
3734 
3735 # if defined(FEAT_JOB_CHANNEL) || defined(PROTO)
3736 /*
3737  * Build "argv[argc]" from the string "cmd".
3738  * "argv[argc]" is set to NULL;
3739  * Return FAIL when out of memory.
3740  */
3741     int
3742 build_argv_from_string(char_u *cmd, char ***argv, int *argc)
3743 {
3744     char_u	*cmd_copy;
3745     int		i;
3746 
3747     // Make a copy, parsing will modify "cmd".
3748     cmd_copy = vim_strsave(cmd);
3749     if (cmd_copy == NULL
3750 	    || mch_parse_cmd(cmd_copy, FALSE, argv, argc) == FAIL)
3751     {
3752 	vim_free(cmd_copy);
3753 	return FAIL;
3754     }
3755     for (i = 0; i < *argc; i++)
3756 	(*argv)[i] = (char *)vim_strsave((char_u *)(*argv)[i]);
3757     (*argv)[*argc] = NULL;
3758     vim_free(cmd_copy);
3759     return OK;
3760 }
3761 
3762 /*
3763  * Build "argv[argc]" from the list "l".
3764  * "argv[argc]" is set to NULL;
3765  * Return FAIL when out of memory.
3766  */
3767     int
3768 build_argv_from_list(list_T *l, char ***argv, int *argc)
3769 {
3770     listitem_T  *li;
3771     char_u	*s;
3772 
3773     // Pass argv[] to mch_call_shell().
3774     *argv = ALLOC_MULT(char *, l->lv_len + 1);
3775     if (*argv == NULL)
3776 	return FAIL;
3777     *argc = 0;
3778     FOR_ALL_LIST_ITEMS(l, li)
3779     {
3780 	s = tv_get_string_chk(&li->li_tv);
3781 	if (s == NULL)
3782 	{
3783 	    int i;
3784 
3785 	    for (i = 0; i < *argc; ++i)
3786 		VIM_CLEAR((*argv)[i]);
3787 	    return FAIL;
3788 	}
3789 	(*argv)[*argc] = (char *)vim_strsave(s);
3790 	*argc += 1;
3791     }
3792     (*argv)[*argc] = NULL;
3793     return OK;
3794 }
3795 # endif
3796 #endif
3797 
3798 /*
3799  * Change the behavior of vterm.
3800  * 0: As usual.
3801  * 1: Windows 10 version 1809
3802  *      The bug causes unstable handling of ambiguous width character.
3803  * 2: Windows 10 version 1903 & 1909
3804  *      Use the wrong result because each result is different.
3805  * 3: Windows 10 insider preview (current latest logic)
3806  */
3807     int
3808 get_special_pty_type(void)
3809 {
3810 #ifdef MSWIN
3811     return get_conpty_type();
3812 #else
3813     return 0;
3814 #endif
3815 }
3816