xref: /vim-8.2.3635/src/misc1.c (revision 1a928c20)
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  * misc1.c: functions that didn't seem to fit elsewhere
12  */
13 
14 #include "vim.h"
15 #include "version.h"
16 
17 #if defined(MSWIN)
18 # include <lm.h>
19 #endif
20 
21 #define URL_SLASH	1		// path_is_url() has found "://"
22 #define URL_BACKSLASH	2		// path_is_url() has found ":\\"
23 
24 // All user names (for ~user completion as done by shell).
25 static garray_T	ga_users;
26 
27 /*
28  * get_leader_len() returns the length in bytes of the prefix of the given
29  * string which introduces a comment.  If this string is not a comment then
30  * 0 is returned.
31  * When "flags" is not NULL, it is set to point to the flags of the recognized
32  * comment leader.
33  * "backward" must be true for the "O" command.
34  * If "include_space" is set, include trailing whitespace while calculating the
35  * length.
36  */
37     int
38 get_leader_len(
39     char_u	*line,
40     char_u	**flags,
41     int		backward,
42     int		include_space)
43 {
44     int		i, j;
45     int		result;
46     int		got_com = FALSE;
47     int		found_one;
48     char_u	part_buf[COM_MAX_LEN];	// buffer for one option part
49     char_u	*string;		// pointer to comment string
50     char_u	*list;
51     int		middle_match_len = 0;
52     char_u	*prev_list;
53     char_u	*saved_flags = NULL;
54 
55     result = i = 0;
56     while (VIM_ISWHITE(line[i]))    // leading white space is ignored
57 	++i;
58 
59     /*
60      * Repeat to match several nested comment strings.
61      */
62     while (line[i] != NUL)
63     {
64 	/*
65 	 * scan through the 'comments' option for a match
66 	 */
67 	found_one = FALSE;
68 	for (list = curbuf->b_p_com; *list; )
69 	{
70 	    // Get one option part into part_buf[].  Advance "list" to next
71 	    // one.  Put "string" at start of string.
72 	    if (!got_com && flags != NULL)
73 		*flags = list;	    // remember where flags started
74 	    prev_list = list;
75 	    (void)copy_option_part(&list, part_buf, COM_MAX_LEN, ",");
76 	    string = vim_strchr(part_buf, ':');
77 	    if (string == NULL)	    // missing ':', ignore this part
78 		continue;
79 	    *string++ = NUL;	    // isolate flags from string
80 
81 	    // If we found a middle match previously, use that match when this
82 	    // is not a middle or end.
83 	    if (middle_match_len != 0
84 		    && vim_strchr(part_buf, COM_MIDDLE) == NULL
85 		    && vim_strchr(part_buf, COM_END) == NULL)
86 		break;
87 
88 	    // When we already found a nested comment, only accept further
89 	    // nested comments.
90 	    if (got_com && vim_strchr(part_buf, COM_NEST) == NULL)
91 		continue;
92 
93 	    // When 'O' flag present and using "O" command skip this one.
94 	    if (backward && vim_strchr(part_buf, COM_NOBACK) != NULL)
95 		continue;
96 
97 	    // Line contents and string must match.
98 	    // When string starts with white space, must have some white space
99 	    // (but the amount does not need to match, there might be a mix of
100 	    // TABs and spaces).
101 	    if (VIM_ISWHITE(string[0]))
102 	    {
103 		if (i == 0 || !VIM_ISWHITE(line[i - 1]))
104 		    continue;  // missing white space
105 		while (VIM_ISWHITE(string[0]))
106 		    ++string;
107 	    }
108 	    for (j = 0; string[j] != NUL && string[j] == line[i + j]; ++j)
109 		;
110 	    if (string[j] != NUL)
111 		continue;  // string doesn't match
112 
113 	    // When 'b' flag used, there must be white space or an
114 	    // end-of-line after the string in the line.
115 	    if (vim_strchr(part_buf, COM_BLANK) != NULL
116 			   && !VIM_ISWHITE(line[i + j]) && line[i + j] != NUL)
117 		continue;
118 
119 	    // We have found a match, stop searching unless this is a middle
120 	    // comment. The middle comment can be a substring of the end
121 	    // comment in which case it's better to return the length of the
122 	    // end comment and its flags.  Thus we keep searching with middle
123 	    // and end matches and use an end match if it matches better.
124 	    if (vim_strchr(part_buf, COM_MIDDLE) != NULL)
125 	    {
126 		if (middle_match_len == 0)
127 		{
128 		    middle_match_len = j;
129 		    saved_flags = prev_list;
130 		}
131 		continue;
132 	    }
133 	    if (middle_match_len != 0 && j > middle_match_len)
134 		// Use this match instead of the middle match, since it's a
135 		// longer thus better match.
136 		middle_match_len = 0;
137 
138 	    if (middle_match_len == 0)
139 		i += j;
140 	    found_one = TRUE;
141 	    break;
142 	}
143 
144 	if (middle_match_len != 0)
145 	{
146 	    // Use the previously found middle match after failing to find a
147 	    // match with an end.
148 	    if (!got_com && flags != NULL)
149 		*flags = saved_flags;
150 	    i += middle_match_len;
151 	    found_one = TRUE;
152 	}
153 
154 	// No match found, stop scanning.
155 	if (!found_one)
156 	    break;
157 
158 	result = i;
159 
160 	// Include any trailing white space.
161 	while (VIM_ISWHITE(line[i]))
162 	    ++i;
163 
164 	if (include_space)
165 	    result = i;
166 
167 	// If this comment doesn't nest, stop here.
168 	got_com = TRUE;
169 	if (vim_strchr(part_buf, COM_NEST) == NULL)
170 	    break;
171     }
172     return result;
173 }
174 
175 /*
176  * Return the offset at which the last comment in line starts. If there is no
177  * comment in the whole line, -1 is returned.
178  *
179  * When "flags" is not null, it is set to point to the flags describing the
180  * recognized comment leader.
181  */
182     int
183 get_last_leader_offset(char_u *line, char_u **flags)
184 {
185     int		result = -1;
186     int		i, j;
187     int		lower_check_bound = 0;
188     char_u	*string;
189     char_u	*com_leader;
190     char_u	*com_flags;
191     char_u	*list;
192     int		found_one;
193     char_u	part_buf[COM_MAX_LEN];	// buffer for one option part
194 
195     /*
196      * Repeat to match several nested comment strings.
197      */
198     i = (int)STRLEN(line);
199     while (--i >= lower_check_bound)
200     {
201 	/*
202 	 * scan through the 'comments' option for a match
203 	 */
204 	found_one = FALSE;
205 	for (list = curbuf->b_p_com; *list; )
206 	{
207 	    char_u *flags_save = list;
208 
209 	    /*
210 	     * Get one option part into part_buf[].  Advance list to next one.
211 	     * put string at start of string.
212 	     */
213 	    (void)copy_option_part(&list, part_buf, COM_MAX_LEN, ",");
214 	    string = vim_strchr(part_buf, ':');
215 	    if (string == NULL)	// If everything is fine, this cannot actually
216 				// happen.
217 		continue;
218 	    *string++ = NUL;	// Isolate flags from string.
219 	    com_leader = string;
220 
221 	    /*
222 	     * Line contents and string must match.
223 	     * When string starts with white space, must have some white space
224 	     * (but the amount does not need to match, there might be a mix of
225 	     * TABs and spaces).
226 	     */
227 	    if (VIM_ISWHITE(string[0]))
228 	    {
229 		if (i == 0 || !VIM_ISWHITE(line[i - 1]))
230 		    continue;
231 		while (VIM_ISWHITE(*string))
232 		    ++string;
233 	    }
234 	    for (j = 0; string[j] != NUL && string[j] == line[i + j]; ++j)
235 		/* do nothing */;
236 	    if (string[j] != NUL)
237 		continue;
238 
239 	    /*
240 	     * When 'b' flag used, there must be white space or an
241 	     * end-of-line after the string in the line.
242 	     */
243 	    if (vim_strchr(part_buf, COM_BLANK) != NULL
244 		    && !VIM_ISWHITE(line[i + j]) && line[i + j] != NUL)
245 		continue;
246 
247 	    if (vim_strchr(part_buf, COM_MIDDLE) != NULL)
248 	    {
249 		// For a middlepart comment, only consider it to match if
250 		// everything before the current position in the line is
251 		// whitespace.  Otherwise we would think we are inside a
252 		// comment if the middle part appears somewhere in the middle
253 		// of the line.  E.g. for C the "*" appears often.
254 		for (j = 0; VIM_ISWHITE(line[j]) && j <= i; j++)
255 		    ;
256 		if (j < i)
257 		    continue;
258 	    }
259 
260 	    /*
261 	     * We have found a match, stop searching.
262 	     */
263 	    found_one = TRUE;
264 
265 	    if (flags)
266 		*flags = flags_save;
267 	    com_flags = flags_save;
268 
269 	    break;
270 	}
271 
272 	if (found_one)
273 	{
274 	    char_u  part_buf2[COM_MAX_LEN];	// buffer for one option part
275 	    int     len1, len2, off;
276 
277 	    result = i;
278 	    /*
279 	     * If this comment nests, continue searching.
280 	     */
281 	    if (vim_strchr(part_buf, COM_NEST) != NULL)
282 		continue;
283 
284 	    lower_check_bound = i;
285 
286 	    // Let's verify whether the comment leader found is a substring
287 	    // of other comment leaders. If it is, let's adjust the
288 	    // lower_check_bound so that we make sure that we have determined
289 	    // the comment leader correctly.
290 
291 	    while (VIM_ISWHITE(*com_leader))
292 		++com_leader;
293 	    len1 = (int)STRLEN(com_leader);
294 
295 	    for (list = curbuf->b_p_com; *list; )
296 	    {
297 		char_u *flags_save = list;
298 
299 		(void)copy_option_part(&list, part_buf2, COM_MAX_LEN, ",");
300 		if (flags_save == com_flags)
301 		    continue;
302 		string = vim_strchr(part_buf2, ':');
303 		++string;
304 		while (VIM_ISWHITE(*string))
305 		    ++string;
306 		len2 = (int)STRLEN(string);
307 		if (len2 == 0)
308 		    continue;
309 
310 		// Now we have to verify whether string ends with a substring
311 		// beginning the com_leader.
312 		for (off = (len2 > i ? i : len2); off > 0 && off + len1 > len2;)
313 		{
314 		    --off;
315 		    if (!STRNCMP(string + off, com_leader, len2 - off))
316 		    {
317 			if (i - off < lower_check_bound)
318 			    lower_check_bound = i - off;
319 		    }
320 		}
321 	    }
322 	}
323     }
324     return result;
325 }
326 
327 /*
328  * Return the number of window lines occupied by buffer line "lnum".
329  */
330     int
331 plines(linenr_T lnum)
332 {
333     return plines_win(curwin, lnum, TRUE);
334 }
335 
336     int
337 plines_win(
338     win_T	*wp,
339     linenr_T	lnum,
340     int		winheight)	// when TRUE limit to window height
341 {
342 #if defined(FEAT_DIFF) || defined(PROTO)
343     // Check for filler lines above this buffer line.  When folded the result
344     // is one line anyway.
345     return plines_win_nofill(wp, lnum, winheight) + diff_check_fill(wp, lnum);
346 }
347 
348     int
349 plines_nofill(linenr_T lnum)
350 {
351     return plines_win_nofill(curwin, lnum, TRUE);
352 }
353 
354     int
355 plines_win_nofill(
356     win_T	*wp,
357     linenr_T	lnum,
358     int		winheight)	// when TRUE limit to window height
359 {
360 #endif
361     int		lines;
362 
363     if (!wp->w_p_wrap)
364 	return 1;
365 
366     if (wp->w_width == 0)
367 	return 1;
368 
369 #ifdef FEAT_FOLDING
370     // A folded lines is handled just like an empty line.
371     // NOTE: Caller must handle lines that are MAYBE folded.
372     if (lineFolded(wp, lnum) == TRUE)
373 	return 1;
374 #endif
375 
376     lines = plines_win_nofold(wp, lnum);
377     if (winheight > 0 && lines > wp->w_height)
378 	return (int)wp->w_height;
379     return lines;
380 }
381 
382 /*
383  * Return number of window lines physical line "lnum" will occupy in window
384  * "wp".  Does not care about folding, 'wrap' or 'diff'.
385  */
386     int
387 plines_win_nofold(win_T *wp, linenr_T lnum)
388 {
389     char_u	*s;
390     long	col;
391     int		width;
392 
393     s = ml_get_buf(wp->w_buffer, lnum, FALSE);
394     if (*s == NUL)		// empty line
395 	return 1;
396     col = win_linetabsize(wp, s, (colnr_T)MAXCOL);
397 
398     /*
399      * If list mode is on, then the '$' at the end of the line may take up one
400      * extra column.
401      */
402     if (wp->w_p_list && lcs_eol != NUL)
403 	col += 1;
404 
405     /*
406      * Add column offset for 'number', 'relativenumber' and 'foldcolumn'.
407      */
408     width = wp->w_width - win_col_off(wp);
409     if (width <= 0)
410 	return 32000;
411     if (col <= width)
412 	return 1;
413     col -= width;
414     width += win_col_off2(wp);
415     return (col + (width - 1)) / width + 1;
416 }
417 
418 /*
419  * Like plines_win(), but only reports the number of physical screen lines
420  * used from the start of the line to the given column number.
421  */
422     int
423 plines_win_col(win_T *wp, linenr_T lnum, long column)
424 {
425     long	col;
426     char_u	*s;
427     int		lines = 0;
428     int		width;
429     char_u	*line;
430 
431 #ifdef FEAT_DIFF
432     // Check for filler lines above this buffer line.  When folded the result
433     // is one line anyway.
434     lines = diff_check_fill(wp, lnum);
435 #endif
436 
437     if (!wp->w_p_wrap)
438 	return lines + 1;
439 
440     if (wp->w_width == 0)
441 	return lines + 1;
442 
443     line = s = ml_get_buf(wp->w_buffer, lnum, FALSE);
444 
445     col = 0;
446     while (*s != NUL && --column >= 0)
447     {
448 	col += win_lbr_chartabsize(wp, line, s, (colnr_T)col, NULL);
449 	MB_PTR_ADV(s);
450     }
451 
452     /*
453      * If *s is a TAB, and the TAB is not displayed as ^I, and we're not in
454      * INSERT mode, then col must be adjusted so that it represents the last
455      * screen position of the TAB.  This only fixes an error when the TAB wraps
456      * from one screen line to the next (when 'columns' is not a multiple of
457      * 'ts') -- webb.
458      */
459     if (*s == TAB && (State & NORMAL) && (!wp->w_p_list || lcs_tab1))
460 	col += win_lbr_chartabsize(wp, line, s, (colnr_T)col, NULL) - 1;
461 
462     /*
463      * Add column offset for 'number', 'relativenumber', 'foldcolumn', etc.
464      */
465     width = wp->w_width - win_col_off(wp);
466     if (width <= 0)
467 	return 9999;
468 
469     lines += 1;
470     if (col > width)
471 	lines += (col - width) / (width + win_col_off2(wp)) + 1;
472     return lines;
473 }
474 
475     int
476 plines_m_win(win_T *wp, linenr_T first, linenr_T last)
477 {
478     int		count = 0;
479 
480     while (first <= last)
481     {
482 #ifdef FEAT_FOLDING
483 	int	x;
484 
485 	// Check if there are any really folded lines, but also included lines
486 	// that are maybe folded.
487 	x = foldedCount(wp, first, NULL);
488 	if (x > 0)
489 	{
490 	    ++count;	    // count 1 for "+-- folded" line
491 	    first += x;
492 	}
493 	else
494 #endif
495 	{
496 #ifdef FEAT_DIFF
497 	    if (first == wp->w_topline)
498 		count += plines_win_nofill(wp, first, TRUE) + wp->w_topfill;
499 	    else
500 #endif
501 		count += plines_win(wp, first, TRUE);
502 	    ++first;
503 	}
504     }
505     return (count);
506 }
507 
508     int
509 gchar_pos(pos_T *pos)
510 {
511     char_u	*ptr;
512 
513     // When searching columns is sometimes put at the end of a line.
514     if (pos->col == MAXCOL)
515 	return NUL;
516     ptr = ml_get_pos(pos);
517     if (has_mbyte)
518 	return (*mb_ptr2char)(ptr);
519     return (int)*ptr;
520 }
521 
522     int
523 gchar_cursor(void)
524 {
525     if (has_mbyte)
526 	return (*mb_ptr2char)(ml_get_cursor());
527     return (int)*ml_get_cursor();
528 }
529 
530 /*
531  * Write a character at the current cursor position.
532  * It is directly written into the block.
533  */
534     void
535 pchar_cursor(int c)
536 {
537     *(ml_get_buf(curbuf, curwin->w_cursor.lnum, TRUE)
538 						  + curwin->w_cursor.col) = c;
539 }
540 
541 /*
542  * Skip to next part of an option argument: Skip space and comma.
543  */
544     char_u *
545 skip_to_option_part(char_u *p)
546 {
547     if (*p == ',')
548 	++p;
549     while (*p == ' ')
550 	++p;
551     return p;
552 }
553 
554 /*
555  * check_status: called when the status bars for the buffer 'buf'
556  *		 need to be updated
557  */
558     void
559 check_status(buf_T *buf)
560 {
561     win_T	*wp;
562 
563     FOR_ALL_WINDOWS(wp)
564 	if (wp->w_buffer == buf && wp->w_status_height)
565 	{
566 	    wp->w_redr_status = TRUE;
567 	    if (must_redraw < VALID)
568 		must_redraw = VALID;
569 	}
570 }
571 
572 /*
573  * Ask for a reply from the user, a 'y' or a 'n'.
574  * No other characters are accepted, the message is repeated until a valid
575  * reply is entered or CTRL-C is hit.
576  * If direct is TRUE, don't use vgetc() but ui_inchar(), don't get characters
577  * from any buffers but directly from the user.
578  *
579  * return the 'y' or 'n'
580  */
581     int
582 ask_yesno(char_u *str, int direct)
583 {
584     int	    r = ' ';
585     int	    save_State = State;
586 
587     if (exiting)		// put terminal in raw mode for this question
588 	settmode(TMODE_RAW);
589     ++no_wait_return;
590 #ifdef USE_ON_FLY_SCROLL
591     dont_scroll = TRUE;		// disallow scrolling here
592 #endif
593     State = CONFIRM;		// mouse behaves like with :confirm
594     setmouse();			// disables mouse for xterm
595     ++no_mapping;
596     ++allow_keys;		// no mapping here, but recognize keys
597 
598     while (r != 'y' && r != 'n')
599     {
600 	// same highlighting as for wait_return
601 	smsg_attr(HL_ATTR(HLF_R), "%s (y/n)?", str);
602 	if (direct)
603 	    r = get_keystroke();
604 	else
605 	    r = plain_vgetc();
606 	if (r == Ctrl_C || r == ESC)
607 	    r = 'n';
608 	msg_putchar(r);	    // show what you typed
609 	out_flush();
610     }
611     --no_wait_return;
612     State = save_State;
613     setmouse();
614     --no_mapping;
615     --allow_keys;
616 
617     return r;
618 }
619 
620 #if defined(FEAT_EVAL) || defined(PROTO)
621 
622 /*
623  * "mode()" function
624  */
625     void
626 f_mode(typval_T *argvars, typval_T *rettv)
627 {
628     char_u	buf[4];
629 
630     vim_memset(buf, 0, sizeof(buf));
631 
632     if (time_for_testing == 93784)
633     {
634 	// Testing the two-character code.
635 	buf[0] = 'x';
636 	buf[1] = '!';
637     }
638 #ifdef FEAT_TERMINAL
639     else if (term_use_loop())
640 	buf[0] = 't';
641 #endif
642     else if (VIsual_active)
643     {
644 	if (VIsual_select)
645 	    buf[0] = VIsual_mode + 's' - 'v';
646 	else
647 	    buf[0] = VIsual_mode;
648     }
649     else if (State == HITRETURN || State == ASKMORE || State == SETWSIZE
650 		|| State == CONFIRM)
651     {
652 	buf[0] = 'r';
653 	if (State == ASKMORE)
654 	    buf[1] = 'm';
655 	else if (State == CONFIRM)
656 	    buf[1] = '?';
657     }
658     else if (State == EXTERNCMD)
659 	buf[0] = '!';
660     else if (State & INSERT)
661     {
662 	if (State & VREPLACE_FLAG)
663 	{
664 	    buf[0] = 'R';
665 	    buf[1] = 'v';
666 	}
667 	else
668 	{
669 	    if (State & REPLACE_FLAG)
670 		buf[0] = 'R';
671 	    else
672 		buf[0] = 'i';
673 	    if (ins_compl_active())
674 		buf[1] = 'c';
675 	    else if (ctrl_x_mode_not_defined_yet())
676 		buf[1] = 'x';
677 	}
678     }
679     else if ((State & CMDLINE) || exmode_active)
680     {
681 	buf[0] = 'c';
682 	if (exmode_active == EXMODE_VIM)
683 	    buf[1] = 'v';
684 	else if (exmode_active == EXMODE_NORMAL)
685 	    buf[1] = 'e';
686     }
687     else
688     {
689 	buf[0] = 'n';
690 	if (finish_op)
691 	{
692 	    buf[1] = 'o';
693 	    // to be able to detect force-linewise/blockwise/characterwise operations
694 	    buf[2] = motion_force;
695 	}
696 	else if (restart_edit == 'I' || restart_edit == 'R'
697 							|| restart_edit == 'V')
698 	{
699 	    buf[1] = 'i';
700 	    buf[2] = restart_edit;
701 	}
702     }
703 
704     // Clear out the minor mode when the argument is not a non-zero number or
705     // non-empty string.
706     if (!non_zero_arg(&argvars[0]))
707 	buf[1] = NUL;
708 
709     rettv->vval.v_string = vim_strsave(buf);
710     rettv->v_type = VAR_STRING;
711 }
712 
713     static void
714 may_add_state_char(garray_T *gap, char_u *include, int c)
715 {
716     if (include == NULL || vim_strchr(include, c) != NULL)
717 	ga_append(gap, c);
718 }
719 
720 /*
721  * "state()" function
722  */
723     void
724 f_state(typval_T *argvars, typval_T *rettv)
725 {
726     garray_T	ga;
727     char_u	*include = NULL;
728     int		i;
729 
730     ga_init2(&ga, 1, 20);
731     if (argvars[0].v_type != VAR_UNKNOWN)
732 	include = tv_get_string(&argvars[0]);
733 
734     if (!(stuff_empty() && typebuf.tb_len == 0 && scriptin[curscript] == NULL))
735 	may_add_state_char(&ga, include, 'm');
736     if (op_pending())
737 	may_add_state_char(&ga, include, 'o');
738     if (autocmd_busy)
739 	may_add_state_char(&ga, include, 'x');
740     if (ins_compl_active())
741 	may_add_state_char(&ga, include, 'a');
742 
743 # ifdef FEAT_JOB_CHANNEL
744     if (channel_in_blocking_wait())
745 	may_add_state_char(&ga, include, 'w');
746 # endif
747     if (!get_was_safe_state())
748 	may_add_state_char(&ga, include, 'S');
749     for (i = 0; i < get_callback_depth() && i < 3; ++i)
750 	may_add_state_char(&ga, include, 'c');
751     if (msg_scrolled > 0)
752 	may_add_state_char(&ga, include, 's');
753 
754     rettv->v_type = VAR_STRING;
755     rettv->vval.v_string = ga.ga_data;
756 }
757 
758 #endif // FEAT_EVAL
759 
760 /*
761  * Get a key stroke directly from the user.
762  * Ignores mouse clicks and scrollbar events, except a click for the left
763  * button (used at the more prompt).
764  * Doesn't use vgetc(), because it syncs undo and eats mapped characters.
765  * Disadvantage: typeahead is ignored.
766  * Translates the interrupt character for unix to ESC.
767  */
768     int
769 get_keystroke(void)
770 {
771     char_u	*buf = NULL;
772     int		buflen = 150;
773     int		maxlen;
774     int		len = 0;
775     int		n;
776     int		save_mapped_ctrl_c = mapped_ctrl_c;
777     int		waited = 0;
778 
779     mapped_ctrl_c = FALSE;	// mappings are not used here
780     for (;;)
781     {
782 	cursor_on();
783 	out_flush();
784 
785 	// Leave some room for check_termcode() to insert a key code into (max
786 	// 5 chars plus NUL).  And fix_input_buffer() can triple the number of
787 	// bytes.
788 	maxlen = (buflen - 6 - len) / 3;
789 	if (buf == NULL)
790 	    buf = alloc(buflen);
791 	else if (maxlen < 10)
792 	{
793 	    char_u  *t_buf = buf;
794 
795 	    // Need some more space. This might happen when receiving a long
796 	    // escape sequence.
797 	    buflen += 100;
798 	    buf = vim_realloc(buf, buflen);
799 	    if (buf == NULL)
800 		vim_free(t_buf);
801 	    maxlen = (buflen - 6 - len) / 3;
802 	}
803 	if (buf == NULL)
804 	{
805 	    do_outofmem_msg((long_u)buflen);
806 	    return ESC;  // panic!
807 	}
808 
809 	// First time: blocking wait.  Second time: wait up to 100ms for a
810 	// terminal code to complete.
811 	n = ui_inchar(buf + len, maxlen, len == 0 ? -1L : 100L, 0);
812 	if (n > 0)
813 	{
814 	    // Replace zero and CSI by a special key code.
815 	    n = fix_input_buffer(buf + len, n);
816 	    len += n;
817 	    waited = 0;
818 	}
819 	else if (len > 0)
820 	    ++waited;	    // keep track of the waiting time
821 
822 	// Incomplete termcode and not timed out yet: get more characters
823 	if ((n = check_termcode(1, buf, buflen, &len)) < 0
824 	       && (!p_ttimeout || waited * 100L < (p_ttm < 0 ? p_tm : p_ttm)))
825 	    continue;
826 
827 	if (n == KEYLEN_REMOVED)  // key code removed
828 	{
829 	    if (must_redraw != 0 && !need_wait_return && (State & CMDLINE) == 0)
830 	    {
831 		// Redrawing was postponed, do it now.
832 		update_screen(0);
833 		setcursor(); // put cursor back where it belongs
834 	    }
835 	    continue;
836 	}
837 	if (n > 0)		// found a termcode: adjust length
838 	    len = n;
839 	if (len == 0)		// nothing typed yet
840 	    continue;
841 
842 	// Handle modifier and/or special key code.
843 	n = buf[0];
844 	if (n == K_SPECIAL)
845 	{
846 	    n = TO_SPECIAL(buf[1], buf[2]);
847 	    if (buf[1] == KS_MODIFIER
848 		    || n == K_IGNORE
849 		    || (is_mouse_key(n) && n != K_LEFTMOUSE)
850 #ifdef FEAT_GUI
851 		    || n == K_VER_SCROLLBAR
852 		    || n == K_HOR_SCROLLBAR
853 #endif
854 	       )
855 	    {
856 		if (buf[1] == KS_MODIFIER)
857 		    mod_mask = buf[2];
858 		len -= 3;
859 		if (len > 0)
860 		    mch_memmove(buf, buf + 3, (size_t)len);
861 		continue;
862 	    }
863 	    break;
864 	}
865 	if (has_mbyte)
866 	{
867 	    if (MB_BYTE2LEN(n) > len)
868 		continue;	// more bytes to get
869 	    buf[len >= buflen ? buflen - 1 : len] = NUL;
870 	    n = (*mb_ptr2char)(buf);
871 	}
872 #ifdef UNIX
873 	if (n == intr_char)
874 	    n = ESC;
875 #endif
876 	break;
877     }
878     vim_free(buf);
879 
880     mapped_ctrl_c = save_mapped_ctrl_c;
881     return n;
882 }
883 
884 /*
885  * Get a number from the user.
886  * When "mouse_used" is not NULL allow using the mouse.
887  */
888     int
889 get_number(
890     int	    colon,			// allow colon to abort
891     int	    *mouse_used)
892 {
893     int	n = 0;
894     int	c;
895     int typed = 0;
896 
897     if (mouse_used != NULL)
898 	*mouse_used = FALSE;
899 
900     // When not printing messages, the user won't know what to type, return a
901     // zero (as if CR was hit).
902     if (msg_silent != 0)
903 	return 0;
904 
905 #ifdef USE_ON_FLY_SCROLL
906     dont_scroll = TRUE;		// disallow scrolling here
907 #endif
908     ++no_mapping;
909     ++allow_keys;		// no mapping here, but recognize keys
910     for (;;)
911     {
912 	windgoto(msg_row, msg_col);
913 	c = safe_vgetc();
914 	if (VIM_ISDIGIT(c))
915 	{
916 	    n = n * 10 + c - '0';
917 	    msg_putchar(c);
918 	    ++typed;
919 	}
920 	else if (c == K_DEL || c == K_KDEL || c == K_BS || c == Ctrl_H)
921 	{
922 	    if (typed > 0)
923 	    {
924 		msg_puts("\b \b");
925 		--typed;
926 	    }
927 	    n /= 10;
928 	}
929 	else if (mouse_used != NULL && c == K_LEFTMOUSE)
930 	{
931 	    *mouse_used = TRUE;
932 	    n = mouse_row + 1;
933 	    break;
934 	}
935 	else if (n == 0 && c == ':' && colon)
936 	{
937 	    stuffcharReadbuff(':');
938 	    if (!exmode_active)
939 		cmdline_row = msg_row;
940 	    skip_redraw = TRUE;	    // skip redraw once
941 	    do_redraw = FALSE;
942 	    break;
943 	}
944 	else if (c == CAR || c == NL || c == Ctrl_C || c == ESC)
945 	    break;
946     }
947     --no_mapping;
948     --allow_keys;
949     return n;
950 }
951 
952 /*
953  * Ask the user to enter a number.
954  * When "mouse_used" is not NULL allow using the mouse and in that case return
955  * the line number.
956  */
957     int
958 prompt_for_number(int *mouse_used)
959 {
960     int		i;
961     int		save_cmdline_row;
962     int		save_State;
963 
964     // When using ":silent" assume that <CR> was entered.
965     if (mouse_used != NULL)
966 	msg_puts(_("Type number and <Enter> or click with mouse (empty cancels): "));
967     else
968 	msg_puts(_("Type number and <Enter> (empty cancels): "));
969 
970     // Set the state such that text can be selected/copied/pasted and we still
971     // get mouse events. redraw_after_callback() will not redraw if cmdline_row
972     // is zero.
973     save_cmdline_row = cmdline_row;
974     cmdline_row = 0;
975     save_State = State;
976     State = CMDLINE;
977     // May show different mouse shape.
978     setmouse();
979 
980     i = get_number(TRUE, mouse_used);
981     if (KeyTyped)
982     {
983 	// don't call wait_return() now
984 	if (msg_row > 0)
985 	    cmdline_row = msg_row - 1;
986 	need_wait_return = FALSE;
987 	msg_didany = FALSE;
988 	msg_didout = FALSE;
989     }
990     else
991 	cmdline_row = save_cmdline_row;
992     State = save_State;
993     // May need to restore mouse shape.
994     setmouse();
995 
996     return i;
997 }
998 
999     void
1000 msgmore(long n)
1001 {
1002     long pn;
1003 
1004     if (global_busy	    // no messages now, wait until global is finished
1005 	    || !messaging())  // 'lazyredraw' set, don't do messages now
1006 	return;
1007 
1008     // We don't want to overwrite another important message, but do overwrite
1009     // a previous "more lines" or "fewer lines" message, so that "5dd" and
1010     // then "put" reports the last action.
1011     if (keep_msg != NULL && !keep_msg_more)
1012 	return;
1013 
1014     if (n > 0)
1015 	pn = n;
1016     else
1017 	pn = -n;
1018 
1019     if (pn > p_report)
1020     {
1021 	if (n > 0)
1022 	    vim_snprintf(msg_buf, MSG_BUF_LEN,
1023 		    NGETTEXT("%ld more line", "%ld more lines", pn), pn);
1024 	else
1025 	    vim_snprintf(msg_buf, MSG_BUF_LEN,
1026 		    NGETTEXT("%ld line less", "%ld fewer lines", pn), pn);
1027 	if (got_int)
1028 	    vim_strcat((char_u *)msg_buf, (char_u *)_(" (Interrupted)"),
1029 								  MSG_BUF_LEN);
1030 	if (msg(msg_buf))
1031 	{
1032 	    set_keep_msg((char_u *)msg_buf, 0);
1033 	    keep_msg_more = TRUE;
1034 	}
1035     }
1036 }
1037 
1038 /*
1039  * flush map and typeahead buffers and give a warning for an error
1040  */
1041     void
1042 beep_flush(void)
1043 {
1044     if (emsg_silent == 0)
1045     {
1046 	flush_buffers(FLUSH_MINIMAL);
1047 	vim_beep(BO_ERROR);
1048     }
1049 }
1050 
1051 /*
1052  * Give a warning for an error.
1053  */
1054     void
1055 vim_beep(
1056     unsigned val) // one of the BO_ values, e.g., BO_OPER
1057 {
1058 #ifdef FEAT_EVAL
1059     called_vim_beep = TRUE;
1060 #endif
1061 
1062     if (emsg_silent == 0)
1063     {
1064 	if (!((bo_flags & val) || (bo_flags & BO_ALL)))
1065 	{
1066 #ifdef ELAPSED_FUNC
1067 	    static int		did_init = FALSE;
1068 	    static elapsed_T	start_tv;
1069 
1070 	    // Only beep once per half a second, otherwise a sequence of beeps
1071 	    // would freeze Vim.
1072 	    if (!did_init || ELAPSED_FUNC(start_tv) > 500)
1073 	    {
1074 		did_init = TRUE;
1075 		ELAPSED_INIT(start_tv);
1076 #endif
1077 		if (p_vb
1078 #ifdef FEAT_GUI
1079 			// While the GUI is starting up the termcap is set for
1080 			// the GUI but the output still goes to a terminal.
1081 			&& !(gui.in_use && gui.starting)
1082 #endif
1083 			)
1084 		{
1085 		    out_str_cf(T_VB);
1086 #ifdef FEAT_VTP
1087 		    // No restore color information, refresh the screen.
1088 		    if (has_vtp_working() != 0
1089 # ifdef FEAT_TERMGUICOLORS
1090 			    && (p_tgc || (!p_tgc && t_colors >= 256))
1091 # endif
1092 			)
1093 		    {
1094 			redraw_later(CLEAR);
1095 			update_screen(0);
1096 			redrawcmd();
1097 		    }
1098 #endif
1099 		}
1100 		else
1101 		    out_char(BELL);
1102 #ifdef ELAPSED_FUNC
1103 	    }
1104 #endif
1105 	}
1106 
1107 	// When 'debug' contains "beep" produce a message.  If we are sourcing
1108 	// a script or executing a function give the user a hint where the beep
1109 	// comes from.
1110 	if (vim_strchr(p_debug, 'e') != NULL)
1111 	{
1112 	    msg_source(HL_ATTR(HLF_W));
1113 	    msg_attr(_("Beep!"), HL_ATTR(HLF_W));
1114 	}
1115     }
1116 }
1117 
1118 /*
1119  * To get the "real" home directory:
1120  * - get value of $HOME
1121  * For Unix:
1122  *  - go to that directory
1123  *  - do mch_dirname() to get the real name of that directory.
1124  *  This also works with mounts and links.
1125  *  Don't do this for MS-DOS, it will change the "current dir" for a drive.
1126  * For Windows:
1127  *  This code is duplicated in init_homedir() in dosinst.c.  Keep in sync!
1128  */
1129     void
1130 init_homedir(void)
1131 {
1132     char_u  *var;
1133 
1134     // In case we are called a second time (when 'encoding' changes).
1135     VIM_CLEAR(homedir);
1136 
1137 #ifdef VMS
1138     var = mch_getenv((char_u *)"SYS$LOGIN");
1139 #else
1140     var = mch_getenv((char_u *)"HOME");
1141 #endif
1142 
1143 #ifdef MSWIN
1144     /*
1145      * Typically, $HOME is not defined on Windows, unless the user has
1146      * specifically defined it for Vim's sake.  However, on Windows NT
1147      * platforms, $HOMEDRIVE and $HOMEPATH are automatically defined for
1148      * each user.  Try constructing $HOME from these.
1149      */
1150     if (var == NULL || *var == NUL)
1151     {
1152 	char_u *homedrive, *homepath;
1153 
1154 	homedrive = mch_getenv((char_u *)"HOMEDRIVE");
1155 	homepath = mch_getenv((char_u *)"HOMEPATH");
1156 	if (homepath == NULL || *homepath == NUL)
1157 	    homepath = (char_u *)"\\";
1158 	if (homedrive != NULL
1159 			   && STRLEN(homedrive) + STRLEN(homepath) < MAXPATHL)
1160 	{
1161 	    sprintf((char *)NameBuff, "%s%s", homedrive, homepath);
1162 	    if (NameBuff[0] != NUL)
1163 		var = NameBuff;
1164 	}
1165     }
1166 
1167     if (var == NULL)
1168 	var = mch_getenv((char_u *)"USERPROFILE");
1169 
1170     /*
1171      * Weird but true: $HOME may contain an indirect reference to another
1172      * variable, esp. "%USERPROFILE%".  Happens when $USERPROFILE isn't set
1173      * when $HOME is being set.
1174      */
1175     if (var != NULL && *var == '%')
1176     {
1177 	char_u	*p;
1178 	char_u	*exp;
1179 
1180 	p = vim_strchr(var + 1, '%');
1181 	if (p != NULL)
1182 	{
1183 	    vim_strncpy(NameBuff, var + 1, p - (var + 1));
1184 	    exp = mch_getenv(NameBuff);
1185 	    if (exp != NULL && *exp != NUL
1186 					&& STRLEN(exp) + STRLEN(p) < MAXPATHL)
1187 	    {
1188 		vim_snprintf((char *)NameBuff, MAXPATHL, "%s%s", exp, p + 1);
1189 		var = NameBuff;
1190 	    }
1191 	}
1192     }
1193 
1194     if (var != NULL && *var == NUL)	// empty is same as not set
1195 	var = NULL;
1196 
1197     if (enc_utf8 && var != NULL)
1198     {
1199 	int	len;
1200 	char_u  *pp = NULL;
1201 
1202 	// Convert from active codepage to UTF-8.  Other conversions are
1203 	// not done, because they would fail for non-ASCII characters.
1204 	acp_to_enc(var, (int)STRLEN(var), &pp, &len);
1205 	if (pp != NULL)
1206 	{
1207 	    homedir = pp;
1208 	    return;
1209 	}
1210     }
1211 
1212     /*
1213      * Default home dir is C:/
1214      * Best assumption we can make in such a situation.
1215      */
1216     if (var == NULL)
1217 	var = (char_u *)"C:/";
1218 #endif
1219 
1220     if (var != NULL)
1221     {
1222 #ifdef UNIX
1223 	/*
1224 	 * Change to the directory and get the actual path.  This resolves
1225 	 * links.  Don't do it when we can't return.
1226 	 */
1227 	if (mch_dirname(NameBuff, MAXPATHL) == OK
1228 					  && mch_chdir((char *)NameBuff) == 0)
1229 	{
1230 	    if (!mch_chdir((char *)var) && mch_dirname(IObuff, IOSIZE) == OK)
1231 		var = IObuff;
1232 	    if (mch_chdir((char *)NameBuff) != 0)
1233 		emsg(_(e_prev_dir));
1234 	}
1235 #endif
1236 	homedir = vim_strsave(var);
1237     }
1238 }
1239 
1240 #if defined(EXITFREE) || defined(PROTO)
1241     void
1242 free_homedir(void)
1243 {
1244     vim_free(homedir);
1245 }
1246 
1247     void
1248 free_users(void)
1249 {
1250     ga_clear_strings(&ga_users);
1251 }
1252 #endif
1253 
1254 /*
1255  * Call expand_env() and store the result in an allocated string.
1256  * This is not very memory efficient, this expects the result to be freed
1257  * again soon.
1258  */
1259     char_u *
1260 expand_env_save(char_u *src)
1261 {
1262     return expand_env_save_opt(src, FALSE);
1263 }
1264 
1265 /*
1266  * Idem, but when "one" is TRUE handle the string as one file name, only
1267  * expand "~" at the start.
1268  */
1269     char_u *
1270 expand_env_save_opt(char_u *src, int one)
1271 {
1272     char_u	*p;
1273 
1274     p = alloc(MAXPATHL);
1275     if (p != NULL)
1276 	expand_env_esc(src, p, MAXPATHL, FALSE, one, NULL);
1277     return p;
1278 }
1279 
1280 /*
1281  * Expand environment variable with path name.
1282  * "~/" is also expanded, using $HOME.	For Unix "~user/" is expanded.
1283  * Skips over "\ ", "\~" and "\$" (not for Win32 though).
1284  * If anything fails no expansion is done and dst equals src.
1285  */
1286     void
1287 expand_env(
1288     char_u	*src,		// input string e.g. "$HOME/vim.hlp"
1289     char_u	*dst,		// where to put the result
1290     int		dstlen)		// maximum length of the result
1291 {
1292     expand_env_esc(src, dst, dstlen, FALSE, FALSE, NULL);
1293 }
1294 
1295     void
1296 expand_env_esc(
1297     char_u	*srcp,		// input string e.g. "$HOME/vim.hlp"
1298     char_u	*dst,		// where to put the result
1299     int		dstlen,		// maximum length of the result
1300     int		esc,		// escape spaces in expanded variables
1301     int		one,		// "srcp" is one file name
1302     char_u	*startstr)	// start again after this (can be NULL)
1303 {
1304     char_u	*src;
1305     char_u	*tail;
1306     int		c;
1307     char_u	*var;
1308     int		copy_char;
1309     int		mustfree;	// var was allocated, need to free it later
1310     int		at_start = TRUE; // at start of a name
1311     int		startstr_len = 0;
1312 
1313     if (startstr != NULL)
1314 	startstr_len = (int)STRLEN(startstr);
1315 
1316     src = skipwhite(srcp);
1317     --dstlen;		    // leave one char space for "\,"
1318     while (*src && dstlen > 0)
1319     {
1320 #ifdef FEAT_EVAL
1321 	// Skip over `=expr`.
1322 	if (src[0] == '`' && src[1] == '=')
1323 	{
1324 	    size_t len;
1325 
1326 	    var = src;
1327 	    src += 2;
1328 	    (void)skip_expr(&src);
1329 	    if (*src == '`')
1330 		++src;
1331 	    len = src - var;
1332 	    if (len > (size_t)dstlen)
1333 		len = dstlen;
1334 	    vim_strncpy(dst, var, len);
1335 	    dst += len;
1336 	    dstlen -= (int)len;
1337 	    continue;
1338 	}
1339 #endif
1340 	copy_char = TRUE;
1341 	if ((*src == '$'
1342 #ifdef VMS
1343 		    && at_start
1344 #endif
1345 	   )
1346 #if defined(MSWIN)
1347 		|| *src == '%'
1348 #endif
1349 		|| (*src == '~' && at_start))
1350 	{
1351 	    mustfree = FALSE;
1352 
1353 	    /*
1354 	     * The variable name is copied into dst temporarily, because it may
1355 	     * be a string in read-only memory and a NUL needs to be appended.
1356 	     */
1357 	    if (*src != '~')				// environment var
1358 	    {
1359 		tail = src + 1;
1360 		var = dst;
1361 		c = dstlen - 1;
1362 
1363 #ifdef UNIX
1364 		// Unix has ${var-name} type environment vars
1365 		if (*tail == '{' && !vim_isIDc('{'))
1366 		{
1367 		    tail++;	// ignore '{'
1368 		    while (c-- > 0 && *tail && *tail != '}')
1369 			*var++ = *tail++;
1370 		}
1371 		else
1372 #endif
1373 		{
1374 		    while (c-- > 0 && *tail != NUL && ((vim_isIDc(*tail))
1375 #if defined(MSWIN)
1376 			    || (*src == '%' && *tail != '%')
1377 #endif
1378 			    ))
1379 			*var++ = *tail++;
1380 		}
1381 
1382 #if defined(MSWIN) || defined(UNIX)
1383 # ifdef UNIX
1384 		if (src[1] == '{' && *tail != '}')
1385 # else
1386 		if (*src == '%' && *tail != '%')
1387 # endif
1388 		    var = NULL;
1389 		else
1390 		{
1391 # ifdef UNIX
1392 		    if (src[1] == '{')
1393 # else
1394 		    if (*src == '%')
1395 #endif
1396 			++tail;
1397 #endif
1398 		    *var = NUL;
1399 		    var = vim_getenv(dst, &mustfree);
1400 #if defined(MSWIN) || defined(UNIX)
1401 		}
1402 #endif
1403 	    }
1404 							// home directory
1405 	    else if (  src[1] == NUL
1406 		    || vim_ispathsep(src[1])
1407 		    || vim_strchr((char_u *)" ,\t\n", src[1]) != NULL)
1408 	    {
1409 		var = homedir;
1410 		tail = src + 1;
1411 	    }
1412 	    else					// user directory
1413 	    {
1414 #if defined(UNIX) || (defined(VMS) && defined(USER_HOME))
1415 		/*
1416 		 * Copy ~user to dst[], so we can put a NUL after it.
1417 		 */
1418 		tail = src;
1419 		var = dst;
1420 		c = dstlen - 1;
1421 		while (	   c-- > 0
1422 			&& *tail
1423 			&& vim_isfilec(*tail)
1424 			&& !vim_ispathsep(*tail))
1425 		    *var++ = *tail++;
1426 		*var = NUL;
1427 # ifdef UNIX
1428 		/*
1429 		 * If the system supports getpwnam(), use it.
1430 		 * Otherwise, or if getpwnam() fails, the shell is used to
1431 		 * expand ~user.  This is slower and may fail if the shell
1432 		 * does not support ~user (old versions of /bin/sh).
1433 		 */
1434 #  if defined(HAVE_GETPWNAM) && defined(HAVE_PWD_H)
1435 		{
1436 		    // Note: memory allocated by getpwnam() is never freed.
1437 		    // Calling endpwent() apparently doesn't help.
1438 		    struct passwd *pw = (*dst == NUL)
1439 					? NULL : getpwnam((char *)dst + 1);
1440 
1441 		    var = (pw == NULL) ? NULL : (char_u *)pw->pw_dir;
1442 		}
1443 		if (var == NULL)
1444 #  endif
1445 		{
1446 		    expand_T	xpc;
1447 
1448 		    ExpandInit(&xpc);
1449 		    xpc.xp_context = EXPAND_FILES;
1450 		    var = ExpandOne(&xpc, dst, NULL,
1451 				WILD_ADD_SLASH|WILD_SILENT, WILD_EXPAND_FREE);
1452 		    mustfree = TRUE;
1453 		}
1454 
1455 # else	// !UNIX, thus VMS
1456 		/*
1457 		 * USER_HOME is a comma-separated list of
1458 		 * directories to search for the user account in.
1459 		 */
1460 		{
1461 		    char_u	test[MAXPATHL], paths[MAXPATHL];
1462 		    char_u	*path, *next_path, *ptr;
1463 		    stat_T	st;
1464 
1465 		    STRCPY(paths, USER_HOME);
1466 		    next_path = paths;
1467 		    while (*next_path)
1468 		    {
1469 			for (path = next_path; *next_path && *next_path != ',';
1470 				next_path++);
1471 			if (*next_path)
1472 			    *next_path++ = NUL;
1473 			STRCPY(test, path);
1474 			STRCAT(test, "/");
1475 			STRCAT(test, dst + 1);
1476 			if (mch_stat(test, &st) == 0)
1477 			{
1478 			    var = alloc(STRLEN(test) + 1);
1479 			    STRCPY(var, test);
1480 			    mustfree = TRUE;
1481 			    break;
1482 			}
1483 		    }
1484 		}
1485 # endif // UNIX
1486 #else
1487 		// cannot expand user's home directory, so don't try
1488 		var = NULL;
1489 		tail = (char_u *)"";	// for gcc
1490 #endif // UNIX || VMS
1491 	    }
1492 
1493 #ifdef BACKSLASH_IN_FILENAME
1494 	    // If 'shellslash' is set change backslashes to forward slashes.
1495 	    // Can't use slash_adjust(), p_ssl may be set temporarily.
1496 	    if (p_ssl && var != NULL && vim_strchr(var, '\\') != NULL)
1497 	    {
1498 		char_u	*p = vim_strsave(var);
1499 
1500 		if (p != NULL)
1501 		{
1502 		    if (mustfree)
1503 			vim_free(var);
1504 		    var = p;
1505 		    mustfree = TRUE;
1506 		    forward_slash(var);
1507 		}
1508 	    }
1509 #endif
1510 
1511 	    // If "var" contains white space, escape it with a backslash.
1512 	    // Required for ":e ~/tt" when $HOME includes a space.
1513 	    if (esc && var != NULL && vim_strpbrk(var, (char_u *)" \t") != NULL)
1514 	    {
1515 		char_u	*p = vim_strsave_escaped(var, (char_u *)" \t");
1516 
1517 		if (p != NULL)
1518 		{
1519 		    if (mustfree)
1520 			vim_free(var);
1521 		    var = p;
1522 		    mustfree = TRUE;
1523 		}
1524 	    }
1525 
1526 	    if (var != NULL && *var != NUL
1527 		    && (STRLEN(var) + STRLEN(tail) + 1 < (unsigned)dstlen))
1528 	    {
1529 		STRCPY(dst, var);
1530 		dstlen -= (int)STRLEN(var);
1531 		c = (int)STRLEN(var);
1532 		// if var[] ends in a path separator and tail[] starts
1533 		// with it, skip a character
1534 		if (*var != NUL && after_pathsep(dst, dst + c)
1535 #if defined(BACKSLASH_IN_FILENAME) || defined(AMIGA)
1536 			&& dst[-1] != ':'
1537 #endif
1538 			&& vim_ispathsep(*tail))
1539 		    ++tail;
1540 		dst += c;
1541 		src = tail;
1542 		copy_char = FALSE;
1543 	    }
1544 	    if (mustfree)
1545 		vim_free(var);
1546 	}
1547 
1548 	if (copy_char)	    // copy at least one char
1549 	{
1550 	    /*
1551 	     * Recognize the start of a new name, for '~'.
1552 	     * Don't do this when "one" is TRUE, to avoid expanding "~" in
1553 	     * ":edit foo ~ foo".
1554 	     */
1555 	    at_start = FALSE;
1556 	    if (src[0] == '\\' && src[1] != NUL)
1557 	    {
1558 		*dst++ = *src++;
1559 		--dstlen;
1560 	    }
1561 	    else if ((src[0] == ' ' || src[0] == ',') && !one)
1562 		at_start = TRUE;
1563 	    if (dstlen > 0)
1564 	    {
1565 		*dst++ = *src++;
1566 		--dstlen;
1567 
1568 		if (startstr != NULL && src - startstr_len >= srcp
1569 			&& STRNCMP(src - startstr_len, startstr,
1570 							    startstr_len) == 0)
1571 		    at_start = TRUE;
1572 	    }
1573 	}
1574 
1575     }
1576     *dst = NUL;
1577 }
1578 
1579 /*
1580  * If the string between "p" and "pend" ends in "name/", return "pend" minus
1581  * the length of "name/".  Otherwise return "pend".
1582  */
1583     static char_u *
1584 remove_tail(char_u *p, char_u *pend, char_u *name)
1585 {
1586     int		len = (int)STRLEN(name) + 1;
1587     char_u	*newend = pend - len;
1588 
1589     if (newend >= p
1590 	    && fnamencmp(newend, name, len - 1) == 0
1591 	    && (newend == p || after_pathsep(p, newend)))
1592 	return newend;
1593     return pend;
1594 }
1595 
1596 /*
1597  * Check if the directory "vimdir/<version>" or "vimdir/runtime" exists.
1598  * Return NULL if not, return its name in allocated memory otherwise.
1599  */
1600     static char_u *
1601 vim_version_dir(char_u *vimdir)
1602 {
1603     char_u	*p;
1604 
1605     if (vimdir == NULL || *vimdir == NUL)
1606 	return NULL;
1607     p = concat_fnames(vimdir, (char_u *)VIM_VERSION_NODOT, TRUE);
1608     if (p != NULL && mch_isdir(p))
1609 	return p;
1610     vim_free(p);
1611     p = concat_fnames(vimdir, (char_u *)RUNTIME_DIRNAME, TRUE);
1612     if (p != NULL && mch_isdir(p))
1613 	return p;
1614     vim_free(p);
1615     return NULL;
1616 }
1617 
1618 /*
1619  * Vim's version of getenv().
1620  * Special handling of $HOME, $VIM and $VIMRUNTIME.
1621  * Also does ACP to 'enc' conversion for Win32.
1622  * "mustfree" is set to TRUE when returned is allocated, it must be
1623  * initialized to FALSE by the caller.
1624  */
1625     char_u *
1626 vim_getenv(char_u *name, int *mustfree)
1627 {
1628     char_u	*p = NULL;
1629     char_u	*pend;
1630     int		vimruntime;
1631 #ifdef MSWIN
1632     WCHAR	*wn, *wp;
1633 
1634     // use "C:/" when $HOME is not set
1635     if (STRCMP(name, "HOME") == 0)
1636 	return homedir;
1637 
1638     // Use Wide function
1639     wn = enc_to_utf16(name, NULL);
1640     if (wn == NULL)
1641 	return NULL;
1642 
1643     wp = _wgetenv(wn);
1644     vim_free(wn);
1645 
1646     if (wp != NULL && *wp == NUL)   // empty is the same as not set
1647 	wp = NULL;
1648 
1649     if (wp != NULL)
1650     {
1651 	p = utf16_to_enc(wp, NULL);
1652 	if (p == NULL)
1653 	    return NULL;
1654 
1655 	*mustfree = TRUE;
1656 	return p;
1657     }
1658 #else
1659     p = mch_getenv(name);
1660     if (p != NULL && *p == NUL)	    // empty is the same as not set
1661 	p = NULL;
1662 
1663     if (p != NULL)
1664 	return p;
1665 #endif
1666 
1667     // handling $VIMRUNTIME and $VIM is below, bail out if it's another name.
1668     vimruntime = (STRCMP(name, "VIMRUNTIME") == 0);
1669     if (!vimruntime && STRCMP(name, "VIM") != 0)
1670 	return NULL;
1671 
1672     /*
1673      * When expanding $VIMRUNTIME fails, try using $VIM/vim<version> or $VIM.
1674      * Don't do this when default_vimruntime_dir is non-empty.
1675      */
1676     if (vimruntime
1677 #ifdef HAVE_PATHDEF
1678 	    && *default_vimruntime_dir == NUL
1679 #endif
1680        )
1681     {
1682 #ifdef MSWIN
1683 	// Use Wide function
1684 	wp = _wgetenv(L"VIM");
1685 	if (wp != NULL && *wp == NUL)	    // empty is the same as not set
1686 	    wp = NULL;
1687 	if (wp != NULL)
1688 	{
1689 	    char_u *q = utf16_to_enc(wp, NULL);
1690 	    if (q != NULL)
1691 	    {
1692 		p = vim_version_dir(q);
1693 		*mustfree = TRUE;
1694 		if (p == NULL)
1695 		    p = q;
1696 	    }
1697 	}
1698 #else
1699 	p = mch_getenv((char_u *)"VIM");
1700 	if (p != NULL && *p == NUL)	    // empty is the same as not set
1701 	    p = NULL;
1702 	if (p != NULL)
1703 	{
1704 	    p = vim_version_dir(p);
1705 	    if (p != NULL)
1706 		*mustfree = TRUE;
1707 	    else
1708 		p = mch_getenv((char_u *)"VIM");
1709 	}
1710 #endif
1711     }
1712 
1713     /*
1714      * When expanding $VIM or $VIMRUNTIME fails, try using:
1715      * - the directory name from 'helpfile' (unless it contains '$')
1716      * - the executable name from argv[0]
1717      */
1718     if (p == NULL)
1719     {
1720 	if (p_hf != NULL && vim_strchr(p_hf, '$') == NULL)
1721 	    p = p_hf;
1722 #ifdef USE_EXE_NAME
1723 	/*
1724 	 * Use the name of the executable, obtained from argv[0].
1725 	 */
1726 	else
1727 	    p = exe_name;
1728 #endif
1729 	if (p != NULL)
1730 	{
1731 	    // remove the file name
1732 	    pend = gettail(p);
1733 
1734 	    // remove "doc/" from 'helpfile', if present
1735 	    if (p == p_hf)
1736 		pend = remove_tail(p, pend, (char_u *)"doc");
1737 
1738 #ifdef USE_EXE_NAME
1739 # ifdef MACOS_X
1740 	    // remove "MacOS" from exe_name and add "Resources/vim"
1741 	    if (p == exe_name)
1742 	    {
1743 		char_u	*pend1;
1744 		char_u	*pnew;
1745 
1746 		pend1 = remove_tail(p, pend, (char_u *)"MacOS");
1747 		if (pend1 != pend)
1748 		{
1749 		    pnew = alloc(pend1 - p + 15);
1750 		    if (pnew != NULL)
1751 		    {
1752 			STRNCPY(pnew, p, (pend1 - p));
1753 			STRCPY(pnew + (pend1 - p), "Resources/vim");
1754 			p = pnew;
1755 			pend = p + STRLEN(p);
1756 		    }
1757 		}
1758 	    }
1759 # endif
1760 	    // remove "src/" from exe_name, if present
1761 	    if (p == exe_name)
1762 		pend = remove_tail(p, pend, (char_u *)"src");
1763 #endif
1764 
1765 	    // for $VIM, remove "runtime/" or "vim54/", if present
1766 	    if (!vimruntime)
1767 	    {
1768 		pend = remove_tail(p, pend, (char_u *)RUNTIME_DIRNAME);
1769 		pend = remove_tail(p, pend, (char_u *)VIM_VERSION_NODOT);
1770 	    }
1771 
1772 	    // remove trailing path separator
1773 	    if (pend > p && after_pathsep(p, pend))
1774 		--pend;
1775 
1776 #ifdef MACOS_X
1777 	    if (p == exe_name || p == p_hf)
1778 #endif
1779 		// check that the result is a directory name
1780 		p = vim_strnsave(p, (int)(pend - p));
1781 
1782 	    if (p != NULL && !mch_isdir(p))
1783 		VIM_CLEAR(p);
1784 	    else
1785 	    {
1786 #ifdef USE_EXE_NAME
1787 		// may add "/vim54" or "/runtime" if it exists
1788 		if (vimruntime && (pend = vim_version_dir(p)) != NULL)
1789 		{
1790 		    vim_free(p);
1791 		    p = pend;
1792 		}
1793 #endif
1794 		*mustfree = TRUE;
1795 	    }
1796 	}
1797     }
1798 
1799 #ifdef HAVE_PATHDEF
1800     // When there is a pathdef.c file we can use default_vim_dir and
1801     // default_vimruntime_dir
1802     if (p == NULL)
1803     {
1804 	// Only use default_vimruntime_dir when it is not empty
1805 	if (vimruntime && *default_vimruntime_dir != NUL)
1806 	{
1807 	    p = default_vimruntime_dir;
1808 	    *mustfree = FALSE;
1809 	}
1810 	else if (*default_vim_dir != NUL)
1811 	{
1812 	    if (vimruntime && (p = vim_version_dir(default_vim_dir)) != NULL)
1813 		*mustfree = TRUE;
1814 	    else
1815 	    {
1816 		p = default_vim_dir;
1817 		*mustfree = FALSE;
1818 	    }
1819 	}
1820     }
1821 #endif
1822 
1823     /*
1824      * Set the environment variable, so that the new value can be found fast
1825      * next time, and others can also use it (e.g. Perl).
1826      */
1827     if (p != NULL)
1828     {
1829 	if (vimruntime)
1830 	{
1831 	    vim_setenv((char_u *)"VIMRUNTIME", p);
1832 	    didset_vimruntime = TRUE;
1833 	}
1834 	else
1835 	{
1836 	    vim_setenv((char_u *)"VIM", p);
1837 	    didset_vim = TRUE;
1838 	}
1839     }
1840     return p;
1841 }
1842 
1843 #if defined(FEAT_EVAL) || defined(PROTO)
1844     void
1845 vim_unsetenv(char_u *var)
1846 {
1847 #ifdef HAVE_UNSETENV
1848     unsetenv((char *)var);
1849 #else
1850     vim_setenv(var, (char_u *)"");
1851 #endif
1852 }
1853 #endif
1854 
1855 
1856 /*
1857  * Our portable version of setenv.
1858  */
1859     void
1860 vim_setenv(char_u *name, char_u *val)
1861 {
1862 #ifdef HAVE_SETENV
1863     mch_setenv((char *)name, (char *)val, 1);
1864 #else
1865     char_u	*envbuf;
1866 
1867     /*
1868      * Putenv does not copy the string, it has to remain
1869      * valid.  The allocated memory will never be freed.
1870      */
1871     envbuf = alloc(STRLEN(name) + STRLEN(val) + 2);
1872     if (envbuf != NULL)
1873     {
1874 	sprintf((char *)envbuf, "%s=%s", name, val);
1875 	putenv((char *)envbuf);
1876     }
1877 #endif
1878 #ifdef FEAT_GETTEXT
1879     /*
1880      * When setting $VIMRUNTIME adjust the directory to find message
1881      * translations to $VIMRUNTIME/lang.
1882      */
1883     if (*val != NUL && STRICMP(name, "VIMRUNTIME") == 0)
1884     {
1885 	char_u	*buf = concat_str(val, (char_u *)"/lang");
1886 
1887 	if (buf != NULL)
1888 	{
1889 	    bindtextdomain(VIMPACKAGE, (char *)buf);
1890 	    vim_free(buf);
1891 	}
1892     }
1893 #endif
1894 }
1895 
1896 /*
1897  * Function given to ExpandGeneric() to obtain an environment variable name.
1898  */
1899     char_u *
1900 get_env_name(
1901     expand_T	*xp UNUSED,
1902     int		idx)
1903 {
1904 # if defined(AMIGA)
1905     /*
1906      * No environ[] on the Amiga.
1907      */
1908     return NULL;
1909 # else
1910 # ifndef __WIN32__
1911     // Borland C++ 5.2 has this in a header file.
1912     extern char		**environ;
1913 # endif
1914 # define ENVNAMELEN 100
1915     static char_u	name[ENVNAMELEN];
1916     char_u		*str;
1917     int			n;
1918 
1919     str = (char_u *)environ[idx];
1920     if (str == NULL)
1921 	return NULL;
1922 
1923     for (n = 0; n < ENVNAMELEN - 1; ++n)
1924     {
1925 	if (str[n] == '=' || str[n] == NUL)
1926 	    break;
1927 	name[n] = str[n];
1928     }
1929     name[n] = NUL;
1930     return name;
1931 # endif
1932 }
1933 
1934 /*
1935  * Add a user name to the list of users in ga_users.
1936  * Do nothing if user name is NULL or empty.
1937  */
1938     static void
1939 add_user(char_u *user, int need_copy)
1940 {
1941     char_u	*user_copy = (user != NULL && need_copy)
1942 						    ? vim_strsave(user) : user;
1943 
1944     if (user_copy == NULL || *user_copy == NUL || ga_grow(&ga_users, 1) == FAIL)
1945     {
1946 	if (need_copy)
1947 	    vim_free(user);
1948 	return;
1949     }
1950     ((char_u **)(ga_users.ga_data))[ga_users.ga_len++] = user_copy;
1951 }
1952 
1953 /*
1954  * Find all user names for user completion.
1955  * Done only once and then cached.
1956  */
1957     static void
1958 init_users(void)
1959 {
1960     static int	lazy_init_done = FALSE;
1961 
1962     if (lazy_init_done)
1963 	return;
1964 
1965     lazy_init_done = TRUE;
1966     ga_init2(&ga_users, sizeof(char_u *), 20);
1967 
1968 # if defined(HAVE_GETPWENT) && defined(HAVE_PWD_H)
1969     {
1970 	struct passwd*	pw;
1971 
1972 	setpwent();
1973 	while ((pw = getpwent()) != NULL)
1974 	    add_user((char_u *)pw->pw_name, TRUE);
1975 	endpwent();
1976     }
1977 # elif defined(MSWIN)
1978     {
1979 	DWORD		nusers = 0, ntotal = 0, i;
1980 	PUSER_INFO_0	uinfo;
1981 
1982 	if (NetUserEnum(NULL, 0, 0, (LPBYTE *) &uinfo, MAX_PREFERRED_LENGTH,
1983 				       &nusers, &ntotal, NULL) == NERR_Success)
1984 	{
1985 	    for (i = 0; i < nusers; i++)
1986 		add_user(utf16_to_enc(uinfo[i].usri0_name, NULL), FALSE);
1987 
1988 	    NetApiBufferFree(uinfo);
1989 	}
1990     }
1991 # endif
1992 # if defined(HAVE_GETPWNAM)
1993     {
1994 	char_u	*user_env = mch_getenv((char_u *)"USER");
1995 
1996 	// The $USER environment variable may be a valid remote user name (NIS,
1997 	// LDAP) not already listed by getpwent(), as getpwent() only lists
1998 	// local user names.  If $USER is not already listed, check whether it
1999 	// is a valid remote user name using getpwnam() and if it is, add it to
2000 	// the list of user names.
2001 
2002 	if (user_env != NULL && *user_env != NUL)
2003 	{
2004 	    int	i;
2005 
2006 	    for (i = 0; i < ga_users.ga_len; i++)
2007 	    {
2008 		char_u	*local_user = ((char_u **)ga_users.ga_data)[i];
2009 
2010 		if (STRCMP(local_user, user_env) == 0)
2011 		    break;
2012 	    }
2013 
2014 	    if (i == ga_users.ga_len)
2015 	    {
2016 		struct passwd	*pw = getpwnam((char *)user_env);
2017 
2018 		if (pw != NULL)
2019 		    add_user((char_u *)pw->pw_name, TRUE);
2020 	    }
2021 	}
2022     }
2023 # endif
2024 }
2025 
2026 /*
2027  * Function given to ExpandGeneric() to obtain an user names.
2028  */
2029     char_u*
2030 get_users(expand_T *xp UNUSED, int idx)
2031 {
2032     init_users();
2033     if (idx < ga_users.ga_len)
2034 	return ((char_u **)ga_users.ga_data)[idx];
2035     return NULL;
2036 }
2037 
2038 /*
2039  * Check whether name matches a user name. Return:
2040  * 0 if name does not match any user name.
2041  * 1 if name partially matches the beginning of a user name.
2042  * 2 is name fully matches a user name.
2043  */
2044     int
2045 match_user(char_u *name)
2046 {
2047     int i;
2048     int n = (int)STRLEN(name);
2049     int result = 0;
2050 
2051     init_users();
2052     for (i = 0; i < ga_users.ga_len; i++)
2053     {
2054 	if (STRCMP(((char_u **)ga_users.ga_data)[i], name) == 0)
2055 	    return 2; // full match
2056 	if (STRNCMP(((char_u **)ga_users.ga_data)[i], name, n) == 0)
2057 	    result = 1; // partial match
2058     }
2059     return result;
2060 }
2061 
2062 /*
2063  * Concatenate two strings and return the result in allocated memory.
2064  * Returns NULL when out of memory.
2065  */
2066     char_u  *
2067 concat_str(char_u *str1, char_u *str2)
2068 {
2069     char_u  *dest;
2070     size_t  l = STRLEN(str1);
2071 
2072     dest = alloc(l + STRLEN(str2) + 1L);
2073     if (dest != NULL)
2074     {
2075 	STRCPY(dest, str1);
2076 	STRCPY(dest + l, str2);
2077     }
2078     return dest;
2079 }
2080 
2081     static void
2082 prepare_to_exit(void)
2083 {
2084 #if defined(SIGHUP) && defined(SIG_IGN)
2085     // Ignore SIGHUP, because a dropped connection causes a read error, which
2086     // makes Vim exit and then handling SIGHUP causes various reentrance
2087     // problems.
2088     signal(SIGHUP, SIG_IGN);
2089 #endif
2090 
2091 #ifdef FEAT_GUI
2092     if (gui.in_use)
2093     {
2094 	gui.dying = TRUE;
2095 	out_trash();	// trash any pending output
2096     }
2097     else
2098 #endif
2099     {
2100 	windgoto((int)Rows - 1, 0);
2101 
2102 	/*
2103 	 * Switch terminal mode back now, so messages end up on the "normal"
2104 	 * screen (if there are two screens).
2105 	 */
2106 	settmode(TMODE_COOK);
2107 	stoptermcap();
2108 	out_flush();
2109     }
2110 }
2111 
2112 /*
2113  * Preserve files and exit.
2114  * When called IObuff must contain a message.
2115  * NOTE: This may be called from deathtrap() in a signal handler, avoid unsafe
2116  * functions, such as allocating memory.
2117  */
2118     void
2119 preserve_exit(void)
2120 {
2121     buf_T	*buf;
2122 
2123     prepare_to_exit();
2124 
2125     // Setting this will prevent free() calls.  That avoids calling free()
2126     // recursively when free() was invoked with a bad pointer.
2127     really_exiting = TRUE;
2128 
2129     out_str(IObuff);
2130     screen_start();		    // don't know where cursor is now
2131     out_flush();
2132 
2133     ml_close_notmod();		    // close all not-modified buffers
2134 
2135     FOR_ALL_BUFFERS(buf)
2136     {
2137 	if (buf->b_ml.ml_mfp != NULL && buf->b_ml.ml_mfp->mf_fname != NULL)
2138 	{
2139 	    OUT_STR("Vim: preserving files...\n");
2140 	    screen_start();	    // don't know where cursor is now
2141 	    out_flush();
2142 	    ml_sync_all(FALSE, FALSE);	// preserve all swap files
2143 	    break;
2144 	}
2145     }
2146 
2147     ml_close_all(FALSE);	    // close all memfiles, without deleting
2148 
2149     OUT_STR("Vim: Finished.\n");
2150 
2151     getout(1);
2152 }
2153 
2154 /*
2155  * Check for CTRL-C pressed, but only once in a while.
2156  * Should be used instead of ui_breakcheck() for functions that check for
2157  * each line in the file.  Calling ui_breakcheck() each time takes too much
2158  * time, because it can be a system call.
2159  */
2160 
2161 #ifndef BREAKCHECK_SKIP
2162 # define BREAKCHECK_SKIP 1000
2163 #endif
2164 
2165 static int	breakcheck_count = 0;
2166 
2167     void
2168 line_breakcheck(void)
2169 {
2170     if (++breakcheck_count >= BREAKCHECK_SKIP)
2171     {
2172 	breakcheck_count = 0;
2173 	ui_breakcheck();
2174     }
2175 }
2176 
2177 /*
2178  * Like line_breakcheck() but check 10 times less often.
2179  */
2180     void
2181 fast_breakcheck(void)
2182 {
2183     if (++breakcheck_count >= BREAKCHECK_SKIP * 10)
2184     {
2185 	breakcheck_count = 0;
2186 	ui_breakcheck();
2187     }
2188 }
2189 
2190 #if defined(VIM_BACKTICK) || defined(FEAT_EVAL) \
2191 	|| (defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \
2192 	|| defined(PROTO)
2193 
2194 #ifndef SEEK_SET
2195 # define SEEK_SET 0
2196 #endif
2197 #ifndef SEEK_END
2198 # define SEEK_END 2
2199 #endif
2200 
2201 /*
2202  * Get the stdout of an external command.
2203  * If "ret_len" is NULL replace NUL characters with NL.  When "ret_len" is not
2204  * NULL store the length there.
2205  * Returns an allocated string, or NULL for error.
2206  */
2207     char_u *
2208 get_cmd_output(
2209     char_u	*cmd,
2210     char_u	*infile,	// optional input file name
2211     int		flags,		// can be SHELL_SILENT
2212     int		*ret_len)
2213 {
2214     char_u	*tempname;
2215     char_u	*command;
2216     char_u	*buffer = NULL;
2217     int		len;
2218     int		i = 0;
2219     FILE	*fd;
2220 
2221     if (check_restricted() || check_secure())
2222 	return NULL;
2223 
2224     // get a name for the temp file
2225     if ((tempname = vim_tempname('o', FALSE)) == NULL)
2226     {
2227 	emsg(_(e_notmp));
2228 	return NULL;
2229     }
2230 
2231     // Add the redirection stuff
2232     command = make_filter_cmd(cmd, infile, tempname);
2233     if (command == NULL)
2234 	goto done;
2235 
2236     /*
2237      * Call the shell to execute the command (errors are ignored).
2238      * Don't check timestamps here.
2239      */
2240     ++no_check_timestamps;
2241     call_shell(command, SHELL_DOOUT | SHELL_EXPAND | flags);
2242     --no_check_timestamps;
2243 
2244     vim_free(command);
2245 
2246     /*
2247      * read the names from the file into memory
2248      */
2249 # ifdef VMS
2250     // created temporary file is not always readable as binary
2251     fd = mch_fopen((char *)tempname, "r");
2252 # else
2253     fd = mch_fopen((char *)tempname, READBIN);
2254 # endif
2255 
2256     if (fd == NULL)
2257     {
2258 	semsg(_(e_notopen), tempname);
2259 	goto done;
2260     }
2261 
2262     fseek(fd, 0L, SEEK_END);
2263     len = ftell(fd);		    // get size of temp file
2264     fseek(fd, 0L, SEEK_SET);
2265 
2266     buffer = alloc(len + 1);
2267     if (buffer != NULL)
2268 	i = (int)fread((char *)buffer, (size_t)1, (size_t)len, fd);
2269     fclose(fd);
2270     mch_remove(tempname);
2271     if (buffer == NULL)
2272 	goto done;
2273 #ifdef VMS
2274     len = i;	// VMS doesn't give us what we asked for...
2275 #endif
2276     if (i != len)
2277     {
2278 	semsg(_(e_notread), tempname);
2279 	VIM_CLEAR(buffer);
2280     }
2281     else if (ret_len == NULL)
2282     {
2283 	// Change NUL into SOH, otherwise the string is truncated.
2284 	for (i = 0; i < len; ++i)
2285 	    if (buffer[i] == NUL)
2286 		buffer[i] = 1;
2287 
2288 	buffer[len] = NUL;	// make sure the buffer is terminated
2289     }
2290     else
2291 	*ret_len = len;
2292 
2293 done:
2294     vim_free(tempname);
2295     return buffer;
2296 }
2297 
2298 # if defined(FEAT_EVAL) || defined(PROTO)
2299 
2300     static void
2301 get_cmd_output_as_rettv(
2302     typval_T	*argvars,
2303     typval_T	*rettv,
2304     int		retlist)
2305 {
2306     char_u	*res = NULL;
2307     char_u	*p;
2308     char_u	*infile = NULL;
2309     int		err = FALSE;
2310     FILE	*fd;
2311     list_T	*list = NULL;
2312     int		flags = SHELL_SILENT;
2313 
2314     rettv->v_type = VAR_STRING;
2315     rettv->vval.v_string = NULL;
2316     if (check_restricted() || check_secure())
2317 	goto errret;
2318 
2319     if (argvars[1].v_type != VAR_UNKNOWN)
2320     {
2321 	/*
2322 	 * Write the text to a temp file, to be used for input of the shell
2323 	 * command.
2324 	 */
2325 	if ((infile = vim_tempname('i', TRUE)) == NULL)
2326 	{
2327 	    emsg(_(e_notmp));
2328 	    goto errret;
2329 	}
2330 
2331 	fd = mch_fopen((char *)infile, WRITEBIN);
2332 	if (fd == NULL)
2333 	{
2334 	    semsg(_(e_notopen), infile);
2335 	    goto errret;
2336 	}
2337 	if (argvars[1].v_type == VAR_NUMBER)
2338 	{
2339 	    linenr_T	lnum;
2340 	    buf_T	*buf;
2341 
2342 	    buf = buflist_findnr(argvars[1].vval.v_number);
2343 	    if (buf == NULL)
2344 	    {
2345 		semsg(_(e_nobufnr), argvars[1].vval.v_number);
2346 		fclose(fd);
2347 		goto errret;
2348 	    }
2349 
2350 	    for (lnum = 1; lnum <= buf->b_ml.ml_line_count; lnum++)
2351 	    {
2352 		for (p = ml_get_buf(buf, lnum, FALSE); *p != NUL; ++p)
2353 		    if (putc(*p == '\n' ? NUL : *p, fd) == EOF)
2354 		    {
2355 			err = TRUE;
2356 			break;
2357 		    }
2358 		if (putc(NL, fd) == EOF)
2359 		{
2360 		    err = TRUE;
2361 		    break;
2362 		}
2363 	    }
2364 	}
2365 	else if (argvars[1].v_type == VAR_LIST)
2366 	{
2367 	    if (write_list(fd, argvars[1].vval.v_list, TRUE) == FAIL)
2368 		err = TRUE;
2369 	}
2370 	else
2371 	{
2372 	    size_t	len;
2373 	    char_u	buf[NUMBUFLEN];
2374 
2375 	    p = tv_get_string_buf_chk(&argvars[1], buf);
2376 	    if (p == NULL)
2377 	    {
2378 		fclose(fd);
2379 		goto errret;		// type error; errmsg already given
2380 	    }
2381 	    len = STRLEN(p);
2382 	    if (len > 0 && fwrite(p, len, 1, fd) != 1)
2383 		err = TRUE;
2384 	}
2385 	if (fclose(fd) != 0)
2386 	    err = TRUE;
2387 	if (err)
2388 	{
2389 	    emsg(_("E677: Error writing temp file"));
2390 	    goto errret;
2391 	}
2392     }
2393 
2394     // Omit SHELL_COOKED when invoked with ":silent".  Avoids that the shell
2395     // echoes typeahead, that messes up the display.
2396     if (!msg_silent)
2397 	flags += SHELL_COOKED;
2398 
2399     if (retlist)
2400     {
2401 	int		len;
2402 	listitem_T	*li;
2403 	char_u		*s = NULL;
2404 	char_u		*start;
2405 	char_u		*end;
2406 	int		i;
2407 
2408 	res = get_cmd_output(tv_get_string(&argvars[0]), infile, flags, &len);
2409 	if (res == NULL)
2410 	    goto errret;
2411 
2412 	list = list_alloc();
2413 	if (list == NULL)
2414 	    goto errret;
2415 
2416 	for (i = 0; i < len; ++i)
2417 	{
2418 	    start = res + i;
2419 	    while (i < len && res[i] != NL)
2420 		++i;
2421 	    end = res + i;
2422 
2423 	    s = alloc(end - start + 1);
2424 	    if (s == NULL)
2425 		goto errret;
2426 
2427 	    for (p = s; start < end; ++p, ++start)
2428 		*p = *start == NUL ? NL : *start;
2429 	    *p = NUL;
2430 
2431 	    li = listitem_alloc();
2432 	    if (li == NULL)
2433 	    {
2434 		vim_free(s);
2435 		goto errret;
2436 	    }
2437 	    li->li_tv.v_type = VAR_STRING;
2438 	    li->li_tv.v_lock = 0;
2439 	    li->li_tv.vval.v_string = s;
2440 	    list_append(list, li);
2441 	}
2442 
2443 	rettv_list_set(rettv, list);
2444 	list = NULL;
2445     }
2446     else
2447     {
2448 	res = get_cmd_output(tv_get_string(&argvars[0]), infile, flags, NULL);
2449 #ifdef USE_CRNL
2450 	// translate <CR><NL> into <NL>
2451 	if (res != NULL)
2452 	{
2453 	    char_u	*s, *d;
2454 
2455 	    d = res;
2456 	    for (s = res; *s; ++s)
2457 	    {
2458 		if (s[0] == CAR && s[1] == NL)
2459 		    ++s;
2460 		*d++ = *s;
2461 	    }
2462 	    *d = NUL;
2463 	}
2464 #endif
2465 	rettv->vval.v_string = res;
2466 	res = NULL;
2467     }
2468 
2469 errret:
2470     if (infile != NULL)
2471     {
2472 	mch_remove(infile);
2473 	vim_free(infile);
2474     }
2475     if (res != NULL)
2476 	vim_free(res);
2477     if (list != NULL)
2478 	list_free(list);
2479 }
2480 
2481 /*
2482  * "system()" function
2483  */
2484     void
2485 f_system(typval_T *argvars, typval_T *rettv)
2486 {
2487     get_cmd_output_as_rettv(argvars, rettv, FALSE);
2488 }
2489 
2490 /*
2491  * "systemlist()" function
2492  */
2493     void
2494 f_systemlist(typval_T *argvars, typval_T *rettv)
2495 {
2496     get_cmd_output_as_rettv(argvars, rettv, TRUE);
2497 }
2498 # endif // FEAT_EVAL
2499 
2500 #endif
2501 
2502 /*
2503  * Return TRUE when need to go to Insert mode because of 'insertmode'.
2504  * Don't do this when still processing a command or a mapping.
2505  * Don't do this when inside a ":normal" command.
2506  */
2507     int
2508 goto_im(void)
2509 {
2510     return (p_im && stuff_empty() && typebuf_typed());
2511 }
2512 
2513 /*
2514  * Returns the isolated name of the shell in allocated memory:
2515  * - Skip beyond any path.  E.g., "/usr/bin/csh -f" -> "csh -f".
2516  * - Remove any argument.  E.g., "csh -f" -> "csh".
2517  * But don't allow a space in the path, so that this works:
2518  *   "/usr/bin/csh --rcfile ~/.cshrc"
2519  * But don't do that for Windows, it's common to have a space in the path.
2520  */
2521     char_u *
2522 get_isolated_shell_name(void)
2523 {
2524     char_u *p;
2525 
2526 #ifdef MSWIN
2527     p = gettail(p_sh);
2528     p = vim_strnsave(p, (int)(skiptowhite(p) - p));
2529 #else
2530     p = skiptowhite(p_sh);
2531     if (*p == NUL)
2532     {
2533 	// No white space, use the tail.
2534 	p = vim_strsave(gettail(p_sh));
2535     }
2536     else
2537     {
2538 	char_u  *p1, *p2;
2539 
2540 	// Find the last path separator before the space.
2541 	p1 = p_sh;
2542 	for (p2 = p_sh; p2 < p; MB_PTR_ADV(p2))
2543 	    if (vim_ispathsep(*p2))
2544 		p1 = p2 + 1;
2545 	p = vim_strnsave(p1, (int)(p - p1));
2546     }
2547 #endif
2548     return p;
2549 }
2550 
2551 /*
2552  * Check if the "://" of a URL is at the pointer, return URL_SLASH.
2553  * Also check for ":\\", which MS Internet Explorer accepts, return
2554  * URL_BACKSLASH.
2555  */
2556     int
2557 path_is_url(char_u *p)
2558 {
2559     if (STRNCMP(p, "://", (size_t)3) == 0)
2560 	return URL_SLASH;
2561     else if (STRNCMP(p, ":\\\\", (size_t)3) == 0)
2562 	return URL_BACKSLASH;
2563     return 0;
2564 }
2565 
2566 /*
2567  * Check if "fname" starts with "name://".  Return URL_SLASH if it does.
2568  * Return URL_BACKSLASH for "name:\\".
2569  * Return zero otherwise.
2570  */
2571     int
2572 path_with_url(char_u *fname)
2573 {
2574     char_u *p;
2575 
2576     for (p = fname; isalpha(*p); ++p)
2577 	;
2578     return path_is_url(p);
2579 }
2580 
2581 /*
2582  * Put timestamp "tt" in "buf[buflen]" in a nice format.
2583  */
2584     void
2585 add_time(char_u *buf, size_t buflen, time_t tt)
2586 {
2587 #ifdef HAVE_STRFTIME
2588     struct tm	tmval;
2589     struct tm	*curtime;
2590 
2591     if (vim_time() - tt >= 100)
2592     {
2593 	curtime = vim_localtime(&tt, &tmval);
2594 	if (vim_time() - tt < (60L * 60L * 12L))
2595 	    // within 12 hours
2596 	    (void)strftime((char *)buf, buflen, "%H:%M:%S", curtime);
2597 	else
2598 	    // longer ago
2599 	    (void)strftime((char *)buf, buflen, "%Y/%m/%d %H:%M:%S", curtime);
2600     }
2601     else
2602 #endif
2603     {
2604 	long seconds = (long)(vim_time() - tt);
2605 
2606 	vim_snprintf((char *)buf, buflen,
2607 		NGETTEXT("%ld second ago", "%ld seconds ago", seconds),
2608 		seconds);
2609     }
2610 }
2611