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
virtual_active(void)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
getviscol(void)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
coladvance_force(colnr_T wcol)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
getviscol2(colnr_T col,colnr_T coladd UNUSED)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
coladvance(colnr_T wcol)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
getvpos(pos_T * pos,colnr_T wcol)116 getvpos(pos_T *pos, colnr_T wcol)
117 {
118     return coladvance2(pos, FALSE, virtual_active(), wcol);
119 }
120 
121     static int
coladvance2(pos_T * pos,int addspaces,int finetune,colnr_T wcol_arg)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 		&& width > 0)
166 	{
167 	    csize = linetabsize(line);
168 	    if (csize > 0)
169 		csize--;
170 
171 	    if (wcol / width > (colnr_T)csize / width
172 		    && ((State & INSERT) == 0 || (int)wcol > csize + 1))
173 	    {
174 		// In case of line wrapping don't move the cursor beyond the
175 		// right screen edge.  In Insert mode allow going just beyond
176 		// the last character (like what happens when typing and
177 		// reaching the right window edge).
178 		wcol = (csize / width + 1) * width - 1;
179 	    }
180 	}
181 
182 	ptr = line;
183 	while (col <= wcol && *ptr != NUL)
184 	{
185 	    // Count a tab for what it's worth (if list mode not on)
186 #ifdef FEAT_LINEBREAK
187 	    csize = win_lbr_chartabsize(curwin, line, ptr, col, &head);
188 	    MB_PTR_ADV(ptr);
189 #else
190 	    csize = lbr_chartabsize_adv(line, &ptr, col);
191 #endif
192 	    col += csize;
193 	}
194 	idx = (int)(ptr - line);
195 	/*
196 	 * Handle all the special cases.  The virtual_active() check
197 	 * is needed to ensure that a virtual position off the end of
198 	 * a line has the correct indexing.  The one_more comparison
199 	 * replaces an explicit add of one_more later on.
200 	 */
201 	if (col > wcol || (!virtual_active() && one_more == 0))
202 	{
203 	    idx -= 1;
204 # ifdef FEAT_LINEBREAK
205 	    // Don't count the chars from 'showbreak'.
206 	    csize -= head;
207 # endif
208 	    col -= csize;
209 	}
210 
211 	if (virtual_active()
212 		&& addspaces
213 		&& wcol >= 0
214 		&& ((col != wcol && col != wcol + 1) || csize > 1))
215 	{
216 	    // 'virtualedit' is set: The difference between wcol and col is
217 	    // filled with spaces.
218 
219 	    if (line[idx] == NUL)
220 	    {
221 		// Append spaces
222 		int	correct = wcol - col;
223 		char_u	*newline = alloc(idx + correct + 1);
224 		int	t;
225 
226 		if (newline == NULL)
227 		    return FAIL;
228 
229 		for (t = 0; t < idx; ++t)
230 		    newline[t] = line[t];
231 
232 		for (t = 0; t < correct; ++t)
233 		    newline[t + idx] = ' ';
234 
235 		newline[idx + correct] = NUL;
236 
237 		ml_replace(pos->lnum, newline, FALSE);
238 		changed_bytes(pos->lnum, (colnr_T)idx);
239 		idx += correct;
240 		col = wcol;
241 	    }
242 	    else
243 	    {
244 		// Break a tab
245 		int	linelen = (int)STRLEN(line);
246 		int	correct = wcol - col - csize + 1; // negative!!
247 		char_u	*newline;
248 		int	t, s = 0;
249 		int	v;
250 
251 		if (-correct > csize)
252 		    return FAIL;
253 
254 		newline = alloc(linelen + csize);
255 		if (newline == NULL)
256 		    return FAIL;
257 
258 		for (t = 0; t < linelen; t++)
259 		{
260 		    if (t != idx)
261 			newline[s++] = line[t];
262 		    else
263 			for (v = 0; v < csize; v++)
264 			    newline[s++] = ' ';
265 		}
266 
267 		newline[linelen + csize - 1] = NUL;
268 
269 		ml_replace(pos->lnum, newline, FALSE);
270 		changed_bytes(pos->lnum, idx);
271 		idx += (csize - 1 + correct);
272 		col += correct;
273 	    }
274 	}
275     }
276 
277     if (idx < 0)
278 	pos->col = 0;
279     else
280 	pos->col = idx;
281 
282     pos->coladd = 0;
283 
284     if (finetune)
285     {
286 	if (wcol == MAXCOL)
287 	{
288 	    // The width of the last character is used to set coladd.
289 	    if (!one_more)
290 	    {
291 		colnr_T	    scol, ecol;
292 
293 		getvcol(curwin, pos, &scol, NULL, &ecol);
294 		pos->coladd = ecol - scol;
295 	    }
296 	}
297 	else
298 	{
299 	    int b = (int)wcol - (int)col;
300 
301 	    // The difference between wcol and col is used to set coladd.
302 	    if (b > 0 && b < (MAXCOL - 2 * curwin->w_width))
303 		pos->coladd = b;
304 
305 	    col += b;
306 	}
307     }
308 
309     // prevent from moving onto a trail byte
310     if (has_mbyte)
311 	mb_adjustpos(curbuf, pos);
312 
313     if (wcol < 0 || col < wcol)
314 	return FAIL;
315     return OK;
316 }
317 
318 /*
319  * Increment the cursor position.  See inc() for return values.
320  */
321     int
inc_cursor(void)322 inc_cursor(void)
323 {
324     return inc(&curwin->w_cursor);
325 }
326 
327 /*
328  * Increment the line pointer "lp" crossing line boundaries as necessary.
329  * Return 1 when going to the next line.
330  * Return 2 when moving forward onto a NUL at the end of the line).
331  * Return -1 when at the end of file.
332  * Return 0 otherwise.
333  */
334     int
inc(pos_T * lp)335 inc(pos_T *lp)
336 {
337     char_u  *p;
338 
339     // when searching position may be set to end of a line
340     if (lp->col != MAXCOL)
341     {
342 	p = ml_get_pos(lp);
343 	if (*p != NUL)	// still within line, move to next char (may be NUL)
344 	{
345 	    if (has_mbyte)
346 	    {
347 		int l = (*mb_ptr2len)(p);
348 
349 		lp->col += l;
350 		return ((p[l] != NUL) ? 0 : 2);
351 	    }
352 	    lp->col++;
353 	    lp->coladd = 0;
354 	    return ((p[1] != NUL) ? 0 : 2);
355 	}
356     }
357     if (lp->lnum != curbuf->b_ml.ml_line_count)     // there is a next line
358     {
359 	lp->col = 0;
360 	lp->lnum++;
361 	lp->coladd = 0;
362 	return 1;
363     }
364     return -1;
365 }
366 
367 /*
368  * incl(lp): same as inc(), but skip the NUL at the end of non-empty lines
369  */
370     int
incl(pos_T * lp)371 incl(pos_T *lp)
372 {
373     int	    r;
374 
375     if ((r = inc(lp)) >= 1 && lp->col)
376 	r = inc(lp);
377     return r;
378 }
379 
380 /*
381  * dec(p)
382  *
383  * Decrement the line pointer 'p' crossing line boundaries as necessary.
384  * Return 1 when crossing a line, -1 when at start of file, 0 otherwise.
385  */
386     int
dec_cursor(void)387 dec_cursor(void)
388 {
389     return dec(&curwin->w_cursor);
390 }
391 
392     int
dec(pos_T * lp)393 dec(pos_T *lp)
394 {
395     char_u	*p;
396 
397     lp->coladd = 0;
398     if (lp->col == MAXCOL)
399     {
400 	// past end of line
401 	p = ml_get(lp->lnum);
402 	lp->col = (colnr_T)STRLEN(p);
403 	if (has_mbyte)
404 	    lp->col -= (*mb_head_off)(p, p + lp->col);
405 	return 0;
406     }
407 
408     if (lp->col > 0)
409     {
410 	// still within line
411 	lp->col--;
412 	if (has_mbyte)
413 	{
414 	    p = ml_get(lp->lnum);
415 	    lp->col -= (*mb_head_off)(p, p + lp->col);
416 	}
417 	return 0;
418     }
419 
420     if (lp->lnum > 1)
421     {
422 	// there is a prior line
423 	lp->lnum--;
424 	p = ml_get(lp->lnum);
425 	lp->col = (colnr_T)STRLEN(p);
426 	if (has_mbyte)
427 	    lp->col -= (*mb_head_off)(p, p + lp->col);
428 	return 1;
429     }
430 
431     // at start of file
432     return -1;
433 }
434 
435 /*
436  * decl(lp): same as dec(), but skip the NUL at the end of non-empty lines
437  */
438     int
decl(pos_T * lp)439 decl(pos_T *lp)
440 {
441     int	    r;
442 
443     if ((r = dec(lp)) == 1 && lp->col)
444 	r = dec(lp);
445     return r;
446 }
447 
448 /*
449  * Get the line number relative to the current cursor position, i.e. the
450  * difference between line number and cursor position. Only look for lines that
451  * can be visible, folded lines don't count.
452  */
453     linenr_T
get_cursor_rel_lnum(win_T * wp,linenr_T lnum)454 get_cursor_rel_lnum(
455     win_T	*wp,
456     linenr_T	lnum)		    // line number to get the result for
457 {
458     linenr_T	cursor = wp->w_cursor.lnum;
459     linenr_T	retval = 0;
460 
461 #ifdef FEAT_FOLDING
462     if (hasAnyFolding(wp))
463     {
464 	if (lnum > cursor)
465 	{
466 	    while (lnum > cursor)
467 	    {
468 		(void)hasFoldingWin(wp, lnum, &lnum, NULL, TRUE, NULL);
469 		// if lnum and cursor are in the same fold,
470 		// now lnum <= cursor
471 		if (lnum > cursor)
472 		    retval++;
473 		lnum--;
474 	    }
475 	}
476 	else if (lnum < cursor)
477 	{
478 	    while (lnum < cursor)
479 	    {
480 		(void)hasFoldingWin(wp, lnum, NULL, &lnum, TRUE, NULL);
481 		// if lnum and cursor are in the same fold,
482 		// now lnum >= cursor
483 		if (lnum < cursor)
484 		    retval--;
485 		lnum++;
486 	    }
487 	}
488 	// else if (lnum == cursor)
489 	//     retval = 0;
490     }
491     else
492 #endif
493 	retval = lnum - cursor;
494 
495     return retval;
496 }
497 
498 /*
499  * Make sure "pos.lnum" and "pos.col" are valid in "buf".
500  * This allows for the col to be on the NUL byte.
501  */
502     void
check_pos(buf_T * buf,pos_T * pos)503 check_pos(buf_T *buf, pos_T *pos)
504 {
505     char_u *line;
506     colnr_T len;
507 
508     if (pos->lnum > buf->b_ml.ml_line_count)
509 	pos->lnum = buf->b_ml.ml_line_count;
510 
511     if (pos->col > 0)
512     {
513 	line = ml_get_buf(buf, pos->lnum, FALSE);
514 	len = (colnr_T)STRLEN(line);
515 	if (pos->col > len)
516 	    pos->col = len;
517     }
518 }
519 
520 /*
521  * Make sure curwin->w_cursor.lnum is valid.
522  */
523     void
check_cursor_lnum(void)524 check_cursor_lnum(void)
525 {
526     if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count)
527     {
528 #ifdef FEAT_FOLDING
529 	// If there is a closed fold at the end of the file, put the cursor in
530 	// its first line.  Otherwise in the last line.
531 	if (!hasFolding(curbuf->b_ml.ml_line_count,
532 						&curwin->w_cursor.lnum, NULL))
533 #endif
534 	    curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
535     }
536     if (curwin->w_cursor.lnum <= 0)
537 	curwin->w_cursor.lnum = 1;
538 }
539 
540 /*
541  * Make sure curwin->w_cursor.col is valid.
542  */
543     void
check_cursor_col(void)544 check_cursor_col(void)
545 {
546     check_cursor_col_win(curwin);
547 }
548 
549 /*
550  * Make sure win->w_cursor.col is valid.
551  */
552     void
check_cursor_col_win(win_T * win)553 check_cursor_col_win(win_T *win)
554 {
555     colnr_T      len;
556     colnr_T      oldcol = win->w_cursor.col;
557     colnr_T      oldcoladd = win->w_cursor.col + win->w_cursor.coladd;
558     unsigned int cur_ve_flags = get_ve_flags();
559 
560     len = (colnr_T)STRLEN(ml_get_buf(win->w_buffer, win->w_cursor.lnum, FALSE));
561     if (len == 0)
562 	win->w_cursor.col = 0;
563     else if (win->w_cursor.col >= len)
564     {
565 	// Allow cursor past end-of-line when:
566 	// - in Insert mode or restarting Insert mode
567 	// - in Visual mode and 'selection' isn't "old"
568 	// - 'virtualedit' is set
569 	if ((State & INSERT) || restart_edit
570 		|| (VIsual_active && *p_sel != 'o')
571 		|| (cur_ve_flags & VE_ONEMORE)
572 		|| virtual_active())
573 	    win->w_cursor.col = len;
574 	else
575 	{
576 	    win->w_cursor.col = len - 1;
577 	    // Move the cursor to the head byte.
578 	    if (has_mbyte)
579 		mb_adjustpos(win->w_buffer, &win->w_cursor);
580 	}
581     }
582     else if (win->w_cursor.col < 0)
583 	win->w_cursor.col = 0;
584 
585     // If virtual editing is on, we can leave the cursor on the old position,
586     // only we must set it to virtual.  But don't do it when at the end of the
587     // line.
588     if (oldcol == MAXCOL)
589 	win->w_cursor.coladd = 0;
590     else if (cur_ve_flags == VE_ALL)
591     {
592 	if (oldcoladd > win->w_cursor.col)
593 	{
594 	    win->w_cursor.coladd = oldcoladd - win->w_cursor.col;
595 
596 	    // Make sure that coladd is not more than the char width.
597 	    // Not for the last character, coladd is then used when the cursor
598 	    // is actually after the last character.
599 	    if (win->w_cursor.col + 1 < len && win->w_cursor.coladd > 0)
600 	    {
601 		int cs, ce;
602 
603 		getvcol(win, &win->w_cursor, &cs, NULL, &ce);
604 		if (win->w_cursor.coladd > ce - cs)
605 		    win->w_cursor.coladd = ce - cs;
606 	    }
607 	}
608 	else
609 	    // avoid weird number when there is a miscalculation or overflow
610 	    win->w_cursor.coladd = 0;
611     }
612 }
613 
614 /*
615  * make sure curwin->w_cursor in on a valid character
616  */
617     void
check_cursor(void)618 check_cursor(void)
619 {
620     check_cursor_lnum();
621     check_cursor_col();
622 }
623 
624 #if defined(FEAT_TEXTOBJ) || defined(PROTO)
625 /*
626  * Make sure curwin->w_cursor is not on the NUL at the end of the line.
627  * Allow it when in Visual mode and 'selection' is not "old".
628  */
629     void
adjust_cursor_col(void)630 adjust_cursor_col(void)
631 {
632     if (curwin->w_cursor.col > 0
633 	    && (!VIsual_active || *p_sel == 'o')
634 	    && gchar_cursor() == NUL)
635 	--curwin->w_cursor.col;
636 }
637 #endif
638 
639 /*
640  * When curwin->w_leftcol has changed, adjust the cursor position.
641  * Return TRUE if the cursor was moved.
642  */
643     int
leftcol_changed(void)644 leftcol_changed(void)
645 {
646     long	lastcol;
647     colnr_T	s, e;
648     int		retval = FALSE;
649     long        siso = get_sidescrolloff_value();
650 
651     changed_cline_bef_curs();
652     lastcol = curwin->w_leftcol + curwin->w_width - curwin_col_off() - 1;
653     validate_virtcol();
654 
655     /*
656      * If the cursor is right or left of the screen, move it to last or first
657      * character.
658      */
659     if (curwin->w_virtcol > (colnr_T)(lastcol - siso))
660     {
661 	retval = TRUE;
662 	coladvance((colnr_T)(lastcol - siso));
663     }
664     else if (curwin->w_virtcol < curwin->w_leftcol + siso)
665     {
666 	retval = TRUE;
667 	(void)coladvance((colnr_T)(curwin->w_leftcol + siso));
668     }
669 
670     /*
671      * If the start of the character under the cursor is not on the screen,
672      * advance the cursor one more char.  If this fails (last char of the
673      * line) adjust the scrolling.
674      */
675     getvvcol(curwin, &curwin->w_cursor, &s, NULL, &e);
676     if (e > (colnr_T)lastcol)
677     {
678 	retval = TRUE;
679 	coladvance(s - 1);
680     }
681     else if (s < curwin->w_leftcol)
682     {
683 	retval = TRUE;
684 	if (coladvance(e + 1) == FAIL)	// there isn't another character
685 	{
686 	    curwin->w_leftcol = s;	// adjust w_leftcol instead
687 	    changed_cline_bef_curs();
688 	}
689     }
690 
691     if (retval)
692 	curwin->w_set_curswant = TRUE;
693     redraw_later(NOT_VALID);
694     return retval;
695 }
696 
697 /*
698  * Isolate one part of a string option where parts are separated with
699  * "sep_chars".
700  * The part is copied into "buf[maxlen]".
701  * "*option" is advanced to the next part.
702  * The length is returned.
703  */
704     int
copy_option_part(char_u ** option,char_u * buf,int maxlen,char * sep_chars)705 copy_option_part(
706     char_u	**option,
707     char_u	*buf,
708     int		maxlen,
709     char	*sep_chars)
710 {
711     int	    len = 0;
712     char_u  *p = *option;
713 
714     // skip '.' at start of option part, for 'suffixes'
715     if (*p == '.')
716 	buf[len++] = *p++;
717     while (*p != NUL && vim_strchr((char_u *)sep_chars, *p) == NULL)
718     {
719 	/*
720 	 * Skip backslash before a separator character and space.
721 	 */
722 	if (p[0] == '\\' && vim_strchr((char_u *)sep_chars, p[1]) != NULL)
723 	    ++p;
724 	if (len < maxlen - 1)
725 	    buf[len++] = *p;
726 	++p;
727     }
728     buf[len] = NUL;
729 
730     if (*p != NUL && *p != ',')	// skip non-standard separator
731 	++p;
732     p = skip_to_option_part(p);	// p points to next file name
733 
734     *option = p;
735     return len;
736 }
737 
738 #ifndef HAVE_MEMSET
739     void *
vim_memset(void * ptr,int c,size_t size)740 vim_memset(void *ptr, int c, size_t size)
741 {
742     char *p = ptr;
743 
744     while (size-- > 0)
745 	*p++ = c;
746     return ptr;
747 }
748 #endif
749 
750 /*
751  * Vim has its own isspace() function, because on some machines isspace()
752  * can't handle characters above 128.
753  */
754     int
vim_isspace(int x)755 vim_isspace(int x)
756 {
757     return ((x >= 9 && x <= 13) || x == ' ');
758 }
759 
760 /************************************************************************
761  * functions that use lookup tables for various things, generally to do with
762  * special key codes.
763  */
764 
765 /*
766  * Some useful tables.
767  */
768 
769 static struct modmasktable
770 {
771     short	mod_mask;	// Bit-mask for particular key modifier
772     short	mod_flag;	// Bit(s) for particular key modifier
773     char_u	name;		// Single letter name of modifier
774 } mod_mask_table[] =
775 {
776     {MOD_MASK_ALT,		MOD_MASK_ALT,		(char_u)'M'},
777     {MOD_MASK_META,		MOD_MASK_META,		(char_u)'T'},
778     {MOD_MASK_CTRL,		MOD_MASK_CTRL,		(char_u)'C'},
779     {MOD_MASK_SHIFT,		MOD_MASK_SHIFT,		(char_u)'S'},
780     {MOD_MASK_MULTI_CLICK,	MOD_MASK_2CLICK,	(char_u)'2'},
781     {MOD_MASK_MULTI_CLICK,	MOD_MASK_3CLICK,	(char_u)'3'},
782     {MOD_MASK_MULTI_CLICK,	MOD_MASK_4CLICK,	(char_u)'4'},
783 #ifdef MACOS_X
784     {MOD_MASK_CMD,		MOD_MASK_CMD,		(char_u)'D'},
785 #endif
786     // 'A' must be the last one
787     {MOD_MASK_ALT,		MOD_MASK_ALT,		(char_u)'A'},
788     {0, 0, NUL}
789     // NOTE: when adding an entry, update MAX_KEY_NAME_LEN!
790 };
791 
792 /*
793  * Shifted key terminal codes and their unshifted equivalent.
794  * Don't add mouse codes here, they are handled separately!
795  */
796 #define MOD_KEYS_ENTRY_SIZE 5
797 
798 static char_u modifier_keys_table[] =
799 {
800 //  mod mask	    with modifier		without modifier
801     MOD_MASK_SHIFT, '&', '9',			'@', '1',	// begin
802     MOD_MASK_SHIFT, '&', '0',			'@', '2',	// cancel
803     MOD_MASK_SHIFT, '*', '1',			'@', '4',	// command
804     MOD_MASK_SHIFT, '*', '2',			'@', '5',	// copy
805     MOD_MASK_SHIFT, '*', '3',			'@', '6',	// create
806     MOD_MASK_SHIFT, '*', '4',			'k', 'D',	// delete char
807     MOD_MASK_SHIFT, '*', '5',			'k', 'L',	// delete line
808     MOD_MASK_SHIFT, '*', '7',			'@', '7',	// end
809     MOD_MASK_CTRL,  KS_EXTRA, (int)KE_C_END,	'@', '7',	// end
810     MOD_MASK_SHIFT, '*', '9',			'@', '9',	// exit
811     MOD_MASK_SHIFT, '*', '0',			'@', '0',	// find
812     MOD_MASK_SHIFT, '#', '1',			'%', '1',	// help
813     MOD_MASK_SHIFT, '#', '2',			'k', 'h',	// home
814     MOD_MASK_CTRL,  KS_EXTRA, (int)KE_C_HOME,	'k', 'h',	// home
815     MOD_MASK_SHIFT, '#', '3',			'k', 'I',	// insert
816     MOD_MASK_SHIFT, '#', '4',			'k', 'l',	// left arrow
817     MOD_MASK_CTRL,  KS_EXTRA, (int)KE_C_LEFT,	'k', 'l',	// left arrow
818     MOD_MASK_SHIFT, '%', 'a',			'%', '3',	// message
819     MOD_MASK_SHIFT, '%', 'b',			'%', '4',	// move
820     MOD_MASK_SHIFT, '%', 'c',			'%', '5',	// next
821     MOD_MASK_SHIFT, '%', 'd',			'%', '7',	// options
822     MOD_MASK_SHIFT, '%', 'e',			'%', '8',	// previous
823     MOD_MASK_SHIFT, '%', 'f',			'%', '9',	// print
824     MOD_MASK_SHIFT, '%', 'g',			'%', '0',	// redo
825     MOD_MASK_SHIFT, '%', 'h',			'&', '3',	// replace
826     MOD_MASK_SHIFT, '%', 'i',			'k', 'r',	// right arr.
827     MOD_MASK_CTRL,  KS_EXTRA, (int)KE_C_RIGHT,	'k', 'r',	// right arr.
828     MOD_MASK_SHIFT, '%', 'j',			'&', '5',	// resume
829     MOD_MASK_SHIFT, '!', '1',			'&', '6',	// save
830     MOD_MASK_SHIFT, '!', '2',			'&', '7',	// suspend
831     MOD_MASK_SHIFT, '!', '3',			'&', '8',	// undo
832     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_UP,	'k', 'u',	// up arrow
833     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_DOWN,	'k', 'd',	// down arrow
834 
835 								// vt100 F1
836     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_XF1,	KS_EXTRA, (int)KE_XF1,
837     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_XF2,	KS_EXTRA, (int)KE_XF2,
838     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_XF3,	KS_EXTRA, (int)KE_XF3,
839     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_XF4,	KS_EXTRA, (int)KE_XF4,
840 
841     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F1,	'k', '1',	// F1
842     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F2,	'k', '2',
843     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F3,	'k', '3',
844     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F4,	'k', '4',
845     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F5,	'k', '5',
846     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F6,	'k', '6',
847     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F7,	'k', '7',
848     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F8,	'k', '8',
849     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F9,	'k', '9',
850     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F10,	'k', ';',	// F10
851 
852     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F11,	'F', '1',
853     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F12,	'F', '2',
854     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F13,	'F', '3',
855     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F14,	'F', '4',
856     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F15,	'F', '5',
857     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F16,	'F', '6',
858     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F17,	'F', '7',
859     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F18,	'F', '8',
860     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F19,	'F', '9',
861     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F20,	'F', 'A',
862 
863     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F21,	'F', 'B',
864     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F22,	'F', 'C',
865     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F23,	'F', 'D',
866     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F24,	'F', 'E',
867     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F25,	'F', 'F',
868     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F26,	'F', 'G',
869     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F27,	'F', 'H',
870     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F28,	'F', 'I',
871     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F29,	'F', 'J',
872     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F30,	'F', 'K',
873 
874     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F31,	'F', 'L',
875     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F32,	'F', 'M',
876     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F33,	'F', 'N',
877     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F34,	'F', 'O',
878     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F35,	'F', 'P',
879     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F36,	'F', 'Q',
880     MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F37,	'F', 'R',
881 
882 							    // TAB pseudo code
883     MOD_MASK_SHIFT, 'k', 'B',			KS_EXTRA, (int)KE_TAB,
884 
885     NUL
886 };
887 
888 static struct key_name_entry
889 {
890     int	    key;	// Special key code or ascii value
891     char_u  *name;	// Name of key
892 } key_names_table[] =
893 {
894     {' ',		(char_u *)"Space"},
895     {TAB,		(char_u *)"Tab"},
896     {K_TAB,		(char_u *)"Tab"},
897     {NL,		(char_u *)"NL"},
898     {NL,		(char_u *)"NewLine"},	// Alternative name
899     {NL,		(char_u *)"LineFeed"},	// Alternative name
900     {NL,		(char_u *)"LF"},	// Alternative name
901     {CAR,		(char_u *)"CR"},
902     {CAR,		(char_u *)"Return"},	// Alternative name
903     {CAR,		(char_u *)"Enter"},	// Alternative name
904     {K_BS,		(char_u *)"BS"},
905     {K_BS,		(char_u *)"BackSpace"},	// Alternative name
906     {ESC,		(char_u *)"Esc"},
907     {CSI,		(char_u *)"CSI"},
908     {K_CSI,		(char_u *)"xCSI"},
909     {'|',		(char_u *)"Bar"},
910     {'\\',		(char_u *)"Bslash"},
911     {K_DEL,		(char_u *)"Del"},
912     {K_DEL,		(char_u *)"Delete"},	// Alternative name
913     {K_KDEL,		(char_u *)"kDel"},
914     {K_UP,		(char_u *)"Up"},
915     {K_DOWN,		(char_u *)"Down"},
916     {K_LEFT,		(char_u *)"Left"},
917     {K_RIGHT,		(char_u *)"Right"},
918     {K_XUP,		(char_u *)"xUp"},
919     {K_XDOWN,		(char_u *)"xDown"},
920     {K_XLEFT,		(char_u *)"xLeft"},
921     {K_XRIGHT,		(char_u *)"xRight"},
922     {K_PS,		(char_u *)"PasteStart"},
923     {K_PE,		(char_u *)"PasteEnd"},
924 
925     {K_F1,		(char_u *)"F1"},
926     {K_F2,		(char_u *)"F2"},
927     {K_F3,		(char_u *)"F3"},
928     {K_F4,		(char_u *)"F4"},
929     {K_F5,		(char_u *)"F5"},
930     {K_F6,		(char_u *)"F6"},
931     {K_F7,		(char_u *)"F7"},
932     {K_F8,		(char_u *)"F8"},
933     {K_F9,		(char_u *)"F9"},
934     {K_F10,		(char_u *)"F10"},
935 
936     {K_F11,		(char_u *)"F11"},
937     {K_F12,		(char_u *)"F12"},
938     {K_F13,		(char_u *)"F13"},
939     {K_F14,		(char_u *)"F14"},
940     {K_F15,		(char_u *)"F15"},
941     {K_F16,		(char_u *)"F16"},
942     {K_F17,		(char_u *)"F17"},
943     {K_F18,		(char_u *)"F18"},
944     {K_F19,		(char_u *)"F19"},
945     {K_F20,		(char_u *)"F20"},
946 
947     {K_F21,		(char_u *)"F21"},
948     {K_F22,		(char_u *)"F22"},
949     {K_F23,		(char_u *)"F23"},
950     {K_F24,		(char_u *)"F24"},
951     {K_F25,		(char_u *)"F25"},
952     {K_F26,		(char_u *)"F26"},
953     {K_F27,		(char_u *)"F27"},
954     {K_F28,		(char_u *)"F28"},
955     {K_F29,		(char_u *)"F29"},
956     {K_F30,		(char_u *)"F30"},
957 
958     {K_F31,		(char_u *)"F31"},
959     {K_F32,		(char_u *)"F32"},
960     {K_F33,		(char_u *)"F33"},
961     {K_F34,		(char_u *)"F34"},
962     {K_F35,		(char_u *)"F35"},
963     {K_F36,		(char_u *)"F36"},
964     {K_F37,		(char_u *)"F37"},
965 
966     {K_XF1,		(char_u *)"xF1"},
967     {K_XF2,		(char_u *)"xF2"},
968     {K_XF3,		(char_u *)"xF3"},
969     {K_XF4,		(char_u *)"xF4"},
970 
971     {K_HELP,		(char_u *)"Help"},
972     {K_UNDO,		(char_u *)"Undo"},
973     {K_INS,		(char_u *)"Insert"},
974     {K_INS,		(char_u *)"Ins"},	// Alternative name
975     {K_KINS,		(char_u *)"kInsert"},
976     {K_HOME,		(char_u *)"Home"},
977     {K_KHOME,		(char_u *)"kHome"},
978     {K_XHOME,		(char_u *)"xHome"},
979     {K_ZHOME,		(char_u *)"zHome"},
980     {K_END,		(char_u *)"End"},
981     {K_KEND,		(char_u *)"kEnd"},
982     {K_XEND,		(char_u *)"xEnd"},
983     {K_ZEND,		(char_u *)"zEnd"},
984     {K_PAGEUP,		(char_u *)"PageUp"},
985     {K_PAGEDOWN,	(char_u *)"PageDown"},
986     {K_KPAGEUP,		(char_u *)"kPageUp"},
987     {K_KPAGEDOWN,	(char_u *)"kPageDown"},
988 
989     {K_KPLUS,		(char_u *)"kPlus"},
990     {K_KMINUS,		(char_u *)"kMinus"},
991     {K_KDIVIDE,		(char_u *)"kDivide"},
992     {K_KMULTIPLY,	(char_u *)"kMultiply"},
993     {K_KENTER,		(char_u *)"kEnter"},
994     {K_KPOINT,		(char_u *)"kPoint"},
995 
996     {K_K0,		(char_u *)"k0"},
997     {K_K1,		(char_u *)"k1"},
998     {K_K2,		(char_u *)"k2"},
999     {K_K3,		(char_u *)"k3"},
1000     {K_K4,		(char_u *)"k4"},
1001     {K_K5,		(char_u *)"k5"},
1002     {K_K6,		(char_u *)"k6"},
1003     {K_K7,		(char_u *)"k7"},
1004     {K_K8,		(char_u *)"k8"},
1005     {K_K9,		(char_u *)"k9"},
1006 
1007     {'<',		(char_u *)"lt"},
1008 
1009     {K_MOUSE,		(char_u *)"Mouse"},
1010 #ifdef FEAT_MOUSE_NET
1011     {K_NETTERM_MOUSE,	(char_u *)"NetMouse"},
1012 #endif
1013 #ifdef FEAT_MOUSE_DEC
1014     {K_DEC_MOUSE,	(char_u *)"DecMouse"},
1015 #endif
1016 #ifdef FEAT_MOUSE_JSB
1017     {K_JSBTERM_MOUSE,	(char_u *)"JsbMouse"},
1018 #endif
1019 #ifdef FEAT_MOUSE_PTERM
1020     {K_PTERM_MOUSE,	(char_u *)"PtermMouse"},
1021 #endif
1022 #ifdef FEAT_MOUSE_URXVT
1023     {K_URXVT_MOUSE,	(char_u *)"UrxvtMouse"},
1024 #endif
1025     {K_SGR_MOUSE,	(char_u *)"SgrMouse"},
1026     {K_SGR_MOUSERELEASE, (char_u *)"SgrMouseRelease"},
1027     {K_LEFTMOUSE,	(char_u *)"LeftMouse"},
1028     {K_LEFTMOUSE_NM,	(char_u *)"LeftMouseNM"},
1029     {K_LEFTDRAG,	(char_u *)"LeftDrag"},
1030     {K_LEFTRELEASE,	(char_u *)"LeftRelease"},
1031     {K_LEFTRELEASE_NM,	(char_u *)"LeftReleaseNM"},
1032     {K_MOUSEMOVE,	(char_u *)"MouseMove"},
1033     {K_MIDDLEMOUSE,	(char_u *)"MiddleMouse"},
1034     {K_MIDDLEDRAG,	(char_u *)"MiddleDrag"},
1035     {K_MIDDLERELEASE,	(char_u *)"MiddleRelease"},
1036     {K_RIGHTMOUSE,	(char_u *)"RightMouse"},
1037     {K_RIGHTDRAG,	(char_u *)"RightDrag"},
1038     {K_RIGHTRELEASE,	(char_u *)"RightRelease"},
1039     {K_MOUSEDOWN,	(char_u *)"ScrollWheelUp"},
1040     {K_MOUSEUP,		(char_u *)"ScrollWheelDown"},
1041     {K_MOUSELEFT,	(char_u *)"ScrollWheelRight"},
1042     {K_MOUSERIGHT,	(char_u *)"ScrollWheelLeft"},
1043     {K_MOUSEDOWN,	(char_u *)"MouseDown"}, // OBSOLETE: Use
1044     {K_MOUSEUP,		(char_u *)"MouseUp"},	// ScrollWheelXXX instead
1045     {K_X1MOUSE,		(char_u *)"X1Mouse"},
1046     {K_X1DRAG,		(char_u *)"X1Drag"},
1047     {K_X1RELEASE,		(char_u *)"X1Release"},
1048     {K_X2MOUSE,		(char_u *)"X2Mouse"},
1049     {K_X2DRAG,		(char_u *)"X2Drag"},
1050     {K_X2RELEASE,		(char_u *)"X2Release"},
1051     {K_DROP,		(char_u *)"Drop"},
1052     {K_ZERO,		(char_u *)"Nul"},
1053 #ifdef FEAT_EVAL
1054     {K_SNR,		(char_u *)"SNR"},
1055 #endif
1056     {K_PLUG,		(char_u *)"Plug"},
1057     {K_CURSORHOLD,	(char_u *)"CursorHold"},
1058     {K_IGNORE,		(char_u *)"Ignore"},
1059     {K_COMMAND,		(char_u *)"Cmd"},
1060     {K_FOCUSGAINED,	(char_u *)"FocusGained"},
1061     {K_FOCUSLOST,	(char_u *)"FocusLost"},
1062     {0,			NULL}
1063     // NOTE: When adding a long name update MAX_KEY_NAME_LEN.
1064 };
1065 
1066 #define KEY_NAMES_TABLE_LEN ARRAY_LENGTH(key_names_table)
1067 
1068 /*
1069  * Return the modifier mask bit (MOD_MASK_*) which corresponds to the given
1070  * modifier name ('S' for Shift, 'C' for Ctrl etc).
1071  */
1072     static int
name_to_mod_mask(int c)1073 name_to_mod_mask(int c)
1074 {
1075     int	    i;
1076 
1077     c = TOUPPER_ASC(c);
1078     for (i = 0; mod_mask_table[i].mod_mask != 0; i++)
1079 	if (c == mod_mask_table[i].name)
1080 	    return mod_mask_table[i].mod_flag;
1081     return 0;
1082 }
1083 
1084 /*
1085  * Check if if there is a special key code for "key" that includes the
1086  * modifiers specified.
1087  */
1088     int
simplify_key(int key,int * modifiers)1089 simplify_key(int key, int *modifiers)
1090 {
1091     int	    i;
1092     int	    key0;
1093     int	    key1;
1094 
1095     if (*modifiers & (MOD_MASK_SHIFT | MOD_MASK_CTRL | MOD_MASK_ALT))
1096     {
1097 	// TAB is a special case
1098 	if (key == TAB && (*modifiers & MOD_MASK_SHIFT))
1099 	{
1100 	    *modifiers &= ~MOD_MASK_SHIFT;
1101 	    return K_S_TAB;
1102 	}
1103 	key0 = KEY2TERMCAP0(key);
1104 	key1 = KEY2TERMCAP1(key);
1105 	for (i = 0; modifier_keys_table[i] != NUL; i += MOD_KEYS_ENTRY_SIZE)
1106 	    if (key0 == modifier_keys_table[i + 3]
1107 		    && key1 == modifier_keys_table[i + 4]
1108 		    && (*modifiers & modifier_keys_table[i]))
1109 	    {
1110 		*modifiers &= ~modifier_keys_table[i];
1111 		return TERMCAP2KEY(modifier_keys_table[i + 1],
1112 						   modifier_keys_table[i + 2]);
1113 	    }
1114     }
1115     return key;
1116 }
1117 
1118 /*
1119  * Change <xHome> to <Home>, <xUp> to <Up>, etc.
1120  */
1121     int
handle_x_keys(int key)1122 handle_x_keys(int key)
1123 {
1124     switch (key)
1125     {
1126 	case K_XUP:	return K_UP;
1127 	case K_XDOWN:	return K_DOWN;
1128 	case K_XLEFT:	return K_LEFT;
1129 	case K_XRIGHT:	return K_RIGHT;
1130 	case K_XHOME:	return K_HOME;
1131 	case K_ZHOME:	return K_HOME;
1132 	case K_XEND:	return K_END;
1133 	case K_ZEND:	return K_END;
1134 	case K_XF1:	return K_F1;
1135 	case K_XF2:	return K_F2;
1136 	case K_XF3:	return K_F3;
1137 	case K_XF4:	return K_F4;
1138 	case K_S_XF1:	return K_S_F1;
1139 	case K_S_XF2:	return K_S_F2;
1140 	case K_S_XF3:	return K_S_F3;
1141 	case K_S_XF4:	return K_S_F4;
1142     }
1143     return key;
1144 }
1145 
1146 /*
1147  * Return a string which contains the name of the given key when the given
1148  * modifiers are down.
1149  */
1150     char_u *
get_special_key_name(int c,int modifiers)1151 get_special_key_name(int c, int modifiers)
1152 {
1153     static char_u string[MAX_KEY_NAME_LEN + 1];
1154 
1155     int	    i, idx;
1156     int	    table_idx;
1157     char_u  *s;
1158 
1159     string[0] = '<';
1160     idx = 1;
1161 
1162     // Key that stands for a normal character.
1163     if (IS_SPECIAL(c) && KEY2TERMCAP0(c) == KS_KEY)
1164 	c = KEY2TERMCAP1(c);
1165 
1166     /*
1167      * Translate shifted special keys into unshifted keys and set modifier.
1168      * Same for CTRL and ALT modifiers.
1169      */
1170     if (IS_SPECIAL(c))
1171     {
1172 	for (i = 0; modifier_keys_table[i] != 0; i += MOD_KEYS_ENTRY_SIZE)
1173 	    if (       KEY2TERMCAP0(c) == (int)modifier_keys_table[i + 1]
1174 		    && (int)KEY2TERMCAP1(c) == (int)modifier_keys_table[i + 2])
1175 	    {
1176 		modifiers |= modifier_keys_table[i];
1177 		c = TERMCAP2KEY(modifier_keys_table[i + 3],
1178 						   modifier_keys_table[i + 4]);
1179 		break;
1180 	    }
1181     }
1182 
1183     // try to find the key in the special key table
1184     table_idx = find_special_key_in_table(c);
1185 
1186     /*
1187      * When not a known special key, and not a printable character, try to
1188      * extract modifiers.
1189      */
1190     if (c > 0 && (*mb_char2len)(c) == 1)
1191     {
1192 	if (table_idx < 0
1193 		&& (!vim_isprintc(c) || (c & 0x7f) == ' ')
1194 		&& (c & 0x80))
1195 	{
1196 	    c &= 0x7f;
1197 	    modifiers |= MOD_MASK_ALT;
1198 	    // try again, to find the un-alted key in the special key table
1199 	    table_idx = find_special_key_in_table(c);
1200 	}
1201 	if (table_idx < 0 && !vim_isprintc(c) && c < ' ')
1202 	{
1203 #ifdef EBCDIC
1204 	    c = CtrlChar(c);
1205 #else
1206 	    c += '@';
1207 #endif
1208 	    modifiers |= MOD_MASK_CTRL;
1209 	}
1210     }
1211 
1212     // translate the modifier into a string
1213     for (i = 0; mod_mask_table[i].name != 'A'; i++)
1214 	if ((modifiers & mod_mask_table[i].mod_mask)
1215 						== mod_mask_table[i].mod_flag)
1216 	{
1217 	    string[idx++] = mod_mask_table[i].name;
1218 	    string[idx++] = (char_u)'-';
1219 	}
1220 
1221     if (table_idx < 0)		// unknown special key, may output t_xx
1222     {
1223 	if (IS_SPECIAL(c))
1224 	{
1225 	    string[idx++] = 't';
1226 	    string[idx++] = '_';
1227 	    string[idx++] = KEY2TERMCAP0(c);
1228 	    string[idx++] = KEY2TERMCAP1(c);
1229 	}
1230 	// Not a special key, only modifiers, output directly
1231 	else
1232 	{
1233 	    if (has_mbyte && (*mb_char2len)(c) > 1)
1234 		idx += (*mb_char2bytes)(c, string + idx);
1235 	    else if (vim_isprintc(c))
1236 		string[idx++] = c;
1237 	    else
1238 	    {
1239 		s = transchar(c);
1240 		while (*s)
1241 		    string[idx++] = *s++;
1242 	    }
1243 	}
1244     }
1245     else		// use name of special key
1246     {
1247 	size_t len = STRLEN(key_names_table[table_idx].name);
1248 
1249 	if (len + idx + 2 <= MAX_KEY_NAME_LEN)
1250 	{
1251 	    STRCPY(string + idx, key_names_table[table_idx].name);
1252 	    idx += (int)len;
1253 	}
1254     }
1255     string[idx++] = '>';
1256     string[idx] = NUL;
1257     return string;
1258 }
1259 
1260 /*
1261  * Try translating a <> name at (*srcp)[] to dst[].
1262  * Return the number of characters added to dst[], zero for no match.
1263  * If there is a match, srcp is advanced to after the <> name.
1264  * dst[] must be big enough to hold the result (up to six characters)!
1265  */
1266     int
trans_special(char_u ** srcp,char_u * dst,int flags,int * did_simplify)1267 trans_special(
1268     char_u	**srcp,
1269     char_u	*dst,
1270     int		flags,		// FSK_ values
1271     int		*did_simplify)  // FSK_SIMPLIFY and found <C-H> or <A-x>
1272 {
1273     int		modifiers = 0;
1274     int		key;
1275 
1276     key = find_special_key(srcp, &modifiers, flags, did_simplify);
1277     if (key == 0)
1278 	return 0;
1279 
1280     return special_to_buf(key, modifiers, flags & FSK_KEYCODE, dst);
1281 }
1282 
1283 /*
1284  * Put the character sequence for "key" with "modifiers" into "dst" and return
1285  * the resulting length.
1286  * When "keycode" is TRUE prefer key code, e.g. K_DEL instead of DEL.
1287  * The sequence is not NUL terminated.
1288  * This is how characters in a string are encoded.
1289  */
1290     int
special_to_buf(int key,int modifiers,int keycode,char_u * dst)1291 special_to_buf(int key, int modifiers, int keycode, char_u *dst)
1292 {
1293     int		dlen = 0;
1294 
1295     // Put the appropriate modifier in a string
1296     if (modifiers != 0)
1297     {
1298 	dst[dlen++] = K_SPECIAL;
1299 	dst[dlen++] = KS_MODIFIER;
1300 	dst[dlen++] = modifiers;
1301     }
1302 
1303     if (IS_SPECIAL(key))
1304     {
1305 	dst[dlen++] = K_SPECIAL;
1306 	dst[dlen++] = KEY2TERMCAP0(key);
1307 	dst[dlen++] = KEY2TERMCAP1(key);
1308     }
1309     else if (has_mbyte && !keycode)
1310 	dlen += (*mb_char2bytes)(key, dst + dlen);
1311     else if (keycode)
1312 	dlen = (int)(add_char2buf(key, dst + dlen) - dst);
1313     else
1314 	dst[dlen++] = key;
1315 
1316     return dlen;
1317 }
1318 
1319 /*
1320  * Try translating a <> name at (*srcp)[], return the key and modifiers.
1321  * srcp is advanced to after the <> name.
1322  * returns 0 if there is no match.
1323  */
1324     int
find_special_key(char_u ** srcp,int * modp,int flags,int * did_simplify)1325 find_special_key(
1326     char_u	**srcp,
1327     int		*modp,
1328     int		flags,		// FSK_ values
1329     int		*did_simplify)  // found <C-H> or <A-x>
1330 {
1331     char_u	*last_dash;
1332     char_u	*end_of_name;
1333     char_u	*src;
1334     char_u	*bp;
1335     int		in_string = flags & FSK_IN_STRING;
1336     int		modifiers;
1337     int		bit;
1338     int		key;
1339     uvarnumber_T	n;
1340     int		l;
1341 
1342     src = *srcp;
1343     if (src[0] != '<')
1344 	return 0;
1345     if (src[1] == '*')	    // <*xxx>: do not simplify
1346 	++src;
1347 
1348     // Find end of modifier list
1349     last_dash = src;
1350     for (bp = src + 1; *bp == '-' || vim_isNormalIDc(*bp); bp++)
1351     {
1352 	if (*bp == '-')
1353 	{
1354 	    last_dash = bp;
1355 	    if (bp[1] != NUL)
1356 	    {
1357 		if (has_mbyte)
1358 		    l = mb_ptr2len(bp + 1);
1359 		else
1360 		    l = 1;
1361 		// Anything accepted, like <C-?>.
1362 		// <C-"> or <M-"> are not special in strings as " is
1363 		// the string delimiter. With a backslash it works: <M-\">
1364 		if (!(in_string && bp[1] == '"') && bp[l + 1] == '>')
1365 		    bp += l;
1366 		else if (in_string && bp[1] == '\\' && bp[2] == '"'
1367 							   && bp[3] == '>')
1368 		    bp += 2;
1369 	    }
1370 	}
1371 	if (bp[0] == 't' && bp[1] == '_' && bp[2] && bp[3])
1372 	    bp += 3;	// skip t_xx, xx may be '-' or '>'
1373 	else if (STRNICMP(bp, "char-", 5) == 0)
1374 	{
1375 	    vim_str2nr(bp + 5, NULL, &l, STR2NR_ALL, NULL, NULL, 0, TRUE);
1376 	    if (l == 0)
1377 	    {
1378 		emsg(_(e_invarg));
1379 		return 0;
1380 	    }
1381 	    bp += l + 5;
1382 	    break;
1383 	}
1384     }
1385 
1386     if (*bp == '>')	// found matching '>'
1387     {
1388 	end_of_name = bp + 1;
1389 
1390 	// Which modifiers are given?
1391 	modifiers = 0x0;
1392 	for (bp = src + 1; bp < last_dash; bp++)
1393 	{
1394 	    if (*bp != '-')
1395 	    {
1396 		bit = name_to_mod_mask(*bp);
1397 		if (bit == 0x0)
1398 		    break;	// Illegal modifier name
1399 		modifiers |= bit;
1400 	    }
1401 	}
1402 
1403 	/*
1404 	 * Legal modifier name.
1405 	 */
1406 	if (bp >= last_dash)
1407 	{
1408 	    if (STRNICMP(last_dash + 1, "char-", 5) == 0
1409 						 && VIM_ISDIGIT(last_dash[6]))
1410 	    {
1411 		// <Char-123> or <Char-033> or <Char-0x33>
1412 		vim_str2nr(last_dash + 6, NULL, &l, STR2NR_ALL, NULL,
1413 								  &n, 0, TRUE);
1414 		if (l == 0)
1415 		{
1416 		    emsg(_(e_invarg));
1417 		    return 0;
1418 		}
1419 		key = (int)n;
1420 	    }
1421 	    else
1422 	    {
1423 		int off = 1;
1424 
1425 		// Modifier with single letter, or special key name.
1426 		if (in_string && last_dash[1] == '\\' && last_dash[2] == '"')
1427 		    off = 2;
1428 		if (has_mbyte)
1429 		    l = mb_ptr2len(last_dash + off);
1430 		else
1431 		    l = 1;
1432 		if (modifiers != 0 && last_dash[l + off] == '>')
1433 		    key = PTR2CHAR(last_dash + off);
1434 		else
1435 		{
1436 		    key = get_special_key_code(last_dash + off);
1437 		    if (!(flags & FSK_KEEP_X_KEY))
1438 			key = handle_x_keys(key);
1439 		}
1440 	    }
1441 
1442 	    /*
1443 	     * get_special_key_code() may return NUL for invalid
1444 	     * special key name.
1445 	     */
1446 	    if (key != NUL)
1447 	    {
1448 		/*
1449 		 * Only use a modifier when there is no special key code that
1450 		 * includes the modifier.
1451 		 */
1452 		key = simplify_key(key, &modifiers);
1453 
1454 		if (!(flags & FSK_KEYCODE))
1455 		{
1456 		    // don't want keycode, use single byte code
1457 		    if (key == K_BS)
1458 			key = BS;
1459 		    else if (key == K_DEL || key == K_KDEL)
1460 			key = DEL;
1461 		}
1462 
1463 		// Normal Key with modifier: Try to make a single byte code.
1464 		if (!IS_SPECIAL(key))
1465 		    key = extract_modifiers(key, &modifiers,
1466 					   flags & FSK_SIMPLIFY, did_simplify);
1467 
1468 		*modp = modifiers;
1469 		*srcp = end_of_name;
1470 		return key;
1471 	    }
1472 	}
1473     }
1474     return 0;
1475 }
1476 
1477 
1478 /*
1479  * Some keys are used with Ctrl without Shift and are still expected to be
1480  * mapped as if Shift was pressed:
1481  * CTRL-2 is CTRL-@
1482  * CTRL-6 is CTRL-^
1483  * CTRL-- is CTRL-_
1484  * Also, <C-H> and <C-h> mean the same thing, always use "H".
1485  * Returns the possibly adjusted key.
1486  */
1487     int
may_adjust_key_for_ctrl(int modifiers,int key)1488 may_adjust_key_for_ctrl(int modifiers, int key)
1489 {
1490     if (modifiers & MOD_MASK_CTRL)
1491     {
1492 	if (ASCII_ISALPHA(key))
1493 	    return TOUPPER_ASC(key);
1494 	if (key == '2')
1495 	    return '@';
1496 	if (key == '6')
1497 	    return '^';
1498 	if (key == '-')
1499 	    return '_';
1500     }
1501     return key;
1502 }
1503 
1504 /*
1505  * Some keys already have Shift included, pass them as normal keys.
1506  * When Ctrl is also used <C-H> and <C-S-H> are different, but <C-S-{> should
1507  * be <C-{>.  Same for <C-S-}> and <C-S-|>.
1508  * Also for <A-S-a> and <M-S-a>.
1509  * This includes all printable ASCII characters except numbers and a-z.
1510  */
1511     int
may_remove_shift_modifier(int modifiers,int key)1512 may_remove_shift_modifier(int modifiers, int key)
1513 {
1514     if ((modifiers == MOD_MASK_SHIFT
1515 		|| modifiers == (MOD_MASK_SHIFT | MOD_MASK_ALT)
1516 		|| modifiers == (MOD_MASK_SHIFT | MOD_MASK_META))
1517 	    && ((key >= '!' && key <= '/')
1518 		|| (key >= ':' && key <= 'Z')
1519 		|| (key >= '[' && key <= '`')
1520 		|| (key >= '{' && key <= '~')))
1521 	return modifiers & ~MOD_MASK_SHIFT;
1522 
1523     if (modifiers == (MOD_MASK_SHIFT | MOD_MASK_CTRL)
1524 		&& (key == '{' || key == '}' || key == '|'))
1525 	return modifiers & ~MOD_MASK_SHIFT;
1526 
1527     return modifiers;
1528 }
1529 
1530 /*
1531  * Try to include modifiers in the key.
1532  * Changes "Shift-a" to 'A', "Alt-A" to 0xc0, etc.
1533  * When "simplify" is FALSE don't do Ctrl and Alt.
1534  * When "simplify" is TRUE and Ctrl or Alt is removed from modifiers set
1535  * "did_simplify" when it's not NULL.
1536  */
1537     int
extract_modifiers(int key,int * modp,int simplify,int * did_simplify)1538 extract_modifiers(int key, int *modp, int simplify, int *did_simplify)
1539 {
1540     int	modifiers = *modp;
1541 
1542 #ifdef MACOS_X
1543     // Command-key really special, no fancynest
1544     if (!(modifiers & MOD_MASK_CMD))
1545 #endif
1546     if ((modifiers & MOD_MASK_SHIFT) && ASCII_ISALPHA(key))
1547     {
1548 	key = TOUPPER_ASC(key);
1549 	// With <C-S-a> we keep the shift modifier.
1550 	// With <S-a>, <A-S-a> and <S-A> we don't keep the shift modifier.
1551 	if (simplify || modifiers == MOD_MASK_SHIFT
1552 		|| modifiers == (MOD_MASK_SHIFT | MOD_MASK_ALT)
1553 		|| modifiers == (MOD_MASK_SHIFT | MOD_MASK_META))
1554 	    modifiers &= ~MOD_MASK_SHIFT;
1555     }
1556 
1557     // <C-H> and <C-h> mean the same thing, always use "H"
1558     if ((modifiers & MOD_MASK_CTRL) && ASCII_ISALPHA(key))
1559 	key = TOUPPER_ASC(key);
1560 
1561     if (simplify && (modifiers & MOD_MASK_CTRL)
1562 #ifdef EBCDIC
1563 	    // TODO: EBCDIC Better use:
1564 	    // && (Ctrl_chr(key) || key == '?')
1565 	    // ???
1566 	    && strchr("?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_", key)
1567 						       != NULL
1568 #else
1569 	    && ((key >= '?' && key <= '_') || ASCII_ISALPHA(key))
1570 #endif
1571 	    )
1572     {
1573 	key = Ctrl_chr(key);
1574 	modifiers &= ~MOD_MASK_CTRL;
1575 	// <C-@> is <Nul>
1576 	if (key == 0)
1577 	    key = K_ZERO;
1578 	if (did_simplify != NULL)
1579 	    *did_simplify = TRUE;
1580     }
1581 
1582 #ifdef MACOS_X
1583     // Command-key really special, no fancynest
1584     if (!(modifiers & MOD_MASK_CMD))
1585 #endif
1586     if (simplify && (modifiers & MOD_MASK_ALT) && key < 0x80
1587 	    && !enc_dbcs)		// avoid creating a lead byte
1588     {
1589 	key |= 0x80;
1590 	modifiers &= ~MOD_MASK_ALT;	// remove the META modifier
1591 	if (did_simplify != NULL)
1592 	    *did_simplify = TRUE;
1593     }
1594 
1595     *modp = modifiers;
1596     return key;
1597 }
1598 
1599 /*
1600  * Try to find key "c" in the special key table.
1601  * Return the index when found, -1 when not found.
1602  */
1603     int
find_special_key_in_table(int c)1604 find_special_key_in_table(int c)
1605 {
1606     int	    i;
1607 
1608     for (i = 0; key_names_table[i].name != NULL; i++)
1609 	if (c == key_names_table[i].key)
1610 	    break;
1611     if (key_names_table[i].name == NULL)
1612 	i = -1;
1613     return i;
1614 }
1615 
1616 /*
1617  * Find the special key with the given name (the given string does not have to
1618  * end with NUL, the name is assumed to end before the first non-idchar).
1619  * If the name starts with "t_" the next two characters are interpreted as a
1620  * termcap name.
1621  * Return the key code, or 0 if not found.
1622  */
1623     int
get_special_key_code(char_u * name)1624 get_special_key_code(char_u *name)
1625 {
1626     char_u  *table_name;
1627     char_u  string[3];
1628     int	    i, j;
1629 
1630     /*
1631      * If it's <t_xx> we get the code for xx from the termcap
1632      */
1633     if (name[0] == 't' && name[1] == '_' && name[2] != NUL && name[3] != NUL)
1634     {
1635 	string[0] = name[2];
1636 	string[1] = name[3];
1637 	string[2] = NUL;
1638 	if (add_termcap_entry(string, FALSE) == OK)
1639 	    return TERMCAP2KEY(name[2], name[3]);
1640     }
1641     else
1642 	for (i = 0; key_names_table[i].name != NULL; i++)
1643 	{
1644 	    table_name = key_names_table[i].name;
1645 	    for (j = 0; vim_isNormalIDc(name[j]) && table_name[j] != NUL; j++)
1646 		if (TOLOWER_ASC(table_name[j]) != TOLOWER_ASC(name[j]))
1647 		    break;
1648 	    if (!vim_isNormalIDc(name[j]) && table_name[j] == NUL)
1649 		return key_names_table[i].key;
1650 	}
1651     return 0;
1652 }
1653 
1654     char_u *
get_key_name(int i)1655 get_key_name(int i)
1656 {
1657     if (i >= (int)KEY_NAMES_TABLE_LEN)
1658 	return NULL;
1659     return  key_names_table[i].name;
1660 }
1661 
1662 /*
1663  * Return the current end-of-line type: EOL_DOS, EOL_UNIX or EOL_MAC.
1664  */
1665     int
get_fileformat(buf_T * buf)1666 get_fileformat(buf_T *buf)
1667 {
1668     int		c = *buf->b_p_ff;
1669 
1670     if (buf->b_p_bin || c == 'u')
1671 	return EOL_UNIX;
1672     if (c == 'm')
1673 	return EOL_MAC;
1674     return EOL_DOS;
1675 }
1676 
1677 /*
1678  * Like get_fileformat(), but override 'fileformat' with "p" for "++opt=val"
1679  * argument.
1680  */
1681     int
get_fileformat_force(buf_T * buf,exarg_T * eap)1682 get_fileformat_force(
1683     buf_T	*buf,
1684     exarg_T	*eap)	    // can be NULL!
1685 {
1686     int		c;
1687 
1688     if (eap != NULL && eap->force_ff != 0)
1689 	c = eap->force_ff;
1690     else
1691     {
1692 	if ((eap != NULL && eap->force_bin != 0)
1693 			       ? (eap->force_bin == FORCE_BIN) : buf->b_p_bin)
1694 	    return EOL_UNIX;
1695 	c = *buf->b_p_ff;
1696     }
1697     if (c == 'u')
1698 	return EOL_UNIX;
1699     if (c == 'm')
1700 	return EOL_MAC;
1701     return EOL_DOS;
1702 }
1703 
1704 /*
1705  * Set the current end-of-line type to EOL_DOS, EOL_UNIX or EOL_MAC.
1706  * Sets both 'textmode' and 'fileformat'.
1707  * Note: Does _not_ set global value of 'textmode'!
1708  */
1709     void
set_fileformat(int t,int opt_flags)1710 set_fileformat(
1711     int		t,
1712     int		opt_flags)	// OPT_LOCAL and/or OPT_GLOBAL
1713 {
1714     char	*p = NULL;
1715 
1716     switch (t)
1717     {
1718     case EOL_DOS:
1719 	p = FF_DOS;
1720 	curbuf->b_p_tx = TRUE;
1721 	break;
1722     case EOL_UNIX:
1723 	p = FF_UNIX;
1724 	curbuf->b_p_tx = FALSE;
1725 	break;
1726     case EOL_MAC:
1727 	p = FF_MAC;
1728 	curbuf->b_p_tx = FALSE;
1729 	break;
1730     }
1731     if (p != NULL)
1732 	set_string_option_direct((char_u *)"ff", -1, (char_u *)p,
1733 						     OPT_FREE | opt_flags, 0);
1734 
1735     // This may cause the buffer to become (un)modified.
1736     check_status(curbuf);
1737     redraw_tabline = TRUE;
1738     need_maketitle = TRUE;	    // set window title later
1739 }
1740 
1741 /*
1742  * Return the default fileformat from 'fileformats'.
1743  */
1744     int
default_fileformat(void)1745 default_fileformat(void)
1746 {
1747     switch (*p_ffs)
1748     {
1749 	case 'm':   return EOL_MAC;
1750 	case 'd':   return EOL_DOS;
1751     }
1752     return EOL_UNIX;
1753 }
1754 
1755 /*
1756  * Call shell.	Calls mch_call_shell, with 'shellxquote' added.
1757  */
1758     int
call_shell(char_u * cmd,int opt)1759 call_shell(char_u *cmd, int opt)
1760 {
1761     char_u	*ncmd;
1762     int		retval;
1763 #ifdef FEAT_PROFILE
1764     proftime_T	wait_time;
1765 #endif
1766 
1767     if (p_verbose > 3)
1768     {
1769 	verbose_enter();
1770 	smsg(_("Calling shell to execute: \"%s\""), cmd == NULL ? p_sh : cmd);
1771 	out_char('\n');
1772 	cursor_on();
1773 	verbose_leave();
1774     }
1775 
1776 #ifdef FEAT_PROFILE
1777     if (do_profiling == PROF_YES)
1778 	prof_child_enter(&wait_time);
1779 #endif
1780 
1781     if (*p_sh == NUL)
1782     {
1783 	emsg(_(e_shellempty));
1784 	retval = -1;
1785     }
1786     else
1787     {
1788 #ifdef FEAT_GUI_MSWIN
1789 	// Don't hide the pointer while executing a shell command.
1790 	gui_mch_mousehide(FALSE);
1791 #endif
1792 #ifdef FEAT_GUI
1793 	++hold_gui_events;
1794 #endif
1795 	// The external command may update a tags file, clear cached tags.
1796 	tag_freematch();
1797 
1798 	if (cmd == NULL || *p_sxq == NUL)
1799 	    retval = mch_call_shell(cmd, opt);
1800 	else
1801 	{
1802 	    char_u *ecmd = cmd;
1803 
1804 	    if (*p_sxe != NUL && *p_sxq == '(')
1805 	    {
1806 		ecmd = vim_strsave_escaped_ext(cmd, p_sxe, '^', FALSE);
1807 		if (ecmd == NULL)
1808 		    ecmd = cmd;
1809 	    }
1810 	    ncmd = alloc(STRLEN(ecmd) + STRLEN(p_sxq) * 2 + 1);
1811 	    if (ncmd != NULL)
1812 	    {
1813 		STRCPY(ncmd, p_sxq);
1814 		STRCAT(ncmd, ecmd);
1815 		// When 'shellxquote' is ( append ).
1816 		// When 'shellxquote' is "( append )".
1817 		STRCAT(ncmd, *p_sxq == '(' ? (char_u *)")"
1818 		    : *p_sxq == '"' && *(p_sxq+1) == '(' ? (char_u *)")\""
1819 		    : p_sxq);
1820 		retval = mch_call_shell(ncmd, opt);
1821 		vim_free(ncmd);
1822 	    }
1823 	    else
1824 		retval = -1;
1825 	    if (ecmd != cmd)
1826 		vim_free(ecmd);
1827 	}
1828 #ifdef FEAT_GUI
1829 	--hold_gui_events;
1830 #endif
1831 	/*
1832 	 * Check the window size, in case it changed while executing the
1833 	 * external command.
1834 	 */
1835 	shell_resized_check();
1836     }
1837 
1838 #ifdef FEAT_EVAL
1839     set_vim_var_nr(VV_SHELL_ERROR, (long)retval);
1840 # ifdef FEAT_PROFILE
1841     if (do_profiling == PROF_YES)
1842 	prof_child_exit(&wait_time);
1843 # endif
1844 #endif
1845 
1846     return retval;
1847 }
1848 
1849 /*
1850  * VISUAL, SELECTMODE and OP_PENDING State are never set, they are equal to
1851  * NORMAL State with a condition.  This function returns the real State.
1852  */
1853     int
get_real_state(void)1854 get_real_state(void)
1855 {
1856     if (State & NORMAL)
1857     {
1858 	if (VIsual_active)
1859 	{
1860 	    if (VIsual_select)
1861 		return SELECTMODE;
1862 	    return VISUAL;
1863 	}
1864 	else if (finish_op)
1865 	    return OP_PENDING;
1866     }
1867     return State;
1868 }
1869 
1870 /*
1871  * Return TRUE if "p" points to just after a path separator.
1872  * Takes care of multi-byte characters.
1873  * "b" must point to the start of the file name
1874  */
1875     int
after_pathsep(char_u * b,char_u * p)1876 after_pathsep(char_u *b, char_u *p)
1877 {
1878     return p > b && vim_ispathsep(p[-1])
1879 			     && (!has_mbyte || (*mb_head_off)(b, p - 1) == 0);
1880 }
1881 
1882 /*
1883  * Return TRUE if file names "f1" and "f2" are in the same directory.
1884  * "f1" may be a short name, "f2" must be a full path.
1885  */
1886     int
same_directory(char_u * f1,char_u * f2)1887 same_directory(char_u *f1, char_u *f2)
1888 {
1889     char_u	ffname[MAXPATHL];
1890     char_u	*t1;
1891     char_u	*t2;
1892 
1893     // safety check
1894     if (f1 == NULL || f2 == NULL)
1895 	return FALSE;
1896 
1897     (void)vim_FullName(f1, ffname, MAXPATHL, FALSE);
1898     t1 = gettail_sep(ffname);
1899     t2 = gettail_sep(f2);
1900     return (t1 - ffname == t2 - f2
1901 	     && pathcmp((char *)ffname, (char *)f2, (int)(t1 - ffname)) == 0);
1902 }
1903 
1904 #if defined(FEAT_SESSION) || defined(FEAT_AUTOCHDIR) \
1905 	|| defined(MSWIN) || defined(FEAT_GUI_GTK) \
1906 	|| defined(FEAT_NETBEANS_INTG) \
1907 	|| defined(PROTO)
1908 /*
1909  * Change to a file's directory.
1910  * Caller must call shorten_fnames()!
1911  * Return OK or FAIL.
1912  */
1913     int
vim_chdirfile(char_u * fname,char * trigger_autocmd)1914 vim_chdirfile(char_u *fname, char *trigger_autocmd)
1915 {
1916     char_u	old_dir[MAXPATHL];
1917     char_u	new_dir[MAXPATHL];
1918     int		res;
1919 
1920     if (mch_dirname(old_dir, MAXPATHL) != OK)
1921 	*old_dir = NUL;
1922 
1923     vim_strncpy(new_dir, fname, MAXPATHL - 1);
1924     *gettail_sep(new_dir) = NUL;
1925 
1926     if (pathcmp((char *)old_dir, (char *)new_dir, -1) == 0)
1927 	// nothing to do
1928 	res = OK;
1929     else
1930     {
1931 	res = mch_chdir((char *)new_dir) == 0 ? OK : FAIL;
1932 
1933 	if (res == OK && trigger_autocmd != NULL)
1934 	    apply_autocmds(EVENT_DIRCHANGED, (char_u *)trigger_autocmd,
1935 						       new_dir, FALSE, curbuf);
1936     }
1937     return res;
1938 }
1939 #endif
1940 
1941 #if defined(STAT_IGNORES_SLASH) || defined(PROTO)
1942 /*
1943  * Check if "name" ends in a slash and is not a directory.
1944  * Used for systems where stat() ignores a trailing slash on a file name.
1945  * The Vim code assumes a trailing slash is only ignored for a directory.
1946  */
1947     static int
illegal_slash(const char * name)1948 illegal_slash(const char *name)
1949 {
1950     if (name[0] == NUL)
1951 	return FALSE;	    // no file name is not illegal
1952     if (name[strlen(name) - 1] != '/')
1953 	return FALSE;	    // no trailing slash
1954     if (mch_isdir((char_u *)name))
1955 	return FALSE;	    // trailing slash for a directory
1956     return TRUE;
1957 }
1958 
1959 /*
1960  * Special implementation of mch_stat() for Solaris.
1961  */
1962     int
vim_stat(const char * name,stat_T * stp)1963 vim_stat(const char *name, stat_T *stp)
1964 {
1965     // On Solaris stat() accepts "file/" as if it was "file".  Return -1 if
1966     // the name ends in "/" and it's not a directory.
1967     return illegal_slash(name) ? -1 : stat(name, stp);
1968 }
1969 #endif
1970 
1971 #if defined(CURSOR_SHAPE) || defined(PROTO)
1972 
1973 /*
1974  * Handling of cursor and mouse pointer shapes in various modes.
1975  */
1976 
1977 cursorentry_T shape_table[SHAPE_IDX_COUNT] =
1978 {
1979     // The values will be filled in from the 'guicursor' and 'mouseshape'
1980     // defaults when Vim starts.
1981     // Adjust the SHAPE_IDX_ defines when making changes!
1982     {0,	0, 0, 700L, 400L, 250L, 0, 0, "n", SHAPE_CURSOR+SHAPE_MOUSE},
1983     {0,	0, 0, 700L, 400L, 250L, 0, 0, "v", SHAPE_CURSOR+SHAPE_MOUSE},
1984     {0,	0, 0, 700L, 400L, 250L, 0, 0, "i", SHAPE_CURSOR+SHAPE_MOUSE},
1985     {0,	0, 0, 700L, 400L, 250L, 0, 0, "r", SHAPE_CURSOR+SHAPE_MOUSE},
1986     {0,	0, 0, 700L, 400L, 250L, 0, 0, "c", SHAPE_CURSOR+SHAPE_MOUSE},
1987     {0,	0, 0, 700L, 400L, 250L, 0, 0, "ci", SHAPE_CURSOR+SHAPE_MOUSE},
1988     {0,	0, 0, 700L, 400L, 250L, 0, 0, "cr", SHAPE_CURSOR+SHAPE_MOUSE},
1989     {0,	0, 0, 700L, 400L, 250L, 0, 0, "o", SHAPE_CURSOR+SHAPE_MOUSE},
1990     {0,	0, 0, 700L, 400L, 250L, 0, 0, "ve", SHAPE_CURSOR+SHAPE_MOUSE},
1991     {0,	0, 0,   0L,   0L,   0L, 0, 0, "e", SHAPE_MOUSE},
1992     {0,	0, 0,   0L,   0L,   0L, 0, 0, "s", SHAPE_MOUSE},
1993     {0,	0, 0,   0L,   0L,   0L, 0, 0, "sd", SHAPE_MOUSE},
1994     {0,	0, 0,   0L,   0L,   0L, 0, 0, "vs", SHAPE_MOUSE},
1995     {0,	0, 0,   0L,   0L,   0L, 0, 0, "vd", SHAPE_MOUSE},
1996     {0,	0, 0,   0L,   0L,   0L, 0, 0, "m", SHAPE_MOUSE},
1997     {0,	0, 0,   0L,   0L,   0L, 0, 0, "ml", SHAPE_MOUSE},
1998     {0,	0, 0, 100L, 100L, 100L, 0, 0, "sm", SHAPE_CURSOR},
1999 };
2000 
2001 #ifdef FEAT_MOUSESHAPE
2002 /*
2003  * Table with names for mouse shapes.  Keep in sync with all the tables for
2004  * mch_set_mouse_shape()!.
2005  */
2006 static char * mshape_names[] =
2007 {
2008     "arrow",	// default, must be the first one
2009     "blank",	// hidden
2010     "beam",
2011     "updown",
2012     "udsizing",
2013     "leftright",
2014     "lrsizing",
2015     "busy",
2016     "no",
2017     "crosshair",
2018     "hand1",
2019     "hand2",
2020     "pencil",
2021     "question",
2022     "rightup-arrow",
2023     "up-arrow",
2024     NULL
2025 };
2026 #endif
2027 
2028 /*
2029  * Parse the 'guicursor' option ("what" is SHAPE_CURSOR) or 'mouseshape'
2030  * ("what" is SHAPE_MOUSE).
2031  * Returns error message for an illegal option, NULL otherwise.
2032  */
2033     char *
parse_shape_opt(int what)2034 parse_shape_opt(int what)
2035 {
2036     char_u	*modep;
2037     char_u	*colonp;
2038     char_u	*commap;
2039     char_u	*slashp;
2040     char_u	*p, *endp;
2041     int		idx = 0;		// init for GCC
2042     int		all_idx;
2043     int		len;
2044     int		i;
2045     long	n;
2046     int		found_ve = FALSE;	// found "ve" flag
2047     int		round;
2048 
2049     /*
2050      * First round: check for errors; second round: do it for real.
2051      */
2052     for (round = 1; round <= 2; ++round)
2053     {
2054 	/*
2055 	 * Repeat for all comma separated parts.
2056 	 */
2057 #ifdef FEAT_MOUSESHAPE
2058 	if (what == SHAPE_MOUSE)
2059 	    modep = p_mouseshape;
2060 	else
2061 #endif
2062 	    modep = p_guicursor;
2063 	while (*modep != NUL)
2064 	{
2065 	    colonp = vim_strchr(modep, ':');
2066 	    commap = vim_strchr(modep, ',');
2067 
2068 	    if (colonp == NULL || (commap != NULL && commap < colonp))
2069 		return N_("E545: Missing colon");
2070 	    if (colonp == modep)
2071 		return N_("E546: Illegal mode");
2072 
2073 	    /*
2074 	     * Repeat for all mode's before the colon.
2075 	     * For the 'a' mode, we loop to handle all the modes.
2076 	     */
2077 	    all_idx = -1;
2078 	    while (modep < colonp || all_idx >= 0)
2079 	    {
2080 		if (all_idx < 0)
2081 		{
2082 		    // Find the mode.
2083 		    if (modep[1] == '-' || modep[1] == ':')
2084 			len = 1;
2085 		    else
2086 			len = 2;
2087 		    if (len == 1 && TOLOWER_ASC(modep[0]) == 'a')
2088 			all_idx = SHAPE_IDX_COUNT - 1;
2089 		    else
2090 		    {
2091 			for (idx = 0; idx < SHAPE_IDX_COUNT; ++idx)
2092 			    if (STRNICMP(modep, shape_table[idx].name, len)
2093 									 == 0)
2094 				break;
2095 			if (idx == SHAPE_IDX_COUNT
2096 				   || (shape_table[idx].used_for & what) == 0)
2097 			    return N_("E546: Illegal mode");
2098 			if (len == 2 && modep[0] == 'v' && modep[1] == 'e')
2099 			    found_ve = TRUE;
2100 		    }
2101 		    modep += len + 1;
2102 		}
2103 
2104 		if (all_idx >= 0)
2105 		    idx = all_idx--;
2106 		else if (round == 2)
2107 		{
2108 #ifdef FEAT_MOUSESHAPE
2109 		    if (what == SHAPE_MOUSE)
2110 		    {
2111 			// Set the default, for the missing parts
2112 			shape_table[idx].mshape = 0;
2113 		    }
2114 		    else
2115 #endif
2116 		    {
2117 			// Set the defaults, for the missing parts
2118 			shape_table[idx].shape = SHAPE_BLOCK;
2119 			shape_table[idx].blinkwait = 700L;
2120 			shape_table[idx].blinkon = 400L;
2121 			shape_table[idx].blinkoff = 250L;
2122 		    }
2123 		}
2124 
2125 		// Parse the part after the colon
2126 		for (p = colonp + 1; *p && *p != ','; )
2127 		{
2128 #ifdef FEAT_MOUSESHAPE
2129 		    if (what == SHAPE_MOUSE)
2130 		    {
2131 			for (i = 0; ; ++i)
2132 			{
2133 			    if (mshape_names[i] == NULL)
2134 			    {
2135 				if (!VIM_ISDIGIT(*p))
2136 				    return N_("E547: Illegal mouseshape");
2137 				if (round == 2)
2138 				    shape_table[idx].mshape =
2139 					      getdigits(&p) + MSHAPE_NUMBERED;
2140 				else
2141 				    (void)getdigits(&p);
2142 				break;
2143 			    }
2144 			    len = (int)STRLEN(mshape_names[i]);
2145 			    if (STRNICMP(p, mshape_names[i], len) == 0)
2146 			    {
2147 				if (round == 2)
2148 				    shape_table[idx].mshape = i;
2149 				p += len;
2150 				break;
2151 			    }
2152 			}
2153 		    }
2154 		    else // if (what == SHAPE_MOUSE)
2155 #endif
2156 		    {
2157 			/*
2158 			 * First handle the ones with a number argument.
2159 			 */
2160 			i = *p;
2161 			len = 0;
2162 			if (STRNICMP(p, "ver", 3) == 0)
2163 			    len = 3;
2164 			else if (STRNICMP(p, "hor", 3) == 0)
2165 			    len = 3;
2166 			else if (STRNICMP(p, "blinkwait", 9) == 0)
2167 			    len = 9;
2168 			else if (STRNICMP(p, "blinkon", 7) == 0)
2169 			    len = 7;
2170 			else if (STRNICMP(p, "blinkoff", 8) == 0)
2171 			    len = 8;
2172 			if (len != 0)
2173 			{
2174 			    p += len;
2175 			    if (!VIM_ISDIGIT(*p))
2176 				return N_("E548: digit expected");
2177 			    n = getdigits(&p);
2178 			    if (len == 3)   // "ver" or "hor"
2179 			    {
2180 				if (n == 0)
2181 				    return N_("E549: Illegal percentage");
2182 				if (round == 2)
2183 				{
2184 				    if (TOLOWER_ASC(i) == 'v')
2185 					shape_table[idx].shape = SHAPE_VER;
2186 				    else
2187 					shape_table[idx].shape = SHAPE_HOR;
2188 				    shape_table[idx].percentage = n;
2189 				}
2190 			    }
2191 			    else if (round == 2)
2192 			    {
2193 				if (len == 9)
2194 				    shape_table[idx].blinkwait = n;
2195 				else if (len == 7)
2196 				    shape_table[idx].blinkon = n;
2197 				else
2198 				    shape_table[idx].blinkoff = n;
2199 			    }
2200 			}
2201 			else if (STRNICMP(p, "block", 5) == 0)
2202 			{
2203 			    if (round == 2)
2204 				shape_table[idx].shape = SHAPE_BLOCK;
2205 			    p += 5;
2206 			}
2207 			else	// must be a highlight group name then
2208 			{
2209 			    endp = vim_strchr(p, '-');
2210 			    if (commap == NULL)		    // last part
2211 			    {
2212 				if (endp == NULL)
2213 				    endp = p + STRLEN(p);   // find end of part
2214 			    }
2215 			    else if (endp > commap || endp == NULL)
2216 				endp = commap;
2217 			    slashp = vim_strchr(p, '/');
2218 			    if (slashp != NULL && slashp < endp)
2219 			    {
2220 				// "group/langmap_group"
2221 				i = syn_check_group(p, (int)(slashp - p));
2222 				p = slashp + 1;
2223 			    }
2224 			    if (round == 2)
2225 			    {
2226 				shape_table[idx].id = syn_check_group(p,
2227 							     (int)(endp - p));
2228 				shape_table[idx].id_lm = shape_table[idx].id;
2229 				if (slashp != NULL && slashp < endp)
2230 				    shape_table[idx].id = i;
2231 			    }
2232 			    p = endp;
2233 			}
2234 		    } // if (what != SHAPE_MOUSE)
2235 
2236 		    if (*p == '-')
2237 			++p;
2238 		}
2239 	    }
2240 	    modep = p;
2241 	    if (*modep == ',')
2242 		++modep;
2243 	}
2244     }
2245 
2246     // If the 's' flag is not given, use the 'v' cursor for 's'
2247     if (!found_ve)
2248     {
2249 #ifdef FEAT_MOUSESHAPE
2250 	if (what == SHAPE_MOUSE)
2251 	{
2252 	    shape_table[SHAPE_IDX_VE].mshape = shape_table[SHAPE_IDX_V].mshape;
2253 	}
2254 	else
2255 #endif
2256 	{
2257 	    shape_table[SHAPE_IDX_VE].shape = shape_table[SHAPE_IDX_V].shape;
2258 	    shape_table[SHAPE_IDX_VE].percentage =
2259 					 shape_table[SHAPE_IDX_V].percentage;
2260 	    shape_table[SHAPE_IDX_VE].blinkwait =
2261 					  shape_table[SHAPE_IDX_V].blinkwait;
2262 	    shape_table[SHAPE_IDX_VE].blinkon =
2263 					    shape_table[SHAPE_IDX_V].blinkon;
2264 	    shape_table[SHAPE_IDX_VE].blinkoff =
2265 					   shape_table[SHAPE_IDX_V].blinkoff;
2266 	    shape_table[SHAPE_IDX_VE].id = shape_table[SHAPE_IDX_V].id;
2267 	    shape_table[SHAPE_IDX_VE].id_lm = shape_table[SHAPE_IDX_V].id_lm;
2268 	}
2269     }
2270 
2271     return NULL;
2272 }
2273 
2274 # if defined(MCH_CURSOR_SHAPE) || defined(FEAT_GUI) \
2275 	|| defined(FEAT_MOUSESHAPE) || defined(PROTO)
2276 /*
2277  * Return the index into shape_table[] for the current mode.
2278  * When "mouse" is TRUE, consider indexes valid for the mouse pointer.
2279  */
2280     int
get_shape_idx(int mouse)2281 get_shape_idx(int mouse)
2282 {
2283 #ifdef FEAT_MOUSESHAPE
2284     if (mouse && (State == HITRETURN || State == ASKMORE))
2285     {
2286 # ifdef FEAT_GUI
2287 	int x, y;
2288 	gui_mch_getmouse(&x, &y);
2289 	if (Y_2_ROW(y) == Rows - 1)
2290 	    return SHAPE_IDX_MOREL;
2291 # endif
2292 	return SHAPE_IDX_MORE;
2293     }
2294     if (mouse && drag_status_line)
2295 	return SHAPE_IDX_SDRAG;
2296     if (mouse && drag_sep_line)
2297 	return SHAPE_IDX_VDRAG;
2298 #endif
2299     if (!mouse && State == SHOWMATCH)
2300 	return SHAPE_IDX_SM;
2301     if (State & VREPLACE_FLAG)
2302 	return SHAPE_IDX_R;
2303     if (State & REPLACE_FLAG)
2304 	return SHAPE_IDX_R;
2305     if (State & INSERT)
2306 	return SHAPE_IDX_I;
2307     if (State & CMDLINE)
2308     {
2309 	if (cmdline_at_end())
2310 	    return SHAPE_IDX_C;
2311 	if (cmdline_overstrike())
2312 	    return SHAPE_IDX_CR;
2313 	return SHAPE_IDX_CI;
2314     }
2315     if (finish_op)
2316 	return SHAPE_IDX_O;
2317     if (VIsual_active)
2318     {
2319 	if (*p_sel == 'e')
2320 	    return SHAPE_IDX_VE;
2321 	else
2322 	    return SHAPE_IDX_V;
2323     }
2324     return SHAPE_IDX_N;
2325 }
2326 #endif
2327 
2328 # if defined(FEAT_MOUSESHAPE) || defined(PROTO)
2329 static int old_mouse_shape = 0;
2330 
2331 /*
2332  * Set the mouse shape:
2333  * If "shape" is -1, use shape depending on the current mode,
2334  * depending on the current state.
2335  * If "shape" is -2, only update the shape when it's CLINE or STATUS (used
2336  * when the mouse moves off the status or command line).
2337  */
2338     void
update_mouseshape(int shape_idx)2339 update_mouseshape(int shape_idx)
2340 {
2341     int new_mouse_shape;
2342 
2343     // Only works in GUI mode.
2344     if (!gui.in_use || gui.starting)
2345 	return;
2346 
2347     // Postpone the updating when more is to come.  Speeds up executing of
2348     // mappings.
2349     if (shape_idx == -1 && char_avail())
2350     {
2351 	postponed_mouseshape = TRUE;
2352 	return;
2353     }
2354 
2355     // When ignoring the mouse don't change shape on the statusline.
2356     if (*p_mouse == NUL
2357 	    && (shape_idx == SHAPE_IDX_CLINE
2358 		|| shape_idx == SHAPE_IDX_STATUS
2359 		|| shape_idx == SHAPE_IDX_VSEP))
2360 	shape_idx = -2;
2361 
2362     if (shape_idx == -2
2363 	    && old_mouse_shape != shape_table[SHAPE_IDX_CLINE].mshape
2364 	    && old_mouse_shape != shape_table[SHAPE_IDX_STATUS].mshape
2365 	    && old_mouse_shape != shape_table[SHAPE_IDX_VSEP].mshape)
2366 	return;
2367     if (shape_idx < 0)
2368 	new_mouse_shape = shape_table[get_shape_idx(TRUE)].mshape;
2369     else
2370 	new_mouse_shape = shape_table[shape_idx].mshape;
2371     if (new_mouse_shape != old_mouse_shape)
2372     {
2373 	mch_set_mouse_shape(new_mouse_shape);
2374 	old_mouse_shape = new_mouse_shape;
2375     }
2376     postponed_mouseshape = FALSE;
2377 }
2378 # endif
2379 
2380 #endif // CURSOR_SHAPE
2381 
2382 
2383 /*
2384  * Change directory to "new_dir".  If FEAT_SEARCHPATH is defined, search
2385  * 'cdpath' for relative directory names, otherwise just mch_chdir().
2386  */
2387     int
vim_chdir(char_u * new_dir)2388 vim_chdir(char_u *new_dir)
2389 {
2390 #ifndef FEAT_SEARCHPATH
2391     return mch_chdir((char *)new_dir);
2392 #else
2393     char_u	*dir_name;
2394     int		r;
2395 
2396     dir_name = find_directory_in_path(new_dir, (int)STRLEN(new_dir),
2397 						FNAME_MESS, curbuf->b_ffname);
2398     if (dir_name == NULL)
2399 	return -1;
2400     r = mch_chdir((char *)dir_name);
2401     vim_free(dir_name);
2402     return r;
2403 #endif
2404 }
2405 
2406 /*
2407  * Get user name from machine-specific function.
2408  * Returns the user name in "buf[len]".
2409  * Some systems are quite slow in obtaining the user name (Windows NT), thus
2410  * cache the result.
2411  * Returns OK or FAIL.
2412  */
2413     int
get_user_name(char_u * buf,int len)2414 get_user_name(char_u *buf, int len)
2415 {
2416     if (username == NULL)
2417     {
2418 	if (mch_get_user_name(buf, len) == FAIL)
2419 	    return FAIL;
2420 	username = vim_strsave(buf);
2421     }
2422     else
2423 	vim_strncpy(buf, username, len - 1);
2424     return OK;
2425 }
2426 
2427 /*
2428  * Free the memory allocated by get_user_name()
2429  */
2430     void
free_username(void)2431 free_username(void)
2432 {
2433     vim_free(username);
2434 }
2435 
2436 #ifndef HAVE_QSORT
2437 /*
2438  * Our own qsort(), for systems that don't have it.
2439  * It's simple and slow.  From the K&R C book.
2440  */
2441     void
qsort(void * base,size_t elm_count,size_t elm_size,int (* cmp)(const void *,const void *))2442 qsort(
2443     void	*base,
2444     size_t	elm_count,
2445     size_t	elm_size,
2446     int (*cmp)(const void *, const void *))
2447 {
2448     char_u	*buf;
2449     char_u	*p1;
2450     char_u	*p2;
2451     int		i, j;
2452     int		gap;
2453 
2454     buf = alloc(elm_size);
2455     if (buf == NULL)
2456 	return;
2457 
2458     for (gap = elm_count / 2; gap > 0; gap /= 2)
2459 	for (i = gap; i < elm_count; ++i)
2460 	    for (j = i - gap; j >= 0; j -= gap)
2461 	    {
2462 		// Compare the elements.
2463 		p1 = (char_u *)base + j * elm_size;
2464 		p2 = (char_u *)base + (j + gap) * elm_size;
2465 		if ((*cmp)((void *)p1, (void *)p2) <= 0)
2466 		    break;
2467 		// Exchange the elements.
2468 		mch_memmove(buf, p1, elm_size);
2469 		mch_memmove(p1, p2, elm_size);
2470 		mch_memmove(p2, buf, elm_size);
2471 	    }
2472 
2473     vim_free(buf);
2474 }
2475 #endif
2476 
2477 /*
2478  * The putenv() implementation below comes from the "screen" program.
2479  * Included with permission from Juergen Weigert.
2480  * See pty.c for the copyright notice.
2481  */
2482 
2483 /*
2484  *  putenv  --	put value into environment
2485  *
2486  *  Usage:  i = putenv (string)
2487  *    int i;
2488  *    char  *string;
2489  *
2490  *  where string is of the form <name>=<value>.
2491  *  Putenv returns 0 normally, -1 on error (not enough core for malloc).
2492  *
2493  *  Putenv may need to add a new name into the environment, or to
2494  *  associate a value longer than the current value with a particular
2495  *  name.  So, to make life simpler, putenv() copies your entire
2496  *  environment into the heap (i.e. malloc()) from the stack
2497  *  (i.e. where it resides when your process is initiated) the first
2498  *  time you call it.
2499  *
2500  *  (history removed, not very interesting.  See the "screen" sources.)
2501  */
2502 
2503 #if !defined(HAVE_SETENV) && !defined(HAVE_PUTENV)
2504 
2505 #define EXTRASIZE 5		// increment to add to env. size
2506 
2507 static int  envsize = -1;	// current size of environment
2508 extern char **environ;		// the global which is your env.
2509 
2510 static int  findenv(char *name); // look for a name in the env.
2511 static int  newenv(void);	// copy env. from stack to heap
2512 static int  moreenv(void);	// incr. size of env.
2513 
2514     int
putenv(const char * string)2515 putenv(const char *string)
2516 {
2517     int	    i;
2518     char    *p;
2519 
2520     if (envsize < 0)
2521     {				// first time putenv called
2522 	if (newenv() < 0)	// copy env. to heap
2523 	    return -1;
2524     }
2525 
2526     i = findenv((char *)string); // look for name in environment
2527 
2528     if (i < 0)
2529     {				// name must be added
2530 	for (i = 0; environ[i]; i++);
2531 	if (i >= (envsize - 1))
2532 	{			// need new slot
2533 	    if (moreenv() < 0)
2534 		return -1;
2535 	}
2536 	p = alloc(strlen(string) + 1);
2537 	if (p == NULL)		// not enough core
2538 	    return -1;
2539 	environ[i + 1] = 0;	// new end of env.
2540     }
2541     else
2542     {				// name already in env.
2543 	p = vim_realloc(environ[i], strlen(string) + 1);
2544 	if (p == NULL)
2545 	    return -1;
2546     }
2547     sprintf(p, "%s", string);	// copy into env.
2548     environ[i] = p;
2549 
2550     return 0;
2551 }
2552 
2553     static int
findenv(char * name)2554 findenv(char *name)
2555 {
2556     char    *namechar, *envchar;
2557     int	    i, found;
2558 
2559     found = 0;
2560     for (i = 0; environ[i] && !found; i++)
2561     {
2562 	envchar = environ[i];
2563 	namechar = name;
2564 	while (*namechar && *namechar != '=' && (*namechar == *envchar))
2565 	{
2566 	    namechar++;
2567 	    envchar++;
2568 	}
2569 	found = ((*namechar == '\0' || *namechar == '=') && *envchar == '=');
2570     }
2571     return found ? i - 1 : -1;
2572 }
2573 
2574     static int
newenv(void)2575 newenv(void)
2576 {
2577     char    **env, *elem;
2578     int	    i, esize;
2579 
2580     for (i = 0; environ[i]; i++)
2581 	;
2582 
2583     esize = i + EXTRASIZE + 1;
2584     env = ALLOC_MULT(char *, esize);
2585     if (env == NULL)
2586 	return -1;
2587 
2588     for (i = 0; environ[i]; i++)
2589     {
2590 	elem = alloc(strlen(environ[i]) + 1);
2591 	if (elem == NULL)
2592 	    return -1;
2593 	env[i] = elem;
2594 	strcpy(elem, environ[i]);
2595     }
2596 
2597     env[i] = 0;
2598     environ = env;
2599     envsize = esize;
2600     return 0;
2601 }
2602 
2603     static int
moreenv(void)2604 moreenv(void)
2605 {
2606     int	    esize;
2607     char    **env;
2608 
2609     esize = envsize + EXTRASIZE;
2610     env = vim_realloc((char *)environ, esize * sizeof (*env));
2611     if (env == 0)
2612 	return -1;
2613     environ = env;
2614     envsize = esize;
2615     return 0;
2616 }
2617 
2618 # ifdef USE_VIMPTY_GETENV
2619 /*
2620  * Used for mch_getenv() for Mac.
2621  */
2622     char_u *
vimpty_getenv(const char_u * string)2623 vimpty_getenv(const char_u *string)
2624 {
2625     int i;
2626     char_u *p;
2627 
2628     if (envsize < 0)
2629 	return NULL;
2630 
2631     i = findenv((char *)string);
2632 
2633     if (i < 0)
2634 	return NULL;
2635 
2636     p = vim_strchr((char_u *)environ[i], '=');
2637     return (p + 1);
2638 }
2639 # endif
2640 
2641 #endif // !defined(HAVE_SETENV) && !defined(HAVE_PUTENV)
2642 
2643 #if defined(FEAT_EVAL) || defined(FEAT_SPELL) || defined(PROTO)
2644 /*
2645  * Return 0 for not writable, 1 for writable file, 2 for a dir which we have
2646  * rights to write into.
2647  */
2648     int
filewritable(char_u * fname)2649 filewritable(char_u *fname)
2650 {
2651     int		retval = 0;
2652 #if defined(UNIX) || defined(VMS)
2653     int		perm = 0;
2654 #endif
2655 
2656 #if defined(UNIX) || defined(VMS)
2657     perm = mch_getperm(fname);
2658 #endif
2659     if (
2660 # ifdef MSWIN
2661 	    mch_writable(fname) &&
2662 # else
2663 # if defined(UNIX) || defined(VMS)
2664 	    (perm & 0222) &&
2665 #  endif
2666 # endif
2667 	    mch_access((char *)fname, W_OK) == 0
2668        )
2669     {
2670 	++retval;
2671 	if (mch_isdir(fname))
2672 	    ++retval;
2673     }
2674     return retval;
2675 }
2676 #endif
2677 
2678 #if defined(FEAT_SPELL) || defined(FEAT_PERSISTENT_UNDO) || defined(PROTO)
2679 /*
2680  * Read 2 bytes from "fd" and turn them into an int, MSB first.
2681  * Returns -1 when encountering EOF.
2682  */
2683     int
get2c(FILE * fd)2684 get2c(FILE *fd)
2685 {
2686     int		c, n;
2687 
2688     n = getc(fd);
2689     if (n == EOF) return -1;
2690     c = getc(fd);
2691     if (c == EOF) return -1;
2692     return (n << 8) + c;
2693 }
2694 
2695 /*
2696  * Read 3 bytes from "fd" and turn them into an int, MSB first.
2697  * Returns -1 when encountering EOF.
2698  */
2699     int
get3c(FILE * fd)2700 get3c(FILE *fd)
2701 {
2702     int		c, n;
2703 
2704     n = getc(fd);
2705     if (n == EOF) return -1;
2706     c = getc(fd);
2707     if (c == EOF) return -1;
2708     n = (n << 8) + c;
2709     c = getc(fd);
2710     if (c == EOF) return -1;
2711     return (n << 8) + c;
2712 }
2713 
2714 /*
2715  * Read 4 bytes from "fd" and turn them into an int, MSB first.
2716  * Returns -1 when encountering EOF.
2717  */
2718     int
get4c(FILE * fd)2719 get4c(FILE *fd)
2720 {
2721     int		c;
2722     // Use unsigned rather than int otherwise result is undefined
2723     // when left-shift sets the MSB.
2724     unsigned	n;
2725 
2726     c = getc(fd);
2727     if (c == EOF) return -1;
2728     n = (unsigned)c;
2729     c = getc(fd);
2730     if (c == EOF) return -1;
2731     n = (n << 8) + (unsigned)c;
2732     c = getc(fd);
2733     if (c == EOF) return -1;
2734     n = (n << 8) + (unsigned)c;
2735     c = getc(fd);
2736     if (c == EOF) return -1;
2737     n = (n << 8) + (unsigned)c;
2738     return (int)n;
2739 }
2740 
2741 /*
2742  * Read a string of length "cnt" from "fd" into allocated memory.
2743  * Returns NULL when out of memory or unable to read that many bytes.
2744  */
2745     char_u *
read_string(FILE * fd,int cnt)2746 read_string(FILE *fd, int cnt)
2747 {
2748     char_u	*str;
2749     int		i;
2750     int		c;
2751 
2752     // allocate memory
2753     str = alloc(cnt + 1);
2754     if (str != NULL)
2755     {
2756 	// Read the string.  Quit when running into the EOF.
2757 	for (i = 0; i < cnt; ++i)
2758 	{
2759 	    c = getc(fd);
2760 	    if (c == EOF)
2761 	    {
2762 		vim_free(str);
2763 		return NULL;
2764 	    }
2765 	    str[i] = c;
2766 	}
2767 	str[i] = NUL;
2768     }
2769     return str;
2770 }
2771 
2772 /*
2773  * Write a number to file "fd", MSB first, in "len" bytes.
2774  */
2775     int
put_bytes(FILE * fd,long_u nr,int len)2776 put_bytes(FILE *fd, long_u nr, int len)
2777 {
2778     int	    i;
2779 
2780     for (i = len - 1; i >= 0; --i)
2781 	if (putc((int)(nr >> (i * 8)), fd) == EOF)
2782 	    return FAIL;
2783     return OK;
2784 }
2785 
2786 #endif
2787 
2788 #ifndef PROTO  // proto is defined in vim.h
2789 # ifdef ELAPSED_TIMEVAL
2790 /*
2791  * Return time in msec since "start_tv".
2792  */
2793     long
elapsed(struct timeval * start_tv)2794 elapsed(struct timeval *start_tv)
2795 {
2796     struct timeval  now_tv;
2797 
2798     gettimeofday(&now_tv, NULL);
2799     return (now_tv.tv_sec - start_tv->tv_sec) * 1000L
2800 	 + (now_tv.tv_usec - start_tv->tv_usec) / 1000L;
2801 }
2802 # endif
2803 
2804 # ifdef ELAPSED_TICKCOUNT
2805 /*
2806  * Return time in msec since "start_tick".
2807  */
2808     long
elapsed(DWORD start_tick)2809 elapsed(DWORD start_tick)
2810 {
2811     DWORD	now = GetTickCount();
2812 
2813     return (long)now - (long)start_tick;
2814 }
2815 # endif
2816 #endif
2817 
2818 #if defined(FEAT_JOB_CHANNEL) \
2819 	|| (defined(UNIX) && (!defined(USE_SYSTEM) \
2820 	|| (defined(FEAT_GUI) && defined(FEAT_TERMINAL)))) \
2821 	|| defined(PROTO)
2822 /*
2823  * Parse "cmd" and put the white-separated parts in "argv".
2824  * "argv" is an allocated array with "argc" entries and room for 4 more.
2825  * Returns FAIL when out of memory.
2826  */
2827     int
mch_parse_cmd(char_u * cmd,int use_shcf,char *** argv,int * argc)2828 mch_parse_cmd(char_u *cmd, int use_shcf, char ***argv, int *argc)
2829 {
2830     int		i;
2831     char_u	*p, *d;
2832     int		inquote;
2833 
2834     /*
2835      * Do this loop twice:
2836      * 1: find number of arguments
2837      * 2: separate them and build argv[]
2838      */
2839     for (i = 1; i <= 2; ++i)
2840     {
2841 	p = skipwhite(cmd);
2842 	inquote = FALSE;
2843 	*argc = 0;
2844 	while (*p != NUL)
2845 	{
2846 	    if (i == 2)
2847 		(*argv)[*argc] = (char *)p;
2848 	    ++*argc;
2849 	    d = p;
2850 	    while (*p != NUL && (inquote || (*p != ' ' && *p != TAB)))
2851 	    {
2852 		if (p[0] == '"')
2853 		    // quotes surrounding an argument and are dropped
2854 		    inquote = !inquote;
2855 		else
2856 		{
2857 		    if (rem_backslash(p))
2858 		    {
2859 			// First pass: skip over "\ " and "\"".
2860 			// Second pass: Remove the backslash.
2861 			++p;
2862 		    }
2863 		    if (i == 2)
2864 			*d++ = *p;
2865 		}
2866 		++p;
2867 	    }
2868 	    if (*p == NUL)
2869 	    {
2870 		if (i == 2)
2871 		    *d++ = NUL;
2872 		break;
2873 	    }
2874 	    if (i == 2)
2875 		*d++ = NUL;
2876 	    p = skipwhite(p + 1);
2877 	}
2878 	if (*argv == NULL)
2879 	{
2880 	    if (use_shcf)
2881 	    {
2882 		// Account for possible multiple args in p_shcf.
2883 		p = p_shcf;
2884 		for (;;)
2885 		{
2886 		    p = skiptowhite(p);
2887 		    if (*p == NUL)
2888 			break;
2889 		    ++*argc;
2890 		    p = skipwhite(p);
2891 		}
2892 	    }
2893 
2894 	    *argv = ALLOC_MULT(char *, *argc + 4);
2895 	    if (*argv == NULL)	    // out of memory
2896 		return FAIL;
2897 	}
2898     }
2899     return OK;
2900 }
2901 
2902 # if defined(FEAT_JOB_CHANNEL) || defined(PROTO)
2903 /*
2904  * Build "argv[argc]" from the string "cmd".
2905  * "argv[argc]" is set to NULL;
2906  * Return FAIL when out of memory.
2907  */
2908     int
build_argv_from_string(char_u * cmd,char *** argv,int * argc)2909 build_argv_from_string(char_u *cmd, char ***argv, int *argc)
2910 {
2911     char_u	*cmd_copy;
2912     int		i;
2913 
2914     // Make a copy, parsing will modify "cmd".
2915     cmd_copy = vim_strsave(cmd);
2916     if (cmd_copy == NULL
2917 	    || mch_parse_cmd(cmd_copy, FALSE, argv, argc) == FAIL)
2918     {
2919 	vim_free(cmd_copy);
2920 	return FAIL;
2921     }
2922     for (i = 0; i < *argc; i++)
2923 	(*argv)[i] = (char *)vim_strsave((char_u *)(*argv)[i]);
2924     (*argv)[*argc] = NULL;
2925     vim_free(cmd_copy);
2926     return OK;
2927 }
2928 
2929 /*
2930  * Build "argv[argc]" from the list "l".
2931  * "argv[argc]" is set to NULL;
2932  * Return FAIL when out of memory.
2933  */
2934     int
build_argv_from_list(list_T * l,char *** argv,int * argc)2935 build_argv_from_list(list_T *l, char ***argv, int *argc)
2936 {
2937     listitem_T  *li;
2938     char_u	*s;
2939 
2940     // Pass argv[] to mch_call_shell().
2941     *argv = ALLOC_MULT(char *, l->lv_len + 1);
2942     if (*argv == NULL)
2943 	return FAIL;
2944     *argc = 0;
2945     FOR_ALL_LIST_ITEMS(l, li)
2946     {
2947 	s = tv_get_string_chk(&li->li_tv);
2948 	if (s == NULL)
2949 	{
2950 	    int i;
2951 
2952 	    for (i = 0; i < *argc; ++i)
2953 		VIM_CLEAR((*argv)[i]);
2954 	    (*argv)[0] = NULL;
2955 	    return FAIL;
2956 	}
2957 	(*argv)[*argc] = (char *)vim_strsave(s);
2958 	*argc += 1;
2959     }
2960     (*argv)[*argc] = NULL;
2961     return OK;
2962 }
2963 # endif
2964 #endif
2965 
2966 /*
2967  * Change the behavior of vterm.
2968  * 0: As usual.
2969  * 1: Windows 10 version 1809
2970  *      The bug causes unstable handling of ambiguous width character.
2971  * 2: Windows 10 version 1903 & 1909
2972  *      Use the wrong result because each result is different.
2973  * 3: Windows 10 insider preview (current latest logic)
2974  */
2975     int
get_special_pty_type(void)2976 get_special_pty_type(void)
2977 {
2978 #ifdef MSWIN
2979     return get_conpty_type();
2980 #else
2981     return 0;
2982 #endif
2983 }
2984